nss: upgrade to release 3.73
[LibreOffice.git] / registry / source / reflread.cxx
blob57884e110075df30b9396c2fd9a89c94b7c6ab0a
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 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 /**************************************************************************
49 class BlopObject
51 holds any data in a flat memory buffer
53 **************************************************************************/
55 namespace {
57 class BlopObject
59 public:
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) {
71 throw BoundsError();
73 return m_pBuffer[index];
76 sal_Int16 readINT16(sal_uInt32 index) const
78 if (m_bufferLen < 2 || index >= m_bufferLen - 1) {
79 throw BoundsError();
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) {
87 throw BoundsError();
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) {
95 throw BoundsError();
97 return (
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) {
108 throw BoundsError();
110 return (
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) {
121 throw BoundsError();
123 return (
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) {
138 throw BoundsError();
140 return (
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)
156 : m_bufferLen(len)
158 m_pBuffer = buffer;
161 /**************************************************************************
163 class StringCache
165 **************************************************************************/
167 namespace {
169 class StringCache
171 public:
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)
185 , m_stringsCopied(0)
189 const sal_Unicode* StringCache::getString(sal_uInt16 index) const
191 if ((index > 0) && (index <= m_stringsCopied))
192 return m_stringTable[index - 1].get();
193 else
194 return nullptr;
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;
209 else
210 return 0;
213 /**************************************************************************
215 class ConstantPool
217 **************************************************************************/
219 namespace {
221 class ConstantPool : public BlopObject
223 public:
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()
259 m_pIndex.reset();
260 m_pStringCache.reset();
262 sal_uInt32 offset = 0;
263 sal_uInt16 numOfStrings = 0;
265 if (m_numOfEntries)
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 )
278 numOfStrings++;
284 if (numOfStrings)
286 m_pStringCache.reset( new StringCache(numOfStrings) );
289 m_bufferLen = offset;
291 return 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));
303 return 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;
315 if (n < m_bufferLen
316 && std::memchr(m_pBuffer + n, 0, m_bufferLen - n) != nullptr)
318 aName = reinterpret_cast<const char*>(m_pBuffer + n);
323 return aName;
326 bool ConstantPool::readBOOLConstant(sal_uInt16 index) const
328 bool aBool = false;
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;
338 return aBool;
341 sal_Int8 ConstantPool::readBYTEConstant(sal_uInt16 index) const
343 sal_Int8 aByte = 0;
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));
354 return aByte;
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);
369 return aINT16;
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);
384 return asal_uInt16;
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);
399 return aINT32;
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);
414 return aUINT32;
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);
429 return aINT64;
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);
444 return aUINT64;
447 float ConstantPool::readFloatConstant(sal_uInt16 index) const
449 union
451 float v;
452 sal_uInt32 b;
453 } x = { 0.0f };
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);
461 #else
462 # error no IEEE
463 #endif
467 return x.v;
470 double ConstantPool::readDoubleConstant(sal_uInt16 index) const
472 union
474 double v;
475 struct
477 sal_uInt32 b1;
478 sal_uInt32 b2;
479 } b;
480 } x = { 0.0 };
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));
491 # else
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);
494 # endif
495 #else
496 # error no IEEE
497 #endif
501 return x.v;
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;
517 if (n >= m_bufferLen
518 || (std::memchr(m_pBuffer + n, 0, m_bufferLen - n)
519 == nullptr))
521 throw BoundsError();
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));
530 return aString;
533 /**************************************************************************
535 class FieldList
537 **************************************************************************/
539 namespace {
541 class FieldList : public BlopObject
543 public:
545 sal_uInt16 m_numOfEntries;
546 size_t m_FIELD_ENTRY_SIZE;
547 ConstantPool* m_pCP;
549 FieldList(const sal_uInt8* buffer, sal_uInt32 len, sal_uInt16 numEntries, ConstantPool* pCP)
550 : BlopObject(buffer, len)
551 , m_numOfEntries(numEntries)
552 , m_pCP(pCP)
554 if ( m_numOfEntries > 0 )
556 sal_uInt16 numOfFieldEntries = readUINT16(0);
557 m_FIELD_ENTRY_SIZE = numOfFieldEntries * sizeof(sal_uInt16);
558 } else
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))
583 try {
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");
590 return aName;
593 const char* FieldList::getFieldType(sal_uInt16 index) const
595 const char* aName = nullptr;
597 if ((m_numOfEntries > 0) && (index <= m_numOfEntries))
599 try {
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");
606 return aName;
609 RTFieldAccess FieldList::getFieldAccess(sal_uInt16 index) const
611 RTFieldAccess aAccess = RTFieldAccess::INVALID;
613 if ((m_numOfEntries > 0) && (index <= m_numOfEntries))
615 try {
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");
622 return aAccess;
625 RTValueType FieldList::getFieldConstValue(sal_uInt16 index, RTConstValueUnion* value) const
627 RTValueType ret = RT_TYPE_NONE;
628 try {
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);
636 ret = RT_TYPE_BOOL;
637 break;
638 case CP_TAG_CONST_BYTE:
639 value->aByte = m_pCP->readBYTEConstant(cpIndex);
640 ret = RT_TYPE_BYTE;
641 break;
642 case CP_TAG_CONST_INT16:
643 value->aShort = m_pCP->readINT16Constant(cpIndex);
644 ret = RT_TYPE_INT16;
645 break;
646 case CP_TAG_CONST_UINT16:
647 value->aUShort = m_pCP->readUINT16Constant(cpIndex);
648 ret = RT_TYPE_UINT16;
649 break;
650 case CP_TAG_CONST_INT32:
651 value->aLong = m_pCP->readINT32Constant(cpIndex);
652 ret = RT_TYPE_INT32;
653 break;
654 case CP_TAG_CONST_UINT32:
655 value->aULong = m_pCP->readUINT32Constant(cpIndex);
656 ret = RT_TYPE_UINT32;
657 break;
658 case CP_TAG_CONST_INT64:
659 value->aHyper = m_pCP->readINT64Constant(cpIndex);
660 ret = RT_TYPE_INT64;
661 break;
662 case CP_TAG_CONST_UINT64:
663 value->aUHyper = m_pCP->readUINT64Constant(cpIndex);
664 ret = RT_TYPE_UINT64;
665 break;
666 case CP_TAG_CONST_FLOAT:
667 value->aFloat = m_pCP->readFloatConstant(cpIndex);
668 ret = RT_TYPE_FLOAT;
669 break;
670 case CP_TAG_CONST_DOUBLE:
671 value->aDouble = m_pCP->readDoubleConstant(cpIndex);
672 ret = RT_TYPE_DOUBLE;
673 break;
674 case CP_TAG_CONST_STRING:
675 value->aString = m_pCP->readStringConstant(cpIndex);
676 ret = RT_TYPE_STRING;
677 break;
678 default:
679 break;
682 } catch (BlopObject::BoundsError &) {
683 SAL_WARN("registry", "bad data");
685 return ret;
688 const char* FieldList::getFieldDoku(sal_uInt16 index) const
690 const char* aDoku = nullptr;
692 if ((m_numOfEntries > 0) && (index <= m_numOfEntries))
694 try {
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");
701 return aDoku;
704 const char* FieldList::getFieldFileName(sal_uInt16 index) const
706 const char* aFileName = nullptr;
708 if ((m_numOfEntries > 0) && (index <= m_numOfEntries))
710 try {
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");
717 return aFileName;
720 /**************************************************************************
722 class ReferenceList
724 **************************************************************************/
726 namespace {
728 class ReferenceList : public BlopObject
730 public:
732 sal_uInt16 m_numOfEntries;
733 size_t m_REFERENCE_ENTRY_SIZE;
734 ConstantPool* m_pCP;
736 ReferenceList(const sal_uInt8* buffer, sal_uInt32 len, sal_uInt16 numEntries, ConstantPool* pCP)
737 : BlopObject(buffer, len)
738 , m_numOfEntries(numEntries)
739 , m_pCP(pCP)
741 if ( m_numOfEntries > 0 )
743 sal_uInt16 numOfReferenceEntries = readUINT16(0);
744 m_REFERENCE_ENTRY_SIZE = numOfReferenceEntries * sizeof(sal_uInt16);
745 } else
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))
765 try {
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");
772 return aName;
775 RTReferenceType ReferenceList::getReferenceType(sal_uInt16 index) const
777 RTReferenceType refType = RTReferenceType::INVALID;
779 if ((m_numOfEntries > 0) && (index <= m_numOfEntries))
781 try {
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");
788 return refType;
791 const char* ReferenceList::getReferenceDoku(sal_uInt16 index) const
793 const char* aDoku = nullptr;
795 if ((m_numOfEntries > 0) && (index <= m_numOfEntries))
797 try {
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");
804 return aDoku;
807 RTFieldAccess ReferenceList::getReferenceAccess(sal_uInt16 index) const
809 RTFieldAccess aAccess = RTFieldAccess::INVALID;
811 if ((m_numOfEntries > 0) && (index <= m_numOfEntries))
813 try {
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");
820 return aAccess;
823 /**************************************************************************
825 class MethodList
827 **************************************************************************/
829 namespace {
831 class MethodList : public BlopObject
833 public:
835 sal_uInt16 m_numOfEntries;
836 size_t m_PARAM_ENTRY_SIZE;
837 std::unique_ptr<sal_uInt32[]> m_pIndex;
838 ConstantPool* m_pCP;
840 MethodList(const sal_uInt8* buffer, sal_uInt32 len, sal_uInt16 numEntries, ConstantPool* pCP)
841 : BlopObject(buffer, len)
842 , m_numOfEntries(numEntries)
843 , m_pCP(pCP)
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);
850 } else
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;
869 private:
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()
882 m_pIndex.reset();
884 sal_uInt32 offset = 0;
886 if (m_numOfEntries)
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);
899 return offset;
902 const char* MethodList::getMethodName(sal_uInt16 index) const
904 const char* aName = nullptr;
906 if ((m_numOfEntries > 0) && (index <= m_numOfEntries))
908 try {
909 aName = m_pCP->readUTF8NameConstant(readUINT16(m_pIndex[index] + METHOD_OFFSET_NAME));
910 } catch (BlopObject::BoundsError &) {
911 SAL_WARN("registry", "bad data");
915 return aName;
918 sal_uInt16 MethodList::getMethodParamCount(sal_uInt16 index) const
920 sal_uInt16 aCount = 0;
922 if ((m_numOfEntries > 0) && (index <= m_numOfEntries))
924 try {
925 aCount = readUINT16(m_pIndex[index] + METHOD_OFFSET_PARAM_COUNT);
926 } catch (BlopObject::BoundsError &) {
927 SAL_WARN("registry", "bad data");
931 return aCount;
934 const char* MethodList::getMethodParamType(sal_uInt16 index, sal_uInt16 paramIndex) const
936 const char* aName = nullptr;
937 try {
938 if ((m_numOfEntries > 0) &&
939 (index <= m_numOfEntries) &&
940 (paramIndex <= readUINT16(m_pIndex[index] + METHOD_OFFSET_PARAM_COUNT)))
942 aName = m_pCP->readUTF8NameConstant(
943 readUINT16(
944 m_pIndex[index] +
945 calcMethodParamIndex(paramIndex) +
946 PARAM_OFFSET_TYPE));
948 } catch (BlopObject::BoundsError &) {
949 SAL_WARN("registry", "bad data");
951 return aName;
954 const char* MethodList::getMethodParamName(sal_uInt16 index, sal_uInt16 paramIndex) const
956 const char* aName = nullptr;
957 try {
958 if ((m_numOfEntries > 0) &&
959 (index <= m_numOfEntries) &&
960 (paramIndex <= readUINT16(m_pIndex[index] + METHOD_OFFSET_PARAM_COUNT)))
962 aName = m_pCP->readUTF8NameConstant(
963 readUINT16(
964 m_pIndex[index] +
965 calcMethodParamIndex(paramIndex) +
966 PARAM_OFFSET_NAME));
968 } catch (BlopObject::BoundsError &) {
969 SAL_WARN("registry", "bad data");
971 return aName;
974 RTParamMode MethodList::getMethodParamMode(sal_uInt16 index, sal_uInt16 paramIndex) const
976 RTParamMode aMode = RT_PARAM_INVALID;
977 try {
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(
983 m_pIndex[index] +
984 calcMethodParamIndex(paramIndex) +
985 PARAM_OFFSET_MODE));
987 } catch (BlopObject::BoundsError &) {
988 SAL_WARN("registry", "bad data");
990 return aMode;
993 #if defined(__COVERITY__)
994 extern "C" void __coverity_tainted_data_sanitize__(void *);
995 #endif
997 sal_uInt16 MethodList::getMethodExcCount(sal_uInt16 index) const
999 sal_uInt16 aCount = 0;
1001 if ((m_numOfEntries > 0) && (index <= m_numOfEntries))
1003 try {
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);
1007 #endif
1008 } catch (BlopObject::BoundsError &) {
1009 SAL_WARN("registry", "bad data");
1013 return aCount;
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))
1022 try {
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(
1027 readUINT16(
1028 excOffset +
1029 sizeof(sal_uInt16) +
1030 (excIndex * sizeof(sal_uInt16))));
1032 } catch (BlopObject::BoundsError &) {
1033 SAL_WARN("registry", "bad data");
1037 return aName;
1040 const char* MethodList::getMethodReturnType(sal_uInt16 index) const
1042 const char* aName = nullptr;
1044 if ((m_numOfEntries > 0) && (index <= m_numOfEntries))
1046 try {
1047 aName = m_pCP->readUTF8NameConstant(readUINT16(m_pIndex[index] + METHOD_OFFSET_RETURN));
1048 } catch (BlopObject::BoundsError &) {
1049 SAL_WARN("registry", "bad data");
1053 return aName;
1056 RTMethodMode MethodList::getMethodMode(sal_uInt16 index) const
1058 RTMethodMode aMode = RTMethodMode::INVALID;
1060 if ((m_numOfEntries > 0) && (index <= m_numOfEntries))
1062 try {
1063 aMode = static_cast<RTMethodMode>(readUINT16(m_pIndex[index] + METHOD_OFFSET_MODE));
1064 } catch (BlopObject::BoundsError &) {
1065 SAL_WARN("registry", "bad data");
1069 return aMode;
1072 const char* MethodList::getMethodDoku(sal_uInt16 index) const
1074 const char* aDoku = nullptr;
1076 if ((m_numOfEntries > 0) && (index <= m_numOfEntries))
1078 try {
1079 aDoku = m_pCP->readUTF8NameConstant(readUINT16(m_pIndex[index] + METHOD_OFFSET_DOKU));
1080 } catch (BlopObject::BoundsError &) {
1081 SAL_WARN("registry", "bad data");
1085 return aDoku;
1088 /**************************************************************************
1090 class TypeRegistryEntry
1092 **************************************************************************/
1094 namespace {
1096 class TypeRegistryEntry: public BlopObject {
1097 public:
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;
1106 TypeRegistryEntry(
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();
1132 m_pCP.reset(
1133 new ConstantPool(
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();
1143 m_pFields.reset(
1144 new FieldList(
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();
1154 m_pMethods.reset(
1155 new MethodList(
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(
1166 new ReferenceList(
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 /**************************************************************************
1178 C-API
1180 **************************************************************************/
1182 bool TYPEREG_CALLTYPE typereg_reader_create(
1183 void const * buffer, sal_uInt32 length,
1184 void ** result)
1186 if (length < OFFSET_CP || length > SAL_MAX_UINT32) {
1187 *result = nullptr;
1188 return true;
1190 std::unique_ptr< TypeRegistryEntry > entry;
1191 try {
1192 try {
1193 entry.reset(
1194 new TypeRegistryEntry(
1195 static_cast< sal_uInt8 const * >(buffer), length));
1196 } catch (std::bad_alloc &) {
1197 return false;
1199 if (entry->readUINT32(OFFSET_SIZE) != length) {
1200 *result = nullptr;
1201 return true;
1203 typereg_Version version = entry->getVersion();
1204 if (version < TYPEREG_VERSION_0 || version > TYPEREG_VERSION_1) {
1205 *result = nullptr;
1206 return true;
1208 *result = entry.release();
1209 return true;
1210 } catch (BlopObject::BoundsError &) {
1211 SAL_WARN("registry", "bad data");
1212 return false;
1216 static TypeReaderImpl TYPEREG_CALLTYPE createEntry(const sal_uInt8* buffer, sal_uInt32 len)
1218 void * handle;
1219 typereg_reader_create(buffer, len, &handle);
1220 return 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)
1238 delete pEntry;
1242 typereg_Version TYPEREG_CALLTYPE typereg_reader_getVersion(void const * handle) {
1243 if (handle != nullptr) {
1244 try {
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) {
1257 try {
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) {
1270 try {
1271 return (entry->readUINT16(OFFSET_TYPE_CLASS) & RT_TYPE_PUBLISHED) != 0;
1272 } catch (BlopObject::BoundsError &) {
1273 SAL_WARN("registry", "bad data");
1276 return false;
1279 void TYPEREG_CALLTYPE typereg_reader_getTypeName(void * hEntry, rtl_uString** pTypeName)
1281 TypeRegistryEntry* pEntry = static_cast<TypeRegistryEntry*>(hEntry);
1282 if (pEntry != nullptr) {
1283 try {
1284 const char* pTmp = pEntry->m_pCP->readUTF8NameConstant(pEntry->readUINT16(OFFSET_THIS_TYPE));
1285 rtl_string2UString(
1286 pTypeName, pTmp, pTmp == nullptr ? 0 : rtl_str_getLength(pTmp),
1287 RTL_TEXTENCODING_UTF8, OSTRING_TO_OUSTRING_CVTFLAGS);
1288 return;
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) {
1301 try {
1302 const char* pTmp = pEntry->m_pCP->readUTF8NameConstant(pEntry->readUINT16(pEntry->m_offset_SUPERTYPES )); //+ (index * sizeof(sal_uInt16))));
1303 rtl_string2UString(
1304 pSuperTypeName, pTmp, pTmp == nullptr ? 0 : rtl_str_getLength(pTmp),
1305 RTL_TEXTENCODING_UTF8, OSTRING_TO_OUSTRING_CVTFLAGS);
1306 return;
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) {
1318 try {
1319 const char* pTmp = pEntry->m_pCP->readUTF8NameConstant(pEntry->readUINT16(OFFSET_DOKU));
1320 rtl_string2UString(
1321 pDoku, pTmp, pTmp == nullptr ? 0 : rtl_str_getLength(pTmp),
1322 RTL_TEXTENCODING_UTF8, OSTRING_TO_OUSTRING_CVTFLAGS);
1323 return;
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) {
1335 try {
1336 const char* pTmp = pEntry->m_pCP->readUTF8NameConstant(pEntry->readUINT16(OFFSET_FILENAME));
1337 rtl_string2UString(
1338 pFileName, pTmp, pTmp == nullptr ? 0 : rtl_str_getLength(pTmp),
1339 RTL_TEXTENCODING_UTF8, OSTRING_TO_OUSTRING_CVTFLAGS);
1340 return;
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);
1370 return;
1372 const char* pTmp = pEntry->m_pFields->getFieldName(index);
1373 rtl_string2UString(
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);
1385 return;
1388 const char* pTmp = pEntry->m_pFields->getFieldType(index);
1389 rtl_string2UString(
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;
1411 return true;
1414 try {
1415 *type = pEntry->m_pFields->getFieldConstValue(index, value);
1416 } catch (std::bad_alloc &) {
1417 return false;
1419 return true;
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);
1426 return t;
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);
1436 return;
1439 const char* pTmp = pEntry->m_pFields->getFieldDoku(index);
1440 rtl_string2UString(
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);
1452 return;
1455 const char* pTmp = pEntry->m_pFields->getFieldFileName(index);
1456 rtl_string2UString(
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);
1478 return;
1481 const char* pTmp = pEntry->m_pMethods->getMethodName(index);
1482 rtl_string2UString(
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);
1504 return;
1507 const char* pTmp = pEntry->m_pMethods->getMethodParamType(index, paramIndex);
1508 rtl_string2UString(
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);
1520 return;
1523 const char* pTmp = pEntry->m_pMethods->getMethodParamName(index, paramIndex);
1524 rtl_string2UString(
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);
1555 return;
1558 const char* pTmp = pEntry->m_pMethods->getMethodExcType(index, excIndex);
1559 rtl_string2UString(
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);
1571 return;
1574 const char* pTmp = pEntry->m_pMethods->getMethodReturnType(index);
1575 rtl_string2UString(
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);
1596 return;
1599 const char* pTmp = pEntry->m_pMethods->getMethodDoku(index);
1600 rtl_string2UString(
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);
1621 return;
1624 const char* pTmp = pEntry->m_pReferences->getReferenceName(index);
1625 rtl_string2UString(
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);
1646 return;
1649 const char* pTmp = pEntry->m_pReferences->getReferenceDoku(index);
1650 rtl_string2UString(
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) {
1678 try {
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))));
1681 rtl_string2UString(
1682 pSuperTypeName, pTmp, pTmp == nullptr ? 0 : rtl_str_getLength(pTmp),
1683 RTL_TEXTENCODING_UTF8, OSTRING_TO_OUSTRING_CVTFLAGS);
1684 return;
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)
1694 : m_hImpl(nullptr)
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
1707 OUString sRet;
1708 typereg_reader_getTypeName(m_hImpl, &sRet.pData);
1709 return sRet;
1712 OUString RegistryTypeReader::getSuperTypeName() const
1714 OUString sRet;
1715 ::getSuperTypeName(m_hImpl, &sRet.pData);
1716 return sRet;
1719 sal_uInt32 RegistryTypeReader::getFieldCount() const
1720 { return ::getFieldCount(m_hImpl); }
1722 OUString RegistryTypeReader::getFieldName( sal_uInt16 index ) const
1724 OUString sRet;
1725 typereg_reader_getFieldName(m_hImpl, &sRet.pData, index);
1726 return sRet;
1729 OUString RegistryTypeReader::getFieldType( sal_uInt16 index ) const
1731 OUString sRet;
1732 typereg_reader_getFieldTypeName(m_hImpl, &sRet.pData, index);
1733 return sRet;
1736 RTFieldAccess RegistryTypeReader::getFieldAccess( sal_uInt16 index ) const
1737 { return typereg_reader_getFieldFlags(m_hImpl, index); }
1739 RTConstValue RegistryTypeReader::getFieldConstValue( sal_uInt16 index ) const
1741 RTConstValue ret;
1742 ret.m_type = ::getFieldConstValue(m_hImpl, index, &ret.m_value);
1743 return ret;
1746 OUString RegistryTypeReader::getFieldDoku( sal_uInt16 index ) const
1748 OUString sRet;
1749 typereg_reader_getFieldDocumentation(m_hImpl, &sRet.pData, index);
1750 return sRet;
1753 OUString RegistryTypeReader::getFieldFileName( sal_uInt16 index ) const
1755 OUString sRet;
1756 typereg_reader_getFieldFileName(m_hImpl, &sRet.pData, index);
1757 return sRet;
1760 /* vim:set shiftwidth=4 softtabstop=4 expandtab: */