Version 7.6.3.2-android, tag libreoffice-7.6.3.2-android
[LibreOffice.git] / registry / source / reflread.cxx
blobfe223c7b46cbe4f07125853567560a93b1e29026
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 <sal/log.hxx>
32 #include <registry/refltype.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 namespace {
49 /**
50 Holds any data in a flat memory buffer
52 class BlopObject
54 public:
55 struct BoundsError {};
57 const sal_uInt8* m_pBuffer;
58 sal_uInt32 m_bufferLen;
60 BlopObject(const sal_uInt8* buffer, sal_uInt32 len);
61 // throws std::bad_alloc
63 sal_uInt8 readBYTE(sal_uInt32 index) const
65 if (index >= m_bufferLen) {
66 throw BoundsError();
68 return m_pBuffer[index];
71 sal_Int16 readINT16(sal_uInt32 index) const
73 if (m_bufferLen < 2 || index >= m_bufferLen - 1) {
74 throw BoundsError();
76 return ((m_pBuffer[index] << 8) | (m_pBuffer[index+1] << 0));
79 sal_uInt16 readUINT16(sal_uInt32 index) const
81 if (m_bufferLen < 2 || index >= m_bufferLen - 1) {
82 throw BoundsError();
84 return ((m_pBuffer[index] << 8) | (m_pBuffer[index+1] << 0));
87 sal_Int32 readINT32(sal_uInt32 index) const
89 if (m_bufferLen < 4 || index >= m_bufferLen - 3) {
90 throw BoundsError();
92 return (
93 (m_pBuffer[index] << 24) |
94 (m_pBuffer[index+1] << 16) |
95 (m_pBuffer[index+2] << 8) |
96 (m_pBuffer[index+3] << 0)
100 sal_uInt32 readUINT32(sal_uInt32 index) const
102 if (m_bufferLen < 4 || index >= m_bufferLen - 3) {
103 throw BoundsError();
105 return (
106 (m_pBuffer[index] << 24) |
107 (m_pBuffer[index+1] << 16) |
108 (m_pBuffer[index+2] << 8) |
109 (m_pBuffer[index+3] << 0)
113 sal_Int64 readINT64(sal_uInt32 index) const
115 if (m_bufferLen < 8 || index >= m_bufferLen - 7) {
116 throw BoundsError();
118 return (
119 (static_cast<sal_Int64>(m_pBuffer[index]) << 56) |
120 (static_cast<sal_Int64>(m_pBuffer[index+1]) << 48) |
121 (static_cast<sal_Int64>(m_pBuffer[index+2]) << 40) |
122 (static_cast<sal_Int64>(m_pBuffer[index+3]) << 32) |
123 (static_cast<sal_Int64>(m_pBuffer[index+4]) << 24) |
124 (static_cast<sal_Int64>(m_pBuffer[index+5]) << 16) |
125 (static_cast<sal_Int64>(m_pBuffer[index+6]) << 8) |
126 (static_cast<sal_Int64>(m_pBuffer[index+7]) << 0)
130 sal_uInt64 readUINT64(sal_uInt32 index) const
132 if (m_bufferLen < 8 || index >= m_bufferLen - 7) {
133 throw BoundsError();
135 return (
136 (static_cast<sal_uInt64>(m_pBuffer[index]) << 56) |
137 (static_cast<sal_uInt64>(m_pBuffer[index+1]) << 48) |
138 (static_cast<sal_uInt64>(m_pBuffer[index+2]) << 40) |
139 (static_cast<sal_uInt64>(m_pBuffer[index+3]) << 32) |
140 (static_cast<sal_uInt64>(m_pBuffer[index+4]) << 24) |
141 (static_cast<sal_uInt64>(m_pBuffer[index+5]) << 16) |
142 (static_cast<sal_uInt64>(m_pBuffer[index+6]) << 8) |
143 (static_cast<sal_uInt64>(m_pBuffer[index+7]) << 0)
150 BlopObject::BlopObject(const sal_uInt8* buffer, sal_uInt32 len)
151 : m_bufferLen(len)
153 m_pBuffer = buffer;
156 namespace {
158 class StringCache
160 public:
161 std::vector<std::unique_ptr<sal_Unicode[]>> m_stringTable;
162 sal_uInt16 m_stringsCopied;
164 explicit StringCache(sal_uInt16 size); // throws std::bad_alloc
166 const sal_Unicode* getString(sal_uInt16 index) const;
167 sal_uInt16 createString(const sal_uInt8* buffer); // throws std::bad_alloc
172 StringCache::StringCache(sal_uInt16 size)
173 : m_stringTable(size)
174 , m_stringsCopied(0)
178 const sal_Unicode* StringCache::getString(sal_uInt16 index) const
180 if ((index > 0) && (index <= m_stringsCopied))
181 return m_stringTable[index - 1].get();
182 else
183 return nullptr;
186 sal_uInt16 StringCache::createString(const sal_uInt8* buffer)
188 if (m_stringsCopied < m_stringTable.size())
190 sal_uInt32 len = UINT16StringLen(buffer);
192 m_stringTable[m_stringsCopied].reset( new sal_Unicode[len + 1] );
194 readString(buffer, m_stringTable[m_stringsCopied].get(), (len + 1) * sizeof(sal_Unicode));
196 return ++m_stringsCopied;
198 else
199 return 0;
202 namespace {
204 class ConstantPool : public BlopObject
206 public:
208 sal_uInt16 m_numOfEntries;
209 std::unique_ptr<sal_Int32[]> m_pIndex; // index values may be < 0 for cached string constants
211 std::unique_ptr<StringCache> m_pStringCache;
213 ConstantPool(const sal_uInt8* buffer, sal_uInt32 len, sal_uInt16 numEntries)
214 : BlopObject(buffer, len)
215 , m_numOfEntries(numEntries)
219 sal_uInt32 parseIndex(); // throws std::bad_alloc
221 CPInfoTag readTag(sal_uInt16 index) const;
223 const char* readUTF8NameConstant(sal_uInt16 index) const;
224 bool readBOOLConstant(sal_uInt16 index) const;
225 sal_Int8 readBYTEConstant(sal_uInt16 index) const;
226 sal_Int16 readINT16Constant(sal_uInt16 index) const;
227 sal_uInt16 readUINT16Constant(sal_uInt16 index) const;
228 sal_Int32 readINT32Constant(sal_uInt16 index) const;
229 sal_uInt32 readUINT32Constant(sal_uInt16 index) const;
230 sal_Int64 readINT64Constant(sal_uInt16 index) const;
231 sal_uInt64 readUINT64Constant(sal_uInt16 index) const;
232 float readFloatConstant(sal_uInt16 index) const;
233 double readDoubleConstant(sal_uInt16 index) const;
234 const sal_Unicode* readStringConstant(sal_uInt16 index) const;
235 // throws std::bad_alloc
240 sal_uInt32 ConstantPool::parseIndex()
242 m_pIndex.reset();
243 m_pStringCache.reset();
245 sal_uInt32 offset = 0;
246 sal_uInt16 numOfStrings = 0;
248 if (m_numOfEntries)
250 m_pIndex.reset( new sal_Int32[m_numOfEntries] );
252 for (int i = 0; i < m_numOfEntries; i++)
254 m_pIndex[i] = offset;
256 offset += readUINT32(offset);
258 if ( static_cast<CPInfoTag>(readUINT16(m_pIndex[i] + CP_OFFSET_ENTRY_TAG)) ==
259 CP_TAG_CONST_STRING )
261 numOfStrings++;
267 if (numOfStrings)
269 m_pStringCache.reset( new StringCache(numOfStrings) );
272 m_bufferLen = offset;
274 return offset;
277 CPInfoTag ConstantPool::readTag(sal_uInt16 index) const
279 CPInfoTag tag = CP_TAG_INVALID;
281 if (m_pIndex && (index > 0) && (index <= m_numOfEntries))
283 tag = static_cast<CPInfoTag>(readUINT16(m_pIndex[index - 1] + CP_OFFSET_ENTRY_TAG));
286 return tag;
289 const char* ConstantPool::readUTF8NameConstant(sal_uInt16 index) const
291 const char* aName = NULL_STRING;
293 if (m_pIndex && (index > 0) && (index <= m_numOfEntries))
295 if (readUINT16(m_pIndex[index - 1] + CP_OFFSET_ENTRY_TAG) == CP_TAG_UTF8_NAME)
297 sal_uInt32 n = m_pIndex[index - 1] + CP_OFFSET_ENTRY_DATA;
298 if (n < m_bufferLen
299 && std::memchr(m_pBuffer + n, 0, m_bufferLen - n) != nullptr)
301 aName = reinterpret_cast<const char*>(m_pBuffer + n);
306 return aName;
309 bool ConstantPool::readBOOLConstant(sal_uInt16 index) const
311 bool aBool = false;
313 if (m_pIndex && (index> 0) && (index <= m_numOfEntries))
315 if (readUINT16(m_pIndex[index - 1] + CP_OFFSET_ENTRY_TAG) == CP_TAG_CONST_BOOL)
317 aBool = readBYTE(m_pIndex[index - 1] + CP_OFFSET_ENTRY_DATA) != 0;
321 return aBool;
324 sal_Int8 ConstantPool::readBYTEConstant(sal_uInt16 index) const
326 sal_Int8 aByte = 0;
328 if (m_pIndex && (index> 0) && (index <= m_numOfEntries))
330 if (readUINT16(m_pIndex[index - 1] + CP_OFFSET_ENTRY_TAG) == CP_TAG_CONST_BYTE)
332 aByte = static_cast< sal_Int8 >(
333 readBYTE(m_pIndex[index - 1] + CP_OFFSET_ENTRY_DATA));
337 return aByte;
340 sal_Int16 ConstantPool::readINT16Constant(sal_uInt16 index) const
342 sal_Int16 aINT16 = 0;
344 if (m_pIndex && (index> 0) && (index <= m_numOfEntries))
346 if (readUINT16(m_pIndex[index - 1] + CP_OFFSET_ENTRY_TAG) == CP_TAG_CONST_INT16)
348 aINT16 = readINT16(m_pIndex[index - 1] + CP_OFFSET_ENTRY_DATA);
352 return aINT16;
355 sal_uInt16 ConstantPool::readUINT16Constant(sal_uInt16 index) const
357 sal_uInt16 asal_uInt16 = 0;
359 if (m_pIndex && (index> 0) && (index <= m_numOfEntries))
361 if (readUINT16(m_pIndex[index - 1] + CP_OFFSET_ENTRY_TAG) == CP_TAG_CONST_UINT16)
363 asal_uInt16 = readUINT16(m_pIndex[index - 1] + CP_OFFSET_ENTRY_DATA);
367 return asal_uInt16;
370 sal_Int32 ConstantPool::readINT32Constant(sal_uInt16 index) const
372 sal_Int32 aINT32 = 0;
374 if (m_pIndex && (index> 0) && (index <= m_numOfEntries))
376 if (readUINT16(m_pIndex[index - 1] + CP_OFFSET_ENTRY_TAG) == CP_TAG_CONST_INT32)
378 aINT32 = readINT32(m_pIndex[index - 1] + CP_OFFSET_ENTRY_DATA);
382 return aINT32;
385 sal_uInt32 ConstantPool::readUINT32Constant(sal_uInt16 index) const
387 sal_uInt32 aUINT32 = 0;
389 if (m_pIndex && (index> 0) && (index <= m_numOfEntries))
391 if (readUINT16(m_pIndex[index - 1] + CP_OFFSET_ENTRY_TAG) == CP_TAG_CONST_UINT32)
393 aUINT32 = readUINT32(m_pIndex[index - 1] + CP_OFFSET_ENTRY_DATA);
397 return aUINT32;
400 sal_Int64 ConstantPool::readINT64Constant(sal_uInt16 index) const
402 sal_Int64 aINT64 = 0;
404 if (m_pIndex && (index> 0) && (index <= m_numOfEntries))
406 if (readUINT16(m_pIndex[index - 1] + CP_OFFSET_ENTRY_TAG) == CP_TAG_CONST_INT64)
408 aINT64 = readINT64(m_pIndex[index - 1] + CP_OFFSET_ENTRY_DATA);
412 return aINT64;
415 sal_uInt64 ConstantPool::readUINT64Constant(sal_uInt16 index) const
417 sal_uInt64 aUINT64 = 0;
419 if (m_pIndex && (index> 0) && (index <= m_numOfEntries))
421 if (readUINT16(m_pIndex[index - 1] + CP_OFFSET_ENTRY_TAG) == CP_TAG_CONST_UINT64)
423 aUINT64 = readUINT64(m_pIndex[index - 1] + CP_OFFSET_ENTRY_DATA);
427 return aUINT64;
430 float ConstantPool::readFloatConstant(sal_uInt16 index) const
432 union
434 float v;
435 sal_uInt32 b;
436 } x = { 0.0f };
438 if (m_pIndex && (index> 0) && (index <= m_numOfEntries))
440 if (readUINT16(m_pIndex[index - 1] + CP_OFFSET_ENTRY_TAG) == CP_TAG_CONST_FLOAT)
442 #ifdef REGTYPE_IEEE_NATIVE
443 x.b = readUINT32(m_pIndex[index - 1] + CP_OFFSET_ENTRY_DATA);
444 #else
445 # error no IEEE
446 #endif
450 return x.v;
453 double ConstantPool::readDoubleConstant(sal_uInt16 index) const
455 union
457 double v;
458 struct
460 sal_uInt32 b1;
461 sal_uInt32 b2;
462 } b;
463 } x = { 0.0 };
465 if (m_pIndex && (index> 0) && (index <= m_numOfEntries))
467 if (readUINT16(m_pIndex[index - 1] + CP_OFFSET_ENTRY_TAG) == CP_TAG_CONST_DOUBLE)
470 #ifdef REGTYPE_IEEE_NATIVE
471 # ifdef OSL_BIGENDIAN
472 x.b.b1 = readUINT32(m_pIndex[index - 1] + CP_OFFSET_ENTRY_DATA);
473 x.b.b2 = readUINT32(m_pIndex[index - 1] + CP_OFFSET_ENTRY_DATA + sizeof(sal_uInt32));
474 # else
475 x.b.b1 = readUINT32(m_pIndex[index - 1] + CP_OFFSET_ENTRY_DATA + sizeof(sal_uInt32));
476 x.b.b2 = readUINT32(m_pIndex[index - 1] + CP_OFFSET_ENTRY_DATA);
477 # endif
478 #else
479 # error no IEEE
480 #endif
484 return x.v;
487 const sal_Unicode* ConstantPool::readStringConstant(sal_uInt16 index) const
489 const sal_Unicode* aString = NULL_WSTRING;
491 if (m_pIndex && (index> 0) && (index <= m_numOfEntries) && m_pStringCache)
493 if (m_pIndex[index - 1] >= 0)
495 // create cached string now
497 if (readUINT16(m_pIndex[index - 1] + CP_OFFSET_ENTRY_TAG) == CP_TAG_CONST_STRING)
499 sal_uInt32 n = m_pIndex[index - 1] + CP_OFFSET_ENTRY_DATA;
500 if (n >= m_bufferLen
501 || (std::memchr(m_pBuffer + n, 0, m_bufferLen - n)
502 == nullptr))
504 throw BoundsError();
506 m_pIndex[index - 1] = -1 * m_pStringCache->createString(m_pBuffer + n);
510 aString = m_pStringCache->getString(static_cast<sal_uInt16>(m_pIndex[index - 1] * -1));
513 return aString;
516 namespace {
518 class FieldList : public BlopObject
520 public:
522 sal_uInt16 m_numOfEntries;
523 size_t m_FIELD_ENTRY_SIZE;
524 ConstantPool* m_pCP;
526 FieldList(const sal_uInt8* buffer, sal_uInt32 len, sal_uInt16 numEntries, ConstantPool* pCP)
527 : BlopObject(buffer, len)
528 , m_numOfEntries(numEntries)
529 , m_pCP(pCP)
531 if ( m_numOfEntries > 0 )
533 sal_uInt16 numOfFieldEntries = readUINT16(0);
534 m_FIELD_ENTRY_SIZE = numOfFieldEntries * sizeof(sal_uInt16);
535 } else
537 m_FIELD_ENTRY_SIZE = 0;
541 sal_uInt32 parseIndex() const { return ((m_numOfEntries ? sizeof(sal_uInt16) : 0) + (m_numOfEntries * m_FIELD_ENTRY_SIZE));}
543 const char* getFieldName(sal_uInt16 index) const;
544 const char* getFieldType(sal_uInt16 index) const;
545 RTFieldAccess getFieldAccess(sal_uInt16 index) const;
546 RTValueType getFieldConstValue(sal_uInt16 index, RTConstValueUnion* value) const;
547 // throws std::bad_alloc
548 const char* getFieldDoku(sal_uInt16 index) const;
549 const char* getFieldFileName(sal_uInt16 index) const;
554 const char* FieldList::getFieldName(sal_uInt16 index) const
556 const char* aName = nullptr;
558 if ((m_numOfEntries > 0) && (index <= m_numOfEntries))
560 try {
561 aName = m_pCP->readUTF8NameConstant(readUINT16(sizeof(sal_uInt16) + (index * m_FIELD_ENTRY_SIZE) + FIELD_OFFSET_NAME));
562 } catch (BlopObject::BoundsError &) {
563 SAL_WARN("registry", "bad data");
567 return aName;
570 const char* FieldList::getFieldType(sal_uInt16 index) const
572 const char* aName = nullptr;
574 if ((m_numOfEntries > 0) && (index <= m_numOfEntries))
576 try {
577 aName = m_pCP->readUTF8NameConstant(readUINT16(sizeof(sal_uInt16) + (index * m_FIELD_ENTRY_SIZE) + FIELD_OFFSET_TYPE));
578 } catch (BlopObject::BoundsError &) {
579 SAL_WARN("registry", "bad data");
583 return aName;
586 RTFieldAccess FieldList::getFieldAccess(sal_uInt16 index) const
588 RTFieldAccess aAccess = RTFieldAccess::INVALID;
590 if ((m_numOfEntries > 0) && (index <= m_numOfEntries))
592 try {
593 aAccess = static_cast<RTFieldAccess>(readUINT16(sizeof(sal_uInt16) + (index * m_FIELD_ENTRY_SIZE) + FIELD_OFFSET_ACCESS));
594 } catch (BlopObject::BoundsError &) {
595 SAL_WARN("registry", "bad data");
599 return aAccess;
602 RTValueType FieldList::getFieldConstValue(sal_uInt16 index, RTConstValueUnion* value) const
604 RTValueType ret = RT_TYPE_NONE;
605 try {
606 if ((m_numOfEntries > 0) && (index <= m_numOfEntries))
608 sal_uInt16 cpIndex = readUINT16(sizeof(sal_uInt16) + (index * m_FIELD_ENTRY_SIZE) + FIELD_OFFSET_VALUE);
609 switch (m_pCP->readTag(cpIndex))
611 case CP_TAG_CONST_BOOL:
612 value->aBool = m_pCP->readBOOLConstant(cpIndex);
613 ret = RT_TYPE_BOOL;
614 break;
615 case CP_TAG_CONST_BYTE:
616 value->aByte = m_pCP->readBYTEConstant(cpIndex);
617 ret = RT_TYPE_BYTE;
618 break;
619 case CP_TAG_CONST_INT16:
620 value->aShort = m_pCP->readINT16Constant(cpIndex);
621 ret = RT_TYPE_INT16;
622 break;
623 case CP_TAG_CONST_UINT16:
624 value->aUShort = m_pCP->readUINT16Constant(cpIndex);
625 ret = RT_TYPE_UINT16;
626 break;
627 case CP_TAG_CONST_INT32:
628 value->aLong = m_pCP->readINT32Constant(cpIndex);
629 ret = RT_TYPE_INT32;
630 break;
631 case CP_TAG_CONST_UINT32:
632 value->aULong = m_pCP->readUINT32Constant(cpIndex);
633 ret = RT_TYPE_UINT32;
634 break;
635 case CP_TAG_CONST_INT64:
636 value->aHyper = m_pCP->readINT64Constant(cpIndex);
637 ret = RT_TYPE_INT64;
638 break;
639 case CP_TAG_CONST_UINT64:
640 value->aUHyper = m_pCP->readUINT64Constant(cpIndex);
641 ret = RT_TYPE_UINT64;
642 break;
643 case CP_TAG_CONST_FLOAT:
644 value->aFloat = m_pCP->readFloatConstant(cpIndex);
645 ret = RT_TYPE_FLOAT;
646 break;
647 case CP_TAG_CONST_DOUBLE:
648 value->aDouble = m_pCP->readDoubleConstant(cpIndex);
649 ret = RT_TYPE_DOUBLE;
650 break;
651 case CP_TAG_CONST_STRING:
652 value->aString = m_pCP->readStringConstant(cpIndex);
653 ret = RT_TYPE_STRING;
654 break;
655 default:
656 break;
659 } catch (BlopObject::BoundsError &) {
660 SAL_WARN("registry", "bad data");
662 return ret;
665 const char* FieldList::getFieldDoku(sal_uInt16 index) const
667 const char* aDoku = nullptr;
669 if ((m_numOfEntries > 0) && (index <= m_numOfEntries))
671 try {
672 aDoku = m_pCP->readUTF8NameConstant(readUINT16(sizeof(sal_uInt16) + (index * m_FIELD_ENTRY_SIZE) + FIELD_OFFSET_DOKU));
673 } catch (BlopObject::BoundsError &) {
674 SAL_WARN("registry", "bad data");
678 return aDoku;
681 const char* FieldList::getFieldFileName(sal_uInt16 index) const
683 const char* aFileName = nullptr;
685 if ((m_numOfEntries > 0) && (index <= m_numOfEntries))
687 try {
688 aFileName = m_pCP->readUTF8NameConstant(readUINT16(sizeof(sal_uInt16) + (index * m_FIELD_ENTRY_SIZE) + FIELD_OFFSET_FILENAME));
689 } catch (BlopObject::BoundsError &) {
690 SAL_WARN("registry", "bad data");
694 return aFileName;
697 namespace {
699 class ReferenceList : public BlopObject
701 public:
703 sal_uInt16 m_numOfEntries;
704 size_t m_REFERENCE_ENTRY_SIZE;
705 ConstantPool* m_pCP;
707 ReferenceList(const sal_uInt8* buffer, sal_uInt32 len, sal_uInt16 numEntries, ConstantPool* pCP)
708 : BlopObject(buffer, len)
709 , m_numOfEntries(numEntries)
710 , m_pCP(pCP)
712 if ( m_numOfEntries > 0 )
714 sal_uInt16 numOfReferenceEntries = readUINT16(0);
715 m_REFERENCE_ENTRY_SIZE = numOfReferenceEntries * sizeof(sal_uInt16);
716 } else
718 m_REFERENCE_ENTRY_SIZE = 0;
722 const char* getReferenceName(sal_uInt16 index) const;
723 RTReferenceType getReferenceType(sal_uInt16 index) const;
724 const char* getReferenceDoku(sal_uInt16 index) const;
725 RTFieldAccess getReferenceAccess(sal_uInt16 index) const;
730 const char* ReferenceList::getReferenceName(sal_uInt16 index) const
732 const char* aName = nullptr;
734 if ((m_numOfEntries > 0) && (index <= m_numOfEntries))
736 try {
737 aName = m_pCP->readUTF8NameConstant(readUINT16(sizeof(sal_uInt16) + (index * m_REFERENCE_ENTRY_SIZE) + REFERENCE_OFFSET_NAME));
738 } catch (BlopObject::BoundsError &) {
739 SAL_WARN("registry", "bad data");
743 return aName;
746 RTReferenceType ReferenceList::getReferenceType(sal_uInt16 index) const
748 RTReferenceType refType = RTReferenceType::INVALID;
750 if ((m_numOfEntries > 0) && (index <= m_numOfEntries))
752 try {
753 refType = static_cast<RTReferenceType>(readUINT16(sizeof(sal_uInt16) + (index * m_REFERENCE_ENTRY_SIZE) + REFERENCE_OFFSET_TYPE));
754 } catch (BlopObject::BoundsError &) {
755 SAL_WARN("registry", "bad data");
759 return refType;
762 const char* ReferenceList::getReferenceDoku(sal_uInt16 index) const
764 const char* aDoku = nullptr;
766 if ((m_numOfEntries > 0) && (index <= m_numOfEntries))
768 try {
769 aDoku = m_pCP->readUTF8NameConstant(readUINT16(sizeof(sal_uInt16) + (index * m_REFERENCE_ENTRY_SIZE) + REFERENCE_OFFSET_DOKU));
770 } catch (BlopObject::BoundsError &) {
771 SAL_WARN("registry", "bad data");
775 return aDoku;
778 RTFieldAccess ReferenceList::getReferenceAccess(sal_uInt16 index) const
780 RTFieldAccess aAccess = RTFieldAccess::INVALID;
782 if ((m_numOfEntries > 0) && (index <= m_numOfEntries))
784 try {
785 aAccess = static_cast<RTFieldAccess>(readUINT16(sizeof(sal_uInt16) + (index * m_REFERENCE_ENTRY_SIZE) + REFERENCE_OFFSET_ACCESS));
786 } catch (BlopObject::BoundsError &) {
787 SAL_WARN("registry", "bad data");
791 return aAccess;
794 namespace {
796 class MethodList : public BlopObject
798 public:
800 sal_uInt16 m_numOfEntries;
801 size_t m_PARAM_ENTRY_SIZE;
802 std::unique_ptr<sal_uInt32[]> m_pIndex;
803 ConstantPool* m_pCP;
805 MethodList(const sal_uInt8* buffer, sal_uInt32 len, sal_uInt16 numEntries, ConstantPool* pCP)
806 : BlopObject(buffer, len)
807 , m_numOfEntries(numEntries)
808 , m_pCP(pCP)
810 if ( m_numOfEntries > 0 )
812 readUINT16(0) /* numOfMethodEntries */;
813 sal_uInt16 numOfParamEntries = readUINT16(sizeof(sal_uInt16));
814 m_PARAM_ENTRY_SIZE = numOfParamEntries * sizeof(sal_uInt16);
815 } else
817 m_PARAM_ENTRY_SIZE = 0;
821 sal_uInt32 parseIndex(); // throws std::bad_alloc
823 const char* getMethodName(sal_uInt16 index) const;
824 sal_uInt16 getMethodParamCount(sal_uInt16 index) const;
825 const char* getMethodParamType(sal_uInt16 index, sal_uInt16 paramIndex) const;
826 const char* getMethodParamName(sal_uInt16 index, sal_uInt16 paramIndex) const;
827 RTParamMode getMethodParamMode(sal_uInt16 index, sal_uInt16 paramIndex) const;
828 sal_uInt16 getMethodExcCount(sal_uInt16 index) const;
829 const char* getMethodExcType(sal_uInt16 index, sal_uInt16 excIndex) const;
830 const char* getMethodReturnType(sal_uInt16 index) const;
831 RTMethodMode getMethodMode(sal_uInt16 index) const;
832 const char* getMethodDoku(sal_uInt16 index) const;
834 private:
835 sal_uInt16 calcMethodParamIndex( const sal_uInt16 index ) const;
840 sal_uInt16 MethodList::calcMethodParamIndex( const sal_uInt16 index ) const
842 return (METHOD_OFFSET_PARAM_COUNT + sizeof(sal_uInt16) + (index * m_PARAM_ENTRY_SIZE));
845 sal_uInt32 MethodList::parseIndex()
847 m_pIndex.reset();
849 sal_uInt32 offset = 0;
851 if (m_numOfEntries)
853 offset = 2 * sizeof(sal_uInt16);
854 m_pIndex.reset( new sal_uInt32[m_numOfEntries] );
856 for (int i = 0; i < m_numOfEntries; i++)
858 m_pIndex[i] = offset;
860 offset += readUINT16(offset);
864 return offset;
867 const char* MethodList::getMethodName(sal_uInt16 index) const
869 const char* aName = nullptr;
871 if ((m_numOfEntries > 0) && (index <= m_numOfEntries))
873 try {
874 aName = m_pCP->readUTF8NameConstant(readUINT16(m_pIndex[index] + METHOD_OFFSET_NAME));
875 } catch (BlopObject::BoundsError &) {
876 SAL_WARN("registry", "bad data");
880 return aName;
883 sal_uInt16 MethodList::getMethodParamCount(sal_uInt16 index) const
885 sal_uInt16 aCount = 0;
887 if ((m_numOfEntries > 0) && (index <= m_numOfEntries))
889 try {
890 aCount = readUINT16(m_pIndex[index] + METHOD_OFFSET_PARAM_COUNT);
891 } catch (BlopObject::BoundsError &) {
892 SAL_WARN("registry", "bad data");
896 return aCount;
899 const char* MethodList::getMethodParamType(sal_uInt16 index, sal_uInt16 paramIndex) const
901 const char* aName = nullptr;
902 try {
903 if ((m_numOfEntries > 0) &&
904 (index <= m_numOfEntries) &&
905 (paramIndex <= readUINT16(m_pIndex[index] + METHOD_OFFSET_PARAM_COUNT)))
907 aName = m_pCP->readUTF8NameConstant(
908 readUINT16(
909 m_pIndex[index] +
910 calcMethodParamIndex(paramIndex) +
911 PARAM_OFFSET_TYPE));
913 } catch (BlopObject::BoundsError &) {
914 SAL_WARN("registry", "bad data");
916 return aName;
919 const char* MethodList::getMethodParamName(sal_uInt16 index, sal_uInt16 paramIndex) const
921 const char* aName = nullptr;
922 try {
923 if ((m_numOfEntries > 0) &&
924 (index <= m_numOfEntries) &&
925 (paramIndex <= readUINT16(m_pIndex[index] + METHOD_OFFSET_PARAM_COUNT)))
927 aName = m_pCP->readUTF8NameConstant(
928 readUINT16(
929 m_pIndex[index] +
930 calcMethodParamIndex(paramIndex) +
931 PARAM_OFFSET_NAME));
933 } catch (BlopObject::BoundsError &) {
934 SAL_WARN("registry", "bad data");
936 return aName;
939 RTParamMode MethodList::getMethodParamMode(sal_uInt16 index, sal_uInt16 paramIndex) const
941 RTParamMode aMode = RT_PARAM_INVALID;
942 try {
943 if ((m_numOfEntries > 0) &&
944 (index <= m_numOfEntries) &&
945 (paramIndex <= readUINT16(m_pIndex[index] + METHOD_OFFSET_PARAM_COUNT)))
947 aMode = static_cast<RTParamMode>(readUINT16(
948 m_pIndex[index] +
949 calcMethodParamIndex(paramIndex) +
950 PARAM_OFFSET_MODE));
952 } catch (BlopObject::BoundsError &) {
953 SAL_WARN("registry", "bad data");
955 return aMode;
958 #if defined(__COVERITY__)
959 extern "C" void __coverity_tainted_data_sanitize__(void *);
960 #endif
962 sal_uInt16 MethodList::getMethodExcCount(sal_uInt16 index) const
964 sal_uInt16 aCount = 0;
966 if ((m_numOfEntries > 0) && (index <= m_numOfEntries))
968 try {
969 aCount = readUINT16(m_pIndex[index] + calcMethodParamIndex(readUINT16(m_pIndex[index] + METHOD_OFFSET_PARAM_COUNT)));
970 #if defined(__COVERITY__)
971 __coverity_tainted_data_sanitize__(&aCount);
972 #endif
973 } catch (BlopObject::BoundsError &) {
974 SAL_WARN("registry", "bad data");
978 return aCount;
981 const char* MethodList::getMethodExcType(sal_uInt16 index, sal_uInt16 excIndex) const
983 const char* aName = nullptr;
985 if ((m_numOfEntries > 0) && (index <= m_numOfEntries))
987 try {
988 sal_uInt32 excOffset = m_pIndex[index] + calcMethodParamIndex(readUINT16(m_pIndex[index] + METHOD_OFFSET_PARAM_COUNT));
989 if (excIndex <= readUINT16(excOffset))
991 aName = m_pCP->readUTF8NameConstant(
992 readUINT16(
993 excOffset +
994 sizeof(sal_uInt16) +
995 (excIndex * sizeof(sal_uInt16))));
997 } catch (BlopObject::BoundsError &) {
998 SAL_WARN("registry", "bad data");
1002 return aName;
1005 const char* MethodList::getMethodReturnType(sal_uInt16 index) const
1007 const char* aName = nullptr;
1009 if ((m_numOfEntries > 0) && (index <= m_numOfEntries))
1011 try {
1012 aName = m_pCP->readUTF8NameConstant(readUINT16(m_pIndex[index] + METHOD_OFFSET_RETURN));
1013 } catch (BlopObject::BoundsError &) {
1014 SAL_WARN("registry", "bad data");
1018 return aName;
1021 RTMethodMode MethodList::getMethodMode(sal_uInt16 index) const
1023 RTMethodMode aMode = RTMethodMode::INVALID;
1025 if ((m_numOfEntries > 0) && (index <= m_numOfEntries))
1027 try {
1028 aMode = static_cast<RTMethodMode>(readUINT16(m_pIndex[index] + METHOD_OFFSET_MODE));
1029 } catch (BlopObject::BoundsError &) {
1030 SAL_WARN("registry", "bad data");
1034 return aMode;
1037 const char* MethodList::getMethodDoku(sal_uInt16 index) const
1039 const char* aDoku = nullptr;
1041 if ((m_numOfEntries > 0) && (index <= m_numOfEntries))
1043 try {
1044 aDoku = m_pCP->readUTF8NameConstant(readUINT16(m_pIndex[index] + METHOD_OFFSET_DOKU));
1045 } catch (BlopObject::BoundsError &) {
1046 SAL_WARN("registry", "bad data");
1050 return aDoku;
1053 namespace {
1055 class TypeRegistryEntry: public BlopObject {
1056 public:
1057 std::unique_ptr<ConstantPool> m_pCP;
1058 std::unique_ptr<FieldList> m_pFields;
1059 std::unique_ptr<MethodList> m_pMethods;
1060 std::unique_ptr<ReferenceList> m_pReferences;
1061 sal_uInt32 m_refCount;
1062 sal_uInt16 m_nSuperTypes;
1063 sal_uInt32 m_offset_SUPERTYPES;
1065 TypeRegistryEntry(
1066 const sal_uInt8* buffer, sal_uInt32 len);
1067 // throws std::bad_alloc
1069 typereg_Version getVersion() const;
1074 TypeRegistryEntry::TypeRegistryEntry(
1075 const sal_uInt8* buffer, sal_uInt32 len):
1076 BlopObject(buffer, len), m_refCount(1), m_nSuperTypes(0),
1077 m_offset_SUPERTYPES(0)
1079 std::size_t const entrySize = sizeof(sal_uInt16);
1080 sal_uInt16 nHeaderEntries = readUINT16(OFFSET_N_ENTRIES);
1081 sal_uInt32 offset_N_SUPERTYPES = OFFSET_N_ENTRIES + entrySize + (nHeaderEntries * entrySize); // cannot overflow
1082 m_offset_SUPERTYPES = offset_N_SUPERTYPES + entrySize; // cannot overflow
1083 m_nSuperTypes = readUINT16(offset_N_SUPERTYPES);
1085 sal_uInt32 offset_CP_SIZE = m_offset_SUPERTYPES + (m_nSuperTypes * entrySize); // cannot overflow
1086 sal_uInt32 offset_CP = offset_CP_SIZE + entrySize; // cannot overflow
1088 if (offset_CP > m_bufferLen) {
1089 throw BoundsError();
1091 m_pCP.reset(
1092 new ConstantPool(
1093 m_pBuffer + offset_CP, m_bufferLen - offset_CP,
1094 readUINT16(offset_CP_SIZE)));
1096 sal_uInt32 offset = offset_CP + m_pCP->parseIndex(); //TODO: overflow
1098 assert(m_bufferLen >= entrySize);
1099 if (offset > m_bufferLen - entrySize) {
1100 throw BoundsError();
1102 m_pFields.reset(
1103 new FieldList(
1104 m_pBuffer + offset + entrySize, m_bufferLen - (offset + entrySize),
1105 readUINT16(offset), m_pCP.get()));
1107 offset += sizeof(sal_uInt16) + m_pFields->parseIndex(); //TODO: overflow
1109 assert(m_bufferLen >= entrySize);
1110 if (offset > m_bufferLen - entrySize) {
1111 throw BoundsError();
1113 m_pMethods.reset(
1114 new MethodList(
1115 m_pBuffer + offset + entrySize, m_bufferLen - (offset + entrySize),
1116 readUINT16(offset), m_pCP.get()));
1118 offset += sizeof(sal_uInt16) + m_pMethods->parseIndex(); //TODO: overflow
1120 assert(m_bufferLen >= entrySize);
1121 if (offset > m_bufferLen - entrySize) {
1122 throw BoundsError();
1124 m_pReferences.reset(
1125 new ReferenceList(
1126 m_pBuffer + offset + entrySize, m_bufferLen - (offset + entrySize),
1127 readUINT16(offset), m_pCP.get()));
1130 typereg_Version TypeRegistryEntry::getVersion() const {
1131 // Assumes two's complement arithmetic with modulo-semantics:
1132 return static_cast< typereg_Version >(readUINT32(OFFSET_MAGIC) - magic);
1135 bool TYPEREG_CALLTYPE typereg_reader_create(
1136 void const * buffer, sal_uInt32 length,
1137 void ** result)
1139 if (length < OFFSET_CP || length > SAL_MAX_UINT32) {
1140 *result = nullptr;
1141 return true;
1143 std::unique_ptr< TypeRegistryEntry > entry;
1144 try {
1145 try {
1146 entry.reset(
1147 new TypeRegistryEntry(
1148 static_cast< sal_uInt8 const * >(buffer), length));
1149 } catch (std::bad_alloc &) {
1150 return false;
1152 if (entry->readUINT32(OFFSET_SIZE) != length) {
1153 *result = nullptr;
1154 return true;
1156 typereg_Version version = entry->getVersion();
1157 if (version < TYPEREG_VERSION_0 || version > TYPEREG_VERSION_1) {
1158 *result = nullptr;
1159 return true;
1161 *result = entry.release();
1162 return true;
1163 } catch (BlopObject::BoundsError &) {
1164 SAL_WARN("registry", "bad data");
1165 return false;
1169 void TYPEREG_CALLTYPE typereg_reader_acquire(void * hEntry)
1171 TypeRegistryEntry* pEntry = static_cast<TypeRegistryEntry*>(hEntry);
1173 if (pEntry != nullptr)
1174 pEntry->m_refCount++;
1177 void TYPEREG_CALLTYPE typereg_reader_release(void * hEntry)
1179 TypeRegistryEntry* pEntry = static_cast<TypeRegistryEntry*>(hEntry);
1181 if (pEntry != nullptr)
1183 if (--pEntry->m_refCount == 0)
1184 delete pEntry;
1188 typereg_Version TYPEREG_CALLTYPE typereg_reader_getVersion(void const * handle) {
1189 if (handle != nullptr) {
1190 try {
1191 return static_cast< TypeRegistryEntry const * >(handle)->getVersion();
1192 } catch (BlopObject::BoundsError &) {
1193 SAL_WARN("registry", "bad data");
1196 return TYPEREG_VERSION_0;
1199 RTTypeClass TYPEREG_CALLTYPE typereg_reader_getTypeClass(void * hEntry)
1201 TypeRegistryEntry* pEntry = static_cast<TypeRegistryEntry*>(hEntry);
1202 if (pEntry != nullptr) {
1203 try {
1204 return static_cast<RTTypeClass>(pEntry->readUINT16(OFFSET_TYPE_CLASS) & ~RT_TYPE_PUBLISHED);
1205 } catch (BlopObject::BoundsError &) {
1206 SAL_WARN("registry", "bad data");
1209 return RT_TYPE_INVALID;
1212 bool TYPEREG_CALLTYPE typereg_reader_isPublished(void * hEntry)
1214 TypeRegistryEntry * entry = static_cast< TypeRegistryEntry * >(hEntry);
1215 if (entry != nullptr) {
1216 try {
1217 return (entry->readUINT16(OFFSET_TYPE_CLASS) & RT_TYPE_PUBLISHED) != 0;
1218 } catch (BlopObject::BoundsError &) {
1219 SAL_WARN("registry", "bad data");
1222 return false;
1225 void TYPEREG_CALLTYPE typereg_reader_getTypeName(void * hEntry, rtl_uString** pTypeName)
1227 TypeRegistryEntry* pEntry = static_cast<TypeRegistryEntry*>(hEntry);
1228 if (pEntry != nullptr) {
1229 try {
1230 const char* pTmp = pEntry->m_pCP->readUTF8NameConstant(pEntry->readUINT16(OFFSET_THIS_TYPE));
1231 rtl_string2UString(
1232 pTypeName, pTmp, pTmp == nullptr ? 0 : rtl_str_getLength(pTmp),
1233 RTL_TEXTENCODING_UTF8, OSTRING_TO_OUSTRING_CVTFLAGS);
1234 return;
1235 } catch (BlopObject::BoundsError &) {
1236 SAL_WARN("registry", "bad data");
1239 rtl_uString_new(pTypeName);
1243 void TYPEREG_CALLTYPE typereg_reader_getDocumentation(void * hEntry, rtl_uString** pDoku)
1245 TypeRegistryEntry* pEntry = static_cast<TypeRegistryEntry*>(hEntry);
1246 if (pEntry != nullptr) {
1247 try {
1248 const char* pTmp = pEntry->m_pCP->readUTF8NameConstant(pEntry->readUINT16(OFFSET_DOKU));
1249 rtl_string2UString(
1250 pDoku, pTmp, pTmp == nullptr ? 0 : rtl_str_getLength(pTmp),
1251 RTL_TEXTENCODING_UTF8, OSTRING_TO_OUSTRING_CVTFLAGS);
1252 return;
1253 } catch (BlopObject::BoundsError &) {
1254 SAL_WARN("registry", "bad data");
1257 rtl_uString_new(pDoku);
1260 void TYPEREG_CALLTYPE typereg_reader_getFileName(void * hEntry, rtl_uString** pFileName)
1262 TypeRegistryEntry* pEntry = static_cast<TypeRegistryEntry*>(hEntry);
1263 if (pEntry != nullptr) {
1264 try {
1265 const char* pTmp = pEntry->m_pCP->readUTF8NameConstant(pEntry->readUINT16(OFFSET_FILENAME));
1266 rtl_string2UString(
1267 pFileName, pTmp, pTmp == nullptr ? 0 : rtl_str_getLength(pTmp),
1268 RTL_TEXTENCODING_UTF8, OSTRING_TO_OUSTRING_CVTFLAGS);
1269 return;
1270 } catch (BlopObject::BoundsError &) {
1271 SAL_WARN("registry", "bad data");
1274 rtl_uString_new(pFileName);
1278 sal_uInt16 TYPEREG_CALLTYPE typereg_reader_getFieldCount(void * hEntry)
1280 TypeRegistryEntry* pEntry = static_cast<TypeRegistryEntry*>(hEntry);
1282 if (pEntry == nullptr) return 0;
1284 return pEntry->m_pFields->m_numOfEntries;
1287 void TYPEREG_CALLTYPE typereg_reader_getFieldName(void * hEntry, rtl_uString** pFieldName, sal_uInt16 index)
1289 TypeRegistryEntry* pEntry = static_cast<TypeRegistryEntry*>(hEntry);
1291 if (pEntry == nullptr)
1293 rtl_uString_new(pFieldName);
1294 return;
1296 const char* pTmp = pEntry->m_pFields->getFieldName(index);
1297 rtl_string2UString(
1298 pFieldName, pTmp, pTmp == nullptr ? 0 : rtl_str_getLength(pTmp),
1299 RTL_TEXTENCODING_UTF8, OSTRING_TO_OUSTRING_CVTFLAGS);
1302 void TYPEREG_CALLTYPE typereg_reader_getFieldTypeName(void * hEntry, rtl_uString** pFieldType, sal_uInt16 index)
1304 TypeRegistryEntry* pEntry = static_cast<TypeRegistryEntry*>(hEntry);
1306 if (pEntry == nullptr)
1308 rtl_uString_new(pFieldType);
1309 return;
1312 const char* pTmp = pEntry->m_pFields->getFieldType(index);
1313 rtl_string2UString(
1314 pFieldType, pTmp, pTmp == nullptr ? 0 : rtl_str_getLength(pTmp),
1315 RTL_TEXTENCODING_UTF8, OSTRING_TO_OUSTRING_CVTFLAGS);
1318 RTFieldAccess TYPEREG_CALLTYPE typereg_reader_getFieldFlags(void * hEntry, sal_uInt16 index)
1320 TypeRegistryEntry* pEntry = static_cast<TypeRegistryEntry*>(hEntry);
1322 if (pEntry == nullptr) return RTFieldAccess::INVALID;
1324 return pEntry->m_pFields->getFieldAccess(index);
1327 bool TYPEREG_CALLTYPE typereg_reader_getFieldValue(
1328 void * hEntry, sal_uInt16 index, RTValueType * type,
1329 RTConstValueUnion * value)
1331 TypeRegistryEntry* pEntry = static_cast<TypeRegistryEntry*>(hEntry);
1333 if (pEntry == nullptr) {
1334 *type = RT_TYPE_NONE;
1335 return true;
1338 try {
1339 *type = pEntry->m_pFields->getFieldConstValue(index, value);
1340 } catch (std::bad_alloc &) {
1341 return false;
1343 return true;
1346 void TYPEREG_CALLTYPE typereg_reader_getFieldDocumentation(void * hEntry, rtl_uString** pDoku, sal_uInt16 index)
1348 TypeRegistryEntry* pEntry = static_cast<TypeRegistryEntry*>(hEntry);
1350 if (pEntry == nullptr)
1352 rtl_uString_new(pDoku);
1353 return;
1356 const char* pTmp = pEntry->m_pFields->getFieldDoku(index);
1357 rtl_string2UString(
1358 pDoku, pTmp, pTmp == nullptr ? 0 : rtl_str_getLength(pTmp),
1359 RTL_TEXTENCODING_UTF8, OSTRING_TO_OUSTRING_CVTFLAGS);
1362 void TYPEREG_CALLTYPE typereg_reader_getFieldFileName(void * hEntry, rtl_uString** pFieldFileName, sal_uInt16 index)
1364 TypeRegistryEntry* pEntry = static_cast<TypeRegistryEntry*>(hEntry);
1366 if (pEntry == nullptr)
1368 rtl_uString_new(pFieldFileName);
1369 return;
1372 const char* pTmp = pEntry->m_pFields->getFieldFileName(index);
1373 rtl_string2UString(
1374 pFieldFileName, pTmp, pTmp == nullptr ? 0 : rtl_str_getLength(pTmp),
1375 RTL_TEXTENCODING_UTF8, OSTRING_TO_OUSTRING_CVTFLAGS);
1379 sal_uInt16 TYPEREG_CALLTYPE typereg_reader_getMethodCount(void * hEntry)
1381 TypeRegistryEntry* pEntry = static_cast<TypeRegistryEntry*>(hEntry);
1383 if (pEntry == nullptr) return 0;
1385 return pEntry->m_pMethods->m_numOfEntries;
1388 void TYPEREG_CALLTYPE typereg_reader_getMethodName(void * hEntry, rtl_uString** pMethodName, sal_uInt16 index)
1390 TypeRegistryEntry* pEntry = static_cast<TypeRegistryEntry*>(hEntry);
1392 if (pEntry == nullptr)
1394 rtl_uString_new(pMethodName);
1395 return;
1398 const char* pTmp = pEntry->m_pMethods->getMethodName(index);
1399 rtl_string2UString(
1400 pMethodName, pTmp, pTmp == nullptr ? 0 : rtl_str_getLength(pTmp),
1401 RTL_TEXTENCODING_UTF8, OSTRING_TO_OUSTRING_CVTFLAGS);
1404 sal_uInt16 TYPEREG_CALLTYPE typereg_reader_getMethodParameterCount(
1405 void * hEntry, sal_uInt16 index)
1407 TypeRegistryEntry* pEntry = static_cast<TypeRegistryEntry*>(hEntry);
1409 if (pEntry == nullptr) return 0;
1411 return pEntry->m_pMethods->getMethodParamCount(index);
1414 void TYPEREG_CALLTYPE typereg_reader_getMethodParameterTypeName(void * hEntry, rtl_uString** pMethodParamType, sal_uInt16 index, sal_uInt16 paramIndex)
1416 TypeRegistryEntry* pEntry = static_cast<TypeRegistryEntry*>(hEntry);
1418 if (pEntry == nullptr)
1420 rtl_uString_new(pMethodParamType);
1421 return;
1424 const char* pTmp = pEntry->m_pMethods->getMethodParamType(index, paramIndex);
1425 rtl_string2UString(
1426 pMethodParamType, pTmp, pTmp == nullptr ? 0 : rtl_str_getLength(pTmp),
1427 RTL_TEXTENCODING_UTF8, OSTRING_TO_OUSTRING_CVTFLAGS);
1430 void TYPEREG_CALLTYPE typereg_reader_getMethodParameterName(void * hEntry, rtl_uString** pMethodParamName, sal_uInt16 index, sal_uInt16 paramIndex)
1432 TypeRegistryEntry* pEntry = static_cast<TypeRegistryEntry*>(hEntry);
1434 if (pEntry == nullptr)
1436 rtl_uString_new(pMethodParamName);
1437 return;
1440 const char* pTmp = pEntry->m_pMethods->getMethodParamName(index, paramIndex);
1441 rtl_string2UString(
1442 pMethodParamName, pTmp, pTmp == nullptr ? 0 : rtl_str_getLength(pTmp),
1443 RTL_TEXTENCODING_UTF8, OSTRING_TO_OUSTRING_CVTFLAGS);
1446 RTParamMode TYPEREG_CALLTYPE typereg_reader_getMethodParameterFlags(void * hEntry, sal_uInt16 index, sal_uInt16 paramIndex)
1448 TypeRegistryEntry* pEntry = static_cast<TypeRegistryEntry*>(hEntry);
1450 if (pEntry == nullptr) return RT_PARAM_INVALID;
1452 return pEntry->m_pMethods->getMethodParamMode(index, paramIndex);
1455 sal_uInt16 TYPEREG_CALLTYPE typereg_reader_getMethodExceptionCount(
1456 void * hEntry, sal_uInt16 index)
1458 TypeRegistryEntry* pEntry = static_cast<TypeRegistryEntry*>(hEntry);
1460 if (pEntry == nullptr) return 0;
1462 return pEntry->m_pMethods->getMethodExcCount(index);
1465 void TYPEREG_CALLTYPE typereg_reader_getMethodExceptionTypeName(void * hEntry, rtl_uString** pMethodExcpType, sal_uInt16 index, sal_uInt16 excIndex)
1467 TypeRegistryEntry* pEntry = static_cast<TypeRegistryEntry*>(hEntry);
1469 if (pEntry == nullptr)
1471 rtl_uString_new(pMethodExcpType);
1472 return;
1475 const char* pTmp = pEntry->m_pMethods->getMethodExcType(index, excIndex);
1476 rtl_string2UString(
1477 pMethodExcpType, pTmp, pTmp == nullptr ? 0 : rtl_str_getLength(pTmp),
1478 RTL_TEXTENCODING_UTF8, OSTRING_TO_OUSTRING_CVTFLAGS);
1481 void TYPEREG_CALLTYPE typereg_reader_getMethodReturnTypeName(void * hEntry, rtl_uString** pMethodReturnType, sal_uInt16 index)
1483 TypeRegistryEntry* pEntry = static_cast<TypeRegistryEntry*>(hEntry);
1485 if (pEntry == nullptr)
1487 rtl_uString_new(pMethodReturnType);
1488 return;
1491 const char* pTmp = pEntry->m_pMethods->getMethodReturnType(index);
1492 rtl_string2UString(
1493 pMethodReturnType, pTmp, pTmp == nullptr ? 0 : rtl_str_getLength(pTmp),
1494 RTL_TEXTENCODING_UTF8, OSTRING_TO_OUSTRING_CVTFLAGS);
1497 RTMethodMode TYPEREG_CALLTYPE typereg_reader_getMethodFlags(void * hEntry, sal_uInt16 index)
1499 TypeRegistryEntry* pEntry = static_cast<TypeRegistryEntry*>(hEntry);
1501 if (pEntry == nullptr) return RTMethodMode::INVALID;
1503 return pEntry->m_pMethods->getMethodMode(index);
1506 void TYPEREG_CALLTYPE typereg_reader_getMethodDocumentation(void * hEntry, rtl_uString** pMethodDoku, sal_uInt16 index)
1508 TypeRegistryEntry* pEntry = static_cast<TypeRegistryEntry*>(hEntry);
1510 if (pEntry == nullptr)
1512 rtl_uString_new(pMethodDoku);
1513 return;
1516 const char* pTmp = pEntry->m_pMethods->getMethodDoku(index);
1517 rtl_string2UString(
1518 pMethodDoku, pTmp, pTmp == nullptr ? 0 : rtl_str_getLength(pTmp),
1519 RTL_TEXTENCODING_UTF8, OSTRING_TO_OUSTRING_CVTFLAGS);
1522 sal_uInt16 TYPEREG_CALLTYPE typereg_reader_getReferenceCount(void * hEntry)
1524 TypeRegistryEntry* pEntry = static_cast<TypeRegistryEntry*>(hEntry);
1526 if (pEntry == nullptr) return 0;
1528 return pEntry->m_pReferences->m_numOfEntries;
1531 void TYPEREG_CALLTYPE typereg_reader_getReferenceTypeName(void * hEntry, rtl_uString** pReferenceName, sal_uInt16 index)
1533 TypeRegistryEntry* pEntry = static_cast<TypeRegistryEntry*>(hEntry);
1535 if (pEntry == nullptr)
1537 rtl_uString_new(pReferenceName);
1538 return;
1541 const char* pTmp = pEntry->m_pReferences->getReferenceName(index);
1542 rtl_string2UString(
1543 pReferenceName, pTmp, pTmp == nullptr ? 0 : rtl_str_getLength(pTmp),
1544 RTL_TEXTENCODING_UTF8, OSTRING_TO_OUSTRING_CVTFLAGS);
1547 RTReferenceType TYPEREG_CALLTYPE typereg_reader_getReferenceSort(void * hEntry, sal_uInt16 index)
1549 TypeRegistryEntry* pEntry = static_cast<TypeRegistryEntry*>(hEntry);
1551 if (pEntry == nullptr) return RTReferenceType::INVALID;
1553 return pEntry->m_pReferences->getReferenceType(index);
1556 void TYPEREG_CALLTYPE typereg_reader_getReferenceDocumentation(void * hEntry, rtl_uString** pReferenceDoku, sal_uInt16 index)
1558 TypeRegistryEntry* pEntry = static_cast<TypeRegistryEntry*>(hEntry);
1560 if (pEntry == nullptr)
1562 rtl_uString_new(pReferenceDoku);
1563 return;
1566 const char* pTmp = pEntry->m_pReferences->getReferenceDoku(index);
1567 rtl_string2UString(
1568 pReferenceDoku, pTmp, pTmp == nullptr ? 0 : rtl_str_getLength(pTmp),
1569 RTL_TEXTENCODING_UTF8, OSTRING_TO_OUSTRING_CVTFLAGS);
1572 RTFieldAccess TYPEREG_CALLTYPE typereg_reader_getReferenceFlags(void * hEntry, sal_uInt16 index)
1574 TypeRegistryEntry* pEntry = static_cast<TypeRegistryEntry*>(hEntry);
1576 if (pEntry == nullptr) return RTFieldAccess::INVALID;
1578 return pEntry->m_pReferences->getReferenceAccess(index);
1581 sal_uInt16 TYPEREG_CALLTYPE typereg_reader_getSuperTypeCount(void * hEntry)
1583 TypeRegistryEntry* pEntry = static_cast<TypeRegistryEntry*>(hEntry);
1585 if (pEntry == nullptr) return 0;
1587 return pEntry->m_nSuperTypes;
1590 void TYPEREG_CALLTYPE typereg_reader_getSuperTypeName(
1591 void * hEntry, rtl_uString ** pSuperTypeName, sal_uInt16 index)
1593 TypeRegistryEntry* pEntry = static_cast<TypeRegistryEntry*>(hEntry);
1594 if (pEntry != nullptr) {
1595 try {
1596 OSL_ASSERT(index < pEntry->m_nSuperTypes);
1597 const char* pTmp = pEntry->m_pCP->readUTF8NameConstant(pEntry->readUINT16(pEntry->m_offset_SUPERTYPES + (index * sizeof(sal_uInt16))));
1598 rtl_string2UString(
1599 pSuperTypeName, pTmp, pTmp == nullptr ? 0 : rtl_str_getLength(pTmp),
1600 RTL_TEXTENCODING_UTF8, OSTRING_TO_OUSTRING_CVTFLAGS);
1601 return;
1602 } catch (BlopObject::BoundsError &) {
1603 SAL_WARN("registry", "bad data");
1606 rtl_uString_new(pSuperTypeName);
1609 /* vim:set shiftwidth=4 softtabstop=4 expandtab: */