LCOV - code coverage report
Current view: top level - unoidl/source - unoidl-write.cxx (source / functions) Hit Total Coverage
Test: commit c8344322a7af75b84dd3ca8f78b05543a976dfd5 Lines: 556 650 85.5 %
Date: 2015-06-13 12:38:46 Functions: 29 30 96.7 %
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         838 : OUString getArgumentUri(sal_uInt32 argument, bool * entities) {
      58         838 :     OUString arg;
      59         838 :     rtl_getAppCommandArg(argument, &arg.pData);
      60         838 :     if (arg.startsWith("@", &arg)) {
      61           5 :         if (entities == 0) {
      62           0 :             badUsage();
      63             :         }
      64           5 :         *entities = true;
      65         833 :     } else if (entities != 0) {
      66         334 :         *entities = false;
      67             :     }
      68        1676 :     OUString url;
      69         838 :     osl::FileBase::RC e1 = osl::FileBase::getFileURLFromSystemPath(arg, url);
      70         838 :     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        1676 :     OUString cwd;
      77         838 :     oslProcessError e2 = osl_getProcessWorkingDir(&cwd.pData);
      78         838 :     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         838 :     OUString abs;
      85         838 :     e1 = osl::FileBase::getAbsoluteFileURL(cwd, url, abs);
      86         838 :     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        1676 :     return abs;
      93             : }
      94             : 
      95       52579 : sal_uInt64 getOffset(osl::File & file) {
      96             :     sal_uInt64 off;
      97       52579 :     osl::FileBase::RC e = file.getPos(off);
      98       52579 :     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       52579 :     return off;
     105             : }
     106             : 
     107      199899 : void write(osl::File & file, void const * buffer, sal_uInt64 size) {
     108             :     sal_uInt64 n;
     109      199899 :     osl::FileBase::RC e = file.write(buffer, size, n);
     110      199899 :     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      199899 :     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      199899 : }
     123             : 
     124       27401 : void write8(osl::File & file, sal_uInt64 value) {
     125       27401 :     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       27401 :     buf[0] = value & 0xFF;
     132       27401 :     write(file, buf, SAL_N_ELEMENTS(buf));
     133       27401 : }
     134             : 
     135        5247 : void write16(osl::File & file, sal_uInt64 value) {
     136        5247 :     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        5247 :     buf[0] = value & 0xFF;
     143        5247 :     buf[1] = (value >> 8) & 0xFF;
     144        5247 :     write(file, buf, SAL_N_ELEMENTS(buf));
     145        5247 : }
     146             : 
     147      132881 : void write32(osl::File & file, sal_uInt64 value) {
     148      132881 :     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      132881 :     buf[0] = value & 0xFF;
     155      132881 :     buf[1] = (value >> 8) & 0xFF;
     156      132881 :     buf[2] = (value >> 16) & 0xFF;
     157      132881 :     buf[3] = (value >> 24) & 0xFF;
     158      132881 :     write(file, buf, SAL_N_ELEMENTS(buf));
     159      132881 : }
     160             : 
     161          46 : void write64(osl::File & file, sal_uInt64 value) {
     162             :     unsigned char buf[8];
     163          46 :     buf[0] = value & 0xFF;
     164          46 :     buf[1] = (value >> 8) & 0xFF;
     165          46 :     buf[2] = (value >> 16) & 0xFF;
     166          46 :     buf[3] = (value >> 24) & 0xFF;
     167          46 :     buf[4] = (value >> 32) & 0xFF;
     168          46 :     buf[5] = (value >> 40) & 0xFF;
     169          46 :     buf[6] = (value >> 48) & 0xFF;
     170          46 :     buf[7] = (value >> 56) & 0xFF;
     171          46 :     write(file, buf, SAL_N_ELEMENTS(buf));
     172          46 : }
     173             : 
     174          21 : 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          21 :     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          21 :     write(file, sa.buf, SAL_N_ELEMENTS(sa.buf));
     185          21 : }
     186             : 
     187           1 : 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           1 :     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           1 :     write(file, sa.buf, SAL_N_ELEMENTS(sa.buf));
     200           1 : }
     201             : 
     202       69616 : OString toAscii(OUString const & name) {
     203       69616 :     OString ascii;
     204       69616 :     if (!name.convertToString(
     205             :             &ascii, RTL_TEXTENCODING_ASCII_US,
     206             :             (RTL_UNICODETOTEXT_FLAGS_UNDEFINED_ERROR
     207       69616 :              | 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       69616 :     return ascii;
     214             : }
     215             : 
     216         281 : OString toUtf8(OUString const & string) {
     217         281 :     OString ascii;
     218         281 :     if (!string.convertToString(
     219             :             &ascii, RTL_TEXTENCODING_UTF8,
     220             :             (RTL_UNICODETOTEXT_FLAGS_UNDEFINED_ERROR
     221         281 :              | 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         281 :     return ascii;
     228             : }
     229             : 
     230       18277 : sal_uInt64 writeNulName(osl::File & file, OUString const & name) {
     231       18277 :     OString ascii(toAscii(name));
     232       18277 :     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       18277 :     sal_uInt64 off = getOffset(file);
     238       18277 :     write(file, ascii.getStr(), ascii.getLength() + 1);
     239       18277 :     return off;
     240             : }
     241             : 
     242       51620 : void writeIdxString(osl::File & file, OString const & string) {
     243       51620 :     static std::map< OString, sal_uInt64 > reuse;
     244       51620 :     std::map< OString, sal_uInt64 >::iterator i(reuse.find(string));
     245       51620 :     if (i == reuse.end()) {
     246       15717 :         reuse.insert(std::make_pair(string, getOffset(file)));
     247             :         assert(
     248             :             (static_cast< sal_uInt64 >(string.getLength()) & 0x80000000) == 0);
     249       15717 :         write32(file, static_cast< sal_uInt64 >(string.getLength()));
     250       15717 :         write(file, string.getStr(), string.getLength());
     251             :     } else {
     252       35903 :         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       35903 :         write32(file, i->second | 0x80000000);
     259             :     }
     260       51620 : }
     261             : 
     262       51339 : void writeIdxName(osl::File & file, OUString const & name) {
     263       51339 :     writeIdxString(file, toAscii(name));
     264       51339 : }
     265             : 
     266       37194 : void writeAnnotations(
     267             :     osl::File & file, bool annotate,
     268             :     std::vector< OUString > const & annotations)
     269             : {
     270             :     assert(annotate || annotations.empty());
     271       37194 :     if (annotate) {
     272        1394 :         write32(file, annotations.size());
     273             :             // overflow from std::vector::size_type -> sal_uInt64 is unrealistic
     274        5025 :         for (std::vector< OUString >::const_iterator i(annotations.begin());
     275        3350 :              i != annotations.end(); ++i)
     276             :         {
     277         281 :             writeIdxString(file, toUtf8(*i));
     278             :         }
     279             :     }
     280       37194 : }
     281             : 
     282        6059 : 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        6059 :     sal_uInt64 v = entity->getSort();
     289        6059 :     if (entity->isPublished()) {
     290        2785 :         v |= 0x80;
     291             :     }
     292        6059 :     if (annotated) {
     293         228 :         v |= 0x40;
     294             :     }
     295        6059 :     if (flag) {
     296         599 :         v |= 0x20;
     297             :     }
     298        6059 :     write8(file, v);
     299        6059 : }
     300             : 
     301       31548 : struct Item {
     302        6310 :     explicit Item(rtl::Reference< unoidl::Entity > const & theEntity):
     303        6310 :         entity(theEntity), nameOffset(0), dataOffset(0)
     304        6310 :     {}
     305             : 
     306             :     rtl::Reference< unoidl::Entity > entity;
     307             :     std::map< OUString, Item > module;
     308             :     sal_uInt64 nameOffset;
     309             :     sal_uInt64 dataOffset;
     310             : };
     311             : 
     312       59840 : struct ConstItem {
     313       11968 :     ConstItem(
     314             :         unoidl::ConstantValue const & theConstant,
     315             :         std::vector< OUString > const & theAnnotations):
     316             :         constant(theConstant), annotations(theAnnotations), nameOffset(0),
     317       11968 :         dataOffset(0)
     318       11968 :     {}
     319             : 
     320             :     unoidl::ConstantValue constant;
     321             :     std::vector< OUString > annotations;
     322             :     sal_uInt64 nameOffset;
     323             :     sal_uInt64 dataOffset;
     324             : };
     325             : 
     326           5 : void mapEntities(
     327             :     rtl::Reference< unoidl::Manager > const & manager, OUString const & uri,
     328             :     std::map< OUString, Item > & map)
     329             : {
     330             :     assert(manager.is());
     331           5 :     osl::File f(uri);
     332           5 :     osl::FileBase::RC e = f.open(osl_File_OpenFlag_Read);
     333           5 :     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          10 :         e = f.isEndOfFile(&eof);
     342          10 :         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          10 :         if (eof) {
     349           5 :             break;
     350             :         }
     351           5 :         rtl::ByteSequence s1;
     352           5 :         e = f.readLine(s1);
     353           5 :         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          10 :         OUString s2;
     360           5 :         if (!rtl_convertStringToUString(
     361           5 :                 &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          10 :                  | 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        5357 :         for (sal_Int32 i = 0; i != -1;) {
     373        5347 :             OUString t(s2.getToken(0, ' ', i));
     374        5347 :             if (!t.isEmpty()) {
     375        5342 :                 rtl::Reference< unoidl::Entity > ent(manager->findEntity(t));
     376        5342 :                 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        5342 :                 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        5342 :                 std::map< OUString, Item > * map2 = &map;
     389        5342 :                 for (sal_Int32 j = 0;;) {
     390       26363 :                     OUString id(t.getToken(0, '.', j));
     391       26363 :                     if (j == -1) {
     392        5342 :                         map2->insert(std::make_pair(id, Item(ent)));
     393        5342 :                         break;
     394             :                     }
     395       21021 :                     std::map< OUString, Item >::iterator k(map2->find(id));
     396       21021 :                     if (k == map2->end()) {
     397             :                         rtl::Reference< unoidl::Entity > ent2(
     398         150 :                             manager->findEntity(t.copy(0, j - 1)));
     399             :                         assert(ent2.is());
     400         150 :                         k = map2->insert(std::make_pair(id, Item(ent2))).first;
     401             :                     }
     402             :                     assert(
     403             :                         k->second.entity->getSort()
     404             :                         == unoidl::Entity::SORT_MODULE);
     405       21021 :                     map2 = &k->second.module;
     406       21021 :                 }
     407             :             }
     408        5347 :         }
     409           5 :     }
     410          10 :     e = f.close();
     411           5 :     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           5 :     }
     417           5 : }
     418             : 
     419         249 : void mapCursor(
     420             :     rtl::Reference< unoidl::MapCursor > const & cursor,
     421             :     std::map< OUString, Item > & map)
     422             : {
     423         249 :     if (cursor.is()) {
     424             :         for (;;) {
     425        1067 :             OUString name;
     426        1885 :             rtl::Reference< unoidl::Entity > ent(cursor->getNext(&name));
     427        1067 :             if (!ent.is()) {
     428         249 :                 break;
     429             :             }
     430             :             std::pair< std::map< OUString, Item >::iterator, bool > i(
     431         818 :                 map.insert(std::make_pair(name, Item(ent))));
     432         818 :             if (!i.second) {
     433           0 :                 std::cout << "Duplicate name \"" << name << '"' << std::endl;
     434           0 :                 std::exit(EXIT_FAILURE);
     435             :             }
     436         818 :             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         200 :                             i.first->second.entity.get()))->createCursor(),
     443         200 :                     i.first->second.module);
     444             :             }
     445         818 :         }
     446             :     }
     447         249 : }
     448             : 
     449         404 : sal_uInt64 writeMap(
     450             :     osl::File & file, std::map< OUString, Item > & map, std::size_t * rootSize)
     451             : {
     452        6713 :     for (std::map< OUString, Item >::iterator i(map.begin()); i != map.end();
     453             :          ++i)
     454             :     {
     455        6309 :         switch (i->second.entity->getSort()) {
     456             :         case unoidl::Entity::SORT_MODULE:
     457         250 :             i->second.dataOffset = writeMap(file, i->second.module, 0);
     458         250 :             break;
     459             :         case unoidl::Entity::SORT_ENUM_TYPE:
     460             :             {
     461             :                 rtl::Reference< unoidl::EnumTypeEntity > ent2(
     462             :                     static_cast< unoidl::EnumTypeEntity * >(
     463         226 :                         i->second.entity.get()));
     464         226 :                 bool ann = !ent2->getAnnotations().empty();
     465        4615 :                 for (std::vector< unoidl::EnumTypeEntity::Member >::
     466         226 :                          const_iterator j(ent2->getMembers().begin());
     467        4583 :                      !ann && j != ent2->getMembers().end(); ++j)
     468             :                 {
     469        1307 :                     ann = !j->annotations.empty();
     470             :                 }
     471         226 :                 i->second.dataOffset = getOffset(file);
     472         226 :                 writeKind(file, ent2.get(), ann);
     473         226 :                 write32(file, ent2->getMembers().size());
     474        4785 :                 for (std::vector< unoidl::EnumTypeEntity::Member >::
     475         226 :                          const_iterator j(ent2->getMembers().begin());
     476        3190 :                      j != ent2->getMembers().end(); ++j)
     477             :                 {
     478        1369 :                     writeIdxName(file, j->name);
     479        1369 :                     write32(file, static_cast< sal_uInt32 >(j->value));
     480        1369 :                     writeAnnotations(file, ann, j->annotations);
     481             :                 }
     482         226 :                 writeAnnotations(file, ann, ent2->getAnnotations());
     483         226 :                 break;
     484             :             }
     485             :         case unoidl::Entity::SORT_PLAIN_STRUCT_TYPE:
     486             :             {
     487             :                 rtl::Reference< unoidl::PlainStructTypeEntity > ent2(
     488             :                     static_cast< unoidl::PlainStructTypeEntity * >(
     489         443 :                         i->second.entity.get()));
     490         443 :                 bool ann = !ent2->getAnnotations().empty();
     491        5718 :                 for (std::vector< unoidl::PlainStructTypeEntity::Member >::
     492         443 :                          const_iterator j(ent2->getDirectMembers().begin());
     493        5688 :                      !ann && j != ent2->getDirectMembers().end(); ++j)
     494             :                 {
     495        1458 :                     ann = !j->annotations.empty();
     496             :                 }
     497         443 :                 i->second.dataOffset = getOffset(file);
     498             :                 writeKind(
     499         443 :                     file, ent2.get(), ann, !ent2->getDirectBase().isEmpty());
     500         443 :                 if (!ent2->getDirectBase().isEmpty()) {
     501         107 :                     writeIdxName(file, ent2->getDirectBase());
     502             :                 }
     503         443 :                 write32(file, ent2->getDirectMembers().size());
     504        5868 :                 for (std::vector< unoidl::PlainStructTypeEntity::Member >::
     505         443 :                          const_iterator j(ent2->getDirectMembers().begin());
     506        3912 :                      j != ent2->getDirectMembers().end(); ++j)
     507             :                 {
     508        1513 :                     writeIdxName(file, j->name);
     509        1513 :                     writeIdxName(file, j->type);
     510        1513 :                     writeAnnotations(file, ann, j->annotations);
     511             :                 }
     512         443 :                 writeAnnotations(file, ann, ent2->getAnnotations());
     513         443 :                 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          33 :                             i->second.entity.get()));
     522          33 :                 bool ann = !ent2->getAnnotations().empty();
     523         216 :                 for (std::vector<
     524             :                          unoidl::PolymorphicStructTypeTemplateEntity::Member >::
     525             :                          const_iterator j(
     526          33 :                              ent2->getMembers().begin());
     527         216 :                      !ann && j != ent2->getMembers().end(); ++j)
     528             :                 {
     529          39 :                     ann = !j->annotations.empty();
     530             :                 }
     531          33 :                 i->second.dataOffset = getOffset(file);
     532          33 :                 writeKind(file, ent2.get(), ann);
     533          33 :                 write32(file, ent2->getTypeParameters().size());
     534         207 :                 for (std::vector< OUString >::const_iterator j(
     535          33 :                          ent2->getTypeParameters().begin());
     536         138 :                      j != ent2->getTypeParameters().end(); ++j)
     537             :                 {
     538          36 :                     writeIdxName(file, *j);
     539             :                 }
     540          33 :                 write32(file, ent2->getMembers().size());
     541         216 :                 for (std::vector<
     542             :                          unoidl::PolymorphicStructTypeTemplateEntity::Member >::
     543             :                          const_iterator j(
     544          33 :                              ent2->getMembers().begin());
     545         144 :                      j != ent2->getMembers().end(); ++j)
     546             :                 {
     547          39 :                     sal_uInt64 f = 0;
     548          39 :                     if (j->parameterized) {
     549          24 :                         f |= 0x01;
     550             :                     }
     551          39 :                     write8(file, f);
     552          39 :                     writeIdxName(file, j->name);
     553          39 :                     writeIdxName(file, j->type);
     554          39 :                     writeAnnotations(file, ann, j->annotations);
     555             :                 }
     556          33 :                 writeAnnotations(file, ann, ent2->getAnnotations());
     557          33 :                 break;
     558             :             }
     559             :         case unoidl::Entity::SORT_EXCEPTION_TYPE:
     560             :             {
     561             :                 rtl::Reference< unoidl::ExceptionTypeEntity > ent2(
     562             :                     static_cast< unoidl::ExceptionTypeEntity * >(
     563         277 :                         i->second.entity.get()));
     564         277 :                 bool ann = !ent2->getAnnotations().empty();
     565        1319 :                 for (std::vector< unoidl::ExceptionTypeEntity::Member >::
     566         277 :                          const_iterator j(ent2->getDirectMembers().begin());
     567        1315 :                      !ann && j != ent2->getDirectMembers().end(); ++j)
     568             :                 {
     569         162 :                     ann = !j->annotations.empty();
     570             :                 }
     571         277 :                 i->second.dataOffset = getOffset(file);
     572             :                 writeKind(
     573         277 :                     file, ent2.get(), ann, !ent2->getDirectBase().isEmpty());
     574         277 :                 if (!ent2->getDirectBase().isEmpty()) {
     575         252 :                     writeIdxName(file, ent2->getDirectBase());
     576             :                 }
     577         277 :                 write32(file, ent2->getDirectMembers().size());
     578        1320 :                 for (std::vector< unoidl::ExceptionTypeEntity::Member >::
     579         277 :                          const_iterator j(ent2->getDirectMembers().begin());
     580         880 :                      j != ent2->getDirectMembers().end(); ++j)
     581             :                 {
     582         163 :                     writeIdxName(file, j->name);
     583         163 :                     writeIdxName(file, j->type);
     584         163 :                     writeAnnotations(file, ann, j->annotations);
     585             :                 }
     586         277 :                 writeAnnotations(file, ann, ent2->getAnnotations());
     587         277 :                 break;
     588             :             }
     589             :         case unoidl::Entity::SORT_INTERFACE_TYPE:
     590             :             {
     591             :                 rtl::Reference< unoidl::InterfaceTypeEntity > ent2(
     592             :                     static_cast< unoidl::InterfaceTypeEntity * >(
     593        2053 :                         i->second.entity.get()));
     594        2053 :                 bool ann = !ent2->getAnnotations().empty();
     595       12882 :                 for (std::vector< unoidl::AnnotatedReference >::const_iterator
     596        2053 :                          j(ent2->getDirectMandatoryBases().begin());
     597       12690 :                      !ann && j != ent2->getDirectMandatoryBases().end(); ++j)
     598             :                 {
     599        2209 :                     ann = !j->annotations.empty();
     600             :                 }
     601        6357 :                 for (std::vector< unoidl::AnnotatedReference >::const_iterator
     602        2053 :                          j(ent2->getDirectOptionalBases().begin());
     603        6165 :                      !ann && j != ent2->getDirectOptionalBases().end(); ++j)
     604             :                 {
     605          34 :                     ann = !j->annotations.empty();
     606             :                 }
     607        9878 :                 for (std::vector< unoidl::InterfaceTypeEntity::Attribute >::
     608        2053 :                          const_iterator j(ent2->getDirectAttributes().begin());
     609        9682 :                      !ann && j != ent2->getDirectAttributes().end(); ++j)
     610             :                 {
     611        1207 :                     ann = !j->annotations.empty();
     612             :                 }
     613       24456 :                 for (std::vector< unoidl::InterfaceTypeEntity::Method >::
     614        2053 :                          const_iterator j(ent2->getDirectMethods().begin());
     615       24246 :                      !ann && j != ent2->getDirectMethods().end(); ++j)
     616             :                 {
     617        6064 :                     ann = !j->annotations.empty();
     618             :                 }
     619        2053 :                 i->second.dataOffset = getOffset(file);
     620        2053 :                 writeKind(file, ent2.get(), ann);
     621        2053 :                 write32(file, ent2->getDirectMandatoryBases().size());
     622       13077 :                 for (std::vector< unoidl::AnnotatedReference >::const_iterator
     623        2053 :                          j(ent2->getDirectMandatoryBases().begin());
     624        8718 :                      j != ent2->getDirectMandatoryBases().end(); ++j)
     625             :                 {
     626        2306 :                     writeIdxName(file, j->name);
     627        2306 :                     writeAnnotations(file, ann, j->annotations);
     628             :                 }
     629        2053 :                 write32(file, ent2->getDirectOptionalBases().size());
     630        6261 :                 for (std::vector< unoidl::AnnotatedReference >::const_iterator
     631        2053 :                          j(ent2->getDirectOptionalBases().begin());
     632        4174 :                      j != ent2->getDirectOptionalBases().end(); ++j)
     633             :                 {
     634          34 :                     writeIdxName(file, j->name);
     635          34 :                     writeAnnotations(file, ann, j->annotations);
     636             :                 }
     637        2053 :                 write32(file, ent2->getDirectAttributes().size());
     638        9828 :                 for (std::vector< unoidl::InterfaceTypeEntity::Attribute >::
     639        2053 :                          const_iterator j(ent2->getDirectAttributes().begin());
     640        6552 :                      j != ent2->getDirectAttributes().end(); ++j)
     641             :                 {
     642        1223 :                     sal_uInt64 f = 0;
     643        1223 :                     if (j->bound) {
     644         157 :                         f |= 0x01;
     645             :                     }
     646        1223 :                     if (j->readOnly) {
     647         272 :                         f |= 0x02;
     648             :                     }
     649        1223 :                     write8(file, f);
     650        1223 :                     writeIdxName(file, j->name);
     651        1223 :                     writeIdxName(file, j->type);
     652        1223 :                     write32(file, j->getExceptions.size());
     653        3966 :                     for (std::vector< OUString >::const_iterator k(
     654        1223 :                              j->getExceptions.begin());
     655        2644 :                          k != j->getExceptions.end(); ++k)
     656             :                     {
     657          99 :                         writeIdxName(file, *k);
     658             :                     }
     659        1223 :                     if (!j->readOnly) {
     660         951 :                         write32(file, j->setExceptions.size());
     661        3228 :                         for (std::vector< OUString >::const_iterator k(
     662         951 :                                  j->setExceptions.begin());
     663        2152 :                              k != j->setExceptions.end(); ++k)
     664             :                         {
     665         125 :                             writeIdxName(file, *k);
     666             :                         }
     667             :                     }
     668        1223 :                     writeAnnotations(file, ann, j->annotations);
     669             :                 }
     670        2053 :                 write32(file, ent2->getDirectMethods().size());
     671       25341 :                 for (std::vector< unoidl::InterfaceTypeEntity::Method >::
     672        2053 :                          const_iterator j(ent2->getDirectMethods().begin());
     673       16894 :                      j != ent2->getDirectMethods().end(); ++j)
     674             :                 {
     675        6394 :                     writeIdxName(file, j->name);
     676        6394 :                     writeIdxName(file, j->returnType);
     677        6394 :                     write32(file, j->parameters.size());
     678       40461 :                     for (std::vector<
     679             :                              unoidl::InterfaceTypeEntity::Method::Parameter >::
     680        6394 :                              const_iterator k(j->parameters.begin());
     681       26974 :                          k != j->parameters.end(); ++k)
     682             :                     {
     683        7093 :                         write8(file, k->direction);
     684        7093 :                         writeIdxName(file, k->name);
     685        7093 :                         writeIdxName(file, k->type);
     686             :                     }
     687        6394 :                     write32(file, j->exceptions.size());
     688       28194 :                     for (std::vector< OUString >::const_iterator k(
     689        6394 :                              j->exceptions.begin());
     690       18796 :                          k != j->exceptions.end(); ++k)
     691             :                     {
     692        3004 :                         writeIdxName(file, *k);
     693             :                     }
     694        6394 :                     writeAnnotations(file, ann, j->annotations);
     695             :                 }
     696        2053 :                 writeAnnotations(file, ann, ent2->getAnnotations());
     697        2053 :                 break;
     698             :             }
     699             :         case unoidl::Entity::SORT_TYPEDEF:
     700             :             {
     701             :                 rtl::Reference< unoidl::TypedefEntity > ent2(
     702             :                     static_cast< unoidl::TypedefEntity * >(
     703          72 :                         i->second.entity.get()));
     704          72 :                 bool ann = !ent2->getAnnotations().empty();
     705          72 :                 i->second.dataOffset = getOffset(file);
     706          72 :                 writeKind(file, ent2.get(), ann);
     707          72 :                 writeIdxName(file, ent2->getType());
     708          72 :                 writeAnnotations(file, ann, ent2->getAnnotations());
     709          72 :                 break;
     710             :             }
     711             :         case unoidl::Entity::SORT_CONSTANT_GROUP:
     712             :             {
     713             :                 rtl::Reference< unoidl::ConstantGroupEntity > ent2(
     714             :                     static_cast< unoidl::ConstantGroupEntity * >(
     715        1204 :                         i->second.entity.get()));
     716        2408 :                 std::map< OUString, ConstItem > cmap;
     717       39516 :                 for (std::vector< unoidl::ConstantGroupEntity::Member >::
     718        1204 :                          const_iterator j(ent2->getMembers().begin());
     719       26344 :                      j != ent2->getMembers().end(); ++j)
     720             :                 {
     721       23936 :                     if (!cmap.insert(
     722             :                             std::make_pair(
     723       23936 :                                 j->name, ConstItem(j->value, j->annotations))).
     724       11968 :                         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       39516 :                 for (std::map< OUString, ConstItem >::iterator j(cmap.begin());
     733       26344 :                      j != cmap.end(); ++j)
     734             :                 {
     735       11968 :                     j->second.dataOffset = getOffset(file);
     736       11968 :                     sal_uInt64 v = j->second.constant.type;
     737       11968 :                     if (!j->second.annotations.empty()) {
     738          14 :                         v |= 0x80;
     739             :                     }
     740       11968 :                     write8(file, v);
     741       11968 :                     switch (j->second.constant.type) {
     742             :                     case unoidl::ConstantValue::TYPE_BOOLEAN:
     743           1 :                         write8(file, j->second.constant.booleanValue ? 1 : 0);
     744           1 :                         break;
     745             :                     case unoidl::ConstantValue::TYPE_BYTE:
     746             :                         write8(
     747             :                             file,
     748             :                             static_cast< sal_uInt8 >(
     749         254 :                                 j->second.constant.byteValue));
     750         254 :                         break;
     751             :                     case unoidl::ConstantValue::TYPE_SHORT:
     752             :                         write16(
     753             :                             file,
     754             :                             static_cast< sal_uInt16 >(
     755        2075 :                                 j->second.constant.shortValue));
     756        2075 :                         break;
     757             :                     case unoidl::ConstantValue::TYPE_UNSIGNED_SHORT:
     758           8 :                         write16(file, j->second.constant.unsignedShortValue);
     759           8 :                         break;
     760             :                     case unoidl::ConstantValue::TYPE_LONG:
     761             :                         write32(
     762             :                             file,
     763             :                             static_cast< sal_uInt32 >(
     764        9554 :                                 j->second.constant.longValue));
     765        9554 :                         break;
     766             :                     case unoidl::ConstantValue::TYPE_UNSIGNED_LONG:
     767           8 :                         write32(file, j->second.constant.unsignedLongValue);
     768           8 :                         break;
     769             :                     case unoidl::ConstantValue::TYPE_HYPER:
     770             :                         write64(
     771             :                             file,
     772             :                             static_cast< sal_uInt64 >(
     773          38 :                                 j->second.constant.hyperValue));
     774          38 :                         break;
     775             :                     case unoidl::ConstantValue::TYPE_UNSIGNED_HYPER:
     776           8 :                         write64(file, j->second.constant.unsignedHyperValue);
     777           8 :                         break;
     778             :                     case unoidl::ConstantValue::TYPE_FLOAT:
     779             :                         writeIso60599Binary32(
     780          21 :                             file, j->second.constant.floatValue);
     781          21 :                         break;
     782             :                     case unoidl::ConstantValue::TYPE_DOUBLE:
     783             :                         writeIso60599Binary64(
     784           1 :                             file, j->second.constant.doubleValue);
     785           1 :                         break;
     786             :                     default:
     787           0 :                         for (;;) { std::abort(); } // this cannot happen
     788             :                     }
     789             :                     writeAnnotations(
     790       11968 :                         file, !j->second.annotations.empty(),
     791       23936 :                         j->second.annotations);
     792             :                 }
     793       39516 :                 for (std::map< OUString, ConstItem >::iterator j(
     794        1204 :                          cmap.begin());
     795       26344 :                      j != cmap.end(); ++j)
     796             :                 {
     797       11968 :                     j->second.nameOffset = writeNulName(file, j->first);
     798             :                 }
     799        1204 :                 bool ann = !ent2->getAnnotations().empty();
     800        1204 :                 i->second.dataOffset = getOffset(file);
     801        1204 :                 writeKind(file, ent2.get(), ann);
     802        1204 :                 write32(file, cmap.size());
     803             :                     // overflow from std::map::size_type -> sal_uInt64 is
     804             :                     // unrealistic
     805       39516 :                 for (std::map< OUString, ConstItem >::iterator j(
     806        1204 :                          cmap.begin());
     807       26344 :                      j != cmap.end(); ++j)
     808             :                 {
     809       11968 :                     write32(file, j->second.nameOffset);
     810       11968 :                     write32(file, j->second.dataOffset);
     811             :                 }
     812        1204 :                 writeAnnotations(file, ann, ent2->getAnnotations());
     813        2408 :                 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         513 :                                 i->second.entity.get()));
     822         513 :                 bool dfltCtor = ent2->getConstructors().size() == 1
     823         513 :                     && ent2->getConstructors()[0].defaultConstructor;
     824         513 :                 bool ann = !ent2->getAnnotations().empty();
     825         513 :                 if (!dfltCtor) {
     826        1731 :                     for (std::vector<
     827             :                              unoidl::SingleInterfaceBasedServiceEntity::
     828             :                              Constructor >::const_iterator j(
     829         273 :                                  ent2->getConstructors().begin());
     830        1731 :                          !ann && j != ent2->getConstructors().end(); ++j)
     831             :                     {
     832         304 :                         ann = !j->annotations.empty();
     833             :                     }
     834             :                 }
     835         513 :                 i->second.dataOffset = getOffset(file);
     836         513 :                 writeKind(file, ent2.get(), ann, dfltCtor);
     837         513 :                 writeIdxName(file, ent2->getBase());
     838         513 :                 if (!dfltCtor) {
     839         273 :                     write32(file, ent2->getConstructors().size());
     840        1731 :                     for (std::vector<
     841             :                              unoidl::SingleInterfaceBasedServiceEntity::
     842             :                              Constructor >::const_iterator j(
     843         273 :                                  ent2->getConstructors().begin());
     844        1154 :                          j != ent2->getConstructors().end(); ++j)
     845             :                     {
     846         304 :                         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         304 :                         writeIdxName(file, j->name);
     853         304 :                         write32(file, j->parameters.size());
     854        2454 :                         for (std::vector<
     855             :                                  unoidl::SingleInterfaceBasedServiceEntity::
     856             :                                  Constructor::Parameter >::const_iterator k(
     857         304 :                                      j->parameters.begin());
     858        1636 :                              k != j->parameters.end(); ++k)
     859             :                         {
     860         514 :                             sal_uInt64 f = 0;
     861         514 :                             if (k->rest) {
     862           6 :                                 f |= 0x04;
     863             :                             }
     864         514 :                             write8(file, f);
     865         514 :                             writeIdxName(file, k->name);
     866         514 :                             writeIdxName(file, k->type);
     867             :                         }
     868         304 :                         write32(file, j->exceptions.size());
     869        1107 :                         for (std::vector< OUString >::const_iterator k(
     870         304 :                                  j->exceptions.begin());
     871         738 :                              k != j->exceptions.end(); ++k)
     872             :                         {
     873          65 :                             writeIdxName(file, *k);
     874             :                         }
     875         304 :                         writeAnnotations(file, ann, j->annotations);
     876             :                     }
     877             :                 }
     878         513 :                 writeAnnotations(file, ann, ent2->getAnnotations());
     879         513 :                 break;
     880             :             }
     881             :         case unoidl::Entity::SORT_ACCUMULATION_BASED_SERVICE:
     882             :             {
     883             :                 rtl::Reference< unoidl::AccumulationBasedServiceEntity > ent2(
     884             :                     static_cast< unoidl::AccumulationBasedServiceEntity * >(
     885        1049 :                         i->second.entity.get()));
     886        1049 :                 bool ann = !ent2->getAnnotations().empty();
     887        5369 :                 for (std::vector< unoidl::AnnotatedReference >::const_iterator
     888        1049 :                          j(ent2->getDirectMandatoryBaseServices().begin());
     889        5287 :                      !ann && j != ent2->getDirectMandatoryBaseServices().end();
     890             :                      ++j)
     891             :                 {
     892         727 :                     ann = !j->annotations.empty();
     893             :                 }
     894        3372 :                 for (std::vector< unoidl::AnnotatedReference >::const_iterator
     895        1049 :                          j(ent2->getDirectOptionalBaseServices().begin());
     896        3288 :                      !ann && j != ent2->getDirectOptionalBaseServices().end();
     897             :                      ++j)
     898             :                 {
     899          61 :                     ann = !j->annotations.empty();
     900             :                 }
     901        7667 :                 for (std::vector< unoidl::AnnotatedReference >::const_iterator
     902        1049 :                          j(ent2->getDirectMandatoryBaseInterfaces().begin());
     903        2541 :                      (!ann
     904       10120 :                       && j != ent2->getDirectMandatoryBaseInterfaces().end());
     905             :                      ++j)
     906             :                 {
     907        1492 :                     ann = !j->annotations.empty();
     908             :                 }
     909        4019 :                 for (std::vector< unoidl::AnnotatedReference >::const_iterator
     910        1049 :                          j(ent2->getDirectOptionalBaseInterfaces().begin());
     911        3925 :                      !ann && j != ent2->getDirectOptionalBaseInterfaces().end();
     912             :                      ++j)
     913             :                 {
     914         275 :                     ann = !j->annotations.empty();
     915             :                 }
     916       12024 :                 for (std::vector<
     917             :                          unoidl::AccumulationBasedServiceEntity::Property >::
     918             :                          const_iterator j(
     919        1049 :                              ent2->getDirectProperties().begin());
     920       11904 :                      !ann && j != ent2->getDirectProperties().end(); ++j)
     921             :                 {
     922        2939 :                     ann = !j->annotations.empty();
     923             :                 }
     924        1049 :                 i->second.dataOffset = getOffset(file);
     925        1049 :                 writeKind(file, ent2.get(), ann);
     926        1049 :                 write32(file, ent2->getDirectMandatoryBaseServices().size());
     927        5355 :                 for (std::vector< unoidl::AnnotatedReference >::const_iterator
     928        1049 :                          j(ent2->getDirectMandatoryBaseServices().begin());
     929        3570 :                      j != ent2->getDirectMandatoryBaseServices().end(); ++j)
     930             :                 {
     931         736 :                     writeIdxName(file, j->name);
     932         736 :                     writeAnnotations(file, ann, j->annotations);
     933             :                 }
     934        1049 :                 write32(file, ent2->getDirectOptionalBaseServices().size());
     935        3333 :                 for (std::vector< unoidl::AnnotatedReference >::const_iterator
     936        1049 :                          j(ent2->getDirectOptionalBaseServices().begin());
     937        2222 :                      j != ent2->getDirectOptionalBaseServices().end(); ++j)
     938             :                 {
     939          62 :                     writeIdxName(file, j->name);
     940          62 :                     writeAnnotations(file, ann, j->annotations);
     941             :                 }
     942        1049 :                 write32(file, ent2->getDirectMandatoryBaseInterfaces().size());
     943        7845 :                 for (std::vector< unoidl::AnnotatedReference >::const_iterator
     944        1049 :                          j(ent2->getDirectMandatoryBaseInterfaces().begin());
     945        5230 :                      j != ent2->getDirectMandatoryBaseInterfaces().end(); ++j)
     946             :                 {
     947        1566 :                     writeIdxName(file, j->name);
     948        1566 :                     writeAnnotations(file, ann, j->annotations);
     949             :                 }
     950        1049 :                 write32(file, ent2->getDirectOptionalBaseInterfaces().size());
     951        4029 :                 for (std::vector< unoidl::AnnotatedReference >::const_iterator
     952        1049 :                          j(ent2->getDirectOptionalBaseInterfaces().begin());
     953        2686 :                      j != ent2->getDirectOptionalBaseInterfaces().end(); ++j)
     954             :                 {
     955         294 :                     writeIdxName(file, j->name);
     956         294 :                     writeAnnotations(file, ann, j->annotations);
     957             :                 }
     958        1049 :                 write32(file, ent2->getDirectProperties().size());
     959       12639 :                 for (std::vector<
     960             :                          unoidl::AccumulationBasedServiceEntity::Property >::
     961             :                          const_iterator j(
     962        1049 :                              ent2->getDirectProperties().begin());
     963        8426 :                      j != ent2->getDirectProperties().end(); ++j)
     964             :                 {
     965        3164 :                     write16(file, static_cast< sal_uInt16 >(j->attributes));
     966        3164 :                     writeIdxName(file, j->name);
     967        3164 :                     writeIdxName(file, j->type);
     968        3164 :                     writeAnnotations(file, ann, j->annotations);
     969             :                 }
     970        1049 :                 writeAnnotations(file, ann, ent2->getAnnotations());
     971        1049 :                 break;
     972             :             }
     973             :         case unoidl::Entity::SORT_INTERFACE_BASED_SINGLETON:
     974             :             {
     975             :                 rtl::Reference< unoidl::InterfaceBasedSingletonEntity > ent2(
     976             :                     static_cast< unoidl::InterfaceBasedSingletonEntity * >(
     977         183 :                         i->second.entity.get()));
     978         183 :                 bool ann = !ent2->getAnnotations().empty();
     979         183 :                 i->second.dataOffset = getOffset(file);
     980         183 :                 writeKind(file, ent2.get(), ann);
     981         183 :                 writeIdxName(file, ent2->getBase());
     982         183 :                 writeAnnotations(file, ann, ent2->getAnnotations());
     983         183 :                 break;
     984             :             }
     985             :         case unoidl::Entity::SORT_SERVICE_BASED_SINGLETON:
     986             :             {
     987             :                 rtl::Reference< unoidl::ServiceBasedSingletonEntity > ent2(
     988             :                     static_cast< unoidl::ServiceBasedSingletonEntity * >(
     989           6 :                         i->second.entity.get()));
     990           6 :                 bool ann = !ent2->getAnnotations().empty();
     991           6 :                 i->second.dataOffset = getOffset(file);
     992           6 :                 writeKind(file, ent2.get(), ann);
     993           6 :                 writeIdxName(file, ent2->getBase());
     994           6 :                 writeAnnotations(file, ann, ent2->getAnnotations());
     995           6 :                 break;
     996             :             }
     997             :         }
     998             :     }
     999        6713 :     for (std::map< OUString, Item >::iterator i(map.begin()); i != map.end();
    1000             :          ++i)
    1001             :     {
    1002        6309 :         i->second.nameOffset = writeNulName(file, i->first);
    1003             :     }
    1004         404 :     sal_uInt64 off = getOffset(file);
    1005         404 :     if (rootSize == 0) {
    1006         250 :         write8(file, 0); // SORT_MODULE
    1007         250 :         write32(file, map.size());
    1008             :             // overflow from std::map::size_type -> sal_uInt64 is unrealistic
    1009             :     } else {
    1010         154 :         *rootSize = map.size();
    1011             :             // overflow from std::map::size_type -> std::size_t is unrealistic
    1012             :     }
    1013        6713 :     for (std::map< OUString, Item >::iterator i(map.begin()); i != map.end();
    1014             :          ++i)
    1015             :     {
    1016        6309 :         write32(file, i->second.nameOffset);
    1017        6309 :         write32(file, i->second.dataOffset);
    1018             :     }
    1019         404 :     return off;
    1020             : }
    1021             : 
    1022             : }
    1023             : 
    1024         678 : SAL_IMPLEMENT_MAIN() {
    1025             :     try {
    1026         339 :         sal_uInt32 args = rtl_getAppCommandArgCount();
    1027         339 :         if (args == 0) {
    1028           0 :             badUsage();
    1029             :         }
    1030         339 :         rtl::Reference< unoidl::Manager > mgr(new unoidl::Manager);
    1031         339 :         bool entities = false;
    1032         678 :         rtl::Reference< unoidl::Provider > prov;
    1033         678 :         std::map< OUString, Item > map;
    1034         838 :         for (sal_uInt32 i = 0; i != args - 1; ++i) {
    1035             :             assert(args > 1);
    1036         684 :             OUString uri(getArgumentUri(i, i == args - 2 ? &entities : 0));
    1037         684 :             if (entities) {
    1038           5 :                 mapEntities(mgr, uri, map);
    1039             :             } else {
    1040             :                 try {
    1041         679 :                     prov = mgr->addProvider(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             :             }
    1048         684 :         }
    1049         154 :         if (!entities) {
    1050             :             mapCursor(
    1051         149 :                 (prov.is()
    1052         149 :                  ? prov->createRootCursor()
    1053             :                  : rtl::Reference< unoidl::MapCursor >()),
    1054         298 :                 map);
    1055             :         }
    1056         308 :         osl::File f(getArgumentUri(args - 1, 0));
    1057         154 :         osl::FileBase::RC e = f.open(osl_File_OpenFlag_Write);
    1058         154 :         if (e == osl::FileBase::E_NOENT) {
    1059          11 :             e = f.open(osl_File_OpenFlag_Write | osl_File_OpenFlag_Create);
    1060             :         }
    1061         154 :         if (e != osl::FileBase::E_None) {
    1062             :             std::cerr
    1063           0 :                 << "Cannot open <" << f.getURL() << "> for writing, error code "
    1064           0 :                 << +e << std::endl;
    1065           0 :             std::exit(EXIT_FAILURE);
    1066             :         }
    1067         154 :         write(f, "UNOIDL\xFF\0", 8);
    1068         154 :         write32(f, 0); // root map offset
    1069         154 :         write32(f, 0); // root map size
    1070             :         write(
    1071             :             f,
    1072         154 :             RTL_CONSTASCII_STRINGPARAM(
    1073             :                 "\0** Created by LibreOffice " LIBO_VERSION_DOTTED
    1074         154 :                 " unoidl-write **\0"));
    1075             :         std::size_t size;
    1076         154 :         sal_uInt64 off = writeMap(f, map, &size);
    1077         154 :         e = f.setSize(getOffset(f)); // truncate in case it already existed
    1078         154 :         if (e != osl::FileBase::E_None) {
    1079             :             std::cerr
    1080           0 :                 << "Cannot set size of <" << f.getURL() << ">, error code "
    1081           0 :                 << +e << std::endl;
    1082           0 :             std::exit(EXIT_FAILURE);
    1083             :         }
    1084         154 :         e = f.setPos(osl_Pos_Absolut, 8);
    1085         154 :         if (e != osl::FileBase::E_None) {
    1086             :             std::cerr
    1087           0 :                 << "Cannot rewind current position in <" << f.getURL()
    1088           0 :                 << ">, error code " << +e << std::endl;
    1089           0 :             std::exit(EXIT_FAILURE);
    1090             :         }
    1091         154 :         write32(f, off);
    1092         154 :         write32(f, size);
    1093             :             // overflow from std::map::size_type -> sal_uInt64 is unrealistic
    1094         154 :         e = f.close();
    1095         154 :         if (e != osl::FileBase::E_None) {
    1096             :             std::cerr
    1097           0 :                 << "Cannot close <" << f.getURL()
    1098           0 :                 << "> after writing, error code " << +e << std::endl;
    1099           0 :             std::exit(EXIT_FAILURE);
    1100             :         }
    1101         493 :         return EXIT_SUCCESS;
    1102           0 :     } catch (unoidl::FileFormatException & e1) {
    1103             :         std::cerr
    1104         370 :             << "Bad input <" << e1.getUri() << ">: " << e1.getDetail()
    1105         185 :             << std::endl;
    1106         185 :         std::exit(EXIT_FAILURE);
    1107             :     }
    1108        1017 : }
    1109             : 
    1110             : /* vim:set shiftwidth=4 softtabstop=4 expandtab: */

Generated by: LCOV version 1.11