LCOV - code coverage report
Current view: top level - registry/source - reflwrit.cxx (source / functions) Hit Total Coverage
Test: commit c8344322a7af75b84dd3ca8f78b05543a976dfd5 Lines: 422 585 72.1 %
Date: 2015-06-13 12:38:46 Functions: 34 51 66.7 %
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             : 
      21             : #include <new>
      22             : #include <sal/types.h>
      23             : #include <sal/macros.h>
      24             : #include <osl/endian.h>
      25             : #include <rtl/alloc.h>
      26             : #include "rtl/string.hxx"
      27             : #include "rtl/ustring.hxx"
      28             : 
      29             : #include "registry/reflwrit.hxx"
      30             : #include "registry/version.h"
      31             : #include "registry/writer.h"
      32             : 
      33             : #include "reflcnst.hxx"
      34             : 
      35             : 
      36             : 
      37             : namespace {
      38             : 
      39        2825 : inline OString toByteString(rtl_uString const * str) {
      40             :     return OString(
      41             :         str->buffer, str->length, RTL_TEXTENCODING_UTF8,
      42        2825 :         OUSTRING_TO_OSTRING_CVTFLAGS);
      43             : }
      44             : 
      45             : }
      46             : 
      47             : static sal_Unicode NULL_WSTRING[1] = { 0 };
      48             : 
      49             : #define BLOP_OFFSET_MAGIC       0
      50             : #define BLOP_OFFSET_SIZE        (BLOP_OFFSET_MAGIC + sizeof(sal_uInt32))
      51             : #define BLOP_OFFSET_MINOR       (BLOP_OFFSET_SIZE + sizeof(sal_uInt32))
      52             : #define BLOP_OFFSET_MAJOR       (BLOP_OFFSET_MINOR + sizeof(sal_uInt16))
      53             : #define BLOP_OFFSET_N_ENTRIES   (BLOP_OFFSET_MAJOR + sizeof(sal_uInt16))
      54             : #define BLOP_HEADER_N_ENTRIES   6
      55             : 
      56             : #define BLOP_FIELD_N_ENTRIES        6
      57             : 
      58             : #define BLOP_METHOD_N_ENTRIES   5
      59             : 
      60             : #define BLOP_PARAM_N_ENTRIES    3
      61             : 
      62             : #define BLOP_REFERENCE_N_ENTRIES    4
      63             : 
      64           0 : sal_uInt32 UINT16StringLen(const sal_uInt8* wstring)
      65             : {
      66           0 :     if (!wstring) return 0;
      67             : 
      68           0 :     const sal_uInt8* b = wstring;
      69             : 
      70           0 :     while (b[0] || b[1]) b += sizeof(sal_uInt16);
      71             : 
      72           0 :     return ((b - wstring) / sizeof(sal_uInt16));
      73             : }
      74             : 
      75           0 : sal_uInt32 writeString(sal_uInt8* buffer, const sal_Unicode* v)
      76             : {
      77           0 :     sal_uInt32 len = rtl_ustr_getLength(v) + 1;
      78             :     sal_uInt32 i;
      79           0 :     sal_uInt8* buff = buffer;
      80             : 
      81           0 :     for (i = 0; i < len; i++)
      82             :     {
      83           0 :         buff += writeUINT16(buff, (sal_uInt16) v[i]);
      84             :     }
      85             : 
      86           0 :     return (buff - buffer);
      87             : }
      88             : 
      89           0 : sal_uInt32 readString(const sal_uInt8* buffer, sal_Unicode* v, sal_uInt32 maxSize)
      90             : {
      91           0 :     sal_uInt32 len = UINT16StringLen(buffer) + 1;
      92             :     sal_uInt32 i;
      93           0 :     sal_uInt8* buff = const_cast<sal_uInt8*>(buffer);
      94             : 
      95           0 :     if(len > maxSize / 2)
      96             :     {
      97           0 :         len = maxSize / 2;
      98             :     }
      99             : 
     100           0 :     for (i = 0; i < (len - 1); i++)
     101             :     {
     102             :         sal_uInt16 aChar;
     103             : 
     104           0 :         buff += readUINT16(buff, aChar);
     105             : 
     106           0 :         v[i] = (sal_Unicode) aChar;
     107             :     }
     108             : 
     109           0 :     v[len - 1] = L'\0';
     110             : 
     111           0 :     return (buff - buffer);
     112             : }
     113             : 
     114           1 : sal_uInt32 writeFloat(sal_uInt8* buffer, float v)
     115             : {
     116             :     union
     117             :     {
     118             :         float   v;
     119             :         sal_uInt32  b;
     120             :     } x;
     121             : 
     122           1 :     x.v = v;
     123             : 
     124             : #ifdef REGTYPE_IEEE_NATIVE
     125           1 :     writeUINT32(buffer, x.b);
     126             : #else
     127             : #   error no IEEE
     128             : #endif
     129             : 
     130           1 :     return sizeof(sal_uInt32);
     131             : }
     132             : 
     133           1 : sal_uInt32 writeDouble(sal_uInt8* buffer, double v)
     134             : {
     135             :     union
     136             :     {
     137             :         double v;
     138             :         struct
     139             :         {
     140             :             sal_uInt32  b1;
     141             :             sal_uInt32  b2;
     142             :         } b;
     143             :     } x;
     144             : 
     145           1 :     x.v = v;
     146             : 
     147             : #ifdef REGTYPE_IEEE_NATIVE
     148             : #   ifdef OSL_BIGENDIAN
     149             :     writeUINT32(buffer, x.b.b1);
     150             :     writeUINT32(buffer + sizeof(sal_uInt32), x.b.b2);
     151             : #   else
     152           1 :     writeUINT32(buffer, x.b.b2);
     153           1 :     writeUINT32(buffer + sizeof(sal_uInt32), x.b.b1);
     154             : #   endif
     155             : #else
     156             : #   error no IEEE
     157             : #endif
     158             : 
     159           1 :     return (sizeof(sal_uInt32) + sizeof(sal_uInt32));
     160             : }
     161             : 
     162             : /**************************************************************************
     163             : 
     164             :     buffer write functions
     165             : 
     166             : **************************************************************************/
     167             : 
     168             : 
     169             : /**************************************************************************
     170             : 
     171             :     struct CPInfo
     172             : 
     173             : **************************************************************************/
     174             : 
     175             : struct CPInfo
     176             : {
     177             :     CPInfoTag   m_tag;
     178             :     union
     179             :     {
     180             :         const sal_Char*     aUtf8;
     181             :         RTUik*              aUik;
     182             :         RTConstValueUnion   aConst;
     183             :     } m_value;
     184             : 
     185             :     sal_uInt16      m_index;
     186             :     struct CPInfo*  m_next;
     187             : 
     188             :     CPInfo(CPInfoTag tag, struct CPInfo* prev);
     189             : 
     190             :     sal_uInt32 getBlopSize();
     191             : 
     192             :     sal_uInt32 toBlop(sal_uInt8* buffer);
     193             : };
     194             : 
     195        1891 : CPInfo::CPInfo(CPInfoTag tag, struct CPInfo* prev)
     196             :     : m_tag(tag)
     197             :     , m_index(0)
     198        1891 :     , m_next(NULL)
     199             : {
     200        1891 :     if (prev)
     201             :     {
     202        1354 :         m_index = prev->m_index + 1;
     203        1354 :         prev->m_next = this;
     204             :     }
     205        1891 : }
     206             : 
     207        2708 : sal_uInt32 CPInfo::getBlopSize()
     208             : {
     209        2708 :     sal_uInt32 size = sizeof(sal_uInt32) /* size */ + sizeof(sal_uInt16) /* tag */;
     210             : 
     211        2708 :     switch (m_tag)
     212             :     {
     213             :         case CP_TAG_CONST_BOOL:
     214           2 :             size += sizeof(sal_uInt8);
     215           2 :             break;
     216             :         case CP_TAG_CONST_BYTE:
     217          20 :             size += sizeof(sal_uInt8);
     218          20 :             break;
     219             :         case CP_TAG_CONST_INT16:
     220          14 :             size += sizeof(sal_Int16);
     221          14 :             break;
     222             :         case CP_TAG_CONST_UINT16:
     223          12 :             size += sizeof(sal_uInt16);
     224          12 :             break;
     225             :         case CP_TAG_CONST_INT32:
     226          98 :             size += sizeof(sal_Int32);
     227          98 :             break;
     228             :         case CP_TAG_CONST_UINT32:
     229          12 :             size += sizeof(sal_uInt32);
     230          12 :             break;
     231             :         case CP_TAG_CONST_INT64:
     232          14 :               size += sizeof(sal_Int64);
     233          14 :             break;
     234             :         case CP_TAG_CONST_UINT64:
     235          12 :             size += sizeof(sal_uInt64);
     236          12 :             break;
     237             :         case CP_TAG_CONST_FLOAT:
     238           2 :             size += sizeof(sal_uInt32);
     239           2 :             break;
     240             :         case CP_TAG_CONST_DOUBLE:
     241           2 :             size += sizeof(sal_uInt32) + sizeof(sal_uInt32);
     242           2 :             break;
     243             :         case CP_TAG_CONST_STRING:
     244           0 :             size += (rtl_ustr_getLength(m_value.aConst.aString) + 1) * sizeof(sal_uInt16);
     245           0 :             break;
     246             :         case CP_TAG_UTF8_NAME:
     247        2520 :             size += strlen(m_value.aUtf8) + 1;
     248        2520 :             break;
     249             :         case CP_TAG_UIK:
     250           0 :             size += sizeof(sal_uInt32) + sizeof(sal_uInt16) + sizeof(sal_uInt16) + sizeof(sal_uInt32) + sizeof(sal_uInt32);
     251           0 :             break;
     252             :         default:
     253           0 :             break;
     254             :     }
     255             : 
     256        2708 :     return size;
     257             : }
     258             : 
     259             : 
     260        1354 : sal_uInt32 CPInfo::toBlop(sal_uInt8* buffer)
     261             : {
     262        1354 :     sal_uInt8* buff = buffer;
     263             : 
     264        1354 :     buff += writeUINT32(buff, getBlopSize());
     265        1354 :     buff += writeUINT16(buff, (sal_uInt16) m_tag);
     266             : 
     267        1354 :     switch (m_tag)
     268             :     {
     269             :         case CP_TAG_CONST_BOOL:
     270           1 :             buff += writeBYTE(buff, (sal_uInt8) m_value.aConst.aBool);
     271           1 :             break;
     272             :         case CP_TAG_CONST_BYTE:
     273          10 :             buff += writeBYTE(
     274          20 :                 buff, static_cast< sal_uInt8 >(m_value.aConst.aByte));
     275          10 :             break;
     276             :         case CP_TAG_CONST_INT16:
     277           7 :             buff += writeINT16(buff, m_value.aConst.aShort);
     278           7 :             break;
     279             :         case CP_TAG_CONST_UINT16:
     280           6 :             buff += writeINT16(buff, m_value.aConst.aUShort);
     281           6 :             break;
     282             :         case CP_TAG_CONST_INT32:
     283          49 :             buff += writeINT32(buff, m_value.aConst.aLong);
     284          49 :             break;
     285             :         case CP_TAG_CONST_UINT32:
     286           6 :             buff += writeUINT32(buff, m_value.aConst.aULong);
     287           6 :             break;
     288             :         case CP_TAG_CONST_INT64:
     289           7 :             buff += writeUINT64(buff, m_value.aConst.aHyper);
     290           7 :             break;
     291             :         case CP_TAG_CONST_UINT64:
     292           6 :             buff += writeUINT64(buff, m_value.aConst.aUHyper);
     293           6 :             break;
     294             :         case CP_TAG_CONST_FLOAT:
     295           1 :             buff += writeFloat(buff, m_value.aConst.aFloat);
     296           1 :             break;
     297             :         case CP_TAG_CONST_DOUBLE:
     298           1 :             buff += writeDouble(buff, m_value.aConst.aDouble);
     299           1 :             break;
     300             :         case CP_TAG_CONST_STRING:
     301           0 :             buff += writeString(buff, m_value.aConst.aString);
     302           0 :             break;
     303             :         case CP_TAG_UTF8_NAME:
     304        1260 :             buff += writeUtf8(buff, m_value.aUtf8);
     305        1260 :             break;
     306             :         case CP_TAG_UIK:
     307           0 :             buff += writeUINT32(buff, m_value.aUik->m_Data1);
     308           0 :             buff += writeUINT16(buff, m_value.aUik->m_Data2);
     309           0 :             buff += writeUINT16(buff, m_value.aUik->m_Data3);
     310           0 :             buff += writeUINT32(buff, m_value.aUik->m_Data4);
     311           0 :             buff += writeUINT32(buff, m_value.aUik->m_Data5);
     312           0 :             break;
     313             :         default:
     314           0 :             break;
     315             :     }
     316             : 
     317        1354 :     return (buff - buffer);
     318             : }
     319             : 
     320             : 
     321             : /**************************************************************************
     322             : 
     323             :     class FieldEntry
     324             : 
     325             : **************************************************************************/
     326             : 
     327             : class FieldEntry
     328             : {
     329             : 
     330             : public:
     331             : 
     332             :     OString           m_name;
     333             :     OString           m_typeName;
     334             :     OString           m_doku;
     335             :     OString           m_fileName;
     336             :     RTFieldAccess     m_access;
     337             :     RTValueType       m_constValueType;
     338             :     RTConstValueUnion m_constValue;
     339             : 
     340             :     FieldEntry();
     341             :     ~FieldEntry();
     342             : 
     343             :     void setData(const OString&    name,
     344             :                  const OString&    typeName,
     345             :                  const OString&    doku,
     346             :                  const OString&    fileName,
     347             :                  RTFieldAccess     access,
     348             :                  RTValueType       constValueType,
     349             :                  RTConstValueUnion constValue);
     350             :         // throws std::bad_alloc
     351             : };
     352             : 
     353         173 : FieldEntry::FieldEntry()
     354             :     : m_access(RTFieldAccess::INVALID)
     355         173 :     , m_constValueType(RT_TYPE_NONE)
     356             : {
     357         173 : }
     358             : 
     359         346 : FieldEntry::~FieldEntry()
     360             : {
     361         173 :     if (
     362         173 :         (m_constValueType == RT_TYPE_STRING) &&
     363           0 :         m_constValue.aString &&
     364           0 :         (m_constValue.aString != NULL_WSTRING)
     365             :        )
     366             :     {
     367           0 :         delete[] m_constValue.aString;
     368             :     }
     369         173 : }
     370             : 
     371         173 : void FieldEntry::setData(const OString&    name,
     372             :                          const OString&    typeName,
     373             :                          const OString&    doku,
     374             :                          const OString&    fileName,
     375             :                          RTFieldAccess      access,
     376             :                          RTValueType        constValueType,
     377             :                          RTConstValueUnion  constValue)
     378             : {
     379         173 :     sal_Unicode * newValue = 0;
     380         173 :     if (constValueType == RT_TYPE_STRING && constValue.aString != 0) {
     381           0 :         sal_Int32 n = rtl_ustr_getLength(constValue.aString) + 1;
     382           0 :         newValue = new sal_Unicode[n];
     383           0 :         memcpy(newValue, constValue.aString, n * sizeof (sal_Unicode));
     384             :     }
     385             : 
     386         173 :     m_name = name;
     387         173 :     m_typeName = typeName;
     388         173 :     m_doku = doku;
     389         173 :     m_fileName = fileName;
     390             : 
     391         173 :     if (
     392         173 :         (m_constValueType == RT_TYPE_STRING) &&
     393           0 :         m_constValue.aString &&
     394           0 :         (m_constValue.aString != NULL_WSTRING)
     395             :        )
     396             :     {
     397           0 :         delete[] m_constValue.aString;
     398             :     }
     399             : 
     400         173 :     m_access = access;
     401         173 :     m_constValueType = constValueType;
     402             : 
     403         173 :     if (m_constValueType == RT_TYPE_STRING)
     404             :     {
     405           0 :         if (constValue.aString == NULL)
     406           0 :             m_constValue.aString = NULL_WSTRING;
     407             :         else
     408             :         {
     409           0 :             m_constValue.aString = newValue;
     410             :         }
     411             :     }
     412             :     else
     413             :     {
     414         173 :         m_constValue = constValue;
     415             :     }
     416         173 : }
     417             : 
     418             : /**************************************************************************
     419             : 
     420             :     class ParamEntry
     421             : 
     422             : **************************************************************************/
     423             : 
     424             : class ParamEntry
     425             : {
     426             : public:
     427             : 
     428             :     OString     m_typeName;
     429             :     OString     m_name;
     430             :     RTParamMode m_mode;
     431             : 
     432             :     ParamEntry();
     433             :     ~ParamEntry();
     434             : 
     435             :     void setData(const OString& typeName,
     436             :                  const OString& name,
     437             :                  RTParamMode    mode);
     438             : };
     439             : 
     440          21 : ParamEntry::ParamEntry()
     441          21 :     : m_mode(RT_PARAM_INVALID)
     442             : {
     443          21 : }
     444             : 
     445          21 : ParamEntry::~ParamEntry()
     446             : {
     447          21 : }
     448             : 
     449          21 : void ParamEntry::setData(const OString& typeName,
     450             :                          const OString& name,
     451             :                          RTParamMode    mode)
     452             : {
     453          21 :     m_name = name;
     454          21 :     m_typeName = typeName;
     455          21 :     m_mode = mode;
     456          21 : }
     457             : 
     458             : /**************************************************************************
     459             : 
     460             :     class ReferenceEntry
     461             : 
     462             : **************************************************************************/
     463             : 
     464             : class ReferenceEntry
     465             : {
     466             : public:
     467             : 
     468             :     OString         m_name;
     469             :     OString         m_doku;
     470             :     RTReferenceType m_type;
     471             :     RTFieldAccess   m_access;
     472             : 
     473             :     ReferenceEntry();
     474             :     ~ReferenceEntry();
     475             : 
     476             :     void setData(const OString&     name,
     477             :                  RTReferenceType    refType,
     478             :                  const OString&     doku,
     479             :                  RTFieldAccess      access);
     480             : };
     481             : 
     482          59 : ReferenceEntry::ReferenceEntry()
     483             :     : m_type(RTReferenceType::INVALID)
     484          59 :     , m_access(RTFieldAccess::INVALID)
     485             : {
     486          59 : }
     487             : 
     488          59 : ReferenceEntry::~ReferenceEntry()
     489             : {
     490          59 : }
     491             : 
     492          59 : void ReferenceEntry::setData(const OString&    name,
     493             :                              RTReferenceType   refType,
     494             :                              const OString&    doku,
     495             :                              RTFieldAccess     access)
     496             : {
     497          59 :     m_name = name;
     498          59 :     m_doku = doku;
     499          59 :     m_type = refType;
     500          59 :     m_access = access;
     501          59 : }
     502             : 
     503             : /**************************************************************************
     504             : 
     505             :     class MethodEntry
     506             : 
     507             : **************************************************************************/
     508             : 
     509             : class MethodEntry
     510             : {
     511             : public:
     512             : 
     513             :     OString         m_name;
     514             :     OString         m_returnTypeName;
     515             :     RTMethodMode    m_mode;
     516             :     sal_uInt16      m_paramCount;
     517             :     ParamEntry*     m_params;
     518             :     sal_uInt16      m_excCount;
     519             :     OString*        m_excNames;
     520             :     OString         m_doku;
     521             : 
     522             :     MethodEntry();
     523             :     ~MethodEntry();
     524             : 
     525             :     void setData(const OString&    name,
     526             :                  const OString&    returnTypeName,
     527             :                  RTMethodMode      mode,
     528             :                  sal_uInt16        paramCount,
     529             :                  sal_uInt16        excCount,
     530             :                  const OString&    doku);
     531             : 
     532             :     void setExcName(sal_uInt16 excIndex, const OString& name);
     533             : 
     534             : protected:
     535             : 
     536             :     void reallocParams(sal_uInt16 size);
     537             :     void reallocExcs(sal_uInt16 size);
     538             : };
     539             : 
     540          54 : MethodEntry::MethodEntry()
     541             :     : m_mode(RTMethodMode::INVALID)
     542             :     , m_paramCount(0)
     543             :     , m_params(NULL)
     544             :     , m_excCount(0)
     545          54 :     , m_excNames(NULL)
     546             : {
     547          54 : }
     548             : 
     549         108 : MethodEntry::~MethodEntry()
     550             : {
     551          54 :     if (m_params)
     552          17 :         delete[] m_params;
     553             : 
     554          54 :     if (m_excNames)
     555          19 :         delete[] m_excNames;
     556          54 : }
     557             : 
     558          54 : void MethodEntry::setData(const OString&    name,
     559             :                           const OString&    returnTypeName,
     560             :                           RTMethodMode      mode,
     561             :                           sal_uInt16        paramCount,
     562             :                           sal_uInt16        excCount,
     563             :                           const OString&    doku)
     564             : {
     565          54 :     m_name = name;
     566          54 :     m_returnTypeName = returnTypeName;
     567          54 :     m_doku = doku;
     568             : 
     569          54 :     m_mode = mode;
     570             : 
     571          54 :     reallocParams(paramCount);
     572          54 :     reallocExcs(excCount);
     573          54 : }
     574             : 
     575          20 : void MethodEntry::setExcName(sal_uInt16 excIndex, const OString& name)
     576             : {
     577          20 :     if (excIndex < m_excCount)
     578             :     {
     579          20 :         m_excNames[excIndex] = name;
     580             :     }
     581          20 : }
     582             : 
     583          54 : void MethodEntry::reallocParams(sal_uInt16 size)
     584             : {
     585             :     ParamEntry* newParams;
     586             : 
     587          54 :     if (size)
     588          17 :         newParams = new ParamEntry[size];
     589             :     else
     590          37 :         newParams = NULL;
     591             : 
     592          54 :     if (m_paramCount)
     593             :     {
     594             :         sal_uInt16 i;
     595           0 :         sal_uInt16 mn = size < m_paramCount ? size : m_paramCount;
     596             : 
     597           0 :         for (i = 0; i < mn; i++)
     598             :         {
     599           0 :             newParams[i].setData(m_params[i].m_typeName, m_params[i].m_name, m_params[i].m_mode);
     600             :         }
     601             : 
     602           0 :         delete[] m_params;
     603             :     }
     604             : 
     605          54 :     m_paramCount = size;
     606          54 :     m_params = newParams;
     607          54 : }
     608             : 
     609          54 : void MethodEntry::reallocExcs(sal_uInt16 size)
     610             : {
     611             :     OString* newExcNames;
     612             : 
     613          54 :     if (size)
     614          19 :         newExcNames = new OString[size];
     615             :     else
     616          35 :         newExcNames = NULL;
     617             : 
     618             :     sal_uInt16 i;
     619          54 :     sal_uInt16 mn = size < m_excCount ? size : m_excCount;
     620             : 
     621          54 :     for (i = 0; i < mn; i++)
     622             :     {
     623           0 :         newExcNames[i] = m_excNames[i];
     624             :     }
     625             : 
     626          54 :     delete[] m_excNames;
     627             : 
     628          54 :     m_excCount = size;
     629          54 :     m_excNames = newExcNames;
     630          54 : }
     631             : 
     632             : 
     633             : /**************************************************************************
     634             : 
     635             :     class TypeRegistryEntry
     636             : 
     637             : **************************************************************************/
     638             : 
     639             : class TypeWriter
     640             : {
     641             : 
     642             : public:
     643             : 
     644             :     sal_uInt32          m_refCount;
     645             :     typereg_Version     m_version;
     646             :     RTTypeClass         m_typeClass;
     647             :     OString             m_typeName;
     648             :     sal_uInt16          m_nSuperTypes;
     649             :     OString*            m_superTypeNames;
     650             :     RTUik*              m_pUik;
     651             :     OString             m_doku;
     652             :     OString             m_fileName;
     653             :     sal_uInt16          m_fieldCount;
     654             :     FieldEntry*         m_fields;
     655             :     sal_uInt16          m_methodCount;
     656             :     MethodEntry*        m_methods;
     657             :     sal_uInt16          m_referenceCount;
     658             :     ReferenceEntry*     m_references;
     659             : 
     660             :     sal_uInt8*          m_blop;
     661             :     sal_uInt32          m_blopSize;
     662             : 
     663             :     TypeWriter(typereg_Version version,
     664             :                OString const & documentation,
     665             :                OString const & fileName,
     666             :                RTTypeClass      RTTypeClass,
     667             :                bool             published,
     668             :                const OString&   typeName,
     669             :                sal_uInt16       superTypeCount,
     670             :                sal_uInt16       FieldCount,
     671             :                sal_uInt16       methodCount,
     672             :                sal_uInt16       referenceCount);
     673             : 
     674             :     ~TypeWriter();
     675             : 
     676             :     void setSuperType(sal_uInt16 index, OString const & name);
     677             : 
     678             :     void createBlop(); // throws std::bad_alloc
     679             : };
     680             : 
     681         537 : TypeWriter::TypeWriter(typereg_Version version,
     682             :                        OString const & documentation,
     683             :                        OString const & fileName,
     684             :                        RTTypeClass      RTTypeClass,
     685             :                        bool             published,
     686             :                        const OString&   typeName,
     687             :                        sal_uInt16       superTypeCount,
     688             :                        sal_uInt16       fieldCount,
     689             :                        sal_uInt16       methodCount,
     690             :                        sal_uInt16       referenceCount)
     691             :     : m_refCount(1)
     692             :     , m_version(version)
     693             :     , m_typeClass(
     694             :         static_cast< enum RTTypeClass >(
     695         537 :             RTTypeClass | (published ? RT_TYPE_PUBLISHED : 0)))
     696             :      , m_typeName(typeName)
     697             :     , m_nSuperTypes(superTypeCount)
     698             :     , m_pUik(NULL)
     699             :     , m_doku(documentation)
     700             :     , m_fileName(fileName)
     701             :     , m_fieldCount(fieldCount)
     702             :     , m_fields(NULL)
     703             :     , m_methodCount(methodCount)
     704             :     , m_methods(NULL)
     705             :     , m_referenceCount(referenceCount)
     706             :     , m_references(NULL)
     707             :     , m_blop(NULL)
     708        1074 :     , m_blopSize(0)
     709             : {
     710         537 :     if (m_nSuperTypes > 0)
     711             :     {
     712         177 :         m_superTypeNames = new OString[m_nSuperTypes];
     713             :     } else
     714             :     {
     715         360 :         m_superTypeNames = NULL;
     716             :     }
     717             : 
     718         537 :     if (m_fieldCount)
     719         122 :         m_fields = new FieldEntry[fieldCount];
     720             : 
     721         537 :     if (m_methodCount)
     722          45 :         m_methods = new MethodEntry[methodCount];
     723             : 
     724         537 :     if (m_referenceCount)
     725          53 :         m_references = new ReferenceEntry[referenceCount];
     726         537 : }
     727             : 
     728        1074 : TypeWriter::~TypeWriter()
     729             : {
     730         537 :     if (m_superTypeNames)
     731         177 :         delete[] m_superTypeNames;
     732             : 
     733         537 :     if (m_blop)
     734         537 :         delete[] m_blop;
     735             : 
     736         537 :     if (m_fieldCount)
     737         122 :         delete[] m_fields;
     738             : 
     739         537 :     if (m_methodCount)
     740          45 :         delete[] m_methods;
     741             : 
     742         537 :     if (m_referenceCount)
     743          53 :         delete[] m_references;
     744             : 
     745         537 :     if (m_pUik)
     746           0 :         delete m_pUik;
     747         537 : }
     748             : 
     749         180 : void TypeWriter::setSuperType(sal_uInt16 index, OString const & name)
     750             : {
     751         180 :     m_superTypeNames[index] = name;
     752         180 : }
     753             : 
     754         537 : void TypeWriter::createBlop()
     755             : {
     756             :     //TODO: Fix memory leaks that occur when std::bad_alloc is thrown
     757             : 
     758         537 :     sal_uInt8*  pBlopFields         = NULL;
     759         537 :     sal_uInt8*  pBlopMethods        = NULL;
     760         537 :     sal_uInt8*  pBlopReferences     = NULL;
     761         537 :     sal_uInt8*  pBuffer             = NULL;
     762         537 :     sal_uInt32  blopFieldsSize      = 0;
     763         537 :     sal_uInt32  blopMethodsSize     = 0;
     764         537 :     sal_uInt32  blopReferenceSize   = 0;
     765             : 
     766         537 :     CPInfo  root(CP_TAG_INVALID, NULL);
     767         537 :     sal_uInt16  cpIndexThisName = 0;
     768         537 :     sal_uInt16* cpIndexSuperNames = NULL;
     769         537 :     sal_uInt16  cpIndexUik = 0;
     770         537 :     sal_uInt16  cpIndexDoku = 0;
     771         537 :     sal_uInt16  cpIndexFileName = 0;
     772         537 :     CPInfo* pInfo = NULL;
     773             : 
     774         537 :     sal_uInt16  entrySize = sizeof(sal_uInt16);
     775         537 :     sal_uInt32  blopHeaderEntrySize = BLOP_OFFSET_N_ENTRIES + entrySize + (BLOP_HEADER_N_ENTRIES * entrySize);
     776         537 :     sal_uInt32  blopFieldEntrySize = BLOP_FIELD_N_ENTRIES * entrySize;
     777         537 :     sal_uInt32  blopMethodEntrySize = BLOP_METHOD_N_ENTRIES * entrySize;
     778         537 :     sal_uInt32  blopParamEntrySize = BLOP_PARAM_N_ENTRIES * entrySize;
     779         537 :     sal_uInt32  blopReferenceEntrySize = BLOP_REFERENCE_N_ENTRIES * entrySize;
     780             : 
     781         537 :     sal_uInt32 blopSize = blopHeaderEntrySize;
     782             : 
     783             :     // create CP entry for this name
     784         537 :     pInfo = new CPInfo(CP_TAG_UTF8_NAME, &root);
     785         537 :     pInfo->m_value.aUtf8 = m_typeName.getStr();
     786         537 :     cpIndexThisName = pInfo->m_index;
     787             : 
     788             :     // nSuperTypes
     789         537 :     blopSize += entrySize;
     790             : 
     791             :     // create CP entry for super names
     792         537 :     if (m_nSuperTypes)
     793             :     {
     794         177 :         blopSize += m_nSuperTypes * entrySize;
     795             : 
     796         177 :         cpIndexSuperNames = new sal_uInt16[m_nSuperTypes];
     797             : 
     798         357 :         for (sal_uInt32 i=0; i < m_nSuperTypes; i++)
     799             :         {
     800         180 :             pInfo = new CPInfo(CP_TAG_UTF8_NAME, pInfo);
     801         180 :             pInfo->m_value.aUtf8 = m_superTypeNames[i].getStr();
     802         180 :             cpIndexSuperNames[i] = pInfo->m_index;
     803             :         }
     804             :     }
     805             : 
     806             :     // create CP entry for uik
     807         537 :     if (m_pUik != NULL)
     808             :     {
     809           0 :         pInfo = new CPInfo(CP_TAG_UIK, pInfo);
     810           0 :         pInfo->m_value.aUik = m_pUik;
     811           0 :         cpIndexUik = pInfo->m_index;
     812             :     }
     813             : 
     814             :     // create CP entry for doku
     815         537 :     if (!m_doku.isEmpty())
     816             :     {
     817           0 :         pInfo = new CPInfo(CP_TAG_UTF8_NAME, pInfo);
     818           0 :         pInfo->m_value.aUtf8 = m_doku.getStr();
     819           0 :         cpIndexDoku = pInfo->m_index;
     820             :     }
     821             : 
     822             :     // create CP entry for idl source filename
     823         537 :     if (!m_fileName.isEmpty())
     824             :     {
     825           0 :         pInfo = new CPInfo(CP_TAG_UTF8_NAME, pInfo);
     826           0 :         pInfo->m_value.aUtf8 = m_fileName.getStr();
     827           0 :         cpIndexFileName = pInfo->m_index;
     828             :     }
     829             : 
     830             :     // fields blop
     831         537 :     blopSize += sizeof(sal_uInt16); // fieldCount + nFieldEntries
     832             : 
     833         537 :     if (m_fieldCount)
     834             :     {
     835         122 :         sal_uInt16 cpIndexName = 0;
     836         122 :         sal_uInt16 cpIndexTypeName = 0;
     837         122 :         sal_uInt16 cpIndexValue = 0;
     838         122 :         sal_uInt16 cpIndexDoku2 = 0;
     839         122 :         sal_uInt16 cpIndexFileName2 = 0;
     840             : 
     841             :         // nFieldEntries + n fields
     842         122 :         blopFieldsSize = sizeof(sal_uInt16) + (m_fieldCount * blopFieldEntrySize);
     843             : 
     844         122 :         blopSize += blopFieldsSize;
     845             : 
     846         122 :         pBlopFields = new sal_uInt8[blopFieldsSize];
     847         122 :         pBuffer = pBlopFields;
     848             : 
     849         122 :         pBuffer += writeUINT16(pBuffer, BLOP_FIELD_N_ENTRIES);
     850             : 
     851         295 :         for (sal_uInt16 i = 0; i < m_fieldCount; i++)
     852             :         {
     853         173 :             cpIndexName = 0;
     854         173 :             cpIndexTypeName = 0;
     855         173 :             cpIndexValue = 0;
     856         173 :             cpIndexDoku2 = 0;
     857         173 :             cpIndexFileName2 = 0;
     858             : 
     859         173 :             pBuffer += writeUINT16(pBuffer, static_cast<sal_uInt16>(m_fields[i].m_access));
     860             : 
     861         173 :             if (!m_fields[i].m_name.isEmpty())
     862             :             {
     863         173 :                 pInfo = new CPInfo(CP_TAG_UTF8_NAME, pInfo);
     864         173 :                 pInfo->m_value.aUtf8 = m_fields[i].m_name.getStr();
     865         173 :                 cpIndexName = pInfo->m_index;
     866             :             }
     867         173 :             pBuffer += writeUINT16(pBuffer, cpIndexName);
     868             : 
     869         173 :             if (!m_fields[i].m_typeName.isEmpty())
     870             :             {
     871         145 :                 pInfo = new CPInfo(CP_TAG_UTF8_NAME, pInfo);
     872         145 :                 pInfo->m_value.aUtf8 = m_fields[i].m_typeName.getStr();
     873         145 :                 cpIndexTypeName = pInfo->m_index;
     874             :             }
     875         173 :             pBuffer += writeUINT16(pBuffer, cpIndexTypeName);
     876             : 
     877         173 :             if (m_fields[i].m_constValueType != RT_TYPE_NONE)
     878             :             {
     879          94 :                 pInfo = new CPInfo((CPInfoTag)m_fields[i].m_constValueType, pInfo);
     880          94 :                 pInfo->m_value.aConst = m_fields[i].m_constValue;
     881          94 :                 cpIndexValue = pInfo->m_index;
     882             :             }
     883         173 :             pBuffer += writeUINT16(pBuffer, cpIndexValue);
     884             : 
     885         173 :             if (!m_fields[i].m_doku.isEmpty())
     886             :             {
     887           0 :                 pInfo = new CPInfo(CP_TAG_UTF8_NAME, pInfo);
     888           0 :                 pInfo->m_value.aUtf8 = m_fields[i].m_doku.getStr();
     889           0 :                 cpIndexDoku2 = pInfo->m_index;
     890             :             }
     891         173 :             pBuffer += writeUINT16(pBuffer, cpIndexDoku2);
     892             : 
     893         173 :             if (!m_fields[i].m_fileName.isEmpty())
     894             :             {
     895           0 :                 pInfo = new CPInfo(CP_TAG_UTF8_NAME, pInfo);
     896           0 :                 pInfo->m_value.aUtf8 = m_fields[i].m_fileName.getStr();
     897           0 :                 cpIndexFileName2 = pInfo->m_index;
     898             :             }
     899         173 :             pBuffer += writeUINT16(pBuffer, cpIndexFileName2);
     900             :         }
     901             :     }
     902             : 
     903             :     // methods blop
     904         537 :     blopSize += sizeof(sal_uInt16); // methodCount
     905             : 
     906         537 :     if (m_methodCount)
     907             :     {
     908          45 :         sal_uInt16* pMethodEntrySize = new sal_uInt16[m_methodCount];
     909          45 :         sal_uInt16  cpIndexName = 0;
     910          45 :         sal_uInt16  cpIndexReturn = 0;
     911          45 :         sal_uInt16  cpIndexDoku2 = 0;
     912             : 
     913             :         // nMethodEntries + nParamEntries
     914          45 :         blopMethodsSize = (2 * sizeof(sal_uInt16));
     915             : 
     916          99 :         for (sal_uInt16 i = 0; i < m_methodCount; i++)
     917             :         {
     918          54 :             pMethodEntrySize[i] = (sal_uInt16)
     919             :                 ( blopMethodEntrySize +                                 // header
     920             :                   sizeof(sal_uInt16) +                                  // parameterCount
     921          54 :                   (m_methods[i].m_paramCount * blopParamEntrySize) +    // exceptions
     922             :                   sizeof(sal_uInt16) +                                  // exceptionCount
     923         108 :                   (m_methods[i].m_excCount * sizeof(sal_uInt16)) );     // exceptions
     924             : 
     925          54 :             blopMethodsSize += pMethodEntrySize[i];
     926             :         }
     927             : 
     928          45 :         pBlopMethods = new sal_uInt8[blopMethodsSize];
     929             : 
     930          45 :         blopSize += blopMethodsSize;
     931             : 
     932          45 :         pBuffer = pBlopMethods;
     933             : 
     934          45 :         pBuffer += writeUINT16(pBuffer, BLOP_METHOD_N_ENTRIES);
     935          45 :         pBuffer += writeUINT16(pBuffer, BLOP_PARAM_N_ENTRIES );
     936             : 
     937          99 :         for (sal_uInt16 i = 0; i < m_methodCount; i++)
     938             :         {
     939          54 :             cpIndexReturn = 0;
     940          54 :             cpIndexDoku2 = 0;
     941             : 
     942          54 :             pBuffer += writeUINT16(pBuffer, pMethodEntrySize[i]);
     943          54 :             pBuffer += writeUINT16(
     944             :                 pBuffer,
     945         108 :                 sal::static_int_cast< sal_uInt16 >(m_methods[i].m_mode));
     946             : 
     947          54 :             if (!m_methods[i].m_name.isEmpty())
     948             :             {
     949          50 :                 pInfo = new CPInfo(CP_TAG_UTF8_NAME, pInfo);
     950          50 :                 pInfo->m_value.aUtf8 = m_methods[i].m_name.getStr();
     951          50 :                 cpIndexName = pInfo->m_index;
     952             :             }
     953          54 :             pBuffer += writeUINT16(pBuffer, cpIndexName);
     954          54 :             cpIndexName = 0;
     955             : 
     956          54 :             if (!m_methods[i].m_returnTypeName.isEmpty())
     957             :             {
     958          54 :                 pInfo = new CPInfo(CP_TAG_UTF8_NAME, pInfo);
     959          54 :                 pInfo->m_value.aUtf8 = m_methods[i].m_returnTypeName.getStr();
     960          54 :                 cpIndexReturn = pInfo->m_index;
     961             :             }
     962          54 :             pBuffer += writeUINT16(pBuffer, cpIndexReturn);
     963             : 
     964          54 :             if (!m_methods[i].m_doku.isEmpty())
     965             :             {
     966           0 :                 pInfo = new CPInfo(CP_TAG_UTF8_NAME, pInfo);
     967           0 :                 pInfo->m_value.aUtf8 = m_methods[i].m_doku.getStr();
     968           0 :                 cpIndexDoku2 = pInfo->m_index;
     969             :             }
     970          54 :             pBuffer += writeUINT16(pBuffer, cpIndexDoku2);
     971             : 
     972             :             sal_uInt16 j;
     973             : 
     974          54 :             pBuffer += writeUINT16(pBuffer, m_methods[i].m_paramCount);
     975             : 
     976          75 :             for (j = 0; j < m_methods[i].m_paramCount; j++)
     977             :             {
     978          21 :                 if (!m_methods[i].m_params[j].m_typeName.isEmpty())
     979             :                 {
     980          21 :                     pInfo = new CPInfo(CP_TAG_UTF8_NAME, pInfo);
     981          21 :                     pInfo->m_value.aUtf8 = m_methods[i].m_params[j].m_typeName.getStr();
     982          21 :                     cpIndexName = pInfo->m_index;
     983             :                 }
     984          21 :                 pBuffer += writeUINT16(pBuffer, cpIndexName);
     985          21 :                 cpIndexName = 0;
     986             : 
     987          21 :                 pBuffer += writeUINT16(
     988             :                     pBuffer,
     989             :                     sal::static_int_cast< sal_uInt16 >(
     990          42 :                         m_methods[i].m_params[j].m_mode));
     991             : 
     992          21 :                 if (!m_methods[i].m_params[j].m_name.isEmpty())
     993             :                 {
     994          21 :                     pInfo = new CPInfo(CP_TAG_UTF8_NAME, pInfo);
     995          21 :                     pInfo->m_value.aUtf8 = m_methods[i].m_params[j].m_name.getStr();
     996          21 :                     cpIndexName = pInfo->m_index;
     997             :                 }
     998          21 :                 pBuffer += writeUINT16(pBuffer, cpIndexName);
     999          21 :                 cpIndexName = 0;
    1000             :             }
    1001             : 
    1002          54 :             pBuffer += writeUINT16(pBuffer, m_methods[i].m_excCount);
    1003             : 
    1004          74 :             for (j = 0; j < m_methods[i].m_excCount; j++)
    1005             :             {
    1006          20 :                 if (!m_methods[i].m_excNames[j].isEmpty())
    1007             :                 {
    1008          20 :                     pInfo = new CPInfo(CP_TAG_UTF8_NAME, pInfo);
    1009          20 :                     pInfo->m_value.aUtf8 = m_methods[i].m_excNames[j].getStr();
    1010          20 :                     cpIndexName = pInfo->m_index;
    1011             :                 }
    1012          20 :                 pBuffer += writeUINT16(pBuffer, cpIndexName);
    1013          20 :                 cpIndexName = 0;
    1014             :             }
    1015             :         }
    1016             : 
    1017          45 :         delete[] pMethodEntrySize;
    1018             :     }
    1019             : 
    1020             :     // reference blop
    1021         537 :     blopSize += entrySize; // referenceCount
    1022             : 
    1023         537 :     if (m_referenceCount)
    1024             :     {
    1025          53 :         sal_uInt16 cpIndexName = 0;
    1026          53 :         sal_uInt16 cpIndexDoku2 = 0;
    1027             : 
    1028             :         // nReferenceEntries + n references
    1029          53 :         blopReferenceSize = entrySize + (m_referenceCount * blopReferenceEntrySize);
    1030             : 
    1031          53 :         blopSize += blopReferenceSize;
    1032             : 
    1033          53 :         pBlopReferences = new sal_uInt8[blopReferenceSize];
    1034          53 :         pBuffer = pBlopReferences;
    1035             : 
    1036          53 :         pBuffer += writeUINT16(pBuffer, BLOP_REFERENCE_N_ENTRIES);
    1037             : 
    1038         112 :         for (sal_uInt16 i = 0; i < m_referenceCount; i++)
    1039             :         {
    1040          59 :             pBuffer += writeUINT16(
    1041             :                 pBuffer,
    1042         118 :                 sal::static_int_cast< sal_uInt16 >(m_references[i].m_type));
    1043             : 
    1044          59 :             cpIndexName = 0;
    1045          59 :             cpIndexDoku2 = 0;
    1046             : 
    1047          59 :             if (!m_references[i].m_name.isEmpty())
    1048             :             {
    1049          59 :                 pInfo = new CPInfo(CP_TAG_UTF8_NAME, pInfo);
    1050          59 :                 pInfo->m_value.aUtf8 = m_references[i].m_name.getStr();
    1051          59 :                 cpIndexName = pInfo->m_index;
    1052             :             }
    1053          59 :             pBuffer += writeUINT16(pBuffer, cpIndexName);
    1054             : 
    1055          59 :             if (!m_references[i].m_doku.isEmpty())
    1056             :             {
    1057           0 :                 pInfo = new CPInfo(CP_TAG_UTF8_NAME, pInfo);
    1058           0 :                 pInfo->m_value.aUtf8 = m_references[i].m_doku.getStr();
    1059           0 :                 cpIndexDoku2 = pInfo->m_index;
    1060             :             }
    1061          59 :             pBuffer += writeUINT16(pBuffer, cpIndexDoku2);
    1062             : 
    1063          59 :             pBuffer += writeUINT16(pBuffer, static_cast<sal_uInt16>(m_references[i].m_access));
    1064             :         }
    1065             :     }
    1066             : 
    1067             : 
    1068             :     // get CP infos blop-length
    1069         537 :     pInfo = root.m_next;
    1070         537 :     sal_uInt32 cpBlopSize = 0;
    1071         537 :     sal_uInt16 cpCount = 0;
    1072             : 
    1073        2428 :     while (pInfo)
    1074             :     {
    1075        1354 :         cpBlopSize += pInfo->getBlopSize();
    1076        1354 :         cpCount++;
    1077        1354 :         pInfo = pInfo->m_next;
    1078             :     }
    1079             : 
    1080         537 :     blopSize += cpBlopSize;
    1081         537 :     blopSize += sizeof(sal_uInt16);   // constantPoolCount
    1082             : 
    1083             :     // write all in flat buffer
    1084             : 
    1085         537 :     sal_uInt8 * blop = new sal_uInt8[blopSize];
    1086             : 
    1087         537 :     pBuffer = blop;
    1088             : 
    1089             :     // Assumes two's complement arithmetic with modulo-semantics:
    1090         537 :     pBuffer += writeUINT32(pBuffer, magic + m_version);
    1091         537 :     pBuffer += writeUINT32(pBuffer, blopSize);
    1092         537 :     pBuffer += writeUINT16(pBuffer, minorVersion);
    1093         537 :     pBuffer += writeUINT16(pBuffer, majorVersion);
    1094         537 :     pBuffer += writeUINT16(pBuffer, BLOP_HEADER_N_ENTRIES);
    1095             : 
    1096         537 :     pBuffer += writeUINT16(pBuffer, (sal_uInt16)RT_UNO_IDL);
    1097         537 :     pBuffer += writeUINT16(pBuffer, (sal_uInt16)m_typeClass);
    1098         537 :     pBuffer += writeUINT16(pBuffer, cpIndexThisName);
    1099         537 :     pBuffer += writeUINT16(pBuffer, cpIndexUik);
    1100         537 :     pBuffer += writeUINT16(pBuffer, cpIndexDoku);
    1101         537 :     pBuffer += writeUINT16(pBuffer, cpIndexFileName);
    1102             : 
    1103             :     // write supertypes
    1104         537 :     pBuffer += writeUINT16(pBuffer, m_nSuperTypes);
    1105         537 :     if (m_nSuperTypes)
    1106             :     {
    1107         357 :         for (sal_uInt32 i=0; i < m_nSuperTypes; i++)
    1108             :         {
    1109         180 :             pBuffer += writeUINT16(pBuffer, cpIndexSuperNames[i]);
    1110             :         }
    1111         177 :         delete[] cpIndexSuperNames;
    1112             :     }
    1113             : 
    1114         537 :     pBuffer += writeUINT16(pBuffer, cpCount);
    1115             : 
    1116             :     // write and delete CP infos
    1117         537 :     pInfo = root.m_next;
    1118             : 
    1119        2428 :     while (pInfo)
    1120             :     {
    1121        1354 :         CPInfo* pNextInfo = pInfo->m_next;
    1122             : 
    1123        1354 :         pBuffer += pInfo->toBlop(pBuffer);
    1124        1354 :         delete pInfo;
    1125             : 
    1126        1354 :         pInfo = pNextInfo;
    1127             :     }
    1128             : 
    1129             :     // write fields
    1130         537 :     pBuffer += writeUINT16(pBuffer, m_fieldCount);
    1131         537 :     if (blopFieldsSize)
    1132             :     {
    1133         122 :         memcpy(pBuffer, pBlopFields, blopFieldsSize);
    1134         122 :         pBuffer += blopFieldsSize;
    1135             :     }
    1136             : 
    1137             :     // write methods
    1138         537 :     pBuffer += writeUINT16(pBuffer, m_methodCount);
    1139         537 :     if (blopMethodsSize)
    1140             :     {
    1141          45 :         memcpy(pBuffer, pBlopMethods, blopMethodsSize);
    1142          45 :         pBuffer += blopMethodsSize;
    1143             :     }
    1144             : 
    1145             :     // write references
    1146         537 :     pBuffer += writeUINT16(pBuffer, m_referenceCount);
    1147         537 :     if (blopReferenceSize)
    1148             :     {
    1149          53 :         memcpy(pBuffer, pBlopReferences, blopReferenceSize);
    1150          53 :         pBuffer += blopReferenceSize;
    1151             :     }
    1152             : 
    1153         537 :     delete[] pBlopFields;
    1154         537 :     delete[] pBlopMethods;
    1155         537 :     delete[] pBlopReferences;
    1156             : 
    1157         537 :     delete[] m_blop;
    1158         537 :     m_blop = blop;
    1159         537 :     m_blopSize = blopSize;
    1160         537 : }
    1161             : 
    1162             : 
    1163             : /**************************************************************************
    1164             : 
    1165             :     C-API
    1166             : 
    1167             : **************************************************************************/
    1168             : 
    1169             : extern "C" {
    1170             : 
    1171           0 : static void TYPEREG_CALLTYPE acquire(TypeWriterImpl hEntry)
    1172             : {
    1173           0 :     TypeWriter* pEntry = static_cast<TypeWriter*>(hEntry);
    1174             : 
    1175           0 :     if (pEntry != NULL)
    1176           0 :         pEntry->m_refCount++;
    1177           0 : }
    1178             : 
    1179           0 : static void TYPEREG_CALLTYPE release(TypeWriterImpl hEntry)
    1180             : {
    1181           0 :     TypeWriter* pEntry = static_cast<TypeWriter*>(hEntry);
    1182             : 
    1183           0 :     if (pEntry != NULL)
    1184             :     {
    1185           0 :         if (--pEntry->m_refCount == 0)
    1186           0 :             delete pEntry;
    1187             :     }
    1188           0 : }
    1189             : 
    1190           0 : static void TYPEREG_CALLTYPE setUik(TypeWriterImpl  hEntry, const RTUik* uik)
    1191             : {
    1192           0 :     TypeWriter* pEntry = static_cast<TypeWriter*>(hEntry);
    1193             : 
    1194           0 :     if (pEntry != NULL)
    1195             :     {
    1196           0 :         if (pEntry->m_pUik)
    1197             :         {
    1198           0 :             pEntry->m_pUik->m_Data1 = uik->m_Data1;
    1199           0 :             pEntry->m_pUik->m_Data2 = uik->m_Data2;
    1200           0 :             pEntry->m_pUik->m_Data3 = uik->m_Data3;
    1201           0 :             pEntry->m_pUik->m_Data4 = uik->m_Data4;
    1202           0 :             pEntry->m_pUik->m_Data5 = uik->m_Data5;
    1203             :         }
    1204             :         else
    1205           0 :             pEntry->m_pUik = new RTUik(*uik);
    1206             :     }
    1207           0 : }
    1208             : 
    1209           0 : static void TYPEREG_CALLTYPE setDoku(TypeWriterImpl hEntry, rtl_uString* doku)
    1210             : {
    1211           0 :     static_cast< TypeWriter * >(hEntry)->m_doku = toByteString(doku);
    1212           0 : }
    1213             : 
    1214           0 : static void TYPEREG_CALLTYPE setFileName(TypeWriterImpl hEntry, rtl_uString* fileName)
    1215             : {
    1216           0 :     static_cast< TypeWriter * >(hEntry)->m_fileName = toByteString(fileName);
    1217           0 : }
    1218             : 
    1219         173 : sal_Bool TYPEREG_CALLTYPE typereg_writer_setFieldData(
    1220             :     void * handle, sal_uInt16 index, rtl_uString const * documentation,
    1221             :     rtl_uString const * fileName, RTFieldAccess flags, rtl_uString const * name,
    1222             :     rtl_uString const * typeName, RTValueType valueType,
    1223             :     RTConstValueUnion valueValue)
    1224             :     SAL_THROW_EXTERN_C()
    1225             : {
    1226             :     try {
    1227             :         static_cast< TypeWriter * >(handle)->m_fields[index].setData(
    1228             :             toByteString(name), toByteString(typeName),
    1229             :             toByteString(documentation), toByteString(fileName), flags,
    1230         173 :             valueType, valueValue);
    1231           0 :     } catch (std::bad_alloc &) {
    1232           0 :         return false;
    1233             :     }
    1234         173 :     return true;
    1235             : }
    1236             : 
    1237           0 : static void TYPEREG_CALLTYPE setFieldData(TypeWriterImpl    hEntry,
    1238             :                                           sal_uInt16        index,
    1239             :                                           rtl_uString*      name,
    1240             :                                           rtl_uString*      typeName,
    1241             :                                           rtl_uString*      doku,
    1242             :                                           rtl_uString*      fileName,
    1243             :                                           RTFieldAccess     access,
    1244             :                                           RTValueType       valueType,
    1245             :                                           RTConstValueUnion constValue)
    1246             : {
    1247             :     typereg_writer_setFieldData(
    1248             :         hEntry, index, doku, fileName, access, name, typeName, valueType,
    1249           0 :         constValue);
    1250           0 : }
    1251             : 
    1252          54 : sal_Bool TYPEREG_CALLTYPE typereg_writer_setMethodData(
    1253             :     void * handle, sal_uInt16 index, rtl_uString const * documentation,
    1254             :     RTMethodMode flags, rtl_uString const * name,
    1255             :     rtl_uString const * returnTypeName, sal_uInt16 parameterCount,
    1256             :     sal_uInt16 exceptionCount)
    1257             :     SAL_THROW_EXTERN_C()
    1258             : {
    1259             :     try {
    1260             :         static_cast< TypeWriter * >(handle)->m_methods[index].setData(
    1261             :             toByteString(name), toByteString(returnTypeName), flags,
    1262          54 :             parameterCount, exceptionCount, toByteString(documentation));
    1263           0 :     } catch (std::bad_alloc &) {
    1264           0 :         return false;
    1265             :     }
    1266          54 :     return true;
    1267             : }
    1268             : 
    1269           0 : static void TYPEREG_CALLTYPE setMethodData(TypeWriterImpl   hEntry,
    1270             :                                            sal_uInt16       index,
    1271             :                                            rtl_uString*     name,
    1272             :                                            rtl_uString*     returnTypeName,
    1273             :                                            RTMethodMode     mode,
    1274             :                                            sal_uInt16       paramCount,
    1275             :                                            sal_uInt16       excCount,
    1276             :                                            rtl_uString*     doku)
    1277             : {
    1278             :     typereg_writer_setMethodData(
    1279           0 :         hEntry, index, doku, mode, name, returnTypeName, paramCount, excCount);
    1280           0 : }
    1281             : 
    1282          21 : sal_Bool TYPEREG_CALLTYPE typereg_writer_setMethodParameterData(
    1283             :     void * handle, sal_uInt16 methodIndex, sal_uInt16 parameterIndex,
    1284             :     RTParamMode flags, rtl_uString const * name, rtl_uString const * typeName)
    1285             :     SAL_THROW_EXTERN_C()
    1286             : {
    1287             :     try {
    1288             :         static_cast< TypeWriter * >(handle)->
    1289          21 :             m_methods[methodIndex].m_params[parameterIndex].setData(
    1290          42 :                 toByteString(typeName), toByteString(name), flags);
    1291           0 :     } catch (std::bad_alloc &) {
    1292           0 :         return false;
    1293             :     }
    1294          21 :     return true;
    1295             : }
    1296             : 
    1297           0 : static void TYPEREG_CALLTYPE setParamData(TypeWriterImpl    hEntry,
    1298             :                                           sal_uInt16        index,
    1299             :                                           sal_uInt16        paramIndex,
    1300             :                                           rtl_uString*      type,
    1301             :                                           rtl_uString*      name,
    1302             :                                           RTParamMode       mode)
    1303             : {
    1304             :     typereg_writer_setMethodParameterData(
    1305           0 :         hEntry, index, paramIndex, mode, name, type);
    1306           0 : }
    1307             : 
    1308          20 : sal_Bool TYPEREG_CALLTYPE typereg_writer_setMethodExceptionTypeName(
    1309             :     void * handle, sal_uInt16 methodIndex, sal_uInt16 exceptionIndex,
    1310             :     rtl_uString const * typeName)
    1311             :     SAL_THROW_EXTERN_C()
    1312             : {
    1313             :     try {
    1314             :         static_cast< TypeWriter * >(handle)->m_methods[methodIndex].setExcName(
    1315          20 :             exceptionIndex, toByteString(typeName));
    1316           0 :     } catch (std::bad_alloc &) {
    1317           0 :         return false;
    1318             :     }
    1319          20 :     return true;
    1320             : }
    1321             : 
    1322           0 : static void TYPEREG_CALLTYPE setExcData(TypeWriterImpl  hEntry,
    1323             :                                         sal_uInt16      index,
    1324             :                                         sal_uInt16      excIndex,
    1325             :                                         rtl_uString*    type)
    1326             : {
    1327           0 :     typereg_writer_setMethodExceptionTypeName(hEntry, index, excIndex, type);
    1328           0 : }
    1329             : 
    1330         537 : void const * TYPEREG_CALLTYPE typereg_writer_getBlob(void * handle, sal_uInt32 * size)
    1331             :     SAL_THROW_EXTERN_C()
    1332             : {
    1333         537 :     TypeWriter * writer = static_cast< TypeWriter * >(handle);
    1334         537 :     if (writer->m_blop == 0) {
    1335             :         try {
    1336         537 :             writer->createBlop();
    1337           0 :         } catch (std::bad_alloc &) {
    1338           0 :             return 0;
    1339             :         }
    1340             :     }
    1341         537 :     *size = writer->m_blopSize;
    1342         537 :     return writer->m_blop;
    1343             : }
    1344             : 
    1345           0 : static const sal_uInt8* TYPEREG_CALLTYPE getBlop(TypeWriterImpl hEntry)
    1346             : {
    1347             :     sal_uInt32 size;
    1348             :     return static_cast< sal_uInt8 const * >(
    1349           0 :         typereg_writer_getBlob(hEntry, &size));
    1350             : }
    1351             : 
    1352           0 : static sal_uInt32 TYPEREG_CALLTYPE getBlopSize(TypeWriterImpl hEntry)
    1353             : {
    1354             :     sal_uInt32 size;
    1355           0 :     typereg_writer_getBlob(hEntry, &size);
    1356           0 :     return size;
    1357             : }
    1358             : 
    1359          59 : sal_Bool TYPEREG_CALLTYPE typereg_writer_setReferenceData(
    1360             :     void * handle, sal_uInt16 index, rtl_uString const * documentation,
    1361             :     RTReferenceType sort, RTFieldAccess flags, rtl_uString const * typeName)
    1362             :     SAL_THROW_EXTERN_C()
    1363             : {
    1364             :     try {
    1365             :         static_cast< TypeWriter * >(handle)->m_references[index].setData(
    1366          59 :             toByteString(typeName), sort, toByteString(documentation), flags);
    1367           0 :     } catch (std::bad_alloc &) {
    1368           0 :         return false;
    1369             :     }
    1370          59 :     return true;
    1371             : }
    1372             : 
    1373           0 : static void TYPEREG_CALLTYPE setReferenceData(TypeWriterImpl    hEntry,
    1374             :                                               sal_uInt16        index,
    1375             :                                               rtl_uString*      name,
    1376             :                                               RTReferenceType   refType,
    1377             :                                               rtl_uString*      doku,
    1378             :                                               RTFieldAccess     access)
    1379             : {
    1380           0 :     typereg_writer_setReferenceData(hEntry, index, doku, refType, access, name);
    1381           0 : }
    1382             : 
    1383         537 : void * TYPEREG_CALLTYPE typereg_writer_create(
    1384             :     typereg_Version version, rtl_uString const * documentation,
    1385             :     rtl_uString const * fileName, RTTypeClass typeClass, sal_Bool published,
    1386             :     rtl_uString const * typeName, sal_uInt16 superTypeCount,
    1387             :     sal_uInt16 fieldCount, sal_uInt16 methodCount, sal_uInt16 referenceCount)
    1388             :     SAL_THROW_EXTERN_C()
    1389             : {
    1390             :     try {
    1391             :         return new TypeWriter(
    1392             :             version, toByteString(documentation), toByteString(fileName),
    1393             :             typeClass, published, toByteString(typeName), superTypeCount,
    1394         537 :             fieldCount, methodCount, referenceCount);
    1395           0 :     } catch (std::bad_alloc &) {
    1396           0 :         return 0;
    1397             :     }
    1398             : }
    1399             : 
    1400         537 : void TYPEREG_CALLTYPE typereg_writer_destroy(void * handle) SAL_THROW_EXTERN_C() {
    1401         537 :     delete static_cast< TypeWriter * >(handle);
    1402         537 : }
    1403             : 
    1404         180 : sal_Bool TYPEREG_CALLTYPE typereg_writer_setSuperTypeName(
    1405             :     void * handle, sal_uInt16 index, rtl_uString const * typeName)
    1406             :     SAL_THROW_EXTERN_C()
    1407             : {
    1408             :     try {
    1409             :         static_cast< TypeWriter * >(handle)->setSuperType(
    1410         180 :             index, toByteString(typeName));
    1411           0 :     } catch (std::bad_alloc &) {
    1412           0 :         return false;
    1413             :     }
    1414         180 :     return true;
    1415             : }
    1416             : 
    1417           0 : static TypeWriterImpl TYPEREG_CALLTYPE createEntry(
    1418             :     RTTypeClass typeClass, rtl_uString * typeName, rtl_uString * superTypeName,
    1419             :     sal_uInt16 fieldCount, sal_uInt16 methodCount, sal_uInt16 referenceCount)
    1420             : {
    1421           0 :     OUString empty;
    1422           0 :     sal_uInt16 superTypeCount = rtl_uString_getLength(superTypeName) == 0
    1423           0 :         ? 0 : 1;
    1424             :     TypeWriterImpl t = typereg_writer_create(
    1425             :         TYPEREG_VERSION_0, empty.pData, empty.pData, typeClass, false, typeName,
    1426           0 :         superTypeCount, fieldCount, methodCount, referenceCount);
    1427           0 :     if (superTypeCount > 0) {
    1428           0 :         typereg_writer_setSuperTypeName(t, 0, superTypeName);
    1429             :     }
    1430           0 :     return t;
    1431             : }
    1432             : 
    1433           0 : RegistryTypeWriter_Api* TYPEREG_CALLTYPE initRegistryTypeWriter_Api()
    1434             : {
    1435             :     static RegistryTypeWriter_Api aApi= {0,0,0,0,0,0,0,0,0,0,0,0,0};
    1436           0 :     if (!aApi.acquire)
    1437             :     {
    1438           0 :         aApi.createEntry        = &createEntry;
    1439           0 :         aApi.acquire            = &acquire;
    1440           0 :         aApi.release            = &release;
    1441           0 :         aApi.setUik             = &setUik;
    1442           0 :         aApi.setDoku            = &setDoku;
    1443           0 :         aApi.setFileName        = &setFileName;
    1444           0 :         aApi.setFieldData       = &setFieldData;
    1445           0 :         aApi.setMethodData      = &setMethodData;
    1446           0 :         aApi.setParamData       = &setParamData;
    1447           0 :         aApi.setExcData         = &setExcData;
    1448           0 :         aApi.getBlop            = &getBlop;
    1449           0 :         aApi.getBlopSize        = &getBlopSize;
    1450           0 :         aApi.setReferenceData   = &setReferenceData;
    1451             : 
    1452           0 :         return (&aApi);
    1453             :     }
    1454             :     else
    1455             :     {
    1456           0 :         return (&aApi);
    1457             :     }
    1458             : }
    1459             : 
    1460             : }
    1461             : 
    1462             : /* vim:set shiftwidth=4 softtabstop=4 expandtab: */

Generated by: LCOV version 1.11