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
This commit is contained in:
parent
866ebf66b3
commit
12353c7386
@ -52,7 +52,7 @@ $(eval $(call gb_Helper_register_executables,NONE, \
|
|||||||
pdf2xml \
|
pdf2xml \
|
||||||
pdfunzip \
|
pdfunzip \
|
||||||
propex \
|
propex \
|
||||||
reg2bin \
|
reg2unoidl \
|
||||||
regsvrex \
|
regsvrex \
|
||||||
rsc \
|
rsc \
|
||||||
rscdep \
|
rscdep \
|
||||||
|
@ -35,7 +35,6 @@ ifneq (,$(filter DESKTOP,$(BUILD_TYPE)))
|
|||||||
|
|
||||||
$(eval $(call gb_Module_add_targets,registry,\
|
$(eval $(call gb_Module_add_targets,registry,\
|
||||||
StaticLibrary_registry_helper \
|
StaticLibrary_registry_helper \
|
||||||
Executable_reg2bin \
|
|
||||||
Executable_regmerge \
|
Executable_regmerge \
|
||||||
Executable_regview \
|
Executable_regview \
|
||||||
Executable_regcompare \
|
Executable_regcompare \
|
||||||
|
File diff suppressed because it is too large
Load Diff
@ -7,15 +7,16 @@
|
|||||||
# file, You can obtain one at http://mozilla.org/MPL/2.0/.
|
# 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, \
|
$(eval $(call gb_Executable_add_exception_objects,reg2unoidl, \
|
||||||
registry/tools/reg2bin \
|
unoidl/source/reg2unoidl \
|
||||||
))
|
))
|
||||||
|
|
||||||
$(eval $(call gb_Executable_use_libraries,reg2bin, \
|
$(eval $(call gb_Executable_use_libraries,reg2unoidl, \
|
||||||
reg \
|
|
||||||
sal \
|
sal \
|
||||||
|
salhelper \
|
||||||
|
unoidl \
|
||||||
))
|
))
|
||||||
|
|
||||||
# vim: set noet sw=4 ts=4:
|
# vim: set noet sw=4 ts=4:
|
@ -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_defs,unoidl,-DLO_DLLIMPLEMENTATION_UNOIDL))
|
||||||
|
|
||||||
$(eval $(call gb_Library_add_exception_objects,unoidl, \
|
$(eval $(call gb_Library_add_exception_objects,unoidl, \
|
||||||
|
unoidl/source/legacyprovider \
|
||||||
unoidl/source/unoidl \
|
unoidl/source/unoidl \
|
||||||
unoidl/source/unoidlprovider \
|
unoidl/source/unoidlprovider \
|
||||||
))
|
))
|
||||||
|
|
||||||
$(eval $(call gb_Library_use_libraries,unoidl, \
|
$(eval $(call gb_Library_use_libraries,unoidl, \
|
||||||
|
reg \
|
||||||
sal \
|
sal \
|
||||||
salhelper \
|
salhelper \
|
||||||
))
|
))
|
||||||
|
@ -10,6 +10,7 @@
|
|||||||
$(eval $(call gb_Module_Module,unoidl))
|
$(eval $(call gb_Module_Module,unoidl))
|
||||||
|
|
||||||
$(eval $(call gb_Module_add_targets,unoidl, \
|
$(eval $(call gb_Module_add_targets,unoidl, \
|
||||||
|
Executable_reg2unoidl \
|
||||||
Library_unoidl \
|
Library_unoidl \
|
||||||
Package_inc \
|
Package_inc \
|
||||||
))
|
))
|
||||||
|
@ -10,6 +10,7 @@
|
|||||||
$(eval $(call gb_Package_Package,unoidl_inc,$(SRCDIR)/unoidl/inc/unoidl))
|
$(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/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/unoidl.hxx,unoidl.hxx))
|
||||||
$(eval $(call gb_Package_add_file,unoidl_inc,inc/unoidl/unoidlprovider.hxx,unoidlprovider.hxx))
|
$(eval $(call gb_Package_add_file,unoidl_inc,inc/unoidl/unoidlprovider.hxx,unoidlprovider.hxx))
|
||||||
|
|
||||||
|
49
unoidl/inc/unoidl/legacyprovider.hxx
Normal file
49
unoidl/inc/unoidl/legacyprovider.hxx
Normal file
@ -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: */
|
@ -601,15 +601,34 @@ public:
|
|||||||
// throws FileFormatException:
|
// throws FileFormatException:
|
||||||
virtual rtl::Reference< MapCursor > createRootCursor() const = 0;
|
virtual rtl::Reference< MapCursor > createRootCursor() const = 0;
|
||||||
|
|
||||||
|
// throws FileFormatException:
|
||||||
|
virtual rtl::Reference< Entity > findEntity(rtl::OUString const & name)
|
||||||
|
const = 0;
|
||||||
|
|
||||||
protected:
|
protected:
|
||||||
SAL_DLLPRIVATE Provider() {}
|
SAL_DLLPRIVATE Provider() {}
|
||||||
|
|
||||||
virtual SAL_DLLPRIVATE ~Provider() throw ();
|
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:
|
// throws FileFormatException, NoSuchFileException:
|
||||||
LO_DLLPUBLIC_UNOIDL rtl::Reference< Provider > loadProvider(
|
LO_DLLPUBLIC_UNOIDL rtl::Reference< Provider > loadProvider(
|
||||||
rtl::OUString const & uri);
|
rtl::Reference< Manager > const & manager, rtl::OUString const & uri);
|
||||||
|
|
||||||
}
|
}
|
||||||
|
|
||||||
|
@ -33,6 +33,10 @@ public:
|
|||||||
// throws FileFormatException:
|
// throws FileFormatException:
|
||||||
virtual rtl::Reference< MapCursor > createRootCursor() const;
|
virtual rtl::Reference< MapCursor > createRootCursor() const;
|
||||||
|
|
||||||
|
// throws FileFormatException:
|
||||||
|
virtual rtl::Reference< Entity > findEntity(rtl::OUString const & name)
|
||||||
|
const;
|
||||||
|
|
||||||
// throws FileFormatException:
|
// throws FileFormatException:
|
||||||
sal_uInt32 find(rtl::OUString const & name, bool * constant = 0) const;
|
sal_uInt32 find(rtl::OUString const & name, bool * constant = 0) const;
|
||||||
|
|
||||||
|
@ -1,2 +1,2 @@
|
|||||||
un unoidl: sal salhelper NULL
|
un unoidl: registry sal salhelper NULL
|
||||||
un unoidl\prj nmake - all un_prj NULL
|
un unoidl\prj nmake - all un_prj NULL
|
||||||
|
778
unoidl/source/legacyprovider.cxx
Normal file
778
unoidl/source/legacyprovider.cxx
Normal file
@ -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: */
|
786
unoidl/source/reg2unoidl.cxx
Normal file
786
unoidl/source/reg2unoidl.cxx
Normal file
@ -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: */
|
@ -13,6 +13,7 @@
|
|||||||
|
|
||||||
#include "rtl/ref.hxx"
|
#include "rtl/ref.hxx"
|
||||||
#include "rtl/ustring.hxx"
|
#include "rtl/ustring.hxx"
|
||||||
|
#include "unoidl/legacyprovider.hxx"
|
||||||
#include "unoidl/unoidl.hxx"
|
#include "unoidl/unoidl.hxx"
|
||||||
#include "unoidl/unoidlprovider.hxx"
|
#include "unoidl/unoidlprovider.hxx"
|
||||||
|
|
||||||
@ -57,10 +58,41 @@ ServiceBasedSingletonEntity::~ServiceBasedSingletonEntity() throw () {}
|
|||||||
|
|
||||||
Provider::~Provider() throw () {}
|
Provider::~Provider() throw () {}
|
||||||
|
|
||||||
rtl::Reference< Provider > loadProvider(OUString const & uri) {
|
rtl::Reference< Provider > loadProvider(
|
||||||
return new UnoidlProvider(uri);
|
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: */
|
/* vim:set shiftwidth=4 softtabstop=4 expandtab: */
|
||||||
|
@ -1251,6 +1251,13 @@ rtl::Reference< MapCursor > UnoidlProvider::createRootCursor() const {
|
|||||||
return new UnoidlCursor(file_, mapBegin_, mapSize_);
|
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 {
|
sal_uInt32 UnoidlProvider::find(OUString const & name, bool * constant) const {
|
||||||
detail::MapEntry const * mapBegin = mapBegin_;
|
detail::MapEntry const * mapBegin = mapBegin_;
|
||||||
sal_uInt32 mapSize = mapSize_;
|
sal_uInt32 mapSize = mapSize_;
|
||||||
|
Loading…
x
Reference in New Issue
Block a user