merged tag ooo/DEV300_m102
[LibreOffice.git] / cppu / source / typelib / typelib.cxx
blobaa0d18589a8944bad520faee16a1f190195a7661
1 /*************************************************************************
3 * DO NOT ALTER OR REMOVE COPYRIGHT NOTICES OR THIS FILE HEADER.
5 * Copyright 2000, 2010 Oracle and/or its affiliates.
7 * OpenOffice.org - a multi-platform office productivity suite
9 * This file is part of OpenOffice.org.
11 * OpenOffice.org is free software: you can redistribute it and/or modify
12 * it under the terms of the GNU Lesser General Public License version 3
13 * only, as published by the Free Software Foundation.
15 * OpenOffice.org is distributed in the hope that it will be useful,
16 * but WITHOUT ANY WARRANTY; without even the implied warranty of
17 * MERCHANTABILITY or FITNESS FOR A PARTICULAR PURPOSE. See the
18 * GNU Lesser General Public License version 3 for more details
19 * (a copy is included in the LICENSE file that accompanied this code).
21 * You should have received a copy of the GNU Lesser General Public License
22 * version 3 along with OpenOffice.org. If not, see
23 * <http://www.openoffice.org/license.html>
24 * for a copy of the LGPLv3 License.
26 ************************************************************************/
28 // MARKER(update_precomp.py): autogen include statement, do not remove
29 #include "precompiled_cppu.hxx"
31 #include <hash_map>
32 #include <list>
33 #include <set>
34 #include <vector>
36 #include <stdarg.h>
37 #include <stdlib.h>
38 #include <string.h>
39 #include <sal/alloca.h>
40 #include <new>
41 #include <osl/interlck.h>
42 #include <osl/mutex.hxx>
43 #include <rtl/ustring.hxx>
44 #include <rtl/ustrbuf.hxx>
45 #include <rtl/alloc.h>
46 #include <rtl/instance.hxx>
47 #include <osl/diagnose.h>
48 #include <typelib/typedescription.h>
49 #include <uno/any2.h>
51 using namespace rtl;
52 using namespace std;
53 using namespace osl;
56 //------------------------------------------------------------------------
57 //------------------------------------------------------------------------
58 #ifdef SAL_W32
59 #pragma pack(push, 8)
60 #elif defined(SAL_OS2)
61 #pragma pack(8)
62 #endif
64 /**
65 * The double member determin the alignment.
66 * Under Os2 and MS-Windows the Alignment is min( 8, sizeof( type ) ).
67 * The aligment of a strukture is min( 8, sizeof( max basic type ) ), the greatest basic type
68 * determine the aligment.
70 struct AlignSize_Impl
72 sal_Int16 nInt16;
73 double dDouble;
76 #ifdef SAL_W32
77 #pragma pack(pop)
78 #elif defined(SAL_OS2)
79 #pragma pack()
80 #endif
82 // the value of the maximal alignment
83 static sal_Int32 nMaxAlignment = (sal_Int32)( (sal_Size)(&((AlignSize_Impl *) 16)->dDouble) - 16);
85 static inline sal_Int32 adjustAlignment( sal_Int32 nRequestedAlignment )
86 SAL_THROW( () )
88 if( nRequestedAlignment > nMaxAlignment )
89 nRequestedAlignment = nMaxAlignment;
90 return nRequestedAlignment;
93 /**
94 * Calculate the new size of the struktur.
96 static inline sal_Int32 newAlignedSize(
97 sal_Int32 OldSize, sal_Int32 ElementSize, sal_Int32 NeededAlignment )
98 SAL_THROW( () )
100 NeededAlignment = adjustAlignment( NeededAlignment );
101 return (OldSize + NeededAlignment -1) / NeededAlignment * NeededAlignment + ElementSize;
104 static inline sal_Bool reallyWeak( typelib_TypeClass eTypeClass )
105 SAL_THROW( () )
107 return TYPELIB_TYPEDESCRIPTIONREFERENCE_ISREALLYWEAK( eTypeClass );
110 static inline sal_Int32 getDescriptionSize( typelib_TypeClass eTypeClass )
111 SAL_THROW( () )
113 OSL_ASSERT( typelib_TypeClass_TYPEDEF != eTypeClass );
115 sal_Int32 nSize;
116 // The reference is the description
117 // if the description is empty, than it must be filled with
118 // the new description
119 switch( eTypeClass )
121 case typelib_TypeClass_ARRAY:
122 nSize = (sal_Int32)sizeof( typelib_ArrayTypeDescription );
123 break;
125 case typelib_TypeClass_SEQUENCE:
126 nSize = (sal_Int32)sizeof( typelib_IndirectTypeDescription );
127 break;
129 case typelib_TypeClass_UNION:
130 nSize = (sal_Int32)sizeof( typelib_UnionTypeDescription );
131 break;
133 case typelib_TypeClass_STRUCT:
134 nSize = (sal_Int32)sizeof( typelib_StructTypeDescription );
135 break;
137 case typelib_TypeClass_EXCEPTION:
138 nSize = (sal_Int32)sizeof( typelib_CompoundTypeDescription );
139 break;
141 case typelib_TypeClass_ENUM:
142 nSize = (sal_Int32)sizeof( typelib_EnumTypeDescription );
143 break;
145 case typelib_TypeClass_INTERFACE:
146 nSize = (sal_Int32)sizeof( typelib_InterfaceTypeDescription );
147 break;
149 case typelib_TypeClass_INTERFACE_METHOD:
150 nSize = (sal_Int32)sizeof( typelib_InterfaceMethodTypeDescription );
151 break;
153 case typelib_TypeClass_INTERFACE_ATTRIBUTE:
154 nSize = (sal_Int32)sizeof( typelib_InterfaceAttributeTypeDescription );
155 break;
157 default:
158 nSize = (sal_Int32)sizeof( typelib_TypeDescription );
160 return nSize;
164 //-----------------------------------------------------------------------------
165 extern "C" void SAL_CALL typelib_typedescriptionreference_getByName(
166 typelib_TypeDescriptionReference ** ppRet, rtl_uString * pName )
167 SAL_THROW_EXTERN_C();
169 //-----------------------------------------------------------------------------
170 struct equalStr_Impl
172 sal_Bool operator()(const sal_Unicode * const & s1, const sal_Unicode * const & s2) const SAL_THROW( () )
173 { return 0 == rtl_ustr_compare( s1, s2 ); }
176 //-----------------------------------------------------------------------------
177 struct hashStr_Impl
179 size_t operator()(const sal_Unicode * const & s) const SAL_THROW( () )
180 { return rtl_ustr_hashCode( s ); }
184 //-----------------------------------------------------------------------------
185 // Heavy hack, the const sal_Unicode * is hold by the typedescription reference
186 typedef hash_map< const sal_Unicode *, typelib_TypeDescriptionReference *,
187 hashStr_Impl, equalStr_Impl > WeakMap_Impl;
189 typedef pair< void *, typelib_typedescription_Callback > CallbackEntry;
190 typedef list< CallbackEntry > CallbackSet_Impl;
191 typedef list< typelib_TypeDescription * > TypeDescriptionList_Impl;
193 // # of cached elements
194 static sal_Int32 nCacheSize = 256;
196 //-----------------------------------------------------------------------------
198 * All members must set initial to 0 and no constructor is needed. So it
199 * doesn't care, when this class is static initialized.<BR>
201 struct TypeDescriptor_Init_Impl
203 //sal_Bool bDesctructorCalled;
204 // all type description references
205 WeakMap_Impl * pWeakMap;
206 // all type description callbacks
207 CallbackSet_Impl * pCallbacks;
208 // A cache to hold descriptions
209 TypeDescriptionList_Impl * pCache;
210 // The mutex to guard all type library accesses
211 Mutex * pMutex;
213 inline Mutex & getMutex() SAL_THROW( () );
215 inline void callChain( typelib_TypeDescription ** ppRet, rtl_uString * pName ) SAL_THROW( () );
217 #if OSL_DEBUG_LEVEL > 1
218 // only for debugging
219 sal_Int32 nTypeDescriptionCount;
220 sal_Int32 nCompoundTypeDescriptionCount;
221 sal_Int32 nUnionTypeDescriptionCount;
222 sal_Int32 nIndirectTypeDescriptionCount;
223 sal_Int32 nArrayTypeDescriptionCount;
224 sal_Int32 nEnumTypeDescriptionCount;
225 sal_Int32 nInterfaceMethodTypeDescriptionCount;
226 sal_Int32 nInterfaceAttributeTypeDescriptionCount;
227 sal_Int32 nInterfaceTypeDescriptionCount;
228 sal_Int32 nTypeDescriptionReferenceCount;
229 #endif
230 ~TypeDescriptor_Init_Impl() SAL_THROW( () );
232 //__________________________________________________________________________________________________
233 inline Mutex & TypeDescriptor_Init_Impl::getMutex() SAL_THROW( () )
235 if( !pMutex )
237 MutexGuard aGuard( Mutex::getGlobalMutex() );
238 if( !pMutex )
239 pMutex = new Mutex();
241 return * pMutex;
243 //__________________________________________________________________________________________________
244 inline void TypeDescriptor_Init_Impl::callChain(
245 typelib_TypeDescription ** ppRet, rtl_uString * pName )
246 SAL_THROW( () )
248 if (pCallbacks)
250 CallbackSet_Impl::const_iterator aIt = pCallbacks->begin();
251 while( aIt != pCallbacks->end() )
253 const CallbackEntry & rEntry = *aIt;
254 (*rEntry.second)( rEntry.first, ppRet, pName );
255 if( *ppRet )
256 return;
257 ++aIt;
260 if (*ppRet)
262 typelib_typedescription_release( *ppRet );
263 *ppRet = 0;
267 //__________________________________________________________________________________________________
268 TypeDescriptor_Init_Impl::~TypeDescriptor_Init_Impl() SAL_THROW( () )
270 if( pCache )
272 TypeDescriptionList_Impl::const_iterator aIt = pCache->begin();
273 while( aIt != pCache->end() )
275 typelib_typedescription_release( (*aIt) );
276 aIt++;
278 delete pCache;
279 pCache = 0;
282 if( pWeakMap )
284 sal_Int32 nSize = pWeakMap->size();
285 typelib_TypeDescriptionReference ** ppTDR = new typelib_TypeDescriptionReference *[ nSize ];
286 // save al weak references
287 WeakMap_Impl::const_iterator aIt = pWeakMap->begin();
288 sal_Int32 i = 0;
289 while( aIt != pWeakMap->end() )
291 typelib_typedescriptionreference_acquire( ppTDR[i++] = (*aIt).second );
292 ++aIt;
295 for( i = 0; i < nSize; i++ )
297 typelib_TypeDescriptionReference * pTDR = ppTDR[i];
298 OSL_ASSERT( pTDR->nRefCount > pTDR->nStaticRefCount );
299 pTDR->nRefCount -= pTDR->nStaticRefCount;
301 if( pTDR->pType && !pTDR->pType->bOnDemand )
303 pTDR->pType->bOnDemand = sal_True;
304 typelib_typedescription_release( pTDR->pType );
306 typelib_typedescriptionreference_release( pTDR );
309 delete [] ppTDR;
311 #if OSL_DEBUG_LEVEL > 1
312 aIt = pWeakMap->begin();
313 while( aIt != pWeakMap->end() )
315 typelib_TypeDescriptionReference * pTDR = (*aIt).second;
316 if (pTDR)
318 OString aTypeName( OUStringToOString( pTDR->pTypeName, RTL_TEXTENCODING_ASCII_US ) );
319 OSL_TRACE(
320 "### remaining type: %s; ref count = %d", aTypeName.getStr(), pTDR->nRefCount );
322 else
324 OSL_TRACE( "### remaining null type entry!?" );
326 ++aIt;
328 #endif
330 delete pWeakMap;
331 pWeakMap = 0;
333 #if OSL_DEBUG_LEVEL > 1
334 OSL_ASSERT( nTypeDescriptionCount == 0 );
335 OSL_ASSERT( nCompoundTypeDescriptionCount == 0 );
336 OSL_ASSERT( nUnionTypeDescriptionCount == 0 );
337 OSL_ASSERT( nIndirectTypeDescriptionCount == 0 );
338 OSL_ASSERT( nArrayTypeDescriptionCount == 0 );
339 OSL_ASSERT( nEnumTypeDescriptionCount == 0 );
340 OSL_ASSERT( nInterfaceMethodTypeDescriptionCount == 0 );
341 OSL_ASSERT( nInterfaceAttributeTypeDescriptionCount == 0 );
342 OSL_ASSERT( nInterfaceTypeDescriptionCount == 0 );
343 OSL_ASSERT( nTypeDescriptionReferenceCount == 0 );
345 OSL_ASSERT( !pCallbacks || pCallbacks->empty() );
346 #endif
347 delete pCallbacks;
348 pCallbacks = 0;
350 if( pMutex )
352 delete pMutex;
353 pMutex = 0;
357 namespace { struct Init : public rtl::Static< TypeDescriptor_Init_Impl, Init > {}; }
359 //------------------------------------------------------------------------
360 //------------------------------------------------------------------------
361 //------------------------------------------------------------------------
362 //------------------------------------------------------------------------
363 extern "C" void SAL_CALL typelib_typedescription_registerCallback(
364 void * pContext, typelib_typedescription_Callback pCallback )
365 SAL_THROW_EXTERN_C()
367 // todo mt safe: guard is no solution, can not acquire while calling callback!
368 TypeDescriptor_Init_Impl &rInit = Init::get();
369 // OslGuard aGuard( rInit.getMutex() );
370 if( !rInit.pCallbacks )
371 rInit.pCallbacks = new CallbackSet_Impl;
372 rInit.pCallbacks->push_back( CallbackEntry( pContext, pCallback ) );
375 //------------------------------------------------------------------------
376 extern "C" void SAL_CALL typelib_typedescription_revokeCallback(
377 void * pContext, typelib_typedescription_Callback pCallback )
378 SAL_THROW_EXTERN_C()
380 TypeDescriptor_Init_Impl &rInit = Init::get();
381 if( rInit.pCallbacks )
383 // todo mt safe: guard is no solution, can not acquire while calling callback!
384 // OslGuard aGuard( rInit.getMutex() );
385 CallbackEntry aEntry( pContext, pCallback );
386 CallbackSet_Impl::iterator iPos( rInit.pCallbacks->begin() );
387 while (!(iPos == rInit.pCallbacks->end()))
389 if (*iPos == aEntry)
391 rInit.pCallbacks->erase( iPos );
392 iPos = rInit.pCallbacks->begin();
394 else
396 ++iPos;
403 //------------------------------------------------------------------------
404 //------------------------------------------------------------------------
405 //------------------------------------------------------------------------
406 extern "C" sal_Int32 SAL_CALL typelib_typedescription_getAlignedUnoSize(
407 const typelib_TypeDescription * pTypeDescription,
408 sal_Int32 nOffset, sal_Int32 & rMaxIntegralTypeSize )
409 SAL_THROW_EXTERN_C();
411 //------------------------------------------------------------------------
412 static inline void typelib_typedescription_initTables(
413 typelib_TypeDescription * pTD )
414 SAL_THROW( () )
416 typelib_InterfaceTypeDescription * pITD = (typelib_InterfaceTypeDescription *)pTD;
418 sal_Bool * pReadWriteAttributes = (sal_Bool *)alloca( pITD->nAllMembers );
419 for ( sal_Int32 i = pITD->nAllMembers; i--; )
421 pReadWriteAttributes[i] = sal_False;
422 if( typelib_TypeClass_INTERFACE_ATTRIBUTE == pITD->ppAllMembers[i]->eTypeClass )
424 typelib_TypeDescription * pM = 0;
425 TYPELIB_DANGER_GET( &pM, pITD->ppAllMembers[i] );
426 OSL_ASSERT( pM );
427 if (pM)
429 pReadWriteAttributes[i] = !((typelib_InterfaceAttributeTypeDescription *)pM)->bReadOnly;
430 TYPELIB_DANGER_RELEASE( pM );
432 #if OSL_DEBUG_LEVEL > 1
433 else
435 OString aStr( OUStringToOString( pITD->ppAllMembers[i]->pTypeName, RTL_TEXTENCODING_ASCII_US ) );
436 OSL_TRACE( "\n### cannot get attribute type description: %s", aStr.getStr() );
438 #endif
442 MutexGuard aGuard( Init::get().getMutex() );
443 if( !pTD->bComplete )
445 // create the index table from member to function table
446 pITD->pMapMemberIndexToFunctionIndex = new sal_Int32[ pITD->nAllMembers ];
447 sal_Int32 nAdditionalOffset = 0; // +1 for read/write attributes
448 sal_Int32 i;
449 for( i = 0; i < pITD->nAllMembers; i++ )
451 // index to the get method of the attribute
452 pITD->pMapMemberIndexToFunctionIndex[i] = i + nAdditionalOffset;
453 // extra offset if it is a read/write attribute?
454 if( pReadWriteAttributes[i] )
456 // a read/write attribute
457 nAdditionalOffset++;
461 // create the index table from function to member table
462 pITD->pMapFunctionIndexToMemberIndex = new sal_Int32[ pITD->nAllMembers + nAdditionalOffset ];
463 nAdditionalOffset = 0; // +1 for read/write attributes
464 for( i = 0; i < pITD->nAllMembers; i++ )
466 // index to the get method of the attribute
467 pITD->pMapFunctionIndexToMemberIndex[i + nAdditionalOffset] = i;
468 // extra offset if it is a read/write attribute?
469 if( pReadWriteAttributes[i] )
471 // a read/write attribute
472 pITD->pMapFunctionIndexToMemberIndex[i + ++nAdditionalOffset] = i;
475 // must be the last action after all initialization is done
476 pITD->nMapFunctionIndexToMemberIndex = pITD->nAllMembers + nAdditionalOffset;
477 pTD->bComplete = sal_True;
481 namespace {
483 // In some situations (notably typelib_typedescription_newInterfaceMethod and
484 // typelib_typedescription_newInterfaceAttribute), only the members nMembers,
485 // ppMembers, nAllMembers, and ppAllMembers of an incomplete interface type
486 // description are necessary, but not the additional
487 // pMapMemberIndexToFunctionIndex, nMapFunctionIndexToMemberIndex, and
488 // pMapFunctionIndexToMemberIndex (which are computed by
489 // typelib_typedescription_initTables). Furthermore, in those situations, it
490 // might be illegal to compute those tables, as the creation of the interface
491 // member type descriptions would recursively require a complete interface type
492 // description. The parameter initTables controls whether or not to call
493 // typelib_typedescription_initTables in those situations.
494 bool complete(typelib_TypeDescription ** ppTypeDescr, bool initTables) {
495 if (! (*ppTypeDescr)->bComplete)
497 OSL_ASSERT( (typelib_TypeClass_STRUCT == (*ppTypeDescr)->eTypeClass ||
498 typelib_TypeClass_EXCEPTION == (*ppTypeDescr)->eTypeClass ||
499 typelib_TypeClass_UNION == (*ppTypeDescr)->eTypeClass ||
500 typelib_TypeClass_ENUM == (*ppTypeDescr)->eTypeClass ||
501 typelib_TypeClass_INTERFACE == (*ppTypeDescr)->eTypeClass) &&
502 !reallyWeak( (*ppTypeDescr)->eTypeClass ) );
504 if (typelib_TypeClass_INTERFACE == (*ppTypeDescr)->eTypeClass &&
505 ((typelib_InterfaceTypeDescription *)*ppTypeDescr)->ppAllMembers)
507 if (initTables) {
508 typelib_typedescription_initTables( *ppTypeDescr );
510 return true;
513 typelib_TypeDescription * pTD = 0;
514 // on demand access of complete td
515 TypeDescriptor_Init_Impl &rInit = Init::get();
516 rInit.callChain( &pTD, (*ppTypeDescr)->pTypeName );
517 if (pTD)
519 if (typelib_TypeClass_TYPEDEF == pTD->eTypeClass)
521 typelib_typedescriptionreference_getDescription(
522 &pTD, ((typelib_IndirectTypeDescription *)pTD)->pType );
523 OSL_ASSERT( pTD );
524 if (! pTD)
525 return false;
528 OSL_ASSERT( typelib_TypeClass_TYPEDEF != pTD->eTypeClass );
529 // typedescription found
530 // set to on demand
531 pTD->bOnDemand = sal_True;
533 if (pTD->eTypeClass == typelib_TypeClass_INTERFACE
534 && !pTD->bComplete && initTables)
536 // mandatory info from callback chain
537 OSL_ASSERT( ((typelib_InterfaceTypeDescription *)pTD)->ppAllMembers );
538 // complete except of tables init
539 typelib_typedescription_initTables( pTD );
540 pTD->bComplete = sal_True;
543 // The type description is hold by the reference until
544 // on demand is activated.
545 ::typelib_typedescription_register( &pTD ); // replaces incomplete one
546 OSL_ASSERT( pTD == *ppTypeDescr ); // has to merge into existing one
548 // insert into the chache
549 MutexGuard aGuard( rInit.getMutex() );
550 if( !rInit.pCache )
551 rInit.pCache = new TypeDescriptionList_Impl;
552 if( (sal_Int32)rInit.pCache->size() >= nCacheSize )
554 typelib_typedescription_release( rInit.pCache->front() );
555 rInit.pCache->pop_front();
557 // descriptions in the cache must be acquired!
558 typelib_typedescription_acquire( pTD );
559 rInit.pCache->push_back( pTD );
561 OSL_ASSERT(
562 pTD->bComplete
563 || (pTD->eTypeClass == typelib_TypeClass_INTERFACE
564 && !initTables));
566 ::typelib_typedescription_release( *ppTypeDescr );
567 *ppTypeDescr = pTD;
569 else
571 #if OSL_DEBUG_LEVEL > 1
572 OString aStr(
573 OUStringToOString( (*ppTypeDescr)->pTypeName, RTL_TEXTENCODING_ASCII_US ) );
574 OSL_TRACE( "\n### type cannot be completed: %s", aStr.getStr() );
575 #endif
576 return false;
579 return true;
584 //------------------------------------------------------------------------
585 extern "C" void SAL_CALL typelib_typedescription_newEmpty(
586 typelib_TypeDescription ** ppRet,
587 typelib_TypeClass eTypeClass, rtl_uString * pTypeName )
588 SAL_THROW_EXTERN_C()
590 if( *ppRet )
592 typelib_typedescription_release( *ppRet );
593 *ppRet = 0;
596 OSL_ASSERT( typelib_TypeClass_TYPEDEF != eTypeClass );
598 typelib_TypeDescription * pRet;
599 switch( eTypeClass )
601 case typelib_TypeClass_ARRAY:
603 typelib_ArrayTypeDescription * pTmp = new typelib_ArrayTypeDescription();
604 typelib_IndirectTypeDescription * pIndirect = (typelib_IndirectTypeDescription *)pTmp;
605 pRet = (typelib_TypeDescription *)pTmp;
606 #if OSL_DEBUG_LEVEL > 1
607 osl_incrementInterlockedCount(
608 &Init::get().nArrayTypeDescriptionCount );
609 #endif
610 pIndirect->pType = 0;
611 pTmp->nDimensions = 0;
612 pTmp->nTotalElements = 0;
613 pTmp->pDimensions = 0;
615 break;
617 case typelib_TypeClass_SEQUENCE:
619 typelib_IndirectTypeDescription * pTmp = new typelib_IndirectTypeDescription();
620 pRet = (typelib_TypeDescription *)pTmp;
621 #if OSL_DEBUG_LEVEL > 1
622 osl_incrementInterlockedCount(
623 &Init::get().nIndirectTypeDescriptionCount );
624 #endif
625 pTmp->pType = 0;
627 break;
629 case typelib_TypeClass_UNION:
631 typelib_UnionTypeDescription * pTmp;
632 pTmp = new typelib_UnionTypeDescription();
633 pRet = (typelib_TypeDescription *)pTmp;
634 #if OSL_DEBUG_LEVEL > 1
635 osl_incrementInterlockedCount(
636 &Init::get().nUnionTypeDescriptionCount );
637 #endif
638 pTmp->nMembers = 0;
639 pTmp->pDiscriminantTypeRef = 0;
640 pTmp->pDiscriminants = 0;
641 pTmp->ppTypeRefs = 0;
642 pTmp->ppMemberNames = 0;
643 pTmp->pDefaultTypeRef = 0;
645 break;
647 case typelib_TypeClass_STRUCT:
649 // FEATURE_EMPTYCLASS
650 typelib_StructTypeDescription * pTmp;
651 pTmp = new typelib_StructTypeDescription();
652 pRet = (typelib_TypeDescription *)pTmp;
653 #if OSL_DEBUG_LEVEL > 1
654 osl_incrementInterlockedCount(
655 &Init::get().nCompoundTypeDescriptionCount );
656 #endif
657 pTmp->aBase.pBaseTypeDescription = 0;
658 pTmp->aBase.nMembers = 0;
659 pTmp->aBase.pMemberOffsets = 0;
660 pTmp->aBase.ppTypeRefs = 0;
661 pTmp->aBase.ppMemberNames = 0;
662 pTmp->pParameterizedTypes = 0;
664 break;
666 case typelib_TypeClass_EXCEPTION:
668 // FEATURE_EMPTYCLASS
669 typelib_CompoundTypeDescription * pTmp;
670 pTmp = new typelib_CompoundTypeDescription();
671 pRet = (typelib_TypeDescription *)pTmp;
672 #if OSL_DEBUG_LEVEL > 1
673 osl_incrementInterlockedCount(
674 &Init::get().nCompoundTypeDescriptionCount );
675 #endif
676 pTmp->pBaseTypeDescription = 0;
677 pTmp->nMembers = 0;
678 pTmp->pMemberOffsets = 0;
679 pTmp->ppTypeRefs = 0;
680 pTmp->ppMemberNames = 0;
682 break;
684 case typelib_TypeClass_ENUM:
686 typelib_EnumTypeDescription * pTmp = new typelib_EnumTypeDescription();
687 pRet = (typelib_TypeDescription *)pTmp;
688 #if OSL_DEBUG_LEVEL > 1
689 osl_incrementInterlockedCount(
690 &Init::get().nEnumTypeDescriptionCount );
691 #endif
692 pTmp->nDefaultEnumValue = 0;
693 pTmp->nEnumValues = 0;
694 pTmp->ppEnumNames = 0;
695 pTmp->pEnumValues = 0;
697 break;
699 case typelib_TypeClass_INTERFACE:
701 typelib_InterfaceTypeDescription * pTmp = new typelib_InterfaceTypeDescription();
702 pRet = (typelib_TypeDescription *)pTmp;
703 #if OSL_DEBUG_LEVEL > 1
704 osl_incrementInterlockedCount(
705 &Init::get().nInterfaceTypeDescriptionCount );
706 #endif
707 pTmp->pBaseTypeDescription = 0;
708 pTmp->nMembers = 0;
709 pTmp->ppMembers = 0;
710 pTmp->nAllMembers = 0;
711 pTmp->ppAllMembers = 0;
712 pTmp->nMapFunctionIndexToMemberIndex = 0;
713 pTmp->pMapFunctionIndexToMemberIndex = 0;
714 pTmp->pMapMemberIndexToFunctionIndex= 0;
715 pTmp->nBaseTypes = 0;
716 pTmp->ppBaseTypes = 0;
718 break;
720 case typelib_TypeClass_INTERFACE_METHOD:
722 typelib_InterfaceMethodTypeDescription * pTmp = new typelib_InterfaceMethodTypeDescription();
723 pRet = (typelib_TypeDescription *)pTmp;
724 #if OSL_DEBUG_LEVEL > 1
725 osl_incrementInterlockedCount(
726 &Init::get().nInterfaceMethodTypeDescriptionCount );
727 #endif
728 pTmp->aBase.pMemberName = 0;
729 pTmp->pReturnTypeRef = 0;
730 pTmp->nParams = 0;
731 pTmp->pParams = 0;
732 pTmp->nExceptions = 0;
733 pTmp->ppExceptions = 0;
734 pTmp->pInterface = 0;
735 pTmp->pBaseRef = 0;
736 pTmp->nIndex = 0;
738 break;
740 case typelib_TypeClass_INTERFACE_ATTRIBUTE:
742 typelib_InterfaceAttributeTypeDescription * pTmp = new typelib_InterfaceAttributeTypeDescription();
743 pRet = (typelib_TypeDescription *)pTmp;
744 #if OSL_DEBUG_LEVEL > 1
745 osl_incrementInterlockedCount(
746 &Init::get().nInterfaceAttributeTypeDescriptionCount );
747 #endif
748 pTmp->aBase.pMemberName = 0;
749 pTmp->pAttributeTypeRef = 0;
750 pTmp->pInterface = 0;
751 pTmp->pBaseRef = 0;
752 pTmp->nIndex = 0;
753 pTmp->nGetExceptions = 0;
754 pTmp->ppGetExceptions = 0;
755 pTmp->nSetExceptions = 0;
756 pTmp->ppSetExceptions = 0;
758 break;
760 default:
762 pRet = new typelib_TypeDescription();
763 #if OSL_DEBUG_LEVEL > 1
764 osl_incrementInterlockedCount( &Init::get().nTypeDescriptionCount );
765 #endif
769 pRet->nRefCount = 1; // reference count is initially 1
770 pRet->nStaticRefCount = 0;
771 pRet->eTypeClass = eTypeClass;
772 pRet->pTypeName = 0;
773 pRet->pUniqueIdentifier = 0;
774 pRet->pReserved = 0;
775 rtl_uString_acquire( pRet->pTypeName = pTypeName );
776 pRet->pSelf = pRet;
777 pRet->bComplete = sal_True;
778 pRet->nSize = 0;
779 pRet->nAlignment = 0;
780 pRet->pWeakRef = 0;
781 pRet->bOnDemand = sal_False;
782 *ppRet = pRet;
785 //------------------------------------------------------------------------
786 namespace {
788 void newTypeDescription(
789 typelib_TypeDescription ** ppRet, typelib_TypeClass eTypeClass,
790 rtl_uString * pTypeName, typelib_TypeDescriptionReference * pType,
791 sal_Int32 nMembers, typelib_CompoundMember_Init * pCompoundMembers,
792 typelib_StructMember_Init * pStructMembers)
794 OSL_ASSERT(
795 (pCompoundMembers == 0 || pStructMembers == 0)
796 && (pStructMembers == 0 || eTypeClass == typelib_TypeClass_STRUCT));
797 if (typelib_TypeClass_TYPEDEF == eTypeClass)
799 OSL_TRACE( "### unexpected typedef!" );
800 typelib_typedescriptionreference_getDescription( ppRet, pType );
801 return;
804 typelib_typedescription_newEmpty( ppRet, eTypeClass, pTypeName );
806 switch( eTypeClass )
808 case typelib_TypeClass_SEQUENCE:
810 OSL_ASSERT( nMembers == 0 );
811 typelib_typedescriptionreference_acquire( pType );
812 ((typelib_IndirectTypeDescription *)*ppRet)->pType = pType;
814 break;
816 case typelib_TypeClass_EXCEPTION:
817 case typelib_TypeClass_STRUCT:
819 // FEATURE_EMPTYCLASS
820 typelib_CompoundTypeDescription * pTmp = (typelib_CompoundTypeDescription*)*ppRet;
822 sal_Int32 nOffset = 0;
823 if( pType )
825 typelib_typedescriptionreference_getDescription(
826 (typelib_TypeDescription **)&pTmp->pBaseTypeDescription, pType );
827 nOffset = ((typelib_TypeDescription *)pTmp->pBaseTypeDescription)->nSize;
828 OSL_ENSURE( newAlignedSize( 0, ((typelib_TypeDescription *)pTmp->pBaseTypeDescription)->nSize, ((typelib_TypeDescription *)pTmp->pBaseTypeDescription)->nAlignment ) == ((typelib_TypeDescription *)pTmp->pBaseTypeDescription)->nSize, "### unexpected offset!" );
830 if( nMembers )
832 pTmp->nMembers = nMembers;
833 pTmp->pMemberOffsets = new sal_Int32[ nMembers ];
834 pTmp->ppTypeRefs = new typelib_TypeDescriptionReference *[ nMembers ];
835 pTmp->ppMemberNames = new rtl_uString *[ nMembers ];
836 bool polymorphic = eTypeClass == typelib_TypeClass_STRUCT
837 && rtl::OUString::unacquired(&pTypeName).indexOf('<') >= 0;
838 OSL_ASSERT(!polymorphic || pStructMembers != 0);
839 if (polymorphic) {
840 reinterpret_cast< typelib_StructTypeDescription * >(pTmp)->
841 pParameterizedTypes = new sal_Bool[nMembers];
843 for( sal_Int32 i = 0 ; i < nMembers; i++ )
845 // read the type and member names
846 pTmp->ppTypeRefs[i] = 0;
847 if (pCompoundMembers != 0) {
848 typelib_typedescriptionreference_new(
849 pTmp->ppTypeRefs +i, pCompoundMembers[i].eTypeClass,
850 pCompoundMembers[i].pTypeName );
851 rtl_uString_acquire(
852 pTmp->ppMemberNames[i]
853 = pCompoundMembers[i].pMemberName );
854 } else {
855 typelib_typedescriptionreference_new(
856 pTmp->ppTypeRefs +i,
857 pStructMembers[i].aBase.eTypeClass,
858 pStructMembers[i].aBase.pTypeName );
859 rtl_uString_acquire(
860 pTmp->ppMemberNames[i]
861 = pStructMembers[i].aBase.pMemberName );
863 // write offset
864 sal_Int32 size;
865 sal_Int32 alignment;
866 if (pTmp->ppTypeRefs[i]->eTypeClass ==
867 typelib_TypeClass_SEQUENCE)
869 // Take care of recursion like
870 // struct S { sequence<S> x; };
871 size = sizeof(void *);
872 alignment = adjustAlignment(size);
873 } else {
874 typelib_TypeDescription * pTD = 0;
875 TYPELIB_DANGER_GET( &pTD, pTmp->ppTypeRefs[i] );
876 OSL_ENSURE( pTD->nSize, "### void member?" );
877 size = pTD->nSize;
878 alignment = pTD->nAlignment;
879 TYPELIB_DANGER_RELEASE( pTD );
881 nOffset = newAlignedSize( nOffset, size, alignment );
882 pTmp->pMemberOffsets[i] = nOffset - size;
884 if (polymorphic) {
885 reinterpret_cast< typelib_StructTypeDescription * >(
886 pTmp)->pParameterizedTypes[i]
887 = pStructMembers[i].bParameterizedType;
892 break;
894 default:
895 break;
898 if( !reallyWeak( eTypeClass ) )
899 (*ppRet)->pWeakRef = (typelib_TypeDescriptionReference *)*ppRet;
900 if( eTypeClass != typelib_TypeClass_VOID )
902 // sizeof( void ) not allowed
903 (*ppRet)->nSize = typelib_typedescription_getAlignedUnoSize( (*ppRet), 0, (*ppRet)->nAlignment );
904 (*ppRet)->nAlignment = adjustAlignment( (*ppRet)->nAlignment );
910 extern "C" void SAL_CALL typelib_typedescription_new(
911 typelib_TypeDescription ** ppRet,
912 typelib_TypeClass eTypeClass,
913 rtl_uString * pTypeName,
914 typelib_TypeDescriptionReference * pType,
915 sal_Int32 nMembers,
916 typelib_CompoundMember_Init * pMembers )
917 SAL_THROW_EXTERN_C()
919 newTypeDescription(
920 ppRet, eTypeClass, pTypeName, pType, nMembers, pMembers, 0);
923 extern "C" void SAL_CALL typelib_typedescription_newStruct(
924 typelib_TypeDescription ** ppRet,
925 rtl_uString * pTypeName,
926 typelib_TypeDescriptionReference * pType,
927 sal_Int32 nMembers,
928 typelib_StructMember_Init * pMembers )
929 SAL_THROW_EXTERN_C()
931 newTypeDescription(
932 ppRet, typelib_TypeClass_STRUCT, pTypeName, pType, nMembers, 0,
933 pMembers);
936 //------------------------------------------------------------------------
937 extern "C" void SAL_CALL typelib_typedescription_newUnion(
938 typelib_TypeDescription ** ppRet,
939 rtl_uString * pTypeName,
940 typelib_TypeDescriptionReference * pDiscriminantTypeRef,
941 sal_Int64 nDefaultDiscriminant,
942 typelib_TypeDescriptionReference * pDefaultTypeRef,
943 sal_Int32 nMembers,
944 typelib_Union_Init * pMembers )
945 SAL_THROW_EXTERN_C()
947 typelib_typedescription_newEmpty( ppRet, typelib_TypeClass_UNION, pTypeName );
948 // discriminant type
949 typelib_UnionTypeDescription * pTmp = (typelib_UnionTypeDescription *)*ppRet;
950 typelib_typedescriptionreference_acquire( pTmp->pDiscriminantTypeRef = pDiscriminantTypeRef );
952 sal_Int32 nPos;
954 pTmp->nMembers = nMembers;
955 // default discriminant
956 if (nMembers)
958 pTmp->pDiscriminants = new sal_Int64[ nMembers ];
959 for ( nPos = nMembers; nPos--; )
961 pTmp->pDiscriminants[nPos] = pMembers[nPos].nDiscriminant;
964 // default default discriminant
965 pTmp->nDefaultDiscriminant = nDefaultDiscriminant;
967 // union member types
968 pTmp->ppTypeRefs = new typelib_TypeDescriptionReference *[ nMembers ];
969 for ( nPos = nMembers; nPos--; )
971 typelib_typedescriptionreference_acquire( pTmp->ppTypeRefs[nPos] = pMembers[nPos].pTypeRef );
973 // union member names
974 pTmp->ppMemberNames = new rtl_uString *[ nMembers ];
975 for ( nPos = nMembers; nPos--; )
977 rtl_uString_acquire( pTmp->ppMemberNames[nPos] = pMembers[nPos].pMemberName );
980 // default union type
981 typelib_typedescriptionreference_acquire( pTmp->pDefaultTypeRef = pDefaultTypeRef );
983 if (! reallyWeak( typelib_TypeClass_UNION ))
984 (*ppRet)->pWeakRef = (typelib_TypeDescriptionReference *)*ppRet;
985 (*ppRet)->nSize = typelib_typedescription_getAlignedUnoSize( (*ppRet), 0, (*ppRet)->nAlignment );
986 (*ppRet)->nAlignment = adjustAlignment( (*ppRet)->nAlignment );
989 //------------------------------------------------------------------------
990 extern "C" void SAL_CALL typelib_typedescription_newEnum(
991 typelib_TypeDescription ** ppRet,
992 rtl_uString * pTypeName,
993 sal_Int32 nDefaultValue,
994 sal_Int32 nEnumValues,
995 rtl_uString ** ppEnumNames,
996 sal_Int32 * pEnumValues )
997 SAL_THROW_EXTERN_C()
999 typelib_typedescription_newEmpty( ppRet, typelib_TypeClass_ENUM, pTypeName );
1000 typelib_EnumTypeDescription * pEnum = (typelib_EnumTypeDescription *)*ppRet;
1002 pEnum->nDefaultEnumValue = nDefaultValue;
1003 pEnum->nEnumValues = nEnumValues;
1004 pEnum->ppEnumNames = new rtl_uString * [ nEnumValues ];
1005 for ( sal_Int32 nPos = nEnumValues; nPos--; )
1007 rtl_uString_acquire( pEnum->ppEnumNames[nPos] = ppEnumNames[nPos] );
1009 pEnum->pEnumValues = new sal_Int32[ nEnumValues ];
1010 ::memcpy( pEnum->pEnumValues, pEnumValues, nEnumValues * sizeof(sal_Int32) );
1012 (*ppRet)->pWeakRef = (typelib_TypeDescriptionReference *)*ppRet;
1013 // sizeof( void ) not allowed
1014 (*ppRet)->nSize = typelib_typedescription_getAlignedUnoSize( (*ppRet), 0, (*ppRet)->nAlignment );
1015 (*ppRet)->nAlignment = adjustAlignment( (*ppRet)->nAlignment );
1018 //------------------------------------------------------------------------
1019 extern "C" void SAL_CALL typelib_typedescription_newArray(
1020 typelib_TypeDescription ** ppRet,
1021 typelib_TypeDescriptionReference * pElementTypeRef,
1022 sal_Int32 nDimensions,
1023 sal_Int32 * pDimensions )
1024 SAL_THROW_EXTERN_C ()
1026 OUStringBuffer aBuf( 32 );
1027 aBuf.append( pElementTypeRef->pTypeName );
1028 sal_Int32 nElements = 1;
1029 for (sal_Int32 i=0; i < nDimensions; i++)
1031 aBuf.appendAscii("[");
1032 aBuf.append(pDimensions[i]);
1033 aBuf.appendAscii("]");
1034 nElements *= pDimensions[i];
1036 OUString aTypeName( aBuf.makeStringAndClear() );
1039 typelib_typedescription_newEmpty( ppRet, typelib_TypeClass_ARRAY, aTypeName.pData );
1040 typelib_ArrayTypeDescription * pArray = (typelib_ArrayTypeDescription *)*ppRet;
1042 pArray->nDimensions = nDimensions;
1043 pArray->nTotalElements = nElements;
1044 pArray->pDimensions = new sal_Int32[ nDimensions ];
1045 ::memcpy( pArray->pDimensions, pDimensions, nDimensions * sizeof(sal_Int32) );
1047 typelib_typedescriptionreference_acquire(pElementTypeRef);
1048 ((typelib_IndirectTypeDescription*)pArray)->pType = pElementTypeRef;
1050 (*ppRet)->pWeakRef = (typelib_TypeDescriptionReference *)*ppRet;
1051 // sizeof( void ) not allowed
1052 (*ppRet)->nSize = typelib_typedescription_getAlignedUnoSize( *ppRet, 0, (*ppRet)->nAlignment );
1053 (*ppRet)->nAlignment = adjustAlignment( (*ppRet)->nAlignment );
1056 //------------------------------------------------------------------------
1057 extern "C" void SAL_CALL typelib_typedescription_newInterface(
1058 typelib_InterfaceTypeDescription ** ppRet,
1059 rtl_uString * pTypeName,
1060 sal_uInt32 nUik1, sal_uInt16 nUik2, sal_uInt16 nUik3, sal_uInt32 nUik4, sal_uInt32 nUik5,
1061 typelib_TypeDescriptionReference * pBaseInterface,
1062 sal_Int32 nMembers,
1063 typelib_TypeDescriptionReference ** ppMembers )
1064 SAL_THROW_EXTERN_C()
1066 typelib_typedescription_newMIInterface(
1067 ppRet, pTypeName, nUik1, nUik2, nUik3, nUik4, nUik5,
1068 pBaseInterface == 0 ? 0 : 1, &pBaseInterface, nMembers, ppMembers);
1071 //------------------------------------------------------------------------
1073 namespace {
1075 class BaseList {
1076 public:
1077 struct Entry {
1078 sal_Int32 memberOffset;
1079 sal_Int32 directBaseIndex;
1080 sal_Int32 directBaseMemberOffset;
1081 typelib_InterfaceTypeDescription const * base;
1084 typedef std::vector< Entry > List;
1086 BaseList(typelib_InterfaceTypeDescription const * desc);
1088 List const & getList() const { return list; }
1090 sal_Int32 getBaseMembers() const { return members; }
1092 private:
1093 typedef std::set< rtl::OUString > Set;
1095 void calculate(
1096 sal_Int32 directBaseIndex, Set & directBaseSet,
1097 sal_Int32 * directBaseMembers,
1098 typelib_InterfaceTypeDescription const * desc);
1100 Set set;
1101 List list;
1102 sal_Int32 members;
1105 BaseList::BaseList(typelib_InterfaceTypeDescription const * desc) {
1106 members = 0;
1107 for (sal_Int32 i = 0; i < desc->nBaseTypes; ++i) {
1108 Set directBaseSet;
1109 sal_Int32 directBaseMembers = 0;
1110 calculate(i, directBaseSet, &directBaseMembers, desc->ppBaseTypes[i]);
1114 void BaseList::calculate(
1115 sal_Int32 directBaseIndex, Set & directBaseSet,
1116 sal_Int32 * directBaseMembers,
1117 typelib_InterfaceTypeDescription const * desc)
1119 for (sal_Int32 i = 0; i < desc->nBaseTypes; ++i) {
1120 calculate(
1121 directBaseIndex, directBaseSet, directBaseMembers,
1122 desc->ppBaseTypes[i]);
1124 if (set.insert(desc->aBase.pTypeName).second) {
1125 Entry e;
1126 e.memberOffset = members;
1127 e.directBaseIndex = directBaseIndex;
1128 e.directBaseMemberOffset = *directBaseMembers;
1129 e.base = desc;
1130 list.push_back(e);
1131 OSL_ASSERT(desc->ppAllMembers != 0);
1132 members += desc->nMembers;
1134 if (directBaseSet.insert(desc->aBase.pTypeName).second) {
1135 OSL_ASSERT(desc->ppAllMembers != 0);
1136 *directBaseMembers += desc->nMembers;
1142 extern "C" void SAL_CALL typelib_typedescription_newMIInterface(
1143 typelib_InterfaceTypeDescription ** ppRet,
1144 rtl_uString * pTypeName,
1145 sal_uInt32 nUik1, sal_uInt16 nUik2, sal_uInt16 nUik3, sal_uInt32 nUik4, sal_uInt32 nUik5,
1146 sal_Int32 nBaseInterfaces,
1147 typelib_TypeDescriptionReference ** ppBaseInterfaces,
1148 sal_Int32 nMembers,
1149 typelib_TypeDescriptionReference ** ppMembers )
1150 SAL_THROW_EXTERN_C()
1152 if (*ppRet != 0) {
1153 typelib_typedescription_release(&(*ppRet)->aBase);
1154 *ppRet = 0;
1157 typelib_InterfaceTypeDescription * pITD = 0;
1158 typelib_typedescription_newEmpty(
1159 (typelib_TypeDescription **)&pITD, typelib_TypeClass_INTERFACE, pTypeName );
1161 pITD->nBaseTypes = nBaseInterfaces;
1162 pITD->ppBaseTypes = new typelib_InterfaceTypeDescription *[nBaseInterfaces];
1163 for (sal_Int32 i = 0; i < nBaseInterfaces; ++i) {
1164 pITD->ppBaseTypes[i] = 0;
1165 typelib_typedescriptionreference_getDescription(
1166 reinterpret_cast< typelib_TypeDescription ** >(
1167 &pITD->ppBaseTypes[i]),
1168 ppBaseInterfaces[i]);
1169 if (pITD->ppBaseTypes[i] == 0
1170 || !complete(
1171 reinterpret_cast< typelib_TypeDescription ** >(
1172 &pITD->ppBaseTypes[i]),
1173 false))
1175 OSL_ASSERT(false);
1176 return;
1178 OSL_ASSERT(pITD->ppBaseTypes[i] != 0);
1180 if (nBaseInterfaces > 0) {
1181 pITD->pBaseTypeDescription = pITD->ppBaseTypes[0];
1183 // set the
1184 pITD->aUik.m_Data1 = nUik1;
1185 pITD->aUik.m_Data2 = nUik2;
1186 pITD->aUik.m_Data3 = nUik3;
1187 pITD->aUik.m_Data4 = nUik4;
1188 pITD->aUik.m_Data5 = nUik5;
1190 BaseList aBaseList(pITD);
1191 pITD->nAllMembers = nMembers + aBaseList.getBaseMembers();
1192 pITD->nMembers = nMembers;
1194 if( pITD->nAllMembers )
1196 // at minimum one member exist, allocate the memory
1197 pITD->ppAllMembers = new typelib_TypeDescriptionReference *[ pITD->nAllMembers ];
1198 sal_Int32 n = 0;
1200 BaseList::List const & rList = aBaseList.getList();
1201 {for (BaseList::List::const_iterator i(rList.begin()); i != rList.end();
1202 ++i)
1204 typelib_InterfaceTypeDescription const * pBase = i->base;
1205 typelib_InterfaceTypeDescription const * pDirectBase
1206 = pITD->ppBaseTypes[i->directBaseIndex];
1207 OSL_ASSERT(pBase->ppAllMembers != 0);
1208 for (sal_Int32 j = 0; j < pBase->nMembers; ++j) {
1209 typelib_TypeDescriptionReference const * pDirectBaseMember
1210 = pDirectBase->ppAllMembers[i->directBaseMemberOffset + j];
1211 rtl::OUStringBuffer aBuf(pDirectBaseMember->pTypeName);
1212 aBuf.appendAscii(RTL_CONSTASCII_STRINGPARAM(":@"));
1213 aBuf.append(i->directBaseIndex);
1214 aBuf.append(static_cast< sal_Unicode >(','));
1215 aBuf.append(i->memberOffset + j);
1216 aBuf.append(static_cast< sal_Unicode >(':'));
1217 aBuf.append(pITD->aBase.pTypeName);
1218 rtl::OUString aName(aBuf.makeStringAndClear());
1219 typelib_TypeDescriptionReference * pDerivedMember = 0;
1220 typelib_typedescriptionreference_new(
1221 &pDerivedMember, pDirectBaseMember->eTypeClass,
1222 aName.pData);
1223 pITD->ppAllMembers[n++] = pDerivedMember;
1227 if( nMembers )
1229 pITD->ppMembers = pITD->ppAllMembers + aBaseList.getBaseMembers();
1232 // add own members
1233 {for( sal_Int32 i = 0; i < nMembers; i++ )
1235 typelib_typedescriptionreference_acquire( ppMembers[i] );
1236 pITD->ppAllMembers[n++] = ppMembers[i];
1240 typelib_TypeDescription * pTmp = (typelib_TypeDescription *)pITD;
1241 if( !reallyWeak( typelib_TypeClass_INTERFACE ) )
1242 pTmp->pWeakRef = (typelib_TypeDescriptionReference *)pTmp;
1243 pTmp->nSize = typelib_typedescription_getAlignedUnoSize( pTmp, 0, pTmp->nAlignment );
1244 pTmp->nAlignment = adjustAlignment( pTmp->nAlignment );
1245 pTmp->bComplete = sal_False;
1247 *ppRet = pITD;
1250 //------------------------------------------------------------------------
1252 namespace {
1254 typelib_TypeDescriptionReference ** copyExceptions(
1255 sal_Int32 count, rtl_uString ** typeNames)
1257 OSL_ASSERT(count >= 0);
1258 if (count == 0) {
1259 return 0;
1261 typelib_TypeDescriptionReference ** p
1262 = new typelib_TypeDescriptionReference *[count];
1263 for (sal_Int32 i = 0; i < count; ++i) {
1264 p[i] = 0;
1265 typelib_typedescriptionreference_new(
1266 p + i, typelib_TypeClass_EXCEPTION, typeNames[i]);
1268 return p;
1273 extern "C" void SAL_CALL typelib_typedescription_newInterfaceMethod(
1274 typelib_InterfaceMethodTypeDescription ** ppRet,
1275 sal_Int32 nAbsolutePosition,
1276 sal_Bool bOneWay,
1277 rtl_uString * pTypeName,
1278 typelib_TypeClass eReturnTypeClass,
1279 rtl_uString * pReturnTypeName,
1280 sal_Int32 nParams,
1281 typelib_Parameter_Init * pParams,
1282 sal_Int32 nExceptions,
1283 rtl_uString ** ppExceptionNames )
1284 SAL_THROW_EXTERN_C()
1286 if (*ppRet != 0) {
1287 typelib_typedescription_release(&(*ppRet)->aBase.aBase);
1288 *ppRet = 0;
1290 sal_Int32 nOffset = rtl_ustr_lastIndexOfChar_WithLength(
1291 pTypeName->buffer, pTypeName->length, ':');
1292 if (nOffset <= 0 || pTypeName->buffer[nOffset - 1] != ':') {
1293 OSL_ENSURE(false, "Bad interface method type name");
1294 return;
1296 rtl::OUString aInterfaceTypeName(pTypeName->buffer, nOffset - 1);
1297 typelib_InterfaceTypeDescription * pInterface = 0;
1298 typelib_typedescription_getByName(
1299 reinterpret_cast< typelib_TypeDescription ** >(&pInterface),
1300 aInterfaceTypeName.pData);
1301 if (pInterface == 0
1302 || pInterface->aBase.eTypeClass != typelib_TypeClass_INTERFACE
1303 || !complete(
1304 reinterpret_cast< typelib_TypeDescription ** >(&pInterface), false))
1306 OSL_ENSURE(false, "No interface corresponding to interface method");
1307 return;
1310 typelib_typedescription_newEmpty(
1311 (typelib_TypeDescription **)ppRet, typelib_TypeClass_INTERFACE_METHOD, pTypeName );
1312 typelib_TypeDescription * pTmp = (typelib_TypeDescription *)*ppRet;
1314 rtl_uString_newFromStr_WithLength( &(*ppRet)->aBase.pMemberName,
1315 pTypeName->buffer + nOffset +1,
1316 pTypeName->length - nOffset -1 );
1317 (*ppRet)->aBase.nPosition = nAbsolutePosition;
1318 (*ppRet)->bOneWay = bOneWay;
1319 typelib_typedescriptionreference_new( &(*ppRet)->pReturnTypeRef, eReturnTypeClass, pReturnTypeName );
1320 (*ppRet)->nParams = nParams;
1321 if( nParams )
1323 (*ppRet)->pParams = new typelib_MethodParameter[ nParams ];
1325 for( sal_Int32 i = 0; i < nParams; i++ )
1327 // get the name of the parameter
1328 (*ppRet)->pParams[ i ].pName = 0;
1329 rtl_uString_acquire( (*ppRet)->pParams[ i ].pName = pParams[i].pParamName );
1330 (*ppRet)->pParams[ i ].pTypeRef = 0;
1331 // get the type name of the parameter and create the weak reference
1332 typelib_typedescriptionreference_new(
1333 &(*ppRet)->pParams[ i ].pTypeRef, pParams[i].eTypeClass, pParams[i].pTypeName );
1334 (*ppRet)->pParams[ i ].bIn = pParams[i].bIn;
1335 (*ppRet)->pParams[ i ].bOut = pParams[i].bOut;
1338 (*ppRet)->nExceptions = nExceptions;
1339 (*ppRet)->ppExceptions = copyExceptions(nExceptions, ppExceptionNames);
1340 (*ppRet)->pInterface = pInterface;
1341 (*ppRet)->pBaseRef = 0;
1342 OSL_ASSERT(
1343 (nAbsolutePosition >= pInterface->nAllMembers - pInterface->nMembers)
1344 && nAbsolutePosition < pInterface->nAllMembers);
1345 (*ppRet)->nIndex = nAbsolutePosition
1346 - (pInterface->nAllMembers - pInterface->nMembers);
1347 if( !reallyWeak( typelib_TypeClass_INTERFACE_METHOD ) )
1348 pTmp->pWeakRef = (typelib_TypeDescriptionReference *)pTmp;
1352 //------------------------------------------------------------------------
1353 extern "C" void SAL_CALL typelib_typedescription_newInterfaceAttribute(
1354 typelib_InterfaceAttributeTypeDescription ** ppRet,
1355 sal_Int32 nAbsolutePosition,
1356 rtl_uString * pTypeName,
1357 typelib_TypeClass eAttributeTypeClass,
1358 rtl_uString * pAttributeTypeName,
1359 sal_Bool bReadOnly )
1360 SAL_THROW_EXTERN_C()
1362 typelib_typedescription_newExtendedInterfaceAttribute(
1363 ppRet, nAbsolutePosition, pTypeName, eAttributeTypeClass,
1364 pAttributeTypeName, bReadOnly, 0, 0, 0, 0);
1367 //------------------------------------------------------------------------
1368 extern "C" void SAL_CALL typelib_typedescription_newExtendedInterfaceAttribute(
1369 typelib_InterfaceAttributeTypeDescription ** ppRet,
1370 sal_Int32 nAbsolutePosition,
1371 rtl_uString * pTypeName,
1372 typelib_TypeClass eAttributeTypeClass,
1373 rtl_uString * pAttributeTypeName,
1374 sal_Bool bReadOnly,
1375 sal_Int32 nGetExceptions, rtl_uString ** ppGetExceptionNames,
1376 sal_Int32 nSetExceptions, rtl_uString ** ppSetExceptionNames )
1377 SAL_THROW_EXTERN_C()
1379 if (*ppRet != 0) {
1380 typelib_typedescription_release(&(*ppRet)->aBase.aBase);
1381 *ppRet = 0;
1383 sal_Int32 nOffset = rtl_ustr_lastIndexOfChar_WithLength(
1384 pTypeName->buffer, pTypeName->length, ':');
1385 if (nOffset <= 0 || pTypeName->buffer[nOffset - 1] != ':') {
1386 OSL_ENSURE(false, "Bad interface attribute type name");
1387 return;
1389 rtl::OUString aInterfaceTypeName(pTypeName->buffer, nOffset - 1);
1390 typelib_InterfaceTypeDescription * pInterface = 0;
1391 typelib_typedescription_getByName(
1392 reinterpret_cast< typelib_TypeDescription ** >(&pInterface),
1393 aInterfaceTypeName.pData);
1394 if (pInterface == 0
1395 || pInterface->aBase.eTypeClass != typelib_TypeClass_INTERFACE
1396 || !complete(
1397 reinterpret_cast< typelib_TypeDescription ** >(&pInterface), false))
1399 OSL_ENSURE(false, "No interface corresponding to interface attribute");
1400 return;
1403 typelib_typedescription_newEmpty(
1404 (typelib_TypeDescription **)ppRet, typelib_TypeClass_INTERFACE_ATTRIBUTE, pTypeName );
1405 typelib_TypeDescription * pTmp = (typelib_TypeDescription *)*ppRet;
1407 rtl_uString_newFromStr_WithLength( &(*ppRet)->aBase.pMemberName,
1408 pTypeName->buffer + nOffset +1,
1409 pTypeName->length - nOffset -1 );
1410 (*ppRet)->aBase.nPosition = nAbsolutePosition;
1411 typelib_typedescriptionreference_new( &(*ppRet)->pAttributeTypeRef, eAttributeTypeClass, pAttributeTypeName );
1412 (*ppRet)->bReadOnly = bReadOnly;
1413 (*ppRet)->pInterface = pInterface;
1414 (*ppRet)->pBaseRef = 0;
1415 OSL_ASSERT(
1416 (nAbsolutePosition >= pInterface->nAllMembers - pInterface->nMembers)
1417 && nAbsolutePosition < pInterface->nAllMembers);
1418 (*ppRet)->nIndex = nAbsolutePosition
1419 - (pInterface->nAllMembers - pInterface->nMembers);
1420 (*ppRet)->nGetExceptions = nGetExceptions;
1421 (*ppRet)->ppGetExceptions = copyExceptions(
1422 nGetExceptions, ppGetExceptionNames);
1423 (*ppRet)->nSetExceptions = nSetExceptions;
1424 (*ppRet)->ppSetExceptions = copyExceptions(
1425 nSetExceptions, ppSetExceptionNames);
1426 if( !reallyWeak( typelib_TypeClass_INTERFACE_ATTRIBUTE ) )
1427 pTmp->pWeakRef = (typelib_TypeDescriptionReference *)pTmp;
1430 //------------------------------------------------------------------------
1431 extern "C" void SAL_CALL typelib_typedescription_acquire(
1432 typelib_TypeDescription * pTypeDescription )
1433 SAL_THROW_EXTERN_C()
1435 ::osl_incrementInterlockedCount( &pTypeDescription->nRefCount );
1438 //------------------------------------------------------------------------
1440 namespace {
1442 void deleteExceptions(
1443 sal_Int32 count, typelib_TypeDescriptionReference ** exceptions)
1445 for (sal_Int32 i = 0; i < count; ++i) {
1446 typelib_typedescriptionreference_release(exceptions[i]);
1448 delete[] exceptions;
1453 // frees anything except typelib_TypeDescription base!
1454 static inline void typelib_typedescription_destructExtendedMembers(
1455 typelib_TypeDescription * pTD )
1456 SAL_THROW( () )
1458 OSL_ASSERT( typelib_TypeClass_TYPEDEF != pTD->eTypeClass );
1460 switch( pTD->eTypeClass )
1462 case typelib_TypeClass_ARRAY:
1463 if( ((typelib_IndirectTypeDescription*)pTD)->pType )
1464 typelib_typedescriptionreference_release( ((typelib_IndirectTypeDescription*)pTD)->pType );
1465 delete [] ((typelib_ArrayTypeDescription *)pTD)->pDimensions;
1466 break;
1467 case typelib_TypeClass_SEQUENCE:
1468 if( ((typelib_IndirectTypeDescription*)pTD)->pType )
1469 typelib_typedescriptionreference_release( ((typelib_IndirectTypeDescription*)pTD)->pType );
1470 break;
1471 case typelib_TypeClass_UNION:
1473 typelib_UnionTypeDescription * pUnionTD = (typelib_UnionTypeDescription *)pTD;
1474 typelib_typedescriptionreference_release( pUnionTD->pDiscriminantTypeRef );
1475 typelib_typedescriptionreference_release( pUnionTD->pDefaultTypeRef );
1477 sal_Int32 nPos;
1478 typelib_TypeDescriptionReference ** ppTypeRefs = pUnionTD->ppTypeRefs;
1479 for ( nPos = pUnionTD->nMembers; nPos--; )
1481 typelib_typedescriptionreference_release( ppTypeRefs[nPos] );
1484 rtl_uString ** ppMemberNames = pUnionTD->ppMemberNames;
1485 for ( nPos = pUnionTD->nMembers; nPos--; )
1487 rtl_uString_release( ppMemberNames[nPos] );
1489 delete [] pUnionTD->ppMemberNames;
1490 delete [] pUnionTD->pDiscriminants;
1491 delete [] pUnionTD->ppTypeRefs;
1493 break;
1494 case typelib_TypeClass_STRUCT:
1495 delete[] reinterpret_cast< typelib_StructTypeDescription * >(pTD)->
1496 pParameterizedTypes;
1497 case typelib_TypeClass_EXCEPTION:
1499 typelib_CompoundTypeDescription * pCTD = (typelib_CompoundTypeDescription*)pTD;
1500 if( pCTD->pBaseTypeDescription )
1501 typelib_typedescription_release( (typelib_TypeDescription *)pCTD->pBaseTypeDescription );
1502 sal_Int32 i;
1503 for( i = 0; i < pCTD->nMembers; i++ )
1505 typelib_typedescriptionreference_release( pCTD->ppTypeRefs[i] );
1507 if (pCTD->ppMemberNames)
1509 for ( i = 0; i < pCTD->nMembers; i++ )
1511 rtl_uString_release( pCTD->ppMemberNames[i] );
1513 delete [] pCTD->ppMemberNames;
1515 delete [] pCTD->ppTypeRefs;
1516 delete [] pCTD->pMemberOffsets;
1518 break;
1519 case typelib_TypeClass_INTERFACE:
1521 typelib_InterfaceTypeDescription * pITD = (typelib_InterfaceTypeDescription*)pTD;
1522 {for( sal_Int32 i = 0; i < pITD->nAllMembers; i++ )
1524 typelib_typedescriptionreference_release( pITD->ppAllMembers[i] );
1526 delete [] pITD->ppAllMembers;
1527 delete [] pITD->pMapMemberIndexToFunctionIndex;
1528 delete [] pITD->pMapFunctionIndexToMemberIndex;
1529 {for (sal_Int32 i = 0; i < pITD->nBaseTypes; ++i) {
1530 typelib_typedescription_release(
1531 reinterpret_cast< typelib_TypeDescription * >(
1532 pITD->ppBaseTypes[i]));
1534 delete[] pITD->ppBaseTypes;
1535 break;
1537 case typelib_TypeClass_INTERFACE_METHOD:
1539 typelib_InterfaceMethodTypeDescription * pIMTD = (typelib_InterfaceMethodTypeDescription*)pTD;
1540 if( pIMTD->pReturnTypeRef )
1541 typelib_typedescriptionreference_release( pIMTD->pReturnTypeRef );
1542 for( sal_Int32 i = 0; i < pIMTD->nParams; i++ )
1544 rtl_uString_release( pIMTD->pParams[ i ].pName );
1545 typelib_typedescriptionreference_release( pIMTD->pParams[ i ].pTypeRef );
1547 delete [] pIMTD->pParams;
1548 deleteExceptions(pIMTD->nExceptions, pIMTD->ppExceptions);
1549 rtl_uString_release( pIMTD->aBase.pMemberName );
1550 typelib_typedescription_release(&pIMTD->pInterface->aBase);
1551 if (pIMTD->pBaseRef != 0) {
1552 typelib_typedescriptionreference_release(pIMTD->pBaseRef);
1555 break;
1556 case typelib_TypeClass_INTERFACE_ATTRIBUTE:
1558 typelib_InterfaceAttributeTypeDescription * pIATD = (typelib_InterfaceAttributeTypeDescription*)pTD;
1559 deleteExceptions(pIATD->nGetExceptions, pIATD->ppGetExceptions);
1560 deleteExceptions(pIATD->nSetExceptions, pIATD->ppSetExceptions);
1561 if( pIATD->pAttributeTypeRef )
1562 typelib_typedescriptionreference_release( pIATD->pAttributeTypeRef );
1563 if( pIATD->aBase.pMemberName )
1564 rtl_uString_release( pIATD->aBase.pMemberName );
1565 typelib_typedescription_release(&pIATD->pInterface->aBase);
1566 if (pIATD->pBaseRef != 0) {
1567 typelib_typedescriptionreference_release(pIATD->pBaseRef);
1570 break;
1571 case typelib_TypeClass_ENUM:
1573 typelib_EnumTypeDescription * pEnum = (typelib_EnumTypeDescription *)pTD;
1574 for ( sal_Int32 nPos = pEnum->nEnumValues; nPos--; )
1576 rtl_uString_release( pEnum->ppEnumNames[nPos] );
1578 delete [] pEnum->ppEnumNames;
1579 delete [] pEnum->pEnumValues;
1581 break;
1582 default:
1583 break;
1587 //------------------------------------------------------------------------
1588 extern "C" void SAL_CALL typelib_typedescription_release(
1589 typelib_TypeDescription * pTD )
1590 SAL_THROW_EXTERN_C()
1592 sal_Int32 ref = ::osl_decrementInterlockedCount( &pTD->nRefCount );
1593 OSL_ASSERT(ref >= 0);
1594 if (0 == ref)
1596 TypeDescriptor_Init_Impl &rInit = Init::get();
1597 if( reallyWeak( pTD->eTypeClass ) )
1599 if( pTD->pWeakRef )
1602 MutexGuard aGuard( rInit.getMutex() );
1603 // remove this description from the weak reference
1604 pTD->pWeakRef->pType = 0;
1606 typelib_typedescriptionreference_release( pTD->pWeakRef );
1609 else
1611 // this description is a reference too, so remove it from the hash table
1612 if( rInit.pWeakMap )
1614 MutexGuard aGuard( rInit.getMutex() );
1615 WeakMap_Impl::iterator aIt = rInit.pWeakMap->find( (sal_Unicode*)pTD->pTypeName->buffer );
1616 if( aIt != rInit.pWeakMap->end() && (void *)(*aIt).second == (void *)pTD )
1618 // remove only if it contains the same object
1619 rInit.pWeakMap->erase( aIt );
1624 typelib_typedescription_destructExtendedMembers( pTD );
1625 rtl_uString_release( pTD->pTypeName );
1627 #if OSL_DEBUG_LEVEL > 1
1628 switch( pTD->eTypeClass )
1630 case typelib_TypeClass_ARRAY:
1631 osl_decrementInterlockedCount( &rInit.nArrayTypeDescriptionCount );
1632 break;
1633 case typelib_TypeClass_SEQUENCE:
1634 osl_decrementInterlockedCount( &rInit.nIndirectTypeDescriptionCount );
1635 break;
1636 case typelib_TypeClass_UNION:
1637 osl_decrementInterlockedCount( &rInit.nUnionTypeDescriptionCount );
1638 break;
1639 case typelib_TypeClass_STRUCT:
1640 case typelib_TypeClass_EXCEPTION:
1641 osl_decrementInterlockedCount( &rInit.nCompoundTypeDescriptionCount );
1642 break;
1643 case typelib_TypeClass_INTERFACE:
1644 osl_decrementInterlockedCount( &rInit.nInterfaceTypeDescriptionCount );
1645 break;
1646 case typelib_TypeClass_INTERFACE_METHOD:
1647 osl_decrementInterlockedCount( &rInit.nInterfaceMethodTypeDescriptionCount );
1648 break;
1649 case typelib_TypeClass_INTERFACE_ATTRIBUTE:
1650 osl_decrementInterlockedCount( &rInit.nInterfaceAttributeTypeDescriptionCount );
1651 break;
1652 case typelib_TypeClass_ENUM:
1653 osl_decrementInterlockedCount( &rInit.nEnumTypeDescriptionCount );
1654 break;
1655 default:
1656 osl_decrementInterlockedCount( &rInit.nTypeDescriptionCount );
1658 #endif
1660 delete pTD;
1664 //------------------------------------------------------------------------
1665 extern "C" void SAL_CALL typelib_typedescription_register(
1666 typelib_TypeDescription ** ppNewDescription )
1667 SAL_THROW_EXTERN_C()
1669 // connect the description with the weak reference
1670 TypeDescriptor_Init_Impl &rInit = Init::get();
1671 ClearableMutexGuard aGuard( rInit.getMutex() );
1673 typelib_TypeDescriptionReference * pTDR = 0;
1674 typelib_typedescriptionreference_getByName( &pTDR, (*ppNewDescription)->pTypeName );
1676 OSL_ASSERT( (*ppNewDescription)->pWeakRef || reallyWeak( (*ppNewDescription)->eTypeClass ) );
1677 if( pTDR )
1679 OSL_ASSERT( (*ppNewDescription)->eTypeClass == pTDR->eTypeClass );
1680 if( pTDR->pType )
1682 if (reallyWeak( pTDR->eTypeClass ))
1684 // pRef->pType->pWeakRef == 0 means that the description is empty
1685 if (pTDR->pType->pWeakRef)
1687 if (osl_incrementInterlockedCount( &pTDR->pType->nRefCount ) > 1)
1689 // The refence is incremented. The object cannot be destroyed.
1690 // Release the guard at the earliest point.
1691 aGuard.clear();
1692 ::typelib_typedescription_release( *ppNewDescription );
1693 *ppNewDescription = pTDR->pType;
1694 ::typelib_typedescriptionreference_release( pTDR );
1695 return;
1697 else
1699 // destruction of this type in progress (another thread!)
1700 osl_decrementInterlockedCount( &pTDR->pType->nRefCount );
1703 // take new descr
1704 pTDR->pType = *ppNewDescription;
1705 OSL_ASSERT( ! (*ppNewDescription)->pWeakRef );
1706 (*ppNewDescription)->pWeakRef = pTDR;
1707 return;
1709 // !reallyWeak
1711 if (((void *)pTDR != (void *)*ppNewDescription) && // if different
1712 (!pTDR->pType->pWeakRef || // uninit: ref data only set
1713 // new one is complete:
1714 (!pTDR->pType->bComplete && (*ppNewDescription)->bComplete) ||
1715 // new one may be partly initialized interface (except of tables):
1716 (typelib_TypeClass_INTERFACE == pTDR->pType->eTypeClass &&
1717 !((typelib_InterfaceTypeDescription *)pTDR->pType)->ppAllMembers &&
1718 (*(typelib_InterfaceTypeDescription **)ppNewDescription)->ppAllMembers)))
1720 // uninitialized or incomplete
1722 if (pTDR->pType->pWeakRef) // if init
1724 typelib_typedescription_destructExtendedMembers( pTDR->pType );
1727 // pTDR->pType->pWeakRef == 0 means that the description is empty
1728 // description is not weak and the not the same
1729 sal_Int32 nSize = getDescriptionSize( (*ppNewDescription)->eTypeClass );
1731 // copy all specific data for the descriptions
1732 ::rtl_copyMemory(
1733 pTDR->pType +1,
1734 *ppNewDescription +1,
1735 nSize - sizeof(typelib_TypeDescription) );
1737 pTDR->pType->bComplete = (*ppNewDescription)->bComplete;
1738 pTDR->pType->nSize = (*ppNewDescription)->nSize;
1739 pTDR->pType->nAlignment = (*ppNewDescription)->nAlignment;
1741 ::rtl_zeroMemory(
1742 *ppNewDescription +1, nSize - sizeof( typelib_TypeDescription ) );
1744 if( pTDR->pType->bOnDemand && !(*ppNewDescription)->bOnDemand )
1746 // switch from OnDemand to !OnDemand, so the description must be acquired
1747 typelib_typedescription_acquire( pTDR->pType );
1749 else if( !pTDR->pType->bOnDemand && (*ppNewDescription)->bOnDemand )
1751 // switch from !OnDemand to OnDemand, so the description must be relesed
1752 typelib_typedescription_release( pTDR->pType );
1755 pTDR->pType->bOnDemand = (*ppNewDescription)->bOnDemand;
1756 // initialized
1757 pTDR->pType->pWeakRef = pTDR;
1760 typelib_typedescription_release( *ppNewDescription );
1761 // pTDR was acquired by getByName(), so it must not be acquired again
1762 *ppNewDescription = pTDR->pType;
1763 return;
1766 else if( reallyWeak( (*ppNewDescription)->eTypeClass) )
1768 typelib_typedescriptionreference_new(
1769 &pTDR, (*ppNewDescription)->eTypeClass, (*ppNewDescription)->pTypeName );
1771 else
1773 pTDR = (typelib_TypeDescriptionReference *)*ppNewDescription;
1774 if( !rInit.pWeakMap )
1775 rInit.pWeakMap = new WeakMap_Impl;
1777 // description is the weak itself, so register it
1778 (*rInit.pWeakMap)[pTDR->pTypeName->buffer] = pTDR;
1779 OSL_ASSERT( (void *)*ppNewDescription == (void *)pTDR );
1782 // By default this reference is not really weak. The reference hold the description
1783 // and the description hold the reference.
1784 if( !(*ppNewDescription)->bOnDemand )
1786 // nor OnDemand so the description must be acquired if registered
1787 typelib_typedescription_acquire( *ppNewDescription );
1790 pTDR->pType = *ppNewDescription;
1791 (*ppNewDescription)->pWeakRef = pTDR;
1792 OSL_ASSERT( rtl_ustr_compare( pTDR->pTypeName->buffer, (*ppNewDescription)->pTypeName->buffer ) == 0 );
1793 OSL_ASSERT( pTDR->eTypeClass == (*ppNewDescription)->eTypeClass );
1796 //------------------------------------------------------------------------
1797 static inline sal_Bool type_equals(
1798 typelib_TypeDescriptionReference * p1, typelib_TypeDescriptionReference * p2 )
1799 SAL_THROW( () )
1801 return (p1 == p2 ||
1802 (p1->eTypeClass == p2->eTypeClass &&
1803 p1->pTypeName->length == p2->pTypeName->length &&
1804 rtl_ustr_compare( p1->pTypeName->buffer, p2->pTypeName->buffer ) == 0));
1806 extern "C" sal_Bool SAL_CALL typelib_typedescription_equals(
1807 const typelib_TypeDescription * p1, const typelib_TypeDescription * p2 )
1808 SAL_THROW_EXTERN_C()
1810 return type_equals(
1811 (typelib_TypeDescriptionReference *)p1, (typelib_TypeDescriptionReference *)p2 );
1814 //------------------------------------------------------------------------
1815 extern "C" sal_Int32 SAL_CALL typelib_typedescription_getAlignedUnoSize(
1816 const typelib_TypeDescription * pTypeDescription,
1817 sal_Int32 nOffset, sal_Int32 & rMaxIntegralTypeSize )
1818 SAL_THROW_EXTERN_C()
1820 sal_Int32 nSize;
1821 if( pTypeDescription->nSize )
1823 // size and alignment are set
1824 rMaxIntegralTypeSize = pTypeDescription->nAlignment;
1825 nSize = pTypeDescription->nSize;
1827 else
1829 nSize = 0;
1830 rMaxIntegralTypeSize = 1;
1832 OSL_ASSERT( typelib_TypeClass_TYPEDEF != pTypeDescription->eTypeClass );
1834 switch( pTypeDescription->eTypeClass )
1836 case typelib_TypeClass_INTERFACE:
1837 // FEATURE_INTERFACE
1838 nSize = rMaxIntegralTypeSize = (sal_Int32)(sizeof( void * ));
1839 break;
1840 case typelib_TypeClass_UNION:
1842 nSize = rMaxIntegralTypeSize = (sal_Int32)(sizeof(sal_Int64));
1843 for ( sal_Int32 nPos = ((typelib_UnionTypeDescription *)pTypeDescription)->nMembers; nPos--; )
1845 typelib_TypeDescription * pTD = 0;
1846 TYPELIB_DANGER_GET( &pTD, ((typelib_UnionTypeDescription *)pTypeDescription)->ppTypeRefs[nPos] );
1847 sal_Int32 nMaxIntegralTypeSize;
1848 sal_Int32 nMemberSize = typelib_typedescription_getAlignedUnoSize( pTD, (sal_Int32)(sizeof(sal_Int64)), nMaxIntegralTypeSize );
1849 TYPELIB_DANGER_RELEASE( pTD );
1850 if (nSize < nMemberSize)
1851 nSize = nMemberSize;
1852 if (rMaxIntegralTypeSize < nMaxIntegralTypeSize)
1853 rMaxIntegralTypeSize = nMaxIntegralTypeSize;
1855 ((typelib_UnionTypeDescription *)pTypeDescription)->nValueOffset = rMaxIntegralTypeSize;
1857 break;
1858 case typelib_TypeClass_ENUM:
1859 nSize = rMaxIntegralTypeSize = (sal_Int32)(sizeof( typelib_TypeClass ));
1860 break;
1861 case typelib_TypeClass_STRUCT:
1862 case typelib_TypeClass_EXCEPTION:
1863 // FEATURE_EMPTYCLASS
1865 typelib_CompoundTypeDescription * pTmp = (typelib_CompoundTypeDescription *)pTypeDescription;
1866 sal_Int32 nStructSize = 0;
1867 if( pTmp->pBaseTypeDescription )
1869 // inherit structs extends the base struct.
1870 nStructSize = pTmp->pBaseTypeDescription->aBase.nSize;
1871 rMaxIntegralTypeSize = pTmp->pBaseTypeDescription->aBase.nAlignment;
1873 for( sal_Int32 i = 0; i < pTmp->nMembers; i++ )
1875 typelib_TypeDescription * pMemberType = 0;
1876 typelib_TypeDescriptionReference * pMemberRef = pTmp->ppTypeRefs[i];
1878 sal_Int32 nMaxIntegral;
1879 if (pMemberRef->eTypeClass == typelib_TypeClass_INTERFACE
1880 || pMemberRef->eTypeClass == typelib_TypeClass_SEQUENCE)
1882 nMaxIntegral = (sal_Int32)(sizeof(void *));
1883 nStructSize = newAlignedSize( nStructSize, nMaxIntegral, nMaxIntegral );
1885 else
1887 TYPELIB_DANGER_GET( &pMemberType, pMemberRef );
1888 nStructSize = typelib_typedescription_getAlignedUnoSize(
1889 pMemberType, nStructSize, nMaxIntegral );
1890 TYPELIB_DANGER_RELEASE( pMemberType );
1892 if( nMaxIntegral > rMaxIntegralTypeSize )
1893 rMaxIntegralTypeSize = nMaxIntegral;
1895 #ifdef __m68k__
1896 // Anything that is at least 16 bits wide is aligned on a 16-bit
1897 // boundary on the m68k default abi
1898 sal_Int32 nMaxAlign = (rMaxIntegralTypeSize > 2) ? 2 : rMaxIntegralTypeSize;
1899 nStructSize = (nStructSize + nMaxAlign -1) / nMaxAlign * nMaxAlign;
1900 #else
1901 // Example: A { double; int; } structure has a size of 16 instead of 10. The
1902 // compiler must follow this rule if it is possible to access members in arrays through:
1903 // (Element *)((char *)pArray + sizeof( Element ) * ElementPos)
1904 nStructSize = (nStructSize + rMaxIntegralTypeSize -1)
1905 / rMaxIntegralTypeSize * rMaxIntegralTypeSize;
1906 #endif
1907 nSize += nStructSize;
1909 break;
1910 case typelib_TypeClass_ARRAY:
1912 typelib_TypeDescription * pTD = 0;
1913 TYPELIB_DANGER_GET( &pTD, ((typelib_IndirectTypeDescription *)pTypeDescription)->pType );
1914 rMaxIntegralTypeSize = pTD->nSize;
1915 TYPELIB_DANGER_RELEASE( pTD );
1916 nSize = ((typelib_ArrayTypeDescription *)pTypeDescription)->nTotalElements * rMaxIntegralTypeSize;
1918 break;
1919 case typelib_TypeClass_SEQUENCE:
1920 nSize = rMaxIntegralTypeSize = (sal_Int32)(sizeof( void * ));
1921 break;
1922 case typelib_TypeClass_ANY:
1923 // FEATURE_ANY
1924 nSize = (sal_Int32)(sizeof( uno_Any ));
1925 rMaxIntegralTypeSize = (sal_Int32)(sizeof( void * ));
1926 break;
1927 case typelib_TypeClass_TYPE:
1928 nSize = rMaxIntegralTypeSize = (sal_Int32)(sizeof( typelib_TypeDescriptionReference * ));
1929 break;
1930 case typelib_TypeClass_BOOLEAN:
1931 nSize = rMaxIntegralTypeSize = (sal_Int32)(sizeof( sal_Bool ));
1932 break;
1933 case typelib_TypeClass_CHAR:
1934 nSize = rMaxIntegralTypeSize = (sal_Int32)(sizeof( sal_Unicode ));
1935 break;
1936 case typelib_TypeClass_STRING:
1937 // FEATURE_STRING
1938 nSize = rMaxIntegralTypeSize = (sal_Int32)(sizeof( rtl_uString * ));
1939 break;
1940 case typelib_TypeClass_FLOAT:
1941 nSize = rMaxIntegralTypeSize = (sal_Int32)(sizeof( float ));
1942 break;
1943 case typelib_TypeClass_DOUBLE:
1944 nSize = rMaxIntegralTypeSize = (sal_Int32)(sizeof( double ));
1945 break;
1946 case typelib_TypeClass_BYTE:
1947 nSize = rMaxIntegralTypeSize = (sal_Int32)(sizeof( sal_Int8 ));
1948 break;
1949 case typelib_TypeClass_SHORT:
1950 case typelib_TypeClass_UNSIGNED_SHORT:
1951 nSize = rMaxIntegralTypeSize = (sal_Int32)(sizeof( sal_Int16 ));
1952 break;
1953 case typelib_TypeClass_LONG:
1954 case typelib_TypeClass_UNSIGNED_LONG:
1955 nSize = rMaxIntegralTypeSize = (sal_Int32)(sizeof( sal_Int32 ));
1956 break;
1957 case typelib_TypeClass_HYPER:
1958 case typelib_TypeClass_UNSIGNED_HYPER:
1959 nSize = rMaxIntegralTypeSize = (sal_Int32)(sizeof( sal_Int64 ));
1960 break;
1961 case typelib_TypeClass_UNKNOWN:
1962 case typelib_TypeClass_SERVICE:
1963 case typelib_TypeClass_MODULE:
1964 default:
1965 OSL_ENSURE( sal_False, "not convertable type" );
1969 return newAlignedSize( nOffset, nSize, rMaxIntegralTypeSize );
1972 //------------------------------------------------------------------------
1974 namespace {
1976 typelib_TypeDescriptionReference ** copyExceptions(
1977 sal_Int32 count, typelib_TypeDescriptionReference ** source)
1979 typelib_TypeDescriptionReference ** p
1980 = new typelib_TypeDescriptionReference *[count];
1981 for (sal_Int32 i = 0; i < count; ++i) {
1982 typelib_typedescriptionreference_acquire(p[i] = source[i]);
1984 return p;
1987 bool createDerivedInterfaceMemberDescription(
1988 typelib_TypeDescription ** result, rtl::OUString const & name,
1989 typelib_TypeDescriptionReference * baseRef,
1990 typelib_TypeDescription const * base, typelib_TypeDescription * interface,
1991 sal_Int32 index, sal_Int32 position)
1993 if (baseRef != 0 && base != 0 && interface != 0) {
1994 switch (base->eTypeClass) {
1995 case typelib_TypeClass_INTERFACE_METHOD:
1997 typelib_typedescription_newEmpty(
1998 result, typelib_TypeClass_INTERFACE_METHOD, name.pData);
1999 typelib_InterfaceMethodTypeDescription const * baseMethod
2000 = reinterpret_cast<
2001 typelib_InterfaceMethodTypeDescription const * >(base);
2002 typelib_InterfaceMethodTypeDescription * newMethod
2003 = reinterpret_cast<
2004 typelib_InterfaceMethodTypeDescription * >(*result);
2005 newMethod->aBase.nPosition = position;
2006 rtl_uString_acquire(
2007 newMethod->aBase.pMemberName
2008 = baseMethod->aBase.pMemberName);
2009 typelib_typedescriptionreference_acquire(
2010 newMethod->pReturnTypeRef = baseMethod->pReturnTypeRef);
2011 newMethod->nParams = baseMethod->nParams;
2012 newMethod->pParams = new typelib_MethodParameter[
2013 newMethod->nParams];
2014 for (sal_Int32 i = 0; i < newMethod->nParams; ++i) {
2015 rtl_uString_acquire(
2016 newMethod->pParams[i].pName
2017 = baseMethod->pParams[i].pName);
2018 typelib_typedescriptionreference_acquire(
2019 newMethod->pParams[i].pTypeRef
2020 = baseMethod->pParams[i].pTypeRef);
2021 newMethod->pParams[i].bIn = baseMethod->pParams[i].bIn;
2022 newMethod->pParams[i].bOut = baseMethod->pParams[i].bOut;
2024 newMethod->nExceptions = baseMethod->nExceptions;
2025 newMethod->ppExceptions = copyExceptions(
2026 baseMethod->nExceptions, baseMethod->ppExceptions);
2027 newMethod->bOneWay = baseMethod->bOneWay;
2028 newMethod->pInterface
2029 = reinterpret_cast< typelib_InterfaceTypeDescription * >(
2030 interface);
2031 newMethod->pBaseRef = baseRef;
2032 newMethod->nIndex = index;
2033 return true;
2036 case typelib_TypeClass_INTERFACE_ATTRIBUTE:
2038 typelib_typedescription_newEmpty(
2039 result, typelib_TypeClass_INTERFACE_ATTRIBUTE, name.pData);
2040 typelib_InterfaceAttributeTypeDescription const * baseAttribute
2041 = reinterpret_cast<
2042 typelib_InterfaceAttributeTypeDescription const * >(base);
2043 typelib_InterfaceAttributeTypeDescription * newAttribute
2044 = reinterpret_cast<
2045 typelib_InterfaceAttributeTypeDescription * >(*result);
2046 newAttribute->aBase.nPosition = position;
2047 rtl_uString_acquire(
2048 newAttribute->aBase.pMemberName
2049 = baseAttribute->aBase.pMemberName);
2050 newAttribute->bReadOnly = baseAttribute->bReadOnly;
2051 typelib_typedescriptionreference_acquire(
2052 newAttribute->pAttributeTypeRef
2053 = baseAttribute->pAttributeTypeRef);
2054 newAttribute->pInterface
2055 = reinterpret_cast< typelib_InterfaceTypeDescription * >(
2056 interface);
2057 newAttribute->pBaseRef = baseRef;
2058 newAttribute->nIndex = index;
2059 newAttribute->nGetExceptions = baseAttribute->nGetExceptions;
2060 newAttribute->ppGetExceptions = copyExceptions(
2061 baseAttribute->nGetExceptions,
2062 baseAttribute->ppGetExceptions);
2063 newAttribute->nSetExceptions = baseAttribute->nSetExceptions;
2064 newAttribute->ppSetExceptions = copyExceptions(
2065 baseAttribute->nSetExceptions,
2066 baseAttribute->ppSetExceptions);
2067 return true;
2070 default:
2071 break;
2074 return false;
2079 extern "C" void SAL_CALL typelib_typedescription_getByName(
2080 typelib_TypeDescription ** ppRet, rtl_uString * pName )
2081 SAL_THROW_EXTERN_C()
2083 if( *ppRet )
2085 typelib_typedescription_release( (*ppRet) );
2086 *ppRet = 0;
2089 static sal_Bool bInited = sal_False;
2090 TypeDescriptor_Init_Impl &rInit = Init::get();
2092 if( !bInited )
2094 // guard against multi thread access
2095 MutexGuard aGuard( rInit.getMutex() );
2096 if( !bInited )
2098 // avoid recursion during the next ...new calls
2099 bInited = sal_True;
2101 rtl_uString * pTypeName = 0;
2102 typelib_TypeDescription * pType = 0;
2103 rtl_uString_newFromAscii( &pTypeName, "type" );
2104 typelib_typedescription_new( &pType, typelib_TypeClass_TYPE, pTypeName, 0, 0, 0 );
2105 typelib_typedescription_register( &pType );
2106 rtl_uString_newFromAscii( &pTypeName, "void" );
2107 typelib_typedescription_new( &pType, typelib_TypeClass_VOID, pTypeName, 0, 0, 0 );
2108 typelib_typedescription_register( &pType );
2109 rtl_uString_newFromAscii( &pTypeName, "boolean" );
2110 typelib_typedescription_new( &pType, typelib_TypeClass_BOOLEAN, pTypeName, 0, 0, 0 );
2111 typelib_typedescription_register( &pType );
2112 rtl_uString_newFromAscii( &pTypeName, "char" );
2113 typelib_typedescription_new( &pType, typelib_TypeClass_CHAR, pTypeName, 0, 0, 0 );
2114 typelib_typedescription_register( &pType );
2115 rtl_uString_newFromAscii( &pTypeName, "byte" );
2116 typelib_typedescription_new( &pType, typelib_TypeClass_BYTE, pTypeName, 0, 0, 0 );
2117 typelib_typedescription_register( &pType );
2118 rtl_uString_newFromAscii( &pTypeName, "string" );
2119 typelib_typedescription_new( &pType, typelib_TypeClass_STRING, pTypeName, 0, 0, 0 );
2120 typelib_typedescription_register( &pType );
2121 rtl_uString_newFromAscii( &pTypeName, "short" );
2122 typelib_typedescription_new( &pType, typelib_TypeClass_SHORT, pTypeName, 0, 0, 0 );
2123 typelib_typedescription_register( &pType );
2124 rtl_uString_newFromAscii( &pTypeName, "unsigned short" );
2125 typelib_typedescription_new( &pType, typelib_TypeClass_UNSIGNED_SHORT, pTypeName, 0, 0, 0 );
2126 typelib_typedescription_register( &pType );
2127 rtl_uString_newFromAscii( &pTypeName, "long" );
2128 typelib_typedescription_new( &pType, typelib_TypeClass_LONG, pTypeName, 0, 0, 0 );
2129 typelib_typedescription_register( &pType );
2130 rtl_uString_newFromAscii( &pTypeName, "unsigned long" );
2131 typelib_typedescription_new( &pType, typelib_TypeClass_UNSIGNED_LONG, pTypeName, 0, 0, 0 );
2132 typelib_typedescription_register( &pType );
2133 rtl_uString_newFromAscii( &pTypeName, "hyper" );
2134 typelib_typedescription_new( &pType, typelib_TypeClass_HYPER, pTypeName, 0, 0, 0 );
2135 typelib_typedescription_register( &pType );
2136 rtl_uString_newFromAscii( &pTypeName, "unsigned hyper" );
2137 typelib_typedescription_new( &pType, typelib_TypeClass_UNSIGNED_HYPER, pTypeName, 0, 0, 0 );
2138 typelib_typedescription_register( &pType );
2139 rtl_uString_newFromAscii( &pTypeName, "float" );
2140 typelib_typedescription_new( &pType, typelib_TypeClass_FLOAT, pTypeName, 0, 0, 0 );
2141 typelib_typedescription_register( &pType );
2142 rtl_uString_newFromAscii( &pTypeName, "double" );
2143 typelib_typedescription_new( &pType, typelib_TypeClass_DOUBLE, pTypeName, 0, 0, 0 );
2144 typelib_typedescription_register( &pType );
2145 rtl_uString_newFromAscii( &pTypeName, "any" );
2146 typelib_typedescription_new( &pType, typelib_TypeClass_ANY, pTypeName, 0, 0, 0 );
2147 typelib_typedescription_register( &pType );
2148 typelib_typedescription_release( pType );
2149 rtl_uString_release( pTypeName );
2153 typelib_TypeDescriptionReference * pTDR = 0;
2154 typelib_typedescriptionreference_getByName( &pTDR, pName );
2155 if( pTDR )
2158 // guard against multi thread access
2159 MutexGuard aGuard( rInit.getMutex() );
2160 // pTDR->pType->pWeakRef == 0 means that the description is empty
2161 if( pTDR->pType && pTDR->pType->pWeakRef )
2163 typelib_typedescription_acquire( pTDR->pType );
2164 *ppRet = pTDR->pType;
2167 typelib_typedescriptionreference_release( pTDR );
2170 if (0 == *ppRet)
2172 // check for sequence
2173 OUString const & name = *reinterpret_cast< OUString const * >( &pName );
2174 if (2 < name.getLength() && '[' == name[ 0 ])
2176 OUString element_name( name.copy( 2 ) );
2177 typelib_TypeDescription * element_td = 0;
2178 typelib_typedescription_getByName( &element_td, element_name.pData );
2179 if (0 != element_td)
2181 typelib_typedescription_new(
2182 ppRet, typelib_TypeClass_SEQUENCE, pName, element_td->pWeakRef, 0, 0 );
2183 // register?
2184 typelib_typedescription_release( element_td );
2187 if (0 == *ppRet)
2189 // Check for derived interface member type:
2190 sal_Int32 i1 = name.lastIndexOf(
2191 rtl::OUString::createFromAscii(":@"));
2192 if (i1 >= 0) {
2193 sal_Int32 i2 = i1 + RTL_CONSTASCII_LENGTH(":@");
2194 sal_Int32 i3 = name.indexOf(',', i2);
2195 if (i3 >= 0) {
2196 sal_Int32 i4 = name.indexOf(':', i3);
2197 if (i4 >= 0) {
2198 typelib_TypeDescriptionReference * pBaseRef = 0;
2199 typelib_TypeDescription * pBase = 0;
2200 typelib_TypeDescription * pInterface = 0;
2201 typelib_typedescriptionreference_getByName(
2202 &pBaseRef, name.copy(0, i1).pData);
2203 if (pBaseRef != 0) {
2204 typelib_typedescriptionreference_getDescription(
2205 &pBase, pBaseRef);
2207 typelib_typedescription_getByName(
2208 &pInterface, name.copy(i4 + 1).pData);
2209 if (!createDerivedInterfaceMemberDescription(
2210 ppRet, name, pBaseRef, pBase, pInterface,
2211 name.copy(i2, i3 - i2).toInt32(),
2212 name.copy(i3 + 1, i4 - i3 - 1).toInt32()))
2214 if (pInterface != 0) {
2215 typelib_typedescription_release(pInterface);
2217 if (pBase != 0) {
2218 typelib_typedescription_release(pBase);
2220 if (pBaseRef != 0) {
2221 typelib_typedescriptionreference_release(
2222 pBaseRef);
2229 if (0 == *ppRet)
2231 // on demand access
2232 rInit.callChain( ppRet, pName );
2235 if( *ppRet )
2237 // typedescription found
2238 if (typelib_TypeClass_TYPEDEF == (*ppRet)->eTypeClass)
2240 typelib_TypeDescription * pTD = 0;
2241 typelib_typedescriptionreference_getDescription(
2242 &pTD, ((typelib_IndirectTypeDescription *)*ppRet)->pType );
2243 typelib_typedescription_release( *ppRet );
2244 *ppRet = pTD;
2246 else
2248 // set to on demand
2249 (*ppRet)->bOnDemand = sal_True;
2250 // The type description is hold by the reference until
2251 // on demand is activated.
2252 typelib_typedescription_register( ppRet );
2254 // insert into the chache
2255 MutexGuard aGuard( rInit.getMutex() );
2256 if( !rInit.pCache )
2257 rInit.pCache = new TypeDescriptionList_Impl;
2258 if( (sal_Int32)rInit.pCache->size() >= nCacheSize )
2260 typelib_typedescription_release( rInit.pCache->front() );
2261 rInit.pCache->pop_front();
2263 // descriptions in the cache must be acquired!
2264 typelib_typedescription_acquire( *ppRet );
2265 rInit.pCache->push_back( *ppRet );
2272 //------------------------------------------------------------------------
2273 //------------------------------------------------------------------------
2274 //------------------------------------------------------------------------
2275 extern "C" void SAL_CALL typelib_typedescriptionreference_newByAsciiName(
2276 typelib_TypeDescriptionReference ** ppTDR,
2277 typelib_TypeClass eTypeClass,
2278 const sal_Char * pTypeName )
2279 SAL_THROW_EXTERN_C()
2281 OUString aTypeName( OUString::createFromAscii( pTypeName ) );
2282 typelib_typedescriptionreference_new( ppTDR, eTypeClass, aTypeName.pData );
2284 //------------------------------------------------------------------------
2285 extern "C" void SAL_CALL typelib_typedescriptionreference_new(
2286 typelib_TypeDescriptionReference ** ppTDR,
2287 typelib_TypeClass eTypeClass, rtl_uString * pTypeName )
2288 SAL_THROW_EXTERN_C()
2290 TypeDescriptor_Init_Impl &rInit = Init::get();
2291 if( eTypeClass == typelib_TypeClass_TYPEDEF )
2293 // on demand access
2294 typelib_TypeDescription * pRet = 0;
2295 rInit.callChain( &pRet, pTypeName );
2296 if( pRet )
2298 // typedescription found
2299 if (typelib_TypeClass_TYPEDEF == pRet->eTypeClass)
2301 typelib_typedescriptionreference_acquire(
2302 ((typelib_IndirectTypeDescription *)pRet)->pType );
2303 if (*ppTDR)
2304 typelib_typedescriptionreference_release( *ppTDR );
2305 *ppTDR = ((typelib_IndirectTypeDescription *)pRet)->pType;
2306 typelib_typedescription_release( pRet );
2308 else
2310 // set to on demand
2311 pRet->bOnDemand = sal_True;
2312 // The type description is hold by the reference until
2313 // on demand is activated.
2314 typelib_typedescription_register( &pRet );
2316 // insert into the chache
2317 MutexGuard aGuard( rInit.getMutex() );
2318 if( !rInit.pCache )
2319 rInit.pCache = new TypeDescriptionList_Impl;
2320 if( (sal_Int32)rInit.pCache->size() >= nCacheSize )
2322 typelib_typedescription_release( rInit.pCache->front() );
2323 rInit.pCache->pop_front();
2325 rInit.pCache->push_back( pRet );
2326 // pRet kept acquired for cache
2328 typelib_typedescriptionreference_acquire( pRet->pWeakRef );
2329 if (*ppTDR)
2330 typelib_typedescriptionreference_release( *ppTDR );
2331 *ppTDR = pRet->pWeakRef;
2334 else if (*ppTDR)
2336 #if OSL_DEBUG_LEVEL > 1
2337 OString aStr( OUStringToOString( pTypeName, RTL_TEXTENCODING_ASCII_US ) );
2338 OSL_ENSURE( !"### typedef not found: ", aStr.getStr() );
2339 #endif
2340 typelib_typedescriptionreference_release( *ppTDR );
2341 *ppTDR = 0;
2343 return;
2346 MutexGuard aGuard( rInit.getMutex() );
2347 typelib_typedescriptionreference_getByName( ppTDR, pTypeName );
2348 if( *ppTDR )
2349 return;
2351 if( reallyWeak( eTypeClass ) )
2353 typelib_TypeDescriptionReference * pTDR = new typelib_TypeDescriptionReference();
2354 #if OSL_DEBUG_LEVEL > 1
2355 osl_incrementInterlockedCount( &rInit.nTypeDescriptionReferenceCount );
2356 #endif
2357 pTDR->nRefCount = 1;
2358 pTDR->nStaticRefCount = 0;
2359 pTDR->eTypeClass = eTypeClass;
2360 pTDR->pUniqueIdentifier = 0;
2361 pTDR->pReserved = 0;
2362 rtl_uString_acquire( pTDR->pTypeName = pTypeName );
2363 pTDR->pType = 0;
2364 *ppTDR = pTDR;
2366 else
2368 typelib_typedescription_newEmpty( (typelib_TypeDescription ** )ppTDR, eTypeClass, pTypeName );
2369 // description will be registered but not acquired
2370 (*(typelib_TypeDescription ** )ppTDR)->bOnDemand = sal_True;
2371 (*(typelib_TypeDescription ** )ppTDR)->bComplete = sal_False;
2374 if( !rInit.pWeakMap )
2375 rInit.pWeakMap = new WeakMap_Impl;
2376 // Heavy hack, the const sal_Unicode * is hold by the typedescription reference
2377 // not registered
2378 rInit.pWeakMap->operator[]( (*ppTDR)->pTypeName->buffer ) = *ppTDR;
2381 //------------------------------------------------------------------------
2382 extern "C" void SAL_CALL typelib_typedescriptionreference_acquire(
2383 typelib_TypeDescriptionReference * pRef )
2384 SAL_THROW_EXTERN_C()
2386 ::osl_incrementInterlockedCount( &pRef->nRefCount );
2389 //------------------------------------------------------------------------
2390 extern "C" void SAL_CALL typelib_typedescriptionreference_release(
2391 typelib_TypeDescriptionReference * pRef )
2392 SAL_THROW_EXTERN_C()
2394 // Is it a type description?
2395 if( reallyWeak( pRef->eTypeClass ) )
2397 if( ! ::osl_decrementInterlockedCount( &pRef->nRefCount ) )
2399 TypeDescriptor_Init_Impl &rInit = Init::get();
2400 if( rInit.pWeakMap )
2402 MutexGuard aGuard( rInit.getMutex() );
2403 WeakMap_Impl::iterator aIt = rInit.pWeakMap->find( (sal_Unicode*)pRef->pTypeName->buffer );
2404 if( !(aIt == rInit.pWeakMap->end()) && (*aIt).second == pRef )
2406 // remove only if it contains the same object
2407 rInit.pWeakMap->erase( aIt );
2411 rtl_uString_release( pRef->pTypeName );
2412 OSL_ASSERT( pRef->pType == 0 );
2413 #if OSL_DEBUG_LEVEL > 1
2414 osl_decrementInterlockedCount( &rInit.nTypeDescriptionReferenceCount );
2415 #endif
2416 delete pRef;
2419 else
2421 typelib_typedescription_release( (typelib_TypeDescription *)pRef );
2425 //------------------------------------------------------------------------
2426 extern "C" void SAL_CALL typelib_typedescriptionreference_getDescription(
2427 typelib_TypeDescription ** ppRet, typelib_TypeDescriptionReference * pRef )
2428 SAL_THROW_EXTERN_C()
2430 if( *ppRet )
2432 typelib_typedescription_release( *ppRet );
2433 *ppRet = 0;
2436 if( !reallyWeak( pRef->eTypeClass ) && pRef->pType && pRef->pType->pWeakRef )
2438 // reference is a description and initialized
2439 osl_incrementInterlockedCount( &((typelib_TypeDescription *)pRef)->nRefCount );
2440 *ppRet = (typelib_TypeDescription *)pRef;
2441 return;
2445 MutexGuard aGuard( Init::get().getMutex() );
2446 // pRef->pType->pWeakRef == 0 means that the description is empty
2447 if( pRef->pType && pRef->pType->pWeakRef )
2449 sal_Int32 n = ::osl_incrementInterlockedCount( &pRef->pType->nRefCount );
2450 if( n > 1 )
2452 // The refence is incremented. The object cannot be destroyed.
2453 // Release the guard at the earliest point.
2454 *ppRet = pRef->pType;
2455 return;
2457 else
2459 ::osl_decrementInterlockedCount( &pRef->pType->nRefCount );
2460 // detruction of this type in progress (another thread!)
2461 // no acces through this weak reference
2462 pRef->pType = 0;
2467 typelib_typedescription_getByName( ppRet, pRef->pTypeName );
2468 OSL_ASSERT( !*ppRet || rtl_ustr_compare( pRef->pTypeName->buffer, (*ppRet)->pTypeName->buffer ) == 0 );
2469 OSL_ASSERT( !*ppRet || pRef->eTypeClass == (*ppRet)->eTypeClass );
2470 OSL_ASSERT( !*ppRet || pRef == (*ppRet)->pWeakRef );
2471 pRef->pType = *ppRet;
2474 //------------------------------------------------------------------------
2475 extern "C" void SAL_CALL typelib_typedescriptionreference_getByName(
2476 typelib_TypeDescriptionReference ** ppRet, rtl_uString * pName )
2477 SAL_THROW_EXTERN_C()
2479 if( *ppRet )
2481 typelib_typedescriptionreference_release( *ppRet );
2482 *ppRet = 0;
2484 TypeDescriptor_Init_Impl &rInit = Init::get();
2485 if( rInit.pWeakMap )
2487 MutexGuard aGuard( rInit.getMutex() );
2488 WeakMap_Impl::const_iterator aIt = rInit.pWeakMap->find( (sal_Unicode*)pName->buffer );
2489 if( !(aIt == rInit.pWeakMap->end()) ) // != failed on msc4.2
2491 sal_Int32 n = ::osl_incrementInterlockedCount( &(*aIt).second->nRefCount );
2492 if( n > 1 )
2494 // The refence is incremented. The object cannot be destroyed.
2495 // Release the guard at the earliest point.
2496 *ppRet = (*aIt).second;
2498 else
2500 // detruction of this type in progress (another thread!)
2501 // no acces through this weak reference
2502 ::osl_decrementInterlockedCount( &(*aIt).second->nRefCount );
2508 //------------------------------------------------------------------------
2509 extern "C" sal_Bool SAL_CALL typelib_typedescriptionreference_equals(
2510 const typelib_TypeDescriptionReference * p1,
2511 const typelib_TypeDescriptionReference * p2 )
2512 SAL_THROW_EXTERN_C()
2514 return (p1 == p2 ||
2515 (p1->eTypeClass == p2->eTypeClass &&
2516 p1->pTypeName->length == p2->pTypeName->length &&
2517 rtl_ustr_compare( p1->pTypeName->buffer, p2->pTypeName->buffer ) == 0));
2520 //##################################################################################################
2521 extern "C" void SAL_CALL typelib_typedescriptionreference_assign(
2522 typelib_TypeDescriptionReference ** ppDest,
2523 typelib_TypeDescriptionReference * pSource )
2524 SAL_THROW_EXTERN_C()
2526 if (*ppDest != pSource)
2528 ::typelib_typedescriptionreference_acquire( pSource );
2529 ::typelib_typedescriptionreference_release( *ppDest );
2530 *ppDest = pSource;
2534 //##################################################################################################
2535 extern "C" void SAL_CALL typelib_setCacheSize( sal_Int32 nNewSize )
2536 SAL_THROW_EXTERN_C()
2538 OSL_ENSURE( nNewSize >= 0, "### illegal cache size given!" );
2539 if (nNewSize >= 0)
2541 TypeDescriptor_Init_Impl &rInit = Init::get();
2542 MutexGuard aGuard( rInit.getMutex() );
2543 if ((nNewSize < nCacheSize) && rInit.pCache)
2545 while ((sal_Int32)rInit.pCache->size() != nNewSize)
2547 typelib_typedescription_release( rInit.pCache->front() );
2548 rInit.pCache->pop_front();
2551 nCacheSize = nNewSize;
2556 static sal_Bool s_aAssignableFromTab[11][11] =
2558 /* from CH,BO,BY,SH,US,LO,UL,HY,UH,FL,DO */
2559 /* TypeClass_CHAR */ { 1, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0 },
2560 /* TypeClass_BOOLEAN */ { 0, 1, 0, 0, 0, 0, 0, 0, 0, 0, 0 },
2561 /* TypeClass_BYTE */ { 0, 0, 1, 0, 0, 0, 0, 0, 0, 0, 0 },
2562 /* TypeClass_SHORT */ { 0, 0, 1, 1, 1, 0, 0, 0, 0, 0, 0 },
2563 /* TypeClass_UNSIGNED_SHORT */ { 0, 0, 1, 1, 1, 0, 0, 0, 0, 0, 0 },
2564 /* TypeClass_LONG */ { 0, 0, 1, 1, 1, 1, 1, 0, 0, 0, 0 },
2565 /* TypeClass_UNSIGNED_LONG */ { 0, 0, 1, 1, 1, 1, 1, 0, 0, 0, 0 },
2566 /* TypeClass_HYPER */ { 0, 0, 1, 1, 1, 1, 1, 1, 1, 0, 0 },
2567 /* TypeClass_UNSIGNED_HYPER */ { 0, 0, 1, 1, 1, 1, 1, 1, 1, 0, 0 },
2568 /* TypeClass_FLOAT */ { 0, 0, 1, 1, 1, 0, 0, 0, 0, 1, 0 },
2569 /* TypeClass_DOUBLE */ { 0, 0, 1, 1, 1, 1, 1, 0, 0, 1, 1 }
2572 //##################################################################################################
2573 extern "C" sal_Bool SAL_CALL typelib_typedescriptionreference_isAssignableFrom(
2574 typelib_TypeDescriptionReference * pAssignable,
2575 typelib_TypeDescriptionReference * pFrom )
2576 SAL_THROW_EXTERN_C()
2578 if (pAssignable && pFrom)
2580 typelib_TypeClass eAssignable = pAssignable->eTypeClass;
2581 typelib_TypeClass eFrom = pFrom->eTypeClass;
2583 if (eAssignable == typelib_TypeClass_ANY) // anything can be assigned to an any .)
2584 return sal_True;
2585 if (eAssignable == eFrom)
2587 if (type_equals( pAssignable, pFrom )) // first shot
2589 return sal_True;
2591 else
2593 switch (eAssignable)
2595 case typelib_TypeClass_STRUCT:
2596 case typelib_TypeClass_EXCEPTION:
2598 typelib_TypeDescription * pFromDescr = 0;
2599 TYPELIB_DANGER_GET( &pFromDescr, pFrom );
2600 if (! ((typelib_CompoundTypeDescription *)pFromDescr)->pBaseTypeDescription)
2602 TYPELIB_DANGER_RELEASE( pFromDescr );
2603 return sal_False;
2605 sal_Bool bRet = typelib_typedescriptionreference_isAssignableFrom(
2606 pAssignable,
2607 ((typelib_TypeDescription *)((typelib_CompoundTypeDescription *)pFromDescr)->pBaseTypeDescription)->pWeakRef );
2608 TYPELIB_DANGER_RELEASE( pFromDescr );
2609 return bRet;
2611 case typelib_TypeClass_INTERFACE:
2613 typelib_TypeDescription * pFromDescr = 0;
2614 TYPELIB_DANGER_GET( &pFromDescr, pFrom );
2615 typelib_InterfaceTypeDescription * pFromIfc
2616 = reinterpret_cast<
2617 typelib_InterfaceTypeDescription * >(pFromDescr);
2618 bool bRet = false;
2619 for (sal_Int32 i = 0; i < pFromIfc->nBaseTypes; ++i) {
2620 if (typelib_typedescriptionreference_isAssignableFrom(
2621 pAssignable,
2622 pFromIfc->ppBaseTypes[i]->aBase.pWeakRef))
2624 bRet = true;
2625 break;
2628 TYPELIB_DANGER_RELEASE( pFromDescr );
2629 return bRet;
2631 default:
2633 return sal_False;
2638 return (eAssignable >= typelib_TypeClass_CHAR && eAssignable <= typelib_TypeClass_DOUBLE &&
2639 eFrom >= typelib_TypeClass_CHAR && eFrom <= typelib_TypeClass_DOUBLE &&
2640 s_aAssignableFromTab[eAssignable-1][eFrom-1]);
2642 return sal_False;
2644 //##################################################################################################
2645 extern "C" sal_Bool SAL_CALL typelib_typedescription_isAssignableFrom(
2646 typelib_TypeDescription * pAssignable,
2647 typelib_TypeDescription * pFrom )
2648 SAL_THROW_EXTERN_C()
2650 return typelib_typedescriptionreference_isAssignableFrom(
2651 pAssignable->pWeakRef, pFrom->pWeakRef );
2654 //##################################################################################################
2655 extern "C" sal_Bool SAL_CALL typelib_typedescription_complete(
2656 typelib_TypeDescription ** ppTypeDescr )
2657 SAL_THROW_EXTERN_C()
2659 return complete(ppTypeDescr, true);