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/.
9 * This file incorporates work covered by the following license notice:
11 * Licensed to the Apache Software Foundation (ASF) under one or more
12 * contributor license agreements. See the NOTICE file distributed
13 * with this work for additional information regarding copyright
14 * ownership. The ASF licenses this file to you under the Apache
15 * License, Version 2.0 (the "License"); you may not use this file
16 * except in compliance with the License. You may obtain a copy of
17 * the License at http://www.apache.org/licenses/LICENSE-2.0 .
20 #include <sal/config.h>
27 #include <sal/types.h>
28 #include <osl/endian.h>
29 #include <osl/diagnose.h>
30 #include "reflread.hxx"
31 #include <sal/log.hxx>
33 #include <registry/typereg_reader.hxx>
34 #include <registry/version.h>
36 #include "reflcnst.hxx"
40 static const sal_Char NULL_STRING
[1] = { 0 };
41 static const sal_Unicode NULL_WSTRING
[1] = { 0 };
43 const sal_uInt32 magic
= 0x12345678;
44 const sal_uInt16 minorVersion
= 0x0000;
45 const sal_uInt16 majorVersion
= 0x0001;
47 /**************************************************************************
51 holds any data in a flat memory buffer
53 **************************************************************************/
58 struct BoundsError
{};
60 const sal_uInt8
* m_pBuffer
;
61 sal_uInt32 m_bufferLen
;
63 BlopObject(const sal_uInt8
* buffer
, sal_uInt32 len
);
64 // throws std::bad_alloc
66 sal_uInt8
readBYTE(sal_uInt32 index
) const
68 if (index
>= m_bufferLen
) {
71 return m_pBuffer
[index
];
74 sal_Int16
readINT16(sal_uInt32 index
) const
76 if (m_bufferLen
< 2 || index
>= m_bufferLen
- 1) {
79 return ((m_pBuffer
[index
] << 8) | (m_pBuffer
[index
+1] << 0));
82 sal_uInt16
readUINT16(sal_uInt32 index
) const
84 if (m_bufferLen
< 2 || index
>= m_bufferLen
- 1) {
87 return ((m_pBuffer
[index
] << 8) | (m_pBuffer
[index
+1] << 0));
90 sal_Int32
readINT32(sal_uInt32 index
) const
92 if (m_bufferLen
< 4 || index
>= m_bufferLen
- 3) {
96 (m_pBuffer
[index
] << 24) |
97 (m_pBuffer
[index
+1] << 16) |
98 (m_pBuffer
[index
+2] << 8) |
99 (m_pBuffer
[index
+3] << 0)
103 sal_uInt32
readUINT32(sal_uInt32 index
) const
105 if (m_bufferLen
< 4 || index
>= m_bufferLen
- 3) {
109 (m_pBuffer
[index
] << 24) |
110 (m_pBuffer
[index
+1] << 16) |
111 (m_pBuffer
[index
+2] << 8) |
112 (m_pBuffer
[index
+3] << 0)
116 sal_Int64
readINT64(sal_uInt32 index
) const
118 if (m_bufferLen
< 8 || index
>= m_bufferLen
- 7) {
122 (static_cast<sal_Int64
>(m_pBuffer
[index
]) << 56) |
123 (static_cast<sal_Int64
>(m_pBuffer
[index
+1]) << 48) |
124 (static_cast<sal_Int64
>(m_pBuffer
[index
+2]) << 40) |
125 (static_cast<sal_Int64
>(m_pBuffer
[index
+3]) << 32) |
126 (static_cast<sal_Int64
>(m_pBuffer
[index
+4]) << 24) |
127 (static_cast<sal_Int64
>(m_pBuffer
[index
+5]) << 16) |
128 (static_cast<sal_Int64
>(m_pBuffer
[index
+6]) << 8) |
129 (static_cast<sal_Int64
>(m_pBuffer
[index
+7]) << 0)
133 sal_uInt64
readUINT64(sal_uInt32 index
) const
135 if (m_bufferLen
< 8 || index
>= m_bufferLen
- 7) {
139 (static_cast<sal_uInt64
>(m_pBuffer
[index
]) << 56) |
140 (static_cast<sal_uInt64
>(m_pBuffer
[index
+1]) << 48) |
141 (static_cast<sal_uInt64
>(m_pBuffer
[index
+2]) << 40) |
142 (static_cast<sal_uInt64
>(m_pBuffer
[index
+3]) << 32) |
143 (static_cast<sal_uInt64
>(m_pBuffer
[index
+4]) << 24) |
144 (static_cast<sal_uInt64
>(m_pBuffer
[index
+5]) << 16) |
145 (static_cast<sal_uInt64
>(m_pBuffer
[index
+6]) << 8) |
146 (static_cast<sal_uInt64
>(m_pBuffer
[index
+7]) << 0)
151 BlopObject::BlopObject(const sal_uInt8
* buffer
, sal_uInt32 len
)
157 /**************************************************************************
161 **************************************************************************/
166 std::vector
<std::unique_ptr
<sal_Unicode
[]>> m_stringTable
;
167 sal_uInt16 m_stringsCopied
;
169 explicit StringCache(sal_uInt16 size
); // throws std::bad_alloc
171 const sal_Unicode
* getString(sal_uInt16 index
) const;
172 sal_uInt16
createString(const sal_uInt8
* buffer
); // throws std::bad_alloc
175 StringCache::StringCache(sal_uInt16 size
)
176 : m_stringTable(size
)
181 const sal_Unicode
* StringCache::getString(sal_uInt16 index
) const
183 if ((index
> 0) && (index
<= m_stringsCopied
))
184 return m_stringTable
[index
- 1].get();
189 sal_uInt16
StringCache::createString(const sal_uInt8
* buffer
)
191 if (m_stringsCopied
< m_stringTable
.size())
193 sal_uInt32 len
= UINT16StringLen(buffer
);
195 m_stringTable
[m_stringsCopied
].reset( new sal_Unicode
[len
+ 1] );
197 readString(buffer
, m_stringTable
[m_stringsCopied
].get(), (len
+ 1) * sizeof(sal_Unicode
));
199 return ++m_stringsCopied
;
205 /**************************************************************************
209 **************************************************************************/
211 class ConstantPool
: public BlopObject
215 sal_uInt16
const m_numOfEntries
;
216 std::unique_ptr
<sal_Int32
[]> m_pIndex
; // index values may be < 0 for cached string constants
218 std::unique_ptr
<StringCache
> m_pStringCache
;
220 ConstantPool(const sal_uInt8
* buffer
, sal_uInt32 len
, sal_uInt16 numEntries
)
221 : BlopObject(buffer
, len
)
222 , m_numOfEntries(numEntries
)
226 sal_uInt32
parseIndex(); // throws std::bad_alloc
228 CPInfoTag
readTag(sal_uInt16 index
) const;
230 const sal_Char
* readUTF8NameConstant(sal_uInt16 index
) const;
231 bool readBOOLConstant(sal_uInt16 index
) const;
232 sal_Int8
readBYTEConstant(sal_uInt16 index
) const;
233 sal_Int16
readINT16Constant(sal_uInt16 index
) const;
234 sal_uInt16
readUINT16Constant(sal_uInt16 index
) const;
235 sal_Int32
readINT32Constant(sal_uInt16 index
) const;
236 sal_uInt32
readUINT32Constant(sal_uInt16 index
) const;
237 sal_Int64
readINT64Constant(sal_uInt16 index
) const;
238 sal_uInt64
readUINT64Constant(sal_uInt16 index
) const;
239 float readFloatConstant(sal_uInt16 index
) const;
240 double readDoubleConstant(sal_uInt16 index
) const;
241 const sal_Unicode
* readStringConstant(sal_uInt16 index
) const;
242 // throws std::bad_alloc
245 sal_uInt32
ConstantPool::parseIndex()
248 m_pStringCache
.reset();
250 sal_uInt32 offset
= 0;
251 sal_uInt16 numOfStrings
= 0;
255 m_pIndex
.reset( new sal_Int32
[m_numOfEntries
] );
257 for (int i
= 0; i
< m_numOfEntries
; i
++)
259 m_pIndex
[i
] = offset
;
261 offset
+= readUINT32(offset
);
263 if ( static_cast<CPInfoTag
>(readUINT16(m_pIndex
[i
] + CP_OFFSET_ENTRY_TAG
)) ==
264 CP_TAG_CONST_STRING
)
274 m_pStringCache
.reset( new StringCache(numOfStrings
) );
277 m_bufferLen
= offset
;
282 CPInfoTag
ConstantPool::readTag(sal_uInt16 index
) const
284 CPInfoTag tag
= CP_TAG_INVALID
;
286 if (m_pIndex
&& (index
> 0) && (index
<= m_numOfEntries
))
288 tag
= static_cast<CPInfoTag
>(readUINT16(m_pIndex
[index
- 1] + CP_OFFSET_ENTRY_TAG
));
294 const sal_Char
* ConstantPool::readUTF8NameConstant(sal_uInt16 index
) const
296 const sal_Char
* aName
= NULL_STRING
;
298 if (m_pIndex
&& (index
> 0) && (index
<= m_numOfEntries
))
300 if (readUINT16(m_pIndex
[index
- 1] + CP_OFFSET_ENTRY_TAG
) == CP_TAG_UTF8_NAME
)
302 sal_uInt32 n
= m_pIndex
[index
- 1] + CP_OFFSET_ENTRY_DATA
;
304 && std::memchr(m_pBuffer
+ n
, 0, m_bufferLen
- n
) != nullptr)
306 aName
= reinterpret_cast<const char*>(m_pBuffer
+ n
);
314 bool ConstantPool::readBOOLConstant(sal_uInt16 index
) const
318 if (m_pIndex
&& (index
> 0) && (index
<= m_numOfEntries
))
320 if (readUINT16(m_pIndex
[index
- 1] + CP_OFFSET_ENTRY_TAG
) == CP_TAG_CONST_BOOL
)
322 aBool
= readBYTE(m_pIndex
[index
- 1] + CP_OFFSET_ENTRY_DATA
) != 0;
329 sal_Int8
ConstantPool::readBYTEConstant(sal_uInt16 index
) const
333 if (m_pIndex
&& (index
> 0) && (index
<= m_numOfEntries
))
335 if (readUINT16(m_pIndex
[index
- 1] + CP_OFFSET_ENTRY_TAG
) == CP_TAG_CONST_BYTE
)
337 aByte
= static_cast< sal_Int8
>(
338 readBYTE(m_pIndex
[index
- 1] + CP_OFFSET_ENTRY_DATA
));
345 sal_Int16
ConstantPool::readINT16Constant(sal_uInt16 index
) const
347 sal_Int16 aINT16
= 0;
349 if (m_pIndex
&& (index
> 0) && (index
<= m_numOfEntries
))
351 if (readUINT16(m_pIndex
[index
- 1] + CP_OFFSET_ENTRY_TAG
) == CP_TAG_CONST_INT16
)
353 aINT16
= readINT16(m_pIndex
[index
- 1] + CP_OFFSET_ENTRY_DATA
);
360 sal_uInt16
ConstantPool::readUINT16Constant(sal_uInt16 index
) const
362 sal_uInt16 asal_uInt16
= 0;
364 if (m_pIndex
&& (index
> 0) && (index
<= m_numOfEntries
))
366 if (readUINT16(m_pIndex
[index
- 1] + CP_OFFSET_ENTRY_TAG
) == CP_TAG_CONST_UINT16
)
368 asal_uInt16
= readUINT16(m_pIndex
[index
- 1] + CP_OFFSET_ENTRY_DATA
);
375 sal_Int32
ConstantPool::readINT32Constant(sal_uInt16 index
) const
377 sal_Int32 aINT32
= 0;
379 if (m_pIndex
&& (index
> 0) && (index
<= m_numOfEntries
))
381 if (readUINT16(m_pIndex
[index
- 1] + CP_OFFSET_ENTRY_TAG
) == CP_TAG_CONST_INT32
)
383 aINT32
= readINT32(m_pIndex
[index
- 1] + CP_OFFSET_ENTRY_DATA
);
390 sal_uInt32
ConstantPool::readUINT32Constant(sal_uInt16 index
) const
392 sal_uInt32 aUINT32
= 0;
394 if (m_pIndex
&& (index
> 0) && (index
<= m_numOfEntries
))
396 if (readUINT16(m_pIndex
[index
- 1] + CP_OFFSET_ENTRY_TAG
) == CP_TAG_CONST_UINT32
)
398 aUINT32
= readUINT32(m_pIndex
[index
- 1] + CP_OFFSET_ENTRY_DATA
);
405 sal_Int64
ConstantPool::readINT64Constant(sal_uInt16 index
) const
407 sal_Int64 aINT64
= 0;
409 if (m_pIndex
&& (index
> 0) && (index
<= m_numOfEntries
))
411 if (readUINT16(m_pIndex
[index
- 1] + CP_OFFSET_ENTRY_TAG
) == CP_TAG_CONST_INT64
)
413 aINT64
= readINT64(m_pIndex
[index
- 1] + CP_OFFSET_ENTRY_DATA
);
420 sal_uInt64
ConstantPool::readUINT64Constant(sal_uInt16 index
) const
422 sal_uInt64 aUINT64
= 0;
424 if (m_pIndex
&& (index
> 0) && (index
<= m_numOfEntries
))
426 if (readUINT16(m_pIndex
[index
- 1] + CP_OFFSET_ENTRY_TAG
) == CP_TAG_CONST_UINT64
)
428 aUINT64
= readUINT64(m_pIndex
[index
- 1] + CP_OFFSET_ENTRY_DATA
);
435 float ConstantPool::readFloatConstant(sal_uInt16 index
) const
443 if (m_pIndex
&& (index
> 0) && (index
<= m_numOfEntries
))
445 if (readUINT16(m_pIndex
[index
- 1] + CP_OFFSET_ENTRY_TAG
) == CP_TAG_CONST_FLOAT
)
447 #ifdef REGTYPE_IEEE_NATIVE
448 x
.b
= readUINT32(m_pIndex
[index
- 1] + CP_OFFSET_ENTRY_DATA
);
458 double ConstantPool::readDoubleConstant(sal_uInt16 index
) const
470 if (m_pIndex
&& (index
> 0) && (index
<= m_numOfEntries
))
472 if (readUINT16(m_pIndex
[index
- 1] + CP_OFFSET_ENTRY_TAG
) == CP_TAG_CONST_DOUBLE
)
475 #ifdef REGTYPE_IEEE_NATIVE
476 # ifdef OSL_BIGENDIAN
477 x
.b
.b1
= readUINT32(m_pIndex
[index
- 1] + CP_OFFSET_ENTRY_DATA
);
478 x
.b
.b2
= readUINT32(m_pIndex
[index
- 1] + CP_OFFSET_ENTRY_DATA
+ sizeof(sal_uInt32
));
480 x
.b
.b1
= readUINT32(m_pIndex
[index
- 1] + CP_OFFSET_ENTRY_DATA
+ sizeof(sal_uInt32
));
481 x
.b
.b2
= readUINT32(m_pIndex
[index
- 1] + CP_OFFSET_ENTRY_DATA
);
492 const sal_Unicode
* ConstantPool::readStringConstant(sal_uInt16 index
) const
494 const sal_Unicode
* aString
= NULL_WSTRING
;
496 if (m_pIndex
&& (index
> 0) && (index
<= m_numOfEntries
) && m_pStringCache
)
498 if (m_pIndex
[index
- 1] >= 0)
500 // create cached string now
502 if (readUINT16(m_pIndex
[index
- 1] + CP_OFFSET_ENTRY_TAG
) == CP_TAG_CONST_STRING
)
504 sal_uInt32 n
= m_pIndex
[index
- 1] + CP_OFFSET_ENTRY_DATA
;
506 || (std::memchr(m_pBuffer
+ n
, 0, m_bufferLen
- n
)
511 m_pIndex
[index
- 1] = -1 * m_pStringCache
->createString(m_pBuffer
+ n
);
515 aString
= m_pStringCache
->getString(static_cast<sal_uInt16
>(m_pIndex
[index
- 1] * -1));
521 /**************************************************************************
525 **************************************************************************/
527 class FieldList
: public BlopObject
531 sal_uInt16
const m_numOfEntries
;
532 size_t m_FIELD_ENTRY_SIZE
;
533 ConstantPool
* const m_pCP
;
535 FieldList(const sal_uInt8
* buffer
, sal_uInt32 len
, sal_uInt16 numEntries
, ConstantPool
* pCP
)
536 : BlopObject(buffer
, len
)
537 , m_numOfEntries(numEntries
)
540 if ( m_numOfEntries
> 0 )
542 sal_uInt16 numOfFieldEntries
= readUINT16(0);
543 m_FIELD_ENTRY_SIZE
= numOfFieldEntries
* sizeof(sal_uInt16
);
546 m_FIELD_ENTRY_SIZE
= 0;
550 sal_uInt32
parseIndex() const { return ((m_numOfEntries
? sizeof(sal_uInt16
) : 0) + (m_numOfEntries
* m_FIELD_ENTRY_SIZE
));}
552 const sal_Char
* getFieldName(sal_uInt16 index
) const;
553 const sal_Char
* getFieldType(sal_uInt16 index
) const;
554 RTFieldAccess
getFieldAccess(sal_uInt16 index
) const;
555 RTValueType
getFieldConstValue(sal_uInt16 index
, RTConstValueUnion
* value
) const;
556 // throws std::bad_alloc
557 const sal_Char
* getFieldDoku(sal_uInt16 index
) const;
558 const sal_Char
* getFieldFileName(sal_uInt16 index
) const;
562 const sal_Char
* FieldList::getFieldName(sal_uInt16 index
) const
564 const sal_Char
* aName
= nullptr;
566 if ((m_numOfEntries
> 0) && (index
<= m_numOfEntries
))
569 aName
= m_pCP
->readUTF8NameConstant(readUINT16(sizeof(sal_uInt16
) + (index
* m_FIELD_ENTRY_SIZE
) + FIELD_OFFSET_NAME
));
570 } catch (BlopObject::BoundsError
&) {
571 SAL_WARN("registry", "bad data");
578 const sal_Char
* FieldList::getFieldType(sal_uInt16 index
) const
580 const sal_Char
* aName
= nullptr;
582 if ((m_numOfEntries
> 0) && (index
<= m_numOfEntries
))
585 aName
= m_pCP
->readUTF8NameConstant(readUINT16(sizeof(sal_uInt16
) + (index
* m_FIELD_ENTRY_SIZE
) + FIELD_OFFSET_TYPE
));
586 } catch (BlopObject::BoundsError
&) {
587 SAL_WARN("registry", "bad data");
594 RTFieldAccess
FieldList::getFieldAccess(sal_uInt16 index
) const
596 RTFieldAccess aAccess
= RTFieldAccess::INVALID
;
598 if ((m_numOfEntries
> 0) && (index
<= m_numOfEntries
))
601 aAccess
= static_cast<RTFieldAccess
>(readUINT16(sizeof(sal_uInt16
) + (index
* m_FIELD_ENTRY_SIZE
) + FIELD_OFFSET_ACCESS
));
602 } catch (BlopObject::BoundsError
&) {
603 SAL_WARN("registry", "bad data");
610 RTValueType
FieldList::getFieldConstValue(sal_uInt16 index
, RTConstValueUnion
* value
) const
612 RTValueType ret
= RT_TYPE_NONE
;
614 if ((m_numOfEntries
> 0) && (index
<= m_numOfEntries
))
616 sal_uInt16 cpIndex
= readUINT16(sizeof(sal_uInt16
) + (index
* m_FIELD_ENTRY_SIZE
) + FIELD_OFFSET_VALUE
);
617 switch (m_pCP
->readTag(cpIndex
))
619 case CP_TAG_CONST_BOOL
:
620 value
->aBool
= m_pCP
->readBOOLConstant(cpIndex
);
623 case CP_TAG_CONST_BYTE
:
624 value
->aByte
= m_pCP
->readBYTEConstant(cpIndex
);
627 case CP_TAG_CONST_INT16
:
628 value
->aShort
= m_pCP
->readINT16Constant(cpIndex
);
631 case CP_TAG_CONST_UINT16
:
632 value
->aUShort
= m_pCP
->readUINT16Constant(cpIndex
);
633 ret
= RT_TYPE_UINT16
;
635 case CP_TAG_CONST_INT32
:
636 value
->aLong
= m_pCP
->readINT32Constant(cpIndex
);
639 case CP_TAG_CONST_UINT32
:
640 value
->aULong
= m_pCP
->readUINT32Constant(cpIndex
);
641 ret
= RT_TYPE_UINT32
;
643 case CP_TAG_CONST_INT64
:
644 value
->aHyper
= m_pCP
->readINT64Constant(cpIndex
);
647 case CP_TAG_CONST_UINT64
:
648 value
->aUHyper
= m_pCP
->readUINT64Constant(cpIndex
);
649 ret
= RT_TYPE_UINT64
;
651 case CP_TAG_CONST_FLOAT
:
652 value
->aFloat
= m_pCP
->readFloatConstant(cpIndex
);
655 case CP_TAG_CONST_DOUBLE
:
656 value
->aDouble
= m_pCP
->readDoubleConstant(cpIndex
);
657 ret
= RT_TYPE_DOUBLE
;
659 case CP_TAG_CONST_STRING
:
660 value
->aString
= m_pCP
->readStringConstant(cpIndex
);
661 ret
= RT_TYPE_STRING
;
667 } catch (BlopObject::BoundsError
&) {
668 SAL_WARN("registry", "bad data");
673 const sal_Char
* FieldList::getFieldDoku(sal_uInt16 index
) const
675 const sal_Char
* aDoku
= nullptr;
677 if ((m_numOfEntries
> 0) && (index
<= m_numOfEntries
))
680 aDoku
= m_pCP
->readUTF8NameConstant(readUINT16(sizeof(sal_uInt16
) + (index
* m_FIELD_ENTRY_SIZE
) + FIELD_OFFSET_DOKU
));
681 } catch (BlopObject::BoundsError
&) {
682 SAL_WARN("registry", "bad data");
689 const sal_Char
* FieldList::getFieldFileName(sal_uInt16 index
) const
691 const sal_Char
* aFileName
= nullptr;
693 if ((m_numOfEntries
> 0) && (index
<= m_numOfEntries
))
696 aFileName
= m_pCP
->readUTF8NameConstant(readUINT16(sizeof(sal_uInt16
) + (index
* m_FIELD_ENTRY_SIZE
) + FIELD_OFFSET_FILENAME
));
697 } catch (BlopObject::BoundsError
&) {
698 SAL_WARN("registry", "bad data");
705 /**************************************************************************
709 **************************************************************************/
711 class ReferenceList
: public BlopObject
715 sal_uInt16
const m_numOfEntries
;
716 size_t m_REFERENCE_ENTRY_SIZE
;
717 ConstantPool
* const m_pCP
;
719 ReferenceList(const sal_uInt8
* buffer
, sal_uInt32 len
, sal_uInt16 numEntries
, ConstantPool
* pCP
)
720 : BlopObject(buffer
, len
)
721 , m_numOfEntries(numEntries
)
724 if ( m_numOfEntries
> 0 )
726 sal_uInt16 numOfReferenceEntries
= readUINT16(0);
727 m_REFERENCE_ENTRY_SIZE
= numOfReferenceEntries
* sizeof(sal_uInt16
);
730 m_REFERENCE_ENTRY_SIZE
= 0;
734 const sal_Char
* getReferenceName(sal_uInt16 index
) const;
735 RTReferenceType
getReferenceType(sal_uInt16 index
) const;
736 const sal_Char
* getReferenceDoku(sal_uInt16 index
) const;
737 RTFieldAccess
getReferenceAccess(sal_uInt16 index
) const;
741 const sal_Char
* ReferenceList::getReferenceName(sal_uInt16 index
) const
743 const sal_Char
* aName
= nullptr;
745 if ((m_numOfEntries
> 0) && (index
<= m_numOfEntries
))
748 aName
= m_pCP
->readUTF8NameConstant(readUINT16(sizeof(sal_uInt16
) + (index
* m_REFERENCE_ENTRY_SIZE
) + REFERENCE_OFFSET_NAME
));
749 } catch (BlopObject::BoundsError
&) {
750 SAL_WARN("registry", "bad data");
757 RTReferenceType
ReferenceList::getReferenceType(sal_uInt16 index
) const
759 RTReferenceType refType
= RTReferenceType::INVALID
;
761 if ((m_numOfEntries
> 0) && (index
<= m_numOfEntries
))
764 refType
= static_cast<RTReferenceType
>(readUINT16(sizeof(sal_uInt16
) + (index
* m_REFERENCE_ENTRY_SIZE
) + REFERENCE_OFFSET_TYPE
));
765 } catch (BlopObject::BoundsError
&) {
766 SAL_WARN("registry", "bad data");
773 const sal_Char
* ReferenceList::getReferenceDoku(sal_uInt16 index
) const
775 const sal_Char
* aDoku
= nullptr;
777 if ((m_numOfEntries
> 0) && (index
<= m_numOfEntries
))
780 aDoku
= m_pCP
->readUTF8NameConstant(readUINT16(sizeof(sal_uInt16
) + (index
* m_REFERENCE_ENTRY_SIZE
) + REFERENCE_OFFSET_DOKU
));
781 } catch (BlopObject::BoundsError
&) {
782 SAL_WARN("registry", "bad data");
789 RTFieldAccess
ReferenceList::getReferenceAccess(sal_uInt16 index
) const
791 RTFieldAccess aAccess
= RTFieldAccess::INVALID
;
793 if ((m_numOfEntries
> 0) && (index
<= m_numOfEntries
))
796 aAccess
= static_cast<RTFieldAccess
>(readUINT16(sizeof(sal_uInt16
) + (index
* m_REFERENCE_ENTRY_SIZE
) + REFERENCE_OFFSET_ACCESS
));
797 } catch (BlopObject::BoundsError
&) {
798 SAL_WARN("registry", "bad data");
805 /**************************************************************************
809 **************************************************************************/
811 class MethodList
: public BlopObject
815 sal_uInt16
const m_numOfEntries
;
816 size_t m_PARAM_ENTRY_SIZE
;
817 std::unique_ptr
<sal_uInt32
[]> m_pIndex
;
818 ConstantPool
* const m_pCP
;
820 MethodList(const sal_uInt8
* buffer
, sal_uInt32 len
, sal_uInt16 numEntries
, ConstantPool
* pCP
)
821 : BlopObject(buffer
, len
)
822 , m_numOfEntries(numEntries
)
825 if ( m_numOfEntries
> 0 )
827 readUINT16(0) /* numOfMethodEntries */;
828 sal_uInt16 numOfParamEntries
= readUINT16(sizeof(sal_uInt16
));
829 m_PARAM_ENTRY_SIZE
= numOfParamEntries
* sizeof(sal_uInt16
);
832 m_PARAM_ENTRY_SIZE
= 0;
836 sal_uInt32
parseIndex(); // throws std::bad_alloc
838 const sal_Char
* getMethodName(sal_uInt16 index
) const;
839 sal_uInt16
getMethodParamCount(sal_uInt16 index
) const;
840 const sal_Char
* getMethodParamType(sal_uInt16 index
, sal_uInt16 paramIndex
) const;
841 const sal_Char
* getMethodParamName(sal_uInt16 index
, sal_uInt16 paramIndex
) const;
842 RTParamMode
getMethodParamMode(sal_uInt16 index
, sal_uInt16 paramIndex
) const;
843 sal_uInt16
getMethodExcCount(sal_uInt16 index
) const;
844 const sal_Char
* getMethodExcType(sal_uInt16 index
, sal_uInt16 excIndex
) const;
845 const sal_Char
* getMethodReturnType(sal_uInt16 index
) const;
846 RTMethodMode
getMethodMode(sal_uInt16 index
) const;
847 const sal_Char
* getMethodDoku(sal_uInt16 index
) const;
850 sal_uInt16
calcMethodParamIndex( const sal_uInt16 index
) const;
853 sal_uInt16
MethodList::calcMethodParamIndex( const sal_uInt16 index
) const
855 return (METHOD_OFFSET_PARAM_COUNT
+ sizeof(sal_uInt16
) + (index
* m_PARAM_ENTRY_SIZE
));
858 sal_uInt32
MethodList::parseIndex()
862 sal_uInt32 offset
= 0;
866 offset
= 2 * sizeof(sal_uInt16
);
867 m_pIndex
.reset( new sal_uInt32
[m_numOfEntries
] );
869 for (int i
= 0; i
< m_numOfEntries
; i
++)
871 m_pIndex
[i
] = offset
;
873 offset
+= readUINT16(offset
);
880 const sal_Char
* MethodList::getMethodName(sal_uInt16 index
) const
882 const sal_Char
* aName
= nullptr;
884 if ((m_numOfEntries
> 0) && (index
<= m_numOfEntries
))
887 aName
= m_pCP
->readUTF8NameConstant(readUINT16(m_pIndex
[index
] + METHOD_OFFSET_NAME
));
888 } catch (BlopObject::BoundsError
&) {
889 SAL_WARN("registry", "bad data");
896 sal_uInt16
MethodList::getMethodParamCount(sal_uInt16 index
) const
898 sal_uInt16 aCount
= 0;
900 if ((m_numOfEntries
> 0) && (index
<= m_numOfEntries
))
903 aCount
= readUINT16(m_pIndex
[index
] + METHOD_OFFSET_PARAM_COUNT
);
904 } catch (BlopObject::BoundsError
&) {
905 SAL_WARN("registry", "bad data");
912 const sal_Char
* MethodList::getMethodParamType(sal_uInt16 index
, sal_uInt16 paramIndex
) const
914 const sal_Char
* aName
= nullptr;
916 if ((m_numOfEntries
> 0) &&
917 (index
<= m_numOfEntries
) &&
918 (paramIndex
<= readUINT16(m_pIndex
[index
] + METHOD_OFFSET_PARAM_COUNT
)))
920 aName
= m_pCP
->readUTF8NameConstant(
923 calcMethodParamIndex(paramIndex
) +
926 } catch (BlopObject::BoundsError
&) {
927 SAL_WARN("registry", "bad data");
932 const sal_Char
* MethodList::getMethodParamName(sal_uInt16 index
, sal_uInt16 paramIndex
) const
934 const sal_Char
* aName
= nullptr;
936 if ((m_numOfEntries
> 0) &&
937 (index
<= m_numOfEntries
) &&
938 (paramIndex
<= readUINT16(m_pIndex
[index
] + METHOD_OFFSET_PARAM_COUNT
)))
940 aName
= m_pCP
->readUTF8NameConstant(
943 calcMethodParamIndex(paramIndex
) +
946 } catch (BlopObject::BoundsError
&) {
947 SAL_WARN("registry", "bad data");
952 RTParamMode
MethodList::getMethodParamMode(sal_uInt16 index
, sal_uInt16 paramIndex
) const
954 RTParamMode aMode
= RT_PARAM_INVALID
;
956 if ((m_numOfEntries
> 0) &&
957 (index
<= m_numOfEntries
) &&
958 (paramIndex
<= readUINT16(m_pIndex
[index
] + METHOD_OFFSET_PARAM_COUNT
)))
960 aMode
= static_cast<RTParamMode
>(readUINT16(
962 calcMethodParamIndex(paramIndex
) +
965 } catch (BlopObject::BoundsError
&) {
966 SAL_WARN("registry", "bad data");
971 #if defined(__COVERITY__)
972 extern "C" void __coverity_tainted_data_sanitize__(void *);
975 sal_uInt16
MethodList::getMethodExcCount(sal_uInt16 index
) const
977 sal_uInt16 aCount
= 0;
979 if ((m_numOfEntries
> 0) && (index
<= m_numOfEntries
))
982 aCount
= readUINT16(m_pIndex
[index
] + calcMethodParamIndex(readUINT16(m_pIndex
[index
] + METHOD_OFFSET_PARAM_COUNT
)));
983 #if defined(__COVERITY__)
984 __coverity_tainted_data_sanitize__(&aCount
);
986 } catch (BlopObject::BoundsError
&) {
987 SAL_WARN("registry", "bad data");
994 const sal_Char
* MethodList::getMethodExcType(sal_uInt16 index
, sal_uInt16 excIndex
) const
996 const sal_Char
* aName
= nullptr;
998 if ((m_numOfEntries
> 0) && (index
<= m_numOfEntries
))
1001 sal_uInt32 excOffset
= m_pIndex
[index
] + calcMethodParamIndex(readUINT16(m_pIndex
[index
] + METHOD_OFFSET_PARAM_COUNT
));
1002 if (excIndex
<= readUINT16(excOffset
))
1004 aName
= m_pCP
->readUTF8NameConstant(
1007 sizeof(sal_uInt16
) +
1008 (excIndex
* sizeof(sal_uInt16
))));
1010 } catch (BlopObject::BoundsError
&) {
1011 SAL_WARN("registry", "bad data");
1018 const sal_Char
* MethodList::getMethodReturnType(sal_uInt16 index
) const
1020 const sal_Char
* aName
= nullptr;
1022 if ((m_numOfEntries
> 0) && (index
<= m_numOfEntries
))
1025 aName
= m_pCP
->readUTF8NameConstant(readUINT16(m_pIndex
[index
] + METHOD_OFFSET_RETURN
));
1026 } catch (BlopObject::BoundsError
&) {
1027 SAL_WARN("registry", "bad data");
1034 RTMethodMode
MethodList::getMethodMode(sal_uInt16 index
) const
1036 RTMethodMode aMode
= RTMethodMode::INVALID
;
1038 if ((m_numOfEntries
> 0) && (index
<= m_numOfEntries
))
1041 aMode
= static_cast<RTMethodMode
>(readUINT16(m_pIndex
[index
] + METHOD_OFFSET_MODE
));
1042 } catch (BlopObject::BoundsError
&) {
1043 SAL_WARN("registry", "bad data");
1050 const sal_Char
* MethodList::getMethodDoku(sal_uInt16 index
) const
1052 const sal_Char
* aDoku
= nullptr;
1054 if ((m_numOfEntries
> 0) && (index
<= m_numOfEntries
))
1057 aDoku
= m_pCP
->readUTF8NameConstant(readUINT16(m_pIndex
[index
] + METHOD_OFFSET_DOKU
));
1058 } catch (BlopObject::BoundsError
&) {
1059 SAL_WARN("registry", "bad data");
1066 /**************************************************************************
1068 class TypeRegistryEntry
1070 **************************************************************************/
1072 class TypeRegistryEntry
: public BlopObject
{
1074 std::unique_ptr
<ConstantPool
> m_pCP
;
1075 std::unique_ptr
<FieldList
> m_pFields
;
1076 std::unique_ptr
<MethodList
> m_pMethods
;
1077 std::unique_ptr
<ReferenceList
> m_pReferences
;
1078 sal_uInt32 m_refCount
;
1079 sal_uInt16 m_nSuperTypes
;
1080 sal_uInt32 m_offset_SUPERTYPES
;
1083 const sal_uInt8
* buffer
, sal_uInt32 len
);
1084 // throws std::bad_alloc
1086 typereg_Version
getVersion() const;
1089 TypeRegistryEntry::TypeRegistryEntry(
1090 const sal_uInt8
* buffer
, sal_uInt32 len
):
1091 BlopObject(buffer
, len
), m_refCount(1), m_nSuperTypes(0),
1092 m_offset_SUPERTYPES(0)
1094 std::size_t const entrySize
= sizeof(sal_uInt16
);
1095 sal_uInt16 nHeaderEntries
= readUINT16(OFFSET_N_ENTRIES
);
1096 sal_uInt32 offset_N_SUPERTYPES
= OFFSET_N_ENTRIES
+ entrySize
+ (nHeaderEntries
* entrySize
); // cannot overflow
1097 m_offset_SUPERTYPES
= offset_N_SUPERTYPES
+ entrySize
; // cannot overflow
1098 m_nSuperTypes
= readUINT16(offset_N_SUPERTYPES
);
1100 sal_uInt32 offset_CP_SIZE
= m_offset_SUPERTYPES
+ (m_nSuperTypes
* entrySize
); // cannot overflow
1101 sal_uInt32 offset_CP
= offset_CP_SIZE
+ entrySize
; // cannot overflow
1103 if (offset_CP
> m_bufferLen
) {
1104 throw BoundsError();
1108 m_pBuffer
+ offset_CP
, m_bufferLen
- offset_CP
,
1109 readUINT16(offset_CP_SIZE
)));
1111 sal_uInt32 offset
= offset_CP
+ m_pCP
->parseIndex(); //TODO: overflow
1113 assert(m_bufferLen
>= entrySize
);
1114 if (offset
> m_bufferLen
- entrySize
) {
1115 throw BoundsError();
1119 m_pBuffer
+ offset
+ entrySize
, m_bufferLen
- (offset
+ entrySize
),
1120 readUINT16(offset
), m_pCP
.get()));
1122 offset
+= sizeof(sal_uInt16
) + m_pFields
->parseIndex(); //TODO: overflow
1124 assert(m_bufferLen
>= entrySize
);
1125 if (offset
> m_bufferLen
- entrySize
) {
1126 throw BoundsError();
1130 m_pBuffer
+ offset
+ entrySize
, m_bufferLen
- (offset
+ entrySize
),
1131 readUINT16(offset
), m_pCP
.get()));
1133 offset
+= sizeof(sal_uInt16
) + m_pMethods
->parseIndex(); //TODO: overflow
1135 assert(m_bufferLen
>= entrySize
);
1136 if (offset
> m_bufferLen
- entrySize
) {
1137 throw BoundsError();
1139 m_pReferences
.reset(
1141 m_pBuffer
+ offset
+ entrySize
, m_bufferLen
- (offset
+ entrySize
),
1142 readUINT16(offset
), m_pCP
.get()));
1145 typereg_Version
TypeRegistryEntry::getVersion() const {
1146 // Assumes two's complement arithmetic with modulo-semantics:
1147 return static_cast< typereg_Version
>(readUINT32(OFFSET_MAGIC
) - magic
);
1150 /**************************************************************************
1154 **************************************************************************/
1156 bool TYPEREG_CALLTYPE
typereg_reader_create(
1157 void const * buffer
, sal_uInt32 length
,
1160 if (length
< OFFSET_CP
|| length
> SAL_MAX_UINT32
) {
1164 std::unique_ptr
< TypeRegistryEntry
> entry
;
1168 new TypeRegistryEntry(
1169 static_cast< sal_uInt8
const * >(buffer
), length
));
1170 } catch (std::bad_alloc
&) {
1173 if (entry
->readUINT32(OFFSET_SIZE
) != length
) {
1177 typereg_Version version
= entry
->getVersion();
1178 if (version
< TYPEREG_VERSION_0
|| version
> TYPEREG_VERSION_1
) {
1182 *result
= entry
.release();
1184 } catch (BlopObject::BoundsError
&) {
1185 SAL_WARN("registry", "bad data");
1190 static TypeReaderImpl TYPEREG_CALLTYPE
createEntry(const sal_uInt8
* buffer
, sal_uInt32 len
)
1193 typereg_reader_create(buffer
, len
, &handle
);
1197 void TYPEREG_CALLTYPE
typereg_reader_acquire(void * hEntry
)
1199 TypeRegistryEntry
* pEntry
= static_cast<TypeRegistryEntry
*>(hEntry
);
1201 if (pEntry
!= nullptr)
1202 pEntry
->m_refCount
++;
1205 void TYPEREG_CALLTYPE
typereg_reader_release(void * hEntry
)
1207 TypeRegistryEntry
* pEntry
= static_cast<TypeRegistryEntry
*>(hEntry
);
1209 if (pEntry
!= nullptr)
1211 if (--pEntry
->m_refCount
== 0)
1216 typereg_Version TYPEREG_CALLTYPE
typereg_reader_getVersion(void const * handle
) {
1217 if (handle
!= nullptr) {
1219 return static_cast< TypeRegistryEntry
const * >(handle
)->getVersion();
1220 } catch (BlopObject::BoundsError
&) {
1221 SAL_WARN("registry", "bad data");
1224 return TYPEREG_VERSION_0
;
1227 RTTypeClass TYPEREG_CALLTYPE
typereg_reader_getTypeClass(void * hEntry
)
1229 TypeRegistryEntry
* pEntry
= static_cast<TypeRegistryEntry
*>(hEntry
);
1230 if (pEntry
!= nullptr) {
1232 return static_cast<RTTypeClass
>(pEntry
->readUINT16(OFFSET_TYPE_CLASS
) & ~RT_TYPE_PUBLISHED
);
1233 } catch (BlopObject::BoundsError
&) {
1234 SAL_WARN("registry", "bad data");
1237 return RT_TYPE_INVALID
;
1240 bool TYPEREG_CALLTYPE
typereg_reader_isPublished(void * hEntry
)
1242 TypeRegistryEntry
* entry
= static_cast< TypeRegistryEntry
* >(hEntry
);
1243 if (entry
!= nullptr) {
1245 return (entry
->readUINT16(OFFSET_TYPE_CLASS
) & RT_TYPE_PUBLISHED
) != 0;
1246 } catch (BlopObject::BoundsError
&) {
1247 SAL_WARN("registry", "bad data");
1253 void TYPEREG_CALLTYPE
typereg_reader_getTypeName(void * hEntry
, rtl_uString
** pTypeName
)
1255 TypeRegistryEntry
* pEntry
= static_cast<TypeRegistryEntry
*>(hEntry
);
1256 if (pEntry
!= nullptr) {
1258 const sal_Char
* pTmp
= pEntry
->m_pCP
->readUTF8NameConstant(pEntry
->readUINT16(OFFSET_THIS_TYPE
));
1260 pTypeName
, pTmp
, pTmp
== nullptr ? 0 : rtl_str_getLength(pTmp
),
1261 RTL_TEXTENCODING_UTF8
, OSTRING_TO_OUSTRING_CVTFLAGS
);
1263 } catch (BlopObject::BoundsError
&) {
1264 SAL_WARN("registry", "bad data");
1267 rtl_uString_new(pTypeName
);
1271 static void TYPEREG_CALLTYPE
getSuperTypeName(TypeReaderImpl hEntry
, rtl_uString
** pSuperTypeName
)
1273 TypeRegistryEntry
* pEntry
= static_cast<TypeRegistryEntry
*>(hEntry
);
1274 if (pEntry
!= nullptr && pEntry
->m_nSuperTypes
!= 0) {
1276 const sal_Char
* pTmp
= pEntry
->m_pCP
->readUTF8NameConstant(pEntry
->readUINT16(pEntry
->m_offset_SUPERTYPES
)); //+ (index * sizeof(sal_uInt16))));
1278 pSuperTypeName
, pTmp
, pTmp
== nullptr ? 0 : rtl_str_getLength(pTmp
),
1279 RTL_TEXTENCODING_UTF8
, OSTRING_TO_OUSTRING_CVTFLAGS
);
1281 } catch (BlopObject::BoundsError
&) {
1282 SAL_WARN("registry", "bad data");
1285 rtl_uString_new(pSuperTypeName
);
1288 void TYPEREG_CALLTYPE
typereg_reader_getDocumentation(void * hEntry
, rtl_uString
** pDoku
)
1290 TypeRegistryEntry
* pEntry
= static_cast<TypeRegistryEntry
*>(hEntry
);
1291 if (pEntry
!= nullptr) {
1293 const sal_Char
* pTmp
= pEntry
->m_pCP
->readUTF8NameConstant(pEntry
->readUINT16(OFFSET_DOKU
));
1295 pDoku
, pTmp
, pTmp
== nullptr ? 0 : rtl_str_getLength(pTmp
),
1296 RTL_TEXTENCODING_UTF8
, OSTRING_TO_OUSTRING_CVTFLAGS
);
1298 } catch (BlopObject::BoundsError
&) {
1299 SAL_WARN("registry", "bad data");
1302 rtl_uString_new(pDoku
);
1305 void TYPEREG_CALLTYPE
typereg_reader_getFileName(void * hEntry
, rtl_uString
** pFileName
)
1307 TypeRegistryEntry
* pEntry
= static_cast<TypeRegistryEntry
*>(hEntry
);
1308 if (pEntry
!= nullptr) {
1310 const sal_Char
* pTmp
= pEntry
->m_pCP
->readUTF8NameConstant(pEntry
->readUINT16(OFFSET_FILENAME
));
1312 pFileName
, pTmp
, pTmp
== nullptr ? 0 : rtl_str_getLength(pTmp
),
1313 RTL_TEXTENCODING_UTF8
, OSTRING_TO_OUSTRING_CVTFLAGS
);
1315 } catch (BlopObject::BoundsError
&) {
1316 SAL_WARN("registry", "bad data");
1319 rtl_uString_new(pFileName
);
1323 sal_uInt16 TYPEREG_CALLTYPE
typereg_reader_getFieldCount(void * hEntry
)
1325 TypeRegistryEntry
* pEntry
= static_cast<TypeRegistryEntry
*>(hEntry
);
1327 if (pEntry
== nullptr) return 0;
1329 return pEntry
->m_pFields
->m_numOfEntries
;
1332 static sal_uInt32 TYPEREG_CALLTYPE
getFieldCount(TypeReaderImpl hEntry
)
1334 return typereg_reader_getFieldCount(hEntry
);
1337 void TYPEREG_CALLTYPE
typereg_reader_getFieldName(void * hEntry
, rtl_uString
** pFieldName
, sal_uInt16 index
)
1339 TypeRegistryEntry
* pEntry
= static_cast<TypeRegistryEntry
*>(hEntry
);
1341 if (pEntry
== nullptr)
1343 rtl_uString_new(pFieldName
);
1346 const sal_Char
* pTmp
= pEntry
->m_pFields
->getFieldName(index
);
1348 pFieldName
, pTmp
, pTmp
== nullptr ? 0 : rtl_str_getLength(pTmp
),
1349 RTL_TEXTENCODING_UTF8
, OSTRING_TO_OUSTRING_CVTFLAGS
);
1352 void TYPEREG_CALLTYPE
typereg_reader_getFieldTypeName(void * hEntry
, rtl_uString
** pFieldType
, sal_uInt16 index
)
1354 TypeRegistryEntry
* pEntry
= static_cast<TypeRegistryEntry
*>(hEntry
);
1356 if (pEntry
== nullptr)
1358 rtl_uString_new(pFieldType
);
1362 const sal_Char
* pTmp
= pEntry
->m_pFields
->getFieldType(index
);
1364 pFieldType
, pTmp
, pTmp
== nullptr ? 0 : rtl_str_getLength(pTmp
),
1365 RTL_TEXTENCODING_UTF8
, OSTRING_TO_OUSTRING_CVTFLAGS
);
1368 RTFieldAccess TYPEREG_CALLTYPE
typereg_reader_getFieldFlags(void * hEntry
, sal_uInt16 index
)
1370 TypeRegistryEntry
* pEntry
= static_cast<TypeRegistryEntry
*>(hEntry
);
1372 if (pEntry
== nullptr) return RTFieldAccess::INVALID
;
1374 return pEntry
->m_pFields
->getFieldAccess(index
);
1377 bool TYPEREG_CALLTYPE
typereg_reader_getFieldValue(
1378 void * hEntry
, sal_uInt16 index
, RTValueType
* type
,
1379 RTConstValueUnion
* value
)
1381 TypeRegistryEntry
* pEntry
= static_cast<TypeRegistryEntry
*>(hEntry
);
1383 if (pEntry
== nullptr) {
1384 *type
= RT_TYPE_NONE
;
1389 *type
= pEntry
->m_pFields
->getFieldConstValue(index
, value
);
1390 } catch (std::bad_alloc
&) {
1396 static RTValueType TYPEREG_CALLTYPE
getFieldConstValue(TypeReaderImpl hEntry
, sal_uInt16 index
, RTConstValueUnion
* value
)
1398 RTValueType t
= RT_TYPE_NONE
;
1399 typereg_reader_getFieldValue(hEntry
, index
, &t
, value
);
1403 void TYPEREG_CALLTYPE
typereg_reader_getFieldDocumentation(void * hEntry
, rtl_uString
** pDoku
, sal_uInt16 index
)
1405 TypeRegistryEntry
* pEntry
= static_cast<TypeRegistryEntry
*>(hEntry
);
1407 if (pEntry
== nullptr)
1409 rtl_uString_new(pDoku
);
1413 const sal_Char
* pTmp
= pEntry
->m_pFields
->getFieldDoku(index
);
1415 pDoku
, pTmp
, pTmp
== nullptr ? 0 : rtl_str_getLength(pTmp
),
1416 RTL_TEXTENCODING_UTF8
, OSTRING_TO_OUSTRING_CVTFLAGS
);
1419 void TYPEREG_CALLTYPE
typereg_reader_getFieldFileName(void * hEntry
, rtl_uString
** pFieldFileName
, sal_uInt16 index
)
1421 TypeRegistryEntry
* pEntry
= static_cast<TypeRegistryEntry
*>(hEntry
);
1423 if (pEntry
== nullptr)
1425 rtl_uString_new(pFieldFileName
);
1429 const sal_Char
* pTmp
= pEntry
->m_pFields
->getFieldFileName(index
);
1431 pFieldFileName
, pTmp
, pTmp
== nullptr ? 0 : rtl_str_getLength(pTmp
),
1432 RTL_TEXTENCODING_UTF8
, OSTRING_TO_OUSTRING_CVTFLAGS
);
1436 sal_uInt16 TYPEREG_CALLTYPE
typereg_reader_getMethodCount(void * hEntry
)
1438 TypeRegistryEntry
* pEntry
= static_cast<TypeRegistryEntry
*>(hEntry
);
1440 if (pEntry
== nullptr) return 0;
1442 return pEntry
->m_pMethods
->m_numOfEntries
;
1445 void TYPEREG_CALLTYPE
typereg_reader_getMethodName(void * hEntry
, rtl_uString
** pMethodName
, sal_uInt16 index
)
1447 TypeRegistryEntry
* pEntry
= static_cast<TypeRegistryEntry
*>(hEntry
);
1449 if (pEntry
== nullptr)
1451 rtl_uString_new(pMethodName
);
1455 const sal_Char
* pTmp
= pEntry
->m_pMethods
->getMethodName(index
);
1457 pMethodName
, pTmp
, pTmp
== nullptr ? 0 : rtl_str_getLength(pTmp
),
1458 RTL_TEXTENCODING_UTF8
, OSTRING_TO_OUSTRING_CVTFLAGS
);
1461 sal_uInt16 TYPEREG_CALLTYPE
typereg_reader_getMethodParameterCount(
1462 void * hEntry
, sal_uInt16 index
)
1464 TypeRegistryEntry
* pEntry
= static_cast<TypeRegistryEntry
*>(hEntry
);
1466 if (pEntry
== nullptr) return 0;
1468 return pEntry
->m_pMethods
->getMethodParamCount(index
);
1471 void TYPEREG_CALLTYPE
typereg_reader_getMethodParameterTypeName(void * hEntry
, rtl_uString
** pMethodParamType
, sal_uInt16 index
, sal_uInt16 paramIndex
)
1473 TypeRegistryEntry
* pEntry
= static_cast<TypeRegistryEntry
*>(hEntry
);
1475 if (pEntry
== nullptr)
1477 rtl_uString_new(pMethodParamType
);
1481 const sal_Char
* pTmp
= pEntry
->m_pMethods
->getMethodParamType(index
, paramIndex
);
1483 pMethodParamType
, pTmp
, pTmp
== nullptr ? 0 : rtl_str_getLength(pTmp
),
1484 RTL_TEXTENCODING_UTF8
, OSTRING_TO_OUSTRING_CVTFLAGS
);
1487 void TYPEREG_CALLTYPE
typereg_reader_getMethodParameterName(void * hEntry
, rtl_uString
** pMethodParamName
, sal_uInt16 index
, sal_uInt16 paramIndex
)
1489 TypeRegistryEntry
* pEntry
= static_cast<TypeRegistryEntry
*>(hEntry
);
1491 if (pEntry
== nullptr)
1493 rtl_uString_new(pMethodParamName
);
1497 const sal_Char
* pTmp
= pEntry
->m_pMethods
->getMethodParamName(index
, paramIndex
);
1499 pMethodParamName
, pTmp
, pTmp
== nullptr ? 0 : rtl_str_getLength(pTmp
),
1500 RTL_TEXTENCODING_UTF8
, OSTRING_TO_OUSTRING_CVTFLAGS
);
1503 RTParamMode TYPEREG_CALLTYPE
typereg_reader_getMethodParameterFlags(void * hEntry
, sal_uInt16 index
, sal_uInt16 paramIndex
)
1505 TypeRegistryEntry
* pEntry
= static_cast<TypeRegistryEntry
*>(hEntry
);
1507 if (pEntry
== nullptr) return RT_PARAM_INVALID
;
1509 return pEntry
->m_pMethods
->getMethodParamMode(index
, paramIndex
);
1512 sal_uInt16 TYPEREG_CALLTYPE
typereg_reader_getMethodExceptionCount(
1513 void * hEntry
, sal_uInt16 index
)
1515 TypeRegistryEntry
* pEntry
= static_cast<TypeRegistryEntry
*>(hEntry
);
1517 if (pEntry
== nullptr) return 0;
1519 return pEntry
->m_pMethods
->getMethodExcCount(index
);
1522 void TYPEREG_CALLTYPE
typereg_reader_getMethodExceptionTypeName(void * hEntry
, rtl_uString
** pMethodExcpType
, sal_uInt16 index
, sal_uInt16 excIndex
)
1524 TypeRegistryEntry
* pEntry
= static_cast<TypeRegistryEntry
*>(hEntry
);
1526 if (pEntry
== nullptr)
1528 rtl_uString_new(pMethodExcpType
);
1532 const sal_Char
* pTmp
= pEntry
->m_pMethods
->getMethodExcType(index
, excIndex
);
1534 pMethodExcpType
, pTmp
, pTmp
== nullptr ? 0 : rtl_str_getLength(pTmp
),
1535 RTL_TEXTENCODING_UTF8
, OSTRING_TO_OUSTRING_CVTFLAGS
);
1538 void TYPEREG_CALLTYPE
typereg_reader_getMethodReturnTypeName(void * hEntry
, rtl_uString
** pMethodReturnType
, sal_uInt16 index
)
1540 TypeRegistryEntry
* pEntry
= static_cast<TypeRegistryEntry
*>(hEntry
);
1542 if (pEntry
== nullptr)
1544 rtl_uString_new(pMethodReturnType
);
1548 const sal_Char
* pTmp
= pEntry
->m_pMethods
->getMethodReturnType(index
);
1550 pMethodReturnType
, pTmp
, pTmp
== nullptr ? 0 : rtl_str_getLength(pTmp
),
1551 RTL_TEXTENCODING_UTF8
, OSTRING_TO_OUSTRING_CVTFLAGS
);
1554 RTMethodMode TYPEREG_CALLTYPE
typereg_reader_getMethodFlags(void * hEntry
, sal_uInt16 index
)
1556 TypeRegistryEntry
* pEntry
= static_cast<TypeRegistryEntry
*>(hEntry
);
1558 if (pEntry
== nullptr) return RTMethodMode::INVALID
;
1560 return pEntry
->m_pMethods
->getMethodMode(index
);
1563 void TYPEREG_CALLTYPE
typereg_reader_getMethodDocumentation(void * hEntry
, rtl_uString
** pMethodDoku
, sal_uInt16 index
)
1565 TypeRegistryEntry
* pEntry
= static_cast<TypeRegistryEntry
*>(hEntry
);
1567 if (pEntry
== nullptr)
1569 rtl_uString_new(pMethodDoku
);
1573 const sal_Char
* pTmp
= pEntry
->m_pMethods
->getMethodDoku(index
);
1575 pMethodDoku
, pTmp
, pTmp
== nullptr ? 0 : rtl_str_getLength(pTmp
),
1576 RTL_TEXTENCODING_UTF8
, OSTRING_TO_OUSTRING_CVTFLAGS
);
1579 sal_uInt16 TYPEREG_CALLTYPE
typereg_reader_getReferenceCount(void * hEntry
)
1581 TypeRegistryEntry
* pEntry
= static_cast<TypeRegistryEntry
*>(hEntry
);
1583 if (pEntry
== nullptr) return 0;
1585 return pEntry
->m_pReferences
->m_numOfEntries
;
1588 void TYPEREG_CALLTYPE
typereg_reader_getReferenceTypeName(void * hEntry
, rtl_uString
** pReferenceName
, sal_uInt16 index
)
1590 TypeRegistryEntry
* pEntry
= static_cast<TypeRegistryEntry
*>(hEntry
);
1592 if (pEntry
== nullptr)
1594 rtl_uString_new(pReferenceName
);
1598 const sal_Char
* pTmp
= pEntry
->m_pReferences
->getReferenceName(index
);
1600 pReferenceName
, pTmp
, pTmp
== nullptr ? 0 : rtl_str_getLength(pTmp
),
1601 RTL_TEXTENCODING_UTF8
, OSTRING_TO_OUSTRING_CVTFLAGS
);
1604 RTReferenceType TYPEREG_CALLTYPE
typereg_reader_getReferenceSort(void * hEntry
, sal_uInt16 index
)
1606 TypeRegistryEntry
* pEntry
= static_cast<TypeRegistryEntry
*>(hEntry
);
1608 if (pEntry
== nullptr) return RTReferenceType::INVALID
;
1610 return pEntry
->m_pReferences
->getReferenceType(index
);
1613 void TYPEREG_CALLTYPE
typereg_reader_getReferenceDocumentation(void * hEntry
, rtl_uString
** pReferenceDoku
, sal_uInt16 index
)
1615 TypeRegistryEntry
* pEntry
= static_cast<TypeRegistryEntry
*>(hEntry
);
1617 if (pEntry
== nullptr)
1619 rtl_uString_new(pReferenceDoku
);
1623 const sal_Char
* pTmp
= pEntry
->m_pReferences
->getReferenceDoku(index
);
1625 pReferenceDoku
, pTmp
, pTmp
== nullptr ? 0 : rtl_str_getLength(pTmp
),
1626 RTL_TEXTENCODING_UTF8
, OSTRING_TO_OUSTRING_CVTFLAGS
);
1629 RTFieldAccess TYPEREG_CALLTYPE
typereg_reader_getReferenceFlags(void * hEntry
, sal_uInt16 index
)
1631 TypeRegistryEntry
* pEntry
= static_cast<TypeRegistryEntry
*>(hEntry
);
1633 if (pEntry
== nullptr) return RTFieldAccess::INVALID
;
1635 return pEntry
->m_pReferences
->getReferenceAccess(index
);
1638 sal_uInt16 TYPEREG_CALLTYPE
typereg_reader_getSuperTypeCount(void * hEntry
)
1640 TypeRegistryEntry
* pEntry
= static_cast<TypeRegistryEntry
*>(hEntry
);
1642 if (pEntry
== nullptr) return 0;
1644 return pEntry
->m_nSuperTypes
;
1647 void TYPEREG_CALLTYPE
typereg_reader_getSuperTypeName(
1648 void * hEntry
, rtl_uString
** pSuperTypeName
, sal_uInt16 index
)
1650 TypeRegistryEntry
* pEntry
= static_cast<TypeRegistryEntry
*>(hEntry
);
1651 if (pEntry
!= nullptr) {
1653 OSL_ASSERT(index
< pEntry
->m_nSuperTypes
);
1654 const sal_Char
* pTmp
= pEntry
->m_pCP
->readUTF8NameConstant(pEntry
->readUINT16(pEntry
->m_offset_SUPERTYPES
+ (index
* sizeof(sal_uInt16
))));
1656 pSuperTypeName
, pTmp
, pTmp
== nullptr ? 0 : rtl_str_getLength(pTmp
),
1657 RTL_TEXTENCODING_UTF8
, OSTRING_TO_OUSTRING_CVTFLAGS
);
1659 } catch (BlopObject::BoundsError
&) {
1660 SAL_WARN("registry", "bad data");
1663 rtl_uString_new(pSuperTypeName
);
1666 RegistryTypeReader::RegistryTypeReader(const sal_uInt8
* buffer
,
1667 sal_uInt32 bufferLen
)
1670 m_hImpl
= createEntry(buffer
, bufferLen
);
1673 RegistryTypeReader::~RegistryTypeReader()
1674 { typereg_reader_release(m_hImpl
); }
1676 RTTypeClass
RegistryTypeReader::getTypeClass() const
1677 { return typereg_reader_getTypeClass(m_hImpl
); }
1679 OUString
RegistryTypeReader::getTypeName() const
1682 typereg_reader_getTypeName(m_hImpl
, &sRet
.pData
);
1686 OUString
RegistryTypeReader::getSuperTypeName() const
1689 ::getSuperTypeName(m_hImpl
, &sRet
.pData
);
1693 sal_uInt32
RegistryTypeReader::getFieldCount() const
1694 { return ::getFieldCount(m_hImpl
); }
1696 OUString
RegistryTypeReader::getFieldName( sal_uInt16 index
) const
1699 typereg_reader_getFieldName(m_hImpl
, &sRet
.pData
, index
);
1703 OUString
RegistryTypeReader::getFieldType( sal_uInt16 index
) const
1706 typereg_reader_getFieldTypeName(m_hImpl
, &sRet
.pData
, index
);
1710 RTFieldAccess
RegistryTypeReader::getFieldAccess( sal_uInt16 index
) const
1711 { return typereg_reader_getFieldFlags(m_hImpl
, index
); }
1713 RTConstValue
RegistryTypeReader::getFieldConstValue( sal_uInt16 index
) const
1716 ret
.m_type
= ::getFieldConstValue(m_hImpl
, index
, &ret
.m_value
);
1720 OUString
RegistryTypeReader::getFieldDoku( sal_uInt16 index
) const
1723 typereg_reader_getFieldDocumentation(m_hImpl
, &sRet
.pData
, index
);
1727 OUString
RegistryTypeReader::getFieldFileName( sal_uInt16 index
) const
1730 typereg_reader_getFieldFileName(m_hImpl
, &sRet
.pData
, index
);
1734 /* vim:set shiftwidth=4 softtabstop=4 expandtab: */