21#include <osl/endian.h>
23#include <rtl/character.hxx>
25#include <rtl/textenc.h>
26#include <rtl/textcvt.h>
27#include <rtl/ustring.hxx>
43 sal_uInt16
read16(sal_uInt32 offset)
const;
45 sal_uInt32
read32(sal_uInt32 offset)
const;
47 sal_uInt64
read64(sal_uInt32 offset)
const;
71 sal_uInt16
get16(sal_uInt32 offset)
const;
73 sal_uInt32
get32(sal_uInt32 offset)
const;
75 sal_uInt64
get64(sal_uInt32 offset)
const;
81 OUString
readIdxString(sal_uInt32 * offset, rtl_TextEncoding encoding)
89 unsigned char byte[2];
91 sal_uInt16 getUnsigned16()
const {
92 return static_cast< sal_uInt16
>(
byte[0])
93 | (
static_cast< sal_uInt16
>(
byte[1]) << 8);
99 unsigned char byte[4];
101 sal_uInt32 getUnsigned32()
const {
102 return static_cast< sal_uInt32
>(
byte[0])
103 | (
static_cast< sal_uInt32
>(
byte[1]) << 8)
104 | (
static_cast< sal_uInt32
>(
byte[2]) << 16)
105 | (
static_cast< sal_uInt32
>(
byte[3]) << 24);
108 float getIso60599Binary32()
const {
110 unsigned char buf[4];
113#if defined OSL_LITENDIAN
130 unsigned char byte[8];
132 sal_uInt64 getUnsigned64()
const {
133 return static_cast< sal_uInt64
>(
byte[0])
134 | (
static_cast< sal_uInt64
>(
byte[1]) << 8)
135 | (
static_cast< sal_uInt64
>(
byte[2]) << 16)
136 | (
static_cast< sal_uInt64
>(
byte[3]) << 24)
137 | (
static_cast< sal_uInt64
>(
byte[4]) << 32)
138 | (
static_cast< sal_uInt64
>(
byte[5]) << 40)
139 | (
static_cast< sal_uInt64
>(
byte[6]) << 48)
140 | (
static_cast< sal_uInt64
>(
byte[7]) << 56);
143 double getIso60599Binary64()
const {
145 unsigned char buf[8];
148#if defined OSL_LITENDIAN
174 ||
type ==
u"unsigned long" ||
type ==
u"hyper"
188bool isIdentifier(std::u16string_view type,
bool scoped) {
192 for (
size_t i = 0;
i !=
type.size(); ++
i) {
195 if (!scoped || i == 0 || i ==
type.size() - 1
196 || type[i - 1] ==
'.')
200 }
else if (!rtl::isAsciiAlphanumeric(c) && c !=
'_') {
210 std::u16string_view nucl(type);
213 size_t i = nucl.find(
'<');
214 if (i != std::u16string_view::npos) {
215 std::u16string_view tmpl(nucl.substr(0, i));
219 for (
size_t level = 0; j != nucl.size(); ++j) {
225 }
else if (c ==
'<') {
227 }
else if (c ==
'>') {
234 if (j != nucl.size()) {
235 checkTypeName(file, nucl.substr(i, j - i));
239 }
while (i != nucl.size() && nucl[i] !=
'>');
240 if (i != nucl.size() - 1 || nucl[i] !=
'>' || !args) {
245 if (
isSimpleType(nucl) ? args : !isIdentifier(nucl,
true)) {
246 throw FileFormatException(
247 file->uri, OUString::Concat(
"UNOIDL format: bad type \"") + type +
"\"");
255 throw FileFormatException(
256 file->uri, OUString::Concat(
"UNOIDL format: bad entity name \"") + name +
"\"");
263 oslFileError e = osl_openFile(
uri.pData, &
handle, osl_File_OpenFlag_Read);
265 case osl_File_E_None:
267 case osl_File_E_NOENT:
273 if (e == osl_File_E_None) {
277 if (e != osl_File_E_None) {
278 oslFileError e2 = osl_closeFile(
handle);
280 e2 != osl_File_E_None,
"unoidl",
281 "cannot close " <<
uri <<
": " << +e2);
288 if (offset >
size - 1) {
290 uri,
"UNOIDL format: offset for 8-bit value too large");
297 if (offset >
size - 2) {
299 uri,
"UNOIDL format: offset for 16-bit value too large");
301 return get16(offset);
306 if (offset >
size - 4) {
308 uri,
"UNOIDL format: offset for 32-bit value too large");
310 return get32(offset);
315 if (offset >
size - 8) {
317 uri,
"UNOIDL format: offset for 64-bit value too large");
319 return get64(offset);
324 if (offset >
size - 4) {
326 uri,
"UNOIDL format: offset for 32-bit value too large");
333 if (offset >
size - 8) {
335 uri,
"UNOIDL format: offset for 64-bit value too large");
343 uri,
"UNOIDL format: offset for string too large");
345 sal_uInt64
end = offset;
349 uri,
"UNOIDL format: string misses trailing NUL");
351 if (
static_cast< char const *
>(
address)[
end] == 0) {
359 if (!rtl_convertStringToUString(
360 &
name.pData,
static_cast< char const *
>(
address) + offset,
361 end - offset, RTL_TEXTENCODING_ASCII_US,
362 (RTL_TEXTTOUNICODE_FLAGS_UNDEFINED_ERROR
363 | RTL_TEXTTOUNICODE_FLAGS_MBUNDEFINED_ERROR
364 | RTL_TEXTTOUNICODE_FLAGS_INVALID_ERROR)))
368 checkEntityName(
this,
name);
374 SAL_WARN_IF(e != osl_File_E_None,
"unoidl",
"cannot unmap: " << +e);
375 e = osl_closeFile(
handle);
376 SAL_WARN_IF(e != osl_File_E_None,
"unoidl",
"cannot close: " << +e);
381 assert(offset <=
size - 1);
382 return static_cast< char const *
>(
address)[offset];
387 assert(offset <=
size - 2);
388 return reinterpret_cast< Memory16
const *
>(
389 static_cast< char const *
>(
address) + offset)->getUnsigned16();
394 assert(offset <=
size - 4);
395 return reinterpret_cast< Memory32
const *
>(
396 static_cast< char const *
>(
address) + offset)->getUnsigned32();
401 assert(offset <=
size - 8);
402 return reinterpret_cast< Memory64
const *
>(
403 static_cast< char const *
>(
address) + offset)->getUnsigned64();
408 assert(offset <=
size - 4);
409 return reinterpret_cast< Memory32
const *
>(
410 static_cast< char const *
>(
address) + offset)->getIso60599Binary32();
415 assert(offset <=
size - 8);
416 return reinterpret_cast< Memory64
const *
>(
417 static_cast< char const *
>(
address) + offset)->getIso60599Binary64();
421 sal_uInt32 * offset, rtl_TextEncoding encoding)
const
423 assert(offset !=
nullptr);
424 sal_uInt32 len =
read32(*offset);
426 if ((len & 0x80000000) == 0) {
431 off = len & ~0x80000000;
433 if ((len & 0x80000000) != 0) {
435 uri,
"UNOIDL format: string length high bit set");
440 uri,
"UNOIDL format: size of string is too large");
443 if (!rtl_convertStringToUString(
444 &
name.pData,
static_cast< char const *
>(
address) + off + 4, len,
446 (RTL_TEXTTOUNICODE_FLAGS_UNDEFINED_ERROR
447 | RTL_TEXTTOUNICODE_FLAGS_MBUNDEFINED_ERROR
448 | RTL_TEXTTOUNICODE_FLAGS_INVALID_ERROR)))
451 uri,
"UNOIDL format: string bytes do not match encoding");
469enum Compare { COMPARE_LESS, COMPARE_GREATER, COMPARE_EQUAL };
473 sal_Int32 nameOffset, sal_Int32 nameLength, MapEntry
const * entry)
476 assert(entry !=
nullptr);
477 sal_uInt32 off = entry->name.getUnsigned32();
478 if (off > file->size - 1) {
479 throw FileFormatException(
480 file->uri,
"UNOIDL format: string offset too large");
482 assert(nameLength >= 0);
483 sal_uInt64
min = std::min(
484 static_cast< sal_uInt64
>(nameLength), file->size - off);
485 for (sal_uInt64 i = 0;
i !=
min; ++
i) {
487 sal_Unicode c2 =
static_cast< unsigned char const *
>(file->address)[
491 }
else if (c1 > c2 || c2 == 0) {
494 return COMPARE_GREATER;
497 if (
static_cast< sal_uInt64
>(nameLength) ==
min) {
498 if (file->size - off == min) {
499 throw FileFormatException(
500 file->uri,
"UNOIDL format: string misses trailing NUL");
503 static_cast< unsigned char const *
>(file->address)[off + min] == 0
504 ? COMPARE_EQUAL : COMPARE_LESS;
506 return COMPARE_GREATER;
512 sal_uInt32 mapSize, OUString
const & name, sal_Int32 nameOffset,
513 sal_Int32 nameLength)
518 sal_uInt32
n = mapSize / 2;
519 MapEntry
const *
p = mapBegin +
n;
520 switch (
compare(file, name, nameOffset, nameLength, p)) {
522 return findInMap(file, mapBegin, n, name, nameOffset, nameLength);
523 case COMPARE_GREATER:
525 file, p + 1, mapSize - n - 1, name, nameOffset, nameLength);
529 sal_uInt32 off = mapBegin[
n].data.getUnsigned32();
531 throw FileFormatException(
532 file->uri,
"UNOIDL format: map entry data offset is null");
537#if defined(__COVERITY__)
538extern "C" void __coverity_tainted_data_sanitize__(
void *);
541std::vector< OUString > readAnnotations(
543 sal_uInt32 offset, sal_uInt32 * newOffset =
nullptr)
545 std::vector< OUString > ans;
547 sal_uInt32
n = file->read32(offset);
548#if defined(__COVERITY__)
549 __coverity_tainted_data_sanitize__(&n);
552 for (sal_uInt32 i = 0;
i !=
n; ++
i) {
553 ans.push_back(file->readIdxString(&offset));
556 if (newOffset !=
nullptr) {
562ConstantValue readConstant(
564 sal_uInt32 * newOffset,
bool * annotated)
567 int v = file->read8(offset);
569 if (annotated !=
nullptr) {
570 *annotated = (
v & 0x80) != 0;
574 v = file->read8(offset + 1);
575 if (newOffset !=
nullptr) {
576 *newOffset = offset + 2;
580 return ConstantValue(
false);
582 return ConstantValue(
true);
584 throw FileFormatException(
586 (
"UNOIDL format: bad boolean constant value "
587 + OUString::number(v)));
590 if (newOffset !=
nullptr) {
591 *newOffset = offset + 2;
593 return ConstantValue(
static_cast< sal_Int8 >(file->read8(offset + 1)));
597 if (newOffset !=
nullptr) {
598 *newOffset = offset + 3;
600 return ConstantValue(
601 static_cast< sal_Int16
>(file->read16(offset + 1)));
605 if (newOffset !=
nullptr) {
606 *newOffset = offset + 3;
608 return ConstantValue(file->read16(offset + 1));
610 if (newOffset !=
nullptr) {
611 *newOffset = offset + 5;
613 return ConstantValue(
614 static_cast< sal_Int32
>(file->read32(offset + 1)));
618 if (newOffset !=
nullptr) {
619 *newOffset = offset + 5;
621 return ConstantValue(file->read32(offset + 1));
623 if (newOffset !=
nullptr) {
624 *newOffset = offset + 9;
626 return ConstantValue(
627 static_cast< sal_Int64
>(file->read64(offset + 1)));
631 if (newOffset !=
nullptr) {
632 *newOffset = offset + 9;
634 return ConstantValue(file->read64(offset + 1));
636 if (newOffset !=
nullptr) {
637 *newOffset = offset + 5;
639 return ConstantValue(file->readIso60599Binary32(offset + 1));
641 if (newOffset !=
nullptr) {
642 *newOffset = offset + 9;
644 return ConstantValue(file->readIso60599Binary64(offset + 1));
646 throw FileFormatException(
648 "UNOIDL format: bad constant type byte " + OUString::number(v));
654 std::set<Map> && trace);
656class UnoidlModuleEntity;
658class UnoidlCursor:
public MapCursor {
664 NestedMap
const &
map):
670 virtual ~UnoidlCursor() noexcept
override {}
682 assert(
name !=
nullptr);
693class UnoidlModuleEntity:
public ModuleEntity {
697 sal_uInt32 mapSize, std::set<Map> && trace):
701 map_.map.begin =
reinterpret_cast<MapEntry
const *
>(
702 static_cast<char const *
>(
file_->address) + mapOffset);
703 map_.map.size = mapSize;
704 map_.trace = std::move(trace);
705 if (!
map_.trace.insert(
map_.map).second) {
706 throw FileFormatException(
707 file_->uri,
"UNOIDL format: recursive map");
712 virtual ~UnoidlModuleEntity() noexcept
override {}
714 virtual std::vector< OUString > getMemberNames()
const override;
717 return new UnoidlCursor(
719 const_cast<UnoidlModuleEntity *
>(
this),
map_);
726std::vector< OUString > UnoidlModuleEntity::getMemberNames()
const {
727 std::vector< OUString > names;
737 std::set<Map> && trace)
740 int v = file->read8(offset);
742 bool published = (
v & 0x80) != 0;
743 bool annotated = (
v & 0x40) != 0;
744 bool flag = (
v & 0x20) != 0;
749 throw FileFormatException(
751 (
"UNOIDL format: bad module type byte "
752 + OUString::number(v)));
754 sal_uInt32
n = file->read32(offset + 1);
755 if (n > SAL_MAX_INT32) {
756 throw FileFormatException(
757 file->uri,
"UNOIDL format: too many items in module");
759 if (sal_uInt64(offset) + 5 + 8 * sal_uInt64(n) > file->size)
762 throw FileFormatException(
764 "UNOIDL format: module map offset + size too large");
766 return new UnoidlModuleEntity(file, offset + 5, n, std::move(trace));
770 sal_uInt32
n = file->read32(offset + 1);
772 throw FileFormatException(
773 file->uri,
"UNOIDL format: enum type with no members");
775 if (n > SAL_MAX_INT32) {
776 throw FileFormatException(
777 file->uri,
"UNOIDL format: too many members of enum type");
780 std::vector< EnumTypeEntity::Member > mems;
782 for (sal_uInt32 i = 0;
i !=
n; ++
i) {
783 OUString memName(file->readIdxName(&offset));
784 checkEntityName(file, memName);
785 sal_Int32 memValue =
static_cast< sal_Int32
>(
786 file->read32(offset));
793 readAnnotations(annotated, file, offset, &offset));
795 return new EnumTypeEntity(
796 published, std::move(mems), readAnnotations(annotated, file, offset));
804 base = file->readIdxName(&offset);
805 if (
base.isEmpty()) {
806 throw FileFormatException(
808 (
"UNOIDL format: empty base type name of plain struct"
811 checkTypeName(file, base);
813 sal_uInt32
n = file->read32(offset);
814 if (n > SAL_MAX_INT32) {
815 throw FileFormatException(
817 (
"UNOIDL format: too many direct members of plain struct"
821 std::vector< PlainStructTypeEntity::Member > mems;
823 for (sal_uInt32 i = 0;
i !=
n; ++
i) {
824 OUString memName(file->readIdxName(&offset));
825 checkEntityName(file, memName);
826 OUString memType(file->readIdxName(&offset));
827 checkTypeName(file, memType);
830 readAnnotations(annotated, file, offset, &offset));
832 return new PlainStructTypeEntity(
833 published, base, std::move(mems),
834 readAnnotations(annotated, file, offset));
838 sal_uInt32
n = file->read32(offset + 1);
839 if (n > SAL_MAX_INT32) {
840 throw FileFormatException(
842 (
"UNOIDL format: too many type parameters of polymorphic"
843 " struct type template"));
846 std::vector< OUString > params;
848 for (sal_uInt32 i = 0;
i !=
n; ++
i) {
849 OUString param(file->readIdxName(&offset));
850 checkEntityName(file, param);
851 params.push_back(param);
853 n = file->read32(offset);
854 if (n > SAL_MAX_INT32) {
855 throw FileFormatException(
857 (
"UNOIDL format: too many members of polymorphic struct"
861 std::vector< PolymorphicStructTypeTemplateEntity::Member > mems;
863 for (sal_uInt32 i = 0;
i !=
n; ++
i) {
864 v = file->read8(offset);
866 OUString memName(file->readIdxName(&offset));
867 checkEntityName(file, memName);
868 OUString memType(file->readIdxName(&offset));
869 checkTypeName(file, memType);
871 throw FileFormatException(
873 (
"UNOIDL format: bad flags " + OUString::number(v)
874 +
" for member " + memName
875 +
" of polymorphic struct type template"));
878 memName, memType, v == 1,
879 readAnnotations(annotated, file, offset, &offset));
881 return new PolymorphicStructTypeTemplateEntity(
882 published, std::move(params), std::move(mems),
883 readAnnotations(annotated, file, offset));
891 base = file->readIdxName(&offset);
892 if (
base.isEmpty()) {
893 throw FileFormatException(
895 (
"UNOIDL format: empty base type name of exception"
898 checkTypeName(file, base);
900 sal_uInt32
n = file->read32(offset);
901 if (n > SAL_MAX_INT32) {
902 throw FileFormatException(
904 "UNOIDL format: too many direct members of exception type");
907 std::vector< ExceptionTypeEntity::Member > mems;
909 for (sal_uInt32 i = 0;
i !=
n; ++
i) {
910 OUString memName(file->readIdxName(&offset));
911 checkEntityName(file, memName);
912 OUString memType(file->readIdxName(&offset));
913 checkTypeName(file, memType);
916 readAnnotations(annotated, file, offset, &offset));
918 return new ExceptionTypeEntity(
919 published, base, std::move(mems),
920 readAnnotations(annotated, file, offset));
924 sal_uInt32
n = file->read32(offset + 1);
925 if (n > SAL_MAX_INT32) {
926 throw FileFormatException(
928 (
"UNOIDL format: too many direct mandatory bases of"
932 std::vector< AnnotatedReference > mandBases;
933 mandBases.reserve(n);
934 for (sal_uInt32 i = 0;
i !=
n; ++
i) {
935 OUString
base(file->readIdxName(&offset));
936 checkTypeName(file, base);
937 mandBases.emplace_back(
938 base, readAnnotations(annotated, file, offset, &offset));
940 n = file->read32(offset);
941 if (n > SAL_MAX_INT32) {
942 throw FileFormatException(
944 (
"UNOIDL format: too many direct optional bases of"
948 std::vector< AnnotatedReference > optBases;
950 for (sal_uInt32 i = 0;
i !=
n; ++
i) {
951 OUString
base(file->readIdxName(&offset));
952 checkTypeName(file, base);
953 optBases.emplace_back(
954 base, readAnnotations(annotated, file, offset, &offset));
956 sal_uInt32 nAttrs = file->read32(offset);
957 if (nAttrs > SAL_MAX_INT32) {
958 throw FileFormatException(
960 (
"UNOIDL format: too many direct attributes of interface"
964 std::vector< InterfaceTypeEntity::Attribute > attrs;
965 attrs.reserve(nAttrs);
966 for (sal_uInt32 i = 0;
i != nAttrs; ++
i) {
967 v = file->read8(offset);
969 OUString
attrName(file->readIdxName(&offset));
970 checkEntityName(file, attrName);
971 OUString attrType(file->readIdxName(&offset));
972 checkTypeName(file, attrType);
974 throw FileFormatException(
976 (
"UNOIDL format: bad flags for direct attribute "
977 + attrName +
" of interface type"));
979 std::vector< OUString > getExcs;
980 sal_uInt32
m = file->read32(offset);
981 if (m > SAL_MAX_INT32) {
982 throw FileFormatException(
984 (
"UNOIDL format: too many getter exceptions for direct"
985 " attribute " + attrName +
" of interface type"));
989 for (sal_uInt32 j = 0; j !=
m; ++j) {
990 OUString exc(file->readIdxName(&offset));
991 checkTypeName(file, exc);
992 getExcs.push_back(exc);
994 std::vector< OUString > setExcs;
995 if ((v & 0x02) == 0) {
996 m = file->read32(offset);
997 if (m > SAL_MAX_INT32) {
998 throw FileFormatException(
1000 (
"UNOIDL format: too many setter exceptions for"
1001 " direct attribute " + attrName
1002 +
" of interface type"));
1006 for (sal_uInt32 j = 0; j !=
m; ++j) {
1007 OUString exc(file->readIdxName(&offset));
1008 checkTypeName(file, exc);
1009 setExcs.push_back(exc);
1013 attrName, attrType, (v & 0x01) != 0, (v & 0x02) != 0,
1014 std::move(getExcs), std::move(setExcs),
1015 readAnnotations(annotated, file, offset, &offset));
1017 sal_uInt32 nMeths = file->read32(offset);
1018 if (nMeths > SAL_MAX_INT32 - nAttrs) {
1019 throw FileFormatException(
1021 (
"UNOIDL format: too many direct attributes and methods of"
1022 " interface type"));
1025 std::vector< InterfaceTypeEntity::Method > meths;
1026 meths.reserve(nMeths);
1027 for (sal_uInt32 i = 0;
i != nMeths; ++
i) {
1028 OUString methName(file->readIdxName(&offset));
1029 checkEntityName(file, methName);
1030 OUString methType(file->readIdxName(&offset));
1031 checkTypeName(file, methType);
1032 sal_uInt32
m = file->read32(offset);
1033 if (m > SAL_MAX_INT32) {
1034 throw FileFormatException(
1036 (
"UNOIDL format: too many parameters for method "
1037 + methName +
" of interface type"));
1040 std::vector< InterfaceTypeEntity::Method::Parameter > params;
1042 for (sal_uInt32 j = 0; j !=
m; ++j) {
1043 v = file->read8(offset);
1045 OUString paramName(file->readIdxName(&offset));
1046 checkEntityName(file, paramName);
1047 OUString paramType(file->readIdxName(&offset));
1048 checkTypeName(file, paramType);
1064 throw FileFormatException(
1066 (
"UNOIDL format: bad direction "
1067 + OUString::number(v) +
" of parameter "
1068 + paramName +
" for method " + methName
1069 +
" of interface type"));
1071 params.emplace_back(paramName, paramType, dir);
1073 std::vector< OUString > excs;
1074 m = file->read32(offset);
1075 if (m > SAL_MAX_INT32) {
1076 throw FileFormatException(
1078 (
"UNOIDL format: too many exceptions for method "
1079 + methName +
" of interface type"));
1083 for (sal_uInt32 j = 0; j !=
m; ++j) {
1084 OUString exc(file->readIdxName(&offset));
1085 checkTypeName(file, exc);
1086 excs.push_back(exc);
1089 methName, methType, std::move(params), std::move(excs),
1090 readAnnotations(annotated, file, offset, &offset));
1092 return new InterfaceTypeEntity(
1093 published, std::move(mandBases), std::move(optBases), std::move(attrs), std::move(meths),
1094 readAnnotations(annotated, file, offset));
1099 OUString
base(file->readIdxName(&offset));
1100 checkTypeName(file, base);
1101 return new TypedefEntity(
1102 published, base, readAnnotations(annotated, file, offset));
1106 sal_uInt32
n = file->read32(offset + 1);
1107 if (n > SAL_MAX_INT32) {
1108 throw FileFormatException(
1110 "UNOIDL format: too many constants in constant group");
1112 if (sal_uInt64(offset) + 5 + 8 * sal_uInt64(n) > file->size)
1115 throw FileFormatException(
1117 (
"UNOIDL format: constant group map offset + size too"
1120 MapEntry
const *
p =
reinterpret_cast< MapEntry
const *
>(
1121 static_cast< char const *
>(file->address) + offset + 5);
1122 std::vector< ConstantGroupEntity::Member > mems;
1124 for (sal_uInt32 i = 0;
i !=
n; ++
i) {
1125 sal_uInt32 off =
p[
i].data.getUnsigned32();
1127 ConstantValue val(readConstant(file, off, &off, &ann));
1129 file->readNulName(p[i].name.getUnsigned32()), val,
1130 readAnnotations(ann, file, off));
1132 return new ConstantGroupEntity(
1133 published, std::move(mems),
1134 readAnnotations(annotated, file, offset + 5 + 8 * n));
1140 OUString
base(file->readIdxName(&offset));
1141 checkTypeName(file, base);
1142 std::vector< SingleInterfaceBasedServiceEntity::Constructor > ctors;
1145 SingleInterfaceBasedServiceEntity::Constructor());
1147 sal_uInt32
n = file->read32(offset);
1148 if (n > SAL_MAX_INT32) {
1149 throw FileFormatException(
1151 (
"UNOIDL format: too many constructors of"
1152 " single-interface--based service"));
1156 for (sal_uInt32 i = 0;
i !=
n; ++
i) {
1157 OUString ctorName(file->readIdxName(&offset));
1158 checkEntityName(file, ctorName);
1159 sal_uInt32
m = file->read32(offset);
1160 if (m > SAL_MAX_INT32) {
1161 throw FileFormatException(
1163 (
"UNOIDL format: too many parameters for"
1164 " constructor " + ctorName
1165 +
" of single-interface--based service"));
1169 SingleInterfaceBasedServiceEntity::Constructor::
1172 for (sal_uInt32 j = 0; j !=
m; ++j) {
1173 v = file->read8(offset);
1175 OUString paramName(file->readIdxName(&offset));
1176 checkEntityName(file, paramName);
1177 OUString paramType(file->readIdxName(&offset));
1178 checkTypeName(file, paramType);
1188 throw FileFormatException(
1190 (
"UNOIDL format: bad mode "
1191 + OUString::number(v) +
" of parameter "
1192 + paramName +
" for constructor " + ctorName
1193 +
" of single-interface--based service"));
1195 params.emplace_back(paramName, paramType, rest);
1197 std::vector< OUString > excs;
1198 m = file->read32(offset);
1199 if (m > SAL_MAX_INT32) {
1200 throw FileFormatException(
1202 (
"UNOIDL format: too many exceptions for"
1203 " constructor " + ctorName
1204 +
" of single-interface--based service"));
1208 for (sal_uInt32 j = 0; j !=
m; ++j) {
1209 OUString exc(file->readIdxName(&offset));
1210 checkTypeName(file, exc);
1211 excs.push_back(exc);
1214 SingleInterfaceBasedServiceEntity::Constructor(
1215 ctorName, std::move(params), std::move(excs),
1216 readAnnotations(annotated, file, offset, &offset)));
1219 return new SingleInterfaceBasedServiceEntity(
1220 published, base, std::move(ctors),
1221 readAnnotations(annotated, file, offset));
1225 sal_uInt32
n = file->read32(offset + 1);
1226 if (n > SAL_MAX_INT32) {
1227 throw FileFormatException(
1229 (
"UNOIDL format: too many direct mandatory service bases of"
1230 " accumulation-based service"));
1233 std::vector< AnnotatedReference > mandServs;
1234 mandServs.reserve(n);
1235 for (sal_uInt32 i = 0;
i !=
n; ++
i) {
1236 OUString
base(file->readIdxName(&offset));
1237 checkTypeName(file, base);
1238 mandServs.emplace_back(
1239 base, readAnnotations(annotated, file, offset, &offset));
1241 n = file->read32(offset);
1242 if (n > SAL_MAX_INT32) {
1243 throw FileFormatException(
1245 (
"UNOIDL format: too many direct optional service bases of"
1246 " accumulation-based service"));
1249 std::vector< AnnotatedReference > optServs;
1250 optServs.reserve(n);
1251 for (sal_uInt32 i = 0;
i !=
n; ++
i) {
1252 OUString
base(file->readIdxName(&offset));
1253 checkTypeName(file, base);
1254 optServs.emplace_back(
1255 base, readAnnotations(annotated, file, offset, &offset));
1257 n = file->read32(offset);
1258 if (n > SAL_MAX_INT32) {
1259 throw FileFormatException(
1261 (
"UNOIDL format: too many direct mandatory interface bases"
1262 " of accumulation-based service"));
1265 std::vector< AnnotatedReference > mandIfcs;
1266 mandIfcs.reserve(n);
1267 for (sal_uInt32 i = 0;
i !=
n; ++
i) {
1268 OUString
base(file->readIdxName(&offset));
1269 checkTypeName(file, base);
1270 mandIfcs.emplace_back(
1271 base, readAnnotations(annotated, file, offset, &offset));
1273 n = file->read32(offset);
1274 if (n > SAL_MAX_INT32) {
1275 throw FileFormatException(
1277 (
"UNOIDL format: too many direct optional interface bases"
1278 " of accumulation-based service"));
1281 std::vector< AnnotatedReference > optIfcs;
1283 for (sal_uInt32 i = 0;
i !=
n; ++
i) {
1284 OUString
base(file->readIdxName(&offset));
1285 checkTypeName(file, base);
1286 optIfcs.emplace_back(
1287 base, readAnnotations(annotated, file, offset, &offset));
1289 n = file->read32(offset);
1290 if (n > SAL_MAX_INT32) {
1291 throw FileFormatException(
1293 (
"UNOIDL format: too many direct properties of"
1294 " accumulation-based service"));
1297 std::vector< AccumulationBasedServiceEntity::Property >
props;
1299 for (sal_uInt32 i = 0;
i !=
n; ++
i) {
1300 sal_uInt16 attrs = file->read16(offset);
1302 OUString propName(file->readIdxName(&offset));
1303 checkEntityName(file, propName);
1304 OUString propType(file->readIdxName(&offset));
1305 checkTypeName(file, propType);
1306 if (attrs > 0x01FF) {
1307 throw FileFormatException(
1309 (
"UNOIDL format: bad mode " + OUString::number(v)
1310 +
" of property " + propName
1311 +
" for accumulation-based service"));
1318 readAnnotations(annotated, file, offset, &offset));
1320 return new AccumulationBasedServiceEntity(
1321 published, std::move(mandServs), std::move(optServs), std::move(mandIfcs), std::move(optIfcs), std::move(props),
1322 readAnnotations(annotated, file, offset));
1327 OUString
base(file->readIdxName(&offset));
1328 checkTypeName(file, base);
1329 return new InterfaceBasedSingletonEntity(
1330 published, base, readAnnotations(annotated, file, offset));
1335 OUString
base(file->readIdxName(&offset));
1336 checkTypeName(file, base);
1337 return new ServiceBasedSingletonEntity(
1338 published, base, readAnnotations(annotated, file, offset));
1341 throw FileFormatException(
1342 file->uri,
"UNOIDL format: bad type byte " + OUString::number(v));
1350 if (
file_->size < 8 || std::memcmp(
file_->address,
"UNOIDL\xFF\0", 8) != 0)
1354 "UNOIDL format: does not begin with magic UNOIDL\\xFF and version"
1357 sal_uInt32 off =
file_->read32(8);
1361 file_->uri,
"UNOIDL format: root map offset + size too large");
1364 static_cast< char const *
>(
file_->address) + off);
1369 return new UnoidlCursor(
1377 bool cgroup =
false;
1378 for (sal_Int32
i = 0;;) {
1379 sal_Int32 j =
name.indexOf(
'.',
i);
1381 j =
name.getLength();
1383 sal_Int32 off = findInMap(
1388 if (j ==
name.getLength()) {
1391 : readEntity(
file_, off, std::set(
map.trace));
1399 int v =
file_->read8(off);
1401 if ((
v & 0x3F) == 7) {
1410 map.map.size =
file_->read32(off + 1);
1411 if (sal_uInt64(off) + 5 + 8 * sal_uInt64(
map.map.size) >
file_->size)
1415 file_->uri,
"UNOIDL format: map offset + size too large");
1417 map.map.begin =
reinterpret_cast< MapEntry const *
>(
1418 static_cast< char const *
>(
file_->address) + off + 5);
1419 if (!
map.trace.insert(
map.map).second) {
1421 file_->uri,
"UNOIDL format: recursive map");
sal_uInt64 get64(sal_uInt32 offset) const
MappedFile(OUString fileUrl)
sal_uInt16 read16(sal_uInt32 offset) const
float readIso60599Binary32(sal_uInt32 offset) const
OUString readNulName(sal_uInt32 offset)
sal_uInt32 get32(sal_uInt32 offset) const
sal_uInt8 read8(sal_uInt32 offset) const
OUString readIdxName(sal_uInt32 *offset) const
float getIso60599Binary32(sal_uInt32 offset) const
sal_uInt32 read32(sal_uInt32 offset) const
sal_uInt64 read64(sal_uInt32 offset) const
double readIso60599Binary64(sal_uInt32 offset) const
double getIso60599Binary64(sal_uInt32 offset) const
sal_uInt8 get8(sal_uInt32 offset) const
sal_uInt16 get16(sal_uInt32 offset) const
virtual ~MappedFile() override
OUString readIdxString(sal_uInt32 *offset) const
UnoidlProvider(OUString const &uri)
virtual rtl::Reference< MapCursor > createRootCursor() const override
virtual ~UnoidlProvider() noexcept override
virtual rtl::Reference< Entity > findEntity(OUString const &name) const override
rtl::Reference< detail::MappedFile > file_
#define SAL_WARN_IF(condition, area, stream)
bool isSimpleType(typelib_TypeClass typeClass)
constexpr bool starts_with(std::basic_string_view< charT, traits > sv, std::basic_string_view< charT, traits > x) noexcept
static bool operator<(const Map &map1, const Map &map2)
SwNodeOffset min(const SwNodeOffset &a, const SwNodeOffset &b)
SbxDecimal::CmpResult compare(SAL_UNUSED_PARAMETER const SbxDecimal &, SAL_UNUSED_PARAMETER const SbxDecimal &)
std::map< OUString, rtl::Reference< Entity > > map
rtl::Reference< UnoidlModuleEntity > reference2_
rtl::Reference< MappedFile > file_
rtl::Reference< UnoidlProvider > reference1_