LCOV - code coverage report
Current view: top level - registry/source - reflread.cxx (source / functions) Hit Total Coverage
Test: commit c8344322a7af75b84dd3ca8f78b05543a976dfd5 Lines: 0 761 0.0 %
Date: 2015-06-13 12:38:46 Functions: 0 108 0.0 %
Legend: Lines: hit not hit

          Line data    Source code
       1             : /* -*- Mode: C++; tab-width: 4; indent-tabs-mode: nil; c-basic-offset: 4 -*- */
       2             : /*
       3             :  * This file is part of the LibreOffice project.
       4             :  *
       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/.
       8             :  *
       9             :  * This file incorporates work covered by the following license notice:
      10             :  *
      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 .
      18             :  */
      19             : 
      20             : #include <sal/config.h>
      21             : 
      22             : #include <cstring>
      23             : #include <memory>
      24             : #include <new>
      25             : 
      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>
      32             : 
      33             : #include "registry/typereg_reader.hxx"
      34             : #include "registry/version.h"
      35             : 
      36             : #include "reflcnst.hxx"
      37             : 
      38             : #include <cstddef>
      39             : 
      40             : static const sal_Char NULL_STRING[1] = { 0 };
      41             : static const sal_Unicode NULL_WSTRING[1] = { 0 };
      42             : 
      43             : const sal_uInt32    magic = 0x12345678;
      44             : const sal_uInt16 minorVersion = 0x0000;
      45             : const sal_uInt16 majorVersion = 0x0001;
      46             : 
      47             : /**************************************************************************
      48             : 
      49             :     class BlopObject
      50             : 
      51             :     holds any data in a flat memory buffer
      52             : 
      53             : **************************************************************************/
      54             : 
      55             : class BlopObject
      56             : {
      57             : public:
      58             :     struct BoundsError {};
      59             : 
      60             :     const sal_uInt8* m_pBuffer;
      61             :     sal_uInt32      m_bufferLen;
      62             :     bool            m_isCopied;
      63             : 
      64             :     BlopObject(const sal_uInt8* buffer, sal_uInt32 len, bool copyBuffer);
      65             :         // throws std::bad_alloc
      66             : 
      67             :     ~BlopObject();
      68             : 
      69           0 :     inline sal_uInt8 readBYTE(sal_uInt32 index) const
      70             :     {
      71           0 :         if (index >= m_bufferLen) {
      72           0 :             throw BoundsError();
      73             :         }
      74           0 :         return m_pBuffer[index];
      75             :     }
      76             : 
      77           0 :     inline sal_Int16 readINT16(sal_uInt32 index) const
      78             :     {
      79           0 :         if (m_bufferLen < 2 || index >= m_bufferLen - 1) {
      80           0 :             throw BoundsError();
      81             :         }
      82           0 :         return ((m_pBuffer[index] << 8) | (m_pBuffer[index+1] << 0));
      83             :     }
      84             : 
      85           0 :     inline sal_uInt16 readUINT16(sal_uInt32 index) const
      86             :     {
      87           0 :         if (m_bufferLen < 2 || index >= m_bufferLen - 1) {
      88           0 :             throw BoundsError();
      89             :         }
      90           0 :         return ((m_pBuffer[index] << 8) | (m_pBuffer[index+1] << 0));
      91             :     }
      92             : 
      93           0 :     inline sal_Int32 readINT32(sal_uInt32 index) const
      94             :     {
      95           0 :         if (m_bufferLen < 4 || index >= m_bufferLen - 3) {
      96           0 :             throw BoundsError();
      97             :         }
      98             :         return (
      99           0 :             (m_pBuffer[index]   << 24) |
     100           0 :             (m_pBuffer[index+1] << 16) |
     101           0 :             (m_pBuffer[index+2] << 8)  |
     102           0 :             (m_pBuffer[index+3] << 0)
     103           0 :         );
     104             :     }
     105             : 
     106           0 :     inline sal_uInt32 readUINT32(sal_uInt32 index) const
     107             :     {
     108           0 :         if (m_bufferLen < 4 || index >= m_bufferLen - 3) {
     109           0 :             throw BoundsError();
     110             :         }
     111             :         return (
     112           0 :             (m_pBuffer[index]   << 24) |
     113           0 :             (m_pBuffer[index+1] << 16) |
     114           0 :             (m_pBuffer[index+2] << 8)  |
     115           0 :             (m_pBuffer[index+3] << 0)
     116           0 :         );
     117             :     }
     118             : 
     119           0 :     inline sal_Int64 readINT64(sal_uInt32 index) const
     120             :     {
     121           0 :         if (m_bufferLen < 8 || index >= m_bufferLen - 7) {
     122           0 :             throw BoundsError();
     123             :         }
     124             :         return (
     125           0 :             ((sal_Int64)m_pBuffer[index]   << 56) |
     126           0 :             ((sal_Int64)m_pBuffer[index+1] << 48) |
     127           0 :             ((sal_Int64)m_pBuffer[index+2] << 40) |
     128           0 :             ((sal_Int64)m_pBuffer[index+3] << 32) |
     129           0 :             ((sal_Int64)m_pBuffer[index+4] << 24) |
     130           0 :             ((sal_Int64)m_pBuffer[index+5] << 16) |
     131           0 :             ((sal_Int64)m_pBuffer[index+6] << 8)  |
     132           0 :             ((sal_Int64)m_pBuffer[index+7] << 0)
     133           0 :         );
     134             :     }
     135             : 
     136           0 :     inline sal_uInt64 readUINT64(sal_uInt32 index) const
     137             :     {
     138           0 :         if (m_bufferLen < 8 || index >= m_bufferLen - 7) {
     139           0 :             throw BoundsError();
     140             :         }
     141             :         return (
     142           0 :             ((sal_uInt64)m_pBuffer[index]   << 56) |
     143           0 :             ((sal_uInt64)m_pBuffer[index+1] << 48) |
     144           0 :             ((sal_uInt64)m_pBuffer[index+2] << 40) |
     145           0 :             ((sal_uInt64)m_pBuffer[index+3] << 32) |
     146           0 :             ((sal_uInt64)m_pBuffer[index+4] << 24) |
     147           0 :             ((sal_uInt64)m_pBuffer[index+5] << 16) |
     148           0 :             ((sal_uInt64)m_pBuffer[index+6] << 8)  |
     149           0 :             ((sal_uInt64)m_pBuffer[index+7] << 0)
     150           0 :         );
     151             :     }
     152             : };
     153             : 
     154           0 : BlopObject::BlopObject(const sal_uInt8* buffer, sal_uInt32 len, bool copyBuffer)
     155             :     : m_bufferLen(len)
     156           0 :     , m_isCopied(copyBuffer)
     157             : {
     158           0 :     if (m_isCopied)
     159             :     {
     160           0 :         m_pBuffer = 0;
     161           0 :         sal_uInt8* newBuffer = new sal_uInt8[len];
     162           0 :         memcpy(newBuffer, buffer, len);
     163           0 :         m_pBuffer = newBuffer;
     164             :     }
     165             :     else
     166             :     {
     167           0 :         m_pBuffer = buffer;
     168             :     }
     169           0 : }
     170             : 
     171           0 : BlopObject::~BlopObject()
     172             : {
     173           0 :     if (m_isCopied)
     174             :     {
     175           0 :         delete[] m_pBuffer;
     176             :     }
     177           0 : }
     178             : 
     179             : /**************************************************************************
     180             : 
     181             :     class StringCache
     182             : 
     183             : **************************************************************************/
     184             : 
     185             : class StringCache
     186             : {
     187             : public:
     188             :     sal_Unicode**   m_stringTable;
     189             :     sal_uInt16      m_numOfStrings;
     190             :     sal_uInt16      m_stringsCopied;
     191             : 
     192             :     StringCache(sal_uInt16 size); // throws std::bad_alloc
     193             :     ~StringCache();
     194             : 
     195             :     const sal_Unicode*  getString(sal_uInt16 index);
     196             :     sal_uInt16 createString(const sal_uInt8* buffer); // throws std::bad_alloc
     197             : };
     198             : 
     199           0 : StringCache::StringCache(sal_uInt16 size)
     200             :     : m_stringTable(NULL)
     201             :     , m_numOfStrings(size)
     202           0 :     , m_stringsCopied(0)
     203             : {
     204           0 :     m_stringTable = new sal_Unicode*[m_numOfStrings];
     205             : 
     206           0 :     for (sal_uInt16 i = 0; i < m_numOfStrings; i++)
     207             :     {
     208           0 :         m_stringTable[i] = NULL;
     209             :     }
     210           0 : }
     211             : 
     212           0 : StringCache::~StringCache()
     213             : {
     214           0 :     if (m_stringTable)
     215             :     {
     216           0 :         for (sal_uInt16 i = 0; i < m_stringsCopied; i++)
     217             :         {
     218           0 :             delete[] m_stringTable[i];
     219             :         }
     220             : 
     221           0 :         delete[] m_stringTable;
     222             :     }
     223           0 : }
     224             : 
     225           0 : const sal_Unicode* StringCache::getString(sal_uInt16 index)
     226             : {
     227           0 :     if ((index > 0) && (index <= m_stringsCopied))
     228           0 :         return m_stringTable[index - 1];
     229             :     else
     230           0 :         return NULL;
     231             : }
     232             : 
     233           0 : sal_uInt16 StringCache::createString(const sal_uInt8* buffer)
     234             : {
     235           0 :     if (m_stringsCopied < m_numOfStrings)
     236             :     {
     237           0 :         sal_uInt32 len = UINT16StringLen(buffer);
     238             : 
     239           0 :         m_stringTable[m_stringsCopied] = new sal_Unicode[len + 1];
     240             : 
     241           0 :         readString(buffer, m_stringTable[m_stringsCopied], (len + 1) * sizeof(sal_Unicode));
     242             : 
     243           0 :         return ++m_stringsCopied;
     244             :     }
     245             :     else
     246           0 :         return 0;
     247             : }
     248             : 
     249             : /**************************************************************************
     250             : 
     251             :     class ConstantPool
     252             : 
     253             : **************************************************************************/
     254             : 
     255             : class ConstantPool : public BlopObject
     256             : {
     257             : public:
     258             : 
     259             :     sal_uInt16  m_numOfEntries;
     260             :     sal_Int32*  m_pIndex;           // index values may be < 0 for cached string constants
     261             : 
     262             :     StringCache* m_pStringCache;
     263             : 
     264           0 :     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           0 :         , m_pStringCache(NULL)
     269             :     {
     270           0 :     }
     271             : 
     272             :     ~ConstantPool();
     273             : 
     274             :     sal_uInt32 parseIndex(); // throws std::bad_alloc
     275             : 
     276             :     CPInfoTag       readTag(sal_uInt16 index);
     277             : 
     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);
     292             : };
     293             : 
     294           0 : ConstantPool::~ConstantPool()
     295             : {
     296           0 :     delete[] m_pIndex;
     297           0 :     delete m_pStringCache;
     298           0 : }
     299             : 
     300           0 : sal_uInt32 ConstantPool::parseIndex()
     301             : {
     302           0 :     if (m_pIndex)
     303             :     {
     304           0 :         delete[] m_pIndex;
     305           0 :         m_pIndex = NULL;
     306             :     }
     307             : 
     308           0 :     if (m_pStringCache)
     309             :     {
     310           0 :         delete m_pStringCache;
     311           0 :         m_pStringCache = NULL;
     312             :     }
     313             : 
     314           0 :     sal_uInt32  offset = 0;
     315           0 :     sal_uInt16  numOfStrings = 0;
     316             : 
     317           0 :     if (m_numOfEntries)
     318             :     {
     319           0 :         m_pIndex = new sal_Int32[m_numOfEntries];
     320             : 
     321           0 :         for (int i = 0; i < m_numOfEntries; i++)
     322             :         {
     323           0 :             m_pIndex[i] = offset;
     324             : 
     325           0 :             offset += readUINT32(offset);
     326             : 
     327           0 :             if ( ((CPInfoTag) readUINT16(m_pIndex[i] + CP_OFFSET_ENTRY_TAG)) ==
     328             :                  CP_TAG_CONST_STRING )
     329             :             {
     330           0 :                 numOfStrings++;
     331             :             }
     332             : 
     333             :         }
     334             :     }
     335             : 
     336           0 :     if (numOfStrings)
     337             :     {
     338           0 :         m_pStringCache = new StringCache(numOfStrings);
     339             :     }
     340             : 
     341           0 :     m_bufferLen = offset;
     342             : 
     343           0 :     return offset;
     344             : }
     345             : 
     346           0 : CPInfoTag ConstantPool::readTag(sal_uInt16 index)
     347             : {
     348           0 :     CPInfoTag tag = CP_TAG_INVALID;
     349             : 
     350           0 :     if (m_pIndex && (index > 0) && (index <= m_numOfEntries))
     351             :     {
     352           0 :         tag = (CPInfoTag) readUINT16(m_pIndex[index - 1] + CP_OFFSET_ENTRY_TAG);
     353             :     }
     354             : 
     355           0 :     return tag;
     356             : }
     357             : 
     358           0 : const sal_Char* ConstantPool::readUTF8NameConstant(sal_uInt16 index)
     359             : {
     360           0 :     const sal_Char* aName = NULL_STRING;
     361             : 
     362           0 :     if (m_pIndex && (index > 0) && (index <= m_numOfEntries))
     363             :     {
     364           0 :         if (readUINT16(m_pIndex[index - 1] + CP_OFFSET_ENTRY_TAG) == CP_TAG_UTF8_NAME)
     365             :         {
     366           0 :             sal_uInt32 n = m_pIndex[index - 1] + CP_OFFSET_ENTRY_DATA;
     367           0 :             if (n < m_bufferLen
     368           0 :                 && std::memchr(m_pBuffer + n, 0, m_bufferLen - n) != nullptr)
     369             :             {
     370           0 :                 aName = reinterpret_cast<const char*>(m_pBuffer + n);
     371             :             }
     372             :         }
     373             :     }
     374             : 
     375           0 :     return aName;
     376             : }
     377             : 
     378           0 : bool ConstantPool::readBOOLConstant(sal_uInt16 index)
     379             : {
     380           0 :     bool aBool = false;
     381             : 
     382           0 :     if (m_pIndex && (index> 0) && (index <= m_numOfEntries))
     383             :     {
     384           0 :         if (readUINT16(m_pIndex[index - 1] + CP_OFFSET_ENTRY_TAG) == CP_TAG_CONST_BOOL)
     385             :         {
     386           0 :             aBool = readBYTE(m_pIndex[index - 1] + CP_OFFSET_ENTRY_DATA) != 0;
     387             :         }
     388             :     }
     389             : 
     390           0 :     return aBool;
     391             : }
     392             : 
     393           0 : sal_Int8 ConstantPool::readBYTEConstant(sal_uInt16 index)
     394             : {
     395           0 :     sal_Int8 aByte = 0;
     396             : 
     397           0 :     if (m_pIndex && (index> 0) && (index <= m_numOfEntries))
     398             :     {
     399           0 :         if (readUINT16(m_pIndex[index - 1] + CP_OFFSET_ENTRY_TAG) == CP_TAG_CONST_BYTE)
     400             :         {
     401             :             aByte = static_cast< sal_Int8 >(
     402           0 :                 readBYTE(m_pIndex[index - 1] + CP_OFFSET_ENTRY_DATA));
     403             :         }
     404             :     }
     405             : 
     406           0 :     return aByte;
     407             : }
     408             : 
     409           0 : sal_Int16 ConstantPool::readINT16Constant(sal_uInt16 index)
     410             : {
     411           0 :     sal_Int16 aINT16 = 0;
     412             : 
     413           0 :     if (m_pIndex && (index> 0) && (index <= m_numOfEntries))
     414             :     {
     415           0 :         if (readUINT16(m_pIndex[index - 1] + CP_OFFSET_ENTRY_TAG) == CP_TAG_CONST_INT16)
     416             :         {
     417           0 :             aINT16 = readINT16(m_pIndex[index - 1] + CP_OFFSET_ENTRY_DATA);
     418             :         }
     419             :     }
     420             : 
     421           0 :     return aINT16;
     422             : }
     423             : 
     424           0 : sal_uInt16 ConstantPool::readUINT16Constant(sal_uInt16 index)
     425             : {
     426           0 :     sal_uInt16 asal_uInt16 = 0;
     427             : 
     428           0 :     if (m_pIndex && (index> 0) && (index <= m_numOfEntries))
     429             :     {
     430           0 :         if (readUINT16(m_pIndex[index - 1] + CP_OFFSET_ENTRY_TAG) == CP_TAG_CONST_UINT16)
     431             :         {
     432           0 :             asal_uInt16 = readUINT16(m_pIndex[index - 1] + CP_OFFSET_ENTRY_DATA);
     433             :         }
     434             :     }
     435             : 
     436           0 :     return asal_uInt16;
     437             : }
     438             : 
     439           0 : sal_Int32 ConstantPool::readINT32Constant(sal_uInt16 index)
     440             : {
     441           0 :     sal_Int32 aINT32 = 0;
     442             : 
     443           0 :     if (m_pIndex && (index> 0) && (index <= m_numOfEntries))
     444             :     {
     445           0 :         if (readUINT16(m_pIndex[index - 1] + CP_OFFSET_ENTRY_TAG) == CP_TAG_CONST_INT32)
     446             :         {
     447           0 :             aINT32 = readINT32(m_pIndex[index - 1] + CP_OFFSET_ENTRY_DATA);
     448             :         }
     449             :     }
     450             : 
     451           0 :     return aINT32;
     452             : }
     453             : 
     454           0 : sal_uInt32 ConstantPool::readUINT32Constant(sal_uInt16 index)
     455             : {
     456           0 :     sal_uInt32 aUINT32 = 0;
     457             : 
     458           0 :     if (m_pIndex && (index> 0) && (index <= m_numOfEntries))
     459             :     {
     460           0 :         if (readUINT16(m_pIndex[index - 1] + CP_OFFSET_ENTRY_TAG) == CP_TAG_CONST_UINT32)
     461             :         {
     462           0 :             aUINT32 = readUINT32(m_pIndex[index - 1] + CP_OFFSET_ENTRY_DATA);
     463             :         }
     464             :     }
     465             : 
     466           0 :     return aUINT32;
     467             : }
     468             : 
     469           0 : sal_Int64 ConstantPool::readINT64Constant(sal_uInt16 index)
     470             : {
     471           0 :     sal_Int64 aINT64 = 0;
     472             : 
     473           0 :     if (m_pIndex && (index> 0) && (index <= m_numOfEntries))
     474             :     {
     475           0 :         if (readUINT16(m_pIndex[index - 1] + CP_OFFSET_ENTRY_TAG) == CP_TAG_CONST_INT64)
     476             :         {
     477           0 :             aINT64 = readINT64(m_pIndex[index - 1] + CP_OFFSET_ENTRY_DATA);
     478             :         }
     479             :     }
     480             : 
     481           0 :     return aINT64;
     482             : }
     483             : 
     484           0 : sal_uInt64 ConstantPool::readUINT64Constant(sal_uInt16 index)
     485             : {
     486           0 :     sal_uInt64 aUINT64 = 0;
     487             : 
     488           0 :     if (m_pIndex && (index> 0) && (index <= m_numOfEntries))
     489             :     {
     490           0 :         if (readUINT16(m_pIndex[index - 1] + CP_OFFSET_ENTRY_TAG) == CP_TAG_CONST_UINT64)
     491             :         {
     492           0 :             aUINT64 = readUINT64(m_pIndex[index - 1] + CP_OFFSET_ENTRY_DATA);
     493             :         }
     494             :     }
     495             : 
     496           0 :     return aUINT64;
     497             : }
     498             : 
     499           0 : float ConstantPool::readFloatConstant(sal_uInt16 index)
     500             : {
     501             :     union
     502             :     {
     503             :         float   v;
     504             :         sal_uInt32  b;
     505           0 :     } x = { 0.0f };
     506             : 
     507           0 :     if (m_pIndex && (index> 0) && (index <= m_numOfEntries))
     508             :     {
     509           0 :         if (readUINT16(m_pIndex[index - 1] + CP_OFFSET_ENTRY_TAG) == CP_TAG_CONST_FLOAT)
     510             :         {
     511             : #ifdef REGTYPE_IEEE_NATIVE
     512           0 :             x.b = readUINT32(m_pIndex[index - 1] + CP_OFFSET_ENTRY_DATA);
     513             : #else
     514             : #   error no IEEE
     515             : #endif
     516             :         }
     517             :     }
     518             : 
     519           0 :     return  x.v;
     520             : }
     521             : 
     522           0 : double ConstantPool::readDoubleConstant(sal_uInt16 index)
     523             : {
     524             :     union
     525             :     {
     526             :         double v;
     527             :         struct
     528             :         {
     529             :             sal_uInt32  b1;
     530             :             sal_uInt32  b2;
     531             :         } b;
     532           0 :     } x = { 0.0 };
     533             : 
     534           0 :     if (m_pIndex && (index> 0) && (index <= m_numOfEntries))
     535             :     {
     536           0 :         if (readUINT16(m_pIndex[index - 1] + CP_OFFSET_ENTRY_TAG) == CP_TAG_CONST_DOUBLE)
     537             :         {
     538             : 
     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           0 :             x.b.b1 = readUINT32(m_pIndex[index - 1] + CP_OFFSET_ENTRY_DATA + sizeof(sal_uInt32));
     545           0 :             x.b.b2 = readUINT32(m_pIndex[index - 1] + CP_OFFSET_ENTRY_DATA);
     546             : #   endif
     547             : #else
     548             : #   error no IEEE
     549             : #endif
     550             :         }
     551             :     }
     552             : 
     553           0 :     return x.v;
     554             : }
     555             : 
     556           0 : const sal_Unicode* ConstantPool::readStringConstant(sal_uInt16 index)
     557             : {
     558           0 :     const sal_Unicode* aString = NULL_WSTRING;
     559             : 
     560           0 :     if (m_pIndex && (index> 0) && (index <= m_numOfEntries) && m_pStringCache)
     561             :     {
     562           0 :         if (m_pIndex[index - 1] >= 0)
     563             :         {
     564             :             // create cached string now
     565             : 
     566           0 :             if (readUINT16(m_pIndex[index - 1] + CP_OFFSET_ENTRY_TAG) == CP_TAG_CONST_STRING)
     567             :             {
     568           0 :                 sal_uInt32 n = m_pIndex[index - 1] + CP_OFFSET_ENTRY_DATA;
     569           0 :                 if (n >= m_bufferLen
     570           0 :                     || (std::memchr(m_pBuffer + n, 0, m_bufferLen - n)
     571             :                         == nullptr))
     572             :                 {
     573           0 :                     throw BoundsError();
     574             :                 }
     575           0 :                 m_pIndex[index - 1] = -1 * m_pStringCache->createString(m_pBuffer + n);
     576             :             }
     577             :         }
     578             : 
     579           0 :         aString = m_pStringCache->getString((sal_uInt16) (m_pIndex[index - 1] * -1));
     580             :     }
     581             : 
     582           0 :     return aString;
     583             : }
     584             : 
     585           0 : void ConstantPool::readUIK(sal_uInt16 index, RTUik* uik)
     586             : {
     587           0 :     if (index == 0)
     588             :     {
     589           0 :         uik->m_Data1 = 0;
     590           0 :         uik->m_Data2 = 0;
     591           0 :         uik->m_Data3 = 0;
     592           0 :         uik->m_Data4 = 0;
     593           0 :         uik->m_Data5 = 0;
     594             :     }
     595           0 :     else if (m_pIndex && (index <= m_numOfEntries))
     596             :     {
     597           0 :         if (readUINT16(m_pIndex[index - 1] + CP_OFFSET_ENTRY_TAG) == CP_TAG_UIK)
     598             :         {
     599           0 :             uik->m_Data1 = readUINT32(m_pIndex[index - 1] + CP_OFFSET_ENTRY_UIK1);
     600           0 :             uik->m_Data2 = readUINT16(m_pIndex[index - 1] + CP_OFFSET_ENTRY_UIK2);
     601           0 :             uik->m_Data3 = readUINT16(m_pIndex[index - 1] + CP_OFFSET_ENTRY_UIK3);
     602           0 :             uik->m_Data4 = readUINT32(m_pIndex[index - 1] + CP_OFFSET_ENTRY_UIK4);
     603           0 :             uik->m_Data5 = readUINT32(m_pIndex[index - 1] + CP_OFFSET_ENTRY_UIK5);
     604             :         }
     605             :     }
     606           0 : }
     607             : 
     608             : /**************************************************************************
     609             : 
     610             :     class FieldList
     611             : 
     612             : **************************************************************************/
     613             : 
     614           0 : class FieldList : public BlopObject
     615             : {
     616             : public:
     617             : 
     618             :     sal_uInt16      m_numOfEntries;
     619             :     sal_uInt16      m_numOfFieldEntries;
     620             :     size_t          m_FIELD_ENTRY_SIZE;
     621             :     ConstantPool*   m_pCP;
     622             : 
     623           0 :     FieldList(const sal_uInt8* buffer, sal_uInt32 len, sal_uInt16 numEntries, ConstantPool* pCP)
     624             :         : BlopObject(buffer, len, false)
     625             :         , m_numOfEntries(numEntries)
     626           0 :         , m_pCP(pCP)
     627             :     {
     628           0 :         if ( m_numOfEntries > 0 )
     629             :         {
     630           0 :             m_numOfFieldEntries = readUINT16(0);
     631           0 :             m_FIELD_ENTRY_SIZE = m_numOfFieldEntries * sizeof(sal_uInt16);
     632             :         } else
     633             :         {
     634           0 :             m_numOfFieldEntries = 0;
     635           0 :             m_FIELD_ENTRY_SIZE = 0;
     636             :         }
     637           0 :     }
     638             : 
     639           0 :     sal_uInt32 parseIndex() { return ((m_numOfEntries ? sizeof(sal_uInt16) : 0) + (m_numOfEntries * m_FIELD_ENTRY_SIZE));}
     640             : 
     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);
     648             : };
     649             : 
     650             : 
     651           0 : const sal_Char* FieldList::getFieldName(sal_uInt16 index)
     652             : {
     653           0 :     const sal_Char* aName = NULL;
     654             : 
     655           0 :     if ((m_numOfEntries > 0) && (index <= m_numOfEntries))
     656             :     {
     657             :         try {
     658           0 :             aName = m_pCP->readUTF8NameConstant(readUINT16(sizeof(sal_uInt16) + (index * m_FIELD_ENTRY_SIZE) + FIELD_OFFSET_NAME));
     659           0 :         } catch (BlopObject::BoundsError &) {
     660             :             SAL_WARN("registry", "bad data");
     661             :         }
     662             :     }
     663             : 
     664           0 :     return aName;
     665             : }
     666             : 
     667           0 : const sal_Char* FieldList::getFieldType(sal_uInt16 index)
     668             : {
     669           0 :     const sal_Char* aName = NULL;
     670             : 
     671           0 :     if ((m_numOfEntries > 0) && (index <= m_numOfEntries))
     672             :     {
     673             :         try {
     674           0 :             aName = m_pCP->readUTF8NameConstant(readUINT16(sizeof(sal_uInt16) + (index * m_FIELD_ENTRY_SIZE) + FIELD_OFFSET_TYPE));
     675           0 :         } catch (BlopObject::BoundsError &) {
     676             :             SAL_WARN("registry", "bad data");
     677             :         }
     678             :     }
     679             : 
     680           0 :     return aName;
     681             : }
     682             : 
     683           0 : RTFieldAccess FieldList::getFieldAccess(sal_uInt16 index)
     684             : {
     685           0 :     RTFieldAccess aAccess = RTFieldAccess::INVALID;
     686             : 
     687           0 :     if ((m_numOfEntries > 0) && (index <= m_numOfEntries))
     688             :     {
     689             :         try {
     690           0 :             aAccess = (RTFieldAccess) readUINT16(sizeof(sal_uInt16) + (index * m_FIELD_ENTRY_SIZE) + FIELD_OFFSET_ACCESS);
     691           0 :         } catch (BlopObject::BoundsError &) {
     692             :             SAL_WARN("registry", "bad data");
     693             :         }
     694             :     }
     695             : 
     696           0 :     return aAccess;
     697             : }
     698             : 
     699           0 : RTValueType FieldList::getFieldConstValue(sal_uInt16 index, RTConstValueUnion* value)
     700             : {
     701           0 :     RTValueType ret = RT_TYPE_NONE;
     702             :     try {
     703           0 :         if ((m_numOfEntries > 0) && (index <= m_numOfEntries))
     704             :         {
     705           0 :             sal_uInt16 cpIndex = readUINT16(sizeof(sal_uInt16) + (index * m_FIELD_ENTRY_SIZE) + FIELD_OFFSET_VALUE);
     706           0 :             switch (m_pCP->readTag(cpIndex))
     707             :             {
     708             :             case CP_TAG_CONST_BOOL:
     709           0 :                 value->aBool = m_pCP->readBOOLConstant(cpIndex);
     710           0 :                 ret = RT_TYPE_BOOL;
     711           0 :                 break;
     712             :             case CP_TAG_CONST_BYTE:
     713           0 :                 value->aByte = m_pCP->readBYTEConstant(cpIndex);
     714           0 :                 ret = RT_TYPE_BYTE;
     715           0 :                 break;
     716             :             case CP_TAG_CONST_INT16:
     717           0 :                 value->aShort = m_pCP->readINT16Constant(cpIndex);
     718           0 :                 ret = RT_TYPE_INT16;
     719           0 :                 break;
     720             :             case CP_TAG_CONST_UINT16:
     721           0 :                 value->aUShort = m_pCP->readUINT16Constant(cpIndex);
     722           0 :                 ret = RT_TYPE_UINT16;
     723           0 :                 break;
     724             :             case CP_TAG_CONST_INT32:
     725           0 :                 value->aLong = m_pCP->readINT32Constant(cpIndex);
     726           0 :                 ret = RT_TYPE_INT32;
     727           0 :                 break;
     728             :             case CP_TAG_CONST_UINT32:
     729           0 :                 value->aULong = m_pCP->readUINT32Constant(cpIndex);
     730           0 :                 ret = RT_TYPE_UINT32;
     731           0 :                 break;
     732             :             case CP_TAG_CONST_INT64:
     733           0 :               value->aHyper = m_pCP->readINT64Constant(cpIndex);
     734           0 :                 ret = RT_TYPE_INT64;
     735           0 :                 break;
     736             :             case CP_TAG_CONST_UINT64:
     737           0 :               value->aUHyper = m_pCP->readUINT64Constant(cpIndex);
     738           0 :                 ret = RT_TYPE_UINT64;
     739           0 :                 break;
     740             :             case CP_TAG_CONST_FLOAT:
     741           0 :                 value->aFloat = m_pCP->readFloatConstant(cpIndex);
     742           0 :                 ret = RT_TYPE_FLOAT;
     743           0 :                 break;
     744             :             case CP_TAG_CONST_DOUBLE:
     745           0 :                 value->aDouble = m_pCP->readDoubleConstant(cpIndex);
     746           0 :                 ret = RT_TYPE_DOUBLE;
     747           0 :                 break;
     748             :             case CP_TAG_CONST_STRING:
     749           0 :                 value->aString = m_pCP->readStringConstant(cpIndex);
     750           0 :                 ret = RT_TYPE_STRING;
     751           0 :                 break;
     752             :             default:
     753           0 :                 break;
     754             :             }
     755             :         }
     756           0 :     } catch (BlopObject::BoundsError &) {
     757             :         SAL_WARN("registry", "bad data");
     758             :     }
     759           0 :     return ret;
     760             : }
     761             : 
     762           0 : const sal_Char* FieldList::getFieldDoku(sal_uInt16 index)
     763             : {
     764           0 :     const sal_Char* aDoku = NULL;
     765             : 
     766           0 :     if ((m_numOfEntries > 0) && (index <= m_numOfEntries))
     767             :     {
     768             :         try {
     769           0 :             aDoku = m_pCP->readUTF8NameConstant(readUINT16(sizeof(sal_uInt16) + (index * m_FIELD_ENTRY_SIZE) + FIELD_OFFSET_DOKU));
     770           0 :         } catch (BlopObject::BoundsError &) {
     771             :             SAL_WARN("registry", "bad data");
     772             :         }
     773             :     }
     774             : 
     775           0 :     return aDoku;
     776             : }
     777             : 
     778           0 : const sal_Char* FieldList::getFieldFileName(sal_uInt16 index)
     779             : {
     780           0 :     const sal_Char* aFileName = NULL;
     781             : 
     782           0 :     if ((m_numOfEntries > 0) && (index <= m_numOfEntries))
     783             :     {
     784             :         try {
     785           0 :             aFileName = m_pCP->readUTF8NameConstant(readUINT16(sizeof(sal_uInt16) + (index * m_FIELD_ENTRY_SIZE) + FIELD_OFFSET_FILENAME));
     786           0 :         } catch (BlopObject::BoundsError &) {
     787             :             SAL_WARN("registry", "bad data");
     788             :         }
     789             :     }
     790             : 
     791           0 :     return aFileName;
     792             : }
     793             : 
     794             : /**************************************************************************
     795             : 
     796             :     class ReferenceList
     797             : 
     798             : **************************************************************************/
     799             : 
     800           0 : class ReferenceList : public BlopObject
     801             : {
     802             : public:
     803             : 
     804             :     sal_uInt16      m_numOfEntries;
     805             :     sal_uInt16      m_numOfReferenceEntries;
     806             :     size_t          m_REFERENCE_ENTRY_SIZE;
     807             :     ConstantPool*   m_pCP;
     808             : 
     809           0 :     ReferenceList(const sal_uInt8* buffer, sal_uInt32 len, sal_uInt16 numEntries, ConstantPool* pCP)
     810             :         : BlopObject(buffer, len, false)
     811             :         , m_numOfEntries(numEntries)
     812           0 :         , m_pCP(pCP)
     813             :     {
     814           0 :         if ( m_numOfEntries > 0 )
     815             :         {
     816           0 :             m_numOfReferenceEntries = readUINT16(0);
     817           0 :             m_REFERENCE_ENTRY_SIZE = m_numOfReferenceEntries * sizeof(sal_uInt16);
     818             :         } else
     819             :         {
     820           0 :             m_numOfReferenceEntries = 0;
     821           0 :             m_REFERENCE_ENTRY_SIZE = 0;
     822             :         }
     823           0 :     }
     824             : 
     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);
     829             : };
     830             : 
     831             : 
     832           0 : const sal_Char* ReferenceList::getReferenceName(sal_uInt16 index)
     833             : {
     834           0 :     const sal_Char* aName = NULL;
     835             : 
     836           0 :     if ((m_numOfEntries > 0) && (index <= m_numOfEntries))
     837             :     {
     838             :         try {
     839           0 :             aName = m_pCP->readUTF8NameConstant(readUINT16(sizeof(sal_uInt16) + (index * m_REFERENCE_ENTRY_SIZE) + REFERENCE_OFFSET_NAME));
     840           0 :         } catch (BlopObject::BoundsError &) {
     841             :             SAL_WARN("registry", "bad data");
     842             :         }
     843             :     }
     844             : 
     845           0 :     return aName;
     846             : }
     847             : 
     848           0 : RTReferenceType ReferenceList::getReferenceType(sal_uInt16 index)
     849             : {
     850           0 :     RTReferenceType refType = RTReferenceType::INVALID;
     851             : 
     852           0 :     if ((m_numOfEntries > 0) && (index <= m_numOfEntries))
     853             :     {
     854             :         try {
     855           0 :             refType = (RTReferenceType) readUINT16(sizeof(sal_uInt16) + (index * m_REFERENCE_ENTRY_SIZE) + REFERENCE_OFFSET_TYPE);
     856           0 :         } catch (BlopObject::BoundsError &) {
     857             :             SAL_WARN("registry", "bad data");
     858             :         }
     859             :     }
     860             : 
     861           0 :     return refType;
     862             : }
     863             : 
     864           0 : const sal_Char* ReferenceList::getReferenceDoku(sal_uInt16 index)
     865             : {
     866           0 :     const sal_Char* aDoku = NULL;
     867             : 
     868           0 :     if ((m_numOfEntries > 0) && (index <= m_numOfEntries))
     869             :     {
     870             :         try {
     871           0 :             aDoku = m_pCP->readUTF8NameConstant(readUINT16(sizeof(sal_uInt16) + (index * m_REFERENCE_ENTRY_SIZE) + REFERENCE_OFFSET_DOKU));
     872           0 :         } catch (BlopObject::BoundsError &) {
     873             :             SAL_WARN("registry", "bad data");
     874             :         }
     875             :     }
     876             : 
     877           0 :     return aDoku;
     878             : }
     879             : 
     880           0 : RTFieldAccess ReferenceList::getReferenceAccess(sal_uInt16 index)
     881             : {
     882           0 :     RTFieldAccess aAccess = RTFieldAccess::INVALID;
     883             : 
     884           0 :     if ((m_numOfEntries > 0) && (index <= m_numOfEntries))
     885             :     {
     886             :         try {
     887           0 :             aAccess = (RTFieldAccess) readUINT16(sizeof(sal_uInt16) + (index * m_REFERENCE_ENTRY_SIZE) + REFERENCE_OFFSET_ACCESS);
     888           0 :         } catch (BlopObject::BoundsError &) {
     889             :             SAL_WARN("registry", "bad data");
     890             :         }
     891             :     }
     892             : 
     893           0 :     return aAccess;
     894             : }
     895             : 
     896             : /**************************************************************************
     897             : 
     898             :     class MethodList
     899             : 
     900             : **************************************************************************/
     901             : 
     902             : class MethodList : public BlopObject
     903             : {
     904             : public:
     905             : 
     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;
     912             : 
     913           0 :     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           0 :         , m_pCP(pCP)
     918             :     {
     919           0 :         if ( m_numOfEntries > 0 )
     920             :         {
     921           0 :             m_numOfMethodEntries = readUINT16(0);
     922           0 :             m_numOfParamEntries = readUINT16(sizeof(sal_uInt16));
     923           0 :             m_PARAM_ENTRY_SIZE = m_numOfParamEntries * sizeof(sal_uInt16);
     924             :         } else
     925             :         {
     926           0 :             m_numOfMethodEntries = 0;
     927           0 :             m_numOfParamEntries = 0;
     928           0 :             m_PARAM_ENTRY_SIZE = 0;
     929             :         }
     930           0 :     }
     931             : 
     932             :     ~MethodList();
     933             : 
     934             :     sal_uInt32 parseIndex(); // throws std::bad_alloc
     935             : 
     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);
     946             : 
     947             : private:
     948             :     sal_uInt16 calcMethodParamIndex( const sal_uInt16 index );
     949             : };
     950             : 
     951           0 : MethodList::~MethodList()
     952             : {
     953           0 :     if (m_pIndex) delete[] m_pIndex;
     954           0 : }
     955             : 
     956           0 : sal_uInt16 MethodList::calcMethodParamIndex( const sal_uInt16 index )
     957             : {
     958           0 :     return (METHOD_OFFSET_PARAM_COUNT + sizeof(sal_uInt16) + (index * m_PARAM_ENTRY_SIZE));
     959             : }
     960             : 
     961           0 : sal_uInt32 MethodList::parseIndex()
     962             : {
     963           0 :     if (m_pIndex)
     964             :     {
     965           0 :         delete[] m_pIndex;
     966           0 :         m_pIndex = NULL;
     967             :     }
     968             : 
     969           0 :     sal_uInt32 offset = 0;
     970             : 
     971           0 :     if (m_numOfEntries)
     972             :     {
     973           0 :         offset = 2 * sizeof(sal_uInt16);
     974           0 :         m_pIndex = new sal_uInt32[m_numOfEntries];
     975             : 
     976           0 :         for (int i = 0; i < m_numOfEntries; i++)
     977             :         {
     978           0 :             m_pIndex[i] = offset;
     979             : 
     980           0 :             offset += readUINT16(offset);
     981             :         }
     982             :     }
     983             : 
     984           0 :     return offset;
     985             : }
     986             : 
     987           0 : const sal_Char* MethodList::getMethodName(sal_uInt16 index)
     988             : {
     989           0 :     const sal_Char* aName = NULL;
     990             : 
     991           0 :     if ((m_numOfEntries > 0) && (index <= m_numOfEntries))
     992             :     {
     993             :         try {
     994           0 :             aName = m_pCP->readUTF8NameConstant(readUINT16(m_pIndex[index] + METHOD_OFFSET_NAME));
     995           0 :         } catch (BlopObject::BoundsError &) {
     996             :             SAL_WARN("registry", "bad data");
     997             :         }
     998             :     }
     999             : 
    1000           0 :     return aName;
    1001             : }
    1002             : 
    1003           0 : sal_uInt16 MethodList::getMethodParamCount(sal_uInt16 index)
    1004             : {
    1005           0 :     sal_uInt16 aCount = 0;
    1006             : 
    1007           0 :     if ((m_numOfEntries > 0) && (index <= m_numOfEntries))
    1008             :     {
    1009             :         try {
    1010           0 :             aCount = readUINT16(m_pIndex[index] + METHOD_OFFSET_PARAM_COUNT);
    1011           0 :         } catch (BlopObject::BoundsError &) {
    1012             :             SAL_WARN("registry", "bad data");
    1013             :         }
    1014             :     }
    1015             : 
    1016           0 :     return aCount;
    1017             : }
    1018             : 
    1019           0 : const sal_Char* MethodList::getMethodParamType(sal_uInt16 index, sal_uInt16 paramIndex)
    1020             : {
    1021           0 :     const sal_Char* aName = NULL;
    1022             :     try {
    1023           0 :         if ((m_numOfEntries > 0) &&
    1024           0 :             (index <= m_numOfEntries) &&
    1025           0 :             (paramIndex <= readUINT16(m_pIndex[index] + METHOD_OFFSET_PARAM_COUNT)))
    1026             :         {
    1027             :             aName = m_pCP->readUTF8NameConstant(
    1028             :                 readUINT16(
    1029           0 :                     m_pIndex[index] +
    1030           0 :                     calcMethodParamIndex(paramIndex) +
    1031           0 :                     PARAM_OFFSET_TYPE));
    1032             :         }
    1033           0 :     } catch (BlopObject::BoundsError &) {
    1034             :         SAL_WARN("registry", "bad data");
    1035             :     }
    1036           0 :     return aName;
    1037             : }
    1038             : 
    1039           0 : const sal_Char* MethodList::getMethodParamName(sal_uInt16 index, sal_uInt16 paramIndex)
    1040             : {
    1041           0 :     const sal_Char* aName = NULL;
    1042             :     try {
    1043           0 :         if ((m_numOfEntries > 0) &&
    1044           0 :             (index <= m_numOfEntries) &&
    1045           0 :             (paramIndex <= readUINT16(m_pIndex[index] + METHOD_OFFSET_PARAM_COUNT)))
    1046             :         {
    1047             :             aName = m_pCP->readUTF8NameConstant(
    1048             :                 readUINT16(
    1049           0 :                     m_pIndex[index] +
    1050           0 :                     calcMethodParamIndex(paramIndex) +
    1051           0 :                     PARAM_OFFSET_NAME));
    1052             :         }
    1053           0 :     } catch (BlopObject::BoundsError &) {
    1054             :         SAL_WARN("registry", "bad data");
    1055             :     }
    1056           0 :     return aName;
    1057             : }
    1058             : 
    1059           0 : RTParamMode MethodList::getMethodParamMode(sal_uInt16 index, sal_uInt16 paramIndex)
    1060             : {
    1061           0 :     RTParamMode aMode = RT_PARAM_INVALID;
    1062             :     try {
    1063           0 :         if ((m_numOfEntries > 0) &&
    1064           0 :             (index <= m_numOfEntries) &&
    1065           0 :             (paramIndex <= readUINT16(m_pIndex[index] + METHOD_OFFSET_PARAM_COUNT)))
    1066             :         {
    1067             :             aMode = (RTParamMode) readUINT16(
    1068           0 :                 m_pIndex[index] +
    1069           0 :                 calcMethodParamIndex(paramIndex) +
    1070           0 :                 PARAM_OFFSET_MODE);
    1071             :         }
    1072           0 :     } catch (BlopObject::BoundsError &) {
    1073             :         SAL_WARN("registry", "bad data");
    1074             :     }
    1075           0 :     return aMode;
    1076             : }
    1077             : 
    1078           0 : sal_uInt16 MethodList::getMethodExcCount(sal_uInt16 index)
    1079             : {
    1080           0 :     sal_uInt16 aCount = 0;
    1081             : 
    1082           0 :     if ((m_numOfEntries > 0) && (index <= m_numOfEntries))
    1083             :     {
    1084             :         try {
    1085           0 :             aCount = readUINT16(m_pIndex[index] + calcMethodParamIndex(readUINT16(m_pIndex[index] + METHOD_OFFSET_PARAM_COUNT)));
    1086           0 :         } catch (BlopObject::BoundsError &) {
    1087             :             SAL_WARN("registry", "bad data");
    1088             :         }
    1089             :     }
    1090             : 
    1091           0 :     return aCount;
    1092             : }
    1093             : 
    1094           0 : const sal_Char* MethodList::getMethodExcType(sal_uInt16 index, sal_uInt16 excIndex)
    1095             : {
    1096           0 :     const sal_Char* aName = NULL;
    1097             : 
    1098           0 :     if ((m_numOfEntries > 0) && (index <= m_numOfEntries))
    1099             :     {
    1100             :         try {
    1101           0 :             sal_uInt32 excOffset = m_pIndex[index] + calcMethodParamIndex(readUINT16(m_pIndex[index] + METHOD_OFFSET_PARAM_COUNT));
    1102           0 :             if (excIndex <= readUINT16(excOffset))
    1103             :             {
    1104             :                 aName = m_pCP->readUTF8NameConstant(
    1105             :                     readUINT16(
    1106             :                         excOffset +
    1107             :                         sizeof(sal_uInt16) +
    1108           0 :                         (excIndex * sizeof(sal_uInt16))));
    1109             :             }
    1110           0 :         } catch (BlopObject::BoundsError &) {
    1111             :             SAL_WARN("registry", "bad data");
    1112             :         }
    1113             :     }
    1114             : 
    1115           0 :     return aName;
    1116             : }
    1117             : 
    1118           0 : const sal_Char* MethodList::getMethodReturnType(sal_uInt16 index)
    1119             : {
    1120           0 :     const sal_Char* aName = NULL;
    1121             : 
    1122           0 :     if ((m_numOfEntries > 0) && (index <= m_numOfEntries))
    1123             :     {
    1124             :         try {
    1125           0 :             aName = m_pCP->readUTF8NameConstant(readUINT16(m_pIndex[index] + METHOD_OFFSET_RETURN));
    1126           0 :         } catch (BlopObject::BoundsError &) {
    1127             :             SAL_WARN("registry", "bad data");
    1128             :         }
    1129             :     }
    1130             : 
    1131           0 :     return aName;
    1132             : }
    1133             : 
    1134           0 : RTMethodMode MethodList::getMethodMode(sal_uInt16 index)
    1135             : {
    1136           0 :     RTMethodMode aMode = RTMethodMode::INVALID;
    1137             : 
    1138           0 :     if ((m_numOfEntries > 0) && (index <= m_numOfEntries))
    1139             :     {
    1140             :         try {
    1141           0 :             aMode = (RTMethodMode) readUINT16(m_pIndex[index] + METHOD_OFFSET_MODE);
    1142           0 :         } catch (BlopObject::BoundsError &) {
    1143             :             SAL_WARN("registry", "bad data");
    1144             :         }
    1145             :     }
    1146             : 
    1147           0 :     return aMode;
    1148             : }
    1149             : 
    1150           0 : const sal_Char* MethodList::getMethodDoku(sal_uInt16 index)
    1151             : {
    1152           0 :     const sal_Char* aDoku = NULL;
    1153             : 
    1154           0 :     if ((m_numOfEntries > 0) && (index <= m_numOfEntries))
    1155             :     {
    1156             :         try {
    1157           0 :             aDoku = m_pCP->readUTF8NameConstant(readUINT16(m_pIndex[index] + METHOD_OFFSET_DOKU));
    1158           0 :         } catch (BlopObject::BoundsError &) {
    1159             :             SAL_WARN("registry", "bad data");
    1160             :         }
    1161             :     }
    1162             : 
    1163           0 :     return aDoku;
    1164             : }
    1165             : 
    1166             : /**************************************************************************
    1167             : 
    1168             :     class TypeRegistryEntry
    1169             : 
    1170             : **************************************************************************/
    1171             : 
    1172           0 : 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;
    1181             : 
    1182             :     TypeRegistryEntry(
    1183             :         const sal_uInt8* buffer, sal_uInt32 len, bool copyBuffer);
    1184             :         // throws std::bad_alloc
    1185             : 
    1186             :     typereg_Version getVersion() const;
    1187             : };
    1188             : 
    1189           0 : TypeRegistryEntry::TypeRegistryEntry(
    1190             :     const sal_uInt8* buffer, sal_uInt32 len, bool copyBuffer):
    1191             :     BlopObject(buffer, len, copyBuffer), m_refCount(1), m_nSuperTypes(0),
    1192           0 :     m_offset_SUPERTYPES(0)
    1193             : {
    1194           0 :     std::size_t const entrySize = sizeof(sal_uInt16);
    1195           0 :     sal_uInt16 nHeaderEntries = readUINT16(OFFSET_N_ENTRIES);
    1196           0 :     sal_uInt32 offset_N_SUPERTYPES = OFFSET_N_ENTRIES + entrySize + (nHeaderEntries * entrySize); // cannot overflow
    1197           0 :     m_offset_SUPERTYPES = offset_N_SUPERTYPES + entrySize; // cannot overflow
    1198           0 :     m_nSuperTypes = readUINT16(offset_N_SUPERTYPES);
    1199             : 
    1200           0 :     sal_uInt32 offset_CP_SIZE = m_offset_SUPERTYPES + (m_nSuperTypes * entrySize); // cannot overflow
    1201           0 :     sal_uInt32 offset_CP = offset_CP_SIZE + entrySize; // cannot overflow
    1202             : 
    1203           0 :     if (offset_CP > m_bufferLen) {
    1204           0 :         throw BoundsError();
    1205             :     }
    1206             :     m_pCP.reset(
    1207             :         new ConstantPool(
    1208             :             m_pBuffer + offset_CP, m_bufferLen - offset_CP,
    1209           0 :             readUINT16(offset_CP_SIZE)));
    1210             : 
    1211           0 :     sal_uInt32 offset = offset_CP + m_pCP->parseIndex(); //TODO: overflow
    1212             : 
    1213             :     assert(m_bufferLen >= entrySize);
    1214           0 :     if (offset > m_bufferLen - entrySize) {
    1215           0 :         throw BoundsError();
    1216             :     }
    1217             :     m_pFields.reset(
    1218             :         new FieldList(
    1219           0 :             m_pBuffer + offset + entrySize, m_bufferLen - (offset + entrySize),
    1220           0 :             readUINT16(offset), m_pCP.get()));
    1221             : 
    1222           0 :     offset += sizeof(sal_uInt16) + m_pFields->parseIndex(); //TODO: overflow
    1223             : 
    1224             :     assert(m_bufferLen >= entrySize);
    1225           0 :     if (offset > m_bufferLen - entrySize) {
    1226           0 :         throw BoundsError();
    1227             :     }
    1228             :     m_pMethods.reset(
    1229             :         new MethodList(
    1230           0 :             m_pBuffer + offset + entrySize, m_bufferLen - (offset + entrySize),
    1231           0 :             readUINT16(offset), m_pCP.get()));
    1232             : 
    1233           0 :     offset += sizeof(sal_uInt16) + m_pMethods->parseIndex(); //TODO: overflow
    1234             : 
    1235             :     assert(m_bufferLen >= entrySize);
    1236           0 :     if (offset > m_bufferLen - entrySize) {
    1237           0 :         throw BoundsError();
    1238             :     }
    1239             :     m_pReferences.reset(
    1240             :         new ReferenceList(
    1241           0 :             m_pBuffer + offset + entrySize, m_bufferLen - (offset + entrySize),
    1242           0 :             readUINT16(offset), m_pCP.get()));
    1243           0 : }
    1244             : 
    1245           0 : typereg_Version TypeRegistryEntry::getVersion() const {
    1246             :     // Assumes two's complement arithmetic with modulo-semantics:
    1247           0 :     return static_cast< typereg_Version >(readUINT32(OFFSET_MAGIC) - magic);
    1248             : }
    1249             : 
    1250             : /**************************************************************************
    1251             : 
    1252             :     C-API
    1253             : 
    1254             : **************************************************************************/
    1255             : 
    1256           0 : bool TYPEREG_CALLTYPE typereg_reader_create(
    1257             :     void const * buffer, sal_uInt32 length, bool copy,
    1258             :     typereg_Version maxVersion, void ** result)
    1259             : {
    1260           0 :     if (length < OFFSET_CP || length > SAL_MAX_UINT32) {
    1261           0 :         *result = 0;
    1262           0 :         return true;
    1263             :     }
    1264           0 :     std::unique_ptr< TypeRegistryEntry > entry;
    1265             :     try {
    1266             :         try {
    1267             :             entry.reset(
    1268             :                 new TypeRegistryEntry(
    1269             :                     static_cast< sal_uInt8 const * >(buffer),
    1270           0 :                     static_cast< sal_uInt32 >(length), copy));
    1271           0 :         } catch (std::bad_alloc &) {
    1272           0 :             return false;
    1273             :         }
    1274           0 :         if (entry->readUINT32(OFFSET_SIZE) != length) {
    1275           0 :             *result = 0;
    1276           0 :             return true;
    1277             :         }
    1278           0 :         typereg_Version version = entry->getVersion();;
    1279           0 :         if (version < TYPEREG_VERSION_0 || version > maxVersion) {
    1280           0 :             *result = 0;
    1281           0 :             return true;
    1282             :         }
    1283           0 :         *result = entry.release();
    1284           0 :         return true;
    1285           0 :     } catch (BlopObject::BoundsError &) {
    1286             :         SAL_WARN("registry", "bad data");
    1287           0 :         return false;
    1288           0 :     }
    1289             : }
    1290             : 
    1291           0 : static TypeReaderImpl TYPEREG_CALLTYPE createEntry(const sal_uInt8* buffer, sal_uInt32 len, bool copyBuffer)
    1292             : {
    1293             :     void * handle;
    1294           0 :     typereg_reader_create(buffer, len, copyBuffer, TYPEREG_VERSION_1, &handle);
    1295           0 :     return handle;
    1296             : }
    1297             : 
    1298           0 : void TYPEREG_CALLTYPE typereg_reader_acquire(void * hEntry)
    1299             : {
    1300           0 :     TypeRegistryEntry* pEntry = static_cast<TypeRegistryEntry*>(hEntry);
    1301             : 
    1302           0 :     if (pEntry != NULL)
    1303           0 :         pEntry->m_refCount++;
    1304           0 : }
    1305             : 
    1306           0 : void TYPEREG_CALLTYPE typereg_reader_release(void * hEntry)
    1307             : {
    1308           0 :     TypeRegistryEntry* pEntry = static_cast<TypeRegistryEntry*>(hEntry);
    1309             : 
    1310           0 :     if (pEntry != NULL)
    1311             :     {
    1312           0 :         if (--pEntry->m_refCount == 0)
    1313           0 :             delete pEntry;
    1314             :     }
    1315           0 : }
    1316             : 
    1317           0 : typereg_Version TYPEREG_CALLTYPE typereg_reader_getVersion(void * handle) {
    1318           0 :     if (handle != nullptr) {
    1319             :         try {
    1320           0 :             return static_cast< TypeRegistryEntry * >(handle)->getVersion();
    1321           0 :         } catch (BlopObject::BoundsError &) {
    1322             :             SAL_WARN("registry", "bad data");
    1323             :         }
    1324             :     }
    1325           0 :     return TYPEREG_VERSION_0;
    1326             : }
    1327             : 
    1328           0 : static sal_uInt16 TYPEREG_CALLTYPE getMinorVersion(TypeReaderImpl hEntry)
    1329             : {
    1330           0 :     TypeRegistryEntry* pEntry = static_cast<TypeRegistryEntry*>(hEntry);
    1331           0 :     if (pEntry != nullptr) {
    1332             :         try {
    1333           0 :             return pEntry->readUINT16(OFFSET_MINOR_VERSION);
    1334           0 :         } catch (BlopObject::BoundsError &) {
    1335             :             SAL_WARN("registry", "bad data");
    1336             :         }
    1337             :     }
    1338           0 :     return 0;
    1339             : }
    1340             : 
    1341           0 : static sal_uInt16 TYPEREG_CALLTYPE getMajorVersion(TypeReaderImpl hEntry)
    1342             : {
    1343           0 :     TypeRegistryEntry* pEntry = static_cast<TypeRegistryEntry*>(hEntry);
    1344           0 :     if (pEntry != nullptr) {
    1345             :         try {
    1346           0 :             return pEntry->readUINT16(OFFSET_MAJOR_VERSION);
    1347           0 :         } catch (BlopObject::BoundsError &) {
    1348             :             SAL_WARN("registry", "bad data");
    1349             :         }
    1350             :     }
    1351           0 :     return 0;
    1352             : }
    1353             : 
    1354           0 : RTTypeClass TYPEREG_CALLTYPE typereg_reader_getTypeClass(void * hEntry)
    1355             : {
    1356           0 :     TypeRegistryEntry* pEntry = static_cast<TypeRegistryEntry*>(hEntry);
    1357           0 :     if (pEntry != nullptr) {
    1358             :         try {
    1359             :             return (RTTypeClass)
    1360           0 :                 (pEntry->readUINT16(OFFSET_TYPE_CLASS) & ~RT_TYPE_PUBLISHED);
    1361           0 :         } catch (BlopObject::BoundsError &) {
    1362             :             SAL_WARN("registry", "bad data");
    1363             :         }
    1364             :     }
    1365           0 :     return RT_TYPE_INVALID;
    1366             : }
    1367             : 
    1368           0 : bool TYPEREG_CALLTYPE typereg_reader_isPublished(void * hEntry)
    1369             : {
    1370           0 :     TypeRegistryEntry * entry = static_cast< TypeRegistryEntry * >(hEntry);
    1371           0 :     if (entry != nullptr) {
    1372             :         try {
    1373           0 :             return (entry->readUINT16(OFFSET_TYPE_CLASS) & RT_TYPE_PUBLISHED) != 0;
    1374           0 :         } catch (BlopObject::BoundsError &) {
    1375             :             SAL_WARN("registry", "bad data");
    1376             :         }
    1377             :     }
    1378           0 :     return false;
    1379             : }
    1380             : 
    1381           0 : void TYPEREG_CALLTYPE typereg_reader_getTypeName(void * hEntry, rtl_uString** pTypeName)
    1382             : {
    1383           0 :     TypeRegistryEntry* pEntry = static_cast<TypeRegistryEntry*>(hEntry);
    1384           0 :     if (pEntry != nullptr) {
    1385             :         try {
    1386           0 :             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           0 :                 RTL_TEXTENCODING_UTF8, OSTRING_TO_OUSTRING_CVTFLAGS);
    1390           0 :             return;
    1391           0 :         } catch (BlopObject::BoundsError &) {
    1392             :             SAL_WARN("registry", "bad data");
    1393             :         }
    1394             :     }
    1395           0 :     rtl_uString_new(pTypeName);
    1396             : }
    1397             : 
    1398             : 
    1399           0 : static void TYPEREG_CALLTYPE getSuperTypeName(TypeReaderImpl hEntry, rtl_uString** pSuperTypeName)
    1400             : {
    1401           0 :     TypeRegistryEntry* pEntry = static_cast<TypeRegistryEntry*>(hEntry);
    1402           0 :     if (pEntry != nullptr && pEntry->m_nSuperTypes != 0) {
    1403             :         try {
    1404           0 :             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           0 :                 RTL_TEXTENCODING_UTF8, OSTRING_TO_OUSTRING_CVTFLAGS);
    1408           0 :             return;
    1409           0 :         } catch (BlopObject::BoundsError &) {
    1410             :             SAL_WARN("registry", "bad data");
    1411             :         }
    1412             :     }
    1413           0 :     rtl_uString_new(pSuperTypeName);
    1414             : }
    1415             : 
    1416           0 : static void TYPEREG_CALLTYPE getUik(TypeReaderImpl hEntry, RTUik* uik)
    1417             : {
    1418           0 :     TypeRegistryEntry* pEntry = static_cast<TypeRegistryEntry*>(hEntry);
    1419             : 
    1420           0 :     if (pEntry != NULL)
    1421             :     {
    1422             :         try {
    1423           0 :             pEntry->m_pCP->readUIK(pEntry->readUINT16(OFFSET_UIK), uik);
    1424           0 :         } catch (BlopObject::BoundsError &) {
    1425             :             SAL_WARN("registry", "bad data");
    1426             :         }
    1427             :     }
    1428           0 : }
    1429             : 
    1430           0 : void TYPEREG_CALLTYPE typereg_reader_getDocumentation(void * hEntry, rtl_uString** pDoku)
    1431             : {
    1432           0 :     TypeRegistryEntry* pEntry = static_cast<TypeRegistryEntry*>(hEntry);
    1433           0 :     if (pEntry != nullptr) {
    1434             :         try {
    1435           0 :             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           0 :                 RTL_TEXTENCODING_UTF8, OSTRING_TO_OUSTRING_CVTFLAGS);
    1439           0 :             return;
    1440           0 :         } catch (BlopObject::BoundsError &) {
    1441             :             SAL_WARN("registry", "bad data");
    1442             :         }
    1443             :     }
    1444           0 :     rtl_uString_new(pDoku);
    1445             : }
    1446             : 
    1447           0 : void TYPEREG_CALLTYPE typereg_reader_getFileName(void * hEntry, rtl_uString** pFileName)
    1448             : {
    1449           0 :     TypeRegistryEntry* pEntry = static_cast<TypeRegistryEntry*>(hEntry);
    1450           0 :     if (pEntry != nullptr) {
    1451             :         try {
    1452           0 :             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           0 :                 RTL_TEXTENCODING_UTF8, OSTRING_TO_OUSTRING_CVTFLAGS);
    1456           0 :             return;
    1457           0 :         } catch (BlopObject::BoundsError &) {
    1458             :             SAL_WARN("registry", "bad data");
    1459             :         }
    1460             :     }
    1461           0 :     rtl_uString_new(pFileName);
    1462             : }
    1463             : 
    1464             : 
    1465           0 : sal_uInt16 TYPEREG_CALLTYPE typereg_reader_getFieldCount(void * hEntry)
    1466             : {
    1467           0 :     TypeRegistryEntry* pEntry = static_cast<TypeRegistryEntry*>(hEntry);
    1468             : 
    1469           0 :     if (pEntry == NULL) return 0;
    1470             : 
    1471           0 :     return pEntry->m_pFields->m_numOfEntries;
    1472             : }
    1473             : 
    1474           0 : static sal_uInt32 TYPEREG_CALLTYPE getFieldCount(TypeReaderImpl hEntry)
    1475             : {
    1476           0 :     return typereg_reader_getFieldCount(hEntry);
    1477             : }
    1478             : 
    1479           0 : void TYPEREG_CALLTYPE typereg_reader_getFieldName(void * hEntry, rtl_uString** pFieldName, sal_uInt16 index)
    1480             : {
    1481           0 :     TypeRegistryEntry* pEntry = static_cast<TypeRegistryEntry*>(hEntry);
    1482             : 
    1483           0 :     if (pEntry == NULL)
    1484             :     {
    1485           0 :         rtl_uString_new(pFieldName);
    1486           0 :         return;
    1487             :     }
    1488           0 :     const sal_Char* pTmp = pEntry->m_pFields->getFieldName(index);
    1489             :     rtl_string2UString(
    1490             :         pFieldName, pTmp, pTmp == 0 ? 0 : rtl_str_getLength(pTmp),
    1491           0 :         RTL_TEXTENCODING_UTF8, OSTRING_TO_OUSTRING_CVTFLAGS);
    1492             : }
    1493             : 
    1494           0 : void TYPEREG_CALLTYPE typereg_reader_getFieldTypeName(void * hEntry, rtl_uString** pFieldType, sal_uInt16 index)
    1495             : {
    1496           0 :     TypeRegistryEntry* pEntry = static_cast<TypeRegistryEntry*>(hEntry);
    1497             : 
    1498           0 :     if (pEntry == NULL)
    1499             :     {
    1500           0 :         rtl_uString_new(pFieldType);
    1501           0 :         return;
    1502             :     }
    1503             : 
    1504           0 :     const sal_Char* pTmp = pEntry->m_pFields->getFieldType(index);
    1505             :     rtl_string2UString(
    1506             :         pFieldType, pTmp, pTmp == 0 ? 0 : rtl_str_getLength(pTmp),
    1507           0 :         RTL_TEXTENCODING_UTF8, OSTRING_TO_OUSTRING_CVTFLAGS);
    1508             : }
    1509             : 
    1510           0 : RTFieldAccess TYPEREG_CALLTYPE typereg_reader_getFieldFlags(void * hEntry, sal_uInt16 index)
    1511             : {
    1512           0 :     TypeRegistryEntry* pEntry = static_cast<TypeRegistryEntry*>(hEntry);
    1513             : 
    1514           0 :     if (pEntry == NULL) return RTFieldAccess::INVALID;
    1515             : 
    1516           0 :     return pEntry->m_pFields->getFieldAccess(index);
    1517             : }
    1518             : 
    1519           0 : bool TYPEREG_CALLTYPE typereg_reader_getFieldValue(
    1520             :     void * hEntry, sal_uInt16 index, RTValueType * type,
    1521             :     RTConstValueUnion * value)
    1522             : {
    1523           0 :     TypeRegistryEntry* pEntry = static_cast<TypeRegistryEntry*>(hEntry);
    1524             : 
    1525           0 :     if (pEntry == NULL) {
    1526           0 :         *type = RT_TYPE_NONE;
    1527           0 :         return true;
    1528             :     }
    1529             : 
    1530             :     try {
    1531           0 :         *type = pEntry->m_pFields->getFieldConstValue(index, value);
    1532           0 :     } catch (std::bad_alloc &) {
    1533           0 :         return false;
    1534             :     }
    1535           0 :     return true;
    1536             : }
    1537             : 
    1538           0 : static RTValueType TYPEREG_CALLTYPE getFieldConstValue(TypeReaderImpl hEntry, sal_uInt16 index, RTConstValueUnion* value)
    1539             : {
    1540           0 :     RTValueType t = RT_TYPE_NONE;
    1541           0 :     typereg_reader_getFieldValue(hEntry, index, &t, value);
    1542           0 :     return t;
    1543             : }
    1544             : 
    1545           0 : void TYPEREG_CALLTYPE typereg_reader_getFieldDocumentation(void * hEntry, rtl_uString** pDoku, sal_uInt16 index)
    1546             : {
    1547           0 :     TypeRegistryEntry* pEntry = static_cast<TypeRegistryEntry*>(hEntry);
    1548             : 
    1549           0 :     if (pEntry == NULL)
    1550             :     {
    1551           0 :         rtl_uString_new(pDoku);
    1552           0 :         return;
    1553             :     }
    1554             : 
    1555           0 :     const sal_Char* pTmp = pEntry->m_pFields->getFieldDoku(index);
    1556             :     rtl_string2UString(
    1557             :         pDoku, pTmp, pTmp == 0 ? 0 : rtl_str_getLength(pTmp),
    1558           0 :         RTL_TEXTENCODING_UTF8, OSTRING_TO_OUSTRING_CVTFLAGS);
    1559             : }
    1560             : 
    1561           0 : void TYPEREG_CALLTYPE typereg_reader_getFieldFileName(void * hEntry, rtl_uString** pFieldFileName, sal_uInt16 index)
    1562             : {
    1563           0 :     TypeRegistryEntry* pEntry = static_cast<TypeRegistryEntry*>(hEntry);
    1564             : 
    1565           0 :     if (pEntry == NULL)
    1566             :     {
    1567           0 :         rtl_uString_new(pFieldFileName);
    1568           0 :         return;
    1569             :     }
    1570             : 
    1571           0 :     const sal_Char* pTmp = pEntry->m_pFields->getFieldFileName(index);
    1572             :     rtl_string2UString(
    1573             :         pFieldFileName, pTmp, pTmp == 0 ? 0 : rtl_str_getLength(pTmp),
    1574           0 :         RTL_TEXTENCODING_UTF8, OSTRING_TO_OUSTRING_CVTFLAGS);
    1575             : }
    1576             : 
    1577             : 
    1578           0 : sal_uInt16 TYPEREG_CALLTYPE typereg_reader_getMethodCount(void * hEntry)
    1579             : {
    1580           0 :     TypeRegistryEntry* pEntry = static_cast<TypeRegistryEntry*>(hEntry);
    1581             : 
    1582           0 :     if (pEntry == NULL) return 0;
    1583             : 
    1584           0 :     return pEntry->m_pMethods->m_numOfEntries;
    1585             : }
    1586             : 
    1587           0 : static sal_uInt32 TYPEREG_CALLTYPE getMethodCount(TypeReaderImpl hEntry)
    1588             : {
    1589           0 :     return typereg_reader_getMethodCount(hEntry);
    1590             : }
    1591             : 
    1592           0 : void TYPEREG_CALLTYPE typereg_reader_getMethodName(void * hEntry, rtl_uString** pMethodName, sal_uInt16 index)
    1593             : {
    1594           0 :     TypeRegistryEntry* pEntry = static_cast<TypeRegistryEntry*>(hEntry);
    1595             : 
    1596           0 :     if (pEntry == NULL)
    1597             :     {
    1598           0 :         rtl_uString_new(pMethodName);
    1599           0 :         return;
    1600             :     }
    1601             : 
    1602           0 :     const sal_Char* pTmp = pEntry->m_pMethods->getMethodName(index);
    1603             :     rtl_string2UString(
    1604             :         pMethodName, pTmp, pTmp == 0 ? 0 : rtl_str_getLength(pTmp),
    1605           0 :         RTL_TEXTENCODING_UTF8, OSTRING_TO_OUSTRING_CVTFLAGS);
    1606             : }
    1607             : 
    1608           0 : sal_uInt16 TYPEREG_CALLTYPE typereg_reader_getMethodParameterCount(
    1609             :     void * hEntry, sal_uInt16 index)
    1610             : {
    1611           0 :     TypeRegistryEntry* pEntry = static_cast<TypeRegistryEntry*>(hEntry);
    1612             : 
    1613           0 :     if (pEntry == NULL) return 0;
    1614             : 
    1615           0 :     return pEntry->m_pMethods->getMethodParamCount(index);
    1616             : }
    1617             : 
    1618           0 : static sal_uInt32 TYPEREG_CALLTYPE getMethodParamCount(TypeReaderImpl hEntry, sal_uInt16 index)
    1619             : {
    1620           0 :     return typereg_reader_getMethodParameterCount(hEntry, index);
    1621             : }
    1622             : 
    1623           0 : void TYPEREG_CALLTYPE typereg_reader_getMethodParameterTypeName(void * hEntry, rtl_uString** pMethodParamType, sal_uInt16 index, sal_uInt16 paramIndex)
    1624             : {
    1625           0 :     TypeRegistryEntry* pEntry = static_cast<TypeRegistryEntry*>(hEntry);
    1626             : 
    1627           0 :     if (pEntry == NULL)
    1628             :     {
    1629           0 :         rtl_uString_new(pMethodParamType);
    1630           0 :         return;
    1631             :     }
    1632             : 
    1633           0 :     const sal_Char* pTmp = pEntry->m_pMethods->getMethodParamType(index, paramIndex);
    1634             :     rtl_string2UString(
    1635             :         pMethodParamType, pTmp, pTmp == 0 ? 0 : rtl_str_getLength(pTmp),
    1636           0 :         RTL_TEXTENCODING_UTF8, OSTRING_TO_OUSTRING_CVTFLAGS);
    1637             : }
    1638             : 
    1639           0 : void TYPEREG_CALLTYPE typereg_reader_getMethodParameterName(void * hEntry, rtl_uString** pMethodParamName, sal_uInt16 index, sal_uInt16 paramIndex)
    1640             : {
    1641           0 :     TypeRegistryEntry* pEntry = static_cast<TypeRegistryEntry*>(hEntry);
    1642             : 
    1643           0 :     if (pEntry == NULL)
    1644             :     {
    1645           0 :         rtl_uString_new(pMethodParamName);
    1646           0 :         return;
    1647             :     }
    1648             : 
    1649           0 :     const sal_Char* pTmp = pEntry->m_pMethods->getMethodParamName(index, paramIndex);
    1650             :     rtl_string2UString(
    1651             :         pMethodParamName, pTmp, pTmp == 0 ? 0 : rtl_str_getLength(pTmp),
    1652           0 :         RTL_TEXTENCODING_UTF8, OSTRING_TO_OUSTRING_CVTFLAGS);
    1653             : }
    1654             : 
    1655           0 : RTParamMode TYPEREG_CALLTYPE typereg_reader_getMethodParameterFlags(void * hEntry, sal_uInt16 index, sal_uInt16 paramIndex)
    1656             : {
    1657           0 :     TypeRegistryEntry* pEntry = static_cast<TypeRegistryEntry*>(hEntry);
    1658             : 
    1659           0 :     if (pEntry == NULL) return RT_PARAM_INVALID;
    1660             : 
    1661           0 :     return pEntry->m_pMethods->getMethodParamMode(index, paramIndex);
    1662             : }
    1663             : 
    1664           0 : sal_uInt16 TYPEREG_CALLTYPE typereg_reader_getMethodExceptionCount(
    1665             :     void * hEntry, sal_uInt16 index)
    1666             : {
    1667           0 :     TypeRegistryEntry* pEntry = static_cast<TypeRegistryEntry*>(hEntry);
    1668             : 
    1669           0 :     if (pEntry == NULL) return 0;
    1670             : 
    1671           0 :     return pEntry->m_pMethods->getMethodExcCount(index);
    1672             : }
    1673             : 
    1674           0 : static sal_uInt32 TYPEREG_CALLTYPE getMethodExcCount(TypeReaderImpl hEntry, sal_uInt16 index)
    1675             : {
    1676           0 :     return typereg_reader_getMethodExceptionCount(hEntry, index);
    1677             : }
    1678             : 
    1679           0 : void TYPEREG_CALLTYPE typereg_reader_getMethodExceptionTypeName(void * hEntry, rtl_uString** pMethodExcpType, sal_uInt16 index, sal_uInt16 excIndex)
    1680             : {
    1681           0 :     TypeRegistryEntry* pEntry = static_cast<TypeRegistryEntry*>(hEntry);
    1682             : 
    1683           0 :     if (pEntry == NULL)
    1684             :     {
    1685           0 :         rtl_uString_new(pMethodExcpType);
    1686           0 :         return;
    1687             :     }
    1688             : 
    1689           0 :     const sal_Char* pTmp = pEntry->m_pMethods->getMethodExcType(index, excIndex);
    1690             :     rtl_string2UString(
    1691             :         pMethodExcpType, pTmp, pTmp == 0 ? 0 : rtl_str_getLength(pTmp),
    1692           0 :         RTL_TEXTENCODING_UTF8, OSTRING_TO_OUSTRING_CVTFLAGS);
    1693             : }
    1694             : 
    1695           0 : void TYPEREG_CALLTYPE typereg_reader_getMethodReturnTypeName(void * hEntry, rtl_uString** pMethodReturnType, sal_uInt16 index)
    1696             : {
    1697           0 :     TypeRegistryEntry* pEntry = static_cast<TypeRegistryEntry*>(hEntry);
    1698             : 
    1699           0 :     if (pEntry == NULL)
    1700             :     {
    1701           0 :         rtl_uString_new(pMethodReturnType);
    1702           0 :         return;
    1703             :     }
    1704             : 
    1705           0 :     const sal_Char* pTmp = pEntry->m_pMethods->getMethodReturnType(index);
    1706             :     rtl_string2UString(
    1707             :         pMethodReturnType, pTmp, pTmp == 0 ? 0 : rtl_str_getLength(pTmp),
    1708           0 :         RTL_TEXTENCODING_UTF8, OSTRING_TO_OUSTRING_CVTFLAGS);
    1709             : }
    1710             : 
    1711           0 : RTMethodMode TYPEREG_CALLTYPE typereg_reader_getMethodFlags(void * hEntry, sal_uInt16 index)
    1712             : {
    1713           0 :     TypeRegistryEntry* pEntry = static_cast<TypeRegistryEntry*>(hEntry);
    1714             : 
    1715           0 :     if (pEntry == NULL) return RTMethodMode::INVALID;
    1716             : 
    1717           0 :     return pEntry->m_pMethods->getMethodMode(index);
    1718             : }
    1719             : 
    1720           0 : void TYPEREG_CALLTYPE typereg_reader_getMethodDocumentation(void * hEntry, rtl_uString** pMethodDoku, sal_uInt16 index)
    1721             : {
    1722           0 :     TypeRegistryEntry* pEntry = static_cast<TypeRegistryEntry*>(hEntry);
    1723             : 
    1724           0 :     if (pEntry == NULL)
    1725             :     {
    1726           0 :         rtl_uString_new(pMethodDoku);
    1727           0 :         return;
    1728             :     }
    1729             : 
    1730           0 :     const sal_Char* pTmp = pEntry->m_pMethods->getMethodDoku(index);
    1731             :     rtl_string2UString(
    1732             :         pMethodDoku, pTmp, pTmp == 0 ? 0 : rtl_str_getLength(pTmp),
    1733           0 :         RTL_TEXTENCODING_UTF8, OSTRING_TO_OUSTRING_CVTFLAGS);
    1734             : }
    1735             : 
    1736           0 : sal_uInt16 TYPEREG_CALLTYPE typereg_reader_getReferenceCount(void * hEntry)
    1737             : {
    1738           0 :     TypeRegistryEntry* pEntry = static_cast<TypeRegistryEntry*>(hEntry);
    1739             : 
    1740           0 :     if (pEntry == NULL) return 0;
    1741             : 
    1742           0 :     return pEntry->m_pReferences->m_numOfEntries;
    1743             : }
    1744             : 
    1745           0 : static sal_uInt32 TYPEREG_CALLTYPE getReferenceCount(TypeReaderImpl hEntry)
    1746             : {
    1747           0 :     return typereg_reader_getReferenceCount(hEntry);
    1748             : }
    1749             : 
    1750           0 : void TYPEREG_CALLTYPE typereg_reader_getReferenceTypeName(void * hEntry, rtl_uString** pReferenceName, sal_uInt16 index)
    1751             : {
    1752           0 :     TypeRegistryEntry* pEntry = static_cast<TypeRegistryEntry*>(hEntry);
    1753             : 
    1754           0 :     if (pEntry == NULL)
    1755             :     {
    1756           0 :         rtl_uString_new(pReferenceName);
    1757           0 :         return;
    1758             :     }
    1759             : 
    1760           0 :     const sal_Char* pTmp = pEntry->m_pReferences->getReferenceName(index);
    1761             :     rtl_string2UString(
    1762             :         pReferenceName, pTmp, pTmp == 0 ? 0 : rtl_str_getLength(pTmp),
    1763           0 :         RTL_TEXTENCODING_UTF8, OSTRING_TO_OUSTRING_CVTFLAGS);
    1764             : }
    1765             : 
    1766           0 : RTReferenceType TYPEREG_CALLTYPE typereg_reader_getReferenceSort(void * hEntry, sal_uInt16 index)
    1767             : {
    1768           0 :     TypeRegistryEntry* pEntry = static_cast<TypeRegistryEntry*>(hEntry);
    1769             : 
    1770           0 :     if (pEntry == NULL) return RTReferenceType::INVALID;
    1771             : 
    1772           0 :     return pEntry->m_pReferences->getReferenceType(index);
    1773             : }
    1774             : 
    1775           0 : void TYPEREG_CALLTYPE typereg_reader_getReferenceDocumentation(void * hEntry, rtl_uString** pReferenceDoku, sal_uInt16 index)
    1776             : {
    1777           0 :     TypeRegistryEntry* pEntry = static_cast<TypeRegistryEntry*>(hEntry);
    1778             : 
    1779           0 :     if (pEntry == NULL)
    1780             :     {
    1781           0 :         rtl_uString_new(pReferenceDoku);
    1782           0 :         return;
    1783             :     }
    1784             : 
    1785           0 :     const sal_Char* pTmp = pEntry->m_pReferences->getReferenceDoku(index);
    1786             :     rtl_string2UString(
    1787             :         pReferenceDoku, pTmp, pTmp == 0 ? 0 : rtl_str_getLength(pTmp),
    1788           0 :         RTL_TEXTENCODING_UTF8, OSTRING_TO_OUSTRING_CVTFLAGS);
    1789             : }
    1790             : 
    1791           0 : RTFieldAccess TYPEREG_CALLTYPE typereg_reader_getReferenceFlags(void * hEntry, sal_uInt16 index)
    1792             : {
    1793           0 :     TypeRegistryEntry* pEntry = static_cast<TypeRegistryEntry*>(hEntry);
    1794             : 
    1795           0 :     if (pEntry == NULL) return RTFieldAccess::INVALID;
    1796             : 
    1797           0 :     return pEntry->m_pReferences->getReferenceAccess(index);
    1798             : }
    1799             : 
    1800           0 : sal_uInt16 TYPEREG_CALLTYPE typereg_reader_getSuperTypeCount(void * hEntry)
    1801             : {
    1802           0 :     TypeRegistryEntry* pEntry = static_cast<TypeRegistryEntry*>(hEntry);
    1803             : 
    1804           0 :     if (pEntry == NULL) return 0;
    1805             : 
    1806           0 :     return pEntry->m_nSuperTypes;
    1807             : }
    1808             : 
    1809           0 : void TYPEREG_CALLTYPE typereg_reader_getSuperTypeName(
    1810             :     void * hEntry, rtl_uString ** pSuperTypeName, sal_uInt16 index)
    1811             : {
    1812           0 :     TypeRegistryEntry* pEntry = static_cast<TypeRegistryEntry*>(hEntry);
    1813           0 :     if (pEntry != nullptr) {
    1814             :         try {
    1815             :             OSL_ASSERT(index < pEntry->m_nSuperTypes);
    1816           0 :             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           0 :                 RTL_TEXTENCODING_UTF8, OSTRING_TO_OUSTRING_CVTFLAGS);
    1820           0 :             return;
    1821           0 :         } catch (BlopObject::BoundsError &) {
    1822             :             SAL_WARN("registry", "bad data");
    1823             :         }
    1824             :     }
    1825           0 :     rtl_uString_new(pSuperTypeName);
    1826             : }
    1827             : 
    1828           0 : RegistryTypeReader_Api* TYPEREG_CALLTYPE initRegistryTypeReader_Api()
    1829             : {
    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           0 :     if (!aApi.acquire)
    1832             :     {
    1833           0 :         aApi.createEntry            = &createEntry;
    1834           0 :         aApi.acquire                = &typereg_reader_acquire;
    1835           0 :         aApi.release                = &typereg_reader_release;
    1836           0 :         aApi.getMinorVersion        = &getMinorVersion;
    1837           0 :         aApi.getMajorVersion        = &getMajorVersion;
    1838           0 :         aApi.getTypeClass           = &typereg_reader_getTypeClass;
    1839           0 :         aApi.getTypeName            = &typereg_reader_getTypeName;
    1840           0 :         aApi.getSuperTypeName       = &getSuperTypeName;
    1841           0 :         aApi.getUik                 = &getUik;
    1842           0 :         aApi.getDoku                = &typereg_reader_getDocumentation;
    1843           0 :         aApi.getFileName            = &typereg_reader_getFileName;
    1844           0 :         aApi.getFieldCount          = &getFieldCount;
    1845           0 :         aApi.getFieldName           = &typereg_reader_getFieldName;
    1846           0 :         aApi.getFieldType           = &typereg_reader_getFieldTypeName;
    1847           0 :         aApi.getFieldAccess         = &typereg_reader_getFieldFlags;
    1848           0 :         aApi.getFieldConstValue     = &getFieldConstValue;
    1849           0 :         aApi.getFieldDoku           = &typereg_reader_getFieldDocumentation;
    1850           0 :         aApi.getFieldFileName       = &typereg_reader_getFieldFileName;
    1851           0 :         aApi.getMethodCount         = &getMethodCount;
    1852           0 :         aApi.getMethodName          = &typereg_reader_getMethodName;
    1853           0 :         aApi.getMethodParamCount    = &getMethodParamCount;
    1854           0 :         aApi.getMethodParamType = &typereg_reader_getMethodParameterTypeName;
    1855           0 :         aApi.getMethodParamName     = &typereg_reader_getMethodParameterName;
    1856           0 :         aApi.getMethodParamMode     = &typereg_reader_getMethodParameterFlags;
    1857           0 :         aApi.getMethodExcCount      = &getMethodExcCount;
    1858           0 :         aApi.getMethodExcType = &typereg_reader_getMethodExceptionTypeName;
    1859           0 :         aApi.getMethodReturnType    = &typereg_reader_getMethodReturnTypeName;
    1860           0 :         aApi.getMethodMode          = &typereg_reader_getMethodFlags;
    1861           0 :         aApi.getMethodDoku          = &typereg_reader_getMethodDocumentation;
    1862           0 :         aApi.getReferenceCount      = &getReferenceCount;
    1863           0 :         aApi.getReferenceName       = &typereg_reader_getReferenceTypeName;
    1864           0 :         aApi.getReferenceType       = &typereg_reader_getReferenceSort;
    1865           0 :         aApi.getReferenceDoku       = &typereg_reader_getReferenceDocumentation;
    1866           0 :         aApi.getReferenceAccess     = &typereg_reader_getReferenceFlags;
    1867             : 
    1868           0 :         return (&aApi);
    1869             :     }
    1870             :     else
    1871             :     {
    1872           0 :         return (&aApi);
    1873             :     }
    1874             : }
    1875             : 
    1876             : /* vim:set shiftwidth=4 softtabstop=4 expandtab: */

Generated by: LCOV version 1.11