bump product version to 6.3.0.0.beta1
[LibreOffice.git] / registry / source / reflread.cxx
blobb799e8b30ef2660866de0bd8ec83ea38ff6df657
1 /* -*- Mode: C++; tab-width: 4; indent-tabs-mode: nil; c-basic-offset: 4 -*- */
2 /*
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>
22 #include <cstring>
23 #include <memory>
24 #include <new>
25 #include <vector>
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"
38 #include <cstddef>
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 /**************************************************************************
49 class BlopObject
51 holds any data in a flat memory buffer
53 **************************************************************************/
55 class BlopObject
57 public:
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) {
69 throw BoundsError();
71 return m_pBuffer[index];
74 sal_Int16 readINT16(sal_uInt32 index) const
76 if (m_bufferLen < 2 || index >= m_bufferLen - 1) {
77 throw BoundsError();
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) {
85 throw BoundsError();
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) {
93 throw BoundsError();
95 return (
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) {
106 throw BoundsError();
108 return (
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) {
119 throw BoundsError();
121 return (
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) {
136 throw BoundsError();
138 return (
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)
152 : m_bufferLen(len)
154 m_pBuffer = buffer;
157 /**************************************************************************
159 class StringCache
161 **************************************************************************/
163 class StringCache
165 public:
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)
177 , m_stringsCopied(0)
181 const sal_Unicode* StringCache::getString(sal_uInt16 index) const
183 if ((index > 0) && (index <= m_stringsCopied))
184 return m_stringTable[index - 1].get();
185 else
186 return nullptr;
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;
201 else
202 return 0;
205 /**************************************************************************
207 class ConstantPool
209 **************************************************************************/
211 class ConstantPool : public BlopObject
213 public:
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()
247 m_pIndex.reset();
248 m_pStringCache.reset();
250 sal_uInt32 offset = 0;
251 sal_uInt16 numOfStrings = 0;
253 if (m_numOfEntries)
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 )
266 numOfStrings++;
272 if (numOfStrings)
274 m_pStringCache.reset( new StringCache(numOfStrings) );
277 m_bufferLen = offset;
279 return 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));
291 return 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;
303 if (n < m_bufferLen
304 && std::memchr(m_pBuffer + n, 0, m_bufferLen - n) != nullptr)
306 aName = reinterpret_cast<const char*>(m_pBuffer + n);
311 return aName;
314 bool ConstantPool::readBOOLConstant(sal_uInt16 index) const
316 bool aBool = false;
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;
326 return aBool;
329 sal_Int8 ConstantPool::readBYTEConstant(sal_uInt16 index) const
331 sal_Int8 aByte = 0;
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));
342 return aByte;
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);
357 return aINT16;
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);
372 return asal_uInt16;
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);
387 return aINT32;
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);
402 return aUINT32;
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);
417 return aINT64;
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);
432 return aUINT64;
435 float ConstantPool::readFloatConstant(sal_uInt16 index) const
437 union
439 float v;
440 sal_uInt32 b;
441 } x = { 0.0f };
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);
449 #else
450 # error no IEEE
451 #endif
455 return x.v;
458 double ConstantPool::readDoubleConstant(sal_uInt16 index) const
460 union
462 double v;
463 struct
465 sal_uInt32 b1;
466 sal_uInt32 b2;
467 } b;
468 } x = { 0.0 };
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));
479 # else
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);
482 # endif
483 #else
484 # error no IEEE
485 #endif
489 return x.v;
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;
505 if (n >= m_bufferLen
506 || (std::memchr(m_pBuffer + n, 0, m_bufferLen - n)
507 == nullptr))
509 throw BoundsError();
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));
518 return aString;
521 /**************************************************************************
523 class FieldList
525 **************************************************************************/
527 class FieldList : public BlopObject
529 public:
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)
538 , m_pCP(pCP)
540 if ( m_numOfEntries > 0 )
542 sal_uInt16 numOfFieldEntries = readUINT16(0);
543 m_FIELD_ENTRY_SIZE = numOfFieldEntries * sizeof(sal_uInt16);
544 } else
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))
568 try {
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");
575 return aName;
578 const sal_Char* FieldList::getFieldType(sal_uInt16 index) const
580 const sal_Char* aName = nullptr;
582 if ((m_numOfEntries > 0) && (index <= m_numOfEntries))
584 try {
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");
591 return aName;
594 RTFieldAccess FieldList::getFieldAccess(sal_uInt16 index) const
596 RTFieldAccess aAccess = RTFieldAccess::INVALID;
598 if ((m_numOfEntries > 0) && (index <= m_numOfEntries))
600 try {
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");
607 return aAccess;
610 RTValueType FieldList::getFieldConstValue(sal_uInt16 index, RTConstValueUnion* value) const
612 RTValueType ret = RT_TYPE_NONE;
613 try {
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);
621 ret = RT_TYPE_BOOL;
622 break;
623 case CP_TAG_CONST_BYTE:
624 value->aByte = m_pCP->readBYTEConstant(cpIndex);
625 ret = RT_TYPE_BYTE;
626 break;
627 case CP_TAG_CONST_INT16:
628 value->aShort = m_pCP->readINT16Constant(cpIndex);
629 ret = RT_TYPE_INT16;
630 break;
631 case CP_TAG_CONST_UINT16:
632 value->aUShort = m_pCP->readUINT16Constant(cpIndex);
633 ret = RT_TYPE_UINT16;
634 break;
635 case CP_TAG_CONST_INT32:
636 value->aLong = m_pCP->readINT32Constant(cpIndex);
637 ret = RT_TYPE_INT32;
638 break;
639 case CP_TAG_CONST_UINT32:
640 value->aULong = m_pCP->readUINT32Constant(cpIndex);
641 ret = RT_TYPE_UINT32;
642 break;
643 case CP_TAG_CONST_INT64:
644 value->aHyper = m_pCP->readINT64Constant(cpIndex);
645 ret = RT_TYPE_INT64;
646 break;
647 case CP_TAG_CONST_UINT64:
648 value->aUHyper = m_pCP->readUINT64Constant(cpIndex);
649 ret = RT_TYPE_UINT64;
650 break;
651 case CP_TAG_CONST_FLOAT:
652 value->aFloat = m_pCP->readFloatConstant(cpIndex);
653 ret = RT_TYPE_FLOAT;
654 break;
655 case CP_TAG_CONST_DOUBLE:
656 value->aDouble = m_pCP->readDoubleConstant(cpIndex);
657 ret = RT_TYPE_DOUBLE;
658 break;
659 case CP_TAG_CONST_STRING:
660 value->aString = m_pCP->readStringConstant(cpIndex);
661 ret = RT_TYPE_STRING;
662 break;
663 default:
664 break;
667 } catch (BlopObject::BoundsError &) {
668 SAL_WARN("registry", "bad data");
670 return ret;
673 const sal_Char* FieldList::getFieldDoku(sal_uInt16 index) const
675 const sal_Char* aDoku = nullptr;
677 if ((m_numOfEntries > 0) && (index <= m_numOfEntries))
679 try {
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");
686 return aDoku;
689 const sal_Char* FieldList::getFieldFileName(sal_uInt16 index) const
691 const sal_Char* aFileName = nullptr;
693 if ((m_numOfEntries > 0) && (index <= m_numOfEntries))
695 try {
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");
702 return aFileName;
705 /**************************************************************************
707 class ReferenceList
709 **************************************************************************/
711 class ReferenceList : public BlopObject
713 public:
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)
722 , m_pCP(pCP)
724 if ( m_numOfEntries > 0 )
726 sal_uInt16 numOfReferenceEntries = readUINT16(0);
727 m_REFERENCE_ENTRY_SIZE = numOfReferenceEntries * sizeof(sal_uInt16);
728 } else
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))
747 try {
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");
754 return aName;
757 RTReferenceType ReferenceList::getReferenceType(sal_uInt16 index) const
759 RTReferenceType refType = RTReferenceType::INVALID;
761 if ((m_numOfEntries > 0) && (index <= m_numOfEntries))
763 try {
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");
770 return refType;
773 const sal_Char* ReferenceList::getReferenceDoku(sal_uInt16 index) const
775 const sal_Char* aDoku = nullptr;
777 if ((m_numOfEntries > 0) && (index <= m_numOfEntries))
779 try {
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");
786 return aDoku;
789 RTFieldAccess ReferenceList::getReferenceAccess(sal_uInt16 index) const
791 RTFieldAccess aAccess = RTFieldAccess::INVALID;
793 if ((m_numOfEntries > 0) && (index <= m_numOfEntries))
795 try {
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");
802 return aAccess;
805 /**************************************************************************
807 class MethodList
809 **************************************************************************/
811 class MethodList : public BlopObject
813 public:
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)
823 , m_pCP(pCP)
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);
830 } else
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;
849 private:
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()
860 m_pIndex.reset();
862 sal_uInt32 offset = 0;
864 if (m_numOfEntries)
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);
877 return 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))
886 try {
887 aName = m_pCP->readUTF8NameConstant(readUINT16(m_pIndex[index] + METHOD_OFFSET_NAME));
888 } catch (BlopObject::BoundsError &) {
889 SAL_WARN("registry", "bad data");
893 return aName;
896 sal_uInt16 MethodList::getMethodParamCount(sal_uInt16 index) const
898 sal_uInt16 aCount = 0;
900 if ((m_numOfEntries > 0) && (index <= m_numOfEntries))
902 try {
903 aCount = readUINT16(m_pIndex[index] + METHOD_OFFSET_PARAM_COUNT);
904 } catch (BlopObject::BoundsError &) {
905 SAL_WARN("registry", "bad data");
909 return aCount;
912 const sal_Char* MethodList::getMethodParamType(sal_uInt16 index, sal_uInt16 paramIndex) const
914 const sal_Char* aName = nullptr;
915 try {
916 if ((m_numOfEntries > 0) &&
917 (index <= m_numOfEntries) &&
918 (paramIndex <= readUINT16(m_pIndex[index] + METHOD_OFFSET_PARAM_COUNT)))
920 aName = m_pCP->readUTF8NameConstant(
921 readUINT16(
922 m_pIndex[index] +
923 calcMethodParamIndex(paramIndex) +
924 PARAM_OFFSET_TYPE));
926 } catch (BlopObject::BoundsError &) {
927 SAL_WARN("registry", "bad data");
929 return aName;
932 const sal_Char* MethodList::getMethodParamName(sal_uInt16 index, sal_uInt16 paramIndex) const
934 const sal_Char* aName = nullptr;
935 try {
936 if ((m_numOfEntries > 0) &&
937 (index <= m_numOfEntries) &&
938 (paramIndex <= readUINT16(m_pIndex[index] + METHOD_OFFSET_PARAM_COUNT)))
940 aName = m_pCP->readUTF8NameConstant(
941 readUINT16(
942 m_pIndex[index] +
943 calcMethodParamIndex(paramIndex) +
944 PARAM_OFFSET_NAME));
946 } catch (BlopObject::BoundsError &) {
947 SAL_WARN("registry", "bad data");
949 return aName;
952 RTParamMode MethodList::getMethodParamMode(sal_uInt16 index, sal_uInt16 paramIndex) const
954 RTParamMode aMode = RT_PARAM_INVALID;
955 try {
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(
961 m_pIndex[index] +
962 calcMethodParamIndex(paramIndex) +
963 PARAM_OFFSET_MODE));
965 } catch (BlopObject::BoundsError &) {
966 SAL_WARN("registry", "bad data");
968 return aMode;
971 #if defined(__COVERITY__)
972 extern "C" void __coverity_tainted_data_sanitize__(void *);
973 #endif
975 sal_uInt16 MethodList::getMethodExcCount(sal_uInt16 index) const
977 sal_uInt16 aCount = 0;
979 if ((m_numOfEntries > 0) && (index <= m_numOfEntries))
981 try {
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);
985 #endif
986 } catch (BlopObject::BoundsError &) {
987 SAL_WARN("registry", "bad data");
991 return aCount;
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))
1000 try {
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(
1005 readUINT16(
1006 excOffset +
1007 sizeof(sal_uInt16) +
1008 (excIndex * sizeof(sal_uInt16))));
1010 } catch (BlopObject::BoundsError &) {
1011 SAL_WARN("registry", "bad data");
1015 return aName;
1018 const sal_Char* MethodList::getMethodReturnType(sal_uInt16 index) const
1020 const sal_Char* aName = nullptr;
1022 if ((m_numOfEntries > 0) && (index <= m_numOfEntries))
1024 try {
1025 aName = m_pCP->readUTF8NameConstant(readUINT16(m_pIndex[index] + METHOD_OFFSET_RETURN));
1026 } catch (BlopObject::BoundsError &) {
1027 SAL_WARN("registry", "bad data");
1031 return aName;
1034 RTMethodMode MethodList::getMethodMode(sal_uInt16 index) const
1036 RTMethodMode aMode = RTMethodMode::INVALID;
1038 if ((m_numOfEntries > 0) && (index <= m_numOfEntries))
1040 try {
1041 aMode = static_cast<RTMethodMode>(readUINT16(m_pIndex[index] + METHOD_OFFSET_MODE));
1042 } catch (BlopObject::BoundsError &) {
1043 SAL_WARN("registry", "bad data");
1047 return aMode;
1050 const sal_Char* MethodList::getMethodDoku(sal_uInt16 index) const
1052 const sal_Char* aDoku = nullptr;
1054 if ((m_numOfEntries > 0) && (index <= m_numOfEntries))
1056 try {
1057 aDoku = m_pCP->readUTF8NameConstant(readUINT16(m_pIndex[index] + METHOD_OFFSET_DOKU));
1058 } catch (BlopObject::BoundsError &) {
1059 SAL_WARN("registry", "bad data");
1063 return aDoku;
1066 /**************************************************************************
1068 class TypeRegistryEntry
1070 **************************************************************************/
1072 class TypeRegistryEntry: public BlopObject {
1073 public:
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;
1082 TypeRegistryEntry(
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();
1106 m_pCP.reset(
1107 new ConstantPool(
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();
1117 m_pFields.reset(
1118 new FieldList(
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();
1128 m_pMethods.reset(
1129 new MethodList(
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(
1140 new ReferenceList(
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 /**************************************************************************
1152 C-API
1154 **************************************************************************/
1156 bool TYPEREG_CALLTYPE typereg_reader_create(
1157 void const * buffer, sal_uInt32 length,
1158 void ** result)
1160 if (length < OFFSET_CP || length > SAL_MAX_UINT32) {
1161 *result = nullptr;
1162 return true;
1164 std::unique_ptr< TypeRegistryEntry > entry;
1165 try {
1166 try {
1167 entry.reset(
1168 new TypeRegistryEntry(
1169 static_cast< sal_uInt8 const * >(buffer), length));
1170 } catch (std::bad_alloc &) {
1171 return false;
1173 if (entry->readUINT32(OFFSET_SIZE) != length) {
1174 *result = nullptr;
1175 return true;
1177 typereg_Version version = entry->getVersion();
1178 if (version < TYPEREG_VERSION_0 || version > TYPEREG_VERSION_1) {
1179 *result = nullptr;
1180 return true;
1182 *result = entry.release();
1183 return true;
1184 } catch (BlopObject::BoundsError &) {
1185 SAL_WARN("registry", "bad data");
1186 return false;
1190 static TypeReaderImpl TYPEREG_CALLTYPE createEntry(const sal_uInt8* buffer, sal_uInt32 len)
1192 void * handle;
1193 typereg_reader_create(buffer, len, &handle);
1194 return 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)
1212 delete pEntry;
1216 typereg_Version TYPEREG_CALLTYPE typereg_reader_getVersion(void const * handle) {
1217 if (handle != nullptr) {
1218 try {
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) {
1231 try {
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) {
1244 try {
1245 return (entry->readUINT16(OFFSET_TYPE_CLASS) & RT_TYPE_PUBLISHED) != 0;
1246 } catch (BlopObject::BoundsError &) {
1247 SAL_WARN("registry", "bad data");
1250 return false;
1253 void TYPEREG_CALLTYPE typereg_reader_getTypeName(void * hEntry, rtl_uString** pTypeName)
1255 TypeRegistryEntry* pEntry = static_cast<TypeRegistryEntry*>(hEntry);
1256 if (pEntry != nullptr) {
1257 try {
1258 const sal_Char* pTmp = pEntry->m_pCP->readUTF8NameConstant(pEntry->readUINT16(OFFSET_THIS_TYPE));
1259 rtl_string2UString(
1260 pTypeName, pTmp, pTmp == nullptr ? 0 : rtl_str_getLength(pTmp),
1261 RTL_TEXTENCODING_UTF8, OSTRING_TO_OUSTRING_CVTFLAGS);
1262 return;
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) {
1275 try {
1276 const sal_Char* pTmp = pEntry->m_pCP->readUTF8NameConstant(pEntry->readUINT16(pEntry->m_offset_SUPERTYPES )); //+ (index * sizeof(sal_uInt16))));
1277 rtl_string2UString(
1278 pSuperTypeName, pTmp, pTmp == nullptr ? 0 : rtl_str_getLength(pTmp),
1279 RTL_TEXTENCODING_UTF8, OSTRING_TO_OUSTRING_CVTFLAGS);
1280 return;
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) {
1292 try {
1293 const sal_Char* pTmp = pEntry->m_pCP->readUTF8NameConstant(pEntry->readUINT16(OFFSET_DOKU));
1294 rtl_string2UString(
1295 pDoku, pTmp, pTmp == nullptr ? 0 : rtl_str_getLength(pTmp),
1296 RTL_TEXTENCODING_UTF8, OSTRING_TO_OUSTRING_CVTFLAGS);
1297 return;
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) {
1309 try {
1310 const sal_Char* pTmp = pEntry->m_pCP->readUTF8NameConstant(pEntry->readUINT16(OFFSET_FILENAME));
1311 rtl_string2UString(
1312 pFileName, pTmp, pTmp == nullptr ? 0 : rtl_str_getLength(pTmp),
1313 RTL_TEXTENCODING_UTF8, OSTRING_TO_OUSTRING_CVTFLAGS);
1314 return;
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);
1344 return;
1346 const sal_Char* pTmp = pEntry->m_pFields->getFieldName(index);
1347 rtl_string2UString(
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);
1359 return;
1362 const sal_Char* pTmp = pEntry->m_pFields->getFieldType(index);
1363 rtl_string2UString(
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;
1385 return true;
1388 try {
1389 *type = pEntry->m_pFields->getFieldConstValue(index, value);
1390 } catch (std::bad_alloc &) {
1391 return false;
1393 return true;
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);
1400 return t;
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);
1410 return;
1413 const sal_Char* pTmp = pEntry->m_pFields->getFieldDoku(index);
1414 rtl_string2UString(
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);
1426 return;
1429 const sal_Char* pTmp = pEntry->m_pFields->getFieldFileName(index);
1430 rtl_string2UString(
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);
1452 return;
1455 const sal_Char* pTmp = pEntry->m_pMethods->getMethodName(index);
1456 rtl_string2UString(
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);
1478 return;
1481 const sal_Char* pTmp = pEntry->m_pMethods->getMethodParamType(index, paramIndex);
1482 rtl_string2UString(
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);
1494 return;
1497 const sal_Char* pTmp = pEntry->m_pMethods->getMethodParamName(index, paramIndex);
1498 rtl_string2UString(
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);
1529 return;
1532 const sal_Char* pTmp = pEntry->m_pMethods->getMethodExcType(index, excIndex);
1533 rtl_string2UString(
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);
1545 return;
1548 const sal_Char* pTmp = pEntry->m_pMethods->getMethodReturnType(index);
1549 rtl_string2UString(
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);
1570 return;
1573 const sal_Char* pTmp = pEntry->m_pMethods->getMethodDoku(index);
1574 rtl_string2UString(
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);
1595 return;
1598 const sal_Char* pTmp = pEntry->m_pReferences->getReferenceName(index);
1599 rtl_string2UString(
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);
1620 return;
1623 const sal_Char* pTmp = pEntry->m_pReferences->getReferenceDoku(index);
1624 rtl_string2UString(
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) {
1652 try {
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))));
1655 rtl_string2UString(
1656 pSuperTypeName, pTmp, pTmp == nullptr ? 0 : rtl_str_getLength(pTmp),
1657 RTL_TEXTENCODING_UTF8, OSTRING_TO_OUSTRING_CVTFLAGS);
1658 return;
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)
1668 : m_hImpl(nullptr)
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
1681 OUString sRet;
1682 typereg_reader_getTypeName(m_hImpl, &sRet.pData);
1683 return sRet;
1686 OUString RegistryTypeReader::getSuperTypeName() const
1688 OUString sRet;
1689 ::getSuperTypeName(m_hImpl, &sRet.pData);
1690 return sRet;
1693 sal_uInt32 RegistryTypeReader::getFieldCount() const
1694 { return ::getFieldCount(m_hImpl); }
1696 OUString RegistryTypeReader::getFieldName( sal_uInt16 index ) const
1698 OUString sRet;
1699 typereg_reader_getFieldName(m_hImpl, &sRet.pData, index);
1700 return sRet;
1703 OUString RegistryTypeReader::getFieldType( sal_uInt16 index ) const
1705 OUString sRet;
1706 typereg_reader_getFieldTypeName(m_hImpl, &sRet.pData, index);
1707 return sRet;
1710 RTFieldAccess RegistryTypeReader::getFieldAccess( sal_uInt16 index ) const
1711 { return typereg_reader_getFieldFlags(m_hImpl, index); }
1713 RTConstValue RegistryTypeReader::getFieldConstValue( sal_uInt16 index ) const
1715 RTConstValue ret;
1716 ret.m_type = ::getFieldConstValue(m_hImpl, index, &ret.m_value);
1717 return ret;
1720 OUString RegistryTypeReader::getFieldDoku( sal_uInt16 index ) const
1722 OUString sRet;
1723 typereg_reader_getFieldDocumentation(m_hImpl, &sRet.pData, index);
1724 return sRet;
1727 OUString RegistryTypeReader::getFieldFileName( sal_uInt16 index ) const
1729 OUString sRet;
1730 typereg_reader_getFieldFileName(m_hImpl, &sRet.pData, index);
1731 return sRet;
1734 /* vim:set shiftwidth=4 softtabstop=4 expandtab: */