LCOV - code coverage report
Current view: top level - unoidl/source - unoidl-write.cxx (source / functions) Hit Total Coverage
Test: commit e02a6cb2c3e2b23b203b422e4e0680877f232636 Lines: 0 651 0.0 %
Date: 2014-04-14 Functions: 0 30 0.0 %
Legend: Lines: hit not hit

          Line data    Source code
       1             : /* -*- Mode: C++; tab-width: 4; indent-tabs-mode: nil; c-basic-offset: 4 -*- */
       2             : /*
       3             :  * This file is part of the LibreOffice project.
       4             :  *
       5             :  * This Source Code Form is subject to the terms of the Mozilla Public
       6             :  * License, v. 2.0. If a copy of the MPL was not distributed with this
       7             :  * file, You can obtain one at http://mozilla.org/MPL/2.0/.
       8             :  */
       9             : 
      10             : #include "sal/config.h"
      11             : 
      12             : #include <cassert>
      13             : #include <cstddef>
      14             : #include <cstdlib>
      15             : #include <iostream>
      16             : #include <map>
      17             : #include <utility>
      18             : #include <vector>
      19             : 
      20             : #include "config_version.h"
      21             : #include "osl/endian.h"
      22             : #include "osl/file.h"
      23             : #include "osl/file.hxx"
      24             : #include "osl/process.h"
      25             : #include "rtl/process.h"
      26             : #include "rtl/string.h"
      27             : #include "rtl/string.hxx"
      28             : #include "rtl/textenc.h"
      29             : #include "rtl/textcvt.h"
      30             : #include "rtl/ustring.hxx"
      31             : #include "sal/macros.h"
      32             : #include "sal/main.h"
      33             : #include "unoidl/unoidl.hxx"
      34             : 
      35             : namespace {
      36             : 
      37           0 : void badUsage() {
      38             :     std::cerr
      39           0 :         << "Usage:" << std::endl << std::endl
      40           0 :         << "  unoidl-write [<registries>] [@<entities file>] <unoidl file>"
      41           0 :         << std::endl << std::endl
      42             :         << ("where each <registry> is either a new- or legacy-format .rdb file,"
      43           0 :             " a single .idl")
      44           0 :         << std::endl
      45             :         << ("file, or a root directory of an .idl file tree; and the UTF-8"
      46           0 :             " encoded <entities")
      47           0 :         << std::endl
      48             :         << ("file> contains zero or more space-separated names of (non-module)"
      49           0 :             " entities to")
      50           0 :         << std::endl
      51             :         << ("include in the output, and, if omitted, defaults to the complete"
      52           0 :             " content of the")
      53           0 :         << std::endl << "last <registry>, if any." << std::endl;
      54           0 :     std::exit(EXIT_FAILURE);
      55             : }
      56             : 
      57           0 : OUString getArgumentUri(sal_uInt32 argument, bool * entities) {
      58           0 :     OUString arg;
      59           0 :     rtl_getAppCommandArg(argument, &arg.pData);
      60           0 :     if (arg.startsWith("@", &arg)) {
      61           0 :         if (entities == 0) {
      62           0 :             badUsage();
      63             :         }
      64           0 :         *entities = true;
      65           0 :     } else if (entities != 0) {
      66           0 :         *entities = false;
      67             :     }
      68           0 :     OUString url;
      69           0 :     osl::FileBase::RC e1 = osl::FileBase::getFileURLFromSystemPath(arg, url);
      70           0 :     if (e1 != osl::FileBase::E_None) {
      71             :         std::cerr
      72           0 :             << "Cannot convert \"" << arg << "\" to file URL, error code "
      73           0 :             << +e1 << std::endl;
      74           0 :         std::exit(EXIT_FAILURE);
      75             :     }
      76           0 :     OUString cwd;
      77           0 :     oslProcessError e2 = osl_getProcessWorkingDir(&cwd.pData);
      78           0 :     if (e2 != osl_Process_E_None) {
      79             :         std::cerr
      80           0 :             << "Cannot obtain working directory, error code " << +e2
      81           0 :             << std::endl;
      82           0 :         std::exit(EXIT_FAILURE);
      83             :     }
      84           0 :     OUString abs;
      85           0 :     e1 = osl::FileBase::getAbsoluteFileURL(cwd, url, abs);
      86           0 :     if (e1 != osl::FileBase::E_None) {
      87             :         std::cerr
      88           0 :             << "Cannot make \"" << url
      89           0 :             << "\" into an absolute file URL, error code " << +e1 << std::endl;
      90           0 :         std::exit(EXIT_FAILURE);
      91             :     }
      92           0 :     return abs;
      93             : }
      94             : 
      95           0 : sal_uInt64 getOffset(osl::File & file) {
      96             :     sal_uInt64 off;
      97           0 :     osl::FileBase::RC e = file.getPos(off);
      98           0 :     if (e != osl::FileBase::E_None) {
      99             :         std::cerr
     100           0 :             << "Cannot determine current position in <" << file.getURL()
     101           0 :             << ">, error code " << +e << std::endl;
     102           0 :         std::exit(EXIT_FAILURE);
     103             :     }
     104           0 :     return off;
     105             : }
     106             : 
     107           0 : void write(osl::File & file, void const * buffer, sal_uInt64 size) {
     108             :     sal_uInt64 n;
     109           0 :     osl::FileBase::RC e = file.write(buffer, size, n);
     110           0 :     if (e != osl::FileBase::E_None) {
     111             :         std::cerr
     112           0 :             << "Cannot write to <" << file.getURL() << ">, error code " << +e
     113           0 :             << std::endl;
     114           0 :         std::exit(EXIT_FAILURE);
     115             :     }
     116           0 :     if (n != size) {
     117             :         std::cerr
     118           0 :             << "Bad write of " << n << " instead of " << size << " bytes to <"
     119           0 :             << file.getURL() << '>' << std::endl;
     120           0 :         std::exit(EXIT_FAILURE);
     121             :     }
     122           0 : }
     123             : 
     124           0 : void write8(osl::File & file, sal_uInt64 value) {
     125           0 :     if (value > 0xFF) {
     126             :         std::cerr
     127           0 :             << "Cannot write value >= 2^8; input is too large" << std::endl;
     128           0 :         std::exit(EXIT_FAILURE);
     129             :     }
     130             :     unsigned char buf[1];
     131           0 :     buf[0] = value & 0xFF;
     132           0 :     write(file, buf, SAL_N_ELEMENTS(buf));
     133           0 : }
     134             : 
     135           0 : void write16(osl::File & file, sal_uInt64 value) {
     136           0 :     if (value > 0xFFFF) {
     137             :         std::cerr
     138           0 :             << "Cannot write value >= 2^16; input is too large" << std::endl;
     139           0 :         std::exit(EXIT_FAILURE);
     140             :     }
     141             :     unsigned char buf[2];
     142           0 :     buf[0] = value & 0xFF;
     143           0 :     buf[1] = (value >> 8) & 0xFF;
     144           0 :     write(file, buf, SAL_N_ELEMENTS(buf));
     145           0 : }
     146             : 
     147           0 : void write32(osl::File & file, sal_uInt64 value) {
     148           0 :     if (value > 0xFFFFFFFF) {
     149             :         std::cerr
     150           0 :             << "Cannot write value >= 2^32; input is too large" << std::endl;
     151           0 :         std::exit(EXIT_FAILURE);
     152             :     }
     153             :     unsigned char buf[4];
     154           0 :     buf[0] = value & 0xFF;
     155           0 :     buf[1] = (value >> 8) & 0xFF;
     156           0 :     buf[2] = (value >> 16) & 0xFF;
     157           0 :     buf[3] = (value >> 24) & 0xFF;
     158           0 :     write(file, buf, SAL_N_ELEMENTS(buf));
     159           0 : }
     160             : 
     161           0 : void write64(osl::File & file, sal_uInt64 value) {
     162             :     unsigned char buf[8];
     163           0 :     buf[0] = value & 0xFF;
     164           0 :     buf[1] = (value >> 8) & 0xFF;
     165           0 :     buf[2] = (value >> 16) & 0xFF;
     166           0 :     buf[3] = (value >> 24) & 0xFF;
     167           0 :     buf[4] = (value >> 32) & 0xFF;
     168           0 :     buf[5] = (value >> 40) & 0xFF;
     169           0 :     buf[6] = (value >> 48) & 0xFF;
     170           0 :     buf[7] = (value >> 56) & 0xFF;
     171           0 :     write(file, buf, SAL_N_ELEMENTS(buf));
     172           0 : }
     173             : 
     174           0 : void writeIso60599Binary32(osl::File & file, float value) {
     175             :     union {
     176             :         unsigned char buf[4];
     177             :         float f; // assuming float is ISO 60599 binary32
     178             :     } sa;
     179           0 :     sa.f = value;
     180             : #if defined OSL_BIGENDIAN
     181             :     std::swap(sa.buf[0], sa.buf[3]);
     182             :     std::swap(sa.buf[1], sa.buf[2]);
     183             : #endif
     184           0 :     write(file, sa.buf, SAL_N_ELEMENTS(sa.buf));
     185           0 : }
     186             : 
     187           0 : void writeIso60599Binary64(osl::File & file, double value) {
     188             :     union {
     189             :         unsigned char buf[8];
     190             :         float d; // assuming double is ISO 60599 binary64
     191             :     } sa;
     192           0 :     sa.d = value;
     193             : #if defined OSL_BIGENDIAN
     194             :     std::swap(sa.buf[0], sa.buf[7]);
     195             :     std::swap(sa.buf[1], sa.buf[6]);
     196             :     std::swap(sa.buf[2], sa.buf[5]);
     197             :     std::swap(sa.buf[3], sa.buf[4]);
     198             : #endif
     199           0 :     write(file, sa.buf, SAL_N_ELEMENTS(sa.buf));
     200           0 : }
     201             : 
     202           0 : OString toAscii(OUString const & name) {
     203           0 :     OString ascii;
     204           0 :     if (!name.convertToString(
     205             :             &ascii, RTL_TEXTENCODING_ASCII_US,
     206             :             (RTL_UNICODETOTEXT_FLAGS_UNDEFINED_ERROR
     207           0 :              | RTL_UNICODETOTEXT_FLAGS_INVALID_ERROR)))
     208             :     {
     209             :         std::cerr
     210           0 :             << "Cannot convert \"" << name << "\" to US ASCII" << std::endl;
     211           0 :         std::exit(EXIT_FAILURE);
     212             :     }
     213           0 :     return ascii;
     214             : }
     215             : 
     216           0 : OString toUtf8(OUString const & string) {
     217           0 :     OString ascii;
     218           0 :     if (!string.convertToString(
     219             :             &ascii, RTL_TEXTENCODING_UTF8,
     220             :             (RTL_UNICODETOTEXT_FLAGS_UNDEFINED_ERROR
     221           0 :              | RTL_UNICODETOTEXT_FLAGS_INVALID_ERROR)))
     222             :     {
     223             :         std::cerr
     224           0 :             << "Cannot convert \"" << string << "\" to UTF-8" << std::endl;
     225           0 :         std::exit(EXIT_FAILURE);
     226             :     }
     227           0 :     return ascii;
     228             : }
     229             : 
     230           0 : sal_uInt64 writeNulName(osl::File & file, OUString const & name) {
     231           0 :     OString ascii(toAscii(name));
     232           0 :     if (ascii.indexOf('\0') != -1) {
     233             :         std::cerr
     234           0 :             << "Name \"" << ascii << "\" contains NUL characters" << std::endl;
     235           0 :         std::exit(EXIT_FAILURE);
     236             :     }
     237           0 :     sal_uInt64 off = getOffset(file);
     238           0 :     write(file, ascii.getStr(), ascii.getLength() + 1);
     239           0 :     return off;
     240             : }
     241             : 
     242           0 : void writeIdxString(osl::File & file, OString const & string) {
     243           0 :     static std::map< OString, sal_uInt64 > reuse;
     244           0 :     std::map< OString, sal_uInt64 >::iterator i(reuse.find(string));
     245           0 :     if (i == reuse.end()) {
     246           0 :         reuse.insert(std::make_pair(string, getOffset(file)));
     247             :         assert(
     248             :             (static_cast< sal_uInt64 >(string.getLength()) & 0x80000000) == 0);
     249           0 :         write32(file, static_cast< sal_uInt64 >(string.getLength()));
     250           0 :         write(file, string.getStr(), string.getLength());
     251             :     } else {
     252           0 :         if ((i->second & 0x80000000) != 0) {
     253             :             std::cerr
     254           0 :                 << "Cannot write index 0x" << std::hex << i->second << std::dec
     255           0 :                 << " of \"" << string << "\"; input is too large" << std::endl;
     256           0 :             std::exit(EXIT_FAILURE);
     257             :         }
     258           0 :         write32(file, i->second | 0x80000000);
     259             :     }
     260           0 : }
     261             : 
     262           0 : void writeIdxName(osl::File & file, OUString const & name) {
     263           0 :     writeIdxString(file, toAscii(name));
     264           0 : }
     265             : 
     266           0 : void writeAnnotations(
     267             :     osl::File & file, bool annotate,
     268             :     std::vector< OUString > const & annotations)
     269             : {
     270             :     assert(annotate || annotations.empty());
     271           0 :     if (annotate) {
     272           0 :         write32(file, annotations.size());
     273             :             // overflow from std::vector::size_type -> sal_uInt64 is unrealistic
     274           0 :         for (std::vector< OUString >::const_iterator i(annotations.begin());
     275           0 :              i != annotations.end(); ++i)
     276             :         {
     277           0 :             writeIdxString(file, toUtf8(*i));
     278             :         }
     279             :     }
     280           0 : }
     281             : 
     282           0 : void writeKind(
     283             :     osl::File & file,
     284             :     rtl::Reference< unoidl::PublishableEntity > const & entity,
     285             :     bool annotated, bool flag = false)
     286             : {
     287             :     assert(entity.is());
     288           0 :     sal_uInt64 v = entity->getSort();
     289           0 :     if (entity->isPublished()) {
     290           0 :         v |= 0x80;
     291             :     }
     292           0 :     if (annotated) {
     293           0 :         v |= 0x40;
     294             :     }
     295           0 :     if (flag) {
     296           0 :         v |= 0x20;
     297             :     }
     298           0 :     write8(file, v);
     299           0 : }
     300             : 
     301           0 : struct Item {
     302           0 :     explicit Item(rtl::Reference< unoidl::Entity > const & theEntity):
     303           0 :         entity(theEntity), nameOffset(0), dataOffset(0)
     304           0 :     {}
     305             : 
     306             :     rtl::Reference< unoidl::Entity > entity;
     307             :     std::map< OUString, Item > module;
     308             :     sal_uInt64 nameOffset;
     309             :     sal_uInt64 dataOffset;
     310             : };
     311             : 
     312           0 : struct ConstItem {
     313           0 :     ConstItem(
     314             :         unoidl::ConstantValue const & theConstant,
     315             :         std::vector< OUString > const & theAnnotations):
     316             :         constant(theConstant), annotations(theAnnotations), nameOffset(0),
     317           0 :         dataOffset(0)
     318           0 :     {}
     319             : 
     320             :     unoidl::ConstantValue constant;
     321             :     std::vector< OUString > annotations;
     322             :     sal_uInt64 nameOffset;
     323             :     sal_uInt64 dataOffset;
     324             : };
     325             : 
     326           0 : void mapEntities(
     327             :     rtl::Reference< unoidl::Manager > const & manager, OUString const & uri,
     328             :     std::map< OUString, Item > & map)
     329             : {
     330             :     assert(manager.is());
     331           0 :     osl::File f(uri);
     332           0 :     osl::FileBase::RC e = f.open(osl_File_OpenFlag_Read);
     333           0 :     if (e != osl::FileBase::E_None) {
     334             :         std::cerr
     335           0 :             << "Cannot open <" << f.getURL() << "> for reading, error code "
     336           0 :             << +e << std::endl;
     337           0 :         std::exit(EXIT_FAILURE);
     338             :     }
     339             :     for (;;) {
     340             :         sal_Bool eof;
     341           0 :         e = f.isEndOfFile(&eof);
     342           0 :         if (e != osl::FileBase::E_None) {
     343             :             std::cerr
     344           0 :                 << "Cannot check <" << f.getURL() << "> for EOF, error code "
     345           0 :                 << +e << std::endl;
     346           0 :             std::exit(EXIT_FAILURE);
     347             :         }
     348           0 :         if (eof) {
     349           0 :             break;
     350             :         }
     351           0 :         rtl::ByteSequence s1;
     352           0 :         e = f.readLine(s1);
     353           0 :         if (e != osl::FileBase::E_None) {
     354             :             std::cerr
     355           0 :                 << "Cannot read from <" << f.getURL() << ">, error code "
     356           0 :                 << +e << std::endl;
     357           0 :             std::exit(EXIT_FAILURE);
     358             :         }
     359           0 :         OUString s2;
     360           0 :         if (!rtl_convertStringToUString(
     361           0 :                 &s2.pData, reinterpret_cast< char const * >(s1.getConstArray()),
     362             :                 s1.getLength(), RTL_TEXTENCODING_UTF8,
     363             :                 (RTL_TEXTTOUNICODE_FLAGS_UNDEFINED_ERROR
     364             :                  | RTL_TEXTTOUNICODE_FLAGS_MBUNDEFINED_ERROR
     365           0 :                  | RTL_TEXTTOUNICODE_FLAGS_INVALID_ERROR)))
     366             :         {
     367             :             std::cerr
     368           0 :                 << "Cannot interpret line read from <" << f.getURL()
     369           0 :                 << "> as UTF-8" << std::endl;
     370           0 :             std::exit(EXIT_FAILURE);
     371             :         }
     372           0 :         for (sal_Int32 i = 0; i != -1;) {
     373           0 :             OUString t(s2.getToken(0, ' ', i));
     374           0 :             if (!t.isEmpty()) {
     375           0 :                 rtl::Reference< unoidl::Entity > ent(manager->findEntity(t));
     376           0 :                 if (!ent.is()) {
     377             :                     std::cerr
     378           0 :                         << "Unknown entity \"" << t << "\" read from <"
     379           0 :                         << f.getURL() << ">" << std::endl;
     380           0 :                     std::exit(EXIT_FAILURE);
     381             :                 }
     382           0 :                 if (ent->getSort() == unoidl::Entity::SORT_MODULE) {
     383             :                     std::cerr
     384           0 :                         << "Module entity \"" << t << "\" read from <"
     385           0 :                         << f.getURL() << ">" << std::endl;
     386           0 :                     std::exit(EXIT_FAILURE);
     387             :                 }
     388           0 :                 std::map< OUString, Item > * map2 = &map;
     389           0 :                 for (sal_Int32 j = 0;;) {
     390           0 :                     OUString id(t.getToken(0, '.', j));
     391           0 :                     if (j == -1) {
     392           0 :                         map2->insert(std::make_pair(id, Item(ent)));
     393           0 :                         break;
     394             :                     }
     395           0 :                     std::map< OUString, Item >::iterator k(map2->find(id));
     396           0 :                     if (k == map2->end()) {
     397             :                         rtl::Reference< unoidl::Entity > ent2(
     398           0 :                             manager->findEntity(t.copy(0, j - 1)));
     399             :                         assert(ent2.is());
     400           0 :                         k = map2->insert(std::make_pair(id, Item(ent2))).first;
     401             :                     }
     402             :                     assert(
     403             :                         k->second.entity->getSort()
     404             :                         == unoidl::Entity::SORT_MODULE);
     405           0 :                     map2 = &k->second.module;
     406           0 :                 }
     407             :             }
     408           0 :         }
     409           0 :     }
     410           0 :     e = f.close();
     411           0 :     if (e != osl::FileBase::E_None) {
     412             :         std::cerr
     413           0 :             << "Cannot close <" << f.getURL() << "> after reading, error code "
     414           0 :             << +e << std::endl;
     415           0 :         std::exit(EXIT_FAILURE);
     416           0 :     }
     417           0 : }
     418             : 
     419           0 : void mapCursor(
     420             :     rtl::Reference< unoidl::MapCursor > const & cursor,
     421             :     std::map< OUString, Item > & map)
     422             : {
     423           0 :     if (cursor.is()) {
     424             :         for (;;) {
     425           0 :             OUString name;
     426           0 :             rtl::Reference< unoidl::Entity > ent(cursor->getNext(&name));
     427           0 :             if (!ent.is()) {
     428           0 :                 break;
     429             :             }
     430             :             std::pair< std::map< OUString, Item >::iterator, bool > i(
     431           0 :                 map.insert(std::make_pair(name, Item(ent))));
     432           0 :             if (!i.second) {
     433           0 :                 std::cout << "Duplicate name \"" << name << '"' << std::endl;
     434           0 :                 std::exit(EXIT_FAILURE);
     435             :             }
     436           0 :             if (i.first->second.entity->getSort()
     437             :                 == unoidl::Entity::SORT_MODULE)
     438             :             {
     439             :                 mapCursor(
     440             :                     rtl::Reference< unoidl::ModuleEntity >(
     441             :                         static_cast< unoidl::ModuleEntity * >(
     442           0 :                             i.first->second.entity.get()))->createCursor(),
     443           0 :                     i.first->second.module);
     444             :             }
     445           0 :         }
     446             :     }
     447           0 : }
     448             : 
     449           0 : sal_uInt64 writeMap(
     450             :     osl::File & file, std::map< OUString, Item > & map, std::size_t * rootSize)
     451             : {
     452           0 :     for (std::map< OUString, Item >::iterator i(map.begin()); i != map.end();
     453             :          ++i)
     454             :     {
     455           0 :         switch (i->second.entity->getSort()) {
     456             :         case unoidl::Entity::SORT_MODULE:
     457           0 :             i->second.dataOffset = writeMap(file, i->second.module, 0);
     458           0 :             break;
     459             :         case unoidl::Entity::SORT_ENUM_TYPE:
     460             :             {
     461             :                 rtl::Reference< unoidl::EnumTypeEntity > ent2(
     462             :                     static_cast< unoidl::EnumTypeEntity * >(
     463           0 :                         i->second.entity.get()));
     464           0 :                 bool ann = !ent2->getAnnotations().empty();
     465           0 :                 for (std::vector< unoidl::EnumTypeEntity::Member >::
     466           0 :                          const_iterator j(ent2->getMembers().begin());
     467           0 :                      !ann && j != ent2->getMembers().end(); ++j)
     468             :                 {
     469           0 :                     ann = !j->annotations.empty();
     470             :                 }
     471           0 :                 i->second.dataOffset = getOffset(file);
     472           0 :                 writeKind(file, ent2.get(), ann);
     473           0 :                 write32(file, ent2->getMembers().size());
     474           0 :                 for (std::vector< unoidl::EnumTypeEntity::Member >::
     475           0 :                          const_iterator j(ent2->getMembers().begin());
     476           0 :                      j != ent2->getMembers().end(); ++j)
     477             :                 {
     478           0 :                     writeIdxName(file, j->name);
     479           0 :                     write32(file, static_cast< sal_uInt32 >(j->value));
     480           0 :                     writeAnnotations(file, ann, j->annotations);
     481             :                 }
     482           0 :                 writeAnnotations(file, ann, ent2->getAnnotations());
     483           0 :                 break;
     484             :             }
     485             :         case unoidl::Entity::SORT_PLAIN_STRUCT_TYPE:
     486             :             {
     487             :                 rtl::Reference< unoidl::PlainStructTypeEntity > ent2(
     488             :                     static_cast< unoidl::PlainStructTypeEntity * >(
     489           0 :                         i->second.entity.get()));
     490           0 :                 bool ann = !ent2->getAnnotations().empty();
     491           0 :                 for (std::vector< unoidl::PlainStructTypeEntity::Member >::
     492           0 :                          const_iterator j(ent2->getDirectMembers().begin());
     493           0 :                      !ann && j != ent2->getDirectMembers().end(); ++j)
     494             :                 {
     495           0 :                     ann = !j->annotations.empty();
     496             :                 }
     497           0 :                 i->second.dataOffset = getOffset(file);
     498             :                 writeKind(
     499           0 :                     file, ent2.get(), ann, !ent2->getDirectBase().isEmpty());
     500           0 :                 if (!ent2->getDirectBase().isEmpty()) {
     501           0 :                     writeIdxName(file, ent2->getDirectBase());
     502             :                 }
     503           0 :                 write32(file, ent2->getDirectMembers().size());
     504           0 :                 for (std::vector< unoidl::PlainStructTypeEntity::Member >::
     505           0 :                          const_iterator j(ent2->getDirectMembers().begin());
     506           0 :                      j != ent2->getDirectMembers().end(); ++j)
     507             :                 {
     508           0 :                     writeIdxName(file, j->name);
     509           0 :                     writeIdxName(file, j->type);
     510           0 :                     writeAnnotations(file, ann, j->annotations);
     511             :                 }
     512           0 :                 writeAnnotations(file, ann, ent2->getAnnotations());
     513           0 :                 break;
     514             :             }
     515             :         case unoidl::Entity::SORT_POLYMORPHIC_STRUCT_TYPE_TEMPLATE:
     516             :             {
     517             :                 rtl::Reference< unoidl::PolymorphicStructTypeTemplateEntity >
     518             :                     ent2(
     519             :                         static_cast<
     520             :                         unoidl::PolymorphicStructTypeTemplateEntity * >(
     521           0 :                             i->second.entity.get()));
     522           0 :                 bool ann = !ent2->getAnnotations().empty();
     523           0 :                 for (std::vector<
     524             :                          unoidl::PolymorphicStructTypeTemplateEntity::Member >::
     525             :                          const_iterator j(
     526           0 :                              ent2->getMembers().begin());
     527           0 :                      !ann && j != ent2->getMembers().end(); ++j)
     528             :                 {
     529           0 :                     ann = !j->annotations.empty();
     530             :                 }
     531           0 :                 i->second.dataOffset = getOffset(file);
     532           0 :                 writeKind(file, ent2.get(), ann);
     533           0 :                 write32(file, ent2->getTypeParameters().size());
     534           0 :                 for (std::vector< OUString >::const_iterator j(
     535           0 :                          ent2->getTypeParameters().begin());
     536           0 :                      j != ent2->getTypeParameters().end(); ++j)
     537             :                 {
     538           0 :                     writeIdxName(file, *j);
     539             :                 }
     540           0 :                 write32(file, ent2->getMembers().size());
     541           0 :                 for (std::vector<
     542             :                          unoidl::PolymorphicStructTypeTemplateEntity::Member >::
     543             :                          const_iterator j(
     544           0 :                              ent2->getMembers().begin());
     545           0 :                      j != ent2->getMembers().end(); ++j)
     546             :                 {
     547           0 :                     sal_uInt64 f = 0;
     548           0 :                     if (j->parameterized) {
     549           0 :                         f |= 0x01;
     550             :                     }
     551           0 :                     write8(file, f);
     552           0 :                     writeIdxName(file, j->name);
     553           0 :                     writeIdxName(file, j->type);
     554           0 :                     writeAnnotations(file, ann, j->annotations);
     555             :                 }
     556           0 :                 writeAnnotations(file, ann, ent2->getAnnotations());
     557           0 :                 break;
     558             :             }
     559             :         case unoidl::Entity::SORT_EXCEPTION_TYPE:
     560             :             {
     561             :                 rtl::Reference< unoidl::ExceptionTypeEntity > ent2(
     562             :                     static_cast< unoidl::ExceptionTypeEntity * >(
     563           0 :                         i->second.entity.get()));
     564           0 :                 bool ann = !ent2->getAnnotations().empty();
     565           0 :                 for (std::vector< unoidl::ExceptionTypeEntity::Member >::
     566           0 :                          const_iterator j(ent2->getDirectMembers().begin());
     567           0 :                      !ann && j != ent2->getDirectMembers().end(); ++j)
     568             :                 {
     569           0 :                     ann = !j->annotations.empty();
     570             :                 }
     571           0 :                 i->second.dataOffset = getOffset(file);
     572             :                 writeKind(
     573           0 :                     file, ent2.get(), ann, !ent2->getDirectBase().isEmpty());
     574           0 :                 if (!ent2->getDirectBase().isEmpty()) {
     575           0 :                     writeIdxName(file, ent2->getDirectBase());
     576             :                 }
     577           0 :                 write32(file, ent2->getDirectMembers().size());
     578           0 :                 for (std::vector< unoidl::ExceptionTypeEntity::Member >::
     579           0 :                          const_iterator j(ent2->getDirectMembers().begin());
     580           0 :                      j != ent2->getDirectMembers().end(); ++j)
     581             :                 {
     582           0 :                     writeIdxName(file, j->name);
     583           0 :                     writeIdxName(file, j->type);
     584           0 :                     writeAnnotations(file, ann, j->annotations);
     585             :                 }
     586           0 :                 writeAnnotations(file, ann, ent2->getAnnotations());
     587           0 :                 break;
     588             :             }
     589             :         case unoidl::Entity::SORT_INTERFACE_TYPE:
     590             :             {
     591             :                 rtl::Reference< unoidl::InterfaceTypeEntity > ent2(
     592             :                     static_cast< unoidl::InterfaceTypeEntity * >(
     593           0 :                         i->second.entity.get()));
     594           0 :                 bool ann = !ent2->getAnnotations().empty();
     595           0 :                 for (std::vector< unoidl::AnnotatedReference >::const_iterator
     596           0 :                          j(ent2->getDirectMandatoryBases().begin());
     597           0 :                      !ann && j != ent2->getDirectMandatoryBases().end(); ++j)
     598             :                 {
     599           0 :                     ann = !j->annotations.empty();
     600             :                 }
     601           0 :                 for (std::vector< unoidl::AnnotatedReference >::const_iterator
     602           0 :                          j(ent2->getDirectOptionalBases().begin());
     603           0 :                      !ann && j != ent2->getDirectOptionalBases().end(); ++j)
     604             :                 {
     605           0 :                     ann = !j->annotations.empty();
     606             :                 }
     607           0 :                 for (std::vector< unoidl::InterfaceTypeEntity::Attribute >::
     608           0 :                          const_iterator j(ent2->getDirectAttributes().begin());
     609           0 :                      !ann && j != ent2->getDirectAttributes().end(); ++j)
     610             :                 {
     611           0 :                     ann = !j->annotations.empty();
     612             :                 }
     613           0 :                 for (std::vector< unoidl::InterfaceTypeEntity::Method >::
     614           0 :                          const_iterator j(ent2->getDirectMethods().begin());
     615           0 :                      !ann && j != ent2->getDirectMethods().end(); ++j)
     616             :                 {
     617           0 :                     ann = !j->annotations.empty();
     618             :                 }
     619           0 :                 i->second.dataOffset = getOffset(file);
     620           0 :                 writeKind(file, ent2.get(), ann);
     621           0 :                 write32(file, ent2->getDirectMandatoryBases().size());
     622           0 :                 for (std::vector< unoidl::AnnotatedReference >::const_iterator
     623           0 :                          j(ent2->getDirectMandatoryBases().begin());
     624           0 :                      j != ent2->getDirectMandatoryBases().end(); ++j)
     625             :                 {
     626           0 :                     writeIdxName(file, j->name);
     627           0 :                     writeAnnotations(file, ann, j->annotations);
     628             :                 }
     629           0 :                 write32(file, ent2->getDirectOptionalBases().size());
     630           0 :                 for (std::vector< unoidl::AnnotatedReference >::const_iterator
     631           0 :                          j(ent2->getDirectOptionalBases().begin());
     632           0 :                      j != ent2->getDirectOptionalBases().end(); ++j)
     633             :                 {
     634           0 :                     writeIdxName(file, j->name);
     635           0 :                     writeAnnotations(file, ann, j->annotations);
     636             :                 }
     637           0 :                 write32(file, ent2->getDirectAttributes().size());
     638           0 :                 for (std::vector< unoidl::InterfaceTypeEntity::Attribute >::
     639           0 :                          const_iterator j(ent2->getDirectAttributes().begin());
     640           0 :                      j != ent2->getDirectAttributes().end(); ++j)
     641             :                 {
     642           0 :                     sal_uInt64 f = 0;
     643           0 :                     if (j->bound) {
     644           0 :                         f |= 0x01;
     645             :                     }
     646           0 :                     if (j->readOnly) {
     647           0 :                         f |= 0x02;
     648             :                     }
     649           0 :                     write8(file, f);
     650           0 :                     writeIdxName(file, j->name);
     651           0 :                     writeIdxName(file, j->type);
     652           0 :                     write32(file, j->getExceptions.size());
     653           0 :                     for (std::vector< OUString >::const_iterator k(
     654           0 :                              j->getExceptions.begin());
     655           0 :                          k != j->getExceptions.end(); ++k)
     656             :                     {
     657           0 :                         writeIdxName(file, *k);
     658             :                     }
     659           0 :                     if (!j->readOnly) {
     660           0 :                         write32(file, j->setExceptions.size());
     661           0 :                         for (std::vector< OUString >::const_iterator k(
     662           0 :                                  j->setExceptions.begin());
     663           0 :                              k != j->setExceptions.end(); ++k)
     664             :                         {
     665           0 :                             writeIdxName(file, *k);
     666             :                         }
     667             :                     }
     668           0 :                     writeAnnotations(file, ann, j->annotations);
     669             :                 }
     670           0 :                 write32(file, ent2->getDirectMethods().size());
     671           0 :                 for (std::vector< unoidl::InterfaceTypeEntity::Method >::
     672           0 :                          const_iterator j(ent2->getDirectMethods().begin());
     673           0 :                      j != ent2->getDirectMethods().end(); ++j)
     674             :                 {
     675           0 :                     writeIdxName(file, j->name);
     676           0 :                     writeIdxName(file, j->returnType);
     677           0 :                     write32(file, j->parameters.size());
     678           0 :                     for (std::vector<
     679             :                              unoidl::InterfaceTypeEntity::Method::Parameter >::
     680           0 :                              const_iterator k(j->parameters.begin());
     681           0 :                          k != j->parameters.end(); ++k)
     682             :                     {
     683           0 :                         write8(file, k->direction);
     684           0 :                         writeIdxName(file, k->name);
     685           0 :                         writeIdxName(file, k->type);
     686             :                     }
     687           0 :                     write32(file, j->exceptions.size());
     688           0 :                     for (std::vector< OUString >::const_iterator k(
     689           0 :                              j->exceptions.begin());
     690           0 :                          k != j->exceptions.end(); ++k)
     691             :                     {
     692           0 :                         writeIdxName(file, *k);
     693             :                     }
     694           0 :                     writeAnnotations(file, ann, j->annotations);
     695             :                 }
     696           0 :                 writeAnnotations(file, ann, ent2->getAnnotations());
     697           0 :                 break;
     698             :             }
     699             :         case unoidl::Entity::SORT_TYPEDEF:
     700             :             {
     701             :                 rtl::Reference< unoidl::TypedefEntity > ent2(
     702             :                     static_cast< unoidl::TypedefEntity * >(
     703           0 :                         i->second.entity.get()));
     704           0 :                 bool ann = !ent2->getAnnotations().empty();
     705           0 :                 i->second.dataOffset = getOffset(file);
     706           0 :                 writeKind(file, ent2.get(), ann);
     707           0 :                 writeIdxName(file, ent2->getType());
     708           0 :                 writeAnnotations(file, ann, ent2->getAnnotations());
     709           0 :                 break;
     710             :             }
     711             :         case unoidl::Entity::SORT_CONSTANT_GROUP:
     712             :             {
     713             :                 rtl::Reference< unoidl::ConstantGroupEntity > ent2(
     714             :                     static_cast< unoidl::ConstantGroupEntity * >(
     715           0 :                         i->second.entity.get()));
     716           0 :                 std::map< OUString, ConstItem > cmap;
     717           0 :                 for (std::vector< unoidl::ConstantGroupEntity::Member >::
     718           0 :                          const_iterator j(ent2->getMembers().begin());
     719           0 :                      j != ent2->getMembers().end(); ++j)
     720             :                 {
     721           0 :                     if (!cmap.insert(
     722             :                             std::make_pair(
     723           0 :                                 j->name, ConstItem(j->value, j->annotations))).
     724           0 :                         second)
     725             :                     {
     726             :                         std::cout
     727           0 :                             << "Duplicate constant group member name \""
     728           0 :                             << j->name << '"' << std::endl;
     729           0 :                         std::exit(EXIT_FAILURE);
     730             :                     }
     731             :                 }
     732           0 :                 for (std::map< OUString, ConstItem >::iterator j(cmap.begin());
     733           0 :                      j != cmap.end(); ++j)
     734             :                 {
     735           0 :                     j->second.dataOffset = getOffset(file);
     736           0 :                     sal_uInt64 v = j->second.constant.type;
     737           0 :                     if (!j->second.annotations.empty()) {
     738           0 :                         v |= 0x80;
     739             :                     }
     740           0 :                     write8(file, v);
     741           0 :                     switch (j->second.constant.type) {
     742             :                     case unoidl::ConstantValue::TYPE_BOOLEAN:
     743           0 :                         write8(file, j->second.constant.booleanValue ? 1 : 0);
     744           0 :                         break;
     745             :                     case unoidl::ConstantValue::TYPE_BYTE:
     746             :                         write8(
     747             :                             file,
     748             :                             static_cast< sal_uInt8 >(
     749           0 :                                 j->second.constant.byteValue));
     750           0 :                         break;
     751             :                     case unoidl::ConstantValue::TYPE_SHORT:
     752             :                         write16(
     753             :                             file,
     754             :                             static_cast< sal_uInt16 >(
     755           0 :                                 j->second.constant.shortValue));
     756           0 :                         break;
     757             :                     case unoidl::ConstantValue::TYPE_UNSIGNED_SHORT:
     758           0 :                         write16(file, j->second.constant.unsignedShortValue);
     759           0 :                         break;
     760             :                     case unoidl::ConstantValue::TYPE_LONG:
     761             :                         write32(
     762             :                             file,
     763             :                             static_cast< sal_uInt32 >(
     764           0 :                                 j->second.constant.longValue));
     765           0 :                         break;
     766             :                     case unoidl::ConstantValue::TYPE_UNSIGNED_LONG:
     767           0 :                         write32(file, j->second.constant.unsignedLongValue);
     768           0 :                         break;
     769             :                     case unoidl::ConstantValue::TYPE_HYPER:
     770             :                         write64(
     771             :                             file,
     772             :                             static_cast< sal_uInt64 >(
     773           0 :                                 j->second.constant.hyperValue));
     774           0 :                         break;
     775             :                     case unoidl::ConstantValue::TYPE_UNSIGNED_HYPER:
     776           0 :                         write64(file, j->second.constant.unsignedHyperValue);
     777           0 :                         break;
     778             :                     case unoidl::ConstantValue::TYPE_FLOAT:
     779             :                         writeIso60599Binary32(
     780           0 :                             file, j->second.constant.floatValue);
     781           0 :                         break;
     782             :                     case unoidl::ConstantValue::TYPE_DOUBLE:
     783             :                         writeIso60599Binary64(
     784           0 :                             file, j->second.constant.doubleValue);
     785           0 :                         break;
     786             :                     default:
     787           0 :                         for (;;) { std::abort(); } // this cannot happen
     788             :                     }
     789             :                     writeAnnotations(
     790           0 :                         file, !j->second.annotations.empty(),
     791           0 :                         j->second.annotations);
     792             :                 }
     793           0 :                 for (std::map< OUString, ConstItem >::iterator j(
     794           0 :                          cmap.begin());
     795           0 :                      j != cmap.end(); ++j)
     796             :                 {
     797           0 :                     j->second.nameOffset = writeNulName(file, j->first);
     798             :                 }
     799           0 :                 bool ann = !ent2->getAnnotations().empty();
     800           0 :                 i->second.dataOffset = getOffset(file);
     801           0 :                 writeKind(file, ent2.get(), ann);
     802           0 :                 write32(file, cmap.size());
     803             :                     // overflow from std::map::size_type -> sal_uInt64 is
     804             :                     // unrealistic
     805           0 :                 for (std::map< OUString, ConstItem >::iterator j(
     806           0 :                          cmap.begin());
     807           0 :                      j != cmap.end(); ++j)
     808             :                 {
     809           0 :                     write32(file, j->second.nameOffset);
     810           0 :                     write32(file, j->second.dataOffset);
     811             :                 }
     812           0 :                 writeAnnotations(file, ann, ent2->getAnnotations());
     813           0 :                 break;
     814             :             }
     815             :         case unoidl::Entity::SORT_SINGLE_INTERFACE_BASED_SERVICE:
     816             :             {
     817             :                 rtl::Reference< unoidl::SingleInterfaceBasedServiceEntity >
     818             :                     ent2(
     819             :                         static_cast<
     820             :                             unoidl::SingleInterfaceBasedServiceEntity * >(
     821           0 :                                 i->second.entity.get()));
     822           0 :                 bool dfltCtor = ent2->getConstructors().size() == 1
     823           0 :                     && ent2->getConstructors()[0].defaultConstructor;
     824           0 :                 bool ann = !ent2->getAnnotations().empty();
     825           0 :                 if (!dfltCtor) {
     826           0 :                     for (std::vector<
     827             :                              unoidl::SingleInterfaceBasedServiceEntity::
     828             :                              Constructor >::const_iterator j(
     829           0 :                                  ent2->getConstructors().begin());
     830           0 :                          !ann && j != ent2->getConstructors().end(); ++j)
     831             :                     {
     832           0 :                         ann = !j->annotations.empty();
     833             :                     }
     834             :                 }
     835           0 :                 i->second.dataOffset = getOffset(file);
     836           0 :                 writeKind(file, ent2.get(), ann, dfltCtor);
     837           0 :                 writeIdxName(file, ent2->getBase());
     838           0 :                 if (!dfltCtor) {
     839           0 :                     write32(file, ent2->getConstructors().size());
     840           0 :                     for (std::vector<
     841             :                              unoidl::SingleInterfaceBasedServiceEntity::
     842             :                              Constructor >::const_iterator j(
     843           0 :                                  ent2->getConstructors().begin());
     844           0 :                          j != ent2->getConstructors().end(); ++j)
     845             :                     {
     846           0 :                         if (j->defaultConstructor) {
     847             :                             std::cout
     848           0 :                                 << "Unexpected default constructor \""
     849           0 :                                 << j->name << '"' << std::endl;
     850           0 :                             std::exit(EXIT_FAILURE);
     851             :                         }
     852           0 :                         writeIdxName(file, j->name);
     853           0 :                         write32(file, j->parameters.size());
     854           0 :                         for (std::vector<
     855             :                                  unoidl::SingleInterfaceBasedServiceEntity::
     856             :                                  Constructor::Parameter >::const_iterator k(
     857           0 :                                      j->parameters.begin());
     858           0 :                              k != j->parameters.end(); ++k)
     859             :                         {
     860           0 :                             sal_uInt64 f = 0;
     861           0 :                             if (k->rest) {
     862           0 :                                 f |= 0x04;
     863             :                             }
     864           0 :                             write8(file, f);
     865           0 :                             writeIdxName(file, k->name);
     866           0 :                             writeIdxName(file, k->type);
     867             :                         }
     868           0 :                         write32(file, j->exceptions.size());
     869           0 :                         for (std::vector< OUString >::const_iterator k(
     870           0 :                                  j->exceptions.begin());
     871           0 :                              k != j->exceptions.end(); ++k)
     872             :                         {
     873           0 :                             writeIdxName(file, *k);
     874             :                         }
     875           0 :                         writeAnnotations(file, ann, j->annotations);
     876             :                     }
     877             :                 }
     878           0 :                 writeAnnotations(file, ann, ent2->getAnnotations());
     879           0 :                 break;
     880             :             }
     881             :         case unoidl::Entity::SORT_ACCUMULATION_BASED_SERVICE:
     882             :             {
     883             :                 rtl::Reference< unoidl::AccumulationBasedServiceEntity > ent2(
     884             :                     static_cast< unoidl::AccumulationBasedServiceEntity * >(
     885           0 :                         i->second.entity.get()));
     886           0 :                 bool ann = !ent2->getAnnotations().empty();
     887           0 :                 for (std::vector< unoidl::AnnotatedReference >::const_iterator
     888           0 :                          j(ent2->getDirectMandatoryBaseServices().begin());
     889           0 :                      !ann && j != ent2->getDirectMandatoryBaseServices().end();
     890             :                      ++j)
     891             :                 {
     892           0 :                     ann = !j->annotations.empty();
     893             :                 }
     894           0 :                 for (std::vector< unoidl::AnnotatedReference >::const_iterator
     895           0 :                          j(ent2->getDirectOptionalBaseServices().begin());
     896           0 :                      !ann && j != ent2->getDirectOptionalBaseServices().end();
     897             :                      ++j)
     898             :                 {
     899           0 :                     ann = !j->annotations.empty();
     900             :                 }
     901           0 :                 for (std::vector< unoidl::AnnotatedReference >::const_iterator
     902           0 :                          j(ent2->getDirectMandatoryBaseInterfaces().begin());
     903           0 :                      (!ann
     904           0 :                       && j != ent2->getDirectMandatoryBaseInterfaces().end());
     905             :                      ++j)
     906             :                 {
     907           0 :                     ann = !j->annotations.empty();
     908             :                 }
     909           0 :                 for (std::vector< unoidl::AnnotatedReference >::const_iterator
     910           0 :                          j(ent2->getDirectOptionalBaseInterfaces().begin());
     911           0 :                      !ann && j != ent2->getDirectOptionalBaseInterfaces().end();
     912             :                      ++j)
     913             :                 {
     914           0 :                     ann = !j->annotations.empty();
     915             :                 }
     916           0 :                 for (std::vector<
     917             :                          unoidl::AccumulationBasedServiceEntity::Property >::
     918             :                          const_iterator j(
     919           0 :                              ent2->getDirectProperties().begin());
     920           0 :                      !ann && j != ent2->getDirectProperties().end(); ++j)
     921             :                 {
     922           0 :                     ann = !j->annotations.empty();
     923             :                 }
     924           0 :                 i->second.dataOffset = getOffset(file);
     925           0 :                 writeKind(file, ent2.get(), ann);
     926           0 :                 write32(file, ent2->getDirectMandatoryBaseServices().size());
     927           0 :                 for (std::vector< unoidl::AnnotatedReference >::const_iterator
     928           0 :                          j(ent2->getDirectMandatoryBaseServices().begin());
     929           0 :                      j != ent2->getDirectMandatoryBaseServices().end(); ++j)
     930             :                 {
     931           0 :                     writeIdxName(file, j->name);
     932           0 :                     writeAnnotations(file, ann, j->annotations);
     933             :                 }
     934           0 :                 write32(file, ent2->getDirectOptionalBaseServices().size());
     935           0 :                 for (std::vector< unoidl::AnnotatedReference >::const_iterator
     936           0 :                          j(ent2->getDirectOptionalBaseServices().begin());
     937           0 :                      j != ent2->getDirectOptionalBaseServices().end(); ++j)
     938             :                 {
     939           0 :                     writeIdxName(file, j->name);
     940           0 :                     writeAnnotations(file, ann, j->annotations);
     941             :                 }
     942           0 :                 write32(file, ent2->getDirectMandatoryBaseInterfaces().size());
     943           0 :                 for (std::vector< unoidl::AnnotatedReference >::const_iterator
     944           0 :                          j(ent2->getDirectMandatoryBaseInterfaces().begin());
     945           0 :                      j != ent2->getDirectMandatoryBaseInterfaces().end(); ++j)
     946             :                 {
     947           0 :                     writeIdxName(file, j->name);
     948           0 :                     writeAnnotations(file, ann, j->annotations);
     949             :                 }
     950           0 :                 write32(file, ent2->getDirectOptionalBaseInterfaces().size());
     951           0 :                 for (std::vector< unoidl::AnnotatedReference >::const_iterator
     952           0 :                          j(ent2->getDirectOptionalBaseInterfaces().begin());
     953           0 :                      j != ent2->getDirectOptionalBaseInterfaces().end(); ++j)
     954             :                 {
     955           0 :                     writeIdxName(file, j->name);
     956           0 :                     writeAnnotations(file, ann, j->annotations);
     957             :                 }
     958           0 :                 write32(file, ent2->getDirectProperties().size());
     959           0 :                 for (std::vector<
     960             :                          unoidl::AccumulationBasedServiceEntity::Property >::
     961             :                          const_iterator j(
     962           0 :                              ent2->getDirectProperties().begin());
     963           0 :                      j != ent2->getDirectProperties().end(); ++j)
     964             :                 {
     965           0 :                     write16(file, static_cast< sal_uInt16 >(j->attributes));
     966           0 :                     writeIdxName(file, j->name);
     967           0 :                     writeIdxName(file, j->type);
     968           0 :                     writeAnnotations(file, ann, j->annotations);
     969             :                 }
     970           0 :                 writeAnnotations(file, ann, ent2->getAnnotations());
     971           0 :                 break;
     972             :             }
     973             :         case unoidl::Entity::SORT_INTERFACE_BASED_SINGLETON:
     974             :             {
     975             :                 rtl::Reference< unoidl::InterfaceBasedSingletonEntity > ent2(
     976             :                     static_cast< unoidl::InterfaceBasedSingletonEntity * >(
     977           0 :                         i->second.entity.get()));
     978           0 :                 bool ann = !ent2->getAnnotations().empty();
     979           0 :                 i->second.dataOffset = getOffset(file);
     980           0 :                 writeKind(file, ent2.get(), ann);
     981           0 :                 writeIdxName(file, ent2->getBase());
     982           0 :                 writeAnnotations(file, ann, ent2->getAnnotations());
     983           0 :                 break;
     984             :             }
     985             :         case unoidl::Entity::SORT_SERVICE_BASED_SINGLETON:
     986             :             {
     987             :                 rtl::Reference< unoidl::ServiceBasedSingletonEntity > ent2(
     988             :                     static_cast< unoidl::ServiceBasedSingletonEntity * >(
     989           0 :                         i->second.entity.get()));
     990           0 :                 bool ann = !ent2->getAnnotations().empty();
     991           0 :                 i->second.dataOffset = getOffset(file);
     992           0 :                 writeKind(file, ent2.get(), ann);
     993           0 :                 writeIdxName(file, ent2->getBase());
     994           0 :                 writeAnnotations(file, ann, ent2->getAnnotations());
     995           0 :                 break;
     996             :             }
     997             :         }
     998             :     }
     999           0 :     for (std::map< OUString, Item >::iterator i(map.begin()); i != map.end();
    1000             :          ++i)
    1001             :     {
    1002           0 :         i->second.nameOffset = writeNulName(file, i->first);
    1003             :     }
    1004           0 :     sal_uInt64 off = getOffset(file);
    1005           0 :     if (rootSize == 0) {
    1006           0 :         write8(file, 0); // SORT_MODULE
    1007           0 :         write32(file, map.size());
    1008             :             // overflow from std::map::size_type -> sal_uInt64 is unrealistic
    1009             :     } else {
    1010           0 :         *rootSize = map.size();
    1011             :             // overflow from std::map::size_type -> std::size_t is unrealistic
    1012             :     }
    1013           0 :     for (std::map< OUString, Item >::iterator i(map.begin()); i != map.end();
    1014             :          ++i)
    1015             :     {
    1016           0 :         write32(file, i->second.nameOffset);
    1017           0 :         write32(file, i->second.dataOffset);
    1018             :     }
    1019           0 :     return off;
    1020             : }
    1021             : 
    1022             : }
    1023             : 
    1024           0 : SAL_IMPLEMENT_MAIN() {
    1025             :     try {
    1026           0 :         sal_uInt32 args = rtl_getAppCommandArgCount();
    1027           0 :         if (args == 0) {
    1028           0 :             badUsage();
    1029             :         }
    1030           0 :         rtl::Reference< unoidl::Manager > mgr(new unoidl::Manager);
    1031           0 :         bool entities = false;
    1032           0 :         rtl::Reference< unoidl::Provider > prov;
    1033           0 :         std::map< OUString, Item > map;
    1034           0 :         for (sal_uInt32 i = 0; i != args - 1; ++i) {
    1035             :             assert(args > 1);
    1036           0 :             OUString uri(getArgumentUri(i, i == args - 2 ? &entities : 0));
    1037           0 :             if (entities) {
    1038           0 :                 mapEntities(mgr, uri, map);
    1039             :             } else {
    1040             :                 try {
    1041           0 :                     prov = unoidl::loadProvider(mgr, uri);
    1042           0 :                 } catch (unoidl::NoSuchFileException &) {
    1043             :                     std::cerr
    1044           0 :                         << "Input <" << uri << "> does not exist" << std::endl;
    1045           0 :                     std::exit(EXIT_FAILURE);
    1046             :                 }
    1047           0 :                 mgr->addProvider(prov);
    1048             :             }
    1049           0 :         }
    1050           0 :         if (!entities) {
    1051             :             mapCursor(
    1052           0 :                 (prov.is()
    1053           0 :                  ? prov->createRootCursor()
    1054             :                  : rtl::Reference< unoidl::MapCursor >()),
    1055           0 :                 map);
    1056             :         }
    1057           0 :         osl::File f(getArgumentUri(args - 1, 0));
    1058           0 :         osl::FileBase::RC e = f.open(osl_File_OpenFlag_Write);
    1059           0 :         if (e == osl::FileBase::E_NOENT) {
    1060           0 :             e = f.open(osl_File_OpenFlag_Write | osl_File_OpenFlag_Create);
    1061             :         }
    1062           0 :         if (e != osl::FileBase::E_None) {
    1063             :             std::cerr
    1064           0 :                 << "Cannot open <" << f.getURL() << "> for writing, error code "
    1065           0 :                 << +e << std::endl;
    1066           0 :             std::exit(EXIT_FAILURE);
    1067             :         }
    1068           0 :         write(f, "UNOIDL\xFF\0", 8);
    1069           0 :         write32(f, 0); // root map offset
    1070           0 :         write32(f, 0); // root map size
    1071             :         write(
    1072             :             f,
    1073           0 :             RTL_CONSTASCII_STRINGPARAM(
    1074             :                 "\0** Created by LibreOffice " LIBO_VERSION_DOTTED
    1075           0 :                 " unoidl-write **\0"));
    1076             :         std::size_t size;
    1077           0 :         sal_uInt64 off = writeMap(f, map, &size);
    1078           0 :         e = f.setSize(getOffset(f)); // truncate in case it already existed
    1079           0 :         if (e != osl::FileBase::E_None) {
    1080             :             std::cerr
    1081           0 :                 << "Cannot set size of <" << f.getURL() << ">, error code "
    1082           0 :                 << +e << std::endl;
    1083           0 :             std::exit(EXIT_FAILURE);
    1084             :         }
    1085           0 :         e = f.setPos(osl_Pos_Absolut, 8);
    1086           0 :         if (e != osl::FileBase::E_None) {
    1087             :             std::cerr
    1088           0 :                 << "Cannot rewind current position in <" << f.getURL()
    1089           0 :                 << ">, error code " << +e << std::endl;
    1090           0 :             std::exit(EXIT_FAILURE);
    1091             :         }
    1092           0 :         write32(f, off);
    1093           0 :         write32(f, size);
    1094             :             // overflow from std::map::size_type -> sal_uInt64 is unrealistic
    1095           0 :         e = f.close();
    1096           0 :         if (e != osl::FileBase::E_None) {
    1097             :             std::cerr
    1098           0 :                 << "Cannot close <" << f.getURL()
    1099           0 :                 << "> after writing, error code " << +e << std::endl;
    1100           0 :             std::exit(EXIT_FAILURE);
    1101             :         }
    1102           0 :         return EXIT_SUCCESS;
    1103           0 :     } catch (unoidl::FileFormatException & e1) {
    1104             :         std::cerr
    1105           0 :             << "Bad input <" << e1.getUri() << ">: " << e1.getDetail()
    1106           0 :             << std::endl;
    1107           0 :         std::exit(EXIT_FAILURE);
    1108             :     }
    1109           0 : }
    1110             : 
    1111             : /* vim:set shiftwidth=4 softtabstop=4 expandtab: */

Generated by: LCOV version 1.10