1 /* -*- Mode: C++; tab-width: 4; indent-tabs-mode: nil; c-basic-offset: 4 -*- */
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/.
10 #include "sal/config.h"
20 #include "config_version.h"
21 #include "osl/endian.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"
33 #include "unoidl/unoidl.hxx"
37 OUString
getArgumentUri(sal_uInt32 argument
) {
39 rtl_getAppCommandArg(argument
, &arg
.pData
);
41 osl::FileBase::RC e1
= osl::FileBase::getFileURLFromSystemPath(arg
, url
);
42 if (e1
!= osl::FileBase::E_None
) {
44 << "Cannot convert \"" << arg
<< "\" to file URL, error code "
46 std::exit(EXIT_FAILURE
);
49 oslProcessError e2
= osl_getProcessWorkingDir(&cwd
.pData
);
50 if (e2
!= osl_Process_E_None
) {
52 << "Cannot obtain working directory, error code " << +e2
54 std::exit(EXIT_FAILURE
);
57 e1
= osl::FileBase::getAbsoluteFileURL(cwd
, url
, abs
);
58 if (e1
!= osl::FileBase::E_None
) {
60 << "Cannot make \"" << url
61 << "\" into an absolute file URL, error code " << +e1
<< std::endl
;
62 std::exit(EXIT_FAILURE
);
67 rtl::Reference
< unoidl::Provider
> load(
68 rtl::Reference
< unoidl::Manager
> const & manager
, OUString
const & uri
)
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
) {
77 << "Cannot read input <" << uri
<< ">: " << e
.getDetail()
79 std::exit(EXIT_FAILURE
);
83 sal_uInt64
getOffset(osl::File
& file
) {
85 osl::FileBase::RC e
= file
.getPos(off
);
86 if (e
!= osl::FileBase::E_None
) {
88 << "Cannot determine current position in <" << file
.getURL()
89 << ">, error code " << +e
<< std::endl
;
90 std::exit(EXIT_FAILURE
);
95 void write(osl::File
& file
, void const * buffer
, sal_uInt64 size
) {
97 osl::FileBase::RC e
= file
.write(buffer
, size
, n
);
98 if (e
!= osl::FileBase::E_None
) {
100 << "Cannot write to <" << file
.getURL() << ">, error code " << +e
102 std::exit(EXIT_FAILURE
);
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
) {
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) {
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) {
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
) {
164 unsigned char buf
[4];
165 float f
; // assuming float is ISO 60599 binary32
168 #if defined OSL_BIGENDIAN
169 std::swap(sa
.buf
[0], sa
.buf
[3]);
170 std::swap(sa
.buf
[1], sa
.buf
[2]);
172 write(file
, sa
.buf
, SAL_N_ELEMENTS(sa
.buf
));
175 void writeIso60599Binary64(osl::File
& file
, double value
) {
177 unsigned char buf
[8];
178 float d
; // assuming double is ISO 60599 binary64
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]);
187 write(file
, sa
.buf
, SAL_N_ELEMENTS(sa
.buf
));
190 OString
toAscii(OUString
const & name
) {
192 if (!name
.convertToString(
193 &ascii
, RTL_TEXTENCODING_ASCII_US
,
194 (RTL_UNICODETOTEXT_FLAGS_UNDEFINED_ERROR
195 | RTL_UNICODETOTEXT_FLAGS_INVALID_ERROR
)))
198 << "Cannot convert \"" << name
<< "\" to US ASCII" << std::endl
;
199 std::exit(EXIT_FAILURE
);
204 OString
toUtf8(OUString
const & string
) {
206 if (!string
.convertToString(
207 &ascii
, RTL_TEXTENCODING_UTF8
,
208 (RTL_UNICODETOTEXT_FLAGS_UNDEFINED_ERROR
209 | RTL_UNICODETOTEXT_FLAGS_INVALID_ERROR
)))
212 << "Cannot convert \"" << string
<< "\" to UTF-8" << std::endl
;
213 std::exit(EXIT_FAILURE
);
218 sal_uInt64
writeNulName(osl::File
& file
, OUString
const & name
) {
219 OString
ascii(toAscii(name
));
220 if (ascii
.indexOf('\0') != -1) {
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);
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
)));
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());
240 if ((i
->second
& 0x80000000) != 0) {
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());
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
));
272 rtl::Reference
< unoidl::PublishableEntity
> const & entity
,
273 bool annotated
, bool flag
= false)
276 sal_uInt64 v
= entity
->getSort();
277 if (entity
->isPublished()) {
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
;
301 unoidl::ConstantValue
const & theConstant
,
302 std::vector
< OUString
> const & theAnnotations
):
303 constant(theConstant
), annotations(theAnnotations
), nameOffset(0),
307 unoidl::ConstantValue constant
;
308 std::vector
< OUString
> annotations
;
309 sal_uInt64 nameOffset
;
310 sal_uInt64 dataOffset
;
314 osl::File
& file
, rtl::Reference
< unoidl::MapCursor
> const & cursor
,
315 std::size_t * rootSize
)
318 std::map
< OUString
, Item
> map
;
321 rtl::Reference
< unoidl::Entity
> ent(cursor
->getNext(&name
));
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();
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);
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());
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
);
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());
398 case unoidl::Entity::SORT_POLYMORPHIC_STRUCT_TYPE_TEMPLATE
:
400 rtl::Reference
< unoidl::PolymorphicStructTypeTemplateEntity
>
403 unoidl::PolymorphicStructTypeTemplateEntity
* >(
404 i
->second
.entity
.get()));
405 bool ann
= !ent2
->getAnnotations().empty();
407 unoidl::PolymorphicStructTypeTemplateEntity::Member
>::
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());
425 unoidl::PolymorphicStructTypeTemplateEntity::Member
>::
427 ent2
->getMembers().begin());
428 j
!= ent2
->getMembers().end(); ++j
)
431 if (j
->parameterized
) {
435 writeIdxName(file
, j
->name
);
436 writeIdxName(file
, j
->type
);
437 writeAnnotations(file
, ann
, j
->annotations
);
439 writeAnnotations(file
, ann
, ent2
->getAnnotations());
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
);
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());
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
)
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
);
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());
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());
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());
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
)
606 j
->name
, ConstItem(j
->value
, j
->annotations
))).
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()) {
624 switch (j
->second
.constant
.type
) {
625 case unoidl::ConstantValue::TYPE_BOOLEAN
:
626 write8(file
, j
->second
.constant
.booleanValue
? 1 : 0);
628 case unoidl::ConstantValue::TYPE_BYTE
:
631 static_cast< sal_uInt8
>(
632 j
->second
.constant
.byteValue
));
634 case unoidl::ConstantValue::TYPE_SHORT
:
637 static_cast< sal_uInt16
>(
638 j
->second
.constant
.shortValue
));
640 case unoidl::ConstantValue::TYPE_UNSIGNED_SHORT
:
641 write16(file
, j
->second
.constant
.unsignedShortValue
);
643 case unoidl::ConstantValue::TYPE_LONG
:
646 static_cast< sal_uInt32
>(
647 j
->second
.constant
.longValue
));
649 case unoidl::ConstantValue::TYPE_UNSIGNED_LONG
:
650 write32(file
, j
->second
.constant
.unsignedLongValue
);
652 case unoidl::ConstantValue::TYPE_HYPER
:
655 static_cast< sal_uInt64
>(
656 j
->second
.constant
.hyperValue
));
658 case unoidl::ConstantValue::TYPE_UNSIGNED_HYPER
:
659 write64(file
, j
->second
.constant
.unsignedHyperValue
);
661 case unoidl::ConstantValue::TYPE_FLOAT
:
662 writeIso60599Binary32(
663 file
, j
->second
.constant
.floatValue
);
665 case unoidl::ConstantValue::TYPE_DOUBLE
:
666 writeIso60599Binary64(
667 file
, j
->second
.constant
.doubleValue
);
670 for (;;) { std::abort(); } // this cannot happen
673 file
, !j
->second
.annotations
.empty(),
674 j
->second
.annotations
);
676 for (std::map
< OUString
, ConstItem
>::iterator
j(
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
688 for (std::map
< OUString
, ConstItem
>::iterator
j(
690 j
!= cmap
.end(); ++j
)
692 write32(file
, j
->second
.nameOffset
);
693 write32(file
, j
->second
.dataOffset
);
695 writeAnnotations(file
, ann
, ent2
->getAnnotations());
698 case unoidl::Entity::SORT_SINGLE_INTERFACE_BASED_SERVICE
:
700 rtl::Reference
< unoidl::SingleInterfaceBasedServiceEntity
>
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();
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());
722 write32(file
, ent2
->getConstructors().size());
724 unoidl::SingleInterfaceBasedServiceEntity::
725 Constructor
>::const_iterator
j(
726 ent2
->getConstructors().begin());
727 j
!= ent2
->getConstructors().end(); ++j
)
729 if (j
->defaultConstructor
) {
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());
738 unoidl::SingleInterfaceBasedServiceEntity::
739 Constructor::Parameter
>::const_iterator
k(
740 j
->parameters
.begin());
741 k
!= j
->parameters
.end(); ++k
)
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());
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();
775 ann
= !j
->annotations
.empty();
777 for (std::vector
< unoidl::AnnotatedReference
>::const_iterator
778 j(ent2
->getDirectOptionalBaseServices().begin());
779 !ann
&& j
!= ent2
->getDirectOptionalBaseServices().end();
782 ann
= !j
->annotations
.empty();
784 for (std::vector
< unoidl::AnnotatedReference
>::const_iterator
785 j(ent2
->getDirectMandatoryBaseInterfaces().begin());
787 && j
!= ent2
->getDirectMandatoryBaseInterfaces().end());
790 ann
= !j
->annotations
.empty();
792 for (std::vector
< unoidl::AnnotatedReference
>::const_iterator
793 j(ent2
->getDirectOptionalBaseInterfaces().begin());
794 !ann
&& j
!= ent2
->getDirectOptionalBaseInterfaces().end();
797 ann
= !j
->annotations
.empty();
800 unoidl::AccumulationBasedServiceEntity::Property
>::
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());
843 unoidl::AccumulationBasedServiceEntity::Property
>::
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());
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());
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());
882 for (std::map
< OUString
, Item
>::iterator
i(map
.begin()); i
!= map
.end();
885 i
->second
.nameOffset
= writeNulName(file
, i
->first
);
887 sal_uInt64 off
= getOffset(file
);
889 write8(file
, 0); // SORT_MODULE
890 write32(file
, map
.size());
891 // overflow from std::map::size_type -> sal_uInt64 is unrealistic
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();
899 write32(file
, i
->second
.nameOffset
);
900 write32(file
, i
->second
.dataOffset
);
907 SAL_IMPLEMENT_MAIN() {
908 sal_uInt32 args
= rtl_getAppCommandArgCount();
911 << "Usage: reg2unoidl <extra .rdb files> <.rdb file> <unoidl file>"
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
) {
928 << "Cannot open <" << f
.getURL() << "> for writing, error code "
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
937 RTL_CONSTASCII_STRINGPARAM(
938 "\0** Created by LibreOffice " LIBO_VERSION_DOTTED
939 " reg2unoidl **\0"));
943 off
= writeMap(f
, prov
->createRootCursor(), &size
);
944 } catch (unoidl::FileFormatException
& e1
) {
946 << "Bad input <" << e1
.getUri() << ">: " << e1
.getDetail()
948 std::exit(EXIT_FAILURE
);
950 e
= f
.setSize(getOffset(f
)); // truncate in case it already existed
951 if (e
!= osl::FileBase::E_None
) {
953 << "Cannot set size of <" << f
.getURL() << ">, error code " << +e
955 std::exit(EXIT_FAILURE
);
957 e
= f
.setPos(osl_Pos_Absolut
, 8);
958 if (e
!= osl::FileBase::E_None
) {
960 << "Cannot rewind current position in <" << f
.getURL()
961 << ">, error code " << +e
<< std::endl
;
962 std::exit(EXIT_FAILURE
);
966 // overflow from std::map::size_type -> sal_uInt64 is unrealistic
968 if (e
!= osl::FileBase::E_None
) {
970 << "Cannot close <" << f
.getURL() << "> after writing, error code "
972 std::exit(EXIT_FAILURE
);
977 /* vim:set shiftwidth=4 softtabstop=4 expandtab: */