From a1dff2901e9b6f70ea87df5e76825367b38ceaf4 Mon Sep 17 00:00:00 2001 From: Stephan Bergmann Date: Thu, 16 May 2013 14:50:21 +0200 Subject: 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 --- unoidl/README | 120 +++++++++----- unoidl/source/legacyprovider.cxx | 117 +++++++++----- unoidl/source/reg2unoidl.cxx | 339 ++++++++++++++++++++++++++++++--------- unoidl/source/unoidlprovider.cxx | 338 ++++++++++++++++++++++++++------------ 4 files changed, 651 insertions(+), 263 deletions(-) (limited to 'unoidl') 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)); -- cgit