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

Generated by: LCOV version 1.10