Branch libreoffice-5-0-4
[LibreOffice.git] / registry / source / reflread.cxx
blob346fce02a8b7f9e37ceaa92a54c32d3a79991282
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>
26 #include <string.h>
27 #include <sal/types.h>
28 #include <osl/endian.h>
29 #include <osl/diagnose.h>
30 #include <registry/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;
62 bool m_isCopied;
64 BlopObject(const sal_uInt8* buffer, sal_uInt32 len, bool copyBuffer);
65 // throws std::bad_alloc
67 ~BlopObject();
69 inline sal_uInt8 readBYTE(sal_uInt32 index) const
71 if (index >= m_bufferLen) {
72 throw BoundsError();
74 return m_pBuffer[index];
77 inline sal_Int16 readINT16(sal_uInt32 index) const
79 if (m_bufferLen < 2 || index >= m_bufferLen - 1) {
80 throw BoundsError();
82 return ((m_pBuffer[index] << 8) | (m_pBuffer[index+1] << 0));
85 inline sal_uInt16 readUINT16(sal_uInt32 index) const
87 if (m_bufferLen < 2 || index >= m_bufferLen - 1) {
88 throw BoundsError();
90 return ((m_pBuffer[index] << 8) | (m_pBuffer[index+1] << 0));
93 inline sal_Int32 readINT32(sal_uInt32 index) const
95 if (m_bufferLen < 4 || index >= m_bufferLen - 3) {
96 throw BoundsError();
98 return (
99 (m_pBuffer[index] << 24) |
100 (m_pBuffer[index+1] << 16) |
101 (m_pBuffer[index+2] << 8) |
102 (m_pBuffer[index+3] << 0)
106 inline sal_uInt32 readUINT32(sal_uInt32 index) const
108 if (m_bufferLen < 4 || index >= m_bufferLen - 3) {
109 throw BoundsError();
111 return (
112 (m_pBuffer[index] << 24) |
113 (m_pBuffer[index+1] << 16) |
114 (m_pBuffer[index+2] << 8) |
115 (m_pBuffer[index+3] << 0)
119 inline sal_Int64 readINT64(sal_uInt32 index) const
121 if (m_bufferLen < 8 || index >= m_bufferLen - 7) {
122 throw BoundsError();
124 return (
125 ((sal_Int64)m_pBuffer[index] << 56) |
126 ((sal_Int64)m_pBuffer[index+1] << 48) |
127 ((sal_Int64)m_pBuffer[index+2] << 40) |
128 ((sal_Int64)m_pBuffer[index+3] << 32) |
129 ((sal_Int64)m_pBuffer[index+4] << 24) |
130 ((sal_Int64)m_pBuffer[index+5] << 16) |
131 ((sal_Int64)m_pBuffer[index+6] << 8) |
132 ((sal_Int64)m_pBuffer[index+7] << 0)
136 inline sal_uInt64 readUINT64(sal_uInt32 index) const
138 if (m_bufferLen < 8 || index >= m_bufferLen - 7) {
139 throw BoundsError();
141 return (
142 ((sal_uInt64)m_pBuffer[index] << 56) |
143 ((sal_uInt64)m_pBuffer[index+1] << 48) |
144 ((sal_uInt64)m_pBuffer[index+2] << 40) |
145 ((sal_uInt64)m_pBuffer[index+3] << 32) |
146 ((sal_uInt64)m_pBuffer[index+4] << 24) |
147 ((sal_uInt64)m_pBuffer[index+5] << 16) |
148 ((sal_uInt64)m_pBuffer[index+6] << 8) |
149 ((sal_uInt64)m_pBuffer[index+7] << 0)
154 BlopObject::BlopObject(const sal_uInt8* buffer, sal_uInt32 len, bool copyBuffer)
155 : m_bufferLen(len)
156 , m_isCopied(copyBuffer)
158 if (m_isCopied)
160 m_pBuffer = 0;
161 sal_uInt8* newBuffer = new sal_uInt8[len];
162 memcpy(newBuffer, buffer, len);
163 m_pBuffer = newBuffer;
165 else
167 m_pBuffer = buffer;
171 BlopObject::~BlopObject()
173 if (m_isCopied)
175 delete[] m_pBuffer;
179 /**************************************************************************
181 class StringCache
183 **************************************************************************/
185 class StringCache
187 public:
188 sal_Unicode** m_stringTable;
189 sal_uInt16 m_numOfStrings;
190 sal_uInt16 m_stringsCopied;
192 StringCache(sal_uInt16 size); // throws std::bad_alloc
193 ~StringCache();
195 const sal_Unicode* getString(sal_uInt16 index);
196 sal_uInt16 createString(const sal_uInt8* buffer); // throws std::bad_alloc
199 StringCache::StringCache(sal_uInt16 size)
200 : m_stringTable(NULL)
201 , m_numOfStrings(size)
202 , m_stringsCopied(0)
204 m_stringTable = new sal_Unicode*[m_numOfStrings];
206 for (sal_uInt16 i = 0; i < m_numOfStrings; i++)
208 m_stringTable[i] = NULL;
212 StringCache::~StringCache()
214 if (m_stringTable)
216 for (sal_uInt16 i = 0; i < m_stringsCopied; i++)
218 delete[] m_stringTable[i];
221 delete[] m_stringTable;
225 const sal_Unicode* StringCache::getString(sal_uInt16 index)
227 if ((index > 0) && (index <= m_stringsCopied))
228 return m_stringTable[index - 1];
229 else
230 return NULL;
233 sal_uInt16 StringCache::createString(const sal_uInt8* buffer)
235 if (m_stringsCopied < m_numOfStrings)
237 sal_uInt32 len = UINT16StringLen(buffer);
239 m_stringTable[m_stringsCopied] = new sal_Unicode[len + 1];
241 readString(buffer, m_stringTable[m_stringsCopied], (len + 1) * sizeof(sal_Unicode));
243 return ++m_stringsCopied;
245 else
246 return 0;
249 /**************************************************************************
251 class ConstantPool
253 **************************************************************************/
255 class ConstantPool : public BlopObject
257 public:
259 sal_uInt16 m_numOfEntries;
260 sal_Int32* m_pIndex; // index values may be < 0 for cached string constants
262 StringCache* m_pStringCache;
264 ConstantPool(const sal_uInt8* buffer, sal_uInt32 len, sal_uInt16 numEntries)
265 : BlopObject(buffer, len, false)
266 , m_numOfEntries(numEntries)
267 , m_pIndex(NULL)
268 , m_pStringCache(NULL)
272 ~ConstantPool();
274 sal_uInt32 parseIndex(); // throws std::bad_alloc
276 CPInfoTag readTag(sal_uInt16 index);
278 const sal_Char* readUTF8NameConstant(sal_uInt16 index);
279 bool readBOOLConstant(sal_uInt16 index);
280 sal_Int8 readBYTEConstant(sal_uInt16 index);
281 sal_Int16 readINT16Constant(sal_uInt16 index);
282 sal_uInt16 readUINT16Constant(sal_uInt16 index);
283 sal_Int32 readINT32Constant(sal_uInt16 index);
284 sal_uInt32 readUINT32Constant(sal_uInt16 index);
285 sal_Int64 readINT64Constant(sal_uInt16 index);
286 sal_uInt64 readUINT64Constant(sal_uInt16 index);
287 float readFloatConstant(sal_uInt16 index);
288 double readDoubleConstant(sal_uInt16 index);
289 const sal_Unicode* readStringConstant(sal_uInt16 index);
290 // throws std::bad_alloc
291 void readUIK(sal_uInt16 index, RTUik* uik);
294 ConstantPool::~ConstantPool()
296 delete[] m_pIndex;
297 delete m_pStringCache;
300 sal_uInt32 ConstantPool::parseIndex()
302 if (m_pIndex)
304 delete[] m_pIndex;
305 m_pIndex = NULL;
308 if (m_pStringCache)
310 delete m_pStringCache;
311 m_pStringCache = NULL;
314 sal_uInt32 offset = 0;
315 sal_uInt16 numOfStrings = 0;
317 if (m_numOfEntries)
319 m_pIndex = new sal_Int32[m_numOfEntries];
321 for (int i = 0; i < m_numOfEntries; i++)
323 m_pIndex[i] = offset;
325 offset += readUINT32(offset);
327 if ( ((CPInfoTag) readUINT16(m_pIndex[i] + CP_OFFSET_ENTRY_TAG)) ==
328 CP_TAG_CONST_STRING )
330 numOfStrings++;
336 if (numOfStrings)
338 m_pStringCache = new StringCache(numOfStrings);
341 m_bufferLen = offset;
343 return offset;
346 CPInfoTag ConstantPool::readTag(sal_uInt16 index)
348 CPInfoTag tag = CP_TAG_INVALID;
350 if (m_pIndex && (index > 0) && (index <= m_numOfEntries))
352 tag = (CPInfoTag) readUINT16(m_pIndex[index - 1] + CP_OFFSET_ENTRY_TAG);
355 return tag;
358 const sal_Char* ConstantPool::readUTF8NameConstant(sal_uInt16 index)
360 const sal_Char* aName = NULL_STRING;
362 if (m_pIndex && (index > 0) && (index <= m_numOfEntries))
364 if (readUINT16(m_pIndex[index - 1] + CP_OFFSET_ENTRY_TAG) == CP_TAG_UTF8_NAME)
366 sal_uInt32 n = m_pIndex[index - 1] + CP_OFFSET_ENTRY_DATA;
367 if (n < m_bufferLen
368 && std::memchr(m_pBuffer + n, 0, m_bufferLen - n) != nullptr)
370 aName = reinterpret_cast<const char*>(m_pBuffer + n);
375 return aName;
378 bool ConstantPool::readBOOLConstant(sal_uInt16 index)
380 bool aBool = false;
382 if (m_pIndex && (index> 0) && (index <= m_numOfEntries))
384 if (readUINT16(m_pIndex[index - 1] + CP_OFFSET_ENTRY_TAG) == CP_TAG_CONST_BOOL)
386 aBool = readBYTE(m_pIndex[index - 1] + CP_OFFSET_ENTRY_DATA) != 0;
390 return aBool;
393 sal_Int8 ConstantPool::readBYTEConstant(sal_uInt16 index)
395 sal_Int8 aByte = 0;
397 if (m_pIndex && (index> 0) && (index <= m_numOfEntries))
399 if (readUINT16(m_pIndex[index - 1] + CP_OFFSET_ENTRY_TAG) == CP_TAG_CONST_BYTE)
401 aByte = static_cast< sal_Int8 >(
402 readBYTE(m_pIndex[index - 1] + CP_OFFSET_ENTRY_DATA));
406 return aByte;
409 sal_Int16 ConstantPool::readINT16Constant(sal_uInt16 index)
411 sal_Int16 aINT16 = 0;
413 if (m_pIndex && (index> 0) && (index <= m_numOfEntries))
415 if (readUINT16(m_pIndex[index - 1] + CP_OFFSET_ENTRY_TAG) == CP_TAG_CONST_INT16)
417 aINT16 = readINT16(m_pIndex[index - 1] + CP_OFFSET_ENTRY_DATA);
421 return aINT16;
424 sal_uInt16 ConstantPool::readUINT16Constant(sal_uInt16 index)
426 sal_uInt16 asal_uInt16 = 0;
428 if (m_pIndex && (index> 0) && (index <= m_numOfEntries))
430 if (readUINT16(m_pIndex[index - 1] + CP_OFFSET_ENTRY_TAG) == CP_TAG_CONST_UINT16)
432 asal_uInt16 = readUINT16(m_pIndex[index - 1] + CP_OFFSET_ENTRY_DATA);
436 return asal_uInt16;
439 sal_Int32 ConstantPool::readINT32Constant(sal_uInt16 index)
441 sal_Int32 aINT32 = 0;
443 if (m_pIndex && (index> 0) && (index <= m_numOfEntries))
445 if (readUINT16(m_pIndex[index - 1] + CP_OFFSET_ENTRY_TAG) == CP_TAG_CONST_INT32)
447 aINT32 = readINT32(m_pIndex[index - 1] + CP_OFFSET_ENTRY_DATA);
451 return aINT32;
454 sal_uInt32 ConstantPool::readUINT32Constant(sal_uInt16 index)
456 sal_uInt32 aUINT32 = 0;
458 if (m_pIndex && (index> 0) && (index <= m_numOfEntries))
460 if (readUINT16(m_pIndex[index - 1] + CP_OFFSET_ENTRY_TAG) == CP_TAG_CONST_UINT32)
462 aUINT32 = readUINT32(m_pIndex[index - 1] + CP_OFFSET_ENTRY_DATA);
466 return aUINT32;
469 sal_Int64 ConstantPool::readINT64Constant(sal_uInt16 index)
471 sal_Int64 aINT64 = 0;
473 if (m_pIndex && (index> 0) && (index <= m_numOfEntries))
475 if (readUINT16(m_pIndex[index - 1] + CP_OFFSET_ENTRY_TAG) == CP_TAG_CONST_INT64)
477 aINT64 = readINT64(m_pIndex[index - 1] + CP_OFFSET_ENTRY_DATA);
481 return aINT64;
484 sal_uInt64 ConstantPool::readUINT64Constant(sal_uInt16 index)
486 sal_uInt64 aUINT64 = 0;
488 if (m_pIndex && (index> 0) && (index <= m_numOfEntries))
490 if (readUINT16(m_pIndex[index - 1] + CP_OFFSET_ENTRY_TAG) == CP_TAG_CONST_UINT64)
492 aUINT64 = readUINT64(m_pIndex[index - 1] + CP_OFFSET_ENTRY_DATA);
496 return aUINT64;
499 float ConstantPool::readFloatConstant(sal_uInt16 index)
501 union
503 float v;
504 sal_uInt32 b;
505 } x = { 0.0f };
507 if (m_pIndex && (index> 0) && (index <= m_numOfEntries))
509 if (readUINT16(m_pIndex[index - 1] + CP_OFFSET_ENTRY_TAG) == CP_TAG_CONST_FLOAT)
511 #ifdef REGTYPE_IEEE_NATIVE
512 x.b = readUINT32(m_pIndex[index - 1] + CP_OFFSET_ENTRY_DATA);
513 #else
514 # error no IEEE
515 #endif
519 return x.v;
522 double ConstantPool::readDoubleConstant(sal_uInt16 index)
524 union
526 double v;
527 struct
529 sal_uInt32 b1;
530 sal_uInt32 b2;
531 } b;
532 } x = { 0.0 };
534 if (m_pIndex && (index> 0) && (index <= m_numOfEntries))
536 if (readUINT16(m_pIndex[index - 1] + CP_OFFSET_ENTRY_TAG) == CP_TAG_CONST_DOUBLE)
539 #ifdef REGTYPE_IEEE_NATIVE
540 # ifdef OSL_BIGENDIAN
541 x.b.b1 = readUINT32(m_pIndex[index - 1] + CP_OFFSET_ENTRY_DATA);
542 x.b.b2 = readUINT32(m_pIndex[index - 1] + CP_OFFSET_ENTRY_DATA + sizeof(sal_uInt32));
543 # else
544 x.b.b1 = readUINT32(m_pIndex[index - 1] + CP_OFFSET_ENTRY_DATA + sizeof(sal_uInt32));
545 x.b.b2 = readUINT32(m_pIndex[index - 1] + CP_OFFSET_ENTRY_DATA);
546 # endif
547 #else
548 # error no IEEE
549 #endif
553 return x.v;
556 const sal_Unicode* ConstantPool::readStringConstant(sal_uInt16 index)
558 const sal_Unicode* aString = NULL_WSTRING;
560 if (m_pIndex && (index> 0) && (index <= m_numOfEntries) && m_pStringCache)
562 if (m_pIndex[index - 1] >= 0)
564 // create cached string now
566 if (readUINT16(m_pIndex[index - 1] + CP_OFFSET_ENTRY_TAG) == CP_TAG_CONST_STRING)
568 sal_uInt32 n = m_pIndex[index - 1] + CP_OFFSET_ENTRY_DATA;
569 if (n >= m_bufferLen
570 || (std::memchr(m_pBuffer + n, 0, m_bufferLen - n)
571 == nullptr))
573 throw BoundsError();
575 m_pIndex[index - 1] = -1 * m_pStringCache->createString(m_pBuffer + n);
579 aString = m_pStringCache->getString((sal_uInt16) (m_pIndex[index - 1] * -1));
582 return aString;
585 void ConstantPool::readUIK(sal_uInt16 index, RTUik* uik)
587 if (index == 0)
589 uik->m_Data1 = 0;
590 uik->m_Data2 = 0;
591 uik->m_Data3 = 0;
592 uik->m_Data4 = 0;
593 uik->m_Data5 = 0;
595 else if (m_pIndex && (index <= m_numOfEntries))
597 if (readUINT16(m_pIndex[index - 1] + CP_OFFSET_ENTRY_TAG) == CP_TAG_UIK)
599 uik->m_Data1 = readUINT32(m_pIndex[index - 1] + CP_OFFSET_ENTRY_UIK1);
600 uik->m_Data2 = readUINT16(m_pIndex[index - 1] + CP_OFFSET_ENTRY_UIK2);
601 uik->m_Data3 = readUINT16(m_pIndex[index - 1] + CP_OFFSET_ENTRY_UIK3);
602 uik->m_Data4 = readUINT32(m_pIndex[index - 1] + CP_OFFSET_ENTRY_UIK4);
603 uik->m_Data5 = readUINT32(m_pIndex[index - 1] + CP_OFFSET_ENTRY_UIK5);
608 /**************************************************************************
610 class FieldList
612 **************************************************************************/
614 class FieldList : public BlopObject
616 public:
618 sal_uInt16 m_numOfEntries;
619 sal_uInt16 m_numOfFieldEntries;
620 size_t m_FIELD_ENTRY_SIZE;
621 ConstantPool* m_pCP;
623 FieldList(const sal_uInt8* buffer, sal_uInt32 len, sal_uInt16 numEntries, ConstantPool* pCP)
624 : BlopObject(buffer, len, false)
625 , m_numOfEntries(numEntries)
626 , m_pCP(pCP)
628 if ( m_numOfEntries > 0 )
630 m_numOfFieldEntries = readUINT16(0);
631 m_FIELD_ENTRY_SIZE = m_numOfFieldEntries * sizeof(sal_uInt16);
632 } else
634 m_numOfFieldEntries = 0;
635 m_FIELD_ENTRY_SIZE = 0;
639 sal_uInt32 parseIndex() { return ((m_numOfEntries ? sizeof(sal_uInt16) : 0) + (m_numOfEntries * m_FIELD_ENTRY_SIZE));}
641 const sal_Char* getFieldName(sal_uInt16 index);
642 const sal_Char* getFieldType(sal_uInt16 index);
643 RTFieldAccess getFieldAccess(sal_uInt16 index);
644 RTValueType getFieldConstValue(sal_uInt16 index, RTConstValueUnion* value);
645 // throws std::bad_alloc
646 const sal_Char* getFieldDoku(sal_uInt16 index);
647 const sal_Char* getFieldFileName(sal_uInt16 index);
651 const sal_Char* FieldList::getFieldName(sal_uInt16 index)
653 const sal_Char* aName = NULL;
655 if ((m_numOfEntries > 0) && (index <= m_numOfEntries))
657 try {
658 aName = m_pCP->readUTF8NameConstant(readUINT16(sizeof(sal_uInt16) + (index * m_FIELD_ENTRY_SIZE) + FIELD_OFFSET_NAME));
659 } catch (BlopObject::BoundsError &) {
660 SAL_WARN("registry", "bad data");
664 return aName;
667 const sal_Char* FieldList::getFieldType(sal_uInt16 index)
669 const sal_Char* aName = NULL;
671 if ((m_numOfEntries > 0) && (index <= m_numOfEntries))
673 try {
674 aName = m_pCP->readUTF8NameConstant(readUINT16(sizeof(sal_uInt16) + (index * m_FIELD_ENTRY_SIZE) + FIELD_OFFSET_TYPE));
675 } catch (BlopObject::BoundsError &) {
676 SAL_WARN("registry", "bad data");
680 return aName;
683 RTFieldAccess FieldList::getFieldAccess(sal_uInt16 index)
685 RTFieldAccess aAccess = RTFieldAccess::INVALID;
687 if ((m_numOfEntries > 0) && (index <= m_numOfEntries))
689 try {
690 aAccess = (RTFieldAccess) readUINT16(sizeof(sal_uInt16) + (index * m_FIELD_ENTRY_SIZE) + FIELD_OFFSET_ACCESS);
691 } catch (BlopObject::BoundsError &) {
692 SAL_WARN("registry", "bad data");
696 return aAccess;
699 RTValueType FieldList::getFieldConstValue(sal_uInt16 index, RTConstValueUnion* value)
701 RTValueType ret = RT_TYPE_NONE;
702 try {
703 if ((m_numOfEntries > 0) && (index <= m_numOfEntries))
705 sal_uInt16 cpIndex = readUINT16(sizeof(sal_uInt16) + (index * m_FIELD_ENTRY_SIZE) + FIELD_OFFSET_VALUE);
706 switch (m_pCP->readTag(cpIndex))
708 case CP_TAG_CONST_BOOL:
709 value->aBool = m_pCP->readBOOLConstant(cpIndex);
710 ret = RT_TYPE_BOOL;
711 break;
712 case CP_TAG_CONST_BYTE:
713 value->aByte = m_pCP->readBYTEConstant(cpIndex);
714 ret = RT_TYPE_BYTE;
715 break;
716 case CP_TAG_CONST_INT16:
717 value->aShort = m_pCP->readINT16Constant(cpIndex);
718 ret = RT_TYPE_INT16;
719 break;
720 case CP_TAG_CONST_UINT16:
721 value->aUShort = m_pCP->readUINT16Constant(cpIndex);
722 ret = RT_TYPE_UINT16;
723 break;
724 case CP_TAG_CONST_INT32:
725 value->aLong = m_pCP->readINT32Constant(cpIndex);
726 ret = RT_TYPE_INT32;
727 break;
728 case CP_TAG_CONST_UINT32:
729 value->aULong = m_pCP->readUINT32Constant(cpIndex);
730 ret = RT_TYPE_UINT32;
731 break;
732 case CP_TAG_CONST_INT64:
733 value->aHyper = m_pCP->readINT64Constant(cpIndex);
734 ret = RT_TYPE_INT64;
735 break;
736 case CP_TAG_CONST_UINT64:
737 value->aUHyper = m_pCP->readUINT64Constant(cpIndex);
738 ret = RT_TYPE_UINT64;
739 break;
740 case CP_TAG_CONST_FLOAT:
741 value->aFloat = m_pCP->readFloatConstant(cpIndex);
742 ret = RT_TYPE_FLOAT;
743 break;
744 case CP_TAG_CONST_DOUBLE:
745 value->aDouble = m_pCP->readDoubleConstant(cpIndex);
746 ret = RT_TYPE_DOUBLE;
747 break;
748 case CP_TAG_CONST_STRING:
749 value->aString = m_pCP->readStringConstant(cpIndex);
750 ret = RT_TYPE_STRING;
751 break;
752 default:
753 break;
756 } catch (BlopObject::BoundsError &) {
757 SAL_WARN("registry", "bad data");
759 return ret;
762 const sal_Char* FieldList::getFieldDoku(sal_uInt16 index)
764 const sal_Char* aDoku = NULL;
766 if ((m_numOfEntries > 0) && (index <= m_numOfEntries))
768 try {
769 aDoku = m_pCP->readUTF8NameConstant(readUINT16(sizeof(sal_uInt16) + (index * m_FIELD_ENTRY_SIZE) + FIELD_OFFSET_DOKU));
770 } catch (BlopObject::BoundsError &) {
771 SAL_WARN("registry", "bad data");
775 return aDoku;
778 const sal_Char* FieldList::getFieldFileName(sal_uInt16 index)
780 const sal_Char* aFileName = NULL;
782 if ((m_numOfEntries > 0) && (index <= m_numOfEntries))
784 try {
785 aFileName = m_pCP->readUTF8NameConstant(readUINT16(sizeof(sal_uInt16) + (index * m_FIELD_ENTRY_SIZE) + FIELD_OFFSET_FILENAME));
786 } catch (BlopObject::BoundsError &) {
787 SAL_WARN("registry", "bad data");
791 return aFileName;
794 /**************************************************************************
796 class ReferenceList
798 **************************************************************************/
800 class ReferenceList : public BlopObject
802 public:
804 sal_uInt16 m_numOfEntries;
805 sal_uInt16 m_numOfReferenceEntries;
806 size_t m_REFERENCE_ENTRY_SIZE;
807 ConstantPool* m_pCP;
809 ReferenceList(const sal_uInt8* buffer, sal_uInt32 len, sal_uInt16 numEntries, ConstantPool* pCP)
810 : BlopObject(buffer, len, false)
811 , m_numOfEntries(numEntries)
812 , m_pCP(pCP)
814 if ( m_numOfEntries > 0 )
816 m_numOfReferenceEntries = readUINT16(0);
817 m_REFERENCE_ENTRY_SIZE = m_numOfReferenceEntries * sizeof(sal_uInt16);
818 } else
820 m_numOfReferenceEntries = 0;
821 m_REFERENCE_ENTRY_SIZE = 0;
825 const sal_Char* getReferenceName(sal_uInt16 index);
826 RTReferenceType getReferenceType(sal_uInt16 index);
827 const sal_Char* getReferenceDoku(sal_uInt16 index);
828 RTFieldAccess getReferenceAccess(sal_uInt16 index);
832 const sal_Char* ReferenceList::getReferenceName(sal_uInt16 index)
834 const sal_Char* aName = NULL;
836 if ((m_numOfEntries > 0) && (index <= m_numOfEntries))
838 try {
839 aName = m_pCP->readUTF8NameConstant(readUINT16(sizeof(sal_uInt16) + (index * m_REFERENCE_ENTRY_SIZE) + REFERENCE_OFFSET_NAME));
840 } catch (BlopObject::BoundsError &) {
841 SAL_WARN("registry", "bad data");
845 return aName;
848 RTReferenceType ReferenceList::getReferenceType(sal_uInt16 index)
850 RTReferenceType refType = RTReferenceType::INVALID;
852 if ((m_numOfEntries > 0) && (index <= m_numOfEntries))
854 try {
855 refType = (RTReferenceType) readUINT16(sizeof(sal_uInt16) + (index * m_REFERENCE_ENTRY_SIZE) + REFERENCE_OFFSET_TYPE);
856 } catch (BlopObject::BoundsError &) {
857 SAL_WARN("registry", "bad data");
861 return refType;
864 const sal_Char* ReferenceList::getReferenceDoku(sal_uInt16 index)
866 const sal_Char* aDoku = NULL;
868 if ((m_numOfEntries > 0) && (index <= m_numOfEntries))
870 try {
871 aDoku = m_pCP->readUTF8NameConstant(readUINT16(sizeof(sal_uInt16) + (index * m_REFERENCE_ENTRY_SIZE) + REFERENCE_OFFSET_DOKU));
872 } catch (BlopObject::BoundsError &) {
873 SAL_WARN("registry", "bad data");
877 return aDoku;
880 RTFieldAccess ReferenceList::getReferenceAccess(sal_uInt16 index)
882 RTFieldAccess aAccess = RTFieldAccess::INVALID;
884 if ((m_numOfEntries > 0) && (index <= m_numOfEntries))
886 try {
887 aAccess = (RTFieldAccess) readUINT16(sizeof(sal_uInt16) + (index * m_REFERENCE_ENTRY_SIZE) + REFERENCE_OFFSET_ACCESS);
888 } catch (BlopObject::BoundsError &) {
889 SAL_WARN("registry", "bad data");
893 return aAccess;
896 /**************************************************************************
898 class MethodList
900 **************************************************************************/
902 class MethodList : public BlopObject
904 public:
906 sal_uInt16 m_numOfEntries;
907 sal_uInt16 m_numOfMethodEntries;
908 sal_uInt16 m_numOfParamEntries;
909 size_t m_PARAM_ENTRY_SIZE;
910 sal_uInt32* m_pIndex;
911 ConstantPool* m_pCP;
913 MethodList(const sal_uInt8* buffer, sal_uInt32 len, sal_uInt16 numEntries, ConstantPool* pCP)
914 : BlopObject(buffer, len, false)
915 , m_numOfEntries(numEntries)
916 , m_pIndex(NULL)
917 , m_pCP(pCP)
919 if ( m_numOfEntries > 0 )
921 m_numOfMethodEntries = readUINT16(0);
922 m_numOfParamEntries = readUINT16(sizeof(sal_uInt16));
923 m_PARAM_ENTRY_SIZE = m_numOfParamEntries * sizeof(sal_uInt16);
924 } else
926 m_numOfMethodEntries = 0;
927 m_numOfParamEntries = 0;
928 m_PARAM_ENTRY_SIZE = 0;
932 ~MethodList();
934 sal_uInt32 parseIndex(); // throws std::bad_alloc
936 const sal_Char* getMethodName(sal_uInt16 index);
937 sal_uInt16 getMethodParamCount(sal_uInt16 index);
938 const sal_Char* getMethodParamType(sal_uInt16 index, sal_uInt16 paramIndex);
939 const sal_Char* getMethodParamName(sal_uInt16 index, sal_uInt16 paramIndex);
940 RTParamMode getMethodParamMode(sal_uInt16 index, sal_uInt16 paramIndex);
941 sal_uInt16 getMethodExcCount(sal_uInt16 index);
942 const sal_Char* getMethodExcType(sal_uInt16 index, sal_uInt16 excIndex);
943 const sal_Char* getMethodReturnType(sal_uInt16 index);
944 RTMethodMode getMethodMode(sal_uInt16 index);
945 const sal_Char* getMethodDoku(sal_uInt16 index);
947 private:
948 sal_uInt16 calcMethodParamIndex( const sal_uInt16 index );
951 MethodList::~MethodList()
953 if (m_pIndex) delete[] m_pIndex;
956 sal_uInt16 MethodList::calcMethodParamIndex( const sal_uInt16 index )
958 return (METHOD_OFFSET_PARAM_COUNT + sizeof(sal_uInt16) + (index * m_PARAM_ENTRY_SIZE));
961 sal_uInt32 MethodList::parseIndex()
963 if (m_pIndex)
965 delete[] m_pIndex;
966 m_pIndex = NULL;
969 sal_uInt32 offset = 0;
971 if (m_numOfEntries)
973 offset = 2 * sizeof(sal_uInt16);
974 m_pIndex = new sal_uInt32[m_numOfEntries];
976 for (int i = 0; i < m_numOfEntries; i++)
978 m_pIndex[i] = offset;
980 offset += readUINT16(offset);
984 return offset;
987 const sal_Char* MethodList::getMethodName(sal_uInt16 index)
989 const sal_Char* aName = NULL;
991 if ((m_numOfEntries > 0) && (index <= m_numOfEntries))
993 try {
994 aName = m_pCP->readUTF8NameConstant(readUINT16(m_pIndex[index] + METHOD_OFFSET_NAME));
995 } catch (BlopObject::BoundsError &) {
996 SAL_WARN("registry", "bad data");
1000 return aName;
1003 sal_uInt16 MethodList::getMethodParamCount(sal_uInt16 index)
1005 sal_uInt16 aCount = 0;
1007 if ((m_numOfEntries > 0) && (index <= m_numOfEntries))
1009 try {
1010 aCount = readUINT16(m_pIndex[index] + METHOD_OFFSET_PARAM_COUNT);
1011 } catch (BlopObject::BoundsError &) {
1012 SAL_WARN("registry", "bad data");
1016 return aCount;
1019 const sal_Char* MethodList::getMethodParamType(sal_uInt16 index, sal_uInt16 paramIndex)
1021 const sal_Char* aName = NULL;
1022 try {
1023 if ((m_numOfEntries > 0) &&
1024 (index <= m_numOfEntries) &&
1025 (paramIndex <= readUINT16(m_pIndex[index] + METHOD_OFFSET_PARAM_COUNT)))
1027 aName = m_pCP->readUTF8NameConstant(
1028 readUINT16(
1029 m_pIndex[index] +
1030 calcMethodParamIndex(paramIndex) +
1031 PARAM_OFFSET_TYPE));
1033 } catch (BlopObject::BoundsError &) {
1034 SAL_WARN("registry", "bad data");
1036 return aName;
1039 const sal_Char* MethodList::getMethodParamName(sal_uInt16 index, sal_uInt16 paramIndex)
1041 const sal_Char* aName = NULL;
1042 try {
1043 if ((m_numOfEntries > 0) &&
1044 (index <= m_numOfEntries) &&
1045 (paramIndex <= readUINT16(m_pIndex[index] + METHOD_OFFSET_PARAM_COUNT)))
1047 aName = m_pCP->readUTF8NameConstant(
1048 readUINT16(
1049 m_pIndex[index] +
1050 calcMethodParamIndex(paramIndex) +
1051 PARAM_OFFSET_NAME));
1053 } catch (BlopObject::BoundsError &) {
1054 SAL_WARN("registry", "bad data");
1056 return aName;
1059 RTParamMode MethodList::getMethodParamMode(sal_uInt16 index, sal_uInt16 paramIndex)
1061 RTParamMode aMode = RT_PARAM_INVALID;
1062 try {
1063 if ((m_numOfEntries > 0) &&
1064 (index <= m_numOfEntries) &&
1065 (paramIndex <= readUINT16(m_pIndex[index] + METHOD_OFFSET_PARAM_COUNT)))
1067 aMode = (RTParamMode) readUINT16(
1068 m_pIndex[index] +
1069 calcMethodParamIndex(paramIndex) +
1070 PARAM_OFFSET_MODE);
1072 } catch (BlopObject::BoundsError &) {
1073 SAL_WARN("registry", "bad data");
1075 return aMode;
1078 sal_uInt16 MethodList::getMethodExcCount(sal_uInt16 index)
1080 sal_uInt16 aCount = 0;
1082 if ((m_numOfEntries > 0) && (index <= m_numOfEntries))
1084 try {
1085 aCount = readUINT16(m_pIndex[index] + calcMethodParamIndex(readUINT16(m_pIndex[index] + METHOD_OFFSET_PARAM_COUNT)));
1086 } catch (BlopObject::BoundsError &) {
1087 SAL_WARN("registry", "bad data");
1091 return aCount;
1094 const sal_Char* MethodList::getMethodExcType(sal_uInt16 index, sal_uInt16 excIndex)
1096 const sal_Char* aName = NULL;
1098 if ((m_numOfEntries > 0) && (index <= m_numOfEntries))
1100 try {
1101 sal_uInt32 excOffset = m_pIndex[index] + calcMethodParamIndex(readUINT16(m_pIndex[index] + METHOD_OFFSET_PARAM_COUNT));
1102 if (excIndex <= readUINT16(excOffset))
1104 aName = m_pCP->readUTF8NameConstant(
1105 readUINT16(
1106 excOffset +
1107 sizeof(sal_uInt16) +
1108 (excIndex * sizeof(sal_uInt16))));
1110 } catch (BlopObject::BoundsError &) {
1111 SAL_WARN("registry", "bad data");
1115 return aName;
1118 const sal_Char* MethodList::getMethodReturnType(sal_uInt16 index)
1120 const sal_Char* aName = NULL;
1122 if ((m_numOfEntries > 0) && (index <= m_numOfEntries))
1124 try {
1125 aName = m_pCP->readUTF8NameConstant(readUINT16(m_pIndex[index] + METHOD_OFFSET_RETURN));
1126 } catch (BlopObject::BoundsError &) {
1127 SAL_WARN("registry", "bad data");
1131 return aName;
1134 RTMethodMode MethodList::getMethodMode(sal_uInt16 index)
1136 RTMethodMode aMode = RTMethodMode::INVALID;
1138 if ((m_numOfEntries > 0) && (index <= m_numOfEntries))
1140 try {
1141 aMode = (RTMethodMode) readUINT16(m_pIndex[index] + METHOD_OFFSET_MODE);
1142 } catch (BlopObject::BoundsError &) {
1143 SAL_WARN("registry", "bad data");
1147 return aMode;
1150 const sal_Char* MethodList::getMethodDoku(sal_uInt16 index)
1152 const sal_Char* aDoku = NULL;
1154 if ((m_numOfEntries > 0) && (index <= m_numOfEntries))
1156 try {
1157 aDoku = m_pCP->readUTF8NameConstant(readUINT16(m_pIndex[index] + METHOD_OFFSET_DOKU));
1158 } catch (BlopObject::BoundsError &) {
1159 SAL_WARN("registry", "bad data");
1163 return aDoku;
1166 /**************************************************************************
1168 class TypeRegistryEntry
1170 **************************************************************************/
1172 class TypeRegistryEntry: public BlopObject {
1173 public:
1174 std::unique_ptr<ConstantPool> m_pCP;
1175 std::unique_ptr<FieldList> m_pFields;
1176 std::unique_ptr<MethodList> m_pMethods;
1177 std::unique_ptr<ReferenceList> m_pReferences;
1178 sal_uInt32 m_refCount;
1179 sal_uInt16 m_nSuperTypes;
1180 sal_uInt32 m_offset_SUPERTYPES;
1182 TypeRegistryEntry(
1183 const sal_uInt8* buffer, sal_uInt32 len, bool copyBuffer);
1184 // throws std::bad_alloc
1186 typereg_Version getVersion() const;
1189 TypeRegistryEntry::TypeRegistryEntry(
1190 const sal_uInt8* buffer, sal_uInt32 len, bool copyBuffer):
1191 BlopObject(buffer, len, copyBuffer), m_refCount(1), m_nSuperTypes(0),
1192 m_offset_SUPERTYPES(0)
1194 std::size_t const entrySize = sizeof(sal_uInt16);
1195 sal_uInt16 nHeaderEntries = readUINT16(OFFSET_N_ENTRIES);
1196 sal_uInt32 offset_N_SUPERTYPES = OFFSET_N_ENTRIES + entrySize + (nHeaderEntries * entrySize); // cannot overflow
1197 m_offset_SUPERTYPES = offset_N_SUPERTYPES + entrySize; // cannot overflow
1198 m_nSuperTypes = readUINT16(offset_N_SUPERTYPES);
1200 sal_uInt32 offset_CP_SIZE = m_offset_SUPERTYPES + (m_nSuperTypes * entrySize); // cannot overflow
1201 sal_uInt32 offset_CP = offset_CP_SIZE + entrySize; // cannot overflow
1203 if (offset_CP > m_bufferLen) {
1204 throw BoundsError();
1206 m_pCP.reset(
1207 new ConstantPool(
1208 m_pBuffer + offset_CP, m_bufferLen - offset_CP,
1209 readUINT16(offset_CP_SIZE)));
1211 sal_uInt32 offset = offset_CP + m_pCP->parseIndex(); //TODO: overflow
1213 assert(m_bufferLen >= entrySize);
1214 if (offset > m_bufferLen - entrySize) {
1215 throw BoundsError();
1217 m_pFields.reset(
1218 new FieldList(
1219 m_pBuffer + offset + entrySize, m_bufferLen - (offset + entrySize),
1220 readUINT16(offset), m_pCP.get()));
1222 offset += sizeof(sal_uInt16) + m_pFields->parseIndex(); //TODO: overflow
1224 assert(m_bufferLen >= entrySize);
1225 if (offset > m_bufferLen - entrySize) {
1226 throw BoundsError();
1228 m_pMethods.reset(
1229 new MethodList(
1230 m_pBuffer + offset + entrySize, m_bufferLen - (offset + entrySize),
1231 readUINT16(offset), m_pCP.get()));
1233 offset += sizeof(sal_uInt16) + m_pMethods->parseIndex(); //TODO: overflow
1235 assert(m_bufferLen >= entrySize);
1236 if (offset > m_bufferLen - entrySize) {
1237 throw BoundsError();
1239 m_pReferences.reset(
1240 new ReferenceList(
1241 m_pBuffer + offset + entrySize, m_bufferLen - (offset + entrySize),
1242 readUINT16(offset), m_pCP.get()));
1245 typereg_Version TypeRegistryEntry::getVersion() const {
1246 // Assumes two's complement arithmetic with modulo-semantics:
1247 return static_cast< typereg_Version >(readUINT32(OFFSET_MAGIC) - magic);
1250 /**************************************************************************
1252 C-API
1254 **************************************************************************/
1256 bool TYPEREG_CALLTYPE typereg_reader_create(
1257 void const * buffer, sal_uInt32 length, bool copy,
1258 typereg_Version maxVersion, void ** result)
1260 if (length < OFFSET_CP || length > SAL_MAX_UINT32) {
1261 *result = 0;
1262 return true;
1264 std::unique_ptr< TypeRegistryEntry > entry;
1265 try {
1266 try {
1267 entry.reset(
1268 new TypeRegistryEntry(
1269 static_cast< sal_uInt8 const * >(buffer),
1270 static_cast< sal_uInt32 >(length), copy));
1271 } catch (std::bad_alloc &) {
1272 return false;
1274 if (entry->readUINT32(OFFSET_SIZE) != length) {
1275 *result = 0;
1276 return true;
1278 typereg_Version version = entry->getVersion();;
1279 if (version < TYPEREG_VERSION_0 || version > maxVersion) {
1280 *result = 0;
1281 return true;
1283 *result = entry.release();
1284 return true;
1285 } catch (BlopObject::BoundsError &) {
1286 SAL_WARN("registry", "bad data");
1287 return false;
1291 static TypeReaderImpl TYPEREG_CALLTYPE createEntry(const sal_uInt8* buffer, sal_uInt32 len, bool copyBuffer)
1293 void * handle;
1294 typereg_reader_create(buffer, len, copyBuffer, TYPEREG_VERSION_1, &handle);
1295 return handle;
1298 void TYPEREG_CALLTYPE typereg_reader_acquire(void * hEntry)
1300 TypeRegistryEntry* pEntry = static_cast<TypeRegistryEntry*>(hEntry);
1302 if (pEntry != NULL)
1303 pEntry->m_refCount++;
1306 void TYPEREG_CALLTYPE typereg_reader_release(void * hEntry)
1308 TypeRegistryEntry* pEntry = static_cast<TypeRegistryEntry*>(hEntry);
1310 if (pEntry != NULL)
1312 if (--pEntry->m_refCount == 0)
1313 delete pEntry;
1317 typereg_Version TYPEREG_CALLTYPE typereg_reader_getVersion(void * handle) {
1318 if (handle != nullptr) {
1319 try {
1320 return static_cast< TypeRegistryEntry * >(handle)->getVersion();
1321 } catch (BlopObject::BoundsError &) {
1322 SAL_WARN("registry", "bad data");
1325 return TYPEREG_VERSION_0;
1328 static sal_uInt16 TYPEREG_CALLTYPE getMinorVersion(TypeReaderImpl hEntry)
1330 TypeRegistryEntry* pEntry = static_cast<TypeRegistryEntry*>(hEntry);
1331 if (pEntry != nullptr) {
1332 try {
1333 return pEntry->readUINT16(OFFSET_MINOR_VERSION);
1334 } catch (BlopObject::BoundsError &) {
1335 SAL_WARN("registry", "bad data");
1338 return 0;
1341 static sal_uInt16 TYPEREG_CALLTYPE getMajorVersion(TypeReaderImpl hEntry)
1343 TypeRegistryEntry* pEntry = static_cast<TypeRegistryEntry*>(hEntry);
1344 if (pEntry != nullptr) {
1345 try {
1346 return pEntry->readUINT16(OFFSET_MAJOR_VERSION);
1347 } catch (BlopObject::BoundsError &) {
1348 SAL_WARN("registry", "bad data");
1351 return 0;
1354 RTTypeClass TYPEREG_CALLTYPE typereg_reader_getTypeClass(void * hEntry)
1356 TypeRegistryEntry* pEntry = static_cast<TypeRegistryEntry*>(hEntry);
1357 if (pEntry != nullptr) {
1358 try {
1359 return (RTTypeClass)
1360 (pEntry->readUINT16(OFFSET_TYPE_CLASS) & ~RT_TYPE_PUBLISHED);
1361 } catch (BlopObject::BoundsError &) {
1362 SAL_WARN("registry", "bad data");
1365 return RT_TYPE_INVALID;
1368 bool TYPEREG_CALLTYPE typereg_reader_isPublished(void * hEntry)
1370 TypeRegistryEntry * entry = static_cast< TypeRegistryEntry * >(hEntry);
1371 if (entry != nullptr) {
1372 try {
1373 return (entry->readUINT16(OFFSET_TYPE_CLASS) & RT_TYPE_PUBLISHED) != 0;
1374 } catch (BlopObject::BoundsError &) {
1375 SAL_WARN("registry", "bad data");
1378 return false;
1381 void TYPEREG_CALLTYPE typereg_reader_getTypeName(void * hEntry, rtl_uString** pTypeName)
1383 TypeRegistryEntry* pEntry = static_cast<TypeRegistryEntry*>(hEntry);
1384 if (pEntry != nullptr) {
1385 try {
1386 const sal_Char* pTmp = pEntry->m_pCP->readUTF8NameConstant(pEntry->readUINT16(OFFSET_THIS_TYPE));
1387 rtl_string2UString(
1388 pTypeName, pTmp, pTmp == 0 ? 0 : rtl_str_getLength(pTmp),
1389 RTL_TEXTENCODING_UTF8, OSTRING_TO_OUSTRING_CVTFLAGS);
1390 return;
1391 } catch (BlopObject::BoundsError &) {
1392 SAL_WARN("registry", "bad data");
1395 rtl_uString_new(pTypeName);
1399 static void TYPEREG_CALLTYPE getSuperTypeName(TypeReaderImpl hEntry, rtl_uString** pSuperTypeName)
1401 TypeRegistryEntry* pEntry = static_cast<TypeRegistryEntry*>(hEntry);
1402 if (pEntry != nullptr && pEntry->m_nSuperTypes != 0) {
1403 try {
1404 const sal_Char* pTmp = pEntry->m_pCP->readUTF8NameConstant(pEntry->readUINT16(pEntry->m_offset_SUPERTYPES )); //+ (index * sizeof(sal_uInt16))));
1405 rtl_string2UString(
1406 pSuperTypeName, pTmp, pTmp == 0 ? 0 : rtl_str_getLength(pTmp),
1407 RTL_TEXTENCODING_UTF8, OSTRING_TO_OUSTRING_CVTFLAGS);
1408 return;
1409 } catch (BlopObject::BoundsError &) {
1410 SAL_WARN("registry", "bad data");
1413 rtl_uString_new(pSuperTypeName);
1416 static void TYPEREG_CALLTYPE getUik(TypeReaderImpl hEntry, RTUik* uik)
1418 TypeRegistryEntry* pEntry = static_cast<TypeRegistryEntry*>(hEntry);
1420 if (pEntry != NULL)
1422 try {
1423 pEntry->m_pCP->readUIK(pEntry->readUINT16(OFFSET_UIK), uik);
1424 } catch (BlopObject::BoundsError &) {
1425 SAL_WARN("registry", "bad data");
1430 void TYPEREG_CALLTYPE typereg_reader_getDocumentation(void * hEntry, rtl_uString** pDoku)
1432 TypeRegistryEntry* pEntry = static_cast<TypeRegistryEntry*>(hEntry);
1433 if (pEntry != nullptr) {
1434 try {
1435 const sal_Char* pTmp = pEntry->m_pCP->readUTF8NameConstant(pEntry->readUINT16(OFFSET_DOKU));
1436 rtl_string2UString(
1437 pDoku, pTmp, pTmp == 0 ? 0 : rtl_str_getLength(pTmp),
1438 RTL_TEXTENCODING_UTF8, OSTRING_TO_OUSTRING_CVTFLAGS);
1439 return;
1440 } catch (BlopObject::BoundsError &) {
1441 SAL_WARN("registry", "bad data");
1444 rtl_uString_new(pDoku);
1447 void TYPEREG_CALLTYPE typereg_reader_getFileName(void * hEntry, rtl_uString** pFileName)
1449 TypeRegistryEntry* pEntry = static_cast<TypeRegistryEntry*>(hEntry);
1450 if (pEntry != nullptr) {
1451 try {
1452 const sal_Char* pTmp = pEntry->m_pCP->readUTF8NameConstant(pEntry->readUINT16(OFFSET_FILENAME));
1453 rtl_string2UString(
1454 pFileName, pTmp, pTmp == 0 ? 0 : rtl_str_getLength(pTmp),
1455 RTL_TEXTENCODING_UTF8, OSTRING_TO_OUSTRING_CVTFLAGS);
1456 return;
1457 } catch (BlopObject::BoundsError &) {
1458 SAL_WARN("registry", "bad data");
1461 rtl_uString_new(pFileName);
1465 sal_uInt16 TYPEREG_CALLTYPE typereg_reader_getFieldCount(void * hEntry)
1467 TypeRegistryEntry* pEntry = static_cast<TypeRegistryEntry*>(hEntry);
1469 if (pEntry == NULL) return 0;
1471 return pEntry->m_pFields->m_numOfEntries;
1474 static sal_uInt32 TYPEREG_CALLTYPE getFieldCount(TypeReaderImpl hEntry)
1476 return typereg_reader_getFieldCount(hEntry);
1479 void TYPEREG_CALLTYPE typereg_reader_getFieldName(void * hEntry, rtl_uString** pFieldName, sal_uInt16 index)
1481 TypeRegistryEntry* pEntry = static_cast<TypeRegistryEntry*>(hEntry);
1483 if (pEntry == NULL)
1485 rtl_uString_new(pFieldName);
1486 return;
1488 const sal_Char* pTmp = pEntry->m_pFields->getFieldName(index);
1489 rtl_string2UString(
1490 pFieldName, pTmp, pTmp == 0 ? 0 : rtl_str_getLength(pTmp),
1491 RTL_TEXTENCODING_UTF8, OSTRING_TO_OUSTRING_CVTFLAGS);
1494 void TYPEREG_CALLTYPE typereg_reader_getFieldTypeName(void * hEntry, rtl_uString** pFieldType, sal_uInt16 index)
1496 TypeRegistryEntry* pEntry = static_cast<TypeRegistryEntry*>(hEntry);
1498 if (pEntry == NULL)
1500 rtl_uString_new(pFieldType);
1501 return;
1504 const sal_Char* pTmp = pEntry->m_pFields->getFieldType(index);
1505 rtl_string2UString(
1506 pFieldType, pTmp, pTmp == 0 ? 0 : rtl_str_getLength(pTmp),
1507 RTL_TEXTENCODING_UTF8, OSTRING_TO_OUSTRING_CVTFLAGS);
1510 RTFieldAccess TYPEREG_CALLTYPE typereg_reader_getFieldFlags(void * hEntry, sal_uInt16 index)
1512 TypeRegistryEntry* pEntry = static_cast<TypeRegistryEntry*>(hEntry);
1514 if (pEntry == NULL) return RTFieldAccess::INVALID;
1516 return pEntry->m_pFields->getFieldAccess(index);
1519 bool TYPEREG_CALLTYPE typereg_reader_getFieldValue(
1520 void * hEntry, sal_uInt16 index, RTValueType * type,
1521 RTConstValueUnion * value)
1523 TypeRegistryEntry* pEntry = static_cast<TypeRegistryEntry*>(hEntry);
1525 if (pEntry == NULL) {
1526 *type = RT_TYPE_NONE;
1527 return true;
1530 try {
1531 *type = pEntry->m_pFields->getFieldConstValue(index, value);
1532 } catch (std::bad_alloc &) {
1533 return false;
1535 return true;
1538 static RTValueType TYPEREG_CALLTYPE getFieldConstValue(TypeReaderImpl hEntry, sal_uInt16 index, RTConstValueUnion* value)
1540 RTValueType t = RT_TYPE_NONE;
1541 typereg_reader_getFieldValue(hEntry, index, &t, value);
1542 return t;
1545 void TYPEREG_CALLTYPE typereg_reader_getFieldDocumentation(void * hEntry, rtl_uString** pDoku, sal_uInt16 index)
1547 TypeRegistryEntry* pEntry = static_cast<TypeRegistryEntry*>(hEntry);
1549 if (pEntry == NULL)
1551 rtl_uString_new(pDoku);
1552 return;
1555 const sal_Char* pTmp = pEntry->m_pFields->getFieldDoku(index);
1556 rtl_string2UString(
1557 pDoku, pTmp, pTmp == 0 ? 0 : rtl_str_getLength(pTmp),
1558 RTL_TEXTENCODING_UTF8, OSTRING_TO_OUSTRING_CVTFLAGS);
1561 void TYPEREG_CALLTYPE typereg_reader_getFieldFileName(void * hEntry, rtl_uString** pFieldFileName, sal_uInt16 index)
1563 TypeRegistryEntry* pEntry = static_cast<TypeRegistryEntry*>(hEntry);
1565 if (pEntry == NULL)
1567 rtl_uString_new(pFieldFileName);
1568 return;
1571 const sal_Char* pTmp = pEntry->m_pFields->getFieldFileName(index);
1572 rtl_string2UString(
1573 pFieldFileName, pTmp, pTmp == 0 ? 0 : rtl_str_getLength(pTmp),
1574 RTL_TEXTENCODING_UTF8, OSTRING_TO_OUSTRING_CVTFLAGS);
1578 sal_uInt16 TYPEREG_CALLTYPE typereg_reader_getMethodCount(void * hEntry)
1580 TypeRegistryEntry* pEntry = static_cast<TypeRegistryEntry*>(hEntry);
1582 if (pEntry == NULL) return 0;
1584 return pEntry->m_pMethods->m_numOfEntries;
1587 static sal_uInt32 TYPEREG_CALLTYPE getMethodCount(TypeReaderImpl hEntry)
1589 return typereg_reader_getMethodCount(hEntry);
1592 void TYPEREG_CALLTYPE typereg_reader_getMethodName(void * hEntry, rtl_uString** pMethodName, sal_uInt16 index)
1594 TypeRegistryEntry* pEntry = static_cast<TypeRegistryEntry*>(hEntry);
1596 if (pEntry == NULL)
1598 rtl_uString_new(pMethodName);
1599 return;
1602 const sal_Char* pTmp = pEntry->m_pMethods->getMethodName(index);
1603 rtl_string2UString(
1604 pMethodName, pTmp, pTmp == 0 ? 0 : rtl_str_getLength(pTmp),
1605 RTL_TEXTENCODING_UTF8, OSTRING_TO_OUSTRING_CVTFLAGS);
1608 sal_uInt16 TYPEREG_CALLTYPE typereg_reader_getMethodParameterCount(
1609 void * hEntry, sal_uInt16 index)
1611 TypeRegistryEntry* pEntry = static_cast<TypeRegistryEntry*>(hEntry);
1613 if (pEntry == NULL) return 0;
1615 return pEntry->m_pMethods->getMethodParamCount(index);
1618 static sal_uInt32 TYPEREG_CALLTYPE getMethodParamCount(TypeReaderImpl hEntry, sal_uInt16 index)
1620 return typereg_reader_getMethodParameterCount(hEntry, index);
1623 void TYPEREG_CALLTYPE typereg_reader_getMethodParameterTypeName(void * hEntry, rtl_uString** pMethodParamType, sal_uInt16 index, sal_uInt16 paramIndex)
1625 TypeRegistryEntry* pEntry = static_cast<TypeRegistryEntry*>(hEntry);
1627 if (pEntry == NULL)
1629 rtl_uString_new(pMethodParamType);
1630 return;
1633 const sal_Char* pTmp = pEntry->m_pMethods->getMethodParamType(index, paramIndex);
1634 rtl_string2UString(
1635 pMethodParamType, pTmp, pTmp == 0 ? 0 : rtl_str_getLength(pTmp),
1636 RTL_TEXTENCODING_UTF8, OSTRING_TO_OUSTRING_CVTFLAGS);
1639 void TYPEREG_CALLTYPE typereg_reader_getMethodParameterName(void * hEntry, rtl_uString** pMethodParamName, sal_uInt16 index, sal_uInt16 paramIndex)
1641 TypeRegistryEntry* pEntry = static_cast<TypeRegistryEntry*>(hEntry);
1643 if (pEntry == NULL)
1645 rtl_uString_new(pMethodParamName);
1646 return;
1649 const sal_Char* pTmp = pEntry->m_pMethods->getMethodParamName(index, paramIndex);
1650 rtl_string2UString(
1651 pMethodParamName, pTmp, pTmp == 0 ? 0 : rtl_str_getLength(pTmp),
1652 RTL_TEXTENCODING_UTF8, OSTRING_TO_OUSTRING_CVTFLAGS);
1655 RTParamMode TYPEREG_CALLTYPE typereg_reader_getMethodParameterFlags(void * hEntry, sal_uInt16 index, sal_uInt16 paramIndex)
1657 TypeRegistryEntry* pEntry = static_cast<TypeRegistryEntry*>(hEntry);
1659 if (pEntry == NULL) return RT_PARAM_INVALID;
1661 return pEntry->m_pMethods->getMethodParamMode(index, paramIndex);
1664 sal_uInt16 TYPEREG_CALLTYPE typereg_reader_getMethodExceptionCount(
1665 void * hEntry, sal_uInt16 index)
1667 TypeRegistryEntry* pEntry = static_cast<TypeRegistryEntry*>(hEntry);
1669 if (pEntry == NULL) return 0;
1671 return pEntry->m_pMethods->getMethodExcCount(index);
1674 static sal_uInt32 TYPEREG_CALLTYPE getMethodExcCount(TypeReaderImpl hEntry, sal_uInt16 index)
1676 return typereg_reader_getMethodExceptionCount(hEntry, index);
1679 void TYPEREG_CALLTYPE typereg_reader_getMethodExceptionTypeName(void * hEntry, rtl_uString** pMethodExcpType, sal_uInt16 index, sal_uInt16 excIndex)
1681 TypeRegistryEntry* pEntry = static_cast<TypeRegistryEntry*>(hEntry);
1683 if (pEntry == NULL)
1685 rtl_uString_new(pMethodExcpType);
1686 return;
1689 const sal_Char* pTmp = pEntry->m_pMethods->getMethodExcType(index, excIndex);
1690 rtl_string2UString(
1691 pMethodExcpType, pTmp, pTmp == 0 ? 0 : rtl_str_getLength(pTmp),
1692 RTL_TEXTENCODING_UTF8, OSTRING_TO_OUSTRING_CVTFLAGS);
1695 void TYPEREG_CALLTYPE typereg_reader_getMethodReturnTypeName(void * hEntry, rtl_uString** pMethodReturnType, sal_uInt16 index)
1697 TypeRegistryEntry* pEntry = static_cast<TypeRegistryEntry*>(hEntry);
1699 if (pEntry == NULL)
1701 rtl_uString_new(pMethodReturnType);
1702 return;
1705 const sal_Char* pTmp = pEntry->m_pMethods->getMethodReturnType(index);
1706 rtl_string2UString(
1707 pMethodReturnType, pTmp, pTmp == 0 ? 0 : rtl_str_getLength(pTmp),
1708 RTL_TEXTENCODING_UTF8, OSTRING_TO_OUSTRING_CVTFLAGS);
1711 RTMethodMode TYPEREG_CALLTYPE typereg_reader_getMethodFlags(void * hEntry, sal_uInt16 index)
1713 TypeRegistryEntry* pEntry = static_cast<TypeRegistryEntry*>(hEntry);
1715 if (pEntry == NULL) return RTMethodMode::INVALID;
1717 return pEntry->m_pMethods->getMethodMode(index);
1720 void TYPEREG_CALLTYPE typereg_reader_getMethodDocumentation(void * hEntry, rtl_uString** pMethodDoku, sal_uInt16 index)
1722 TypeRegistryEntry* pEntry = static_cast<TypeRegistryEntry*>(hEntry);
1724 if (pEntry == NULL)
1726 rtl_uString_new(pMethodDoku);
1727 return;
1730 const sal_Char* pTmp = pEntry->m_pMethods->getMethodDoku(index);
1731 rtl_string2UString(
1732 pMethodDoku, pTmp, pTmp == 0 ? 0 : rtl_str_getLength(pTmp),
1733 RTL_TEXTENCODING_UTF8, OSTRING_TO_OUSTRING_CVTFLAGS);
1736 sal_uInt16 TYPEREG_CALLTYPE typereg_reader_getReferenceCount(void * hEntry)
1738 TypeRegistryEntry* pEntry = static_cast<TypeRegistryEntry*>(hEntry);
1740 if (pEntry == NULL) return 0;
1742 return pEntry->m_pReferences->m_numOfEntries;
1745 static sal_uInt32 TYPEREG_CALLTYPE getReferenceCount(TypeReaderImpl hEntry)
1747 return typereg_reader_getReferenceCount(hEntry);
1750 void TYPEREG_CALLTYPE typereg_reader_getReferenceTypeName(void * hEntry, rtl_uString** pReferenceName, sal_uInt16 index)
1752 TypeRegistryEntry* pEntry = static_cast<TypeRegistryEntry*>(hEntry);
1754 if (pEntry == NULL)
1756 rtl_uString_new(pReferenceName);
1757 return;
1760 const sal_Char* pTmp = pEntry->m_pReferences->getReferenceName(index);
1761 rtl_string2UString(
1762 pReferenceName, pTmp, pTmp == 0 ? 0 : rtl_str_getLength(pTmp),
1763 RTL_TEXTENCODING_UTF8, OSTRING_TO_OUSTRING_CVTFLAGS);
1766 RTReferenceType TYPEREG_CALLTYPE typereg_reader_getReferenceSort(void * hEntry, sal_uInt16 index)
1768 TypeRegistryEntry* pEntry = static_cast<TypeRegistryEntry*>(hEntry);
1770 if (pEntry == NULL) return RTReferenceType::INVALID;
1772 return pEntry->m_pReferences->getReferenceType(index);
1775 void TYPEREG_CALLTYPE typereg_reader_getReferenceDocumentation(void * hEntry, rtl_uString** pReferenceDoku, sal_uInt16 index)
1777 TypeRegistryEntry* pEntry = static_cast<TypeRegistryEntry*>(hEntry);
1779 if (pEntry == NULL)
1781 rtl_uString_new(pReferenceDoku);
1782 return;
1785 const sal_Char* pTmp = pEntry->m_pReferences->getReferenceDoku(index);
1786 rtl_string2UString(
1787 pReferenceDoku, pTmp, pTmp == 0 ? 0 : rtl_str_getLength(pTmp),
1788 RTL_TEXTENCODING_UTF8, OSTRING_TO_OUSTRING_CVTFLAGS);
1791 RTFieldAccess TYPEREG_CALLTYPE typereg_reader_getReferenceFlags(void * hEntry, sal_uInt16 index)
1793 TypeRegistryEntry* pEntry = static_cast<TypeRegistryEntry*>(hEntry);
1795 if (pEntry == NULL) return RTFieldAccess::INVALID;
1797 return pEntry->m_pReferences->getReferenceAccess(index);
1800 sal_uInt16 TYPEREG_CALLTYPE typereg_reader_getSuperTypeCount(void * hEntry)
1802 TypeRegistryEntry* pEntry = static_cast<TypeRegistryEntry*>(hEntry);
1804 if (pEntry == NULL) return 0;
1806 return pEntry->m_nSuperTypes;
1809 void TYPEREG_CALLTYPE typereg_reader_getSuperTypeName(
1810 void * hEntry, rtl_uString ** pSuperTypeName, sal_uInt16 index)
1812 TypeRegistryEntry* pEntry = static_cast<TypeRegistryEntry*>(hEntry);
1813 if (pEntry != nullptr) {
1814 try {
1815 OSL_ASSERT(index < pEntry->m_nSuperTypes);
1816 const sal_Char* pTmp = pEntry->m_pCP->readUTF8NameConstant(pEntry->readUINT16(pEntry->m_offset_SUPERTYPES + (index * sizeof(sal_uInt16))));
1817 rtl_string2UString(
1818 pSuperTypeName, pTmp, pTmp == 0 ? 0 : rtl_str_getLength(pTmp),
1819 RTL_TEXTENCODING_UTF8, OSTRING_TO_OUSTRING_CVTFLAGS);
1820 return;
1821 } catch (BlopObject::BoundsError &) {
1822 SAL_WARN("registry", "bad data");
1825 rtl_uString_new(pSuperTypeName);
1828 RegistryTypeReader_Api* TYPEREG_CALLTYPE initRegistryTypeReader_Api()
1830 static RegistryTypeReader_Api aApi= {0,0,0,0,0,0,0,0,0,0,0,0,0,0,0,0,0,0,0,0,0,0,0,0,0,0,0,0,0,0,0,0,0,0};
1831 if (!aApi.acquire)
1833 aApi.createEntry = &createEntry;
1834 aApi.acquire = &typereg_reader_acquire;
1835 aApi.release = &typereg_reader_release;
1836 aApi.getMinorVersion = &getMinorVersion;
1837 aApi.getMajorVersion = &getMajorVersion;
1838 aApi.getTypeClass = &typereg_reader_getTypeClass;
1839 aApi.getTypeName = &typereg_reader_getTypeName;
1840 aApi.getSuperTypeName = &getSuperTypeName;
1841 aApi.getUik = &getUik;
1842 aApi.getDoku = &typereg_reader_getDocumentation;
1843 aApi.getFileName = &typereg_reader_getFileName;
1844 aApi.getFieldCount = &getFieldCount;
1845 aApi.getFieldName = &typereg_reader_getFieldName;
1846 aApi.getFieldType = &typereg_reader_getFieldTypeName;
1847 aApi.getFieldAccess = &typereg_reader_getFieldFlags;
1848 aApi.getFieldConstValue = &getFieldConstValue;
1849 aApi.getFieldDoku = &typereg_reader_getFieldDocumentation;
1850 aApi.getFieldFileName = &typereg_reader_getFieldFileName;
1851 aApi.getMethodCount = &getMethodCount;
1852 aApi.getMethodName = &typereg_reader_getMethodName;
1853 aApi.getMethodParamCount = &getMethodParamCount;
1854 aApi.getMethodParamType = &typereg_reader_getMethodParameterTypeName;
1855 aApi.getMethodParamName = &typereg_reader_getMethodParameterName;
1856 aApi.getMethodParamMode = &typereg_reader_getMethodParameterFlags;
1857 aApi.getMethodExcCount = &getMethodExcCount;
1858 aApi.getMethodExcType = &typereg_reader_getMethodExceptionTypeName;
1859 aApi.getMethodReturnType = &typereg_reader_getMethodReturnTypeName;
1860 aApi.getMethodMode = &typereg_reader_getMethodFlags;
1861 aApi.getMethodDoku = &typereg_reader_getMethodDocumentation;
1862 aApi.getReferenceCount = &getReferenceCount;
1863 aApi.getReferenceName = &typereg_reader_getReferenceTypeName;
1864 aApi.getReferenceType = &typereg_reader_getReferenceSort;
1865 aApi.getReferenceDoku = &typereg_reader_getReferenceDocumentation;
1866 aApi.getReferenceAccess = &typereg_reader_getReferenceFlags;
1868 return (&aApi);
1870 else
1872 return (&aApi);
1876 /* vim:set shiftwidth=4 softtabstop=4 expandtab: */