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