LCOV - code coverage report
Current view: top level - libreoffice/cppu/source/typelib - typelib.cxx (source / functions) Hit Total Coverage
Test: libreoffice_filtered.info Lines: 896 1097 81.7 %
Date: 2012-12-27 Functions: 49 55 89.1 %
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             : #if OSL_DEBUG_LEVEL > 1
      22             : #include <stdio.h>
      23             : #endif
      24             : 
      25             : #include <boost/unordered_map.hpp>
      26             : #include <list>
      27             : #include <set>
      28             : #include <vector>
      29             : 
      30             : #include <stdarg.h>
      31             : #include <stdlib.h>
      32             : #include <string.h>
      33             : #include <sal/alloca.h>
      34             : #include <new>
      35             : #include <osl/interlck.h>
      36             : #include <osl/mutex.hxx>
      37             : #include <rtl/ustring.hxx>
      38             : #include <rtl/ustrbuf.hxx>
      39             : #include <rtl/alloc.h>
      40             : #include <rtl/instance.hxx>
      41             : #include <osl/diagnose.h>
      42             : #include <typelib/typedescription.h>
      43             : #include <uno/any2.h>
      44             : 
      45             : using namespace std;
      46             : using namespace osl;
      47             : 
      48             : using ::rtl::OUString;
      49             : using ::rtl::OUStringBuffer;
      50             : using ::rtl::OString;
      51             : 
      52             : #ifdef SAL_W32
      53             : #pragma pack(push, 8)
      54             : #endif
      55             : 
      56             : /**
      57             :  * The double member determin the alignment.
      58             :  * Under Os2 and MS-Windows the Alignment is min( 8, sizeof( type ) ).
      59             :  * The aligment of a strukture is min( 8, sizeof( max basic type ) ), the greatest basic type
      60             :  * determine the aligment.
      61             :  */
      62             : struct AlignSize_Impl
      63             : {
      64             :     sal_Int16 nInt16;
      65             : #ifdef AIX
      66             :     //double: doubleword aligned if -qalign=natural/-malign=natural
      67             :     //which isn't the default ABI. Otherwise word aligned, While a long long int
      68             :     //is always doubleword aligned, so use that instead.
      69             :     sal_Int64 dDouble;
      70             : #else
      71             :     double dDouble;
      72             : #endif
      73             : };
      74             : 
      75             : #ifdef SAL_W32
      76             : #pragma pack(pop)
      77             : #endif
      78             : 
      79             : // the value of the maximal alignment
      80             : static sal_Int32 nMaxAlignment = (sal_Int32)( (sal_Size)(&((AlignSize_Impl *) 16)->dDouble) - 16);
      81             : 
      82       96473 : static inline sal_Int32 adjustAlignment( sal_Int32 nRequestedAlignment )
      83             :     SAL_THROW(())
      84             : {
      85       96473 :     if( nRequestedAlignment > nMaxAlignment )
      86        1584 :         nRequestedAlignment = nMaxAlignment;
      87       96473 :     return nRequestedAlignment;
      88             : }
      89             : 
      90             : /**
      91             :  * Calculate the new size of the struktur.
      92             :  */
      93       58251 : static inline sal_Int32 newAlignedSize(
      94             :     sal_Int32 OldSize, sal_Int32 ElementSize, sal_Int32 NeededAlignment )
      95             :     SAL_THROW(())
      96             : {
      97       58251 :     NeededAlignment = adjustAlignment( NeededAlignment );
      98       58251 :     return (OldSize + NeededAlignment -1) / NeededAlignment * NeededAlignment + ElementSize;
      99             : }
     100             : 
     101    13565491 : static inline sal_Bool reallyWeak( typelib_TypeClass eTypeClass )
     102             :     SAL_THROW(())
     103             : {
     104    13565491 :     return TYPELIB_TYPEDESCRIPTIONREFERENCE_ISREALLYWEAK( eTypeClass );
     105             : }
     106             : 
     107        6923 : static inline sal_Int32 getDescriptionSize( typelib_TypeClass eTypeClass )
     108             :     SAL_THROW(())
     109             : {
     110             :     OSL_ASSERT( typelib_TypeClass_TYPEDEF != eTypeClass );
     111             : 
     112             :     sal_Int32 nSize;
     113             :     // The reference is the description
     114             :     // if the description is empty, than it must be filled with
     115             :     // the new description
     116        6923 :     switch( eTypeClass )
     117             :     {
     118             :         case typelib_TypeClass_ARRAY:
     119           0 :             nSize = (sal_Int32)sizeof( typelib_ArrayTypeDescription );
     120           0 :         break;
     121             : 
     122             :         case typelib_TypeClass_SEQUENCE:
     123          11 :             nSize = (sal_Int32)sizeof( typelib_IndirectTypeDescription );
     124          11 :         break;
     125             : 
     126             :         case typelib_TypeClass_UNION:
     127           0 :             nSize = (sal_Int32)sizeof( typelib_UnionTypeDescription );
     128           0 :         break;
     129             : 
     130             :         case typelib_TypeClass_STRUCT:
     131         532 :             nSize = (sal_Int32)sizeof( typelib_StructTypeDescription );
     132         532 :         break;
     133             : 
     134             :         case typelib_TypeClass_EXCEPTION:
     135        1589 :             nSize = (sal_Int32)sizeof( typelib_CompoundTypeDescription );
     136        1589 :         break;
     137             : 
     138             :         case typelib_TypeClass_ENUM:
     139         140 :             nSize = (sal_Int32)sizeof( typelib_EnumTypeDescription );
     140         140 :         break;
     141             : 
     142             :         case typelib_TypeClass_INTERFACE:
     143        3846 :             nSize = (sal_Int32)sizeof( typelib_InterfaceTypeDescription );
     144        3846 :         break;
     145             : 
     146             :         case typelib_TypeClass_INTERFACE_METHOD:
     147           0 :             nSize = (sal_Int32)sizeof( typelib_InterfaceMethodTypeDescription );
     148           0 :         break;
     149             : 
     150             :         case typelib_TypeClass_INTERFACE_ATTRIBUTE:
     151           0 :             nSize = (sal_Int32)sizeof( typelib_InterfaceAttributeTypeDescription );
     152           0 :         break;
     153             : 
     154             :         default:
     155         805 :             nSize = (sal_Int32)sizeof( typelib_TypeDescription );
     156             :     }
     157        6923 :     return nSize;
     158             : }
     159             : 
     160             : 
     161             : //-----------------------------------------------------------------------------
     162             : extern "C" void SAL_CALL typelib_typedescriptionreference_getByName(
     163             :     typelib_TypeDescriptionReference ** ppRet, rtl_uString * pName )
     164             :     SAL_THROW_EXTERN_C();
     165             : 
     166             : //-----------------------------------------------------------------------------
     167             : struct equalStr_Impl
     168             : {
     169      572523 :     sal_Bool operator()(const sal_Unicode * const & s1, const sal_Unicode * const & s2) const SAL_THROW(())
     170      572523 :         { return 0 == rtl_ustr_compare( s1, s2 ); }
     171             : };
     172             : 
     173             : //-----------------------------------------------------------------------------
     174             : struct hashStr_Impl
     175             : {
     176      797988 :     size_t operator()(const sal_Unicode * const & s) const SAL_THROW(())
     177      797988 :         { return rtl_ustr_hashCode( s ); }
     178             : };
     179             : 
     180             : 
     181             : //-----------------------------------------------------------------------------
     182             : // Heavy hack, the const sal_Unicode * is hold by the typedescription reference
     183             : typedef boost::unordered_map< const sal_Unicode *, typelib_TypeDescriptionReference *,
     184             :                   hashStr_Impl, equalStr_Impl > WeakMap_Impl;
     185             : 
     186             : typedef pair< void *, typelib_typedescription_Callback > CallbackEntry;
     187             : typedef list< CallbackEntry > CallbackSet_Impl;
     188             : typedef list< typelib_TypeDescription * > TypeDescriptionList_Impl;
     189             : 
     190             : // # of cached elements
     191             : static sal_Int32 nCacheSize = 256;
     192             : 
     193             : struct TypeDescriptor_Init_Impl
     194             : {
     195             :     //sal_Bool          bDesctructorCalled;
     196             :     // all type description references
     197             :     WeakMap_Impl *              pWeakMap;
     198             :     // all type description callbacks
     199             :     CallbackSet_Impl *          pCallbacks;
     200             :     // A cache to hold descriptions
     201             :     TypeDescriptionList_Impl *  pCache;
     202             :     // The mutex to guard all type library accesses
     203             :     Mutex *                     pMutex;
     204             : 
     205             :     inline Mutex & getMutex() SAL_THROW(());
     206             : 
     207             :     inline void callChain( typelib_TypeDescription ** ppRet, rtl_uString * pName ) SAL_THROW(());
     208             : 
     209             : #if OSL_DEBUG_LEVEL > 1
     210             :     // only for debugging
     211             :     sal_Int32           nTypeDescriptionCount;
     212             :     sal_Int32           nCompoundTypeDescriptionCount;
     213             :     sal_Int32           nUnionTypeDescriptionCount;
     214             :     sal_Int32           nIndirectTypeDescriptionCount;
     215             :     sal_Int32           nArrayTypeDescriptionCount;
     216             :     sal_Int32           nEnumTypeDescriptionCount;
     217             :     sal_Int32           nInterfaceMethodTypeDescriptionCount;
     218             :     sal_Int32           nInterfaceAttributeTypeDescriptionCount;
     219             :     sal_Int32           nInterfaceTypeDescriptionCount;
     220             :     sal_Int32           nTypeDescriptionReferenceCount;
     221             : #endif
     222             : 
     223         266 :     TypeDescriptor_Init_Impl():
     224         266 :         pWeakMap(0), pCallbacks(0), pCache(0), pMutex(0)
     225             : #if OSL_DEBUG_LEVEL > 1
     226             :         , nTypeDescriptionCount(0), nCompoundTypeDescriptionCount(0),
     227             :         nUnionTypeDescriptionCount(0), nIndirectTypeDescriptionCount(0),
     228             :         nArrayTypeDescriptionCount(0), nEnumTypeDescriptionCount(0),
     229             :         nInterfaceMethodTypeDescriptionCount(0),
     230             :         nInterfaceAttributeTypeDescriptionCount(0),
     231             :         nInterfaceTypeDescriptionCount(0), nTypeDescriptionReferenceCount(0)
     232             : #endif
     233         266 :     {}
     234             : 
     235             :     ~TypeDescriptor_Init_Impl() SAL_THROW(());
     236             : };
     237             : //__________________________________________________________________________________________________
     238     1355064 : inline Mutex & TypeDescriptor_Init_Impl::getMutex() SAL_THROW(())
     239             : {
     240     1355064 :     if( !pMutex )
     241             :     {
     242         266 :         MutexGuard aGuard( Mutex::getGlobalMutex() );
     243         266 :         if( !pMutex )
     244         266 :             pMutex = new Mutex();
     245             :     }
     246     1355064 :     return * pMutex;
     247             : }
     248             : //__________________________________________________________________________________________________
     249        4845 : inline void TypeDescriptor_Init_Impl::callChain(
     250             :     typelib_TypeDescription ** ppRet, rtl_uString * pName )
     251             :     SAL_THROW(())
     252             : {
     253        4845 :     if (pCallbacks)
     254             :     {
     255        4845 :         CallbackSet_Impl::const_iterator aIt = pCallbacks->begin();
     256        9690 :         while( aIt != pCallbacks->end() )
     257             :         {
     258        4845 :             const CallbackEntry & rEntry = *aIt;
     259        4845 :             (*rEntry.second)( rEntry.first, ppRet, pName );
     260        4845 :             if( *ppRet )
     261        4845 :                 return;
     262           0 :             ++aIt;
     263             :         }
     264             :     }
     265           0 :     if (*ppRet)
     266             :     {
     267           0 :         typelib_typedescription_release( *ppRet );
     268           0 :         *ppRet = 0;
     269             :     }
     270             : }
     271             : 
     272             : //__________________________________________________________________________________________________
     273         266 : TypeDescriptor_Init_Impl::~TypeDescriptor_Init_Impl() SAL_THROW(())
     274             : {
     275         266 :     if( pCache )
     276             :     {
     277          34 :         TypeDescriptionList_Impl::const_iterator aIt = pCache->begin();
     278        3610 :         while( aIt != pCache->end() )
     279             :         {
     280        3542 :             typelib_typedescription_release( (*aIt) );
     281        3542 :             ++aIt;
     282             :         }
     283          34 :         delete pCache;
     284          34 :         pCache = 0;
     285             :     }
     286             : 
     287         266 :     if( pWeakMap )
     288             :     {
     289         266 :         std::vector< typelib_TypeDescriptionReference * > ppTDR;
     290             :         // save al weak references
     291         266 :         WeakMap_Impl::const_iterator aIt = pWeakMap->begin();
     292      109799 :         while( aIt != pWeakMap->end() )
     293             :         {
     294      109267 :             ppTDR.push_back( (*aIt).second );
     295      109267 :             typelib_typedescriptionreference_acquire( ppTDR.back() );
     296      109267 :             ++aIt;
     297             :         }
     298             : 
     299      328599 :         for( std::vector< typelib_TypeDescriptionReference * >::iterator i(
     300         266 :                  ppTDR.begin() );
     301      219066 :              i != ppTDR.end(); ++i )
     302             :         {
     303      109267 :             typelib_TypeDescriptionReference * pTDR = *i;
     304             :             OSL_ASSERT( pTDR->nRefCount > pTDR->nStaticRefCount );
     305      109267 :             pTDR->nRefCount -= pTDR->nStaticRefCount;
     306             : 
     307      109267 :             if( pTDR->pType && !pTDR->pType->bOnDemand )
     308             :             {
     309       48272 :                 pTDR->pType->bOnDemand = sal_True;
     310       48272 :                 typelib_typedescription_release( pTDR->pType );
     311             :             }
     312      109267 :             typelib_typedescriptionreference_release( pTDR );
     313             :         }
     314             : 
     315             : #if OSL_DEBUG_LEVEL > 1
     316             :         aIt = pWeakMap->begin();
     317             :         while( aIt != pWeakMap->end() )
     318             :         {
     319             :             typelib_TypeDescriptionReference * pTDR = (*aIt).second;
     320             :             if (pTDR)
     321             :             {
     322             :                 OString aTypeName( rtl::OUStringToOString( pTDR->pTypeName, RTL_TEXTENCODING_ASCII_US ) );
     323             :                 OSL_TRACE(
     324             :                     "### remaining type: %s; ref count = %d", aTypeName.getStr(), pTDR->nRefCount );
     325             :             }
     326             :             else
     327             :             {
     328             :                 OSL_TRACE( "### remaining null type entry!?" );
     329             :             }
     330             :             ++aIt;
     331             :         }
     332             : #endif
     333             : 
     334         266 :         delete pWeakMap;
     335         266 :         pWeakMap = 0;
     336             :     }
     337             : #if OSL_DEBUG_LEVEL > 1
     338             :     OSL_ENSURE( !nTypeDescriptionCount, "### nTypeDescriptionCount is not zero" );
     339             :     OSL_ENSURE( !nCompoundTypeDescriptionCount, "### nCompoundTypeDescriptionCount is not zero" );
     340             :     OSL_ENSURE( !nUnionTypeDescriptionCount, "### nUnionTypeDescriptionCount is not zero" );
     341             :     OSL_ENSURE( !nIndirectTypeDescriptionCount, "### nIndirectTypeDescriptionCount is not zero" );
     342             :     OSL_ENSURE( !nArrayTypeDescriptionCount, "### nArrayTypeDescriptionCount is not zero" );
     343             :     OSL_ENSURE( !nEnumTypeDescriptionCount, "### nEnumTypeDescriptionCount is not zero" );
     344             :     OSL_ENSURE( !nInterfaceMethodTypeDescriptionCount, "### nInterfaceMethodTypeDescriptionCount is not zero" );
     345             :     OSL_ENSURE( !nInterfaceAttributeTypeDescriptionCount, "### nInterfaceAttributeTypeDescriptionCount is not zero" );
     346             :     OSL_ENSURE( !nInterfaceTypeDescriptionCount, "### nInterfaceTypeDescriptionCount is not zero" );
     347             :     OSL_ENSURE( !nTypeDescriptionReferenceCount, "### nTypeDescriptionReferenceCount is not zero" );
     348             : 
     349             :     OSL_ENSURE( !pCallbacks || pCallbacks->empty(), "### pCallbacks is not NULL or empty" );
     350             : #endif
     351             : 
     352         266 :     delete pCallbacks;
     353         266 :     pCallbacks = 0;
     354             : 
     355         266 :     if( pMutex )
     356             :     {
     357         266 :         delete pMutex;
     358         266 :         pMutex = 0;
     359             :     }
     360         266 : };
     361             : 
     362             : namespace { struct Init : public rtl::Static< TypeDescriptor_Init_Impl, Init > {}; }
     363             : 
     364         259 : extern "C" CPPU_DLLPUBLIC void SAL_CALL typelib_typedescription_registerCallback(
     365             :     void * pContext, typelib_typedescription_Callback pCallback )
     366             :     SAL_THROW_EXTERN_C()
     367             : {
     368             :     // todo mt safe: guard is no solution, can not acquire while calling callback!
     369         259 :     TypeDescriptor_Init_Impl &rInit = Init::get();
     370             : //      OslGuard aGuard( rInit.getMutex() );
     371         259 :     if( !rInit.pCallbacks )
     372         257 :         rInit.pCallbacks = new CallbackSet_Impl;
     373         259 :     rInit.pCallbacks->push_back( CallbackEntry( pContext, pCallback ) );
     374         259 : }
     375             : 
     376             : //------------------------------------------------------------------------
     377          39 : extern "C" CPPU_DLLPUBLIC void SAL_CALL typelib_typedescription_revokeCallback(
     378             :     void * pContext, typelib_typedescription_Callback pCallback )
     379             :     SAL_THROW_EXTERN_C()
     380             : {
     381          39 :     TypeDescriptor_Init_Impl &rInit = Init::get();
     382          39 :     if( rInit.pCallbacks )
     383             :     {
     384             :         // todo mt safe: guard is no solution, can not acquire while calling callback!
     385             : //          OslGuard aGuard( rInit.getMutex() );
     386          39 :         CallbackEntry aEntry( pContext, pCallback );
     387          39 :         CallbackSet_Impl::iterator iPos( rInit.pCallbacks->begin() );
     388         120 :         while (!(iPos == rInit.pCallbacks->end()))
     389             :         {
     390          42 :             if (*iPos == aEntry)
     391             :             {
     392          39 :                 rInit.pCallbacks->erase( iPos );
     393          39 :                 iPos = rInit.pCallbacks->begin();
     394             :             }
     395             :             else
     396             :             {
     397           3 :                 ++iPos;
     398             :             }
     399             :         }
     400             :     }
     401          39 : }
     402             : 
     403             : extern "C" sal_Int32 SAL_CALL typelib_typedescription_getAlignedUnoSize(
     404             :     const typelib_TypeDescription * pTypeDescription,
     405             :     sal_Int32 nOffset, sal_Int32 & rMaxIntegralTypeSize )
     406             :     SAL_THROW_EXTERN_C();
     407             : 
     408             : //------------------------------------------------------------------------
     409        1086 : static inline void typelib_typedescription_initTables(
     410             :     typelib_TypeDescription * pTD )
     411             :     SAL_THROW(())
     412             : {
     413        1086 :     typelib_InterfaceTypeDescription * pITD = (typelib_InterfaceTypeDescription *)pTD;
     414             : 
     415        1086 :     sal_Bool * pReadWriteAttributes = (sal_Bool *)alloca( pITD->nAllMembers );
     416       10674 :     for ( sal_Int32 i = pITD->nAllMembers; i--; )
     417             :     {
     418        8502 :         pReadWriteAttributes[i] = sal_False;
     419        8502 :         if( typelib_TypeClass_INTERFACE_ATTRIBUTE == pITD->ppAllMembers[i]->eTypeClass )
     420             :         {
     421         478 :             typelib_TypeDescription * pM = 0;
     422         478 :             TYPELIB_DANGER_GET( &pM, pITD->ppAllMembers[i] );
     423             :             OSL_ASSERT( pM );
     424         478 :             if (pM)
     425             :             {
     426         478 :                 pReadWriteAttributes[i] = !((typelib_InterfaceAttributeTypeDescription *)pM)->bReadOnly;
     427         478 :                 TYPELIB_DANGER_RELEASE( pM );
     428             :             }
     429             : #if OSL_DEBUG_LEVEL > 1
     430             :             else
     431             :             {
     432             :                 OString aStr( rtl::OUStringToOString( pITD->ppAllMembers[i]->pTypeName, RTL_TEXTENCODING_ASCII_US ) );
     433             :                 OSL_TRACE( "\n### cannot get attribute type description: %s", aStr.getStr() );
     434             :             }
     435             : #endif
     436             :         }
     437             :     }
     438             : 
     439        1086 :     MutexGuard aGuard( Init::get().getMutex() );
     440        1086 :     if( !pTD->bComplete )
     441             :     {
     442             :         // create the index table from member to function table
     443        1086 :         pITD->pMapMemberIndexToFunctionIndex = new sal_Int32[ pITD->nAllMembers ];
     444        1086 :         sal_Int32 nAdditionalOffset = 0; // +1 for read/write attributes
     445             :         sal_Int32 i;
     446        9588 :         for( i = 0; i < pITD->nAllMembers; i++ )
     447             :         {
     448             :             // index to the get method of the attribute
     449        8502 :             pITD->pMapMemberIndexToFunctionIndex[i] = i + nAdditionalOffset;
     450             :             // extra offset if it is a read/write attribute?
     451        8502 :             if( pReadWriteAttributes[i] )
     452             :             {
     453             :                 // a read/write attribute
     454         310 :                 nAdditionalOffset++;
     455             :             }
     456             :         }
     457             : 
     458             :         // create the index table from function to member table
     459        1086 :         pITD->pMapFunctionIndexToMemberIndex = new sal_Int32[ pITD->nAllMembers + nAdditionalOffset ];
     460        1086 :         nAdditionalOffset = 0; // +1 for read/write attributes
     461        9588 :         for( i = 0; i < pITD->nAllMembers; i++ )
     462             :         {
     463             :             // index to the get method of the attribute
     464        8502 :             pITD->pMapFunctionIndexToMemberIndex[i + nAdditionalOffset] = i;
     465             :             // extra offset if it is a read/write attribute?
     466        8502 :             if( pReadWriteAttributes[i] )
     467             :             {
     468             :                 // a read/write attribute
     469         310 :                 pITD->pMapFunctionIndexToMemberIndex[i + ++nAdditionalOffset] = i;
     470             :             }
     471             :         }
     472             :         // must be the last action after all initialization is done
     473        1086 :         pITD->nMapFunctionIndexToMemberIndex = pITD->nAllMembers + nAdditionalOffset;
     474        1086 :         pTD->bComplete = sal_True;
     475        1086 :     }
     476        1086 : }
     477             : 
     478             : namespace {
     479             : 
     480             : // In some situations (notably typelib_typedescription_newInterfaceMethod and
     481             : // typelib_typedescription_newInterfaceAttribute), only the members nMembers,
     482             : // ppMembers, nAllMembers, and ppAllMembers of an incomplete interface type
     483             : // description are necessary, but not the additional
     484             : // pMapMemberIndexToFunctionIndex, nMapFunctionIndexToMemberIndex, and
     485             : // pMapFunctionIndexToMemberIndex (which are computed by
     486             : // typelib_typedescription_initTables).  Furthermore, in those situations, it
     487             : // might be illegal to compute those tables, as the creation of the interface
     488             : // member type descriptions would recursively require a complete interface type
     489             : // description.  The parameter initTables controls whether or not to call
     490             : // typelib_typedescription_initTables in those situations.
     491       86592 : bool complete(typelib_TypeDescription ** ppTypeDescr, bool initTables) {
     492       86592 :     if (! (*ppTypeDescr)->bComplete)
     493             :     {
     494             :         OSL_ASSERT( (typelib_TypeClass_STRUCT == (*ppTypeDescr)->eTypeClass ||
     495             :                      typelib_TypeClass_EXCEPTION == (*ppTypeDescr)->eTypeClass ||
     496             :                      typelib_TypeClass_UNION == (*ppTypeDescr)->eTypeClass ||
     497             :                      typelib_TypeClass_ENUM == (*ppTypeDescr)->eTypeClass ||
     498             :                      typelib_TypeClass_INTERFACE == (*ppTypeDescr)->eTypeClass) &&
     499             :                     !reallyWeak( (*ppTypeDescr)->eTypeClass ) );
     500             : 
     501       75821 :         if (typelib_TypeClass_INTERFACE == (*ppTypeDescr)->eTypeClass &&
     502             :             ((typelib_InterfaceTypeDescription *)*ppTypeDescr)->ppAllMembers)
     503             :         {
     504       75821 :             if (initTables) {
     505        1086 :                 typelib_typedescription_initTables( *ppTypeDescr );
     506             :             }
     507       75821 :             return true;
     508             :         }
     509             : 
     510           0 :         typelib_TypeDescription * pTD = 0;
     511             :         // on demand access of complete td
     512           0 :         TypeDescriptor_Init_Impl &rInit = Init::get();
     513           0 :         rInit.callChain( &pTD, (*ppTypeDescr)->pTypeName );
     514           0 :         if (pTD)
     515             :         {
     516           0 :             if (typelib_TypeClass_TYPEDEF == pTD->eTypeClass)
     517             :             {
     518             :                 typelib_typedescriptionreference_getDescription(
     519           0 :                     &pTD, ((typelib_IndirectTypeDescription *)pTD)->pType );
     520             :                 OSL_ASSERT( pTD );
     521           0 :                 if (! pTD)
     522           0 :                     return false;
     523             :             }
     524             : 
     525             :             OSL_ASSERT( typelib_TypeClass_TYPEDEF != pTD->eTypeClass );
     526             :             // typedescription found
     527             :             // set to on demand
     528           0 :             pTD->bOnDemand = sal_True;
     529             : 
     530           0 :             if (pTD->eTypeClass == typelib_TypeClass_INTERFACE
     531           0 :                 && !pTD->bComplete && initTables)
     532             :             {
     533             :                 // mandatory info from callback chain
     534             :                 OSL_ASSERT( ((typelib_InterfaceTypeDescription *)pTD)->ppAllMembers );
     535             :                 // complete except of tables init
     536           0 :                 typelib_typedescription_initTables( pTD );
     537           0 :                 pTD->bComplete = sal_True;
     538             :             }
     539             : 
     540             :             // The type description is hold by the reference until
     541             :             // on demand is activated.
     542           0 :             ::typelib_typedescription_register( &pTD ); // replaces incomplete one
     543             :             OSL_ASSERT( pTD == *ppTypeDescr ); // has to merge into existing one
     544             : 
     545             :             // insert into the chache
     546           0 :             MutexGuard aGuard( rInit.getMutex() );
     547           0 :             if( !rInit.pCache )
     548           0 :                 rInit.pCache = new TypeDescriptionList_Impl;
     549           0 :             if( (sal_Int32)rInit.pCache->size() >= nCacheSize )
     550             :             {
     551           0 :                 typelib_typedescription_release( rInit.pCache->front() );
     552           0 :                 rInit.pCache->pop_front();
     553             :             }
     554             :             // descriptions in the cache must be acquired!
     555           0 :             typelib_typedescription_acquire( pTD );
     556           0 :             rInit.pCache->push_back( pTD );
     557             : 
     558             :             OSL_ASSERT(
     559             :                 pTD->bComplete
     560             :                 || (pTD->eTypeClass == typelib_TypeClass_INTERFACE
     561             :                     && !initTables));
     562             : 
     563           0 :             ::typelib_typedescription_release( *ppTypeDescr );
     564           0 :             *ppTypeDescr = pTD;
     565             :         }
     566             :         else
     567             :         {
     568             : #if OSL_DEBUG_LEVEL > 1
     569             :             OString aStr(
     570             :                 rtl::OUStringToOString( (*ppTypeDescr)->pTypeName, RTL_TEXTENCODING_ASCII_US ) );
     571             :             OSL_TRACE( "\n### type cannot be completed: %s", aStr.getStr() );
     572             : #endif
     573           0 :             return false;
     574             :         }
     575             :     }
     576       10771 :     return true;
     577             : }
     578             : 
     579             : }
     580             : 
     581             : //------------------------------------------------------------------------
     582      115727 : extern "C" void SAL_CALL typelib_typedescription_newEmpty(
     583             :     typelib_TypeDescription ** ppRet,
     584             :     typelib_TypeClass eTypeClass, rtl_uString * pTypeName )
     585             :     SAL_THROW_EXTERN_C()
     586             : {
     587      115727 :     if( *ppRet )
     588             :     {
     589        3960 :         typelib_typedescription_release( *ppRet );
     590        3960 :         *ppRet = 0;
     591             :     }
     592             : 
     593             :     OSL_ASSERT( typelib_TypeClass_TYPEDEF != eTypeClass );
     594             : 
     595             :     typelib_TypeDescription * pRet;
     596      115727 :     switch( eTypeClass )
     597             :     {
     598             :         case typelib_TypeClass_ARRAY:
     599             :         {
     600           0 :             typelib_ArrayTypeDescription * pTmp = new typelib_ArrayTypeDescription();
     601           0 :             typelib_IndirectTypeDescription * pIndirect = (typelib_IndirectTypeDescription *)pTmp;
     602           0 :             pRet = (typelib_TypeDescription *)pTmp;
     603             : #if OSL_DEBUG_LEVEL > 1
     604             :             osl_atomic_increment( &Init::get().nArrayTypeDescriptionCount );
     605             : #endif
     606           0 :             pIndirect->pType = 0;
     607           0 :             pTmp->nDimensions = 0;
     608           0 :             pTmp->nTotalElements = 0;
     609           0 :             pTmp->pDimensions = 0;
     610             :         }
     611           0 :         break;
     612             : 
     613             :         case typelib_TypeClass_SEQUENCE:
     614             :         {
     615        3076 :             typelib_IndirectTypeDescription * pTmp = new typelib_IndirectTypeDescription();
     616        3076 :             pRet = (typelib_TypeDescription *)pTmp;
     617             : #if OSL_DEBUG_LEVEL > 1
     618             :             osl_atomic_increment( &Init::get().nIndirectTypeDescriptionCount );
     619             : #endif
     620        3076 :             pTmp->pType = 0;
     621             :         }
     622        3076 :         break;
     623             : 
     624             :         case typelib_TypeClass_UNION:
     625             :         {
     626             :             typelib_UnionTypeDescription * pTmp;
     627           0 :             pTmp = new typelib_UnionTypeDescription();
     628           0 :             pRet = (typelib_TypeDescription *)pTmp;
     629             : #if OSL_DEBUG_LEVEL > 1
     630             :             osl_atomic_increment( &Init::get().nUnionTypeDescriptionCount );
     631             : #endif
     632           0 :             pTmp->nMembers = 0;
     633           0 :             pTmp->pDiscriminantTypeRef = 0;
     634           0 :             pTmp->pDiscriminants = 0;
     635           0 :             pTmp->ppTypeRefs = 0;
     636           0 :             pTmp->ppMemberNames = 0;
     637           0 :             pTmp->pDefaultTypeRef = 0;
     638             :         }
     639           0 :         break;
     640             : 
     641             :         case typelib_TypeClass_STRUCT:
     642             :         {
     643             :             // FEATURE_EMPTYCLASS
     644             :             typelib_StructTypeDescription * pTmp;
     645        2682 :             pTmp = new typelib_StructTypeDescription();
     646        2682 :             pRet = (typelib_TypeDescription *)pTmp;
     647             : #if OSL_DEBUG_LEVEL > 1
     648             :             osl_atomic_increment( &Init::get().nCompoundTypeDescriptionCount );
     649             : #endif
     650        2682 :             pTmp->aBase.pBaseTypeDescription = 0;
     651        2682 :             pTmp->aBase.nMembers = 0;
     652        2682 :             pTmp->aBase.pMemberOffsets = 0;
     653        2682 :             pTmp->aBase.ppTypeRefs = 0;
     654        2682 :             pTmp->aBase.ppMemberNames = 0;
     655        2682 :             pTmp->pParameterizedTypes = 0;
     656             :         }
     657        2682 :         break;
     658             : 
     659             :         case typelib_TypeClass_EXCEPTION:
     660             :         {
     661             :             // FEATURE_EMPTYCLASS
     662             :             typelib_CompoundTypeDescription * pTmp;
     663        6996 :             pTmp = new typelib_CompoundTypeDescription();
     664        6996 :             pRet = (typelib_TypeDescription *)pTmp;
     665             : #if OSL_DEBUG_LEVEL > 1
     666             :             osl_atomic_increment( &Init::get().nCompoundTypeDescriptionCount );
     667             : #endif
     668        6996 :             pTmp->pBaseTypeDescription = 0;
     669        6996 :             pTmp->nMembers = 0;
     670        6996 :             pTmp->pMemberOffsets = 0;
     671        6996 :             pTmp->ppTypeRefs = 0;
     672        6996 :             pTmp->ppMemberNames = 0;
     673             :         }
     674        6996 :         break;
     675             : 
     676             :         case typelib_TypeClass_ENUM:
     677             :         {
     678        1757 :             typelib_EnumTypeDescription * pTmp = new typelib_EnumTypeDescription();
     679        1757 :             pRet = (typelib_TypeDescription *)pTmp;
     680             : #if OSL_DEBUG_LEVEL > 1
     681             :             osl_atomic_increment( &Init::get().nEnumTypeDescriptionCount );
     682             : #endif
     683        1757 :             pTmp->nDefaultEnumValue = 0;
     684        1757 :             pTmp->nEnumValues       = 0;
     685        1757 :             pTmp->ppEnumNames       = 0;
     686        1757 :             pTmp->pEnumValues       = 0;
     687             :         }
     688        1757 :         break;
     689             : 
     690             :         case typelib_TypeClass_INTERFACE:
     691             :         {
     692       31825 :             typelib_InterfaceTypeDescription * pTmp = new typelib_InterfaceTypeDescription();
     693       31825 :             pRet = (typelib_TypeDescription *)pTmp;
     694             : #if OSL_DEBUG_LEVEL > 1
     695             :             osl_atomic_increment( &Init::get().nInterfaceTypeDescriptionCount );
     696             : #endif
     697       31825 :             pTmp->pBaseTypeDescription = 0;
     698       31825 :             pTmp->nMembers = 0;
     699       31825 :             pTmp->ppMembers = 0;
     700       31825 :             pTmp->nAllMembers = 0;
     701       31825 :             pTmp->ppAllMembers = 0;
     702       31825 :             pTmp->nMapFunctionIndexToMemberIndex = 0;
     703       31825 :             pTmp->pMapFunctionIndexToMemberIndex = 0;
     704       31825 :             pTmp->pMapMemberIndexToFunctionIndex= 0;
     705       31825 :             pTmp->nBaseTypes = 0;
     706       31825 :             pTmp->ppBaseTypes = 0;
     707             :         }
     708       31825 :         break;
     709             : 
     710             :         case typelib_TypeClass_INTERFACE_METHOD:
     711             :         {
     712       63601 :             typelib_InterfaceMethodTypeDescription * pTmp = new typelib_InterfaceMethodTypeDescription();
     713       63601 :             pRet = (typelib_TypeDescription *)pTmp;
     714             : #if OSL_DEBUG_LEVEL > 1
     715             :             osl_atomic_increment( &Init::get().nInterfaceMethodTypeDescriptionCount );
     716             : #endif
     717       63601 :             pTmp->aBase.pMemberName = 0;
     718       63601 :             pTmp->pReturnTypeRef = 0;
     719       63601 :             pTmp->nParams = 0;
     720       63601 :             pTmp->pParams = 0;
     721       63601 :             pTmp->nExceptions = 0;
     722       63601 :             pTmp->ppExceptions = 0;
     723       63601 :             pTmp->pInterface = 0;
     724       63601 :             pTmp->pBaseRef = 0;
     725       63601 :             pTmp->nIndex = 0;
     726             :         }
     727       63601 :         break;
     728             : 
     729             :         case typelib_TypeClass_INTERFACE_ATTRIBUTE:
     730             :         {
     731        1008 :             typelib_InterfaceAttributeTypeDescription * pTmp = new typelib_InterfaceAttributeTypeDescription();
     732        1008 :             pRet = (typelib_TypeDescription *)pTmp;
     733             : #if OSL_DEBUG_LEVEL > 1
     734             :             osl_atomic_increment( &Init::get().nInterfaceAttributeTypeDescriptionCount );
     735             : #endif
     736        1008 :             pTmp->aBase.pMemberName = 0;
     737        1008 :             pTmp->pAttributeTypeRef = 0;
     738        1008 :             pTmp->pInterface = 0;
     739        1008 :             pTmp->pBaseRef = 0;
     740        1008 :             pTmp->nIndex = 0;
     741        1008 :             pTmp->nGetExceptions = 0;
     742        1008 :             pTmp->ppGetExceptions = 0;
     743        1008 :             pTmp->nSetExceptions = 0;
     744        1008 :             pTmp->ppSetExceptions = 0;
     745             :         }
     746        1008 :         break;
     747             : 
     748             :         default:
     749             :         {
     750        4782 :             pRet = new typelib_TypeDescription();
     751             : #if OSL_DEBUG_LEVEL > 1
     752             :             osl_atomic_increment( &Init::get().nTypeDescriptionCount );
     753             : #endif
     754             :         }
     755             :     }
     756             : 
     757      115727 :     pRet->nRefCount = 1; // reference count is initially 1
     758      115727 :     pRet->nStaticRefCount = 0;
     759      115727 :     pRet->eTypeClass = eTypeClass;
     760      115727 :     pRet->pTypeName = 0;
     761      115727 :     pRet->pUniqueIdentifier = 0;
     762      115727 :     pRet->pReserved = 0;
     763      115727 :     rtl_uString_acquire( pRet->pTypeName = pTypeName );
     764      115727 :     pRet->pSelf = pRet;
     765      115727 :     pRet->bComplete = sal_True;
     766      115727 :     pRet->nSize = 0;
     767      115727 :     pRet->nAlignment = 0;
     768      115727 :     pRet->pWeakRef = 0;
     769      115727 :     pRet->bOnDemand = sal_False;
     770      115727 :     *ppRet = pRet;
     771      115727 : }
     772             : 
     773             : //------------------------------------------------------------------------
     774             : namespace {
     775             : 
     776       13710 : void newTypeDescription(
     777             :     typelib_TypeDescription ** ppRet, typelib_TypeClass eTypeClass,
     778             :     rtl_uString * pTypeName, typelib_TypeDescriptionReference * pType,
     779             :     sal_Int32 nMembers, typelib_CompoundMember_Init * pCompoundMembers,
     780             :     typelib_StructMember_Init * pStructMembers)
     781             : {
     782             :     OSL_ASSERT(
     783             :         (pCompoundMembers == 0 || pStructMembers == 0)
     784             :         && (pStructMembers == 0 || eTypeClass == typelib_TypeClass_STRUCT));
     785       13710 :     if (typelib_TypeClass_TYPEDEF == eTypeClass)
     786             :     {
     787             :         OSL_TRACE( "### unexpected typedef!" );
     788           0 :         typelib_typedescriptionreference_getDescription( ppRet, pType );
     789       13710 :         return;
     790             :     }
     791             : 
     792       13710 :     typelib_typedescription_newEmpty( ppRet, eTypeClass, pTypeName );
     793             : 
     794       13710 :     switch( eTypeClass )
     795             :     {
     796             :         case typelib_TypeClass_SEQUENCE:
     797             :         {
     798             :             OSL_ASSERT( nMembers == 0 );
     799        3052 :             typelib_typedescriptionreference_acquire( pType );
     800        3052 :             ((typelib_IndirectTypeDescription *)*ppRet)->pType = pType;
     801             :         }
     802        3052 :         break;
     803             : 
     804             :         case typelib_TypeClass_EXCEPTION:
     805             :         case typelib_TypeClass_STRUCT:
     806             :         {
     807             :             // FEATURE_EMPTYCLASS
     808        6682 :             typelib_CompoundTypeDescription * pTmp = (typelib_CompoundTypeDescription*)*ppRet;
     809             : 
     810        6682 :             sal_Int32 nOffset = 0;
     811        6682 :             if( pType )
     812             :             {
     813             :                 typelib_typedescriptionreference_getDescription(
     814        4877 :                     (typelib_TypeDescription **)&pTmp->pBaseTypeDescription, pType );
     815        4877 :                 nOffset = ((typelib_TypeDescription *)pTmp->pBaseTypeDescription)->nSize;
     816             :                 OSL_ENSURE( newAlignedSize( 0, ((typelib_TypeDescription *)pTmp->pBaseTypeDescription)->nSize, ((typelib_TypeDescription *)pTmp->pBaseTypeDescription)->nAlignment ) == ((typelib_TypeDescription *)pTmp->pBaseTypeDescription)->nSize, "### unexpected offset!" );
     817             :             }
     818        6682 :             if( nMembers )
     819             :             {
     820        2785 :                 pTmp->nMembers = nMembers;
     821        2785 :                 pTmp->pMemberOffsets = new sal_Int32[ nMembers ];
     822        2785 :                 pTmp->ppTypeRefs = new typelib_TypeDescriptionReference *[ nMembers ];
     823        2785 :                 pTmp->ppMemberNames = new rtl_uString *[ nMembers ];
     824             :                 bool polymorphic = eTypeClass == typelib_TypeClass_STRUCT
     825        2785 :                     && rtl::OUString::unacquired(&pTypeName).indexOf('<') >= 0;
     826             :                 OSL_ASSERT(!polymorphic || pStructMembers != 0);
     827        2785 :                 if (polymorphic) {
     828             :                     reinterpret_cast< typelib_StructTypeDescription * >(pTmp)->
     829          54 :                         pParameterizedTypes = new sal_Bool[nMembers];
     830             :                 }
     831       10525 :                 for( sal_Int32 i = 0 ; i < nMembers; i++ )
     832             :                 {
     833             :                     // read the type and member names
     834        7740 :                     pTmp->ppTypeRefs[i] = 0;
     835        7740 :                     if (pCompoundMembers != 0) {
     836             :                         typelib_typedescriptionreference_new(
     837        1263 :                             pTmp->ppTypeRefs +i, pCompoundMembers[i].eTypeClass,
     838        2526 :                             pCompoundMembers[i].pTypeName );
     839             :                         rtl_uString_acquire(
     840        2526 :                             pTmp->ppMemberNames[i]
     841        2526 :                             = pCompoundMembers[i].pMemberName );
     842             :                     } else {
     843             :                         typelib_typedescriptionreference_new(
     844             :                             pTmp->ppTypeRefs +i,
     845        6477 :                             pStructMembers[i].aBase.eTypeClass,
     846       12954 :                             pStructMembers[i].aBase.pTypeName );
     847             :                         rtl_uString_acquire(
     848       12954 :                             pTmp->ppMemberNames[i]
     849       12954 :                             = pStructMembers[i].aBase.pMemberName );
     850             :                     }
     851             :                     // write offset
     852             :                     sal_Int32 size;
     853             :                     sal_Int32 alignment;
     854        7740 :                     if (pTmp->ppTypeRefs[i]->eTypeClass ==
     855             :                         typelib_TypeClass_SEQUENCE)
     856             :                     {
     857             :                         // Take care of recursion like
     858             :                         // struct S { sequence<S> x; };
     859         142 :                         size = sizeof(void *);
     860         142 :                         alignment = adjustAlignment(size);
     861             :                     } else {
     862        7598 :                         typelib_TypeDescription * pTD = 0;
     863        7598 :                         TYPELIB_DANGER_GET( &pTD, pTmp->ppTypeRefs[i] );
     864             :                         OSL_ENSURE( pTD->nSize, "### void member?" );
     865        7598 :                         size = pTD->nSize;
     866        7598 :                         alignment = pTD->nAlignment;
     867        7598 :                         TYPELIB_DANGER_RELEASE( pTD );
     868             :                     }
     869        7740 :                     nOffset = newAlignedSize( nOffset, size, alignment );
     870        7740 :                     pTmp->pMemberOffsets[i] = nOffset - size;
     871             : 
     872        7740 :                     if (polymorphic) {
     873             :                         reinterpret_cast< typelib_StructTypeDescription * >(
     874          71 :                             pTmp)->pParameterizedTypes[i]
     875          71 :                             = pStructMembers[i].bParameterizedType;
     876             :                     }
     877             :                 }
     878             :             }
     879             :         }
     880        6682 :         break;
     881             : 
     882             :         default:
     883        3976 :         break;
     884             :     }
     885             : 
     886       13710 :     if( !reallyWeak( eTypeClass ) )
     887       13710 :         (*ppRet)->pWeakRef = (typelib_TypeDescriptionReference *)*ppRet;
     888       13710 :     if( eTypeClass != typelib_TypeClass_VOID )
     889             :     {
     890             :         // sizeof( void ) not allowed
     891       13446 :         (*ppRet)->nSize = typelib_typedescription_getAlignedUnoSize( (*ppRet), 0, (*ppRet)->nAlignment );
     892       13446 :         (*ppRet)->nAlignment = adjustAlignment( (*ppRet)->nAlignment );
     893             :     }
     894             : }
     895             : 
     896             : }
     897             : 
     898       11865 : extern "C" CPPU_DLLPUBLIC void SAL_CALL typelib_typedescription_new(
     899             :     typelib_TypeDescription ** ppRet,
     900             :     typelib_TypeClass eTypeClass,
     901             :     rtl_uString * pTypeName,
     902             :     typelib_TypeDescriptionReference * pType,
     903             :     sal_Int32 nMembers,
     904             :     typelib_CompoundMember_Init * pMembers )
     905             :     SAL_THROW_EXTERN_C()
     906             : {
     907             :     newTypeDescription(
     908       11865 :         ppRet, eTypeClass, pTypeName, pType, nMembers, pMembers, 0);
     909       11865 : }
     910             : 
     911        1845 : extern "C" CPPU_DLLPUBLIC void SAL_CALL typelib_typedescription_newStruct(
     912             :     typelib_TypeDescription ** ppRet,
     913             :     rtl_uString * pTypeName,
     914             :     typelib_TypeDescriptionReference * pType,
     915             :     sal_Int32 nMembers,
     916             :     typelib_StructMember_Init * pMembers )
     917             :     SAL_THROW_EXTERN_C()
     918             : {
     919             :     newTypeDescription(
     920             :         ppRet, typelib_TypeClass_STRUCT, pTypeName, pType, nMembers, 0,
     921        1845 :         pMembers);
     922        1845 : }
     923             : 
     924             : //------------------------------------------------------------------------
     925           0 : extern "C" CPPU_DLLPUBLIC void SAL_CALL typelib_typedescription_newUnion(
     926             :     typelib_TypeDescription ** ppRet,
     927             :     rtl_uString * pTypeName,
     928             :     typelib_TypeDescriptionReference * pDiscriminantTypeRef,
     929             :     sal_Int64 nDefaultDiscriminant,
     930             :     typelib_TypeDescriptionReference * pDefaultTypeRef,
     931             :     sal_Int32 nMembers,
     932             :     typelib_Union_Init * pMembers )
     933             :     SAL_THROW_EXTERN_C()
     934             : {
     935           0 :     typelib_typedescription_newEmpty( ppRet, typelib_TypeClass_UNION, pTypeName );
     936             :     // discriminant type
     937           0 :     typelib_UnionTypeDescription * pTmp = (typelib_UnionTypeDescription *)*ppRet;
     938           0 :     typelib_typedescriptionreference_acquire( pTmp->pDiscriminantTypeRef = pDiscriminantTypeRef );
     939             : 
     940             :     sal_Int32 nPos;
     941             : 
     942           0 :     pTmp->nMembers = nMembers;
     943             :     // default discriminant
     944           0 :     if (nMembers)
     945             :     {
     946           0 :         pTmp->pDiscriminants = new sal_Int64[ nMembers ];
     947           0 :         for ( nPos = nMembers; nPos--; )
     948             :         {
     949           0 :             pTmp->pDiscriminants[nPos] = pMembers[nPos].nDiscriminant;
     950             :         }
     951             :     }
     952             :     // default default discriminant
     953           0 :     pTmp->nDefaultDiscriminant = nDefaultDiscriminant;
     954             : 
     955             :     // union member types
     956           0 :     pTmp->ppTypeRefs = new typelib_TypeDescriptionReference *[ nMembers ];
     957           0 :     for ( nPos = nMembers; nPos--; )
     958             :     {
     959           0 :         typelib_typedescriptionreference_acquire( pTmp->ppTypeRefs[nPos] = pMembers[nPos].pTypeRef );
     960             :     }
     961             :     // union member names
     962           0 :     pTmp->ppMemberNames = new rtl_uString *[ nMembers ];
     963           0 :     for ( nPos = nMembers; nPos--; )
     964             :     {
     965           0 :         rtl_uString_acquire( pTmp->ppMemberNames[nPos] = pMembers[nPos].pMemberName );
     966             :     }
     967             : 
     968             :     // default union type
     969           0 :     typelib_typedescriptionreference_acquire( pTmp->pDefaultTypeRef = pDefaultTypeRef );
     970             : 
     971           0 :     if (! reallyWeak( typelib_TypeClass_UNION ))
     972           0 :         (*ppRet)->pWeakRef = (typelib_TypeDescriptionReference *)*ppRet;
     973           0 :     (*ppRet)->nSize = typelib_typedescription_getAlignedUnoSize( (*ppRet), 0, (*ppRet)->nAlignment );
     974           0 :     (*ppRet)->nAlignment = adjustAlignment( (*ppRet)->nAlignment );
     975           0 : }
     976             : 
     977             : //------------------------------------------------------------------------
     978         698 : extern "C" CPPU_DLLPUBLIC void SAL_CALL typelib_typedescription_newEnum(
     979             :     typelib_TypeDescription ** ppRet,
     980             :     rtl_uString * pTypeName,
     981             :     sal_Int32 nDefaultValue,
     982             :     sal_Int32 nEnumValues,
     983             :     rtl_uString ** ppEnumNames,
     984             :     sal_Int32 * pEnumValues )
     985             :     SAL_THROW_EXTERN_C()
     986             : {
     987         698 :     typelib_typedescription_newEmpty( ppRet, typelib_TypeClass_ENUM, pTypeName );
     988         698 :     typelib_EnumTypeDescription * pEnum = (typelib_EnumTypeDescription *)*ppRet;
     989             : 
     990         698 :     pEnum->nDefaultEnumValue = nDefaultValue;
     991         698 :     pEnum->nEnumValues       = nEnumValues;
     992         698 :     pEnum->ppEnumNames       = new rtl_uString * [ nEnumValues ];
     993        6205 :     for ( sal_Int32 nPos = nEnumValues; nPos--; )
     994             :     {
     995        4809 :         rtl_uString_acquire( pEnum->ppEnumNames[nPos] = ppEnumNames[nPos] );
     996             :     }
     997         698 :     pEnum->pEnumValues      = new sal_Int32[ nEnumValues ];
     998         698 :     ::memcpy( pEnum->pEnumValues, pEnumValues, nEnumValues * sizeof(sal_Int32) );
     999             : 
    1000         698 :     (*ppRet)->pWeakRef = (typelib_TypeDescriptionReference *)*ppRet;
    1001             :     // sizeof( void ) not allowed
    1002         698 :     (*ppRet)->nSize = typelib_typedescription_getAlignedUnoSize( (*ppRet), 0, (*ppRet)->nAlignment );
    1003         698 :     (*ppRet)->nAlignment = adjustAlignment( (*ppRet)->nAlignment );
    1004         698 : }
    1005             : 
    1006             : //------------------------------------------------------------------------
    1007           0 : extern "C" CPPU_DLLPUBLIC void SAL_CALL typelib_typedescription_newArray(
    1008             :     typelib_TypeDescription ** ppRet,
    1009             :     typelib_TypeDescriptionReference * pElementTypeRef,
    1010             :     sal_Int32 nDimensions,
    1011             :     sal_Int32 * pDimensions )
    1012             :     SAL_THROW_EXTERN_C ()
    1013             : {
    1014           0 :     OUStringBuffer aBuf( 32 );
    1015           0 :     aBuf.append( pElementTypeRef->pTypeName );
    1016           0 :     sal_Int32 nElements = 1;
    1017           0 :     for (sal_Int32 i=0; i < nDimensions; i++)
    1018             :     {
    1019           0 :         aBuf.appendAscii("[");
    1020           0 :         aBuf.append(pDimensions[i]);
    1021           0 :         aBuf.appendAscii("]");
    1022           0 :         nElements *= pDimensions[i];
    1023             :     }
    1024           0 :     OUString aTypeName( aBuf.makeStringAndClear() );
    1025             : 
    1026             : 
    1027           0 :     typelib_typedescription_newEmpty( ppRet, typelib_TypeClass_ARRAY, aTypeName.pData );
    1028           0 :     typelib_ArrayTypeDescription * pArray = (typelib_ArrayTypeDescription *)*ppRet;
    1029             : 
    1030           0 :     pArray->nDimensions = nDimensions;
    1031           0 :     pArray->nTotalElements = nElements;
    1032           0 :     pArray->pDimensions = new sal_Int32[ nDimensions ];
    1033           0 :     ::memcpy( pArray->pDimensions, pDimensions, nDimensions * sizeof(sal_Int32) );
    1034             : 
    1035           0 :     typelib_typedescriptionreference_acquire(pElementTypeRef);
    1036           0 :     ((typelib_IndirectTypeDescription*)pArray)->pType = pElementTypeRef;
    1037             : 
    1038           0 :     (*ppRet)->pWeakRef = (typelib_TypeDescriptionReference *)*ppRet;
    1039             :     // sizeof( void ) not allowed
    1040           0 :     (*ppRet)->nSize = typelib_typedescription_getAlignedUnoSize( *ppRet, 0, (*ppRet)->nAlignment );
    1041           0 :     (*ppRet)->nAlignment = adjustAlignment( (*ppRet)->nAlignment );
    1042           0 : }
    1043             : 
    1044             : //------------------------------------------------------------------------
    1045         265 : extern "C" CPPU_DLLPUBLIC void SAL_CALL typelib_typedescription_newInterface(
    1046             :     typelib_InterfaceTypeDescription ** ppRet,
    1047             :     rtl_uString * pTypeName,
    1048             :     sal_uInt32 nUik1, sal_uInt16 nUik2, sal_uInt16 nUik3, sal_uInt32 nUik4, sal_uInt32 nUik5,
    1049             :     typelib_TypeDescriptionReference * pBaseInterface,
    1050             :     sal_Int32 nMembers,
    1051             :     typelib_TypeDescriptionReference ** ppMembers )
    1052             :     SAL_THROW_EXTERN_C()
    1053             : {
    1054             :     typelib_typedescription_newMIInterface(
    1055             :         ppRet, pTypeName, nUik1, nUik2, nUik3, nUik4, nUik5,
    1056         265 :         pBaseInterface == 0 ? 0 : 1, &pBaseInterface, nMembers, ppMembers);
    1057         265 : }
    1058             : 
    1059             : //------------------------------------------------------------------------
    1060             : 
    1061             : namespace {
    1062             : 
    1063       23936 : class BaseList {
    1064             : public:
    1065             :     struct Entry {
    1066             :         sal_Int32 memberOffset;
    1067             :         sal_Int32 directBaseIndex;
    1068             :         sal_Int32 directBaseMemberOffset;
    1069             :         typelib_InterfaceTypeDescription const * base;
    1070             :     };
    1071             : 
    1072             :     typedef std::vector< Entry > List;
    1073             : 
    1074             :     BaseList(typelib_InterfaceTypeDescription const * desc);
    1075             : 
    1076       23936 :     List const & getList() const { return list; }
    1077             : 
    1078       47718 :     sal_Int32 getBaseMembers() const { return members; }
    1079             : 
    1080             : private:
    1081             :     typedef std::set< rtl::OUString > Set;
    1082             : 
    1083             :     void calculate(
    1084             :         sal_Int32 directBaseIndex, Set & directBaseSet,
    1085             :         sal_Int32 * directBaseMembers,
    1086             :         typelib_InterfaceTypeDescription const * desc);
    1087             : 
    1088             :     Set set;
    1089             :     List list;
    1090             :     sal_Int32 members;
    1091             : };
    1092             : 
    1093       23936 : BaseList::BaseList(typelib_InterfaceTypeDescription const * desc) {
    1094       23936 :     members = 0;
    1095       45308 :     for (sal_Int32 i = 0; i < desc->nBaseTypes; ++i) {
    1096       21372 :         Set directBaseSet;
    1097       21372 :         sal_Int32 directBaseMembers = 0;
    1098       21372 :         calculate(i, directBaseSet, &directBaseMembers, desc->ppBaseTypes[i]);
    1099       21372 :     }
    1100       23936 : }
    1101             : 
    1102       28231 : void BaseList::calculate(
    1103             :     sal_Int32 directBaseIndex, Set & directBaseSet,
    1104             :     sal_Int32 * directBaseMembers,
    1105             :     typelib_InterfaceTypeDescription const * desc)
    1106             : {
    1107       35090 :     for (sal_Int32 i = 0; i < desc->nBaseTypes; ++i) {
    1108             :         calculate(
    1109             :             directBaseIndex, directBaseSet, directBaseMembers,
    1110        6859 :             desc->ppBaseTypes[i]);
    1111             :     }
    1112       28231 :     if (set.insert(desc->aBase.pTypeName).second) {
    1113             :         Entry e;
    1114       27871 :         e.memberOffset = members;
    1115       27871 :         e.directBaseIndex = directBaseIndex;
    1116       27871 :         e.directBaseMemberOffset = *directBaseMembers;
    1117       27871 :         e.base = desc;
    1118       27871 :         list.push_back(e);
    1119             :         OSL_ASSERT(desc->ppAllMembers != 0);
    1120       27871 :         members += desc->nMembers;
    1121             :     }
    1122       28231 :     if (directBaseSet.insert(desc->aBase.pTypeName).second) {
    1123             :         OSL_ASSERT(desc->ppAllMembers != 0);
    1124       28171 :         *directBaseMembers += desc->nMembers;
    1125             :     }
    1126       28231 : }
    1127             : 
    1128             : }
    1129             : 
    1130       23936 : extern "C" CPPU_DLLPUBLIC void SAL_CALL typelib_typedescription_newMIInterface(
    1131             :     typelib_InterfaceTypeDescription ** ppRet,
    1132             :     rtl_uString * pTypeName,
    1133             :     sal_uInt32 nUik1, sal_uInt16 nUik2, sal_uInt16 nUik3, sal_uInt32 nUik4, sal_uInt32 nUik5,
    1134             :     sal_Int32 nBaseInterfaces,
    1135             :     typelib_TypeDescriptionReference ** ppBaseInterfaces,
    1136             :     sal_Int32 nMembers,
    1137             :     typelib_TypeDescriptionReference ** ppMembers )
    1138             :     SAL_THROW_EXTERN_C()
    1139             : {
    1140       23936 :     if (*ppRet != 0) {
    1141           0 :         typelib_typedescription_release(&(*ppRet)->aBase);
    1142           0 :         *ppRet = 0;
    1143             :     }
    1144             : 
    1145       23936 :     typelib_InterfaceTypeDescription * pITD = 0;
    1146             :     typelib_typedescription_newEmpty(
    1147       23936 :         (typelib_TypeDescription **)&pITD, typelib_TypeClass_INTERFACE, pTypeName );
    1148             : 
    1149       23936 :     pITD->nBaseTypes = nBaseInterfaces;
    1150       23936 :     pITD->ppBaseTypes = new typelib_InterfaceTypeDescription *[nBaseInterfaces];
    1151       45308 :     for (sal_Int32 i = 0; i < nBaseInterfaces; ++i) {
    1152       21372 :         pITD->ppBaseTypes[i] = 0;
    1153             :         typelib_typedescriptionreference_getDescription(
    1154             :             reinterpret_cast< typelib_TypeDescription ** >(
    1155             :                 &pITD->ppBaseTypes[i]),
    1156       21372 :             ppBaseInterfaces[i]);
    1157       42744 :         if (pITD->ppBaseTypes[i] == 0
    1158             :             || !complete(
    1159             :                 reinterpret_cast< typelib_TypeDescription ** >(
    1160             :                     &pITD->ppBaseTypes[i]),
    1161       21372 :                 false))
    1162             :         {
    1163             :             OSL_ASSERT(false);
    1164       23936 :             return;
    1165             :         }
    1166             :         OSL_ASSERT(pITD->ppBaseTypes[i] != 0);
    1167             :     }
    1168       23936 :     if (nBaseInterfaces > 0) {
    1169       21081 :         pITD->pBaseTypeDescription = pITD->ppBaseTypes[0];
    1170             :     }
    1171             :     // set the
    1172       23936 :     pITD->aUik.m_Data1 = nUik1;
    1173       23936 :     pITD->aUik.m_Data2 = nUik2;
    1174       23936 :     pITD->aUik.m_Data3 = nUik3;
    1175       23936 :     pITD->aUik.m_Data4 = nUik4;
    1176       23936 :     pITD->aUik.m_Data5 = nUik5;
    1177             : 
    1178       23936 :     BaseList aBaseList(pITD);
    1179       23936 :     pITD->nAllMembers = nMembers + aBaseList.getBaseMembers();
    1180       23936 :     pITD->nMembers = nMembers;
    1181             : 
    1182       23936 :     if( pITD->nAllMembers )
    1183             :     {
    1184             :         // at minimum one member exist, allocate the memory
    1185       23936 :         pITD->ppAllMembers = new typelib_TypeDescriptionReference *[ pITD->nAllMembers ];
    1186       23936 :         sal_Int32 n = 0;
    1187             : 
    1188       23936 :         BaseList::List const & rList = aBaseList.getList();
    1189       51807 :         {for (BaseList::List::const_iterator i(rList.begin()); i != rList.end();
    1190             :               ++i)
    1191             :         {
    1192       27871 :             typelib_InterfaceTypeDescription const * pBase = i->base;
    1193             :             typelib_InterfaceTypeDescription const * pDirectBase
    1194       27871 :                 = pITD->ppBaseTypes[i->directBaseIndex];
    1195             :             OSL_ASSERT(pBase->ppAllMembers != 0);
    1196      107607 :             for (sal_Int32 j = 0; j < pBase->nMembers; ++j) {
    1197             :                 typelib_TypeDescriptionReference const * pDirectBaseMember
    1198       79736 :                     = pDirectBase->ppAllMembers[i->directBaseMemberOffset + j];
    1199       79736 :                 rtl::OUStringBuffer aBuf(pDirectBaseMember->pTypeName);
    1200       79736 :                 aBuf.appendAscii(RTL_CONSTASCII_STRINGPARAM(":@"));
    1201       79736 :                 aBuf.append(i->directBaseIndex);
    1202       79736 :                 aBuf.append(static_cast< sal_Unicode >(','));
    1203       79736 :                 aBuf.append(i->memberOffset + j);
    1204       79736 :                 aBuf.append(static_cast< sal_Unicode >(':'));
    1205       79736 :                 aBuf.append(pITD->aBase.pTypeName);
    1206       79736 :                 rtl::OUString aName(aBuf.makeStringAndClear());
    1207       79736 :                 typelib_TypeDescriptionReference * pDerivedMember = 0;
    1208             :                 typelib_typedescriptionreference_new(
    1209             :                     &pDerivedMember, pDirectBaseMember->eTypeClass,
    1210       79736 :                     aName.pData);
    1211       79736 :                 pITD->ppAllMembers[n++] = pDerivedMember;
    1212       79736 :             }
    1213             :         }}
    1214             : 
    1215       23936 :         if( nMembers )
    1216             :         {
    1217       23782 :             pITD->ppMembers = pITD->ppAllMembers + aBaseList.getBaseMembers();
    1218             :         }
    1219             : 
    1220             :         // add own members
    1221      104609 :         {for( sal_Int32 i = 0; i < nMembers; i++ )
    1222             :         {
    1223       80673 :             typelib_typedescriptionreference_acquire( ppMembers[i] );
    1224       80673 :             pITD->ppAllMembers[n++] = ppMembers[i];
    1225             :         }}
    1226             :     }
    1227             : 
    1228       23936 :     typelib_TypeDescription * pTmp = (typelib_TypeDescription *)pITD;
    1229       23936 :     if( !reallyWeak( typelib_TypeClass_INTERFACE ) )
    1230       23936 :         pTmp->pWeakRef = (typelib_TypeDescriptionReference *)pTmp;
    1231       23936 :     pTmp->nSize = typelib_typedescription_getAlignedUnoSize( pTmp, 0, pTmp->nAlignment );
    1232       23936 :     pTmp->nAlignment = adjustAlignment( pTmp->nAlignment );
    1233       23936 :     pTmp->bComplete = sal_False;
    1234             : 
    1235       23936 :     *ppRet = pITD;
    1236             : }
    1237             : 
    1238             : //------------------------------------------------------------------------
    1239             : 
    1240             : namespace {
    1241             : 
    1242       62255 : typelib_TypeDescriptionReference ** copyExceptions(
    1243             :     sal_Int32 count, rtl_uString ** typeNames)
    1244             : {
    1245             :     OSL_ASSERT(count >= 0);
    1246       62255 :     if (count == 0) {
    1247        3209 :         return 0;
    1248             :     }
    1249             :     typelib_TypeDescriptionReference ** p
    1250       59046 :         = new typelib_TypeDescriptionReference *[count];
    1251      165030 :     for (sal_Int32 i = 0; i < count; ++i) {
    1252      105984 :         p[i] = 0;
    1253             :         typelib_typedescriptionreference_new(
    1254      105984 :             p + i, typelib_TypeClass_EXCEPTION, typeNames[i]);
    1255             :     }
    1256       59046 :     return p;
    1257             : }
    1258             : 
    1259             : }
    1260             : 
    1261       60453 : extern "C" CPPU_DLLPUBLIC void SAL_CALL typelib_typedescription_newInterfaceMethod(
    1262             :     typelib_InterfaceMethodTypeDescription ** ppRet,
    1263             :     sal_Int32 nAbsolutePosition,
    1264             :     sal_Bool bOneWay,
    1265             :     rtl_uString * pTypeName,
    1266             :     typelib_TypeClass eReturnTypeClass,
    1267             :     rtl_uString * pReturnTypeName,
    1268             :     sal_Int32 nParams,
    1269             :     typelib_Parameter_Init * pParams,
    1270             :     sal_Int32 nExceptions,
    1271             :     rtl_uString ** ppExceptionNames )
    1272             :     SAL_THROW_EXTERN_C()
    1273             : {
    1274       60453 :     if (*ppRet != 0) {
    1275       41474 :         typelib_typedescription_release(&(*ppRet)->aBase.aBase);
    1276       41474 :         *ppRet = 0;
    1277             :     }
    1278             :     sal_Int32 nOffset = rtl_ustr_lastIndexOfChar_WithLength(
    1279       60453 :         pTypeName->buffer, pTypeName->length, ':');
    1280       60453 :     if (nOffset <= 0 || pTypeName->buffer[nOffset - 1] != ':') {
    1281             :         OSL_FAIL("Bad interface method type name");
    1282             :         return;
    1283             :     }
    1284       60453 :     rtl::OUString aInterfaceTypeName(pTypeName->buffer, nOffset - 1);
    1285       60453 :     typelib_InterfaceTypeDescription * pInterface = 0;
    1286             :     typelib_typedescription_getByName(
    1287             :         reinterpret_cast< typelib_TypeDescription ** >(&pInterface),
    1288       60453 :         aInterfaceTypeName.pData);
    1289      120906 :     if (pInterface == 0
    1290             :         || pInterface->aBase.eTypeClass != typelib_TypeClass_INTERFACE
    1291             :         || !complete(
    1292       60453 :             reinterpret_cast< typelib_TypeDescription ** >(&pInterface), false))
    1293             :     {
    1294             :         OSL_FAIL("No interface corresponding to interface method");
    1295             :         return;
    1296             :     }
    1297             : 
    1298             :     typelib_typedescription_newEmpty(
    1299       60453 :         (typelib_TypeDescription **)ppRet, typelib_TypeClass_INTERFACE_METHOD, pTypeName );
    1300       60453 :     typelib_TypeDescription * pTmp = (typelib_TypeDescription *)*ppRet;
    1301             : 
    1302             :     rtl_uString_newFromStr_WithLength( &(*ppRet)->aBase.pMemberName,
    1303       60453 :                                        pTypeName->buffer + nOffset +1,
    1304      120906 :                                        pTypeName->length - nOffset -1 );
    1305       60453 :     (*ppRet)->aBase.nPosition = nAbsolutePosition;
    1306       60453 :     (*ppRet)->bOneWay = bOneWay;
    1307       60453 :     typelib_typedescriptionreference_new( &(*ppRet)->pReturnTypeRef, eReturnTypeClass, pReturnTypeName );
    1308       60453 :     (*ppRet)->nParams = nParams;
    1309       60453 :     if( nParams )
    1310             :     {
    1311       32879 :         (*ppRet)->pParams = new typelib_MethodParameter[ nParams ];
    1312             : 
    1313       77914 :         for( sal_Int32 i = 0; i < nParams; i++ )
    1314             :         {
    1315             :             // get the name of the parameter
    1316       45035 :             (*ppRet)->pParams[ i ].pName = 0;
    1317       45035 :             rtl_uString_acquire( (*ppRet)->pParams[ i ].pName = pParams[i].pParamName );
    1318       45035 :             (*ppRet)->pParams[ i ].pTypeRef = 0;
    1319             :             // get the type name of the parameter and create the weak reference
    1320             :             typelib_typedescriptionreference_new(
    1321       45035 :                 &(*ppRet)->pParams[ i ].pTypeRef, pParams[i].eTypeClass, pParams[i].pTypeName );
    1322       45035 :             (*ppRet)->pParams[ i ].bIn = pParams[i].bIn;
    1323       45035 :             (*ppRet)->pParams[ i ].bOut = pParams[i].bOut;
    1324             :         }
    1325             :     }
    1326       60453 :     (*ppRet)->nExceptions = nExceptions;
    1327       60453 :     (*ppRet)->ppExceptions = copyExceptions(nExceptions, ppExceptionNames);
    1328       60453 :     (*ppRet)->pInterface = pInterface;
    1329       60453 :     (*ppRet)->pBaseRef = 0;
    1330             :     OSL_ASSERT(
    1331             :         (nAbsolutePosition >= pInterface->nAllMembers - pInterface->nMembers)
    1332             :         && nAbsolutePosition < pInterface->nAllMembers);
    1333             :     (*ppRet)->nIndex = nAbsolutePosition
    1334       60453 :         - (pInterface->nAllMembers - pInterface->nMembers);
    1335       60453 :     if( !reallyWeak( typelib_TypeClass_INTERFACE_METHOD ) )
    1336           0 :         pTmp->pWeakRef = (typelib_TypeDescriptionReference *)pTmp;
    1337             : }
    1338             : 
    1339             : 
    1340             : //------------------------------------------------------------------------
    1341           0 : extern "C" CPPU_DLLPUBLIC void SAL_CALL typelib_typedescription_newInterfaceAttribute(
    1342             :     typelib_InterfaceAttributeTypeDescription ** ppRet,
    1343             :     sal_Int32 nAbsolutePosition,
    1344             :     rtl_uString * pTypeName,
    1345             :     typelib_TypeClass eAttributeTypeClass,
    1346             :     rtl_uString * pAttributeTypeName,
    1347             :     sal_Bool bReadOnly )
    1348             :     SAL_THROW_EXTERN_C()
    1349             : {
    1350             :     typelib_typedescription_newExtendedInterfaceAttribute(
    1351             :         ppRet, nAbsolutePosition, pTypeName, eAttributeTypeClass,
    1352           0 :         pAttributeTypeName, bReadOnly, 0, 0, 0, 0);
    1353           0 : }
    1354             : 
    1355             : //------------------------------------------------------------------------
    1356         901 : extern "C" CPPU_DLLPUBLIC void SAL_CALL typelib_typedescription_newExtendedInterfaceAttribute(
    1357             :     typelib_InterfaceAttributeTypeDescription ** ppRet,
    1358             :     sal_Int32 nAbsolutePosition,
    1359             :     rtl_uString * pTypeName,
    1360             :     typelib_TypeClass eAttributeTypeClass,
    1361             :     rtl_uString * pAttributeTypeName,
    1362             :     sal_Bool bReadOnly,
    1363             :     sal_Int32 nGetExceptions, rtl_uString ** ppGetExceptionNames,
    1364             :     sal_Int32 nSetExceptions, rtl_uString ** ppSetExceptionNames )
    1365             :     SAL_THROW_EXTERN_C()
    1366             : {
    1367         901 :     if (*ppRet != 0) {
    1368           0 :         typelib_typedescription_release(&(*ppRet)->aBase.aBase);
    1369           0 :         *ppRet = 0;
    1370             :     }
    1371             :     sal_Int32 nOffset = rtl_ustr_lastIndexOfChar_WithLength(
    1372         901 :         pTypeName->buffer, pTypeName->length, ':');
    1373         901 :     if (nOffset <= 0 || pTypeName->buffer[nOffset - 1] != ':') {
    1374             :         OSL_FAIL("Bad interface attribute type name");
    1375             :         return;
    1376             :     }
    1377         901 :     rtl::OUString aInterfaceTypeName(pTypeName->buffer, nOffset - 1);
    1378         901 :     typelib_InterfaceTypeDescription * pInterface = 0;
    1379             :     typelib_typedescription_getByName(
    1380             :         reinterpret_cast< typelib_TypeDescription ** >(&pInterface),
    1381         901 :         aInterfaceTypeName.pData);
    1382        1802 :     if (pInterface == 0
    1383             :         || pInterface->aBase.eTypeClass != typelib_TypeClass_INTERFACE
    1384             :         || !complete(
    1385         901 :             reinterpret_cast< typelib_TypeDescription ** >(&pInterface), false))
    1386             :     {
    1387             :         OSL_FAIL("No interface corresponding to interface attribute");
    1388             :         return;
    1389             :     }
    1390             : 
    1391             :     typelib_typedescription_newEmpty(
    1392         901 :         (typelib_TypeDescription **)ppRet, typelib_TypeClass_INTERFACE_ATTRIBUTE, pTypeName );
    1393         901 :     typelib_TypeDescription * pTmp = (typelib_TypeDescription *)*ppRet;
    1394             : 
    1395             :     rtl_uString_newFromStr_WithLength( &(*ppRet)->aBase.pMemberName,
    1396         901 :                                        pTypeName->buffer + nOffset +1,
    1397        1802 :                                        pTypeName->length - nOffset -1 );
    1398         901 :     (*ppRet)->aBase.nPosition = nAbsolutePosition;
    1399         901 :     typelib_typedescriptionreference_new( &(*ppRet)->pAttributeTypeRef, eAttributeTypeClass, pAttributeTypeName );
    1400         901 :     (*ppRet)->bReadOnly = bReadOnly;
    1401         901 :     (*ppRet)->pInterface = pInterface;
    1402         901 :     (*ppRet)->pBaseRef = 0;
    1403             :     OSL_ASSERT(
    1404             :         (nAbsolutePosition >= pInterface->nAllMembers - pInterface->nMembers)
    1405             :         && nAbsolutePosition < pInterface->nAllMembers);
    1406             :     (*ppRet)->nIndex = nAbsolutePosition
    1407         901 :         - (pInterface->nAllMembers - pInterface->nMembers);
    1408         901 :     (*ppRet)->nGetExceptions = nGetExceptions;
    1409             :     (*ppRet)->ppGetExceptions = copyExceptions(
    1410         901 :         nGetExceptions, ppGetExceptionNames);
    1411         901 :     (*ppRet)->nSetExceptions = nSetExceptions;
    1412             :     (*ppRet)->ppSetExceptions = copyExceptions(
    1413         901 :         nSetExceptions, ppSetExceptionNames);
    1414         901 :     if( !reallyWeak( typelib_TypeClass_INTERFACE_ATTRIBUTE ) )
    1415           0 :         pTmp->pWeakRef = (typelib_TypeDescriptionReference *)pTmp;
    1416             : }
    1417             : 
    1418             : //------------------------------------------------------------------------
    1419      176896 : extern "C" CPPU_DLLPUBLIC void SAL_CALL typelib_typedescription_acquire(
    1420             :     typelib_TypeDescription * pTypeDescription )
    1421             :     SAL_THROW_EXTERN_C()
    1422             : {
    1423      176896 :     osl_atomic_increment( &pTypeDescription->nRefCount );
    1424      176896 : }
    1425             : 
    1426             : //------------------------------------------------------------------------
    1427             : 
    1428             : namespace {
    1429             : 
    1430       60083 : void deleteExceptions(
    1431             :     sal_Int32 count, typelib_TypeDescriptionReference ** exceptions)
    1432             : {
    1433      164059 :     for (sal_Int32 i = 0; i < count; ++i) {
    1434      103976 :         typelib_typedescriptionreference_release(exceptions[i]);
    1435             :     }
    1436       60083 :     delete[] exceptions;
    1437       60083 : }
    1438             : 
    1439             : }
    1440             : 
    1441             : // frees anything except typelib_TypeDescription base!
    1442       97301 : static inline void typelib_typedescription_destructExtendedMembers(
    1443             :     typelib_TypeDescription * pTD )
    1444             :     SAL_THROW(())
    1445             : {
    1446             :     OSL_ASSERT( typelib_TypeClass_TYPEDEF != pTD->eTypeClass );
    1447             : 
    1448       97301 :     switch( pTD->eTypeClass )
    1449             :     {
    1450             :     case typelib_TypeClass_ARRAY:
    1451           0 :         if( ((typelib_IndirectTypeDescription*)pTD)->pType )
    1452           0 :             typelib_typedescriptionreference_release( ((typelib_IndirectTypeDescription*)pTD)->pType );
    1453           0 :         delete [] ((typelib_ArrayTypeDescription *)pTD)->pDimensions;
    1454           0 :         break;
    1455             :     case typelib_TypeClass_SEQUENCE:
    1456        2916 :         if( ((typelib_IndirectTypeDescription*)pTD)->pType )
    1457        2905 :             typelib_typedescriptionreference_release( ((typelib_IndirectTypeDescription*)pTD)->pType );
    1458        2916 :         break;
    1459             :     case typelib_TypeClass_UNION:
    1460             :     {
    1461           0 :         typelib_UnionTypeDescription * pUnionTD = (typelib_UnionTypeDescription *)pTD;
    1462           0 :         typelib_typedescriptionreference_release( pUnionTD->pDiscriminantTypeRef );
    1463           0 :         typelib_typedescriptionreference_release( pUnionTD->pDefaultTypeRef );
    1464             : 
    1465             :         sal_Int32 nPos;
    1466           0 :         typelib_TypeDescriptionReference ** ppTypeRefs = pUnionTD->ppTypeRefs;
    1467           0 :         for ( nPos = pUnionTD->nMembers; nPos--; )
    1468             :         {
    1469           0 :             typelib_typedescriptionreference_release( ppTypeRefs[nPos] );
    1470             :         }
    1471             : 
    1472           0 :         rtl_uString ** ppMemberNames = pUnionTD->ppMemberNames;
    1473           0 :         for ( nPos = pUnionTD->nMembers; nPos--; )
    1474             :         {
    1475           0 :             rtl_uString_release( ppMemberNames[nPos] );
    1476             :         }
    1477           0 :         delete [] pUnionTD->ppMemberNames;
    1478           0 :         delete [] pUnionTD->pDiscriminants;
    1479           0 :         delete [] pUnionTD->ppTypeRefs;
    1480             :     }
    1481           0 :     break;
    1482             :     case typelib_TypeClass_STRUCT:
    1483             :         delete[] reinterpret_cast< typelib_StructTypeDescription * >(pTD)->
    1484        1650 :             pParameterizedTypes;
    1485             :     case typelib_TypeClass_EXCEPTION:
    1486             :     {
    1487        7197 :         typelib_CompoundTypeDescription * pCTD = (typelib_CompoundTypeDescription*)pTD;
    1488        7197 :         if( pCTD->pBaseTypeDescription )
    1489        3994 :             typelib_typedescription_release( (typelib_TypeDescription *)pCTD->pBaseTypeDescription );
    1490             :         sal_Int32 i;
    1491       11023 :         for( i = 0; i < pCTD->nMembers; i++ )
    1492             :         {
    1493        3826 :             typelib_typedescriptionreference_release( pCTD->ppTypeRefs[i] );
    1494             :         }
    1495        7197 :         if (pCTD->ppMemberNames)
    1496             :         {
    1497        4311 :             for ( i = 0; i < pCTD->nMembers; i++ )
    1498             :             {
    1499        3312 :                 rtl_uString_release( pCTD->ppMemberNames[i] );
    1500             :             }
    1501         999 :             delete [] pCTD->ppMemberNames;
    1502             :         }
    1503        7197 :         delete [] pCTD->ppTypeRefs;
    1504        7197 :         delete [] pCTD->pMemberOffsets;
    1505             :     }
    1506        7197 :     break;
    1507             :     case typelib_TypeClass_INTERFACE:
    1508             :     {
    1509       23894 :         typelib_InterfaceTypeDescription * pITD = (typelib_InterfaceTypeDescription*)pTD;
    1510      122800 :         {for( sal_Int32 i = 0; i < pITD->nAllMembers; i++ )
    1511             :         {
    1512       98906 :             typelib_typedescriptionreference_release( pITD->ppAllMembers[i] );
    1513             :         }}
    1514       23894 :         delete [] pITD->ppAllMembers;
    1515       23894 :         delete [] pITD->pMapMemberIndexToFunctionIndex;
    1516       23894 :         delete [] pITD->pMapFunctionIndexToMemberIndex;
    1517       37961 :         {for (sal_Int32 i = 0; i < pITD->nBaseTypes; ++i) {
    1518             :             typelib_typedescription_release(
    1519             :                 reinterpret_cast< typelib_TypeDescription * >(
    1520       14067 :                     pITD->ppBaseTypes[i]));
    1521             :         }}
    1522       23894 :         delete[] pITD->ppBaseTypes;
    1523       23894 :         break;
    1524             :     }
    1525             :     case typelib_TypeClass_INTERFACE_METHOD:
    1526             :     {
    1527       58497 :         typelib_InterfaceMethodTypeDescription * pIMTD = (typelib_InterfaceMethodTypeDescription*)pTD;
    1528       58497 :         if( pIMTD->pReturnTypeRef )
    1529       58497 :             typelib_typedescriptionreference_release( pIMTD->pReturnTypeRef );
    1530      101053 :         for( sal_Int32 i = 0; i < pIMTD->nParams; i++ )
    1531             :         {
    1532       42556 :             rtl_uString_release( pIMTD->pParams[ i ].pName );
    1533       42556 :             typelib_typedescriptionreference_release( pIMTD->pParams[ i ].pTypeRef );
    1534             :         }
    1535       58497 :         delete [] pIMTD->pParams;
    1536       58497 :         deleteExceptions(pIMTD->nExceptions, pIMTD->ppExceptions);
    1537       58497 :         rtl_uString_release( pIMTD->aBase.pMemberName );
    1538       58497 :         typelib_typedescription_release(&pIMTD->pInterface->aBase);
    1539       58497 :         if (pIMTD->pBaseRef != 0) {
    1540         118 :             typelib_typedescriptionreference_release(pIMTD->pBaseRef);
    1541             :         }
    1542             :     }
    1543       58497 :     break;
    1544             :     case typelib_TypeClass_INTERFACE_ATTRIBUTE:
    1545             :     {
    1546         793 :         typelib_InterfaceAttributeTypeDescription * pIATD = (typelib_InterfaceAttributeTypeDescription*)pTD;
    1547         793 :         deleteExceptions(pIATD->nGetExceptions, pIATD->ppGetExceptions);
    1548         793 :         deleteExceptions(pIATD->nSetExceptions, pIATD->ppSetExceptions);
    1549         793 :         if( pIATD->pAttributeTypeRef )
    1550         793 :             typelib_typedescriptionreference_release( pIATD->pAttributeTypeRef );
    1551         793 :         if( pIATD->aBase.pMemberName )
    1552         793 :             rtl_uString_release( pIATD->aBase.pMemberName );
    1553         793 :         typelib_typedescription_release(&pIATD->pInterface->aBase);
    1554         793 :         if (pIATD->pBaseRef != 0) {
    1555          32 :             typelib_typedescriptionreference_release(pIATD->pBaseRef);
    1556             :         }
    1557             :     }
    1558         793 :     break;
    1559             :     case typelib_TypeClass_ENUM:
    1560             :     {
    1561        1166 :         typelib_EnumTypeDescription * pEnum = (typelib_EnumTypeDescription *)pTD;
    1562        3266 :         for ( sal_Int32 nPos = pEnum->nEnumValues; nPos--; )
    1563             :         {
    1564         934 :             rtl_uString_release( pEnum->ppEnumNames[nPos] );
    1565             :         }
    1566        1166 :         delete [] pEnum->ppEnumNames;
    1567        1166 :         delete [] pEnum->pEnumValues;
    1568             :     }
    1569        1166 :     break;
    1570             :     default:
    1571        2838 :     break;
    1572             :     }
    1573       97301 : }
    1574             : 
    1575             : //------------------------------------------------------------------------
    1576    13158315 : extern "C" CPPU_DLLPUBLIC void SAL_CALL typelib_typedescription_release(
    1577             :     typelib_TypeDescription * pTD )
    1578             :     SAL_THROW_EXTERN_C()
    1579             : {
    1580    13158315 :     sal_Int32 ref = osl_atomic_decrement( &pTD->nRefCount );
    1581             :     OSL_ASSERT(ref >= 0);
    1582    13158315 :     if (0 == ref)
    1583             :     {
    1584       94441 :         TypeDescriptor_Init_Impl &rInit = Init::get();
    1585       94441 :         if( reallyWeak( pTD->eTypeClass ) )
    1586             :         {
    1587       59290 :             if( pTD->pWeakRef )
    1588             :             {
    1589             :                 {
    1590       26491 :                 MutexGuard aGuard( rInit.getMutex() );
    1591             :                 // remove this description from the weak reference
    1592       26491 :                 pTD->pWeakRef->pType = 0;
    1593             :                 }
    1594       26491 :                 typelib_typedescriptionreference_release( pTD->pWeakRef );
    1595             :             }
    1596             :         }
    1597             :         else
    1598             :         {
    1599             :             // this description is a reference too, so remove it from the hash table
    1600       35151 :             if( rInit.pWeakMap )
    1601             :             {
    1602       35151 :                 MutexGuard aGuard( rInit.getMutex() );
    1603       35151 :                 WeakMap_Impl::iterator aIt = rInit.pWeakMap->find( (sal_Unicode*)pTD->pTypeName->buffer );
    1604       35151 :                 if( aIt != rInit.pWeakMap->end() && (void *)(*aIt).second == (void *)pTD )
    1605             :                 {
    1606             :                     // remove only if it contains the same object
    1607       13094 :                     rInit.pWeakMap->erase( aIt );
    1608       35151 :                 }
    1609             :             }
    1610             :         }
    1611             : 
    1612       94441 :         typelib_typedescription_destructExtendedMembers( pTD );
    1613       94441 :         rtl_uString_release( pTD->pTypeName );
    1614             : 
    1615             : #if OSL_DEBUG_LEVEL > 1
    1616             :         switch( pTD->eTypeClass )
    1617             :         {
    1618             :         case typelib_TypeClass_ARRAY:
    1619             :             osl_atomic_decrement( &rInit.nArrayTypeDescriptionCount );
    1620             :             break;
    1621             :         case typelib_TypeClass_SEQUENCE:
    1622             :             osl_atomic_decrement( &rInit.nIndirectTypeDescriptionCount );
    1623             :             break;
    1624             :         case typelib_TypeClass_UNION:
    1625             :             osl_atomic_decrement( &rInit.nUnionTypeDescriptionCount );
    1626             :             break;
    1627             :         case typelib_TypeClass_STRUCT:
    1628             :         case typelib_TypeClass_EXCEPTION:
    1629             :             osl_atomic_decrement( &rInit.nCompoundTypeDescriptionCount );
    1630             :             break;
    1631             :         case typelib_TypeClass_INTERFACE:
    1632             :             osl_atomic_decrement( &rInit.nInterfaceTypeDescriptionCount );
    1633             :             break;
    1634             :         case typelib_TypeClass_INTERFACE_METHOD:
    1635             :             osl_atomic_decrement( &rInit.nInterfaceMethodTypeDescriptionCount );
    1636             :             break;
    1637             :         case typelib_TypeClass_INTERFACE_ATTRIBUTE:
    1638             :             osl_atomic_decrement( &rInit.nInterfaceAttributeTypeDescriptionCount );
    1639             :             break;
    1640             :         case typelib_TypeClass_ENUM:
    1641             :             osl_atomic_decrement( &rInit.nEnumTypeDescriptionCount );
    1642             :             break;
    1643             :         default:
    1644             :             osl_atomic_decrement( &rInit.nTypeDescriptionCount );
    1645             :         }
    1646             : #endif
    1647             : 
    1648       94441 :         delete pTD;
    1649             :     }
    1650    13158315 : }
    1651             : 
    1652             : //------------------------------------------------------------------------
    1653      107130 : extern "C" CPPU_DLLPUBLIC void SAL_CALL typelib_typedescription_register(
    1654             :     typelib_TypeDescription ** ppNewDescription )
    1655             :     SAL_THROW_EXTERN_C()
    1656             : {
    1657             :     // connect the description with the weak reference
    1658      107130 :     TypeDescriptor_Init_Impl &rInit = Init::get();
    1659      107130 :     ClearableMutexGuard aGuard( rInit.getMutex() );
    1660             : 
    1661      107130 :     typelib_TypeDescriptionReference * pTDR = 0;
    1662      107130 :     typelib_typedescriptionreference_getByName( &pTDR, (*ppNewDescription)->pTypeName );
    1663             : 
    1664             :     OSL_ASSERT( (*ppNewDescription)->pWeakRef || reallyWeak( (*ppNewDescription)->eTypeClass ) );
    1665      107130 :     if( pTDR )
    1666             :     {
    1667             :         OSL_ASSERT( (*ppNewDescription)->eTypeClass == pTDR->eTypeClass );
    1668       86666 :         if( pTDR->pType )
    1669             :         {
    1670       54856 :             if (reallyWeak( pTDR->eTypeClass ))
    1671             :             {
    1672             :                 // pRef->pType->pWeakRef == 0 means that the description is empty
    1673       32799 :                 if (pTDR->pType->pWeakRef)
    1674             :                 {
    1675       32799 :                     if (osl_atomic_increment( &pTDR->pType->nRefCount ) > 1)
    1676             :                     {
    1677             :                         // The refence is incremented. The object cannot be destroyed.
    1678             :                         // Release the guard at the earliest point.
    1679       32799 :                         aGuard.clear();
    1680       32799 :                         ::typelib_typedescription_release( *ppNewDescription );
    1681       32799 :                         *ppNewDescription = pTDR->pType;
    1682       32799 :                         ::typelib_typedescriptionreference_release( pTDR );
    1683             :                         return;
    1684             :                     }
    1685             :                     else
    1686             :                     {
    1687             :                         // destruction of this type in progress (another thread!)
    1688           0 :                         osl_atomic_decrement( &pTDR->pType->nRefCount );
    1689             :                     }
    1690             :                 }
    1691             :                 // take new descr
    1692           0 :                 pTDR->pType = *ppNewDescription;
    1693             :                 OSL_ASSERT( ! (*ppNewDescription)->pWeakRef );
    1694           0 :                 (*ppNewDescription)->pWeakRef = pTDR;
    1695             :                 return;
    1696             :             }
    1697             :             // !reallyWeak
    1698             : 
    1699       76249 :             if (((void *)pTDR != (void *)*ppNewDescription) && // if different
    1700       22057 :                 (!pTDR->pType->pWeakRef || // uninit: ref data only set
    1701             :                  // new one is complete:
    1702       17994 :                  (!pTDR->pType->bComplete && (*ppNewDescription)->bComplete) ||
    1703             :                  // new one may be partly initialized interface (except of tables):
    1704             :                  (typelib_TypeClass_INTERFACE == pTDR->pType->eTypeClass &&
    1705       14141 :                   !((typelib_InterfaceTypeDescription *)pTDR->pType)->ppAllMembers &&
    1706             :                   (*(typelib_InterfaceTypeDescription **)ppNewDescription)->ppAllMembers)))
    1707             :             {
    1708             :                 // uninitialized or incomplete
    1709             : 
    1710        6923 :                 if (pTDR->pType->pWeakRef) // if init
    1711             :                 {
    1712        2860 :                     typelib_typedescription_destructExtendedMembers( pTDR->pType );
    1713             :                 }
    1714             : 
    1715             :                 // pTDR->pType->pWeakRef == 0 means that the description is empty
    1716             :                 // description is not weak and the not the same
    1717        6923 :                 sal_Int32 nSize = getDescriptionSize( (*ppNewDescription)->eTypeClass );
    1718             : 
    1719             :                 // copy all specific data for the descriptions
    1720             :                 memcpy(
    1721        6923 :                     pTDR->pType +1,
    1722             :                     *ppNewDescription +1,
    1723       13846 :                     nSize - sizeof(typelib_TypeDescription) );
    1724             : 
    1725        6923 :                 pTDR->pType->bComplete = (*ppNewDescription)->bComplete;
    1726        6923 :                 pTDR->pType->nSize = (*ppNewDescription)->nSize;
    1727        6923 :                 pTDR->pType->nAlignment = (*ppNewDescription)->nAlignment;
    1728             : 
    1729             :                 memset(
    1730        6923 :                     *ppNewDescription +1,
    1731             :                     0,
    1732       13846 :                     nSize - sizeof( typelib_TypeDescription ) );
    1733             : 
    1734        6923 :                 if( pTDR->pType->bOnDemand && !(*ppNewDescription)->bOnDemand )
    1735             :                 {
    1736             :                     // switch from OnDemand to !OnDemand, so the description must be acquired
    1737        1118 :                     typelib_typedescription_acquire( pTDR->pType );
    1738             :                 }
    1739        5805 :                 else if( !pTDR->pType->bOnDemand && (*ppNewDescription)->bOnDemand )
    1740             :                 {
    1741             :                     // switch from !OnDemand to OnDemand, so the description must be relesed
    1742           0 :                     typelib_typedescription_release( pTDR->pType );
    1743             :                 }
    1744             : 
    1745        6923 :                 pTDR->pType->bOnDemand = (*ppNewDescription)->bOnDemand;
    1746             :                 // initialized
    1747        6923 :                 pTDR->pType->pWeakRef = pTDR;
    1748             :             }
    1749             : 
    1750       22057 :             typelib_typedescription_release( *ppNewDescription );
    1751             :             // pTDR was acquired by getByName(), so it must not be acquired again
    1752       22057 :             *ppNewDescription = pTDR->pType;
    1753             :             return;
    1754             :         }
    1755             :     }
    1756       20464 :     else if( reallyWeak( (*ppNewDescription)->eTypeClass) )
    1757             :     {
    1758             :         typelib_typedescriptionreference_new(
    1759           0 :             &pTDR, (*ppNewDescription)->eTypeClass, (*ppNewDescription)->pTypeName );
    1760             :     }
    1761             :     else
    1762             :     {
    1763       20464 :         pTDR = (typelib_TypeDescriptionReference *)*ppNewDescription;
    1764       20464 :         if( !rInit.pWeakMap )
    1765           0 :             rInit.pWeakMap = new WeakMap_Impl;
    1766             : 
    1767             :         // description is the weak itself, so register it
    1768       20464 :         (*rInit.pWeakMap)[pTDR->pTypeName->buffer] = pTDR;
    1769             :         OSL_ASSERT( (void *)*ppNewDescription == (void *)pTDR );
    1770             :     }
    1771             : 
    1772             :     // By default this reference is not really weak. The reference hold the description
    1773             :     // and the description hold the reference.
    1774       52274 :     if( !(*ppNewDescription)->bOnDemand )
    1775             :     {
    1776             :         // nor OnDemand so the description must be acquired if registered
    1777       47154 :         typelib_typedescription_acquire( *ppNewDescription );
    1778             :     }
    1779             : 
    1780       52274 :     pTDR->pType = *ppNewDescription;
    1781       52274 :     (*ppNewDescription)->pWeakRef = pTDR;
    1782             :     OSL_ASSERT( rtl_ustr_compare( pTDR->pTypeName->buffer, (*ppNewDescription)->pTypeName->buffer ) == 0 );
    1783      107130 :     OSL_ASSERT( pTDR->eTypeClass == (*ppNewDescription)->eTypeClass );
    1784             : }
    1785             : 
    1786             : //------------------------------------------------------------------------
    1787        3414 : static inline sal_Bool type_equals(
    1788             :     typelib_TypeDescriptionReference * p1, typelib_TypeDescriptionReference * p2 )
    1789             :     SAL_THROW(())
    1790             : {
    1791             :     return (p1 == p2 ||
    1792             :             (p1->eTypeClass == p2->eTypeClass &&
    1793             :              p1->pTypeName->length == p2->pTypeName->length &&
    1794        3414 :              rtl_ustr_compare( p1->pTypeName->buffer, p2->pTypeName->buffer ) == 0));
    1795             : }
    1796           8 : extern "C" CPPU_DLLPUBLIC sal_Bool SAL_CALL typelib_typedescription_equals(
    1797             :     const typelib_TypeDescription * p1, const typelib_TypeDescription * p2 )
    1798             :     SAL_THROW_EXTERN_C()
    1799             : {
    1800             :     return type_equals(
    1801           8 :         (typelib_TypeDescriptionReference *)p1, (typelib_TypeDescriptionReference *)p2 );
    1802             : }
    1803             : 
    1804             : //------------------------------------------------------------------------
    1805       49711 : extern "C" sal_Int32 SAL_CALL typelib_typedescription_getAlignedUnoSize(
    1806             :     const typelib_TypeDescription * pTypeDescription,
    1807             :     sal_Int32 nOffset, sal_Int32 & rMaxIntegralTypeSize )
    1808             :     SAL_THROW_EXTERN_C()
    1809             : {
    1810             :     sal_Int32 nSize;
    1811       49711 :     if( pTypeDescription->nSize )
    1812             :     {
    1813             :         // size and alignment are set
    1814        7454 :         rMaxIntegralTypeSize = pTypeDescription->nAlignment;
    1815        7454 :         nSize = pTypeDescription->nSize;
    1816             :     }
    1817             :     else
    1818             :     {
    1819       42257 :         nSize = 0;
    1820       42257 :         rMaxIntegralTypeSize = 1;
    1821             : 
    1822             :         OSL_ASSERT( typelib_TypeClass_TYPEDEF != pTypeDescription->eTypeClass );
    1823             : 
    1824       42257 :         switch( pTypeDescription->eTypeClass )
    1825             :         {
    1826             :             case typelib_TypeClass_INTERFACE:
    1827             :                 // FEATURE_INTERFACE
    1828       25543 :                 nSize = rMaxIntegralTypeSize = (sal_Int32)(sizeof( void * ));
    1829       25543 :                 break;
    1830             :             case typelib_TypeClass_UNION:
    1831             :                 {
    1832           0 :                 nSize = rMaxIntegralTypeSize = (sal_Int32)(sizeof(sal_Int64));
    1833           0 :                 for ( sal_Int32 nPos = ((typelib_UnionTypeDescription *)pTypeDescription)->nMembers; nPos--; )
    1834             :                 {
    1835           0 :                     typelib_TypeDescription * pTD = 0;
    1836           0 :                     TYPELIB_DANGER_GET( &pTD, ((typelib_UnionTypeDescription *)pTypeDescription)->ppTypeRefs[nPos] );
    1837             :                     sal_Int32 nMaxIntegralTypeSize;
    1838           0 :                     sal_Int32 nMemberSize = typelib_typedescription_getAlignedUnoSize( pTD, (sal_Int32)(sizeof(sal_Int64)), nMaxIntegralTypeSize );
    1839           0 :                     TYPELIB_DANGER_RELEASE( pTD );
    1840           0 :                     if (nSize < nMemberSize)
    1841           0 :                         nSize = nMemberSize;
    1842           0 :                     if (rMaxIntegralTypeSize < nMaxIntegralTypeSize)
    1843           0 :                         rMaxIntegralTypeSize = nMaxIntegralTypeSize;
    1844             :                 }
    1845           0 :                 ((typelib_UnionTypeDescription *)pTypeDescription)->nValueOffset = rMaxIntegralTypeSize;
    1846             :                 }
    1847           0 :                 break;
    1848             :             case typelib_TypeClass_ENUM:
    1849        1212 :                 nSize = rMaxIntegralTypeSize = (sal_Int32)(sizeof( typelib_TypeClass ));
    1850        1212 :                 break;
    1851             :             case typelib_TypeClass_STRUCT:
    1852             :             case typelib_TypeClass_EXCEPTION:
    1853             :                 // FEATURE_EMPTYCLASS
    1854             :                 {
    1855        8738 :                 typelib_CompoundTypeDescription * pTmp = (typelib_CompoundTypeDescription *)pTypeDescription;
    1856        8738 :                 sal_Int32 nStructSize = 0;
    1857        8738 :                 if( pTmp->pBaseTypeDescription )
    1858             :                 {
    1859             :                     // inherit structs extends the base struct.
    1860        6933 :                     nStructSize = pTmp->pBaseTypeDescription->aBase.nSize;
    1861        6933 :                     rMaxIntegralTypeSize = pTmp->pBaseTypeDescription->aBase.nAlignment;
    1862             :                  }
    1863       16992 :                 for( sal_Int32 i = 0; i < pTmp->nMembers; i++ )
    1864             :                 {
    1865        8254 :                     typelib_TypeDescription * pMemberType = 0;
    1866        8254 :                     typelib_TypeDescriptionReference * pMemberRef = pTmp->ppTypeRefs[i];
    1867             : 
    1868             :                     sal_Int32 nMaxIntegral;
    1869        8254 :                     if (pMemberRef->eTypeClass == typelib_TypeClass_INTERFACE
    1870             :                         || pMemberRef->eTypeClass == typelib_TypeClass_SEQUENCE)
    1871             :                     {
    1872         800 :                         nMaxIntegral = (sal_Int32)(sizeof(void *));
    1873         800 :                         nStructSize = newAlignedSize( nStructSize, nMaxIntegral, nMaxIntegral );
    1874             :                     }
    1875             :                     else
    1876             :                     {
    1877        7454 :                         TYPELIB_DANGER_GET( &pMemberType, pMemberRef );
    1878             :                         nStructSize = typelib_typedescription_getAlignedUnoSize(
    1879        7454 :                             pMemberType, nStructSize, nMaxIntegral );
    1880        7454 :                         TYPELIB_DANGER_RELEASE( pMemberType );
    1881             :                     }
    1882        8254 :                     if( nMaxIntegral > rMaxIntegralTypeSize )
    1883        1829 :                         rMaxIntegralTypeSize = nMaxIntegral;
    1884             :                 }
    1885             : #ifdef __m68k__
    1886             :                 // Anything that is at least 16 bits wide is aligned on a 16-bit
    1887             :                 // boundary on the m68k default abi
    1888             :                 sal_Int32 nMaxAlign = (rMaxIntegralTypeSize > 2) ? 2 : rMaxIntegralTypeSize;
    1889             :                 nStructSize = (nStructSize + nMaxAlign -1) / nMaxAlign * nMaxAlign;
    1890             : #else
    1891             :                 // Example: A { double; int; } structure has a size of 16 instead of 10. The
    1892             :                 // compiler must follow this rule if it is possible to access members in arrays through:
    1893             :                 // (Element *)((char *)pArray + sizeof( Element ) * ElementPos)
    1894             :                 nStructSize = (nStructSize + rMaxIntegralTypeSize -1)
    1895        8738 :                                 / rMaxIntegralTypeSize * rMaxIntegralTypeSize;
    1896             : #endif
    1897        8738 :                 nSize += nStructSize;
    1898             :                 }
    1899        8738 :                 break;
    1900             :             case typelib_TypeClass_ARRAY:
    1901             :                 {
    1902           0 :                 typelib_TypeDescription * pTD = 0;
    1903           0 :                 TYPELIB_DANGER_GET( &pTD, ((typelib_IndirectTypeDescription *)pTypeDescription)->pType );
    1904           0 :                 rMaxIntegralTypeSize = pTD->nSize;
    1905           0 :                 TYPELIB_DANGER_RELEASE( pTD );
    1906           0 :                 nSize = ((typelib_ArrayTypeDescription *)pTypeDescription)->nTotalElements * rMaxIntegralTypeSize;
    1907             :                 }
    1908           0 :                 break;
    1909             :             case typelib_TypeClass_SEQUENCE:
    1910        3052 :                 nSize = rMaxIntegralTypeSize = (sal_Int32)(sizeof( void * ));
    1911        3052 :                 break;
    1912             :             case typelib_TypeClass_ANY:
    1913             :                 // FEATURE_ANY
    1914         264 :                 nSize = (sal_Int32)(sizeof( uno_Any ));
    1915         264 :                 rMaxIntegralTypeSize = (sal_Int32)(sizeof( void * ));
    1916         264 :                 break;
    1917             :             case typelib_TypeClass_TYPE:
    1918         264 :                 nSize = rMaxIntegralTypeSize = (sal_Int32)(sizeof( typelib_TypeDescriptionReference * ));
    1919         264 :                 break;
    1920             :             case typelib_TypeClass_BOOLEAN:
    1921         264 :                 nSize = rMaxIntegralTypeSize = (sal_Int32)(sizeof( sal_Bool ));
    1922         264 :                 break;
    1923             :             case typelib_TypeClass_CHAR:
    1924         264 :                 nSize = rMaxIntegralTypeSize = (sal_Int32)(sizeof( sal_Unicode ));
    1925         264 :                 break;
    1926             :             case typelib_TypeClass_STRING:
    1927             :                 // FEATURE_STRING
    1928         264 :                 nSize = rMaxIntegralTypeSize = (sal_Int32)(sizeof( rtl_uString * ));
    1929         264 :                 break;
    1930             :             case typelib_TypeClass_FLOAT:
    1931         264 :                 nSize = rMaxIntegralTypeSize = (sal_Int32)(sizeof( float ));
    1932         264 :                 break;
    1933             :             case typelib_TypeClass_DOUBLE:
    1934             : #ifdef AIX
    1935             :                 //See previous AIX ifdef comment for an explanation
    1936             :                 nSize = (sal_Int32)(sizeof(double));
    1937             :                 rMaxIntegralTypeSize = (sal_Int32)(sizeof(void*));
    1938             : #else
    1939         264 :                 nSize = rMaxIntegralTypeSize = (sal_Int32)(sizeof( double ));
    1940             : #endif
    1941         264 :                 break;
    1942             :             case typelib_TypeClass_BYTE:
    1943         264 :                 nSize = rMaxIntegralTypeSize = (sal_Int32)(sizeof( sal_Int8 ));
    1944         264 :                 break;
    1945             :             case typelib_TypeClass_SHORT:
    1946             :             case typelib_TypeClass_UNSIGNED_SHORT:
    1947         528 :                 nSize = rMaxIntegralTypeSize = (sal_Int32)(sizeof( sal_Int16 ));
    1948         528 :                 break;
    1949             :             case typelib_TypeClass_LONG:
    1950             :             case typelib_TypeClass_UNSIGNED_LONG:
    1951         544 :                 nSize = rMaxIntegralTypeSize = (sal_Int32)(sizeof( sal_Int32 ));
    1952         544 :                 break;
    1953             :             case typelib_TypeClass_HYPER:
    1954             :             case typelib_TypeClass_UNSIGNED_HYPER:
    1955         528 :                 nSize = rMaxIntegralTypeSize = (sal_Int32)(sizeof( sal_Int64 ));
    1956         528 :                 break;
    1957             :             case typelib_TypeClass_UNKNOWN:
    1958             :             case typelib_TypeClass_SERVICE:
    1959             :             case typelib_TypeClass_MODULE:
    1960             :             default:
    1961             :                 OSL_FAIL( "not convertable type" );
    1962             :         };
    1963             :     }
    1964             : 
    1965       49711 :     return newAlignedSize( nOffset, nSize, rMaxIntegralTypeSize );
    1966             : }
    1967             : 
    1968             : //------------------------------------------------------------------------
    1969             : 
    1970             : namespace {
    1971             : 
    1972        3362 : typelib_TypeDescriptionReference ** copyExceptions(
    1973             :     sal_Int32 count, typelib_TypeDescriptionReference ** source)
    1974             : {
    1975             :     typelib_TypeDescriptionReference ** p
    1976        3362 :         = new typelib_TypeDescriptionReference *[count];
    1977        4831 :     for (sal_Int32 i = 0; i < count; ++i) {
    1978        1469 :         typelib_typedescriptionreference_acquire(p[i] = source[i]);
    1979             :     }
    1980        3362 :     return p;
    1981             : }
    1982             : 
    1983        3255 : bool createDerivedInterfaceMemberDescription(
    1984             :     typelib_TypeDescription ** result, rtl::OUString const & name,
    1985             :     typelib_TypeDescriptionReference * baseRef,
    1986             :     typelib_TypeDescription const * base, typelib_TypeDescription * interface,
    1987             :     sal_Int32 index, sal_Int32 position)
    1988             : {
    1989        3255 :     if (baseRef != 0 && base != 0 && interface != 0) {
    1990        3255 :         switch (base->eTypeClass) {
    1991             :         case typelib_TypeClass_INTERFACE_METHOD:
    1992             :             {
    1993             :                 typelib_typedescription_newEmpty(
    1994        3148 :                     result, typelib_TypeClass_INTERFACE_METHOD, name.pData);
    1995             :                 typelib_InterfaceMethodTypeDescription const * baseMethod
    1996             :                     = reinterpret_cast<
    1997        3148 :                     typelib_InterfaceMethodTypeDescription const * >(base);
    1998             :                 typelib_InterfaceMethodTypeDescription * newMethod
    1999             :                     = reinterpret_cast<
    2000        3148 :                     typelib_InterfaceMethodTypeDescription * >(*result);
    2001        3148 :                 newMethod->aBase.nPosition = position;
    2002             :                 rtl_uString_acquire(
    2003             :                     newMethod->aBase.pMemberName
    2004        3148 :                     = baseMethod->aBase.pMemberName);
    2005             :                 typelib_typedescriptionreference_acquire(
    2006        3148 :                     newMethod->pReturnTypeRef = baseMethod->pReturnTypeRef);
    2007        3148 :                 newMethod->nParams = baseMethod->nParams;
    2008             :                 newMethod->pParams = new typelib_MethodParameter[
    2009        3148 :                     newMethod->nParams];
    2010        4633 :                 for (sal_Int32 i = 0; i < newMethod->nParams; ++i) {
    2011             :                     rtl_uString_acquire(
    2012        1485 :                         newMethod->pParams[i].pName
    2013        1485 :                         = baseMethod->pParams[i].pName);
    2014             :                     typelib_typedescriptionreference_acquire(
    2015        1485 :                         newMethod->pParams[i].pTypeRef
    2016        1485 :                         = baseMethod->pParams[i].pTypeRef);
    2017        1485 :                     newMethod->pParams[i].bIn = baseMethod->pParams[i].bIn;
    2018        1485 :                     newMethod->pParams[i].bOut = baseMethod->pParams[i].bOut;
    2019             :                 }
    2020        3148 :                 newMethod->nExceptions = baseMethod->nExceptions;
    2021             :                 newMethod->ppExceptions = copyExceptions(
    2022        3148 :                     baseMethod->nExceptions, baseMethod->ppExceptions);
    2023        3148 :                 newMethod->bOneWay = baseMethod->bOneWay;
    2024             :                 newMethod->pInterface
    2025             :                     = reinterpret_cast< typelib_InterfaceTypeDescription * >(
    2026        3148 :                         interface);
    2027        3148 :                 newMethod->pBaseRef = baseRef;
    2028        3148 :                 newMethod->nIndex = index;
    2029        3148 :                 return true;
    2030             :             }
    2031             : 
    2032             :         case typelib_TypeClass_INTERFACE_ATTRIBUTE:
    2033             :             {
    2034             :                 typelib_typedescription_newEmpty(
    2035         107 :                     result, typelib_TypeClass_INTERFACE_ATTRIBUTE, name.pData);
    2036             :                 typelib_InterfaceAttributeTypeDescription const * baseAttribute
    2037             :                     = reinterpret_cast<
    2038         107 :                     typelib_InterfaceAttributeTypeDescription const * >(base);
    2039             :                 typelib_InterfaceAttributeTypeDescription * newAttribute
    2040             :                     = reinterpret_cast<
    2041         107 :                     typelib_InterfaceAttributeTypeDescription * >(*result);
    2042         107 :                 newAttribute->aBase.nPosition = position;
    2043             :                 rtl_uString_acquire(
    2044             :                     newAttribute->aBase.pMemberName
    2045         107 :                     = baseAttribute->aBase.pMemberName);
    2046         107 :                 newAttribute->bReadOnly = baseAttribute->bReadOnly;
    2047             :                 typelib_typedescriptionreference_acquire(
    2048             :                     newAttribute->pAttributeTypeRef
    2049         107 :                     = baseAttribute->pAttributeTypeRef);
    2050             :                 newAttribute->pInterface
    2051             :                     = reinterpret_cast< typelib_InterfaceTypeDescription * >(
    2052         107 :                         interface);
    2053         107 :                 newAttribute->pBaseRef = baseRef;
    2054         107 :                 newAttribute->nIndex = index;
    2055         107 :                 newAttribute->nGetExceptions = baseAttribute->nGetExceptions;
    2056             :                 newAttribute->ppGetExceptions = copyExceptions(
    2057             :                     baseAttribute->nGetExceptions,
    2058         107 :                     baseAttribute->ppGetExceptions);
    2059         107 :                 newAttribute->nSetExceptions = baseAttribute->nSetExceptions;
    2060             :                 newAttribute->ppSetExceptions = copyExceptions(
    2061             :                     baseAttribute->nSetExceptions,
    2062         107 :                     baseAttribute->ppSetExceptions);
    2063         107 :                 return true;
    2064             :             }
    2065             : 
    2066             :         default:
    2067           0 :             break;
    2068             :         }
    2069             :     }
    2070           0 :     return false;
    2071             : }
    2072             : 
    2073             : }
    2074             : 
    2075       76281 : extern "C" CPPU_DLLPUBLIC void SAL_CALL typelib_typedescription_getByName(
    2076             :     typelib_TypeDescription ** ppRet, rtl_uString * pName )
    2077             :     SAL_THROW_EXTERN_C()
    2078             : {
    2079       76281 :     if( *ppRet )
    2080             :     {
    2081           0 :         typelib_typedescription_release( (*ppRet) );
    2082           0 :         *ppRet = 0;
    2083             :     }
    2084             : 
    2085             :     static sal_Bool bInited = sal_False;
    2086       76281 :     TypeDescriptor_Init_Impl &rInit = Init::get();
    2087             : 
    2088       76281 :     if( !bInited )
    2089             :     {
    2090             :         // guard against multi thread access
    2091         264 :         MutexGuard aGuard( rInit.getMutex() );
    2092         264 :         if( !bInited )
    2093             :         {
    2094             :             // avoid recursion during the next ...new calls
    2095         264 :             bInited = sal_True;
    2096             : 
    2097         264 :             rtl_uString * pTypeName = 0;
    2098         264 :             typelib_TypeDescription * pType = 0;
    2099         264 :             rtl_uString_newFromAscii( &pTypeName, "type" );
    2100         264 :             typelib_typedescription_new( &pType, typelib_TypeClass_TYPE, pTypeName, 0, 0, 0 );
    2101         264 :             typelib_typedescription_register( &pType );
    2102         264 :             rtl_uString_newFromAscii( &pTypeName, "void" );
    2103         264 :             typelib_typedescription_new( &pType, typelib_TypeClass_VOID, pTypeName, 0, 0, 0 );
    2104         264 :             typelib_typedescription_register( &pType );
    2105         264 :             rtl_uString_newFromAscii( &pTypeName, "boolean" );
    2106         264 :             typelib_typedescription_new( &pType, typelib_TypeClass_BOOLEAN, pTypeName, 0, 0, 0 );
    2107         264 :             typelib_typedescription_register( &pType );
    2108         264 :             rtl_uString_newFromAscii( &pTypeName, "char" );
    2109         264 :             typelib_typedescription_new( &pType, typelib_TypeClass_CHAR, pTypeName, 0, 0, 0 );
    2110         264 :             typelib_typedescription_register( &pType );
    2111         264 :             rtl_uString_newFromAscii( &pTypeName, "byte" );
    2112         264 :             typelib_typedescription_new( &pType, typelib_TypeClass_BYTE, pTypeName, 0, 0, 0 );
    2113         264 :             typelib_typedescription_register( &pType );
    2114         264 :             rtl_uString_newFromAscii( &pTypeName, "string" );
    2115         264 :             typelib_typedescription_new( &pType, typelib_TypeClass_STRING, pTypeName, 0, 0, 0 );
    2116         264 :             typelib_typedescription_register( &pType );
    2117         264 :             rtl_uString_newFromAscii( &pTypeName, "short" );
    2118         264 :             typelib_typedescription_new( &pType, typelib_TypeClass_SHORT, pTypeName, 0, 0, 0 );
    2119         264 :             typelib_typedescription_register( &pType );
    2120         264 :             rtl_uString_newFromAscii( &pTypeName, "unsigned short" );
    2121         264 :             typelib_typedescription_new( &pType, typelib_TypeClass_UNSIGNED_SHORT, pTypeName, 0, 0, 0 );
    2122         264 :             typelib_typedescription_register( &pType );
    2123         264 :             rtl_uString_newFromAscii( &pTypeName, "long" );
    2124         264 :             typelib_typedescription_new( &pType, typelib_TypeClass_LONG, pTypeName, 0, 0, 0 );
    2125         264 :             typelib_typedescription_register( &pType );
    2126         264 :             rtl_uString_newFromAscii( &pTypeName, "unsigned long" );
    2127         264 :             typelib_typedescription_new( &pType, typelib_TypeClass_UNSIGNED_LONG, pTypeName, 0, 0, 0 );
    2128         264 :             typelib_typedescription_register( &pType );
    2129         264 :             rtl_uString_newFromAscii( &pTypeName, "hyper" );
    2130         264 :             typelib_typedescription_new( &pType, typelib_TypeClass_HYPER, pTypeName, 0, 0, 0 );
    2131         264 :             typelib_typedescription_register( &pType );
    2132         264 :             rtl_uString_newFromAscii( &pTypeName, "unsigned hyper" );
    2133         264 :             typelib_typedescription_new( &pType, typelib_TypeClass_UNSIGNED_HYPER, pTypeName, 0, 0, 0 );
    2134         264 :             typelib_typedescription_register( &pType );
    2135         264 :             rtl_uString_newFromAscii( &pTypeName, "float" );
    2136         264 :             typelib_typedescription_new( &pType, typelib_TypeClass_FLOAT, pTypeName, 0, 0, 0 );
    2137         264 :             typelib_typedescription_register( &pType );
    2138         264 :             rtl_uString_newFromAscii( &pTypeName, "double" );
    2139         264 :             typelib_typedescription_new( &pType, typelib_TypeClass_DOUBLE, pTypeName, 0, 0, 0 );
    2140         264 :             typelib_typedescription_register( &pType );
    2141         264 :             rtl_uString_newFromAscii( &pTypeName, "any" );
    2142         264 :             typelib_typedescription_new( &pType, typelib_TypeClass_ANY, pTypeName, 0, 0, 0 );
    2143         264 :             typelib_typedescription_register( &pType );
    2144         264 :             typelib_typedescription_release( pType );
    2145         264 :             rtl_uString_release( pTypeName );
    2146         264 :         }
    2147             :     }
    2148             : 
    2149       76281 :     typelib_TypeDescriptionReference * pTDR = 0;
    2150       76281 :     typelib_typedescriptionreference_getByName( &pTDR, pName );
    2151       76281 :     if( pTDR )
    2152             :     {
    2153             :         {
    2154             :         // guard against multi thread access
    2155       76267 :         MutexGuard aGuard( rInit.getMutex() );
    2156             :         // pTDR->pType->pWeakRef == 0 means that the description is empty
    2157       76267 :         if( pTDR->pType && pTDR->pType->pWeakRef )
    2158             :         {
    2159       68217 :             typelib_typedescription_acquire( pTDR->pType );
    2160       68217 :             *ppRet = pTDR->pType;
    2161       76267 :         }
    2162             :         }
    2163       76267 :         typelib_typedescriptionreference_release( pTDR );
    2164             :     }
    2165             : 
    2166       76281 :     if (0 == *ppRet)
    2167             :     {
    2168             :         // check for sequence
    2169        8064 :         OUString const & name = *reinterpret_cast< OUString const * >( &pName );
    2170        8064 :         if (2 < name.getLength() && '[' == name[ 0 ])
    2171             :         {
    2172          11 :             OUString element_name( name.copy( 2 ) );
    2173          11 :             typelib_TypeDescription * element_td = 0;
    2174          11 :             typelib_typedescription_getByName( &element_td, element_name.pData );
    2175          11 :             if (0 != element_td)
    2176             :             {
    2177             :                 typelib_typedescription_new(
    2178          11 :                     ppRet, typelib_TypeClass_SEQUENCE, pName, element_td->pWeakRef, 0, 0 );
    2179             :                 // register?
    2180          11 :                 typelib_typedescription_release( element_td );
    2181          11 :             }
    2182             :         }
    2183        8064 :         if (0 == *ppRet)
    2184             :         {
    2185             :             // Check for derived interface member type:
    2186             :             sal_Int32 i1 = name.lastIndexOf(
    2187        8053 :                 rtl::OUString(RTL_CONSTASCII_USTRINGPARAM(":@")));
    2188        8053 :             if (i1 >= 0) {
    2189        3255 :                 sal_Int32 i2 = i1 + RTL_CONSTASCII_LENGTH(":@");
    2190        3255 :                 sal_Int32 i3 = name.indexOf(',', i2);
    2191        3255 :                 if (i3 >= 0) {
    2192        3255 :                     sal_Int32 i4 = name.indexOf(':', i3);
    2193        3255 :                     if (i4 >= 0) {
    2194        3255 :                         typelib_TypeDescriptionReference * pBaseRef = 0;
    2195        3255 :                         typelib_TypeDescription * pBase = 0;
    2196        3255 :                         typelib_TypeDescription * pInterface = 0;
    2197             :                         typelib_typedescriptionreference_getByName(
    2198        3255 :                             &pBaseRef, name.copy(0, i1).pData);
    2199        3255 :                         if (pBaseRef != 0) {
    2200             :                             typelib_typedescriptionreference_getDescription(
    2201        3255 :                                 &pBase, pBaseRef);
    2202             :                         }
    2203             :                         typelib_typedescription_getByName(
    2204        3255 :                             &pInterface, name.copy(i4 + 1).pData);
    2205        6510 :                         if (!createDerivedInterfaceMemberDescription(
    2206             :                                 ppRet, name, pBaseRef, pBase, pInterface,
    2207             :                                 name.copy(i2, i3 - i2).toInt32(),
    2208        6510 :                                 name.copy(i3 + 1, i4 - i3 - 1).toInt32()))
    2209             :                         {
    2210           0 :                             if (pInterface != 0) {
    2211           0 :                                 typelib_typedescription_release(pInterface);
    2212             :                             }
    2213           0 :                             if (pBase != 0) {
    2214           0 :                                 typelib_typedescription_release(pBase);
    2215             :                             }
    2216           0 :                             if (pBaseRef != 0) {
    2217             :                                 typelib_typedescriptionreference_release(
    2218           0 :                                     pBaseRef);
    2219             :                             }
    2220             :                         }
    2221             :                     }
    2222             :                 }
    2223             :             }
    2224             :         }
    2225        8064 :         if (0 == *ppRet)
    2226             :         {
    2227             :             // on demand access
    2228        4798 :             rInit.callChain( ppRet, pName );
    2229             :         }
    2230             : 
    2231        8064 :         if( *ppRet )
    2232             :         {
    2233             :             // typedescription found
    2234        8064 :             if (typelib_TypeClass_TYPEDEF == (*ppRet)->eTypeClass)
    2235             :             {
    2236           0 :                 typelib_TypeDescription * pTD = 0;
    2237             :                 typelib_typedescriptionreference_getDescription(
    2238           0 :                     &pTD, ((typelib_IndirectTypeDescription *)*ppRet)->pType );
    2239           0 :                 typelib_typedescription_release( *ppRet );
    2240           0 :                 *ppRet = pTD;
    2241             :             }
    2242             :             else
    2243             :             {
    2244             :                 // set to on demand
    2245        8064 :                 (*ppRet)->bOnDemand = sal_True;
    2246             :                 // The type description is hold by the reference until
    2247             :                 // on demand is activated.
    2248        8064 :                 typelib_typedescription_register( ppRet );
    2249             : 
    2250             :                 // insert into the chache
    2251        8064 :                 MutexGuard aGuard( rInit.getMutex() );
    2252        8064 :                 if( !rInit.pCache )
    2253          34 :                     rInit.pCache = new TypeDescriptionList_Impl;
    2254        8064 :                 if( (sal_Int32)rInit.pCache->size() >= nCacheSize )
    2255             :                 {
    2256        4553 :                     typelib_typedescription_release( rInit.pCache->front() );
    2257        4553 :                     rInit.pCache->pop_front();
    2258             :                 }
    2259             :                 // descriptions in the cache must be acquired!
    2260        8064 :                 typelib_typedescription_acquire( *ppRet );
    2261        8064 :                 rInit.pCache->push_back( *ppRet );
    2262             :             }
    2263             :         }
    2264             :     }
    2265       76281 : }
    2266             : 
    2267           0 : extern "C" CPPU_DLLPUBLIC void SAL_CALL typelib_typedescriptionreference_newByAsciiName(
    2268             :     typelib_TypeDescriptionReference ** ppTDR,
    2269             :     typelib_TypeClass eTypeClass,
    2270             :     const sal_Char * pTypeName )
    2271             :     SAL_THROW_EXTERN_C()
    2272             : {
    2273           0 :     OUString aTypeName( OUString::createFromAscii( pTypeName ) );
    2274           0 :     typelib_typedescriptionreference_new( ppTDR, eTypeClass, aTypeName.pData );
    2275           0 : }
    2276             : //------------------------------------------------------------------------
    2277      429896 : extern "C" CPPU_DLLPUBLIC void SAL_CALL typelib_typedescriptionreference_new(
    2278             :     typelib_TypeDescriptionReference ** ppTDR,
    2279             :     typelib_TypeClass eTypeClass, rtl_uString * pTypeName )
    2280             :     SAL_THROW_EXTERN_C()
    2281             : {
    2282      429896 :     TypeDescriptor_Init_Impl &rInit = Init::get();
    2283      429896 :     if( eTypeClass == typelib_TypeClass_TYPEDEF )
    2284             :     {
    2285             :         // on demand access
    2286          47 :         typelib_TypeDescription * pRet = 0;
    2287          47 :         rInit.callChain( &pRet, pTypeName );
    2288          47 :         if( pRet )
    2289             :         {
    2290             :             // typedescription found
    2291          47 :             if (typelib_TypeClass_TYPEDEF == pRet->eTypeClass)
    2292             :             {
    2293             :                 typelib_typedescriptionreference_acquire(
    2294           0 :                     ((typelib_IndirectTypeDescription *)pRet)->pType );
    2295           0 :                 if (*ppTDR)
    2296           0 :                     typelib_typedescriptionreference_release( *ppTDR );
    2297           0 :                 *ppTDR = ((typelib_IndirectTypeDescription *)pRet)->pType;
    2298           0 :                 typelib_typedescription_release( pRet );
    2299             :             }
    2300             :             else
    2301             :             {
    2302             :                 // set to on demand
    2303          47 :                 pRet->bOnDemand = sal_True;
    2304             :                 // The type description is hold by the reference until
    2305             :                 // on demand is activated.
    2306          47 :                 typelib_typedescription_register( &pRet );
    2307             : 
    2308             :                 // insert into the chache
    2309          47 :                 MutexGuard aGuard( rInit.getMutex() );
    2310          47 :                 if( !rInit.pCache )
    2311           0 :                     rInit.pCache = new TypeDescriptionList_Impl;
    2312          47 :                 if( (sal_Int32)rInit.pCache->size() >= nCacheSize )
    2313             :                 {
    2314          16 :                     typelib_typedescription_release( rInit.pCache->front() );
    2315          16 :                     rInit.pCache->pop_front();
    2316             :                 }
    2317          47 :                 rInit.pCache->push_back( pRet );
    2318             :                 // pRet kept acquired for cache
    2319             : 
    2320          47 :                 typelib_typedescriptionreference_acquire( pRet->pWeakRef );
    2321          47 :                 if (*ppTDR)
    2322           0 :                     typelib_typedescriptionreference_release( *ppTDR );
    2323          47 :                 *ppTDR = pRet->pWeakRef;
    2324             :             }
    2325             :         }
    2326           0 :         else if (*ppTDR)
    2327             :         {
    2328             : #if OSL_DEBUG_LEVEL > 1
    2329             :             OString aStr( rtl::OUStringToOString( pTypeName, RTL_TEXTENCODING_ASCII_US ) );
    2330             :             OSL_ENSURE( !"### typedef not found: ", aStr.getStr() );
    2331             : #endif
    2332           0 :             typelib_typedescriptionreference_release( *ppTDR );
    2333           0 :             *ppTDR = 0;
    2334             :         }
    2335             :         return;
    2336             :     }
    2337             : 
    2338      429849 :     MutexGuard aGuard( rInit.getMutex() );
    2339      429849 :     typelib_typedescriptionreference_getByName( ppTDR, pTypeName );
    2340      429849 :     if( *ppTDR )
    2341             :         return;
    2342             : 
    2343       88828 :     if( reallyWeak( eTypeClass ) )
    2344             :     {
    2345       80231 :         typelib_TypeDescriptionReference * pTDR = new typelib_TypeDescriptionReference();
    2346             : #if OSL_DEBUG_LEVEL > 1
    2347             :         osl_atomic_increment( &rInit.nTypeDescriptionReferenceCount );
    2348             : #endif
    2349       80231 :         pTDR->nRefCount = 1;
    2350       80231 :         pTDR->nStaticRefCount = 0;
    2351       80231 :         pTDR->eTypeClass = eTypeClass;
    2352       80231 :         pTDR->pUniqueIdentifier = 0;
    2353       80231 :         pTDR->pReserved = 0;
    2354       80231 :         rtl_uString_acquire( pTDR->pTypeName = pTypeName );
    2355       80231 :         pTDR->pType = 0;
    2356       80231 :         *ppTDR = pTDR;
    2357             :     }
    2358             :     else
    2359             :     {
    2360        8597 :         typelib_typedescription_newEmpty( (typelib_TypeDescription ** )ppTDR, eTypeClass, pTypeName );
    2361             :         // description will be registered but not acquired
    2362        8597 :         (*(typelib_TypeDescription ** )ppTDR)->bOnDemand = sal_True;
    2363        8597 :         (*(typelib_TypeDescription ** )ppTDR)->bComplete = sal_False;
    2364             :     }
    2365             : 
    2366       88828 :     if( !rInit.pWeakMap )
    2367         266 :         rInit.pWeakMap = new WeakMap_Impl;
    2368             :     // Heavy hack, the const sal_Unicode * is hold by the typedescription reference
    2369             :     // not registered
    2370       88828 :     rInit.pWeakMap->operator[]( (*ppTDR)->pTypeName->buffer ) = *ppTDR;
    2371             : }
    2372             : 
    2373             : //------------------------------------------------------------------------
    2374     5700922 : extern "C" CPPU_DLLPUBLIC void SAL_CALL typelib_typedescriptionreference_acquire(
    2375             :     typelib_TypeDescriptionReference * pRef )
    2376             :     SAL_THROW_EXTERN_C()
    2377             : {
    2378     5700922 :     osl_atomic_increment( &pRef->nRefCount );
    2379     5700922 : }
    2380             : 
    2381             : //------------------------------------------------------------------------
    2382    13141990 : extern "C" CPPU_DLLPUBLIC void SAL_CALL typelib_typedescriptionreference_release(
    2383             :     typelib_TypeDescriptionReference * pRef )
    2384             :     SAL_THROW_EXTERN_C()
    2385             : {
    2386             :     // Is it a type description?
    2387    13141990 :     if( reallyWeak( pRef->eTypeClass ) )
    2388             :     {
    2389      324341 :         if( ! osl_atomic_decrement( &pRef->nRefCount ) )
    2390             :         {
    2391       18728 :             TypeDescriptor_Init_Impl &rInit = Init::get();
    2392       18728 :             if( rInit.pWeakMap )
    2393             :             {
    2394       18728 :                 MutexGuard aGuard( rInit.getMutex() );
    2395       18728 :                 WeakMap_Impl::iterator aIt = rInit.pWeakMap->find( (sal_Unicode*)pRef->pTypeName->buffer );
    2396       18728 :                 if( !(aIt == rInit.pWeakMap->end()) && (*aIt).second == pRef )
    2397             :                 {
    2398             :                     // remove only if it contains the same object
    2399       18728 :                     rInit.pWeakMap->erase( aIt );
    2400       18728 :                 }
    2401             :             }
    2402             : 
    2403       18728 :             rtl_uString_release( pRef->pTypeName );
    2404             :             OSL_ASSERT( pRef->pType == 0 );
    2405             : #if OSL_DEBUG_LEVEL > 1
    2406             :             osl_atomic_decrement( &rInit.nTypeDescriptionReferenceCount );
    2407             : #endif
    2408       18728 :             delete pRef;
    2409             :         }
    2410             :     }
    2411             :     else
    2412             :     {
    2413    12817649 :         typelib_typedescription_release( (typelib_TypeDescription *)pRef );
    2414             :     }
    2415    13141990 : }
    2416             : 
    2417             : //------------------------------------------------------------------------
    2418       65912 : extern "C" CPPU_DLLPUBLIC void SAL_CALL typelib_typedescriptionreference_getDescription(
    2419             :     typelib_TypeDescription ** ppRet, typelib_TypeDescriptionReference * pRef )
    2420             :     SAL_THROW_EXTERN_C()
    2421             : {
    2422       65912 :     if( *ppRet )
    2423             :     {
    2424           0 :         typelib_typedescription_release( *ppRet );
    2425           0 :         *ppRet = 0;
    2426             :     }
    2427             : 
    2428       65912 :     if( !reallyWeak( pRef->eTypeClass ) && pRef->pType && pRef->pType->pWeakRef )
    2429             :     {
    2430             :         // reference is a description and initialized
    2431       48742 :         osl_atomic_increment( &((typelib_TypeDescription *)pRef)->nRefCount );
    2432       48742 :         *ppRet = (typelib_TypeDescription *)pRef;
    2433       48742 :         return;
    2434             :     }
    2435             : 
    2436             :     {
    2437       17170 :     MutexGuard aGuard( Init::get().getMutex() );
    2438             :     // pRef->pType->pWeakRef == 0 means that the description is empty
    2439       17170 :     if( pRef->pType && pRef->pType->pWeakRef )
    2440             :     {
    2441        8869 :         sal_Int32 n = osl_atomic_increment( &pRef->pType->nRefCount );
    2442        8869 :         if( n > 1 )
    2443             :         {
    2444             :             // The refence is incremented. The object cannot be destroyed.
    2445             :             // Release the guard at the earliest point.
    2446        8869 :             *ppRet = pRef->pType;
    2447             :             return;
    2448             :         }
    2449             :         else
    2450             :         {
    2451           0 :             osl_atomic_decrement( &pRef->pType->nRefCount );
    2452             :             // detruction of this type in progress (another thread!)
    2453             :             // no acces through this weak reference
    2454           0 :             pRef->pType = 0;
    2455             :         }
    2456       17170 :     }
    2457             :     }
    2458             : 
    2459        8301 :     typelib_typedescription_getByName( ppRet, pRef->pTypeName );
    2460             :     OSL_ASSERT( !*ppRet || rtl_ustr_compare( pRef->pTypeName->buffer, (*ppRet)->pTypeName->buffer ) == 0 );
    2461             :     OSL_ASSERT( !*ppRet || pRef->eTypeClass == (*ppRet)->eTypeClass );
    2462             :     OSL_ASSERT( !*ppRet || pRef == (*ppRet)->pWeakRef );
    2463        8301 :     pRef->pType = *ppRet;
    2464             : }
    2465             : 
    2466             : //------------------------------------------------------------------------
    2467      635083 : extern "C" void SAL_CALL typelib_typedescriptionreference_getByName(
    2468             :     typelib_TypeDescriptionReference ** ppRet, rtl_uString * pName )
    2469             :     SAL_THROW_EXTERN_C()
    2470             : {
    2471      635083 :     if( *ppRet )
    2472             :     {
    2473           0 :         typelib_typedescriptionreference_release( *ppRet );
    2474           0 :         *ppRet = 0;
    2475             :     }
    2476      635083 :     TypeDescriptor_Init_Impl &rInit = Init::get();
    2477      635083 :     if( rInit.pWeakMap )
    2478             :     {
    2479      634817 :         MutexGuard aGuard( rInit.getMutex() );
    2480      634817 :         WeakMap_Impl::const_iterator aIt = rInit.pWeakMap->find( (sal_Unicode*)pName->buffer );
    2481      634817 :         if( !(aIt == rInit.pWeakMap->end()) ) // != failed on msc4.2
    2482             :         {
    2483      518593 :             sal_Int32 n = osl_atomic_increment( &(*aIt).second->nRefCount );
    2484      518593 :             if( n > 1 )
    2485             :             {
    2486             :                 // The refence is incremented. The object cannot be destroyed.
    2487             :                 // Release the guard at the earliest point.
    2488      518593 :                 *ppRet = (*aIt).second;
    2489             :             }
    2490             :             else
    2491             :             {
    2492             :                 // detruction of this type in progress (another thread!)
    2493             :                 // no acces through this weak reference
    2494           0 :                 osl_atomic_decrement( &(*aIt).second->nRefCount );
    2495             :             }
    2496      634817 :         }
    2497             :     }
    2498      635083 : }
    2499             : 
    2500             : //------------------------------------------------------------------------
    2501     6906446 : extern "C" CPPU_DLLPUBLIC sal_Bool SAL_CALL typelib_typedescriptionreference_equals(
    2502             :     const typelib_TypeDescriptionReference * p1,
    2503             :     const typelib_TypeDescriptionReference * p2 )
    2504             :     SAL_THROW_EXTERN_C()
    2505             : {
    2506             :     return (p1 == p2 ||
    2507             :             (p1->eTypeClass == p2->eTypeClass &&
    2508             :              p1->pTypeName->length == p2->pTypeName->length &&
    2509     6906446 :              rtl_ustr_compare( p1->pTypeName->buffer, p2->pTypeName->buffer ) == 0));
    2510             : }
    2511             : 
    2512             : //##################################################################################################
    2513      113564 : extern "C" CPPU_DLLPUBLIC void SAL_CALL typelib_typedescriptionreference_assign(
    2514             :     typelib_TypeDescriptionReference ** ppDest,
    2515             :     typelib_TypeDescriptionReference * pSource )
    2516             :     SAL_THROW_EXTERN_C()
    2517             : {
    2518      113564 :     if (*ppDest != pSource)
    2519             :     {
    2520      104757 :         ::typelib_typedescriptionreference_acquire( pSource );
    2521      104757 :         ::typelib_typedescriptionreference_release( *ppDest );
    2522      104757 :         *ppDest = pSource;
    2523             :     }
    2524      113564 : }
    2525             : 
    2526             : //##################################################################################################
    2527           0 : extern "C" CPPU_DLLPUBLIC void SAL_CALL typelib_setCacheSize( sal_Int32 nNewSize )
    2528             :     SAL_THROW_EXTERN_C()
    2529             : {
    2530             :     OSL_ENSURE( nNewSize >= 0, "### illegal cache size given!" );
    2531           0 :     if (nNewSize >= 0)
    2532             :     {
    2533           0 :         TypeDescriptor_Init_Impl &rInit = Init::get();
    2534           0 :         MutexGuard aGuard( rInit.getMutex() );
    2535           0 :         if ((nNewSize < nCacheSize) && rInit.pCache)
    2536             :         {
    2537           0 :             while ((sal_Int32)rInit.pCache->size() != nNewSize)
    2538             :             {
    2539           0 :                 typelib_typedescription_release( rInit.pCache->front() );
    2540           0 :                 rInit.pCache->pop_front();
    2541             :             }
    2542             :         }
    2543           0 :         nCacheSize = nNewSize;
    2544             :     }
    2545           0 : }
    2546             : 
    2547             : 
    2548             : static sal_Bool s_aAssignableFromTab[11][11] =
    2549             : {
    2550             :                          /* from CH,BO,BY,SH,US,LO,UL,HY,UH,FL,DO */
    2551             : /* TypeClass_CHAR */            { 1, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0 },
    2552             : /* TypeClass_BOOLEAN */         { 0, 1, 0, 0, 0, 0, 0, 0, 0, 0, 0 },
    2553             : /* TypeClass_BYTE */            { 0, 0, 1, 0, 0, 0, 0, 0, 0, 0, 0 },
    2554             : /* TypeClass_SHORT */           { 0, 0, 1, 1, 1, 0, 0, 0, 0, 0, 0 },
    2555             : /* TypeClass_UNSIGNED_SHORT */  { 0, 0, 1, 1, 1, 0, 0, 0, 0, 0, 0 },
    2556             : /* TypeClass_LONG */            { 0, 0, 1, 1, 1, 1, 1, 0, 0, 0, 0 },
    2557             : /* TypeClass_UNSIGNED_LONG */   { 0, 0, 1, 1, 1, 1, 1, 0, 0, 0, 0 },
    2558             : /* TypeClass_HYPER */           { 0, 0, 1, 1, 1, 1, 1, 1, 1, 0, 0 },
    2559             : /* TypeClass_UNSIGNED_HYPER */  { 0, 0, 1, 1, 1, 1, 1, 1, 1, 0, 0 },
    2560             : /* TypeClass_FLOAT */           { 0, 0, 1, 1, 1, 0, 0, 0, 0, 1, 0 },
    2561             : /* TypeClass_DOUBLE */          { 0, 0, 1, 1, 1, 1, 1, 0, 0, 1, 1 }
    2562             : };
    2563             : 
    2564             : //##################################################################################################
    2565        3439 : extern "C" CPPU_DLLPUBLIC sal_Bool SAL_CALL typelib_typedescriptionreference_isAssignableFrom(
    2566             :     typelib_TypeDescriptionReference * pAssignable,
    2567             :     typelib_TypeDescriptionReference * pFrom )
    2568             :     SAL_THROW_EXTERN_C()
    2569             : {
    2570        3439 :     if (pAssignable && pFrom)
    2571             :     {
    2572        3439 :         typelib_TypeClass eAssignable = pAssignable->eTypeClass;
    2573        3439 :         typelib_TypeClass eFrom       = pFrom->eTypeClass;
    2574             : 
    2575        3439 :         if (eAssignable == typelib_TypeClass_ANY) // anything can be assigned to an any .)
    2576           0 :             return sal_True;
    2577        3439 :         if (eAssignable == eFrom)
    2578             :         {
    2579        3406 :             if (type_equals( pAssignable, pFrom )) // first shot
    2580             :             {
    2581        3329 :                 return sal_True;
    2582             :             }
    2583             :             else
    2584             :             {
    2585          77 :                 switch (eAssignable)
    2586             :                 {
    2587             :                 case typelib_TypeClass_STRUCT:
    2588             :                 case typelib_TypeClass_EXCEPTION:
    2589             :                 {
    2590          11 :                     typelib_TypeDescription * pFromDescr = 0;
    2591          11 :                     TYPELIB_DANGER_GET( &pFromDescr, pFrom );
    2592          11 :                     if (! ((typelib_CompoundTypeDescription *)pFromDescr)->pBaseTypeDescription)
    2593             :                     {
    2594           1 :                         TYPELIB_DANGER_RELEASE( pFromDescr );
    2595           1 :                         return sal_False;
    2596             :                     }
    2597             :                     sal_Bool bRet = typelib_typedescriptionreference_isAssignableFrom(
    2598             :                         pAssignable,
    2599          10 :                         ((typelib_TypeDescription *)((typelib_CompoundTypeDescription *)pFromDescr)->pBaseTypeDescription)->pWeakRef );
    2600          10 :                     TYPELIB_DANGER_RELEASE( pFromDescr );
    2601          10 :                     return bRet;
    2602             :                 }
    2603             :                 case typelib_TypeClass_INTERFACE:
    2604             :                 {
    2605          66 :                     typelib_TypeDescription * pFromDescr = 0;
    2606          66 :                     TYPELIB_DANGER_GET( &pFromDescr, pFrom );
    2607             :                     typelib_InterfaceTypeDescription * pFromIfc
    2608             :                         = reinterpret_cast<
    2609          66 :                             typelib_InterfaceTypeDescription * >(pFromDescr);
    2610          66 :                     bool bRet = false;
    2611          99 :                     for (sal_Int32 i = 0; i < pFromIfc->nBaseTypes; ++i) {
    2612          33 :                         if (typelib_typedescriptionreference_isAssignableFrom(
    2613             :                                 pAssignable,
    2614          33 :                                 pFromIfc->ppBaseTypes[i]->aBase.pWeakRef))
    2615             :                         {
    2616           0 :                             bRet = true;
    2617           0 :                             break;
    2618             :                         }
    2619             :                     }
    2620          66 :                     TYPELIB_DANGER_RELEASE( pFromDescr );
    2621          66 :                     return bRet;
    2622             :                 }
    2623             :                 default:
    2624             :                 {
    2625           0 :                     return sal_False;
    2626             :                 }
    2627             :                 }
    2628             :             }
    2629             :         }
    2630             :         return (eAssignable >= typelib_TypeClass_CHAR && eAssignable <= typelib_TypeClass_DOUBLE &&
    2631             :                 eFrom >= typelib_TypeClass_CHAR && eFrom <= typelib_TypeClass_DOUBLE &&
    2632          33 :                 s_aAssignableFromTab[eAssignable-1][eFrom-1]);
    2633             :     }
    2634           0 :     return sal_False;
    2635             : }
    2636             : //##################################################################################################
    2637           0 : extern "C" CPPU_DLLPUBLIC sal_Bool SAL_CALL typelib_typedescription_isAssignableFrom(
    2638             :     typelib_TypeDescription * pAssignable,
    2639             :     typelib_TypeDescription * pFrom )
    2640             :     SAL_THROW_EXTERN_C()
    2641             : {
    2642             :     return typelib_typedescriptionreference_isAssignableFrom(
    2643           0 :         pAssignable->pWeakRef, pFrom->pWeakRef );
    2644             : }
    2645             : 
    2646             : //##################################################################################################
    2647        3866 : extern "C" CPPU_DLLPUBLIC sal_Bool SAL_CALL typelib_typedescription_complete(
    2648             :     typelib_TypeDescription ** ppTypeDescr )
    2649             :     SAL_THROW_EXTERN_C()
    2650             : {
    2651        3866 :     return complete(ppTypeDescr, true);
    2652             : }
    2653             : 
    2654             : /* vim:set shiftwidth=4 softtabstop=4 expandtab: */

Generated by: LCOV version 1.10