...that had caused unoidl-write to generate garbage values when writing constants of type double to binary type libraries. (But which had apparently gone largely unnoticed until now, as the only actual use so far of such a constant of type double that I could find is > const double aConstDouble = 3.14e-10; in the unused stoc/test/testcorefl.idl test file.) Change-Id: I9a6fdb7a4aaff1008b8264cbbc64a84e60bd3813 Reviewed-on: https://gerrit.libreoffice.org/c/core/+/164096 Tested-by: Jenkins Reviewed-by: Stephan Bergmann <stephan.bergmann@allotropia.de>
Support for UNOIDL Registry Formats
Library_unoidl contains the unoidl::Manager and unoidl::Provider implementations
for the following registry formats:
- The new
UNOIDLbinarytypes.rdbformat. - The old legacy binary
types.rdbformat (based on modules "store" and "registry"). - A source-file format, reading (multiple)
UNOIDLentity definitions directly from a single.idlsource file. - A source-tree format, reading
UNOIDLentity definitions directly from a tree of.idlsource files rooted at a given directory. (Where an entity namedfoo.bar.Bazis expected in a file namedfoo/bar/Baz.idlwithin that tree.)
(While .idl files still contain #include directives for legacy idlc, the source-
based formats ignore any preprocessing directives starting with # in the .idl
files.) unoidl::Manager::addProvider transparently detects the registry format
for a given URI and instantiates the corresponding provider implementation.
Executable_unoidl-write is a helper tool to convert from any of the registry
formats to the UNOIDL format. It is used at build-time to compile UNOIDL format
.rdb files (that are used at build-time only, or included in installation sets
in URE or program/types/ or as part of bundled extensions that are created
during the build and not merely included as pre-built .oxt files) from source
.idl files.
Executable_unoidl-read is a helper tool to convert from any of the registry
formats to the source-file format. It can be used manually after a LibreOffice
version update to create new reference registries for Executable_unoidl-check.
Executable_unoidl-check is a helper tool to check that one registry is
backwards-compatible with another registry. It is used at build-time to detect
inadvertent breakage of the udkapi and offapi APIs.
Specification of the New UNOIDL types.rdb Format
The format uses byte-oriented, platform-independent, binary files. Larger quantities are stored LSB first, without alignment requirements. Offsets are 32 bit, effectively limiting the overall file size to 4GB, but that is not considered a limitation in practice (and avoids unnecessary bloat compared to 64 bit offsets).
Annotations can be added for (non-module) entities and certain parts of such
entities (e.g., both for an interface type definition and for a direct method of
an interface type definition; the idea is that it can be added for direct parts
that forma a "many-to-one" relationship; there is a tradeoff between generality
of concept and size of representation, esp. for the C++ representation types in
namespace unoidl) and consist of arbitrary sequences of name/value strings.
Each name/value string is encoded as a single UTF-8 string containing a name (an
arbitrary sequence of Unicode code points not containing U+003D EQUALS SIGN),
optionally followed by U+003D EQUALS SIGN and a value (an arbitrary sequence of
Unicode code points). The only annotation name currently in use is "deprecated"
(without a value).
The following definitions are used throughout:
UInt16: 2-byte value, LSB firstUInt32: 4-byte value, LSB firstUInt64: 8-byte value, LSB first- Offset:
UInt32value, counting bytes from start of file NUL-Name: zero or more non-NULUS-ASCII bytes followed by aNULbyte- Len-String: UInt32 number of characters, with
0x80000000bit 0, followed by that many US-ASCII (forUNOIDLrelated names) resp. UTF-8 (for annotations) bytes - Idx-String: either an Offset (with
0x80000000bit 1) of a Len-String, or a Len-String - Annotations:
UInt32numberNof annotations followed byN * Idx-String - Entry: Offset of
NUL-Name followed by Offset of payload - Map: zero or more Entries
The file starts with an 8 byte header, followed by information about the root
map (unoidl-write generates files in a single depth-first pass, so the root map
itself is at the end of the file):
- 7 byte magic header
UNOIDL\xFF - version byte 0
- Offset of root Map
UInt32number of entries of root Map ...
Files generated by unoidl-write follow that by a
"\0** Created by LibreOffice " LIBO_VERSION_DOTTED " unoidl-write **\0"
banner (cf. config_host/config_version.h.in), as a debugging aid. (Old versions
used reg2unoidl instead of unoidl-write in that banner.)
Layout of per-entry payload in the root or a module Map:
-
kind byte:
-
0: module
- followed by:
UInt32numberN1of entries of MapN1 * Entry
- followed by:
-
otherwise:
-
0x80bit: 1 if published -
0x40bit: 1 if annotated -
0x20bit: flag (may only be 1 for certain kinds, see below) -
remaining bits:
-
1: enum type
- followed by:
UInt32number N1 of membersN1 * tupleof:Idx-StringUInt32- if annotated: Annotations
- followed by:
-
2: plain struct type (with base if flag is 1)
- followed by:
- if "with base":
Idx-String UInt32numberN1of direct membersN1 * tupleof:Idx-StringnameIdx-Stringtype- if annotated: Annotations
- if "with base":
- followed by:
-
3: polymorphic struct type template
- followed by:
UInt32numberN1of type parametersN1 * Idx-StringUInt32numberN2of membersN2 * tupleof:- kind byte:
0x01bit is 1 if parameterized type Idx-StringnameIdx-Stringtype- if annotated: Annotations
- kind byte:
- followed by:
-
4: exception type (with base if flag is 1)
- followed by:
- if "with base":
Idx-String UInt32numberN1of direct membersN1 * tupleof:Idx-StringnameIdx-Stringtype- if annotated: Annotations
- if "with base":
- followed by:
-
5: interface type
- followed by:
UInt32numberN1of direct mandatory basesN1 * tupleof:Idx-String- if annotated: Annotations
UInt32numberN2of direct optional basesN2 * tupleof:Idx-String- if annotated: Annotations
UInt32numberN3of direct attributesN3 * tupleof:- kind byte:
0x02bit: 1 if read-only0x01bit: 1 if bound
Idx-StringnameIdx-StringtypeUInt32numberN4of get exceptionsN4 * Idx-StringUInt32numberN5of set exceptionsN5 * Idx-String- if annotated: Annotations
- kind byte:
UInt32numberN6of direct methodsN6 * tupleof:Idx-StringnameIdx-Stringreturn typeUInt32numberN7of parametersN7 * tupleof:- direction byte: 0 for in, 1 for out, 2 for in-out
Idx-StringnameIdx-Stringtype
UInt32numberN8of exceptions- N8 * Idx-String
- if annotated: Annotations
- followed by:
-
6: typedef
- followed by:
Idx-String
- followed by:
-
7: constant group
- followed by:
UInt32numberN1of entries of MapN1 * Entry
- followed by:
-
8: single-interface--based service (with default constructor if flag is 1)
- followed by:
Idx-String- if not "with default constructor":
UInt32numberN1of constructorsN1 * tupleof:Idx-StringUInt32numberN2of parametersN2 * tupleof- kind byte:
0x04bit is 1 if rest parameter Idx-StringnameIdx-Stringtype
- kind byte:
UInt32numberN3of exceptionsN3 * Idx-String- if annotated: Annotations
- followed by:
-
9: accumulation-based service
- followed by:
UInt32numberN1of direct mandatory base servicesN1 * tupleof:Idx-String- if annotated: Annotations
UInt32numberN2of direct optional base servicesN2 * tupleof:Idx-String- if annotated: Annotations
UInt32numberN3of direct mandatory base interfacesN3 * tupleof:Idx-String- if annotated: Annotations
UInt32numberN4of direct optional base interfacesN4 * tupleof:Idx-String- if annotated: Annotations
UInt32numberN5of direct propertiesN5 * tupleof:UInt16kind:0x0100bit: 1 if optional0x0080bit: 1 if removable0x0040bit: 1 if maybedefault0x0020bit: 1 if maybeambiguous0x0010bit: 1 if readonly0x0008bit: 1 if transient0x0004bit: 1 if constrained0x0002bit: 1 if bound0x0001bit: 1 if maybevoidIdx-StringnameIdx-Stringtype- if annotated: Annotations
- followed by:
-
10: interface-based singleton
- followed by:
Idx-String
-
11: service-based singleton
- followed by:
Idx-String
- followed by:
-
-
if annotated, followed by: Annotations
-
-
Layout of per-entry payload in a constant group Map:
-
kind byte:
-
0x80bit: 1 if annotated -
remaining bits:
-
0:
BOOLEAN- followed by value byte, 0 represents false, 1 represents true
-
1:
BYTE- followed by value byte, representing values with two's complement
-
2:
SHORT- followed by
UInt16value, representing values with two's complement
- followed by
-
3:
UNSIGNED SHORT- followed by
UInt16value
- followed by
-
4:
LONG- followed by
UInt32value, representing values with two's complement
- followed by
-
5:
UNSIGNED LONG- followed by
UInt32value
- followed by
-
6:
HYPER- followed by
UInt64value, representing values with two's complement
- followed by
-
7:
UNSIGNED HYPER- followed by
UInt64value
- followed by
-
8:
FLOAT- followed by 4-byte value, representing values in ISO 60599 binary32 format, LSB first
-
9:
DOUBLE- followed by 8-byte value, representing values in ISO 60599 binary64 format, LSB first
-
-
-
if annotated, followed by: Annotations