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

Generated by: LCOV version 1.10