merge the formfield patch from ooo-build
[ooovba.git] / cppu / source / typelib / typelib.cxx
blob6377d57266295e92884836fd78883e95cfe5c043
1 /*************************************************************************
3 * DO NOT ALTER OR REMOVE COPYRIGHT NOTICES OR THIS FILE HEADER.
4 *
5 * Copyright 2008 by Sun Microsystems, Inc.
7 * OpenOffice.org - a multi-platform office productivity suite
9 * $RCSfile: typelib.cxx,v $
10 * $Revision: 1.35.6.1 $
12 * This file is part of OpenOffice.org.
14 * OpenOffice.org is free software: you can redistribute it and/or modify
15 * it under the terms of the GNU Lesser General Public License version 3
16 * only, as published by the Free Software Foundation.
18 * OpenOffice.org is distributed in the hope that it will be useful,
19 * but WITHOUT ANY WARRANTY; without even the implied warranty of
20 * MERCHANTABILITY or FITNESS FOR A PARTICULAR PURPOSE. See the
21 * GNU Lesser General Public License version 3 for more details
22 * (a copy is included in the LICENSE file that accompanied this code).
24 * You should have received a copy of the GNU Lesser General Public License
25 * version 3 along with OpenOffice.org. If not, see
26 * <http://www.openoffice.org/license.html>
27 * for a copy of the LGPLv3 License.
29 ************************************************************************/
31 // MARKER(update_precomp.py): autogen include statement, do not remove
32 #include "precompiled_cppu.hxx"
34 #include <hash_map>
35 #include <list>
36 #include <set>
37 #include <vector>
39 #include <stdarg.h>
40 #include <stdlib.h>
41 #include <string.h>
42 #include <sal/alloca.h>
43 #include <new>
44 #include <osl/interlck.h>
45 #include <osl/mutex.hxx>
46 #include <rtl/ustring.hxx>
47 #include <rtl/ustrbuf.hxx>
48 #include <rtl/alloc.h>
49 #include <rtl/instance.hxx>
50 #include <osl/diagnose.h>
51 #include <typelib/typedescription.h>
52 #include <uno/any2.h>
54 using namespace rtl;
55 using namespace std;
56 using namespace osl;
59 //------------------------------------------------------------------------
60 //------------------------------------------------------------------------
61 #ifdef SAL_W32
62 #pragma pack(push, 8)
63 #elif defined(SAL_OS2)
64 #pragma pack(8)
65 #endif
67 /**
68 * The double member determin the alignment.
69 * Under Os2 and MS-Windows the Alignment is min( 8, sizeof( type ) ).
70 * The aligment of a strukture is min( 8, sizeof( max basic type ) ), the greatest basic type
71 * determine the aligment.
73 struct AlignSize_Impl
75 sal_Int16 nInt16;
76 double dDouble;
79 #ifdef SAL_W32
80 #pragma pack(pop)
81 #elif defined(SAL_OS2)
82 #pragma pack()
83 #endif
85 // the value of the maximal alignment
86 static sal_Int32 nMaxAlignment = (sal_Int32)( (sal_Size)(&((AlignSize_Impl *) 16)->dDouble) - 16);
88 static inline sal_Int32 adjustAlignment( sal_Int32 nRequestedAlignment )
89 SAL_THROW( () )
91 if( nRequestedAlignment > nMaxAlignment )
92 nRequestedAlignment = nMaxAlignment;
93 return nRequestedAlignment;
96 /**
97 * Calculate the new size of the struktur.
99 static inline sal_Int32 newAlignedSize(
100 sal_Int32 OldSize, sal_Int32 ElementSize, sal_Int32 NeededAlignment )
101 SAL_THROW( () )
103 NeededAlignment = adjustAlignment( NeededAlignment );
104 return (OldSize + NeededAlignment -1) / NeededAlignment * NeededAlignment + ElementSize;
107 static inline sal_Bool reallyWeak( typelib_TypeClass eTypeClass )
108 SAL_THROW( () )
110 return TYPELIB_TYPEDESCRIPTIONREFERENCE_ISREALLYWEAK( eTypeClass );
113 static inline sal_Int32 getDescriptionSize( typelib_TypeClass eTypeClass )
114 SAL_THROW( () )
116 OSL_ASSERT( typelib_TypeClass_TYPEDEF != eTypeClass );
118 sal_Int32 nSize;
119 // The reference is the description
120 // if the description is empty, than it must be filled with
121 // the new description
122 switch( eTypeClass )
124 case typelib_TypeClass_ARRAY:
125 nSize = (sal_Int32)sizeof( typelib_ArrayTypeDescription );
126 break;
128 case typelib_TypeClass_SEQUENCE:
129 nSize = (sal_Int32)sizeof( typelib_IndirectTypeDescription );
130 break;
132 case typelib_TypeClass_UNION:
133 nSize = (sal_Int32)sizeof( typelib_UnionTypeDescription );
134 break;
136 case typelib_TypeClass_STRUCT:
137 nSize = (sal_Int32)sizeof( typelib_StructTypeDescription );
138 break;
140 case typelib_TypeClass_EXCEPTION:
141 nSize = (sal_Int32)sizeof( typelib_CompoundTypeDescription );
142 break;
144 case typelib_TypeClass_ENUM:
145 nSize = (sal_Int32)sizeof( typelib_EnumTypeDescription );
146 break;
148 case typelib_TypeClass_INTERFACE:
149 nSize = (sal_Int32)sizeof( typelib_InterfaceTypeDescription );
150 break;
152 case typelib_TypeClass_INTERFACE_METHOD:
153 nSize = (sal_Int32)sizeof( typelib_InterfaceMethodTypeDescription );
154 break;
156 case typelib_TypeClass_INTERFACE_ATTRIBUTE:
157 nSize = (sal_Int32)sizeof( typelib_InterfaceAttributeTypeDescription );
158 break;
160 default:
161 nSize = (sal_Int32)sizeof( typelib_TypeDescription );
163 return nSize;
167 //-----------------------------------------------------------------------------
168 extern "C" void SAL_CALL typelib_typedescriptionreference_getByName(
169 typelib_TypeDescriptionReference ** ppRet, rtl_uString * pName )
170 SAL_THROW_EXTERN_C();
172 //-----------------------------------------------------------------------------
173 struct equalStr_Impl
175 sal_Bool operator()(const sal_Unicode * const & s1, const sal_Unicode * const & s2) const SAL_THROW( () )
176 { return 0 == rtl_ustr_compare( s1, s2 ); }
179 //-----------------------------------------------------------------------------
180 struct hashStr_Impl
182 size_t operator()(const sal_Unicode * const & s) const SAL_THROW( () )
183 { return rtl_ustr_hashCode( s ); }
187 //-----------------------------------------------------------------------------
188 // Heavy hack, the const sal_Unicode * is hold by the typedescription reference
189 typedef hash_map< const sal_Unicode *, typelib_TypeDescriptionReference *,
190 hashStr_Impl, equalStr_Impl > WeakMap_Impl;
192 typedef pair< void *, typelib_typedescription_Callback > CallbackEntry;
193 typedef list< CallbackEntry > CallbackSet_Impl;
194 typedef list< typelib_TypeDescription * > TypeDescriptionList_Impl;
196 // # of cached elements
197 static sal_Int32 nCacheSize = 256;
199 //-----------------------------------------------------------------------------
201 * All members must set initial to 0 and no constructor is needed. So it
202 * doesn't care, when this class is static initialized.<BR>
204 struct TypeDescriptor_Init_Impl
206 //sal_Bool bDesctructorCalled;
207 // all type description references
208 WeakMap_Impl * pWeakMap;
209 // all type description callbacks
210 CallbackSet_Impl * pCallbacks;
211 // A cache to hold descriptions
212 TypeDescriptionList_Impl * pCache;
213 // The mutex to guard all type library accesses
214 Mutex * pMutex;
216 inline Mutex & getMutex() SAL_THROW( () );
218 inline void callChain( typelib_TypeDescription ** ppRet, rtl_uString * pName ) SAL_THROW( () );
220 #if OSL_DEBUG_LEVEL > 1
221 // only for debugging
222 sal_Int32 nTypeDescriptionCount;
223 sal_Int32 nCompoundTypeDescriptionCount;
224 sal_Int32 nUnionTypeDescriptionCount;
225 sal_Int32 nIndirectTypeDescriptionCount;
226 sal_Int32 nArrayTypeDescriptionCount;
227 sal_Int32 nEnumTypeDescriptionCount;
228 sal_Int32 nInterfaceMethodTypeDescriptionCount;
229 sal_Int32 nInterfaceAttributeTypeDescriptionCount;
230 sal_Int32 nInterfaceTypeDescriptionCount;
231 sal_Int32 nTypeDescriptionReferenceCount;
232 #endif
233 ~TypeDescriptor_Init_Impl() SAL_THROW( () );
235 //__________________________________________________________________________________________________
236 inline Mutex & TypeDescriptor_Init_Impl::getMutex() SAL_THROW( () )
238 if( !pMutex )
240 MutexGuard aGuard( Mutex::getGlobalMutex() );
241 if( !pMutex )
242 pMutex = new Mutex();
244 return * pMutex;
246 //__________________________________________________________________________________________________
247 inline void TypeDescriptor_Init_Impl::callChain(
248 typelib_TypeDescription ** ppRet, rtl_uString * pName )
249 SAL_THROW( () )
251 if (pCallbacks)
253 CallbackSet_Impl::const_iterator aIt = pCallbacks->begin();
254 while( aIt != pCallbacks->end() )
256 const CallbackEntry & rEntry = *aIt;
257 (*rEntry.second)( rEntry.first, ppRet, pName );
258 if( *ppRet )
259 return;
260 ++aIt;
263 if (*ppRet)
265 typelib_typedescription_release( *ppRet );
266 *ppRet = 0;
270 // never called
271 #if defined(CPPU_LEAK_STATIC_DATA) && defined(__SUNPRO_CC) && (__SUNPRO_CC == 0x500)
272 static void dumb_sunpro5_must_have_dtor_stl_hashmap_code_if_compiled_with_minus_g() SAL_THROW( () )
274 delete (WeakMap_Impl *)0xbeef1e;
276 #endif
277 //__________________________________________________________________________________________________
278 TypeDescriptor_Init_Impl::~TypeDescriptor_Init_Impl() SAL_THROW( () )
280 #ifndef CPPU_LEAK_STATIC_DATA
281 if( pCache )
283 TypeDescriptionList_Impl::const_iterator aIt = pCache->begin();
284 while( aIt != pCache->end() )
286 typelib_typedescription_release( (*aIt) );
287 aIt++;
289 delete pCache;
290 pCache = 0;
293 if( pWeakMap )
295 sal_Int32 nSize = pWeakMap->size();
296 typelib_TypeDescriptionReference ** ppTDR = new typelib_TypeDescriptionReference *[ nSize ];
297 // save al weak references
298 WeakMap_Impl::const_iterator aIt = pWeakMap->begin();
299 sal_Int32 i = 0;
300 while( aIt != pWeakMap->end() )
302 typelib_typedescriptionreference_acquire( ppTDR[i++] = (*aIt).second );
303 ++aIt;
306 for( i = 0; i < nSize; i++ )
308 typelib_TypeDescriptionReference * pTDR = ppTDR[i];
309 sal_Int32 nStaticCounts = pTDR->nStaticRefCount;
310 OSL_ASSERT( pTDR->nRefCount > pTDR->nStaticRefCount );
311 pTDR->nRefCount -= pTDR->nStaticRefCount;
313 if( pTDR->pType && !pTDR->pType->bOnDemand )
315 pTDR->pType->bOnDemand = sal_True;
316 typelib_typedescription_release( pTDR->pType );
318 typelib_typedescriptionreference_release( pTDR );
321 delete [] ppTDR;
323 #if OSL_DEBUG_LEVEL > 1
324 aIt = pWeakMap->begin();
325 while( aIt != pWeakMap->end() )
327 typelib_TypeDescriptionReference * pTDR = (*aIt).second;
328 if (pTDR)
330 OString aTypeName( OUStringToOString( pTDR->pTypeName, RTL_TEXTENCODING_ASCII_US ) );
331 OSL_TRACE(
332 "### remaining type: %s; ref count = %d", aTypeName.getStr(), pTDR->nRefCount );
334 else
336 OSL_TRACE( "### remaining null type entry!?" );
338 ++aIt;
340 #endif
342 delete pWeakMap;
343 pWeakMap = 0;
345 #if OSL_DEBUG_LEVEL > 1
346 OSL_ASSERT( nTypeDescriptionCount == 0 );
347 OSL_ASSERT( nCompoundTypeDescriptionCount == 0 );
348 OSL_ASSERT( nUnionTypeDescriptionCount == 0 );
349 OSL_ASSERT( nIndirectTypeDescriptionCount == 0 );
350 OSL_ASSERT( nArrayTypeDescriptionCount == 0 );
351 OSL_ASSERT( nEnumTypeDescriptionCount == 0 );
352 OSL_ASSERT( nInterfaceMethodTypeDescriptionCount == 0 );
353 OSL_ASSERT( nInterfaceAttributeTypeDescriptionCount == 0 );
354 OSL_ASSERT( nInterfaceTypeDescriptionCount == 0 );
355 OSL_ASSERT( nTypeDescriptionReferenceCount == 0 );
357 OSL_ASSERT( !pCallbacks || pCallbacks->empty() );
358 #endif
359 delete pCallbacks;
360 pCallbacks = 0;
361 #endif // CPPU_LEAK_STATIC_DATA
363 // todo: maybe into leak block
364 if( pMutex )
366 delete pMutex;
367 pMutex = 0;
371 namespace { struct Init : public rtl::Static< TypeDescriptor_Init_Impl, Init > {}; }
373 //------------------------------------------------------------------------
374 //------------------------------------------------------------------------
375 //------------------------------------------------------------------------
376 //------------------------------------------------------------------------
377 extern "C" void SAL_CALL typelib_typedescription_registerCallback(
378 void * pContext, typelib_typedescription_Callback pCallback )
379 SAL_THROW_EXTERN_C()
381 // todo mt safe: guard is no solution, can not acquire while calling callback!
382 TypeDescriptor_Init_Impl &rInit = Init::get();
383 // OslGuard aGuard( rInit.getMutex() );
384 if( !rInit.pCallbacks )
385 rInit.pCallbacks = new CallbackSet_Impl;
386 rInit.pCallbacks->push_back( CallbackEntry( pContext, pCallback ) );
389 //------------------------------------------------------------------------
390 extern "C" void SAL_CALL typelib_typedescription_revokeCallback(
391 void * pContext, typelib_typedescription_Callback pCallback )
392 SAL_THROW_EXTERN_C()
394 TypeDescriptor_Init_Impl &rInit = Init::get();
395 if( rInit.pCallbacks )
397 // todo mt safe: guard is no solution, can not acquire while calling callback!
398 // OslGuard aGuard( rInit.getMutex() );
399 CallbackEntry aEntry( pContext, pCallback );
400 CallbackSet_Impl::iterator iPos( rInit.pCallbacks->begin() );
401 while (!(iPos == rInit.pCallbacks->end()))
403 if (*iPos == aEntry)
405 rInit.pCallbacks->erase( iPos );
406 iPos = rInit.pCallbacks->begin();
408 else
410 ++iPos;
417 //------------------------------------------------------------------------
418 //------------------------------------------------------------------------
419 //------------------------------------------------------------------------
420 extern "C" sal_Int32 SAL_CALL typelib_typedescription_getAlignedUnoSize(
421 const typelib_TypeDescription * pTypeDescription,
422 sal_Int32 nOffset, sal_Int32 & rMaxIntegralTypeSize )
423 SAL_THROW_EXTERN_C();
425 //------------------------------------------------------------------------
426 static inline void typelib_typedescription_initTables(
427 typelib_TypeDescription * pTD )
428 SAL_THROW( () )
430 typelib_InterfaceTypeDescription * pITD = (typelib_InterfaceTypeDescription *)pTD;
432 sal_Bool * pReadWriteAttributes = (sal_Bool *)alloca( pITD->nAllMembers );
433 for ( sal_Int32 i = pITD->nAllMembers; i--; )
435 pReadWriteAttributes[i] = sal_False;
436 if( typelib_TypeClass_INTERFACE_ATTRIBUTE == pITD->ppAllMembers[i]->eTypeClass )
438 typelib_TypeDescription * pM = 0;
439 TYPELIB_DANGER_GET( &pM, pITD->ppAllMembers[i] );
440 OSL_ASSERT( pM );
441 if (pM)
443 pReadWriteAttributes[i] = !((typelib_InterfaceAttributeTypeDescription *)pM)->bReadOnly;
444 TYPELIB_DANGER_RELEASE( pM );
446 #if OSL_DEBUG_LEVEL > 1
447 else
449 OString aStr( OUStringToOString( pITD->ppAllMembers[i]->pTypeName, RTL_TEXTENCODING_ASCII_US ) );
450 OSL_TRACE( "\n### cannot get attribute type description: %s", aStr.getStr() );
452 #endif
456 MutexGuard aGuard( Init::get().getMutex() );
457 if( !pTD->bComplete )
459 // create the index table from member to function table
460 pITD->pMapMemberIndexToFunctionIndex = new sal_Int32[ pITD->nAllMembers ];
461 sal_Int32 nAdditionalOffset = 0; // +1 for read/write attributes
462 sal_Int32 i;
463 for( i = 0; i < pITD->nAllMembers; i++ )
465 // index to the get method of the attribute
466 pITD->pMapMemberIndexToFunctionIndex[i] = i + nAdditionalOffset;
467 // extra offset if it is a read/write attribute?
468 if( pReadWriteAttributes[i] )
470 // a read/write attribute
471 nAdditionalOffset++;
475 // create the index table from function to member table
476 pITD->pMapFunctionIndexToMemberIndex = new sal_Int32[ pITD->nAllMembers + nAdditionalOffset ];
477 nAdditionalOffset = 0; // +1 for read/write attributes
478 for( i = 0; i < pITD->nAllMembers; i++ )
480 // index to the get method of the attribute
481 pITD->pMapFunctionIndexToMemberIndex[i + nAdditionalOffset] = i;
482 // extra offset if it is a read/write attribute?
483 if( pReadWriteAttributes[i] )
485 // a read/write attribute
486 pITD->pMapFunctionIndexToMemberIndex[i + ++nAdditionalOffset] = i;
489 // must be the last action after all initialization is done
490 pITD->nMapFunctionIndexToMemberIndex = pITD->nAllMembers + nAdditionalOffset;
491 pTD->bComplete = sal_True;
495 namespace {
497 // In some situations (notably typelib_typedescription_newInterfaceMethod and
498 // typelib_typedescription_newInterfaceAttribute), only the members nMembers,
499 // ppMembers, nAllMembers, and ppAllMembers of an incomplete interface type
500 // description are necessary, but not the additional
501 // pMapMemberIndexToFunctionIndex, nMapFunctionIndexToMemberIndex, and
502 // pMapFunctionIndexToMemberIndex (which are computed by
503 // typelib_typedescription_initTables). Furthermore, in those situations, it
504 // might be illegal to compute those tables, as the creation of the interface
505 // member type descriptions would recursively require a complete interface type
506 // description. The parameter initTables controls whether or not to call
507 // typelib_typedescription_initTables in those situations.
508 bool complete(typelib_TypeDescription ** ppTypeDescr, bool initTables) {
509 if (! (*ppTypeDescr)->bComplete)
511 OSL_ASSERT( (typelib_TypeClass_STRUCT == (*ppTypeDescr)->eTypeClass ||
512 typelib_TypeClass_EXCEPTION == (*ppTypeDescr)->eTypeClass ||
513 typelib_TypeClass_UNION == (*ppTypeDescr)->eTypeClass ||
514 typelib_TypeClass_ENUM == (*ppTypeDescr)->eTypeClass ||
515 typelib_TypeClass_INTERFACE == (*ppTypeDescr)->eTypeClass) &&
516 !reallyWeak( (*ppTypeDescr)->eTypeClass ) );
518 if (typelib_TypeClass_INTERFACE == (*ppTypeDescr)->eTypeClass &&
519 ((typelib_InterfaceTypeDescription *)*ppTypeDescr)->ppAllMembers)
521 if (initTables) {
522 typelib_typedescription_initTables( *ppTypeDescr );
524 return true;
527 typelib_TypeDescription * pTD = 0;
528 // on demand access of complete td
529 TypeDescriptor_Init_Impl &rInit = Init::get();
530 rInit.callChain( &pTD, (*ppTypeDescr)->pTypeName );
531 if (pTD)
533 if (typelib_TypeClass_TYPEDEF == pTD->eTypeClass)
535 typelib_typedescriptionreference_getDescription(
536 &pTD, ((typelib_IndirectTypeDescription *)pTD)->pType );
537 OSL_ASSERT( pTD );
538 if (! pTD)
539 return false;
542 OSL_ASSERT( typelib_TypeClass_TYPEDEF != pTD->eTypeClass );
543 // typedescription found
544 // set to on demand
545 pTD->bOnDemand = sal_True;
547 if (pTD->eTypeClass == typelib_TypeClass_INTERFACE
548 && !pTD->bComplete && initTables)
550 // mandatory info from callback chain
551 OSL_ASSERT( ((typelib_InterfaceTypeDescription *)pTD)->ppAllMembers );
552 // complete except of tables init
553 typelib_typedescription_initTables( pTD );
554 pTD->bComplete = sal_True;
557 // The type description is hold by the reference until
558 // on demand is activated.
559 ::typelib_typedescription_register( &pTD ); // replaces incomplete one
560 OSL_ASSERT( pTD == *ppTypeDescr ); // has to merge into existing one
562 // insert into the chache
563 MutexGuard aGuard( rInit.getMutex() );
564 if( !rInit.pCache )
565 rInit.pCache = new TypeDescriptionList_Impl;
566 if( (sal_Int32)rInit.pCache->size() >= nCacheSize )
568 typelib_typedescription_release( rInit.pCache->front() );
569 rInit.pCache->pop_front();
571 // descriptions in the cache must be acquired!
572 typelib_typedescription_acquire( pTD );
573 rInit.pCache->push_back( pTD );
575 OSL_ASSERT(
576 pTD->bComplete
577 || (pTD->eTypeClass == typelib_TypeClass_INTERFACE
578 && !initTables));
580 ::typelib_typedescription_release( *ppTypeDescr );
581 *ppTypeDescr = pTD;
583 else
585 #if OSL_DEBUG_LEVEL > 1
586 OString aStr(
587 OUStringToOString( (*ppTypeDescr)->pTypeName, RTL_TEXTENCODING_ASCII_US ) );
588 OSL_TRACE( "\n### type cannot be completed: %s", aStr.getStr() );
589 #endif
590 return false;
593 return true;
598 //------------------------------------------------------------------------
599 extern "C" void SAL_CALL typelib_typedescription_newEmpty(
600 typelib_TypeDescription ** ppRet,
601 typelib_TypeClass eTypeClass, rtl_uString * pTypeName )
602 SAL_THROW_EXTERN_C()
604 if( *ppRet )
606 typelib_typedescription_release( *ppRet );
607 *ppRet = 0;
610 OSL_ASSERT( typelib_TypeClass_TYPEDEF != eTypeClass );
612 typelib_TypeDescription * pRet;
613 switch( eTypeClass )
615 case typelib_TypeClass_ARRAY:
617 typelib_ArrayTypeDescription * pTmp = new typelib_ArrayTypeDescription();
618 typelib_IndirectTypeDescription * pIndirect = (typelib_IndirectTypeDescription *)pTmp;
619 pRet = (typelib_TypeDescription *)pTmp;
620 #if OSL_DEBUG_LEVEL > 1
621 osl_incrementInterlockedCount(
622 &Init::get().nArrayTypeDescriptionCount );
623 #endif
624 pIndirect->pType = 0;
625 pTmp->nDimensions = 0;
626 pTmp->nTotalElements = 0;
627 pTmp->pDimensions = 0;
629 break;
631 case typelib_TypeClass_SEQUENCE:
633 typelib_IndirectTypeDescription * pTmp = new typelib_IndirectTypeDescription();
634 pRet = (typelib_TypeDescription *)pTmp;
635 #if OSL_DEBUG_LEVEL > 1
636 osl_incrementInterlockedCount(
637 &Init::get().nIndirectTypeDescriptionCount );
638 #endif
639 pTmp->pType = 0;
641 break;
643 case typelib_TypeClass_UNION:
645 typelib_UnionTypeDescription * pTmp;
646 pTmp = new typelib_UnionTypeDescription();
647 pRet = (typelib_TypeDescription *)pTmp;
648 #if OSL_DEBUG_LEVEL > 1
649 osl_incrementInterlockedCount(
650 &Init::get().nUnionTypeDescriptionCount );
651 #endif
652 pTmp->nMembers = 0;
653 pTmp->pDiscriminantTypeRef = 0;
654 pTmp->pDiscriminants = 0;
655 pTmp->ppTypeRefs = 0;
656 pTmp->ppMemberNames = 0;
657 pTmp->pDefaultTypeRef = 0;
659 break;
661 case typelib_TypeClass_STRUCT:
663 // FEATURE_EMPTYCLASS
664 typelib_StructTypeDescription * pTmp;
665 pTmp = new typelib_StructTypeDescription();
666 pRet = (typelib_TypeDescription *)pTmp;
667 #if OSL_DEBUG_LEVEL > 1
668 osl_incrementInterlockedCount(
669 &Init::get().nCompoundTypeDescriptionCount );
670 #endif
671 pTmp->aBase.pBaseTypeDescription = 0;
672 pTmp->aBase.nMembers = 0;
673 pTmp->aBase.pMemberOffsets = 0;
674 pTmp->aBase.ppTypeRefs = 0;
675 pTmp->aBase.ppMemberNames = 0;
676 pTmp->pParameterizedTypes = 0;
678 break;
680 case typelib_TypeClass_EXCEPTION:
682 // FEATURE_EMPTYCLASS
683 typelib_CompoundTypeDescription * pTmp;
684 pTmp = new typelib_CompoundTypeDescription();
685 pRet = (typelib_TypeDescription *)pTmp;
686 #if OSL_DEBUG_LEVEL > 1
687 osl_incrementInterlockedCount(
688 &Init::get().nCompoundTypeDescriptionCount );
689 #endif
690 pTmp->pBaseTypeDescription = 0;
691 pTmp->nMembers = 0;
692 pTmp->pMemberOffsets = 0;
693 pTmp->ppTypeRefs = 0;
694 pTmp->ppMemberNames = 0;
696 break;
698 case typelib_TypeClass_ENUM:
700 typelib_EnumTypeDescription * pTmp = new typelib_EnumTypeDescription();
701 pRet = (typelib_TypeDescription *)pTmp;
702 #if OSL_DEBUG_LEVEL > 1
703 osl_incrementInterlockedCount(
704 &Init::get().nEnumTypeDescriptionCount );
705 #endif
706 pTmp->nDefaultEnumValue = 0;
707 pTmp->nEnumValues = 0;
708 pTmp->ppEnumNames = 0;
709 pTmp->pEnumValues = 0;
711 break;
713 case typelib_TypeClass_INTERFACE:
715 typelib_InterfaceTypeDescription * pTmp = new typelib_InterfaceTypeDescription();
716 pRet = (typelib_TypeDescription *)pTmp;
717 #if OSL_DEBUG_LEVEL > 1
718 osl_incrementInterlockedCount(
719 &Init::get().nInterfaceTypeDescriptionCount );
720 #endif
721 pTmp->pBaseTypeDescription = 0;
722 pTmp->nMembers = 0;
723 pTmp->ppMembers = 0;
724 pTmp->nAllMembers = 0;
725 pTmp->ppAllMembers = 0;
726 pTmp->nMapFunctionIndexToMemberIndex = 0;
727 pTmp->pMapFunctionIndexToMemberIndex = 0;
728 pTmp->pMapMemberIndexToFunctionIndex= 0;
729 pTmp->nBaseTypes = 0;
730 pTmp->ppBaseTypes = 0;
732 break;
734 case typelib_TypeClass_INTERFACE_METHOD:
736 typelib_InterfaceMethodTypeDescription * pTmp = new typelib_InterfaceMethodTypeDescription();
737 pRet = (typelib_TypeDescription *)pTmp;
738 #if OSL_DEBUG_LEVEL > 1
739 osl_incrementInterlockedCount(
740 &Init::get().nInterfaceMethodTypeDescriptionCount );
741 #endif
742 pTmp->aBase.pMemberName = 0;
743 pTmp->pReturnTypeRef = 0;
744 pTmp->nParams = 0;
745 pTmp->pParams = 0;
746 pTmp->nExceptions = 0;
747 pTmp->ppExceptions = 0;
748 pTmp->pInterface = 0;
749 pTmp->pBaseRef = 0;
750 pTmp->nIndex = 0;
752 break;
754 case typelib_TypeClass_INTERFACE_ATTRIBUTE:
756 typelib_InterfaceAttributeTypeDescription * pTmp = new typelib_InterfaceAttributeTypeDescription();
757 pRet = (typelib_TypeDescription *)pTmp;
758 #if OSL_DEBUG_LEVEL > 1
759 osl_incrementInterlockedCount(
760 &Init::get().nInterfaceAttributeTypeDescriptionCount );
761 #endif
762 pTmp->aBase.pMemberName = 0;
763 pTmp->pAttributeTypeRef = 0;
764 pTmp->pInterface = 0;
765 pTmp->pBaseRef = 0;
766 pTmp->nIndex = 0;
767 pTmp->nGetExceptions = 0;
768 pTmp->ppGetExceptions = 0;
769 pTmp->nSetExceptions = 0;
770 pTmp->ppSetExceptions = 0;
772 break;
774 default:
776 pRet = new typelib_TypeDescription();
777 #if OSL_DEBUG_LEVEL > 1
778 osl_incrementInterlockedCount( &Init::get().nTypeDescriptionCount );
779 #endif
783 pRet->nRefCount = 1; // reference count is initially 1
784 pRet->nStaticRefCount = 0;
785 pRet->eTypeClass = eTypeClass;
786 pRet->pTypeName = 0;
787 pRet->pUniqueIdentifier = 0;
788 pRet->pReserved = 0;
789 rtl_uString_acquire( pRet->pTypeName = pTypeName );
790 pRet->pSelf = pRet;
791 pRet->bComplete = sal_True;
792 pRet->nSize = 0;
793 pRet->nAlignment = 0;
794 pRet->pWeakRef = 0;
795 pRet->bOnDemand = sal_False;
796 *ppRet = pRet;
799 //------------------------------------------------------------------------
800 namespace {
802 void newTypeDescription(
803 typelib_TypeDescription ** ppRet, typelib_TypeClass eTypeClass,
804 rtl_uString * pTypeName, typelib_TypeDescriptionReference * pType,
805 sal_Int32 nMembers, typelib_CompoundMember_Init * pCompoundMembers,
806 typelib_StructMember_Init * pStructMembers)
808 OSL_ASSERT(
809 (pCompoundMembers == 0 || pStructMembers == 0)
810 && (pStructMembers == 0 || eTypeClass == typelib_TypeClass_STRUCT));
811 if (typelib_TypeClass_TYPEDEF == eTypeClass)
813 OSL_TRACE( "### unexpected typedef!" );
814 typelib_typedescriptionreference_getDescription( ppRet, pType );
815 return;
818 typelib_typedescription_newEmpty( ppRet, eTypeClass, pTypeName );
820 switch( eTypeClass )
822 case typelib_TypeClass_SEQUENCE:
824 OSL_ASSERT( nMembers == 0 );
825 typelib_typedescriptionreference_acquire( pType );
826 ((typelib_IndirectTypeDescription *)*ppRet)->pType = pType;
828 break;
830 case typelib_TypeClass_EXCEPTION:
831 case typelib_TypeClass_STRUCT:
833 // FEATURE_EMPTYCLASS
834 typelib_CompoundTypeDescription * pTmp = (typelib_CompoundTypeDescription*)*ppRet;
836 sal_Int32 nOffset = 0;
837 if( pType )
839 typelib_typedescriptionreference_getDescription(
840 (typelib_TypeDescription **)&pTmp->pBaseTypeDescription, pType );
841 nOffset = ((typelib_TypeDescription *)pTmp->pBaseTypeDescription)->nSize;
842 OSL_ENSURE( newAlignedSize( 0, ((typelib_TypeDescription *)pTmp->pBaseTypeDescription)->nSize, ((typelib_TypeDescription *)pTmp->pBaseTypeDescription)->nAlignment ) == ((typelib_TypeDescription *)pTmp->pBaseTypeDescription)->nSize, "### unexpected offset!" );
844 if( nMembers )
846 pTmp->nMembers = nMembers;
847 pTmp->pMemberOffsets = new sal_Int32[ nMembers ];
848 pTmp->ppTypeRefs = new typelib_TypeDescriptionReference *[ nMembers ];
849 pTmp->ppMemberNames = new rtl_uString *[ nMembers ];
850 bool polymorphic = eTypeClass == typelib_TypeClass_STRUCT
851 && rtl::OUString::unacquired(&pTypeName).indexOf('<') >= 0;
852 OSL_ASSERT(!polymorphic || pStructMembers != 0);
853 if (polymorphic) {
854 reinterpret_cast< typelib_StructTypeDescription * >(pTmp)->
855 pParameterizedTypes = new sal_Bool[nMembers];
857 for( sal_Int32 i = 0 ; i < nMembers; i++ )
859 // read the type and member names
860 pTmp->ppTypeRefs[i] = 0;
861 if (pCompoundMembers != 0) {
862 typelib_typedescriptionreference_new(
863 pTmp->ppTypeRefs +i, pCompoundMembers[i].eTypeClass,
864 pCompoundMembers[i].pTypeName );
865 rtl_uString_acquire(
866 pTmp->ppMemberNames[i]
867 = pCompoundMembers[i].pMemberName );
868 } else {
869 typelib_typedescriptionreference_new(
870 pTmp->ppTypeRefs +i,
871 pStructMembers[i].aBase.eTypeClass,
872 pStructMembers[i].aBase.pTypeName );
873 rtl_uString_acquire(
874 pTmp->ppMemberNames[i]
875 = pStructMembers[i].aBase.pMemberName );
877 // write offset
878 sal_Int32 size;
879 sal_Int32 alignment;
880 if (pTmp->ppTypeRefs[i]->eTypeClass ==
881 typelib_TypeClass_SEQUENCE)
883 // Take care of recursion like
884 // struct S { sequence<S> x; };
885 size = sizeof(void *);
886 alignment = adjustAlignment(size);
887 } else {
888 typelib_TypeDescription * pTD = 0;
889 TYPELIB_DANGER_GET( &pTD, pTmp->ppTypeRefs[i] );
890 OSL_ENSURE( pTD->nSize, "### void member?" );
891 size = pTD->nSize;
892 alignment = pTD->nAlignment;
893 TYPELIB_DANGER_RELEASE( pTD );
895 nOffset = newAlignedSize( nOffset, size, alignment );
896 pTmp->pMemberOffsets[i] = nOffset - size;
898 if (polymorphic) {
899 reinterpret_cast< typelib_StructTypeDescription * >(
900 pTmp)->pParameterizedTypes[i]
901 = pStructMembers[i].bParameterizedType;
906 break;
908 default:
909 break;
912 if( !reallyWeak( eTypeClass ) )
913 (*ppRet)->pWeakRef = (typelib_TypeDescriptionReference *)*ppRet;
914 if( eTypeClass != typelib_TypeClass_VOID )
916 // sizeof( void ) not allowed
917 (*ppRet)->nSize = typelib_typedescription_getAlignedUnoSize( (*ppRet), 0, (*ppRet)->nAlignment );
918 (*ppRet)->nAlignment = adjustAlignment( (*ppRet)->nAlignment );
924 extern "C" void SAL_CALL typelib_typedescription_new(
925 typelib_TypeDescription ** ppRet,
926 typelib_TypeClass eTypeClass,
927 rtl_uString * pTypeName,
928 typelib_TypeDescriptionReference * pType,
929 sal_Int32 nMembers,
930 typelib_CompoundMember_Init * pMembers )
931 SAL_THROW_EXTERN_C()
933 newTypeDescription(
934 ppRet, eTypeClass, pTypeName, pType, nMembers, pMembers, 0);
937 extern "C" void SAL_CALL typelib_typedescription_newStruct(
938 typelib_TypeDescription ** ppRet,
939 rtl_uString * pTypeName,
940 typelib_TypeDescriptionReference * pType,
941 sal_Int32 nMembers,
942 typelib_StructMember_Init * pMembers )
943 SAL_THROW_EXTERN_C()
945 newTypeDescription(
946 ppRet, typelib_TypeClass_STRUCT, pTypeName, pType, nMembers, 0,
947 pMembers);
950 //------------------------------------------------------------------------
951 extern "C" void SAL_CALL typelib_typedescription_newUnion(
952 typelib_TypeDescription ** ppRet,
953 rtl_uString * pTypeName,
954 typelib_TypeDescriptionReference * pDiscriminantTypeRef,
955 sal_Int64 nDefaultDiscriminant,
956 typelib_TypeDescriptionReference * pDefaultTypeRef,
957 sal_Int32 nMembers,
958 typelib_Union_Init * pMembers )
959 SAL_THROW_EXTERN_C()
961 typelib_typedescription_newEmpty( ppRet, typelib_TypeClass_UNION, pTypeName );
962 // discriminant type
963 typelib_UnionTypeDescription * pTmp = (typelib_UnionTypeDescription *)*ppRet;
964 typelib_typedescriptionreference_acquire( pTmp->pDiscriminantTypeRef = pDiscriminantTypeRef );
966 sal_Int32 nPos;
968 pTmp->nMembers = nMembers;
969 // default discriminant
970 if (nMembers)
972 pTmp->pDiscriminants = new sal_Int64[ nMembers ];
973 for ( nPos = nMembers; nPos--; )
975 pTmp->pDiscriminants[nPos] = pMembers[nPos].nDiscriminant;
978 // default default discriminant
979 pTmp->nDefaultDiscriminant = nDefaultDiscriminant;
981 // union member types
982 pTmp->ppTypeRefs = new typelib_TypeDescriptionReference *[ nMembers ];
983 for ( nPos = nMembers; nPos--; )
985 typelib_typedescriptionreference_acquire( pTmp->ppTypeRefs[nPos] = pMembers[nPos].pTypeRef );
987 // union member names
988 pTmp->ppMemberNames = new rtl_uString *[ nMembers ];
989 for ( nPos = nMembers; nPos--; )
991 rtl_uString_acquire( pTmp->ppMemberNames[nPos] = pMembers[nPos].pMemberName );
994 // default union type
995 typelib_typedescriptionreference_acquire( pTmp->pDefaultTypeRef = pDefaultTypeRef );
997 if (! reallyWeak( typelib_TypeClass_UNION ))
998 (*ppRet)->pWeakRef = (typelib_TypeDescriptionReference *)*ppRet;
999 (*ppRet)->nSize = typelib_typedescription_getAlignedUnoSize( (*ppRet), 0, (*ppRet)->nAlignment );
1000 (*ppRet)->nAlignment = adjustAlignment( (*ppRet)->nAlignment );
1003 //------------------------------------------------------------------------
1004 extern "C" void SAL_CALL typelib_typedescription_newEnum(
1005 typelib_TypeDescription ** ppRet,
1006 rtl_uString * pTypeName,
1007 sal_Int32 nDefaultValue,
1008 sal_Int32 nEnumValues,
1009 rtl_uString ** ppEnumNames,
1010 sal_Int32 * pEnumValues )
1011 SAL_THROW_EXTERN_C()
1013 typelib_typedescription_newEmpty( ppRet, typelib_TypeClass_ENUM, pTypeName );
1014 typelib_EnumTypeDescription * pEnum = (typelib_EnumTypeDescription *)*ppRet;
1016 pEnum->nDefaultEnumValue = nDefaultValue;
1017 pEnum->nEnumValues = nEnumValues;
1018 pEnum->ppEnumNames = new rtl_uString * [ nEnumValues ];
1019 for ( sal_Int32 nPos = nEnumValues; nPos--; )
1021 rtl_uString_acquire( pEnum->ppEnumNames[nPos] = ppEnumNames[nPos] );
1023 pEnum->pEnumValues = new sal_Int32[ nEnumValues ];
1024 ::memcpy( pEnum->pEnumValues, pEnumValues, nEnumValues * sizeof(sal_Int32) );
1026 (*ppRet)->pWeakRef = (typelib_TypeDescriptionReference *)*ppRet;
1027 // sizeof( void ) not allowed
1028 (*ppRet)->nSize = typelib_typedescription_getAlignedUnoSize( (*ppRet), 0, (*ppRet)->nAlignment );
1029 (*ppRet)->nAlignment = adjustAlignment( (*ppRet)->nAlignment );
1032 //------------------------------------------------------------------------
1033 extern "C" void SAL_CALL typelib_typedescription_newArray(
1034 typelib_TypeDescription ** ppRet,
1035 typelib_TypeDescriptionReference * pElementTypeRef,
1036 sal_Int32 nDimensions,
1037 sal_Int32 * pDimensions )
1038 SAL_THROW_EXTERN_C ()
1040 OUStringBuffer aBuf( 32 );
1041 aBuf.append( pElementTypeRef->pTypeName );
1042 sal_Int32 nElements = 1;
1043 for (sal_Int32 i=0; i < nDimensions; i++)
1045 aBuf.appendAscii("[");
1046 aBuf.append(pDimensions[i]);
1047 aBuf.appendAscii("]");
1048 nElements *= pDimensions[i];
1050 OUString aTypeName( aBuf.makeStringAndClear() );
1053 typelib_typedescription_newEmpty( ppRet, typelib_TypeClass_ARRAY, aTypeName.pData );
1054 typelib_ArrayTypeDescription * pArray = (typelib_ArrayTypeDescription *)*ppRet;
1056 pArray->nDimensions = nDimensions;
1057 pArray->nTotalElements = nElements;
1058 pArray->pDimensions = new sal_Int32[ nDimensions ];
1059 ::memcpy( pArray->pDimensions, pDimensions, nDimensions * sizeof(sal_Int32) );
1061 typelib_typedescriptionreference_acquire(pElementTypeRef);
1062 ((typelib_IndirectTypeDescription*)pArray)->pType = pElementTypeRef;
1064 (*ppRet)->pWeakRef = (typelib_TypeDescriptionReference *)*ppRet;
1065 // sizeof( void ) not allowed
1066 (*ppRet)->nSize = typelib_typedescription_getAlignedUnoSize( *ppRet, 0, (*ppRet)->nAlignment );
1067 (*ppRet)->nAlignment = adjustAlignment( (*ppRet)->nAlignment );
1070 //------------------------------------------------------------------------
1071 extern "C" void SAL_CALL typelib_typedescription_newInterface(
1072 typelib_InterfaceTypeDescription ** ppRet,
1073 rtl_uString * pTypeName,
1074 sal_uInt32 nUik1, sal_uInt16 nUik2, sal_uInt16 nUik3, sal_uInt32 nUik4, sal_uInt32 nUik5,
1075 typelib_TypeDescriptionReference * pBaseInterface,
1076 sal_Int32 nMembers,
1077 typelib_TypeDescriptionReference ** ppMembers )
1078 SAL_THROW_EXTERN_C()
1080 typelib_typedescription_newMIInterface(
1081 ppRet, pTypeName, nUik1, nUik2, nUik3, nUik4, nUik5,
1082 pBaseInterface == 0 ? 0 : 1, &pBaseInterface, nMembers, ppMembers);
1085 //------------------------------------------------------------------------
1087 namespace {
1089 class BaseList {
1090 public:
1091 struct Entry {
1092 sal_Int32 memberOffset;
1093 sal_Int32 directBaseIndex;
1094 sal_Int32 directBaseMemberOffset;
1095 typelib_InterfaceTypeDescription const * base;
1098 typedef std::vector< Entry > List;
1100 BaseList(typelib_InterfaceTypeDescription const * desc);
1102 List const & getList() const { return list; }
1104 sal_Int32 getBaseMembers() const { return members; }
1106 private:
1107 typedef std::set< rtl::OUString > Set;
1109 void calculate(
1110 sal_Int32 directBaseIndex, Set & directBaseSet,
1111 sal_Int32 * directBaseMembers,
1112 typelib_InterfaceTypeDescription const * desc);
1114 Set set;
1115 List list;
1116 sal_Int32 members;
1119 BaseList::BaseList(typelib_InterfaceTypeDescription const * desc) {
1120 members = 0;
1121 for (sal_Int32 i = 0; i < desc->nBaseTypes; ++i) {
1122 Set directBaseSet;
1123 sal_Int32 directBaseMembers = 0;
1124 calculate(i, directBaseSet, &directBaseMembers, desc->ppBaseTypes[i]);
1128 void BaseList::calculate(
1129 sal_Int32 directBaseIndex, Set & directBaseSet,
1130 sal_Int32 * directBaseMembers,
1131 typelib_InterfaceTypeDescription const * desc)
1133 for (sal_Int32 i = 0; i < desc->nBaseTypes; ++i) {
1134 calculate(
1135 directBaseIndex, directBaseSet, directBaseMembers,
1136 desc->ppBaseTypes[i]);
1138 if (set.insert(desc->aBase.pTypeName).second) {
1139 Entry e;
1140 e.memberOffset = members;
1141 e.directBaseIndex = directBaseIndex;
1142 e.directBaseMemberOffset = *directBaseMembers;
1143 e.base = desc;
1144 list.push_back(e);
1145 OSL_ASSERT(desc->ppAllMembers != 0);
1146 members += desc->nMembers;
1148 if (directBaseSet.insert(desc->aBase.pTypeName).second) {
1149 OSL_ASSERT(desc->ppAllMembers != 0);
1150 *directBaseMembers += desc->nMembers;
1156 extern "C" void SAL_CALL typelib_typedescription_newMIInterface(
1157 typelib_InterfaceTypeDescription ** ppRet,
1158 rtl_uString * pTypeName,
1159 sal_uInt32 nUik1, sal_uInt16 nUik2, sal_uInt16 nUik3, sal_uInt32 nUik4, sal_uInt32 nUik5,
1160 sal_Int32 nBaseInterfaces,
1161 typelib_TypeDescriptionReference ** ppBaseInterfaces,
1162 sal_Int32 nMembers,
1163 typelib_TypeDescriptionReference ** ppMembers )
1164 SAL_THROW_EXTERN_C()
1166 if (*ppRet != 0) {
1167 typelib_typedescription_release(&(*ppRet)->aBase);
1168 *ppRet = 0;
1171 typelib_InterfaceTypeDescription * pITD = 0;
1172 typelib_typedescription_newEmpty(
1173 (typelib_TypeDescription **)&pITD, typelib_TypeClass_INTERFACE, pTypeName );
1175 pITD->nBaseTypes = nBaseInterfaces;
1176 pITD->ppBaseTypes = new typelib_InterfaceTypeDescription *[nBaseInterfaces];
1177 for (sal_Int32 i = 0; i < nBaseInterfaces; ++i) {
1178 pITD->ppBaseTypes[i] = 0;
1179 typelib_typedescriptionreference_getDescription(
1180 reinterpret_cast< typelib_TypeDescription ** >(
1181 &pITD->ppBaseTypes[i]),
1182 ppBaseInterfaces[i]);
1183 if (pITD->ppBaseTypes[i] == 0
1184 || !complete(
1185 reinterpret_cast< typelib_TypeDescription ** >(
1186 &pITD->ppBaseTypes[i]),
1187 false))
1189 OSL_ASSERT(false);
1190 return;
1192 OSL_ASSERT(pITD->ppBaseTypes[i] != 0);
1194 if (nBaseInterfaces > 0) {
1195 pITD->pBaseTypeDescription = pITD->ppBaseTypes[0];
1197 // set the
1198 pITD->aUik.m_Data1 = nUik1;
1199 pITD->aUik.m_Data2 = nUik2;
1200 pITD->aUik.m_Data3 = nUik3;
1201 pITD->aUik.m_Data4 = nUik4;
1202 pITD->aUik.m_Data5 = nUik5;
1204 BaseList aBaseList(pITD);
1205 pITD->nAllMembers = nMembers + aBaseList.getBaseMembers();
1206 pITD->nMembers = nMembers;
1208 if( pITD->nAllMembers )
1210 // at minimum one member exist, allocate the memory
1211 pITD->ppAllMembers = new typelib_TypeDescriptionReference *[ pITD->nAllMembers ];
1212 sal_Int32 n = 0;
1214 BaseList::List const & rList = aBaseList.getList();
1215 {for (BaseList::List::const_iterator i(rList.begin()); i != rList.end();
1216 ++i)
1218 typelib_InterfaceTypeDescription const * pBase = i->base;
1219 typelib_InterfaceTypeDescription const * pDirectBase
1220 = pITD->ppBaseTypes[i->directBaseIndex];
1221 OSL_ASSERT(pBase->ppAllMembers != 0);
1222 for (sal_Int32 j = 0; j < pBase->nMembers; ++j) {
1223 typelib_TypeDescriptionReference const * pDirectBaseMember
1224 = pDirectBase->ppAllMembers[i->directBaseMemberOffset + j];
1225 rtl::OUStringBuffer aBuf(pDirectBaseMember->pTypeName);
1226 aBuf.appendAscii(RTL_CONSTASCII_STRINGPARAM(":@"));
1227 aBuf.append(i->directBaseIndex);
1228 aBuf.append(static_cast< sal_Unicode >(','));
1229 aBuf.append(i->memberOffset + j);
1230 aBuf.append(static_cast< sal_Unicode >(':'));
1231 aBuf.append(pITD->aBase.pTypeName);
1232 rtl::OUString aName(aBuf.makeStringAndClear());
1233 typelib_TypeDescriptionReference * pDerivedMember = 0;
1234 typelib_typedescriptionreference_new(
1235 &pDerivedMember, pDirectBaseMember->eTypeClass,
1236 aName.pData);
1237 pITD->ppAllMembers[n++] = pDerivedMember;
1241 if( nMembers )
1243 pITD->ppMembers = pITD->ppAllMembers + aBaseList.getBaseMembers();
1246 // add own members
1247 {for( sal_Int32 i = 0; i < nMembers; i++ )
1249 typelib_typedescriptionreference_acquire( ppMembers[i] );
1250 pITD->ppAllMembers[n++] = ppMembers[i];
1254 typelib_TypeDescription * pTmp = (typelib_TypeDescription *)pITD;
1255 if( !reallyWeak( typelib_TypeClass_INTERFACE ) )
1256 pTmp->pWeakRef = (typelib_TypeDescriptionReference *)pTmp;
1257 pTmp->nSize = typelib_typedescription_getAlignedUnoSize( pTmp, 0, pTmp->nAlignment );
1258 pTmp->nAlignment = adjustAlignment( pTmp->nAlignment );
1259 pTmp->bComplete = sal_False;
1261 *ppRet = pITD;
1264 //------------------------------------------------------------------------
1266 namespace {
1268 typelib_TypeDescriptionReference ** copyExceptions(
1269 sal_Int32 count, rtl_uString ** typeNames)
1271 OSL_ASSERT(count >= 0);
1272 if (count == 0) {
1273 return 0;
1275 typelib_TypeDescriptionReference ** p
1276 = new typelib_TypeDescriptionReference *[count];
1277 for (sal_Int32 i = 0; i < count; ++i) {
1278 p[i] = 0;
1279 typelib_typedescriptionreference_new(
1280 p + i, typelib_TypeClass_EXCEPTION, typeNames[i]);
1282 return p;
1287 extern "C" void SAL_CALL typelib_typedescription_newInterfaceMethod(
1288 typelib_InterfaceMethodTypeDescription ** ppRet,
1289 sal_Int32 nAbsolutePosition,
1290 sal_Bool bOneWay,
1291 rtl_uString * pTypeName,
1292 typelib_TypeClass eReturnTypeClass,
1293 rtl_uString * pReturnTypeName,
1294 sal_Int32 nParams,
1295 typelib_Parameter_Init * pParams,
1296 sal_Int32 nExceptions,
1297 rtl_uString ** ppExceptionNames )
1298 SAL_THROW_EXTERN_C()
1300 if (*ppRet != 0) {
1301 typelib_typedescription_release(&(*ppRet)->aBase.aBase);
1302 *ppRet = 0;
1304 sal_Int32 nOffset = rtl_ustr_lastIndexOfChar_WithLength(
1305 pTypeName->buffer, pTypeName->length, ':');
1306 if (nOffset <= 0 || pTypeName->buffer[nOffset - 1] != ':') {
1307 OSL_ENSURE(false, "Bad interface method type name");
1308 return;
1310 rtl::OUString aInterfaceTypeName(pTypeName->buffer, nOffset - 1);
1311 typelib_InterfaceTypeDescription * pInterface = 0;
1312 typelib_typedescription_getByName(
1313 reinterpret_cast< typelib_TypeDescription ** >(&pInterface),
1314 aInterfaceTypeName.pData);
1315 if (pInterface == 0
1316 || pInterface->aBase.eTypeClass != typelib_TypeClass_INTERFACE
1317 || !complete(
1318 reinterpret_cast< typelib_TypeDescription ** >(&pInterface), false))
1320 OSL_ENSURE(false, "No interface corresponding to interface method");
1321 return;
1324 typelib_typedescription_newEmpty(
1325 (typelib_TypeDescription **)ppRet, typelib_TypeClass_INTERFACE_METHOD, pTypeName );
1326 typelib_TypeDescription * pTmp = (typelib_TypeDescription *)*ppRet;
1328 rtl_uString_newFromStr_WithLength( &(*ppRet)->aBase.pMemberName,
1329 pTypeName->buffer + nOffset +1,
1330 pTypeName->length - nOffset -1 );
1331 (*ppRet)->aBase.nPosition = nAbsolutePosition;
1332 (*ppRet)->bOneWay = bOneWay;
1333 typelib_typedescriptionreference_new( &(*ppRet)->pReturnTypeRef, eReturnTypeClass, pReturnTypeName );
1334 (*ppRet)->nParams = nParams;
1335 if( nParams )
1337 (*ppRet)->pParams = new typelib_MethodParameter[ nParams ];
1339 for( sal_Int32 i = 0; i < nParams; i++ )
1341 // get the name of the parameter
1342 (*ppRet)->pParams[ i ].pName = 0;
1343 rtl_uString_acquire( (*ppRet)->pParams[ i ].pName = pParams[i].pParamName );
1344 (*ppRet)->pParams[ i ].pTypeRef = 0;
1345 // get the type name of the parameter and create the weak reference
1346 typelib_typedescriptionreference_new(
1347 &(*ppRet)->pParams[ i ].pTypeRef, pParams[i].eTypeClass, pParams[i].pTypeName );
1348 (*ppRet)->pParams[ i ].bIn = pParams[i].bIn;
1349 (*ppRet)->pParams[ i ].bOut = pParams[i].bOut;
1352 (*ppRet)->nExceptions = nExceptions;
1353 (*ppRet)->ppExceptions = copyExceptions(nExceptions, ppExceptionNames);
1354 (*ppRet)->pInterface = pInterface;
1355 (*ppRet)->pBaseRef = 0;
1356 OSL_ASSERT(
1357 (nAbsolutePosition >= pInterface->nAllMembers - pInterface->nMembers)
1358 && nAbsolutePosition < pInterface->nAllMembers);
1359 (*ppRet)->nIndex = nAbsolutePosition
1360 - (pInterface->nAllMembers - pInterface->nMembers);
1361 if( !reallyWeak( typelib_TypeClass_INTERFACE_METHOD ) )
1362 pTmp->pWeakRef = (typelib_TypeDescriptionReference *)pTmp;
1366 //------------------------------------------------------------------------
1367 extern "C" void SAL_CALL typelib_typedescription_newInterfaceAttribute(
1368 typelib_InterfaceAttributeTypeDescription ** ppRet,
1369 sal_Int32 nAbsolutePosition,
1370 rtl_uString * pTypeName,
1371 typelib_TypeClass eAttributeTypeClass,
1372 rtl_uString * pAttributeTypeName,
1373 sal_Bool bReadOnly )
1374 SAL_THROW_EXTERN_C()
1376 typelib_typedescription_newExtendedInterfaceAttribute(
1377 ppRet, nAbsolutePosition, pTypeName, eAttributeTypeClass,
1378 pAttributeTypeName, bReadOnly, 0, 0, 0, 0);
1381 //------------------------------------------------------------------------
1382 extern "C" void SAL_CALL typelib_typedescription_newExtendedInterfaceAttribute(
1383 typelib_InterfaceAttributeTypeDescription ** ppRet,
1384 sal_Int32 nAbsolutePosition,
1385 rtl_uString * pTypeName,
1386 typelib_TypeClass eAttributeTypeClass,
1387 rtl_uString * pAttributeTypeName,
1388 sal_Bool bReadOnly,
1389 sal_Int32 nGetExceptions, rtl_uString ** ppGetExceptionNames,
1390 sal_Int32 nSetExceptions, rtl_uString ** ppSetExceptionNames )
1391 SAL_THROW_EXTERN_C()
1393 if (*ppRet != 0) {
1394 typelib_typedescription_release(&(*ppRet)->aBase.aBase);
1395 *ppRet = 0;
1397 sal_Int32 nOffset = rtl_ustr_lastIndexOfChar_WithLength(
1398 pTypeName->buffer, pTypeName->length, ':');
1399 if (nOffset <= 0 || pTypeName->buffer[nOffset - 1] != ':') {
1400 OSL_ENSURE(false, "Bad interface attribute type name");
1401 return;
1403 rtl::OUString aInterfaceTypeName(pTypeName->buffer, nOffset - 1);
1404 typelib_InterfaceTypeDescription * pInterface = 0;
1405 typelib_typedescription_getByName(
1406 reinterpret_cast< typelib_TypeDescription ** >(&pInterface),
1407 aInterfaceTypeName.pData);
1408 if (pInterface == 0
1409 || pInterface->aBase.eTypeClass != typelib_TypeClass_INTERFACE
1410 || !complete(
1411 reinterpret_cast< typelib_TypeDescription ** >(&pInterface), false))
1413 OSL_ENSURE(false, "No interface corresponding to interface attribute");
1414 return;
1417 typelib_typedescription_newEmpty(
1418 (typelib_TypeDescription **)ppRet, typelib_TypeClass_INTERFACE_ATTRIBUTE, pTypeName );
1419 typelib_TypeDescription * pTmp = (typelib_TypeDescription *)*ppRet;
1421 rtl_uString_newFromStr_WithLength( &(*ppRet)->aBase.pMemberName,
1422 pTypeName->buffer + nOffset +1,
1423 pTypeName->length - nOffset -1 );
1424 (*ppRet)->aBase.nPosition = nAbsolutePosition;
1425 typelib_typedescriptionreference_new( &(*ppRet)->pAttributeTypeRef, eAttributeTypeClass, pAttributeTypeName );
1426 (*ppRet)->bReadOnly = bReadOnly;
1427 (*ppRet)->pInterface = pInterface;
1428 (*ppRet)->pBaseRef = 0;
1429 OSL_ASSERT(
1430 (nAbsolutePosition >= pInterface->nAllMembers - pInterface->nMembers)
1431 && nAbsolutePosition < pInterface->nAllMembers);
1432 (*ppRet)->nIndex = nAbsolutePosition
1433 - (pInterface->nAllMembers - pInterface->nMembers);
1434 (*ppRet)->nGetExceptions = nGetExceptions;
1435 (*ppRet)->ppGetExceptions = copyExceptions(
1436 nGetExceptions, ppGetExceptionNames);
1437 (*ppRet)->nSetExceptions = nSetExceptions;
1438 (*ppRet)->ppSetExceptions = copyExceptions(
1439 nSetExceptions, ppSetExceptionNames);
1440 if( !reallyWeak( typelib_TypeClass_INTERFACE_ATTRIBUTE ) )
1441 pTmp->pWeakRef = (typelib_TypeDescriptionReference *)pTmp;
1444 //------------------------------------------------------------------------
1445 extern "C" void SAL_CALL typelib_typedescription_acquire(
1446 typelib_TypeDescription * pTypeDescription )
1447 SAL_THROW_EXTERN_C()
1449 ::osl_incrementInterlockedCount( &pTypeDescription->nRefCount );
1452 //------------------------------------------------------------------------
1454 namespace {
1456 void deleteExceptions(
1457 sal_Int32 count, typelib_TypeDescriptionReference ** exceptions)
1459 for (sal_Int32 i = 0; i < count; ++i) {
1460 typelib_typedescriptionreference_release(exceptions[i]);
1462 delete[] exceptions;
1467 // frees anything except typelib_TypeDescription base!
1468 static inline void typelib_typedescription_destructExtendedMembers(
1469 typelib_TypeDescription * pTD )
1470 SAL_THROW( () )
1472 OSL_ASSERT( typelib_TypeClass_TYPEDEF != pTD->eTypeClass );
1474 switch( pTD->eTypeClass )
1476 case typelib_TypeClass_ARRAY:
1477 if( ((typelib_IndirectTypeDescription*)pTD)->pType )
1478 typelib_typedescriptionreference_release( ((typelib_IndirectTypeDescription*)pTD)->pType );
1479 delete [] ((typelib_ArrayTypeDescription *)pTD)->pDimensions;
1480 break;
1481 case typelib_TypeClass_SEQUENCE:
1482 if( ((typelib_IndirectTypeDescription*)pTD)->pType )
1483 typelib_typedescriptionreference_release( ((typelib_IndirectTypeDescription*)pTD)->pType );
1484 break;
1485 case typelib_TypeClass_UNION:
1487 typelib_UnionTypeDescription * pUnionTD = (typelib_UnionTypeDescription *)pTD;
1488 typelib_typedescriptionreference_release( pUnionTD->pDiscriminantTypeRef );
1489 typelib_typedescriptionreference_release( pUnionTD->pDefaultTypeRef );
1491 sal_Int32 nPos;
1492 typelib_TypeDescriptionReference ** ppTypeRefs = pUnionTD->ppTypeRefs;
1493 for ( nPos = pUnionTD->nMembers; nPos--; )
1495 typelib_typedescriptionreference_release( ppTypeRefs[nPos] );
1498 rtl_uString ** ppMemberNames = pUnionTD->ppMemberNames;
1499 for ( nPos = pUnionTD->nMembers; nPos--; )
1501 rtl_uString_release( ppMemberNames[nPos] );
1503 delete [] pUnionTD->ppMemberNames;
1504 delete [] pUnionTD->pDiscriminants;
1505 delete [] pUnionTD->ppTypeRefs;
1507 break;
1508 case typelib_TypeClass_STRUCT:
1509 delete[] reinterpret_cast< typelib_StructTypeDescription * >(pTD)->
1510 pParameterizedTypes;
1511 case typelib_TypeClass_EXCEPTION:
1513 typelib_CompoundTypeDescription * pCTD = (typelib_CompoundTypeDescription*)pTD;
1514 if( pCTD->pBaseTypeDescription )
1515 typelib_typedescription_release( (typelib_TypeDescription *)pCTD->pBaseTypeDescription );
1516 sal_Int32 i;
1517 for( i = 0; i < pCTD->nMembers; i++ )
1519 typelib_typedescriptionreference_release( pCTD->ppTypeRefs[i] );
1521 if (pCTD->ppMemberNames)
1523 for ( i = 0; i < pCTD->nMembers; i++ )
1525 rtl_uString_release( pCTD->ppMemberNames[i] );
1527 delete [] pCTD->ppMemberNames;
1529 delete [] pCTD->ppTypeRefs;
1530 delete [] pCTD->pMemberOffsets;
1532 break;
1533 case typelib_TypeClass_INTERFACE:
1535 typelib_InterfaceTypeDescription * pITD = (typelib_InterfaceTypeDescription*)pTD;
1536 {for( sal_Int32 i = 0; i < pITD->nAllMembers; i++ )
1538 typelib_typedescriptionreference_release( pITD->ppAllMembers[i] );
1540 delete [] pITD->ppAllMembers;
1541 delete [] pITD->pMapMemberIndexToFunctionIndex;
1542 delete [] pITD->pMapFunctionIndexToMemberIndex;
1543 {for (sal_Int32 i = 0; i < pITD->nBaseTypes; ++i) {
1544 typelib_typedescription_release(
1545 reinterpret_cast< typelib_TypeDescription * >(
1546 pITD->ppBaseTypes[i]));
1548 delete[] pITD->ppBaseTypes;
1549 break;
1551 case typelib_TypeClass_INTERFACE_METHOD:
1553 typelib_InterfaceMethodTypeDescription * pIMTD = (typelib_InterfaceMethodTypeDescription*)pTD;
1554 if( pIMTD->pReturnTypeRef )
1555 typelib_typedescriptionreference_release( pIMTD->pReturnTypeRef );
1556 for( sal_Int32 i = 0; i < pIMTD->nParams; i++ )
1558 rtl_uString_release( pIMTD->pParams[ i ].pName );
1559 typelib_typedescriptionreference_release( pIMTD->pParams[ i ].pTypeRef );
1561 delete [] pIMTD->pParams;
1562 deleteExceptions(pIMTD->nExceptions, pIMTD->ppExceptions);
1563 rtl_uString_release( pIMTD->aBase.pMemberName );
1564 typelib_typedescription_release(&pIMTD->pInterface->aBase);
1565 if (pIMTD->pBaseRef != 0) {
1566 typelib_typedescriptionreference_release(pIMTD->pBaseRef);
1569 break;
1570 case typelib_TypeClass_INTERFACE_ATTRIBUTE:
1572 typelib_InterfaceAttributeTypeDescription * pIATD = (typelib_InterfaceAttributeTypeDescription*)pTD;
1573 deleteExceptions(pIATD->nGetExceptions, pIATD->ppGetExceptions);
1574 deleteExceptions(pIATD->nSetExceptions, pIATD->ppSetExceptions);
1575 if( pIATD->pAttributeTypeRef )
1576 typelib_typedescriptionreference_release( pIATD->pAttributeTypeRef );
1577 if( pIATD->aBase.pMemberName )
1578 rtl_uString_release( pIATD->aBase.pMemberName );
1579 typelib_typedescription_release(&pIATD->pInterface->aBase);
1580 if (pIATD->pBaseRef != 0) {
1581 typelib_typedescriptionreference_release(pIATD->pBaseRef);
1584 break;
1585 case typelib_TypeClass_ENUM:
1587 typelib_EnumTypeDescription * pEnum = (typelib_EnumTypeDescription *)pTD;
1588 for ( sal_Int32 nPos = pEnum->nEnumValues; nPos--; )
1590 rtl_uString_release( pEnum->ppEnumNames[nPos] );
1592 delete [] pEnum->ppEnumNames;
1593 delete [] pEnum->pEnumValues;
1595 break;
1596 default:
1597 break;
1601 //------------------------------------------------------------------------
1602 extern "C" void SAL_CALL typelib_typedescription_release(
1603 typelib_TypeDescription * pTD )
1604 SAL_THROW_EXTERN_C()
1606 sal_Int32 ref = ::osl_decrementInterlockedCount( &pTD->nRefCount );
1607 OSL_ASSERT(ref >= 0);
1608 if (0 == ref)
1610 TypeDescriptor_Init_Impl &rInit = Init::get();
1611 if( reallyWeak( pTD->eTypeClass ) )
1613 if( pTD->pWeakRef )
1616 MutexGuard aGuard( rInit.getMutex() );
1617 // remove this description from the weak reference
1618 pTD->pWeakRef->pType = 0;
1620 typelib_typedescriptionreference_release( pTD->pWeakRef );
1623 else
1625 // this description is a reference too, so remove it from the hash table
1626 if( rInit.pWeakMap )
1628 MutexGuard aGuard( rInit.getMutex() );
1629 WeakMap_Impl::iterator aIt = rInit.pWeakMap->find( (sal_Unicode*)pTD->pTypeName->buffer );
1630 if( aIt != rInit.pWeakMap->end() && (void *)(*aIt).second == (void *)pTD )
1632 // remove only if it contains the same object
1633 rInit.pWeakMap->erase( aIt );
1638 typelib_typedescription_destructExtendedMembers( pTD );
1639 rtl_uString_release( pTD->pTypeName );
1641 #if OSL_DEBUG_LEVEL > 1
1642 switch( pTD->eTypeClass )
1644 case typelib_TypeClass_ARRAY:
1645 osl_decrementInterlockedCount( &rInit.nArrayTypeDescriptionCount );
1646 break;
1647 case typelib_TypeClass_SEQUENCE:
1648 osl_decrementInterlockedCount( &rInit.nIndirectTypeDescriptionCount );
1649 break;
1650 case typelib_TypeClass_UNION:
1651 osl_decrementInterlockedCount( &rInit.nUnionTypeDescriptionCount );
1652 break;
1653 case typelib_TypeClass_STRUCT:
1654 case typelib_TypeClass_EXCEPTION:
1655 osl_decrementInterlockedCount( &rInit.nCompoundTypeDescriptionCount );
1656 break;
1657 case typelib_TypeClass_INTERFACE:
1658 osl_decrementInterlockedCount( &rInit.nInterfaceTypeDescriptionCount );
1659 break;
1660 case typelib_TypeClass_INTERFACE_METHOD:
1661 osl_decrementInterlockedCount( &rInit.nInterfaceMethodTypeDescriptionCount );
1662 break;
1663 case typelib_TypeClass_INTERFACE_ATTRIBUTE:
1664 osl_decrementInterlockedCount( &rInit.nInterfaceAttributeTypeDescriptionCount );
1665 break;
1666 case typelib_TypeClass_ENUM:
1667 osl_decrementInterlockedCount( &rInit.nEnumTypeDescriptionCount );
1668 break;
1669 default:
1670 osl_decrementInterlockedCount( &rInit.nTypeDescriptionCount );
1672 #endif
1674 delete pTD;
1678 //------------------------------------------------------------------------
1679 extern "C" void SAL_CALL typelib_typedescription_register(
1680 typelib_TypeDescription ** ppNewDescription )
1681 SAL_THROW_EXTERN_C()
1683 // connect the description with the weak reference
1684 TypeDescriptor_Init_Impl &rInit = Init::get();
1685 ClearableMutexGuard aGuard( rInit.getMutex() );
1687 typelib_TypeDescriptionReference * pTDR = 0;
1688 typelib_typedescriptionreference_getByName( &pTDR, (*ppNewDescription)->pTypeName );
1690 OSL_ASSERT( (*ppNewDescription)->pWeakRef || reallyWeak( (*ppNewDescription)->eTypeClass ) );
1691 if( pTDR )
1693 OSL_ASSERT( (*ppNewDescription)->eTypeClass == pTDR->eTypeClass );
1694 if( pTDR->pType )
1696 if (reallyWeak( pTDR->eTypeClass ))
1698 // pRef->pType->pWeakRef == 0 means that the description is empty
1699 if (pTDR->pType->pWeakRef)
1701 if (osl_incrementInterlockedCount( &pTDR->pType->nRefCount ) > 1)
1703 // The refence is incremented. The object cannot be destroyed.
1704 // Release the guard at the earliest point.
1705 aGuard.clear();
1706 ::typelib_typedescription_release( *ppNewDescription );
1707 *ppNewDescription = pTDR->pType;
1708 ::typelib_typedescriptionreference_release( pTDR );
1709 return;
1711 else
1713 // destruction of this type in progress (another thread!)
1714 osl_decrementInterlockedCount( &pTDR->pType->nRefCount );
1717 // take new descr
1718 pTDR->pType = *ppNewDescription;
1719 OSL_ASSERT( ! (*ppNewDescription)->pWeakRef );
1720 (*ppNewDescription)->pWeakRef = pTDR;
1721 return;
1723 // !reallyWeak
1725 if (((void *)pTDR != (void *)*ppNewDescription) && // if different
1726 (!pTDR->pType->pWeakRef || // uninit: ref data only set
1727 // new one is complete:
1728 (!pTDR->pType->bComplete && (*ppNewDescription)->bComplete) ||
1729 // new one may be partly initialized interface (except of tables):
1730 (typelib_TypeClass_INTERFACE == pTDR->pType->eTypeClass &&
1731 !((typelib_InterfaceTypeDescription *)pTDR->pType)->ppAllMembers &&
1732 (*(typelib_InterfaceTypeDescription **)ppNewDescription)->ppAllMembers)))
1734 // uninitialized or incomplete
1736 if (pTDR->pType->pWeakRef) // if init
1738 typelib_typedescription_destructExtendedMembers( pTDR->pType );
1741 // pTDR->pType->pWeakRef == 0 means that the description is empty
1742 // description is not weak and the not the same
1743 sal_Int32 nSize = getDescriptionSize( (*ppNewDescription)->eTypeClass );
1745 // copy all specific data for the descriptions
1746 ::rtl_copyMemory(
1747 pTDR->pType +1,
1748 *ppNewDescription +1,
1749 nSize - sizeof(typelib_TypeDescription) );
1751 pTDR->pType->bComplete = (*ppNewDescription)->bComplete;
1752 pTDR->pType->nSize = (*ppNewDescription)->nSize;
1753 pTDR->pType->nAlignment = (*ppNewDescription)->nAlignment;
1755 ::rtl_zeroMemory(
1756 *ppNewDescription +1, nSize - sizeof( typelib_TypeDescription ) );
1758 if( pTDR->pType->bOnDemand && !(*ppNewDescription)->bOnDemand )
1760 // switch from OnDemand to !OnDemand, so the description must be acquired
1761 typelib_typedescription_acquire( pTDR->pType );
1763 else if( !pTDR->pType->bOnDemand && (*ppNewDescription)->bOnDemand )
1765 // switch from !OnDemand to OnDemand, so the description must be relesed
1766 typelib_typedescription_release( pTDR->pType );
1769 pTDR->pType->bOnDemand = (*ppNewDescription)->bOnDemand;
1770 // initialized
1771 pTDR->pType->pWeakRef = pTDR;
1774 typelib_typedescription_release( *ppNewDescription );
1775 // pTDR was acquired by getByName(), so it must not be acquired again
1776 *ppNewDescription = pTDR->pType;
1777 return;
1780 else if( reallyWeak( (*ppNewDescription)->eTypeClass) )
1782 typelib_typedescriptionreference_new(
1783 &pTDR, (*ppNewDescription)->eTypeClass, (*ppNewDescription)->pTypeName );
1785 else
1787 pTDR = (typelib_TypeDescriptionReference *)*ppNewDescription;
1788 if( !rInit.pWeakMap )
1789 rInit.pWeakMap = new WeakMap_Impl;
1791 // description is the weak itself, so register it
1792 (*rInit.pWeakMap)[pTDR->pTypeName->buffer] = pTDR;
1793 OSL_ASSERT( (void *)*ppNewDescription == (void *)pTDR );
1796 // By default this reference is not really weak. The reference hold the description
1797 // and the description hold the reference.
1798 if( !(*ppNewDescription)->bOnDemand )
1800 // nor OnDemand so the description must be acquired if registered
1801 typelib_typedescription_acquire( *ppNewDescription );
1804 pTDR->pType = *ppNewDescription;
1805 (*ppNewDescription)->pWeakRef = pTDR;
1806 OSL_ASSERT( rtl_ustr_compare( pTDR->pTypeName->buffer, (*ppNewDescription)->pTypeName->buffer ) == 0 );
1807 OSL_ASSERT( pTDR->eTypeClass == (*ppNewDescription)->eTypeClass );
1810 //------------------------------------------------------------------------
1811 static inline sal_Bool type_equals(
1812 typelib_TypeDescriptionReference * p1, typelib_TypeDescriptionReference * p2 )
1813 SAL_THROW( () )
1815 return (p1 == p2 ||
1816 (p1->eTypeClass == p2->eTypeClass &&
1817 p1->pTypeName->length == p2->pTypeName->length &&
1818 rtl_ustr_compare( p1->pTypeName->buffer, p2->pTypeName->buffer ) == 0));
1820 extern "C" sal_Bool SAL_CALL typelib_typedescription_equals(
1821 const typelib_TypeDescription * p1, const typelib_TypeDescription * p2 )
1822 SAL_THROW_EXTERN_C()
1824 return type_equals(
1825 (typelib_TypeDescriptionReference *)p1, (typelib_TypeDescriptionReference *)p2 );
1828 //------------------------------------------------------------------------
1829 extern "C" sal_Int32 SAL_CALL typelib_typedescription_getAlignedUnoSize(
1830 const typelib_TypeDescription * pTypeDescription,
1831 sal_Int32 nOffset, sal_Int32 & rMaxIntegralTypeSize )
1832 SAL_THROW_EXTERN_C()
1834 sal_Int32 nSize;
1835 if( pTypeDescription->nSize )
1837 // size and alignment are set
1838 rMaxIntegralTypeSize = pTypeDescription->nAlignment;
1839 nSize = pTypeDescription->nSize;
1841 else
1843 nSize = 0;
1844 rMaxIntegralTypeSize = 1;
1846 OSL_ASSERT( typelib_TypeClass_TYPEDEF != pTypeDescription->eTypeClass );
1848 switch( pTypeDescription->eTypeClass )
1850 case typelib_TypeClass_INTERFACE:
1851 // FEATURE_INTERFACE
1852 nSize = rMaxIntegralTypeSize = (sal_Int32)(sizeof( void * ));
1853 break;
1854 case typelib_TypeClass_UNION:
1856 nSize = rMaxIntegralTypeSize = (sal_Int32)(sizeof(sal_Int64));
1857 for ( sal_Int32 nPos = ((typelib_UnionTypeDescription *)pTypeDescription)->nMembers; nPos--; )
1859 typelib_TypeDescription * pTD = 0;
1860 TYPELIB_DANGER_GET( &pTD, ((typelib_UnionTypeDescription *)pTypeDescription)->ppTypeRefs[nPos] );
1861 sal_Int32 nMaxIntegralTypeSize;
1862 sal_Int32 nMemberSize = typelib_typedescription_getAlignedUnoSize( pTD, (sal_Int32)(sizeof(sal_Int64)), nMaxIntegralTypeSize );
1863 TYPELIB_DANGER_RELEASE( pTD );
1864 if (nSize < nMemberSize)
1865 nSize = nMemberSize;
1866 if (rMaxIntegralTypeSize < nMaxIntegralTypeSize)
1867 rMaxIntegralTypeSize = nMaxIntegralTypeSize;
1869 ((typelib_UnionTypeDescription *)pTypeDescription)->nValueOffset = rMaxIntegralTypeSize;
1871 break;
1872 case typelib_TypeClass_ENUM:
1873 nSize = rMaxIntegralTypeSize = (sal_Int32)(sizeof( typelib_TypeClass ));
1874 break;
1875 case typelib_TypeClass_STRUCT:
1876 case typelib_TypeClass_EXCEPTION:
1877 // FEATURE_EMPTYCLASS
1879 typelib_CompoundTypeDescription * pTmp = (typelib_CompoundTypeDescription *)pTypeDescription;
1880 sal_Int32 nStructSize = 0;
1881 if( pTmp->pBaseTypeDescription )
1883 // inherit structs extends the base struct.
1884 nStructSize = pTmp->pBaseTypeDescription->aBase.nSize;
1885 rMaxIntegralTypeSize = pTmp->pBaseTypeDescription->aBase.nAlignment;
1887 for( sal_Int32 i = 0; i < pTmp->nMembers; i++ )
1889 typelib_TypeDescription * pMemberType = 0;
1890 typelib_TypeDescriptionReference * pMemberRef = pTmp->ppTypeRefs[i];
1892 sal_Int32 nMaxIntegral;
1893 if (pMemberRef->eTypeClass == typelib_TypeClass_INTERFACE
1894 || pMemberRef->eTypeClass == typelib_TypeClass_SEQUENCE)
1896 nMaxIntegral = (sal_Int32)(sizeof(void *));
1897 nStructSize = newAlignedSize( nStructSize, nMaxIntegral, nMaxIntegral );
1899 else
1901 TYPELIB_DANGER_GET( &pMemberType, pMemberRef );
1902 nStructSize = typelib_typedescription_getAlignedUnoSize(
1903 pMemberType, nStructSize, nMaxIntegral );
1904 TYPELIB_DANGER_RELEASE( pMemberType );
1906 if( nMaxIntegral > rMaxIntegralTypeSize )
1907 rMaxIntegralTypeSize = nMaxIntegral;
1909 #ifdef __m68k__
1910 // Anything that is at least 16 bits wide is aligned on a 16-bit
1911 // boundary on the m68k default abi
1912 sal_Int32 nMaxAlign = (rMaxIntegralTypeSize > 2) ? 2 : rMaxIntegralTypeSize;
1913 nStructSize = (nStructSize + nMaxAlign -1) / nMaxAlign * nMaxAlign;
1914 #else
1915 // Example: A { double; int; } structure has a size of 16 instead of 10. The
1916 // compiler must follow this rule if it is possible to access members in arrays through:
1917 // (Element *)((char *)pArray + sizeof( Element ) * ElementPos)
1918 nStructSize = (nStructSize + rMaxIntegralTypeSize -1)
1919 / rMaxIntegralTypeSize * rMaxIntegralTypeSize;
1920 #endif
1921 nSize += nStructSize;
1923 break;
1924 case typelib_TypeClass_ARRAY:
1926 typelib_TypeDescription * pTD = 0;
1927 TYPELIB_DANGER_GET( &pTD, ((typelib_IndirectTypeDescription *)pTypeDescription)->pType );
1928 rMaxIntegralTypeSize = pTD->nSize;
1929 TYPELIB_DANGER_RELEASE( pTD );
1930 nSize = ((typelib_ArrayTypeDescription *)pTypeDescription)->nTotalElements * rMaxIntegralTypeSize;
1932 break;
1933 case typelib_TypeClass_SEQUENCE:
1934 nSize = rMaxIntegralTypeSize = (sal_Int32)(sizeof( void * ));
1935 break;
1936 case typelib_TypeClass_ANY:
1937 // FEATURE_ANY
1938 nSize = (sal_Int32)(sizeof( uno_Any ));
1939 rMaxIntegralTypeSize = (sal_Int32)(sizeof( void * ));
1940 break;
1941 case typelib_TypeClass_TYPE:
1942 nSize = rMaxIntegralTypeSize = (sal_Int32)(sizeof( typelib_TypeDescriptionReference * ));
1943 break;
1944 case typelib_TypeClass_BOOLEAN:
1945 nSize = rMaxIntegralTypeSize = (sal_Int32)(sizeof( sal_Bool ));
1946 break;
1947 case typelib_TypeClass_CHAR:
1948 nSize = rMaxIntegralTypeSize = (sal_Int32)(sizeof( sal_Unicode ));
1949 break;
1950 case typelib_TypeClass_STRING:
1951 // FEATURE_STRING
1952 nSize = rMaxIntegralTypeSize = (sal_Int32)(sizeof( rtl_uString * ));
1953 break;
1954 case typelib_TypeClass_FLOAT:
1955 nSize = rMaxIntegralTypeSize = (sal_Int32)(sizeof( float ));
1956 break;
1957 case typelib_TypeClass_DOUBLE:
1958 nSize = rMaxIntegralTypeSize = (sal_Int32)(sizeof( double ));
1959 break;
1960 case typelib_TypeClass_BYTE:
1961 nSize = rMaxIntegralTypeSize = (sal_Int32)(sizeof( sal_Int8 ));
1962 break;
1963 case typelib_TypeClass_SHORT:
1964 case typelib_TypeClass_UNSIGNED_SHORT:
1965 nSize = rMaxIntegralTypeSize = (sal_Int32)(sizeof( sal_Int16 ));
1966 break;
1967 case typelib_TypeClass_LONG:
1968 case typelib_TypeClass_UNSIGNED_LONG:
1969 nSize = rMaxIntegralTypeSize = (sal_Int32)(sizeof( sal_Int32 ));
1970 break;
1971 case typelib_TypeClass_HYPER:
1972 case typelib_TypeClass_UNSIGNED_HYPER:
1973 nSize = rMaxIntegralTypeSize = (sal_Int32)(sizeof( sal_Int64 ));
1974 break;
1975 case typelib_TypeClass_UNKNOWN:
1976 case typelib_TypeClass_SERVICE:
1977 case typelib_TypeClass_MODULE:
1978 default:
1979 OSL_ENSURE( sal_False, "not convertable type" );
1983 return newAlignedSize( nOffset, nSize, rMaxIntegralTypeSize );
1986 //------------------------------------------------------------------------
1988 namespace {
1990 typelib_TypeDescriptionReference ** copyExceptions(
1991 sal_Int32 count, typelib_TypeDescriptionReference ** source)
1993 typelib_TypeDescriptionReference ** p
1994 = new typelib_TypeDescriptionReference *[count];
1995 for (sal_Int32 i = 0; i < count; ++i) {
1996 typelib_typedescriptionreference_acquire(p[i] = source[i]);
1998 return p;
2001 bool createDerivedInterfaceMemberDescription(
2002 typelib_TypeDescription ** result, rtl::OUString const & name,
2003 typelib_TypeDescriptionReference * baseRef,
2004 typelib_TypeDescription const * base, typelib_TypeDescription * interface,
2005 sal_Int32 index, sal_Int32 position)
2007 if (baseRef != 0 && base != 0 && interface != 0) {
2008 switch (base->eTypeClass) {
2009 case typelib_TypeClass_INTERFACE_METHOD:
2011 typelib_typedescription_newEmpty(
2012 result, typelib_TypeClass_INTERFACE_METHOD, name.pData);
2013 typelib_InterfaceMethodTypeDescription const * baseMethod
2014 = reinterpret_cast<
2015 typelib_InterfaceMethodTypeDescription const * >(base);
2016 typelib_InterfaceMethodTypeDescription * newMethod
2017 = reinterpret_cast<
2018 typelib_InterfaceMethodTypeDescription * >(*result);
2019 newMethod->aBase.nPosition = position;
2020 rtl_uString_acquire(
2021 newMethod->aBase.pMemberName
2022 = baseMethod->aBase.pMemberName);
2023 typelib_typedescriptionreference_acquire(
2024 newMethod->pReturnTypeRef = baseMethod->pReturnTypeRef);
2025 newMethod->nParams = baseMethod->nParams;
2026 newMethod->pParams = new typelib_MethodParameter[
2027 newMethod->nParams];
2028 for (sal_Int32 i = 0; i < newMethod->nParams; ++i) {
2029 rtl_uString_acquire(
2030 newMethod->pParams[i].pName
2031 = baseMethod->pParams[i].pName);
2032 typelib_typedescriptionreference_acquire(
2033 newMethod->pParams[i].pTypeRef
2034 = baseMethod->pParams[i].pTypeRef);
2035 newMethod->pParams[i].bIn = baseMethod->pParams[i].bIn;
2036 newMethod->pParams[i].bOut = baseMethod->pParams[i].bOut;
2038 newMethod->nExceptions = baseMethod->nExceptions;
2039 newMethod->ppExceptions = copyExceptions(
2040 baseMethod->nExceptions, baseMethod->ppExceptions);
2041 newMethod->bOneWay = baseMethod->bOneWay;
2042 newMethod->pInterface
2043 = reinterpret_cast< typelib_InterfaceTypeDescription * >(
2044 interface);
2045 newMethod->pBaseRef = baseRef;
2046 newMethod->nIndex = index;
2047 return true;
2050 case typelib_TypeClass_INTERFACE_ATTRIBUTE:
2052 typelib_typedescription_newEmpty(
2053 result, typelib_TypeClass_INTERFACE_ATTRIBUTE, name.pData);
2054 typelib_InterfaceAttributeTypeDescription const * baseAttribute
2055 = reinterpret_cast<
2056 typelib_InterfaceAttributeTypeDescription const * >(base);
2057 typelib_InterfaceAttributeTypeDescription * newAttribute
2058 = reinterpret_cast<
2059 typelib_InterfaceAttributeTypeDescription * >(*result);
2060 newAttribute->aBase.nPosition = position;
2061 rtl_uString_acquire(
2062 newAttribute->aBase.pMemberName
2063 = baseAttribute->aBase.pMemberName);
2064 newAttribute->bReadOnly = baseAttribute->bReadOnly;
2065 typelib_typedescriptionreference_acquire(
2066 newAttribute->pAttributeTypeRef
2067 = baseAttribute->pAttributeTypeRef);
2068 newAttribute->pInterface
2069 = reinterpret_cast< typelib_InterfaceTypeDescription * >(
2070 interface);
2071 newAttribute->pBaseRef = baseRef;
2072 newAttribute->nIndex = index;
2073 newAttribute->nGetExceptions = baseAttribute->nGetExceptions;
2074 newAttribute->ppGetExceptions = copyExceptions(
2075 baseAttribute->nGetExceptions,
2076 baseAttribute->ppGetExceptions);
2077 newAttribute->nSetExceptions = baseAttribute->nSetExceptions;
2078 newAttribute->ppSetExceptions = copyExceptions(
2079 baseAttribute->nSetExceptions,
2080 baseAttribute->ppSetExceptions);
2081 return true;
2084 default:
2085 break;
2088 return false;
2093 extern "C" void SAL_CALL typelib_typedescription_getByName(
2094 typelib_TypeDescription ** ppRet, rtl_uString * pName )
2095 SAL_THROW_EXTERN_C()
2097 if( *ppRet )
2099 typelib_typedescription_release( (*ppRet) );
2100 *ppRet = 0;
2103 static sal_Bool bInited = sal_False;
2104 TypeDescriptor_Init_Impl &rInit = Init::get();
2106 if( !bInited )
2108 // guard against multi thread access
2109 MutexGuard aGuard( rInit.getMutex() );
2110 if( !bInited )
2112 // avoid recursion during the next ...new calls
2113 bInited = sal_True;
2115 rtl_uString * pTypeName = 0;
2116 typelib_TypeDescription * pType = 0;
2117 rtl_uString_newFromAscii( &pTypeName, "type" );
2118 typelib_typedescription_new( &pType, typelib_TypeClass_TYPE, pTypeName, 0, 0, 0 );
2119 typelib_typedescription_register( &pType );
2120 rtl_uString_newFromAscii( &pTypeName, "void" );
2121 typelib_typedescription_new( &pType, typelib_TypeClass_VOID, pTypeName, 0, 0, 0 );
2122 typelib_typedescription_register( &pType );
2123 rtl_uString_newFromAscii( &pTypeName, "boolean" );
2124 typelib_typedescription_new( &pType, typelib_TypeClass_BOOLEAN, pTypeName, 0, 0, 0 );
2125 typelib_typedescription_register( &pType );
2126 rtl_uString_newFromAscii( &pTypeName, "char" );
2127 typelib_typedescription_new( &pType, typelib_TypeClass_CHAR, pTypeName, 0, 0, 0 );
2128 typelib_typedescription_register( &pType );
2129 rtl_uString_newFromAscii( &pTypeName, "byte" );
2130 typelib_typedescription_new( &pType, typelib_TypeClass_BYTE, pTypeName, 0, 0, 0 );
2131 typelib_typedescription_register( &pType );
2132 rtl_uString_newFromAscii( &pTypeName, "string" );
2133 typelib_typedescription_new( &pType, typelib_TypeClass_STRING, pTypeName, 0, 0, 0 );
2134 typelib_typedescription_register( &pType );
2135 rtl_uString_newFromAscii( &pTypeName, "short" );
2136 typelib_typedescription_new( &pType, typelib_TypeClass_SHORT, pTypeName, 0, 0, 0 );
2137 typelib_typedescription_register( &pType );
2138 rtl_uString_newFromAscii( &pTypeName, "unsigned short" );
2139 typelib_typedescription_new( &pType, typelib_TypeClass_UNSIGNED_SHORT, pTypeName, 0, 0, 0 );
2140 typelib_typedescription_register( &pType );
2141 rtl_uString_newFromAscii( &pTypeName, "long" );
2142 typelib_typedescription_new( &pType, typelib_TypeClass_LONG, pTypeName, 0, 0, 0 );
2143 typelib_typedescription_register( &pType );
2144 rtl_uString_newFromAscii( &pTypeName, "unsigned long" );
2145 typelib_typedescription_new( &pType, typelib_TypeClass_UNSIGNED_LONG, pTypeName, 0, 0, 0 );
2146 typelib_typedescription_register( &pType );
2147 rtl_uString_newFromAscii( &pTypeName, "hyper" );
2148 typelib_typedescription_new( &pType, typelib_TypeClass_HYPER, pTypeName, 0, 0, 0 );
2149 typelib_typedescription_register( &pType );
2150 rtl_uString_newFromAscii( &pTypeName, "unsigned hyper" );
2151 typelib_typedescription_new( &pType, typelib_TypeClass_UNSIGNED_HYPER, pTypeName, 0, 0, 0 );
2152 typelib_typedescription_register( &pType );
2153 rtl_uString_newFromAscii( &pTypeName, "float" );
2154 typelib_typedescription_new( &pType, typelib_TypeClass_FLOAT, pTypeName, 0, 0, 0 );
2155 typelib_typedescription_register( &pType );
2156 rtl_uString_newFromAscii( &pTypeName, "double" );
2157 typelib_typedescription_new( &pType, typelib_TypeClass_DOUBLE, pTypeName, 0, 0, 0 );
2158 typelib_typedescription_register( &pType );
2159 rtl_uString_newFromAscii( &pTypeName, "any" );
2160 typelib_typedescription_new( &pType, typelib_TypeClass_ANY, pTypeName, 0, 0, 0 );
2161 typelib_typedescription_register( &pType );
2162 typelib_typedescription_release( pType );
2163 rtl_uString_release( pTypeName );
2167 typelib_TypeDescriptionReference * pTDR = 0;
2168 typelib_typedescriptionreference_getByName( &pTDR, pName );
2169 if( pTDR )
2172 // guard against multi thread access
2173 MutexGuard aGuard( rInit.getMutex() );
2174 // pTDR->pType->pWeakRef == 0 means that the description is empty
2175 if( pTDR->pType && pTDR->pType->pWeakRef )
2177 typelib_typedescription_acquire( pTDR->pType );
2178 *ppRet = pTDR->pType;
2181 typelib_typedescriptionreference_release( pTDR );
2184 if (0 == *ppRet)
2186 // check for sequence
2187 OUString const & name = *reinterpret_cast< OUString const * >( &pName );
2188 if (2 < name.getLength() && '[' == name[ 0 ])
2190 OUString element_name( name.copy( 2 ) );
2191 typelib_TypeDescription * element_td = 0;
2192 typelib_typedescription_getByName( &element_td, element_name.pData );
2193 if (0 != element_td)
2195 typelib_typedescription_new(
2196 ppRet, typelib_TypeClass_SEQUENCE, pName, element_td->pWeakRef, 0, 0 );
2197 // register?
2198 typelib_typedescription_release( element_td );
2201 if (0 == *ppRet)
2203 // Check for derived interface member type:
2204 sal_Int32 i1 = name.lastIndexOf(
2205 rtl::OUString::createFromAscii(":@"));
2206 if (i1 >= 0) {
2207 sal_Int32 i2 = i1 + RTL_CONSTASCII_LENGTH(":@");
2208 sal_Int32 i3 = name.indexOf(',', i2);
2209 if (i3 >= 0) {
2210 sal_Int32 i4 = name.indexOf(':', i3);
2211 if (i4 >= 0) {
2212 typelib_TypeDescriptionReference * pBaseRef = 0;
2213 typelib_TypeDescription * pBase = 0;
2214 typelib_TypeDescription * pInterface = 0;
2215 typelib_typedescriptionreference_getByName(
2216 &pBaseRef, name.copy(0, i1).pData);
2217 if (pBaseRef != 0) {
2218 typelib_typedescriptionreference_getDescription(
2219 &pBase, pBaseRef);
2221 typelib_typedescription_getByName(
2222 &pInterface, name.copy(i4 + 1).pData);
2223 if (!createDerivedInterfaceMemberDescription(
2224 ppRet, name, pBaseRef, pBase, pInterface,
2225 name.copy(i2, i3 - i2).toInt32(),
2226 name.copy(i3 + 1, i4 - i3 - 1).toInt32()))
2228 if (pInterface != 0) {
2229 typelib_typedescription_release(pInterface);
2231 if (pBase != 0) {
2232 typelib_typedescription_release(pBase);
2234 if (pBaseRef != 0) {
2235 typelib_typedescriptionreference_release(
2236 pBaseRef);
2243 if (0 == *ppRet)
2245 // on demand access
2246 rInit.callChain( ppRet, pName );
2249 if( *ppRet )
2251 // typedescription found
2252 if (typelib_TypeClass_TYPEDEF == (*ppRet)->eTypeClass)
2254 typelib_TypeDescription * pTD = 0;
2255 typelib_typedescriptionreference_getDescription(
2256 &pTD, ((typelib_IndirectTypeDescription *)*ppRet)->pType );
2257 typelib_typedescription_release( *ppRet );
2258 *ppRet = pTD;
2260 else
2262 // set to on demand
2263 (*ppRet)->bOnDemand = sal_True;
2264 // The type description is hold by the reference until
2265 // on demand is activated.
2266 typelib_typedescription_register( ppRet );
2268 // insert into the chache
2269 MutexGuard aGuard( rInit.getMutex() );
2270 if( !rInit.pCache )
2271 rInit.pCache = new TypeDescriptionList_Impl;
2272 if( (sal_Int32)rInit.pCache->size() >= nCacheSize )
2274 typelib_typedescription_release( rInit.pCache->front() );
2275 rInit.pCache->pop_front();
2277 // descriptions in the cache must be acquired!
2278 typelib_typedescription_acquire( *ppRet );
2279 rInit.pCache->push_back( *ppRet );
2286 //------------------------------------------------------------------------
2287 //------------------------------------------------------------------------
2288 //------------------------------------------------------------------------
2289 extern "C" void SAL_CALL typelib_typedescriptionreference_newByAsciiName(
2290 typelib_TypeDescriptionReference ** ppTDR,
2291 typelib_TypeClass eTypeClass,
2292 const sal_Char * pTypeName )
2293 SAL_THROW_EXTERN_C()
2295 OUString aTypeName( OUString::createFromAscii( pTypeName ) );
2296 typelib_typedescriptionreference_new( ppTDR, eTypeClass, aTypeName.pData );
2298 //------------------------------------------------------------------------
2299 extern "C" void SAL_CALL typelib_typedescriptionreference_new(
2300 typelib_TypeDescriptionReference ** ppTDR,
2301 typelib_TypeClass eTypeClass, rtl_uString * pTypeName )
2302 SAL_THROW_EXTERN_C()
2304 TypeDescriptor_Init_Impl &rInit = Init::get();
2305 if( eTypeClass == typelib_TypeClass_TYPEDEF )
2307 // on demand access
2308 typelib_TypeDescription * pRet = 0;
2309 rInit.callChain( &pRet, pTypeName );
2310 if( pRet )
2312 // typedescription found
2313 if (typelib_TypeClass_TYPEDEF == pRet->eTypeClass)
2315 typelib_typedescriptionreference_acquire(
2316 ((typelib_IndirectTypeDescription *)pRet)->pType );
2317 if (*ppTDR)
2318 typelib_typedescriptionreference_release( *ppTDR );
2319 *ppTDR = ((typelib_IndirectTypeDescription *)pRet)->pType;
2320 typelib_typedescription_release( pRet );
2322 else
2324 // set to on demand
2325 pRet->bOnDemand = sal_True;
2326 // The type description is hold by the reference until
2327 // on demand is activated.
2328 typelib_typedescription_register( &pRet );
2330 // insert into the chache
2331 MutexGuard aGuard( rInit.getMutex() );
2332 if( !rInit.pCache )
2333 rInit.pCache = new TypeDescriptionList_Impl;
2334 if( (sal_Int32)rInit.pCache->size() >= nCacheSize )
2336 typelib_typedescription_release( rInit.pCache->front() );
2337 rInit.pCache->pop_front();
2339 rInit.pCache->push_back( pRet );
2340 // pRet kept acquired for cache
2342 typelib_typedescriptionreference_acquire( pRet->pWeakRef );
2343 if (*ppTDR)
2344 typelib_typedescriptionreference_release( *ppTDR );
2345 *ppTDR = pRet->pWeakRef;
2348 else if (*ppTDR)
2350 #if OSL_DEBUG_LEVEL > 1
2351 OString aStr( OUStringToOString( pTypeName, RTL_TEXTENCODING_ASCII_US ) );
2352 OSL_ENSURE( !"### typedef not found: ", aStr.getStr() );
2353 #endif
2354 typelib_typedescriptionreference_release( *ppTDR );
2355 *ppTDR = 0;
2357 return;
2360 MutexGuard aGuard( rInit.getMutex() );
2361 typelib_typedescriptionreference_getByName( ppTDR, pTypeName );
2362 if( *ppTDR )
2363 return;
2365 if( reallyWeak( eTypeClass ) )
2367 typelib_TypeDescriptionReference * pTDR = new typelib_TypeDescriptionReference();
2368 #if OSL_DEBUG_LEVEL > 1
2369 osl_incrementInterlockedCount( &rInit.nTypeDescriptionReferenceCount );
2370 #endif
2371 pTDR->nRefCount = 1;
2372 pTDR->nStaticRefCount = 0;
2373 pTDR->eTypeClass = eTypeClass;
2374 pTDR->pUniqueIdentifier = 0;
2375 pTDR->pReserved = 0;
2376 rtl_uString_acquire( pTDR->pTypeName = pTypeName );
2377 pTDR->pType = 0;
2378 *ppTDR = pTDR;
2380 else
2382 typelib_typedescription_newEmpty( (typelib_TypeDescription ** )ppTDR, eTypeClass, pTypeName );
2383 // description will be registered but not acquired
2384 (*(typelib_TypeDescription ** )ppTDR)->bOnDemand = sal_True;
2385 (*(typelib_TypeDescription ** )ppTDR)->bComplete = sal_False;
2388 if( !rInit.pWeakMap )
2389 rInit.pWeakMap = new WeakMap_Impl;
2390 // Heavy hack, the const sal_Unicode * is hold by the typedescription reference
2391 // not registered
2392 rInit.pWeakMap->operator[]( (*ppTDR)->pTypeName->buffer ) = *ppTDR;
2395 //------------------------------------------------------------------------
2396 extern "C" void SAL_CALL typelib_typedescriptionreference_acquire(
2397 typelib_TypeDescriptionReference * pRef )
2398 SAL_THROW_EXTERN_C()
2400 ::osl_incrementInterlockedCount( &pRef->nRefCount );
2403 //------------------------------------------------------------------------
2404 extern "C" void SAL_CALL typelib_typedescriptionreference_release(
2405 typelib_TypeDescriptionReference * pRef )
2406 SAL_THROW_EXTERN_C()
2408 // Is it a type description?
2409 if( reallyWeak( pRef->eTypeClass ) )
2411 if( ! ::osl_decrementInterlockedCount( &pRef->nRefCount ) )
2413 TypeDescriptor_Init_Impl &rInit = Init::get();
2414 if( rInit.pWeakMap )
2416 MutexGuard aGuard( rInit.getMutex() );
2417 WeakMap_Impl::iterator aIt = rInit.pWeakMap->find( (sal_Unicode*)pRef->pTypeName->buffer );
2418 if( !(aIt == rInit.pWeakMap->end()) && (*aIt).second == pRef )
2420 // remove only if it contains the same object
2421 rInit.pWeakMap->erase( aIt );
2425 rtl_uString_release( pRef->pTypeName );
2426 OSL_ASSERT( pRef->pType == 0 );
2427 #if OSL_DEBUG_LEVEL > 1
2428 osl_decrementInterlockedCount( &rInit.nTypeDescriptionReferenceCount );
2429 #endif
2430 delete pRef;
2433 else
2435 typelib_typedescription_release( (typelib_TypeDescription *)pRef );
2439 //------------------------------------------------------------------------
2440 extern "C" void SAL_CALL typelib_typedescriptionreference_getDescription(
2441 typelib_TypeDescription ** ppRet, typelib_TypeDescriptionReference * pRef )
2442 SAL_THROW_EXTERN_C()
2444 if( *ppRet )
2446 typelib_typedescription_release( *ppRet );
2447 *ppRet = 0;
2450 if( !reallyWeak( pRef->eTypeClass ) && pRef->pType && pRef->pType->pWeakRef )
2452 // reference is a description and initialized
2453 osl_incrementInterlockedCount( &((typelib_TypeDescription *)pRef)->nRefCount );
2454 *ppRet = (typelib_TypeDescription *)pRef;
2455 return;
2459 MutexGuard aGuard( Init::get().getMutex() );
2460 // pRef->pType->pWeakRef == 0 means that the description is empty
2461 if( pRef->pType && pRef->pType->pWeakRef )
2463 sal_Int32 n = ::osl_incrementInterlockedCount( &pRef->pType->nRefCount );
2464 if( n > 1 )
2466 // The refence is incremented. The object cannot be destroyed.
2467 // Release the guard at the earliest point.
2468 *ppRet = pRef->pType;
2469 return;
2471 else
2473 ::osl_decrementInterlockedCount( &pRef->pType->nRefCount );
2474 // detruction of this type in progress (another thread!)
2475 // no acces through this weak reference
2476 pRef->pType = 0;
2481 typelib_typedescription_getByName( ppRet, pRef->pTypeName );
2482 OSL_ASSERT( !*ppRet || rtl_ustr_compare( pRef->pTypeName->buffer, (*ppRet)->pTypeName->buffer ) == 0 );
2483 OSL_ASSERT( !*ppRet || pRef->eTypeClass == (*ppRet)->eTypeClass );
2484 OSL_ASSERT( !*ppRet || pRef == (*ppRet)->pWeakRef );
2485 pRef->pType = *ppRet;
2488 //------------------------------------------------------------------------
2489 extern "C" void SAL_CALL typelib_typedescriptionreference_getByName(
2490 typelib_TypeDescriptionReference ** ppRet, rtl_uString * pName )
2491 SAL_THROW_EXTERN_C()
2493 if( *ppRet )
2495 typelib_typedescriptionreference_release( *ppRet );
2496 *ppRet = 0;
2498 TypeDescriptor_Init_Impl &rInit = Init::get();
2499 if( rInit.pWeakMap )
2501 MutexGuard aGuard( rInit.getMutex() );
2502 WeakMap_Impl::const_iterator aIt = rInit.pWeakMap->find( (sal_Unicode*)pName->buffer );
2503 if( !(aIt == rInit.pWeakMap->end()) ) // != failed on msc4.2
2505 sal_Int32 n = ::osl_incrementInterlockedCount( &(*aIt).second->nRefCount );
2506 if( n > 1 )
2508 // The refence is incremented. The object cannot be destroyed.
2509 // Release the guard at the earliest point.
2510 *ppRet = (*aIt).second;
2512 else
2514 // detruction of this type in progress (another thread!)
2515 // no acces through this weak reference
2516 ::osl_decrementInterlockedCount( &(*aIt).second->nRefCount );
2522 //------------------------------------------------------------------------
2523 extern "C" sal_Bool SAL_CALL typelib_typedescriptionreference_equals(
2524 const typelib_TypeDescriptionReference * p1,
2525 const typelib_TypeDescriptionReference * p2 )
2526 SAL_THROW_EXTERN_C()
2528 return (p1 == p2 ||
2529 (p1->eTypeClass == p2->eTypeClass &&
2530 p1->pTypeName->length == p2->pTypeName->length &&
2531 rtl_ustr_compare( p1->pTypeName->buffer, p2->pTypeName->buffer ) == 0));
2534 //##################################################################################################
2535 extern "C" void SAL_CALL typelib_typedescriptionreference_assign(
2536 typelib_TypeDescriptionReference ** ppDest,
2537 typelib_TypeDescriptionReference * pSource )
2538 SAL_THROW_EXTERN_C()
2540 if (*ppDest != pSource)
2542 ::typelib_typedescriptionreference_acquire( pSource );
2543 ::typelib_typedescriptionreference_release( *ppDest );
2544 *ppDest = pSource;
2548 //##################################################################################################
2549 extern "C" void SAL_CALL typelib_setCacheSize( sal_Int32 nNewSize )
2550 SAL_THROW_EXTERN_C()
2552 OSL_ENSURE( nNewSize >= 0, "### illegal cache size given!" );
2553 if (nNewSize >= 0)
2555 TypeDescriptor_Init_Impl &rInit = Init::get();
2556 MutexGuard aGuard( rInit.getMutex() );
2557 if ((nNewSize < nCacheSize) && rInit.pCache)
2559 while ((sal_Int32)rInit.pCache->size() != nNewSize)
2561 typelib_typedescription_release( rInit.pCache->front() );
2562 rInit.pCache->pop_front();
2565 nCacheSize = nNewSize;
2570 static sal_Bool s_aAssignableFromTab[11][11] =
2572 /* from CH,BO,BY,SH,US,LO,UL,HY,UH,FL,DO */
2573 /* TypeClass_CHAR */ { 1, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0 },
2574 /* TypeClass_BOOLEAN */ { 0, 1, 0, 0, 0, 0, 0, 0, 0, 0, 0 },
2575 /* TypeClass_BYTE */ { 0, 0, 1, 0, 0, 0, 0, 0, 0, 0, 0 },
2576 /* TypeClass_SHORT */ { 0, 0, 1, 1, 1, 0, 0, 0, 0, 0, 0 },
2577 /* TypeClass_UNSIGNED_SHORT */ { 0, 0, 1, 1, 1, 0, 0, 0, 0, 0, 0 },
2578 /* TypeClass_LONG */ { 0, 0, 1, 1, 1, 1, 1, 0, 0, 0, 0 },
2579 /* TypeClass_UNSIGNED_LONG */ { 0, 0, 1, 1, 1, 1, 1, 0, 0, 0, 0 },
2580 /* TypeClass_HYPER */ { 0, 0, 1, 1, 1, 1, 1, 1, 1, 0, 0 },
2581 /* TypeClass_UNSIGNED_HYPER */ { 0, 0, 1, 1, 1, 1, 1, 1, 1, 0, 0 },
2582 /* TypeClass_FLOAT */ { 0, 0, 1, 1, 1, 0, 0, 0, 0, 1, 0 },
2583 /* TypeClass_DOUBLE */ { 0, 0, 1, 1, 1, 1, 1, 0, 0, 1, 1 }
2586 //##################################################################################################
2587 extern "C" sal_Bool SAL_CALL typelib_typedescriptionreference_isAssignableFrom(
2588 typelib_TypeDescriptionReference * pAssignable,
2589 typelib_TypeDescriptionReference * pFrom )
2590 SAL_THROW_EXTERN_C()
2592 if (pAssignable && pFrom)
2594 typelib_TypeClass eAssignable = pAssignable->eTypeClass;
2595 typelib_TypeClass eFrom = pFrom->eTypeClass;
2597 if (eAssignable == typelib_TypeClass_ANY) // anything can be assigned to an any .)
2598 return sal_True;
2599 if (eAssignable == eFrom)
2601 if (type_equals( pAssignable, pFrom )) // first shot
2603 return sal_True;
2605 else
2607 switch (eAssignable)
2609 case typelib_TypeClass_STRUCT:
2610 case typelib_TypeClass_EXCEPTION:
2612 typelib_TypeDescription * pFromDescr = 0;
2613 TYPELIB_DANGER_GET( &pFromDescr, pFrom );
2614 if (! ((typelib_CompoundTypeDescription *)pFromDescr)->pBaseTypeDescription)
2616 TYPELIB_DANGER_RELEASE( pFromDescr );
2617 return sal_False;
2619 sal_Bool bRet = typelib_typedescriptionreference_isAssignableFrom(
2620 pAssignable,
2621 ((typelib_TypeDescription *)((typelib_CompoundTypeDescription *)pFromDescr)->pBaseTypeDescription)->pWeakRef );
2622 TYPELIB_DANGER_RELEASE( pFromDescr );
2623 return bRet;
2625 case typelib_TypeClass_INTERFACE:
2627 typelib_TypeDescription * pFromDescr = 0;
2628 TYPELIB_DANGER_GET( &pFromDescr, pFrom );
2629 typelib_InterfaceTypeDescription * pFromIfc
2630 = reinterpret_cast<
2631 typelib_InterfaceTypeDescription * >(pFromDescr);
2632 bool bRet = false;
2633 for (sal_Int32 i = 0; i < pFromIfc->nBaseTypes; ++i) {
2634 if (typelib_typedescriptionreference_isAssignableFrom(
2635 pAssignable,
2636 pFromIfc->ppBaseTypes[i]->aBase.pWeakRef))
2638 bRet = true;
2639 break;
2642 TYPELIB_DANGER_RELEASE( pFromDescr );
2643 return bRet;
2645 default:
2647 return sal_False;
2652 return (eAssignable >= typelib_TypeClass_CHAR && eAssignable <= typelib_TypeClass_DOUBLE &&
2653 eFrom >= typelib_TypeClass_CHAR && eFrom <= typelib_TypeClass_DOUBLE &&
2654 s_aAssignableFromTab[eAssignable-1][eFrom-1]);
2656 return sal_False;
2658 //##################################################################################################
2659 extern "C" sal_Bool SAL_CALL typelib_typedescription_isAssignableFrom(
2660 typelib_TypeDescription * pAssignable,
2661 typelib_TypeDescription * pFrom )
2662 SAL_THROW_EXTERN_C()
2664 return typelib_typedescriptionreference_isAssignableFrom(
2665 pAssignable->pWeakRef, pFrom->pWeakRef );
2668 //##################################################################################################
2669 extern "C" sal_Bool SAL_CALL typelib_typedescription_complete(
2670 typelib_TypeDescription ** ppTypeDescr )
2671 SAL_THROW_EXTERN_C()
2673 return complete(ppTypeDescr, true);