1 /*************************************************************************
3 * DO NOT ALTER OR REMOVE COPYRIGHT NOTICES OR THIS FILE HEADER.
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"
42 #include <sal/alloca.h>
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>
59 //------------------------------------------------------------------------
60 //------------------------------------------------------------------------
63 #elif defined(SAL_OS2)
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.
81 #elif defined(SAL_OS2)
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
)
91 if( nRequestedAlignment
> nMaxAlignment
)
92 nRequestedAlignment
= nMaxAlignment
;
93 return nRequestedAlignment
;
97 * Calculate the new size of the struktur.
99 static inline sal_Int32
newAlignedSize(
100 sal_Int32 OldSize
, sal_Int32 ElementSize
, sal_Int32 NeededAlignment
)
103 NeededAlignment
= adjustAlignment( NeededAlignment
);
104 return (OldSize
+ NeededAlignment
-1) / NeededAlignment
* NeededAlignment
+ ElementSize
;
107 static inline sal_Bool
reallyWeak( typelib_TypeClass eTypeClass
)
110 return TYPELIB_TYPEDESCRIPTIONREFERENCE_ISREALLYWEAK( eTypeClass
);
113 static inline sal_Int32
getDescriptionSize( typelib_TypeClass eTypeClass
)
116 OSL_ASSERT( typelib_TypeClass_TYPEDEF
!= eTypeClass
);
119 // The reference is the description
120 // if the description is empty, than it must be filled with
121 // the new description
124 case typelib_TypeClass_ARRAY
:
125 nSize
= (sal_Int32
)sizeof( typelib_ArrayTypeDescription
);
128 case typelib_TypeClass_SEQUENCE
:
129 nSize
= (sal_Int32
)sizeof( typelib_IndirectTypeDescription
);
132 case typelib_TypeClass_UNION
:
133 nSize
= (sal_Int32
)sizeof( typelib_UnionTypeDescription
);
136 case typelib_TypeClass_STRUCT
:
137 nSize
= (sal_Int32
)sizeof( typelib_StructTypeDescription
);
140 case typelib_TypeClass_EXCEPTION
:
141 nSize
= (sal_Int32
)sizeof( typelib_CompoundTypeDescription
);
144 case typelib_TypeClass_ENUM
:
145 nSize
= (sal_Int32
)sizeof( typelib_EnumTypeDescription
);
148 case typelib_TypeClass_INTERFACE
:
149 nSize
= (sal_Int32
)sizeof( typelib_InterfaceTypeDescription
);
152 case typelib_TypeClass_INTERFACE_METHOD
:
153 nSize
= (sal_Int32
)sizeof( typelib_InterfaceMethodTypeDescription
);
156 case typelib_TypeClass_INTERFACE_ATTRIBUTE
:
157 nSize
= (sal_Int32
)sizeof( typelib_InterfaceAttributeTypeDescription
);
161 nSize
= (sal_Int32
)sizeof( typelib_TypeDescription
);
167 //-----------------------------------------------------------------------------
168 extern "C" void SAL_CALL
typelib_typedescriptionreference_getByName(
169 typelib_TypeDescriptionReference
** ppRet
, rtl_uString
* pName
)
170 SAL_THROW_EXTERN_C();
172 //-----------------------------------------------------------------------------
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 //-----------------------------------------------------------------------------
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
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
;
233 ~TypeDescriptor_Init_Impl() SAL_THROW( () );
235 //__________________________________________________________________________________________________
236 inline Mutex
& TypeDescriptor_Init_Impl::getMutex() SAL_THROW( () )
240 MutexGuard
aGuard( Mutex::getGlobalMutex() );
242 pMutex
= new Mutex();
246 //__________________________________________________________________________________________________
247 inline void TypeDescriptor_Init_Impl::callChain(
248 typelib_TypeDescription
** ppRet
, rtl_uString
* pName
)
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
);
265 typelib_typedescription_release( *ppRet
);
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;
277 //__________________________________________________________________________________________________
278 TypeDescriptor_Init_Impl::~TypeDescriptor_Init_Impl() SAL_THROW( () )
280 #ifndef CPPU_LEAK_STATIC_DATA
283 TypeDescriptionList_Impl::const_iterator aIt
= pCache
->begin();
284 while( aIt
!= pCache
->end() )
286 typelib_typedescription_release( (*aIt
) );
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();
300 while( aIt
!= pWeakMap
->end() )
302 typelib_typedescriptionreference_acquire( ppTDR
[i
++] = (*aIt
).second
);
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
);
323 #if OSL_DEBUG_LEVEL > 1
324 aIt
= pWeakMap
->begin();
325 while( aIt
!= pWeakMap
->end() )
327 typelib_TypeDescriptionReference
* pTDR
= (*aIt
).second
;
330 OString
aTypeName( OUStringToOString( pTDR
->pTypeName
, RTL_TEXTENCODING_ASCII_US
) );
332 "### remaining type: %s; ref count = %d", aTypeName
.getStr(), pTDR
->nRefCount
);
336 OSL_TRACE( "### remaining null type entry!?" );
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() );
361 #endif // CPPU_LEAK_STATIC_DATA
363 // todo: maybe into leak block
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
)
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
)
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()))
405 rInit
.pCallbacks
->erase( iPos
);
406 iPos
= rInit
.pCallbacks
->begin();
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
)
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
] );
443 pReadWriteAttributes
[i
] = !((typelib_InterfaceAttributeTypeDescription
*)pM
)->bReadOnly
;
444 TYPELIB_DANGER_RELEASE( pM
);
446 #if OSL_DEBUG_LEVEL > 1
449 OString
aStr( OUStringToOString( pITD
->ppAllMembers
[i
]->pTypeName
, RTL_TEXTENCODING_ASCII_US
) );
450 OSL_TRACE( "\n### cannot get attribute type description: %s", aStr
.getStr() );
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
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
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
;
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
)
522 typelib_typedescription_initTables( *ppTypeDescr
);
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
);
533 if (typelib_TypeClass_TYPEDEF
== pTD
->eTypeClass
)
535 typelib_typedescriptionreference_getDescription(
536 &pTD
, ((typelib_IndirectTypeDescription
*)pTD
)->pType
);
542 OSL_ASSERT( typelib_TypeClass_TYPEDEF
!= pTD
->eTypeClass
);
543 // typedescription found
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() );
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
);
577 || (pTD
->eTypeClass
== typelib_TypeClass_INTERFACE
580 ::typelib_typedescription_release( *ppTypeDescr
);
585 #if OSL_DEBUG_LEVEL > 1
587 OUStringToOString( (*ppTypeDescr
)->pTypeName
, RTL_TEXTENCODING_ASCII_US
) );
588 OSL_TRACE( "\n### type cannot be completed: %s", aStr
.getStr() );
598 //------------------------------------------------------------------------
599 extern "C" void SAL_CALL
typelib_typedescription_newEmpty(
600 typelib_TypeDescription
** ppRet
,
601 typelib_TypeClass eTypeClass
, rtl_uString
* pTypeName
)
606 typelib_typedescription_release( *ppRet
);
610 OSL_ASSERT( typelib_TypeClass_TYPEDEF
!= eTypeClass
);
612 typelib_TypeDescription
* pRet
;
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
);
624 pIndirect
->pType
= 0;
625 pTmp
->nDimensions
= 0;
626 pTmp
->nTotalElements
= 0;
627 pTmp
->pDimensions
= 0;
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
);
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
);
653 pTmp
->pDiscriminantTypeRef
= 0;
654 pTmp
->pDiscriminants
= 0;
655 pTmp
->ppTypeRefs
= 0;
656 pTmp
->ppMemberNames
= 0;
657 pTmp
->pDefaultTypeRef
= 0;
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
);
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;
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
);
690 pTmp
->pBaseTypeDescription
= 0;
692 pTmp
->pMemberOffsets
= 0;
693 pTmp
->ppTypeRefs
= 0;
694 pTmp
->ppMemberNames
= 0;
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
);
706 pTmp
->nDefaultEnumValue
= 0;
707 pTmp
->nEnumValues
= 0;
708 pTmp
->ppEnumNames
= 0;
709 pTmp
->pEnumValues
= 0;
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
);
721 pTmp
->pBaseTypeDescription
= 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;
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
);
742 pTmp
->aBase
.pMemberName
= 0;
743 pTmp
->pReturnTypeRef
= 0;
746 pTmp
->nExceptions
= 0;
747 pTmp
->ppExceptions
= 0;
748 pTmp
->pInterface
= 0;
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
);
762 pTmp
->aBase
.pMemberName
= 0;
763 pTmp
->pAttributeTypeRef
= 0;
764 pTmp
->pInterface
= 0;
767 pTmp
->nGetExceptions
= 0;
768 pTmp
->ppGetExceptions
= 0;
769 pTmp
->nSetExceptions
= 0;
770 pTmp
->ppSetExceptions
= 0;
776 pRet
= new typelib_TypeDescription();
777 #if OSL_DEBUG_LEVEL > 1
778 osl_incrementInterlockedCount( &Init::get().nTypeDescriptionCount
);
783 pRet
->nRefCount
= 1; // reference count is initially 1
784 pRet
->nStaticRefCount
= 0;
785 pRet
->eTypeClass
= eTypeClass
;
787 pRet
->pUniqueIdentifier
= 0;
789 rtl_uString_acquire( pRet
->pTypeName
= pTypeName
);
791 pRet
->bComplete
= sal_True
;
793 pRet
->nAlignment
= 0;
795 pRet
->bOnDemand
= sal_False
;
799 //------------------------------------------------------------------------
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
)
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
);
818 typelib_typedescription_newEmpty( ppRet
, eTypeClass
, pTypeName
);
822 case typelib_TypeClass_SEQUENCE
:
824 OSL_ASSERT( nMembers
== 0 );
825 typelib_typedescriptionreference_acquire( pType
);
826 ((typelib_IndirectTypeDescription
*)*ppRet
)->pType
= pType
;
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;
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!" );
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);
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
);
866 pTmp
->ppMemberNames
[i
]
867 = pCompoundMembers
[i
].pMemberName
);
869 typelib_typedescriptionreference_new(
871 pStructMembers
[i
].aBase
.eTypeClass
,
872 pStructMembers
[i
].aBase
.pTypeName
);
874 pTmp
->ppMemberNames
[i
]
875 = pStructMembers
[i
].aBase
.pMemberName
);
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
);
888 typelib_TypeDescription
* pTD
= 0;
889 TYPELIB_DANGER_GET( &pTD
, pTmp
->ppTypeRefs
[i
] );
890 OSL_ENSURE( pTD
->nSize
, "### void member?" );
892 alignment
= pTD
->nAlignment
;
893 TYPELIB_DANGER_RELEASE( pTD
);
895 nOffset
= newAlignedSize( nOffset
, size
, alignment
);
896 pTmp
->pMemberOffsets
[i
] = nOffset
- size
;
899 reinterpret_cast< typelib_StructTypeDescription
* >(
900 pTmp
)->pParameterizedTypes
[i
]
901 = pStructMembers
[i
].bParameterizedType
;
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
,
930 typelib_CompoundMember_Init
* pMembers
)
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
,
942 typelib_StructMember_Init
* pMembers
)
946 ppRet
, typelib_TypeClass_STRUCT
, pTypeName
, pType
, nMembers
, 0,
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
,
958 typelib_Union_Init
* pMembers
)
961 typelib_typedescription_newEmpty( ppRet
, typelib_TypeClass_UNION
, pTypeName
);
963 typelib_UnionTypeDescription
* pTmp
= (typelib_UnionTypeDescription
*)*ppRet
;
964 typelib_typedescriptionreference_acquire( pTmp
->pDiscriminantTypeRef
= pDiscriminantTypeRef
);
968 pTmp
->nMembers
= nMembers
;
969 // default discriminant
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
,
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 //------------------------------------------------------------------------
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
; }
1107 typedef std::set
< rtl::OUString
> Set
;
1110 sal_Int32 directBaseIndex
, Set
& directBaseSet
,
1111 sal_Int32
* directBaseMembers
,
1112 typelib_InterfaceTypeDescription
const * desc
);
1119 BaseList::BaseList(typelib_InterfaceTypeDescription
const * desc
) {
1121 for (sal_Int32 i
= 0; i
< desc
->nBaseTypes
; ++i
) {
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
) {
1135 directBaseIndex
, directBaseSet
, directBaseMembers
,
1136 desc
->ppBaseTypes
[i
]);
1138 if (set
.insert(desc
->aBase
.pTypeName
).second
) {
1140 e
.memberOffset
= members
;
1141 e
.directBaseIndex
= directBaseIndex
;
1142 e
.directBaseMemberOffset
= *directBaseMembers
;
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
,
1163 typelib_TypeDescriptionReference
** ppMembers
)
1164 SAL_THROW_EXTERN_C()
1167 typelib_typedescription_release(&(*ppRet
)->aBase
);
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
1185 reinterpret_cast< typelib_TypeDescription
** >(
1186 &pITD
->ppBaseTypes
[i
]),
1192 OSL_ASSERT(pITD
->ppBaseTypes
[i
] != 0);
1194 if (nBaseInterfaces
> 0) {
1195 pITD
->pBaseTypeDescription
= pITD
->ppBaseTypes
[0];
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
];
1214 BaseList::List
const & rList
= aBaseList
.getList();
1215 {for (BaseList::List::const_iterator
i(rList
.begin()); i
!= rList
.end();
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
,
1237 pITD
->ppAllMembers
[n
++] = pDerivedMember
;
1243 pITD
->ppMembers
= pITD
->ppAllMembers
+ aBaseList
.getBaseMembers();
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
;
1264 //------------------------------------------------------------------------
1268 typelib_TypeDescriptionReference
** copyExceptions(
1269 sal_Int32 count
, rtl_uString
** typeNames
)
1271 OSL_ASSERT(count
>= 0);
1275 typelib_TypeDescriptionReference
** p
1276 = new typelib_TypeDescriptionReference
*[count
];
1277 for (sal_Int32 i
= 0; i
< count
; ++i
) {
1279 typelib_typedescriptionreference_new(
1280 p
+ i
, typelib_TypeClass_EXCEPTION
, typeNames
[i
]);
1287 extern "C" void SAL_CALL
typelib_typedescription_newInterfaceMethod(
1288 typelib_InterfaceMethodTypeDescription
** ppRet
,
1289 sal_Int32 nAbsolutePosition
,
1291 rtl_uString
* pTypeName
,
1292 typelib_TypeClass eReturnTypeClass
,
1293 rtl_uString
* pReturnTypeName
,
1295 typelib_Parameter_Init
* pParams
,
1296 sal_Int32 nExceptions
,
1297 rtl_uString
** ppExceptionNames
)
1298 SAL_THROW_EXTERN_C()
1301 typelib_typedescription_release(&(*ppRet
)->aBase
.aBase
);
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");
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
);
1316 || pInterface
->aBase
.eTypeClass
!= typelib_TypeClass_INTERFACE
1318 reinterpret_cast< typelib_TypeDescription
** >(&pInterface
), false))
1320 OSL_ENSURE(false, "No interface corresponding to interface method");
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
;
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;
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
,
1389 sal_Int32 nGetExceptions
, rtl_uString
** ppGetExceptionNames
,
1390 sal_Int32 nSetExceptions
, rtl_uString
** ppSetExceptionNames
)
1391 SAL_THROW_EXTERN_C()
1394 typelib_typedescription_release(&(*ppRet
)->aBase
.aBase
);
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");
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
);
1409 || pInterface
->aBase
.eTypeClass
!= typelib_TypeClass_INTERFACE
1411 reinterpret_cast< typelib_TypeDescription
** >(&pInterface
), false))
1413 OSL_ENSURE(false, "No interface corresponding to interface attribute");
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;
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 //------------------------------------------------------------------------
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
)
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
;
1481 case typelib_TypeClass_SEQUENCE
:
1482 if( ((typelib_IndirectTypeDescription
*)pTD
)->pType
)
1483 typelib_typedescriptionreference_release( ((typelib_IndirectTypeDescription
*)pTD
)->pType
);
1485 case typelib_TypeClass_UNION
:
1487 typelib_UnionTypeDescription
* pUnionTD
= (typelib_UnionTypeDescription
*)pTD
;
1488 typelib_typedescriptionreference_release( pUnionTD
->pDiscriminantTypeRef
);
1489 typelib_typedescriptionreference_release( pUnionTD
->pDefaultTypeRef
);
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
;
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
);
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
;
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
;
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
);
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
);
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
;
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);
1610 TypeDescriptor_Init_Impl
&rInit
= Init::get();
1611 if( reallyWeak( pTD
->eTypeClass
) )
1616 MutexGuard
aGuard( rInit
.getMutex() );
1617 // remove this description from the weak reference
1618 pTD
->pWeakRef
->pType
= 0;
1620 typelib_typedescriptionreference_release( pTD
->pWeakRef
);
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
);
1647 case typelib_TypeClass_SEQUENCE
:
1648 osl_decrementInterlockedCount( &rInit
.nIndirectTypeDescriptionCount
);
1650 case typelib_TypeClass_UNION
:
1651 osl_decrementInterlockedCount( &rInit
.nUnionTypeDescriptionCount
);
1653 case typelib_TypeClass_STRUCT
:
1654 case typelib_TypeClass_EXCEPTION
:
1655 osl_decrementInterlockedCount( &rInit
.nCompoundTypeDescriptionCount
);
1657 case typelib_TypeClass_INTERFACE
:
1658 osl_decrementInterlockedCount( &rInit
.nInterfaceTypeDescriptionCount
);
1660 case typelib_TypeClass_INTERFACE_METHOD
:
1661 osl_decrementInterlockedCount( &rInit
.nInterfaceMethodTypeDescriptionCount
);
1663 case typelib_TypeClass_INTERFACE_ATTRIBUTE
:
1664 osl_decrementInterlockedCount( &rInit
.nInterfaceAttributeTypeDescriptionCount
);
1666 case typelib_TypeClass_ENUM
:
1667 osl_decrementInterlockedCount( &rInit
.nEnumTypeDescriptionCount
);
1670 osl_decrementInterlockedCount( &rInit
.nTypeDescriptionCount
);
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
) );
1693 OSL_ASSERT( (*ppNewDescription
)->eTypeClass
== pTDR
->eTypeClass
);
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.
1706 ::typelib_typedescription_release( *ppNewDescription
);
1707 *ppNewDescription
= pTDR
->pType
;
1708 ::typelib_typedescriptionreference_release( pTDR
);
1713 // destruction of this type in progress (another thread!)
1714 osl_decrementInterlockedCount( &pTDR
->pType
->nRefCount
);
1718 pTDR
->pType
= *ppNewDescription
;
1719 OSL_ASSERT( ! (*ppNewDescription
)->pWeakRef
);
1720 (*ppNewDescription
)->pWeakRef
= pTDR
;
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
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
;
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
;
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
;
1780 else if( reallyWeak( (*ppNewDescription
)->eTypeClass
) )
1782 typelib_typedescriptionreference_new(
1783 &pTDR
, (*ppNewDescription
)->eTypeClass
, (*ppNewDescription
)->pTypeName
);
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
)
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()
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()
1835 if( pTypeDescription
->nSize
)
1837 // size and alignment are set
1838 rMaxIntegralTypeSize
= pTypeDescription
->nAlignment
;
1839 nSize
= pTypeDescription
->nSize
;
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 * ));
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
;
1872 case typelib_TypeClass_ENUM
:
1873 nSize
= rMaxIntegralTypeSize
= (sal_Int32
)(sizeof( typelib_TypeClass
));
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
);
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
;
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
;
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
;
1921 nSize
+= nStructSize
;
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
;
1933 case typelib_TypeClass_SEQUENCE
:
1934 nSize
= rMaxIntegralTypeSize
= (sal_Int32
)(sizeof( void * ));
1936 case typelib_TypeClass_ANY
:
1938 nSize
= (sal_Int32
)(sizeof( uno_Any
));
1939 rMaxIntegralTypeSize
= (sal_Int32
)(sizeof( void * ));
1941 case typelib_TypeClass_TYPE
:
1942 nSize
= rMaxIntegralTypeSize
= (sal_Int32
)(sizeof( typelib_TypeDescriptionReference
* ));
1944 case typelib_TypeClass_BOOLEAN
:
1945 nSize
= rMaxIntegralTypeSize
= (sal_Int32
)(sizeof( sal_Bool
));
1947 case typelib_TypeClass_CHAR
:
1948 nSize
= rMaxIntegralTypeSize
= (sal_Int32
)(sizeof( sal_Unicode
));
1950 case typelib_TypeClass_STRING
:
1952 nSize
= rMaxIntegralTypeSize
= (sal_Int32
)(sizeof( rtl_uString
* ));
1954 case typelib_TypeClass_FLOAT
:
1955 nSize
= rMaxIntegralTypeSize
= (sal_Int32
)(sizeof( float ));
1957 case typelib_TypeClass_DOUBLE
:
1958 nSize
= rMaxIntegralTypeSize
= (sal_Int32
)(sizeof( double ));
1960 case typelib_TypeClass_BYTE
:
1961 nSize
= rMaxIntegralTypeSize
= (sal_Int32
)(sizeof( sal_Int8
));
1963 case typelib_TypeClass_SHORT
:
1964 case typelib_TypeClass_UNSIGNED_SHORT
:
1965 nSize
= rMaxIntegralTypeSize
= (sal_Int32
)(sizeof( sal_Int16
));
1967 case typelib_TypeClass_LONG
:
1968 case typelib_TypeClass_UNSIGNED_LONG
:
1969 nSize
= rMaxIntegralTypeSize
= (sal_Int32
)(sizeof( sal_Int32
));
1971 case typelib_TypeClass_HYPER
:
1972 case typelib_TypeClass_UNSIGNED_HYPER
:
1973 nSize
= rMaxIntegralTypeSize
= (sal_Int32
)(sizeof( sal_Int64
));
1975 case typelib_TypeClass_UNKNOWN
:
1976 case typelib_TypeClass_SERVICE
:
1977 case typelib_TypeClass_MODULE
:
1979 OSL_ENSURE( sal_False
, "not convertable type" );
1983 return newAlignedSize( nOffset
, nSize
, rMaxIntegralTypeSize
);
1986 //------------------------------------------------------------------------
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
]);
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
2015 typelib_InterfaceMethodTypeDescription
const * >(base
);
2016 typelib_InterfaceMethodTypeDescription
* newMethod
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
* >(
2045 newMethod
->pBaseRef
= baseRef
;
2046 newMethod
->nIndex
= index
;
2050 case typelib_TypeClass_INTERFACE_ATTRIBUTE
:
2052 typelib_typedescription_newEmpty(
2053 result
, typelib_TypeClass_INTERFACE_ATTRIBUTE
, name
.pData
);
2054 typelib_InterfaceAttributeTypeDescription
const * baseAttribute
2056 typelib_InterfaceAttributeTypeDescription
const * >(base
);
2057 typelib_InterfaceAttributeTypeDescription
* newAttribute
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
* >(
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
);
2093 extern "C" void SAL_CALL
typelib_typedescription_getByName(
2094 typelib_TypeDescription
** ppRet
, rtl_uString
* pName
)
2095 SAL_THROW_EXTERN_C()
2099 typelib_typedescription_release( (*ppRet
) );
2103 static sal_Bool bInited
= sal_False
;
2104 TypeDescriptor_Init_Impl
&rInit
= Init::get();
2108 // guard against multi thread access
2109 MutexGuard
aGuard( rInit
.getMutex() );
2112 // avoid recursion during the next ...new calls
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
);
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
);
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 );
2198 typelib_typedescription_release( element_td
);
2203 // Check for derived interface member type:
2204 sal_Int32 i1
= name
.lastIndexOf(
2205 rtl::OUString::createFromAscii(":@"));
2207 sal_Int32 i2
= i1
+ RTL_CONSTASCII_LENGTH(":@");
2208 sal_Int32 i3
= name
.indexOf(',', i2
);
2210 sal_Int32 i4
= name
.indexOf(':', i3
);
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(
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
);
2232 typelib_typedescription_release(pBase
);
2234 if (pBaseRef
!= 0) {
2235 typelib_typedescriptionreference_release(
2246 rInit
.callChain( ppRet
, pName
);
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
);
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() );
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
)
2308 typelib_TypeDescription
* pRet
= 0;
2309 rInit
.callChain( &pRet
, pTypeName
);
2312 // typedescription found
2313 if (typelib_TypeClass_TYPEDEF
== pRet
->eTypeClass
)
2315 typelib_typedescriptionreference_acquire(
2316 ((typelib_IndirectTypeDescription
*)pRet
)->pType
);
2318 typelib_typedescriptionreference_release( *ppTDR
);
2319 *ppTDR
= ((typelib_IndirectTypeDescription
*)pRet
)->pType
;
2320 typelib_typedescription_release( pRet
);
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() );
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
);
2344 typelib_typedescriptionreference_release( *ppTDR
);
2345 *ppTDR
= pRet
->pWeakRef
;
2350 #if OSL_DEBUG_LEVEL > 1
2351 OString
aStr( OUStringToOString( pTypeName
, RTL_TEXTENCODING_ASCII_US
) );
2352 OSL_ENSURE( !"### typedef not found: ", aStr
.getStr() );
2354 typelib_typedescriptionreference_release( *ppTDR
);
2360 MutexGuard
aGuard( rInit
.getMutex() );
2361 typelib_typedescriptionreference_getByName( ppTDR
, pTypeName
);
2365 if( reallyWeak( eTypeClass
) )
2367 typelib_TypeDescriptionReference
* pTDR
= new typelib_TypeDescriptionReference();
2368 #if OSL_DEBUG_LEVEL > 1
2369 osl_incrementInterlockedCount( &rInit
.nTypeDescriptionReferenceCount
);
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
);
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
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
);
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()
2446 typelib_typedescription_release( *ppRet
);
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
;
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
);
2466 // The refence is incremented. The object cannot be destroyed.
2467 // Release the guard at the earliest point.
2468 *ppRet
= pRef
->pType
;
2473 ::osl_decrementInterlockedCount( &pRef
->pType
->nRefCount
);
2474 // detruction of this type in progress (another thread!)
2475 // no acces through this weak reference
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()
2495 typelib_typedescriptionreference_release( *ppRet
);
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
);
2508 // The refence is incremented. The object cannot be destroyed.
2509 // Release the guard at the earliest point.
2510 *ppRet
= (*aIt
).second
;
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()
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
);
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!" );
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 .)
2599 if (eAssignable
== eFrom
)
2601 if (type_equals( pAssignable
, pFrom
)) // first shot
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
);
2619 sal_Bool bRet
= typelib_typedescriptionreference_isAssignableFrom(
2621 ((typelib_TypeDescription
*)((typelib_CompoundTypeDescription
*)pFromDescr
)->pBaseTypeDescription
)->pWeakRef
);
2622 TYPELIB_DANGER_RELEASE( pFromDescr
);
2625 case typelib_TypeClass_INTERFACE
:
2627 typelib_TypeDescription
* pFromDescr
= 0;
2628 TYPELIB_DANGER_GET( &pFromDescr
, pFrom
);
2629 typelib_InterfaceTypeDescription
* pFromIfc
2631 typelib_InterfaceTypeDescription
* >(pFromDescr
);
2633 for (sal_Int32 i
= 0; i
< pFromIfc
->nBaseTypes
; ++i
) {
2634 if (typelib_typedescriptionreference_isAssignableFrom(
2636 pFromIfc
->ppBaseTypes
[i
]->aBase
.pWeakRef
))
2642 TYPELIB_DANGER_RELEASE( pFromDescr
);
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]);
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);