bump product version to 4.1.6.2
[LibreOffice.git] / unoidl / source / reg2unoidl.cxx
blobbf2b6d271ab2bbdd74d1be1f3392d473dfd30ed7
1 /* -*- Mode: C++; tab-width: 4; indent-tabs-mode: nil; c-basic-offset: 4 -*- */
2 /*
3 * This file is part of the LibreOffice project.
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 */
10 #include "sal/config.h"
12 #include <cassert>
13 #include <cstddef>
14 #include <cstdlib>
15 #include <iostream>
16 #include <map>
17 #include <utility>
18 #include <vector>
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"
35 namespace {
37 OUString getArgumentUri(sal_uInt32 argument) {
38 OUString arg;
39 rtl_getAppCommandArg(argument, &arg.pData);
40 OUString url;
41 osl::FileBase::RC e1 = osl::FileBase::getFileURLFromSystemPath(arg, url);
42 if (e1 != osl::FileBase::E_None) {
43 std::cerr
44 << "Cannot convert \"" << arg << "\" to file URL, error code "
45 << +e1 << std::endl;
46 std::exit(EXIT_FAILURE);
48 OUString cwd;
49 oslProcessError e2 = osl_getProcessWorkingDir(&cwd.pData);
50 if (e2 != osl_Process_E_None) {
51 std::cerr
52 << "Cannot obtain working directory, error code " << +e2
53 << std::endl;
54 std::exit(EXIT_FAILURE);
56 OUString abs;
57 e1 = osl::FileBase::getAbsoluteFileURL(cwd, url, abs);
58 if (e1 != osl::FileBase::E_None) {
59 std::cerr
60 << "Cannot make \"" << url
61 << "\" into an absolute file URL, error code " << +e1 << std::endl;
62 std::exit(EXIT_FAILURE);
64 return abs;
67 rtl::Reference< unoidl::Provider > load(
68 rtl::Reference< unoidl::Manager > const & manager, OUString const & uri)
70 try {
71 return unoidl::loadProvider(manager, uri);
72 } catch (unoidl::NoSuchFileException &) {
73 std::cerr << "Input <" << uri << "> does not exist" << std::endl;
74 std::exit(EXIT_FAILURE);
75 } catch (unoidl::FileFormatException & e) {
76 std::cerr
77 << "Cannot read input <" << uri << ">: " << e.getDetail()
78 << std::endl;
79 std::exit(EXIT_FAILURE);
83 sal_uInt64 getOffset(osl::File & file) {
84 sal_uInt64 off;
85 osl::FileBase::RC e = file.getPos(off);
86 if (e != osl::FileBase::E_None) {
87 std::cerr
88 << "Cannot determine current position in <" << file.getURL()
89 << ">, error code " << +e << std::endl;
90 std::exit(EXIT_FAILURE);
92 return off;
95 void write(osl::File & file, void const * buffer, sal_uInt64 size) {
96 sal_uInt64 n;
97 osl::FileBase::RC e = file.write(buffer, size, n);
98 if (e != osl::FileBase::E_None) {
99 std::cerr
100 << "Cannot write to <" << file.getURL() << ">, error code " << +e
101 << std::endl;
102 std::exit(EXIT_FAILURE);
104 if (n != size) {
105 std::cerr
106 << "Bad write of " << n << " instead of " << size << " bytes to <"
107 << file.getURL() << '>' << std::endl;
108 std::exit(EXIT_FAILURE);
112 void write8(osl::File & file, sal_uInt64 value) {
113 if (value > 0xFF) {
114 std::cerr
115 << "Cannot write value >= 2^8; input is too large" << std::endl;
116 std::exit(EXIT_FAILURE);
118 unsigned char buf[1];
119 buf[0] = value & 0xFF;
120 write(file, buf, SAL_N_ELEMENTS(buf));
123 void write16(osl::File & file, sal_uInt64 value) {
124 if (value > 0xFFFF) {
125 std::cerr
126 << "Cannot write value >= 2^16; input is too large" << std::endl;
127 std::exit(EXIT_FAILURE);
129 unsigned char buf[2];
130 buf[0] = value & 0xFF;
131 buf[1] = (value >> 8) & 0xFF;
132 write(file, buf, SAL_N_ELEMENTS(buf));
135 void write32(osl::File & file, sal_uInt64 value) {
136 if (value > 0xFFFFFFFF) {
137 std::cerr
138 << "Cannot write value >= 2^32; input is too large" << std::endl;
139 std::exit(EXIT_FAILURE);
141 unsigned char buf[4];
142 buf[0] = value & 0xFF;
143 buf[1] = (value >> 8) & 0xFF;
144 buf[2] = (value >> 16) & 0xFF;
145 buf[3] = (value >> 24) & 0xFF;
146 write(file, buf, SAL_N_ELEMENTS(buf));
149 void write64(osl::File & file, sal_uInt64 value) {
150 unsigned char buf[8];
151 buf[0] = value & 0xFF;
152 buf[1] = (value >> 8) & 0xFF;
153 buf[2] = (value >> 16) & 0xFF;
154 buf[3] = (value >> 24) & 0xFF;
155 buf[4] = (value >> 32) & 0xFF;
156 buf[5] = (value >> 40) & 0xFF;
157 buf[6] = (value >> 48) & 0xFF;
158 buf[7] = (value >> 56) & 0xFF;
159 write(file, buf, SAL_N_ELEMENTS(buf));
162 void writeIso60599Binary32(osl::File & file, float value) {
163 union {
164 unsigned char buf[4];
165 float f; // assuming float is ISO 60599 binary32
166 } sa;
167 sa.f = value;
168 #if defined OSL_BIGENDIAN
169 std::swap(sa.buf[0], sa.buf[3]);
170 std::swap(sa.buf[1], sa.buf[2]);
171 #endif
172 write(file, sa.buf, SAL_N_ELEMENTS(sa.buf));
175 void writeIso60599Binary64(osl::File & file, double value) {
176 union {
177 unsigned char buf[8];
178 float d; // assuming double is ISO 60599 binary64
179 } sa;
180 sa.d = value;
181 #if defined OSL_BIGENDIAN
182 std::swap(sa.buf[0], sa.buf[7]);
183 std::swap(sa.buf[1], sa.buf[6]);
184 std::swap(sa.buf[2], sa.buf[5]);
185 std::swap(sa.buf[3], sa.buf[4]);
186 #endif
187 write(file, sa.buf, SAL_N_ELEMENTS(sa.buf));
190 OString toAscii(OUString const & name) {
191 OString ascii;
192 if (!name.convertToString(
193 &ascii, RTL_TEXTENCODING_ASCII_US,
194 (RTL_UNICODETOTEXT_FLAGS_UNDEFINED_ERROR
195 | RTL_UNICODETOTEXT_FLAGS_INVALID_ERROR)))
197 std::cerr
198 << "Cannot convert \"" << name << "\" to US ASCII" << std::endl;
199 std::exit(EXIT_FAILURE);
201 return ascii;
204 OString toUtf8(OUString const & string) {
205 OString ascii;
206 if (!string.convertToString(
207 &ascii, RTL_TEXTENCODING_UTF8,
208 (RTL_UNICODETOTEXT_FLAGS_UNDEFINED_ERROR
209 | RTL_UNICODETOTEXT_FLAGS_INVALID_ERROR)))
211 std::cerr
212 << "Cannot convert \"" << string << "\" to UTF-8" << std::endl;
213 std::exit(EXIT_FAILURE);
215 return ascii;
218 sal_uInt64 writeNulName(osl::File & file, OUString const & name) {
219 OString ascii(toAscii(name));
220 if (ascii.indexOf('\0') != -1) {
221 std::cerr
222 << "Name \"" << ascii << "\" contains NUL characters" << std::endl;
223 std::exit(EXIT_FAILURE);
225 sal_uInt64 off = getOffset(file);
226 write(file, ascii.getStr(), ascii.getLength() + 1);
227 return off;
230 void writeIdxString(osl::File & file, OString const & string) {
231 static std::map< OString, sal_uInt64 > reuse;
232 std::map< OString, sal_uInt64 >::iterator i(reuse.find(string));
233 if (i == reuse.end()) {
234 reuse.insert(std::make_pair(string, getOffset(file)));
235 assert(
236 (static_cast< sal_uInt64 >(string.getLength()) & 0x80000000) == 0);
237 write32(file, static_cast< sal_uInt64 >(string.getLength()));
238 write(file, string.getStr(), string.getLength());
239 } else {
240 if ((i->second & 0x80000000) != 0) {
241 std::cerr
242 << "Cannot write index 0x" << std::hex << i->second << std::dec
243 << " of \"" << string << "\"; input is too large" << std::endl;
244 std::exit(EXIT_FAILURE);
246 write32(file, i->second | 0x80000000);
250 void writeIdxName(osl::File & file, OUString const & name) {
251 writeIdxString(file, toAscii(name));
254 void writeAnnotations(
255 osl::File & file, bool annotate,
256 std::vector< OUString > const & annotations)
258 assert(annotate || annotations.empty());
259 if (annotate) {
260 write32(file, annotations.size());
261 // overflow from std::vector::size_type -> sal_uInt64 is unrealistic
262 for (std::vector< OUString >::const_iterator i(annotations.begin());
263 i != annotations.end(); ++i)
265 writeIdxString(file, toUtf8(*i));
270 void writeKind(
271 osl::File & file,
272 rtl::Reference< unoidl::PublishableEntity > const & entity,
273 bool annotated, bool flag = false)
275 assert(entity.is());
276 sal_uInt64 v = entity->getSort();
277 if (entity->isPublished()) {
278 v |= 0x80;
280 if (annotated) {
281 v |= 0x40;
283 if (flag) {
284 v |= 0x20;
286 write8(file, v);
289 struct Item {
290 explicit Item(rtl::Reference< unoidl::Entity > const & theEntity):
291 entity(theEntity), nameOffset(0), dataOffset(0)
294 rtl::Reference< unoidl::Entity > entity;
295 sal_uInt64 nameOffset;
296 sal_uInt64 dataOffset;
299 struct ConstItem {
300 ConstItem(
301 unoidl::ConstantValue const & theConstant,
302 std::vector< OUString > const & theAnnotations):
303 constant(theConstant), annotations(theAnnotations), nameOffset(0),
304 dataOffset(0)
307 unoidl::ConstantValue constant;
308 std::vector< OUString > annotations;
309 sal_uInt64 nameOffset;
310 sal_uInt64 dataOffset;
313 sal_uInt64 writeMap(
314 osl::File & file, rtl::Reference< unoidl::MapCursor > const & cursor,
315 std::size_t * rootSize)
317 assert(cursor.is());
318 std::map< OUString, Item > map;
319 for (;;) {
320 OUString name;
321 rtl::Reference< unoidl::Entity > ent(cursor->getNext(&name));
322 if (!ent.is()) {
323 break;
325 if (!map.insert(std::make_pair(name, Item(ent))).second) {
326 std::cout << "Duplicate name \"" << name << '"' << std::endl;
327 std::exit(EXIT_FAILURE);
330 for (std::map< OUString, Item >::iterator i(map.begin()); i != map.end();
331 ++i)
333 switch (i->second.entity->getSort()) {
334 case unoidl::Entity::SORT_MODULE:
336 rtl::Reference< unoidl::ModuleEntity > ent2(
337 static_cast< unoidl::ModuleEntity * >(
338 i->second.entity.get()));
339 i->second.dataOffset = writeMap(file, ent2->createCursor(), 0);
340 break;
342 case unoidl::Entity::SORT_ENUM_TYPE:
344 rtl::Reference< unoidl::EnumTypeEntity > ent2(
345 static_cast< unoidl::EnumTypeEntity * >(
346 i->second.entity.get()));
347 bool ann = !ent2->getAnnotations().empty();
348 for (std::vector< unoidl::EnumTypeEntity::Member >::
349 const_iterator j(ent2->getMembers().begin());
350 !ann && j != ent2->getMembers().end(); ++j)
352 ann = !j->annotations.empty();
354 i->second.dataOffset = getOffset(file);
355 writeKind(file, ent2.get(), ann);
356 write32(file, ent2->getMembers().size());
357 for (std::vector< unoidl::EnumTypeEntity::Member >::
358 const_iterator j(ent2->getMembers().begin());
359 j != ent2->getMembers().end(); ++j)
361 writeIdxName(file, j->name);
362 write32(file, static_cast< sal_uInt32 >(j->value));
363 writeAnnotations(file, ann, j->annotations);
365 writeAnnotations(file, ann, ent2->getAnnotations());
366 break;
368 case unoidl::Entity::SORT_PLAIN_STRUCT_TYPE:
370 rtl::Reference< unoidl::PlainStructTypeEntity > ent2(
371 static_cast< unoidl::PlainStructTypeEntity * >(
372 i->second.entity.get()));
373 bool ann = !ent2->getAnnotations().empty();
374 for (std::vector< unoidl::PlainStructTypeEntity::Member >::
375 const_iterator j(ent2->getDirectMembers().begin());
376 !ann && j != ent2->getDirectMembers().end(); ++j)
378 ann = !j->annotations.empty();
380 i->second.dataOffset = getOffset(file);
381 writeKind(
382 file, ent2.get(), ann, !ent2->getDirectBase().isEmpty());
383 if (!ent2->getDirectBase().isEmpty()) {
384 writeIdxName(file, ent2->getDirectBase());
386 write32(file, ent2->getDirectMembers().size());
387 for (std::vector< unoidl::PlainStructTypeEntity::Member >::
388 const_iterator j(ent2->getDirectMembers().begin());
389 j != ent2->getDirectMembers().end(); ++j)
391 writeIdxName(file, j->name);
392 writeIdxName(file, j->type);
393 writeAnnotations(file, ann, j->annotations);
395 writeAnnotations(file, ann, ent2->getAnnotations());
396 break;
398 case unoidl::Entity::SORT_POLYMORPHIC_STRUCT_TYPE_TEMPLATE:
400 rtl::Reference< unoidl::PolymorphicStructTypeTemplateEntity >
401 ent2(
402 static_cast<
403 unoidl::PolymorphicStructTypeTemplateEntity * >(
404 i->second.entity.get()));
405 bool ann = !ent2->getAnnotations().empty();
406 for (std::vector<
407 unoidl::PolymorphicStructTypeTemplateEntity::Member >::
408 const_iterator j(
409 ent2->getMembers().begin());
410 !ann && j != ent2->getMembers().end(); ++j)
412 ann = !j->annotations.empty();
414 i->second.dataOffset = getOffset(file);
415 writeKind(file, ent2.get(), ann);
416 write32(file, ent2->getTypeParameters().size());
417 for (std::vector< OUString >::const_iterator j(
418 ent2->getTypeParameters().begin());
419 j != ent2->getTypeParameters().end(); ++j)
421 writeIdxName(file, *j);
423 write32(file, ent2->getMembers().size());
424 for (std::vector<
425 unoidl::PolymorphicStructTypeTemplateEntity::Member >::
426 const_iterator j(
427 ent2->getMembers().begin());
428 j != ent2->getMembers().end(); ++j)
430 sal_uInt64 f = 0;
431 if (j->parameterized) {
432 f |= 0x01;
434 write8(file, f);
435 writeIdxName(file, j->name);
436 writeIdxName(file, j->type);
437 writeAnnotations(file, ann, j->annotations);
439 writeAnnotations(file, ann, ent2->getAnnotations());
440 break;
442 case unoidl::Entity::SORT_EXCEPTION_TYPE:
444 rtl::Reference< unoidl::ExceptionTypeEntity > ent2(
445 static_cast< unoidl::ExceptionTypeEntity * >(
446 i->second.entity.get()));
447 bool ann = !ent2->getAnnotations().empty();
448 for (std::vector< unoidl::ExceptionTypeEntity::Member >::
449 const_iterator j(ent2->getDirectMembers().begin());
450 !ann && j != ent2->getDirectMembers().end(); ++j)
452 ann = !j->annotations.empty();
454 i->second.dataOffset = getOffset(file);
455 writeKind(
456 file, ent2.get(), ann, !ent2->getDirectBase().isEmpty());
457 if (!ent2->getDirectBase().isEmpty()) {
458 writeIdxName(file, ent2->getDirectBase());
460 write32(file, ent2->getDirectMembers().size());
461 for (std::vector< unoidl::ExceptionTypeEntity::Member >::
462 const_iterator j(ent2->getDirectMembers().begin());
463 j != ent2->getDirectMembers().end(); ++j)
465 writeIdxName(file, j->name);
466 writeIdxName(file, j->type);
467 writeAnnotations(file, ann, j->annotations);
469 writeAnnotations(file, ann, ent2->getAnnotations());
470 break;
472 case unoidl::Entity::SORT_INTERFACE_TYPE:
474 rtl::Reference< unoidl::InterfaceTypeEntity > ent2(
475 static_cast< unoidl::InterfaceTypeEntity * >(
476 i->second.entity.get()));
477 bool ann = !ent2->getAnnotations().empty();
478 for (std::vector< unoidl::AnnotatedReference >::const_iterator
479 j(ent2->getDirectMandatoryBases().begin());
480 !ann && j != ent2->getDirectMandatoryBases().end(); ++j)
482 ann = !j->annotations.empty();
484 for (std::vector< unoidl::AnnotatedReference >::const_iterator
485 j(ent2->getDirectOptionalBases().begin());
486 !ann && j != ent2->getDirectOptionalBases().end(); ++j)
488 ann = !j->annotations.empty();
490 for (std::vector< unoidl::InterfaceTypeEntity::Attribute >::
491 const_iterator j(ent2->getDirectAttributes().begin());
492 !ann && j != ent2->getDirectAttributes().end(); ++j)
494 ann = !j->annotations.empty();
496 for (std::vector< unoidl::InterfaceTypeEntity::Method >::
497 const_iterator j(ent2->getDirectMethods().begin());
498 !ann && j != ent2->getDirectMethods().end(); ++j)
500 ann = !j->annotations.empty();
502 i->second.dataOffset = getOffset(file);
503 writeKind(file, ent2.get(), ann);
504 write32(file, ent2->getDirectMandatoryBases().size());
505 for (std::vector< unoidl::AnnotatedReference >::const_iterator
506 j(ent2->getDirectMandatoryBases().begin());
507 j != ent2->getDirectMandatoryBases().end(); ++j)
509 writeIdxName(file, j->name);
510 writeAnnotations(file, ann, j->annotations);
512 write32(file, ent2->getDirectOptionalBases().size());
513 for (std::vector< unoidl::AnnotatedReference >::const_iterator
514 j(ent2->getDirectOptionalBases().begin());
515 j != ent2->getDirectOptionalBases().end(); ++j)
517 writeIdxName(file, j->name);
518 writeAnnotations(file, ann, j->annotations);
520 write32(file, ent2->getDirectAttributes().size());
521 for (std::vector< unoidl::InterfaceTypeEntity::Attribute >::
522 const_iterator j(ent2->getDirectAttributes().begin());
523 j != ent2->getDirectAttributes().end(); ++j)
525 sal_uInt64 f = 0;
526 if (j->bound) {
527 f |= 0x01;
529 if (j->readOnly) {
530 f |= 0x02;
532 write8(file, f);
533 writeIdxName(file, j->name);
534 writeIdxName(file, j->type);
535 write32(file, j->getExceptions.size());
536 for (std::vector< OUString >::const_iterator k(
537 j->getExceptions.begin());
538 k != j->getExceptions.end(); ++k)
540 writeIdxName(file, *k);
542 if (!j->readOnly) {
543 write32(file, j->setExceptions.size());
544 for (std::vector< OUString >::const_iterator k(
545 j->setExceptions.begin());
546 k != j->setExceptions.end(); ++k)
548 writeIdxName(file, *k);
551 writeAnnotations(file, ann, j->annotations);
553 write32(file, ent2->getDirectMethods().size());
554 for (std::vector< unoidl::InterfaceTypeEntity::Method >::
555 const_iterator j(ent2->getDirectMethods().begin());
556 j != ent2->getDirectMethods().end(); ++j)
558 writeIdxName(file, j->name);
559 writeIdxName(file, j->returnType);
560 write32(file, j->parameters.size());
561 for (std::vector<
562 unoidl::InterfaceTypeEntity::Method::Parameter >::
563 const_iterator k(j->parameters.begin());
564 k != j->parameters.end(); ++k)
566 write8(file, k->direction);
567 writeIdxName(file, k->name);
568 writeIdxName(file, k->type);
570 write32(file, j->exceptions.size());
571 for (std::vector< OUString >::const_iterator k(
572 j->exceptions.begin());
573 k != j->exceptions.end(); ++k)
575 writeIdxName(file, *k);
577 writeAnnotations(file, ann, j->annotations);
579 writeAnnotations(file, ann, ent2->getAnnotations());
580 break;
582 case unoidl::Entity::SORT_TYPEDEF:
584 rtl::Reference< unoidl::TypedefEntity > ent2(
585 static_cast< unoidl::TypedefEntity * >(
586 i->second.entity.get()));
587 bool ann = !ent2->getAnnotations().empty();
588 i->second.dataOffset = getOffset(file);
589 writeKind(file, ent2.get(), ann);
590 writeIdxName(file, ent2->getType());
591 writeAnnotations(file, ann, ent2->getAnnotations());
592 break;
594 case unoidl::Entity::SORT_CONSTANT_GROUP:
596 rtl::Reference< unoidl::ConstantGroupEntity > ent2(
597 static_cast< unoidl::ConstantGroupEntity * >(
598 i->second.entity.get()));
599 std::map< OUString, ConstItem > cmap;
600 for (std::vector< unoidl::ConstantGroupEntity::Member >::
601 const_iterator j(ent2->getMembers().begin());
602 j != ent2->getMembers().end(); ++j)
604 if (!cmap.insert(
605 std::make_pair(
606 j->name, ConstItem(j->value, j->annotations))).
607 second)
609 std::cout
610 << "Duplicate constant group member name \""
611 << j->name << '"' << std::endl;
612 std::exit(EXIT_FAILURE);
615 for (std::map< OUString, ConstItem >::iterator j(cmap.begin());
616 j != cmap.end(); ++j)
618 j->second.dataOffset = getOffset(file);
619 sal_uInt64 v = j->second.constant.type;
620 if (!j->second.annotations.empty()) {
621 v |= 0x80;
623 write8(file, v);
624 switch (j->second.constant.type) {
625 case unoidl::ConstantValue::TYPE_BOOLEAN:
626 write8(file, j->second.constant.booleanValue ? 1 : 0);
627 break;
628 case unoidl::ConstantValue::TYPE_BYTE:
629 write8(
630 file,
631 static_cast< sal_uInt8 >(
632 j->second.constant.byteValue));
633 break;
634 case unoidl::ConstantValue::TYPE_SHORT:
635 write16(
636 file,
637 static_cast< sal_uInt16 >(
638 j->second.constant.shortValue));
639 break;
640 case unoidl::ConstantValue::TYPE_UNSIGNED_SHORT:
641 write16(file, j->second.constant.unsignedShortValue);
642 break;
643 case unoidl::ConstantValue::TYPE_LONG:
644 write32(
645 file,
646 static_cast< sal_uInt32 >(
647 j->second.constant.longValue));
648 break;
649 case unoidl::ConstantValue::TYPE_UNSIGNED_LONG:
650 write32(file, j->second.constant.unsignedLongValue);
651 break;
652 case unoidl::ConstantValue::TYPE_HYPER:
653 write64(
654 file,
655 static_cast< sal_uInt64 >(
656 j->second.constant.hyperValue));
657 break;
658 case unoidl::ConstantValue::TYPE_UNSIGNED_HYPER:
659 write64(file, j->second.constant.unsignedHyperValue);
660 break;
661 case unoidl::ConstantValue::TYPE_FLOAT:
662 writeIso60599Binary32(
663 file, j->second.constant.floatValue);
664 break;
665 case unoidl::ConstantValue::TYPE_DOUBLE:
666 writeIso60599Binary64(
667 file, j->second.constant.doubleValue);
668 break;
669 default:
670 for (;;) { std::abort(); } // this cannot happen
672 writeAnnotations(
673 file, !j->second.annotations.empty(),
674 j->second.annotations);
676 for (std::map< OUString, ConstItem >::iterator j(
677 cmap.begin());
678 j != cmap.end(); ++j)
680 j->second.nameOffset = writeNulName(file, j->first);
682 bool ann = !ent2->getAnnotations().empty();
683 i->second.dataOffset = getOffset(file);
684 writeKind(file, ent2.get(), ann);
685 write32(file, cmap.size());
686 // overflow from std::map::size_type -> sal_uInt64 is
687 // unrealistic
688 for (std::map< OUString, ConstItem >::iterator j(
689 cmap.begin());
690 j != cmap.end(); ++j)
692 write32(file, j->second.nameOffset);
693 write32(file, j->second.dataOffset);
695 writeAnnotations(file, ann, ent2->getAnnotations());
696 break;
698 case unoidl::Entity::SORT_SINGLE_INTERFACE_BASED_SERVICE:
700 rtl::Reference< unoidl::SingleInterfaceBasedServiceEntity >
701 ent2(
702 static_cast<
703 unoidl::SingleInterfaceBasedServiceEntity * >(
704 i->second.entity.get()));
705 bool dfltCtor = ent2->getConstructors().size() == 1
706 && ent2->getConstructors()[0].defaultConstructor;
707 bool ann = !ent2->getAnnotations().empty();
708 if (!dfltCtor) {
709 for (std::vector<
710 unoidl::SingleInterfaceBasedServiceEntity::
711 Constructor >::const_iterator j(
712 ent2->getConstructors().begin());
713 !ann && j != ent2->getConstructors().end(); ++j)
715 ann = !j->annotations.empty();
718 i->second.dataOffset = getOffset(file);
719 writeKind(file, ent2.get(), ann, dfltCtor);
720 writeIdxName(file, ent2->getBase());
721 if (!dfltCtor) {
722 write32(file, ent2->getConstructors().size());
723 for (std::vector<
724 unoidl::SingleInterfaceBasedServiceEntity::
725 Constructor >::const_iterator j(
726 ent2->getConstructors().begin());
727 j != ent2->getConstructors().end(); ++j)
729 if (j->defaultConstructor) {
730 std::cout
731 << "Unexpected default constructor \""
732 << j->name << '"' << std::endl;
733 std::exit(EXIT_FAILURE);
735 writeIdxName(file, j->name);
736 write32(file, j->parameters.size());
737 for (std::vector<
738 unoidl::SingleInterfaceBasedServiceEntity::
739 Constructor::Parameter >::const_iterator k(
740 j->parameters.begin());
741 k != j->parameters.end(); ++k)
743 sal_uInt64 f = 0;
744 if (k->rest) {
745 f |= 0x04;
747 write8(file, f);
748 writeIdxName(file, k->name);
749 writeIdxName(file, k->type);
751 write32(file, j->exceptions.size());
752 for (std::vector< OUString >::const_iterator k(
753 j->exceptions.begin());
754 k != j->exceptions.end(); ++k)
756 writeIdxName(file, *k);
758 writeAnnotations(file, ann, j->annotations);
761 writeAnnotations(file, ann, ent2->getAnnotations());
762 break;
764 case unoidl::Entity::SORT_ACCUMULATION_BASED_SERVICE:
766 rtl::Reference< unoidl::AccumulationBasedServiceEntity > ent2(
767 static_cast< unoidl::AccumulationBasedServiceEntity * >(
768 i->second.entity.get()));
769 bool ann = !ent2->getAnnotations().empty();
770 for (std::vector< unoidl::AnnotatedReference >::const_iterator
771 j(ent2->getDirectMandatoryBaseServices().begin());
772 !ann && j != ent2->getDirectMandatoryBaseServices().end();
773 ++j)
775 ann = !j->annotations.empty();
777 for (std::vector< unoidl::AnnotatedReference >::const_iterator
778 j(ent2->getDirectOptionalBaseServices().begin());
779 !ann && j != ent2->getDirectOptionalBaseServices().end();
780 ++j)
782 ann = !j->annotations.empty();
784 for (std::vector< unoidl::AnnotatedReference >::const_iterator
785 j(ent2->getDirectMandatoryBaseInterfaces().begin());
786 (!ann
787 && j != ent2->getDirectMandatoryBaseInterfaces().end());
788 ++j)
790 ann = !j->annotations.empty();
792 for (std::vector< unoidl::AnnotatedReference >::const_iterator
793 j(ent2->getDirectOptionalBaseInterfaces().begin());
794 !ann && j != ent2->getDirectOptionalBaseInterfaces().end();
795 ++j)
797 ann = !j->annotations.empty();
799 for (std::vector<
800 unoidl::AccumulationBasedServiceEntity::Property >::
801 const_iterator j(
802 ent2->getDirectProperties().begin());
803 !ann && j != ent2->getDirectProperties().end(); ++j)
805 ann = !j->annotations.empty();
807 i->second.dataOffset = getOffset(file);
808 writeKind(file, ent2.get(), ann);
809 write32(file, ent2->getDirectMandatoryBaseServices().size());
810 for (std::vector< unoidl::AnnotatedReference >::const_iterator
811 j(ent2->getDirectMandatoryBaseServices().begin());
812 j != ent2->getDirectMandatoryBaseServices().end(); ++j)
814 writeIdxName(file, j->name);
815 writeAnnotations(file, ann, j->annotations);
817 write32(file, ent2->getDirectOptionalBaseServices().size());
818 for (std::vector< unoidl::AnnotatedReference >::const_iterator
819 j(ent2->getDirectOptionalBaseServices().begin());
820 j != ent2->getDirectOptionalBaseServices().end(); ++j)
822 writeIdxName(file, j->name);
823 writeAnnotations(file, ann, j->annotations);
825 write32(file, ent2->getDirectMandatoryBaseInterfaces().size());
826 for (std::vector< unoidl::AnnotatedReference >::const_iterator
827 j(ent2->getDirectMandatoryBaseInterfaces().begin());
828 j != ent2->getDirectMandatoryBaseInterfaces().end(); ++j)
830 writeIdxName(file, j->name);
831 writeAnnotations(file, ann, j->annotations);
833 write32(file, ent2->getDirectOptionalBaseInterfaces().size());
834 for (std::vector< unoidl::AnnotatedReference >::const_iterator
835 j(ent2->getDirectOptionalBaseInterfaces().begin());
836 j != ent2->getDirectOptionalBaseInterfaces().end(); ++j)
838 writeIdxName(file, j->name);
839 writeAnnotations(file, ann, j->annotations);
841 write32(file, ent2->getDirectProperties().size());
842 for (std::vector<
843 unoidl::AccumulationBasedServiceEntity::Property >::
844 const_iterator j(
845 ent2->getDirectProperties().begin());
846 j != ent2->getDirectProperties().end(); ++j)
848 write16(file, static_cast< sal_uInt16 >(j->attributes));
849 writeIdxName(file, j->name);
850 writeIdxName(file, j->type);
851 writeAnnotations(file, ann, j->annotations);
853 writeAnnotations(file, ann, ent2->getAnnotations());
854 break;
856 case unoidl::Entity::SORT_INTERFACE_BASED_SINGLETON:
858 rtl::Reference< unoidl::InterfaceBasedSingletonEntity > ent2(
859 static_cast< unoidl::InterfaceBasedSingletonEntity * >(
860 i->second.entity.get()));
861 bool ann = !ent2->getAnnotations().empty();
862 i->second.dataOffset = getOffset(file);
863 writeKind(file, ent2.get(), ann);
864 writeIdxName(file, ent2->getBase());
865 writeAnnotations(file, ann, ent2->getAnnotations());
866 break;
868 case unoidl::Entity::SORT_SERVICE_BASED_SINGLETON:
870 rtl::Reference< unoidl::ServiceBasedSingletonEntity > ent2(
871 static_cast< unoidl::ServiceBasedSingletonEntity * >(
872 i->second.entity.get()));
873 bool ann = !ent2->getAnnotations().empty();
874 i->second.dataOffset = getOffset(file);
875 writeKind(file, ent2.get(), ann);
876 writeIdxName(file, ent2->getBase());
877 writeAnnotations(file, ann, ent2->getAnnotations());
878 break;
882 for (std::map< OUString, Item >::iterator i(map.begin()); i != map.end();
883 ++i)
885 i->second.nameOffset = writeNulName(file, i->first);
887 sal_uInt64 off = getOffset(file);
888 if (rootSize == 0) {
889 write8(file, 0); // SORT_MODULE
890 write32(file, map.size());
891 // overflow from std::map::size_type -> sal_uInt64 is unrealistic
892 } else {
893 *rootSize = map.size();
894 // overflow from std::map::size_type -> std::size_t is unrealistic
896 for (std::map< OUString, Item >::iterator i(map.begin()); i != map.end();
897 ++i)
899 write32(file, i->second.nameOffset);
900 write32(file, i->second.dataOffset);
902 return off;
907 SAL_IMPLEMENT_MAIN() {
908 sal_uInt32 args = rtl_getAppCommandArgCount();
909 if (args < 2) {
910 std::cerr
911 << "Usage: reg2unoidl <extra .rdb files> <.rdb file> <unoidl file>"
912 << std::endl;
913 std::exit(EXIT_FAILURE);
915 rtl::Reference< unoidl::Manager > mgr(new unoidl::Manager);
916 for (sal_uInt32 i = 0; i != args - 2; ++i) {
917 mgr->addProvider(load(mgr, getArgumentUri(i)));
919 rtl::Reference< unoidl::Provider > prov(
920 load(mgr, getArgumentUri(args - 2)));
921 osl::File f(getArgumentUri(args - 1));
922 osl::FileBase::RC e = f.open(osl_File_OpenFlag_Write);
923 if (e == osl::FileBase::E_NOENT) {
924 e = f.open(osl_File_OpenFlag_Write | osl_File_OpenFlag_Create);
926 if (e != osl::FileBase::E_None) {
927 std::cerr
928 << "Cannot open <" << f.getURL() << "> for writing, error code "
929 << +e << std::endl;
930 std::exit(EXIT_FAILURE);
932 write(f, "UNOIDL\xFF\0", 8);
933 write32(f, 0); // root map offset
934 write32(f, 0); // root map size
935 write(
937 RTL_CONSTASCII_STRINGPARAM(
938 "\0** Created by LibreOffice " LIBO_VERSION_DOTTED
939 " reg2unoidl **\0"));
940 sal_uInt64 off;
941 std::size_t size;
942 try {
943 off = writeMap(f, prov->createRootCursor(), &size);
944 } catch (unoidl::FileFormatException & e1) {
945 std::cerr
946 << "Bad input <" << e1.getUri() << ">: " << e1.getDetail()
947 << std::endl;
948 std::exit(EXIT_FAILURE);
950 e = f.setSize(getOffset(f)); // truncate in case it already existed
951 if (e != osl::FileBase::E_None) {
952 std::cerr
953 << "Cannot set size of <" << f.getURL() << ">, error code " << +e
954 << std::endl;
955 std::exit(EXIT_FAILURE);
957 e = f.setPos(osl_Pos_Absolut, 8);
958 if (e != osl::FileBase::E_None) {
959 std::cerr
960 << "Cannot rewind current position in <" << f.getURL()
961 << ">, error code " << +e << std::endl;
962 std::exit(EXIT_FAILURE);
964 write32(f, off);
965 write32(f, size);
966 // overflow from std::map::size_type -> sal_uInt64 is unrealistic
967 e = f.close();
968 if (e != osl::FileBase::E_None) {
969 std::cerr
970 << "Cannot close <" << f.getURL() << "> after writing, error code "
971 << +e << std::endl;
972 std::exit(EXIT_FAILURE);
974 return EXIT_SUCCESS;
977 /* vim:set shiftwidth=4 softtabstop=4 expandtab: */