summaryrefslogtreecommitdiff
diff options
context:
space:
mode:
authorStephan Bergmann <sbergman@redhat.com>2013-03-01 23:23:50 +0100
committerStephan Bergmann <sbergman@redhat.com>2013-03-01 23:23:50 +0100
commit12353c73868d26690aa4ac008ef5e9f2db8bc12c (patch)
tree5dc83b1d377e9b51c5af215e94b2ed9777cf762a
parent866ebf66b3a50b2d601825e4533898949d5b86c8 (diff)
WIP: Experimental new binary type.rdb format
Add LegacyProvider to read the old format (requires a provider Manager, to resolve singletons' bases, to decide whether they are interface- or service- based). Replace registry-based reg2bin with provider-based reg2unoidl. Change-Id: I5865e62308cc2d9c5439211ac803d84e93aab656
-rw-r--r--Repository.mk2
-rw-r--r--registry/Module_registry.mk1
-rw-r--r--registry/tools/reg2bin.cxx1464
-rw-r--r--unoidl/Executable_reg2unoidl.mk (renamed from registry/Executable_reg2bin.mk)11
-rw-r--r--unoidl/Library_unoidl.mk2
-rw-r--r--unoidl/Module_unoidl.mk1
-rw-r--r--unoidl/Package_inc.mk1
-rw-r--r--unoidl/inc/unoidl/legacyprovider.hxx49
-rw-r--r--unoidl/inc/unoidl/unoidl.hxx21
-rw-r--r--unoidl/inc/unoidl/unoidlprovider.hxx4
-rw-r--r--unoidl/prj/build.lst2
-rw-r--r--unoidl/source/legacyprovider.cxx778
-rw-r--r--unoidl/source/reg2unoidl.cxx786
-rw-r--r--unoidl/source/unoidl.cxx36
-rw-r--r--unoidl/source/unoidlprovider.cxx7
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_;