summaryrefslogtreecommitdiff
path: root/unoidl
diff options
context:
space:
mode:
authorStephan Bergmann <sbergman@redhat.com>2013-05-16 14:50:21 +0200
committerStephan Bergmann <sbergman@redhat.com>2013-05-16 16:12:45 +0200
commita1dff2901e9b6f70ea87df5e76825367b38ceaf4 (patch)
treed1284375fd10c07c736c2edec450cfd823b096d0 /unoidl
parent08662568a590bfb20849fce077d8b5aff8b99b57 (diff)
Support for annotations in the new UNOIDL format
...used for now to transport @deprecated information. Also, improve Idx-String (formerly Idx-Name, but also used for UTF-8 annotations now) format, using the 0x80000000 for the indirection rather than the base case. (And the README erroneously used "Offset of" Idx-String all over the place.) Change-Id: I7003b1558ab536a11a9af308f9b16a7ef8840792
Diffstat (limited to 'unoidl')
-rw-r--r--unoidl/README120
-rw-r--r--unoidl/source/legacyprovider.cxx117
-rw-r--r--unoidl/source/reg2unoidl.cxx339
-rw-r--r--unoidl/source/unoidlprovider.cxx338
4 files changed, 651 insertions, 263 deletions
diff --git a/unoidl/README b/unoidl/README
index 5daff7a618c2..84246e9db876 100644
--- a/unoidl/README
+++ b/unoidl/README
@@ -27,6 +27,18 @@ quantities are stored LSB first, without alignment requirements. Offsets are
considered a limitation in practice (and avoids unnecessary bloat compared to
64 bit offsets).
+Annotations can be added for (non-module) entities and certain parts of such
+entities (e.g., both for an interface type definition and for a direct method of
+an interface type definition; the idea is that it can be added for direct parts
+that forma a "many-to-one" relationship; there is a tradeoff between generality
+of concept and size of representation, esp. for the C++ representation types in
+namespace unoidl) and consist of arbitrary sequences of name/value strings.
+Each name/value string is encoded as a single UTF-8 string containing a name (an
+arbitrary sequence of Unicode code points not containing U+003D EQUALS SIGN),
+optionally followed by U+003D EQUALS SIGN and a value (an abritrary sequence of
+Unicode code points). The only annotation name currently in use is "deprecated"
+(without a value).
+
The following definitions are used throughout:
* UInt16: 2-byte value, LSB first
@@ -34,10 +46,12 @@ The following definitions are used throughout:
* UInt64: 8-byte value, LSB first
* Offset: UInt32 value, counting bytes from start of file
* NUL-Name: zero or more non-NUL US-ASCII bytes followed by a NUL byte
-* Len-Name: UInt32 number of characters, with 0x80000000 bit 1, followed by that
- many (- 0x80000000) US-ASCII bytes
-* Idx-Name: either an Offset (with 0x80000000 bit 0) of a Len-Name, or a
- Len-Name
+* Len-String: UInt32 number of characters, with 0x80000000 bit 0, followed by
+ that many US-ASCII (for UNOIDL related names) resp. UTF-8 (for annotations)
+ bytes
+* Idx-String: either an Offset (with 0x80000000 bit 1) of a Len-String, or a
+ Len-String
+* Annotations: UInt32 number N of annotations followed by N * Idx-String
* Entry: Offset of NUL-Name followed by Offset of payload
* Map: zero or more Entries
@@ -68,7 +82,7 @@ Layout of per-entry payload in the root or a module Map:
** otherwise:
*** 0x80 bit: 1 if published
-*** 0x40 bit: 1 if deprecated
+*** 0x40 bit: 1 if annotated
*** 0x20 bit: flag (may only be 1 for certain kinds, see below)
*** remaining bits:
@@ -76,67 +90,77 @@ Layout of per-entry payload in the root or a module Map:
***** followed by:
****** UInt32 number N1 of members
****** N1 * tuple of:
-******* Offset of Idx-Name
+******* Idx-String
******* UInt32
+******* if annotated: Annotations
**** 2: plain struct type (with base if flag is 1)
***** followed by:
-****** if "with base": Offset of Idx-Name
+****** if "with base": Idx-String
****** UInt32 number N1 of direct members
****** N1 * tuple of:
-******* Offset of Idx-Name name
-******* Offset of Idx-Name type
+******* Idx-String name
+******* Idx-String type
+******* if annotated: Annotations
**** 3: polymorphic struct type template
***** followed by:
****** UInt32 number N1 of type parameters
-****** N1 * Offset of Idx-Name
+****** N1 * Idx-String
****** UInt32 number N2 of members
****** N2 * tuple of:
******* kind byte: 0x01 bit is 1 if parameterized type
-******* Offset of Idx-Name name
-******* Offset of Idx-Name type
+******* Idx-String name
+******* Idx-String type
+******* if annotated: Annotations
**** 4: exception type (with base if flag is 1)
***** followed by:
-****** if "with base": Offset of Idx-Name
+****** if "with base": Idx-String
****** UInt32 number N1 of direct members
****** N1 * tuple of:
-******* Offset of Idx-Name name
-******* Offset of Idx-Name type
+******* Idx-String name
+******* Idx-String type
+******* if annotated: Annotations
**** 5: interface type
***** followed by:
****** UInt32 number N1 of direct mandatory bases
-****** N1 * Offset of Idx-Name
+****** N1 * tuple of:
+******* Idx-String
+******* if annotated: Annotations
****** UInt32 number N2 of direct optional bases
-****** N2 * Offset of Idx-Name
+****** N2 * tuple of:
+******* Idx-String
+******* if annotated: Annotations
****** UInt32 number N3 of direct attributes
****** N3 * tuple of:
******* kind byte:
******** 0x02 bit: 1 if read-only
******** 0x01 bit: 1 if bound
-******* Offset of Idx-Name name
-******* Offset of Idx-Name type
+******* Idx-String name
+******* Idx-String type
******* UInt32 number N4 of get exceptions
-******* N4 * Offset of Idx-Name
+******* N4 * Idx-String
******* UInt32 number N5 of set exceptions
-******* N5 * Offset of Idx-Name
+******* N5 * Idx-String
+******* if annotated: Annotations
****** UInt32 number N6 of direct methods
****** N6 * tuple of:
-******* Offset of Idx-Name name
-******* Offset of Idx-Name return type
+******* Idx-String name
+******* Idx-String return type
******* UInt32 number N7 of parameters
******* N7 * tuple of:
******** direction byte: 0 for in, 1 for out, 2 for in-out
-******** Offset of Idx-Name name
-******** Offset of Idx-Name type
+******** Idx-String name
+******** Idx-String type
******* UInt32 number N8 of exceptions
-******* N8 * Offset of Idx-Name
+******* N8 * Idx-String
+******* if annotated: Annotations
**** 6: typedef
***** followed by:
-****** Offset of Idx-Name
+****** Idx-String
**** 7: constant group
***** followed by:
@@ -145,29 +169,38 @@ Layout of per-entry payload in the root or a module Map:
**** 8: single-interface--based service (with default constructor if flag is 1)
***** followed by:
-****** Offset of Idx-Name
+****** Idx-String
****** if not "with default constructor":
******* UInt32 number N1 of constructors
******* N1 * tuple of:
-******** Offset of Idx-Name
+******** Idx-String
******** UInt32 number N2 of parameters
******** N2 * tuple of
********* kind byte: 0x04 bit is 1 if rest parameter
-********* Offset of Idx-Name name
-********* Offset of Idx-Name type
+********* Idx-String name
+********* Idx-String type
******** UInt32 number N3 of exceptions
-******** N3 * Offset of Idx-Name
+******** N3 * Idx-String
+******** if annotated: Annotations
**** 9: accumulation-based service
***** followed by:
****** UInt32 number N1 of direct mandatory base services
-****** N1 * Offset of Idx-Name
+****** N1 * tuple of:
+******* Idx-String
+******* if annotated: Annotations
****** UInt32 number N2 of direct optional base services
-****** N2 * Offset of Idx-Name
+****** N2 * tuple of:
+******* Idx-String
+******* if annotated: Annotations
****** UInt32 number N3 of direct mandatory base interfaces
-****** N3 * Offset of Idx-Name
+****** N3 * tuple of:
+******* Idx-String
+******* if annotated: Annotations
****** UInt32 number N4 of direct optional base interfaces
-****** N4 * Offset of Idx-Name
+****** N4 * tuple of:
+******* Idx-String
+******* if annotated: Annotations
****** UInt32 number N5 of direct properties
****** N5 * tuple of:
******* UInt16 kind:
@@ -180,21 +213,24 @@ Layout of per-entry payload in the root or a module Map:
******** 0x0004 bit: 1 if constrained
******** 0x0002 bit: 1 if bound
******** 0x0001 bit: 1 if maybevoid
-******* Offset of Idx-Name name
-******* Offset of Idx-Name type
+******* Idx-String name
+******* Idx-String type
+******* if annotated: Annotations
**** 10: interface-based singleton
***** followed by:
-****** Offset of Idx-Name
+****** Idx-String
**** 11: service-based singleton
***** followed by:
-****** Offset of Idx-Name
+****** Idx-String
+
+*** if annotated, followed by: Annotations
Layout of per-entry payload in a constant group Map:
* kind byte:
-** 0x80 bit: 1 if deprecated
+** 0x80 bit: 1 if annotated
** remaining bits:
*** 0: BOOLEAN
@@ -228,3 +264,5 @@ Layout of per-entry payload in a constant group Map:
*** 9: DOUBLE
**** followed by 8-byte value, representing values in ISO 60599 binary64 format,
LSB first
+
+* if annotated, followed by: Annotations
diff --git a/unoidl/source/legacyprovider.cxx b/unoidl/source/legacyprovider.cxx
index 485b43d48055..17b95dcd629c 100644
--- a/unoidl/source/legacyprovider.cxx
+++ b/unoidl/source/legacyprovider.cxx
@@ -26,6 +26,15 @@ namespace unoidl {
namespace {
+std::vector< OUString > translateAnnotations(OUString const & documentation) {
+ std::vector< OUString > ans;
+ if (documentation.indexOf("@deprecated") != -1) {
+ //TODO: this check is somewhat crude
+ ans.push_back("deprecated");
+ }
+ return ans;
+}
+
ConstantValue translateConstantValue(
RegistryKey & key, RTConstValue const & value)
{
@@ -219,17 +228,22 @@ rtl::Reference< Entity > readEntity(
switch (reader.getTypeClass()) {
case RT_TYPE_INTERFACE:
{
- std::vector< OUString > mandBases;
+ std::vector< AnnotatedReference > mandBases;
sal_uInt16 n = reader.getSuperTypeCount();
for (sal_uInt16 j = 0; j != n; ++j) {
mandBases.push_back(
- reader.getSuperTypeName(j).replace('/', '.'));
+ AnnotatedReference(
+ reader.getSuperTypeName(j).replace('/', '.'),
+ std::vector< OUString >()));
}
- std::vector< OUString > optBases;
+ std::vector< AnnotatedReference > optBases;
n = reader.getReferenceCount();
for (sal_uInt16 j = 0; j != n; ++j) {
optBases.push_back(
- reader.getReferenceTypeName(j).replace('/', '.'));
+ AnnotatedReference(
+ reader.getReferenceTypeName(j).replace('/', '.'),
+ translateAnnotations(
+ reader.getReferenceDocumentation(j))));
}
sal_uInt16 methodCount = reader.getMethodCount();
std::vector< InterfaceTypeEntity::Attribute > attrs;
@@ -278,7 +292,8 @@ rtl::Reference< Entity > readEntity(
InterfaceTypeEntity::Attribute(
attrName, reader.getFieldTypeName(j).replace('/', '.'),
(flags & RT_ACCESS_BOUND) != 0,
- (flags & RT_ACCESS_READONLY) != 0, getExcs, setExcs));
+ (flags & RT_ACCESS_READONLY) != 0, getExcs, setExcs,
+ translateAnnotations(reader.getFieldDocumentation(j))));
}
std::vector< InterfaceTypeEntity::Method > meths;
for (sal_uInt16 j = 0; j != methodCount; ++j) {
@@ -330,11 +345,14 @@ rtl::Reference< Entity > readEntity(
InterfaceTypeEntity::Method(
reader.getMethodName(j),
reader.getMethodReturnTypeName(j).replace('/', '.'),
- params, excs));
+ params, excs,
+ translateAnnotations(
+ reader.getMethodDocumentation(j))));
}
}
return new InterfaceTypeEntity(
- reader.isPublished(), mandBases, optBases, attrs, meths);
+ reader.isPublished(), mandBases, optBases, attrs, meths,
+ translateAnnotations(reader.getDocumentation()));
}
case RT_TYPE_MODULE:
return new Module(manager, ucr, sub);
@@ -363,10 +381,13 @@ rtl::Reference< Entity > readEntity(
mems.push_back(
PlainStructTypeEntity::Member(
reader.getFieldName(j),
- reader.getFieldTypeName(j).replace('/', '.')));
+ reader.getFieldTypeName(j).replace('/', '.'),
+ translateAnnotations(
+ reader.getFieldDocumentation(j))));
}
return new PlainStructTypeEntity(
- reader.isPublished(), base, mems);
+ reader.isPublished(), base, mems,
+ translateAnnotations(reader.getDocumentation()));
} else {
if (reader.getSuperTypeCount() != 0) {
FileFormatException(
@@ -390,10 +411,13 @@ rtl::Reference< Entity > readEntity(
reader.getFieldTypeName(j).replace('/', '.'),
((reader.getFieldFlags(j)
& RT_ACCESS_PARAMETERIZED_TYPE)
- != 0)));
+ != 0),
+ translateAnnotations(
+ reader.getFieldDocumentation(j))));
}
return new PolymorphicStructTypeTemplateEntity(
- reader.isPublished(), params, mems);
+ reader.isPublished(), params, mems,
+ translateAnnotations(reader.getDocumentation()));
}
}
case RT_TYPE_ENUM:
@@ -412,9 +436,13 @@ rtl::Reference< Entity > readEntity(
}
mems.push_back(
EnumTypeEntity::Member(
- reader.getFieldName(j), v.m_value.aLong));
+ reader.getFieldName(j), v.m_value.aLong,
+ translateAnnotations(reader.getFieldDocumentation(j))));
+
}
- return new EnumTypeEntity(reader.isPublished(), mems);
+ return new EnumTypeEntity(
+ reader.isPublished(), mems,
+ translateAnnotations(reader.getDocumentation()));
}
case RT_TYPE_EXCEPTION:
{
@@ -439,9 +467,12 @@ rtl::Reference< Entity > readEntity(
mems.push_back(
ExceptionTypeEntity::Member(
reader.getFieldName(j),
- reader.getFieldTypeName(j).replace('/', '.')));
+ reader.getFieldTypeName(j).replace('/', '.'),
+ translateAnnotations(reader.getFieldDocumentation(j))));
}
- return new ExceptionTypeEntity(reader.isPublished(), base, mems);
+ return new ExceptionTypeEntity(
+ reader.isPublished(), base, mems,
+ translateAnnotations(reader.getDocumentation()));
}
case RT_TYPE_TYPEDEF:
if (reader.getSuperTypeCount() != 1) {
@@ -452,36 +483,39 @@ rtl::Reference< Entity > readEntity(
+ " of super-types of typedef with key " + sub.getName()));
}
return new TypedefEntity(
- reader.isPublished(), reader.getSuperTypeName(0).replace('/', '.'));
+ reader.isPublished(), reader.getSuperTypeName(0).replace('/', '.'),
+ translateAnnotations(reader.getDocumentation()));
case RT_TYPE_SERVICE:
switch (reader.getSuperTypeCount()) {
case 0:
{
- std::vector< OUString > mandServs;
- std::vector< OUString > optServs;
- std::vector< OUString > mandIfcs;
- std::vector< OUString > optIfcs;
+ std::vector< AnnotatedReference > mandServs;
+ std::vector< AnnotatedReference > optServs;
+ std::vector< AnnotatedReference > mandIfcs;
+ std::vector< AnnotatedReference > optIfcs;
sal_uInt16 n = reader.getReferenceCount();
for (sal_uInt16 j = 0; j != n; ++j) {
- OUString refName(
- reader.getReferenceTypeName(j).replace('/', '.'));
+ AnnotatedReference base(
+ reader.getReferenceTypeName(j).replace('/', '.'),
+ translateAnnotations(
+ reader.getReferenceDocumentation(j)));
switch (reader.getReferenceSort(j)) {
case RT_REF_EXPORTS:
if ((reader.getReferenceFlags(j) & RT_ACCESS_OPTIONAL)
== 0)
{
- mandServs.push_back(refName);
+ mandServs.push_back(base);
} else {
- optServs.push_back(refName);
+ optServs.push_back(base);
}
break;
case RT_REF_SUPPORTS:
if ((reader.getReferenceFlags(j) & RT_ACCESS_OPTIONAL)
== 0)
{
- mandIfcs.push_back(refName);
+ mandIfcs.push_back(base);
} else {
- optIfcs.push_back(refName);
+ optIfcs.push_back(base);
}
break;
default:
@@ -540,11 +574,14 @@ rtl::Reference< Entity > readEntity(
reader.getFieldTypeName(j).replace('/', '.'),
static_cast<
AccumulationBasedServiceEntity::Property::
- Attributes >(attrs)));
+ Attributes >(attrs),
+ translateAnnotations(
+ reader.getFieldDocumentation(j))));
}
return new AccumulationBasedServiceEntity(
reader.isPublished(), mandServs, optServs, mandIfcs,
- optIfcs, props);
+ optIfcs, props,
+ translateAnnotations(reader.getDocumentation()));
}
case 1:
{
@@ -615,17 +652,20 @@ rtl::Reference< Entity > readEntity(
m = reader.getMethodExceptionCount(j);
for (sal_uInt16 k = 0; k != m; ++k) {
excs.push_back(
- reader.getMethodExceptionTypeName(j, k).
- replace('/', '.'));
+ reader.getMethodExceptionTypeName(j, k).replace(
+ '/', '.'));
}
ctors.push_back(
SingleInterfaceBasedServiceEntity::Constructor(
- reader.getMethodName(j), params, excs));
+ reader.getMethodName(j), params, excs,
+ translateAnnotations(
+ reader.getMethodDocumentation(j))));
}
}
return new SingleInterfaceBasedServiceEntity(
reader.isPublished(),
- reader.getSuperTypeName(0).replace('/', '.'), ctors);
+ reader.getSuperTypeName(0).replace('/', '.'), ctors,
+ translateAnnotations(reader.getDocumentation()));
}
default:
throw FileFormatException(
@@ -702,10 +742,12 @@ rtl::Reference< Entity > readEntity(
return newStyle
? rtl::Reference< Entity >(
new InterfaceBasedSingletonEntity(
- reader.isPublished(), baseName))
+ reader.isPublished(), baseName,
+ translateAnnotations(reader.getDocumentation())))
: rtl::Reference< Entity >(
new ServiceBasedSingletonEntity(
- reader.isPublished(), baseName));
+ reader.isPublished(), baseName,
+ translateAnnotations(reader.getDocumentation())));
}
case RT_TYPE_CONSTANTS:
{
@@ -715,9 +757,12 @@ rtl::Reference< Entity > readEntity(
mems.push_back(
ConstantGroupEntity::Member(
reader.getFieldName(j),
- translateConstantValue(sub, reader.getFieldValue(j))));
+ translateConstantValue(sub, reader.getFieldValue(j)),
+ translateAnnotations(reader.getFieldDocumentation(j))));
}
- return new ConstantGroupEntity(reader.isPublished(), mems);
+ return new ConstantGroupEntity(
+ reader.isPublished(), mems,
+ translateAnnotations(reader.getDocumentation()));
}
default:
throw FileFormatException(
diff --git a/unoidl/source/reg2unoidl.cxx b/unoidl/source/reg2unoidl.cxx
index 2bd9e56b6582..bf2b6d271ab2 100644
--- a/unoidl/source/reg2unoidl.cxx
+++ b/unoidl/source/reg2unoidl.cxx
@@ -201,7 +201,21 @@ OString toAscii(OUString const & name) {
return ascii;
}
-sal_uInt64 writeNameNul(osl::File & file, OUString const & name) {
+OString toUtf8(OUString const & string) {
+ OString ascii;
+ if (!string.convertToString(
+ &ascii, RTL_TEXTENCODING_UTF8,
+ (RTL_UNICODETOTEXT_FLAGS_UNDEFINED_ERROR
+ | RTL_UNICODETOTEXT_FLAGS_INVALID_ERROR)))
+ {
+ std::cerr
+ << "Cannot convert \"" << string << "\" to UTF-8" << std::endl;
+ std::exit(EXIT_FAILURE);
+ }
+ return ascii;
+}
+
+sal_uInt64 writeNulName(osl::File & file, OUString const & name) {
OString ascii(toAscii(name));
if (ascii.indexOf('\0') != -1) {
std::cerr
@@ -213,33 +227,57 @@ sal_uInt64 writeNameNul(osl::File & file, OUString const & name) {
return off;
}
-void writeNameLen(osl::File & file, OUString const & name) {
- static std::map< OUString, sal_uInt64 > reuse;
- std::map< OUString, sal_uInt64 >::iterator i(reuse.find(name));
+void writeIdxString(osl::File & file, OString const & string) {
+ static std::map< OString, sal_uInt64 > reuse;
+ std::map< OString, sal_uInt64 >::iterator i(reuse.find(string));
if (i == reuse.end()) {
- reuse.insert(std::make_pair(name, getOffset(file)));
- OString ascii(toAscii(name));
+ reuse.insert(std::make_pair(string, getOffset(file)));
assert(
- (static_cast< sal_uInt64 >(ascii.getLength()) & 0x80000000) == 0);
- write32(
- file, static_cast< sal_uInt64 >(ascii.getLength()) | 0x80000000);
- write(file, ascii.getStr(), ascii.getLength());
+ (static_cast< sal_uInt64 >(string.getLength()) & 0x80000000) == 0);
+ write32(file, static_cast< sal_uInt64 >(string.getLength()));
+ write(file, string.getStr(), string.getLength());
} else {
- write32(file, i->second);
+ if ((i->second & 0x80000000) != 0) {
+ std::cerr
+ << "Cannot write index 0x" << std::hex << i->second << std::dec
+ << " of \"" << string << "\"; input is too large" << std::endl;
+ std::exit(EXIT_FAILURE);
+ }
+ write32(file, i->second | 0x80000000);
+ }
+}
+
+void writeIdxName(osl::File & file, OUString const & name) {
+ writeIdxString(file, toAscii(name));
+}
+
+void writeAnnotations(
+ osl::File & file, bool annotate,
+ std::vector< OUString > const & annotations)
+{
+ assert(annotate || annotations.empty());
+ if (annotate) {
+ write32(file, annotations.size());
+ // overflow from std::vector::size_type -> sal_uInt64 is unrealistic
+ for (std::vector< OUString >::const_iterator i(annotations.begin());
+ i != annotations.end(); ++i)
+ {
+ writeIdxString(file, toUtf8(*i));
+ }
}
}
void writeKind(
osl::File & file,
rtl::Reference< unoidl::PublishableEntity > const & entity,
- bool flag = false)
+ bool annotated, bool flag = false)
{
assert(entity.is());
sal_uInt64 v = entity->getSort();
if (entity->isPublished()) {
v |= 0x80;
}
- if (false /*TODO: deprecated */) {
+ if (annotated) {
v |= 0x40;
}
if (flag) {
@@ -250,7 +288,7 @@ void writeKind(
struct Item {
explicit Item(rtl::Reference< unoidl::Entity > const & theEntity):
- entity(theEntity),nameOffset(0),dataOffset(0)
+ entity(theEntity), nameOffset(0), dataOffset(0)
{}
rtl::Reference< unoidl::Entity > entity;
@@ -259,11 +297,15 @@ struct Item {
};
struct ConstItem {
- explicit ConstItem(unoidl::ConstantValue const & theConstant):
- constant(theConstant),nameOffset(0),dataOffset(0)
+ ConstItem(
+ unoidl::ConstantValue const & theConstant,
+ std::vector< OUString > const & theAnnotations):
+ constant(theConstant), annotations(theAnnotations), nameOffset(0),
+ dataOffset(0)
{}
unoidl::ConstantValue constant;
+ std::vector< OUString > annotations;
sal_uInt64 nameOffset;
sal_uInt64 dataOffset;
};
@@ -302,16 +344,25 @@ sal_uInt64 writeMap(
rtl::Reference< unoidl::EnumTypeEntity > ent2(
static_cast< unoidl::EnumTypeEntity * >(
i->second.entity.get()));
+ bool ann = !ent2->getAnnotations().empty();
+ for (std::vector< unoidl::EnumTypeEntity::Member >::
+ const_iterator j(ent2->getMembers().begin());
+ !ann && j != ent2->getMembers().end(); ++j)
+ {
+ ann = !j->annotations.empty();
+ }
i->second.dataOffset = getOffset(file);
- writeKind(file, ent2.get());
+ writeKind(file, ent2.get(), ann);
write32(file, ent2->getMembers().size());
for (std::vector< unoidl::EnumTypeEntity::Member >::
const_iterator j(ent2->getMembers().begin());
j != ent2->getMembers().end(); ++j)
{
- writeNameLen(file, j->name);
+ writeIdxName(file, j->name);
write32(file, static_cast< sal_uInt32 >(j->value));
+ writeAnnotations(file, ann, j->annotations);
}
+ writeAnnotations(file, ann, ent2->getAnnotations());
break;
}
case unoidl::Entity::SORT_PLAIN_STRUCT_TYPE:
@@ -319,19 +370,29 @@ sal_uInt64 writeMap(
rtl::Reference< unoidl::PlainStructTypeEntity > ent2(
static_cast< unoidl::PlainStructTypeEntity * >(
i->second.entity.get()));
+ bool ann = !ent2->getAnnotations().empty();
+ for (std::vector< unoidl::PlainStructTypeEntity::Member >::
+ const_iterator j(ent2->getDirectMembers().begin());
+ !ann && j != ent2->getDirectMembers().end(); ++j)
+ {
+ ann = !j->annotations.empty();
+ }
i->second.dataOffset = getOffset(file);
- writeKind(file, ent2.get(), !ent2->getDirectBase().isEmpty());
+ writeKind(
+ file, ent2.get(), ann, !ent2->getDirectBase().isEmpty());
if (!ent2->getDirectBase().isEmpty()) {
- writeNameLen(file, ent2->getDirectBase());
+ writeIdxName(file, ent2->getDirectBase());
}
write32(file, ent2->getDirectMembers().size());
for (std::vector< unoidl::PlainStructTypeEntity::Member >::
const_iterator j(ent2->getDirectMembers().begin());
j != ent2->getDirectMembers().end(); ++j)
{
- writeNameLen(file, j->name);
- writeNameLen(file, j->type);
+ writeIdxName(file, j->name);
+ writeIdxName(file, j->type);
+ writeAnnotations(file, ann, j->annotations);
}
+ writeAnnotations(file, ann, ent2->getAnnotations());
break;
}
case unoidl::Entity::SORT_POLYMORPHIC_STRUCT_TYPE_TEMPLATE:
@@ -341,14 +402,23 @@ sal_uInt64 writeMap(
static_cast<
unoidl::PolymorphicStructTypeTemplateEntity * >(
i->second.entity.get()));
+ bool ann = !ent2->getAnnotations().empty();
+ for (std::vector<
+ unoidl::PolymorphicStructTypeTemplateEntity::Member >::
+ const_iterator j(
+ ent2->getMembers().begin());
+ !ann && j != ent2->getMembers().end(); ++j)
+ {
+ ann = !j->annotations.empty();
+ }
i->second.dataOffset = getOffset(file);
- writeKind(file, ent2.get());
+ writeKind(file, ent2.get(), ann);
write32(file, ent2->getTypeParameters().size());
for (std::vector< OUString >::const_iterator j(
ent2->getTypeParameters().begin());
j != ent2->getTypeParameters().end(); ++j)
{
- writeNameLen(file, *j);
+ writeIdxName(file, *j);
}
write32(file, ent2->getMembers().size());
for (std::vector<
@@ -362,9 +432,11 @@ sal_uInt64 writeMap(
f |= 0x01;
}
write8(file, f);
- writeNameLen(file, j->name);
- writeNameLen(file, j->type);
+ writeIdxName(file, j->name);
+ writeIdxName(file, j->type);
+ writeAnnotations(file, ann, j->annotations);
}
+ writeAnnotations(file, ann, ent2->getAnnotations());
break;
}
case unoidl::Entity::SORT_EXCEPTION_TYPE:
@@ -372,19 +444,29 @@ sal_uInt64 writeMap(
rtl::Reference< unoidl::ExceptionTypeEntity > ent2(
static_cast< unoidl::ExceptionTypeEntity * >(
i->second.entity.get()));
+ bool ann = !ent2->getAnnotations().empty();
+ for (std::vector< unoidl::ExceptionTypeEntity::Member >::
+ const_iterator j(ent2->getDirectMembers().begin());
+ !ann && j != ent2->getDirectMembers().end(); ++j)
+ {
+ ann = !j->annotations.empty();
+ }
i->second.dataOffset = getOffset(file);
- writeKind(file, ent2.get(), !ent2->getDirectBase().isEmpty());
+ writeKind(
+ file, ent2.get(), ann, !ent2->getDirectBase().isEmpty());
if (!ent2->getDirectBase().isEmpty()) {
- writeNameLen(file, ent2->getDirectBase());
+ writeIdxName(file, ent2->getDirectBase());
}
write32(file, ent2->getDirectMembers().size());
for (std::vector< unoidl::ExceptionTypeEntity::Member >::
const_iterator j(ent2->getDirectMembers().begin());
j != ent2->getDirectMembers().end(); ++j)
{
- writeNameLen(file, j->name);
- writeNameLen(file, j->type);
+ writeIdxName(file, j->name);
+ writeIdxName(file, j->type);
+ writeAnnotations(file, ann, j->annotations);
}
+ writeAnnotations(file, ann, ent2->getAnnotations());
break;
}
case unoidl::Entity::SORT_INTERFACE_TYPE:
@@ -392,21 +474,48 @@ sal_uInt64 writeMap(
rtl::Reference< unoidl::InterfaceTypeEntity > ent2(
static_cast< unoidl::InterfaceTypeEntity * >(
i->second.entity.get()));
+ bool ann = !ent2->getAnnotations().empty();
+ for (std::vector< unoidl::AnnotatedReference >::const_iterator
+ j(ent2->getDirectMandatoryBases().begin());
+ !ann && j != ent2->getDirectMandatoryBases().end(); ++j)
+ {
+ ann = !j->annotations.empty();
+ }
+ for (std::vector< unoidl::AnnotatedReference >::const_iterator
+ j(ent2->getDirectOptionalBases().begin());
+ !ann && j != ent2->getDirectOptionalBases().end(); ++j)
+ {
+ ann = !j->annotations.empty();
+ }
+ for (std::vector< unoidl::InterfaceTypeEntity::Attribute >::
+ const_iterator j(ent2->getDirectAttributes().begin());
+ !ann && j != ent2->getDirectAttributes().end(); ++j)
+ {
+ ann = !j->annotations.empty();
+ }
+ for (std::vector< unoidl::InterfaceTypeEntity::Method >::
+ const_iterator j(ent2->getDirectMethods().begin());
+ !ann && j != ent2->getDirectMethods().end(); ++j)
+ {
+ ann = !j->annotations.empty();
+ }
i->second.dataOffset = getOffset(file);
- writeKind(file, ent2.get());
+ writeKind(file, ent2.get(), ann);
write32(file, ent2->getDirectMandatoryBases().size());
- for (std::vector< OUString >::const_iterator j(
- ent2->getDirectMandatoryBases().begin());
+ for (std::vector< unoidl::AnnotatedReference >::const_iterator
+ j(ent2->getDirectMandatoryBases().begin());
j != ent2->getDirectMandatoryBases().end(); ++j)
{
- writeNameLen(file, *j);
+ writeIdxName(file, j->name);
+ writeAnnotations(file, ann, j->annotations);
}
write32(file, ent2->getDirectOptionalBases().size());
- for (std::vector< OUString >::const_iterator j(
- ent2->getDirectOptionalBases().begin());
+ for (std::vector< unoidl::AnnotatedReference >::const_iterator
+ j(ent2->getDirectOptionalBases().begin());
j != ent2->getDirectOptionalBases().end(); ++j)
{
- writeNameLen(file, *j);
+ writeIdxName(file, j->name);
+ writeAnnotations(file, ann, j->annotations);
}
write32(file, ent2->getDirectAttributes().size());
for (std::vector< unoidl::InterfaceTypeEntity::Attribute >::
@@ -421,14 +530,14 @@ sal_uInt64 writeMap(
f |= 0x02;
}
write8(file, f);
- writeNameLen(file, j->name);
- writeNameLen(file, j->type);
+ writeIdxName(file, j->name);
+ writeIdxName(file, j->type);
write32(file, j->getExceptions.size());
for (std::vector< OUString >::const_iterator k(
j->getExceptions.begin());
k != j->getExceptions.end(); ++k)
{
- writeNameLen(file, *k);
+ writeIdxName(file, *k);
}
if (!j->readOnly) {
write32(file, j->setExceptions.size());
@@ -436,17 +545,18 @@ sal_uInt64 writeMap(
j->setExceptions.begin());
k != j->setExceptions.end(); ++k)
{
- writeNameLen(file, *k);
+ writeIdxName(file, *k);
}
}
+ writeAnnotations(file, ann, j->annotations);
}
write32(file, ent2->getDirectMethods().size());
for (std::vector< unoidl::InterfaceTypeEntity::Method >::
const_iterator j(ent2->getDirectMethods().begin());
j != ent2->getDirectMethods().end(); ++j)
{
- writeNameLen(file, j->name);
- writeNameLen(file, j->returnType);
+ writeIdxName(file, j->name);
+ writeIdxName(file, j->returnType);
write32(file, j->parameters.size());
for (std::vector<
unoidl::InterfaceTypeEntity::Method::Parameter >::
@@ -454,17 +564,19 @@ sal_uInt64 writeMap(
k != j->parameters.end(); ++k)
{
write8(file, k->direction);
- writeNameLen(file, k->name);
- writeNameLen(file, k->type);
+ writeIdxName(file, k->name);
+ writeIdxName(file, k->type);
}
write32(file, j->exceptions.size());
for (std::vector< OUString >::const_iterator k(
j->exceptions.begin());
k != j->exceptions.end(); ++k)
{
- writeNameLen(file, *k);
+ writeIdxName(file, *k);
}
+ writeAnnotations(file, ann, j->annotations);
}
+ writeAnnotations(file, ann, ent2->getAnnotations());
break;
}
case unoidl::Entity::SORT_TYPEDEF:
@@ -472,9 +584,11 @@ sal_uInt64 writeMap(
rtl::Reference< unoidl::TypedefEntity > ent2(
static_cast< unoidl::TypedefEntity * >(
i->second.entity.get()));
+ bool ann = !ent2->getAnnotations().empty();
i->second.dataOffset = getOffset(file);
- writeKind(file, ent2.get());
- writeNameLen(file, ent2->getType());
+ writeKind(file, ent2.get(), ann);
+ writeIdxName(file, ent2->getType());
+ writeAnnotations(file, ann, ent2->getAnnotations());
break;
}
case unoidl::Entity::SORT_CONSTANT_GROUP:
@@ -488,7 +602,8 @@ sal_uInt64 writeMap(
j != ent2->getMembers().end(); ++j)
{
if (!cmap.insert(
- std::make_pair(j->name, ConstItem(j->value))).
+ std::make_pair(
+ j->name, ConstItem(j->value, j->annotations))).
second)
{
std::cout
@@ -502,7 +617,7 @@ sal_uInt64 writeMap(
{
j->second.dataOffset = getOffset(file);
sal_uInt64 v = j->second.constant.type;
- if (false /*TODO: deprecated */) {
+ if (!j->second.annotations.empty()) {
v |= 0x80;
}
write8(file, v);
@@ -554,15 +669,19 @@ sal_uInt64 writeMap(
default:
for (;;) { std::abort(); } // this cannot happen
}
+ writeAnnotations(
+ file, !j->second.annotations.empty(),
+ j->second.annotations);
}
for (std::map< OUString, ConstItem >::iterator j(
cmap.begin());
j != cmap.end(); ++j)
{
- j->second.nameOffset = writeNameNul(file, j->first);
+ j->second.nameOffset = writeNulName(file, j->first);
}
+ bool ann = !ent2->getAnnotations().empty();
i->second.dataOffset = getOffset(file);
- writeKind(file, ent2.get());
+ writeKind(file, ent2.get(), ann);
write32(file, cmap.size());
// overflow from std::map::size_type -> sal_uInt64 is
// unrealistic
@@ -573,6 +692,7 @@ sal_uInt64 writeMap(
write32(file, j->second.nameOffset);
write32(file, j->second.dataOffset);
}
+ writeAnnotations(file, ann, ent2->getAnnotations());
break;
}
case unoidl::Entity::SORT_SINGLE_INTERFACE_BASED_SERVICE:
@@ -582,11 +702,22 @@ sal_uInt64 writeMap(
static_cast<
unoidl::SingleInterfaceBasedServiceEntity * >(
i->second.entity.get()));
- i->second.dataOffset = getOffset(file);
bool dfltCtor = ent2->getConstructors().size() == 1
&& ent2->getConstructors()[0].defaultConstructor;
- writeKind(file, ent2.get(), dfltCtor);
- writeNameLen(file, ent2->getBase());
+ bool ann = !ent2->getAnnotations().empty();
+ if (!dfltCtor) {
+ for (std::vector<
+ unoidl::SingleInterfaceBasedServiceEntity::
+ Constructor >::const_iterator j(
+ ent2->getConstructors().begin());
+ !ann && j != ent2->getConstructors().end(); ++j)
+ {
+ ann = !j->annotations.empty();
+ }
+ }
+ i->second.dataOffset = getOffset(file);
+ writeKind(file, ent2.get(), ann, dfltCtor);
+ writeIdxName(file, ent2->getBase());
if (!dfltCtor) {
write32(file, ent2->getConstructors().size());
for (std::vector<
@@ -601,7 +732,7 @@ sal_uInt64 writeMap(
<< j->name << '"' << std::endl;
std::exit(EXIT_FAILURE);
}
- writeNameLen(file, j->name);
+ writeIdxName(file, j->name);
write32(file, j->parameters.size());
for (std::vector<
unoidl::SingleInterfaceBasedServiceEntity::
@@ -614,18 +745,20 @@ sal_uInt64 writeMap(
f |= 0x04;
}
write8(file, f);
- writeNameLen(file, k->name);
- writeNameLen(file, k->type);
+ writeIdxName(file, k->name);
+ writeIdxName(file, k->type);
}
write32(file, j->exceptions.size());
for (std::vector< OUString >::const_iterator k(
j->exceptions.begin());
k != j->exceptions.end(); ++k)
{
- writeNameLen(file, *k);
+ writeIdxName(file, *k);
}
+ writeAnnotations(file, ann, j->annotations);
}
}
+ writeAnnotations(file, ann, ent2->getAnnotations());
break;
}
case unoidl::Entity::SORT_ACCUMULATION_BASED_SERVICE:
@@ -633,35 +766,77 @@ sal_uInt64 writeMap(
rtl::Reference< unoidl::AccumulationBasedServiceEntity > ent2(
static_cast< unoidl::AccumulationBasedServiceEntity * >(
i->second.entity.get()));
+ bool ann = !ent2->getAnnotations().empty();
+ for (std::vector< unoidl::AnnotatedReference >::const_iterator
+ j(ent2->getDirectMandatoryBaseServices().begin());
+ !ann && j != ent2->getDirectMandatoryBaseServices().end();
+ ++j)
+ {
+ ann = !j->annotations.empty();
+ }
+ for (std::vector< unoidl::AnnotatedReference >::const_iterator
+ j(ent2->getDirectOptionalBaseServices().begin());
+ !ann && j != ent2->getDirectOptionalBaseServices().end();
+ ++j)
+ {
+ ann = !j->annotations.empty();
+ }
+ for (std::vector< unoidl::AnnotatedReference >::const_iterator
+ j(ent2->getDirectMandatoryBaseInterfaces().begin());
+ (!ann
+ && j != ent2->getDirectMandatoryBaseInterfaces().end());
+ ++j)
+ {
+ ann = !j->annotations.empty();
+ }
+ for (std::vector< unoidl::AnnotatedReference >::const_iterator
+ j(ent2->getDirectOptionalBaseInterfaces().begin());
+ !ann && j != ent2->getDirectOptionalBaseInterfaces().end();
+ ++j)
+ {
+ ann = !j->annotations.empty();
+ }
+ for (std::vector<
+ unoidl::AccumulationBasedServiceEntity::Property >::
+ const_iterator j(
+ ent2->getDirectProperties().begin());
+ !ann && j != ent2->getDirectProperties().end(); ++j)
+ {
+ ann = !j->annotations.empty();
+ }
i->second.dataOffset = getOffset(file);
- writeKind(file, ent2.get());
+ writeKind(file, ent2.get(), ann);
write32(file, ent2->getDirectMandatoryBaseServices().size());
- for (std::vector< OUString >::const_iterator j(
- ent2->getDirectMandatoryBaseServices().begin());
+ for (std::vector< unoidl::AnnotatedReference >::const_iterator
+ j(ent2->getDirectMandatoryBaseServices().begin());
j != ent2->getDirectMandatoryBaseServices().end(); ++j)
{
- writeNameLen(file, *j);
+ writeIdxName(file, j->name);
+ writeAnnotations(file, ann, j->annotations);
}
write32(file, ent2->getDirectOptionalBaseServices().size());
- for (std::vector< OUString >::const_iterator j(
- ent2->getDirectOptionalBaseServices().begin());
+ for (std::vector< unoidl::AnnotatedReference >::const_iterator
+ j(ent2->getDirectOptionalBaseServices().begin());
j != ent2->getDirectOptionalBaseServices().end(); ++j)
{
- writeNameLen(file, *j);
+ writeIdxName(file, j->name);
+ writeAnnotations(file, ann, j->annotations);
}
write32(file, ent2->getDirectMandatoryBaseInterfaces().size());
- for (std::vector< OUString >::const_iterator j(
- ent2->getDirectMandatoryBaseInterfaces().begin());
+ for (std::vector< unoidl::AnnotatedReference >::const_iterator
+ j(ent2->getDirectMandatoryBaseInterfaces().begin());
j != ent2->getDirectMandatoryBaseInterfaces().end(); ++j)
{
- writeNameLen(file, *j);
+ writeIdxName(file, j->name);
+ writeAnnotations(file, ann, j->annotations);
}
write32(file, ent2->getDirectOptionalBaseInterfaces().size());
- for (std::vector< OUString >::const_iterator j(
- ent2->getDirectOptionalBaseInterfaces().begin());
+ for (std::vector< unoidl::AnnotatedReference >::const_iterator
+ j(ent2->getDirectOptionalBaseInterfaces().begin());
j != ent2->getDirectOptionalBaseInterfaces().end(); ++j)
{
- writeNameLen(file, *j);
+ writeIdxName(file, j->name);
+ writeAnnotations(file, ann, j->annotations);
}
write32(file, ent2->getDirectProperties().size());
for (std::vector<
@@ -671,9 +846,11 @@ sal_uInt64 writeMap(
j != ent2->getDirectProperties().end(); ++j)
{
write16(file, static_cast< sal_uInt16 >(j->attributes));
- writeNameLen(file, j->name);
- writeNameLen(file, j->type);
+ writeIdxName(file, j->name);
+ writeIdxName(file, j->type);
+ writeAnnotations(file, ann, j->annotations);
}
+ writeAnnotations(file, ann, ent2->getAnnotations());
break;
}
case unoidl::Entity::SORT_INTERFACE_BASED_SINGLETON:
@@ -681,9 +858,11 @@ sal_uInt64 writeMap(
rtl::Reference< unoidl::InterfaceBasedSingletonEntity > ent2(
static_cast< unoidl::InterfaceBasedSingletonEntity * >(
i->second.entity.get()));
+ bool ann = !ent2->getAnnotations().empty();
i->second.dataOffset = getOffset(file);
- writeKind(file, ent2.get());
- writeNameLen(file, ent2->getBase());
+ writeKind(file, ent2.get(), ann);
+ writeIdxName(file, ent2->getBase());
+ writeAnnotations(file, ann, ent2->getAnnotations());
break;
}
case unoidl::Entity::SORT_SERVICE_BASED_SINGLETON:
@@ -691,9 +870,11 @@ sal_uInt64 writeMap(
rtl::Reference< unoidl::ServiceBasedSingletonEntity > ent2(
static_cast< unoidl::ServiceBasedSingletonEntity * >(
i->second.entity.get()));
+ bool ann = !ent2->getAnnotations().empty();
i->second.dataOffset = getOffset(file);
- writeKind(file, ent2.get());
- writeNameLen(file, ent2->getBase());
+ writeKind(file, ent2.get(), ann);
+ writeIdxName(file, ent2->getBase());
+ writeAnnotations(file, ann, ent2->getAnnotations());
break;
}
}
@@ -701,7 +882,7 @@ sal_uInt64 writeMap(
for (std::map< OUString, Item >::iterator i(map.begin()); i != map.end();
++i)
{
- i->second.nameOffset = writeNameNul(file, i->first);
+ i->second.nameOffset = writeNulName(file, i->first);
}
sal_uInt64 off = getOffset(file);
if (rootSize == 0) {
diff --git a/unoidl/source/unoidlprovider.cxx b/unoidl/source/unoidlprovider.cxx
index 33848a1c632e..47b6f9eb0399 100644
--- a/unoidl/source/unoidlprovider.cxx
+++ b/unoidl/source/unoidlprovider.cxx
@@ -17,6 +17,8 @@
#include "osl/endian.h"
#include "osl/file.h"
#include "rtl/ref.hxx"
+#include "rtl/textenc.h"
+#include "rtl/textcvt.h"
#include "rtl/ustring.hxx"
#include "sal/log.hxx"
#include "sal/types.h"
@@ -132,9 +134,13 @@ public:
double readIso60599Binary64(sal_uInt32 offset) const;
- OUString readNameNul(sal_uInt32 offset) const;
+ OUString readNulName(sal_uInt32 offset) const;
- OUString readNameLen(sal_uInt32 offset, sal_uInt32 * newOffset = 0) const;
+ OUString readIdxName(sal_uInt32 * offset) const
+ { return readIdxString(offset, RTL_TEXTENCODING_ASCII_US); }
+
+ OUString readIdxString(sal_uInt32 * offset) const
+ { return readIdxString(offset, RTL_TEXTENCODING_UTF8); }
OUString uri;
oslFileHandle handle;
@@ -155,6 +161,9 @@ private:
float getIso60599Binary32(sal_uInt32 offset) const;
double getIso60599Binary64(sal_uInt32 offset) const;
+
+ OUString readIdxString(sal_uInt32 * offset, rtl_TextEncoding encoding)
+ const;
};
MappedFile::MappedFile(OUString const & fileUrl): uri(fileUrl) {
@@ -235,7 +244,7 @@ double MappedFile::readIso60599Binary64(sal_uInt32 offset) const {
return getIso60599Binary64(offset);
}
-OUString MappedFile::readNameNul(sal_uInt32 offset) const {
+OUString MappedFile::readNulName(sal_uInt32 offset) const {
if (offset > size) {
throw FileFormatException(
uri, "UNOIDL format: offset for string too large");
@@ -266,44 +275,6 @@ OUString MappedFile::readNameNul(sal_uInt32 offset) const {
return name;
}
-OUString MappedFile::readNameLen(sal_uInt32 offset, sal_uInt32 * newOffset)
- const
-{
- sal_uInt32 len = read32(offset);
- if ((len & 0x80000000) == 0) {
- if (newOffset != 0) {
- *newOffset = offset + 4;
- }
- offset = len;
- len = read32(offset);
- if ((len & 0x80000000) == 0) {
- throw FileFormatException(
- uri, "UNOIDL format: name length high bit unset");
- }
- len &= ~0x80000000;
- } else {
- len &= ~0x80000000;
- if (newOffset != 0) {
- *newOffset = offset + 4 + len;
- }
- }
- if (len > SAL_MAX_INT32 || len > size - offset - 4) {
- throw FileFormatException(
- uri, "UNOIDL format: size of name is too large");
- }
- OUString name;
- if (!rtl_convertStringToUString(
- &name.pData, static_cast< char const * >(address) + offset + 4, len,
- RTL_TEXTENCODING_ASCII_US,
- (RTL_TEXTTOUNICODE_FLAGS_UNDEFINED_ERROR
- | RTL_TEXTTOUNICODE_FLAGS_MBUNDEFINED_ERROR
- | RTL_TEXTTOUNICODE_FLAGS_INVALID_ERROR)))
- {
- throw FileFormatException(uri, "UNOIDL format: name is not ASCII");
- }
- return name;
-}
-
MappedFile::~MappedFile() {
oslFileError e = osl_unmapMappedFile(handle, address, size);
SAL_WARN_IF(e != osl_File_E_None, "unoidl", "cannot unmap: " << +e);
@@ -352,6 +323,42 @@ double MappedFile::getIso60599Binary64(sal_uInt32 offset) const {
static_cast< char const * >(address) + offset)->getIso60599Binary64();
}
+OUString MappedFile::readIdxString(
+ sal_uInt32 * offset, rtl_TextEncoding encoding) const
+{
+ assert(offset != 0);
+ sal_uInt32 len = read32(*offset);
+ sal_uInt32 off;
+ if ((len & 0x80000000) == 0) {
+ off = *offset;
+ *offset += 4 + len;
+ } else {
+ *offset += 4;
+ off = len & ~0x80000000;
+ len = read32(off);
+ if ((len & 0x80000000) != 0) {
+ throw FileFormatException(
+ uri, "UNOIDL format: string length high bit set");
+ }
+ }
+ if (len > SAL_MAX_INT32 || len > size - off - 4) {
+ throw FileFormatException(
+ uri, "UNOIDL format: size of string is too large");
+ }
+ OUString name;
+ if (!rtl_convertStringToUString(
+ &name.pData, static_cast< char const * >(address) + off + 4, len,
+ encoding,
+ (RTL_TEXTTOUNICODE_FLAGS_UNDEFINED_ERROR
+ | RTL_TEXTTOUNICODE_FLAGS_MBUNDEFINED_ERROR
+ | RTL_TEXTTOUNICODE_FLAGS_INVALID_ERROR)))
+ {
+ throw FileFormatException(
+ uri, "UNOIDL format: string bytes do not match encoding");
+ }
+ return name;
+}
+
// sizeof (MapEntry) == 8
struct MapEntry {
Memory32 name;
@@ -430,16 +437,40 @@ sal_uInt32 findInMap(
return off;
}
+std::vector< OUString > readAnnotations(
+ bool annotated, rtl::Reference< detail::MappedFile > const & file,
+ sal_uInt32 offset, sal_uInt32 * newOffset = 0)
+{
+ std::vector< OUString > ans;
+ if (annotated) {
+ sal_uInt32 n = file->read32(offset);
+ offset += 4;
+ for (sal_uInt32 i = 0; i != n; ++i) {
+ ans.push_back(file->readIdxString(&offset));
+ }
+ }
+ if (newOffset != 0) {
+ *newOffset = offset;
+ }
+ return ans;
+}
+
ConstantValue readConstant(
- rtl::Reference< detail::MappedFile > const & file, sal_uInt32 offset)
+ rtl::Reference< detail::MappedFile > const & file, sal_uInt32 offset,
+ sal_uInt32 * newOffset = 0, bool * annotated = 0)
{
assert(file.is());
int v = file->read8(offset);
int type = v & 0x7F;
- bool deprecated = (v & 0x80) != 0; (void)deprecated;//TODO
+ if (annotated != 0) {
+ *annotated = (v & 0x80) != 0;
+ }
switch (type) {
case 0: // BOOLEAN
v = file->read8(offset + 1);
+ if (newOffset != 0) {
+ *newOffset = offset + 2;
+ }
switch (v) {
case 0:
return ConstantValue(false);
@@ -452,33 +483,60 @@ ConstantValue readConstant(
+ OUString::number(v)));
}
case 1: // BYTE
+ if (newOffset != 0) {
+ *newOffset = offset + 2;
+ }
return ConstantValue(static_cast< sal_Int8 >(file->read8(offset + 1)));
//TODO: implementation-defined behavior of conversion from sal_uInt8
// to sal_Int8 relies on two's complement representation
case 2: // SHORT
+ if (newOffset != 0) {
+ *newOffset = offset + 3;
+ }
return ConstantValue(
static_cast< sal_Int16 >(file->read16(offset + 1)));
//TODO: implementation-defined behavior of conversion from
// sal_uInt16 to sal_Int16 relies on two's complement representation
case 3: // UNSIGNED SHORT
+ if (newOffset != 0) {
+ *newOffset = offset + 3;
+ }
return ConstantValue(file->read16(offset + 1));
case 4: // LONG
+ if (newOffset != 0) {
+ *newOffset = offset + 5;
+ }
return ConstantValue(
static_cast< sal_Int32 >(file->read32(offset + 1)));
//TODO: implementation-defined behavior of conversion from
// sal_uInt32 to sal_Int32 relies on two's complement representation
case 5: // UNSIGNED LONG
+ if (newOffset != 0) {
+ *newOffset = offset + 5;
+ }
return ConstantValue(file->read32(offset + 1));
case 6: // HYPER
+ if (newOffset != 0) {
+ *newOffset = offset + 9;
+ }
return ConstantValue(
static_cast< sal_Int64 >(file->read64(offset + 1)));
//TODO: implementation-defined behavior of conversion from
// sal_uInt64 to sal_Int64 relies on two's complement representation
case 7: // UNSIGNED HYPER
+ if (newOffset != 0) {
+ *newOffset = offset + 9;
+ }
return ConstantValue(file->read64(offset + 1));
case 8: // FLOAT
+ if (newOffset != 0) {
+ *newOffset = offset + 5;
+ }
return ConstantValue(file->readIso60599Binary32(offset + 1));
case 9: // DOUBLE
+ if (newOffset != 0) {
+ *newOffset = offset + 9;
+ }
return ConstantValue(file->readIso60599Binary64(offset + 1));
default:
throw FileFormatException(
@@ -512,7 +570,7 @@ rtl::Reference< Entity > UnoidlCursor::getNext(OUString * name) {
assert(name != 0);
rtl::Reference< Entity > ent;
if (mapIndex_ != mapEnd_) {
- *name = file_->readNameNul(mapIndex_->name.getUnsigned32());
+ *name = file_->readNulName(mapIndex_->name.getUnsigned32());
ent = readEntity(file_, mapIndex_->data.getUnsigned32());
++mapIndex_;
}
@@ -547,7 +605,7 @@ private:
std::vector< OUString > UnoidlModuleEntity::getMemberNames() const {
std::vector< OUString > names;
for (sal_uInt32 i = 0; i != mapSize_; ++i) {
- names.push_back(file_->readNameNul(mapBegin_[i].name.getUnsigned32()));
+ names.push_back(file_->readNulName(mapBegin_[i].name.getUnsigned32()));
}
return names;
}
@@ -559,7 +617,7 @@ rtl::Reference< Entity > readEntity(
int v = file->read8(offset);
int type = v & 0x3F;
bool published = (v & 0x80) != 0;
- bool deprecated = (v & 0x40) != 0; (void)deprecated;//TODO
+ bool annotated = (v & 0x40) != 0;
bool flag = (v & 0x20) != 0;
switch (type) {
case 0: // module
@@ -592,16 +650,20 @@ rtl::Reference< Entity > readEntity(
offset += 5;
std::vector< EnumTypeEntity::Member > mems;
for (sal_uInt32 i = 0; i != n; ++i) {
- OUString memName(file->readNameLen(offset, &offset));
+ OUString memName(file->readIdxName(&offset));
sal_Int32 memValue = static_cast< sal_Int32 >(
file->read32(offset));
//TODO: implementation-defined behavior of conversion from
// sal_uInt32 to sal_Int32 relies on two's complement
// representation
offset += 4;
- mems.push_back(EnumTypeEntity::Member(memName, memValue));
+ mems.push_back(
+ EnumTypeEntity::Member(
+ memName, memValue,
+ readAnnotations(annotated, file, offset, &offset)));
}
- return new EnumTypeEntity(published, mems);
+ return new EnumTypeEntity(
+ published, mems, readAnnotations(annotated, file, offset));
}
case 2: // plain struct type without base
case 2 | 0x20: // plain struct type with base
@@ -609,7 +671,7 @@ rtl::Reference< Entity > readEntity(
++offset;
OUString base;
if (flag) {
- base = file->readNameLen(offset, &offset);
+ base = file->readIdxName(&offset);
if (base.isEmpty()) {
throw FileFormatException(
file->uri,
@@ -627,11 +689,16 @@ rtl::Reference< Entity > readEntity(
offset += 4;
std::vector< PlainStructTypeEntity::Member > mems;
for (sal_uInt32 i = 0; i != n; ++i) {
- OUString memName(file->readNameLen(offset, &offset));
- OUString memType(file->readNameLen(offset, &offset));
- mems.push_back(PlainStructTypeEntity::Member(memName, memType));
+ OUString memName(file->readIdxName(&offset));
+ OUString memType(file->readIdxName(&offset));
+ mems.push_back(
+ PlainStructTypeEntity::Member(
+ memName, memType,
+ readAnnotations(annotated, file, offset, &offset)));
}
- return new PlainStructTypeEntity(published, base, mems);
+ return new PlainStructTypeEntity(
+ published, base, mems,
+ readAnnotations(annotated, file, offset));
}
case 3: // polymorphic struct type template
{
@@ -645,7 +712,7 @@ rtl::Reference< Entity > readEntity(
offset += 5;
std::vector< OUString > params;
for (sal_uInt32 i = 0; i != n; ++i) {
- params.push_back(file->readNameLen(offset, &offset));
+ params.push_back(file->readIdxName(&offset));
}
n = file->read32(offset);
if (n > SAL_MAX_INT32) {
@@ -659,8 +726,8 @@ rtl::Reference< Entity > readEntity(
for (sal_uInt32 i = 0; i != n; ++i) {
v = file->read8(offset);
++offset;
- OUString memName(file->readNameLen(offset, &offset));
- OUString memType(file->readNameLen(offset, &offset));
+ OUString memName(file->readIdxName(&offset));
+ OUString memType(file->readIdxName(&offset));
if (v > 1) {
throw FileFormatException(
file->uri,
@@ -670,10 +737,12 @@ rtl::Reference< Entity > readEntity(
}
mems.push_back(
PolymorphicStructTypeTemplateEntity::Member(
- memName, memType, v == 1));
+ memName, memType, v == 1,
+ readAnnotations(annotated, file, offset, &offset)));
}
return new PolymorphicStructTypeTemplateEntity(
- published, params, mems);
+ published, params, mems,
+ readAnnotations(annotated, file, offset));
}
case 4: // exception type without base
case 4 | 0x20: // exception type with base
@@ -681,7 +750,7 @@ rtl::Reference< Entity > readEntity(
++offset;
OUString base;
if (flag) {
- base = file->readNameLen(offset, &offset);
+ base = file->readIdxName(&offset);
if (base.isEmpty()) {
throw FileFormatException(
file->uri,
@@ -698,11 +767,16 @@ rtl::Reference< Entity > readEntity(
offset += 4;
std::vector< ExceptionTypeEntity::Member > mems;
for (sal_uInt32 i = 0; i != n; ++i) {
- OUString memName(file->readNameLen(offset, &offset));
- OUString memType(file->readNameLen(offset, &offset));
- mems.push_back(ExceptionTypeEntity::Member(memName, memType));
+ OUString memName(file->readIdxName(&offset));
+ OUString memType(file->readIdxName(&offset));
+ mems.push_back(
+ ExceptionTypeEntity::Member(
+ memName, memType,
+ readAnnotations(annotated, file, offset, &offset)));
}
- return new ExceptionTypeEntity(published, base, mems);
+ return new ExceptionTypeEntity(
+ published, base, mems,
+ readAnnotations(annotated, file, offset));
}
case 5: // interface type
{
@@ -714,9 +788,13 @@ rtl::Reference< Entity > readEntity(
" interface type"));
}
offset += 5;
- std::vector< OUString > mandBases;
+ std::vector< AnnotatedReference > mandBases;
for (sal_uInt32 i = 0; i != n; ++i) {
- mandBases.push_back(file->readNameLen(offset, &offset));
+ OUString base(file->readIdxName(&offset));
+ mandBases.push_back(
+ AnnotatedReference(
+ base,
+ readAnnotations(annotated, file, offset, &offset)));
}
n = file->read32(offset);
if (n > SAL_MAX_INT32) {
@@ -726,9 +804,13 @@ rtl::Reference< Entity > readEntity(
" interface type"));
}
offset += 4;
- std::vector< OUString > optBases;
+ std::vector< AnnotatedReference > optBases;
for (sal_uInt32 i = 0; i != n; ++i) {
- optBases.push_back(file->readNameLen(offset, &offset));
+ OUString base(file->readIdxName(&offset));
+ optBases.push_back(
+ AnnotatedReference(
+ base,
+ readAnnotations(annotated, file, offset, &offset)));
}
sal_uInt32 nAttrs = file->read32(offset);
if (nAttrs > SAL_MAX_INT32) {
@@ -742,8 +824,8 @@ rtl::Reference< Entity > readEntity(
for (sal_uInt32 i = 0; i != nAttrs; ++i) {
v = file->read8(offset);
++offset;
- OUString attrName(file->readNameLen(offset, &offset));
- OUString attrType(file->readNameLen(offset, &offset));
+ OUString attrName(file->readIdxName(&offset));
+ OUString attrType(file->readIdxName(&offset));
if (v > 0x03) {
throw FileFormatException(
file->uri,
@@ -760,7 +842,7 @@ rtl::Reference< Entity > readEntity(
}
offset += 4;
for (sal_uInt32 j = 0; j != m; ++j) {
- getExcs.push_back(file->readNameLen(offset, &offset));
+ getExcs.push_back(file->readIdxName(&offset));
}
std::vector< OUString > setExcs;
if ((v & 0x02) == 0) {
@@ -774,13 +856,14 @@ rtl::Reference< Entity > readEntity(
}
offset += 4;
for (sal_uInt32 j = 0; j != m; ++j) {
- setExcs.push_back(file->readNameLen(offset, &offset));
+ setExcs.push_back(file->readIdxName(&offset));
}
}
attrs.push_back(
InterfaceTypeEntity::Attribute(
attrName, attrType, (v & 0x01) != 0, (v & 0x02) != 0,
- getExcs, setExcs));
+ getExcs, setExcs,
+ readAnnotations(annotated, file, offset, &offset)));
}
sal_uInt32 nMeths = file->read32(offset);
if (nMeths > SAL_MAX_INT32 - nAttrs) {
@@ -792,8 +875,8 @@ rtl::Reference< Entity > readEntity(
offset += 4;
std::vector< InterfaceTypeEntity::Method > meths;
for (sal_uInt32 i = 0; i != nMeths; ++i) {
- OUString methName(file->readNameLen(offset, &offset));
- OUString methType(file->readNameLen(offset, &offset));
+ OUString methName(file->readIdxName(&offset));
+ OUString methType(file->readIdxName(&offset));
sal_uInt32 m = file->read32(offset);
if (m > SAL_MAX_INT32) {
throw FileFormatException(
@@ -806,8 +889,8 @@ rtl::Reference< Entity > readEntity(
for (sal_uInt32 j = 0; j != m; ++j) {
v = file->read8(offset);
++offset;
- OUString paramName(file->readNameLen(offset, &offset));
- OUString paramType(file->readNameLen(offset, &offset));
+ OUString paramName(file->readIdxName(&offset));
+ OUString paramType(file->readIdxName(&offset));
InterfaceTypeEntity::Method::Parameter::Direction dir;
switch (v) {
case 0:
@@ -844,17 +927,24 @@ rtl::Reference< Entity > readEntity(
}
offset += 4;
for (sal_uInt32 j = 0; j != m; ++j) {
- excs.push_back(file->readNameLen(offset, &offset));
+ excs.push_back(file->readIdxName(&offset));
}
meths.push_back(
InterfaceTypeEntity::Method(
- methName, methType, params, excs));
+ methName, methType, params, excs,
+ readAnnotations(annotated, file, offset, &offset)));
}
return new InterfaceTypeEntity(
- published, mandBases, optBases, attrs, meths);
+ published, mandBases, optBases, attrs, meths,
+ readAnnotations(annotated, file, offset));
}
case 6: // typedef
- return new TypedefEntity(published, file->readNameLen(offset + 1));
+ {
+ ++offset;
+ OUString base(file->readIdxName(&offset));
+ return new TypedefEntity(
+ published, base, readAnnotations(annotated, file, offset));
+ }
case 7: // constant group
{
sal_uInt32 n = file->read32(offset + 1);
@@ -874,17 +964,23 @@ rtl::Reference< Entity > readEntity(
static_cast< char const * >(file->address) + offset + 5);
std::vector< ConstantGroupEntity::Member > mems;
for (sal_uInt32 i = 0; i != n; ++i) {
+ sal_uInt32 off = p[i].data.getUnsigned32();
+ bool ann;
+ ConstantValue val(readConstant(file, off, &off, &ann));
mems.push_back(
ConstantGroupEntity::Member(
- file->readNameNul(p[i].name.getUnsigned32()),
- readConstant(file, p[i].data.getUnsigned32())));
+ file->readNulName(p[i].name.getUnsigned32()), val,
+ readAnnotations(ann, file, off)));
}
- return new ConstantGroupEntity(published, mems);
+ return new ConstantGroupEntity(
+ published, mems,
+ readAnnotations(annotated, file, offset + 5 + 8 * n));
}
case 8: // single-interface--based service without default constructor
case 8 | 0x20: // single-interface--based service with default constructor
{
- OUString base(file->readNameLen(offset + 1, &offset));
+ ++offset;
+ OUString base(file->readIdxName(&offset));
std::vector< SingleInterfaceBasedServiceEntity::Constructor > ctors;
if (flag) {
ctors.push_back(
@@ -899,7 +995,7 @@ rtl::Reference< Entity > readEntity(
}
offset += 4;
for (sal_uInt32 i = 0; i != n; ++i) {
- OUString ctorName(file->readNameLen(offset, &offset));
+ OUString ctorName(file->readIdxName(&offset));
sal_uInt32 m = file->read32(offset);
if (m > SAL_MAX_INT32) {
throw FileFormatException(
@@ -915,8 +1011,8 @@ rtl::Reference< Entity > readEntity(
for (sal_uInt32 j = 0; j != m; ++j) {
v = file->read8(offset);
++offset;
- OUString paramName(file->readNameLen(offset, &offset));
- OUString paramType(file->readNameLen(offset, &offset));
+ OUString paramName(file->readIdxName(&offset));
+ OUString paramType(file->readIdxName(&offset));
bool rest;
switch (v) {
case 0:
@@ -949,15 +1045,17 @@ rtl::Reference< Entity > readEntity(
}
offset += 4;
for (sal_uInt32 j = 0; j != m; ++j) {
- excs.push_back(file->readNameLen(offset, &offset));
+ excs.push_back(file->readIdxName(&offset));
}
ctors.push_back(
SingleInterfaceBasedServiceEntity::Constructor(
- ctorName, params, excs));
+ ctorName, params, excs,
+ readAnnotations(annotated, file, offset, &offset)));
}
}
return new SingleInterfaceBasedServiceEntity(
- published, base, ctors);
+ published, base, ctors,
+ readAnnotations(annotated, file, offset));
}
case 9: // accumulation-based service
{
@@ -969,9 +1067,13 @@ rtl::Reference< Entity > readEntity(
" accumulation-based service"));
}
offset += 5;
- std::vector< OUString > mandServs;
+ std::vector< AnnotatedReference > mandServs;
for (sal_uInt32 i = 0; i != n; ++i) {
- mandServs.push_back(file->readNameLen(offset, &offset));
+ OUString base(file->readIdxName(&offset));
+ mandServs.push_back(
+ AnnotatedReference(
+ base,
+ readAnnotations(annotated, file, offset, &offset)));
}
n = file->read32(offset);
if (n > SAL_MAX_INT32) {
@@ -981,9 +1083,13 @@ rtl::Reference< Entity > readEntity(
" accumulation-based service"));
}
offset += 4;
- std::vector< OUString > optServs;
+ std::vector< AnnotatedReference > optServs;
for (sal_uInt32 i = 0; i != n; ++i) {
- optServs.push_back(file->readNameLen(offset, &offset));
+ OUString base(file->readIdxName(&offset));
+ optServs.push_back(
+ AnnotatedReference(
+ base,
+ readAnnotations(annotated, file, offset, &offset)));
}
n = file->read32(offset);
if (n > SAL_MAX_INT32) {
@@ -993,9 +1099,13 @@ rtl::Reference< Entity > readEntity(
" of accumulation-based service"));
}
offset += 4;
- std::vector< OUString > mandIfcs;
+ std::vector< AnnotatedReference > mandIfcs;
for (sal_uInt32 i = 0; i != n; ++i) {
- mandIfcs.push_back(file->readNameLen(offset, &offset));
+ OUString base(file->readIdxName(&offset));
+ mandIfcs.push_back(
+ AnnotatedReference(
+ base,
+ readAnnotations(annotated, file, offset, &offset)));
}
n = file->read32(offset);
if (n > SAL_MAX_INT32) {
@@ -1005,9 +1115,13 @@ rtl::Reference< Entity > readEntity(
" of accumulation-based service"));
}
offset += 4;
- std::vector< OUString > optIfcs;
+ std::vector< AnnotatedReference > optIfcs;
for (sal_uInt32 i = 0; i != n; ++i) {
- optIfcs.push_back(file->readNameLen(offset, &offset));
+ OUString base(file->readIdxName(&offset));
+ optIfcs.push_back(
+ AnnotatedReference(
+ base,
+ readAnnotations(annotated, file, offset, &offset)));
}
n = file->read32(offset);
if (n > SAL_MAX_INT32) {
@@ -1021,8 +1135,8 @@ rtl::Reference< Entity > readEntity(
for (sal_uInt32 i = 0; i != n; ++i) {
sal_uInt16 attrs = file->read16(offset);
offset += 2;
- OUString propName(file->readNameLen(offset, &offset));
- OUString propType(file->readNameLen(offset, &offset));
+ OUString propName(file->readIdxName(&offset));
+ OUString propType(file->readIdxName(&offset));
if (attrs > 0x01FF) { // see css.beans.PropertyAttribute
throw FileFormatException(
file->uri,
@@ -1036,17 +1150,27 @@ rtl::Reference< Entity > readEntity(
static_cast<
AccumulationBasedServiceEntity::Property::
Attributes >(
- attrs)));
+ attrs),
+ readAnnotations(annotated, file, offset, &offset)));
}
return new AccumulationBasedServiceEntity(
- published, mandServs, optServs, mandIfcs, optIfcs, props);
+ published, mandServs, optServs, mandIfcs, optIfcs, props,
+ readAnnotations(annotated, file, offset));
}
case 10: // interface-based singleton
- return new InterfaceBasedSingletonEntity(
- published, file->readNameLen(offset + 1));
+ {
+ ++offset;
+ OUString base(file->readIdxName(&offset));
+ return new InterfaceBasedSingletonEntity(
+ published, base, readAnnotations(annotated, file, offset));
+ }
case 11: // service-based singleton
- return new ServiceBasedSingletonEntity(
- published, file->readNameLen(offset + 1));
+ {
+ ++offset;
+ OUString base(file->readIdxName(&offset));
+ return new ServiceBasedSingletonEntity(
+ published, base, readAnnotations(annotated, file, offset));
+ }
default:
throw FileFormatException(
file->uri, "UNOIDL format: bad type byte " + OUString::number(v));