LCOV - code coverage report
Current view: top level - cppu/source/typelib - typelib.cxx (source / functions) Hit Total Coverage
Test: commit 10e77ab3ff6f4314137acd6e2702a6e5c1ce1fae Lines: 923 1021 90.4 %
Date: 2014-11-03 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 <boost/unordered_map.hpp>
      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      756978 : static inline sal_Int32 adjustAlignment( sal_Int32 nRequestedAlignment )
      85             : {
      86      756978 :     if( nRequestedAlignment > nMaxAlignment )
      87           0 :         nRequestedAlignment = nMaxAlignment;
      88      756978 :     return nRequestedAlignment;
      89             : }
      90             : 
      91             : /**
      92             :  * Calculate the new size of the structure.
      93             :  */
      94      450348 : static inline sal_Int32 newAlignedSize(
      95             :     sal_Int32 OldSize, sal_Int32 ElementSize, sal_Int32 NeededAlignment )
      96             : {
      97      450348 :     NeededAlignment = adjustAlignment( NeededAlignment );
      98      450348 :     return (OldSize + NeededAlignment -1) / NeededAlignment * NeededAlignment + ElementSize;
      99             : }
     100             : 
     101   576115720 : static inline bool reallyWeak( typelib_TypeClass eTypeClass )
     102             : {
     103   576115720 :     return TYPELIB_TYPEDESCRIPTIONREFERENCE_ISREALLYWEAK( eTypeClass );
     104             : }
     105             : 
     106       67681 : 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       67681 :     switch( eTypeClass )
     115             :     {
     116             :         case typelib_TypeClass_SEQUENCE:
     117        4147 :             nSize = (sal_Int32)sizeof( typelib_IndirectTypeDescription );
     118        4147 :         break;
     119             : 
     120             :         case typelib_TypeClass_STRUCT:
     121        8104 :             nSize = (sal_Int32)sizeof( typelib_StructTypeDescription );
     122        8104 :         break;
     123             : 
     124             :         case typelib_TypeClass_EXCEPTION:
     125         853 :             nSize = (sal_Int32)sizeof( typelib_CompoundTypeDescription );
     126         853 :         break;
     127             : 
     128             :         case typelib_TypeClass_ENUM:
     129        1438 :             nSize = (sal_Int32)sizeof( typelib_EnumTypeDescription );
     130        1438 :         break;
     131             : 
     132             :         case typelib_TypeClass_INTERFACE:
     133       50505 :             nSize = (sal_Int32)sizeof( typelib_InterfaceTypeDescription );
     134       50505 :         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        2634 :             nSize = (sal_Int32)sizeof( typelib_TypeDescription );
     146             :     }
     147       67681 :     return nSize;
     148             : }
     149             : 
     150             : 
     151             : 
     152             : struct equalStr_Impl
     153             : {
     154     4392380 :     bool operator()(const sal_Unicode * const & s1, const sal_Unicode * const & s2) const
     155     4392380 :         { return 0 == rtl_ustr_compare( s1, s2 ); }
     156             : };
     157             : 
     158             : 
     159             : struct hashStr_Impl
     160             : {
     161     6157920 :     size_t operator()(const sal_Unicode * const & s) const
     162     6157920 :         { return rtl_ustr_hashCode( s ); }
     163             : };
     164             : 
     165             : 
     166             : 
     167             : // Heavy hack, the const sal_Unicode * is hold by the typedescription reference
     168             : typedef boost::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         664 :     TypeDescriptor_Init_Impl():
     207         664 :         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         664 :     {}
     217             : 
     218             :     ~TypeDescriptor_Init_Impl();
     219             : };
     220             : 
     221    11101179 : inline Mutex & TypeDescriptor_Init_Impl::getMutex()
     222             : {
     223    11101179 :     if( !pMutex )
     224             :     {
     225         664 :         MutexGuard aGuard( Mutex::getGlobalMutex() );
     226         664 :         if( !pMutex )
     227         664 :             pMutex = new Mutex();
     228             :     }
     229    11101179 :     return * pMutex;
     230             : }
     231             : 
     232       97822 : inline void TypeDescriptor_Init_Impl::callChain(
     233             :     typelib_TypeDescription ** ppRet, rtl_uString * pName )
     234             : {
     235             :     assert(ppRet != 0);
     236             :     assert(*ppRet == 0);
     237       97822 :     if (pCallbacks)
     238             :     {
     239       97822 :         CallbackSet_Impl::const_iterator aIt = pCallbacks->begin();
     240      195792 :         while( aIt != pCallbacks->end() )
     241             :         {
     242       97822 :             const CallbackEntry & rEntry = *aIt;
     243       97822 :             (*rEntry.second)( rEntry.first, ppRet, pName );
     244       97822 :             if( *ppRet )
     245      195348 :                 return;
     246         148 :             ++aIt;
     247             :         }
     248             :     }
     249             : }
     250             : 
     251             : 
     252         664 : TypeDescriptor_Init_Impl::~TypeDescriptor_Init_Impl()
     253             : {
     254         664 :     if( pCache )
     255             :     {
     256         391 :         TypeDescriptionList_Impl::const_iterator aIt = pCache->begin();
     257       54863 :         while( aIt != pCache->end() )
     258             :         {
     259       54081 :             typelib_typedescription_release( (*aIt) );
     260       54081 :             ++aIt;
     261             :         }
     262         391 :         delete pCache;
     263         391 :         pCache = 0;
     264             :     }
     265             : 
     266         664 :     if( pWeakMap )
     267             :     {
     268         664 :         std::vector< typelib_TypeDescriptionReference * > ppTDR;
     269         664 :         ppTDR.reserve( pWeakMap->size() );
     270             : 
     271             :         // save all weak references
     272         664 :         WeakMap_Impl::const_iterator aIt = pWeakMap->begin();
     273      864049 :         while( aIt != pWeakMap->end() )
     274             :         {
     275      862721 :             ppTDR.push_back( (*aIt).second );
     276      862721 :             typelib_typedescriptionreference_acquire( ppTDR.back() );
     277      862721 :             ++aIt;
     278             :         }
     279             : 
     280     2590155 :         for( std::vector< typelib_TypeDescriptionReference * >::iterator i(
     281         664 :                  ppTDR.begin() );
     282     1726770 :              i != ppTDR.end(); ++i )
     283             :         {
     284      862721 :             typelib_TypeDescriptionReference * pTDR = *i;
     285             :             OSL_ASSERT( pTDR->nRefCount > pTDR->nStaticRefCount );
     286      862721 :             pTDR->nRefCount -= pTDR->nStaticRefCount;
     287             : 
     288      862721 :             if( pTDR->pType && !pTDR->pType->bOnDemand )
     289             :             {
     290      130394 :                 pTDR->pType->bOnDemand = sal_True;
     291      130394 :                 typelib_typedescription_release( pTDR->pType );
     292             :             }
     293      862721 :             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         664 :         delete pWeakMap;
     316         664 :         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         664 :     delete pCallbacks;
     332         664 :     pCallbacks = 0;
     333             : 
     334         664 :     if( pMutex )
     335             :     {
     336         664 :         delete pMutex;
     337         664 :         pMutex = 0;
     338             :     }
     339         664 : };
     340             : 
     341             : namespace { struct Init : public rtl::Static< TypeDescriptor_Init_Impl, Init > {}; }
     342             : 
     343         664 : extern "C" CPPU_DLLPUBLIC 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         664 :     TypeDescriptor_Init_Impl &rInit = Init::get();
     349             : //      OslGuard aGuard( rInit.getMutex() );
     350         664 :     if( !rInit.pCallbacks )
     351         642 :         rInit.pCallbacks = new CallbackSet_Impl;
     352         664 :     rInit.pCallbacks->push_back( CallbackEntry( pContext, pCallback ) );
     353         664 : }
     354             : 
     355             : 
     356         658 : extern "C" CPPU_DLLPUBLIC void SAL_CALL typelib_typedescription_revokeCallback(
     357             :     void * pContext, typelib_typedescription_Callback pCallback )
     358             :     SAL_THROW_EXTERN_C()
     359             : {
     360         658 :     TypeDescriptor_Init_Impl &rInit = Init::get();
     361         658 :     if( rInit.pCallbacks )
     362             :     {
     363             :         // todo mt safe: guard is no solution, can not acquire while calling callback!
     364             : //          OslGuard aGuard( rInit.getMutex() );
     365         658 :         CallbackEntry aEntry( pContext, pCallback );
     366         658 :         CallbackSet_Impl::iterator iPos( rInit.pCallbacks->begin() );
     367        2060 :         while (!(iPos == rInit.pCallbacks->end()))
     368             :         {
     369         744 :             if (*iPos == aEntry)
     370             :             {
     371         658 :                 rInit.pCallbacks->erase( iPos );
     372         658 :                 iPos = rInit.pCallbacks->begin();
     373             :             }
     374             :             else
     375             :             {
     376          86 :                 ++iPos;
     377             :             }
     378             :         }
     379             :     }
     380         658 : }
     381             : 
     382       21102 : static inline void typelib_typedescription_initTables(
     383             :     typelib_TypeDescription * pTD )
     384             : {
     385       21102 :     typelib_InterfaceTypeDescription * pITD = (typelib_InterfaceTypeDescription *)pTD;
     386             : 
     387       21102 :     sal_Bool * pReadWriteAttributes = (sal_Bool *)alloca( pITD->nAllMembers );
     388      210446 :     for ( sal_Int32 i = pITD->nAllMembers; i--; )
     389             :     {
     390      168242 :         pReadWriteAttributes[i] = sal_False;
     391      168242 :         if( typelib_TypeClass_INTERFACE_ATTRIBUTE == pITD->ppAllMembers[i]->eTypeClass )
     392             :         {
     393        9072 :             typelib_TypeDescription * pM = 0;
     394        9072 :             TYPELIB_DANGER_GET( &pM, pITD->ppAllMembers[i] );
     395             :             OSL_ASSERT( pM );
     396        9072 :             if (pM)
     397             :             {
     398        9072 :                 pReadWriteAttributes[i] = !((typelib_InterfaceAttributeTypeDescription *)pM)->bReadOnly;
     399        9072 :                 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       21102 :     MutexGuard aGuard( Init::get().getMutex() );
     412       21102 :     if( !pTD->bComplete )
     413             :     {
     414             :         // create the index table from member to function table
     415       21102 :         pITD->pMapMemberIndexToFunctionIndex = new sal_Int32[ pITD->nAllMembers ];
     416       21102 :         sal_Int32 nAdditionalOffset = 0; // +1 for read/write attributes
     417             :         sal_Int32 i;
     418      189344 :         for( i = 0; i < pITD->nAllMembers; i++ )
     419             :         {
     420             :             // index to the get method of the attribute
     421      168242 :             pITD->pMapMemberIndexToFunctionIndex[i] = i + nAdditionalOffset;
     422             :             // extra offset if it is a read/write attribute?
     423      168242 :             if( pReadWriteAttributes[i] )
     424             :             {
     425             :                 // a read/write attribute
     426        5936 :                 nAdditionalOffset++;
     427             :             }
     428             :         }
     429             : 
     430             :         // create the index table from function to member table
     431       21102 :         pITD->pMapFunctionIndexToMemberIndex = new sal_Int32[ pITD->nAllMembers + nAdditionalOffset ];
     432       21102 :         nAdditionalOffset = 0; // +1 for read/write attributes
     433      189344 :         for( i = 0; i < pITD->nAllMembers; i++ )
     434             :         {
     435             :             // index to the get method of the attribute
     436      168242 :             pITD->pMapFunctionIndexToMemberIndex[i + nAdditionalOffset] = i;
     437             :             // extra offset if it is a read/write attribute?
     438      168242 :             if( pReadWriteAttributes[i] )
     439             :             {
     440             :                 // a read/write attribute
     441        5936 :                 pITD->pMapFunctionIndexToMemberIndex[i + ++nAdditionalOffset] = i;
     442             :             }
     443             :         }
     444             :         // must be the last action after all initialization is done
     445       21102 :         pITD->nMapFunctionIndexToMemberIndex = pITD->nAllMembers + nAdditionalOffset;
     446       21102 :         pTD->bComplete = sal_True;
     447       21102 :     }
     448       21102 : }
     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     1469523 : bool complete(typelib_TypeDescription ** ppTypeDescr, bool initTables) {
     464     1469523 :     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      363219 :         if (typelib_TypeClass_INTERFACE == (*ppTypeDescr)->eTypeClass &&
     473             :             ((typelib_InterfaceTypeDescription *)*ppTypeDescr)->ppAllMembers)
     474             :         {
     475      363219 :             if (initTables) {
     476       21102 :                 typelib_typedescription_initTables( *ppTypeDescr );
     477             :             }
     478      726438 :             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, ((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( ((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     1106304 :     return true;
     548             : }
     549             : 
     550             : }
     551             : 
     552             : 
     553      793838 : 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      793838 :     if( *ppRet )
     559             :     {
     560        9840 :         typelib_typedescription_release( *ppRet );
     561        9840 :         *ppRet = 0;
     562             :     }
     563             : 
     564             :     OSL_ASSERT( typelib_TypeClass_TYPEDEF != eTypeClass );
     565             : 
     566             :     typelib_TypeDescription * pRet;
     567      793838 :     switch( eTypeClass )
     568             :     {
     569             :         case typelib_TypeClass_SEQUENCE:
     570             :         {
     571       22127 :             typelib_IndirectTypeDescription * pTmp = new typelib_IndirectTypeDescription();
     572       22127 :             pRet = (typelib_TypeDescription *)pTmp;
     573             : #if OSL_DEBUG_LEVEL > 1
     574             :             osl_atomic_increment( &Init::get().nIndirectTypeDescriptionCount );
     575             : #endif
     576       22127 :             pTmp->pType = 0;
     577             :         }
     578       22127 :         break;
     579             : 
     580             :         case typelib_TypeClass_STRUCT:
     581             :         {
     582             :             // FEATURE_EMPTYCLASS
     583             :             typelib_StructTypeDescription * pTmp;
     584       31409 :             pTmp = new typelib_StructTypeDescription();
     585       31409 :             pRet = (typelib_TypeDescription *)pTmp;
     586             : #if OSL_DEBUG_LEVEL > 1
     587             :             osl_atomic_increment( &Init::get().nCompoundTypeDescriptionCount );
     588             : #endif
     589       31409 :             pTmp->aBase.pBaseTypeDescription = 0;
     590       31409 :             pTmp->aBase.nMembers = 0;
     591       31409 :             pTmp->aBase.pMemberOffsets = 0;
     592       31409 :             pTmp->aBase.ppTypeRefs = 0;
     593       31409 :             pTmp->aBase.ppMemberNames = 0;
     594       31409 :             pTmp->pParameterizedTypes = 0;
     595             :         }
     596       31409 :         break;
     597             : 
     598             :         case typelib_TypeClass_EXCEPTION:
     599             :         {
     600             :             // FEATURE_EMPTYCLASS
     601             :             typelib_CompoundTypeDescription * pTmp;
     602       25431 :             pTmp = new typelib_CompoundTypeDescription();
     603       25431 :             pRet = (typelib_TypeDescription *)pTmp;
     604             : #if OSL_DEBUG_LEVEL > 1
     605             :             osl_atomic_increment( &Init::get().nCompoundTypeDescriptionCount );
     606             : #endif
     607       25431 :             pTmp->pBaseTypeDescription = 0;
     608       25431 :             pTmp->nMembers = 0;
     609       25431 :             pTmp->pMemberOffsets = 0;
     610       25431 :             pTmp->ppTypeRefs = 0;
     611       25431 :             pTmp->ppMemberNames = 0;
     612             :         }
     613       25431 :         break;
     614             : 
     615             :         case typelib_TypeClass_ENUM:
     616             :         {
     617       15998 :             typelib_EnumTypeDescription * pTmp = new typelib_EnumTypeDescription();
     618       15998 :             pRet = (typelib_TypeDescription *)pTmp;
     619             : #if OSL_DEBUG_LEVEL > 1
     620             :             osl_atomic_increment( &Init::get().nEnumTypeDescriptionCount );
     621             : #endif
     622       15998 :             pTmp->nDefaultEnumValue = 0;
     623       15998 :             pTmp->nEnumValues       = 0;
     624       15998 :             pTmp->ppEnumNames       = 0;
     625       15998 :             pTmp->pEnumValues       = 0;
     626             :         }
     627       15998 :         break;
     628             : 
     629             :         case typelib_TypeClass_INTERFACE:
     630             :         {
     631      322699 :             typelib_InterfaceTypeDescription * pTmp = new typelib_InterfaceTypeDescription();
     632      322699 :             pRet = (typelib_TypeDescription *)pTmp;
     633             : #if OSL_DEBUG_LEVEL > 1
     634             :             osl_atomic_increment( &Init::get().nInterfaceTypeDescriptionCount );
     635             : #endif
     636      322699 :             pTmp->pBaseTypeDescription = 0;
     637      322699 :             pTmp->nMembers = 0;
     638      322699 :             pTmp->ppMembers = 0;
     639      322699 :             pTmp->nAllMembers = 0;
     640      322699 :             pTmp->ppAllMembers = 0;
     641      322699 :             pTmp->nMapFunctionIndexToMemberIndex = 0;
     642      322699 :             pTmp->pMapFunctionIndexToMemberIndex = 0;
     643      322699 :             pTmp->pMapMemberIndexToFunctionIndex= 0;
     644      322699 :             pTmp->nBaseTypes = 0;
     645      322699 :             pTmp->ppBaseTypes = 0;
     646             :         }
     647      322699 :         break;
     648             : 
     649             :         case typelib_TypeClass_INTERFACE_METHOD:
     650             :         {
     651      352994 :             typelib_InterfaceMethodTypeDescription * pTmp = new typelib_InterfaceMethodTypeDescription();
     652      352994 :             pRet = (typelib_TypeDescription *)pTmp;
     653             : #if OSL_DEBUG_LEVEL > 1
     654             :             osl_atomic_increment( &Init::get().nInterfaceMethodTypeDescriptionCount );
     655             : #endif
     656      352994 :             pTmp->aBase.pMemberName = 0;
     657      352994 :             pTmp->pReturnTypeRef = 0;
     658      352994 :             pTmp->nParams = 0;
     659      352994 :             pTmp->pParams = 0;
     660      352994 :             pTmp->nExceptions = 0;
     661      352994 :             pTmp->ppExceptions = 0;
     662      352994 :             pTmp->pInterface = 0;
     663      352994 :             pTmp->pBaseRef = 0;
     664      352994 :             pTmp->nIndex = 0;
     665             :         }
     666      352994 :         break;
     667             : 
     668             :         case typelib_TypeClass_INTERFACE_ATTRIBUTE:
     669             :         {
     670        9894 :             typelib_InterfaceAttributeTypeDescription * pTmp = new typelib_InterfaceAttributeTypeDescription();
     671        9894 :             pRet = (typelib_TypeDescription *)pTmp;
     672             : #if OSL_DEBUG_LEVEL > 1
     673             :             osl_atomic_increment( &Init::get().nInterfaceAttributeTypeDescriptionCount );
     674             : #endif
     675        9894 :             pTmp->aBase.pMemberName = 0;
     676        9894 :             pTmp->pAttributeTypeRef = 0;
     677        9894 :             pTmp->pInterface = 0;
     678        9894 :             pTmp->pBaseRef = 0;
     679        9894 :             pTmp->nIndex = 0;
     680        9894 :             pTmp->nGetExceptions = 0;
     681        9894 :             pTmp->ppGetExceptions = 0;
     682        9894 :             pTmp->nSetExceptions = 0;
     683        9894 :             pTmp->ppSetExceptions = 0;
     684             :         }
     685        9894 :         break;
     686             : 
     687             :         default:
     688             :         {
     689       13286 :             pRet = new typelib_TypeDescription();
     690             : #if OSL_DEBUG_LEVEL > 1
     691             :             osl_atomic_increment( &Init::get().nTypeDescriptionCount );
     692             : #endif
     693             :         }
     694             :     }
     695             : 
     696      793838 :     pRet->nRefCount = 1; // reference count is initially 1
     697      793838 :     pRet->nStaticRefCount = 0;
     698      793838 :     pRet->eTypeClass = eTypeClass;
     699      793838 :     pRet->pTypeName = 0;
     700      793838 :     pRet->pUniqueIdentifier = 0;
     701      793838 :     pRet->pReserved = 0;
     702      793838 :     rtl_uString_acquire( pRet->pTypeName = pTypeName );
     703      793838 :     pRet->pSelf = pRet;
     704      793838 :     pRet->bComplete = sal_True;
     705      793838 :     pRet->nSize = 0;
     706      793838 :     pRet->nAlignment = 0;
     707      793838 :     pRet->pWeakRef = 0;
     708      793838 :     pRet->bOnDemand = sal_False;
     709      793838 :     *ppRet = pRet;
     710      793838 : }
     711             : 
     712             : 
     713             : namespace {
     714             : 
     715       67561 : 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       67561 :     if (typelib_TypeClass_TYPEDEF == eTypeClass)
     725             :     {
     726             :         OSL_TRACE( "### unexpected typedef!" );
     727           0 :         typelib_typedescriptionreference_getDescription( ppRet, pType );
     728       67561 :         return;
     729             :     }
     730             : 
     731       67561 :     typelib_typedescription_newEmpty( ppRet, eTypeClass, pTypeName );
     732             : 
     733       67561 :     switch( eTypeClass )
     734             :     {
     735             :         case typelib_TypeClass_SEQUENCE:
     736             :         {
     737             :             OSL_ASSERT( nMembers == 0 );
     738       16109 :             typelib_typedescriptionreference_acquire( pType );
     739       16109 :             ((typelib_IndirectTypeDescription *)*ppRet)->pType = pType;
     740             :         }
     741       16109 :         break;
     742             : 
     743             :         case typelib_TypeClass_EXCEPTION:
     744             :         case typelib_TypeClass_STRUCT:
     745             :         {
     746             :             // FEATURE_EMPTYCLASS
     747       40806 :             typelib_CompoundTypeDescription * pTmp = (typelib_CompoundTypeDescription*)*ppRet;
     748             : 
     749       40806 :             sal_Int32 nOffset = 0;
     750       40806 :             if( pType )
     751             :             {
     752             :                 typelib_typedescriptionreference_getDescription(
     753       22799 :                     (typelib_TypeDescription **)&pTmp->pBaseTypeDescription, pType );
     754       22799 :                 nOffset = ((typelib_TypeDescription *)pTmp->pBaseTypeDescription)->nSize;
     755             :                 OSL_ENSURE( newAlignedSize( 0, ((typelib_TypeDescription *)pTmp->pBaseTypeDescription)->nSize, ((typelib_TypeDescription *)pTmp->pBaseTypeDescription)->nAlignment ) == ((typelib_TypeDescription *)pTmp->pBaseTypeDescription)->nSize, "### unexpected offset!" );
     756             :             }
     757       40806 :             if( nMembers )
     758             :             {
     759       22157 :                 pTmp->nMembers = nMembers;
     760       22157 :                 pTmp->pMemberOffsets = new sal_Int32[ nMembers ];
     761       22157 :                 pTmp->ppTypeRefs = new typelib_TypeDescriptionReference *[ nMembers ];
     762       22157 :                 pTmp->ppMemberNames = new rtl_uString *[ nMembers ];
     763             :                 bool polymorphic = eTypeClass == typelib_TypeClass_STRUCT
     764       22157 :                     && rtl::OUString::unacquired(&pTypeName).indexOf('<') >= 0;
     765             :                 OSL_ASSERT(!polymorphic || pStructMembers != 0);
     766       22157 :                 if (polymorphic) {
     767             :                     reinterpret_cast< typelib_StructTypeDescription * >(pTmp)->
     768         338 :                         pParameterizedTypes = new sal_Bool[nMembers];
     769             :                 }
     770       95010 :                 for( sal_Int32 i = 0 ; i < nMembers; i++ )
     771             :                 {
     772             :                     // read the type and member names
     773       72853 :                     pTmp->ppTypeRefs[i] = 0;
     774       72853 :                     if (pCompoundMembers != 0) {
     775             :                         typelib_typedescriptionreference_new(
     776        5808 :                             pTmp->ppTypeRefs +i, pCompoundMembers[i].eTypeClass,
     777       11616 :                             pCompoundMembers[i].pTypeName );
     778             :                         rtl_uString_acquire(
     779       11616 :                             pTmp->ppMemberNames[i]
     780       11616 :                             = pCompoundMembers[i].pMemberName );
     781             :                     } else {
     782             :                         typelib_typedescriptionreference_new(
     783             :                             pTmp->ppTypeRefs +i,
     784       67045 :                             pStructMembers[i].aBase.eTypeClass,
     785      134090 :                             pStructMembers[i].aBase.pTypeName );
     786             :                         rtl_uString_acquire(
     787      134090 :                             pTmp->ppMemberNames[i]
     788      134090 :                             = pStructMembers[i].aBase.pMemberName );
     789             :                     }
     790             :                     // write offset
     791             :                     sal_Int32 size;
     792             :                     sal_Int32 alignment;
     793       72853 :                     if (pTmp->ppTypeRefs[i]->eTypeClass ==
     794             :                         typelib_TypeClass_SEQUENCE)
     795             :                     {
     796             :                         // Take care of recursion like
     797             :                         // struct S { sequence<S> x; };
     798        2020 :                         size = sizeof(void *);
     799        2020 :                         alignment = adjustAlignment(size);
     800             :                     } else {
     801       70833 :                         typelib_TypeDescription * pTD = 0;
     802       70833 :                         TYPELIB_DANGER_GET( &pTD, pTmp->ppTypeRefs[i] );
     803             :                         OSL_ENSURE( pTD->nSize, "### void member?" );
     804       70833 :                         size = pTD->nSize;
     805       70833 :                         alignment = pTD->nAlignment;
     806       70833 :                         TYPELIB_DANGER_RELEASE( pTD );
     807             :                     }
     808       72853 :                     nOffset = newAlignedSize( nOffset, size, alignment );
     809       72853 :                     pTmp->pMemberOffsets[i] = nOffset - size;
     810             : 
     811       72853 :                     if (polymorphic) {
     812             :                         reinterpret_cast< typelib_StructTypeDescription * >(
     813         602 :                             pTmp)->pParameterizedTypes[i]
     814         602 :                             = pStructMembers[i].bParameterizedType;
     815             :                     }
     816             :                 }
     817             :             }
     818             :         }
     819       40806 :         break;
     820             : 
     821             :         default:
     822       10646 :         break;
     823             :     }
     824             : 
     825       67561 :     if( !reallyWeak( eTypeClass ) )
     826       67561 :         (*ppRet)->pWeakRef = (typelib_TypeDescriptionReference *)*ppRet;
     827       67561 :     if( eTypeClass != typelib_TypeClass_VOID )
     828             :     {
     829             :         // sizeof( void ) not allowed
     830       66905 :         (*ppRet)->nSize = typelib_typedescription_getAlignedUnoSize( (*ppRet), 0, (*ppRet)->nAlignment );
     831       66905 :         (*ppRet)->nAlignment = adjustAlignment( (*ppRet)->nAlignment );
     832             :     }
     833             : }
     834             : 
     835             : }
     836             : 
     837       49709 : extern "C" CPPU_DLLPUBLIC 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       49709 :         ppRet, eTypeClass, pTypeName, pType, nMembers, pMembers, 0);
     848       49709 : }
     849             : 
     850       17852 : extern "C" CPPU_DLLPUBLIC 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       17852 :         pMembers);
     861       17852 : }
     862             : 
     863             : 
     864        7115 : extern "C" CPPU_DLLPUBLIC 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        7115 :     typelib_typedescription_newEmpty( ppRet, typelib_TypeClass_ENUM, pTypeName );
     874        7115 :     typelib_EnumTypeDescription * pEnum = (typelib_EnumTypeDescription *)*ppRet;
     875             : 
     876        7115 :     pEnum->nDefaultEnumValue = nDefaultValue;
     877        7115 :     pEnum->nEnumValues       = nEnumValues;
     878        7115 :     pEnum->ppEnumNames       = new rtl_uString * [ nEnumValues ];
     879       47347 :     for ( sal_Int32 nPos = nEnumValues; nPos--; )
     880             :     {
     881       33117 :         rtl_uString_acquire( pEnum->ppEnumNames[nPos] = ppEnumNames[nPos] );
     882             :     }
     883        7115 :     pEnum->pEnumValues      = new sal_Int32[ nEnumValues ];
     884        7115 :     ::memcpy( pEnum->pEnumValues, pEnumValues, nEnumValues * sizeof(sal_Int32) );
     885             : 
     886        7115 :     (*ppRet)->pWeakRef = (typelib_TypeDescriptionReference *)*ppRet;
     887             :     // sizeof( void ) not allowed
     888        7115 :     (*ppRet)->nSize = typelib_typedescription_getAlignedUnoSize( (*ppRet), 0, (*ppRet)->nAlignment );
     889        7115 :     (*ppRet)->nAlignment = adjustAlignment( (*ppRet)->nAlignment );
     890        7115 : }
     891             : 
     892             : 
     893         838 : extern "C" CPPU_DLLPUBLIC 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[array_vs_singleton]
     905             :     typelib_typedescription_newMIInterface(
     906             :         ppRet, pTypeName, 0, 0, 0, 0, 0, pBaseInterface == 0 ? 0 : 1,
     907         838 :         &pBaseInterface, nMembers, ppMembers);
     908         838 : }
     909             : 
     910             : 
     911             : 
     912             : namespace {
     913             : 
     914      230590 : class BaseList {
     915             : public:
     916             :     struct Entry {
     917             :         sal_Int32 memberOffset;
     918             :         sal_Int32 directBaseIndex;
     919             :         sal_Int32 directBaseMemberOffset;
     920             :         typelib_InterfaceTypeDescription const * base;
     921             :     };
     922             : 
     923             :     typedef std::vector< Entry > List;
     924             : 
     925             :     BaseList(typelib_InterfaceTypeDescription const * desc);
     926             : 
     927      230590 :     List const & getList() const { return list; }
     928             : 
     929      457179 :     sal_Int32 getBaseMembers() const { return members; }
     930             : 
     931             : private:
     932             :     typedef std::set< rtl::OUString > Set;
     933             : 
     934             :     void calculate(
     935             :         sal_Int32 directBaseIndex, Set & directBaseSet,
     936             :         sal_Int32 * directBaseMembers,
     937             :         typelib_InterfaceTypeDescription const * desc);
     938             : 
     939             :     Set set;
     940             :     List list;
     941             :     sal_Int32 members;
     942             : };
     943             : 
     944      230590 : BaseList::BaseList(typelib_InterfaceTypeDescription const * desc) {
     945      230590 :     members = 0;
     946      416231 :     for (sal_Int32 i = 0; i < desc->nBaseTypes; ++i) {
     947      185641 :         Set directBaseSet;
     948      185641 :         sal_Int32 directBaseMembers = 0;
     949      185641 :         calculate(i, directBaseSet, &directBaseMembers, desc->ppBaseTypes[i]);
     950      185641 :     }
     951      230590 : }
     952             : 
     953      269395 : void BaseList::calculate(
     954             :     sal_Int32 directBaseIndex, Set & directBaseSet,
     955             :     sal_Int32 * directBaseMembers,
     956             :     typelib_InterfaceTypeDescription const * desc)
     957             : {
     958      353149 :     for (sal_Int32 i = 0; i < desc->nBaseTypes; ++i) {
     959             :         calculate(
     960             :             directBaseIndex, directBaseSet, directBaseMembers,
     961       83754 :             desc->ppBaseTypes[i]);
     962             :     }
     963      269395 :     if (set.insert(desc->aBase.pTypeName).second) {
     964             :         Entry e;
     965      257389 :         e.memberOffset = members;
     966      257389 :         e.directBaseIndex = directBaseIndex;
     967      257389 :         e.directBaseMemberOffset = *directBaseMembers;
     968      257389 :         e.base = desc;
     969      257389 :         list.push_back(e);
     970             :         OSL_ASSERT(desc->ppAllMembers != 0);
     971      257389 :         members += desc->nMembers;
     972             :     }
     973      269395 :     if (directBaseSet.insert(desc->aBase.pTypeName).second) {
     974             :         OSL_ASSERT(desc->ppAllMembers != 0);
     975      268187 :         *directBaseMembers += desc->nMembers;
     976             :     }
     977      269395 : }
     978             : 
     979             : }
     980             : 
     981      230590 : extern "C" CPPU_DLLPUBLIC void SAL_CALL typelib_typedescription_newMIInterface(
     982             :     typelib_InterfaceTypeDescription ** ppRet,
     983             :     rtl_uString * pTypeName,
     984             :     SAL_UNUSED_PARAMETER sal_uInt32, SAL_UNUSED_PARAMETER sal_uInt16,
     985             :     SAL_UNUSED_PARAMETER sal_uInt16, SAL_UNUSED_PARAMETER sal_uInt32,
     986             :     SAL_UNUSED_PARAMETER sal_uInt32,
     987             :     sal_Int32 nBaseInterfaces,
     988             :     typelib_TypeDescriptionReference ** ppBaseInterfaces,
     989             :     sal_Int32 nMembers,
     990             :     typelib_TypeDescriptionReference ** ppMembers )
     991             :     SAL_THROW_EXTERN_C()
     992             : {
     993      230590 :     if (*ppRet != 0) {
     994           0 :         typelib_typedescription_release(&(*ppRet)->aBase);
     995           0 :         *ppRet = 0;
     996             :     }
     997             : 
     998      230590 :     typelib_InterfaceTypeDescription * pITD = 0;
     999             :     typelib_typedescription_newEmpty(
    1000      230590 :         (typelib_TypeDescription **)&pITD, typelib_TypeClass_INTERFACE, pTypeName );
    1001             : 
    1002      230590 :     pITD->nBaseTypes = nBaseInterfaces;
    1003      230590 :     pITD->ppBaseTypes = new typelib_InterfaceTypeDescription *[nBaseInterfaces];
    1004      416231 :     for (sal_Int32 i = 0; i < nBaseInterfaces; ++i) {
    1005      185641 :         pITD->ppBaseTypes[i] = 0;
    1006             :         typelib_typedescriptionreference_getDescription(
    1007             :             reinterpret_cast< typelib_TypeDescription ** >(
    1008             :                 &pITD->ppBaseTypes[i]),
    1009      185641 :             ppBaseInterfaces[i]);
    1010      371282 :         if (pITD->ppBaseTypes[i] == 0
    1011      371282 :             || !complete(
    1012             :                 reinterpret_cast< typelib_TypeDescription ** >(
    1013             :                     &pITD->ppBaseTypes[i]),
    1014      185641 :                 false))
    1015             :         {
    1016             :             OSL_ASSERT(false);
    1017           0 :             return;
    1018             :         }
    1019             :         OSL_ASSERT(pITD->ppBaseTypes[i] != 0);
    1020             :     }
    1021      230590 :     if (nBaseInterfaces > 0) {
    1022      175277 :         pITD->pBaseTypeDescription = pITD->ppBaseTypes[0];
    1023             :     }
    1024             :     // set the
    1025      230590 :     pITD->aUik.m_Data1 = 0;
    1026      230590 :     pITD->aUik.m_Data2 = 0;
    1027      230590 :     pITD->aUik.m_Data3 = 0;
    1028      230590 :     pITD->aUik.m_Data4 = 0;
    1029      230590 :     pITD->aUik.m_Data5 = 0;
    1030             : 
    1031      230590 :     BaseList aBaseList(pITD);
    1032      230590 :     pITD->nAllMembers = nMembers + aBaseList.getBaseMembers();
    1033      230590 :     pITD->nMembers = nMembers;
    1034             : 
    1035      230590 :     if( pITD->nAllMembers )
    1036             :     {
    1037             :         // at minimum one member exist, allocate the memory
    1038      230590 :         pITD->ppAllMembers = new typelib_TypeDescriptionReference *[ pITD->nAllMembers ];
    1039      230590 :         sal_Int32 n = 0;
    1040             : 
    1041      230590 :         BaseList::List const & rList = aBaseList.getList();
    1042      487979 :         for (BaseList::List::const_iterator i(rList.begin()); i != rList.end();
    1043             :              ++i)
    1044             :         {
    1045      257389 :             typelib_InterfaceTypeDescription const * pBase = i->base;
    1046             :             typelib_InterfaceTypeDescription const * pDirectBase
    1047      257389 :                 = pITD->ppBaseTypes[i->directBaseIndex];
    1048             :             OSL_ASSERT(pBase->ppAllMembers != 0);
    1049     1027911 :             for (sal_Int32 j = 0; j < pBase->nMembers; ++j) {
    1050             :                 typelib_TypeDescriptionReference const * pDirectBaseMember
    1051      770522 :                     = pDirectBase->ppAllMembers[i->directBaseMemberOffset + j];
    1052      770522 :                 rtl::OUStringBuffer aBuf(pDirectBaseMember->pTypeName);
    1053      770522 :                 aBuf.append(":@");
    1054      770522 :                 aBuf.append(i->directBaseIndex);
    1055      770522 :                 aBuf.append(',');
    1056      770522 :                 aBuf.append(i->memberOffset + j);
    1057      770522 :                 aBuf.append(':');
    1058      770522 :                 aBuf.append(pITD->aBase.pTypeName);
    1059     1541044 :                 rtl::OUString aName(aBuf.makeStringAndClear());
    1060      770522 :                 typelib_TypeDescriptionReference * pDerivedMember = 0;
    1061             :                 typelib_typedescriptionreference_new(
    1062             :                     &pDerivedMember, pDirectBaseMember->eTypeClass,
    1063      770522 :                     aName.pData);
    1064      770522 :                 pITD->ppAllMembers[n++] = pDerivedMember;
    1065      770522 :             }
    1066             :         }
    1067             : 
    1068      230590 :         if( nMembers )
    1069             :         {
    1070      226589 :             pITD->ppMembers = pITD->ppAllMembers + aBaseList.getBaseMembers();
    1071             :         }
    1072             : 
    1073             :         // add own members
    1074      927094 :         for( sal_Int32 i = 0; i < nMembers; i++ )
    1075             :         {
    1076      696504 :             typelib_typedescriptionreference_acquire( ppMembers[i] );
    1077      696504 :             pITD->ppAllMembers[n++] = ppMembers[i];
    1078             :         }
    1079             :     }
    1080             : 
    1081      230590 :     typelib_TypeDescription * pTmp = (typelib_TypeDescription *)pITD;
    1082      230590 :     if( !reallyWeak( typelib_TypeClass_INTERFACE ) )
    1083      230590 :         pTmp->pWeakRef = (typelib_TypeDescriptionReference *)pTmp;
    1084      230590 :     pTmp->nSize = typelib_typedescription_getAlignedUnoSize( pTmp, 0, pTmp->nAlignment );
    1085      230590 :     pTmp->nAlignment = adjustAlignment( pTmp->nAlignment );
    1086      230590 :     pTmp->bComplete = sal_False;
    1087             : 
    1088      230590 :     *ppRet = pITD;
    1089             : }
    1090             : 
    1091             : 
    1092             : 
    1093             : namespace {
    1094             : 
    1095      308823 : typelib_TypeDescriptionReference ** copyExceptions(
    1096             :     sal_Int32 count, rtl_uString ** typeNames)
    1097             : {
    1098             :     OSL_ASSERT(count >= 0);
    1099      308823 :     if (count == 0) {
    1100       38136 :         return 0;
    1101             :     }
    1102             :     typelib_TypeDescriptionReference ** p
    1103      270687 :         = new typelib_TypeDescriptionReference *[count];
    1104      731953 :     for (sal_Int32 i = 0; i < count; ++i) {
    1105      461266 :         p[i] = 0;
    1106             :         typelib_typedescriptionreference_new(
    1107      461266 :             p + i, typelib_TypeClass_EXCEPTION, typeNames[i]);
    1108             :     }
    1109      270687 :     return p;
    1110             : }
    1111             : 
    1112             : }
    1113             : 
    1114      293731 : extern "C" CPPU_DLLPUBLIC void SAL_CALL typelib_typedescription_newInterfaceMethod(
    1115             :     typelib_InterfaceMethodTypeDescription ** ppRet,
    1116             :     sal_Int32 nAbsolutePosition,
    1117             :     sal_Bool bOneWay,
    1118             :     rtl_uString * pTypeName,
    1119             :     typelib_TypeClass eReturnTypeClass,
    1120             :     rtl_uString * pReturnTypeName,
    1121             :     sal_Int32 nParams,
    1122             :     typelib_Parameter_Init * pParams,
    1123             :     sal_Int32 nExceptions,
    1124             :     rtl_uString ** ppExceptionNames )
    1125             :     SAL_THROW_EXTERN_C()
    1126             : {
    1127      293731 :     if (*ppRet != 0) {
    1128      162046 :         typelib_typedescription_release(&(*ppRet)->aBase.aBase);
    1129      162046 :         *ppRet = 0;
    1130             :     }
    1131             :     sal_Int32 nOffset = rtl_ustr_lastIndexOfChar_WithLength(
    1132      293731 :         pTypeName->buffer, pTypeName->length, ':');
    1133      293731 :     if (nOffset <= 0 || pTypeName->buffer[nOffset - 1] != ':') {
    1134             :         OSL_FAIL("Bad interface method type name");
    1135           0 :         return;
    1136             :     }
    1137      293731 :     rtl::OUString aInterfaceTypeName(pTypeName->buffer, nOffset - 1);
    1138      293731 :     typelib_InterfaceTypeDescription * pInterface = 0;
    1139             :     typelib_typedescription_getByName(
    1140             :         reinterpret_cast< typelib_TypeDescription ** >(&pInterface),
    1141      293731 :         aInterfaceTypeName.pData);
    1142      587462 :     if (pInterface == 0
    1143      293731 :         || pInterface->aBase.eTypeClass != typelib_TypeClass_INTERFACE
    1144      587462 :         || !complete(
    1145      293731 :             reinterpret_cast< typelib_TypeDescription ** >(&pInterface), false))
    1146             :     {
    1147             :         OSL_FAIL("No interface corresponding to interface method");
    1148           0 :         return;
    1149             :     }
    1150             : 
    1151             :     typelib_typedescription_newEmpty(
    1152      293731 :         (typelib_TypeDescription **)ppRet, typelib_TypeClass_INTERFACE_METHOD, pTypeName );
    1153      293731 :     typelib_TypeDescription * pTmp = (typelib_TypeDescription *)*ppRet;
    1154             : 
    1155             :     rtl_uString_newFromStr_WithLength( &(*ppRet)->aBase.pMemberName,
    1156      293731 :                                        pTypeName->buffer + nOffset +1,
    1157      587462 :                                        pTypeName->length - nOffset -1 );
    1158      293731 :     (*ppRet)->aBase.nPosition = nAbsolutePosition;
    1159      293731 :     (*ppRet)->bOneWay = bOneWay;
    1160      293731 :     typelib_typedescriptionreference_new( &(*ppRet)->pReturnTypeRef, eReturnTypeClass, pReturnTypeName );
    1161      293731 :     (*ppRet)->nParams = nParams;
    1162      293731 :     if( nParams )
    1163             :     {
    1164      169569 :         (*ppRet)->pParams = new typelib_MethodParameter[ nParams ];
    1165             : 
    1166      412276 :         for( sal_Int32 i = 0; i < nParams; i++ )
    1167             :         {
    1168             :             // get the name of the parameter
    1169      242707 :             (*ppRet)->pParams[ i ].pName = 0;
    1170      242707 :             rtl_uString_acquire( (*ppRet)->pParams[ i ].pName = pParams[i].pParamName );
    1171      242707 :             (*ppRet)->pParams[ i ].pTypeRef = 0;
    1172             :             // get the type name of the parameter and create the weak reference
    1173             :             typelib_typedescriptionreference_new(
    1174      242707 :                 &(*ppRet)->pParams[ i ].pTypeRef, pParams[i].eTypeClass, pParams[i].pTypeName );
    1175      242707 :             (*ppRet)->pParams[ i ].bIn = pParams[i].bIn;
    1176      242707 :             (*ppRet)->pParams[ i ].bOut = pParams[i].bOut;
    1177             :         }
    1178             :     }
    1179      293731 :     (*ppRet)->nExceptions = nExceptions;
    1180      293731 :     (*ppRet)->ppExceptions = copyExceptions(nExceptions, ppExceptionNames);
    1181      293731 :     (*ppRet)->pInterface = pInterface;
    1182      293731 :     (*ppRet)->pBaseRef = 0;
    1183             :     OSL_ASSERT(
    1184             :         (nAbsolutePosition >= pInterface->nAllMembers - pInterface->nMembers)
    1185             :         && nAbsolutePosition < pInterface->nAllMembers);
    1186             :     (*ppRet)->nIndex = nAbsolutePosition
    1187      293731 :         - (pInterface->nAllMembers - pInterface->nMembers);
    1188      293731 :     if( !reallyWeak( typelib_TypeClass_INTERFACE_METHOD ) )
    1189           0 :         pTmp->pWeakRef = (typelib_TypeDescriptionReference *)pTmp;
    1190             : }
    1191             : 
    1192             : 
    1193             : 
    1194           0 : extern "C" CPPU_DLLPUBLIC void SAL_CALL typelib_typedescription_newInterfaceAttribute(
    1195             :     typelib_InterfaceAttributeTypeDescription ** ppRet,
    1196             :     sal_Int32 nAbsolutePosition,
    1197             :     rtl_uString * pTypeName,
    1198             :     typelib_TypeClass eAttributeTypeClass,
    1199             :     rtl_uString * pAttributeTypeName,
    1200             :     sal_Bool bReadOnly )
    1201             :     SAL_THROW_EXTERN_C()
    1202             : {
    1203             :     typelib_typedescription_newExtendedInterfaceAttribute(
    1204             :         ppRet, nAbsolutePosition, pTypeName, eAttributeTypeClass,
    1205           0 :         pAttributeTypeName, bReadOnly, 0, 0, 0, 0);
    1206           0 : }
    1207             : 
    1208             : 
    1209        7546 : extern "C" CPPU_DLLPUBLIC void SAL_CALL typelib_typedescription_newExtendedInterfaceAttribute(
    1210             :     typelib_InterfaceAttributeTypeDescription ** ppRet,
    1211             :     sal_Int32 nAbsolutePosition,
    1212             :     rtl_uString * pTypeName,
    1213             :     typelib_TypeClass eAttributeTypeClass,
    1214             :     rtl_uString * pAttributeTypeName,
    1215             :     sal_Bool bReadOnly,
    1216             :     sal_Int32 nGetExceptions, rtl_uString ** ppGetExceptionNames,
    1217             :     sal_Int32 nSetExceptions, rtl_uString ** ppSetExceptionNames )
    1218             :     SAL_THROW_EXTERN_C()
    1219             : {
    1220        7546 :     if (*ppRet != 0) {
    1221           0 :         typelib_typedescription_release(&(*ppRet)->aBase.aBase);
    1222           0 :         *ppRet = 0;
    1223             :     }
    1224             :     sal_Int32 nOffset = rtl_ustr_lastIndexOfChar_WithLength(
    1225        7546 :         pTypeName->buffer, pTypeName->length, ':');
    1226        7546 :     if (nOffset <= 0 || pTypeName->buffer[nOffset - 1] != ':') {
    1227             :         OSL_FAIL("Bad interface attribute type name");
    1228           0 :         return;
    1229             :     }
    1230        7546 :     rtl::OUString aInterfaceTypeName(pTypeName->buffer, nOffset - 1);
    1231        7546 :     typelib_InterfaceTypeDescription * pInterface = 0;
    1232             :     typelib_typedescription_getByName(
    1233             :         reinterpret_cast< typelib_TypeDescription ** >(&pInterface),
    1234        7546 :         aInterfaceTypeName.pData);
    1235       15092 :     if (pInterface == 0
    1236        7546 :         || pInterface->aBase.eTypeClass != typelib_TypeClass_INTERFACE
    1237       15092 :         || !complete(
    1238        7546 :             reinterpret_cast< typelib_TypeDescription ** >(&pInterface), false))
    1239             :     {
    1240             :         OSL_FAIL("No interface corresponding to interface attribute");
    1241           0 :         return;
    1242             :     }
    1243             : 
    1244             :     typelib_typedescription_newEmpty(
    1245        7546 :         (typelib_TypeDescription **)ppRet, typelib_TypeClass_INTERFACE_ATTRIBUTE, pTypeName );
    1246        7546 :     typelib_TypeDescription * pTmp = (typelib_TypeDescription *)*ppRet;
    1247             : 
    1248             :     rtl_uString_newFromStr_WithLength( &(*ppRet)->aBase.pMemberName,
    1249        7546 :                                        pTypeName->buffer + nOffset +1,
    1250       15092 :                                        pTypeName->length - nOffset -1 );
    1251        7546 :     (*ppRet)->aBase.nPosition = nAbsolutePosition;
    1252        7546 :     typelib_typedescriptionreference_new( &(*ppRet)->pAttributeTypeRef, eAttributeTypeClass, pAttributeTypeName );
    1253        7546 :     (*ppRet)->bReadOnly = bReadOnly;
    1254        7546 :     (*ppRet)->pInterface = pInterface;
    1255        7546 :     (*ppRet)->pBaseRef = 0;
    1256             :     OSL_ASSERT(
    1257             :         (nAbsolutePosition >= pInterface->nAllMembers - pInterface->nMembers)
    1258             :         && nAbsolutePosition < pInterface->nAllMembers);
    1259             :     (*ppRet)->nIndex = nAbsolutePosition
    1260        7546 :         - (pInterface->nAllMembers - pInterface->nMembers);
    1261        7546 :     (*ppRet)->nGetExceptions = nGetExceptions;
    1262             :     (*ppRet)->ppGetExceptions = copyExceptions(
    1263        7546 :         nGetExceptions, ppGetExceptionNames);
    1264        7546 :     (*ppRet)->nSetExceptions = nSetExceptions;
    1265             :     (*ppRet)->ppSetExceptions = copyExceptions(
    1266        7546 :         nSetExceptions, ppSetExceptionNames);
    1267        7546 :     if( !reallyWeak( typelib_TypeClass_INTERFACE_ATTRIBUTE ) )
    1268           0 :         pTmp->pWeakRef = (typelib_TypeDescriptionReference *)pTmp;
    1269             : }
    1270             : 
    1271             : 
    1272     5945073 : extern "C" CPPU_DLLPUBLIC void SAL_CALL typelib_typedescription_acquire(
    1273             :     typelib_TypeDescription * pTypeDescription )
    1274             :     SAL_THROW_EXTERN_C()
    1275             : {
    1276     5945073 :     osl_atomic_increment( &pTypeDescription->nRefCount );
    1277     5945073 : }
    1278             : 
    1279             : 
    1280             : 
    1281             : namespace {
    1282             : 
    1283      341974 : void deleteExceptions(
    1284             :     sal_Int32 count, typelib_TypeDescriptionReference ** exceptions)
    1285             : {
    1286      811571 :     for (sal_Int32 i = 0; i < count; ++i) {
    1287      469597 :         typelib_typedescriptionreference_release(exceptions[i]);
    1288             :     }
    1289      341974 :     delete[] exceptions;
    1290      341974 : }
    1291             : 
    1292             : }
    1293             : 
    1294             : // frees anything except typelib_TypeDescription base!
    1295      716307 : static inline void typelib_typedescription_destructExtendedMembers(
    1296             :     typelib_TypeDescription * pTD )
    1297             : {
    1298             :     OSL_ASSERT( typelib_TypeClass_TYPEDEF != pTD->eTypeClass );
    1299             : 
    1300      716307 :     switch( pTD->eTypeClass )
    1301             :     {
    1302             :     case typelib_TypeClass_SEQUENCE:
    1303       17809 :         if( ((typelib_IndirectTypeDescription*)pTD)->pType )
    1304       11811 :             typelib_typedescriptionreference_release( ((typelib_IndirectTypeDescription*)pTD)->pType );
    1305       17809 :         break;
    1306             :     case typelib_TypeClass_STRUCT:
    1307             :         delete[] reinterpret_cast< typelib_StructTypeDescription * >(pTD)->
    1308       29321 :             pParameterizedTypes;
    1309             :         // Fall-through intentional
    1310             :     case typelib_TypeClass_EXCEPTION:
    1311             :     {
    1312       47555 :         typelib_CompoundTypeDescription * pCTD = (typelib_CompoundTypeDescription*)pTD;
    1313       47555 :         if( pCTD->pBaseTypeDescription )
    1314       16188 :             typelib_typedescription_release( (typelib_TypeDescription *)pCTD->pBaseTypeDescription );
    1315             :         sal_Int32 i;
    1316      110547 :         for( i = 0; i < pCTD->nMembers; i++ )
    1317             :         {
    1318       62992 :             typelib_typedescriptionreference_release( pCTD->ppTypeRefs[i] );
    1319             :         }
    1320       47555 :         if (pCTD->ppMemberNames)
    1321             :         {
    1322       81173 :             for ( i = 0; i < pCTD->nMembers; i++ )
    1323             :             {
    1324       62990 :                 rtl_uString_release( pCTD->ppMemberNames[i] );
    1325             :             }
    1326       18183 :             delete [] pCTD->ppMemberNames;
    1327             :         }
    1328       47555 :         delete [] pCTD->ppTypeRefs;
    1329       47555 :         delete [] pCTD->pMemberOffsets;
    1330             :     }
    1331       47555 :     break;
    1332             :     case typelib_TypeClass_INTERFACE:
    1333             :     {
    1334      293282 :         typelib_InterfaceTypeDescription * pITD = (typelib_InterfaceTypeDescription*)pTD;
    1335     1551780 :         for( sal_Int32 i = 0; i < pITD->nAllMembers; i++ )
    1336             :         {
    1337     1258498 :             typelib_typedescriptionreference_release( pITD->ppAllMembers[i] );
    1338             :         }
    1339      293282 :         delete [] pITD->ppAllMembers;
    1340      293282 :         delete [] pITD->pMapMemberIndexToFunctionIndex;
    1341      293282 :         delete [] pITD->pMapFunctionIndexToMemberIndex;
    1342      449851 :         for (sal_Int32 i = 0; i < pITD->nBaseTypes; ++i) {
    1343             :             typelib_typedescription_release(
    1344             :                 reinterpret_cast< typelib_TypeDescription * >(
    1345      156569 :                     pITD->ppBaseTypes[i]));
    1346             :         }
    1347      293282 :         delete[] pITD->ppBaseTypes;
    1348      293282 :         break;
    1349             :     }
    1350             :     case typelib_TypeClass_INTERFACE_METHOD:
    1351             :     {
    1352      325806 :         typelib_InterfaceMethodTypeDescription * pIMTD = (typelib_InterfaceMethodTypeDescription*)pTD;
    1353      325806 :         if( pIMTD->pReturnTypeRef )
    1354      325806 :             typelib_typedescriptionreference_release( pIMTD->pReturnTypeRef );
    1355      574062 :         for( sal_Int32 i = 0; i < pIMTD->nParams; i++ )
    1356             :         {
    1357      248256 :             rtl_uString_release( pIMTD->pParams[ i ].pName );
    1358      248256 :             typelib_typedescriptionreference_release( pIMTD->pParams[ i ].pTypeRef );
    1359             :         }
    1360      325806 :         delete [] pIMTD->pParams;
    1361      325806 :         deleteExceptions(pIMTD->nExceptions, pIMTD->ppExceptions);
    1362      325806 :         rtl_uString_release( pIMTD->aBase.pMemberName );
    1363      325806 :         typelib_typedescription_release(&pIMTD->pInterface->aBase);
    1364      325806 :         if (pIMTD->pBaseRef != 0) {
    1365       43518 :             typelib_typedescriptionreference_release(pIMTD->pBaseRef);
    1366             :         }
    1367             :     }
    1368      325806 :     break;
    1369             :     case typelib_TypeClass_INTERFACE_ATTRIBUTE:
    1370             :     {
    1371        8084 :         typelib_InterfaceAttributeTypeDescription * pIATD = (typelib_InterfaceAttributeTypeDescription*)pTD;
    1372        8084 :         deleteExceptions(pIATD->nGetExceptions, pIATD->ppGetExceptions);
    1373        8084 :         deleteExceptions(pIATD->nSetExceptions, pIATD->ppSetExceptions);
    1374        8084 :         if( pIATD->pAttributeTypeRef )
    1375        8084 :             typelib_typedescriptionreference_release( pIATD->pAttributeTypeRef );
    1376        8084 :         if( pIATD->aBase.pMemberName )
    1377        8084 :             rtl_uString_release( pIATD->aBase.pMemberName );
    1378        8084 :         typelib_typedescription_release(&pIATD->pInterface->aBase);
    1379        8084 :         if (pIATD->pBaseRef != 0) {
    1380        1746 :             typelib_typedescriptionreference_release(pIATD->pBaseRef);
    1381             :         }
    1382             :     }
    1383        8084 :     break;
    1384             :     case typelib_TypeClass_ENUM:
    1385             :     {
    1386       14983 :         typelib_EnumTypeDescription * pEnum = (typelib_EnumTypeDescription *)pTD;
    1387       60510 :         for ( sal_Int32 nPos = pEnum->nEnumValues; nPos--; )
    1388             :         {
    1389       30544 :             rtl_uString_release( pEnum->ppEnumNames[nPos] );
    1390             :         }
    1391       14983 :         delete [] pEnum->ppEnumNames;
    1392       14983 :         delete [] pEnum->pEnumValues;
    1393             :     }
    1394       14983 :     break;
    1395             :     default:
    1396        8788 :     break;
    1397             :     }
    1398      716307 : }
    1399             : 
    1400             : 
    1401   577017415 : extern "C" CPPU_DLLPUBLIC void SAL_CALL typelib_typedescription_release(
    1402             :     typelib_TypeDescription * pTD )
    1403             :     SAL_THROW_EXTERN_C()
    1404             : {
    1405   577017415 :     sal_Int32 ref = osl_atomic_decrement( &pTD->nRefCount );
    1406             :     OSL_ASSERT(ref >= 0);
    1407   577017415 :     if (0 == ref)
    1408             :     {
    1409      716303 :         TypeDescriptor_Init_Impl &rInit = Init::get();
    1410      716303 :         if( reallyWeak( pTD->eTypeClass ) )
    1411             :         {
    1412      333890 :             if( pTD->pWeakRef )
    1413             :             {
    1414             :                 {
    1415      133657 :                 MutexGuard aGuard( rInit.getMutex() );
    1416             :                 // remove this description from the weak reference
    1417      133657 :                 pTD->pWeakRef->pType = 0;
    1418             :                 }
    1419      133657 :                 typelib_typedescriptionreference_release( pTD->pWeakRef );
    1420             :             }
    1421             :         }
    1422             :         else
    1423             :         {
    1424             :             // this description is a reference too, so remove it from the hash table
    1425      382413 :             if( rInit.pWeakMap )
    1426             :             {
    1427      382413 :                 MutexGuard aGuard( rInit.getMutex() );
    1428      382413 :                 WeakMap_Impl::iterator aIt = rInit.pWeakMap->find( (sal_Unicode*)pTD->pTypeName->buffer );
    1429      382413 :                 if( aIt != rInit.pWeakMap->end() && (void *)(*aIt).second == (void *)pTD )
    1430             :                 {
    1431             :                     // remove only if it contains the same object
    1432      136156 :                     rInit.pWeakMap->erase( aIt );
    1433      382413 :                 }
    1434             :             }
    1435             :         }
    1436             : 
    1437      716303 :         typelib_typedescription_destructExtendedMembers( pTD );
    1438      716303 :         rtl_uString_release( pTD->pTypeName );
    1439             : 
    1440             : #if OSL_DEBUG_LEVEL > 1
    1441             :         switch( pTD->eTypeClass )
    1442             :         {
    1443             :         case typelib_TypeClass_SEQUENCE:
    1444             :             osl_atomic_decrement( &rInit.nIndirectTypeDescriptionCount );
    1445             :             break;
    1446             :         case typelib_TypeClass_STRUCT:
    1447             :         case typelib_TypeClass_EXCEPTION:
    1448             :             osl_atomic_decrement( &rInit.nCompoundTypeDescriptionCount );
    1449             :             break;
    1450             :         case typelib_TypeClass_INTERFACE:
    1451             :             osl_atomic_decrement( &rInit.nInterfaceTypeDescriptionCount );
    1452             :             break;
    1453             :         case typelib_TypeClass_INTERFACE_METHOD:
    1454             :             osl_atomic_decrement( &rInit.nInterfaceMethodTypeDescriptionCount );
    1455             :             break;
    1456             :         case typelib_TypeClass_INTERFACE_ATTRIBUTE:
    1457             :             osl_atomic_decrement( &rInit.nInterfaceAttributeTypeDescriptionCount );
    1458             :             break;
    1459             :         case typelib_TypeClass_ENUM:
    1460             :             osl_atomic_decrement( &rInit.nEnumTypeDescriptionCount );
    1461             :             break;
    1462             :         default:
    1463             :             osl_atomic_decrement( &rInit.nTypeDescriptionCount );
    1464             :         }
    1465             : #endif
    1466             : 
    1467      716303 :         delete pTD;
    1468             :     }
    1469   577017415 : }
    1470             : 
    1471             : 
    1472      668184 : extern "C" CPPU_DLLPUBLIC void SAL_CALL typelib_typedescription_register(
    1473             :     typelib_TypeDescription ** ppNewDescription )
    1474             :     SAL_THROW_EXTERN_C()
    1475             : {
    1476             :     // connect the description with the weak reference
    1477      668184 :     TypeDescriptor_Init_Impl &rInit = Init::get();
    1478      668184 :     ClearableMutexGuard aGuard( rInit.getMutex() );
    1479             : 
    1480      668184 :     typelib_TypeDescriptionReference * pTDR = 0;
    1481      668184 :     typelib_typedescriptionreference_getByName( &pTDR, (*ppNewDescription)->pTypeName );
    1482             : 
    1483             :     OSL_ASSERT( (*ppNewDescription)->pWeakRef || reallyWeak( (*ppNewDescription)->eTypeClass ) );
    1484      668184 :     if( pTDR )
    1485             :     {
    1486             :         OSL_ASSERT( (*ppNewDescription)->eTypeClass == pTDR->eTypeClass );
    1487      609145 :         if( pTDR->pType )
    1488             :         {
    1489      446490 :             if (reallyWeak( pTDR->eTypeClass ))
    1490             :             {
    1491             :                 // pRef->pType->pWeakRef == 0 means that the description is empty
    1492      200233 :                 if (pTDR->pType->pWeakRef)
    1493             :                 {
    1494      200233 :                     if (osl_atomic_increment( &pTDR->pType->nRefCount ) > 1)
    1495             :                     {
    1496             :                         // The refence is incremented. The object cannot be destroyed.
    1497             :                         // Release the guard at the earliest point.
    1498      200233 :                         aGuard.clear();
    1499      200233 :                         ::typelib_typedescription_release( *ppNewDescription );
    1500      200233 :                         *ppNewDescription = pTDR->pType;
    1501      200233 :                         ::typelib_typedescriptionreference_release( pTDR );
    1502      200233 :                         return;
    1503             :                     }
    1504             :                     else
    1505             :                     {
    1506             :                         // destruction of this type in progress (another thread!)
    1507           0 :                         (void)osl_atomic_decrement( &pTDR->pType->nRefCount );
    1508             :                     }
    1509             :                 }
    1510             :                 // take new descr
    1511           0 :                 pTDR->pType = *ppNewDescription;
    1512             :                 OSL_ASSERT( ! (*ppNewDescription)->pWeakRef );
    1513           0 :                 (*ppNewDescription)->pWeakRef = pTDR;
    1514           0 :                 return;
    1515             :             }
    1516             :             // !reallyWeak
    1517             : 
    1518      492514 :             if (((void *)pTDR != (void *)*ppNewDescription) && // if different
    1519      424837 :                 (!pTDR->pType->pWeakRef || // uninit: ref data only set
    1520             :                  // new one is complete:
    1521      448344 :                  (!pTDR->pType->bComplete && (*ppNewDescription)->bComplete) ||
    1522             :                  // new one may be partly initialized interface (except of tables):
    1523      327813 :                  (typelib_TypeClass_INTERFACE == pTDR->pType->eTypeClass &&
    1524      149237 :                   !((typelib_InterfaceTypeDescription *)pTDR->pType)->ppAllMembers &&
    1525             :                   (*(typelib_InterfaceTypeDescription **)ppNewDescription)->ppAllMembers)))
    1526             :             {
    1527             :                 // uninitialized or incomplete
    1528             : 
    1529       67681 :                 if (pTDR->pType->pWeakRef) // if init
    1530             :                 {
    1531           4 :                     typelib_typedescription_destructExtendedMembers( pTDR->pType );
    1532             :                 }
    1533             : 
    1534             :                 // pTDR->pType->pWeakRef == 0 means that the description is empty
    1535             :                 // description is not weak and the not the same
    1536       67681 :                 sal_Int32 nSize = getDescriptionSize( (*ppNewDescription)->eTypeClass );
    1537             : 
    1538             :                 // copy all specific data for the descriptions
    1539             :                 memcpy(
    1540       67681 :                     pTDR->pType +1,
    1541             :                     *ppNewDescription +1,
    1542      135362 :                     nSize - sizeof(typelib_TypeDescription) );
    1543             : 
    1544       67681 :                 pTDR->pType->bComplete = (*ppNewDescription)->bComplete;
    1545       67681 :                 pTDR->pType->nSize = (*ppNewDescription)->nSize;
    1546       67681 :                 pTDR->pType->nAlignment = (*ppNewDescription)->nAlignment;
    1547             : 
    1548             :                 memset(
    1549       67681 :                     *ppNewDescription +1,
    1550             :                     0,
    1551      135362 :                     nSize - sizeof( typelib_TypeDescription ) );
    1552             : 
    1553       67681 :                 if( pTDR->pType->bOnDemand && !(*ppNewDescription)->bOnDemand )
    1554             :                 {
    1555             :                     // switch from OnDemand to !OnDemand, so the description must be acquired
    1556       13877 :                     typelib_typedescription_acquire( pTDR->pType );
    1557             :                 }
    1558       53804 :                 else if( !pTDR->pType->bOnDemand && (*ppNewDescription)->bOnDemand )
    1559             :                 {
    1560             :                     // switch from !OnDemand to OnDemand, so the description must be relesed
    1561           0 :                     typelib_typedescription_release( pTDR->pType );
    1562             :                 }
    1563             : 
    1564       67681 :                 pTDR->pType->bOnDemand = (*ppNewDescription)->bOnDemand;
    1565             :                 // initialized
    1566       67681 :                 pTDR->pType->pWeakRef = pTDR;
    1567             :             }
    1568             : 
    1569      246257 :             typelib_typedescription_release( *ppNewDescription );
    1570             :             // pTDR was acquired by getByName(), so it must not be acquired again
    1571      246257 :             *ppNewDescription = pTDR->pType;
    1572      246257 :             return;
    1573             :         }
    1574             :     }
    1575       59039 :     else if( reallyWeak( (*ppNewDescription)->eTypeClass) )
    1576             :     {
    1577             :         typelib_typedescriptionreference_new(
    1578           0 :             &pTDR, (*ppNewDescription)->eTypeClass, (*ppNewDescription)->pTypeName );
    1579             :     }
    1580             :     else
    1581             :     {
    1582       59039 :         pTDR = (typelib_TypeDescriptionReference *)*ppNewDescription;
    1583       59039 :         if( !rInit.pWeakMap )
    1584           0 :             rInit.pWeakMap = new WeakMap_Impl;
    1585             : 
    1586             :         // description is the weak itself, so register it
    1587       59039 :         (*rInit.pWeakMap)[pTDR->pTypeName->buffer] = pTDR;
    1588             :         OSL_ASSERT( (void *)*ppNewDescription == (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      221694 :     if( !(*ppNewDescription)->bOnDemand )
    1594             :     {
    1595             :         // nor OnDemand so the description must be acquired if registered
    1596      116517 :         typelib_typedescription_acquire( *ppNewDescription );
    1597             :     }
    1598             : 
    1599      221694 :     pTDR->pType = *ppNewDescription;
    1600      221694 :     (*ppNewDescription)->pWeakRef = pTDR;
    1601             :     OSL_ASSERT( rtl_ustr_compare( pTDR->pTypeName->buffer, (*ppNewDescription)->pTypeName->buffer ) == 0 );
    1602      221694 :     OSL_ASSERT( pTDR->eTypeClass == (*ppNewDescription)->eTypeClass );
    1603             : }
    1604             : 
    1605             : 
    1606      266196 : static inline bool type_equals(
    1607             :     typelib_TypeDescriptionReference * p1, typelib_TypeDescriptionReference * p2 )
    1608             : {
    1609      532392 :     return (p1 == p2 ||
    1610       89115 :             (p1->eTypeClass == p2->eTypeClass &&
    1611       44480 :              p1->pTypeName->length == p2->pTypeName->length &&
    1612      267018 :              rtl_ustr_compare( p1->pTypeName->buffer, p2->pTypeName->buffer ) == 0));
    1613             : }
    1614       49110 : extern "C" CPPU_DLLPUBLIC 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       49110 :         (typelib_TypeDescriptionReference *)p1, (typelib_TypeDescriptionReference *)p2 );
    1620             : }
    1621             : 
    1622             : 
    1623      372630 : 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      372630 :     if( pTypeDescription->nSize )
    1630             :     {
    1631             :         // size and alignment are set
    1632       67990 :         rMaxIntegralTypeSize = pTypeDescription->nAlignment;
    1633       67990 :         nSize = pTypeDescription->nSize;
    1634             :     }
    1635             :     else
    1636             :     {
    1637      304640 :         nSize = 0;
    1638      304640 :         rMaxIntegralTypeSize = 1;
    1639             : 
    1640             :         OSL_ASSERT( typelib_TypeClass_TYPEDEF != pTypeDescription->eTypeClass );
    1641             : 
    1642      304640 :         switch( pTypeDescription->eTypeClass )
    1643             :         {
    1644             :             case typelib_TypeClass_INTERFACE:
    1645             :                 // FEATURE_INTERFACE
    1646      230596 :                 nSize = rMaxIntegralTypeSize = (sal_Int32)(sizeof( void * ));
    1647      230596 :                 break;
    1648             :             case typelib_TypeClass_ENUM:
    1649        7115 :                 nSize = rMaxIntegralTypeSize = (sal_Int32)(sizeof( typelib_TypeClass ));
    1650        7115 :                 break;
    1651             :             case typelib_TypeClass_STRUCT:
    1652             :             case typelib_TypeClass_EXCEPTION:
    1653             :                 // FEATURE_EMPTYCLASS
    1654             :                 {
    1655       40830 :                 typelib_CompoundTypeDescription * pTmp = (typelib_CompoundTypeDescription *)pTypeDescription;
    1656       40830 :                 sal_Int32 nStructSize = 0;
    1657       40830 :                 if( pTmp->pBaseTypeDescription )
    1658             :                 {
    1659             :                     // inherit structs extends the base struct.
    1660       22823 :                     nStructSize = pTmp->pBaseTypeDescription->aBase.nSize;
    1661       22823 :                     rMaxIntegralTypeSize = pTmp->pBaseTypeDescription->aBase.nAlignment;
    1662             :                  }
    1663      113685 :                 for( sal_Int32 i = 0; i < pTmp->nMembers; i++ )
    1664             :                 {
    1665       72855 :                     typelib_TypeDescription * pMemberType = 0;
    1666       72855 :                     typelib_TypeDescriptionReference * pMemberRef = pTmp->ppTypeRefs[i];
    1667             : 
    1668             :                     sal_Int32 nMaxIntegral;
    1669       72855 :                     if (pMemberRef->eTypeClass == typelib_TypeClass_INTERFACE
    1670       70010 :                         || pMemberRef->eTypeClass == typelib_TypeClass_SEQUENCE)
    1671             :                     {
    1672        4865 :                         nMaxIntegral = (sal_Int32)(sizeof(void *));
    1673        4865 :                         nStructSize = newAlignedSize( nStructSize, nMaxIntegral, nMaxIntegral );
    1674             :                     }
    1675             :                     else
    1676             :                     {
    1677       67990 :                         TYPELIB_DANGER_GET( &pMemberType, pMemberRef );
    1678             :                         nStructSize = typelib_typedescription_getAlignedUnoSize(
    1679       67990 :                             pMemberType, nStructSize, nMaxIntegral );
    1680       67990 :                         TYPELIB_DANGER_RELEASE( pMemberType );
    1681             :                     }
    1682       72855 :                     if( nMaxIntegral > rMaxIntegralTypeSize )
    1683       18904 :                         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       40830 :                 nStructSize = (nStructSize + rMaxIntegralTypeSize -1)
    1695       40830 :                                 / rMaxIntegralTypeSize * rMaxIntegralTypeSize;
    1696             : #endif
    1697       40830 :                 nSize += nStructSize;
    1698             :                 }
    1699       40830 :                 break;
    1700             :             case typelib_TypeClass_SEQUENCE:
    1701       16109 :                 nSize = rMaxIntegralTypeSize = (sal_Int32)(sizeof( void * ));
    1702       16109 :                 break;
    1703             :             case typelib_TypeClass_ANY:
    1704             :                 // FEATURE_ANY
    1705         656 :                 nSize = (sal_Int32)(sizeof( uno_Any ));
    1706         656 :                 rMaxIntegralTypeSize = (sal_Int32)(sizeof( void * ));
    1707         656 :                 break;
    1708             :             case typelib_TypeClass_TYPE:
    1709         656 :                 nSize = rMaxIntegralTypeSize = (sal_Int32)(sizeof( typelib_TypeDescriptionReference * ));
    1710         656 :                 break;
    1711             :             case typelib_TypeClass_BOOLEAN:
    1712         656 :                 nSize = rMaxIntegralTypeSize = (sal_Int32)(sizeof( sal_Bool ));
    1713         656 :                 break;
    1714             :             case typelib_TypeClass_CHAR:
    1715         656 :                 nSize = rMaxIntegralTypeSize = (sal_Int32)(sizeof( sal_Unicode ));
    1716         656 :                 break;
    1717             :             case typelib_TypeClass_STRING:
    1718             :                 // FEATURE_STRING
    1719         656 :                 nSize = rMaxIntegralTypeSize = (sal_Int32)(sizeof( rtl_uString * ));
    1720         656 :                 break;
    1721             :             case typelib_TypeClass_FLOAT:
    1722         656 :                 nSize = rMaxIntegralTypeSize = (sal_Int32)(sizeof( float ));
    1723         656 :                 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         688 :                 nSize = rMaxIntegralTypeSize = (sal_Int32)(sizeof( double ));
    1731             : #endif
    1732         688 :                 break;
    1733             :             case typelib_TypeClass_BYTE:
    1734         656 :                 nSize = rMaxIntegralTypeSize = (sal_Int32)(sizeof( sal_Int8 ));
    1735         656 :                 break;
    1736             :             case typelib_TypeClass_SHORT:
    1737             :             case typelib_TypeClass_UNSIGNED_SHORT:
    1738        1312 :                 nSize = rMaxIntegralTypeSize = (sal_Int32)(sizeof( sal_Int16 ));
    1739        1312 :                 break;
    1740             :             case typelib_TypeClass_LONG:
    1741             :             case typelib_TypeClass_UNSIGNED_LONG:
    1742        2086 :                 nSize = rMaxIntegralTypeSize = (sal_Int32)(sizeof( sal_Int32 ));
    1743        2086 :                 break;
    1744             :             case typelib_TypeClass_HYPER:
    1745             :             case typelib_TypeClass_UNSIGNED_HYPER:
    1746        1312 :                 nSize = rMaxIntegralTypeSize = (sal_Int32)(sizeof( sal_Int64 ));
    1747        1312 :                 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      372630 :     return newAlignedSize( nOffset, nSize, rMaxIntegralTypeSize );
    1757             : }
    1758             : 
    1759             : 
    1760             : 
    1761             : namespace {
    1762             : 
    1763       63959 : typelib_TypeDescriptionReference ** copyExceptions(
    1764             :     sal_Int32 count, typelib_TypeDescriptionReference ** source)
    1765             : {
    1766             :     typelib_TypeDescriptionReference ** p
    1767       63959 :         = new typelib_TypeDescriptionReference *[count];
    1768       91636 :     for (sal_Int32 i = 0; i < count; ++i) {
    1769       27677 :         typelib_typedescriptionreference_acquire(p[i] = source[i]);
    1770             :     }
    1771       63959 :     return p;
    1772             : }
    1773             : 
    1774       61611 : 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       61611 :     if (baseRef != 0 && base != 0 && interface != 0) {
    1781       61611 :         switch (base->eTypeClass) {
    1782             :         case typelib_TypeClass_INTERFACE_METHOD:
    1783             :             {
    1784             :                 typelib_typedescription_newEmpty(
    1785       59263 :                     result, typelib_TypeClass_INTERFACE_METHOD, name.pData);
    1786             :                 typelib_InterfaceMethodTypeDescription const * baseMethod
    1787             :                     = reinterpret_cast<
    1788       59263 :                     typelib_InterfaceMethodTypeDescription const * >(base);
    1789             :                 typelib_InterfaceMethodTypeDescription * newMethod
    1790             :                     = reinterpret_cast<
    1791       59263 :                     typelib_InterfaceMethodTypeDescription * >(*result);
    1792       59263 :                 newMethod->aBase.nPosition = position;
    1793             :                 rtl_uString_acquire(
    1794             :                     newMethod->aBase.pMemberName
    1795       59263 :                     = baseMethod->aBase.pMemberName);
    1796             :                 typelib_typedescriptionreference_acquire(
    1797       59263 :                     newMethod->pReturnTypeRef = baseMethod->pReturnTypeRef);
    1798       59263 :                 newMethod->nParams = baseMethod->nParams;
    1799             :                 newMethod->pParams = new typelib_MethodParameter[
    1800       59263 :                     newMethod->nParams];
    1801       84582 :                 for (sal_Int32 i = 0; i < newMethod->nParams; ++i) {
    1802             :                     rtl_uString_acquire(
    1803       25319 :                         newMethod->pParams[i].pName
    1804       25319 :                         = baseMethod->pParams[i].pName);
    1805             :                     typelib_typedescriptionreference_acquire(
    1806       25319 :                         newMethod->pParams[i].pTypeRef
    1807       25319 :                         = baseMethod->pParams[i].pTypeRef);
    1808       25319 :                     newMethod->pParams[i].bIn = baseMethod->pParams[i].bIn;
    1809       25319 :                     newMethod->pParams[i].bOut = baseMethod->pParams[i].bOut;
    1810             :                 }
    1811       59263 :                 newMethod->nExceptions = baseMethod->nExceptions;
    1812             :                 newMethod->ppExceptions = copyExceptions(
    1813       59263 :                     baseMethod->nExceptions, baseMethod->ppExceptions);
    1814       59263 :                 newMethod->bOneWay = baseMethod->bOneWay;
    1815             :                 newMethod->pInterface
    1816             :                     = reinterpret_cast< typelib_InterfaceTypeDescription * >(
    1817       59263 :                         interface);
    1818       59263 :                 newMethod->pBaseRef = baseRef;
    1819       59263 :                 newMethod->nIndex = index;
    1820       59263 :                 return true;
    1821             :             }
    1822             : 
    1823             :         case typelib_TypeClass_INTERFACE_ATTRIBUTE:
    1824             :             {
    1825             :                 typelib_typedescription_newEmpty(
    1826        2348 :                     result, typelib_TypeClass_INTERFACE_ATTRIBUTE, name.pData);
    1827             :                 typelib_InterfaceAttributeTypeDescription const * baseAttribute
    1828             :                     = reinterpret_cast<
    1829        2348 :                     typelib_InterfaceAttributeTypeDescription const * >(base);
    1830             :                 typelib_InterfaceAttributeTypeDescription * newAttribute
    1831             :                     = reinterpret_cast<
    1832        2348 :                     typelib_InterfaceAttributeTypeDescription * >(*result);
    1833        2348 :                 newAttribute->aBase.nPosition = position;
    1834             :                 rtl_uString_acquire(
    1835             :                     newAttribute->aBase.pMemberName
    1836        2348 :                     = baseAttribute->aBase.pMemberName);
    1837        2348 :                 newAttribute->bReadOnly = baseAttribute->bReadOnly;
    1838             :                 typelib_typedescriptionreference_acquire(
    1839             :                     newAttribute->pAttributeTypeRef
    1840        2348 :                     = baseAttribute->pAttributeTypeRef);
    1841             :                 newAttribute->pInterface
    1842             :                     = reinterpret_cast< typelib_InterfaceTypeDescription * >(
    1843        2348 :                         interface);
    1844        2348 :                 newAttribute->pBaseRef = baseRef;
    1845        2348 :                 newAttribute->nIndex = index;
    1846        2348 :                 newAttribute->nGetExceptions = baseAttribute->nGetExceptions;
    1847             :                 newAttribute->ppGetExceptions = copyExceptions(
    1848             :                     baseAttribute->nGetExceptions,
    1849        2348 :                     baseAttribute->ppGetExceptions);
    1850        2348 :                 newAttribute->nSetExceptions = baseAttribute->nSetExceptions;
    1851             :                 newAttribute->ppSetExceptions = copyExceptions(
    1852             :                     baseAttribute->nSetExceptions,
    1853        2348 :                     baseAttribute->ppSetExceptions);
    1854        2348 :                 return true;
    1855             :             }
    1856             : 
    1857             :         default:
    1858           0 :             break;
    1859             :         }
    1860             :     }
    1861           0 :     return false;
    1862             : }
    1863             : 
    1864             : }
    1865             : 
    1866      613113 : extern "C" CPPU_DLLPUBLIC void SAL_CALL typelib_typedescription_getByName(
    1867             :     typelib_TypeDescription ** ppRet, rtl_uString * pName )
    1868             :     SAL_THROW_EXTERN_C()
    1869             : {
    1870      613113 :     if( *ppRet )
    1871             :     {
    1872           8 :         typelib_typedescription_release( (*ppRet) );
    1873           8 :         *ppRet = 0;
    1874             :     }
    1875             : 
    1876             :     static bool bInited = false;
    1877      613113 :     TypeDescriptor_Init_Impl &rInit = Init::get();
    1878             : 
    1879      613113 :     if( !bInited )
    1880             :     {
    1881             :         // guard against multi thread access
    1882         656 :         MutexGuard aGuard( rInit.getMutex() );
    1883         656 :         if( !bInited )
    1884             :         {
    1885             :             // avoid recursion during the next ...new calls
    1886         656 :             bInited = true;
    1887             : 
    1888         656 :             rtl_uString * pTypeName = 0;
    1889         656 :             typelib_TypeDescription * pType = 0;
    1890         656 :             rtl_uString_newFromAscii( &pTypeName, "type" );
    1891         656 :             typelib_typedescription_new( &pType, typelib_TypeClass_TYPE, pTypeName, 0, 0, 0 );
    1892         656 :             typelib_typedescription_register( &pType );
    1893         656 :             rtl_uString_newFromAscii( &pTypeName, "void" );
    1894         656 :             typelib_typedescription_new( &pType, typelib_TypeClass_VOID, pTypeName, 0, 0, 0 );
    1895         656 :             typelib_typedescription_register( &pType );
    1896         656 :             rtl_uString_newFromAscii( &pTypeName, "boolean" );
    1897         656 :             typelib_typedescription_new( &pType, typelib_TypeClass_BOOLEAN, pTypeName, 0, 0, 0 );
    1898         656 :             typelib_typedescription_register( &pType );
    1899         656 :             rtl_uString_newFromAscii( &pTypeName, "char" );
    1900         656 :             typelib_typedescription_new( &pType, typelib_TypeClass_CHAR, pTypeName, 0, 0, 0 );
    1901         656 :             typelib_typedescription_register( &pType );
    1902         656 :             rtl_uString_newFromAscii( &pTypeName, "byte" );
    1903         656 :             typelib_typedescription_new( &pType, typelib_TypeClass_BYTE, pTypeName, 0, 0, 0 );
    1904         656 :             typelib_typedescription_register( &pType );
    1905         656 :             rtl_uString_newFromAscii( &pTypeName, "string" );
    1906         656 :             typelib_typedescription_new( &pType, typelib_TypeClass_STRING, pTypeName, 0, 0, 0 );
    1907         656 :             typelib_typedescription_register( &pType );
    1908         656 :             rtl_uString_newFromAscii( &pTypeName, "short" );
    1909         656 :             typelib_typedescription_new( &pType, typelib_TypeClass_SHORT, pTypeName, 0, 0, 0 );
    1910         656 :             typelib_typedescription_register( &pType );
    1911         656 :             rtl_uString_newFromAscii( &pTypeName, "unsigned short" );
    1912         656 :             typelib_typedescription_new( &pType, typelib_TypeClass_UNSIGNED_SHORT, pTypeName, 0, 0, 0 );
    1913         656 :             typelib_typedescription_register( &pType );
    1914         656 :             rtl_uString_newFromAscii( &pTypeName, "long" );
    1915         656 :             typelib_typedescription_new( &pType, typelib_TypeClass_LONG, pTypeName, 0, 0, 0 );
    1916         656 :             typelib_typedescription_register( &pType );
    1917         656 :             rtl_uString_newFromAscii( &pTypeName, "unsigned long" );
    1918         656 :             typelib_typedescription_new( &pType, typelib_TypeClass_UNSIGNED_LONG, pTypeName, 0, 0, 0 );
    1919         656 :             typelib_typedescription_register( &pType );
    1920         656 :             rtl_uString_newFromAscii( &pTypeName, "hyper" );
    1921         656 :             typelib_typedescription_new( &pType, typelib_TypeClass_HYPER, pTypeName, 0, 0, 0 );
    1922         656 :             typelib_typedescription_register( &pType );
    1923         656 :             rtl_uString_newFromAscii( &pTypeName, "unsigned hyper" );
    1924         656 :             typelib_typedescription_new( &pType, typelib_TypeClass_UNSIGNED_HYPER, pTypeName, 0, 0, 0 );
    1925         656 :             typelib_typedescription_register( &pType );
    1926         656 :             rtl_uString_newFromAscii( &pTypeName, "float" );
    1927         656 :             typelib_typedescription_new( &pType, typelib_TypeClass_FLOAT, pTypeName, 0, 0, 0 );
    1928         656 :             typelib_typedescription_register( &pType );
    1929         656 :             rtl_uString_newFromAscii( &pTypeName, "double" );
    1930         656 :             typelib_typedescription_new( &pType, typelib_TypeClass_DOUBLE, pTypeName, 0, 0, 0 );
    1931         656 :             typelib_typedescription_register( &pType );
    1932         656 :             rtl_uString_newFromAscii( &pTypeName, "any" );
    1933         656 :             typelib_typedescription_new( &pType, typelib_TypeClass_ANY, pTypeName, 0, 0, 0 );
    1934         656 :             typelib_typedescription_register( &pType );
    1935         656 :             typelib_typedescription_release( pType );
    1936         656 :             rtl_uString_release( pTypeName );
    1937         656 :         }
    1938             :     }
    1939             : 
    1940      613113 :     typelib_TypeDescriptionReference * pTDR = 0;
    1941      613113 :     typelib_typedescriptionreference_getByName( &pTDR, pName );
    1942      613113 :     if( pTDR )
    1943             :     {
    1944             :         {
    1945             :         // guard against multi thread access
    1946      612367 :         MutexGuard aGuard( rInit.getMutex() );
    1947             :         // pTDR->pType->pWeakRef == 0 means that the description is empty
    1948      612367 :         if( pTDR->pType && pTDR->pType->pWeakRef )
    1949             :         {
    1950      454132 :             typelib_typedescription_acquire( pTDR->pType );
    1951      454132 :             *ppRet = pTDR->pType;
    1952      612367 :         }
    1953             :         }
    1954      612367 :         typelib_typedescriptionreference_release( pTDR );
    1955             :     }
    1956             : 
    1957      613113 :     if (0 == *ppRet)
    1958             :     {
    1959             :         // check for sequence
    1960      158981 :         OUString const & name = *reinterpret_cast< OUString const * >( &pName );
    1961      158981 :         if (2 < name.getLength() && '[' == name[ 0 ])
    1962             :         {
    1963         522 :             OUString element_name( name.copy( 2 ) );
    1964         522 :             typelib_TypeDescription * element_td = 0;
    1965         522 :             typelib_typedescription_getByName( &element_td, element_name.pData );
    1966         522 :             if (0 != element_td)
    1967             :             {
    1968             :                 typelib_typedescription_new(
    1969         522 :                     ppRet, typelib_TypeClass_SEQUENCE, pName, element_td->pWeakRef, 0, 0 );
    1970             :                 // register?
    1971         522 :                 typelib_typedescription_release( element_td );
    1972         522 :             }
    1973             :         }
    1974      158981 :         if (0 == *ppRet)
    1975             :         {
    1976             :             // Check for derived interface member type:
    1977             :             sal_Int32 i1 = name.lastIndexOf(
    1978      158459 :                 rtl::OUString(":@"));
    1979      158459 :             if (i1 >= 0) {
    1980       61611 :                 sal_Int32 i2 = i1 + RTL_CONSTASCII_LENGTH(":@");
    1981       61611 :                 sal_Int32 i3 = name.indexOf(',', i2);
    1982       61611 :                 if (i3 >= 0) {
    1983       61611 :                     sal_Int32 i4 = name.indexOf(':', i3);
    1984       61611 :                     if (i4 >= 0) {
    1985       61611 :                         typelib_TypeDescriptionReference * pBaseRef = 0;
    1986       61611 :                         typelib_TypeDescription * pBase = 0;
    1987       61611 :                         typelib_TypeDescription * pInterface = 0;
    1988             :                         typelib_typedescriptionreference_getByName(
    1989       61611 :                             &pBaseRef, name.copy(0, i1).pData);
    1990       61611 :                         if (pBaseRef != 0) {
    1991             :                             typelib_typedescriptionreference_getDescription(
    1992       61611 :                                 &pBase, pBaseRef);
    1993             :                         }
    1994             :                         typelib_typedescription_getByName(
    1995       61611 :                             &pInterface, name.copy(i4 + 1).pData);
    1996      123222 :                         if (!createDerivedInterfaceMemberDescription(
    1997             :                                 ppRet, name, pBaseRef, pBase, pInterface,
    1998             :                                 name.copy(i2, i3 - i2).toInt32(),
    1999      123222 :                                 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      158981 :         if (0 == *ppRet)
    2017             :         {
    2018             :             // on demand access
    2019       96848 :             rInit.callChain( ppRet, pName );
    2020             :         }
    2021             : 
    2022      158981 :         if( *ppRet )
    2023             :         {
    2024             :             // typedescription found
    2025      158833 :             if (typelib_TypeClass_TYPEDEF == (*ppRet)->eTypeClass)
    2026             :             {
    2027           0 :                 typelib_TypeDescription * pTD = 0;
    2028             :                 typelib_typedescriptionreference_getDescription(
    2029           0 :                     &pTD, ((typelib_IndirectTypeDescription *)*ppRet)->pType );
    2030           0 :                 typelib_typedescription_release( *ppRet );
    2031           0 :                 *ppRet = pTD;
    2032             :             }
    2033             :             else
    2034             :             {
    2035             :                 // set to on demand
    2036      158833 :                 (*ppRet)->bOnDemand = sal_True;
    2037             :                 // The type description is hold by the reference until
    2038             :                 // on demand is activated.
    2039      158833 :                 typelib_typedescription_register( ppRet );
    2040             : 
    2041             :                 // insert into the chache
    2042      158833 :                 MutexGuard aGuard( rInit.getMutex() );
    2043      158833 :                 if( !rInit.pCache )
    2044         391 :                     rInit.pCache = new TypeDescriptionList_Impl;
    2045      158833 :                 if( (sal_Int32)rInit.pCache->size() >= nCacheSize )
    2046             :                 {
    2047      105041 :                     typelib_typedescription_release( rInit.pCache->front() );
    2048      105041 :                     rInit.pCache->pop_front();
    2049             :                 }
    2050             :                 // descriptions in the cache must be acquired!
    2051      158833 :                 typelib_typedescription_acquire( *ppRet );
    2052      158833 :                 rInit.pCache->push_back( *ppRet );
    2053             :             }
    2054             :         }
    2055             :     }
    2056      613113 : }
    2057             : 
    2058           0 : extern "C" CPPU_DLLPUBLIC 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     3015517 : extern "C" CPPU_DLLPUBLIC void SAL_CALL typelib_typedescriptionreference_new(
    2069             :     typelib_TypeDescriptionReference ** ppTDR,
    2070             :     typelib_TypeClass eTypeClass, rtl_uString * pTypeName )
    2071             :     SAL_THROW_EXTERN_C()
    2072             : {
    2073     3015517 :     TypeDescriptor_Init_Impl &rInit = Init::get();
    2074     3015517 :     if( eTypeClass == typelib_TypeClass_TYPEDEF )
    2075             :     {
    2076             :         // on demand access
    2077         974 :         typelib_TypeDescription * pRet = 0;
    2078         974 :         rInit.callChain( &pRet, pTypeName );
    2079         974 :         if( pRet )
    2080             :         {
    2081             :             // typedescription found
    2082         974 :             if (typelib_TypeClass_TYPEDEF == pRet->eTypeClass)
    2083             :             {
    2084             :                 typelib_typedescriptionreference_acquire(
    2085           0 :                     ((typelib_IndirectTypeDescription *)pRet)->pType );
    2086           0 :                 if (*ppTDR)
    2087           0 :                     typelib_typedescriptionreference_release( *ppTDR );
    2088           0 :                 *ppTDR = ((typelib_IndirectTypeDescription *)pRet)->pType;
    2089           0 :                 typelib_typedescription_release( pRet );
    2090             :             }
    2091             :             else
    2092             :             {
    2093             :                 // set to on demand
    2094         974 :                 pRet->bOnDemand = sal_True;
    2095             :                 // The type description is hold by the reference until
    2096             :                 // on demand is activated.
    2097         974 :                 typelib_typedescription_register( &pRet );
    2098             : 
    2099             :                 // insert into the chache
    2100         974 :                 MutexGuard aGuard( rInit.getMutex() );
    2101         974 :                 if( !rInit.pCache )
    2102           0 :                     rInit.pCache = new TypeDescriptionList_Impl;
    2103         974 :                 if( (sal_Int32)rInit.pCache->size() >= nCacheSize )
    2104             :                 {
    2105         685 :                     typelib_typedescription_release( rInit.pCache->front() );
    2106         685 :                     rInit.pCache->pop_front();
    2107             :                 }
    2108         974 :                 rInit.pCache->push_back( pRet );
    2109             :                 // pRet kept acquired for cache
    2110             : 
    2111         974 :                 typelib_typedescriptionreference_acquire( pRet->pWeakRef );
    2112         974 :                 if (*ppTDR)
    2113           0 :                     typelib_typedescriptionreference_release( *ppTDR );
    2114         974 :                 *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         974 :         return;
    2127             :     }
    2128             : 
    2129     3014543 :     MutexGuard aGuard( rInit.getMutex() );
    2130     3014543 :     typelib_typedescriptionreference_getByName( ppTDR, pTypeName );
    2131     3014543 :     if( *ppTDR )
    2132     2196664 :         return;
    2133             : 
    2134      817879 :     if( reallyWeak( eTypeClass ) )
    2135             :     {
    2136      692225 :         typelib_TypeDescriptionReference * pTDR = new typelib_TypeDescriptionReference();
    2137             : #if OSL_DEBUG_LEVEL > 1
    2138             :         osl_atomic_increment( &rInit.nTypeDescriptionReferenceCount );
    2139             : #endif
    2140      692225 :         pTDR->nRefCount = 1;
    2141      692225 :         pTDR->nStaticRefCount = 0;
    2142      692225 :         pTDR->eTypeClass = eTypeClass;
    2143      692225 :         pTDR->pUniqueIdentifier = 0;
    2144      692225 :         pTDR->pReserved = 0;
    2145      692225 :         rtl_uString_acquire( pTDR->pTypeName = pTypeName );
    2146      692225 :         pTDR->pType = 0;
    2147      692225 :         *ppTDR = pTDR;
    2148             :     }
    2149             :     else
    2150             :     {
    2151      125654 :         typelib_typedescription_newEmpty( (typelib_TypeDescription ** )ppTDR, eTypeClass, pTypeName );
    2152             :         // description will be registered but not acquired
    2153      125654 :         (*(typelib_TypeDescription ** )ppTDR)->bOnDemand = sal_True;
    2154      125654 :         (*(typelib_TypeDescription ** )ppTDR)->bComplete = sal_False;
    2155             :     }
    2156             : 
    2157      817879 :     if( !rInit.pWeakMap )
    2158         664 :         rInit.pWeakMap = new WeakMap_Impl;
    2159             :     // Heavy hack, the const sal_Unicode * is hold by the typedescription reference
    2160             :     // not registered
    2161      817879 :     rInit.pWeakMap->operator[]( (*ppTDR)->pTypeName->buffer ) = *ppTDR;
    2162             : }
    2163             : 
    2164             : 
    2165   252706404 : extern "C" CPPU_DLLPUBLIC void SAL_CALL typelib_typedescriptionreference_acquire(
    2166             :     typelib_TypeDescriptionReference * pRef )
    2167             :     SAL_THROW_EXTERN_C()
    2168             : {
    2169   252706404 :     osl_atomic_increment( &pRef->nRefCount );
    2170   252706404 : }
    2171             : 
    2172             : 
    2173   568726153 : extern "C" CPPU_DLLPUBLIC void SAL_CALL typelib_typedescriptionreference_release(
    2174             :     typelib_TypeDescriptionReference * pRef )
    2175             :     SAL_THROW_EXTERN_C()
    2176             : {
    2177             :     // Is it a type description?
    2178   568726153 :     if( reallyWeak( pRef->eTypeClass ) )
    2179             :     {
    2180     3154012 :         if( ! osl_atomic_decrement( &pRef->nRefCount ) )
    2181             :         {
    2182      483697 :             TypeDescriptor_Init_Impl &rInit = Init::get();
    2183      483697 :             if( rInit.pWeakMap )
    2184             :             {
    2185      483697 :                 MutexGuard aGuard( rInit.getMutex() );
    2186      483697 :                 WeakMap_Impl::iterator aIt = rInit.pWeakMap->find( (sal_Unicode*)pRef->pTypeName->buffer );
    2187      483697 :                 if( !(aIt == rInit.pWeakMap->end()) && (*aIt).second == pRef )
    2188             :                 {
    2189             :                     // remove only if it contains the same object
    2190      483697 :                     rInit.pWeakMap->erase( aIt );
    2191      483697 :                 }
    2192             :             }
    2193             : 
    2194      483697 :             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      483697 :             delete pRef;
    2200             :         }
    2201             :     }
    2202             :     else
    2203             :     {
    2204   565572145 :         typelib_typedescription_release( (typelib_TypeDescription *)pRef );
    2205             :     }
    2206   568727887 : }
    2207             : 
    2208             : 
    2209     4751570 : extern "C" CPPU_DLLPUBLIC void SAL_CALL typelib_typedescriptionreference_getDescription(
    2210             :     typelib_TypeDescription ** ppRet, typelib_TypeDescriptionReference * pRef )
    2211             :     SAL_THROW_EXTERN_C()
    2212             : {
    2213     4751570 :     if( *ppRet )
    2214             :     {
    2215           0 :         typelib_typedescription_release( *ppRet );
    2216           0 :         *ppRet = 0;
    2217             :     }
    2218             : 
    2219     4751570 :     if( !reallyWeak( pRef->eTypeClass ) && pRef->pType && pRef->pType->pWeakRef )
    2220             :     {
    2221             :         // reference is a description and initialized
    2222     3541702 :         osl_atomic_increment( &((typelib_TypeDescription *)pRef)->nRefCount );
    2223     3541702 :         *ppRet = (typelib_TypeDescription *)pRef;
    2224     3541702 :         return;
    2225             :     }
    2226             : 
    2227             :     {
    2228     1209872 :     MutexGuard aGuard( Init::get().getMutex() );
    2229             :     // pRef->pType->pWeakRef == 0 means that the description is empty
    2230     1209872 :     if( pRef->pType && pRef->pType->pWeakRef )
    2231             :     {
    2232     1052867 :         sal_Int32 n = osl_atomic_increment( &pRef->pType->nRefCount );
    2233     1052867 :         if( n > 1 )
    2234             :         {
    2235             :             // The refence is incremented. The object cannot be destroyed.
    2236             :             // Release the guard at the earliest point.
    2237     1052867 :             *ppRet = pRef->pType;
    2238     1052867 :             return;
    2239             :         }
    2240             :         else
    2241             :         {
    2242           0 :             (void)osl_atomic_decrement( &pRef->pType->nRefCount );
    2243             :             // detruction of this type in progress (another thread!)
    2244             :             // no acces through this weak reference
    2245           0 :             pRef->pType = 0;
    2246             :         }
    2247      157005 :     }
    2248             :     }
    2249             : 
    2250      157005 :     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      157005 :     pRef->pType = *ppRet;
    2255             : }
    2256             : 
    2257             : 
    2258     4415556 : extern "C" void SAL_CALL typelib_typedescriptionreference_getByName(
    2259             :     typelib_TypeDescriptionReference ** ppRet, rtl_uString * pName )
    2260             :     SAL_THROW_EXTERN_C()
    2261             : {
    2262     4415556 :     if( *ppRet )
    2263             :     {
    2264           0 :         typelib_typedescriptionreference_release( *ppRet );
    2265           0 :         *ppRet = 0;
    2266             :     }
    2267     4415556 :     TypeDescriptor_Init_Impl &rInit = Init::get();
    2268     4415556 :     if( rInit.pWeakMap )
    2269             :     {
    2270     4414892 :         MutexGuard aGuard( rInit.getMutex() );
    2271     4414892 :         WeakMap_Impl::const_iterator aIt = rInit.pWeakMap->find( (sal_Unicode*)pName->buffer );
    2272     4414892 :         if( !(aIt == rInit.pWeakMap->end()) ) // != failed on msc4.2
    2273             :         {
    2274     3526270 :             sal_Int32 n = osl_atomic_increment( &(*aIt).second->nRefCount );
    2275     3526270 :             if( n > 1 )
    2276             :             {
    2277             :                 // The refence is incremented. The object cannot be destroyed.
    2278             :                 // Release the guard at the earliest point.
    2279     3526270 :                 *ppRet = (*aIt).second;
    2280             :             }
    2281             :             else
    2282             :             {
    2283             :                 // detruction of this type in progress (another thread!)
    2284             :                 // no acces through this weak reference
    2285           0 :                 (void)osl_atomic_decrement( &(*aIt).second->nRefCount );
    2286             :             }
    2287     4414892 :         }
    2288             :     }
    2289     4415556 : }
    2290             : 
    2291             : 
    2292   266344421 : extern "C" CPPU_DLLPUBLIC sal_Bool SAL_CALL typelib_typedescriptionreference_equals(
    2293             :     const typelib_TypeDescriptionReference * p1,
    2294             :     const typelib_TypeDescriptionReference * p2 )
    2295             :     SAL_THROW_EXTERN_C()
    2296             : {
    2297   532688811 :     return (p1 == p2 ||
    2298   454063697 :             (p1->eTypeClass == p2->eTypeClass &&
    2299   233743329 :              p1->pTypeName->length == p2->pTypeName->length &&
    2300   273382592 :              rtl_ustr_compare( p1->pTypeName->buffer, p2->pTypeName->buffer ) == 0));
    2301             : }
    2302             : 
    2303             : 
    2304    20008550 : extern "C" CPPU_DLLPUBLIC void SAL_CALL typelib_typedescriptionreference_assign(
    2305             :     typelib_TypeDescriptionReference ** ppDest,
    2306             :     typelib_TypeDescriptionReference * pSource )
    2307             :     SAL_THROW_EXTERN_C()
    2308             : {
    2309    20008550 :     if (*ppDest != pSource)
    2310             :     {
    2311    19306506 :         ::typelib_typedescriptionreference_acquire( pSource );
    2312    19306506 :         ::typelib_typedescriptionreference_release( *ppDest );
    2313    19306506 :         *ppDest = pSource;
    2314             :     }
    2315    20008550 : }
    2316             : 
    2317             : 
    2318           0 : extern "C" CPPU_DLLPUBLIC 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      226925 : extern "C" CPPU_DLLPUBLIC sal_Bool SAL_CALL typelib_typedescriptionreference_isAssignableFrom(
    2357             :     typelib_TypeDescriptionReference * pAssignable,
    2358             :     typelib_TypeDescriptionReference * pFrom )
    2359             :     SAL_THROW_EXTERN_C()
    2360             : {
    2361      226925 :     if (pAssignable && pFrom)
    2362             :     {
    2363      226925 :         typelib_TypeClass eAssignable = pAssignable->eTypeClass;
    2364      226925 :         typelib_TypeClass eFrom       = pFrom->eTypeClass;
    2365             : 
    2366      226925 :         if (eAssignable == typelib_TypeClass_ANY) // anything can be assigned to an any .)
    2367           0 :             return sal_True;
    2368      226925 :         if (eAssignable == eFrom)
    2369             :         {
    2370      217086 :             if (type_equals( pAssignable, pFrom )) // first shot
    2371             :             {
    2372      189263 :                 return sal_True;
    2373             :             }
    2374             :             else
    2375             :             {
    2376       27823 :                 switch (eAssignable)
    2377             :                 {
    2378             :                 case typelib_TypeClass_STRUCT:
    2379             :                 case typelib_TypeClass_EXCEPTION:
    2380             :                 {
    2381         452 :                     typelib_TypeDescription * pFromDescr = 0;
    2382         452 :                     TYPELIB_DANGER_GET( &pFromDescr, pFrom );
    2383         452 :                     if (! ((typelib_CompoundTypeDescription *)pFromDescr)->pBaseTypeDescription)
    2384             :                     {
    2385          34 :                         TYPELIB_DANGER_RELEASE( pFromDescr );
    2386          34 :                         return sal_False;
    2387             :                     }
    2388             :                     bool bRet = typelib_typedescriptionreference_isAssignableFrom(
    2389             :                         pAssignable,
    2390         418 :                         ((typelib_TypeDescription *)((typelib_CompoundTypeDescription *)pFromDescr)->pBaseTypeDescription)->pWeakRef );
    2391         418 :                     TYPELIB_DANGER_RELEASE( pFromDescr );
    2392         418 :                     return bRet;
    2393             :                 }
    2394             :                 case typelib_TypeClass_INTERFACE:
    2395             :                 {
    2396       27371 :                     typelib_TypeDescription * pFromDescr = 0;
    2397       27371 :                     TYPELIB_DANGER_GET( &pFromDescr, pFrom );
    2398             :                     typelib_InterfaceTypeDescription * pFromIfc
    2399             :                         = reinterpret_cast<
    2400       27371 :                             typelib_InterfaceTypeDescription * >(pFromDescr);
    2401       27371 :                     bool bRet = false;
    2402       36205 :                     for (sal_Int32 i = 0; i < pFromIfc->nBaseTypes; ++i) {
    2403       15761 :                         if (typelib_typedescriptionreference_isAssignableFrom(
    2404             :                                 pAssignable,
    2405       15761 :                                 pFromIfc->ppBaseTypes[i]->aBase.pWeakRef))
    2406             :                         {
    2407        6927 :                             bRet = true;
    2408        6927 :                             break;
    2409             :                         }
    2410             :                     }
    2411       27371 :                     TYPELIB_DANGER_RELEASE( pFromDescr );
    2412       27371 :                     return bRet;
    2413             :                 }
    2414             :                 default:
    2415             :                 {
    2416           0 :                     return sal_False;
    2417             :                 }
    2418             :                 }
    2419             :             }
    2420             :         }
    2421       24905 :         return (eAssignable >= typelib_TypeClass_CHAR && eAssignable <= typelib_TypeClass_DOUBLE &&
    2422       24612 :                 eFrom >= typelib_TypeClass_CHAR && eFrom <= typelib_TypeClass_DOUBLE &&
    2423       14610 :                 s_aAssignableFromTab[eAssignable-1][eFrom-1]);
    2424             :     }
    2425           0 :     return sal_False;
    2426             : }
    2427             : 
    2428       17095 : extern "C" CPPU_DLLPUBLIC 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       17095 :         pAssignable->pWeakRef, pFrom->pWeakRef );
    2435             : }
    2436             : 
    2437             : 
    2438      982605 : extern "C" CPPU_DLLPUBLIC sal_Bool SAL_CALL typelib_typedescription_complete(
    2439             :     typelib_TypeDescription ** ppTypeDescr )
    2440             :     SAL_THROW_EXTERN_C()
    2441             : {
    2442      982605 :     return complete(ppTypeDescr, true);
    2443             : }
    2444             : 
    2445             : /* vim:set shiftwidth=4 softtabstop=4 expandtab: */

Generated by: LCOV version 1.10