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 const char NULL_STRING
[1] = { 0 };
41 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 **************************************************************************/
60 struct BoundsError
{};
62 const sal_uInt8
* m_pBuffer
;
63 sal_uInt32 m_bufferLen
;
65 BlopObject(const sal_uInt8
* buffer
, sal_uInt32 len
);
66 // throws std::bad_alloc
68 sal_uInt8
readBYTE(sal_uInt32 index
) const
70 if (index
>= m_bufferLen
) {
73 return m_pBuffer
[index
];
76 sal_Int16
readINT16(sal_uInt32 index
) const
78 if (m_bufferLen
< 2 || index
>= m_bufferLen
- 1) {
81 return ((m_pBuffer
[index
] << 8) | (m_pBuffer
[index
+1] << 0));
84 sal_uInt16
readUINT16(sal_uInt32 index
) const
86 if (m_bufferLen
< 2 || index
>= m_bufferLen
- 1) {
89 return ((m_pBuffer
[index
] << 8) | (m_pBuffer
[index
+1] << 0));
92 sal_Int32
readINT32(sal_uInt32 index
) const
94 if (m_bufferLen
< 4 || index
>= m_bufferLen
- 3) {
98 (m_pBuffer
[index
] << 24) |
99 (m_pBuffer
[index
+1] << 16) |
100 (m_pBuffer
[index
+2] << 8) |
101 (m_pBuffer
[index
+3] << 0)
105 sal_uInt32
readUINT32(sal_uInt32 index
) const
107 if (m_bufferLen
< 4 || index
>= m_bufferLen
- 3) {
111 (m_pBuffer
[index
] << 24) |
112 (m_pBuffer
[index
+1] << 16) |
113 (m_pBuffer
[index
+2] << 8) |
114 (m_pBuffer
[index
+3] << 0)
118 sal_Int64
readINT64(sal_uInt32 index
) const
120 if (m_bufferLen
< 8 || index
>= m_bufferLen
- 7) {
124 (static_cast<sal_Int64
>(m_pBuffer
[index
]) << 56) |
125 (static_cast<sal_Int64
>(m_pBuffer
[index
+1]) << 48) |
126 (static_cast<sal_Int64
>(m_pBuffer
[index
+2]) << 40) |
127 (static_cast<sal_Int64
>(m_pBuffer
[index
+3]) << 32) |
128 (static_cast<sal_Int64
>(m_pBuffer
[index
+4]) << 24) |
129 (static_cast<sal_Int64
>(m_pBuffer
[index
+5]) << 16) |
130 (static_cast<sal_Int64
>(m_pBuffer
[index
+6]) << 8) |
131 (static_cast<sal_Int64
>(m_pBuffer
[index
+7]) << 0)
135 sal_uInt64
readUINT64(sal_uInt32 index
) const
137 if (m_bufferLen
< 8 || index
>= m_bufferLen
- 7) {
141 (static_cast<sal_uInt64
>(m_pBuffer
[index
]) << 56) |
142 (static_cast<sal_uInt64
>(m_pBuffer
[index
+1]) << 48) |
143 (static_cast<sal_uInt64
>(m_pBuffer
[index
+2]) << 40) |
144 (static_cast<sal_uInt64
>(m_pBuffer
[index
+3]) << 32) |
145 (static_cast<sal_uInt64
>(m_pBuffer
[index
+4]) << 24) |
146 (static_cast<sal_uInt64
>(m_pBuffer
[index
+5]) << 16) |
147 (static_cast<sal_uInt64
>(m_pBuffer
[index
+6]) << 8) |
148 (static_cast<sal_uInt64
>(m_pBuffer
[index
+7]) << 0)
155 BlopObject::BlopObject(const sal_uInt8
* buffer
, sal_uInt32 len
)
161 /**************************************************************************
165 **************************************************************************/
172 std::vector
<std::unique_ptr
<sal_Unicode
[]>> m_stringTable
;
173 sal_uInt16 m_stringsCopied
;
175 explicit StringCache(sal_uInt16 size
); // throws std::bad_alloc
177 const sal_Unicode
* getString(sal_uInt16 index
) const;
178 sal_uInt16
createString(const sal_uInt8
* buffer
); // throws std::bad_alloc
183 StringCache::StringCache(sal_uInt16 size
)
184 : m_stringTable(size
)
189 const sal_Unicode
* StringCache::getString(sal_uInt16 index
) const
191 if ((index
> 0) && (index
<= m_stringsCopied
))
192 return m_stringTable
[index
- 1].get();
197 sal_uInt16
StringCache::createString(const sal_uInt8
* buffer
)
199 if (m_stringsCopied
< m_stringTable
.size())
201 sal_uInt32 len
= UINT16StringLen(buffer
);
203 m_stringTable
[m_stringsCopied
].reset( new sal_Unicode
[len
+ 1] );
205 readString(buffer
, m_stringTable
[m_stringsCopied
].get(), (len
+ 1) * sizeof(sal_Unicode
));
207 return ++m_stringsCopied
;
213 /**************************************************************************
217 **************************************************************************/
221 class ConstantPool
: public BlopObject
225 sal_uInt16 m_numOfEntries
;
226 std::unique_ptr
<sal_Int32
[]> m_pIndex
; // index values may be < 0 for cached string constants
228 std::unique_ptr
<StringCache
> m_pStringCache
;
230 ConstantPool(const sal_uInt8
* buffer
, sal_uInt32 len
, sal_uInt16 numEntries
)
231 : BlopObject(buffer
, len
)
232 , m_numOfEntries(numEntries
)
236 sal_uInt32
parseIndex(); // throws std::bad_alloc
238 CPInfoTag
readTag(sal_uInt16 index
) const;
240 const char* readUTF8NameConstant(sal_uInt16 index
) const;
241 bool readBOOLConstant(sal_uInt16 index
) const;
242 sal_Int8
readBYTEConstant(sal_uInt16 index
) const;
243 sal_Int16
readINT16Constant(sal_uInt16 index
) const;
244 sal_uInt16
readUINT16Constant(sal_uInt16 index
) const;
245 sal_Int32
readINT32Constant(sal_uInt16 index
) const;
246 sal_uInt32
readUINT32Constant(sal_uInt16 index
) const;
247 sal_Int64
readINT64Constant(sal_uInt16 index
) const;
248 sal_uInt64
readUINT64Constant(sal_uInt16 index
) const;
249 float readFloatConstant(sal_uInt16 index
) const;
250 double readDoubleConstant(sal_uInt16 index
) const;
251 const sal_Unicode
* readStringConstant(sal_uInt16 index
) const;
252 // throws std::bad_alloc
257 sal_uInt32
ConstantPool::parseIndex()
260 m_pStringCache
.reset();
262 sal_uInt32 offset
= 0;
263 sal_uInt16 numOfStrings
= 0;
267 m_pIndex
.reset( new sal_Int32
[m_numOfEntries
] );
269 for (int i
= 0; i
< m_numOfEntries
; i
++)
271 m_pIndex
[i
] = offset
;
273 offset
+= readUINT32(offset
);
275 if ( static_cast<CPInfoTag
>(readUINT16(m_pIndex
[i
] + CP_OFFSET_ENTRY_TAG
)) ==
276 CP_TAG_CONST_STRING
)
286 m_pStringCache
.reset( new StringCache(numOfStrings
) );
289 m_bufferLen
= offset
;
294 CPInfoTag
ConstantPool::readTag(sal_uInt16 index
) const
296 CPInfoTag tag
= CP_TAG_INVALID
;
298 if (m_pIndex
&& (index
> 0) && (index
<= m_numOfEntries
))
300 tag
= static_cast<CPInfoTag
>(readUINT16(m_pIndex
[index
- 1] + CP_OFFSET_ENTRY_TAG
));
306 const char* ConstantPool::readUTF8NameConstant(sal_uInt16 index
) const
308 const char* aName
= NULL_STRING
;
310 if (m_pIndex
&& (index
> 0) && (index
<= m_numOfEntries
))
312 if (readUINT16(m_pIndex
[index
- 1] + CP_OFFSET_ENTRY_TAG
) == CP_TAG_UTF8_NAME
)
314 sal_uInt32 n
= m_pIndex
[index
- 1] + CP_OFFSET_ENTRY_DATA
;
316 && std::memchr(m_pBuffer
+ n
, 0, m_bufferLen
- n
) != nullptr)
318 aName
= reinterpret_cast<const char*>(m_pBuffer
+ n
);
326 bool ConstantPool::readBOOLConstant(sal_uInt16 index
) const
330 if (m_pIndex
&& (index
> 0) && (index
<= m_numOfEntries
))
332 if (readUINT16(m_pIndex
[index
- 1] + CP_OFFSET_ENTRY_TAG
) == CP_TAG_CONST_BOOL
)
334 aBool
= readBYTE(m_pIndex
[index
- 1] + CP_OFFSET_ENTRY_DATA
) != 0;
341 sal_Int8
ConstantPool::readBYTEConstant(sal_uInt16 index
) const
345 if (m_pIndex
&& (index
> 0) && (index
<= m_numOfEntries
))
347 if (readUINT16(m_pIndex
[index
- 1] + CP_OFFSET_ENTRY_TAG
) == CP_TAG_CONST_BYTE
)
349 aByte
= static_cast< sal_Int8
>(
350 readBYTE(m_pIndex
[index
- 1] + CP_OFFSET_ENTRY_DATA
));
357 sal_Int16
ConstantPool::readINT16Constant(sal_uInt16 index
) const
359 sal_Int16 aINT16
= 0;
361 if (m_pIndex
&& (index
> 0) && (index
<= m_numOfEntries
))
363 if (readUINT16(m_pIndex
[index
- 1] + CP_OFFSET_ENTRY_TAG
) == CP_TAG_CONST_INT16
)
365 aINT16
= readINT16(m_pIndex
[index
- 1] + CP_OFFSET_ENTRY_DATA
);
372 sal_uInt16
ConstantPool::readUINT16Constant(sal_uInt16 index
) const
374 sal_uInt16 asal_uInt16
= 0;
376 if (m_pIndex
&& (index
> 0) && (index
<= m_numOfEntries
))
378 if (readUINT16(m_pIndex
[index
- 1] + CP_OFFSET_ENTRY_TAG
) == CP_TAG_CONST_UINT16
)
380 asal_uInt16
= readUINT16(m_pIndex
[index
- 1] + CP_OFFSET_ENTRY_DATA
);
387 sal_Int32
ConstantPool::readINT32Constant(sal_uInt16 index
) const
389 sal_Int32 aINT32
= 0;
391 if (m_pIndex
&& (index
> 0) && (index
<= m_numOfEntries
))
393 if (readUINT16(m_pIndex
[index
- 1] + CP_OFFSET_ENTRY_TAG
) == CP_TAG_CONST_INT32
)
395 aINT32
= readINT32(m_pIndex
[index
- 1] + CP_OFFSET_ENTRY_DATA
);
402 sal_uInt32
ConstantPool::readUINT32Constant(sal_uInt16 index
) const
404 sal_uInt32 aUINT32
= 0;
406 if (m_pIndex
&& (index
> 0) && (index
<= m_numOfEntries
))
408 if (readUINT16(m_pIndex
[index
- 1] + CP_OFFSET_ENTRY_TAG
) == CP_TAG_CONST_UINT32
)
410 aUINT32
= readUINT32(m_pIndex
[index
- 1] + CP_OFFSET_ENTRY_DATA
);
417 sal_Int64
ConstantPool::readINT64Constant(sal_uInt16 index
) const
419 sal_Int64 aINT64
= 0;
421 if (m_pIndex
&& (index
> 0) && (index
<= m_numOfEntries
))
423 if (readUINT16(m_pIndex
[index
- 1] + CP_OFFSET_ENTRY_TAG
) == CP_TAG_CONST_INT64
)
425 aINT64
= readINT64(m_pIndex
[index
- 1] + CP_OFFSET_ENTRY_DATA
);
432 sal_uInt64
ConstantPool::readUINT64Constant(sal_uInt16 index
) const
434 sal_uInt64 aUINT64
= 0;
436 if (m_pIndex
&& (index
> 0) && (index
<= m_numOfEntries
))
438 if (readUINT16(m_pIndex
[index
- 1] + CP_OFFSET_ENTRY_TAG
) == CP_TAG_CONST_UINT64
)
440 aUINT64
= readUINT64(m_pIndex
[index
- 1] + CP_OFFSET_ENTRY_DATA
);
447 float ConstantPool::readFloatConstant(sal_uInt16 index
) const
455 if (m_pIndex
&& (index
> 0) && (index
<= m_numOfEntries
))
457 if (readUINT16(m_pIndex
[index
- 1] + CP_OFFSET_ENTRY_TAG
) == CP_TAG_CONST_FLOAT
)
459 #ifdef REGTYPE_IEEE_NATIVE
460 x
.b
= readUINT32(m_pIndex
[index
- 1] + CP_OFFSET_ENTRY_DATA
);
470 double ConstantPool::readDoubleConstant(sal_uInt16 index
) const
482 if (m_pIndex
&& (index
> 0) && (index
<= m_numOfEntries
))
484 if (readUINT16(m_pIndex
[index
- 1] + CP_OFFSET_ENTRY_TAG
) == CP_TAG_CONST_DOUBLE
)
487 #ifdef REGTYPE_IEEE_NATIVE
488 # ifdef OSL_BIGENDIAN
489 x
.b
.b1
= readUINT32(m_pIndex
[index
- 1] + CP_OFFSET_ENTRY_DATA
);
490 x
.b
.b2
= readUINT32(m_pIndex
[index
- 1] + CP_OFFSET_ENTRY_DATA
+ sizeof(sal_uInt32
));
492 x
.b
.b1
= readUINT32(m_pIndex
[index
- 1] + CP_OFFSET_ENTRY_DATA
+ sizeof(sal_uInt32
));
493 x
.b
.b2
= readUINT32(m_pIndex
[index
- 1] + CP_OFFSET_ENTRY_DATA
);
504 const sal_Unicode
* ConstantPool::readStringConstant(sal_uInt16 index
) const
506 const sal_Unicode
* aString
= NULL_WSTRING
;
508 if (m_pIndex
&& (index
> 0) && (index
<= m_numOfEntries
) && m_pStringCache
)
510 if (m_pIndex
[index
- 1] >= 0)
512 // create cached string now
514 if (readUINT16(m_pIndex
[index
- 1] + CP_OFFSET_ENTRY_TAG
) == CP_TAG_CONST_STRING
)
516 sal_uInt32 n
= m_pIndex
[index
- 1] + CP_OFFSET_ENTRY_DATA
;
518 || (std::memchr(m_pBuffer
+ n
, 0, m_bufferLen
- n
)
523 m_pIndex
[index
- 1] = -1 * m_pStringCache
->createString(m_pBuffer
+ n
);
527 aString
= m_pStringCache
->getString(static_cast<sal_uInt16
>(m_pIndex
[index
- 1] * -1));
533 /**************************************************************************
537 **************************************************************************/
541 class FieldList
: public BlopObject
545 sal_uInt16 m_numOfEntries
;
546 size_t m_FIELD_ENTRY_SIZE
;
549 FieldList(const sal_uInt8
* buffer
, sal_uInt32 len
, sal_uInt16 numEntries
, ConstantPool
* pCP
)
550 : BlopObject(buffer
, len
)
551 , m_numOfEntries(numEntries
)
554 if ( m_numOfEntries
> 0 )
556 sal_uInt16 numOfFieldEntries
= readUINT16(0);
557 m_FIELD_ENTRY_SIZE
= numOfFieldEntries
* sizeof(sal_uInt16
);
560 m_FIELD_ENTRY_SIZE
= 0;
564 sal_uInt32
parseIndex() const { return ((m_numOfEntries
? sizeof(sal_uInt16
) : 0) + (m_numOfEntries
* m_FIELD_ENTRY_SIZE
));}
566 const char* getFieldName(sal_uInt16 index
) const;
567 const char* getFieldType(sal_uInt16 index
) const;
568 RTFieldAccess
getFieldAccess(sal_uInt16 index
) const;
569 RTValueType
getFieldConstValue(sal_uInt16 index
, RTConstValueUnion
* value
) const;
570 // throws std::bad_alloc
571 const char* getFieldDoku(sal_uInt16 index
) const;
572 const char* getFieldFileName(sal_uInt16 index
) const;
577 const char* FieldList::getFieldName(sal_uInt16 index
) const
579 const char* aName
= nullptr;
581 if ((m_numOfEntries
> 0) && (index
<= m_numOfEntries
))
584 aName
= m_pCP
->readUTF8NameConstant(readUINT16(sizeof(sal_uInt16
) + (index
* m_FIELD_ENTRY_SIZE
) + FIELD_OFFSET_NAME
));
585 } catch (BlopObject::BoundsError
&) {
586 SAL_WARN("registry", "bad data");
593 const char* FieldList::getFieldType(sal_uInt16 index
) const
595 const char* aName
= nullptr;
597 if ((m_numOfEntries
> 0) && (index
<= m_numOfEntries
))
600 aName
= m_pCP
->readUTF8NameConstant(readUINT16(sizeof(sal_uInt16
) + (index
* m_FIELD_ENTRY_SIZE
) + FIELD_OFFSET_TYPE
));
601 } catch (BlopObject::BoundsError
&) {
602 SAL_WARN("registry", "bad data");
609 RTFieldAccess
FieldList::getFieldAccess(sal_uInt16 index
) const
611 RTFieldAccess aAccess
= RTFieldAccess::INVALID
;
613 if ((m_numOfEntries
> 0) && (index
<= m_numOfEntries
))
616 aAccess
= static_cast<RTFieldAccess
>(readUINT16(sizeof(sal_uInt16
) + (index
* m_FIELD_ENTRY_SIZE
) + FIELD_OFFSET_ACCESS
));
617 } catch (BlopObject::BoundsError
&) {
618 SAL_WARN("registry", "bad data");
625 RTValueType
FieldList::getFieldConstValue(sal_uInt16 index
, RTConstValueUnion
* value
) const
627 RTValueType ret
= RT_TYPE_NONE
;
629 if ((m_numOfEntries
> 0) && (index
<= m_numOfEntries
))
631 sal_uInt16 cpIndex
= readUINT16(sizeof(sal_uInt16
) + (index
* m_FIELD_ENTRY_SIZE
) + FIELD_OFFSET_VALUE
);
632 switch (m_pCP
->readTag(cpIndex
))
634 case CP_TAG_CONST_BOOL
:
635 value
->aBool
= m_pCP
->readBOOLConstant(cpIndex
);
638 case CP_TAG_CONST_BYTE
:
639 value
->aByte
= m_pCP
->readBYTEConstant(cpIndex
);
642 case CP_TAG_CONST_INT16
:
643 value
->aShort
= m_pCP
->readINT16Constant(cpIndex
);
646 case CP_TAG_CONST_UINT16
:
647 value
->aUShort
= m_pCP
->readUINT16Constant(cpIndex
);
648 ret
= RT_TYPE_UINT16
;
650 case CP_TAG_CONST_INT32
:
651 value
->aLong
= m_pCP
->readINT32Constant(cpIndex
);
654 case CP_TAG_CONST_UINT32
:
655 value
->aULong
= m_pCP
->readUINT32Constant(cpIndex
);
656 ret
= RT_TYPE_UINT32
;
658 case CP_TAG_CONST_INT64
:
659 value
->aHyper
= m_pCP
->readINT64Constant(cpIndex
);
662 case CP_TAG_CONST_UINT64
:
663 value
->aUHyper
= m_pCP
->readUINT64Constant(cpIndex
);
664 ret
= RT_TYPE_UINT64
;
666 case CP_TAG_CONST_FLOAT
:
667 value
->aFloat
= m_pCP
->readFloatConstant(cpIndex
);
670 case CP_TAG_CONST_DOUBLE
:
671 value
->aDouble
= m_pCP
->readDoubleConstant(cpIndex
);
672 ret
= RT_TYPE_DOUBLE
;
674 case CP_TAG_CONST_STRING
:
675 value
->aString
= m_pCP
->readStringConstant(cpIndex
);
676 ret
= RT_TYPE_STRING
;
682 } catch (BlopObject::BoundsError
&) {
683 SAL_WARN("registry", "bad data");
688 const char* FieldList::getFieldDoku(sal_uInt16 index
) const
690 const char* aDoku
= nullptr;
692 if ((m_numOfEntries
> 0) && (index
<= m_numOfEntries
))
695 aDoku
= m_pCP
->readUTF8NameConstant(readUINT16(sizeof(sal_uInt16
) + (index
* m_FIELD_ENTRY_SIZE
) + FIELD_OFFSET_DOKU
));
696 } catch (BlopObject::BoundsError
&) {
697 SAL_WARN("registry", "bad data");
704 const char* FieldList::getFieldFileName(sal_uInt16 index
) const
706 const char* aFileName
= nullptr;
708 if ((m_numOfEntries
> 0) && (index
<= m_numOfEntries
))
711 aFileName
= m_pCP
->readUTF8NameConstant(readUINT16(sizeof(sal_uInt16
) + (index
* m_FIELD_ENTRY_SIZE
) + FIELD_OFFSET_FILENAME
));
712 } catch (BlopObject::BoundsError
&) {
713 SAL_WARN("registry", "bad data");
720 /**************************************************************************
724 **************************************************************************/
728 class ReferenceList
: public BlopObject
732 sal_uInt16 m_numOfEntries
;
733 size_t m_REFERENCE_ENTRY_SIZE
;
736 ReferenceList(const sal_uInt8
* buffer
, sal_uInt32 len
, sal_uInt16 numEntries
, ConstantPool
* pCP
)
737 : BlopObject(buffer
, len
)
738 , m_numOfEntries(numEntries
)
741 if ( m_numOfEntries
> 0 )
743 sal_uInt16 numOfReferenceEntries
= readUINT16(0);
744 m_REFERENCE_ENTRY_SIZE
= numOfReferenceEntries
* sizeof(sal_uInt16
);
747 m_REFERENCE_ENTRY_SIZE
= 0;
751 const char* getReferenceName(sal_uInt16 index
) const;
752 RTReferenceType
getReferenceType(sal_uInt16 index
) const;
753 const char* getReferenceDoku(sal_uInt16 index
) const;
754 RTFieldAccess
getReferenceAccess(sal_uInt16 index
) const;
759 const char* ReferenceList::getReferenceName(sal_uInt16 index
) const
761 const char* aName
= nullptr;
763 if ((m_numOfEntries
> 0) && (index
<= m_numOfEntries
))
766 aName
= m_pCP
->readUTF8NameConstant(readUINT16(sizeof(sal_uInt16
) + (index
* m_REFERENCE_ENTRY_SIZE
) + REFERENCE_OFFSET_NAME
));
767 } catch (BlopObject::BoundsError
&) {
768 SAL_WARN("registry", "bad data");
775 RTReferenceType
ReferenceList::getReferenceType(sal_uInt16 index
) const
777 RTReferenceType refType
= RTReferenceType::INVALID
;
779 if ((m_numOfEntries
> 0) && (index
<= m_numOfEntries
))
782 refType
= static_cast<RTReferenceType
>(readUINT16(sizeof(sal_uInt16
) + (index
* m_REFERENCE_ENTRY_SIZE
) + REFERENCE_OFFSET_TYPE
));
783 } catch (BlopObject::BoundsError
&) {
784 SAL_WARN("registry", "bad data");
791 const char* ReferenceList::getReferenceDoku(sal_uInt16 index
) const
793 const char* aDoku
= nullptr;
795 if ((m_numOfEntries
> 0) && (index
<= m_numOfEntries
))
798 aDoku
= m_pCP
->readUTF8NameConstant(readUINT16(sizeof(sal_uInt16
) + (index
* m_REFERENCE_ENTRY_SIZE
) + REFERENCE_OFFSET_DOKU
));
799 } catch (BlopObject::BoundsError
&) {
800 SAL_WARN("registry", "bad data");
807 RTFieldAccess
ReferenceList::getReferenceAccess(sal_uInt16 index
) const
809 RTFieldAccess aAccess
= RTFieldAccess::INVALID
;
811 if ((m_numOfEntries
> 0) && (index
<= m_numOfEntries
))
814 aAccess
= static_cast<RTFieldAccess
>(readUINT16(sizeof(sal_uInt16
) + (index
* m_REFERENCE_ENTRY_SIZE
) + REFERENCE_OFFSET_ACCESS
));
815 } catch (BlopObject::BoundsError
&) {
816 SAL_WARN("registry", "bad data");
823 /**************************************************************************
827 **************************************************************************/
831 class MethodList
: public BlopObject
835 sal_uInt16 m_numOfEntries
;
836 size_t m_PARAM_ENTRY_SIZE
;
837 std::unique_ptr
<sal_uInt32
[]> m_pIndex
;
840 MethodList(const sal_uInt8
* buffer
, sal_uInt32 len
, sal_uInt16 numEntries
, ConstantPool
* pCP
)
841 : BlopObject(buffer
, len
)
842 , m_numOfEntries(numEntries
)
845 if ( m_numOfEntries
> 0 )
847 readUINT16(0) /* numOfMethodEntries */;
848 sal_uInt16 numOfParamEntries
= readUINT16(sizeof(sal_uInt16
));
849 m_PARAM_ENTRY_SIZE
= numOfParamEntries
* sizeof(sal_uInt16
);
852 m_PARAM_ENTRY_SIZE
= 0;
856 sal_uInt32
parseIndex(); // throws std::bad_alloc
858 const char* getMethodName(sal_uInt16 index
) const;
859 sal_uInt16
getMethodParamCount(sal_uInt16 index
) const;
860 const char* getMethodParamType(sal_uInt16 index
, sal_uInt16 paramIndex
) const;
861 const char* getMethodParamName(sal_uInt16 index
, sal_uInt16 paramIndex
) const;
862 RTParamMode
getMethodParamMode(sal_uInt16 index
, sal_uInt16 paramIndex
) const;
863 sal_uInt16
getMethodExcCount(sal_uInt16 index
) const;
864 const char* getMethodExcType(sal_uInt16 index
, sal_uInt16 excIndex
) const;
865 const char* getMethodReturnType(sal_uInt16 index
) const;
866 RTMethodMode
getMethodMode(sal_uInt16 index
) const;
867 const char* getMethodDoku(sal_uInt16 index
) const;
870 sal_uInt16
calcMethodParamIndex( const sal_uInt16 index
) const;
875 sal_uInt16
MethodList::calcMethodParamIndex( const sal_uInt16 index
) const
877 return (METHOD_OFFSET_PARAM_COUNT
+ sizeof(sal_uInt16
) + (index
* m_PARAM_ENTRY_SIZE
));
880 sal_uInt32
MethodList::parseIndex()
884 sal_uInt32 offset
= 0;
888 offset
= 2 * sizeof(sal_uInt16
);
889 m_pIndex
.reset( new sal_uInt32
[m_numOfEntries
] );
891 for (int i
= 0; i
< m_numOfEntries
; i
++)
893 m_pIndex
[i
] = offset
;
895 offset
+= readUINT16(offset
);
902 const char* MethodList::getMethodName(sal_uInt16 index
) const
904 const char* aName
= nullptr;
906 if ((m_numOfEntries
> 0) && (index
<= m_numOfEntries
))
909 aName
= m_pCP
->readUTF8NameConstant(readUINT16(m_pIndex
[index
] + METHOD_OFFSET_NAME
));
910 } catch (BlopObject::BoundsError
&) {
911 SAL_WARN("registry", "bad data");
918 sal_uInt16
MethodList::getMethodParamCount(sal_uInt16 index
) const
920 sal_uInt16 aCount
= 0;
922 if ((m_numOfEntries
> 0) && (index
<= m_numOfEntries
))
925 aCount
= readUINT16(m_pIndex
[index
] + METHOD_OFFSET_PARAM_COUNT
);
926 } catch (BlopObject::BoundsError
&) {
927 SAL_WARN("registry", "bad data");
934 const char* MethodList::getMethodParamType(sal_uInt16 index
, sal_uInt16 paramIndex
) const
936 const char* aName
= nullptr;
938 if ((m_numOfEntries
> 0) &&
939 (index
<= m_numOfEntries
) &&
940 (paramIndex
<= readUINT16(m_pIndex
[index
] + METHOD_OFFSET_PARAM_COUNT
)))
942 aName
= m_pCP
->readUTF8NameConstant(
945 calcMethodParamIndex(paramIndex
) +
948 } catch (BlopObject::BoundsError
&) {
949 SAL_WARN("registry", "bad data");
954 const char* MethodList::getMethodParamName(sal_uInt16 index
, sal_uInt16 paramIndex
) const
956 const char* aName
= nullptr;
958 if ((m_numOfEntries
> 0) &&
959 (index
<= m_numOfEntries
) &&
960 (paramIndex
<= readUINT16(m_pIndex
[index
] + METHOD_OFFSET_PARAM_COUNT
)))
962 aName
= m_pCP
->readUTF8NameConstant(
965 calcMethodParamIndex(paramIndex
) +
968 } catch (BlopObject::BoundsError
&) {
969 SAL_WARN("registry", "bad data");
974 RTParamMode
MethodList::getMethodParamMode(sal_uInt16 index
, sal_uInt16 paramIndex
) const
976 RTParamMode aMode
= RT_PARAM_INVALID
;
978 if ((m_numOfEntries
> 0) &&
979 (index
<= m_numOfEntries
) &&
980 (paramIndex
<= readUINT16(m_pIndex
[index
] + METHOD_OFFSET_PARAM_COUNT
)))
982 aMode
= static_cast<RTParamMode
>(readUINT16(
984 calcMethodParamIndex(paramIndex
) +
987 } catch (BlopObject::BoundsError
&) {
988 SAL_WARN("registry", "bad data");
993 #if defined(__COVERITY__)
994 extern "C" void __coverity_tainted_data_sanitize__(void *);
997 sal_uInt16
MethodList::getMethodExcCount(sal_uInt16 index
) const
999 sal_uInt16 aCount
= 0;
1001 if ((m_numOfEntries
> 0) && (index
<= m_numOfEntries
))
1004 aCount
= readUINT16(m_pIndex
[index
] + calcMethodParamIndex(readUINT16(m_pIndex
[index
] + METHOD_OFFSET_PARAM_COUNT
)));
1005 #if defined(__COVERITY__)
1006 __coverity_tainted_data_sanitize__(&aCount
);
1008 } catch (BlopObject::BoundsError
&) {
1009 SAL_WARN("registry", "bad data");
1016 const char* MethodList::getMethodExcType(sal_uInt16 index
, sal_uInt16 excIndex
) const
1018 const char* aName
= nullptr;
1020 if ((m_numOfEntries
> 0) && (index
<= m_numOfEntries
))
1023 sal_uInt32 excOffset
= m_pIndex
[index
] + calcMethodParamIndex(readUINT16(m_pIndex
[index
] + METHOD_OFFSET_PARAM_COUNT
));
1024 if (excIndex
<= readUINT16(excOffset
))
1026 aName
= m_pCP
->readUTF8NameConstant(
1029 sizeof(sal_uInt16
) +
1030 (excIndex
* sizeof(sal_uInt16
))));
1032 } catch (BlopObject::BoundsError
&) {
1033 SAL_WARN("registry", "bad data");
1040 const char* MethodList::getMethodReturnType(sal_uInt16 index
) const
1042 const char* aName
= nullptr;
1044 if ((m_numOfEntries
> 0) && (index
<= m_numOfEntries
))
1047 aName
= m_pCP
->readUTF8NameConstant(readUINT16(m_pIndex
[index
] + METHOD_OFFSET_RETURN
));
1048 } catch (BlopObject::BoundsError
&) {
1049 SAL_WARN("registry", "bad data");
1056 RTMethodMode
MethodList::getMethodMode(sal_uInt16 index
) const
1058 RTMethodMode aMode
= RTMethodMode::INVALID
;
1060 if ((m_numOfEntries
> 0) && (index
<= m_numOfEntries
))
1063 aMode
= static_cast<RTMethodMode
>(readUINT16(m_pIndex
[index
] + METHOD_OFFSET_MODE
));
1064 } catch (BlopObject::BoundsError
&) {
1065 SAL_WARN("registry", "bad data");
1072 const char* MethodList::getMethodDoku(sal_uInt16 index
) const
1074 const char* aDoku
= nullptr;
1076 if ((m_numOfEntries
> 0) && (index
<= m_numOfEntries
))
1079 aDoku
= m_pCP
->readUTF8NameConstant(readUINT16(m_pIndex
[index
] + METHOD_OFFSET_DOKU
));
1080 } catch (BlopObject::BoundsError
&) {
1081 SAL_WARN("registry", "bad data");
1088 /**************************************************************************
1090 class TypeRegistryEntry
1092 **************************************************************************/
1096 class TypeRegistryEntry
: public BlopObject
{
1098 std::unique_ptr
<ConstantPool
> m_pCP
;
1099 std::unique_ptr
<FieldList
> m_pFields
;
1100 std::unique_ptr
<MethodList
> m_pMethods
;
1101 std::unique_ptr
<ReferenceList
> m_pReferences
;
1102 sal_uInt32 m_refCount
;
1103 sal_uInt16 m_nSuperTypes
;
1104 sal_uInt32 m_offset_SUPERTYPES
;
1107 const sal_uInt8
* buffer
, sal_uInt32 len
);
1108 // throws std::bad_alloc
1110 typereg_Version
getVersion() const;
1115 TypeRegistryEntry::TypeRegistryEntry(
1116 const sal_uInt8
* buffer
, sal_uInt32 len
):
1117 BlopObject(buffer
, len
), m_refCount(1), m_nSuperTypes(0),
1118 m_offset_SUPERTYPES(0)
1120 std::size_t const entrySize
= sizeof(sal_uInt16
);
1121 sal_uInt16 nHeaderEntries
= readUINT16(OFFSET_N_ENTRIES
);
1122 sal_uInt32 offset_N_SUPERTYPES
= OFFSET_N_ENTRIES
+ entrySize
+ (nHeaderEntries
* entrySize
); // cannot overflow
1123 m_offset_SUPERTYPES
= offset_N_SUPERTYPES
+ entrySize
; // cannot overflow
1124 m_nSuperTypes
= readUINT16(offset_N_SUPERTYPES
);
1126 sal_uInt32 offset_CP_SIZE
= m_offset_SUPERTYPES
+ (m_nSuperTypes
* entrySize
); // cannot overflow
1127 sal_uInt32 offset_CP
= offset_CP_SIZE
+ entrySize
; // cannot overflow
1129 if (offset_CP
> m_bufferLen
) {
1130 throw BoundsError();
1134 m_pBuffer
+ offset_CP
, m_bufferLen
- offset_CP
,
1135 readUINT16(offset_CP_SIZE
)));
1137 sal_uInt32 offset
= offset_CP
+ m_pCP
->parseIndex(); //TODO: overflow
1139 assert(m_bufferLen
>= entrySize
);
1140 if (offset
> m_bufferLen
- entrySize
) {
1141 throw BoundsError();
1145 m_pBuffer
+ offset
+ entrySize
, m_bufferLen
- (offset
+ entrySize
),
1146 readUINT16(offset
), m_pCP
.get()));
1148 offset
+= sizeof(sal_uInt16
) + m_pFields
->parseIndex(); //TODO: overflow
1150 assert(m_bufferLen
>= entrySize
);
1151 if (offset
> m_bufferLen
- entrySize
) {
1152 throw BoundsError();
1156 m_pBuffer
+ offset
+ entrySize
, m_bufferLen
- (offset
+ entrySize
),
1157 readUINT16(offset
), m_pCP
.get()));
1159 offset
+= sizeof(sal_uInt16
) + m_pMethods
->parseIndex(); //TODO: overflow
1161 assert(m_bufferLen
>= entrySize
);
1162 if (offset
> m_bufferLen
- entrySize
) {
1163 throw BoundsError();
1165 m_pReferences
.reset(
1167 m_pBuffer
+ offset
+ entrySize
, m_bufferLen
- (offset
+ entrySize
),
1168 readUINT16(offset
), m_pCP
.get()));
1171 typereg_Version
TypeRegistryEntry::getVersion() const {
1172 // Assumes two's complement arithmetic with modulo-semantics:
1173 return static_cast< typereg_Version
>(readUINT32(OFFSET_MAGIC
) - magic
);
1176 /**************************************************************************
1180 **************************************************************************/
1182 bool TYPEREG_CALLTYPE
typereg_reader_create(
1183 void const * buffer
, sal_uInt32 length
,
1186 if (length
< OFFSET_CP
|| length
> SAL_MAX_UINT32
) {
1190 std::unique_ptr
< TypeRegistryEntry
> entry
;
1194 new TypeRegistryEntry(
1195 static_cast< sal_uInt8
const * >(buffer
), length
));
1196 } catch (std::bad_alloc
&) {
1199 if (entry
->readUINT32(OFFSET_SIZE
) != length
) {
1203 typereg_Version version
= entry
->getVersion();
1204 if (version
< TYPEREG_VERSION_0
|| version
> TYPEREG_VERSION_1
) {
1208 *result
= entry
.release();
1210 } catch (BlopObject::BoundsError
&) {
1211 SAL_WARN("registry", "bad data");
1216 static TypeReaderImpl TYPEREG_CALLTYPE
createEntry(const sal_uInt8
* buffer
, sal_uInt32 len
)
1219 typereg_reader_create(buffer
, len
, &handle
);
1223 void TYPEREG_CALLTYPE
typereg_reader_acquire(void * hEntry
)
1225 TypeRegistryEntry
* pEntry
= static_cast<TypeRegistryEntry
*>(hEntry
);
1227 if (pEntry
!= nullptr)
1228 pEntry
->m_refCount
++;
1231 void TYPEREG_CALLTYPE
typereg_reader_release(void * hEntry
)
1233 TypeRegistryEntry
* pEntry
= static_cast<TypeRegistryEntry
*>(hEntry
);
1235 if (pEntry
!= nullptr)
1237 if (--pEntry
->m_refCount
== 0)
1242 typereg_Version TYPEREG_CALLTYPE
typereg_reader_getVersion(void const * handle
) {
1243 if (handle
!= nullptr) {
1245 return static_cast< TypeRegistryEntry
const * >(handle
)->getVersion();
1246 } catch (BlopObject::BoundsError
&) {
1247 SAL_WARN("registry", "bad data");
1250 return TYPEREG_VERSION_0
;
1253 RTTypeClass TYPEREG_CALLTYPE
typereg_reader_getTypeClass(void * hEntry
)
1255 TypeRegistryEntry
* pEntry
= static_cast<TypeRegistryEntry
*>(hEntry
);
1256 if (pEntry
!= nullptr) {
1258 return static_cast<RTTypeClass
>(pEntry
->readUINT16(OFFSET_TYPE_CLASS
) & ~RT_TYPE_PUBLISHED
);
1259 } catch (BlopObject::BoundsError
&) {
1260 SAL_WARN("registry", "bad data");
1263 return RT_TYPE_INVALID
;
1266 bool TYPEREG_CALLTYPE
typereg_reader_isPublished(void * hEntry
)
1268 TypeRegistryEntry
* entry
= static_cast< TypeRegistryEntry
* >(hEntry
);
1269 if (entry
!= nullptr) {
1271 return (entry
->readUINT16(OFFSET_TYPE_CLASS
) & RT_TYPE_PUBLISHED
) != 0;
1272 } catch (BlopObject::BoundsError
&) {
1273 SAL_WARN("registry", "bad data");
1279 void TYPEREG_CALLTYPE
typereg_reader_getTypeName(void * hEntry
, rtl_uString
** pTypeName
)
1281 TypeRegistryEntry
* pEntry
= static_cast<TypeRegistryEntry
*>(hEntry
);
1282 if (pEntry
!= nullptr) {
1284 const char* pTmp
= pEntry
->m_pCP
->readUTF8NameConstant(pEntry
->readUINT16(OFFSET_THIS_TYPE
));
1286 pTypeName
, pTmp
, pTmp
== nullptr ? 0 : rtl_str_getLength(pTmp
),
1287 RTL_TEXTENCODING_UTF8
, OSTRING_TO_OUSTRING_CVTFLAGS
);
1289 } catch (BlopObject::BoundsError
&) {
1290 SAL_WARN("registry", "bad data");
1293 rtl_uString_new(pTypeName
);
1297 static void TYPEREG_CALLTYPE
getSuperTypeName(TypeReaderImpl hEntry
, rtl_uString
** pSuperTypeName
)
1299 TypeRegistryEntry
* pEntry
= static_cast<TypeRegistryEntry
*>(hEntry
);
1300 if (pEntry
!= nullptr && pEntry
->m_nSuperTypes
!= 0) {
1302 const char* pTmp
= pEntry
->m_pCP
->readUTF8NameConstant(pEntry
->readUINT16(pEntry
->m_offset_SUPERTYPES
)); //+ (index * sizeof(sal_uInt16))));
1304 pSuperTypeName
, pTmp
, pTmp
== nullptr ? 0 : rtl_str_getLength(pTmp
),
1305 RTL_TEXTENCODING_UTF8
, OSTRING_TO_OUSTRING_CVTFLAGS
);
1307 } catch (BlopObject::BoundsError
&) {
1308 SAL_WARN("registry", "bad data");
1311 rtl_uString_new(pSuperTypeName
);
1314 void TYPEREG_CALLTYPE
typereg_reader_getDocumentation(void * hEntry
, rtl_uString
** pDoku
)
1316 TypeRegistryEntry
* pEntry
= static_cast<TypeRegistryEntry
*>(hEntry
);
1317 if (pEntry
!= nullptr) {
1319 const char* pTmp
= pEntry
->m_pCP
->readUTF8NameConstant(pEntry
->readUINT16(OFFSET_DOKU
));
1321 pDoku
, pTmp
, pTmp
== nullptr ? 0 : rtl_str_getLength(pTmp
),
1322 RTL_TEXTENCODING_UTF8
, OSTRING_TO_OUSTRING_CVTFLAGS
);
1324 } catch (BlopObject::BoundsError
&) {
1325 SAL_WARN("registry", "bad data");
1328 rtl_uString_new(pDoku
);
1331 void TYPEREG_CALLTYPE
typereg_reader_getFileName(void * hEntry
, rtl_uString
** pFileName
)
1333 TypeRegistryEntry
* pEntry
= static_cast<TypeRegistryEntry
*>(hEntry
);
1334 if (pEntry
!= nullptr) {
1336 const char* pTmp
= pEntry
->m_pCP
->readUTF8NameConstant(pEntry
->readUINT16(OFFSET_FILENAME
));
1338 pFileName
, pTmp
, pTmp
== nullptr ? 0 : rtl_str_getLength(pTmp
),
1339 RTL_TEXTENCODING_UTF8
, OSTRING_TO_OUSTRING_CVTFLAGS
);
1341 } catch (BlopObject::BoundsError
&) {
1342 SAL_WARN("registry", "bad data");
1345 rtl_uString_new(pFileName
);
1349 sal_uInt16 TYPEREG_CALLTYPE
typereg_reader_getFieldCount(void * hEntry
)
1351 TypeRegistryEntry
* pEntry
= static_cast<TypeRegistryEntry
*>(hEntry
);
1353 if (pEntry
== nullptr) return 0;
1355 return pEntry
->m_pFields
->m_numOfEntries
;
1358 static sal_uInt32 TYPEREG_CALLTYPE
getFieldCount(TypeReaderImpl hEntry
)
1360 return typereg_reader_getFieldCount(hEntry
);
1363 void TYPEREG_CALLTYPE
typereg_reader_getFieldName(void * hEntry
, rtl_uString
** pFieldName
, sal_uInt16 index
)
1365 TypeRegistryEntry
* pEntry
= static_cast<TypeRegistryEntry
*>(hEntry
);
1367 if (pEntry
== nullptr)
1369 rtl_uString_new(pFieldName
);
1372 const char* pTmp
= pEntry
->m_pFields
->getFieldName(index
);
1374 pFieldName
, pTmp
, pTmp
== nullptr ? 0 : rtl_str_getLength(pTmp
),
1375 RTL_TEXTENCODING_UTF8
, OSTRING_TO_OUSTRING_CVTFLAGS
);
1378 void TYPEREG_CALLTYPE
typereg_reader_getFieldTypeName(void * hEntry
, rtl_uString
** pFieldType
, sal_uInt16 index
)
1380 TypeRegistryEntry
* pEntry
= static_cast<TypeRegistryEntry
*>(hEntry
);
1382 if (pEntry
== nullptr)
1384 rtl_uString_new(pFieldType
);
1388 const char* pTmp
= pEntry
->m_pFields
->getFieldType(index
);
1390 pFieldType
, pTmp
, pTmp
== nullptr ? 0 : rtl_str_getLength(pTmp
),
1391 RTL_TEXTENCODING_UTF8
, OSTRING_TO_OUSTRING_CVTFLAGS
);
1394 RTFieldAccess TYPEREG_CALLTYPE
typereg_reader_getFieldFlags(void * hEntry
, sal_uInt16 index
)
1396 TypeRegistryEntry
* pEntry
= static_cast<TypeRegistryEntry
*>(hEntry
);
1398 if (pEntry
== nullptr) return RTFieldAccess::INVALID
;
1400 return pEntry
->m_pFields
->getFieldAccess(index
);
1403 bool TYPEREG_CALLTYPE
typereg_reader_getFieldValue(
1404 void * hEntry
, sal_uInt16 index
, RTValueType
* type
,
1405 RTConstValueUnion
* value
)
1407 TypeRegistryEntry
* pEntry
= static_cast<TypeRegistryEntry
*>(hEntry
);
1409 if (pEntry
== nullptr) {
1410 *type
= RT_TYPE_NONE
;
1415 *type
= pEntry
->m_pFields
->getFieldConstValue(index
, value
);
1416 } catch (std::bad_alloc
&) {
1422 static RTValueType TYPEREG_CALLTYPE
getFieldConstValue(TypeReaderImpl hEntry
, sal_uInt16 index
, RTConstValueUnion
* value
)
1424 RTValueType t
= RT_TYPE_NONE
;
1425 typereg_reader_getFieldValue(hEntry
, index
, &t
, value
);
1429 void TYPEREG_CALLTYPE
typereg_reader_getFieldDocumentation(void * hEntry
, rtl_uString
** pDoku
, sal_uInt16 index
)
1431 TypeRegistryEntry
* pEntry
= static_cast<TypeRegistryEntry
*>(hEntry
);
1433 if (pEntry
== nullptr)
1435 rtl_uString_new(pDoku
);
1439 const char* pTmp
= pEntry
->m_pFields
->getFieldDoku(index
);
1441 pDoku
, pTmp
, pTmp
== nullptr ? 0 : rtl_str_getLength(pTmp
),
1442 RTL_TEXTENCODING_UTF8
, OSTRING_TO_OUSTRING_CVTFLAGS
);
1445 void TYPEREG_CALLTYPE
typereg_reader_getFieldFileName(void * hEntry
, rtl_uString
** pFieldFileName
, sal_uInt16 index
)
1447 TypeRegistryEntry
* pEntry
= static_cast<TypeRegistryEntry
*>(hEntry
);
1449 if (pEntry
== nullptr)
1451 rtl_uString_new(pFieldFileName
);
1455 const char* pTmp
= pEntry
->m_pFields
->getFieldFileName(index
);
1457 pFieldFileName
, pTmp
, pTmp
== nullptr ? 0 : rtl_str_getLength(pTmp
),
1458 RTL_TEXTENCODING_UTF8
, OSTRING_TO_OUSTRING_CVTFLAGS
);
1462 sal_uInt16 TYPEREG_CALLTYPE
typereg_reader_getMethodCount(void * hEntry
)
1464 TypeRegistryEntry
* pEntry
= static_cast<TypeRegistryEntry
*>(hEntry
);
1466 if (pEntry
== nullptr) return 0;
1468 return pEntry
->m_pMethods
->m_numOfEntries
;
1471 void TYPEREG_CALLTYPE
typereg_reader_getMethodName(void * hEntry
, rtl_uString
** pMethodName
, sal_uInt16 index
)
1473 TypeRegistryEntry
* pEntry
= static_cast<TypeRegistryEntry
*>(hEntry
);
1475 if (pEntry
== nullptr)
1477 rtl_uString_new(pMethodName
);
1481 const char* pTmp
= pEntry
->m_pMethods
->getMethodName(index
);
1483 pMethodName
, pTmp
, pTmp
== nullptr ? 0 : rtl_str_getLength(pTmp
),
1484 RTL_TEXTENCODING_UTF8
, OSTRING_TO_OUSTRING_CVTFLAGS
);
1487 sal_uInt16 TYPEREG_CALLTYPE
typereg_reader_getMethodParameterCount(
1488 void * hEntry
, sal_uInt16 index
)
1490 TypeRegistryEntry
* pEntry
= static_cast<TypeRegistryEntry
*>(hEntry
);
1492 if (pEntry
== nullptr) return 0;
1494 return pEntry
->m_pMethods
->getMethodParamCount(index
);
1497 void TYPEREG_CALLTYPE
typereg_reader_getMethodParameterTypeName(void * hEntry
, rtl_uString
** pMethodParamType
, sal_uInt16 index
, sal_uInt16 paramIndex
)
1499 TypeRegistryEntry
* pEntry
= static_cast<TypeRegistryEntry
*>(hEntry
);
1501 if (pEntry
== nullptr)
1503 rtl_uString_new(pMethodParamType
);
1507 const char* pTmp
= pEntry
->m_pMethods
->getMethodParamType(index
, paramIndex
);
1509 pMethodParamType
, pTmp
, pTmp
== nullptr ? 0 : rtl_str_getLength(pTmp
),
1510 RTL_TEXTENCODING_UTF8
, OSTRING_TO_OUSTRING_CVTFLAGS
);
1513 void TYPEREG_CALLTYPE
typereg_reader_getMethodParameterName(void * hEntry
, rtl_uString
** pMethodParamName
, sal_uInt16 index
, sal_uInt16 paramIndex
)
1515 TypeRegistryEntry
* pEntry
= static_cast<TypeRegistryEntry
*>(hEntry
);
1517 if (pEntry
== nullptr)
1519 rtl_uString_new(pMethodParamName
);
1523 const char* pTmp
= pEntry
->m_pMethods
->getMethodParamName(index
, paramIndex
);
1525 pMethodParamName
, pTmp
, pTmp
== nullptr ? 0 : rtl_str_getLength(pTmp
),
1526 RTL_TEXTENCODING_UTF8
, OSTRING_TO_OUSTRING_CVTFLAGS
);
1529 RTParamMode TYPEREG_CALLTYPE
typereg_reader_getMethodParameterFlags(void * hEntry
, sal_uInt16 index
, sal_uInt16 paramIndex
)
1531 TypeRegistryEntry
* pEntry
= static_cast<TypeRegistryEntry
*>(hEntry
);
1533 if (pEntry
== nullptr) return RT_PARAM_INVALID
;
1535 return pEntry
->m_pMethods
->getMethodParamMode(index
, paramIndex
);
1538 sal_uInt16 TYPEREG_CALLTYPE
typereg_reader_getMethodExceptionCount(
1539 void * hEntry
, sal_uInt16 index
)
1541 TypeRegistryEntry
* pEntry
= static_cast<TypeRegistryEntry
*>(hEntry
);
1543 if (pEntry
== nullptr) return 0;
1545 return pEntry
->m_pMethods
->getMethodExcCount(index
);
1548 void TYPEREG_CALLTYPE
typereg_reader_getMethodExceptionTypeName(void * hEntry
, rtl_uString
** pMethodExcpType
, sal_uInt16 index
, sal_uInt16 excIndex
)
1550 TypeRegistryEntry
* pEntry
= static_cast<TypeRegistryEntry
*>(hEntry
);
1552 if (pEntry
== nullptr)
1554 rtl_uString_new(pMethodExcpType
);
1558 const char* pTmp
= pEntry
->m_pMethods
->getMethodExcType(index
, excIndex
);
1560 pMethodExcpType
, pTmp
, pTmp
== nullptr ? 0 : rtl_str_getLength(pTmp
),
1561 RTL_TEXTENCODING_UTF8
, OSTRING_TO_OUSTRING_CVTFLAGS
);
1564 void TYPEREG_CALLTYPE
typereg_reader_getMethodReturnTypeName(void * hEntry
, rtl_uString
** pMethodReturnType
, sal_uInt16 index
)
1566 TypeRegistryEntry
* pEntry
= static_cast<TypeRegistryEntry
*>(hEntry
);
1568 if (pEntry
== nullptr)
1570 rtl_uString_new(pMethodReturnType
);
1574 const char* pTmp
= pEntry
->m_pMethods
->getMethodReturnType(index
);
1576 pMethodReturnType
, pTmp
, pTmp
== nullptr ? 0 : rtl_str_getLength(pTmp
),
1577 RTL_TEXTENCODING_UTF8
, OSTRING_TO_OUSTRING_CVTFLAGS
);
1580 RTMethodMode TYPEREG_CALLTYPE
typereg_reader_getMethodFlags(void * hEntry
, sal_uInt16 index
)
1582 TypeRegistryEntry
* pEntry
= static_cast<TypeRegistryEntry
*>(hEntry
);
1584 if (pEntry
== nullptr) return RTMethodMode::INVALID
;
1586 return pEntry
->m_pMethods
->getMethodMode(index
);
1589 void TYPEREG_CALLTYPE
typereg_reader_getMethodDocumentation(void * hEntry
, rtl_uString
** pMethodDoku
, sal_uInt16 index
)
1591 TypeRegistryEntry
* pEntry
= static_cast<TypeRegistryEntry
*>(hEntry
);
1593 if (pEntry
== nullptr)
1595 rtl_uString_new(pMethodDoku
);
1599 const char* pTmp
= pEntry
->m_pMethods
->getMethodDoku(index
);
1601 pMethodDoku
, pTmp
, pTmp
== nullptr ? 0 : rtl_str_getLength(pTmp
),
1602 RTL_TEXTENCODING_UTF8
, OSTRING_TO_OUSTRING_CVTFLAGS
);
1605 sal_uInt16 TYPEREG_CALLTYPE
typereg_reader_getReferenceCount(void * hEntry
)
1607 TypeRegistryEntry
* pEntry
= static_cast<TypeRegistryEntry
*>(hEntry
);
1609 if (pEntry
== nullptr) return 0;
1611 return pEntry
->m_pReferences
->m_numOfEntries
;
1614 void TYPEREG_CALLTYPE
typereg_reader_getReferenceTypeName(void * hEntry
, rtl_uString
** pReferenceName
, sal_uInt16 index
)
1616 TypeRegistryEntry
* pEntry
= static_cast<TypeRegistryEntry
*>(hEntry
);
1618 if (pEntry
== nullptr)
1620 rtl_uString_new(pReferenceName
);
1624 const char* pTmp
= pEntry
->m_pReferences
->getReferenceName(index
);
1626 pReferenceName
, pTmp
, pTmp
== nullptr ? 0 : rtl_str_getLength(pTmp
),
1627 RTL_TEXTENCODING_UTF8
, OSTRING_TO_OUSTRING_CVTFLAGS
);
1630 RTReferenceType TYPEREG_CALLTYPE
typereg_reader_getReferenceSort(void * hEntry
, sal_uInt16 index
)
1632 TypeRegistryEntry
* pEntry
= static_cast<TypeRegistryEntry
*>(hEntry
);
1634 if (pEntry
== nullptr) return RTReferenceType::INVALID
;
1636 return pEntry
->m_pReferences
->getReferenceType(index
);
1639 void TYPEREG_CALLTYPE
typereg_reader_getReferenceDocumentation(void * hEntry
, rtl_uString
** pReferenceDoku
, sal_uInt16 index
)
1641 TypeRegistryEntry
* pEntry
= static_cast<TypeRegistryEntry
*>(hEntry
);
1643 if (pEntry
== nullptr)
1645 rtl_uString_new(pReferenceDoku
);
1649 const char* pTmp
= pEntry
->m_pReferences
->getReferenceDoku(index
);
1651 pReferenceDoku
, pTmp
, pTmp
== nullptr ? 0 : rtl_str_getLength(pTmp
),
1652 RTL_TEXTENCODING_UTF8
, OSTRING_TO_OUSTRING_CVTFLAGS
);
1655 RTFieldAccess TYPEREG_CALLTYPE
typereg_reader_getReferenceFlags(void * hEntry
, sal_uInt16 index
)
1657 TypeRegistryEntry
* pEntry
= static_cast<TypeRegistryEntry
*>(hEntry
);
1659 if (pEntry
== nullptr) return RTFieldAccess::INVALID
;
1661 return pEntry
->m_pReferences
->getReferenceAccess(index
);
1664 sal_uInt16 TYPEREG_CALLTYPE
typereg_reader_getSuperTypeCount(void * hEntry
)
1666 TypeRegistryEntry
* pEntry
= static_cast<TypeRegistryEntry
*>(hEntry
);
1668 if (pEntry
== nullptr) return 0;
1670 return pEntry
->m_nSuperTypes
;
1673 void TYPEREG_CALLTYPE
typereg_reader_getSuperTypeName(
1674 void * hEntry
, rtl_uString
** pSuperTypeName
, sal_uInt16 index
)
1676 TypeRegistryEntry
* pEntry
= static_cast<TypeRegistryEntry
*>(hEntry
);
1677 if (pEntry
!= nullptr) {
1679 OSL_ASSERT(index
< pEntry
->m_nSuperTypes
);
1680 const char* pTmp
= pEntry
->m_pCP
->readUTF8NameConstant(pEntry
->readUINT16(pEntry
->m_offset_SUPERTYPES
+ (index
* sizeof(sal_uInt16
))));
1682 pSuperTypeName
, pTmp
, pTmp
== nullptr ? 0 : rtl_str_getLength(pTmp
),
1683 RTL_TEXTENCODING_UTF8
, OSTRING_TO_OUSTRING_CVTFLAGS
);
1685 } catch (BlopObject::BoundsError
&) {
1686 SAL_WARN("registry", "bad data");
1689 rtl_uString_new(pSuperTypeName
);
1692 RegistryTypeReader::RegistryTypeReader(const sal_uInt8
* buffer
,
1693 sal_uInt32 bufferLen
)
1696 m_hImpl
= createEntry(buffer
, bufferLen
);
1699 RegistryTypeReader::~RegistryTypeReader()
1700 { typereg_reader_release(m_hImpl
); }
1702 RTTypeClass
RegistryTypeReader::getTypeClass() const
1703 { return typereg_reader_getTypeClass(m_hImpl
); }
1705 OUString
RegistryTypeReader::getTypeName() const
1708 typereg_reader_getTypeName(m_hImpl
, &sRet
.pData
);
1712 OUString
RegistryTypeReader::getSuperTypeName() const
1715 ::getSuperTypeName(m_hImpl
, &sRet
.pData
);
1719 sal_uInt32
RegistryTypeReader::getFieldCount() const
1720 { return ::getFieldCount(m_hImpl
); }
1722 OUString
RegistryTypeReader::getFieldName( sal_uInt16 index
) const
1725 typereg_reader_getFieldName(m_hImpl
, &sRet
.pData
, index
);
1729 OUString
RegistryTypeReader::getFieldType( sal_uInt16 index
) const
1732 typereg_reader_getFieldTypeName(m_hImpl
, &sRet
.pData
, index
);
1736 RTFieldAccess
RegistryTypeReader::getFieldAccess( sal_uInt16 index
) const
1737 { return typereg_reader_getFieldFlags(m_hImpl
, index
); }
1739 RTConstValue
RegistryTypeReader::getFieldConstValue( sal_uInt16 index
) const
1742 ret
.m_type
= ::getFieldConstValue(m_hImpl
, index
, &ret
.m_value
);
1746 OUString
RegistryTypeReader::getFieldDoku( sal_uInt16 index
) const
1749 typereg_reader_getFieldDocumentation(m_hImpl
, &sRet
.pData
, index
);
1753 OUString
RegistryTypeReader::getFieldFileName( sal_uInt16 index
) const
1756 typereg_reader_getFieldFileName(m_hImpl
, &sRet
.pData
, index
);
1760 /* vim:set shiftwidth=4 softtabstop=4 expandtab: */