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

Generated by: LCOV version 1.11