summaryrefslogtreecommitdiff
diff options
context:
space:
mode:
-rw-r--r--Repository.mk2
-rw-r--r--solenv/gbuild/LinkTarget.mk4
-rw-r--r--solenv/gbuild/UnoApiTarget.mk4
-rw-r--r--unoidl/Executable_unoidl-write.mk (renamed from unoidl/Executable_reg2unoidl.mk)8
-rw-r--r--unoidl/Module_unoidl.mk2
-rw-r--r--unoidl/README21
-rwxr-xr-xunoidl/source/sourceprovider.cxx111
-rw-r--r--unoidl/source/unoidl-write.cxx (renamed from unoidl/source/reg2unoidl.cxx)323
8 files changed, 320 insertions, 155 deletions
diff --git a/Repository.mk b/Repository.mk
index cff654bac283..b3111fb8dd1d 100644
--- a/Repository.mk
+++ b/Repository.mk
@@ -48,7 +48,6 @@ $(eval $(call gb_Helper_register_executables,NONE, \
pdfunzip \
pocheck \
propex \
- reg2unoidl \
regsvrex \
rsc \
saxparser \
@@ -60,6 +59,7 @@ $(eval $(call gb_Helper_register_executables,NONE, \
treex \
uiex \
ulfex \
+ unoidl-write \
xrmex \
))
diff --git a/solenv/gbuild/LinkTarget.mk b/solenv/gbuild/LinkTarget.mk
index 44fc886ef0bd..b7150f0db44b 100644
--- a/solenv/gbuild/LinkTarget.mk
+++ b/solenv/gbuild/LinkTarget.mk
@@ -850,11 +850,11 @@ gb_BUILD_HELPER_LIBS := basegfx \
gb_BUILD_HELPER_TOOLS := cppumaker \
idlc \
- reg2unoidl \
regcompare \
regmerge \
rsc \
- svidl
+ svidl \
+ unoidl-write \
define gb_LinkTarget__is_build_lib
$(if $(filter $(1),$(foreach lib,$(gb_BUILD_HELPER_LIBS),$(call gb_Library_get_linktargetname,$(lib)))),$(true),$(false))
diff --git a/solenv/gbuild/UnoApiTarget.mk b/solenv/gbuild/UnoApiTarget.mk
index 97ec26411e14..92b812c15dd2 100644
--- a/solenv/gbuild/UnoApiTarget.mk
+++ b/solenv/gbuild/UnoApiTarget.mk
@@ -80,7 +80,7 @@ endif
gb_UnoApiTarget_REGCOMPAREDEPS := $(call gb_Executable_get_runtime_dependencies,regcompare)
gb_UnoApiTarget_REGCOMPARECOMMAND := SOLARBINDIR=$(OUTDIR_FOR_BUILD)/bin $(call gb_Executable_get_command,regcompare)
-gb_UnoApiTarget_REGMERGEDEPS := $(call gb_Executable_get_runtime_dependencies,regmerge) $(call gb_Executable_get_runtime_dependencies,reg2unoidl)
+gb_UnoApiTarget_REGMERGEDEPS := $(call gb_Executable_get_runtime_dependencies,regmerge) $(call gb_Executable_get_runtime_dependencies,unoidl-write)
gb_UnoApiTarget_REGMERGECOMMAND := SOLARBINDIR=$(OUTDIR_FOR_BUILD)/bin $(call gb_Executable_get_command,regmerge)
gb_UnoApiTarget_TYPESRDB := $(call gb_UnoApiTarget_get_target,types)
@@ -90,7 +90,7 @@ RESPONSEFILE=$(call var2file,$(shell $(gb_MKTEMP)),500,$(1).oldformat $(2) $(3))
$(gb_UnoApiTarget_REGMERGECOMMAND) @$${RESPONSEFILE} && \
rm -f $${RESPONSEFILE} && \
SOLARBINDIR=$(OUTDIR_FOR_BUILD)/bin \
- $(call gb_Executable_get_command,reg2unoidl) \
+ $(call gb_Executable_get_command,unoidl-write) \
$(foreach rdb,$(4),$(call gb_UnoApiTarget_get_target,$(rdb))) \
$(1).oldformat $(1)
endef
diff --git a/unoidl/Executable_reg2unoidl.mk b/unoidl/Executable_unoidl-write.mk
index 7f21a08454cb..8936955afb27 100644
--- a/unoidl/Executable_reg2unoidl.mk
+++ b/unoidl/Executable_unoidl-write.mk
@@ -7,13 +7,13 @@
# file, You can obtain one at http://mozilla.org/MPL/2.0/.
#
-$(eval $(call gb_Executable_Executable,reg2unoidl))
+$(eval $(call gb_Executable_Executable,unoidl-write))
-$(eval $(call gb_Executable_add_exception_objects,reg2unoidl, \
- unoidl/source/reg2unoidl \
+$(eval $(call gb_Executable_add_exception_objects,unoidl-write, \
+ unoidl/source/unoidl-write \
))
-$(eval $(call gb_Executable_use_libraries,reg2unoidl, \
+$(eval $(call gb_Executable_use_libraries,unoidl-write, \
sal \
salhelper \
unoidl \
diff --git a/unoidl/Module_unoidl.mk b/unoidl/Module_unoidl.mk
index 92a779e3770f..c0352579b4c9 100644
--- a/unoidl/Module_unoidl.mk
+++ b/unoidl/Module_unoidl.mk
@@ -14,7 +14,7 @@ $(eval $(call gb_Module_add_targets,unoidl, \
))
$(eval $(call gb_Module_add_targets_for_build,unoidl, \
- Executable_reg2unoidl \
+ Executable_unoidl-write \
))
# vim: set noet sw=4 ts=4:
diff --git a/unoidl/README b/unoidl/README
index 84246e9db876..cf405a12a34b 100644
--- a/unoidl/README
+++ b/unoidl/README
@@ -8,16 +8,16 @@ for both the new and the old types.rdb formats (unoidl::loadProvider tries both
implementations in turn for a given file, so the old format is still supported
transparently for now).
-Executable_reg2unoidl is a helper tool to convert from the old to the new
+Executable_unoidl-write is a helper tool to convert from the old to the new
types.rdb format. It is currently used at build-time. idlc still generates the
old format, and any new-format files (used at build-time only, or included in
installation sets in URE or program/types/ or as part of bundled extensions that
are created during the build and not merely included as pre-built .oxt files)
-are explicitly generated via reg2unoidl. The SDK is still designed to generate
-old-format files exclusively (especially, any non-bundled extensions will only
-contain old-format files for now; that allows to modify the new format further
-without having to worry about compatibility with multiple versions of that
-format).
+are explicitly generated via unoidl-write. The SDK is still designed to
+generate old-format files exclusively (especially, any non-bundled extensions
+will only contain old-format files for now; that allows to modify the new format
+further without having to worry about compatibility with multiple versions of
+that format).
== Specification of the new UNOIDL types.rdb format ==
@@ -56,7 +56,7 @@ The following definitions are used throughout:
* Map: zero or more Entries
The file starts with an 8 byte header, followed by information about the root
-map (reg2unoidl generates files in a single depth-first pass, so the root map
+map (unoidl-write generates files in a single depth-first pass, so the root map
itself is at the end of the file):
* 7 byte magic header "UNOIDL\xFF"
@@ -65,11 +65,12 @@ itself is at the end of the file):
* UInt32 number of entries of root Map
...
-Files generated by reg2unoidl follow that by a
+Files generated by unoidl-write follow that by a
- "\0** Created by LibreOffice " LIBO_VERSION_DOTTED " reg2unoidl **\0"
+ "\0** Created by LibreOffice " LIBO_VERSION_DOTTED " unoidl-write **\0"
-banner (cf. config_host/config_version.h.in), as a debugging aid.
+banner (cf. config_host/config_version.h.in), as a debugging aid. (Old versions
+used "reg2unoidl" instead of "unoidl-write" in that banner.)
Layout of per-entry payload in the root or a module Map:
diff --git a/unoidl/source/sourceprovider.cxx b/unoidl/source/sourceprovider.cxx
index ed44e40e79c0..ea7f1103db5e 100755
--- a/unoidl/source/sourceprovider.cxx
+++ b/unoidl/source/sourceprovider.cxx
@@ -14,6 +14,7 @@
#include <new>
#include "osl/file.h"
+#include "osl/file.hxx"
#include "osl/thread.h"
#include "rtl/character.hxx"
#include "rtl/ref.hxx"
@@ -86,6 +87,20 @@ private:
{ return rtl::Reference<Entity>(); } //TODO
};
+class SourceModuleEntity: public ModuleEntity {
+public:
+ SourceModuleEntity() {}
+
+private:
+ virtual ~SourceModuleEntity() throw () {}
+
+ virtual std::vector<OUString> getMemberNames() const
+ { return std::vector<OUString>(); } //TODO
+
+ virtual rtl::Reference< MapCursor > createCursor() const
+ { return new Cursor; }
+};
+
}
SourceProvider::SourceProvider(
@@ -147,53 +162,67 @@ rtl::Reference<Entity> SourceProvider::findEntity(OUString const & name) const {
throw FileFormatException( //TODO
"", "Illegal UNOIDL identifier \"" + name + "\"");
}
- OUString uri(uri_ + buf.makeStringAndClear() + ".idl");
- oslFileHandle handle;
- oslFileError e = osl_openFile(uri.pData, &handle, osl_File_OpenFlag_Read);
- switch (e) {
- case osl_File_E_None:
- break;
- case osl_File_E_NOENT:
- cache_.insert(
- std::map< OUString, rtl::Reference<Entity> >::value_type(
- name, rtl::Reference<Entity>()));
- return rtl::Reference<Entity>();
- default:
- throw FileFormatException(uri, "cannot open: " + OUString::number(e));
- }
- sal_uInt64 size;
- e = osl_getFileSize(handle, &size);
- if (e != osl_File_E_None) {
- oslFileError e2 = osl_closeFile(handle);
- SAL_WARN_IF(
- e2 != osl_File_E_None, "unoidl",
- "cannot close " << uri << ": " << +e2);
- throw FileFormatException(
- uri, "cannot get size: " + OUString::number(e));
- }
- void * address;
- e = osl_mapFile(handle, &address, size, 0, osl_File_MapFlag_RandomAccess);
- if (e != osl_File_E_None) {
- oslFileError e2 = osl_closeFile(handle);
- SAL_WARN_IF(
- e2 != osl_File_E_None, "unoidl",
- "cannot close " << uri << ": " << +e2);
- throw FileFormatException(uri, "cannot mmap: " + OUString::number(e));
- }
+ OUString uri(uri_ + buf.makeStringAndClear());
rtl::Reference<Entity> ent;
- try {
- ent = parse(manager_, name, uri, address, size);
- } catch (...) {
+ osl::DirectoryItem item;
+ osl::FileStatus status(osl_FileStatus_Mask_Type);
+ if (osl::DirectoryItem::get(uri, item) == osl::FileBase::E_None
+ && item.getFileStatus(status) == osl::FileBase::E_None
+ && status.getFileType() == osl::FileStatus::Directory)
+ {
+ ent = new SourceModuleEntity;
+ } else {
+ uri += ".idl";
+ oslFileHandle handle;
+ oslFileError e = osl_openFile(
+ uri.pData, &handle, osl_File_OpenFlag_Read);
+ switch (e) {
+ case osl_File_E_None:
+ break;
+ case osl_File_E_NOENT:
+ cache_.insert(
+ std::map< OUString, rtl::Reference<Entity> >::value_type(
+ name, rtl::Reference<Entity>()));
+ return rtl::Reference<Entity>();
+ default:
+ throw FileFormatException(
+ uri, "cannot open: " + OUString::number(e));
+ }
+ sal_uInt64 size;
+ e = osl_getFileSize(handle, &size);
+ if (e != osl_File_E_None) {
+ oslFileError e2 = osl_closeFile(handle);
+ SAL_WARN_IF(
+ e2 != osl_File_E_None, "unoidl",
+ "cannot close " << uri << ": " << +e2);
+ throw FileFormatException(
+ uri, "cannot get size: " + OUString::number(e));
+ }
+ void * address;
+ e = osl_mapFile(
+ handle, &address, size, 0, osl_File_MapFlag_RandomAccess);
+ if (e != osl_File_E_None) {
+ oslFileError e2 = osl_closeFile(handle);
+ SAL_WARN_IF(
+ e2 != osl_File_E_None, "unoidl",
+ "cannot close " << uri << ": " << +e2);
+ throw FileFormatException(
+ uri, "cannot mmap: " + OUString::number(e));
+ }
+ try {
+ ent = parse(manager_, name, uri, address, size);
+ } catch (...) {
+ e = osl_unmapMappedFile(handle, address, size);
+ SAL_WARN_IF(e != osl_File_E_None, "unoidl", "cannot unmap: " << +e);
+ e = osl_closeFile(handle);
+ SAL_WARN_IF(e != osl_File_E_None, "unoidl", "cannot close: " << +e);
+ throw;
+ }
e = osl_unmapMappedFile(handle, address, size);
SAL_WARN_IF(e != osl_File_E_None, "unoidl", "cannot unmap: " << +e);
e = osl_closeFile(handle);
SAL_WARN_IF(e != osl_File_E_None, "unoidl", "cannot close: " << +e);
- throw;
}
- e = osl_unmapMappedFile(handle, address, size);
- SAL_WARN_IF(e != osl_File_E_None, "unoidl", "cannot unmap: " << +e);
- e = osl_closeFile(handle);
- SAL_WARN_IF(e != osl_File_E_None, "unoidl", "cannot close: " << +e);
cache_.insert(
std::map< OUString, rtl::Reference<Entity> >::value_type(name, ent));
return ent;
diff --git a/unoidl/source/reg2unoidl.cxx b/unoidl/source/unoidl-write.cxx
index bf2b6d271ab2..dbb3ef7b7b7b 100644
--- a/unoidl/source/reg2unoidl.cxx
+++ b/unoidl/source/unoidl-write.cxx
@@ -34,9 +34,38 @@
namespace {
-OUString getArgumentUri(sal_uInt32 argument) {
+void badUsage() {
+ std::cerr
+ << "Usage:" << std::endl << std::endl
+ << " unoidl-write [<registries>] [@<entities file>] <unoidl file>"
+ << std::endl << std::endl
+ << ("where each <registry> is either a new- or legacy-format .rdb"
+ " file or a")
+ << std::endl
+ << ("root directory of an .idl file tree, and the UTF-8 encoded"
+ " <entities file>")
+ << std::endl
+ << ("contains zero or more space-separated names of (non-module)"
+ " entities to include")
+ << std::endl
+ << ("in the output, and, if omitted, defaults to the complete content"
+ " of the final")
+ << std::endl << "<registry>, if any." << std::endl;
+ std::exit(EXIT_FAILURE);
+}
+
+OUString getArgumentUri(sal_uInt32 argument, bool * entities) {
OUString arg;
rtl_getAppCommandArg(argument, &arg.pData);
+ if (arg.startsWith("@")) {
+ if (entities == 0) {
+ badUsage();
+ }
+ *entities = true;
+ arg = arg.copy(1);
+ } else if (entities != 0) {
+ *entities = false;
+ }
OUString url;
osl::FileBase::RC e1 = osl::FileBase::getFileURLFromSystemPath(arg, url);
if (e1 != osl::FileBase::E_None) {
@@ -64,22 +93,6 @@ OUString getArgumentUri(sal_uInt32 argument) {
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);
@@ -292,6 +305,7 @@ struct Item {
{}
rtl::Reference< unoidl::Entity > entity;
+ std::map< OUString, Item > module;
sal_uInt64 nameOffset;
sal_uInt64 dataOffset;
};
@@ -310,35 +324,139 @@ struct ConstItem {
sal_uInt64 dataOffset;
};
-sal_uInt64 writeMap(
- osl::File & file, rtl::Reference< unoidl::MapCursor > const & cursor,
- std::size_t * rootSize)
+void mapEntities(
+ rtl::Reference< unoidl::Manager > const & manager, OUString const & uri,
+ std::map< OUString, Item > & map)
{
- assert(cursor.is());
- std::map< OUString, Item > map;
+ assert(manager.is());
+ osl::File f(uri);
+ osl::FileBase::RC e = f.open(osl_File_OpenFlag_Read);
+ if (e != osl::FileBase::E_None) {
+ std::cerr
+ << "Cannot open <" << f.getURL() << "> for reading, error code "
+ << +e << std::endl;
+ std::exit(EXIT_FAILURE);
+ }
for (;;) {
- OUString name;
- rtl::Reference< unoidl::Entity > ent(cursor->getNext(&name));
- if (!ent.is()) {
+ sal_Bool eof;
+ e = f.isEndOfFile(&eof);
+ if (e != osl::FileBase::E_None) {
+ std::cerr
+ << "Cannot check <" << f.getURL() << "> for EOF, error code "
+ << +e << std::endl;
+ std::exit(EXIT_FAILURE);
+ }
+ if (eof) {
break;
}
- if (!map.insert(std::make_pair(name, Item(ent))).second) {
- std::cout << "Duplicate name \"" << name << '"' << std::endl;
+ rtl::ByteSequence s1;
+ e = f.readLine(s1);
+ if (e != osl::FileBase::E_None) {
+ std::cerr
+ << "Cannot read from <" << f.getURL() << ">, error code "
+ << +e << std::endl;
+ std::exit(EXIT_FAILURE);
+ }
+ OUString s2;
+ if (!rtl_convertStringToUString(
+ &s2.pData, reinterpret_cast< char const * >(s1.getConstArray()),
+ s1.getLength(), RTL_TEXTENCODING_UTF8,
+ (RTL_TEXTTOUNICODE_FLAGS_UNDEFINED_ERROR
+ | RTL_TEXTTOUNICODE_FLAGS_MBUNDEFINED_ERROR
+ | RTL_TEXTTOUNICODE_FLAGS_INVALID_ERROR)))
+ {
+ std::cerr
+ << "Cannot interpret line read from <" << f.getURL()
+ << "> as UTF-8" << std::endl;
std::exit(EXIT_FAILURE);
}
+ for (sal_Int32 i = 0; i != -1;) {
+ OUString t(s2.getToken(0, ' ', i));
+ if (!t.isEmpty()) {
+ rtl::Reference< unoidl::Entity > ent(manager->findEntity(t));
+ if (!ent.is()) {
+ std::cerr
+ << "Unknown entity \"" << t << "\" read from <"
+ << f.getURL() << ">" << std::endl;
+ std::exit(EXIT_FAILURE);
+ }
+ if (ent->getSort() == unoidl::Entity::SORT_MODULE) {
+ std::cerr
+ << "Module entity \"" << t << "\" read from <"
+ << f.getURL() << ">" << std::endl;
+ std::exit(EXIT_FAILURE);
+ }
+ std::map< OUString, Item > * map2 = &map;
+ for (sal_Int32 j = 0;;) {
+ OUString id(t.getToken(0, '.', j));
+ if (j == -1) {
+ map2->insert(std::make_pair(id, Item(ent)));
+ break;
+ }
+ std::map< OUString, Item >::iterator k(map2->find(id));
+ if (k == map2->end()) {
+ rtl::Reference< unoidl::Entity > ent2(
+ manager->findEntity(t.copy(0, j - 1)));
+ assert(ent2.is());
+ k = map2->insert(std::make_pair(id, Item(ent2))).first;
+ }
+ assert(
+ k->second.entity->getSort()
+ == unoidl::Entity::SORT_MODULE);
+ map2 = &k->second.module;
+ }
+ }
+ }
+ }
+ e = f.close();
+ if (e != osl::FileBase::E_None) {
+ std::cerr
+ << "Cannot close <" << f.getURL() << "> after reading, error code "
+ << +e << std::endl;
+ std::exit(EXIT_FAILURE);
}
+}
+
+void mapCursor(
+ rtl::Reference< unoidl::MapCursor > const & cursor,
+ std::map< OUString, Item > & map)
+{
+ if (cursor.is()) {
+ for (;;) {
+ OUString name;
+ rtl::Reference< unoidl::Entity > ent(cursor->getNext(&name));
+ if (!ent.is()) {
+ break;
+ }
+ std::pair< std::map< OUString, Item >::iterator, bool > i(
+ map.insert(std::make_pair(name, Item(ent))));
+ if (!i.second) {
+ std::cout << "Duplicate name \"" << name << '"' << std::endl;
+ std::exit(EXIT_FAILURE);
+ }
+ if (i.first->second.entity->getSort()
+ == unoidl::Entity::SORT_MODULE)
+ {
+ mapCursor(
+ rtl::Reference< unoidl::ModuleEntity >(
+ static_cast< unoidl::ModuleEntity * >(
+ i.first->second.entity.get()))->createCursor(),
+ i.first->second.module);
+ }
+ }
+ }
+}
+
+sal_uInt64 writeMap(
+ osl::File & file, std::map< OUString, Item > & map, std::size_t * rootSize)
+{
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;
- }
+ i->second.dataOffset = writeMap(file, i->second.module, 0);
+ break;
case unoidl::Entity::SORT_ENUM_TYPE:
{
rtl::Reference< unoidl::EnumTypeEntity > ent2(
@@ -905,73 +1023,90 @@ sal_uInt64 writeMap(
}
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\xFF\0", 8);
- write32(f, 0); // root map offset
- write32(f, 0); // root map size
- write(
- f,
- RTL_CONSTASCII_STRINGPARAM(
- "\0** Created by LibreOffice " LIBO_VERSION_DOTTED
- " reg2unoidl **\0"));
- sal_uInt64 off;
- std::size_t size;
try {
- off = writeMap(f, prov->createRootCursor(), &size);
+ sal_uInt32 args = rtl_getAppCommandArgCount();
+ if (args == 0) {
+ badUsage();
+ }
+ rtl::Reference< unoidl::Manager > mgr(new unoidl::Manager);
+ bool entities = false;
+ rtl::Reference< unoidl::Provider > prov;
+ std::map< OUString, Item > map;
+ for (sal_uInt32 i = 0; i != args - 1; ++i) {
+ assert(args > 1);
+ OUString uri(getArgumentUri(i, i == args - 2 ? &entities : 0));
+ if (entities) {
+ mapEntities(mgr, uri, map);
+ } else {
+ try {
+ prov = unoidl::loadProvider(mgr, uri);
+ } catch (unoidl::NoSuchFileException &) {
+ std::cerr
+ << "Input <" << uri << "> does not exist" << std::endl;
+ std::exit(EXIT_FAILURE);
+ }
+ mgr->addProvider(prov);
+ }
+ }
+ if (!entities) {
+ mapCursor(
+ (prov.is()
+ ? prov->createRootCursor()
+ : rtl::Reference< unoidl::MapCursor >()),
+ map);
+ }
+ osl::File f(getArgumentUri(args - 1, 0));
+ 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\xFF\0", 8);
+ write32(f, 0); // root map offset
+ write32(f, 0); // root map size
+ write(
+ f,
+ RTL_CONSTASCII_STRINGPARAM(
+ "\0** Created by LibreOffice " LIBO_VERSION_DOTTED
+ " unoidl-write **\0"));
+ std::size_t size;
+ sal_uInt64 off = writeMap(f, map, &size);
+ 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;
} catch (unoidl::FileFormatException & e1) {
std::cerr
<< "Bad input <" << e1.getUri() << ">: " << e1.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: */