diff options
-rw-r--r-- | Repository.mk | 2 | ||||
-rw-r--r-- | registry/Module_registry.mk | 1 | ||||
-rw-r--r-- | registry/tools/reg2bin.cxx | 1464 | ||||
-rw-r--r-- | unoidl/Executable_reg2unoidl.mk (renamed from registry/Executable_reg2bin.mk) | 11 | ||||
-rw-r--r-- | unoidl/Library_unoidl.mk | 2 | ||||
-rw-r--r-- | unoidl/Module_unoidl.mk | 1 | ||||
-rw-r--r-- | unoidl/Package_inc.mk | 1 | ||||
-rw-r--r-- | unoidl/inc/unoidl/legacyprovider.hxx | 49 | ||||
-rw-r--r-- | unoidl/inc/unoidl/unoidl.hxx | 21 | ||||
-rw-r--r-- | unoidl/inc/unoidl/unoidlprovider.hxx | 4 | ||||
-rw-r--r-- | unoidl/prj/build.lst | 2 | ||||
-rw-r--r-- | unoidl/source/legacyprovider.cxx | 778 | ||||
-rw-r--r-- | unoidl/source/reg2unoidl.cxx | 786 | ||||
-rw-r--r-- | unoidl/source/unoidl.cxx | 36 | ||||
-rw-r--r-- | unoidl/source/unoidlprovider.cxx | 7 |
15 files changed, 1690 insertions, 1475 deletions
diff --git a/Repository.mk b/Repository.mk index 9c58278753dd..be52c7973322 100644 --- a/Repository.mk +++ b/Repository.mk @@ -52,7 +52,7 @@ $(eval $(call gb_Helper_register_executables,NONE, \ pdf2xml \ pdfunzip \ propex \ - reg2bin \ + reg2unoidl \ regsvrex \ rsc \ rscdep \ diff --git a/registry/Module_registry.mk b/registry/Module_registry.mk index fce6fa434594..a488bd8b14e4 100644 --- a/registry/Module_registry.mk +++ b/registry/Module_registry.mk @@ -35,7 +35,6 @@ ifneq (,$(filter DESKTOP,$(BUILD_TYPE))) $(eval $(call gb_Module_add_targets,registry,\ StaticLibrary_registry_helper \ - Executable_reg2bin \ Executable_regmerge \ Executable_regview \ Executable_regcompare \ diff --git a/registry/tools/reg2bin.cxx b/registry/tools/reg2bin.cxx deleted file mode 100644 index 18976a0f1a58..000000000000 --- a/registry/tools/reg2bin.cxx +++ /dev/null @@ -1,1464 +0,0 @@ -/* -*- Mode: C++; tab-width: 4; indent-tabs-mode: nil; c-basic-offset: 4 -*- */ -/* - * This file is part of the LibreOffice project. - * - * This Source Code Form is subject to the terms of the Mozilla Public - * License, v. 2.0. If a copy of the MPL was not distributed with this - * file, You can obtain one at http://mozilla.org/MPL/2.0/. - */ - -#include "sal/config.h" - -#include <algorithm> -#include <cassert> -#include <cstdlib> -#include <cstring> -#include <iostream> -#include <map> -#include <utility> -#include <vector> - -#include "osl/endian.h" -#include "osl/file.h" -#include "osl/file.hxx" -#include "osl/process.h" -#include "registry/reader.hxx" -#include "registry/refltype.hxx" -#include "registry/registry.hxx" -#include "registry/regtype.h" -#include "registry/types.h" -#include "registry/version.h" -#include "rtl/process.h" -#include "rtl/string.hxx" -#include "rtl/textenc.h" -#include "rtl/textcvt.h" -#include "rtl/ustring.hxx" -#include "sal/macros.h" -#include "sal/main.h" - -namespace { - -rtl::OUString getArgumentUrl(sal_uInt32 argument) { - rtl::OUString arg; - rtl_getAppCommandArg(argument, &arg.pData); - rtl::OUString url; - osl::FileBase::RC e1 = osl::FileBase::getFileURLFromSystemPath(arg, url); - if (e1 != osl::FileBase::E_None) { - std::cerr - << "Cannot convert \"" << arg << "\" to file URL, error code " - << +e1 << "\n"; - std::exit(EXIT_FAILURE); - } - rtl::OUString cwd; - oslProcessError e2 = osl_getProcessWorkingDir(&cwd.pData); - if (e2 != osl_Process_E_None) { - std::cerr - << "Cannot obtain working directory, error code " << +e2 << "\n"; - std::exit(EXIT_FAILURE); - } - rtl::OUString abs; - e1 = osl::FileBase::getAbsoluteFileURL(cwd, url, abs); - if (e1 != osl::FileBase::E_None) { - std::cerr - << "Cannot make \"" << url - << "\" into an absolute file URL, error code " << +e1 << "\n"; - std::exit(EXIT_FAILURE); - } - return abs; -} - -enum Type { - TYPE_MODULE, - TYPE_ENUM, - TYPE_STRUCT, - TYPE_POLYSTRUCT, - TYPE_EXCEPTION, - TYPE_INTERFACE, - TYPE_TYPEDEF, - TYPE_CONSTANTS, - TYPE_NEWSERVICE, - TYPE_OLDSERVICE, - TYPE_NEWSINGLETON, - TYPE_OLDSINGLETON -}; - -struct Field { - Field(rtl::OUString const & theName, sal_Int32 theValue): - name(theName), value(theValue) {} - - Field(rtl::OUString const & theName, rtl::OUString const & theType): - name(theName), type(theType) {} - - Field( - rtl::OUString const & theName, rtl::OUString const & theType, - bool parameterized): - name(theName), type(theType), bound(parameterized) {} - - Field( - rtl::OUString const & theName, rtl::OUString const & theType, - bool theBound, bool theReadOnly, - std::vector< rtl::OUString > theGetExceptions, - std::vector< rtl::OUString > theSetExceptions): - name(theName), type(theType), bound(theBound), readOnly(theReadOnly), - getExceptions(theGetExceptions), setExceptions(theSetExceptions) {} - - Field( - rtl::OUString const & theName, rtl::OUString const & theType, - sal_Int32 flags): - name(theName), type(theType), value(flags) {} - - rtl::OUString name; - rtl::OUString type; - sal_Int32 value; - bool bound; // aka polymorphic struct type template of parameterized type - bool readOnly; - std::vector< rtl::OUString > getExceptions; - std::vector< rtl::OUString > setExceptions; -}; - -struct Parameter { - Parameter( - rtl::OUString const & theName, rtl::OUString const & theType, - RTParamMode theMode): - name(theName), type(theType), mode(theMode) {} - - rtl::OUString name; - rtl::OUString type; - RTParamMode mode; -}; - -struct Method { - 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) {} - - Method( - rtl::OUString const & theName, - std::vector< Parameter > const & theParameters, - std::vector< rtl::OUString > const & theExceptions): - name(theName), parameters(theParameters), exceptions(theExceptions) {} - - rtl::OUString name; - rtl::OUString returnType; - std::vector< Parameter > parameters; - std::vector< rtl::OUString > exceptions; -}; - -enum ConstantType { - CONSTANT_TYPE_BOOLEAN, - CONSTANT_TYPE_BYTE, - CONSTANT_TYPE_SHORT, - CONSTANT_TYPE_UNSIGNED_SHORT, - CONSTANT_TYPE_LONG, - CONSTANT_TYPE_UNSIGNED_LONG, - CONSTANT_TYPE_HYPER, - CONSTANT_TYPE_UNSIGNED_HYPER, - CONSTANT_TYPE_FLOAT, - CONSTANT_TYPE_DOUBLE -}; - -struct Item { - Type type; - std::map< rtl::OUString, Item > elements; - bool published; - bool deprecated; - std::vector< rtl::OUString > supertypes; - std::vector< rtl::OUString > optionalSupertypes; - std::vector< Field > fields; - std::vector< Method > methods; - std::vector< rtl::OUString > references; - std::vector< rtl::OUString > optionalReferences; - ConstantType constantType; - union { - bool bo; - sal_Int8 by; - sal_Int16 s; - sal_uInt16 us; - sal_Int32 l; - sal_uInt32 ul; - sal_Int64 h; - sal_uInt64 uh; - float f; - double d; - } constantValue; - bool defaultConstructor; - sal_uInt64 nameOffset; - sal_uInt64 dataOffset; -}; - -void insert( - rtl::OUString const & name, Item const & item, - std::map< rtl::OUString, Item > * map) -{ - assert(map != 0); - if(!map->insert(std::make_pair(name, item)).second) - { - assert(false); - } -} - -typereg::Reader getReader(RegistryKey & key, std::vector< char > * buffer) { - assert(buffer != 0); - RegValueType type; - sal_uInt32 size; - RegError e = key.getValueInfo("", &type, &size); - if (e != REG_NO_ERROR) { - std::cerr - << "Cannot get value info about key \"" << key.getName() - << "\" in registry \"" << key.getRegistryName() << "\", error code " - << +e << "\n"; - std::exit(EXIT_FAILURE); - } - if (type != RG_VALUETYPE_BINARY) { - std::cerr - << "Unexpected value type " << +type << " of key \"" - << key.getName() << "\" in registry \"" << key.getRegistryName() - << "\"\n"; - std::exit(EXIT_FAILURE); - } - if (size == 0 - /* || size > std::numeric_limits< std::vector< char >::size_type >::max() */) - { - std::cerr - << "Bad binary value size " << size << " of key \"" << key.getName() - << "\" in registry \"" << key.getRegistryName() << "\"\n"; - std::exit(EXIT_FAILURE); - } - buffer->resize(static_cast< std::vector< char >::size_type >(size)); - e = key.getValue("", &(*buffer)[0]); - if (e != REG_NO_ERROR) { - std::cerr - << "Cannot get binary value of key \"" << key.getName() - << "\" in registry \"" << key.getRegistryName() << "\", error code " - << +e << "\n"; - std::exit(EXIT_FAILURE); - } - typereg::Reader reader(&(*buffer)[0], size, false, TYPEREG_VERSION_1); - if (!reader.isValid()) { - std::cerr - << "Malformed binary value of key \"" << key.getName() - << "\" in registry \"" << key.getRegistryName() << "\"\n"; - std::exit(EXIT_FAILURE); - } - return reader; -} - -void setDeprecated(rtl::OUString const & documentation, Item * item) { - assert(item != 0); - item->deprecated = documentation.indexOf("@deprecated") != -1; - //TODO: this check is somewhat crude -} - -void setFlags(typereg::Reader const & reader, Item * item) { - assert(item != 0); - item->published = reader.isPublished(); - setDeprecated(reader.getDocumentation(), item); -} - -void readModule( - std::vector< RegistryKey > & roots, RegistryKey & key, - std::map< rtl::OUString, Item > * map) -{ - RegistryKeyNames names; - RegError e = key.getKeyNames("", names); - if (e != REG_NO_ERROR) { - std::cerr - << "Cannot get sub-key names of \"" << key.getName() - << "\" in registry \"" << roots[0].getRegistryName() - << "\", error code " << +e << "\n"; - std::exit(EXIT_FAILURE); - } - for (sal_uInt32 i = 0; i != names.getLength(); ++i) { - RegistryKey sub; - e = roots[0].openKey(names.getElement(i), sub); - if (e != REG_NO_ERROR) { - std::cerr - << "Cannot get key \"" << names.getElement(i) - << "\" in registry \"" << roots[0].getRegistryName() - << "\", error code " << +e << "\n"; - std::exit(EXIT_FAILURE); - } - std::vector< char > buf; - typereg::Reader reader(getReader(sub, &buf)); - assert(sub.getName().match(key.getName() + "/")); - rtl::OUString name( - sub.getName().copy(key.getName().getLength() + std::strlen("/"))); - switch (reader.getTypeClass()) { - case RT_TYPE_INTERFACE: - { - Item item; - item.type = TYPE_INTERFACE; - setFlags(reader, &item); - sal_uInt16 n = reader.getSuperTypeCount(); - for (sal_uInt16 j = 0; j != n; ++j) { - item.supertypes.push_back( - reader.getSuperTypeName(j).replace('/', '.')); - } - n = reader.getReferenceCount(); // optional base types - for (sal_uInt16 j = 0; j != n; ++j) { - item.optionalSupertypes.push_back( - reader.getReferenceTypeName(j).replace('/', '.')); - } - sal_uInt16 methodCount = reader.getMethodCount(); - n = reader.getFieldCount(); // attributes - for (sal_uInt16 j = 0; j != n; ++j) { - rtl::OUString attrName(reader.getFieldName(j)); - std::vector< rtl::OUString > getExcs; - std::vector< rtl::OUString > setExcs; - for (sal_uInt16 k = 0; k != methodCount; ++k) { - if (reader.getMethodName(k) == attrName) { - switch (reader.getMethodFlags(k)) { - case RT_MODE_ATTRIBUTE_GET: - { - sal_uInt16 m - = reader.getMethodExceptionCount(k); - for (sal_uInt16 l = 0; l != m; ++l) { - getExcs.push_back( - reader. - getMethodExceptionTypeName(k, l). - replace('/', '.')); - } - break; - } - case RT_MODE_ATTRIBUTE_SET: - { - sal_uInt16 m - = reader.getMethodExceptionCount(k); - for (sal_uInt16 l = 0; l != m; ++l) { - setExcs.push_back( - reader. - getMethodExceptionTypeName(k, l). - replace('/', '.')); - } - break; - } - default: - std::cerr - << "Method and attribute with same name \"" - << attrName - << "\" in interface type with key \"" - << sub.getName() << "\" in registry \"" - << roots[0].getRegistryName() << "\"\n"; - std::exit(EXIT_FAILURE); - } - } - } - RTFieldAccess flags = reader.getFieldFlags(j); - item.fields.push_back( - Field( - attrName, - reader.getFieldTypeName(j).replace('/', '.'), - (flags & RT_ACCESS_BOUND) != 0, - (flags & RT_ACCESS_READONLY) != 0, getExcs, - setExcs)); - } - for (sal_uInt16 j = 0; j != methodCount; ++j) { - RTMethodMode flags = reader.getMethodFlags(j); - if (flags != RT_MODE_ATTRIBUTE_GET - && flags != RT_MODE_ATTRIBUTE_SET) - { - std::vector< Parameter > params; - sal_uInt16 m = reader.getMethodParameterCount(j); - for (sal_uInt16 k = 0; k != m; ++k) { - RTParamMode mode = reader.getMethodParameterFlags( - j, k); - switch (mode) { - case RT_PARAM_IN: - case RT_PARAM_OUT: - case RT_PARAM_INOUT: - break; - default: - std::cerr - << "Unexpected mode " << +mode - << " of parameter \"" - << reader.getMethodParameterName(j, k) - << "\" of method \"" - << reader.getMethodName(j) - << "\" in interface type with key \"" - << sub.getName() << "\" in registry \"" - << roots[0].getRegistryName() << "\"\n"; - std::exit(EXIT_FAILURE); - } - params.push_back( - Parameter( - reader.getMethodParameterName(j, k), - (reader.getMethodParameterTypeName(j, k). - replace('/', '.')), - mode)); - } - std::vector< rtl::OUString > excs; - m = reader.getMethodExceptionCount(j); - for (sal_uInt16 k = 0; k != m; ++k) { - excs.push_back( - reader.getMethodExceptionTypeName(j, k).replace( - '/', '.')); - } - item.methods.push_back( - Method( - reader.getMethodName(j), - reader.getMethodReturnTypeName(j).replace( - '/', '.'), - params, excs)); - } - } - insert(name, item, map); - break; - } - case RT_TYPE_MODULE: - { - Item item; - item.type = TYPE_MODULE; - readModule(roots, sub, &item.elements); - insert(name, item, map); - break; - } - case RT_TYPE_STRUCT: - { - Item item; - sal_uInt32 n = reader.getReferenceCount(); - if (n == 0) { - item.type = TYPE_STRUCT; - setFlags(reader, &item); - switch (reader.getSuperTypeCount()) { - case 0: - break; - case 1: - item.supertypes.push_back( - reader.getSuperTypeName(0).replace('/', '.')); - break; - default: - std::cerr - << "Unexpected number " - << reader.getSuperTypeCount() - << (" of super-types of plain struct type with key" - " \"") - << sub.getName() << "\" in registry \"" - << roots[0].getRegistryName() << "\"\n"; - std::exit(EXIT_FAILURE); - } - n = reader.getFieldCount(); - for (sal_uInt16 j = 0; j != n; ++j) { - item.fields.push_back( - Field( - reader.getFieldName(j), - reader.getFieldTypeName(j).replace('/', '.'))); - } - } else { - item.type = TYPE_POLYSTRUCT; - setFlags(reader, &item); - if (reader.getSuperTypeCount() != 0) { - std::cerr - << "Unexpected number " - << reader.getSuperTypeCount() - << (" of super-types of polymorphic struct type" - " template with key \"") - << sub.getName() << "\" in registry \"" - << roots[0].getRegistryName() << "\"\n"; - std::exit(EXIT_FAILURE); - } - for (sal_uInt16 j = 0; j != n; ++j) { - item.references.push_back( - reader.getReferenceTypeName(j).replace('/', '.')); - } - n = reader.getFieldCount(); - for (sal_uInt16 j = 0; j != n; ++j) { - item.fields.push_back( - Field( - reader.getFieldName(j), - reader.getFieldTypeName(j).replace('/', '.'), - ((reader.getFieldFlags(j) - & RT_ACCESS_PARAMETERIZED_TYPE) - != 0))); - } - } - insert(name, item, map); - break; - } - case RT_TYPE_ENUM: - { - Item item; - item.type = TYPE_ENUM; - setFlags(reader, &item); - sal_uInt16 n = reader.getFieldCount(); - for (sal_uInt16 j = 0; j != n; ++j) { - RTConstValue v(reader.getFieldValue(j)); - if (v.m_type != RT_TYPE_INT32) { - std::cerr - << "Unexpected type " << +v.m_type - << " of value of field \"" << reader.getFieldName(j) - << "\" of enum type with key \"" << sub.getName() - << "\" in registry \"" << roots[0].getRegistryName() - << "\"\n"; - std::exit(EXIT_FAILURE); - } - item.fields.push_back( - Field(reader.getFieldName(j), v.m_value.aLong)); - } - insert(name, item, map); - break; - } - case RT_TYPE_EXCEPTION: - { - Item item; - item.type = TYPE_EXCEPTION; - setFlags(reader, &item); - switch (reader.getSuperTypeCount()) { - case 0: - break; - case 1: - item.supertypes.push_back( - reader.getSuperTypeName(0).replace('/', '.')); - break; - default: - std::cerr - << "Unexpected number " << reader.getSuperTypeCount() - << " of super-types of exception type with key \"" - << sub.getName() << "\" in registry \"" - << roots[0].getRegistryName() << "\"\n"; - std::exit(EXIT_FAILURE); - } - sal_uInt16 n = reader.getFieldCount(); - for (sal_uInt16 j = 0; j != n; ++j) { - item.fields.push_back( - Field( - reader.getFieldName(j), - reader.getFieldTypeName(j).replace('/', '.'))); - } - insert(name, item, map); - break; - } - case RT_TYPE_TYPEDEF: - { - Item item; - item.type = TYPE_TYPEDEF; - setFlags(reader, &item); - if (reader.getSuperTypeCount() != 1) { - std::cerr - << "Unexpected number " << reader.getSuperTypeCount() - << " of super-types of typedef with key \"" - << sub.getName() << "\" in registry \"" - << roots[0].getRegistryName() << "\"\n"; - std::exit(EXIT_FAILURE); - } - item.supertypes.push_back( - reader.getSuperTypeName(0).replace('/', '.')); - insert(name, item, map); - break; - } - case RT_TYPE_SERVICE: - { - Item item; - switch (reader.getSuperTypeCount()) { - case 0: - { - item.type = TYPE_OLDSERVICE; - setFlags(reader, &item); - sal_uInt16 n = reader.getReferenceCount(); - for (sal_uInt16 j = 0; j != n; ++j) { - rtl::OUString refName( - reader.getReferenceTypeName(j).replace( - '/', '.')); - switch (reader.getReferenceSort(j)) { - case RT_REF_SUPPORTS: - if ((reader.getReferenceFlags(j) - & RT_ACCESS_OPTIONAL) - != 0) - { - item.optionalSupertypes.push_back(refName); - } else { - item.supertypes.push_back(refName); - } - break; - case RT_REF_EXPORTS: - if ((reader.getReferenceFlags(j) - & RT_ACCESS_OPTIONAL) - != 0) - { - item.optionalReferences.push_back(refName); - } else { - item.references.push_back(refName); - } - break; - default: - std::cerr - << "Unexpected mode " - << +reader.getReferenceSort(j) - << " of reference \"" - << reader.getReferenceTypeName(j) - << "\" in service with key \"" - << sub.getName() << "\" in registry \"" - << roots[0].getRegistryName() << "\"\n"; - std::exit(EXIT_FAILURE); - } - } - n = reader.getFieldCount(); - for (sal_uInt16 j = 0; j != n; ++j) { - RTFieldAccess acc = reader.getFieldFlags(j); - sal_Int32 v = 0; - if ((acc & RT_ACCESS_READONLY) != 0) { - v |= 0x0010; - } - if ((acc & RT_ACCESS_OPTIONAL) != 0) { - v |= 0x0100; - } - if ((acc & RT_ACCESS_MAYBEVOID) != 0) { - v |= 0x0001; - } - if ((acc & RT_ACCESS_BOUND) != 0) { - v |= 0x0002; - } - if ((acc & RT_ACCESS_CONSTRAINED) != 0) { - v |= 0x0004; - } - if ((acc & RT_ACCESS_TRANSIENT) != 0) { - v |= 0x0008; - } - if ((acc & RT_ACCESS_MAYBEAMBIGUOUS) != 0) { - v |= 0x0020; - } - if ((acc & RT_ACCESS_MAYBEDEFAULT) != 0) { - v |= 0x0040; - } - if ((acc & RT_ACCESS_REMOVEABLE) != 0) { - v |= 0x0080; - } - item.fields.push_back( - Field( - reader.getFieldName(j), - reader.getFieldTypeName(j).replace( - '/', '.'), - v)); - } - break; - } - case 1: - { - item.type = TYPE_NEWSERVICE; - setFlags(reader, &item); - item.supertypes.push_back( - reader.getSuperTypeName(0).replace('/', '.')); - sal_uInt16 n = reader.getMethodCount(); - if (n == 1 && reader.getMethodFlags(0) == 0 - && reader.getMethodName(0).isEmpty() - && reader.getMethodReturnTypeName(0) == "void" - && reader.getMethodParameterCount(0) == 0 - && reader.getMethodExceptionCount(0) == 0) - { - item.defaultConstructor = true; - } else { - item.defaultConstructor = false; - for (sal_uInt16 j = 0; j != n; ++j) { - if (reader.getMethodFlags(j) != RT_MODE_TWOWAY) - { - std::cerr - << "Unexpected mode " - << +reader.getMethodFlags(j) - << " of constructor \"" - << reader.getMethodName(j) - << "\" in service with key \"" - << sub.getName() << "\" in registry \"" - << roots[0].getRegistryName() << "\"\n"; - std::exit(EXIT_FAILURE); - } - std::vector< Parameter > params; - sal_uInt16 m = reader.getMethodParameterCount( - j); - for (sal_uInt16 k = 0; k != m; ++k) { - RTParamMode mode - = reader.getMethodParameterFlags(j, k); - if ((mode & ~RT_PARAM_REST) != RT_PARAM_IN) - { - std::cerr - << "Unexpected mode " << +mode - << " of parameter \"" - << reader.getMethodParameterName( - j, k) - << "\" of constructor \"" - << reader.getMethodName(j) - << "\" in service with key \"" - << sub.getName() - << "\" in registry \"" - << roots[0].getRegistryName() - << "\"\n"; - std::exit(EXIT_FAILURE); - } - if ((mode & RT_PARAM_REST) != 0 - && !(m == 1 - && ((reader. - getMethodParameterTypeName( - j, 1)) - == "any"))) - { - std::cerr - << "Bad rest parameter \"" - << reader.getMethodParameterName( - j, k) - << "\" of constructor \"" - << reader.getMethodName(j) - << "\" in service with key \"" - << sub.getName() - << "\" in registry \"" - << roots[0].getRegistryName() - << "\"\n"; - std::exit(EXIT_FAILURE); - } - params.push_back( - Parameter( - reader.getMethodParameterName(j, k), - (reader. - getMethodParameterTypeName(j, k). - replace('/', '.')), - mode)); - } - std::vector< rtl::OUString > excs; - m = reader.getMethodExceptionCount(j); - for (sal_uInt16 k = 0; k != m; ++k) { - excs.push_back( - reader.getMethodExceptionTypeName(j, k). - replace('/', '.')); - } - item.methods.push_back( - Method( - reader.getMethodName(j), params, excs)); - } - } - break; - } - default: - std::cerr - << "Unexpected number " << reader.getSuperTypeCount() - << " of super-types of service with key \"" - << sub.getName() << "\" in registry \"" - << roots[0].getRegistryName() << "\"\n"; - std::exit(EXIT_FAILURE); - } - insert(name, item, map); - break; - } - case RT_TYPE_SINGLETON: - { - Item item; - if (reader.getSuperTypeCount() != 1) { - std::cerr - << "Unexpected number " << reader.getSuperTypeCount() - << " of super-types of singleton with key \"" - << sub.getName() << "\" in registry \"" - << roots[0].getRegistryName() << "\"\n"; - std::exit(EXIT_FAILURE); - } - rtl::OUString path("/UCR/" + reader.getSuperTypeName(0)); - RegistryKey key2; - for (std::vector< RegistryKey >::iterator j(roots.begin()); - j != roots.end(); ++j) - { - e = j->openKey(path, key2); - switch (e) { - case REG_NO_ERROR: - { - std::vector< char > buf2; - typereg::Reader reader2(getReader(key2, &buf2)); - switch (reader2.getTypeClass()) { - case RT_TYPE_INTERFACE: - item.type = TYPE_NEWSINGLETON; - goto done; - case RT_TYPE_SERVICE: - item.type = TYPE_OLDSINGLETON; - goto done; - default: - std::cerr - << "Unexpected type class " - << +reader2.getTypeClass() - << " of super-type with key \"" - << key2.getName() << "\" in registry \"" - << j->getRegistryName() - << "\" of singleton with key \"" - << sub.getName() << "\" in registry \"" - << roots[0].getRegistryName() << "\"\n"; - std::exit(EXIT_FAILURE); - } - break; - } - case REG_KEY_NOT_EXISTS: - break; - default: - std::cerr - << "Cannot get key \"" << path - << "\" in registry \"" << j->getRegistryName() - << "\", error code " << +e << "\n"; - std::exit(EXIT_FAILURE); - } - } - std::cerr - << "Unknown super-type with key \"" << path - << "\" of singleton with key \"" << sub.getName() - << "\" in registry \"" << roots[0].getRegistryName() - << "\"\n"; - std::exit(EXIT_FAILURE); - done: - setFlags(reader, &item); - item.supertypes.push_back( - reader.getSuperTypeName(0).replace('/', '.')); - insert(name, item, map); - break; - } - case RT_TYPE_CONSTANTS: - { - Item item; - item.type = TYPE_CONSTANTS; - setFlags(reader, &item); - sal_uInt16 n = reader.getFieldCount(); - for (sal_uInt16 j = 0; j != n; ++j) { - Item item2; - setDeprecated(reader.getFieldDocumentation(j), &item2); - RTConstValue v(reader.getFieldValue(j)); - switch (v.m_type) { - case RT_TYPE_BOOL: - item2.constantType = CONSTANT_TYPE_BOOLEAN; - item2.constantValue.bo = v.m_value.aBool; - break; - case RT_TYPE_BYTE: - item2.constantType = CONSTANT_TYPE_BYTE; - item2.constantValue.by = v.m_value.aByte; - break; - case RT_TYPE_INT16: - item2.constantType = CONSTANT_TYPE_SHORT; - item2.constantValue.s = v.m_value.aShort; - break; - case RT_TYPE_UINT16: - item2.constantType = CONSTANT_TYPE_UNSIGNED_SHORT; - item2.constantValue.us = v.m_value.aUShort; - break; - case RT_TYPE_INT32: - item2.constantType = CONSTANT_TYPE_LONG; - item2.constantValue.l = v.m_value.aLong; - break; - case RT_TYPE_UINT32: - item2.constantType = CONSTANT_TYPE_UNSIGNED_LONG; - item2.constantValue.ul = v.m_value.aULong; - break; - case RT_TYPE_INT64: - item2.constantType = CONSTANT_TYPE_HYPER; - item2.constantValue.h = v.m_value.aHyper; - break; - case RT_TYPE_UINT64: - item2.constantType = CONSTANT_TYPE_UNSIGNED_HYPER; - item2.constantValue.uh = v.m_value.aUHyper; - break; - case RT_TYPE_FLOAT: - item2.constantType = CONSTANT_TYPE_FLOAT; - item2.constantValue.f = v.m_value.aFloat; - break; - case RT_TYPE_DOUBLE: - item2.constantType = CONSTANT_TYPE_DOUBLE; - item2.constantValue.d = v.m_value.aDouble; - break; - default: - std::cerr - << "Unexpected type " << +v.m_type - << " of value of field \"" << reader.getFieldName(j) - << "\" of constant group with key \"" - << sub.getName() << "\" in registry \"" - << roots[0].getRegistryName() << "\"\n"; - std::exit(EXIT_FAILURE); - } - insert(reader.getFieldName(j), item2, &item.elements); - } - insert(name, item, map); - break; - } - default: - std::cerr - << "Unexpected type class " << +reader.getTypeClass() - << " of key \"" << sub.getName() << "\" in registry \"" - << roots[0].getRegistryName() << "\"\n"; - std::exit(EXIT_FAILURE); - } - } -} - -sal_uInt64 getOffset(osl::File & file) { - sal_uInt64 off; - osl::FileBase::RC e = file.getPos(off); - if (e != osl::FileBase::E_None) { - std::cerr - << "Cannot determine current position in \"" << file.getURL() - << "\", error code " << +e << "\n"; - std::exit(EXIT_FAILURE); - } - return off; -} - -void write(osl::File & file, void const * buffer, sal_uInt64 size) { - sal_uInt64 n; - osl::FileBase::RC e = file.write(buffer, size, n); - if (e != osl::FileBase::E_None) { - std::cerr - << "Cannot write to \"" << file.getURL() << "\", error code " << +e - << "\n"; - std::exit(EXIT_FAILURE); - } - if (n != size) { - std::cerr - << "Bad write of " << n << " instead of " << size << " bytes to \"" - << file.getURL() << "\"\n"; - std::exit(EXIT_FAILURE); - } -} - -void write8(osl::File & file, sal_uInt64 value) { - if (value > 0xFF) { - std::cerr << "Cannot write value >= 2^8; input is too large\n"; - std::exit(EXIT_FAILURE); - } - unsigned char buf[1]; - buf[0] = value & 0xFF; - write(file, buf, SAL_N_ELEMENTS(buf)); -} - -void write16(osl::File & file, sal_uInt64 value) { - if (value > 0xFFFF) { - std::cerr << "Cannot write value >= 2^16; input is too large\n"; - std::exit(EXIT_FAILURE); - } - unsigned char buf[2]; - buf[0] = value & 0xFF; - buf[1] = (value >> 8) & 0xFF; - write(file, buf, SAL_N_ELEMENTS(buf)); -} - -void write32(osl::File & file, sal_uInt64 value) { - if (value > 0xFFFFFFFF) { - std::cerr << "Cannot write value >= 2^32; input is too large\n"; - std::exit(EXIT_FAILURE); - } - unsigned char buf[4]; - buf[0] = value & 0xFF; - buf[1] = (value >> 8) & 0xFF; - buf[2] = (value >> 16) & 0xFF; - buf[3] = (value >> 24) & 0xFF; - write(file, buf, SAL_N_ELEMENTS(buf)); -} - -void write64(osl::File & file, sal_uInt64 value) { - unsigned char buf[8]; - buf[0] = value & 0xFF; - buf[1] = (value >> 8) & 0xFF; - buf[2] = (value >> 16) & 0xFF; - buf[3] = (value >> 24) & 0xFF; - buf[3] = (value >> 32) & 0xFF; - buf[3] = (value >> 40) & 0xFF; - buf[3] = (value >> 48) & 0xFF; - buf[3] = (value >> 56) & 0xFF; - write(file, buf, SAL_N_ELEMENTS(buf)); -} - -void writeIso60599Binary32(osl::File & file, float value) { - union { - unsigned char buf[4]; - float f; // assuming float is ISO 60599 binary32 - } sa; - sa.f = value; -#if defined OSL_BIGENDIAN - std::swap(sa.buf[0], sa.buf[3]); - std::swap(sa.buf[1], sa.buf[2]); -#endif - write(file, sa.buf, SAL_N_ELEMENTS(sa.buf)); -} - -void writeIso60599Binary64(osl::File & file, double value) { - union { - unsigned char buf[8]; - float d; // assuming double is ISO 60599 binary64 - } sa; - sa.d = value; -#if defined OSL_BIGENDIAN - std::swap(sa.buf[0], sa.buf[7]); - std::swap(sa.buf[1], sa.buf[6]); - std::swap(sa.buf[2], sa.buf[5]); - std::swap(sa.buf[3], sa.buf[4]); -#endif - write(file, sa.buf, SAL_N_ELEMENTS(sa.buf)); -} - -rtl::OString toAscii(rtl::OUString const & name) { - rtl::OString ascii; - if (!name.convertToString( - &ascii, RTL_TEXTENCODING_ASCII_US, - (RTL_UNICODETOTEXT_FLAGS_UNDEFINED_ERROR - | RTL_UNICODETOTEXT_FLAGS_INVALID_ERROR))) - { - std::cerr << "Cannot convert \"" << name << "\" to US ASCII\n"; - std::exit(EXIT_FAILURE); - } - return ascii; -} - -sal_uInt64 writeNameNul(osl::File & file, rtl::OUString const & name) { - rtl::OString ascii(toAscii(name)); - if (ascii.indexOf('\0') != -1) { - std::cerr << "Name \"" << ascii << "\" contains NUL characters\n"; - std::exit(EXIT_FAILURE); - } - sal_uInt64 off = getOffset(file); - write(file, ascii.getStr(), ascii.getLength() + 1); - return off; -} - -void writeNameLen(osl::File & file, rtl::OUString const & name) { - static std::map< rtl::OUString, sal_uInt64 > reuse; - std::map< rtl::OUString, sal_uInt64 >::iterator i(reuse.find(name)); - if (i == reuse.end()) { - reuse.insert(std::make_pair(name, getOffset(file))); - rtl::OString ascii(toAscii(name)); - assert( - (static_cast< sal_uInt64 >(ascii.getLength()) & 0x80000000) == 0); - write32( - file, static_cast< sal_uInt64 >(ascii.getLength()) | 0x80000000); - write(file, ascii.getStr(), ascii.getLength()); - } else { - write32(file, i->second); - } -} - -void writeType(osl::File & file, Item const & item, bool flag = false) { - assert(item.type != TYPE_MODULE); - sal_uInt64 v = item.type; - if (item.published) { - v |= 0x80; - } - if (item.deprecated) { - v |= 0x40; - } - if (flag) { - v |= 0x20; - } - write8(file, v); -} - -sal_uInt64 writeMap( - osl::File & file, std::map< rtl::OUString, Item > & map, bool root) -{ - for (std::map< rtl::OUString, Item >::iterator i(map.begin()); - i != map.end(); ++i) - { - switch (i->second.type) { - case TYPE_MODULE: - i->second.dataOffset = writeMap(file, i->second.elements, false); - break; - case TYPE_ENUM: - i->second.dataOffset = getOffset(file); - writeType(file, i->second); - write32(file, i->second.fields.size()); - for (std::vector< Field >::const_iterator j( - i->second.fields.begin()); - j != i->second.fields.end(); ++j) - { - writeNameLen(file, j->name); - write32(file, static_cast< sal_uInt32 >(j->value)); - } - break; - case TYPE_STRUCT: - case TYPE_EXCEPTION: - i->second.dataOffset = getOffset(file); - writeType(file, i->second, !i->second.supertypes.empty()); - if (!i->second.supertypes.empty()) { - writeNameLen(file, i->second.supertypes[0]); - } - write32(file, i->second.fields.size()); - for (std::vector< Field >::const_iterator j( - i->second.fields.begin()); - j != i->second.fields.end(); ++j) - { - writeNameLen(file, j->name); - writeNameLen(file, j->type); - } - break; - case TYPE_POLYSTRUCT: - i->second.dataOffset = getOffset(file); - writeType(file, i->second); - write32(file, i->second.references.size()); - for (std::vector< rtl::OUString >::const_iterator j( - i->second.references.begin()); - j != i->second.references.end(); ++j) - { - writeNameLen(file, *j); - } - write32(file, i->second.fields.size()); - for (std::vector< Field >::const_iterator j( - i->second.fields.begin()); - j != i->second.fields.end(); ++j) - { - sal_uInt64 f = 0; - if (j->bound) { - f |= 0x01; - } - write8(file, f); - writeNameLen(file, j->name); - writeNameLen(file, j->type); - } - break; - case TYPE_INTERFACE: - i->second.dataOffset = getOffset(file); - writeType(file, i->second); - write32(file, i->second.supertypes.size()); - for (std::vector< rtl::OUString >::const_iterator j( - i->second.supertypes.begin()); - j != i->second.supertypes.end(); ++j) - { - writeNameLen(file, *j); - } - write32(file, i->second.optionalSupertypes.size()); - for (std::vector< rtl::OUString >::const_iterator j( - i->second.optionalSupertypes.begin()); - j != i->second.optionalSupertypes.end(); ++j) - { - writeNameLen(file, *j); - } - write32(file, i->second.fields.size()); - for (std::vector< Field >::const_iterator j( - i->second.fields.begin()); - j != i->second.fields.end(); ++j) - { - sal_uInt64 f = 0; - if (j->bound) { - f |= 0x01; - } - if (j->readOnly) { - f |= 0x02; - } - write8(file, f); - writeNameLen(file, j->name); - writeNameLen(file, j->type); - write32(file, j->getExceptions.size()); - for (std::vector< rtl::OUString >::const_iterator k( - j->getExceptions.begin()); - k != j->getExceptions.end(); ++k) - { - writeNameLen(file, *k); - } - if (!j->readOnly) { - write32(file, j->setExceptions.size()); - for (std::vector< rtl::OUString >::const_iterator k( - j->setExceptions.begin()); - k != j->setExceptions.end(); ++k) - { - writeNameLen(file, *k); - } - } - } - write32(file, i->second.methods.size()); - for (std::vector< Method >::const_iterator j( - i->second.methods.begin()); - j != i->second.methods.end(); ++j) - { - writeNameLen(file, j->name); - writeNameLen(file, j->returnType); - write32(file, j->parameters.size()); - for (std::vector< Parameter >::const_iterator k( - j->parameters.begin()); - k != j->parameters.end(); ++k) - { - sal_uInt64 f = sal_uInt64(); - switch (k->mode) { - case RT_PARAM_IN: - f = 0; - break; - case RT_PARAM_OUT: - f = 1; - break; - case RT_PARAM_INOUT: - f = 2; - break; - default: - std::abort(); // this cannot happen - } - write8(file, f); - writeNameLen(file, k->name); - writeNameLen(file, k->type); - } - write32(file, j->exceptions.size()); - for (std::vector< rtl::OUString >::const_iterator k( - j->exceptions.begin()); - k != j->exceptions.end(); ++k) - { - writeNameLen(file, *k); - } - } - break; - case TYPE_TYPEDEF: - i->second.dataOffset = getOffset(file); - writeType(file, i->second); - assert(i->second.supertypes.size() == 1); - writeNameLen(file, i->second.supertypes[0]); - break; - case TYPE_CONSTANTS: - for (std::map< rtl::OUString, Item >::iterator j( - i->second.elements.begin()); - j != i->second.elements.end(); ++j) - { - j->second.dataOffset = getOffset(file); - sal_uInt64 v = j->second.constantType; - if (j->second.deprecated) { - v |= 0x80; - } - write8(file, v); - switch (j->second.constantType) { - case CONSTANT_TYPE_BOOLEAN: - write8(file, j->second.constantValue.bo ? 1 : 0); - break; - case CONSTANT_TYPE_BYTE: - write8( - file, - static_cast< sal_uInt8 >(j->second.constantValue.by)); - break; - case CONSTANT_TYPE_SHORT: - write16( - file, - static_cast< sal_uInt16 >(j->second.constantValue.s)); - break; - case CONSTANT_TYPE_UNSIGNED_SHORT: - write16(file, j->second.constantValue.us); - break; - case CONSTANT_TYPE_LONG: - write32( - file, - static_cast< sal_uInt32 >(j->second.constantValue.l)); - break; - case CONSTANT_TYPE_UNSIGNED_LONG: - write32(file, j->second.constantValue.ul); - break; - case CONSTANT_TYPE_HYPER: - write64( - file, - static_cast< sal_uInt64 >(j->second.constantValue.h)); - break; - case CONSTANT_TYPE_UNSIGNED_HYPER: - write64(file, j->second.constantValue.uh); - break; - case CONSTANT_TYPE_FLOAT: - writeIso60599Binary32(file, j->second.constantValue.f); - break; - case CONSTANT_TYPE_DOUBLE: - writeIso60599Binary64(file, j->second.constantValue.d); - break; - default: - std::abort(); // this cannot happen - } - } - for (std::map< rtl::OUString, Item >::iterator j( - i->second.elements.begin()); - j != i->second.elements.end(); ++j) - { - j->second.nameOffset = writeNameNul(file, j->first); - } - i->second.dataOffset = getOffset(file); - writeType(file, i->second); - write32(file, i->second.elements.size()); - // overflow from std::map::size_type -> sal_uInt64 is - // unrealistic - for (std::map< rtl::OUString, Item >::iterator j( - i->second.elements.begin()); - j != i->second.elements.end(); ++j) - { - write32(file, j->second.nameOffset); - write32(file, j->second.dataOffset); - } - break; - case TYPE_NEWSERVICE: - i->second.dataOffset = getOffset(file); - writeType(file, i->second, i->second.defaultConstructor); - assert(i->second.supertypes.size() == 1); - writeNameLen(file, i->second.supertypes[0]); - if (!i->second.defaultConstructor) { - write32(file, i->second.methods.size()); - for (std::vector< Method >::const_iterator j( - i->second.methods.begin()); - j != i->second.methods.end(); ++j) - { - writeNameLen(file, j->name); - write32(file, j->parameters.size()); - for (std::vector< Parameter >::const_iterator k( - j->parameters.begin()); - k != j->parameters.end(); ++k) - { - sal_uInt64 f = 0; - if ((k->mode & RT_PARAM_REST) != 0) { - f |= 0x04; - } - write8(file, f); - writeNameLen(file, k->name); - writeNameLen(file, k->type); - } - write32(file, j->exceptions.size()); - for (std::vector< rtl::OUString >::const_iterator k( - j->exceptions.begin()); - k != j->exceptions.end(); ++k) - { - writeNameLen(file, *k); - } - } - } - break; - case TYPE_OLDSERVICE: - i->second.dataOffset = getOffset(file); - writeType(file, i->second); - write32(file, i->second.references.size()); - for (std::vector< rtl::OUString >::const_iterator j( - i->second.references.begin()); - j != i->second.references.end(); ++j) - { - writeNameLen(file, *j); - } - write32(file, i->second.optionalReferences.size()); - for (std::vector< rtl::OUString >::const_iterator j( - i->second.optionalReferences.begin()); - j != i->second.optionalReferences.end(); ++j) - { - writeNameLen(file, *j); - } - write32(file, i->second.supertypes.size()); - for (std::vector< rtl::OUString >::const_iterator j( - i->second.supertypes.begin()); - j != i->second.supertypes.end(); ++j) - { - writeNameLen(file, *j); - } - write32(file, i->second.optionalSupertypes.size()); - for (std::vector< rtl::OUString >::const_iterator j( - i->second.optionalSupertypes.begin()); - j != i->second.optionalSupertypes.end(); ++j) - { - writeNameLen(file, *j); - } - write32(file, i->second.fields.size()); - for (std::vector< Field >::const_iterator j( - i->second.fields.begin()); - j != i->second.fields.end(); ++j) - { - write16(file, static_cast< sal_uInt16 >(j->value)); - writeNameLen(file, j->name); - writeNameLen(file, j->type); - } - break; - case TYPE_NEWSINGLETON: - i->second.dataOffset = getOffset(file); - writeType(file, i->second); - assert(i->second.supertypes.size() == 1); - writeNameLen(file, i->second.supertypes[0]); - break; - case TYPE_OLDSINGLETON: - i->second.dataOffset = getOffset(file); - writeType(file, i->second); - assert(i->second.supertypes.size() == 1); - writeNameLen(file, i->second.supertypes[0]); - break; - } - } - for (std::map< rtl::OUString, Item >::iterator i(map.begin()); - i != map.end(); ++i) - { - i->second.nameOffset = writeNameNul(file, i->first); - } - sal_uInt64 off = getOffset(file); - if (!root) { - write8(file, 0); // TYPE_MODULE - write32(file, map.size()); - // overflow from std::map::size_type -> sal_uInt64 is unrealistic - } - for (std::map< rtl::OUString, Item >::iterator i(map.begin()); - i != map.end(); ++i) - { - write32(file, i->second.nameOffset); - write32(file, i->second.dataOffset); - } - return off; -} - -} - -SAL_IMPLEMENT_MAIN() { - sal_uInt32 args = rtl_getAppCommandArgCount(); - if (args < 2) { - std::cerr - << ("Usage: reg2bin <.bin file> <.rdb file> <additional .rdb files>" - "\n"); - std::exit(EXIT_FAILURE); - } - std::vector< RegistryKey > roots; - for (sal_uInt32 i = 1; i != args; ++i) { - rtl::OUString url(getArgumentUrl(i)); - Registry reg; - RegError e = reg.open(url, REG_READONLY); - if (e != REG_NO_ERROR) { - std::cerr - << "Cannot open registry \"" << url << "\", error code " << +e - << "\n"; - std::exit(EXIT_FAILURE); - } - RegistryKey root; - e = reg.openRootKey(root); - if (e != REG_NO_ERROR) { - std::cerr - << "Cannot get root key of registry \"" << url - << "\", error code " << +e << "\n"; - std::exit(EXIT_FAILURE); - } - roots.push_back(root); - } - RegistryKey ucr; - RegError e1 = roots[0].openKey("UCR", ucr); - if (e1 != REG_NO_ERROR) { - std::cerr - << "Cannot get /UCR key of registry \"" - << roots[0].getRegistryName() << "\", error code " << +e1 << "\n"; - std::exit(EXIT_FAILURE); - } - std::map< rtl::OUString, Item > map; - readModule(roots, ucr, &map); - osl::File f(getArgumentUrl(0)); - osl::FileBase::RC e2 = f.open(osl_File_OpenFlag_Write); - if (e2 == osl::FileBase::E_NOENT) { - e2 = f.open(osl_File_OpenFlag_Write | osl_File_OpenFlag_Create); - } - if (e2 != osl::FileBase::E_None) { - std::cerr - << "Cannot open \"" << f.getURL() << "\" for writing, error code " - << +e2 << "\n"; - std::exit(EXIT_FAILURE); - } - write(f, "UNOIDL\0\xFF", 8); - write32(f, 0); // root map offset - write32(f, 0); // root map size - sal_uInt64 off = writeMap(f, map, true); - e2 = f.setSize(getOffset(f)); // truncate in case it already existed - if (e2 != osl::FileBase::E_None) { - std::cerr - << "Cannot set size of \"" << f.getURL() << "\", error code " - << +e2 << "\n"; - std::exit(EXIT_FAILURE); - } - - e2 = f.setPos(osl_Pos_Absolut, 8); - if (e2 != osl::FileBase::E_None) { - std::cerr - << "Cannot rewind current position in \"" << f.getURL() - << "\", error code " << +e2 << "\n"; - std::exit(EXIT_FAILURE); - } - write32(f, off); - write32(f, map.size()); - // overflow from std::map::size_type -> sal_uInt64 is unrealistic - e2 = f.close(); - if (e2 != osl::FileBase::E_None) { - std::cerr - << "Cannot close \"" << f.getURL() - << "\" after writing, error code " << +e2 << "\n"; - std::exit(EXIT_FAILURE); - } - return EXIT_SUCCESS; -} - -/* vim:set shiftwidth=4 softtabstop=4 expandtab: */ diff --git a/registry/Executable_reg2bin.mk b/unoidl/Executable_reg2unoidl.mk index c28770be96ba..7f21a08454cb 100644 --- a/registry/Executable_reg2bin.mk +++ b/unoidl/Executable_reg2unoidl.mk @@ -7,15 +7,16 @@ # file, You can obtain one at http://mozilla.org/MPL/2.0/. # -$(eval $(call gb_Executable_Executable,reg2bin)) +$(eval $(call gb_Executable_Executable,reg2unoidl)) -$(eval $(call gb_Executable_add_exception_objects,reg2bin, \ - registry/tools/reg2bin \ +$(eval $(call gb_Executable_add_exception_objects,reg2unoidl, \ + unoidl/source/reg2unoidl \ )) -$(eval $(call gb_Executable_use_libraries,reg2bin, \ - reg \ +$(eval $(call gb_Executable_use_libraries,reg2unoidl, \ sal \ + salhelper \ + unoidl \ )) # vim: set noet sw=4 ts=4: diff --git a/unoidl/Library_unoidl.mk b/unoidl/Library_unoidl.mk index 8a7a668299e7..5de3cf163ac0 100644 --- a/unoidl/Library_unoidl.mk +++ b/unoidl/Library_unoidl.mk @@ -12,11 +12,13 @@ $(eval $(call gb_Library_Library,unoidl)) $(eval $(call gb_Library_add_defs,unoidl,-DLO_DLLIMPLEMENTATION_UNOIDL)) $(eval $(call gb_Library_add_exception_objects,unoidl, \ + unoidl/source/legacyprovider \ unoidl/source/unoidl \ unoidl/source/unoidlprovider \ )) $(eval $(call gb_Library_use_libraries,unoidl, \ + reg \ sal \ salhelper \ )) diff --git a/unoidl/Module_unoidl.mk b/unoidl/Module_unoidl.mk index 7017b80a897c..e612d9d051d8 100644 --- a/unoidl/Module_unoidl.mk +++ b/unoidl/Module_unoidl.mk @@ -10,6 +10,7 @@ $(eval $(call gb_Module_Module,unoidl)) $(eval $(call gb_Module_add_targets,unoidl, \ + Executable_reg2unoidl \ Library_unoidl \ Package_inc \ )) diff --git a/unoidl/Package_inc.mk b/unoidl/Package_inc.mk index 563ae365d07c..84a11a311e8b 100644 --- a/unoidl/Package_inc.mk +++ b/unoidl/Package_inc.mk @@ -10,6 +10,7 @@ $(eval $(call gb_Package_Package,unoidl_inc,$(SRCDIR)/unoidl/inc/unoidl)) $(eval $(call gb_Package_add_file,unoidl_inc,inc/unoidl/detail/dllapi.hxx,detail/dllapi.hxx)) +$(eval $(call gb_Package_add_file,unoidl_inc,inc/unoidl/legacyprovider.hxx,legacyprovider.hxx)) $(eval $(call gb_Package_add_file,unoidl_inc,inc/unoidl/unoidl.hxx,unoidl.hxx)) $(eval $(call gb_Package_add_file,unoidl_inc,inc/unoidl/unoidlprovider.hxx,unoidlprovider.hxx)) diff --git a/unoidl/inc/unoidl/legacyprovider.hxx b/unoidl/inc/unoidl/legacyprovider.hxx new file mode 100644 index 000000000000..68db79c933c2 --- /dev/null +++ b/unoidl/inc/unoidl/legacyprovider.hxx @@ -0,0 +1,49 @@ +/* -*- Mode: C++; tab-width: 4; indent-tabs-mode: nil; c-basic-offset: 4 -*- */ +/* + * This file is part of the LibreOffice project. + * + * This Source Code Form is subject to the terms of the Mozilla Public + * License, v. 2.0. If a copy of the MPL was not distributed with this + * file, You can obtain one at http://mozilla.org/MPL/2.0/. + */ + +#ifndef INCLUDED_UNOIDL_LEGACYPROVIDER_HXX +#define INCLUDED_UNOIDL_LEGACYPROVIDER_HXX + +#include "sal/config.h" + +#include "registry/registry.hxx" +#include "rtl/ref.hxx" +#include "sal/types.h" +#include "unoidl/detail/dllapi.hxx" +#include "unoidl/unoidl.hxx" + +namespace rtl { class OUString; } + +namespace unoidl { + +class LO_DLLPUBLIC_UNOIDL LegacyProvider: public Provider { +public: + // throws FileFormatException, NoSuchFileException: + LegacyProvider( + rtl::Reference< Manager > const & manager, rtl::OUString const & uri); + + // throws FileFormatException: + virtual rtl::Reference< MapCursor > createRootCursor() const; + + // throws FileFormatException: + virtual rtl::Reference< Entity > findEntity(rtl::OUString const & name) + const; + +private: + virtual SAL_DLLPRIVATE ~LegacyProvider() throw (); + + rtl::Reference< Manager > manager_; + mutable RegistryKey ucr_; +}; + +} + +#endif + +/* vim:set shiftwidth=4 softtabstop=4 expandtab: */ diff --git a/unoidl/inc/unoidl/unoidl.hxx b/unoidl/inc/unoidl/unoidl.hxx index 372ed3889ade..5597227c16e0 100644 --- a/unoidl/inc/unoidl/unoidl.hxx +++ b/unoidl/inc/unoidl/unoidl.hxx @@ -601,15 +601,34 @@ public: // throws FileFormatException: virtual rtl::Reference< MapCursor > createRootCursor() const = 0; + // throws FileFormatException: + virtual rtl::Reference< Entity > findEntity(rtl::OUString const & name) + const = 0; + protected: SAL_DLLPRIVATE Provider() {} virtual SAL_DLLPRIVATE ~Provider() throw (); }; +class LO_DLLPUBLIC_UNOIDL Manager: public salhelper::SimpleReferenceObject { +public: + Manager() {} + + void addProvider(rtl::Reference< Provider > const & provider); + + // throws FileFormatException: + rtl::Reference< Entity > findEntity(rtl::OUString const & name) const; + +private: + virtual SAL_DLLPRIVATE ~Manager() throw (); + + std::vector< rtl::Reference< Provider > > providers_; +}; + // throws FileFormatException, NoSuchFileException: LO_DLLPUBLIC_UNOIDL rtl::Reference< Provider > loadProvider( - rtl::OUString const & uri); + rtl::Reference< Manager > const & manager, rtl::OUString const & uri); } diff --git a/unoidl/inc/unoidl/unoidlprovider.hxx b/unoidl/inc/unoidl/unoidlprovider.hxx index 07388a604034..b72a629990ef 100644 --- a/unoidl/inc/unoidl/unoidlprovider.hxx +++ b/unoidl/inc/unoidl/unoidlprovider.hxx @@ -34,6 +34,10 @@ public: virtual rtl::Reference< MapCursor > createRootCursor() const; // throws FileFormatException: + virtual rtl::Reference< Entity > findEntity(rtl::OUString const & name) + const; + + // throws FileFormatException: sal_uInt32 find(rtl::OUString const & name, bool * constant = 0) const; // throws FileFormatException: diff --git a/unoidl/prj/build.lst b/unoidl/prj/build.lst index 32409d2a0b63..c6b2abf3cafc 100644 --- a/unoidl/prj/build.lst +++ b/unoidl/prj/build.lst @@ -1,2 +1,2 @@ -un unoidl: sal salhelper NULL +un unoidl: registry sal salhelper NULL un unoidl\prj nmake - all un_prj NULL diff --git a/unoidl/source/legacyprovider.cxx b/unoidl/source/legacyprovider.cxx new file mode 100644 index 000000000000..0f620bc51fd0 --- /dev/null +++ b/unoidl/source/legacyprovider.cxx @@ -0,0 +1,778 @@ +/* -*- Mode: C++; tab-width: 4; indent-tabs-mode: nil; c-basic-offset: 4 -*- */ +/* + * This file is part of the LibreOffice project. + * + * This Source Code Form is subject to the terms of the Mozilla Public + * License, v. 2.0. If a copy of the MPL was not distributed with this + * file, You can obtain one at http://mozilla.org/MPL/2.0/. + */ + +#include "sal/config.h" + +#include <cassert> +#include <cstring> +#include <vector> + +#include "registry/reader.hxx" +#include "registry/registry.hxx" +#include "registry/regtype.h" +#include "rtl/ref.hxx" +#include "rtl/ustring.hxx" +#include "sal/types.h" +#include "unoidl/legacyprovider.hxx" +#include "unoidl/unoidl.hxx" + +namespace unoidl { + +namespace { + +ConstantValue translateConstantValue( + RegistryKey & key, RTConstValue const & value) +{ + switch (value.m_type) { + case RT_TYPE_BOOL: + return ConstantValue(static_cast< bool >(value.m_value.aBool)); + case RT_TYPE_BYTE: + return ConstantValue(value.m_value.aByte); + case RT_TYPE_INT16: + return ConstantValue(value.m_value.aShort); + case RT_TYPE_UINT16: + return ConstantValue(value.m_value.aUShort); + case RT_TYPE_INT32: + return ConstantValue(value.m_value.aLong); + case RT_TYPE_UINT32: + return ConstantValue(value.m_value.aULong); + case RT_TYPE_INT64: + return ConstantValue(value.m_value.aHyper); + case RT_TYPE_UINT64: + return ConstantValue(value.m_value.aUHyper); + case RT_TYPE_FLOAT: + return ConstantValue(value.m_value.aFloat); + case RT_TYPE_DOUBLE: + return ConstantValue(value.m_value.aDouble); + default: + throw FileFormatException( + key.getRegistryName(), + ("legacy format: unexpected type " + OUString::number(value.m_type) + + " of value of a field of constant group with key " + + key.getName())); + } +} + +rtl::Reference< Entity > readEntity( + rtl::Reference< Manager > const & manager, RegistryKey & ucr, + RegistryKey & key, OUString const & path, bool probe); + +class Cursor: public MapCursor { +public: + Cursor( + rtl::Reference< Manager > const & manager, RegistryKey const & ucr, + RegistryKey const & key); + +private: + virtual ~Cursor() throw () {} + + virtual rtl::Reference< Entity > getNext(OUString * name); + + rtl::Reference< Manager > manager_; + RegistryKey ucr_; + RegistryKey key_; + OUString prefix_; + RegistryKeyNames names_; + sal_uInt32 index_; +}; + +Cursor::Cursor( + rtl::Reference< Manager > const & manager, RegistryKey const & ucr, + RegistryKey const & key): + manager_(manager), ucr_(ucr), key_(key), index_(0) +{ + prefix_ = key_.getName(); + if (!prefix_.endsWith("/")) { + prefix_ += "/"; + } + RegError e = key_.getKeyNames("", names_); + if (e != REG_NO_ERROR) { + throw FileFormatException( + key_.getRegistryName(), + ("legacy format: cannot get sub-key names of " + key_.getName() + + ": " + OUString::number(e))); + } +} + +rtl::Reference< Entity > Cursor::getNext(OUString * name) { + assert(name != 0); + rtl::Reference< Entity > ent; + if (index_ != names_.getLength()) { + OUString path(names_.getElement(index_)); + assert(path.match(prefix_)); + *name = path.copy(prefix_.getLength()); + ent = readEntity(manager_, ucr_, key_, *name, false); + assert(ent.is()); + ++index_; + } + return ent; +} + +class Module: public ModuleEntity { +public: + Module( + rtl::Reference< Manager > const & manager, RegistryKey const & ucr, + RegistryKey const & key): + manager_(manager), ucr_(ucr), key_(key) + {} + +private: + virtual ~Module() throw () {} + + virtual std::vector< OUString > getMemberNames() const; + + virtual rtl::Reference< MapCursor > createCursor() const + { return new Cursor(manager_, ucr_, key_); } + + rtl::Reference< Manager > manager_; + RegistryKey ucr_; + mutable RegistryKey key_; +}; + +std::vector< OUString > Module::getMemberNames() const { + RegistryKeyNames names; + RegError e = key_.getKeyNames("", names); + if (e != REG_NO_ERROR) { + throw FileFormatException( + key_.getRegistryName(), + ("legacy format: cannot get sub-key names of " + key_.getName() + + ": " + OUString::number(e))); + } + std::vector< OUString > ns; + for (sal_uInt32 i = 0; i != names.getLength(); ++i) { + ns.push_back(names.getElement(i)); + } + return ns; +} + +typereg::Reader getReader(RegistryKey & key, std::vector< char > * buffer) { + assert(buffer != 0); + RegValueType type; + sal_uInt32 size; + RegError e = key.getValueInfo("", &type, &size); + if (e != REG_NO_ERROR) { + throw FileFormatException( + key.getRegistryName(), + ("legacy format: cannot get value info about key " + key.getName() + + ": " + OUString::number(e))); + } + if (type != RG_VALUETYPE_BINARY) { + throw FileFormatException( + key.getRegistryName(), + ("legacy format: unexpected value type " + OUString::number(type) + + " of key " + key.getName())); + } + if (size == 0 + /*TODO: || size > std::numeric_limits< std::vector< char >::size_type >::max() */) + { + throw FileFormatException( + key.getRegistryName(), + ("legacy format: bad binary value size " + OUString::number(size) + + " of key " + key.getName())); + } + buffer->resize(static_cast< std::vector< char >::size_type >(size)); + e = key.getValue("", &(*buffer)[0]); + if (e != REG_NO_ERROR) { + throw FileFormatException( + key.getRegistryName(), + ("legacy format: cannot get binary value of key " + key.getName() + + ": " + OUString::number(e))); + } + typereg::Reader reader(&(*buffer)[0], size, false, TYPEREG_VERSION_1); + if (!reader.isValid()) { + throw FileFormatException( + key.getRegistryName(), + "legacy format: malformed binary value of key " + key.getName()); + } + return reader; +} + +rtl::Reference< Entity > readEntity( + rtl::Reference< Manager > const & manager, RegistryKey & ucr, + RegistryKey & key, OUString const & path, bool probe) +{ + assert(manager.is()); + RegistryKey sub; + RegError e = key.openKey(path, sub); + switch (e) { + case REG_NO_ERROR: + break; + case REG_KEY_NOT_EXISTS: + if (probe) { + return rtl::Reference< Entity >(); + } + // fall through + default: + throw FileFormatException( + key.getRegistryName(), + ("legacy format: cannot open sub-key " + path + " of " + + key.getName() + ": " + OUString::number(e))); + } + std::vector< char > buf; + typereg::Reader reader(getReader(sub, &buf)); + switch (reader.getTypeClass()) { + case RT_TYPE_INTERFACE: + { + std::vector< OUString > mandBases; + sal_uInt16 n = reader.getSuperTypeCount(); + for (sal_uInt16 j = 0; j != n; ++j) { + mandBases.push_back( + reader.getSuperTypeName(j).replace('/', '.')); + } + std::vector< OUString > optBases; + n = reader.getReferenceCount(); + for (sal_uInt16 j = 0; j != n; ++j) { + optBases.push_back( + reader.getReferenceTypeName(j).replace('/', '.')); + } + sal_uInt16 methodCount = reader.getMethodCount(); + std::vector< InterfaceTypeEntity::Attribute > attrs; + n = reader.getFieldCount(); // attributes + for (sal_uInt16 j = 0; j != n; ++j) { + OUString attrName(reader.getFieldName(j)); + std::vector< OUString > getExcs; + std::vector< OUString > setExcs; + for (sal_uInt16 k = 0; k != methodCount; ++k) { + if (reader.getMethodName(k) == attrName) { + switch (reader.getMethodFlags(k)) { + case RT_MODE_ATTRIBUTE_GET: + { + sal_uInt16 m + = reader.getMethodExceptionCount(k); + for (sal_uInt16 l = 0; l != m; ++l) { + getExcs.push_back( + reader.getMethodExceptionTypeName(k, l). + replace('/', '.')); + } + break; + } + case RT_MODE_ATTRIBUTE_SET: + { + sal_uInt16 m + = reader.getMethodExceptionCount(k); + for (sal_uInt16 l = 0; l != m; ++l) { + setExcs.push_back( + reader.getMethodExceptionTypeName(k, l). + replace('/', '.')); + } + break; + } + default: + throw FileFormatException( + key.getRegistryName(), + ("legacy format: method and attribute with same" + " name " + attrName + + " in interface type with key " + + sub.getName())); + } + } + } + RTFieldAccess flags = reader.getFieldFlags(j); + attrs.push_back( + InterfaceTypeEntity::Attribute( + attrName, reader.getFieldTypeName(j).replace('/', '.'), + (flags & RT_ACCESS_BOUND) != 0, + (flags & RT_ACCESS_READONLY) != 0, getExcs, setExcs)); + } + std::vector< InterfaceTypeEntity::Method > meths; + for (sal_uInt16 j = 0; j != methodCount; ++j) { + RTMethodMode flags = reader.getMethodFlags(j); + if (flags != RT_MODE_ATTRIBUTE_GET + && flags != RT_MODE_ATTRIBUTE_SET) + { + std::vector< InterfaceTypeEntity::Method::Parameter > + params; + sal_uInt16 m = reader.getMethodParameterCount(j); + for (sal_uInt16 k = 0; k != m; ++k) { + RTParamMode mode = reader.getMethodParameterFlags(j, k); + InterfaceTypeEntity::Method::Parameter::Direction dir; + switch (mode) { + case RT_PARAM_IN: + dir = InterfaceTypeEntity::Method::Parameter:: + Direction::DIRECTION_IN; + break; + case RT_PARAM_OUT: + dir = InterfaceTypeEntity::Method::Parameter:: + Direction::DIRECTION_OUT; + break; + case RT_PARAM_INOUT: + dir = InterfaceTypeEntity::Method::Parameter:: + Direction::DIRECTION_IN_OUT; + break; + default: + throw FileFormatException( + key.getRegistryName(), + ("legacy format: unexpected mode " + + OUString::number(mode) + " of parameter " + + reader.getMethodParameterName(j, k) + + " of method " + reader.getMethodName(j) + + " in interface type with key " + + sub.getName())); + } + params.push_back( + InterfaceTypeEntity::Method::Parameter( + reader.getMethodParameterName(j, k), + (reader.getMethodParameterTypeName(j, k). + replace('/', '.')), + dir)); + } + std::vector< OUString > excs; + m = reader.getMethodExceptionCount(j); + for (sal_uInt16 k = 0; k != m; ++k) { + excs.push_back( + reader.getMethodExceptionTypeName(j, k).replace( + '/', '.')); + } + meths.push_back( + InterfaceTypeEntity::Method( + reader.getMethodName(j), + reader.getMethodReturnTypeName(j).replace('/', '.'), + params, excs)); + } + } + return new InterfaceTypeEntity( + reader.isPublished(), mandBases, optBases, attrs, meths); + } + case RT_TYPE_MODULE: + return new Module(manager, ucr, sub); + case RT_TYPE_STRUCT: + { + sal_uInt32 n = reader.getReferenceCount(); + if (n == 0) { + OUString base; + switch (reader.getSuperTypeCount()) { + case 0: + break; + case 1: + base = reader.getSuperTypeName(0).replace('/', '.'); + break; + default: + FileFormatException( + key.getRegistryName(), + ("legacy format: unexpected number " + + OUString::number(reader.getSuperTypeCount()) + + " of super-types of plain struct type with key " + + sub.getName())); + } + std::vector< PlainStructTypeEntity::Member > mems; + n = reader.getFieldCount(); + for (sal_uInt16 j = 0; j != n; ++j) { + mems.push_back( + PlainStructTypeEntity::Member( + reader.getFieldName(j), + reader.getFieldTypeName(j).replace('/', '.'))); + } + return new PlainStructTypeEntity( + reader.isPublished(), base, mems); + } else { + if (reader.getSuperTypeCount() != 0) { + FileFormatException( + key.getRegistryName(), + ("legacy format: unexpected number " + + OUString::number(reader.getSuperTypeCount()) + + " of super-types of polymorphic struct type template" + " with key " + sub.getName())); + } + std::vector< OUString > params; + for (sal_uInt16 j = 0; j != n; ++j) { + params.push_back( + reader.getReferenceTypeName(j).replace('/', '.')); + } + std::vector< PolymorphicStructTypeTemplateEntity::Member > mems; + n = reader.getFieldCount(); + for (sal_uInt16 j = 0; j != n; ++j) { + mems.push_back( + PolymorphicStructTypeTemplateEntity::Member( + reader.getFieldName(j), + reader.getFieldTypeName(j).replace('/', '.'), + ((reader.getFieldFlags(j) + & RT_ACCESS_PARAMETERIZED_TYPE) + != 0))); + } + return new PolymorphicStructTypeTemplateEntity( + reader.isPublished(), params, mems); + } + } + case RT_TYPE_ENUM: + { + std::vector< EnumTypeEntity::Member > mems; + sal_uInt16 n = reader.getFieldCount(); + for (sal_uInt16 j = 0; j != n; ++j) { + RTConstValue v(reader.getFieldValue(j)); + if (v.m_type != RT_TYPE_INT32) { + FileFormatException( + key.getRegistryName(), + ("legacy format: unexpected type " + + OUString::number(v.m_type) + " of value of field " + + reader.getFieldName(j) + " of enum type with key " + + sub.getName())); + } + mems.push_back( + EnumTypeEntity::Member( + reader.getFieldName(j), v.m_value.aLong)); + } + return new EnumTypeEntity(reader.isPublished(), mems); + } + case RT_TYPE_EXCEPTION: + { + OUString base; + switch (reader.getSuperTypeCount()) { + case 0: + break; + case 1: + base = reader.getSuperTypeName(0).replace('/', '.'); + break; + default: + throw FileFormatException( + key.getRegistryName(), + ("legacy format: unexpected number " + + OUString::number(reader.getSuperTypeCount()) + + " of super-types of exception type with key " + + sub.getName())); + } + std::vector< ExceptionTypeEntity::Member > mems; + sal_uInt16 n = reader.getFieldCount(); + for (sal_uInt16 j = 0; j != n; ++j) { + mems.push_back( + ExceptionTypeEntity::Member( + reader.getFieldName(j), + reader.getFieldTypeName(j).replace('/', '.'))); + } + return new ExceptionTypeEntity(reader.isPublished(), base, mems); + } + case RT_TYPE_TYPEDEF: + if (reader.getSuperTypeCount() != 1) { + throw FileFormatException( + key.getRegistryName(), + ("legacy format: unexpected number " + + OUString::number(reader.getSuperTypeCount()) + + " of super-types of typedef with key " + sub.getName())); + } + return new TypedefEntity( + reader.isPublished(), reader.getSuperTypeName(0).replace('/', '.')); + case RT_TYPE_SERVICE: + switch (reader.getSuperTypeCount()) { + case 0: + { + std::vector< OUString > mandServs; + std::vector< OUString > optServs; + std::vector< OUString > mandIfcs; + std::vector< OUString > optIfcs; + sal_uInt16 n = reader.getReferenceCount(); + for (sal_uInt16 j = 0; j != n; ++j) { + OUString refName( + reader.getReferenceTypeName(j).replace('/', '.')); + switch (reader.getReferenceSort(j)) { + case RT_REF_EXPORTS: + if ((reader.getReferenceFlags(j) & RT_ACCESS_OPTIONAL) + == 0) + { + mandServs.push_back(refName); + } else { + optServs.push_back(refName); + } + break; + case RT_REF_SUPPORTS: + if ((reader.getReferenceFlags(j) & RT_ACCESS_OPTIONAL) + == 0) + { + mandIfcs.push_back(refName); + } else { + optIfcs.push_back(refName); + } + break; + default: + throw FileFormatException( + key.getRegistryName(), + ("legacy format: unexpected mode " + + OUString::number(reader.getReferenceSort(j)) + + " of reference " + reader.getReferenceTypeName(j) + + " in service with key " + sub.getName())); + } + } + std::vector< AccumulationBasedServiceEntity::Property > props; + n = reader.getFieldCount(); + for (sal_uInt16 j = 0; j != n; ++j) { + RTFieldAccess acc = reader.getFieldFlags(j); + int attrs = 0; + if ((acc & RT_ACCESS_READONLY) != 0) { + attrs |= AccumulationBasedServiceEntity::Property:: + ATTRIBUTE_READ_ONLY; + } + if ((acc & RT_ACCESS_OPTIONAL) != 0) { + attrs |= AccumulationBasedServiceEntity::Property:: + ATTRIBUTE_OPTIONAL; + } + if ((acc & RT_ACCESS_MAYBEVOID) != 0) { + attrs |= AccumulationBasedServiceEntity::Property:: + ATTRIBUTE_MAYBE_VOID; + } + if ((acc & RT_ACCESS_BOUND) != 0) { + attrs |= AccumulationBasedServiceEntity::Property:: + ATTRIBUTE_BOUND; + } + if ((acc & RT_ACCESS_CONSTRAINED) != 0) { + attrs |= AccumulationBasedServiceEntity::Property:: + ATTRIBUTE_CONSTRAINED; + } + if ((acc & RT_ACCESS_TRANSIENT) != 0) { + attrs |= AccumulationBasedServiceEntity::Property:: + ATTRIBUTE_TRANSIENT; + } + if ((acc & RT_ACCESS_MAYBEAMBIGUOUS) != 0) { + attrs |= AccumulationBasedServiceEntity::Property:: + ATTRIBUTE_MAYBE_AMBIGUOUS; + } + if ((acc & RT_ACCESS_MAYBEDEFAULT) != 0) { + attrs |= AccumulationBasedServiceEntity::Property:: + ATTRIBUTE_MAYBE_DEFAULT; + } + if ((acc & RT_ACCESS_REMOVEABLE) != 0) { + attrs |= AccumulationBasedServiceEntity::Property:: + ATTRIBUTE_REMOVABLE; + } + props.push_back( + AccumulationBasedServiceEntity::Property( + reader.getFieldName(j), + reader.getFieldTypeName(j).replace('/', '.'), + static_cast< + AccumulationBasedServiceEntity::Property:: + Attributes >(attrs))); + } + return new AccumulationBasedServiceEntity( + reader.isPublished(), mandServs, optServs, mandIfcs, + optIfcs, props); + } + case 1: + { + std::vector< SingleInterfaceBasedServiceEntity::Constructor > + ctors; + sal_uInt16 n = reader.getMethodCount(); + if (n == 1 && reader.getMethodFlags(0) == 0 + && reader.getMethodName(0).isEmpty() + && reader.getMethodReturnTypeName(0) == "void" + && reader.getMethodParameterCount(0) == 0 + && reader.getMethodExceptionCount(0) == 0) + { + ctors.push_back( + SingleInterfaceBasedServiceEntity::Constructor()); + } else { + for (sal_uInt16 j = 0; j != n; ++j) { + if (reader.getMethodFlags(j) != RT_MODE_TWOWAY) { + throw FileFormatException( + key.getRegistryName(), + ("legacy format: unexpected mode " + + OUString::number(reader.getMethodFlags(j)) + + " of constructor " + reader.getMethodName(j) + + " in service with key " + sub.getName())); + } + std::vector< + SingleInterfaceBasedServiceEntity::Constructor:: + Parameter > params; + sal_uInt16 m = reader.getMethodParameterCount(j); + for (sal_uInt16 k = 0; k != m; ++k) { + RTParamMode mode + = reader.getMethodParameterFlags(j, k); + if ((mode & ~RT_PARAM_REST) != RT_PARAM_IN) { + throw FileFormatException( + key.getRegistryName(), + ("legacy format: unexpected mode " + + OUString::number(mode) + + " of parameter " + + reader.getMethodParameterName(j, k) + + " of constructor " + + reader.getMethodName(j) + + " in service with key " + + sub.getName())); + } + if ((mode & RT_PARAM_REST) != 0 + && !(m == 1 + && ((reader.getMethodParameterTypeName( + j, 1)) + == "any"))) + { + throw FileFormatException( + key.getRegistryName(), + ("legacy format: bad rest parameter " + + reader.getMethodParameterName(j, k) + + " of constructor " + + reader.getMethodName(j) + + " in service with key " + + sub.getName())); + } + params.push_back( + SingleInterfaceBasedServiceEntity::Constructor:: + Parameter( + reader.getMethodParameterName(j, k), + (reader.getMethodParameterTypeName(j, k). + replace('/', '.')), + (mode & RT_PARAM_REST) != 0)); + } + std::vector< OUString > excs; + m = reader.getMethodExceptionCount(j); + for (sal_uInt16 k = 0; k != m; ++k) { + excs.push_back( + reader.getMethodExceptionTypeName(j, k). + replace('/', '.')); + } + ctors.push_back( + SingleInterfaceBasedServiceEntity::Constructor( + reader.getMethodName(j), params, excs)); + } + } + return new SingleInterfaceBasedServiceEntity( + reader.isPublished(), + reader.getSuperTypeName(0).replace('/', '.'), ctors); + } + default: + throw FileFormatException( + key.getRegistryName(), + ("legacy format: unexpected number " + + OUString::number(reader.getSuperTypeCount()) + + " of super-types of service with key " + sub.getName())); + } + case RT_TYPE_SINGLETON: + { + if (reader.getSuperTypeCount() != 1) { + throw FileFormatException( + key.getRegistryName(), + ("legacy format: unexpected number " + + OUString::number(reader.getSuperTypeCount()) + + " of super-types of singleton with key " + + sub.getName())); + } + OUString basePath(reader.getSuperTypeName(0)); + OUString baseName(basePath.replace('/', '.')); + bool newStyle; + rtl::Reference< Entity > base(manager->findEntity(baseName)); + if (base.is()) { + switch (base->getSort()) { + case Entity::SORT_INTERFACE_TYPE: + newStyle = true; + break; + case Entity::SORT_ACCUMULATION_BASED_SERVICE: + newStyle = false; + break; + default: + throw FileFormatException( + key.getRegistryName(), + ("legacy format: unexpected sort " + + OUString::number(base->getSort()) + " of base " + + baseName + " of singleton with key " + + sub.getName())); + } + } else { + RegistryKey key2; + e = ucr.openKey(basePath, key2); + switch (e) { + case REG_NO_ERROR: + break; + case REG_KEY_NOT_EXISTS: + throw FileFormatException( + key.getRegistryName(), + ("legacy format: unknown super-type " + basePath + + " of super-type with key " + sub.getName())); + default: + throw FileFormatException( + key.getRegistryName(), + ("legacy format: cannot open ucr sub-key " + basePath + + ": " + OUString::number(e))); + } + std::vector< char > buf2; + typereg::Reader reader2(getReader(key2, &buf2)); + switch (reader2.getTypeClass()) { + case RT_TYPE_INTERFACE: + newStyle = true; + break; + case RT_TYPE_SERVICE: + newStyle = false; + break; + default: + throw FileFormatException( + key.getRegistryName(), + ("legacy format: unexpected type class " + + OUString::number(reader2.getTypeClass()) + + " of super-type with key " + key2.getName() + + " of singleton with key " + sub.getName())); + } + } + return newStyle + ? rtl::Reference< Entity >( + new InterfaceBasedSingletonEntity( + reader.isPublished(), baseName)) + : rtl::Reference< Entity >( + new ServiceBasedSingletonEntity( + reader.isPublished(), baseName)); + } + case RT_TYPE_CONSTANTS: + { + std::vector< ConstantGroupEntity::Member > mems; + sal_uInt16 n = reader.getFieldCount(); + for (sal_uInt16 j = 0; j != n; ++j) { + mems.push_back( + ConstantGroupEntity::Member( + reader.getFieldName(j), + translateConstantValue(sub, reader.getFieldValue(j)))); + } + return new ConstantGroupEntity(reader.isPublished(), mems); + } + default: + throw FileFormatException( + key.getRegistryName(), + ("legacy format: unexpected type class " + + OUString::number(reader.getTypeClass()) + " of key " + + sub.getName())); + } +} + +} + +LegacyProvider::LegacyProvider( + rtl::Reference< Manager > const & manager, OUString const & uri): + manager_(manager) +{ + Registry reg; + RegError e = reg.open(uri, REG_READONLY); + switch (e) { + case REG_NO_ERROR: + break; + case REG_REGISTRY_NOT_EXISTS: + throw NoSuchFileException(uri); + default: + throw FileFormatException( + uri, "cannot open legacy file: " + OUString::number(e)); + } + RegistryKey root; + e = reg.openRootKey(root); + if (e != REG_NO_ERROR) { + throw FileFormatException( + uri, "legacy format: cannot open root key: " + OUString::number(e)); + } + e = root.openKey("UCR", ucr_); + if (e != REG_NO_ERROR) { + throw FileFormatException( + uri, "legacy format: cannot open UCR key: " + OUString::number(e)); + } +} + +rtl::Reference< MapCursor > LegacyProvider::createRootCursor() const { + return new Cursor(manager_, ucr_, ucr_); +} + +rtl::Reference< Entity > LegacyProvider::findEntity(rtl::OUString const & name) + const +{ + return readEntity(manager_, ucr_, ucr_, name.replace('.', '/'), true); +} + +LegacyProvider::~LegacyProvider() throw () {} + +} + +/* vim:set shiftwidth=4 softtabstop=4 expandtab: */ diff --git a/unoidl/source/reg2unoidl.cxx b/unoidl/source/reg2unoidl.cxx new file mode 100644 index 000000000000..b0a013d68a5f --- /dev/null +++ b/unoidl/source/reg2unoidl.cxx @@ -0,0 +1,786 @@ +/* -*- Mode: C++; tab-width: 4; indent-tabs-mode: nil; c-basic-offset: 4 -*- */ +/* + * This file is part of the LibreOffice project. + * + * This Source Code Form is subject to the terms of the Mozilla Public + * License, v. 2.0. If a copy of the MPL was not distributed with this + * file, You can obtain one at http://mozilla.org/MPL/2.0/. + */ + +#include "sal/config.h" + +#include <cassert> +#include <cstddef> +#include <cstdlib> +#include <iostream> +#include <map> +#include <utility> +#include <vector> + +#include "osl/endian.h" +#include "osl/file.h" +#include "osl/file.hxx" +#include "osl/process.h" +#include "rtl/process.h" +#include "rtl/string.hxx" +#include "rtl/textenc.h" +#include "rtl/textcvt.h" +#include "rtl/ustring.hxx" +#include "sal/macros.h" +#include "sal/main.h" +#include "unoidl/unoidl.hxx" + +namespace { + +OUString getArgumentUri(sal_uInt32 argument) { + OUString arg; + rtl_getAppCommandArg(argument, &arg.pData); + OUString url; + osl::FileBase::RC e1 = osl::FileBase::getFileURLFromSystemPath(arg, url); + if (e1 != osl::FileBase::E_None) { + std::cerr + << "Cannot convert \"" << arg << "\" to file URL, error code " + << +e1 << std::endl; + std::exit(EXIT_FAILURE); + } + OUString cwd; + oslProcessError e2 = osl_getProcessWorkingDir(&cwd.pData); + if (e2 != osl_Process_E_None) { + std::cerr + << "Cannot obtain working directory, error code " << +e2 + << std::endl; + std::exit(EXIT_FAILURE); + } + OUString abs; + e1 = osl::FileBase::getAbsoluteFileURL(cwd, url, abs); + if (e1 != osl::FileBase::E_None) { + std::cerr + << "Cannot make \"" << url + << "\" into an absolute file URL, error code " << +e1 << std::endl; + std::exit(EXIT_FAILURE); + } + return abs; +} + +rtl::Reference< unoidl::Provider > load( + rtl::Reference< unoidl::Manager > const & manager, OUString const & uri) +{ + try { + return unoidl::loadProvider(manager, uri); + } catch (unoidl::NoSuchFileException &) { + std::cerr << "Input <" << uri << "> does not exist" << std::endl; + std::exit(EXIT_FAILURE); + } catch (unoidl::FileFormatException & e) { + std::cerr + << "Cannot read input <" << uri << ">: " << e.getDetail() + << std::endl; + std::exit(EXIT_FAILURE); + } +} + +sal_uInt64 getOffset(osl::File & file) { + sal_uInt64 off; + osl::FileBase::RC e = file.getPos(off); + if (e != osl::FileBase::E_None) { + std::cerr + << "Cannot determine current position in <" << file.getURL() + << ">, error code " << +e << std::endl; + std::exit(EXIT_FAILURE); + } + return off; +} + +void write(osl::File & file, void const * buffer, sal_uInt64 size) { + sal_uInt64 n; + osl::FileBase::RC e = file.write(buffer, size, n); + if (e != osl::FileBase::E_None) { + std::cerr + << "Cannot write to <" << file.getURL() << ">, error code " << +e + << std::endl; + std::exit(EXIT_FAILURE); + } + if (n != size) { + std::cerr + << "Bad write of " << n << " instead of " << size << " bytes to <" + << file.getURL() << '>' << std::endl; + std::exit(EXIT_FAILURE); + } +} + +void write8(osl::File & file, sal_uInt64 value) { + if (value > 0xFF) { + std::cerr + << "Cannot write value >= 2^8; input is too large" << std::endl; + std::exit(EXIT_FAILURE); + } + unsigned char buf[1]; + buf[0] = value & 0xFF; + write(file, buf, SAL_N_ELEMENTS(buf)); +} + +void write16(osl::File & file, sal_uInt64 value) { + if (value > 0xFFFF) { + std::cerr + << "Cannot write value >= 2^16; input is too large" << std::endl; + std::exit(EXIT_FAILURE); + } + unsigned char buf[2]; + buf[0] = value & 0xFF; + buf[1] = (value >> 8) & 0xFF; + write(file, buf, SAL_N_ELEMENTS(buf)); +} + +void write32(osl::File & file, sal_uInt64 value) { + if (value > 0xFFFFFFFF) { + std::cerr + << "Cannot write value >= 2^32; input is too large" << std::endl; + std::exit(EXIT_FAILURE); + } + unsigned char buf[4]; + buf[0] = value & 0xFF; + buf[1] = (value >> 8) & 0xFF; + buf[2] = (value >> 16) & 0xFF; + buf[3] = (value >> 24) & 0xFF; + write(file, buf, SAL_N_ELEMENTS(buf)); +} + +void write64(osl::File & file, sal_uInt64 value) { + unsigned char buf[8]; + buf[0] = value & 0xFF; + buf[1] = (value >> 8) & 0xFF; + buf[2] = (value >> 16) & 0xFF; + buf[3] = (value >> 24) & 0xFF; + buf[3] = (value >> 32) & 0xFF; + buf[3] = (value >> 40) & 0xFF; + buf[3] = (value >> 48) & 0xFF; + buf[3] = (value >> 56) & 0xFF; + write(file, buf, SAL_N_ELEMENTS(buf)); +} + +void writeIso60599Binary32(osl::File & file, float value) { + union { + unsigned char buf[4]; + float f; // assuming float is ISO 60599 binary32 + } sa; + sa.f = value; +#if defined OSL_BIGENDIAN + std::swap(sa.buf[0], sa.buf[3]); + std::swap(sa.buf[1], sa.buf[2]); +#endif + write(file, sa.buf, SAL_N_ELEMENTS(sa.buf)); +} + +void writeIso60599Binary64(osl::File & file, double value) { + union { + unsigned char buf[8]; + float d; // assuming double is ISO 60599 binary64 + } sa; + sa.d = value; +#if defined OSL_BIGENDIAN + std::swap(sa.buf[0], sa.buf[7]); + std::swap(sa.buf[1], sa.buf[6]); + std::swap(sa.buf[2], sa.buf[5]); + std::swap(sa.buf[3], sa.buf[4]); +#endif + write(file, sa.buf, SAL_N_ELEMENTS(sa.buf)); +} + +OString toAscii(OUString const & name) { + OString ascii; + if (!name.convertToString( + &ascii, RTL_TEXTENCODING_ASCII_US, + (RTL_UNICODETOTEXT_FLAGS_UNDEFINED_ERROR + | RTL_UNICODETOTEXT_FLAGS_INVALID_ERROR))) + { + std::cerr + << "Cannot convert \"" << name << "\" to US ASCII" << std::endl; + std::exit(EXIT_FAILURE); + } + return ascii; +} + +sal_uInt64 writeNameNul(osl::File & file, OUString const & name) { + OString ascii(toAscii(name)); + if (ascii.indexOf('\0') != -1) { + std::cerr + << "Name \"" << ascii << "\" contains NUL characters" << std::endl; + std::exit(EXIT_FAILURE); + } + sal_uInt64 off = getOffset(file); + write(file, ascii.getStr(), ascii.getLength() + 1); + return off; +} + +void writeNameLen(osl::File & file, OUString const & name) { + static std::map< OUString, sal_uInt64 > reuse; + std::map< OUString, sal_uInt64 >::iterator i(reuse.find(name)); + if (i == reuse.end()) { + reuse.insert(std::make_pair(name, getOffset(file))); + OString ascii(toAscii(name)); + assert( + (static_cast< sal_uInt64 >(ascii.getLength()) & 0x80000000) == 0); + write32( + file, static_cast< sal_uInt64 >(ascii.getLength()) | 0x80000000); + write(file, ascii.getStr(), ascii.getLength()); + } else { + write32(file, i->second); + } +} + +void writeKind( + osl::File & file, + rtl::Reference< unoidl::PublishableEntity > const & entity, + bool flag = false) +{ + assert(entity.is()); + sal_uInt64 v = entity->getSort(); + if (entity->isPublished()) { + v |= 0x80; + } + if (false /*TODO: deprecated */) { + v |= 0x40; + } + if (flag) { + v |= 0x20; + } + write8(file, v); +} + +sal_uInt64 writeMap( + osl::File & file, rtl::Reference< unoidl::MapCursor > const & cursor, + std::size_t * rootSize) +{ + assert(cursor.is()); + struct Item { + explicit Item(rtl::Reference< unoidl::Entity > const & theEntity): + entity(theEntity) + {} + rtl::Reference< unoidl::Entity > entity; + sal_uInt64 nameOffset; + sal_uInt64 dataOffset; + }; + std::map< OUString, Item > map; + for (;;) { + OUString name; + rtl::Reference< unoidl::Entity > ent(cursor->getNext(&name)); + if (!ent.is()) { + break; + } + if (!map.insert(std::make_pair(name, Item(ent))).second) { + std::cout << "Duplicate name \"" << name << '"' << std::endl; + std::exit(EXIT_FAILURE); + } + } + for (std::map< OUString, Item >::iterator i(map.begin()); i != map.end(); + ++i) + { + switch (i->second.entity->getSort()) { + case unoidl::Entity::SORT_MODULE: + { + rtl::Reference< unoidl::ModuleEntity > ent2( + static_cast< unoidl::ModuleEntity * >( + i->second.entity.get())); + i->second.dataOffset = writeMap(file, ent2->createCursor(), 0); + break; + } + case unoidl::Entity::SORT_ENUM_TYPE: + { + rtl::Reference< unoidl::EnumTypeEntity > ent2( + static_cast< unoidl::EnumTypeEntity * >( + i->second.entity.get())); + i->second.dataOffset = getOffset(file); + writeKind(file, ent2.get()); + write32(file, ent2->getMembers().size()); + for (std::vector< unoidl::EnumTypeEntity::Member >:: + const_iterator j(ent2->getMembers().begin()); + j != ent2->getMembers().end(); ++j) + { + writeNameLen(file, j->name); + write32(file, static_cast< sal_uInt32 >(j->value)); + } + break; + } + case unoidl::Entity::SORT_PLAIN_STRUCT_TYPE: + { + rtl::Reference< unoidl::PlainStructTypeEntity > ent2( + static_cast< unoidl::PlainStructTypeEntity * >( + i->second.entity.get())); + i->second.dataOffset = getOffset(file); + writeKind(file, ent2.get(), !ent2->getDirectBase().isEmpty()); + if (!ent2->getDirectBase().isEmpty()) { + writeNameLen(file, ent2->getDirectBase()); + } + write32(file, ent2->getDirectMembers().size()); + for (std::vector< unoidl::PlainStructTypeEntity::Member >:: + const_iterator j(ent2->getDirectMembers().begin()); + j != ent2->getDirectMembers().end(); ++j) + { + writeNameLen(file, j->name); + writeNameLen(file, j->type); + } + break; + } + case unoidl::Entity::SORT_POLYMORPHIC_STRUCT_TYPE_TEMPLATE: + { + rtl::Reference< unoidl::PolymorphicStructTypeTemplateEntity > + ent2( + static_cast< + unoidl::PolymorphicStructTypeTemplateEntity * >( + i->second.entity.get())); + i->second.dataOffset = getOffset(file); + writeKind(file, ent2.get()); + write32(file, ent2->getTypeParameters().size()); + for (std::vector< OUString >::const_iterator j( + ent2->getTypeParameters().begin()); + j != ent2->getTypeParameters().end(); ++j) + { + writeNameLen(file, *j); + } + write32(file, ent2->getMembers().size()); + for (std::vector< + unoidl::PolymorphicStructTypeTemplateEntity::Member >:: + const_iterator j( + ent2->getMembers().begin()); + j != ent2->getMembers().end(); ++j) + { + sal_uInt64 f = 0; + if (j->parameterized) { + f |= 0x01; + } + write8(file, f); + writeNameLen(file, j->name); + writeNameLen(file, j->type); + } + break; + } + case unoidl::Entity::SORT_EXCEPTION_TYPE: + { + rtl::Reference< unoidl::ExceptionTypeEntity > ent2( + static_cast< unoidl::ExceptionTypeEntity * >( + i->second.entity.get())); + i->second.dataOffset = getOffset(file); + writeKind(file, ent2.get(), !ent2->getDirectBase().isEmpty()); + if (!ent2->getDirectBase().isEmpty()) { + writeNameLen(file, ent2->getDirectBase()); + } + write32(file, ent2->getDirectMembers().size()); + for (std::vector< unoidl::ExceptionTypeEntity::Member >:: + const_iterator j(ent2->getDirectMembers().begin()); + j != ent2->getDirectMembers().end(); ++j) + { + writeNameLen(file, j->name); + writeNameLen(file, j->type); + } + break; + } + case unoidl::Entity::SORT_INTERFACE_TYPE: + { + rtl::Reference< unoidl::InterfaceTypeEntity > ent2( + static_cast< unoidl::InterfaceTypeEntity * >( + i->second.entity.get())); + i->second.dataOffset = getOffset(file); + writeKind(file, ent2.get()); + write32(file, ent2->getDirectMandatoryBases().size()); + for (std::vector< OUString >::const_iterator j( + ent2->getDirectMandatoryBases().begin()); + j != ent2->getDirectMandatoryBases().end(); ++j) + { + writeNameLen(file, *j); + } + write32(file, ent2->getDirectOptionalBases().size()); + for (std::vector< OUString >::const_iterator j( + ent2->getDirectOptionalBases().begin()); + j != ent2->getDirectOptionalBases().end(); ++j) + { + writeNameLen(file, *j); + } + write32(file, ent2->getDirectAttributes().size()); + for (std::vector< unoidl::InterfaceTypeEntity::Attribute >:: + const_iterator j(ent2->getDirectAttributes().begin()); + j != ent2->getDirectAttributes().end(); ++j) + { + sal_uInt64 f = 0; + if (j->bound) { + f |= 0x01; + } + if (j->readOnly) { + f |= 0x02; + } + write8(file, f); + writeNameLen(file, j->name); + writeNameLen(file, j->type); + write32(file, j->getExceptions.size()); + for (std::vector< OUString >::const_iterator k( + j->getExceptions.begin()); + k != j->getExceptions.end(); ++k) + { + writeNameLen(file, *k); + } + if (!j->readOnly) { + write32(file, j->setExceptions.size()); + for (std::vector< OUString >::const_iterator k( + j->setExceptions.begin()); + k != j->setExceptions.end(); ++k) + { + writeNameLen(file, *k); + } + } + } + write32(file, ent2->getDirectMethods().size()); + for (std::vector< unoidl::InterfaceTypeEntity::Method >:: + const_iterator j(ent2->getDirectMethods().begin()); + j != ent2->getDirectMethods().end(); ++j) + { + writeNameLen(file, j->name); + writeNameLen(file, j->returnType); + write32(file, j->parameters.size()); + for (std::vector< + unoidl::InterfaceTypeEntity::Method::Parameter >:: + const_iterator k(j->parameters.begin()); + k != j->parameters.end(); ++k) + { + write8(file, k->direction); + writeNameLen(file, k->name); + writeNameLen(file, k->type); + } + write32(file, j->exceptions.size()); + for (std::vector< OUString >::const_iterator k( + j->exceptions.begin()); + k != j->exceptions.end(); ++k) + { + writeNameLen(file, *k); + } + } + break; + } + case unoidl::Entity::SORT_TYPEDEF: + { + rtl::Reference< unoidl::TypedefEntity > ent2( + static_cast< unoidl::TypedefEntity * >( + i->second.entity.get())); + i->second.dataOffset = getOffset(file); + writeKind(file, ent2.get()); + writeNameLen(file, ent2->getType()); + break; + } + case unoidl::Entity::SORT_CONSTANT_GROUP: + { + rtl::Reference< unoidl::ConstantGroupEntity > ent2( + static_cast< unoidl::ConstantGroupEntity * >( + i->second.entity.get())); + struct ConstItem { + explicit ConstItem( + unoidl::ConstantValue const & theConstant): + constant(theConstant) + {} + unoidl::ConstantValue constant; + sal_uInt64 nameOffset; + sal_uInt64 dataOffset; + }; + std::map< OUString, ConstItem > cmap; + for (std::vector< unoidl::ConstantGroupEntity::Member >:: + const_iterator j(ent2->getMembers().begin()); + j != ent2->getMembers().end(); ++j) + { + if (!cmap.insert( + std::make_pair(j->name, ConstItem(j->value))). + second) + { + std::cout + << "Duplicate constant group member name \"" + << j->name << '"' << std::endl; + std::exit(EXIT_FAILURE); + } + } + for (std::map< OUString, ConstItem >::iterator j(cmap.begin()); + j != cmap.end(); ++j) + { + j->second.dataOffset = getOffset(file); + sal_uInt64 v = j->second.constant.type; + if (false /*TODO: deprecated */) { + v |= 0x80; + } + write8(file, v); + switch (j->second.constant.type) { + case unoidl::ConstantValue::TYPE_BOOLEAN: + write8(file, j->second.constant.booleanValue ? 1 : 0); + break; + case unoidl::ConstantValue::TYPE_BYTE: + write8( + file, + static_cast< sal_uInt8 >( + j->second.constant.byteValue)); + break; + case unoidl::ConstantValue::TYPE_SHORT: + write16( + file, + static_cast< sal_uInt16 >( + j->second.constant.shortValue)); + break; + case unoidl::ConstantValue::TYPE_UNSIGNED_SHORT: + write16(file, j->second.constant.unsignedShortValue); + break; + case unoidl::ConstantValue::TYPE_LONG: + write32( + file, + static_cast< sal_uInt32 >( + j->second.constant.longValue)); + break; + case unoidl::ConstantValue::TYPE_UNSIGNED_LONG: + write32(file, j->second.constant.unsignedLongValue); + break; + case unoidl::ConstantValue::TYPE_HYPER: + write64( + file, + static_cast< sal_uInt64 >( + j->second.constant.hyperValue)); + break; + case unoidl::ConstantValue::TYPE_UNSIGNED_HYPER: + write64(file, j->second.constant.unsignedHyperValue); + break; + case unoidl::ConstantValue::TYPE_FLOAT: + writeIso60599Binary32( + file, j->second.constant.floatValue); + break; + case unoidl::ConstantValue::TYPE_DOUBLE: + writeIso60599Binary64( + file, j->second.constant.doubleValue); + break; + default: + for (;;) { std::abort(); } // this cannot happen + } + } + for (std::map< OUString, ConstItem >::iterator j( + cmap.begin()); + j != cmap.end(); ++j) + { + j->second.nameOffset = writeNameNul(file, j->first); + } + i->second.dataOffset = getOffset(file); + writeKind(file, ent2.get()); + write32(file, cmap.size()); + // overflow from std::map::size_type -> sal_uInt64 is + // unrealistic + for (std::map< OUString, ConstItem >::iterator j( + cmap.begin()); + j != cmap.end(); ++j) + { + write32(file, j->second.nameOffset); + write32(file, j->second.dataOffset); + } + break; + } + case unoidl::Entity::SORT_SINGLE_INTERFACE_BASED_SERVICE: + { + rtl::Reference< unoidl::SingleInterfaceBasedServiceEntity > + ent2( + static_cast< + unoidl::SingleInterfaceBasedServiceEntity * >( + i->second.entity.get())); + i->second.dataOffset = getOffset(file); + bool dfltCtor = ent2->getConstructors().size() == 1 + && ent2->getConstructors()[0].defaultConstructor; + writeKind(file, ent2.get(), dfltCtor); + writeNameLen(file, ent2->getBase()); + if (!dfltCtor) { + write32(file, ent2->getConstructors().size()); + for (std::vector< + unoidl::SingleInterfaceBasedServiceEntity:: + Constructor >::const_iterator j( + ent2->getConstructors().begin()); + j != ent2->getConstructors().end(); ++j) + { + if (j->defaultConstructor) { + std::cout + << "Unexpected default constructor \"" + << j->name << '"' << std::endl; + std::exit(EXIT_FAILURE); + } + writeNameLen(file, j->name); + write32(file, j->parameters.size()); + for (std::vector< + unoidl::SingleInterfaceBasedServiceEntity:: + Constructor::Parameter >::const_iterator k( + j->parameters.begin()); + k != j->parameters.end(); ++k) + { + sal_uInt64 f = 0; + if (k->rest) { + f |= 0x04; + } + write8(file, f); + writeNameLen(file, k->name); + writeNameLen(file, k->type); + } + write32(file, j->exceptions.size()); + for (std::vector< OUString >::const_iterator k( + j->exceptions.begin()); + k != j->exceptions.end(); ++k) + { + writeNameLen(file, *k); + } + } + } + break; + } + case unoidl::Entity::SORT_ACCUMULATION_BASED_SERVICE: + { + rtl::Reference< unoidl::AccumulationBasedServiceEntity > ent2( + static_cast< unoidl::AccumulationBasedServiceEntity * >( + i->second.entity.get())); + i->second.dataOffset = getOffset(file); + writeKind(file, ent2.get()); + write32(file, ent2->getDirectMandatoryBaseServices().size()); + for (std::vector< OUString >::const_iterator j( + ent2->getDirectMandatoryBaseServices().begin()); + j != ent2->getDirectMandatoryBaseServices().end(); ++j) + { + writeNameLen(file, *j); + } + write32(file, ent2->getDirectOptionalBaseServices().size()); + for (std::vector< OUString >::const_iterator j( + ent2->getDirectOptionalBaseServices().begin()); + j != ent2->getDirectOptionalBaseServices().end(); ++j) + { + writeNameLen(file, *j); + } + write32(file, ent2->getDirectMandatoryBaseInterfaces().size()); + for (std::vector< OUString >::const_iterator j( + ent2->getDirectMandatoryBaseInterfaces().begin()); + j != ent2->getDirectMandatoryBaseInterfaces().end(); ++j) + { + writeNameLen(file, *j); + } + write32(file, ent2->getDirectOptionalBaseInterfaces().size()); + for (std::vector< OUString >::const_iterator j( + ent2->getDirectOptionalBaseInterfaces().begin()); + j != ent2->getDirectOptionalBaseInterfaces().end(); ++j) + { + writeNameLen(file, *j); + } + write32(file, ent2->getDirectProperties().size()); + for (std::vector< + unoidl::AccumulationBasedServiceEntity::Property >:: + const_iterator j( + ent2->getDirectProperties().begin()); + j != ent2->getDirectProperties().end(); ++j) + { + write16(file, static_cast< sal_uInt16 >(j->attributes)); + writeNameLen(file, j->name); + writeNameLen(file, j->type); + } + break; + } + case unoidl::Entity::SORT_INTERFACE_BASED_SINGLETON: + { + rtl::Reference< unoidl::InterfaceBasedSingletonEntity > ent2( + static_cast< unoidl::InterfaceBasedSingletonEntity * >( + i->second.entity.get())); + i->second.dataOffset = getOffset(file); + writeKind(file, ent2.get()); + writeNameLen(file, ent2->getBase()); + break; + } + case unoidl::Entity::SORT_SERVICE_BASED_SINGLETON: + { + rtl::Reference< unoidl::ServiceBasedSingletonEntity > ent2( + static_cast< unoidl::ServiceBasedSingletonEntity * >( + i->second.entity.get())); + i->second.dataOffset = getOffset(file); + writeKind(file, ent2.get()); + writeNameLen(file, ent2->getBase()); + break; + } + } + } + for (std::map< OUString, Item >::iterator i(map.begin()); i != map.end(); + ++i) + { + i->second.nameOffset = writeNameNul(file, i->first); + } + sal_uInt64 off = getOffset(file); + if (rootSize == 0) { + write8(file, 0); // SORT_MODULE + write32(file, map.size()); + // overflow from std::map::size_type -> sal_uInt64 is unrealistic + } else { + *rootSize = map.size(); + // overflow from std::map::size_type -> std::size_t is unrealistic + } + for (std::map< OUString, Item >::iterator i(map.begin()); i != map.end(); + ++i) + { + write32(file, i->second.nameOffset); + write32(file, i->second.dataOffset); + } + return off; +} + +} + +SAL_IMPLEMENT_MAIN() { + sal_uInt32 args = rtl_getAppCommandArgCount(); + if (args < 2) { + std::cerr + << "Usage: reg2unoidl <extra .rdb files> <.rdb file> <unoidl file>" + << std::endl; + std::exit(EXIT_FAILURE); + } + rtl::Reference< unoidl::Manager > mgr(new unoidl::Manager); + for (sal_uInt32 i = 0; i != args - 2; ++i) { + mgr->addProvider(load(mgr, getArgumentUri(i))); + } + rtl::Reference< unoidl::Provider > prov( + load(mgr, getArgumentUri(args - 2))); + osl::File f(getArgumentUri(args - 1)); + osl::FileBase::RC e = f.open(osl_File_OpenFlag_Write); + if (e == osl::FileBase::E_NOENT) { + e = f.open(osl_File_OpenFlag_Write | osl_File_OpenFlag_Create); + } + if (e != osl::FileBase::E_None) { + std::cerr + << "Cannot open <" << f.getURL() << "> for writing, error code " + << +e << std::endl; + std::exit(EXIT_FAILURE); + } + write(f, "UNOIDL\0\xFF", 8); + write32(f, 0); // root map offset + write32(f, 0); // root map size + sal_uInt64 off; + std::size_t size; + try { + off = writeMap(f, prov->createRootCursor(), &size); + } catch (unoidl::FileFormatException & e) { + std::cerr + << "Bad input <" << e.getUri() << ">: " << e.getDetail() + << std::endl; + std::exit(EXIT_FAILURE); + } + e = f.setSize(getOffset(f)); // truncate in case it already existed + if (e != osl::FileBase::E_None) { + std::cerr + << "Cannot set size of <" << f.getURL() << ">, error code " << +e + << std::endl; + std::exit(EXIT_FAILURE); + } + e = f.setPos(osl_Pos_Absolut, 8); + if (e != osl::FileBase::E_None) { + std::cerr + << "Cannot rewind current position in <" << f.getURL() + << ">, error code " << +e << std::endl; + std::exit(EXIT_FAILURE); + } + write32(f, off); + write32(f, size); + // overflow from std::map::size_type -> sal_uInt64 is unrealistic + e = f.close(); + if (e != osl::FileBase::E_None) { + std::cerr + << "Cannot close <" << f.getURL() << "> after writing, error code " + << +e << std::endl; + std::exit(EXIT_FAILURE); + } + return EXIT_SUCCESS; +} + +/* vim:set shiftwidth=4 softtabstop=4 expandtab: */ diff --git a/unoidl/source/unoidl.cxx b/unoidl/source/unoidl.cxx index f34eee0ae7a6..0ffeb6bdd014 100644 --- a/unoidl/source/unoidl.cxx +++ b/unoidl/source/unoidl.cxx @@ -13,6 +13,7 @@ #include "rtl/ref.hxx" #include "rtl/ustring.hxx" +#include "unoidl/legacyprovider.hxx" #include "unoidl/unoidl.hxx" #include "unoidl/unoidlprovider.hxx" @@ -57,10 +58,41 @@ ServiceBasedSingletonEntity::~ServiceBasedSingletonEntity() throw () {} Provider::~Provider() throw () {} -rtl::Reference< Provider > loadProvider(OUString const & uri) { - return new UnoidlProvider(uri); +rtl::Reference< Provider > loadProvider( + rtl::Reference< Manager > const & manager, OUString const & uri) +{ + try { + return new UnoidlProvider(uri); + } catch (FileFormatException & e) { + SAL_INFO( + "unoidl", + "FileFormatException \"" << e.getDetail() << "\", retrying <" << uri + << "> as legacy format"); + return new LegacyProvider(manager, uri); + } } +void Manager::addProvider(rtl::Reference< Provider > const & provider) { + assert(provider.is()); + providers_.push_back(provider); +} + +rtl::Reference< Entity > Manager::findEntity(rtl::OUString const & name) const { + //TODO: add caching + for (std::vector< rtl::Reference< Provider > >::const_iterator i( + providers_.begin()); + i != providers_.end(); ++i) + { + rtl::Reference< Entity > ent((*i)->findEntity(name)); + if (ent.is()) { + return ent; + } + } + return rtl::Reference< Entity >(); +} + +Manager::~Manager() throw () {} + } /* vim:set shiftwidth=4 softtabstop=4 expandtab: */ diff --git a/unoidl/source/unoidlprovider.cxx b/unoidl/source/unoidlprovider.cxx index 03daf5aac222..da3a147113d7 100644 --- a/unoidl/source/unoidlprovider.cxx +++ b/unoidl/source/unoidlprovider.cxx @@ -1251,6 +1251,13 @@ rtl::Reference< MapCursor > UnoidlProvider::createRootCursor() const { return new UnoidlCursor(file_, mapBegin_, mapSize_); } +rtl::Reference< Entity > UnoidlProvider::findEntity(OUString const & name) const +{ + bool cnst; + sal_uInt32 off = find(name, &cnst); + return off == 0 || cnst ? rtl::Reference< Entity >() : getEntity(off); +} + sal_uInt32 UnoidlProvider::find(OUString const & name, bool * constant) const { detail::MapEntry const * mapBegin = mapBegin_; sal_uInt32 mapSize = mapSize_; |