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

Generated by: LCOV version 1.10