bump product version to 4.1.6.2
[LibreOffice.git] / cppu / source / typelib / typelib.cxx
blob6fcda8a9a864414d31becfae77ecac436615610a
1 /* -*- Mode: C++; tab-width: 4; indent-tabs-mode: nil; c-basic-offset: 4 -*- */
2 /*
3 * This file is part of the LibreOffice project.
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/.
9 * This file incorporates work covered by the following license notice:
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 .
21 #if OSL_DEBUG_LEVEL > 1
22 #include <stdio.h>
23 #endif
25 #include <boost/unordered_map.hpp>
26 #include <cassert>
27 #include <list>
28 #include <set>
29 #include <vector>
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>
46 using namespace std;
47 using namespace osl;
49 using ::rtl::OUString;
50 using ::rtl::OUStringBuffer;
51 using ::rtl::OString;
53 #ifdef SAL_W32
54 #pragma pack(push, 8)
55 #endif
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.
63 struct AlignSize_Impl
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
76 #ifdef SAL_W32
77 #pragma pack(pop)
78 #endif
80 // the value of the maximal alignment
81 static sal_Int32 nMaxAlignment = (sal_Int32)( (sal_Size)(&((AlignSize_Impl *) 16)->dDouble) - 16);
83 static inline sal_Int32 adjustAlignment( sal_Int32 nRequestedAlignment )
84 SAL_THROW(())
86 if( nRequestedAlignment > nMaxAlignment )
87 nRequestedAlignment = nMaxAlignment;
88 return nRequestedAlignment;
91 /**
92 * Calculate the new size of the struktur.
94 static inline sal_Int32 newAlignedSize(
95 sal_Int32 OldSize, sal_Int32 ElementSize, sal_Int32 NeededAlignment )
96 SAL_THROW(())
98 NeededAlignment = adjustAlignment( NeededAlignment );
99 return (OldSize + NeededAlignment -1) / NeededAlignment * NeededAlignment + ElementSize;
102 static inline sal_Bool reallyWeak( typelib_TypeClass eTypeClass )
103 SAL_THROW(())
105 return TYPELIB_TYPEDESCRIPTIONREFERENCE_ISREALLYWEAK( eTypeClass );
108 static inline sal_Int32 getDescriptionSize( typelib_TypeClass eTypeClass )
109 SAL_THROW(())
111 OSL_ASSERT( typelib_TypeClass_TYPEDEF != eTypeClass );
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 switch( eTypeClass )
119 case typelib_TypeClass_ARRAY:
120 nSize = (sal_Int32)sizeof( typelib_ArrayTypeDescription );
121 break;
123 case typelib_TypeClass_SEQUENCE:
124 nSize = (sal_Int32)sizeof( typelib_IndirectTypeDescription );
125 break;
127 case typelib_TypeClass_UNION:
128 nSize = (sal_Int32)sizeof( typelib_UnionTypeDescription );
129 break;
131 case typelib_TypeClass_STRUCT:
132 nSize = (sal_Int32)sizeof( typelib_StructTypeDescription );
133 break;
135 case typelib_TypeClass_EXCEPTION:
136 nSize = (sal_Int32)sizeof( typelib_CompoundTypeDescription );
137 break;
139 case typelib_TypeClass_ENUM:
140 nSize = (sal_Int32)sizeof( typelib_EnumTypeDescription );
141 break;
143 case typelib_TypeClass_INTERFACE:
144 nSize = (sal_Int32)sizeof( typelib_InterfaceTypeDescription );
145 break;
147 case typelib_TypeClass_INTERFACE_METHOD:
148 nSize = (sal_Int32)sizeof( typelib_InterfaceMethodTypeDescription );
149 break;
151 case typelib_TypeClass_INTERFACE_ATTRIBUTE:
152 nSize = (sal_Int32)sizeof( typelib_InterfaceAttributeTypeDescription );
153 break;
155 default:
156 nSize = (sal_Int32)sizeof( typelib_TypeDescription );
158 return nSize;
162 //-----------------------------------------------------------------------------
163 extern "C" void SAL_CALL typelib_typedescriptionreference_getByName(
164 typelib_TypeDescriptionReference ** ppRet, rtl_uString * pName )
165 SAL_THROW_EXTERN_C();
167 //-----------------------------------------------------------------------------
168 struct equalStr_Impl
170 sal_Bool operator()(const sal_Unicode * const & s1, const sal_Unicode * const & s2) const SAL_THROW(())
171 { return 0 == rtl_ustr_compare( s1, s2 ); }
174 //-----------------------------------------------------------------------------
175 struct hashStr_Impl
177 size_t operator()(const sal_Unicode * const & s) const SAL_THROW(())
178 { return rtl_ustr_hashCode( s ); }
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;
187 typedef pair< void *, typelib_typedescription_Callback > CallbackEntry;
188 typedef list< CallbackEntry > CallbackSet_Impl;
189 typedef list< typelib_TypeDescription * > TypeDescriptionList_Impl;
191 // # of cached elements
192 static sal_Int32 nCacheSize = 256;
194 struct TypeDescriptor_Init_Impl
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;
206 inline Mutex & getMutex() SAL_THROW(());
208 inline void callChain( typelib_TypeDescription ** ppRet, rtl_uString * pName ) SAL_THROW(());
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
224 TypeDescriptor_Init_Impl():
225 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
236 ~TypeDescriptor_Init_Impl() SAL_THROW(());
238 //__________________________________________________________________________________________________
239 inline Mutex & TypeDescriptor_Init_Impl::getMutex() SAL_THROW(())
241 if( !pMutex )
243 MutexGuard aGuard( Mutex::getGlobalMutex() );
244 if( !pMutex )
245 pMutex = new Mutex();
247 return * pMutex;
249 //__________________________________________________________________________________________________
250 inline void TypeDescriptor_Init_Impl::callChain(
251 typelib_TypeDescription ** ppRet, rtl_uString * pName )
252 SAL_THROW(())
254 assert(ppRet != 0);
255 assert(*ppRet == 0);
256 if (pCallbacks)
258 CallbackSet_Impl::const_iterator aIt = pCallbacks->begin();
259 while( aIt != pCallbacks->end() )
261 const CallbackEntry & rEntry = *aIt;
262 (*rEntry.second)( rEntry.first, ppRet, pName );
263 if( *ppRet )
264 return;
265 ++aIt;
270 //__________________________________________________________________________________________________
271 TypeDescriptor_Init_Impl::~TypeDescriptor_Init_Impl() SAL_THROW(())
273 if( pCache )
275 TypeDescriptionList_Impl::const_iterator aIt = pCache->begin();
276 while( aIt != pCache->end() )
278 typelib_typedescription_release( (*aIt) );
279 ++aIt;
281 delete pCache;
282 pCache = 0;
285 if( pWeakMap )
287 std::vector< typelib_TypeDescriptionReference * > ppTDR;
288 // save al weak references
289 WeakMap_Impl::const_iterator aIt = pWeakMap->begin();
290 while( aIt != pWeakMap->end() )
292 ppTDR.push_back( (*aIt).second );
293 typelib_typedescriptionreference_acquire( ppTDR.back() );
294 ++aIt;
297 for( std::vector< typelib_TypeDescriptionReference * >::iterator i(
298 ppTDR.begin() );
299 i != ppTDR.end(); ++i )
301 typelib_TypeDescriptionReference * pTDR = *i;
302 OSL_ASSERT( pTDR->nRefCount > pTDR->nStaticRefCount );
303 pTDR->nRefCount -= pTDR->nStaticRefCount;
305 if( pTDR->pType && !pTDR->pType->bOnDemand )
307 pTDR->pType->bOnDemand = sal_True;
308 typelib_typedescription_release( pTDR->pType );
310 typelib_typedescriptionreference_release( pTDR );
313 #if OSL_DEBUG_LEVEL > 1
314 aIt = pWeakMap->begin();
315 while( aIt != pWeakMap->end() )
317 typelib_TypeDescriptionReference * pTDR = (*aIt).second;
318 if (pTDR)
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 );
324 else
326 OSL_TRACE( "### remaining null type entry!?" );
328 ++aIt;
330 #endif
332 delete pWeakMap;
333 pWeakMap = 0;
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" );
347 OSL_ENSURE( !pCallbacks || pCallbacks->empty(), "### pCallbacks is not NULL or empty" );
348 #endif
350 delete pCallbacks;
351 pCallbacks = 0;
353 if( pMutex )
355 delete pMutex;
356 pMutex = 0;
360 namespace { struct Init : public rtl::Static< TypeDescriptor_Init_Impl, Init > {}; }
362 extern "C" CPPU_DLLPUBLIC void SAL_CALL typelib_typedescription_registerCallback(
363 void * pContext, typelib_typedescription_Callback pCallback )
364 SAL_THROW_EXTERN_C()
366 // todo mt safe: guard is no solution, can not acquire while calling callback!
367 TypeDescriptor_Init_Impl &rInit = Init::get();
368 // OslGuard aGuard( rInit.getMutex() );
369 if( !rInit.pCallbacks )
370 rInit.pCallbacks = new CallbackSet_Impl;
371 rInit.pCallbacks->push_back( CallbackEntry( pContext, pCallback ) );
374 //------------------------------------------------------------------------
375 extern "C" CPPU_DLLPUBLIC void SAL_CALL typelib_typedescription_revokeCallback(
376 void * pContext, typelib_typedescription_Callback pCallback )
377 SAL_THROW_EXTERN_C()
379 TypeDescriptor_Init_Impl &rInit = Init::get();
380 if( rInit.pCallbacks )
382 // todo mt safe: guard is no solution, can not acquire while calling callback!
383 // OslGuard aGuard( rInit.getMutex() );
384 CallbackEntry aEntry( pContext, pCallback );
385 CallbackSet_Impl::iterator iPos( rInit.pCallbacks->begin() );
386 while (!(iPos == rInit.pCallbacks->end()))
388 if (*iPos == aEntry)
390 rInit.pCallbacks->erase( iPos );
391 iPos = rInit.pCallbacks->begin();
393 else
395 ++iPos;
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();
406 //------------------------------------------------------------------------
407 static inline void typelib_typedescription_initTables(
408 typelib_TypeDescription * pTD )
409 SAL_THROW(())
411 typelib_InterfaceTypeDescription * pITD = (typelib_InterfaceTypeDescription *)pTD;
413 sal_Bool * pReadWriteAttributes = (sal_Bool *)alloca( pITD->nAllMembers );
414 for ( sal_Int32 i = pITD->nAllMembers; i--; )
416 pReadWriteAttributes[i] = sal_False;
417 if( typelib_TypeClass_INTERFACE_ATTRIBUTE == pITD->ppAllMembers[i]->eTypeClass )
419 typelib_TypeDescription * pM = 0;
420 TYPELIB_DANGER_GET( &pM, pITD->ppAllMembers[i] );
421 OSL_ASSERT( pM );
422 if (pM)
424 pReadWriteAttributes[i] = !((typelib_InterfaceAttributeTypeDescription *)pM)->bReadOnly;
425 TYPELIB_DANGER_RELEASE( pM );
427 #if OSL_DEBUG_LEVEL > 1
428 else
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() );
433 #endif
437 MutexGuard aGuard( Init::get().getMutex() );
438 if( !pTD->bComplete )
440 // create the index table from member to function table
441 pITD->pMapMemberIndexToFunctionIndex = new sal_Int32[ pITD->nAllMembers ];
442 sal_Int32 nAdditionalOffset = 0; // +1 for read/write attributes
443 sal_Int32 i;
444 for( i = 0; i < pITD->nAllMembers; i++ )
446 // index to the get method of the attribute
447 pITD->pMapMemberIndexToFunctionIndex[i] = i + nAdditionalOffset;
448 // extra offset if it is a read/write attribute?
449 if( pReadWriteAttributes[i] )
451 // a read/write attribute
452 nAdditionalOffset++;
456 // create the index table from function to member table
457 pITD->pMapFunctionIndexToMemberIndex = new sal_Int32[ pITD->nAllMembers + nAdditionalOffset ];
458 nAdditionalOffset = 0; // +1 for read/write attributes
459 for( i = 0; i < pITD->nAllMembers; i++ )
461 // index to the get method of the attribute
462 pITD->pMapFunctionIndexToMemberIndex[i + nAdditionalOffset] = i;
463 // extra offset if it is a read/write attribute?
464 if( pReadWriteAttributes[i] )
466 // a read/write attribute
467 pITD->pMapFunctionIndexToMemberIndex[i + ++nAdditionalOffset] = i;
470 // must be the last action after all initialization is done
471 pITD->nMapFunctionIndexToMemberIndex = pITD->nAllMembers + nAdditionalOffset;
472 pTD->bComplete = sal_True;
476 namespace {
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 bool complete(typelib_TypeDescription ** ppTypeDescr, bool initTables) {
490 if (! (*ppTypeDescr)->bComplete)
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 ) );
499 if (typelib_TypeClass_INTERFACE == (*ppTypeDescr)->eTypeClass &&
500 ((typelib_InterfaceTypeDescription *)*ppTypeDescr)->ppAllMembers)
502 if (initTables) {
503 typelib_typedescription_initTables( *ppTypeDescr );
505 return true;
508 typelib_TypeDescription * pTD = 0;
509 // on demand access of complete td
510 TypeDescriptor_Init_Impl &rInit = Init::get();
511 rInit.callChain( &pTD, (*ppTypeDescr)->pTypeName );
512 if (pTD)
514 if (typelib_TypeClass_TYPEDEF == pTD->eTypeClass)
516 typelib_typedescriptionreference_getDescription(
517 &pTD, ((typelib_IndirectTypeDescription *)pTD)->pType );
518 OSL_ASSERT( pTD );
519 if (! pTD)
520 return false;
523 OSL_ASSERT( typelib_TypeClass_TYPEDEF != pTD->eTypeClass );
524 // typedescription found
525 // set to on demand
526 pTD->bOnDemand = sal_True;
528 if (pTD->eTypeClass == typelib_TypeClass_INTERFACE
529 && !pTD->bComplete && initTables)
531 // mandatory info from callback chain
532 OSL_ASSERT( ((typelib_InterfaceTypeDescription *)pTD)->ppAllMembers );
533 // complete except of tables init
534 typelib_typedescription_initTables( pTD );
535 pTD->bComplete = sal_True;
538 // The type description is hold by the reference until
539 // on demand is activated.
540 ::typelib_typedescription_register( &pTD ); // replaces incomplete one
541 OSL_ASSERT( pTD == *ppTypeDescr ); // has to merge into existing one
543 // insert into the chache
544 MutexGuard aGuard( rInit.getMutex() );
545 if( !rInit.pCache )
546 rInit.pCache = new TypeDescriptionList_Impl;
547 if( (sal_Int32)rInit.pCache->size() >= nCacheSize )
549 typelib_typedescription_release( rInit.pCache->front() );
550 rInit.pCache->pop_front();
552 // descriptions in the cache must be acquired!
553 typelib_typedescription_acquire( pTD );
554 rInit.pCache->push_back( pTD );
556 OSL_ASSERT(
557 pTD->bComplete
558 || (pTD->eTypeClass == typelib_TypeClass_INTERFACE
559 && !initTables));
561 ::typelib_typedescription_release( *ppTypeDescr );
562 *ppTypeDescr = pTD;
564 else
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 return false;
574 return true;
579 //------------------------------------------------------------------------
580 extern "C" void SAL_CALL typelib_typedescription_newEmpty(
581 typelib_TypeDescription ** ppRet,
582 typelib_TypeClass eTypeClass, rtl_uString * pTypeName )
583 SAL_THROW_EXTERN_C()
585 if( *ppRet )
587 typelib_typedescription_release( *ppRet );
588 *ppRet = 0;
591 OSL_ASSERT( typelib_TypeClass_TYPEDEF != eTypeClass );
593 typelib_TypeDescription * pRet;
594 switch( eTypeClass )
596 case typelib_TypeClass_ARRAY:
598 typelib_ArrayTypeDescription * pTmp = new typelib_ArrayTypeDescription();
599 typelib_IndirectTypeDescription * pIndirect = (typelib_IndirectTypeDescription *)pTmp;
600 pRet = (typelib_TypeDescription *)pTmp;
601 #if OSL_DEBUG_LEVEL > 1
602 osl_atomic_increment( &Init::get().nArrayTypeDescriptionCount );
603 #endif
604 pIndirect->pType = 0;
605 pTmp->nDimensions = 0;
606 pTmp->nTotalElements = 0;
607 pTmp->pDimensions = 0;
609 break;
611 case typelib_TypeClass_SEQUENCE:
613 typelib_IndirectTypeDescription * pTmp = new typelib_IndirectTypeDescription();
614 pRet = (typelib_TypeDescription *)pTmp;
615 #if OSL_DEBUG_LEVEL > 1
616 osl_atomic_increment( &Init::get().nIndirectTypeDescriptionCount );
617 #endif
618 pTmp->pType = 0;
620 break;
622 case typelib_TypeClass_UNION:
624 typelib_UnionTypeDescription * pTmp;
625 pTmp = new typelib_UnionTypeDescription();
626 pRet = (typelib_TypeDescription *)pTmp;
627 #if OSL_DEBUG_LEVEL > 1
628 osl_atomic_increment( &Init::get().nUnionTypeDescriptionCount );
629 #endif
630 pTmp->nMembers = 0;
631 pTmp->pDiscriminantTypeRef = 0;
632 pTmp->pDiscriminants = 0;
633 pTmp->ppTypeRefs = 0;
634 pTmp->ppMemberNames = 0;
635 pTmp->pDefaultTypeRef = 0;
637 break;
639 case typelib_TypeClass_STRUCT:
641 // FEATURE_EMPTYCLASS
642 typelib_StructTypeDescription * pTmp;
643 pTmp = new typelib_StructTypeDescription();
644 pRet = (typelib_TypeDescription *)pTmp;
645 #if OSL_DEBUG_LEVEL > 1
646 osl_atomic_increment( &Init::get().nCompoundTypeDescriptionCount );
647 #endif
648 pTmp->aBase.pBaseTypeDescription = 0;
649 pTmp->aBase.nMembers = 0;
650 pTmp->aBase.pMemberOffsets = 0;
651 pTmp->aBase.ppTypeRefs = 0;
652 pTmp->aBase.ppMemberNames = 0;
653 pTmp->pParameterizedTypes = 0;
655 break;
657 case typelib_TypeClass_EXCEPTION:
659 // FEATURE_EMPTYCLASS
660 typelib_CompoundTypeDescription * pTmp;
661 pTmp = new typelib_CompoundTypeDescription();
662 pRet = (typelib_TypeDescription *)pTmp;
663 #if OSL_DEBUG_LEVEL > 1
664 osl_atomic_increment( &Init::get().nCompoundTypeDescriptionCount );
665 #endif
666 pTmp->pBaseTypeDescription = 0;
667 pTmp->nMembers = 0;
668 pTmp->pMemberOffsets = 0;
669 pTmp->ppTypeRefs = 0;
670 pTmp->ppMemberNames = 0;
672 break;
674 case typelib_TypeClass_ENUM:
676 typelib_EnumTypeDescription * pTmp = new typelib_EnumTypeDescription();
677 pRet = (typelib_TypeDescription *)pTmp;
678 #if OSL_DEBUG_LEVEL > 1
679 osl_atomic_increment( &Init::get().nEnumTypeDescriptionCount );
680 #endif
681 pTmp->nDefaultEnumValue = 0;
682 pTmp->nEnumValues = 0;
683 pTmp->ppEnumNames = 0;
684 pTmp->pEnumValues = 0;
686 break;
688 case typelib_TypeClass_INTERFACE:
690 typelib_InterfaceTypeDescription * pTmp = new typelib_InterfaceTypeDescription();
691 pRet = (typelib_TypeDescription *)pTmp;
692 #if OSL_DEBUG_LEVEL > 1
693 osl_atomic_increment( &Init::get().nInterfaceTypeDescriptionCount );
694 #endif
695 pTmp->pBaseTypeDescription = 0;
696 pTmp->nMembers = 0;
697 pTmp->ppMembers = 0;
698 pTmp->nAllMembers = 0;
699 pTmp->ppAllMembers = 0;
700 pTmp->nMapFunctionIndexToMemberIndex = 0;
701 pTmp->pMapFunctionIndexToMemberIndex = 0;
702 pTmp->pMapMemberIndexToFunctionIndex= 0;
703 pTmp->nBaseTypes = 0;
704 pTmp->ppBaseTypes = 0;
706 break;
708 case typelib_TypeClass_INTERFACE_METHOD:
710 typelib_InterfaceMethodTypeDescription * pTmp = new typelib_InterfaceMethodTypeDescription();
711 pRet = (typelib_TypeDescription *)pTmp;
712 #if OSL_DEBUG_LEVEL > 1
713 osl_atomic_increment( &Init::get().nInterfaceMethodTypeDescriptionCount );
714 #endif
715 pTmp->aBase.pMemberName = 0;
716 pTmp->pReturnTypeRef = 0;
717 pTmp->nParams = 0;
718 pTmp->pParams = 0;
719 pTmp->nExceptions = 0;
720 pTmp->ppExceptions = 0;
721 pTmp->pInterface = 0;
722 pTmp->pBaseRef = 0;
723 pTmp->nIndex = 0;
725 break;
727 case typelib_TypeClass_INTERFACE_ATTRIBUTE:
729 typelib_InterfaceAttributeTypeDescription * pTmp = new typelib_InterfaceAttributeTypeDescription();
730 pRet = (typelib_TypeDescription *)pTmp;
731 #if OSL_DEBUG_LEVEL > 1
732 osl_atomic_increment( &Init::get().nInterfaceAttributeTypeDescriptionCount );
733 #endif
734 pTmp->aBase.pMemberName = 0;
735 pTmp->pAttributeTypeRef = 0;
736 pTmp->pInterface = 0;
737 pTmp->pBaseRef = 0;
738 pTmp->nIndex = 0;
739 pTmp->nGetExceptions = 0;
740 pTmp->ppGetExceptions = 0;
741 pTmp->nSetExceptions = 0;
742 pTmp->ppSetExceptions = 0;
744 break;
746 default:
748 pRet = new typelib_TypeDescription();
749 #if OSL_DEBUG_LEVEL > 1
750 osl_atomic_increment( &Init::get().nTypeDescriptionCount );
751 #endif
755 pRet->nRefCount = 1; // reference count is initially 1
756 pRet->nStaticRefCount = 0;
757 pRet->eTypeClass = eTypeClass;
758 pRet->pTypeName = 0;
759 pRet->pUniqueIdentifier = 0;
760 pRet->pReserved = 0;
761 rtl_uString_acquire( pRet->pTypeName = pTypeName );
762 pRet->pSelf = pRet;
763 pRet->bComplete = sal_True;
764 pRet->nSize = 0;
765 pRet->nAlignment = 0;
766 pRet->pWeakRef = 0;
767 pRet->bOnDemand = sal_False;
768 *ppRet = pRet;
771 //------------------------------------------------------------------------
772 namespace {
774 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)
780 OSL_ASSERT(
781 (pCompoundMembers == 0 || pStructMembers == 0)
782 && (pStructMembers == 0 || eTypeClass == typelib_TypeClass_STRUCT));
783 if (typelib_TypeClass_TYPEDEF == eTypeClass)
785 OSL_TRACE( "### unexpected typedef!" );
786 typelib_typedescriptionreference_getDescription( ppRet, pType );
787 return;
790 typelib_typedescription_newEmpty( ppRet, eTypeClass, pTypeName );
792 switch( eTypeClass )
794 case typelib_TypeClass_SEQUENCE:
796 OSL_ASSERT( nMembers == 0 );
797 typelib_typedescriptionreference_acquire( pType );
798 ((typelib_IndirectTypeDescription *)*ppRet)->pType = pType;
800 break;
802 case typelib_TypeClass_EXCEPTION:
803 case typelib_TypeClass_STRUCT:
805 // FEATURE_EMPTYCLASS
806 typelib_CompoundTypeDescription * pTmp = (typelib_CompoundTypeDescription*)*ppRet;
808 sal_Int32 nOffset = 0;
809 if( pType )
811 typelib_typedescriptionreference_getDescription(
812 (typelib_TypeDescription **)&pTmp->pBaseTypeDescription, pType );
813 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!" );
816 if( nMembers )
818 pTmp->nMembers = nMembers;
819 pTmp->pMemberOffsets = new sal_Int32[ nMembers ];
820 pTmp->ppTypeRefs = new typelib_TypeDescriptionReference *[ nMembers ];
821 pTmp->ppMemberNames = new rtl_uString *[ nMembers ];
822 bool polymorphic = eTypeClass == typelib_TypeClass_STRUCT
823 && rtl::OUString::unacquired(&pTypeName).indexOf('<') >= 0;
824 OSL_ASSERT(!polymorphic || pStructMembers != 0);
825 if (polymorphic) {
826 reinterpret_cast< typelib_StructTypeDescription * >(pTmp)->
827 pParameterizedTypes = new sal_Bool[nMembers];
829 for( sal_Int32 i = 0 ; i < nMembers; i++ )
831 // read the type and member names
832 pTmp->ppTypeRefs[i] = 0;
833 if (pCompoundMembers != 0) {
834 typelib_typedescriptionreference_new(
835 pTmp->ppTypeRefs +i, pCompoundMembers[i].eTypeClass,
836 pCompoundMembers[i].pTypeName );
837 rtl_uString_acquire(
838 pTmp->ppMemberNames[i]
839 = pCompoundMembers[i].pMemberName );
840 } else {
841 typelib_typedescriptionreference_new(
842 pTmp->ppTypeRefs +i,
843 pStructMembers[i].aBase.eTypeClass,
844 pStructMembers[i].aBase.pTypeName );
845 rtl_uString_acquire(
846 pTmp->ppMemberNames[i]
847 = pStructMembers[i].aBase.pMemberName );
849 // write offset
850 sal_Int32 size;
851 sal_Int32 alignment;
852 if (pTmp->ppTypeRefs[i]->eTypeClass ==
853 typelib_TypeClass_SEQUENCE)
855 // Take care of recursion like
856 // struct S { sequence<S> x; };
857 size = sizeof(void *);
858 alignment = adjustAlignment(size);
859 } else {
860 typelib_TypeDescription * pTD = 0;
861 TYPELIB_DANGER_GET( &pTD, pTmp->ppTypeRefs[i] );
862 OSL_ENSURE( pTD->nSize, "### void member?" );
863 size = pTD->nSize;
864 alignment = pTD->nAlignment;
865 TYPELIB_DANGER_RELEASE( pTD );
867 nOffset = newAlignedSize( nOffset, size, alignment );
868 pTmp->pMemberOffsets[i] = nOffset - size;
870 if (polymorphic) {
871 reinterpret_cast< typelib_StructTypeDescription * >(
872 pTmp)->pParameterizedTypes[i]
873 = pStructMembers[i].bParameterizedType;
878 break;
880 default:
881 break;
884 if( !reallyWeak( eTypeClass ) )
885 (*ppRet)->pWeakRef = (typelib_TypeDescriptionReference *)*ppRet;
886 if( eTypeClass != typelib_TypeClass_VOID )
888 // sizeof( void ) not allowed
889 (*ppRet)->nSize = typelib_typedescription_getAlignedUnoSize( (*ppRet), 0, (*ppRet)->nAlignment );
890 (*ppRet)->nAlignment = adjustAlignment( (*ppRet)->nAlignment );
896 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()
905 newTypeDescription(
906 ppRet, eTypeClass, pTypeName, pType, nMembers, pMembers, 0);
909 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()
917 newTypeDescription(
918 ppRet, typelib_TypeClass_STRUCT, pTypeName, pType, nMembers, 0,
919 pMembers);
922 //------------------------------------------------------------------------
923 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()
933 typelib_typedescription_newEmpty( ppRet, typelib_TypeClass_UNION, pTypeName );
934 // discriminant type
935 typelib_UnionTypeDescription * pTmp = (typelib_UnionTypeDescription *)*ppRet;
936 typelib_typedescriptionreference_acquire( pTmp->pDiscriminantTypeRef = pDiscriminantTypeRef );
938 sal_Int32 nPos;
940 pTmp->nMembers = nMembers;
941 // default discriminant
942 if (nMembers)
944 pTmp->pDiscriminants = new sal_Int64[ nMembers ];
945 for ( nPos = nMembers; nPos--; )
947 pTmp->pDiscriminants[nPos] = pMembers[nPos].nDiscriminant;
950 // default default discriminant
951 pTmp->nDefaultDiscriminant = nDefaultDiscriminant;
953 // union member types
954 pTmp->ppTypeRefs = new typelib_TypeDescriptionReference *[ nMembers ];
955 for ( nPos = nMembers; nPos--; )
957 typelib_typedescriptionreference_acquire( pTmp->ppTypeRefs[nPos] = pMembers[nPos].pTypeRef );
959 // union member names
960 pTmp->ppMemberNames = new rtl_uString *[ nMembers ];
961 for ( nPos = nMembers; nPos--; )
963 rtl_uString_acquire( pTmp->ppMemberNames[nPos] = pMembers[nPos].pMemberName );
966 // default union type
967 typelib_typedescriptionreference_acquire( pTmp->pDefaultTypeRef = pDefaultTypeRef );
969 if (! reallyWeak( typelib_TypeClass_UNION ))
970 (*ppRet)->pWeakRef = (typelib_TypeDescriptionReference *)*ppRet;
971 (*ppRet)->nSize = typelib_typedescription_getAlignedUnoSize( (*ppRet), 0, (*ppRet)->nAlignment );
972 (*ppRet)->nAlignment = adjustAlignment( (*ppRet)->nAlignment );
975 //------------------------------------------------------------------------
976 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()
985 typelib_typedescription_newEmpty( ppRet, typelib_TypeClass_ENUM, pTypeName );
986 typelib_EnumTypeDescription * pEnum = (typelib_EnumTypeDescription *)*ppRet;
988 pEnum->nDefaultEnumValue = nDefaultValue;
989 pEnum->nEnumValues = nEnumValues;
990 pEnum->ppEnumNames = new rtl_uString * [ nEnumValues ];
991 for ( sal_Int32 nPos = nEnumValues; nPos--; )
993 rtl_uString_acquire( pEnum->ppEnumNames[nPos] = ppEnumNames[nPos] );
995 pEnum->pEnumValues = new sal_Int32[ nEnumValues ];
996 ::memcpy( pEnum->pEnumValues, pEnumValues, nEnumValues * sizeof(sal_Int32) );
998 (*ppRet)->pWeakRef = (typelib_TypeDescriptionReference *)*ppRet;
999 // sizeof( void ) not allowed
1000 (*ppRet)->nSize = typelib_typedescription_getAlignedUnoSize( (*ppRet), 0, (*ppRet)->nAlignment );
1001 (*ppRet)->nAlignment = adjustAlignment( (*ppRet)->nAlignment );
1004 //------------------------------------------------------------------------
1005 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 ()
1012 OUStringBuffer aBuf( 32 );
1013 aBuf.append( pElementTypeRef->pTypeName );
1014 sal_Int32 nElements = 1;
1015 for (sal_Int32 i=0; i < nDimensions; i++)
1017 aBuf.appendAscii("[");
1018 aBuf.append(pDimensions[i]);
1019 aBuf.appendAscii("]");
1020 nElements *= pDimensions[i];
1022 OUString aTypeName( aBuf.makeStringAndClear() );
1025 typelib_typedescription_newEmpty( ppRet, typelib_TypeClass_ARRAY, aTypeName.pData );
1026 typelib_ArrayTypeDescription * pArray = (typelib_ArrayTypeDescription *)*ppRet;
1028 pArray->nDimensions = nDimensions;
1029 pArray->nTotalElements = nElements;
1030 pArray->pDimensions = new sal_Int32[ nDimensions ];
1031 ::memcpy( pArray->pDimensions, pDimensions, nDimensions * sizeof(sal_Int32) );
1033 typelib_typedescriptionreference_acquire(pElementTypeRef);
1034 ((typelib_IndirectTypeDescription*)pArray)->pType = pElementTypeRef;
1036 (*ppRet)->pWeakRef = (typelib_TypeDescriptionReference *)*ppRet;
1037 // sizeof( void ) not allowed
1038 (*ppRet)->nSize = typelib_typedescription_getAlignedUnoSize( *ppRet, 0, (*ppRet)->nAlignment );
1039 (*ppRet)->nAlignment = adjustAlignment( (*ppRet)->nAlignment );
1042 //------------------------------------------------------------------------
1043 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()
1052 typelib_typedescription_newMIInterface(
1053 ppRet, pTypeName, nUik1, nUik2, nUik3, nUik4, nUik5,
1054 pBaseInterface == 0 ? 0 : 1, &pBaseInterface, nMembers, ppMembers);
1057 //------------------------------------------------------------------------
1059 namespace {
1061 class BaseList {
1062 public:
1063 struct Entry {
1064 sal_Int32 memberOffset;
1065 sal_Int32 directBaseIndex;
1066 sal_Int32 directBaseMemberOffset;
1067 typelib_InterfaceTypeDescription const * base;
1070 typedef std::vector< Entry > List;
1072 BaseList(typelib_InterfaceTypeDescription const * desc);
1074 List const & getList() const { return list; }
1076 sal_Int32 getBaseMembers() const { return members; }
1078 private:
1079 typedef std::set< rtl::OUString > Set;
1081 void calculate(
1082 sal_Int32 directBaseIndex, Set & directBaseSet,
1083 sal_Int32 * directBaseMembers,
1084 typelib_InterfaceTypeDescription const * desc);
1086 Set set;
1087 List list;
1088 sal_Int32 members;
1091 BaseList::BaseList(typelib_InterfaceTypeDescription const * desc) {
1092 members = 0;
1093 for (sal_Int32 i = 0; i < desc->nBaseTypes; ++i) {
1094 Set directBaseSet;
1095 sal_Int32 directBaseMembers = 0;
1096 calculate(i, directBaseSet, &directBaseMembers, desc->ppBaseTypes[i]);
1100 void BaseList::calculate(
1101 sal_Int32 directBaseIndex, Set & directBaseSet,
1102 sal_Int32 * directBaseMembers,
1103 typelib_InterfaceTypeDescription const * desc)
1105 for (sal_Int32 i = 0; i < desc->nBaseTypes; ++i) {
1106 calculate(
1107 directBaseIndex, directBaseSet, directBaseMembers,
1108 desc->ppBaseTypes[i]);
1110 if (set.insert(desc->aBase.pTypeName).second) {
1111 Entry e;
1112 e.memberOffset = members;
1113 e.directBaseIndex = directBaseIndex;
1114 e.directBaseMemberOffset = *directBaseMembers;
1115 e.base = desc;
1116 list.push_back(e);
1117 OSL_ASSERT(desc->ppAllMembers != 0);
1118 members += desc->nMembers;
1120 if (directBaseSet.insert(desc->aBase.pTypeName).second) {
1121 OSL_ASSERT(desc->ppAllMembers != 0);
1122 *directBaseMembers += desc->nMembers;
1128 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()
1138 if (*ppRet != 0) {
1139 typelib_typedescription_release(&(*ppRet)->aBase);
1140 *ppRet = 0;
1143 typelib_InterfaceTypeDescription * pITD = 0;
1144 typelib_typedescription_newEmpty(
1145 (typelib_TypeDescription **)&pITD, typelib_TypeClass_INTERFACE, pTypeName );
1147 pITD->nBaseTypes = nBaseInterfaces;
1148 pITD->ppBaseTypes = new typelib_InterfaceTypeDescription *[nBaseInterfaces];
1149 for (sal_Int32 i = 0; i < nBaseInterfaces; ++i) {
1150 pITD->ppBaseTypes[i] = 0;
1151 typelib_typedescriptionreference_getDescription(
1152 reinterpret_cast< typelib_TypeDescription ** >(
1153 &pITD->ppBaseTypes[i]),
1154 ppBaseInterfaces[i]);
1155 if (pITD->ppBaseTypes[i] == 0
1156 || !complete(
1157 reinterpret_cast< typelib_TypeDescription ** >(
1158 &pITD->ppBaseTypes[i]),
1159 false))
1161 OSL_ASSERT(false);
1162 return;
1164 OSL_ASSERT(pITD->ppBaseTypes[i] != 0);
1166 if (nBaseInterfaces > 0) {
1167 pITD->pBaseTypeDescription = pITD->ppBaseTypes[0];
1169 // set the
1170 pITD->aUik.m_Data1 = nUik1;
1171 pITD->aUik.m_Data2 = nUik2;
1172 pITD->aUik.m_Data3 = nUik3;
1173 pITD->aUik.m_Data4 = nUik4;
1174 pITD->aUik.m_Data5 = nUik5;
1176 BaseList aBaseList(pITD);
1177 pITD->nAllMembers = nMembers + aBaseList.getBaseMembers();
1178 pITD->nMembers = nMembers;
1180 if( pITD->nAllMembers )
1182 // at minimum one member exist, allocate the memory
1183 pITD->ppAllMembers = new typelib_TypeDescriptionReference *[ pITD->nAllMembers ];
1184 sal_Int32 n = 0;
1186 BaseList::List const & rList = aBaseList.getList();
1187 for (BaseList::List::const_iterator i(rList.begin()); i != rList.end();
1188 ++i)
1190 typelib_InterfaceTypeDescription const * pBase = i->base;
1191 typelib_InterfaceTypeDescription const * pDirectBase
1192 = pITD->ppBaseTypes[i->directBaseIndex];
1193 OSL_ASSERT(pBase->ppAllMembers != 0);
1194 for (sal_Int32 j = 0; j < pBase->nMembers; ++j) {
1195 typelib_TypeDescriptionReference const * pDirectBaseMember
1196 = pDirectBase->ppAllMembers[i->directBaseMemberOffset + j];
1197 rtl::OUStringBuffer aBuf(pDirectBaseMember->pTypeName);
1198 aBuf.appendAscii(RTL_CONSTASCII_STRINGPARAM(":@"));
1199 aBuf.append(i->directBaseIndex);
1200 aBuf.append(static_cast< sal_Unicode >(','));
1201 aBuf.append(i->memberOffset + j);
1202 aBuf.append(static_cast< sal_Unicode >(':'));
1203 aBuf.append(pITD->aBase.pTypeName);
1204 rtl::OUString aName(aBuf.makeStringAndClear());
1205 typelib_TypeDescriptionReference * pDerivedMember = 0;
1206 typelib_typedescriptionreference_new(
1207 &pDerivedMember, pDirectBaseMember->eTypeClass,
1208 aName.pData);
1209 pITD->ppAllMembers[n++] = pDerivedMember;
1213 if( nMembers )
1215 pITD->ppMembers = pITD->ppAllMembers + aBaseList.getBaseMembers();
1218 // add own members
1219 for( sal_Int32 i = 0; i < nMembers; i++ )
1221 typelib_typedescriptionreference_acquire( ppMembers[i] );
1222 pITD->ppAllMembers[n++] = ppMembers[i];
1226 typelib_TypeDescription * pTmp = (typelib_TypeDescription *)pITD;
1227 if( !reallyWeak( typelib_TypeClass_INTERFACE ) )
1228 pTmp->pWeakRef = (typelib_TypeDescriptionReference *)pTmp;
1229 pTmp->nSize = typelib_typedescription_getAlignedUnoSize( pTmp, 0, pTmp->nAlignment );
1230 pTmp->nAlignment = adjustAlignment( pTmp->nAlignment );
1231 pTmp->bComplete = sal_False;
1233 *ppRet = pITD;
1236 //------------------------------------------------------------------------
1238 namespace {
1240 typelib_TypeDescriptionReference ** copyExceptions(
1241 sal_Int32 count, rtl_uString ** typeNames)
1243 OSL_ASSERT(count >= 0);
1244 if (count == 0) {
1245 return 0;
1247 typelib_TypeDescriptionReference ** p
1248 = new typelib_TypeDescriptionReference *[count];
1249 for (sal_Int32 i = 0; i < count; ++i) {
1250 p[i] = 0;
1251 typelib_typedescriptionreference_new(
1252 p + i, typelib_TypeClass_EXCEPTION, typeNames[i]);
1254 return p;
1259 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()
1272 if (*ppRet != 0) {
1273 typelib_typedescription_release(&(*ppRet)->aBase.aBase);
1274 *ppRet = 0;
1276 sal_Int32 nOffset = rtl_ustr_lastIndexOfChar_WithLength(
1277 pTypeName->buffer, pTypeName->length, ':');
1278 if (nOffset <= 0 || pTypeName->buffer[nOffset - 1] != ':') {
1279 OSL_FAIL("Bad interface method type name");
1280 return;
1282 rtl::OUString aInterfaceTypeName(pTypeName->buffer, nOffset - 1);
1283 typelib_InterfaceTypeDescription * pInterface = 0;
1284 typelib_typedescription_getByName(
1285 reinterpret_cast< typelib_TypeDescription ** >(&pInterface),
1286 aInterfaceTypeName.pData);
1287 if (pInterface == 0
1288 || pInterface->aBase.eTypeClass != typelib_TypeClass_INTERFACE
1289 || !complete(
1290 reinterpret_cast< typelib_TypeDescription ** >(&pInterface), false))
1292 OSL_FAIL("No interface corresponding to interface method");
1293 return;
1296 typelib_typedescription_newEmpty(
1297 (typelib_TypeDescription **)ppRet, typelib_TypeClass_INTERFACE_METHOD, pTypeName );
1298 typelib_TypeDescription * pTmp = (typelib_TypeDescription *)*ppRet;
1300 rtl_uString_newFromStr_WithLength( &(*ppRet)->aBase.pMemberName,
1301 pTypeName->buffer + nOffset +1,
1302 pTypeName->length - nOffset -1 );
1303 (*ppRet)->aBase.nPosition = nAbsolutePosition;
1304 (*ppRet)->bOneWay = bOneWay;
1305 typelib_typedescriptionreference_new( &(*ppRet)->pReturnTypeRef, eReturnTypeClass, pReturnTypeName );
1306 (*ppRet)->nParams = nParams;
1307 if( nParams )
1309 (*ppRet)->pParams = new typelib_MethodParameter[ nParams ];
1311 for( sal_Int32 i = 0; i < nParams; i++ )
1313 // get the name of the parameter
1314 (*ppRet)->pParams[ i ].pName = 0;
1315 rtl_uString_acquire( (*ppRet)->pParams[ i ].pName = pParams[i].pParamName );
1316 (*ppRet)->pParams[ i ].pTypeRef = 0;
1317 // get the type name of the parameter and create the weak reference
1318 typelib_typedescriptionreference_new(
1319 &(*ppRet)->pParams[ i ].pTypeRef, pParams[i].eTypeClass, pParams[i].pTypeName );
1320 (*ppRet)->pParams[ i ].bIn = pParams[i].bIn;
1321 (*ppRet)->pParams[ i ].bOut = pParams[i].bOut;
1324 (*ppRet)->nExceptions = nExceptions;
1325 (*ppRet)->ppExceptions = copyExceptions(nExceptions, ppExceptionNames);
1326 (*ppRet)->pInterface = pInterface;
1327 (*ppRet)->pBaseRef = 0;
1328 OSL_ASSERT(
1329 (nAbsolutePosition >= pInterface->nAllMembers - pInterface->nMembers)
1330 && nAbsolutePosition < pInterface->nAllMembers);
1331 (*ppRet)->nIndex = nAbsolutePosition
1332 - (pInterface->nAllMembers - pInterface->nMembers);
1333 if( !reallyWeak( typelib_TypeClass_INTERFACE_METHOD ) )
1334 pTmp->pWeakRef = (typelib_TypeDescriptionReference *)pTmp;
1338 //------------------------------------------------------------------------
1339 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()
1348 typelib_typedescription_newExtendedInterfaceAttribute(
1349 ppRet, nAbsolutePosition, pTypeName, eAttributeTypeClass,
1350 pAttributeTypeName, bReadOnly, 0, 0, 0, 0);
1353 //------------------------------------------------------------------------
1354 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()
1365 if (*ppRet != 0) {
1366 typelib_typedescription_release(&(*ppRet)->aBase.aBase);
1367 *ppRet = 0;
1369 sal_Int32 nOffset = rtl_ustr_lastIndexOfChar_WithLength(
1370 pTypeName->buffer, pTypeName->length, ':');
1371 if (nOffset <= 0 || pTypeName->buffer[nOffset - 1] != ':') {
1372 OSL_FAIL("Bad interface attribute type name");
1373 return;
1375 rtl::OUString aInterfaceTypeName(pTypeName->buffer, nOffset - 1);
1376 typelib_InterfaceTypeDescription * pInterface = 0;
1377 typelib_typedescription_getByName(
1378 reinterpret_cast< typelib_TypeDescription ** >(&pInterface),
1379 aInterfaceTypeName.pData);
1380 if (pInterface == 0
1381 || pInterface->aBase.eTypeClass != typelib_TypeClass_INTERFACE
1382 || !complete(
1383 reinterpret_cast< typelib_TypeDescription ** >(&pInterface), false))
1385 OSL_FAIL("No interface corresponding to interface attribute");
1386 return;
1389 typelib_typedescription_newEmpty(
1390 (typelib_TypeDescription **)ppRet, typelib_TypeClass_INTERFACE_ATTRIBUTE, pTypeName );
1391 typelib_TypeDescription * pTmp = (typelib_TypeDescription *)*ppRet;
1393 rtl_uString_newFromStr_WithLength( &(*ppRet)->aBase.pMemberName,
1394 pTypeName->buffer + nOffset +1,
1395 pTypeName->length - nOffset -1 );
1396 (*ppRet)->aBase.nPosition = nAbsolutePosition;
1397 typelib_typedescriptionreference_new( &(*ppRet)->pAttributeTypeRef, eAttributeTypeClass, pAttributeTypeName );
1398 (*ppRet)->bReadOnly = bReadOnly;
1399 (*ppRet)->pInterface = pInterface;
1400 (*ppRet)->pBaseRef = 0;
1401 OSL_ASSERT(
1402 (nAbsolutePosition >= pInterface->nAllMembers - pInterface->nMembers)
1403 && nAbsolutePosition < pInterface->nAllMembers);
1404 (*ppRet)->nIndex = nAbsolutePosition
1405 - (pInterface->nAllMembers - pInterface->nMembers);
1406 (*ppRet)->nGetExceptions = nGetExceptions;
1407 (*ppRet)->ppGetExceptions = copyExceptions(
1408 nGetExceptions, ppGetExceptionNames);
1409 (*ppRet)->nSetExceptions = nSetExceptions;
1410 (*ppRet)->ppSetExceptions = copyExceptions(
1411 nSetExceptions, ppSetExceptionNames);
1412 if( !reallyWeak( typelib_TypeClass_INTERFACE_ATTRIBUTE ) )
1413 pTmp->pWeakRef = (typelib_TypeDescriptionReference *)pTmp;
1416 //------------------------------------------------------------------------
1417 extern "C" CPPU_DLLPUBLIC void SAL_CALL typelib_typedescription_acquire(
1418 typelib_TypeDescription * pTypeDescription )
1419 SAL_THROW_EXTERN_C()
1421 osl_atomic_increment( &pTypeDescription->nRefCount );
1424 //------------------------------------------------------------------------
1426 namespace {
1428 void deleteExceptions(
1429 sal_Int32 count, typelib_TypeDescriptionReference ** exceptions)
1431 for (sal_Int32 i = 0; i < count; ++i) {
1432 typelib_typedescriptionreference_release(exceptions[i]);
1434 delete[] exceptions;
1439 // frees anything except typelib_TypeDescription base!
1440 static inline void typelib_typedescription_destructExtendedMembers(
1441 typelib_TypeDescription * pTD )
1442 SAL_THROW(())
1444 OSL_ASSERT( typelib_TypeClass_TYPEDEF != pTD->eTypeClass );
1446 switch( pTD->eTypeClass )
1448 case typelib_TypeClass_ARRAY:
1449 if( ((typelib_IndirectTypeDescription*)pTD)->pType )
1450 typelib_typedescriptionreference_release( ((typelib_IndirectTypeDescription*)pTD)->pType );
1451 delete [] ((typelib_ArrayTypeDescription *)pTD)->pDimensions;
1452 break;
1453 case typelib_TypeClass_SEQUENCE:
1454 if( ((typelib_IndirectTypeDescription*)pTD)->pType )
1455 typelib_typedescriptionreference_release( ((typelib_IndirectTypeDescription*)pTD)->pType );
1456 break;
1457 case typelib_TypeClass_UNION:
1459 typelib_UnionTypeDescription * pUnionTD = (typelib_UnionTypeDescription *)pTD;
1460 typelib_typedescriptionreference_release( pUnionTD->pDiscriminantTypeRef );
1461 typelib_typedescriptionreference_release( pUnionTD->pDefaultTypeRef );
1463 sal_Int32 nPos;
1464 typelib_TypeDescriptionReference ** ppTypeRefs = pUnionTD->ppTypeRefs;
1465 for ( nPos = pUnionTD->nMembers; nPos--; )
1467 typelib_typedescriptionreference_release( ppTypeRefs[nPos] );
1470 rtl_uString ** ppMemberNames = pUnionTD->ppMemberNames;
1471 for ( nPos = pUnionTD->nMembers; nPos--; )
1473 rtl_uString_release( ppMemberNames[nPos] );
1475 delete [] pUnionTD->ppMemberNames;
1476 delete [] pUnionTD->pDiscriminants;
1477 delete [] pUnionTD->ppTypeRefs;
1479 break;
1480 case typelib_TypeClass_STRUCT:
1481 delete[] reinterpret_cast< typelib_StructTypeDescription * >(pTD)->
1482 pParameterizedTypes;
1483 // Fall-through intentional
1484 case typelib_TypeClass_EXCEPTION:
1486 typelib_CompoundTypeDescription * pCTD = (typelib_CompoundTypeDescription*)pTD;
1487 if( pCTD->pBaseTypeDescription )
1488 typelib_typedescription_release( (typelib_TypeDescription *)pCTD->pBaseTypeDescription );
1489 sal_Int32 i;
1490 for( i = 0; i < pCTD->nMembers; i++ )
1492 typelib_typedescriptionreference_release( pCTD->ppTypeRefs[i] );
1494 if (pCTD->ppMemberNames)
1496 for ( i = 0; i < pCTD->nMembers; i++ )
1498 rtl_uString_release( pCTD->ppMemberNames[i] );
1500 delete [] pCTD->ppMemberNames;
1502 delete [] pCTD->ppTypeRefs;
1503 delete [] pCTD->pMemberOffsets;
1505 break;
1506 case typelib_TypeClass_INTERFACE:
1508 typelib_InterfaceTypeDescription * pITD = (typelib_InterfaceTypeDescription*)pTD;
1509 for( sal_Int32 i = 0; i < pITD->nAllMembers; i++ )
1511 typelib_typedescriptionreference_release( pITD->ppAllMembers[i] );
1513 delete [] pITD->ppAllMembers;
1514 delete [] pITD->pMapMemberIndexToFunctionIndex;
1515 delete [] pITD->pMapFunctionIndexToMemberIndex;
1516 for (sal_Int32 i = 0; i < pITD->nBaseTypes; ++i) {
1517 typelib_typedescription_release(
1518 reinterpret_cast< typelib_TypeDescription * >(
1519 pITD->ppBaseTypes[i]));
1521 delete[] pITD->ppBaseTypes;
1522 break;
1524 case typelib_TypeClass_INTERFACE_METHOD:
1526 typelib_InterfaceMethodTypeDescription * pIMTD = (typelib_InterfaceMethodTypeDescription*)pTD;
1527 if( pIMTD->pReturnTypeRef )
1528 typelib_typedescriptionreference_release( pIMTD->pReturnTypeRef );
1529 for( sal_Int32 i = 0; i < pIMTD->nParams; i++ )
1531 rtl_uString_release( pIMTD->pParams[ i ].pName );
1532 typelib_typedescriptionreference_release( pIMTD->pParams[ i ].pTypeRef );
1534 delete [] pIMTD->pParams;
1535 deleteExceptions(pIMTD->nExceptions, pIMTD->ppExceptions);
1536 rtl_uString_release( pIMTD->aBase.pMemberName );
1537 typelib_typedescription_release(&pIMTD->pInterface->aBase);
1538 if (pIMTD->pBaseRef != 0) {
1539 typelib_typedescriptionreference_release(pIMTD->pBaseRef);
1542 break;
1543 case typelib_TypeClass_INTERFACE_ATTRIBUTE:
1545 typelib_InterfaceAttributeTypeDescription * pIATD = (typelib_InterfaceAttributeTypeDescription*)pTD;
1546 deleteExceptions(pIATD->nGetExceptions, pIATD->ppGetExceptions);
1547 deleteExceptions(pIATD->nSetExceptions, pIATD->ppSetExceptions);
1548 if( pIATD->pAttributeTypeRef )
1549 typelib_typedescriptionreference_release( pIATD->pAttributeTypeRef );
1550 if( pIATD->aBase.pMemberName )
1551 rtl_uString_release( pIATD->aBase.pMemberName );
1552 typelib_typedescription_release(&pIATD->pInterface->aBase);
1553 if (pIATD->pBaseRef != 0) {
1554 typelib_typedescriptionreference_release(pIATD->pBaseRef);
1557 break;
1558 case typelib_TypeClass_ENUM:
1560 typelib_EnumTypeDescription * pEnum = (typelib_EnumTypeDescription *)pTD;
1561 for ( sal_Int32 nPos = pEnum->nEnumValues; nPos--; )
1563 rtl_uString_release( pEnum->ppEnumNames[nPos] );
1565 delete [] pEnum->ppEnumNames;
1566 delete [] pEnum->pEnumValues;
1568 break;
1569 default:
1570 break;
1574 //------------------------------------------------------------------------
1575 extern "C" CPPU_DLLPUBLIC void SAL_CALL typelib_typedescription_release(
1576 typelib_TypeDescription * pTD )
1577 SAL_THROW_EXTERN_C()
1579 sal_Int32 ref = osl_atomic_decrement( &pTD->nRefCount );
1580 OSL_ASSERT(ref >= 0);
1581 if (0 == ref)
1583 TypeDescriptor_Init_Impl &rInit = Init::get();
1584 if( reallyWeak( pTD->eTypeClass ) )
1586 if( pTD->pWeakRef )
1589 MutexGuard aGuard( rInit.getMutex() );
1590 // remove this description from the weak reference
1591 pTD->pWeakRef->pType = 0;
1593 typelib_typedescriptionreference_release( pTD->pWeakRef );
1596 else
1598 // this description is a reference too, so remove it from the hash table
1599 if( rInit.pWeakMap )
1601 MutexGuard aGuard( rInit.getMutex() );
1602 WeakMap_Impl::iterator aIt = rInit.pWeakMap->find( (sal_Unicode*)pTD->pTypeName->buffer );
1603 if( aIt != rInit.pWeakMap->end() && (void *)(*aIt).second == (void *)pTD )
1605 // remove only if it contains the same object
1606 rInit.pWeakMap->erase( aIt );
1611 typelib_typedescription_destructExtendedMembers( pTD );
1612 rtl_uString_release( pTD->pTypeName );
1614 #if OSL_DEBUG_LEVEL > 1
1615 switch( pTD->eTypeClass )
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 );
1645 #endif
1647 delete pTD;
1651 //------------------------------------------------------------------------
1652 extern "C" CPPU_DLLPUBLIC void SAL_CALL typelib_typedescription_register(
1653 typelib_TypeDescription ** ppNewDescription )
1654 SAL_THROW_EXTERN_C()
1656 // connect the description with the weak reference
1657 TypeDescriptor_Init_Impl &rInit = Init::get();
1658 ClearableMutexGuard aGuard( rInit.getMutex() );
1660 typelib_TypeDescriptionReference * pTDR = 0;
1661 typelib_typedescriptionreference_getByName( &pTDR, (*ppNewDescription)->pTypeName );
1663 OSL_ASSERT( (*ppNewDescription)->pWeakRef || reallyWeak( (*ppNewDescription)->eTypeClass ) );
1664 if( pTDR )
1666 OSL_ASSERT( (*ppNewDescription)->eTypeClass == pTDR->eTypeClass );
1667 if( pTDR->pType )
1669 if (reallyWeak( pTDR->eTypeClass ))
1671 // pRef->pType->pWeakRef == 0 means that the description is empty
1672 if (pTDR->pType->pWeakRef)
1674 if (osl_atomic_increment( &pTDR->pType->nRefCount ) > 1)
1676 // The refence is incremented. The object cannot be destroyed.
1677 // Release the guard at the earliest point.
1678 aGuard.clear();
1679 ::typelib_typedescription_release( *ppNewDescription );
1680 *ppNewDescription = pTDR->pType;
1681 ::typelib_typedescriptionreference_release( pTDR );
1682 return;
1684 else
1686 // destruction of this type in progress (another thread!)
1687 osl_atomic_decrement( &pTDR->pType->nRefCount );
1690 // take new descr
1691 pTDR->pType = *ppNewDescription;
1692 OSL_ASSERT( ! (*ppNewDescription)->pWeakRef );
1693 (*ppNewDescription)->pWeakRef = pTDR;
1694 return;
1696 // !reallyWeak
1698 if (((void *)pTDR != (void *)*ppNewDescription) && // if different
1699 (!pTDR->pType->pWeakRef || // uninit: ref data only set
1700 // new one is complete:
1701 (!pTDR->pType->bComplete && (*ppNewDescription)->bComplete) ||
1702 // new one may be partly initialized interface (except of tables):
1703 (typelib_TypeClass_INTERFACE == pTDR->pType->eTypeClass &&
1704 !((typelib_InterfaceTypeDescription *)pTDR->pType)->ppAllMembers &&
1705 (*(typelib_InterfaceTypeDescription **)ppNewDescription)->ppAllMembers)))
1707 // uninitialized or incomplete
1709 if (pTDR->pType->pWeakRef) // if init
1711 typelib_typedescription_destructExtendedMembers( pTDR->pType );
1714 // pTDR->pType->pWeakRef == 0 means that the description is empty
1715 // description is not weak and the not the same
1716 sal_Int32 nSize = getDescriptionSize( (*ppNewDescription)->eTypeClass );
1718 // copy all specific data for the descriptions
1719 memcpy(
1720 pTDR->pType +1,
1721 *ppNewDescription +1,
1722 nSize - sizeof(typelib_TypeDescription) );
1724 pTDR->pType->bComplete = (*ppNewDescription)->bComplete;
1725 pTDR->pType->nSize = (*ppNewDescription)->nSize;
1726 pTDR->pType->nAlignment = (*ppNewDescription)->nAlignment;
1728 memset(
1729 *ppNewDescription +1,
1731 nSize - sizeof( typelib_TypeDescription ) );
1733 if( pTDR->pType->bOnDemand && !(*ppNewDescription)->bOnDemand )
1735 // switch from OnDemand to !OnDemand, so the description must be acquired
1736 typelib_typedescription_acquire( pTDR->pType );
1738 else if( !pTDR->pType->bOnDemand && (*ppNewDescription)->bOnDemand )
1740 // switch from !OnDemand to OnDemand, so the description must be relesed
1741 typelib_typedescription_release( pTDR->pType );
1744 pTDR->pType->bOnDemand = (*ppNewDescription)->bOnDemand;
1745 // initialized
1746 pTDR->pType->pWeakRef = pTDR;
1749 typelib_typedescription_release( *ppNewDescription );
1750 // pTDR was acquired by getByName(), so it must not be acquired again
1751 *ppNewDescription = pTDR->pType;
1752 return;
1755 else if( reallyWeak( (*ppNewDescription)->eTypeClass) )
1757 typelib_typedescriptionreference_new(
1758 &pTDR, (*ppNewDescription)->eTypeClass, (*ppNewDescription)->pTypeName );
1760 else
1762 pTDR = (typelib_TypeDescriptionReference *)*ppNewDescription;
1763 if( !rInit.pWeakMap )
1764 rInit.pWeakMap = new WeakMap_Impl;
1766 // description is the weak itself, so register it
1767 (*rInit.pWeakMap)[pTDR->pTypeName->buffer] = pTDR;
1768 OSL_ASSERT( (void *)*ppNewDescription == (void *)pTDR );
1771 // By default this reference is not really weak. The reference hold the description
1772 // and the description hold the reference.
1773 if( !(*ppNewDescription)->bOnDemand )
1775 // nor OnDemand so the description must be acquired if registered
1776 typelib_typedescription_acquire( *ppNewDescription );
1779 pTDR->pType = *ppNewDescription;
1780 (*ppNewDescription)->pWeakRef = pTDR;
1781 OSL_ASSERT( rtl_ustr_compare( pTDR->pTypeName->buffer, (*ppNewDescription)->pTypeName->buffer ) == 0 );
1782 OSL_ASSERT( pTDR->eTypeClass == (*ppNewDescription)->eTypeClass );
1785 //------------------------------------------------------------------------
1786 static inline sal_Bool type_equals(
1787 typelib_TypeDescriptionReference * p1, typelib_TypeDescriptionReference * p2 )
1788 SAL_THROW(())
1790 return (p1 == p2 ||
1791 (p1->eTypeClass == p2->eTypeClass &&
1792 p1->pTypeName->length == p2->pTypeName->length &&
1793 rtl_ustr_compare( p1->pTypeName->buffer, p2->pTypeName->buffer ) == 0));
1795 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()
1799 return type_equals(
1800 (typelib_TypeDescriptionReference *)p1, (typelib_TypeDescriptionReference *)p2 );
1803 //------------------------------------------------------------------------
1804 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()
1809 sal_Int32 nSize;
1810 if( pTypeDescription->nSize )
1812 // size and alignment are set
1813 rMaxIntegralTypeSize = pTypeDescription->nAlignment;
1814 nSize = pTypeDescription->nSize;
1816 else
1818 nSize = 0;
1819 rMaxIntegralTypeSize = 1;
1821 OSL_ASSERT( typelib_TypeClass_TYPEDEF != pTypeDescription->eTypeClass );
1823 switch( pTypeDescription->eTypeClass )
1825 case typelib_TypeClass_INTERFACE:
1826 // FEATURE_INTERFACE
1827 nSize = rMaxIntegralTypeSize = (sal_Int32)(sizeof( void * ));
1828 break;
1829 case typelib_TypeClass_UNION:
1831 nSize = rMaxIntegralTypeSize = (sal_Int32)(sizeof(sal_Int64));
1832 for ( sal_Int32 nPos = ((typelib_UnionTypeDescription *)pTypeDescription)->nMembers; nPos--; )
1834 typelib_TypeDescription * pTD = 0;
1835 TYPELIB_DANGER_GET( &pTD, ((typelib_UnionTypeDescription *)pTypeDescription)->ppTypeRefs[nPos] );
1836 sal_Int32 nMaxIntegralTypeSize;
1837 sal_Int32 nMemberSize = typelib_typedescription_getAlignedUnoSize( pTD, (sal_Int32)(sizeof(sal_Int64)), nMaxIntegralTypeSize );
1838 TYPELIB_DANGER_RELEASE( pTD );
1839 if (nSize < nMemberSize)
1840 nSize = nMemberSize;
1841 if (rMaxIntegralTypeSize < nMaxIntegralTypeSize)
1842 rMaxIntegralTypeSize = nMaxIntegralTypeSize;
1844 ((typelib_UnionTypeDescription *)pTypeDescription)->nValueOffset = rMaxIntegralTypeSize;
1846 break;
1847 case typelib_TypeClass_ENUM:
1848 nSize = rMaxIntegralTypeSize = (sal_Int32)(sizeof( typelib_TypeClass ));
1849 break;
1850 case typelib_TypeClass_STRUCT:
1851 case typelib_TypeClass_EXCEPTION:
1852 // FEATURE_EMPTYCLASS
1854 typelib_CompoundTypeDescription * pTmp = (typelib_CompoundTypeDescription *)pTypeDescription;
1855 sal_Int32 nStructSize = 0;
1856 if( pTmp->pBaseTypeDescription )
1858 // inherit structs extends the base struct.
1859 nStructSize = pTmp->pBaseTypeDescription->aBase.nSize;
1860 rMaxIntegralTypeSize = pTmp->pBaseTypeDescription->aBase.nAlignment;
1862 for( sal_Int32 i = 0; i < pTmp->nMembers; i++ )
1864 typelib_TypeDescription * pMemberType = 0;
1865 typelib_TypeDescriptionReference * pMemberRef = pTmp->ppTypeRefs[i];
1867 sal_Int32 nMaxIntegral;
1868 if (pMemberRef->eTypeClass == typelib_TypeClass_INTERFACE
1869 || pMemberRef->eTypeClass == typelib_TypeClass_SEQUENCE)
1871 nMaxIntegral = (sal_Int32)(sizeof(void *));
1872 nStructSize = newAlignedSize( nStructSize, nMaxIntegral, nMaxIntegral );
1874 else
1876 TYPELIB_DANGER_GET( &pMemberType, pMemberRef );
1877 nStructSize = typelib_typedescription_getAlignedUnoSize(
1878 pMemberType, nStructSize, nMaxIntegral );
1879 TYPELIB_DANGER_RELEASE( pMemberType );
1881 if( nMaxIntegral > rMaxIntegralTypeSize )
1882 rMaxIntegralTypeSize = nMaxIntegral;
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 nStructSize = (nStructSize + rMaxIntegralTypeSize -1)
1894 / rMaxIntegralTypeSize * rMaxIntegralTypeSize;
1895 #endif
1896 nSize += nStructSize;
1898 break;
1899 case typelib_TypeClass_ARRAY:
1901 typelib_TypeDescription * pTD = 0;
1902 TYPELIB_DANGER_GET( &pTD, ((typelib_IndirectTypeDescription *)pTypeDescription)->pType );
1903 rMaxIntegralTypeSize = pTD->nSize;
1904 TYPELIB_DANGER_RELEASE( pTD );
1905 nSize = ((typelib_ArrayTypeDescription *)pTypeDescription)->nTotalElements * rMaxIntegralTypeSize;
1907 break;
1908 case typelib_TypeClass_SEQUENCE:
1909 nSize = rMaxIntegralTypeSize = (sal_Int32)(sizeof( void * ));
1910 break;
1911 case typelib_TypeClass_ANY:
1912 // FEATURE_ANY
1913 nSize = (sal_Int32)(sizeof( uno_Any ));
1914 rMaxIntegralTypeSize = (sal_Int32)(sizeof( void * ));
1915 break;
1916 case typelib_TypeClass_TYPE:
1917 nSize = rMaxIntegralTypeSize = (sal_Int32)(sizeof( typelib_TypeDescriptionReference * ));
1918 break;
1919 case typelib_TypeClass_BOOLEAN:
1920 nSize = rMaxIntegralTypeSize = (sal_Int32)(sizeof( sal_Bool ));
1921 break;
1922 case typelib_TypeClass_CHAR:
1923 nSize = rMaxIntegralTypeSize = (sal_Int32)(sizeof( sal_Unicode ));
1924 break;
1925 case typelib_TypeClass_STRING:
1926 // FEATURE_STRING
1927 nSize = rMaxIntegralTypeSize = (sal_Int32)(sizeof( rtl_uString * ));
1928 break;
1929 case typelib_TypeClass_FLOAT:
1930 nSize = rMaxIntegralTypeSize = (sal_Int32)(sizeof( float ));
1931 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 nSize = rMaxIntegralTypeSize = (sal_Int32)(sizeof( double ));
1939 #endif
1940 break;
1941 case typelib_TypeClass_BYTE:
1942 nSize = rMaxIntegralTypeSize = (sal_Int32)(sizeof( sal_Int8 ));
1943 break;
1944 case typelib_TypeClass_SHORT:
1945 case typelib_TypeClass_UNSIGNED_SHORT:
1946 nSize = rMaxIntegralTypeSize = (sal_Int32)(sizeof( sal_Int16 ));
1947 break;
1948 case typelib_TypeClass_LONG:
1949 case typelib_TypeClass_UNSIGNED_LONG:
1950 nSize = rMaxIntegralTypeSize = (sal_Int32)(sizeof( sal_Int32 ));
1951 break;
1952 case typelib_TypeClass_HYPER:
1953 case typelib_TypeClass_UNSIGNED_HYPER:
1954 nSize = rMaxIntegralTypeSize = (sal_Int32)(sizeof( sal_Int64 ));
1955 break;
1956 case typelib_TypeClass_UNKNOWN:
1957 case typelib_TypeClass_SERVICE:
1958 case typelib_TypeClass_MODULE:
1959 default:
1960 OSL_FAIL( "not convertible type" );
1964 return newAlignedSize( nOffset, nSize, rMaxIntegralTypeSize );
1967 //------------------------------------------------------------------------
1969 namespace {
1971 typelib_TypeDescriptionReference ** copyExceptions(
1972 sal_Int32 count, typelib_TypeDescriptionReference ** source)
1974 typelib_TypeDescriptionReference ** p
1975 = new typelib_TypeDescriptionReference *[count];
1976 for (sal_Int32 i = 0; i < count; ++i) {
1977 typelib_typedescriptionreference_acquire(p[i] = source[i]);
1979 return p;
1982 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)
1988 if (baseRef != 0 && base != 0 && interface != 0) {
1989 switch (base->eTypeClass) {
1990 case typelib_TypeClass_INTERFACE_METHOD:
1992 typelib_typedescription_newEmpty(
1993 result, typelib_TypeClass_INTERFACE_METHOD, name.pData);
1994 typelib_InterfaceMethodTypeDescription const * baseMethod
1995 = reinterpret_cast<
1996 typelib_InterfaceMethodTypeDescription const * >(base);
1997 typelib_InterfaceMethodTypeDescription * newMethod
1998 = reinterpret_cast<
1999 typelib_InterfaceMethodTypeDescription * >(*result);
2000 newMethod->aBase.nPosition = position;
2001 rtl_uString_acquire(
2002 newMethod->aBase.pMemberName
2003 = baseMethod->aBase.pMemberName);
2004 typelib_typedescriptionreference_acquire(
2005 newMethod->pReturnTypeRef = baseMethod->pReturnTypeRef);
2006 newMethod->nParams = baseMethod->nParams;
2007 newMethod->pParams = new typelib_MethodParameter[
2008 newMethod->nParams];
2009 for (sal_Int32 i = 0; i < newMethod->nParams; ++i) {
2010 rtl_uString_acquire(
2011 newMethod->pParams[i].pName
2012 = baseMethod->pParams[i].pName);
2013 typelib_typedescriptionreference_acquire(
2014 newMethod->pParams[i].pTypeRef
2015 = baseMethod->pParams[i].pTypeRef);
2016 newMethod->pParams[i].bIn = baseMethod->pParams[i].bIn;
2017 newMethod->pParams[i].bOut = baseMethod->pParams[i].bOut;
2019 newMethod->nExceptions = baseMethod->nExceptions;
2020 newMethod->ppExceptions = copyExceptions(
2021 baseMethod->nExceptions, baseMethod->ppExceptions);
2022 newMethod->bOneWay = baseMethod->bOneWay;
2023 newMethod->pInterface
2024 = reinterpret_cast< typelib_InterfaceTypeDescription * >(
2025 interface);
2026 newMethod->pBaseRef = baseRef;
2027 newMethod->nIndex = index;
2028 return true;
2031 case typelib_TypeClass_INTERFACE_ATTRIBUTE:
2033 typelib_typedescription_newEmpty(
2034 result, typelib_TypeClass_INTERFACE_ATTRIBUTE, name.pData);
2035 typelib_InterfaceAttributeTypeDescription const * baseAttribute
2036 = reinterpret_cast<
2037 typelib_InterfaceAttributeTypeDescription const * >(base);
2038 typelib_InterfaceAttributeTypeDescription * newAttribute
2039 = reinterpret_cast<
2040 typelib_InterfaceAttributeTypeDescription * >(*result);
2041 newAttribute->aBase.nPosition = position;
2042 rtl_uString_acquire(
2043 newAttribute->aBase.pMemberName
2044 = baseAttribute->aBase.pMemberName);
2045 newAttribute->bReadOnly = baseAttribute->bReadOnly;
2046 typelib_typedescriptionreference_acquire(
2047 newAttribute->pAttributeTypeRef
2048 = baseAttribute->pAttributeTypeRef);
2049 newAttribute->pInterface
2050 = reinterpret_cast< typelib_InterfaceTypeDescription * >(
2051 interface);
2052 newAttribute->pBaseRef = baseRef;
2053 newAttribute->nIndex = index;
2054 newAttribute->nGetExceptions = baseAttribute->nGetExceptions;
2055 newAttribute->ppGetExceptions = copyExceptions(
2056 baseAttribute->nGetExceptions,
2057 baseAttribute->ppGetExceptions);
2058 newAttribute->nSetExceptions = baseAttribute->nSetExceptions;
2059 newAttribute->ppSetExceptions = copyExceptions(
2060 baseAttribute->nSetExceptions,
2061 baseAttribute->ppSetExceptions);
2062 return true;
2065 default:
2066 break;
2069 return false;
2074 extern "C" CPPU_DLLPUBLIC void SAL_CALL typelib_typedescription_getByName(
2075 typelib_TypeDescription ** ppRet, rtl_uString * pName )
2076 SAL_THROW_EXTERN_C()
2078 if( *ppRet )
2080 typelib_typedescription_release( (*ppRet) );
2081 *ppRet = 0;
2084 static sal_Bool bInited = sal_False;
2085 TypeDescriptor_Init_Impl &rInit = Init::get();
2087 if( !bInited )
2089 // guard against multi thread access
2090 MutexGuard aGuard( rInit.getMutex() );
2091 if( !bInited )
2093 // avoid recursion during the next ...new calls
2094 bInited = sal_True;
2096 rtl_uString * pTypeName = 0;
2097 typelib_TypeDescription * pType = 0;
2098 rtl_uString_newFromAscii( &pTypeName, "type" );
2099 typelib_typedescription_new( &pType, typelib_TypeClass_TYPE, pTypeName, 0, 0, 0 );
2100 typelib_typedescription_register( &pType );
2101 rtl_uString_newFromAscii( &pTypeName, "void" );
2102 typelib_typedescription_new( &pType, typelib_TypeClass_VOID, pTypeName, 0, 0, 0 );
2103 typelib_typedescription_register( &pType );
2104 rtl_uString_newFromAscii( &pTypeName, "boolean" );
2105 typelib_typedescription_new( &pType, typelib_TypeClass_BOOLEAN, pTypeName, 0, 0, 0 );
2106 typelib_typedescription_register( &pType );
2107 rtl_uString_newFromAscii( &pTypeName, "char" );
2108 typelib_typedescription_new( &pType, typelib_TypeClass_CHAR, pTypeName, 0, 0, 0 );
2109 typelib_typedescription_register( &pType );
2110 rtl_uString_newFromAscii( &pTypeName, "byte" );
2111 typelib_typedescription_new( &pType, typelib_TypeClass_BYTE, pTypeName, 0, 0, 0 );
2112 typelib_typedescription_register( &pType );
2113 rtl_uString_newFromAscii( &pTypeName, "string" );
2114 typelib_typedescription_new( &pType, typelib_TypeClass_STRING, pTypeName, 0, 0, 0 );
2115 typelib_typedescription_register( &pType );
2116 rtl_uString_newFromAscii( &pTypeName, "short" );
2117 typelib_typedescription_new( &pType, typelib_TypeClass_SHORT, pTypeName, 0, 0, 0 );
2118 typelib_typedescription_register( &pType );
2119 rtl_uString_newFromAscii( &pTypeName, "unsigned short" );
2120 typelib_typedescription_new( &pType, typelib_TypeClass_UNSIGNED_SHORT, pTypeName, 0, 0, 0 );
2121 typelib_typedescription_register( &pType );
2122 rtl_uString_newFromAscii( &pTypeName, "long" );
2123 typelib_typedescription_new( &pType, typelib_TypeClass_LONG, pTypeName, 0, 0, 0 );
2124 typelib_typedescription_register( &pType );
2125 rtl_uString_newFromAscii( &pTypeName, "unsigned long" );
2126 typelib_typedescription_new( &pType, typelib_TypeClass_UNSIGNED_LONG, pTypeName, 0, 0, 0 );
2127 typelib_typedescription_register( &pType );
2128 rtl_uString_newFromAscii( &pTypeName, "hyper" );
2129 typelib_typedescription_new( &pType, typelib_TypeClass_HYPER, pTypeName, 0, 0, 0 );
2130 typelib_typedescription_register( &pType );
2131 rtl_uString_newFromAscii( &pTypeName, "unsigned hyper" );
2132 typelib_typedescription_new( &pType, typelib_TypeClass_UNSIGNED_HYPER, pTypeName, 0, 0, 0 );
2133 typelib_typedescription_register( &pType );
2134 rtl_uString_newFromAscii( &pTypeName, "float" );
2135 typelib_typedescription_new( &pType, typelib_TypeClass_FLOAT, pTypeName, 0, 0, 0 );
2136 typelib_typedescription_register( &pType );
2137 rtl_uString_newFromAscii( &pTypeName, "double" );
2138 typelib_typedescription_new( &pType, typelib_TypeClass_DOUBLE, pTypeName, 0, 0, 0 );
2139 typelib_typedescription_register( &pType );
2140 rtl_uString_newFromAscii( &pTypeName, "any" );
2141 typelib_typedescription_new( &pType, typelib_TypeClass_ANY, pTypeName, 0, 0, 0 );
2142 typelib_typedescription_register( &pType );
2143 typelib_typedescription_release( pType );
2144 rtl_uString_release( pTypeName );
2148 typelib_TypeDescriptionReference * pTDR = 0;
2149 typelib_typedescriptionreference_getByName( &pTDR, pName );
2150 if( pTDR )
2153 // guard against multi thread access
2154 MutexGuard aGuard( rInit.getMutex() );
2155 // pTDR->pType->pWeakRef == 0 means that the description is empty
2156 if( pTDR->pType && pTDR->pType->pWeakRef )
2158 typelib_typedescription_acquire( pTDR->pType );
2159 *ppRet = pTDR->pType;
2162 typelib_typedescriptionreference_release( pTDR );
2165 if (0 == *ppRet)
2167 // check for sequence
2168 OUString const & name = *reinterpret_cast< OUString const * >( &pName );
2169 if (2 < name.getLength() && '[' == name[ 0 ])
2171 OUString element_name( name.copy( 2 ) );
2172 typelib_TypeDescription * element_td = 0;
2173 typelib_typedescription_getByName( &element_td, element_name.pData );
2174 if (0 != element_td)
2176 typelib_typedescription_new(
2177 ppRet, typelib_TypeClass_SEQUENCE, pName, element_td->pWeakRef, 0, 0 );
2178 // register?
2179 typelib_typedescription_release( element_td );
2182 if (0 == *ppRet)
2184 // Check for derived interface member type:
2185 sal_Int32 i1 = name.lastIndexOf(
2186 rtl::OUString(":@"));
2187 if (i1 >= 0) {
2188 sal_Int32 i2 = i1 + RTL_CONSTASCII_LENGTH(":@");
2189 sal_Int32 i3 = name.indexOf(',', i2);
2190 if (i3 >= 0) {
2191 sal_Int32 i4 = name.indexOf(':', i3);
2192 if (i4 >= 0) {
2193 typelib_TypeDescriptionReference * pBaseRef = 0;
2194 typelib_TypeDescription * pBase = 0;
2195 typelib_TypeDescription * pInterface = 0;
2196 typelib_typedescriptionreference_getByName(
2197 &pBaseRef, name.copy(0, i1).pData);
2198 if (pBaseRef != 0) {
2199 typelib_typedescriptionreference_getDescription(
2200 &pBase, pBaseRef);
2202 typelib_typedescription_getByName(
2203 &pInterface, name.copy(i4 + 1).pData);
2204 if (!createDerivedInterfaceMemberDescription(
2205 ppRet, name, pBaseRef, pBase, pInterface,
2206 name.copy(i2, i3 - i2).toInt32(),
2207 name.copy(i3 + 1, i4 - i3 - 1).toInt32()))
2209 if (pInterface != 0) {
2210 typelib_typedescription_release(pInterface);
2212 if (pBase != 0) {
2213 typelib_typedescription_release(pBase);
2215 if (pBaseRef != 0) {
2216 typelib_typedescriptionreference_release(
2217 pBaseRef);
2224 if (0 == *ppRet)
2226 // on demand access
2227 rInit.callChain( ppRet, pName );
2230 if( *ppRet )
2232 // typedescription found
2233 if (typelib_TypeClass_TYPEDEF == (*ppRet)->eTypeClass)
2235 typelib_TypeDescription * pTD = 0;
2236 typelib_typedescriptionreference_getDescription(
2237 &pTD, ((typelib_IndirectTypeDescription *)*ppRet)->pType );
2238 typelib_typedescription_release( *ppRet );
2239 *ppRet = pTD;
2241 else
2243 // set to on demand
2244 (*ppRet)->bOnDemand = sal_True;
2245 // The type description is hold by the reference until
2246 // on demand is activated.
2247 typelib_typedescription_register( ppRet );
2249 // insert into the chache
2250 MutexGuard aGuard( rInit.getMutex() );
2251 if( !rInit.pCache )
2252 rInit.pCache = new TypeDescriptionList_Impl;
2253 if( (sal_Int32)rInit.pCache->size() >= nCacheSize )
2255 typelib_typedescription_release( rInit.pCache->front() );
2256 rInit.pCache->pop_front();
2258 // descriptions in the cache must be acquired!
2259 typelib_typedescription_acquire( *ppRet );
2260 rInit.pCache->push_back( *ppRet );
2266 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()
2272 OUString aTypeName( OUString::createFromAscii( pTypeName ) );
2273 typelib_typedescriptionreference_new( ppTDR, eTypeClass, aTypeName.pData );
2275 //------------------------------------------------------------------------
2276 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()
2281 TypeDescriptor_Init_Impl &rInit = Init::get();
2282 if( eTypeClass == typelib_TypeClass_TYPEDEF )
2284 // on demand access
2285 typelib_TypeDescription * pRet = 0;
2286 rInit.callChain( &pRet, pTypeName );
2287 if( pRet )
2289 // typedescription found
2290 if (typelib_TypeClass_TYPEDEF == pRet->eTypeClass)
2292 typelib_typedescriptionreference_acquire(
2293 ((typelib_IndirectTypeDescription *)pRet)->pType );
2294 if (*ppTDR)
2295 typelib_typedescriptionreference_release( *ppTDR );
2296 *ppTDR = ((typelib_IndirectTypeDescription *)pRet)->pType;
2297 typelib_typedescription_release( pRet );
2299 else
2301 // set to on demand
2302 pRet->bOnDemand = sal_True;
2303 // The type description is hold by the reference until
2304 // on demand is activated.
2305 typelib_typedescription_register( &pRet );
2307 // insert into the chache
2308 MutexGuard aGuard( rInit.getMutex() );
2309 if( !rInit.pCache )
2310 rInit.pCache = new TypeDescriptionList_Impl;
2311 if( (sal_Int32)rInit.pCache->size() >= nCacheSize )
2313 typelib_typedescription_release( rInit.pCache->front() );
2314 rInit.pCache->pop_front();
2316 rInit.pCache->push_back( pRet );
2317 // pRet kept acquired for cache
2319 typelib_typedescriptionreference_acquire( pRet->pWeakRef );
2320 if (*ppTDR)
2321 typelib_typedescriptionreference_release( *ppTDR );
2322 *ppTDR = pRet->pWeakRef;
2325 else if (*ppTDR)
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 typelib_typedescriptionreference_release( *ppTDR );
2332 *ppTDR = 0;
2334 return;
2337 MutexGuard aGuard( rInit.getMutex() );
2338 typelib_typedescriptionreference_getByName( ppTDR, pTypeName );
2339 if( *ppTDR )
2340 return;
2342 if( reallyWeak( eTypeClass ) )
2344 typelib_TypeDescriptionReference * pTDR = new typelib_TypeDescriptionReference();
2345 #if OSL_DEBUG_LEVEL > 1
2346 osl_atomic_increment( &rInit.nTypeDescriptionReferenceCount );
2347 #endif
2348 pTDR->nRefCount = 1;
2349 pTDR->nStaticRefCount = 0;
2350 pTDR->eTypeClass = eTypeClass;
2351 pTDR->pUniqueIdentifier = 0;
2352 pTDR->pReserved = 0;
2353 rtl_uString_acquire( pTDR->pTypeName = pTypeName );
2354 pTDR->pType = 0;
2355 *ppTDR = pTDR;
2357 else
2359 typelib_typedescription_newEmpty( (typelib_TypeDescription ** )ppTDR, eTypeClass, pTypeName );
2360 // description will be registered but not acquired
2361 (*(typelib_TypeDescription ** )ppTDR)->bOnDemand = sal_True;
2362 (*(typelib_TypeDescription ** )ppTDR)->bComplete = sal_False;
2365 if( !rInit.pWeakMap )
2366 rInit.pWeakMap = new WeakMap_Impl;
2367 // Heavy hack, the const sal_Unicode * is hold by the typedescription reference
2368 // not registered
2369 rInit.pWeakMap->operator[]( (*ppTDR)->pTypeName->buffer ) = *ppTDR;
2372 //------------------------------------------------------------------------
2373 extern "C" CPPU_DLLPUBLIC void SAL_CALL typelib_typedescriptionreference_acquire(
2374 typelib_TypeDescriptionReference * pRef )
2375 SAL_THROW_EXTERN_C()
2377 osl_atomic_increment( &pRef->nRefCount );
2380 //------------------------------------------------------------------------
2381 extern "C" CPPU_DLLPUBLIC void SAL_CALL typelib_typedescriptionreference_release(
2382 typelib_TypeDescriptionReference * pRef )
2383 SAL_THROW_EXTERN_C()
2385 // Is it a type description?
2386 if( reallyWeak( pRef->eTypeClass ) )
2388 if( ! osl_atomic_decrement( &pRef->nRefCount ) )
2390 TypeDescriptor_Init_Impl &rInit = Init::get();
2391 if( rInit.pWeakMap )
2393 MutexGuard aGuard( rInit.getMutex() );
2394 WeakMap_Impl::iterator aIt = rInit.pWeakMap->find( (sal_Unicode*)pRef->pTypeName->buffer );
2395 if( !(aIt == rInit.pWeakMap->end()) && (*aIt).second == pRef )
2397 // remove only if it contains the same object
2398 rInit.pWeakMap->erase( aIt );
2402 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 delete pRef;
2410 else
2412 typelib_typedescription_release( (typelib_TypeDescription *)pRef );
2416 //------------------------------------------------------------------------
2417 extern "C" CPPU_DLLPUBLIC void SAL_CALL typelib_typedescriptionreference_getDescription(
2418 typelib_TypeDescription ** ppRet, typelib_TypeDescriptionReference * pRef )
2419 SAL_THROW_EXTERN_C()
2421 if( *ppRet )
2423 typelib_typedescription_release( *ppRet );
2424 *ppRet = 0;
2427 if( !reallyWeak( pRef->eTypeClass ) && pRef->pType && pRef->pType->pWeakRef )
2429 // reference is a description and initialized
2430 osl_atomic_increment( &((typelib_TypeDescription *)pRef)->nRefCount );
2431 *ppRet = (typelib_TypeDescription *)pRef;
2432 return;
2436 MutexGuard aGuard( Init::get().getMutex() );
2437 // pRef->pType->pWeakRef == 0 means that the description is empty
2438 if( pRef->pType && pRef->pType->pWeakRef )
2440 sal_Int32 n = osl_atomic_increment( &pRef->pType->nRefCount );
2441 if( n > 1 )
2443 // The refence is incremented. The object cannot be destroyed.
2444 // Release the guard at the earliest point.
2445 *ppRet = pRef->pType;
2446 return;
2448 else
2450 osl_atomic_decrement( &pRef->pType->nRefCount );
2451 // detruction of this type in progress (another thread!)
2452 // no acces through this weak reference
2453 pRef->pType = 0;
2458 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 pRef->pType = *ppRet;
2465 //------------------------------------------------------------------------
2466 extern "C" void SAL_CALL typelib_typedescriptionreference_getByName(
2467 typelib_TypeDescriptionReference ** ppRet, rtl_uString * pName )
2468 SAL_THROW_EXTERN_C()
2470 if( *ppRet )
2472 typelib_typedescriptionreference_release( *ppRet );
2473 *ppRet = 0;
2475 TypeDescriptor_Init_Impl &rInit = Init::get();
2476 if( rInit.pWeakMap )
2478 MutexGuard aGuard( rInit.getMutex() );
2479 WeakMap_Impl::const_iterator aIt = rInit.pWeakMap->find( (sal_Unicode*)pName->buffer );
2480 if( !(aIt == rInit.pWeakMap->end()) ) // != failed on msc4.2
2482 sal_Int32 n = osl_atomic_increment( &(*aIt).second->nRefCount );
2483 if( n > 1 )
2485 // The refence is incremented. The object cannot be destroyed.
2486 // Release the guard at the earliest point.
2487 *ppRet = (*aIt).second;
2489 else
2491 // detruction of this type in progress (another thread!)
2492 // no acces through this weak reference
2493 osl_atomic_decrement( &(*aIt).second->nRefCount );
2499 //------------------------------------------------------------------------
2500 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()
2505 return (p1 == p2 ||
2506 (p1->eTypeClass == p2->eTypeClass &&
2507 p1->pTypeName->length == p2->pTypeName->length &&
2508 rtl_ustr_compare( p1->pTypeName->buffer, p2->pTypeName->buffer ) == 0));
2511 //##################################################################################################
2512 extern "C" CPPU_DLLPUBLIC void SAL_CALL typelib_typedescriptionreference_assign(
2513 typelib_TypeDescriptionReference ** ppDest,
2514 typelib_TypeDescriptionReference * pSource )
2515 SAL_THROW_EXTERN_C()
2517 if (*ppDest != pSource)
2519 ::typelib_typedescriptionreference_acquire( pSource );
2520 ::typelib_typedescriptionreference_release( *ppDest );
2521 *ppDest = pSource;
2525 //##################################################################################################
2526 extern "C" CPPU_DLLPUBLIC void SAL_CALL typelib_setCacheSize( sal_Int32 nNewSize )
2527 SAL_THROW_EXTERN_C()
2529 OSL_ENSURE( nNewSize >= 0, "### illegal cache size given!" );
2530 if (nNewSize >= 0)
2532 TypeDescriptor_Init_Impl &rInit = Init::get();
2533 MutexGuard aGuard( rInit.getMutex() );
2534 if ((nNewSize < nCacheSize) && rInit.pCache)
2536 while ((sal_Int32)rInit.pCache->size() != nNewSize)
2538 typelib_typedescription_release( rInit.pCache->front() );
2539 rInit.pCache->pop_front();
2542 nCacheSize = nNewSize;
2547 static sal_Bool s_aAssignableFromTab[11][11] =
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 }
2563 //##################################################################################################
2564 extern "C" CPPU_DLLPUBLIC sal_Bool SAL_CALL typelib_typedescriptionreference_isAssignableFrom(
2565 typelib_TypeDescriptionReference * pAssignable,
2566 typelib_TypeDescriptionReference * pFrom )
2567 SAL_THROW_EXTERN_C()
2569 if (pAssignable && pFrom)
2571 typelib_TypeClass eAssignable = pAssignable->eTypeClass;
2572 typelib_TypeClass eFrom = pFrom->eTypeClass;
2574 if (eAssignable == typelib_TypeClass_ANY) // anything can be assigned to an any .)
2575 return sal_True;
2576 if (eAssignable == eFrom)
2578 if (type_equals( pAssignable, pFrom )) // first shot
2580 return sal_True;
2582 else
2584 switch (eAssignable)
2586 case typelib_TypeClass_STRUCT:
2587 case typelib_TypeClass_EXCEPTION:
2589 typelib_TypeDescription * pFromDescr = 0;
2590 TYPELIB_DANGER_GET( &pFromDescr, pFrom );
2591 if (! ((typelib_CompoundTypeDescription *)pFromDescr)->pBaseTypeDescription)
2593 TYPELIB_DANGER_RELEASE( pFromDescr );
2594 return sal_False;
2596 sal_Bool bRet = typelib_typedescriptionreference_isAssignableFrom(
2597 pAssignable,
2598 ((typelib_TypeDescription *)((typelib_CompoundTypeDescription *)pFromDescr)->pBaseTypeDescription)->pWeakRef );
2599 TYPELIB_DANGER_RELEASE( pFromDescr );
2600 return bRet;
2602 case typelib_TypeClass_INTERFACE:
2604 typelib_TypeDescription * pFromDescr = 0;
2605 TYPELIB_DANGER_GET( &pFromDescr, pFrom );
2606 typelib_InterfaceTypeDescription * pFromIfc
2607 = reinterpret_cast<
2608 typelib_InterfaceTypeDescription * >(pFromDescr);
2609 bool bRet = false;
2610 for (sal_Int32 i = 0; i < pFromIfc->nBaseTypes; ++i) {
2611 if (typelib_typedescriptionreference_isAssignableFrom(
2612 pAssignable,
2613 pFromIfc->ppBaseTypes[i]->aBase.pWeakRef))
2615 bRet = true;
2616 break;
2619 TYPELIB_DANGER_RELEASE( pFromDescr );
2620 return bRet;
2622 default:
2624 return sal_False;
2629 return (eAssignable >= typelib_TypeClass_CHAR && eAssignable <= typelib_TypeClass_DOUBLE &&
2630 eFrom >= typelib_TypeClass_CHAR && eFrom <= typelib_TypeClass_DOUBLE &&
2631 s_aAssignableFromTab[eAssignable-1][eFrom-1]);
2633 return sal_False;
2635 //##################################################################################################
2636 extern "C" CPPU_DLLPUBLIC sal_Bool SAL_CALL typelib_typedescription_isAssignableFrom(
2637 typelib_TypeDescription * pAssignable,
2638 typelib_TypeDescription * pFrom )
2639 SAL_THROW_EXTERN_C()
2641 return typelib_typedescriptionreference_isAssignableFrom(
2642 pAssignable->pWeakRef, pFrom->pWeakRef );
2645 //##################################################################################################
2646 extern "C" CPPU_DLLPUBLIC sal_Bool SAL_CALL typelib_typedescription_complete(
2647 typelib_TypeDescription ** ppTypeDescr )
2648 SAL_THROW_EXTERN_C()
2650 return complete(ppTypeDescr, true);
2653 /* vim:set shiftwidth=4 softtabstop=4 expandtab: */