summaryrefslogtreecommitdiff
path: root/cppuhelper
diff options
context:
space:
mode:
authorStephan Bergmann <sbergman@redhat.com>2013-01-31 19:06:09 +0100
committerStephan Bergmann <sbergman@redhat.com>2013-01-31 19:09:24 +0100
commit7a9fed14d45ba99d5639d4cc80286ee146b8d40a (patch)
tree8e25391af962166faac3dd90e187b1fd5535c6db /cppuhelper
parentd9a18176d6b56119aa91699cd3aa102e36a7805c (diff)
WIP: Experimental new binary type.rdb format
cppuhelper/source/typedescriptionprovider.cxx would read it if it finds .rdb files in that format. Throwaway new reg2bin tool for now can translate existing .rdb files into the new format. Change-Id: Iacf219c30cfc358c3d31fb0d73966cf2296a4fe5
Diffstat (limited to 'cppuhelper')
-rw-r--r--cppuhelper/source/typedescriptionprovider.cxx3067
1 files changed, 3046 insertions, 21 deletions
diff --git a/cppuhelper/source/typedescriptionprovider.cxx b/cppuhelper/source/typedescriptionprovider.cxx
index 17e447f6f80d..ef9a0e3102fd 100644
--- a/cppuhelper/source/typedescriptionprovider.cxx
+++ b/cppuhelper/source/typedescriptionprovider.cxx
@@ -10,37 +10,3040 @@
#include "sal/config.h"
#include <cassert>
+#include <cstring>
+#include <set>
+#include <stack>
#include <vector>
+#include "boost/noncopyable.hpp"
+#include "com/sun/star/container/NoSuchElementException.hpp"
#include "com/sun/star/container/XHierarchicalNameAccess.hpp"
#include "com/sun/star/lang/XInitialization.hpp"
#include "com/sun/star/lang/XMultiComponentFactory.hpp"
+#include "com/sun/star/reflection/InvalidTypeNameException.hpp"
+#include "com/sun/star/reflection/NoSuchTypeNameException.hpp"
+#include "com/sun/star/reflection/TypeDescriptionSearchDepth.hpp"
+#include "com/sun/star/reflection/XConstantTypeDescription.hpp"
+#include "com/sun/star/reflection/XConstantsTypeDescription.hpp"
+#include "com/sun/star/reflection/XEnumTypeDescription.hpp"
+#include "com/sun/star/reflection/XIndirectTypeDescription.hpp"
+#include "com/sun/star/reflection/XInterfaceAttributeTypeDescription2.hpp"
+#include "com/sun/star/reflection/XInterfaceMethodTypeDescription.hpp"
+#include "com/sun/star/reflection/XInterfaceTypeDescription2.hpp"
+#include "com/sun/star/reflection/XModuleTypeDescription.hpp"
+#include "com/sun/star/reflection/XPublished.hpp"
+#include "com/sun/star/reflection/XServiceTypeDescription2.hpp"
+#include "com/sun/star/reflection/XSingletonTypeDescription2.hpp"
+#include "com/sun/star/reflection/XStructTypeDescription.hpp"
+#include "com/sun/star/reflection/XTypeDescriptionEnumeration.hpp"
+#include "com/sun/star/reflection/XTypeDescriptionEnumerationAccess.hpp"
#include "com/sun/star/registry/InvalidRegistryException.hpp"
#include "com/sun/star/registry/XSimpleRegistry.hpp"
+#include "com/sun/star/uno/Any.hxx"
#include "com/sun/star/uno/DeploymentException.hpp"
#include "com/sun/star/uno/Reference.hxx"
+#include "com/sun/star/uno/RuntimeException.hpp"
#include "com/sun/star/uno/Sequence.hxx"
+#include "com/sun/star/uno/TypeClass.hpp"
#include "com/sun/star/uno/XComponentContext.hpp"
#include "com/sun/star/uno/XInterface.hpp"
+#include "cppuhelper/compbase2.hxx"
+#include "cppuhelper/implbase1.hxx"
+#include "osl/file.h"
#include "osl/file.hxx"
+#include "osl/mutex.hxx"
+#include "rtl/ref.hxx"
#include "rtl/ustring.hxx"
+#include "sal/log.hxx"
+#include "sal/types.h"
+#include "salhelper/simplereferenceobject.hxx"
#include "paths.hxx"
#include "typedescriptionprovider.hxx"
+// New binary format:
+//
+// Uses the following definitions:
+//
+// * UInt16: 2-byte value, LSB first
+// * UInt32: 4-byte value, LSB first
+// * 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 followed by that many US-ASCII bytes
+// * Entry: Offset of NUL-Name followed by Offset of payload
+// * Map: zero or more Entries
+//
+// Layout of per-entry payload in the root or a module Map:
+//
+// * kind byte:
+// ** 0: module
+// *** followed by:
+// **** UInt32 number N1 of entries of Map
+// **** N1 * Entry
+// ** otherwise:
+// *** 0x80 bit: 1 if published
+// *** 0x40 bit: 1 if deprecated
+// *** 0x20 bit: flag (may only be 1 for certain kinds, see below)
+// *** remaining bits:
+// **** 1: enum type
+// ***** followed by:
+// ****** UInt32 number N1 of members
+// ****** N1 * tuple of:
+// ******* Offset of Len-Name
+// ******* UInt32
+// **** 2: plain struct type (with base if flag is 1)
+// ***** followed by:
+// ****** if "with base": Offset of Len-Name
+// ****** UInt32 number N1 of direct members
+// ****** N1 * tuple of:
+// ******* Offset of Len-Name name
+// ******* Offset of Len-Name type
+// **** 3: polymorphic struct type template
+// ***** followed by:
+// ****** UInt32 number N1 of type parameters
+// ****** N1 * Offset of Len-Name
+// ****** UInt32 number N2 of members
+// ****** N2 * tuple of:
+// ******* kind byte: 0x01 bit is 1 if parameterized type
+// ******* Offset of Len-Name name
+// ******* Offset of Len-Name type
+// **** 4: exception type (with base if flag is 1)
+// ***** followed by:
+// ****** if "with base": Offset of Len-Name
+// ****** UInt32 number N1 of direct members
+// ****** N1 * tuple of:
+// ******* Offset of Len-Name name
+// ******* Offset of Len-Name type
+// **** 5: interface type
+// ***** followed by:
+// ****** UInt32 number N1 of direct mandatory bases
+// ****** N1 * Offset of Len-Name
+// ****** UInt32 number N2 of direct optional bases
+// ****** N2 * Offset of Len-Name
+// ****** UInt32 number N3 of direct attributes
+// ****** N3 * tuple of:
+// ******* kind byte:
+// ******** 0x02 bit: 1 if read-only
+// ******** 0x01 bit: 1 if bound
+// ******* Offset of Len-Name name
+// ******* Offset of Len-Name type
+// ******* UInt32 number N4 of get exceptions
+// ******* N4 * Offset of Len-Name
+// ******* UInt32 number N5 of set exceptions
+// ******* N5 * Offset of Len-Name
+// ****** UInt32 number N6 of direct methods
+// ****** N6 * tuple of:
+// ******* Offset of Len-Name name
+// ******* Offset of Len-Name return type
+// ******* UInt32 number N7 of parameters
+// ******* N7 * tuple of:
+// ******** direction byte: 0 for in, 1 for out, 2 for in-out
+// ******** Offset of Len-Name name
+// ******** Offset of Len-Name type
+// ******* UInt32 number N8 of exceptions
+// ******* N8 * Offset of Len-Name
+// **** 6: typedef
+// ***** followed by:
+// ****** Offset of Len-Name
+// **** 7: constant group
+// ***** followed by:
+// ****** UInt32 number N1 of entries of Map
+// ****** N1 * Entry
+// **** 8: single-interface--based service (with default constructor if flag is
+// 1)
+// ***** followed by:
+// ****** Offset of Len-Name
+// ****** if not "with default constructor":
+// ******* UInt32 number N1 of constructors
+// ******* N1 * tuple of:
+// ******** Offset of Len-Name
+// ******** UInt32 number N2 of parameters
+// ******** N2 * tuple of
+// ********* kind byte: 0x04 bit is 1 if rest parameter
+// ********* Offset of Len-Name name
+// ********* Offset of Len-Name type
+// ******** UInt32 number N3 of exceptions
+// ******** N3 * Offset of Len-Name
+// **** 9: accumulation-based service
+// ***** followed by:
+// ****** UInt32 number N1 of direct mandatory base services
+// ****** N1 * Offset of Len-Name
+// ****** UInt32 number N2 of direct optional base services
+// ****** N2 * Offset of Len-Name
+// ****** UInt32 number N3 of direct mandatory base interfaces
+// ****** N3 * Offset of Len-Name
+// ****** UInt32 number N4 of direct optional base interfaces
+// ****** N4 * Offset of Len-Name
+// ****** UInt32 number N5 of direct properties
+// ****** N5 * tuple of:
+// ******* UInt16 kind:
+// ******** 0x0100 bit: 1 if optional
+// ******** 0x0080 bit: 1 if removable
+// ******** 0x0040 bit: 1 if maybedefault
+// ******** 0x0020 bit: 1 if maybeambiguous
+// ******** 0x0010 bit: 1 if readonly
+// ******** 0x0008 bit: 1 if transient
+// ******** 0x0004 bit: 1 if constrained
+// ******** 0x0002 bit: 1 if bound
+// ******** 0x0001 bit: 1 if maybevoid
+// ******* Offset of Len-Name name
+// ******* Offset of Len-Name type
+// **** 10: interface-based singleton
+// ***** followed by:
+// ****** Offset of Len-Name
+// **** 11: service-based singleton
+// ***** followed by:
+// ****** Offset of Len-Name
+//
+// Layout of per-entry payload in a constant group Map:
+//
+// * kind byte:
+// ** 0x80 bit: 1 if deprecated
+// ** remaining bits:
+// *** 0: BOOLEAN
+// **** followed by value byte, 0 represents false, 1 represents true
+// *** 1: BYTE
+// **** followed by value byte, representing values with two's complement
+// *** 2: SHORT
+// **** followed by UInt16 value, representing values with two's complement
+// *** 3: UNSIGNED SHORT
+// **** followed by UInt16 value
+// *** 4: LONG
+// **** followed by UInt32 value, representing values with two's complement
+// *** 5: UNSIGNED LONG
+// **** followed by UInt32 value
+// *** 6: HYPER
+// **** followed by UInt64 value, representing values with two's complement
+// *** 7: UNSIGNED HYPER
+// **** followed by UInt64 value
+// *** 8: FLOAT
+// **** followed by UInt32 value, representing values in IEEE-754 single
+// precision format
+// *** 9: DOUBLE
+// **** followed by UInt64 value, representing values in IEEE-754 double
+// precision format
+//
+// Memory layout:
+//
+// * 8 byte header "UNOIDL\0\xFF
+// * Offset of root Map
+// * UInt32 number of entries of root Map
+// ...
+
namespace {
-void readTypeRdbFile(
- rtl::OUString const & uri, bool optional,
+// sizeof (UInt16) == 2
+struct UInt16 {
+ unsigned char byte[2];
+
+ sal_uInt16 get() const {
+ return static_cast< sal_uInt16 >(byte[0])
+ | (static_cast< sal_uInt16 >(byte[1]) << 8);
+ }
+};
+
+// sizeof (UInt32) == 4
+struct UInt32 {
+ unsigned char byte[4];
+
+ sal_uInt32 get() const {
+ return static_cast< sal_uInt32 >(byte[0])
+ | (static_cast< sal_uInt32 >(byte[1]) << 8)
+ | (static_cast< sal_uInt32 >(byte[2]) << 16)
+ | (static_cast< sal_uInt32 >(byte[3]) << 24);
+ }
+};
+
+// sizeof (UInt64) == 8
+struct UInt64 {
+ unsigned char byte[8];
+
+ sal_uInt64 get() const {
+ return static_cast< sal_uInt64 >(byte[0])
+ | (static_cast< sal_uInt64 >(byte[1]) << 8)
+ | (static_cast< sal_uInt64 >(byte[2]) << 16)
+ | (static_cast< sal_uInt64 >(byte[3]) << 24)
+ | (static_cast< sal_uInt64 >(byte[4]) << 32)
+ | (static_cast< sal_uInt64 >(byte[5]) << 40)
+ | (static_cast< sal_uInt64 >(byte[6]) << 48)
+ | (static_cast< sal_uInt64 >(byte[7]) << 56);
+ }
+};
+
+struct MappedFile:
+ public salhelper::SimpleReferenceObject, private boost::noncopyable
+{
+ explicit MappedFile(rtl::OUString const & fileUrl);
+
+ sal_uInt8 read8(sal_uInt32 offset) const;
+
+ sal_uInt16 read16(sal_uInt32 offset) const;
+
+ sal_uInt32 read32(sal_uInt32 offset) const;
+
+ sal_uInt64 read64(sal_uInt32 offset) const;
+
+ rtl::OUString readNameNul(sal_uInt32 offset) const;
+
+ rtl::OUString readNameLen(sal_uInt32 offset, sal_uInt32 * newOffset = 0)
+ const;
+
+ oslFileHandle handle;
+ sal_uInt64 size;
+ void * address;
+
+private:
+ virtual ~MappedFile();
+
+ sal_uInt8 get8(sal_uInt32 offset) const;
+
+ sal_uInt16 get16(sal_uInt32 offset) const;
+
+ sal_uInt32 get32(sal_uInt32 offset) const;
+
+ sal_uInt64 get64(sal_uInt32 offset) const;
+};
+
+MappedFile::MappedFile(rtl::OUString const & fileUrl) {
+ oslFileError e = osl_openFile(
+ fileUrl.pData, &handle, osl_File_OpenFlag_Read);
+ switch (e) {
+ case osl_File_E_None:
+ break;
+ case osl_File_E_NOENT:
+ throw css::container::NoSuchElementException(
+ fileUrl, css::uno::Reference< css::uno::XInterface >());
+ default:
+ throw css::uno::RuntimeException(
+ "cannot open " + fileUrl + ": " + rtl::OUString::number(e),
+ css::uno::Reference< css::uno::XInterface >());
+ }
+ e = osl_getFileSize(handle, &size);
+ if (e == osl_File_E_None) {
+ e = osl_mapFile(
+ handle, &address, size, 0, osl_File_MapFlag_RandomAccess);
+ }
+ if (e != osl_File_E_None) {
+ oslFileError e2 = osl_closeFile(handle);
+ SAL_WARN_IF(
+ e2 != osl_File_E_None, "cppuhelper",
+ "cannot close " << fileUrl << ": " << +e2);
+ throw css::uno::RuntimeException(
+ "cannot mmap " + fileUrl + ": " + rtl::OUString::number(e),
+ css::uno::Reference< css::uno::XInterface >());
+ }
+}
+
+sal_uInt8 MappedFile::read8(sal_uInt32 offset) const {
+ assert(size >= 8);
+ if (offset > size - 1) {
+ throw css::uno::DeploymentException(
+ "broken UNOIDL file: offset for 8-bit value too large",
+ css::uno::Reference< css::uno::XInterface >());
+ }
+ return get8(offset);
+}
+
+sal_uInt16 MappedFile::read16(sal_uInt32 offset) const {
+ assert(size >= 8);
+ if (offset > size - 2) {
+ throw css::uno::DeploymentException(
+ "broken UNOIDL file: offset for 16-bit value too large",
+ css::uno::Reference< css::uno::XInterface >());
+ }
+ return get16(offset);
+}
+
+sal_uInt32 MappedFile::read32(sal_uInt32 offset) const {
+ assert(size >= 8);
+ if (offset > size - 4) {
+ throw css::uno::DeploymentException(
+ "broken UNOIDL file: offset for 32-bit value too large",
+ css::uno::Reference< css::uno::XInterface >());
+ }
+ return get32(offset);
+}
+
+sal_uInt64 MappedFile::read64(sal_uInt32 offset) const {
+ assert(size >= 8);
+ if (offset > size - 8) {
+ throw css::uno::DeploymentException(
+ "broken UNOIDL file: offset for 64-bit value too large",
+ css::uno::Reference< css::uno::XInterface >());
+ }
+ return get64(offset);
+}
+
+rtl::OUString MappedFile::readNameNul(sal_uInt32 offset) const {
+ if (offset > size) {
+ throw css::uno::DeploymentException(
+ "broken UNOIDL file: offset for string too large",
+ css::uno::Reference< css::uno::XInterface >());
+ }
+ sal_uInt64 end = offset;
+ for (;; ++end) {
+ if (end == size) {
+ throw css::uno::DeploymentException(
+ "broken UNOIDL file: string misses trailing NUL",
+ css::uno::Reference< css::uno::XInterface >());
+ }
+ if (static_cast< char const * >(address)[end] == 0) {
+ break;
+ }
+ }
+ if (end - offset > SAL_MAX_INT32) {
+ throw css::uno::DeploymentException(
+ "broken UNOIDL file: string too long",
+ css::uno::Reference< css::uno::XInterface >());
+ }
+ rtl::OUString name;
+ if (!rtl_convertStringToUString(
+ &name.pData, static_cast< char const * >(address) + offset,
+ end - offset, RTL_TEXTENCODING_ASCII_US,
+ (RTL_TEXTTOUNICODE_FLAGS_UNDEFINED_ERROR
+ | RTL_TEXTTOUNICODE_FLAGS_MBUNDEFINED_ERROR
+ | RTL_TEXTTOUNICODE_FLAGS_INVALID_ERROR)))
+ {
+ throw css::uno::DeploymentException(
+ "broken UNOIDL file: name is not ASCII",
+ css::uno::Reference< css::uno::XInterface >());
+ }
+ return name;
+}
+
+rtl::OUString MappedFile::readNameLen(sal_uInt32 offset, sal_uInt32 * newOffset)
+ const
+{
+ sal_uInt32 len = read32(offset);
+ if (len > SAL_MAX_INT32 || len > size - offset - 4) {
+ throw css::uno::DeploymentException(
+ "broken UNOIDL file: size of name is too large",
+ css::uno::Reference< css::uno::XInterface >());
+ }
+ rtl::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 css::uno::DeploymentException(
+ "broken UNOIDL file: name is not ASCII",
+ css::uno::Reference< css::uno::XInterface >());
+ }
+ if (newOffset != 0) {
+ *newOffset = offset + 4 + len;
+ }
+ return name;
+}
+
+MappedFile::~MappedFile() {
+ oslFileError e = osl_unmapMappedFile(handle, address, size);
+ SAL_WARN_IF(e != osl_File_E_None, "cppuhelper", "cannot unmap: " << +e);
+ e = osl_closeFile(handle);
+ SAL_WARN_IF(e != osl_File_E_None, "cppuhelper", "cannot close: " << +e);
+}
+
+sal_uInt8 MappedFile::get8(sal_uInt32 offset) const {
+ assert(size >= 8);
+ assert(offset <= size - 1);
+ return static_cast< char const * >(address)[offset];
+}
+
+sal_uInt16 MappedFile::get16(sal_uInt32 offset) const {
+ assert(size >= 8);
+ assert(offset <= size - 2);
+ return reinterpret_cast< UInt16 const * >(
+ static_cast< char const * >(address) + offset)->get();
+}
+
+sal_uInt32 MappedFile::get32(sal_uInt32 offset) const {
+ assert(size >= 8);
+ assert(offset <= size - 4);
+ return reinterpret_cast< UInt32 const * >(
+ static_cast< char const * >(address) + offset)->get();
+}
+
+sal_uInt64 MappedFile::get64(sal_uInt32 offset) const {
+ assert(size >= 8);
+ assert(offset <= size - 8);
+ return reinterpret_cast< UInt64 const * >(
+ static_cast< char const * >(address) + offset)->get();
+}
+
+css::uno::Reference< css::reflection::XTypeDescription > resolve(
+ css::uno::Reference< css::uno::XComponentContext > const & context,
+ rtl::OUString const & name)
+{
+ assert(context.is());
+ try {
+ return css::uno::Reference< css::reflection::XTypeDescription >(
+ (css::uno::Reference< css::container::XHierarchicalNameAccess >(
+ context->getValueByName(
+ "/singletons/"
+ "com.sun.star.reflection.theTypeDescriptionManager"),
+ css::uno::UNO_QUERY_THROW)->
+ getByHierarchicalName(name)),
+ css::uno::UNO_QUERY_THROW);
+ } catch (css::container::NoSuchElementException & e) {
+ throw css::uno::DeploymentException(
+ ("cannot resolve type \"" + name + "\"; NoSuchElementException: "
+ + e.Message),
+ e.Context);
+ }
+}
+
+class PublishableDescription:
+ public cppu::WeakImplHelper1< css::reflection::XPublished >,
+ private boost::noncopyable
+{
+protected:
+ PublishableDescription(bool published): published_(published) {}
+
+ virtual ~PublishableDescription() {}
+
+private:
+ virtual sal_Bool SAL_CALL isPublished() throw (css::uno::RuntimeException)
+ { return published_; }
+
+ bool published_;
+};
+
+class ModuleDescription:
+ public cppu::WeakImplHelper1< css::reflection::XModuleTypeDescription >,
+ private boost::noncopyable
+{
+public:
+ ModuleDescription(
+ css::uno::Reference< css::uno::XComponentContext > const & context,
+ rtl::OUString const & name,
+ std::vector< rtl::OUString > const & items):
+ context_(context), name_(name), items_(items)
+ {}
+
+private:
+ virtual ~ModuleDescription() {}
+
+ virtual css::uno::TypeClass SAL_CALL getTypeClass()
+ throw (css::uno::RuntimeException)
+ { return css::uno::TypeClass_MODULE; }
+
+ virtual rtl::OUString SAL_CALL getName() throw (css::uno::RuntimeException)
+ { return name_; }
+
+ virtual
+ css::uno::Sequence<
+ css::uno::Reference< css::reflection::XTypeDescription > >
+ SAL_CALL getMembers() throw (css::uno::RuntimeException);
+
+ css::uno::Reference< css::uno::XComponentContext > context_;
+ rtl::OUString name_;
+ std::vector< rtl::OUString > items_;
+};
+
+css::uno::Sequence< css::uno::Reference< css::reflection::XTypeDescription > >
+ModuleDescription::getMembers() throw (css::uno::RuntimeException) {
+ assert(items_.size() <= SAL_MAX_INT32);
+ sal_Int32 n = static_cast< sal_Int32 >(items_.size());
+ css::uno::Sequence<
+ css::uno::Reference< css::reflection::XTypeDescription > > s(n);
+ for (sal_Int32 i = 0; i != n; ++i) {
+ s[i] = resolve(context_, name_ + "." + items_[i]);
+ }
+ return s;
+}
+
+class EnumTypeDescription:
+ public cppu::ImplInheritanceHelper1<
+ PublishableDescription, css::reflection::XEnumTypeDescription >
+{
+public:
+ struct Member {
+ Member(rtl::OUString const & theName, sal_Int32 theValue):
+ name(theName), value(theValue)
+ {}
+
+ rtl::OUString name;
+ sal_Int32 value;
+ };
+
+ EnumTypeDescription(
+ rtl::OUString const & name, bool published,
+ std::vector< Member > const & members):
+ ImplInheritanceHelper1(published), name_(name), members_(members)
+ { assert(!members_.empty()); }
+
+private:
+ virtual ~EnumTypeDescription() {}
+
+ virtual css::uno::TypeClass SAL_CALL getTypeClass()
+ throw (css::uno::RuntimeException)
+ { return css::uno::TypeClass_ENUM; }
+
+ virtual rtl::OUString SAL_CALL getName() throw (css::uno::RuntimeException)
+ { return name_; }
+
+ virtual sal_Int32 SAL_CALL getDefaultEnumValue()
+ throw (css::uno::RuntimeException)
+ { return members_[0].value; }
+
+ virtual css::uno::Sequence< rtl::OUString > SAL_CALL getEnumNames()
+ throw (css::uno::RuntimeException);
+
+ virtual css::uno::Sequence< sal_Int32 > SAL_CALL getEnumValues()
+ throw (css::uno::RuntimeException);
+
+ rtl::OUString name_;
+ std::vector< Member > members_;
+};
+
+css::uno::Sequence< rtl::OUString > EnumTypeDescription::getEnumNames()
+ throw (css::uno::RuntimeException)
+{
+ assert(members_.size() <= SAL_MAX_INT32);
+ sal_Int32 n = static_cast< sal_Int32 >(members_.size());
+ css::uno::Sequence< rtl::OUString > s(n);
+ for (sal_Int32 i = 0; i != n; ++i) {
+ s[i] = members_[i].name;
+ }
+ return s;
+}
+
+css::uno::Sequence< sal_Int32 > EnumTypeDescription::getEnumValues()
+ throw (css::uno::RuntimeException)
+{
+ assert(members_.size() <= SAL_MAX_INT32);
+ sal_Int32 n = static_cast< sal_Int32 >(members_.size());
+ css::uno::Sequence< sal_Int32 > s(n);
+ for (sal_Int32 i = 0; i != n; ++i) {
+ s[i] = members_[i].value;
+ }
+ return s;
+}
+
+class PlainStructTypeDescription:
+ public cppu::ImplInheritanceHelper1<
+ PublishableDescription, css::reflection::XStructTypeDescription >
+{
+public:
+ struct Member {
+ Member(rtl::OUString const & theName, rtl::OUString const & theType):
+ name(theName), type(theType)
+ {}
+
+ rtl::OUString name;
+ rtl::OUString type;
+ };
+
+ PlainStructTypeDescription(
+ css::uno::Reference< css::uno::XComponentContext > const & context,
+ rtl::OUString const & name, bool published, rtl::OUString const & base,
+ std::vector< Member > const & directMembers):
+ ImplInheritanceHelper1(published), context_(context), name_(name),
+ base_(base), directMembers_(directMembers)
+ {}
+
+private:
+ virtual ~PlainStructTypeDescription() {}
+
+ virtual css::uno::TypeClass SAL_CALL getTypeClass()
+ throw (css::uno::RuntimeException)
+ { return css::uno::TypeClass_STRUCT; }
+
+ virtual rtl::OUString SAL_CALL getName() throw (css::uno::RuntimeException)
+ { return name_; }
+
+ virtual css::uno::Reference< css::reflection::XTypeDescription > SAL_CALL
+ getBaseType() throw (css::uno::RuntimeException) {
+ return base_.isEmpty()
+ ? css::uno::Reference< css::reflection::XTypeDescription >()
+ : resolve(context_, base_);
+ }
+
+ virtual
+ css::uno::Sequence<
+ css::uno::Reference< css::reflection::XTypeDescription > >
+ SAL_CALL getMemberTypes() throw (css::uno::RuntimeException);
+
+ virtual css::uno::Sequence< rtl::OUString > SAL_CALL getMemberNames()
+ throw (css::uno::RuntimeException);
+
+ virtual css::uno::Sequence< rtl::OUString > SAL_CALL getTypeParameters()
+ throw (css::uno::RuntimeException)
+ { return css::uno::Sequence< rtl::OUString >(); }
+
+ virtual
+ css::uno::Sequence<
+ css::uno::Reference< css::reflection::XTypeDescription > >
+ SAL_CALL getTypeArguments() throw (css::uno::RuntimeException) {
+ return css::uno::Sequence<
+ css::uno::Reference< css::reflection::XTypeDescription > >();
+ }
+
+ css::uno::Reference< css::uno::XComponentContext > context_;
+ rtl::OUString name_;
+ rtl::OUString base_;
+ std::vector< Member > directMembers_;
+};
+
+css::uno::Sequence< css::uno::Reference< css::reflection::XTypeDescription > >
+PlainStructTypeDescription::getMemberTypes() throw (css::uno::RuntimeException)
+{
+ assert(directMembers_.size() <= SAL_MAX_INT32);
+ sal_Int32 n = static_cast< sal_Int32 >(directMembers_.size());
+ css::uno::Sequence<
+ css::uno::Reference< css::reflection::XTypeDescription > > s(n);
+ for (sal_Int32 i = 0; i != n; ++i) {
+ s[i] = resolve(context_, directMembers_[i].type);
+ }
+ return s;
+}
+
+css::uno::Sequence< rtl::OUString > PlainStructTypeDescription::getMemberNames()
+ throw (css::uno::RuntimeException)
+{
+ assert(directMembers_.size() <= SAL_MAX_INT32);
+ sal_Int32 n = static_cast< sal_Int32 >(directMembers_.size());
+ css::uno::Sequence< rtl::OUString > s(n);
+ for (sal_Int32 i = 0; i != n; ++i) {
+ s[i] = directMembers_[i].name;
+ }
+ return s;
+}
+
+class ParameterizedMemberTypeDescription:
+ public cppu::WeakImplHelper1< css::reflection::XTypeDescription >,
+ private boost::noncopyable
+{
+public:
+ explicit ParameterizedMemberTypeDescription(
+ rtl::OUString const & typeParameterName):
+ typeParameterName_(typeParameterName)
+ {}
+
+private:
+ virtual ~ParameterizedMemberTypeDescription() {}
+
+ virtual css::uno::TypeClass SAL_CALL getTypeClass()
+ throw (css::uno::RuntimeException)
+ { return css::uno::TypeClass_UNKNOWN; }
+
+ virtual rtl::OUString SAL_CALL getName() throw (css::uno::RuntimeException)
+ { return typeParameterName_; }
+
+ rtl::OUString typeParameterName_;
+};
+
+class PolymorphicStructTypeTemplateDescription:
+ public cppu::ImplInheritanceHelper1<
+ PublishableDescription, css::reflection::XStructTypeDescription >
+{
+public:
+ struct Member {
+ Member(
+ rtl::OUString const & theName, rtl::OUString const & theType,
+ bool theParameterized):
+ name(theName), type(theType), parameterized(theParameterized)
+ {}
+
+ rtl::OUString name;
+ rtl::OUString type;
+ bool parameterized;
+ };
+
+ PolymorphicStructTypeTemplateDescription(
+ css::uno::Reference< css::uno::XComponentContext > const & context,
+ rtl::OUString const & name, bool published,
+ std::vector< rtl::OUString > const & typeParameters,
+ std::vector< Member > const & members):
+ ImplInheritanceHelper1(published), context_(context), name_(name),
+ typeParameters_(typeParameters), members_(members)
+ {}
+
+private:
+ virtual ~PolymorphicStructTypeTemplateDescription() {}
+
+ virtual css::uno::TypeClass SAL_CALL getTypeClass()
+ throw (css::uno::RuntimeException)
+ { return css::uno::TypeClass_STRUCT; }
+
+ virtual rtl::OUString SAL_CALL getName() throw (css::uno::RuntimeException)
+ { return name_; }
+
+ virtual css::uno::Reference< css::reflection::XTypeDescription > SAL_CALL
+ getBaseType() throw (css::uno::RuntimeException)
+ { return css::uno::Reference< css::reflection::XTypeDescription >(); }
+
+ virtual
+ css::uno::Sequence<
+ css::uno::Reference< css::reflection::XTypeDescription > >
+ SAL_CALL getMemberTypes() throw (css::uno::RuntimeException);
+
+ virtual css::uno::Sequence< rtl::OUString > SAL_CALL getMemberNames()
+ throw (css::uno::RuntimeException);
+
+ virtual css::uno::Sequence< rtl::OUString > SAL_CALL getTypeParameters()
+ throw (css::uno::RuntimeException);
+
+ virtual
+ css::uno::Sequence<
+ css::uno::Reference< css::reflection::XTypeDescription > >
+ SAL_CALL getTypeArguments() throw (css::uno::RuntimeException) {
+ return css::uno::Sequence<
+ css::uno::Reference< css::reflection::XTypeDescription > >();
+ }
+
+ css::uno::Reference< css::uno::XComponentContext > context_;
+ rtl::OUString name_;
+ std::vector< rtl::OUString > typeParameters_;
+ std::vector< Member > members_;
+};
+
+css::uno::Sequence< css::uno::Reference< css::reflection::XTypeDescription > >
+PolymorphicStructTypeTemplateDescription::getMemberTypes()
+ throw (css::uno::RuntimeException)
+{
+ assert(members_.size() <= SAL_MAX_INT32);
+ sal_Int32 n = static_cast< sal_Int32 >(members_.size());
+ css::uno::Sequence<
+ css::uno::Reference< css::reflection::XTypeDescription > > s(n);
+ for (sal_Int32 i = 0; i != n; ++i) {
+ s[i] = members_[i].parameterized
+ ? new ParameterizedMemberTypeDescription(members_[i].type)
+ : resolve(context_, members_[i].type);
+ }
+ return s;
+}
+
+css::uno::Sequence< rtl::OUString >
+PolymorphicStructTypeTemplateDescription::getMemberNames()
+ throw (css::uno::RuntimeException)
+{
+ assert(members_.size() <= SAL_MAX_INT32);
+ sal_Int32 n = static_cast< sal_Int32 >(members_.size());
+ css::uno::Sequence< rtl::OUString > s(n);
+ for (sal_Int32 i = 0; i != n; ++i) {
+ s[i] = members_[i].name;
+ }
+ return s;
+}
+
+css::uno::Sequence< rtl::OUString >
+PolymorphicStructTypeTemplateDescription::getTypeParameters()
+ throw (css::uno::RuntimeException)
+{
+ assert(typeParameters_.size() <= SAL_MAX_INT32);
+ sal_Int32 n = static_cast< sal_Int32 >(typeParameters_.size());
+ css::uno::Sequence< rtl::OUString > s(n);
+ for (sal_Int32 i = 0; i != n; ++i) {
+ s[i] = typeParameters_[i];
+ }
+ return s;
+}
+
+class ExceptionTypeDescription:
+ public cppu::ImplInheritanceHelper1<
+ PublishableDescription, css::reflection::XCompoundTypeDescription >
+{
+public:
+ struct Member {
+ Member(rtl::OUString const & theName, rtl::OUString const & theType):
+ name(theName), type(theType)
+ {}
+
+ rtl::OUString name;
+ rtl::OUString type;
+ };
+
+ ExceptionTypeDescription(
+ css::uno::Reference< css::uno::XComponentContext > const & context,
+ rtl::OUString const & name, bool published, rtl::OUString const & base,
+ std::vector< Member > const & directMembers):
+ ImplInheritanceHelper1(published), context_(context), name_(name),
+ base_(base), directMembers_(directMembers)
+ {}
+
+private:
+ virtual ~ExceptionTypeDescription() {}
+
+ virtual css::uno::TypeClass SAL_CALL getTypeClass()
+ throw (css::uno::RuntimeException)
+ { return css::uno::TypeClass_EXCEPTION; }
+
+ virtual rtl::OUString SAL_CALL getName() throw (css::uno::RuntimeException)
+ { return name_; }
+
+ virtual css::uno::Reference< css::reflection::XTypeDescription > SAL_CALL
+ getBaseType() throw (css::uno::RuntimeException) {
+ return base_.isEmpty()
+ ? css::uno::Reference< css::reflection::XTypeDescription >()
+ : resolve(context_, base_);
+ }
+
+ virtual
+ css::uno::Sequence<
+ css::uno::Reference< css::reflection::XTypeDescription > >
+ SAL_CALL getMemberTypes() throw (css::uno::RuntimeException);
+
+ virtual css::uno::Sequence< rtl::OUString > SAL_CALL getMemberNames()
+ throw (css::uno::RuntimeException);
+
+ css::uno::Reference< css::uno::XComponentContext > context_;
+ rtl::OUString name_;
+ rtl::OUString base_;
+ std::vector< Member > directMembers_;
+};
+
+css::uno::Sequence< css::uno::Reference< css::reflection::XTypeDescription > >
+ExceptionTypeDescription::getMemberTypes() throw (css::uno::RuntimeException) {
+ assert(directMembers_.size() <= SAL_MAX_INT32);
+ sal_Int32 n = static_cast< sal_Int32 >(directMembers_.size());
+ css::uno::Sequence<
+ css::uno::Reference< css::reflection::XTypeDescription > > s(n);
+ for (sal_Int32 i = 0; i != n; ++i) {
+ s[i] = resolve(context_, directMembers_[i].type);
+ }
+ return s;
+}
+
+css::uno::Sequence< rtl::OUString > ExceptionTypeDescription::getMemberNames()
+ throw (css::uno::RuntimeException)
+{
+ assert(directMembers_.size() <= SAL_MAX_INT32);
+ sal_Int32 n = static_cast< sal_Int32 >(directMembers_.size());
+ css::uno::Sequence< rtl::OUString > s(n);
+ for (sal_Int32 i = 0; i != n; ++i) {
+ s[i] = directMembers_[i].name;
+ }
+ return s;
+}
+
+css::uno::Reference< css::reflection::XTypeDescription > resolveTypedefs(
+ css::uno::Reference< css::reflection::XTypeDescription > const & type)
+{
+ css::uno::Reference< css::reflection::XTypeDescription > resolved(type);
+ while (resolved->getTypeClass() == css::uno::TypeClass_TYPEDEF) {
+ resolved
+ = (css::uno::Reference< css::reflection::XIndirectTypeDescription >(
+ resolved, css::uno::UNO_QUERY_THROW)->
+ getReferencedType());
+ }
+ return resolved;
+}
+
+class BaseOffset: private boost::noncopyable {
+public:
+ BaseOffset(
+ css::uno::Reference< css::reflection::XInterfaceTypeDescription2 >
+ const & description);
+
+ sal_Int32 get() const { return offset_; }
+
+private:
+ void calculateBases(
+ css::uno::Reference< css::reflection::XInterfaceTypeDescription2 >
+ const & description);
+
+ void calculate(
+ css::uno::Reference< css::reflection::XInterfaceTypeDescription2 >
+ const & description);
+
+ std::set< rtl::OUString > set_;
+ sal_Int32 offset_;
+};
+
+BaseOffset::BaseOffset(
+ css::uno::Reference< css::reflection::XInterfaceTypeDescription2 > const &
+ description):
+ offset_(0)
+{
+ calculateBases(description);
+}
+
+void BaseOffset::calculateBases(
+ css::uno::Reference< css::reflection::XInterfaceTypeDescription2 > const &
+ description)
+{
+ css::uno::Sequence<
+ css::uno::Reference < css::reflection::XTypeDescription > > bases(
+ description->getBaseTypes());
+ for (sal_Int32 i = 0; i != bases.getLength(); ++i) {
+ calculate(
+ css::uno::Reference< css::reflection::XInterfaceTypeDescription2 >(
+ resolveTypedefs(bases[i]), css::uno::UNO_QUERY_THROW));
+ }
+}
+
+void BaseOffset::calculate(
+ css::uno::Reference< css::reflection::XInterfaceTypeDescription2 > const &
+ description)
+{
+ if (set_.insert(description->getName()).second) {
+ calculateBases(description);
+ offset_ += description->getMembers().getLength();
+ }
+}
+
+struct Attribute {
+ Attribute(
+ rtl::OUString const & theName, rtl::OUString const & theType,
+ bool theBound, bool theReadOnly,
+ std::vector< rtl::OUString > const & theGetExceptions,
+ std::vector< rtl::OUString > const & theSetExceptions):
+ name(theName), type(theType), bound(theBound), readOnly(theReadOnly),
+ getExceptions(theGetExceptions), setExceptions(theSetExceptions)
+ {}
+
+ rtl::OUString name;
+ rtl::OUString type;
+ bool bound;
+ bool readOnly;
+ std::vector< rtl::OUString > getExceptions;
+ std::vector< rtl::OUString > setExceptions;
+};
+
+class AttributeDescription:
+ public cppu::WeakImplHelper1<
+ css::reflection::XInterfaceAttributeTypeDescription2 >,
+ private boost::noncopyable
+{
+public:
+ AttributeDescription(
+ css::uno::Reference< css::uno::XComponentContext > const & context,
+ rtl::OUString const & name, Attribute attribute, sal_Int32 position):
+ context_(context), name_(name), attribute_(attribute),
+ position_(position)
+ {}
+
+private:
+ virtual ~AttributeDescription() {}
+
+ virtual css::uno::TypeClass SAL_CALL getTypeClass()
+ throw (css::uno::RuntimeException)
+ { return css::uno::TypeClass_INTERFACE_ATTRIBUTE; }
+
+ virtual rtl::OUString SAL_CALL getName() throw (css::uno::RuntimeException)
+ { return name_; }
+
+ virtual rtl::OUString SAL_CALL getMemberName()
+ throw (css::uno::RuntimeException)
+ { return attribute_.name; }
+
+ virtual sal_Int32 SAL_CALL getPosition() throw (css::uno::RuntimeException)
+ { return position_; }
+
+ virtual sal_Bool SAL_CALL isReadOnly() throw (css::uno::RuntimeException)
+ { return attribute_.readOnly; }
+
+ virtual css::uno::Reference< css::reflection::XTypeDescription > SAL_CALL
+ getType() throw (css::uno::RuntimeException)
+ { return resolve(context_, attribute_.type); }
+
+ virtual sal_Bool SAL_CALL isBound() throw (css::uno::RuntimeException)
+ { return attribute_.bound; }
+
+ virtual
+ css::uno::Sequence<
+ css::uno::Reference< css::reflection::XCompoundTypeDescription > >
+ SAL_CALL getGetExceptions() throw (css::uno::RuntimeException);
+
+ virtual
+ css::uno::Sequence<
+ css::uno::Reference< css::reflection::XCompoundTypeDescription > >
+ SAL_CALL getSetExceptions() throw (css::uno::RuntimeException);
+
+ css::uno::Reference< css::uno::XComponentContext > context_;
+ rtl::OUString name_;
+ Attribute attribute_;
+ sal_Int32 position_;
+};
+
+css::uno::Sequence<
+ css::uno::Reference< css::reflection::XCompoundTypeDescription > >
+AttributeDescription::getGetExceptions() throw (css::uno::RuntimeException) {
+ assert(attribute_.getExceptions.size() <= SAL_MAX_INT32);
+ sal_Int32 n = static_cast< sal_Int32 >(attribute_.getExceptions.size());
+ css::uno::Sequence<
+ css::uno::Reference< css::reflection::XCompoundTypeDescription > > s(n);
+ for (sal_Int32 i = 0; i != n; ++i) {
+ s[i].set(
+ resolve(context_, attribute_.getExceptions[i]),
+ css::uno::UNO_QUERY_THROW);
+ }
+ return s;
+}
+
+css::uno::Sequence<
+ css::uno::Reference< css::reflection::XCompoundTypeDescription > >
+AttributeDescription::getSetExceptions() throw (css::uno::RuntimeException) {
+ assert(attribute_.setExceptions.size() <= SAL_MAX_INT32);
+ sal_Int32 n = static_cast< sal_Int32 >(attribute_.setExceptions.size());
+ css::uno::Sequence<
+ css::uno::Reference< css::reflection::XCompoundTypeDescription > > s(n);
+ for (sal_Int32 i = 0; i != n; ++i) {
+ s[i].set(
+ resolve(context_, attribute_.setExceptions[i]),
+ css::uno::UNO_QUERY_THROW);
+ }
+ return s;
+}
+
+struct Method {
+ struct Parameter {
+ enum Direction { DIRECTION_IN, DIRECTION_OUT, DIRECTION_IN_OUT };
+
+ Parameter(
+ rtl::OUString const & theName, rtl::OUString const & theType,
+ Direction theDirection):
+ name(theName), type(theType), direction(theDirection)
+ {}
+
+ rtl::OUString name;
+ rtl::OUString type;
+ Direction direction;
+ };
+
+ Method(
+ rtl::OUString const & theName, rtl::OUString const & theReturnType,
+ std::vector< Parameter > const & theParameters,
+ std::vector< rtl::OUString > const & theExceptions):
+ name(theName), returnType(theReturnType), parameters(theParameters),
+ exceptions(theExceptions)
+ {}
+
+ rtl::OUString name;
+ rtl::OUString returnType;
+ std::vector< Parameter > parameters;
+ std::vector< rtl::OUString > exceptions;
+};
+
+class MethodParameter:
+ public cppu::WeakImplHelper1< css::reflection::XMethodParameter >,
+ private boost::noncopyable
+{
+public:
+ MethodParameter(
+ css::uno::Reference< css::uno::XComponentContext > const & context,
+ Method::Parameter parameter, sal_Int32 position):
+ context_(context), parameter_(parameter), position_(position)
+ {}
+
+private:
+ virtual ~MethodParameter() {}
+
+ virtual rtl::OUString SAL_CALL getName() throw (css::uno::RuntimeException)
+ { return parameter_.name; }
+
+ virtual css::uno::Reference< css::reflection::XTypeDescription > SAL_CALL
+ getType() throw (css::uno::RuntimeException)
+ { return resolve(context_, parameter_.type); }
+
+ virtual sal_Bool SAL_CALL isIn() throw (css::uno::RuntimeException) {
+ return parameter_.direction == Method::Parameter::DIRECTION_IN
+ || parameter_.direction == Method::Parameter::DIRECTION_IN_OUT;
+ }
+
+ virtual sal_Bool SAL_CALL isOut() throw (css::uno::RuntimeException) {
+ return parameter_.direction == Method::Parameter::DIRECTION_OUT
+ || parameter_.direction == Method::Parameter::DIRECTION_IN_OUT;
+ }
+
+ virtual sal_Int32 SAL_CALL getPosition() throw (css::uno::RuntimeException)
+ { return position_; }
+
+ css::uno::Reference< css::uno::XComponentContext > context_;
+ Method::Parameter parameter_;
+ sal_Int32 position_;
+};
+
+class MethodDescription:
+ public cppu::WeakImplHelper1<
+ css::reflection::XInterfaceMethodTypeDescription >,
+ private boost::noncopyable
+{
+public:
+ MethodDescription(
+ css::uno::Reference< css::uno::XComponentContext > const & context,
+ rtl::OUString const & name, Method method, sal_Int32 position):
+ context_(context), name_(name), method_(method), position_(position)
+ {}
+
+private:
+ virtual ~MethodDescription() {}
+
+ virtual css::uno::TypeClass SAL_CALL getTypeClass()
+ throw (css::uno::RuntimeException)
+ { return css::uno::TypeClass_INTERFACE_METHOD; }
+
+ virtual rtl::OUString SAL_CALL getName() throw (css::uno::RuntimeException)
+ { return name_; }
+
+ virtual rtl::OUString SAL_CALL getMemberName()
+ throw (css::uno::RuntimeException)
+ { return method_.name; }
+
+ virtual sal_Int32 SAL_CALL getPosition() throw (css::uno::RuntimeException)
+ { return position_; }
+
+ virtual css::uno::Reference< css::reflection::XTypeDescription > SAL_CALL
+ getReturnType() throw (css::uno::RuntimeException)
+ { return resolve(context_, method_.returnType); }
+
+ virtual sal_Bool SAL_CALL isOneway() throw (css::uno::RuntimeException)
+ { return false; }
+
+ virtual
+ css::uno::Sequence<
+ css::uno::Reference< css::reflection::XMethodParameter > >
+ SAL_CALL getParameters() throw (css::uno::RuntimeException);
+
+ virtual
+ css::uno::Sequence<
+ css::uno::Reference< css::reflection::XTypeDescription > >
+ SAL_CALL getExceptions() throw (css::uno::RuntimeException);
+
+ css::uno::Reference< css::uno::XComponentContext > context_;
+ rtl::OUString name_;
+ Method method_;
+ sal_Int32 position_;
+};
+
+css::uno::Sequence< css::uno::Reference< css::reflection::XMethodParameter > >
+MethodDescription::getParameters() throw (css::uno::RuntimeException) {
+ assert(method_.parameters.size() <= SAL_MAX_INT32);
+ sal_Int32 n = static_cast< sal_Int32 >(method_.parameters.size());
+ css::uno::Sequence<
+ css::uno::Reference< css::reflection::XMethodParameter > > s(n);
+ for (sal_Int32 i = 0; i != n; ++i) {
+ s[i] = new MethodParameter(context_, method_.parameters[i], i);
+ }
+ return s;
+}
+
+css::uno::Sequence< css::uno::Reference< css::reflection::XTypeDescription > >
+MethodDescription::getExceptions() throw (css::uno::RuntimeException) {
+ assert(method_.exceptions.size() <= SAL_MAX_INT32);
+ sal_Int32 n = static_cast< sal_Int32 >(method_.exceptions.size());
+ css::uno::Sequence<
+ css::uno::Reference< css::reflection::XTypeDescription > > s(n);
+ for (sal_Int32 i = 0; i != n; ++i) {
+ s[i] = resolve(context_, method_.exceptions[i]);
+ }
+ return s;
+}
+
+class InterfaceTypeDescription:
+ public cppu::ImplInheritanceHelper1<
+ PublishableDescription, css::reflection::XInterfaceTypeDescription2 >
+{
+public:
+ InterfaceTypeDescription(
+ css::uno::Reference< css::uno::XComponentContext > const & context,
+ rtl::OUString const & name, bool published,
+ std::vector< rtl::OUString > const & mandatoryDirectBases,
+ std::vector< rtl::OUString > const & optionalDirectBases,
+ std::vector< Attribute > const & directAttributes,
+ std::vector< Method > const & directMethods):
+ ImplInheritanceHelper1(published), context_(context), name_(name),
+ mandatoryDirectBases_(mandatoryDirectBases),
+ optionalDirectBases_(optionalDirectBases),
+ directAttributes_(directAttributes), directMethods_(directMethods)
+ {}
+
+private:
+ virtual ~InterfaceTypeDescription() {}
+
+ virtual css::uno::TypeClass SAL_CALL getTypeClass()
+ throw (css::uno::RuntimeException)
+ { return css::uno::TypeClass_INTERFACE; }
+
+ virtual rtl::OUString SAL_CALL getName() throw (css::uno::RuntimeException)
+ { return name_; }
+
+ virtual css::uno::Reference< css::reflection::XTypeDescription > SAL_CALL
+ getBaseType() throw (css::uno::RuntimeException) {
+ return mandatoryDirectBases_.empty()
+ ? css::uno::Reference< css::reflection::XTypeDescription >()
+ : resolve(context_, mandatoryDirectBases_[0]);
+ }
+
+ virtual css::uno::Uik SAL_CALL getUik() throw (css::uno::RuntimeException)
+ { return css::uno::Uik(); }
+
+ virtual
+ css::uno::Sequence<
+ css::uno::Reference<
+ css::reflection::XInterfaceMemberTypeDescription > >
+ SAL_CALL getMembers() throw (css::uno::RuntimeException);
+
+ virtual
+ css::uno::Sequence<
+ css::uno::Reference< css::reflection::XTypeDescription > >
+ SAL_CALL getBaseTypes() throw (css::uno::RuntimeException);
+
+ virtual
+ css::uno::Sequence<
+ css::uno::Reference< css::reflection::XTypeDescription > >
+ SAL_CALL getOptionalBaseTypes() throw (css::uno::RuntimeException);
+
+ css::uno::Reference< css::uno::XComponentContext > context_;
+ rtl::OUString name_;
+ std::vector< rtl::OUString > mandatoryDirectBases_;
+ std::vector< rtl::OUString > optionalDirectBases_;
+ std::vector< Attribute > directAttributes_;
+ std::vector< Method > directMethods_;
+};
+
+css::uno::Sequence<
+ css::uno::Reference< css::reflection::XInterfaceMemberTypeDescription > >
+InterfaceTypeDescription::getMembers() throw (css::uno::RuntimeException) {
+ assert(
+ directAttributes_.size() <= SAL_MAX_INT32
+ && directMethods_.size() <= SAL_MAX_INT32 - directAttributes_.size());
+ sal_Int32 n1 = static_cast< sal_Int32 >(directAttributes_.size());
+ sal_Int32 n2 = static_cast< sal_Int32 >(directMethods_.size());
+ css::uno::Sequence<
+ css::uno::Reference<
+ css::reflection::XInterfaceMemberTypeDescription > > s(n1 + n2);
+ sal_Int32 off = BaseOffset(this).get();
+ for (sal_Int32 i = 0; i != n1; ++i) {
+ s[i] = new AttributeDescription(
+ context_, name_ + "::" + directAttributes_[i].name,
+ directAttributes_[i], off + i);
+ }
+ for (sal_Int32 i = 0; i != n2; ++i) {
+ s[n1 + i] = new MethodDescription(
+ context_, name_ + "::" + directMethods_[i].name,
+ directMethods_[i], off + n1 + i);
+ }
+ return s;
+}
+
+css::uno::Sequence< css::uno::Reference< css::reflection::XTypeDescription > >
+InterfaceTypeDescription::getBaseTypes() throw (css::uno::RuntimeException) {
+ assert(mandatoryDirectBases_.size() <= SAL_MAX_INT32);
+ sal_Int32 n = static_cast< sal_Int32 >(mandatoryDirectBases_.size());
+ css::uno::Sequence<
+ css::uno::Reference< css::reflection::XTypeDescription > > s(n);
+ for (sal_Int32 i = 0; i != n; ++i) {
+ s[i] = resolve(context_, mandatoryDirectBases_[i]);
+ }
+ return s;
+}
+
+css::uno::Sequence< css::uno::Reference< css::reflection::XTypeDescription > >
+InterfaceTypeDescription::getOptionalBaseTypes()
+ throw (css::uno::RuntimeException)
+{
+ assert(optionalDirectBases_.size() <= SAL_MAX_INT32);
+ sal_Int32 n = static_cast< sal_Int32 >(optionalDirectBases_.size());
+ css::uno::Sequence<
+ css::uno::Reference< css::reflection::XTypeDescription > > s(n);
+ for (sal_Int32 i = 0; i != n; ++i) {
+ s[i] = resolve(context_, optionalDirectBases_[i]);
+ }
+ return s;
+}
+
+class ConstantDescription:
+ public cppu::WeakImplHelper1< css::reflection::XConstantTypeDescription >,
+ private boost::noncopyable
+{
+public:
+ ConstantDescription(
+ rtl::OUString const & name, css::uno::Any const & value):
+ name_(name), value_(value)
+ {}
+
+private:
+ virtual ~ConstantDescription() {}
+
+ virtual css::uno::TypeClass SAL_CALL getTypeClass()
+ throw (css::uno::RuntimeException)
+ { return css::uno::TypeClass_CONSTANT; }
+
+ virtual rtl::OUString SAL_CALL getName() throw (css::uno::RuntimeException)
+ { return name_; }
+
+ virtual css::uno::Any SAL_CALL getConstantValue()
+ throw (css::uno::RuntimeException)
+ { return value_; }
+
+ rtl::OUString name_;
+ css::uno::Any value_;
+};
+
+class ConstantGroupDescription:
+ public cppu::ImplInheritanceHelper1<
+ PublishableDescription, css::reflection::XConstantsTypeDescription >
+{
+public:
+ ConstantGroupDescription(
+ css::uno::Reference< css::uno::XComponentContext > const & context,
+ rtl::OUString const & name, bool published,
+ std::vector< rtl::OUString > const & constants):
+ ImplInheritanceHelper1(published), context_(context), name_(name),
+ constants_(constants)
+ {}
+
+private:
+ virtual ~ConstantGroupDescription() {}
+
+ virtual css::uno::TypeClass SAL_CALL getTypeClass()
+ throw (css::uno::RuntimeException)
+ { return css::uno::TypeClass_CONSTANTS; }
+
+ virtual rtl::OUString SAL_CALL getName() throw (css::uno::RuntimeException)
+ { return name_; }
+
+ virtual
+ css::uno::Sequence<
+ css::uno::Reference< css::reflection::XConstantTypeDescription > >
+ SAL_CALL getConstants() throw (css::uno::RuntimeException);
+
+ css::uno::Reference< css::uno::XComponentContext > context_;
+ rtl::OUString name_;
+ std::vector< rtl::OUString > constants_;
+};
+
+css::uno::Sequence<
+ css::uno::Reference< css::reflection::XConstantTypeDescription > >
+ConstantGroupDescription::getConstants() throw (css::uno::RuntimeException) {
+ assert(constants_.size() <= SAL_MAX_INT32);
+ sal_Int32 n = static_cast< sal_Int32 >(constants_.size());
+ css::uno::Sequence<
+ css::uno::Reference< css::reflection::XConstantTypeDescription > > s(n);
+ for (sal_Int32 i = 0; i != n; ++i) {
+ s[i].set(
+ resolve(context_, name_ + "." + constants_[i]),
+ css::uno::UNO_QUERY_THROW);
+ }
+ return s;
+}
+
+class TypedefDescription:
+ public cppu::ImplInheritanceHelper1<
+ PublishableDescription, css::reflection::XIndirectTypeDescription >
+{
+public:
+ TypedefDescription(
+ css::uno::Reference< css::uno::XComponentContext > const & context,
+ rtl::OUString const & name, bool published, rtl::OUString const & type):
+ ImplInheritanceHelper1(published), context_(context), name_(name),
+ type_(type)
+ {}
+
+private:
+ virtual ~TypedefDescription() {}
+
+ virtual css::uno::TypeClass SAL_CALL getTypeClass()
+ throw (css::uno::RuntimeException)
+ { return css::uno::TypeClass_TYPEDEF; }
+
+ virtual rtl::OUString SAL_CALL getName() throw (css::uno::RuntimeException)
+ { return name_; }
+
+ virtual css::uno::Reference< css::reflection::XTypeDescription > SAL_CALL
+ getReferencedType() throw (css::uno::RuntimeException)
+ { return resolve(context_, type_); }
+
+ css::uno::Reference< css::uno::XComponentContext > context_;
+ rtl::OUString name_;
+ rtl::OUString type_;
+};
+
+struct Constructor {
+ struct Parameter {
+ Parameter(
+ rtl::OUString const & theName, rtl::OUString const & theType,
+ bool theRest):
+ name(theName), type(theType), rest(theRest)
+ {}
+
+ rtl::OUString name;
+ rtl::OUString type;
+ bool rest;
+ };
+
+ Constructor(): defaultConstructor(true) {}
+
+ Constructor(
+ rtl::OUString const & theName,
+ std::vector< Parameter > const & theParameters,
+ std::vector< rtl::OUString > const & theExceptions):
+ defaultConstructor(false), name(theName), parameters(theParameters),
+ exceptions(theExceptions)
+ {}
+
+ bool defaultConstructor;
+ rtl::OUString name;
+ std::vector< Parameter > parameters;
+ std::vector< rtl::OUString > exceptions;
+};
+
+class ConstructorParameter:
+ public cppu::WeakImplHelper1< css::reflection::XParameter >,
+ private boost::noncopyable
+{
+public:
+ ConstructorParameter(
+ css::uno::Reference< css::uno::XComponentContext > const & context,
+ Constructor::Parameter parameter, sal_Int32 position):
+ context_(context), parameter_(parameter), position_(position)
+ {}
+
+private:
+ virtual ~ConstructorParameter() {}
+
+ virtual rtl::OUString SAL_CALL getName() throw (css::uno::RuntimeException)
+ { return parameter_.name; }
+
+ virtual css::uno::Reference< css::reflection::XTypeDescription > SAL_CALL
+ getType() throw (css::uno::RuntimeException)
+ { return resolve(context_, parameter_.type); }
+
+ virtual sal_Bool SAL_CALL isIn() throw (css::uno::RuntimeException)
+ { return true; }
+
+ virtual sal_Bool SAL_CALL isOut() throw (css::uno::RuntimeException)
+ { return false; }
+
+ virtual sal_Int32 SAL_CALL getPosition() throw (css::uno::RuntimeException)
+ { return position_; }
+
+ virtual sal_Bool SAL_CALL isRestParameter()
+ throw (css::uno::RuntimeException)
+ { return parameter_.rest; }
+
+ css::uno::Reference< css::uno::XComponentContext > context_;
+ Constructor::Parameter parameter_;
+ sal_Int32 position_;
+};
+
+class ConstructorDescription:
+ public cppu::WeakImplHelper1<
+ css::reflection::XServiceConstructorDescription >,
+ private boost::noncopyable
+{
+public:
+ ConstructorDescription(
+ css::uno::Reference< css::uno::XComponentContext > const & context,
+ Constructor const & constructor):
+ context_(context), constructor_(constructor)
+ {}
+
+private:
+ virtual ~ConstructorDescription() {}
+
+ virtual sal_Bool SAL_CALL isDefaultConstructor()
+ throw (css::uno::RuntimeException)
+ { return constructor_.defaultConstructor; }
+
+ virtual rtl::OUString SAL_CALL getName() throw (css::uno::RuntimeException)
+ { return constructor_.name; }
+
+ virtual
+ css::uno::Sequence<
+ css::uno::Reference< css::reflection::XParameter > >
+ SAL_CALL getParameters() throw (css::uno::RuntimeException);
+
+ virtual
+ css::uno::Sequence<
+ css::uno::Reference< css::reflection::XCompoundTypeDescription > >
+ SAL_CALL getExceptions() throw (css::uno::RuntimeException);
+
+ css::uno::Reference< css::uno::XComponentContext > context_;
+ Constructor constructor_;
+};
+
+css::uno::Sequence< css::uno::Reference< css::reflection::XParameter > >
+ConstructorDescription::getParameters() throw (css::uno::RuntimeException) {
+ assert(constructor_.parameters.size() <= SAL_MAX_INT32);
+ sal_Int32 n = static_cast< sal_Int32 >(constructor_.parameters.size());
+ css::uno::Sequence< css::uno::Reference< css::reflection::XParameter > > s(
+ n);
+ for (sal_Int32 i = 0; i != n; ++i) {
+ s[i] = new ConstructorParameter(
+ context_, constructor_.parameters[i], i);
+ }
+ return s;
+}
+
+css::uno::Sequence<
+ css::uno::Reference< css::reflection::XCompoundTypeDescription > >
+ConstructorDescription::getExceptions() throw (css::uno::RuntimeException) {
+ assert(constructor_.exceptions.size() <= SAL_MAX_INT32);
+ sal_Int32 n = static_cast< sal_Int32 >(constructor_.exceptions.size());
+ css::uno::Sequence<
+ css::uno::Reference< css::reflection::XCompoundTypeDescription > > s(n);
+ for (sal_Int32 i = 0; i != n; ++i) {
+ s[i].set(
+ resolve(context_, constructor_.exceptions[i]),
+ css::uno::UNO_QUERY_THROW);
+ }
+ return s;
+}
+
+class SingleInterfaceBasedServiceDescription:
+ public cppu::ImplInheritanceHelper1<
+ PublishableDescription, css::reflection::XServiceTypeDescription2 >
+{
+public:
+ SingleInterfaceBasedServiceDescription(
+ css::uno::Reference< css::uno::XComponentContext > const & context,
+ rtl::OUString const & name, bool published, rtl::OUString const & type,
+ std::vector< Constructor > const & constructors):
+ ImplInheritanceHelper1(published), context_(context), name_(name),
+ type_(type), constructors_(constructors)
+ {}
+
+private:
+ virtual ~SingleInterfaceBasedServiceDescription() {}
+
+ virtual css::uno::TypeClass SAL_CALL getTypeClass()
+ throw (css::uno::RuntimeException)
+ { return css::uno::TypeClass_SERVICE; }
+
+ virtual rtl::OUString SAL_CALL getName() throw (css::uno::RuntimeException)
+ { return name_; }
+
+ virtual
+ css::uno::Sequence<
+ css::uno::Reference< css::reflection::XServiceTypeDescription > >
+ SAL_CALL getMandatoryServices() throw (css::uno::RuntimeException)
+ {
+ return css::uno::Sequence<
+ css::uno::Reference< css::reflection::XServiceTypeDescription > >();
+ }
+
+ virtual
+ css::uno::Sequence<
+ css::uno::Reference< css::reflection::XServiceTypeDescription > >
+ SAL_CALL getOptionalServices() throw (css::uno::RuntimeException)
+ {
+ return css::uno::Sequence<
+ css::uno::Reference< css::reflection::XServiceTypeDescription > >();
+ }
+
+ virtual
+ css::uno::Sequence<
+ css::uno::Reference< css::reflection::XInterfaceTypeDescription > >
+ SAL_CALL getMandatoryInterfaces() throw (css::uno::RuntimeException)
+ {
+ return css::uno::Sequence<
+ css::uno::Reference<
+ css::reflection::XInterfaceTypeDescription > >();
+ }
+
+ virtual
+ css::uno::Sequence<
+ css::uno::Reference< css::reflection::XInterfaceTypeDescription > >
+ SAL_CALL getOptionalInterfaces() throw (css::uno::RuntimeException)
+ {
+ return css::uno::Sequence<
+ css::uno::Reference<
+ css::reflection::XInterfaceTypeDescription > >();
+ }
+
+ virtual
+ css::uno::Sequence<
+ css::uno::Reference< css::reflection::XPropertyTypeDescription > >
+ SAL_CALL getProperties() throw (css::uno::RuntimeException)
+ {
+ return css::uno::Sequence<
+ css::uno::Reference<
+ css::reflection::XPropertyTypeDescription > >();
+ }
+
+ virtual sal_Bool SAL_CALL isSingleInterfaceBased()
+ throw (css::uno::RuntimeException)
+ { return true; }
+
+ virtual css::uno::Reference< css::reflection::XTypeDescription > SAL_CALL
+ getInterface() throw (css::uno::RuntimeException)
+ { return resolve(context_, type_); }
+
+ virtual
+ css::uno::Sequence<
+ css::uno::Reference< css::reflection::XServiceConstructorDescription > >
+ SAL_CALL getConstructors() throw (css::uno::RuntimeException);
+
+ css::uno::Reference< css::uno::XComponentContext > context_;
+ rtl::OUString name_;
+ rtl::OUString type_;
+ std::vector< Constructor > constructors_;
+};
+
+css::uno::Sequence<
+ css::uno::Reference< css::reflection::XServiceConstructorDescription > >
+SingleInterfaceBasedServiceDescription::getConstructors()
+ throw (css::uno::RuntimeException)
+{
+ assert(constructors_.size() <= SAL_MAX_INT32);
+ sal_Int32 n = static_cast< sal_Int32 >(constructors_.size());
+ css::uno::Sequence<
+ css::uno::Reference< css::reflection::XServiceConstructorDescription > >
+ s(n);
+ for (sal_Int32 i = 0; i != n; ++i) {
+ s[i] = new ConstructorDescription(context_, constructors_[i]);
+ }
+ return s;
+}
+
+struct Property {
+ Property(
+ rtl::OUString const & theName, rtl::OUString const & theType,
+ sal_uInt16 theAttributes):
+ name(theName), type(theType), attributes(theAttributes)
+ {}
+
+ rtl::OUString name;
+ rtl::OUString type;
+ sal_Int16 attributes;
+};
+
+class PropertyDescription:
+ public cppu::WeakImplHelper1< css::reflection::XPropertyTypeDescription >,
+ private boost::noncopyable
+{
+public:
+ PropertyDescription(
+ css::uno::Reference< css::uno::XComponentContext > const & context,
+ Property const & property):
+ context_(context), property_(property)
+ {}
+
+private:
+ virtual ~PropertyDescription() {}
+
+ virtual css::uno::TypeClass SAL_CALL getTypeClass()
+ throw (css::uno::RuntimeException)
+ { return css::uno::TypeClass_PROPERTY; }
+
+ virtual rtl::OUString SAL_CALL getName() throw (css::uno::RuntimeException)
+ { return property_.name; }
+
+ virtual sal_Int16 SAL_CALL getPropertyFlags()
+ throw (css::uno::RuntimeException)
+ { return property_.attributes; }
+
+ virtual css::uno::Reference< css::reflection::XTypeDescription > SAL_CALL
+ getPropertyTypeDescription() throw (css::uno::RuntimeException)
+ { return resolve(context_, property_.type); }
+
+ css::uno::Reference< css::uno::XComponentContext > context_;
+ Property property_;
+};
+
+class AccumulationBasedServiceDescription:
+ public cppu::ImplInheritanceHelper1<
+ PublishableDescription, css::reflection::XServiceTypeDescription2 >
+{
+public:
+ AccumulationBasedServiceDescription(
+ css::uno::Reference< css::uno::XComponentContext > const & context,
+ rtl::OUString const & name, bool published,
+ std::vector< rtl::OUString > const & mandatoryDirectBaseServices,
+ std::vector< rtl::OUString > const & optionalDirectBaseServices,
+ std::vector< rtl::OUString > const & mandatoryDirectBaseInterfaces,
+ std::vector< rtl::OUString > const & optionalDirectBaseInterfaces,
+ std::vector< Property > const & directProperties):
+ ImplInheritanceHelper1(published), context_(context), name_(name),
+ mandatoryDirectBaseServices_(mandatoryDirectBaseServices),
+ optionalDirectBaseServices_(optionalDirectBaseServices),
+ mandatoryDirectBaseInterfaces_(mandatoryDirectBaseInterfaces),
+ optionalDirectBaseInterfaces_(optionalDirectBaseInterfaces),
+ directProperties_(directProperties)
+ {}
+
+private:
+ virtual ~AccumulationBasedServiceDescription() {}
+
+ virtual css::uno::TypeClass SAL_CALL getTypeClass()
+ throw (css::uno::RuntimeException)
+ { return css::uno::TypeClass_SERVICE; }
+
+ virtual rtl::OUString SAL_CALL getName() throw (css::uno::RuntimeException)
+ { return name_; }
+
+ virtual
+ css::uno::Sequence<
+ css::uno::Reference< css::reflection::XServiceTypeDescription > >
+ SAL_CALL getMandatoryServices() throw (css::uno::RuntimeException);
+
+ virtual
+ css::uno::Sequence<
+ css::uno::Reference< css::reflection::XServiceTypeDescription > >
+ SAL_CALL getOptionalServices() throw (css::uno::RuntimeException);
+
+ virtual
+ css::uno::Sequence<
+ css::uno::Reference< css::reflection::XInterfaceTypeDescription > >
+ SAL_CALL getMandatoryInterfaces() throw (css::uno::RuntimeException);
+
+ virtual
+ css::uno::Sequence<
+ css::uno::Reference< css::reflection::XInterfaceTypeDescription > >
+ SAL_CALL getOptionalInterfaces() throw (css::uno::RuntimeException);
+
+ virtual
+ css::uno::Sequence<
+ css::uno::Reference< css::reflection::XPropertyTypeDescription > >
+ SAL_CALL getProperties() throw (css::uno::RuntimeException);
+
+ virtual sal_Bool SAL_CALL isSingleInterfaceBased()
+ throw (css::uno::RuntimeException)
+ { return false; }
+
+ virtual css::uno::Reference< css::reflection::XTypeDescription > SAL_CALL
+ getInterface() throw (css::uno::RuntimeException)
+ { return css::uno::Reference< css::reflection::XTypeDescription >(); }
+
+ virtual
+ css::uno::Sequence<
+ css::uno::Reference< css::reflection::XServiceConstructorDescription > >
+ SAL_CALL getConstructors() throw (css::uno::RuntimeException)
+ {
+ return css::uno::Sequence<
+ css::uno::Reference<
+ css::reflection::XServiceConstructorDescription > >();
+ }
+
+ css::uno::Reference< css::uno::XComponentContext > context_;
+ rtl::OUString name_;
+ std::vector< rtl::OUString > mandatoryDirectBaseServices_;
+ std::vector< rtl::OUString > optionalDirectBaseServices_;
+ std::vector< rtl::OUString > mandatoryDirectBaseInterfaces_;
+ std::vector< rtl::OUString > optionalDirectBaseInterfaces_;
+ std::vector< Property > directProperties_;
+};
+
+css::uno::Sequence<
+ css::uno::Reference< css::reflection::XServiceTypeDescription > >
+AccumulationBasedServiceDescription::getMandatoryServices()
+ throw (css::uno::RuntimeException)
+{
+ assert(mandatoryDirectBaseServices_.size() <= SAL_MAX_INT32);
+ sal_Int32 n = static_cast< sal_Int32 >(mandatoryDirectBaseServices_.size());
+ css::uno::Sequence<
+ css::uno::Reference< css::reflection::XServiceTypeDescription > > s(n);
+ for (sal_Int32 i = 0; i != n; ++i) {
+ s[i].set(
+ resolve(context_, mandatoryDirectBaseServices_[i]),
+ css::uno::UNO_QUERY_THROW);
+ }
+ return s;
+}
+
+css::uno::Sequence<
+ css::uno::Reference< css::reflection::XServiceTypeDescription > >
+AccumulationBasedServiceDescription::getOptionalServices()
+ throw (css::uno::RuntimeException)
+{
+ assert(optionalDirectBaseServices_.size() <= SAL_MAX_INT32);
+ sal_Int32 n = static_cast< sal_Int32 >(optionalDirectBaseServices_.size());
+ css::uno::Sequence<
+ css::uno::Reference< css::reflection::XServiceTypeDescription > > s(n);
+ for (sal_Int32 i = 0; i != n; ++i) {
+ s[i].set(
+ resolve(context_, optionalDirectBaseServices_[i]),
+ css::uno::UNO_QUERY_THROW);
+ }
+ return s;
+}
+
+css::uno::Sequence<
+ css::uno::Reference< css::reflection::XInterfaceTypeDescription > >
+AccumulationBasedServiceDescription::getMandatoryInterfaces()
+ throw (css::uno::RuntimeException)
+{
+ assert(mandatoryDirectBaseInterfaces_.size() <= SAL_MAX_INT32);
+ sal_Int32 n = static_cast< sal_Int32 >(
+ mandatoryDirectBaseInterfaces_.size());
+ css::uno::Sequence<
+ css::uno::Reference< css::reflection::XInterfaceTypeDescription > > s(
+ n);
+ for (sal_Int32 i = 0; i != n; ++i) {
+ s[i].set(
+ resolveTypedefs(
+ resolve(context_, mandatoryDirectBaseInterfaces_[i])),
+ css::uno::UNO_QUERY_THROW);
+ }
+ return s;
+}
+
+css::uno::Sequence<
+ css::uno::Reference< css::reflection::XInterfaceTypeDescription > >
+AccumulationBasedServiceDescription::getOptionalInterfaces()
+ throw (css::uno::RuntimeException)
+{
+ assert(optionalDirectBaseInterfaces_.size() <= SAL_MAX_INT32);
+ sal_Int32 n = static_cast< sal_Int32 >(
+ optionalDirectBaseInterfaces_.size());
+ css::uno::Sequence<
+ css::uno::Reference< css::reflection::XInterfaceTypeDescription > > s(
+ n);
+ for (sal_Int32 i = 0; i != n; ++i) {
+ s[i].set(
+ resolveTypedefs(
+ resolve(context_, optionalDirectBaseInterfaces_[i])),
+ css::uno::UNO_QUERY_THROW);
+ }
+ return s;
+}
+
+css::uno::Sequence<
+ css::uno::Reference< css::reflection::XPropertyTypeDescription > >
+AccumulationBasedServiceDescription::getProperties()
+ throw (css::uno::RuntimeException)
+{
+ assert(directProperties_.size() <= SAL_MAX_INT32);
+ sal_Int32 n = static_cast< sal_Int32 >(directProperties_.size());
+ css::uno::Sequence<
+ css::uno::Reference< css::reflection::XPropertyTypeDescription > > s(n);
+ for (sal_Int32 i = 0; i != n; ++i) {
+ s[i] = new PropertyDescription(context_, directProperties_[i]);
+ }
+ return s;
+}
+
+class InterfaceBasedSingletonDescription:
+ public cppu::ImplInheritanceHelper1<
+ PublishableDescription, css::reflection::XSingletonTypeDescription2 >
+{
+public:
+ InterfaceBasedSingletonDescription(
+ css::uno::Reference< css::uno::XComponentContext > const & context,
+ rtl::OUString const & name, bool published, rtl::OUString const & type):
+ ImplInheritanceHelper1(published), context_(context), name_(name),
+ type_(type)
+ {}
+
+private:
+ virtual ~InterfaceBasedSingletonDescription() {}
+
+ virtual css::uno::TypeClass SAL_CALL getTypeClass()
+ throw (css::uno::RuntimeException)
+ { return css::uno::TypeClass_SINGLETON; }
+
+ virtual rtl::OUString SAL_CALL getName() throw (css::uno::RuntimeException)
+ { return name_; }
+
+ virtual css::uno::Reference< css::reflection::XServiceTypeDescription >
+ SAL_CALL getService() throw (css::uno::RuntimeException)
+ {
+ return
+ css::uno::Reference< css::reflection::XServiceTypeDescription >();
+ }
+
+ virtual sal_Bool SAL_CALL isInterfaceBased()
+ throw (css::uno::RuntimeException)
+ { return true; }
+
+ virtual css::uno::Reference< css::reflection::XTypeDescription >
+ SAL_CALL getInterface() throw (css::uno::RuntimeException)
+ { return resolve(context_, type_); }
+
+ css::uno::Reference< css::uno::XComponentContext > context_;
+ rtl::OUString name_;
+ rtl::OUString type_;
+};
+
+class ServiceBasedSingletonDescription:
+ public cppu::ImplInheritanceHelper1<
+ PublishableDescription, css::reflection::XSingletonTypeDescription2 >
+{
+public:
+ ServiceBasedSingletonDescription(
+ css::uno::Reference< css::uno::XComponentContext > const & context,
+ rtl::OUString const & name, bool published, rtl::OUString const & type):
+ ImplInheritanceHelper1(published), context_(context), name_(name),
+ type_(type)
+ {}
+
+private:
+ virtual ~ServiceBasedSingletonDescription() {}
+
+ virtual css::uno::TypeClass SAL_CALL getTypeClass()
+ throw (css::uno::RuntimeException)
+ { return css::uno::TypeClass_SINGLETON; }
+
+ virtual rtl::OUString SAL_CALL getName() throw (css::uno::RuntimeException)
+ { return name_; }
+
+ virtual css::uno::Reference< css::reflection::XServiceTypeDescription >
+ SAL_CALL getService() throw (css::uno::RuntimeException)
+ {
+ return css::uno::Reference< css::reflection::XServiceTypeDescription >(
+ resolve(context_, type_), css::uno::UNO_QUERY_THROW);
+ }
+
+ virtual sal_Bool SAL_CALL isInterfaceBased()
+ throw (css::uno::RuntimeException)
+ { return false; }
+
+ virtual css::uno::Reference< css::reflection::XTypeDescription >
+ SAL_CALL getInterface() throw (css::uno::RuntimeException)
+ { return css::uno::Reference< css::reflection::XTypeDescription >(); }
+
+ css::uno::Reference< css::uno::XComponentContext > context_;
+ rtl::OUString name_;
+ rtl::OUString type_;
+};
+
+// sizeof (MapEntry) == 8
+struct MapEntry {
+ UInt32 name;
+ UInt32 data;
+};
+
+class Enumeration:
+ public cppu::WeakImplHelper1<
+ css::reflection::XTypeDescriptionEnumeration >,
+ private boost::noncopyable
+{
+public:
+ Enumeration(
+ css::uno::Reference< css::uno::XComponentContext > const & context,
+ rtl::Reference< MappedFile > const & file, rtl::OUString const & prefix,
+ MapEntry const * mapBegin, sal_uInt32 mapSize,
+ css::uno::Sequence< css::uno::TypeClass > const & types, bool deep):
+ context_(context), file_(file), types_(types), deep_(deep)
+ {
+ positions_.push(Position(prefix, mapBegin, mapSize, false));
+ findMatch();
+ }
+
+private:
+ virtual ~Enumeration() {}
+
+ virtual sal_Bool SAL_CALL hasMoreElements()
+ throw (css::uno::RuntimeException)
+ { return !positions_.empty(); }
+
+ virtual css::uno::Any SAL_CALL nextElement()
+ throw (
+ css::container::NoSuchElementException,
+ css::lang::WrappedTargetException, css::uno::RuntimeException)
+ { return css::uno::makeAny(nextTypeDescription()); }
+
+ virtual css::uno::Reference< css::reflection::XTypeDescription > SAL_CALL
+ nextTypeDescription()
+ throw (
+ css::container::NoSuchElementException, css::uno::RuntimeException);
+
+ bool matches(css::uno::TypeClass tc) const;
+
+ void proceed();
+
+ void findMatch();
+
+ struct Position {
+ Position(
+ rtl::OUString const & thePrefix, MapEntry const * mapBegin,
+ sal_uInt32 mapSize, bool theConstantGroup):
+ prefix(thePrefix), position(mapBegin), end(mapBegin + mapSize),
+ constantGroup(theConstantGroup)
+ {}
+
+ rtl::OUString prefix;
+ MapEntry const * position;
+ MapEntry const * end;
+ bool constantGroup;
+ };
+
+ css::uno::Reference< css::uno::XComponentContext > context_;
+ rtl::Reference< MappedFile > file_;
+ css::uno::Sequence< css::uno::TypeClass > types_;
+ bool deep_;
+
+ osl::Mutex mutex_;
+ std::stack< Position > positions_;
+ rtl::OUString current_;
+};
+
+css::uno::Reference< css::reflection::XTypeDescription >
+Enumeration::nextTypeDescription()
+ throw (css::container::NoSuchElementException, css::uno::RuntimeException)
+{
+ rtl::OUString name;
+ {
+ osl::MutexGuard g(mutex_);
+ if (positions_.empty()) {
+ throw css::container::NoSuchElementException(
+ "exhausted XTypeDescriptionEnumeration",
+ static_cast< cppu::OWeakObject * >(this));
+ }
+ name = current_;
+ proceed();
+ findMatch();
+ }
+ return resolve(context_, name);
+}
+
+bool Enumeration::matches(css::uno::TypeClass tc) const {
+ if (types_.getLength() == 0) {
+ return true;
+ }
+ for (sal_Int32 i = 0; i != types_.getLength(); ++i) {
+ if (types_[i] == tc) {
+ return true;
+ }
+ }
+ return false;
+}
+
+void Enumeration::proceed() {
+ assert(!positions_.empty());
+ assert(positions_.top().position < positions_.top().end);
+ if (deep_) {
+ sal_uInt32 off = positions_.top().position->data.get();
+ int v = file_->read8(off);
+ bool recurse;
+ bool cgroup;
+ if (v == 0) {
+ recurse = true;
+ cgroup = false;
+ } else if ((v & 0x3F) == 7 && matches(css::uno::TypeClass_CONSTANT)) {
+ recurse = true;
+ cgroup = true;
+ } else {
+ recurse = false;
+ }
+ if (recurse) {
+ rtl::OUString prefix(
+ positions_.top().prefix
+ + file_->readNameNul(positions_.top().position->name.get())
+ + ".");
+ sal_uInt32 mapSize = file_->read32(off + 1);
+ if (8 * mapSize > file_->size - off - 5) { //TODO: overflow
+ throw css::uno::DeploymentException(
+ "broken UNOIDL file: map offset + size too large",
+ css::uno::Reference< css::uno::XInterface >());
+ }
+ MapEntry const * mapBegin = reinterpret_cast< MapEntry const * >(
+ static_cast< char const * >(file_->address) + off + 5);
+ ++positions_.top().position;
+ positions_.push(Position(prefix, mapBegin, mapSize, cgroup));
+ return;
+ }
+ }
+ ++positions_.top().position;
+}
+
+void Enumeration::findMatch() {
+ assert(!positions_.empty());
+ for (;; proceed()) {
+ while (positions_.top().position == positions_.top().end) {
+ positions_.pop();
+ if (positions_.empty()) {
+ return;
+ }
+ }
+ bool match;
+ if (positions_.top().constantGroup) {
+ assert(matches(css::uno::TypeClass_CONSTANT));
+ match = true;
+ } else {
+ sal_uInt32 off = positions_.top().position->data.get();
+ int v = file_->read8(off);
+ css::uno::TypeClass tc;
+ switch (v & 0x1F) {
+ case 0: // module
+ tc = css::uno::TypeClass_MODULE;
+ break;
+ case 1: // enum type
+ tc = css::uno::TypeClass_ENUM;
+ break;
+ case 2: // plain struct type (with or without base)
+ case 3: // polymorphic struct type template
+ tc = css::uno::TypeClass_STRUCT;
+ break;
+ case 4: // exception type (with or without base)
+ tc = css::uno::TypeClass_EXCEPTION;
+ break;
+ case 5: // interface type
+ tc = css::uno::TypeClass_INTERFACE;
+ break;
+ case 6: // typedef
+ tc = css::uno::TypeClass_TYPEDEF;
+ break;
+ case 7: // constant group
+ tc = css::uno::TypeClass_CONSTANTS;
+ break;
+ case 8: // single-interface--based service (with or without default
+ // constructor)
+ case 9: // accumulation-based service
+ tc = css::uno::TypeClass_SERVICE;
+ break;
+ case 10: // interface-based singleton
+ case 11: // service-based singleton
+ tc = css::uno::TypeClass_SINGLETON;
+ break;
+ default:
+ throw css::uno::DeploymentException(
+ ("broken UNOIDL file: bad type byte "
+ + rtl::OUString::number(v)),
+ css::uno::Reference< css::uno::XInterface >());
+ }
+ match = matches(tc);
+ }
+ if (match) {
+ current_ = positions_.top().prefix
+ + file_->readNameNul(positions_.top().position->name.get());
+ return;
+ }
+ }
+}
+
+class Provider:
+ private osl::Mutex,
+ public cppu::WeakComponentImplHelper2<
+ css::container::XHierarchicalNameAccess,
+ css::reflection::XTypeDescriptionEnumerationAccess >,
+ private boost::noncopyable
+{
+public:
+ Provider(
+ css::uno::Reference< css::uno::XComponentContext > const & context,
+ rtl::OUString const & uri);
+
+ using WeakComponentImplHelper2::acquire;
+ using WeakComponentImplHelper2::release;
+
+private:
+ enum Compare { COMPARE_LESS, COMPARE_GREATER, COMPARE_EQUAL };
+
+ virtual ~Provider() {}
+
+ virtual void SAL_CALL disposing() {} //TODO
+
+ virtual css::uno::Any SAL_CALL getByHierarchicalName(
+ rtl::OUString const & aName)
+ throw (
+ css::container::NoSuchElementException, css::uno::RuntimeException);
+
+ virtual sal_Bool SAL_CALL hasByHierarchicalName(
+ rtl::OUString const & aName) throw (css::uno::RuntimeException)
+ { return find(aName) != 0; }
+
+ virtual css::uno::Reference< css::reflection::XTypeDescriptionEnumeration >
+ SAL_CALL createTypeDescriptionEnumeration(
+ rtl::OUString const & moduleName,
+ css::uno::Sequence< css::uno::TypeClass > const & types,
+ css::reflection::TypeDescriptionSearchDepth depth)
+ throw(
+ css::reflection::NoSuchTypeNameException,
+ css::reflection::InvalidTypeNameException,
+ css::uno::RuntimeException);
+
+ sal_uInt32 find(rtl::OUString const & name, bool * constant = 0) const;
+
+ sal_uInt32 findInMap(
+ rtl::OUString const & name, sal_Int32 nameOffset, sal_Int32 nameLength,
+ MapEntry const * mapBegin, sal_uInt32 mapSize) const;
+
+ Compare compare(
+ rtl::OUString const & name, sal_Int32 nameOffset, sal_Int32 nameLength,
+ MapEntry const * entry) const;
+
+ css::uno::Reference< css::uno::XComponentContext > context_;
+ rtl::Reference< MappedFile > file_;
+ MapEntry const * mapBegin_;
+ sal_uInt32 mapSize_;
+};
+
+Provider::Provider(
+ css::uno::Reference< css::uno::XComponentContext > const & context,
+ rtl::OUString const & uri):
+ WeakComponentImplHelper2(*static_cast< osl::Mutex * >(this)),
+ context_(context), file_(new MappedFile(uri))
+{
+ if (file_->size < 8 || std::memcmp(file_->address, "UNOIDL\0\xFF", 8) != 0)
+ {
+ throw css::registry::InvalidRegistryException(
+ uri, css::uno::Reference< css::uno::XInterface >());
+ }
+ sal_uInt32 off = file_->read32(8);
+ mapSize_ = file_->read32(12);
+ if (off + 8 * mapSize_ > file_->size) { //TODO: overflow
+ throw css::uno::DeploymentException(
+ "broken UNOIDL file: root map offset + size too large",
+ css::uno::Reference< css::uno::XInterface >());
+ }
+ mapBegin_ = reinterpret_cast< MapEntry const * >(
+ static_cast< char const * >(file_->address) + off);
+}
+
+css::uno::Any Provider::getByHierarchicalName(rtl::OUString const & aName)
+ throw (css::container::NoSuchElementException, css::uno::RuntimeException)
+{
+ bool cnst;
+ sal_uInt32 off = find(aName, &cnst);
+ if (off == 0) {
+ throw css::container::NoSuchElementException(
+ aName, static_cast< cppu::OWeakObject * >(this));
+ }
+ if (cnst) {
+ int v = file_->read8(off);
+ int type = v & 0x7F;
+ bool deprecated = (v & 0x80) != 0; (void)deprecated;//TODO
+ css::uno::Any any;
+ switch (type) {
+ case 0: // BOOLEAN
+ v = file_->read8(off + 1);
+ switch (v) {
+ case 0:
+ any <<= false;
+ break;
+ case 1:
+ any <<= true;
+ break;
+ default:
+ throw css::uno::DeploymentException(
+ ("broken UNOIDL file: bad boolean constant value "
+ + rtl::OUString::number(v)),
+ css::uno::Reference< css::uno::XInterface >());
+ }
+ break;
+ case 1: // BYTE
+ any <<= static_cast< sal_Int8 >(file_->read8(off + 1));
+ //TODO: implementation-defined behavior of conversion from
+ // sal_uInt8 to sal_Int8 relies on two's complement
+ // representation
+ break;
+ case 2: // SHORT
+ any <<= static_cast< sal_Int16 >(file_->read16(off + 1));
+ //TODO: implementation-defined behavior of conversion from
+ // sal_uInt16 to sal_Int16 relies on two's complement
+ // representation
+ break;
+ case 3: // UNSIGNED SHORT
+ any <<= file_->read16(off + 1);
+ break;
+ case 4: // LONG
+ any <<= static_cast< sal_Int32 >(file_->read32(off + 1));
+ //TODO: implementation-defined behavior of conversion from
+ // sal_uInt32 to sal_Int32 relies on two's complement
+ // representation
+ break;
+ case 5: // UNSIGNED LONG
+ any <<= file_->read32(off + 1);
+ break;
+ case 6: // HYPER
+ any <<= static_cast< sal_Int64 >(file_->read64(off + 1));
+ //TODO: implementation-defined behavior of conversion from
+ // sal_uInt64 to sal_Int64 relies on two's complement
+ // representation
+ break;
+ case 7: // UNSIGNED HYPER
+ any <<= file_->read64(off + 1);
+ break;
+ case 8: // FLOAT
+ //TODO
+ case 9: // DOUBLE
+ //TODO
+ default:
+ throw css::uno::DeploymentException(
+ ("broken UNOIDL file: bad constant type byte "
+ + rtl::OUString::number(v)),
+ css::uno::Reference< css::uno::XInterface >());
+ }
+ return css::uno::makeAny<
+ css::uno::Reference< css::reflection::XTypeDescription > >(
+ new ConstantDescription(aName, any));
+ } else {
+ int v = file_->read8(off);
+ int type = v & 0x3F;
+ bool published = (v & 0x80) != 0;
+ bool deprecated = (v & 0x40) != 0; (void)deprecated;//TODO
+ bool flag = (v & 0x20) != 0;
+ switch (type) {
+ case 0: // module
+ {
+ if (v != 0) {
+ throw css::uno::DeploymentException(
+ ("broken UNOIDL file: bad module type byte "
+ + rtl::OUString::number(v)),
+ css::uno::Reference< css::uno::XInterface >());
+ }
+ sal_uInt32 n = file_->read32(off + 1);
+ if (n > SAL_MAX_INT32) {
+ throw css::uno::DeploymentException(
+ ("broken UNOIDL file: too many items in module "
+ + aName),
+ css::uno::Reference< css::uno::XInterface >());
+ }
+ off += 5;
+ std::vector< rtl::OUString > items;
+ for (sal_uInt32 i = 0; i != n; ++i) {
+ items.push_back(file_->readNameNul(file_->read32(off)));
+ off += 8;
+ }
+ return css::uno::makeAny<
+ css::uno::Reference< css::reflection::XTypeDescription > >(
+ new ModuleDescription(context_, aName, items));
+ }
+ case 1: // enum type
+ {
+ sal_uInt32 n = file_->read32(off + 1);
+ if (n > SAL_MAX_INT32) {
+ throw css::uno::DeploymentException(
+ ("broken UNOIDL file: too many members of enum type "
+ + aName),
+ css::uno::Reference< css::uno::XInterface >());
+ }
+ off += 5;
+ std::vector< EnumTypeDescription::Member > mems;
+ for (sal_uInt32 i = 0; i != n; ++i) {
+ rtl::OUString memName(file_->readNameLen(off, &off));
+ sal_Int32 memValue = static_cast< sal_Int32 >(
+ file_->read32(off));
+ //TODO: implementation-defined behavior of conversion
+ // from sal_uInt32 to sal_Int32 relies on two's
+ // complement representation
+ off += 4;
+ mems.push_back(
+ EnumTypeDescription::Member(memName, memValue));
+ }
+ return css::uno::makeAny<
+ css::uno::Reference< css::reflection::XTypeDescription > >(
+ new EnumTypeDescription(aName, published, mems));
+ }
+ case 2: // plain struct type without base
+ case 2 | 0x20: // plain struct type with base
+ {
+ ++off;
+ rtl::OUString base;
+ if (flag) {
+ base = file_->readNameLen(off, &off);
+ if (base.isEmpty()) {
+ throw css::uno::DeploymentException(
+ ("broken UNOIDL file: empty base type name of plain"
+ " struct type " + aName),
+ css::uno::Reference< css::uno::XInterface >());
+ }
+ }
+ sal_uInt32 n = file_->read32(off);
+ if (n > SAL_MAX_INT32) {
+ throw css::uno::DeploymentException(
+ ("broken UNOIDL file: too many direct members of plain"
+ " struct type " + aName),
+ css::uno::Reference< css::uno::XInterface >());
+ }
+ off += 4;
+ std::vector< PlainStructTypeDescription::Member > mems;
+ for (sal_uInt32 i = 0; i != n; ++i) {
+ rtl::OUString memName(file_->readNameLen(off, &off));
+ rtl::OUString memType(file_->readNameLen(off, &off));
+ mems.push_back(
+ PlainStructTypeDescription::Member(memName, memType));
+ }
+ return css::uno::makeAny<
+ css::uno::Reference< css::reflection::XTypeDescription > >(
+ new PlainStructTypeDescription(
+ context_, aName, published, base, mems));
+ }
+ case 3: // polymorphic struct type template
+ {
+ sal_uInt32 n = file_->read32(off + 1);
+ if (n > SAL_MAX_INT32) {
+ throw css::uno::DeploymentException(
+ ("broken UNOIDL file: too many type parameters of"
+ " polymorphic struct type template " + aName),
+ css::uno::Reference< css::uno::XInterface >());
+ }
+ off += 5;
+ std::vector< rtl::OUString > params;
+ for (sal_uInt32 i = 0; i != n; ++i) {
+ params.push_back(file_->readNameLen(off, &off));
+ }
+ std::vector< PolymorphicStructTypeTemplateDescription::Member >
+ mems;
+ for (sal_uInt32 i = 0; i != n; ++i) {
+ v = file_->read8(off);
+ ++off;
+ rtl::OUString memName(file_->readNameLen(off, &off));
+ rtl::OUString memType(file_->readNameLen(off, &off));
+ if (v > 1) {
+ throw css::uno::DeploymentException(
+ ("broken UNOIDL file: bad flags "
+ + rtl::OUString::number(v) + " for member "
+ + memName + " of polymorphic struct type template "
+ + aName),
+ css::uno::Reference< css::uno::XInterface >());
+ }
+ mems.push_back(
+ PolymorphicStructTypeTemplateDescription::Member(
+ memName, memType, v == 1));
+ }
+ return css::uno::makeAny<
+ css::uno::Reference< css::reflection::XTypeDescription > >(
+ new PolymorphicStructTypeTemplateDescription(
+ context_, aName, published, params, mems));
+ }
+ case 4: // exception type without base
+ case 4 | 0x20: // exception type with base
+ {
+ ++off;
+ rtl::OUString base;
+ if (flag) {
+ base = file_->readNameLen(off, &off);
+ if (base.isEmpty()) {
+ throw css::uno::DeploymentException(
+ ("broken UNOIDL file: empty base type name of"
+ " exception type " + aName),
+ css::uno::Reference< css::uno::XInterface >());
+ }
+ }
+ sal_uInt32 n = file_->read32(off);
+ if (n > SAL_MAX_INT32) {
+ throw css::uno::DeploymentException(
+ ("broken UNOIDL file: too many direct members of"
+ " exception type " + aName),
+ css::uno::Reference< css::uno::XInterface >());
+ }
+ off += 4;
+ std::vector< ExceptionTypeDescription::Member > mems;
+ for (sal_uInt32 i = 0; i != n; ++i) {
+ rtl::OUString memName(file_->readNameLen(off, &off));
+ rtl::OUString memType(file_->readNameLen(off, &off));
+ mems.push_back(
+ ExceptionTypeDescription::Member(memName, memType));
+ }
+ return css::uno::makeAny<
+ css::uno::Reference< css::reflection::XTypeDescription > >(
+ new ExceptionTypeDescription(
+ context_, aName, published, base, mems));
+ }
+ case 5: // interface type
+ {
+ sal_uInt32 n = file_->read32(off + 1);
+ if (n > SAL_MAX_INT32) {
+ throw css::uno::DeploymentException(
+ ("broken UNOIDL file: too many mandatory direct bases"
+ " of interface type " + aName),
+ css::uno::Reference< css::uno::XInterface >());
+ }
+ off += 5;
+ std::vector< rtl::OUString > mandBases;
+ for (sal_uInt32 i = 0; i != n; ++i) {
+ mandBases.push_back(file_->readNameLen(off, &off));
+ }
+ n = file_->read32(off);
+ if (n > SAL_MAX_INT32) {
+ throw css::uno::DeploymentException(
+ ("broken UNOIDL file: too many optional direct bases of"
+ " interface type " + aName),
+ css::uno::Reference< css::uno::XInterface >());
+ }
+ off += 4;
+ std::vector< rtl::OUString > optBases;
+ for (sal_uInt32 i = 0; i != n; ++i) {
+ optBases.push_back(file_->readNameLen(off, &off));
+ }
+ sal_uInt32 nAttrs = file_->read32(off);
+ if (nAttrs > SAL_MAX_INT32) {
+ throw css::uno::DeploymentException(
+ ("broken UNOIDL file: too many direct attributes of"
+ " interface type " + aName),
+ css::uno::Reference< css::uno::XInterface >());
+ }
+ off += 4;
+ std::vector< Attribute > attrs;
+ for (sal_uInt32 i = 0; i != nAttrs; ++i) {
+ v = file_->read8(off);
+ ++off;
+ rtl::OUString attrName(file_->readNameLen(off, &off));
+ rtl::OUString attrType(file_->readNameLen(off, &off));
+ if (v > 0x03) {
+ throw css::uno::DeploymentException(
+ ("broken UNOIDL file: bad flags for direct"
+ " attribute " + attrName + " of interface type "
+ + aName),
+ css::uno::Reference< css::uno::XInterface >());
+ }
+ std::vector< rtl::OUString > getExcs;
+ sal_uInt32 m = file_->read32(off);
+ if (m > SAL_MAX_INT32) {
+ throw css::uno::DeploymentException(
+ ("broken UNOIDL file: too many getter exceptions"
+ " for direct attribute " + attrName
+ + " of interface type " + aName),
+ css::uno::Reference< css::uno::XInterface >());
+ }
+ off += 4;
+ for (sal_uInt32 j = 0; j != m; ++j) {
+ getExcs.push_back(file_->readNameLen(off, &off));
+ }
+ std::vector< rtl::OUString > setExcs;
+ if ((v & 0x02) != 0) {
+ m = file_->read32(off);
+ if (m > SAL_MAX_INT32) {
+ throw css::uno::DeploymentException(
+ ("broken UNOIDL file: too many setter"
+ " exceptions for direct attribute " + attrName
+ + " of interface type " + aName),
+ css::uno::Reference< css::uno::XInterface >());
+ }
+ off += 4;
+ for (sal_uInt32 j = 0; j != m; ++j) {
+ setExcs.push_back(file_->readNameLen(off, &off));
+ }
+ }
+ attrs.push_back(
+ Attribute(
+ attrName, attrType, (v & 0x01) != 0,
+ (v & 0x02) != 0, getExcs, setExcs));
+ }
+ sal_uInt32 nMeths = file_->read32(off);
+ if (nMeths > SAL_MAX_INT32 - nAttrs) {
+ throw css::uno::DeploymentException(
+ ("broken UNOIDL file: too many direct attributes and"
+ " methods of interface type " + aName),
+ css::uno::Reference< css::uno::XInterface >());
+ }
+ off += 4;
+ std::vector< Method > meths;
+ for (sal_uInt32 i = 0; i != nMeths; ++i) {
+ rtl::OUString methName(file_->readNameLen(off, &off));
+ rtl::OUString methType(file_->readNameLen(off, &off));
+ sal_uInt32 m = file_->read32(off);
+ if (m > SAL_MAX_INT32) {
+ throw css::uno::DeploymentException(
+ ("broken UNOIDL file: too many parameters for"
+ " method " + methName + " of interface type "
+ + aName),
+ css::uno::Reference< css::uno::XInterface >());
+ }
+ off += 4;
+ std::vector< Method::Parameter > params;
+ for (sal_uInt32 j = 0; j != m; ++j) {
+ v = file_->read8(off);
+ ++off;
+ rtl::OUString paramName(file_->readNameLen(off, &off));
+ rtl::OUString paramType(file_->readNameLen(off, &off));
+ Method::Parameter::Direction dir;
+ switch (v) {
+ case 0:
+ dir = Method::Parameter::DIRECTION_IN;
+ break;
+ case 1:
+ dir = Method::Parameter::DIRECTION_OUT;
+ break;
+ case 2:
+ dir = Method::Parameter::DIRECTION_IN_OUT;
+ break;
+ default:
+ throw css::uno::DeploymentException(
+ ("broken UNOIDL file: bad direction "
+ + rtl::OUString::number(v) + " of parameter "
+ + paramName + " for method " + methName
+ + " of interface type " + aName),
+ css::uno::Reference< css::uno::XInterface >());
+ }
+ params.push_back(
+ Method::Parameter(paramName, paramType, dir));
+ }
+ std::vector< rtl::OUString > excs;
+ m = file_->read32(off);
+ if (m > SAL_MAX_INT32) {
+ throw css::uno::DeploymentException(
+ ("broken UNOIDL file: too many exceptions for"
+ " method " + methName + " of interface type "
+ + aName),
+ css::uno::Reference< css::uno::XInterface >());
+ }
+ off += 4;
+ for (sal_uInt32 j = 0; j != m; ++j) {
+ excs.push_back(file_->readNameLen(off, &off));
+ }
+ meths.push_back(Method(methName, methType, params, excs));
+ }
+ return css::uno::makeAny<
+ css::uno::Reference< css::reflection::XTypeDescription > >(
+ new InterfaceTypeDescription(
+ context_, aName, published, mandBases, optBases,
+ attrs, meths));
+ }
+ case 6: // typedef
+ return css::uno::makeAny<
+ css::uno::Reference< css::reflection::XTypeDescription > >(
+ new TypedefDescription(
+ context_, aName, published,
+ file_->readNameLen(off + 1)));
+ case 7: // constant group
+ {
+ sal_uInt32 n = file_->read32(off + 1);
+ if (n > SAL_MAX_INT32) {
+ throw css::uno::DeploymentException(
+ ("broken UNOIDL file: too many constants in constant"
+ " group " + aName),
+ css::uno::Reference< css::uno::XInterface >());
+ }
+ off += 5;
+ std::vector< rtl::OUString > consts;
+ for (sal_uInt32 i = 0; i != n; ++i) {
+ consts.push_back(file_->readNameNul(file_->read32(off)));
+ off += 8;
+ }
+ return css::uno::makeAny<
+ css::uno::Reference< css::reflection::XTypeDescription > >(
+ new ConstantGroupDescription(
+ context_, aName, published, consts));
+ }
+ case 8: // single-interface--based service without default constructor
+ case 8 | 0x20:
+ // single-interface--based service with default constructor
+ {
+ rtl::OUString base(file_->readNameLen(off + 1, &off));
+ std::vector< Constructor > ctors;
+ if (flag) {
+ ctors.push_back(Constructor());
+ } else {
+ sal_uInt32 n = file_->read32(off);
+ if (n > SAL_MAX_INT32) {
+ throw css::uno::DeploymentException(
+ ("broken UNOIDL file: too many constructors of"
+ " single-interface--based service " + aName),
+ css::uno::Reference< css::uno::XInterface >());
+ }
+ off += 4;
+ for (sal_uInt32 i = 0; i != n; ++i) {
+ rtl::OUString ctorName(file_->readNameLen(off, &off));
+ sal_uInt32 m = file_->read32(off);
+ if (m > SAL_MAX_INT32) {
+ throw css::uno::DeploymentException(
+ ("broken UNOIDL file: too many parameters for"
+ " constructor " + ctorName
+ + " of single-interface--based service "
+ + aName),
+ css::uno::Reference< css::uno::XInterface >());
+ }
+ off += 4;
+ std::vector< Constructor::Parameter > params;
+ for (sal_uInt32 j = 0; j != m; ++j) {
+ v = file_->read8(off);
+ ++off;
+ rtl::OUString paramName(
+ file_->readNameLen(off, &off));
+ rtl::OUString paramType(
+ file_->readNameLen(off, &off));
+ bool rest;
+ switch (v) {
+ case 0:
+ rest = false;
+ break;
+ case 0x04:
+ rest = true;
+ break;
+ default:
+ throw css::uno::DeploymentException(
+ ("broken UNOIDL file: bad mode "
+ + rtl::OUString::number(v)
+ + " of parameter " + paramName
+ + " for constructor " + ctorName
+ + " of single-interface--based service "
+ + aName),
+ css::uno::Reference<
+ css::uno::XInterface >());
+ }
+ params.push_back(
+ Constructor::Parameter(
+ paramName, paramType, rest));
+ }
+ std::vector< rtl::OUString > excs;
+ m = file_->read32(off);
+ if (m > SAL_MAX_INT32) {
+ throw css::uno::DeploymentException(
+ ("broken UNOIDL file: too many exceptions for"
+ " constructor " + ctorName
+ + " of single-interface--based service "
+ + aName),
+ css::uno::Reference< css::uno::XInterface >());
+ }
+ off += 4;
+ for (sal_uInt32 j = 0; j != m; ++j) {
+ excs.push_back(file_->readNameLen(off, &off));
+ }
+ ctors.push_back(Constructor(ctorName, params, excs));
+ }
+ }
+ return css::uno::makeAny<
+ css::uno::Reference< css::reflection::XTypeDescription > >(
+ new SingleInterfaceBasedServiceDescription(
+ context_, aName, published, base, ctors));
+ }
+ case 9: // accumulation-based service
+ {
+ sal_uInt32 n = file_->read32(off + 1);
+ if (n > SAL_MAX_INT32) {
+ throw css::uno::DeploymentException(
+ ("broken UNOIDL file: too many mandatory direct service"
+ " bases of accumulation-based service " + aName),
+ css::uno::Reference< css::uno::XInterface >());
+ }
+ off += 5;
+ std::vector< rtl::OUString > mandServs;
+ for (sal_uInt32 i = 0; i != n; ++i) {
+ mandServs.push_back(file_->readNameLen(off, &off));
+ }
+ n = file_->read32(off);
+ if (n > SAL_MAX_INT32) {
+ throw css::uno::DeploymentException(
+ ("broken UNOIDL file: too many optional direct service"
+ " bases of accumulation-based servcie " + aName),
+ css::uno::Reference< css::uno::XInterface >());
+ }
+ off += 4;
+ std::vector< rtl::OUString > optServs;
+ for (sal_uInt32 i = 0; i != n; ++i) {
+ optServs.push_back(file_->readNameLen(off, &off));
+ }
+ n = file_->read32(off);
+ if (n > SAL_MAX_INT32) {
+ throw css::uno::DeploymentException(
+ ("broken UNOIDL file: too many mandatory direct"
+ " interface bases of accumulation-based servcie "
+ + aName),
+ css::uno::Reference< css::uno::XInterface >());
+ }
+ off += 4;
+ std::vector< rtl::OUString > mandIfcs;
+ for (sal_uInt32 i = 0; i != n; ++i) {
+ mandIfcs.push_back(file_->readNameLen(off, &off));
+ }
+ n = file_->read32(off);
+ if (n > SAL_MAX_INT32) {
+ throw css::uno::DeploymentException(
+ ("broken UNOIDL file: too many optional direct"
+ " interface bases of accumulation-based servcie "
+ + aName),
+ css::uno::Reference< css::uno::XInterface >());
+ }
+ off += 4;
+ std::vector< rtl::OUString > optIfcs;
+ for (sal_uInt32 i = 0; i != n; ++i) {
+ optIfcs.push_back(file_->readNameLen(off, &off));
+ }
+ n = file_->read32(off);
+ if (n > SAL_MAX_INT32) {
+ throw css::uno::DeploymentException(
+ ("broken UNOIDL file: too many direct properties of"
+ " accumulation-based servcie " + aName),
+ css::uno::Reference< css::uno::XInterface >());
+ }
+ off += 4;
+ std::vector< Property > props;
+ for (sal_uInt32 i = 0; i != n; ++i) {
+ sal_uInt16 attrs = file_->read16(off);
+ off += 2;
+ rtl::OUString propName(file_->readNameLen(off, &off));
+ rtl::OUString propType(file_->readNameLen(off, &off));
+ if (attrs > 0x01FF) { // see css.beans.PropertyAttribute
+ throw css::uno::DeploymentException(
+ ("broken UNOIDL file: bad mode "
+ + rtl::OUString::number(v) + " of property "
+ + propName + " for accumulation-based servcie "
+ + aName),
+ css::uno::Reference< css::uno::XInterface >());
+ }
+ props.push_back(
+ Property(
+ propName, propType,
+ static_cast< sal_Int32 >(attrs)));
+ }
+ return css::uno::makeAny<
+ css::uno::Reference< css::reflection::XTypeDescription > >(
+ new AccumulationBasedServiceDescription(
+ context_, aName, published, mandServs, optServs,
+ mandIfcs, optIfcs, props));
+ }
+ case 10: // interface-based singleton
+ return css::uno::makeAny<
+ css::uno::Reference< css::reflection::XTypeDescription > >(
+ new InterfaceBasedSingletonDescription(
+ context_, aName, published,
+ file_->readNameLen(off + 1)));
+ case 11: // service-based singleton
+ return css::uno::makeAny<
+ css::uno::Reference< css::reflection::XTypeDescription > >(
+ new ServiceBasedSingletonDescription(
+ context_, aName, published,
+ file_->readNameLen(off + 1)));
+ default:
+ throw css::uno::DeploymentException(
+ "broken UNOIDL file: bad type byte " + rtl::OUString::number(v),
+ css::uno::Reference< css::uno::XInterface >());
+ }
+ }
+}
+
+css::uno::Reference< css::reflection::XTypeDescriptionEnumeration >
+Provider::createTypeDescriptionEnumeration(
+ rtl::OUString const & moduleName,
+ css::uno::Sequence< css::uno::TypeClass > const & types,
+ css::reflection::TypeDescriptionSearchDepth depth)
+ throw(
+ css::reflection::NoSuchTypeNameException,
+ css::reflection::InvalidTypeNameException, css::uno::RuntimeException)
+{
+ rtl::OUString prefix;
+ MapEntry const * mapBegin;
+ sal_uInt32 mapSize;
+ if (moduleName.isEmpty()) {
+ mapBegin = mapBegin_;
+ mapSize = mapSize_;
+ } else {
+ prefix = moduleName + ".";
+ bool cnst;
+ sal_uInt32 off = find(moduleName, &cnst);
+ if (off == 0) {
+ throw css::reflection::NoSuchTypeNameException(
+ moduleName, static_cast< cppu::OWeakObject * >(this));
+ }
+ if (cnst || file_->read8(off) != 0) { // module
+ throw css::reflection::InvalidTypeNameException(
+ moduleName, static_cast< cppu::OWeakObject * >(this));
+ }
+ mapSize = file_->read32(off + 1);
+ if (8 * mapSize > file_->size - off - 5) { //TODO: overflow
+ throw css::uno::DeploymentException(
+ "broken UNOIDL file: map offset + size too large",
+ css::uno::Reference< css::uno::XInterface >());
+ }
+ mapBegin = reinterpret_cast< MapEntry const * >(
+ static_cast< char const * >(file_->address) + off + 5);
+ }
+ return new Enumeration(
+ context_, file_, prefix, mapBegin, mapSize, types,
+ depth == css::reflection::TypeDescriptionSearchDepth_INFINITE);
+}
+
+sal_uInt32 Provider::find(rtl::OUString const & name, bool * constant) const {
+ MapEntry const * mapBegin = mapBegin_;
+ sal_uInt32 mapSize = mapSize_;
+ bool cgroup = false;
+ for (sal_Int32 i = 0;;) {
+ sal_Int32 j = name.indexOf('.', i);
+ if (j == -1) {
+ j = name.getLength();
+ }
+ sal_Int32 off = findInMap(name, i, j - i, mapBegin, mapSize);
+ if (off == 0) {
+ return 0;
+ }
+ if (j == name.getLength()) {
+ if (constant != 0) {
+ *constant = cgroup;
+ }
+ return off;
+ }
+ if (cgroup) {
+ return 0;
+ //TODO: throw an exception instead here, where the segments of a
+ // constant's name are a prefix of the requested name's
+ // segments?
+ }
+ int v = file_->read8(off);
+ if (v != 0) { // module
+ if ((v & 0x3F) == 7) { // constant group
+ cgroup = true;
+ } else {
+ return 0;
+ //TODO: throw an exception instead here, where the segments
+ // of a non-module, non-constant-group entity's name are a
+ // prefix of the requested name's segments?
+ }
+ }
+ mapSize = file_->read32(off + 1);
+ if (8 * mapSize > file_->size - off - 5) { //TODO: overflow
+ throw css::uno::DeploymentException(
+ "broken UNOIDL file: map offset + size too large",
+ css::uno::Reference< css::uno::XInterface >());
+ }
+ mapBegin = reinterpret_cast< MapEntry const * >(
+ static_cast< char const * >(file_->address) + off + 5);
+ i = j + 1;
+ }
+}
+
+sal_uInt32 Provider::findInMap(
+ rtl::OUString const & name, sal_Int32 nameOffset, sal_Int32 nameLength,
+ MapEntry const * mapBegin, sal_uInt32 mapSize) const
+{
+ if (mapSize == 0) {
+ return 0;
+ }
+ sal_uInt32 n = mapSize / 2;
+ MapEntry const * p = mapBegin + n;
+ switch (compare(name, nameOffset, nameLength, p)) {
+ case COMPARE_LESS:
+ return findInMap(name, nameOffset, nameLength, mapBegin, n);
+ case COMPARE_GREATER:
+ return findInMap(name, nameOffset, nameLength, p + 1, mapSize - n - 1);
+ default: // COMPARE_EQUAL
+ break;
+ }
+ sal_uInt32 off = mapBegin[n].data.get();
+ if (off == 0) {
+ throw css::uno::DeploymentException(
+ "broken UNOIDL file: map entry data offset is null",
+ css::uno::Reference< css::uno::XInterface >());
+ }
+ return off;
+}
+
+Provider::Compare Provider::compare(
+ rtl::OUString const & name, sal_Int32 nameOffset, sal_Int32 nameLength,
+ MapEntry const * entry) const
+{
+ assert(entry != 0);
+ sal_uInt32 off = entry->name.get();
+ if (off > file_->size - 1) { // at least a trailing NUL
+ throw css::uno::DeploymentException(
+ "broken UNOIDL file: string offset too large",
+ css::uno::Reference< css::uno::XInterface >());
+ }
+ assert(nameLength >= 0);
+ sal_uInt64 min = std::min(
+ static_cast< sal_uInt64 >(nameLength), file_->size - off);
+ for (sal_uInt64 i = 0; i != min; ++i) {
+ sal_Unicode c1 = name[nameOffset + i];
+ sal_Unicode c2 = static_cast< unsigned char const * >(file_->address)[
+ off + i];
+ if (c1 < c2) {
+ return COMPARE_LESS;
+ } else if (c1 > c2 || c2 == 0) {
+ // ...the "|| c2 == 0" is for the odd case where name erroneously
+ // contains NUL characters
+ return COMPARE_GREATER;
+ }
+ }
+ if (static_cast< sal_uInt64 >(nameLength) == min) {
+ if (file_->size - off == min) {
+ throw css::uno::DeploymentException(
+ "broken UNOIDL file: string misses trailing NUL",
+ css::uno::Reference< css::uno::XInterface >());
+ }
+ return
+ static_cast< unsigned char const * >(file_->address)[off + min] == 0
+ ? COMPARE_EQUAL : COMPARE_LESS;
+ } else {
+ return COMPARE_GREATER;
+ }
+}
+
+css::uno::Reference< css::container::XHierarchicalNameAccess >
+readLegacyRdbFile(
+ rtl::OUString const & uri,
css::uno::Reference< css::lang::XMultiComponentFactory > const &
serviceManager,
- css::uno::Reference< css::uno::XComponentContext > const & context,
- std::vector<
- css::uno::Reference< css::container::XHierarchicalNameAccess > > *
- providers)
+ css::uno::Reference< css::uno::XComponentContext > const & context)
{
assert(serviceManager.is());
- assert(providers != 0);
css::uno::Reference< css::registry::XSimpleRegistry > reg(
serviceManager->createInstanceWithContext(
"com.sun.star.comp.stoc.SimpleRegistry", context),
@@ -48,25 +3051,48 @@ void readTypeRdbFile(
try {
reg->open(uri, true, false);
} catch (css::registry::InvalidRegistryException & e) {
+ throw css::uno::DeploymentException(
+ "Invalid registry " + uri + ":" + e.Message,
+ css::uno::Reference< css::uno::XInterface >());
+ }
+ css::uno::Sequence< css::uno::Any > arg(1);
+ arg[0] <<= reg;
+ return css::uno::Reference< css::container::XHierarchicalNameAccess >(
+ serviceManager->createInstanceWithArgumentsAndContext(
+ "com.sun.star.comp.stoc.RegistryTypeDescriptionProvider", arg,
+ context),
+ css::uno::UNO_QUERY_THROW);
+}
+
+void readRdbFile(
+ rtl::OUString const & uri, bool optional,
+ css::uno::Reference< css::lang::XMultiComponentFactory > const &
+ serviceManager,
+ css::uno::Reference< css::uno::XComponentContext > const & context,
+ std::vector<
+ css::uno::Reference< css::container::XHierarchicalNameAccess > > *
+ providers)
+{
+ assert(providers != 0);
+ css::uno::Reference< css::container::XHierarchicalNameAccess > prov;
+ try {
+ prov = new Provider(context, uri);
+ } catch (css::container::NoSuchElementException &) {
if (optional) {
SAL_INFO("cppuhelper", "Ignored optional " << uri);
return;
}
throw css::uno::DeploymentException(
- "Invalid registry " + uri + ":" + e.Message,
+ uri + ": no such file",
css::uno::Reference< css::uno::XInterface >());
+ } catch (css::registry::InvalidRegistryException &) {
+ prov = readLegacyRdbFile(uri, serviceManager, context);
}
- css::uno::Sequence< css::uno::Any > arg(1);
- arg[0] <<= reg;
- providers->push_back(
- css::uno::Reference< css::container::XHierarchicalNameAccess >(
- serviceManager->createInstanceWithArgumentsAndContext(
- "com.sun.star.comp.stoc.RegistryTypeDescriptionProvider", arg,
- context),
- css::uno::UNO_QUERY_THROW));
+ assert(prov.is());
+ providers->push_back(prov);
}
-void readTypeRdbDirectory(
+void readRdbDirectory(
rtl::OUString const & uri, bool optional,
css::uno::Reference< css::lang::XMultiComponentFactory > const &
serviceManager,
@@ -95,7 +3121,7 @@ void readTypeRdbDirectory(
if (!cppu::nextDirectoryItem(dir, &fileUri)) {
break;
}
- readTypeRdbFile(fileUri, optional, serviceManager, context, providers);
+ readRdbFile(fileUri, optional, serviceManager, context, providers);
}
}
@@ -120,10 +3146,9 @@ cppuhelper::createTypeDescriptionProviders(
bool directory;
cppu::decodeRdbUri(&uri, &optional, &directory);
if (directory) {
- readTypeRdbDirectory(
- uri, optional, serviceManager, context, &provs);
+ readRdbDirectory(uri, optional, serviceManager, context, &provs);
} else {
- readTypeRdbFile(uri, optional, serviceManager, context, &provs);
+ readRdbFile(uri, optional, serviceManager, context, &provs);
}
}
css::uno::Sequence<