1 /* -*- Mode: C++; tab-width: 4; indent-tabs-mode: nil; c-basic-offset: 4 -*- */
3 * This file is part of the LibreOffice project.
5 * This Source Code Form is subject to the terms of the Mozilla Public
6 * License, v. 2.0. If a copy of the MPL was not distributed with this
7 * file, You can obtain one at http://mozilla.org/MPL/2.0/.
9 * This file incorporates work covered by the following license notice:
11 * Licensed to the Apache Software Foundation (ASF) under one or more
12 * contributor license agreements. See the NOTICE file distributed
13 * with this work for additional information regarding copyright
14 * ownership. The ASF licenses this file to you under the Apache
15 * License, Version 2.0 (the "License"); you may not use this file
16 * except in compliance with the License. You may obtain a copy of
17 * the License at http://www.apache.org/licenses/LICENSE-2.0 .
21 #if OSL_DEBUG_LEVEL > 1
25 #include <boost/unordered_map.hpp>
34 #include <sal/alloca.h>
36 #include <osl/interlck.h>
37 #include <osl/mutex.hxx>
38 #include <rtl/ustring.hxx>
39 #include <rtl/ustrbuf.hxx>
40 #include <rtl/alloc.h>
41 #include <rtl/instance.hxx>
42 #include <osl/diagnose.h>
43 #include <typelib/typedescription.h>
49 using ::rtl::OUString
;
50 using ::rtl::OUStringBuffer
;
58 * The double member determin the alignment.
59 * Under Os2 and MS-Windows the Alignment is min( 8, sizeof( type ) ).
60 * The aligment of a strukture is min( 8, sizeof( max basic type ) ), the greatest basic type
61 * determine the aligment.
67 //double: doubleword aligned if -qalign=natural/-malign=natural
68 //which isn't the default ABI. Otherwise word aligned, While a long long int
69 //is always doubleword aligned, so use that instead.
80 // the value of the maximal alignment
81 static sal_Int32 nMaxAlignment
= (sal_Int32
)( (sal_Size
)(&((AlignSize_Impl
*) 16)->dDouble
) - 16);
83 static inline sal_Int32
adjustAlignment( sal_Int32 nRequestedAlignment
)
86 if( nRequestedAlignment
> nMaxAlignment
)
87 nRequestedAlignment
= nMaxAlignment
;
88 return nRequestedAlignment
;
92 * Calculate the new size of the struktur.
94 static inline sal_Int32
newAlignedSize(
95 sal_Int32 OldSize
, sal_Int32 ElementSize
, sal_Int32 NeededAlignment
)
98 NeededAlignment
= adjustAlignment( NeededAlignment
);
99 return (OldSize
+ NeededAlignment
-1) / NeededAlignment
* NeededAlignment
+ ElementSize
;
102 static inline sal_Bool
reallyWeak( typelib_TypeClass eTypeClass
)
105 return TYPELIB_TYPEDESCRIPTIONREFERENCE_ISREALLYWEAK( eTypeClass
);
108 static inline sal_Int32
getDescriptionSize( typelib_TypeClass eTypeClass
)
111 OSL_ASSERT( typelib_TypeClass_TYPEDEF
!= eTypeClass
);
114 // The reference is the description
115 // if the description is empty, than it must be filled with
116 // the new description
119 case typelib_TypeClass_ARRAY
:
120 nSize
= (sal_Int32
)sizeof( typelib_ArrayTypeDescription
);
123 case typelib_TypeClass_SEQUENCE
:
124 nSize
= (sal_Int32
)sizeof( typelib_IndirectTypeDescription
);
127 case typelib_TypeClass_UNION
:
128 nSize
= (sal_Int32
)sizeof( typelib_UnionTypeDescription
);
131 case typelib_TypeClass_STRUCT
:
132 nSize
= (sal_Int32
)sizeof( typelib_StructTypeDescription
);
135 case typelib_TypeClass_EXCEPTION
:
136 nSize
= (sal_Int32
)sizeof( typelib_CompoundTypeDescription
);
139 case typelib_TypeClass_ENUM
:
140 nSize
= (sal_Int32
)sizeof( typelib_EnumTypeDescription
);
143 case typelib_TypeClass_INTERFACE
:
144 nSize
= (sal_Int32
)sizeof( typelib_InterfaceTypeDescription
);
147 case typelib_TypeClass_INTERFACE_METHOD
:
148 nSize
= (sal_Int32
)sizeof( typelib_InterfaceMethodTypeDescription
);
151 case typelib_TypeClass_INTERFACE_ATTRIBUTE
:
152 nSize
= (sal_Int32
)sizeof( typelib_InterfaceAttributeTypeDescription
);
156 nSize
= (sal_Int32
)sizeof( typelib_TypeDescription
);
162 //-----------------------------------------------------------------------------
163 extern "C" void SAL_CALL
typelib_typedescriptionreference_getByName(
164 typelib_TypeDescriptionReference
** ppRet
, rtl_uString
* pName
)
165 SAL_THROW_EXTERN_C();
167 //-----------------------------------------------------------------------------
170 sal_Bool
operator()(const sal_Unicode
* const & s1
, const sal_Unicode
* const & s2
) const SAL_THROW(())
171 { return 0 == rtl_ustr_compare( s1
, s2
); }
174 //-----------------------------------------------------------------------------
177 size_t operator()(const sal_Unicode
* const & s
) const SAL_THROW(())
178 { return rtl_ustr_hashCode( s
); }
182 //-----------------------------------------------------------------------------
183 // Heavy hack, the const sal_Unicode * is hold by the typedescription reference
184 typedef boost::unordered_map
< const sal_Unicode
*, typelib_TypeDescriptionReference
*,
185 hashStr_Impl
, equalStr_Impl
> WeakMap_Impl
;
187 typedef pair
< void *, typelib_typedescription_Callback
> CallbackEntry
;
188 typedef list
< CallbackEntry
> CallbackSet_Impl
;
189 typedef list
< typelib_TypeDescription
* > TypeDescriptionList_Impl
;
191 // # of cached elements
192 static sal_Int32 nCacheSize
= 256;
194 struct TypeDescriptor_Init_Impl
196 //sal_Bool bDesctructorCalled;
197 // all type description references
198 WeakMap_Impl
* pWeakMap
;
199 // all type description callbacks
200 CallbackSet_Impl
* pCallbacks
;
201 // A cache to hold descriptions
202 TypeDescriptionList_Impl
* pCache
;
203 // The mutex to guard all type library accesses
206 inline Mutex
& getMutex() SAL_THROW(());
208 inline void callChain( typelib_TypeDescription
** ppRet
, rtl_uString
* pName
) SAL_THROW(());
210 #if OSL_DEBUG_LEVEL > 1
211 // only for debugging
212 sal_Int32 nTypeDescriptionCount
;
213 sal_Int32 nCompoundTypeDescriptionCount
;
214 sal_Int32 nUnionTypeDescriptionCount
;
215 sal_Int32 nIndirectTypeDescriptionCount
;
216 sal_Int32 nArrayTypeDescriptionCount
;
217 sal_Int32 nEnumTypeDescriptionCount
;
218 sal_Int32 nInterfaceMethodTypeDescriptionCount
;
219 sal_Int32 nInterfaceAttributeTypeDescriptionCount
;
220 sal_Int32 nInterfaceTypeDescriptionCount
;
221 sal_Int32 nTypeDescriptionReferenceCount
;
224 TypeDescriptor_Init_Impl():
225 pWeakMap(0), pCallbacks(0), pCache(0), pMutex(0)
226 #if OSL_DEBUG_LEVEL > 1
227 , nTypeDescriptionCount(0), nCompoundTypeDescriptionCount(0),
228 nUnionTypeDescriptionCount(0), nIndirectTypeDescriptionCount(0),
229 nArrayTypeDescriptionCount(0), nEnumTypeDescriptionCount(0),
230 nInterfaceMethodTypeDescriptionCount(0),
231 nInterfaceAttributeTypeDescriptionCount(0),
232 nInterfaceTypeDescriptionCount(0), nTypeDescriptionReferenceCount(0)
236 ~TypeDescriptor_Init_Impl() SAL_THROW(());
238 //__________________________________________________________________________________________________
239 inline Mutex
& TypeDescriptor_Init_Impl::getMutex() SAL_THROW(())
243 MutexGuard
aGuard( Mutex::getGlobalMutex() );
245 pMutex
= new Mutex();
249 //__________________________________________________________________________________________________
250 inline void TypeDescriptor_Init_Impl::callChain(
251 typelib_TypeDescription
** ppRet
, rtl_uString
* pName
)
258 CallbackSet_Impl::const_iterator aIt
= pCallbacks
->begin();
259 while( aIt
!= pCallbacks
->end() )
261 const CallbackEntry
& rEntry
= *aIt
;
262 (*rEntry
.second
)( rEntry
.first
, ppRet
, pName
);
270 //__________________________________________________________________________________________________
271 TypeDescriptor_Init_Impl::~TypeDescriptor_Init_Impl() SAL_THROW(())
275 TypeDescriptionList_Impl::const_iterator aIt
= pCache
->begin();
276 while( aIt
!= pCache
->end() )
278 typelib_typedescription_release( (*aIt
) );
287 std::vector
< typelib_TypeDescriptionReference
* > ppTDR
;
288 // save al weak references
289 WeakMap_Impl::const_iterator aIt
= pWeakMap
->begin();
290 while( aIt
!= pWeakMap
->end() )
292 ppTDR
.push_back( (*aIt
).second
);
293 typelib_typedescriptionreference_acquire( ppTDR
.back() );
297 for( std::vector
< typelib_TypeDescriptionReference
* >::iterator
i(
299 i
!= ppTDR
.end(); ++i
)
301 typelib_TypeDescriptionReference
* pTDR
= *i
;
302 OSL_ASSERT( pTDR
->nRefCount
> pTDR
->nStaticRefCount
);
303 pTDR
->nRefCount
-= pTDR
->nStaticRefCount
;
305 if( pTDR
->pType
&& !pTDR
->pType
->bOnDemand
)
307 pTDR
->pType
->bOnDemand
= sal_True
;
308 typelib_typedescription_release( pTDR
->pType
);
310 typelib_typedescriptionreference_release( pTDR
);
313 #if OSL_DEBUG_LEVEL > 1
314 aIt
= pWeakMap
->begin();
315 while( aIt
!= pWeakMap
->end() )
317 typelib_TypeDescriptionReference
* pTDR
= (*aIt
).second
;
320 OString
aTypeName( rtl::OUStringToOString( pTDR
->pTypeName
, RTL_TEXTENCODING_ASCII_US
) );
322 "### remaining type: %s; ref count = %d", aTypeName
.getStr(), pTDR
->nRefCount
);
326 OSL_TRACE( "### remaining null type entry!?" );
335 #if OSL_DEBUG_LEVEL > 1
336 OSL_ENSURE( !nTypeDescriptionCount
, "### nTypeDescriptionCount is not zero" );
337 OSL_ENSURE( !nCompoundTypeDescriptionCount
, "### nCompoundTypeDescriptionCount is not zero" );
338 OSL_ENSURE( !nUnionTypeDescriptionCount
, "### nUnionTypeDescriptionCount is not zero" );
339 OSL_ENSURE( !nIndirectTypeDescriptionCount
, "### nIndirectTypeDescriptionCount is not zero" );
340 OSL_ENSURE( !nArrayTypeDescriptionCount
, "### nArrayTypeDescriptionCount is not zero" );
341 OSL_ENSURE( !nEnumTypeDescriptionCount
, "### nEnumTypeDescriptionCount is not zero" );
342 OSL_ENSURE( !nInterfaceMethodTypeDescriptionCount
, "### nInterfaceMethodTypeDescriptionCount is not zero" );
343 OSL_ENSURE( !nInterfaceAttributeTypeDescriptionCount
, "### nInterfaceAttributeTypeDescriptionCount is not zero" );
344 OSL_ENSURE( !nInterfaceTypeDescriptionCount
, "### nInterfaceTypeDescriptionCount is not zero" );
345 OSL_ENSURE( !nTypeDescriptionReferenceCount
, "### nTypeDescriptionReferenceCount is not zero" );
347 OSL_ENSURE( !pCallbacks
|| pCallbacks
->empty(), "### pCallbacks is not NULL or empty" );
360 namespace { struct Init
: public rtl::Static
< TypeDescriptor_Init_Impl
, Init
> {}; }
362 extern "C" CPPU_DLLPUBLIC
void SAL_CALL
typelib_typedescription_registerCallback(
363 void * pContext
, typelib_typedescription_Callback pCallback
)
366 // todo mt safe: guard is no solution, can not acquire while calling callback!
367 TypeDescriptor_Init_Impl
&rInit
= Init::get();
368 // OslGuard aGuard( rInit.getMutex() );
369 if( !rInit
.pCallbacks
)
370 rInit
.pCallbacks
= new CallbackSet_Impl
;
371 rInit
.pCallbacks
->push_back( CallbackEntry( pContext
, pCallback
) );
374 //------------------------------------------------------------------------
375 extern "C" CPPU_DLLPUBLIC
void SAL_CALL
typelib_typedescription_revokeCallback(
376 void * pContext
, typelib_typedescription_Callback pCallback
)
379 TypeDescriptor_Init_Impl
&rInit
= Init::get();
380 if( rInit
.pCallbacks
)
382 // todo mt safe: guard is no solution, can not acquire while calling callback!
383 // OslGuard aGuard( rInit.getMutex() );
384 CallbackEntry
aEntry( pContext
, pCallback
);
385 CallbackSet_Impl::iterator
iPos( rInit
.pCallbacks
->begin() );
386 while (!(iPos
== rInit
.pCallbacks
->end()))
390 rInit
.pCallbacks
->erase( iPos
);
391 iPos
= rInit
.pCallbacks
->begin();
401 extern "C" sal_Int32 SAL_CALL
typelib_typedescription_getAlignedUnoSize(
402 const typelib_TypeDescription
* pTypeDescription
,
403 sal_Int32 nOffset
, sal_Int32
& rMaxIntegralTypeSize
)
404 SAL_THROW_EXTERN_C();
406 //------------------------------------------------------------------------
407 static inline void typelib_typedescription_initTables(
408 typelib_TypeDescription
* pTD
)
411 typelib_InterfaceTypeDescription
* pITD
= (typelib_InterfaceTypeDescription
*)pTD
;
413 sal_Bool
* pReadWriteAttributes
= (sal_Bool
*)alloca( pITD
->nAllMembers
);
414 for ( sal_Int32 i
= pITD
->nAllMembers
; i
--; )
416 pReadWriteAttributes
[i
] = sal_False
;
417 if( typelib_TypeClass_INTERFACE_ATTRIBUTE
== pITD
->ppAllMembers
[i
]->eTypeClass
)
419 typelib_TypeDescription
* pM
= 0;
420 TYPELIB_DANGER_GET( &pM
, pITD
->ppAllMembers
[i
] );
424 pReadWriteAttributes
[i
] = !((typelib_InterfaceAttributeTypeDescription
*)pM
)->bReadOnly
;
425 TYPELIB_DANGER_RELEASE( pM
);
427 #if OSL_DEBUG_LEVEL > 1
430 OString
aStr( rtl::OUStringToOString( pITD
->ppAllMembers
[i
]->pTypeName
, RTL_TEXTENCODING_ASCII_US
) );
431 OSL_TRACE( "\n### cannot get attribute type description: %s", aStr
.getStr() );
437 MutexGuard
aGuard( Init::get().getMutex() );
438 if( !pTD
->bComplete
)
440 // create the index table from member to function table
441 pITD
->pMapMemberIndexToFunctionIndex
= new sal_Int32
[ pITD
->nAllMembers
];
442 sal_Int32 nAdditionalOffset
= 0; // +1 for read/write attributes
444 for( i
= 0; i
< pITD
->nAllMembers
; i
++ )
446 // index to the get method of the attribute
447 pITD
->pMapMemberIndexToFunctionIndex
[i
] = i
+ nAdditionalOffset
;
448 // extra offset if it is a read/write attribute?
449 if( pReadWriteAttributes
[i
] )
451 // a read/write attribute
456 // create the index table from function to member table
457 pITD
->pMapFunctionIndexToMemberIndex
= new sal_Int32
[ pITD
->nAllMembers
+ nAdditionalOffset
];
458 nAdditionalOffset
= 0; // +1 for read/write attributes
459 for( i
= 0; i
< pITD
->nAllMembers
; i
++ )
461 // index to the get method of the attribute
462 pITD
->pMapFunctionIndexToMemberIndex
[i
+ nAdditionalOffset
] = i
;
463 // extra offset if it is a read/write attribute?
464 if( pReadWriteAttributes
[i
] )
466 // a read/write attribute
467 pITD
->pMapFunctionIndexToMemberIndex
[i
+ ++nAdditionalOffset
] = i
;
470 // must be the last action after all initialization is done
471 pITD
->nMapFunctionIndexToMemberIndex
= pITD
->nAllMembers
+ nAdditionalOffset
;
472 pTD
->bComplete
= sal_True
;
478 // In some situations (notably typelib_typedescription_newInterfaceMethod and
479 // typelib_typedescription_newInterfaceAttribute), only the members nMembers,
480 // ppMembers, nAllMembers, and ppAllMembers of an incomplete interface type
481 // description are necessary, but not the additional
482 // pMapMemberIndexToFunctionIndex, nMapFunctionIndexToMemberIndex, and
483 // pMapFunctionIndexToMemberIndex (which are computed by
484 // typelib_typedescription_initTables). Furthermore, in those situations, it
485 // might be illegal to compute those tables, as the creation of the interface
486 // member type descriptions would recursively require a complete interface type
487 // description. The parameter initTables controls whether or not to call
488 // typelib_typedescription_initTables in those situations.
489 bool complete(typelib_TypeDescription
** ppTypeDescr
, bool initTables
) {
490 if (! (*ppTypeDescr
)->bComplete
)
492 OSL_ASSERT( (typelib_TypeClass_STRUCT
== (*ppTypeDescr
)->eTypeClass
||
493 typelib_TypeClass_EXCEPTION
== (*ppTypeDescr
)->eTypeClass
||
494 typelib_TypeClass_UNION
== (*ppTypeDescr
)->eTypeClass
||
495 typelib_TypeClass_ENUM
== (*ppTypeDescr
)->eTypeClass
||
496 typelib_TypeClass_INTERFACE
== (*ppTypeDescr
)->eTypeClass
) &&
497 !reallyWeak( (*ppTypeDescr
)->eTypeClass
) );
499 if (typelib_TypeClass_INTERFACE
== (*ppTypeDescr
)->eTypeClass
&&
500 ((typelib_InterfaceTypeDescription
*)*ppTypeDescr
)->ppAllMembers
)
503 typelib_typedescription_initTables( *ppTypeDescr
);
508 typelib_TypeDescription
* pTD
= 0;
509 // on demand access of complete td
510 TypeDescriptor_Init_Impl
&rInit
= Init::get();
511 rInit
.callChain( &pTD
, (*ppTypeDescr
)->pTypeName
);
514 if (typelib_TypeClass_TYPEDEF
== pTD
->eTypeClass
)
516 typelib_typedescriptionreference_getDescription(
517 &pTD
, ((typelib_IndirectTypeDescription
*)pTD
)->pType
);
523 OSL_ASSERT( typelib_TypeClass_TYPEDEF
!= pTD
->eTypeClass
);
524 // typedescription found
526 pTD
->bOnDemand
= sal_True
;
528 if (pTD
->eTypeClass
== typelib_TypeClass_INTERFACE
529 && !pTD
->bComplete
&& initTables
)
531 // mandatory info from callback chain
532 OSL_ASSERT( ((typelib_InterfaceTypeDescription
*)pTD
)->ppAllMembers
);
533 // complete except of tables init
534 typelib_typedescription_initTables( pTD
);
535 pTD
->bComplete
= sal_True
;
538 // The type description is hold by the reference until
539 // on demand is activated.
540 ::typelib_typedescription_register( &pTD
); // replaces incomplete one
541 OSL_ASSERT( pTD
== *ppTypeDescr
); // has to merge into existing one
543 // insert into the chache
544 MutexGuard
aGuard( rInit
.getMutex() );
546 rInit
.pCache
= new TypeDescriptionList_Impl
;
547 if( (sal_Int32
)rInit
.pCache
->size() >= nCacheSize
)
549 typelib_typedescription_release( rInit
.pCache
->front() );
550 rInit
.pCache
->pop_front();
552 // descriptions in the cache must be acquired!
553 typelib_typedescription_acquire( pTD
);
554 rInit
.pCache
->push_back( pTD
);
558 || (pTD
->eTypeClass
== typelib_TypeClass_INTERFACE
561 ::typelib_typedescription_release( *ppTypeDescr
);
566 #if OSL_DEBUG_LEVEL > 1
568 rtl::OUStringToOString( (*ppTypeDescr
)->pTypeName
, RTL_TEXTENCODING_ASCII_US
) );
569 OSL_TRACE( "\n### type cannot be completed: %s", aStr
.getStr() );
579 //------------------------------------------------------------------------
580 extern "C" void SAL_CALL
typelib_typedescription_newEmpty(
581 typelib_TypeDescription
** ppRet
,
582 typelib_TypeClass eTypeClass
, rtl_uString
* pTypeName
)
587 typelib_typedescription_release( *ppRet
);
591 OSL_ASSERT( typelib_TypeClass_TYPEDEF
!= eTypeClass
);
593 typelib_TypeDescription
* pRet
;
596 case typelib_TypeClass_ARRAY
:
598 typelib_ArrayTypeDescription
* pTmp
= new typelib_ArrayTypeDescription();
599 typelib_IndirectTypeDescription
* pIndirect
= (typelib_IndirectTypeDescription
*)pTmp
;
600 pRet
= (typelib_TypeDescription
*)pTmp
;
601 #if OSL_DEBUG_LEVEL > 1
602 osl_atomic_increment( &Init::get().nArrayTypeDescriptionCount
);
604 pIndirect
->pType
= 0;
605 pTmp
->nDimensions
= 0;
606 pTmp
->nTotalElements
= 0;
607 pTmp
->pDimensions
= 0;
611 case typelib_TypeClass_SEQUENCE
:
613 typelib_IndirectTypeDescription
* pTmp
= new typelib_IndirectTypeDescription();
614 pRet
= (typelib_TypeDescription
*)pTmp
;
615 #if OSL_DEBUG_LEVEL > 1
616 osl_atomic_increment( &Init::get().nIndirectTypeDescriptionCount
);
622 case typelib_TypeClass_UNION
:
624 typelib_UnionTypeDescription
* pTmp
;
625 pTmp
= new typelib_UnionTypeDescription();
626 pRet
= (typelib_TypeDescription
*)pTmp
;
627 #if OSL_DEBUG_LEVEL > 1
628 osl_atomic_increment( &Init::get().nUnionTypeDescriptionCount
);
631 pTmp
->pDiscriminantTypeRef
= 0;
632 pTmp
->pDiscriminants
= 0;
633 pTmp
->ppTypeRefs
= 0;
634 pTmp
->ppMemberNames
= 0;
635 pTmp
->pDefaultTypeRef
= 0;
639 case typelib_TypeClass_STRUCT
:
641 // FEATURE_EMPTYCLASS
642 typelib_StructTypeDescription
* pTmp
;
643 pTmp
= new typelib_StructTypeDescription();
644 pRet
= (typelib_TypeDescription
*)pTmp
;
645 #if OSL_DEBUG_LEVEL > 1
646 osl_atomic_increment( &Init::get().nCompoundTypeDescriptionCount
);
648 pTmp
->aBase
.pBaseTypeDescription
= 0;
649 pTmp
->aBase
.nMembers
= 0;
650 pTmp
->aBase
.pMemberOffsets
= 0;
651 pTmp
->aBase
.ppTypeRefs
= 0;
652 pTmp
->aBase
.ppMemberNames
= 0;
653 pTmp
->pParameterizedTypes
= 0;
657 case typelib_TypeClass_EXCEPTION
:
659 // FEATURE_EMPTYCLASS
660 typelib_CompoundTypeDescription
* pTmp
;
661 pTmp
= new typelib_CompoundTypeDescription();
662 pRet
= (typelib_TypeDescription
*)pTmp
;
663 #if OSL_DEBUG_LEVEL > 1
664 osl_atomic_increment( &Init::get().nCompoundTypeDescriptionCount
);
666 pTmp
->pBaseTypeDescription
= 0;
668 pTmp
->pMemberOffsets
= 0;
669 pTmp
->ppTypeRefs
= 0;
670 pTmp
->ppMemberNames
= 0;
674 case typelib_TypeClass_ENUM
:
676 typelib_EnumTypeDescription
* pTmp
= new typelib_EnumTypeDescription();
677 pRet
= (typelib_TypeDescription
*)pTmp
;
678 #if OSL_DEBUG_LEVEL > 1
679 osl_atomic_increment( &Init::get().nEnumTypeDescriptionCount
);
681 pTmp
->nDefaultEnumValue
= 0;
682 pTmp
->nEnumValues
= 0;
683 pTmp
->ppEnumNames
= 0;
684 pTmp
->pEnumValues
= 0;
688 case typelib_TypeClass_INTERFACE
:
690 typelib_InterfaceTypeDescription
* pTmp
= new typelib_InterfaceTypeDescription();
691 pRet
= (typelib_TypeDescription
*)pTmp
;
692 #if OSL_DEBUG_LEVEL > 1
693 osl_atomic_increment( &Init::get().nInterfaceTypeDescriptionCount
);
695 pTmp
->pBaseTypeDescription
= 0;
698 pTmp
->nAllMembers
= 0;
699 pTmp
->ppAllMembers
= 0;
700 pTmp
->nMapFunctionIndexToMemberIndex
= 0;
701 pTmp
->pMapFunctionIndexToMemberIndex
= 0;
702 pTmp
->pMapMemberIndexToFunctionIndex
= 0;
703 pTmp
->nBaseTypes
= 0;
704 pTmp
->ppBaseTypes
= 0;
708 case typelib_TypeClass_INTERFACE_METHOD
:
710 typelib_InterfaceMethodTypeDescription
* pTmp
= new typelib_InterfaceMethodTypeDescription();
711 pRet
= (typelib_TypeDescription
*)pTmp
;
712 #if OSL_DEBUG_LEVEL > 1
713 osl_atomic_increment( &Init::get().nInterfaceMethodTypeDescriptionCount
);
715 pTmp
->aBase
.pMemberName
= 0;
716 pTmp
->pReturnTypeRef
= 0;
719 pTmp
->nExceptions
= 0;
720 pTmp
->ppExceptions
= 0;
721 pTmp
->pInterface
= 0;
727 case typelib_TypeClass_INTERFACE_ATTRIBUTE
:
729 typelib_InterfaceAttributeTypeDescription
* pTmp
= new typelib_InterfaceAttributeTypeDescription();
730 pRet
= (typelib_TypeDescription
*)pTmp
;
731 #if OSL_DEBUG_LEVEL > 1
732 osl_atomic_increment( &Init::get().nInterfaceAttributeTypeDescriptionCount
);
734 pTmp
->aBase
.pMemberName
= 0;
735 pTmp
->pAttributeTypeRef
= 0;
736 pTmp
->pInterface
= 0;
739 pTmp
->nGetExceptions
= 0;
740 pTmp
->ppGetExceptions
= 0;
741 pTmp
->nSetExceptions
= 0;
742 pTmp
->ppSetExceptions
= 0;
748 pRet
= new typelib_TypeDescription();
749 #if OSL_DEBUG_LEVEL > 1
750 osl_atomic_increment( &Init::get().nTypeDescriptionCount
);
755 pRet
->nRefCount
= 1; // reference count is initially 1
756 pRet
->nStaticRefCount
= 0;
757 pRet
->eTypeClass
= eTypeClass
;
759 pRet
->pUniqueIdentifier
= 0;
761 rtl_uString_acquire( pRet
->pTypeName
= pTypeName
);
763 pRet
->bComplete
= sal_True
;
765 pRet
->nAlignment
= 0;
767 pRet
->bOnDemand
= sal_False
;
771 //------------------------------------------------------------------------
774 void newTypeDescription(
775 typelib_TypeDescription
** ppRet
, typelib_TypeClass eTypeClass
,
776 rtl_uString
* pTypeName
, typelib_TypeDescriptionReference
* pType
,
777 sal_Int32 nMembers
, typelib_CompoundMember_Init
* pCompoundMembers
,
778 typelib_StructMember_Init
* pStructMembers
)
781 (pCompoundMembers
== 0 || pStructMembers
== 0)
782 && (pStructMembers
== 0 || eTypeClass
== typelib_TypeClass_STRUCT
));
783 if (typelib_TypeClass_TYPEDEF
== eTypeClass
)
785 OSL_TRACE( "### unexpected typedef!" );
786 typelib_typedescriptionreference_getDescription( ppRet
, pType
);
790 typelib_typedescription_newEmpty( ppRet
, eTypeClass
, pTypeName
);
794 case typelib_TypeClass_SEQUENCE
:
796 OSL_ASSERT( nMembers
== 0 );
797 typelib_typedescriptionreference_acquire( pType
);
798 ((typelib_IndirectTypeDescription
*)*ppRet
)->pType
= pType
;
802 case typelib_TypeClass_EXCEPTION
:
803 case typelib_TypeClass_STRUCT
:
805 // FEATURE_EMPTYCLASS
806 typelib_CompoundTypeDescription
* pTmp
= (typelib_CompoundTypeDescription
*)*ppRet
;
808 sal_Int32 nOffset
= 0;
811 typelib_typedescriptionreference_getDescription(
812 (typelib_TypeDescription
**)&pTmp
->pBaseTypeDescription
, pType
);
813 nOffset
= ((typelib_TypeDescription
*)pTmp
->pBaseTypeDescription
)->nSize
;
814 OSL_ENSURE( newAlignedSize( 0, ((typelib_TypeDescription
*)pTmp
->pBaseTypeDescription
)->nSize
, ((typelib_TypeDescription
*)pTmp
->pBaseTypeDescription
)->nAlignment
) == ((typelib_TypeDescription
*)pTmp
->pBaseTypeDescription
)->nSize
, "### unexpected offset!" );
818 pTmp
->nMembers
= nMembers
;
819 pTmp
->pMemberOffsets
= new sal_Int32
[ nMembers
];
820 pTmp
->ppTypeRefs
= new typelib_TypeDescriptionReference
*[ nMembers
];
821 pTmp
->ppMemberNames
= new rtl_uString
*[ nMembers
];
822 bool polymorphic
= eTypeClass
== typelib_TypeClass_STRUCT
823 && rtl::OUString::unacquired(&pTypeName
).indexOf('<') >= 0;
824 OSL_ASSERT(!polymorphic
|| pStructMembers
!= 0);
826 reinterpret_cast< typelib_StructTypeDescription
* >(pTmp
)->
827 pParameterizedTypes
= new sal_Bool
[nMembers
];
829 for( sal_Int32 i
= 0 ; i
< nMembers
; i
++ )
831 // read the type and member names
832 pTmp
->ppTypeRefs
[i
] = 0;
833 if (pCompoundMembers
!= 0) {
834 typelib_typedescriptionreference_new(
835 pTmp
->ppTypeRefs
+i
, pCompoundMembers
[i
].eTypeClass
,
836 pCompoundMembers
[i
].pTypeName
);
838 pTmp
->ppMemberNames
[i
]
839 = pCompoundMembers
[i
].pMemberName
);
841 typelib_typedescriptionreference_new(
843 pStructMembers
[i
].aBase
.eTypeClass
,
844 pStructMembers
[i
].aBase
.pTypeName
);
846 pTmp
->ppMemberNames
[i
]
847 = pStructMembers
[i
].aBase
.pMemberName
);
852 if (pTmp
->ppTypeRefs
[i
]->eTypeClass
==
853 typelib_TypeClass_SEQUENCE
)
855 // Take care of recursion like
856 // struct S { sequence<S> x; };
857 size
= sizeof(void *);
858 alignment
= adjustAlignment(size
);
860 typelib_TypeDescription
* pTD
= 0;
861 TYPELIB_DANGER_GET( &pTD
, pTmp
->ppTypeRefs
[i
] );
862 OSL_ENSURE( pTD
->nSize
, "### void member?" );
864 alignment
= pTD
->nAlignment
;
865 TYPELIB_DANGER_RELEASE( pTD
);
867 nOffset
= newAlignedSize( nOffset
, size
, alignment
);
868 pTmp
->pMemberOffsets
[i
] = nOffset
- size
;
871 reinterpret_cast< typelib_StructTypeDescription
* >(
872 pTmp
)->pParameterizedTypes
[i
]
873 = pStructMembers
[i
].bParameterizedType
;
884 if( !reallyWeak( eTypeClass
) )
885 (*ppRet
)->pWeakRef
= (typelib_TypeDescriptionReference
*)*ppRet
;
886 if( eTypeClass
!= typelib_TypeClass_VOID
)
888 // sizeof( void ) not allowed
889 (*ppRet
)->nSize
= typelib_typedescription_getAlignedUnoSize( (*ppRet
), 0, (*ppRet
)->nAlignment
);
890 (*ppRet
)->nAlignment
= adjustAlignment( (*ppRet
)->nAlignment
);
896 extern "C" CPPU_DLLPUBLIC
void SAL_CALL
typelib_typedescription_new(
897 typelib_TypeDescription
** ppRet
,
898 typelib_TypeClass eTypeClass
,
899 rtl_uString
* pTypeName
,
900 typelib_TypeDescriptionReference
* pType
,
902 typelib_CompoundMember_Init
* pMembers
)
906 ppRet
, eTypeClass
, pTypeName
, pType
, nMembers
, pMembers
, 0);
909 extern "C" CPPU_DLLPUBLIC
void SAL_CALL
typelib_typedescription_newStruct(
910 typelib_TypeDescription
** ppRet
,
911 rtl_uString
* pTypeName
,
912 typelib_TypeDescriptionReference
* pType
,
914 typelib_StructMember_Init
* pMembers
)
918 ppRet
, typelib_TypeClass_STRUCT
, pTypeName
, pType
, nMembers
, 0,
922 //------------------------------------------------------------------------
923 extern "C" CPPU_DLLPUBLIC
void SAL_CALL
typelib_typedescription_newUnion(
924 typelib_TypeDescription
** ppRet
,
925 rtl_uString
* pTypeName
,
926 typelib_TypeDescriptionReference
* pDiscriminantTypeRef
,
927 sal_Int64 nDefaultDiscriminant
,
928 typelib_TypeDescriptionReference
* pDefaultTypeRef
,
930 typelib_Union_Init
* pMembers
)
933 typelib_typedescription_newEmpty( ppRet
, typelib_TypeClass_UNION
, pTypeName
);
935 typelib_UnionTypeDescription
* pTmp
= (typelib_UnionTypeDescription
*)*ppRet
;
936 typelib_typedescriptionreference_acquire( pTmp
->pDiscriminantTypeRef
= pDiscriminantTypeRef
);
940 pTmp
->nMembers
= nMembers
;
941 // default discriminant
944 pTmp
->pDiscriminants
= new sal_Int64
[ nMembers
];
945 for ( nPos
= nMembers
; nPos
--; )
947 pTmp
->pDiscriminants
[nPos
] = pMembers
[nPos
].nDiscriminant
;
950 // default default discriminant
951 pTmp
->nDefaultDiscriminant
= nDefaultDiscriminant
;
953 // union member types
954 pTmp
->ppTypeRefs
= new typelib_TypeDescriptionReference
*[ nMembers
];
955 for ( nPos
= nMembers
; nPos
--; )
957 typelib_typedescriptionreference_acquire( pTmp
->ppTypeRefs
[nPos
] = pMembers
[nPos
].pTypeRef
);
959 // union member names
960 pTmp
->ppMemberNames
= new rtl_uString
*[ nMembers
];
961 for ( nPos
= nMembers
; nPos
--; )
963 rtl_uString_acquire( pTmp
->ppMemberNames
[nPos
] = pMembers
[nPos
].pMemberName
);
966 // default union type
967 typelib_typedescriptionreference_acquire( pTmp
->pDefaultTypeRef
= pDefaultTypeRef
);
969 if (! reallyWeak( typelib_TypeClass_UNION
))
970 (*ppRet
)->pWeakRef
= (typelib_TypeDescriptionReference
*)*ppRet
;
971 (*ppRet
)->nSize
= typelib_typedescription_getAlignedUnoSize( (*ppRet
), 0, (*ppRet
)->nAlignment
);
972 (*ppRet
)->nAlignment
= adjustAlignment( (*ppRet
)->nAlignment
);
975 //------------------------------------------------------------------------
976 extern "C" CPPU_DLLPUBLIC
void SAL_CALL
typelib_typedescription_newEnum(
977 typelib_TypeDescription
** ppRet
,
978 rtl_uString
* pTypeName
,
979 sal_Int32 nDefaultValue
,
980 sal_Int32 nEnumValues
,
981 rtl_uString
** ppEnumNames
,
982 sal_Int32
* pEnumValues
)
985 typelib_typedescription_newEmpty( ppRet
, typelib_TypeClass_ENUM
, pTypeName
);
986 typelib_EnumTypeDescription
* pEnum
= (typelib_EnumTypeDescription
*)*ppRet
;
988 pEnum
->nDefaultEnumValue
= nDefaultValue
;
989 pEnum
->nEnumValues
= nEnumValues
;
990 pEnum
->ppEnumNames
= new rtl_uString
* [ nEnumValues
];
991 for ( sal_Int32 nPos
= nEnumValues
; nPos
--; )
993 rtl_uString_acquire( pEnum
->ppEnumNames
[nPos
] = ppEnumNames
[nPos
] );
995 pEnum
->pEnumValues
= new sal_Int32
[ nEnumValues
];
996 ::memcpy( pEnum
->pEnumValues
, pEnumValues
, nEnumValues
* sizeof(sal_Int32
) );
998 (*ppRet
)->pWeakRef
= (typelib_TypeDescriptionReference
*)*ppRet
;
999 // sizeof( void ) not allowed
1000 (*ppRet
)->nSize
= typelib_typedescription_getAlignedUnoSize( (*ppRet
), 0, (*ppRet
)->nAlignment
);
1001 (*ppRet
)->nAlignment
= adjustAlignment( (*ppRet
)->nAlignment
);
1004 //------------------------------------------------------------------------
1005 extern "C" CPPU_DLLPUBLIC
void SAL_CALL
typelib_typedescription_newArray(
1006 typelib_TypeDescription
** ppRet
,
1007 typelib_TypeDescriptionReference
* pElementTypeRef
,
1008 sal_Int32 nDimensions
,
1009 sal_Int32
* pDimensions
)
1010 SAL_THROW_EXTERN_C ()
1012 OUStringBuffer
aBuf( 32 );
1013 aBuf
.append( pElementTypeRef
->pTypeName
);
1014 sal_Int32 nElements
= 1;
1015 for (sal_Int32 i
=0; i
< nDimensions
; i
++)
1017 aBuf
.appendAscii("[");
1018 aBuf
.append(pDimensions
[i
]);
1019 aBuf
.appendAscii("]");
1020 nElements
*= pDimensions
[i
];
1022 OUString
aTypeName( aBuf
.makeStringAndClear() );
1025 typelib_typedescription_newEmpty( ppRet
, typelib_TypeClass_ARRAY
, aTypeName
.pData
);
1026 typelib_ArrayTypeDescription
* pArray
= (typelib_ArrayTypeDescription
*)*ppRet
;
1028 pArray
->nDimensions
= nDimensions
;
1029 pArray
->nTotalElements
= nElements
;
1030 pArray
->pDimensions
= new sal_Int32
[ nDimensions
];
1031 ::memcpy( pArray
->pDimensions
, pDimensions
, nDimensions
* sizeof(sal_Int32
) );
1033 typelib_typedescriptionreference_acquire(pElementTypeRef
);
1034 ((typelib_IndirectTypeDescription
*)pArray
)->pType
= pElementTypeRef
;
1036 (*ppRet
)->pWeakRef
= (typelib_TypeDescriptionReference
*)*ppRet
;
1037 // sizeof( void ) not allowed
1038 (*ppRet
)->nSize
= typelib_typedescription_getAlignedUnoSize( *ppRet
, 0, (*ppRet
)->nAlignment
);
1039 (*ppRet
)->nAlignment
= adjustAlignment( (*ppRet
)->nAlignment
);
1042 //------------------------------------------------------------------------
1043 extern "C" CPPU_DLLPUBLIC
void SAL_CALL
typelib_typedescription_newInterface(
1044 typelib_InterfaceTypeDescription
** ppRet
,
1045 rtl_uString
* pTypeName
,
1046 sal_uInt32 nUik1
, sal_uInt16 nUik2
, sal_uInt16 nUik3
, sal_uInt32 nUik4
, sal_uInt32 nUik5
,
1047 typelib_TypeDescriptionReference
* pBaseInterface
,
1049 typelib_TypeDescriptionReference
** ppMembers
)
1050 SAL_THROW_EXTERN_C()
1052 typelib_typedescription_newMIInterface(
1053 ppRet
, pTypeName
, nUik1
, nUik2
, nUik3
, nUik4
, nUik5
,
1054 pBaseInterface
== 0 ? 0 : 1, &pBaseInterface
, nMembers
, ppMembers
);
1057 //------------------------------------------------------------------------
1064 sal_Int32 memberOffset
;
1065 sal_Int32 directBaseIndex
;
1066 sal_Int32 directBaseMemberOffset
;
1067 typelib_InterfaceTypeDescription
const * base
;
1070 typedef std::vector
< Entry
> List
;
1072 BaseList(typelib_InterfaceTypeDescription
const * desc
);
1074 List
const & getList() const { return list
; }
1076 sal_Int32
getBaseMembers() const { return members
; }
1079 typedef std::set
< rtl::OUString
> Set
;
1082 sal_Int32 directBaseIndex
, Set
& directBaseSet
,
1083 sal_Int32
* directBaseMembers
,
1084 typelib_InterfaceTypeDescription
const * desc
);
1091 BaseList::BaseList(typelib_InterfaceTypeDescription
const * desc
) {
1093 for (sal_Int32 i
= 0; i
< desc
->nBaseTypes
; ++i
) {
1095 sal_Int32 directBaseMembers
= 0;
1096 calculate(i
, directBaseSet
, &directBaseMembers
, desc
->ppBaseTypes
[i
]);
1100 void BaseList::calculate(
1101 sal_Int32 directBaseIndex
, Set
& directBaseSet
,
1102 sal_Int32
* directBaseMembers
,
1103 typelib_InterfaceTypeDescription
const * desc
)
1105 for (sal_Int32 i
= 0; i
< desc
->nBaseTypes
; ++i
) {
1107 directBaseIndex
, directBaseSet
, directBaseMembers
,
1108 desc
->ppBaseTypes
[i
]);
1110 if (set
.insert(desc
->aBase
.pTypeName
).second
) {
1112 e
.memberOffset
= members
;
1113 e
.directBaseIndex
= directBaseIndex
;
1114 e
.directBaseMemberOffset
= *directBaseMembers
;
1117 OSL_ASSERT(desc
->ppAllMembers
!= 0);
1118 members
+= desc
->nMembers
;
1120 if (directBaseSet
.insert(desc
->aBase
.pTypeName
).second
) {
1121 OSL_ASSERT(desc
->ppAllMembers
!= 0);
1122 *directBaseMembers
+= desc
->nMembers
;
1128 extern "C" CPPU_DLLPUBLIC
void SAL_CALL
typelib_typedescription_newMIInterface(
1129 typelib_InterfaceTypeDescription
** ppRet
,
1130 rtl_uString
* pTypeName
,
1131 sal_uInt32 nUik1
, sal_uInt16 nUik2
, sal_uInt16 nUik3
, sal_uInt32 nUik4
, sal_uInt32 nUik5
,
1132 sal_Int32 nBaseInterfaces
,
1133 typelib_TypeDescriptionReference
** ppBaseInterfaces
,
1135 typelib_TypeDescriptionReference
** ppMembers
)
1136 SAL_THROW_EXTERN_C()
1139 typelib_typedescription_release(&(*ppRet
)->aBase
);
1143 typelib_InterfaceTypeDescription
* pITD
= 0;
1144 typelib_typedescription_newEmpty(
1145 (typelib_TypeDescription
**)&pITD
, typelib_TypeClass_INTERFACE
, pTypeName
);
1147 pITD
->nBaseTypes
= nBaseInterfaces
;
1148 pITD
->ppBaseTypes
= new typelib_InterfaceTypeDescription
*[nBaseInterfaces
];
1149 for (sal_Int32 i
= 0; i
< nBaseInterfaces
; ++i
) {
1150 pITD
->ppBaseTypes
[i
] = 0;
1151 typelib_typedescriptionreference_getDescription(
1152 reinterpret_cast< typelib_TypeDescription
** >(
1153 &pITD
->ppBaseTypes
[i
]),
1154 ppBaseInterfaces
[i
]);
1155 if (pITD
->ppBaseTypes
[i
] == 0
1157 reinterpret_cast< typelib_TypeDescription
** >(
1158 &pITD
->ppBaseTypes
[i
]),
1164 OSL_ASSERT(pITD
->ppBaseTypes
[i
] != 0);
1166 if (nBaseInterfaces
> 0) {
1167 pITD
->pBaseTypeDescription
= pITD
->ppBaseTypes
[0];
1170 pITD
->aUik
.m_Data1
= nUik1
;
1171 pITD
->aUik
.m_Data2
= nUik2
;
1172 pITD
->aUik
.m_Data3
= nUik3
;
1173 pITD
->aUik
.m_Data4
= nUik4
;
1174 pITD
->aUik
.m_Data5
= nUik5
;
1176 BaseList
aBaseList(pITD
);
1177 pITD
->nAllMembers
= nMembers
+ aBaseList
.getBaseMembers();
1178 pITD
->nMembers
= nMembers
;
1180 if( pITD
->nAllMembers
)
1182 // at minimum one member exist, allocate the memory
1183 pITD
->ppAllMembers
= new typelib_TypeDescriptionReference
*[ pITD
->nAllMembers
];
1186 BaseList::List
const & rList
= aBaseList
.getList();
1187 for (BaseList::List::const_iterator
i(rList
.begin()); i
!= rList
.end();
1190 typelib_InterfaceTypeDescription
const * pBase
= i
->base
;
1191 typelib_InterfaceTypeDescription
const * pDirectBase
1192 = pITD
->ppBaseTypes
[i
->directBaseIndex
];
1193 OSL_ASSERT(pBase
->ppAllMembers
!= 0);
1194 for (sal_Int32 j
= 0; j
< pBase
->nMembers
; ++j
) {
1195 typelib_TypeDescriptionReference
const * pDirectBaseMember
1196 = pDirectBase
->ppAllMembers
[i
->directBaseMemberOffset
+ j
];
1197 rtl::OUStringBuffer
aBuf(pDirectBaseMember
->pTypeName
);
1198 aBuf
.appendAscii(RTL_CONSTASCII_STRINGPARAM(":@"));
1199 aBuf
.append(i
->directBaseIndex
);
1200 aBuf
.append(static_cast< sal_Unicode
>(','));
1201 aBuf
.append(i
->memberOffset
+ j
);
1202 aBuf
.append(static_cast< sal_Unicode
>(':'));
1203 aBuf
.append(pITD
->aBase
.pTypeName
);
1204 rtl::OUString
aName(aBuf
.makeStringAndClear());
1205 typelib_TypeDescriptionReference
* pDerivedMember
= 0;
1206 typelib_typedescriptionreference_new(
1207 &pDerivedMember
, pDirectBaseMember
->eTypeClass
,
1209 pITD
->ppAllMembers
[n
++] = pDerivedMember
;
1215 pITD
->ppMembers
= pITD
->ppAllMembers
+ aBaseList
.getBaseMembers();
1219 for( sal_Int32 i
= 0; i
< nMembers
; i
++ )
1221 typelib_typedescriptionreference_acquire( ppMembers
[i
] );
1222 pITD
->ppAllMembers
[n
++] = ppMembers
[i
];
1226 typelib_TypeDescription
* pTmp
= (typelib_TypeDescription
*)pITD
;
1227 if( !reallyWeak( typelib_TypeClass_INTERFACE
) )
1228 pTmp
->pWeakRef
= (typelib_TypeDescriptionReference
*)pTmp
;
1229 pTmp
->nSize
= typelib_typedescription_getAlignedUnoSize( pTmp
, 0, pTmp
->nAlignment
);
1230 pTmp
->nAlignment
= adjustAlignment( pTmp
->nAlignment
);
1231 pTmp
->bComplete
= sal_False
;
1236 //------------------------------------------------------------------------
1240 typelib_TypeDescriptionReference
** copyExceptions(
1241 sal_Int32 count
, rtl_uString
** typeNames
)
1243 OSL_ASSERT(count
>= 0);
1247 typelib_TypeDescriptionReference
** p
1248 = new typelib_TypeDescriptionReference
*[count
];
1249 for (sal_Int32 i
= 0; i
< count
; ++i
) {
1251 typelib_typedescriptionreference_new(
1252 p
+ i
, typelib_TypeClass_EXCEPTION
, typeNames
[i
]);
1259 extern "C" CPPU_DLLPUBLIC
void SAL_CALL
typelib_typedescription_newInterfaceMethod(
1260 typelib_InterfaceMethodTypeDescription
** ppRet
,
1261 sal_Int32 nAbsolutePosition
,
1263 rtl_uString
* pTypeName
,
1264 typelib_TypeClass eReturnTypeClass
,
1265 rtl_uString
* pReturnTypeName
,
1267 typelib_Parameter_Init
* pParams
,
1268 sal_Int32 nExceptions
,
1269 rtl_uString
** ppExceptionNames
)
1270 SAL_THROW_EXTERN_C()
1273 typelib_typedescription_release(&(*ppRet
)->aBase
.aBase
);
1276 sal_Int32 nOffset
= rtl_ustr_lastIndexOfChar_WithLength(
1277 pTypeName
->buffer
, pTypeName
->length
, ':');
1278 if (nOffset
<= 0 || pTypeName
->buffer
[nOffset
- 1] != ':') {
1279 OSL_FAIL("Bad interface method type name");
1282 rtl::OUString
aInterfaceTypeName(pTypeName
->buffer
, nOffset
- 1);
1283 typelib_InterfaceTypeDescription
* pInterface
= 0;
1284 typelib_typedescription_getByName(
1285 reinterpret_cast< typelib_TypeDescription
** >(&pInterface
),
1286 aInterfaceTypeName
.pData
);
1288 || pInterface
->aBase
.eTypeClass
!= typelib_TypeClass_INTERFACE
1290 reinterpret_cast< typelib_TypeDescription
** >(&pInterface
), false))
1292 OSL_FAIL("No interface corresponding to interface method");
1296 typelib_typedescription_newEmpty(
1297 (typelib_TypeDescription
**)ppRet
, typelib_TypeClass_INTERFACE_METHOD
, pTypeName
);
1298 typelib_TypeDescription
* pTmp
= (typelib_TypeDescription
*)*ppRet
;
1300 rtl_uString_newFromStr_WithLength( &(*ppRet
)->aBase
.pMemberName
,
1301 pTypeName
->buffer
+ nOffset
+1,
1302 pTypeName
->length
- nOffset
-1 );
1303 (*ppRet
)->aBase
.nPosition
= nAbsolutePosition
;
1304 (*ppRet
)->bOneWay
= bOneWay
;
1305 typelib_typedescriptionreference_new( &(*ppRet
)->pReturnTypeRef
, eReturnTypeClass
, pReturnTypeName
);
1306 (*ppRet
)->nParams
= nParams
;
1309 (*ppRet
)->pParams
= new typelib_MethodParameter
[ nParams
];
1311 for( sal_Int32 i
= 0; i
< nParams
; i
++ )
1313 // get the name of the parameter
1314 (*ppRet
)->pParams
[ i
].pName
= 0;
1315 rtl_uString_acquire( (*ppRet
)->pParams
[ i
].pName
= pParams
[i
].pParamName
);
1316 (*ppRet
)->pParams
[ i
].pTypeRef
= 0;
1317 // get the type name of the parameter and create the weak reference
1318 typelib_typedescriptionreference_new(
1319 &(*ppRet
)->pParams
[ i
].pTypeRef
, pParams
[i
].eTypeClass
, pParams
[i
].pTypeName
);
1320 (*ppRet
)->pParams
[ i
].bIn
= pParams
[i
].bIn
;
1321 (*ppRet
)->pParams
[ i
].bOut
= pParams
[i
].bOut
;
1324 (*ppRet
)->nExceptions
= nExceptions
;
1325 (*ppRet
)->ppExceptions
= copyExceptions(nExceptions
, ppExceptionNames
);
1326 (*ppRet
)->pInterface
= pInterface
;
1327 (*ppRet
)->pBaseRef
= 0;
1329 (nAbsolutePosition
>= pInterface
->nAllMembers
- pInterface
->nMembers
)
1330 && nAbsolutePosition
< pInterface
->nAllMembers
);
1331 (*ppRet
)->nIndex
= nAbsolutePosition
1332 - (pInterface
->nAllMembers
- pInterface
->nMembers
);
1333 if( !reallyWeak( typelib_TypeClass_INTERFACE_METHOD
) )
1334 pTmp
->pWeakRef
= (typelib_TypeDescriptionReference
*)pTmp
;
1338 //------------------------------------------------------------------------
1339 extern "C" CPPU_DLLPUBLIC
void SAL_CALL
typelib_typedescription_newInterfaceAttribute(
1340 typelib_InterfaceAttributeTypeDescription
** ppRet
,
1341 sal_Int32 nAbsolutePosition
,
1342 rtl_uString
* pTypeName
,
1343 typelib_TypeClass eAttributeTypeClass
,
1344 rtl_uString
* pAttributeTypeName
,
1345 sal_Bool bReadOnly
)
1346 SAL_THROW_EXTERN_C()
1348 typelib_typedescription_newExtendedInterfaceAttribute(
1349 ppRet
, nAbsolutePosition
, pTypeName
, eAttributeTypeClass
,
1350 pAttributeTypeName
, bReadOnly
, 0, 0, 0, 0);
1353 //------------------------------------------------------------------------
1354 extern "C" CPPU_DLLPUBLIC
void SAL_CALL
typelib_typedescription_newExtendedInterfaceAttribute(
1355 typelib_InterfaceAttributeTypeDescription
** ppRet
,
1356 sal_Int32 nAbsolutePosition
,
1357 rtl_uString
* pTypeName
,
1358 typelib_TypeClass eAttributeTypeClass
,
1359 rtl_uString
* pAttributeTypeName
,
1361 sal_Int32 nGetExceptions
, rtl_uString
** ppGetExceptionNames
,
1362 sal_Int32 nSetExceptions
, rtl_uString
** ppSetExceptionNames
)
1363 SAL_THROW_EXTERN_C()
1366 typelib_typedescription_release(&(*ppRet
)->aBase
.aBase
);
1369 sal_Int32 nOffset
= rtl_ustr_lastIndexOfChar_WithLength(
1370 pTypeName
->buffer
, pTypeName
->length
, ':');
1371 if (nOffset
<= 0 || pTypeName
->buffer
[nOffset
- 1] != ':') {
1372 OSL_FAIL("Bad interface attribute type name");
1375 rtl::OUString
aInterfaceTypeName(pTypeName
->buffer
, nOffset
- 1);
1376 typelib_InterfaceTypeDescription
* pInterface
= 0;
1377 typelib_typedescription_getByName(
1378 reinterpret_cast< typelib_TypeDescription
** >(&pInterface
),
1379 aInterfaceTypeName
.pData
);
1381 || pInterface
->aBase
.eTypeClass
!= typelib_TypeClass_INTERFACE
1383 reinterpret_cast< typelib_TypeDescription
** >(&pInterface
), false))
1385 OSL_FAIL("No interface corresponding to interface attribute");
1389 typelib_typedescription_newEmpty(
1390 (typelib_TypeDescription
**)ppRet
, typelib_TypeClass_INTERFACE_ATTRIBUTE
, pTypeName
);
1391 typelib_TypeDescription
* pTmp
= (typelib_TypeDescription
*)*ppRet
;
1393 rtl_uString_newFromStr_WithLength( &(*ppRet
)->aBase
.pMemberName
,
1394 pTypeName
->buffer
+ nOffset
+1,
1395 pTypeName
->length
- nOffset
-1 );
1396 (*ppRet
)->aBase
.nPosition
= nAbsolutePosition
;
1397 typelib_typedescriptionreference_new( &(*ppRet
)->pAttributeTypeRef
, eAttributeTypeClass
, pAttributeTypeName
);
1398 (*ppRet
)->bReadOnly
= bReadOnly
;
1399 (*ppRet
)->pInterface
= pInterface
;
1400 (*ppRet
)->pBaseRef
= 0;
1402 (nAbsolutePosition
>= pInterface
->nAllMembers
- pInterface
->nMembers
)
1403 && nAbsolutePosition
< pInterface
->nAllMembers
);
1404 (*ppRet
)->nIndex
= nAbsolutePosition
1405 - (pInterface
->nAllMembers
- pInterface
->nMembers
);
1406 (*ppRet
)->nGetExceptions
= nGetExceptions
;
1407 (*ppRet
)->ppGetExceptions
= copyExceptions(
1408 nGetExceptions
, ppGetExceptionNames
);
1409 (*ppRet
)->nSetExceptions
= nSetExceptions
;
1410 (*ppRet
)->ppSetExceptions
= copyExceptions(
1411 nSetExceptions
, ppSetExceptionNames
);
1412 if( !reallyWeak( typelib_TypeClass_INTERFACE_ATTRIBUTE
) )
1413 pTmp
->pWeakRef
= (typelib_TypeDescriptionReference
*)pTmp
;
1416 //------------------------------------------------------------------------
1417 extern "C" CPPU_DLLPUBLIC
void SAL_CALL
typelib_typedescription_acquire(
1418 typelib_TypeDescription
* pTypeDescription
)
1419 SAL_THROW_EXTERN_C()
1421 osl_atomic_increment( &pTypeDescription
->nRefCount
);
1424 //------------------------------------------------------------------------
1428 void deleteExceptions(
1429 sal_Int32 count
, typelib_TypeDescriptionReference
** exceptions
)
1431 for (sal_Int32 i
= 0; i
< count
; ++i
) {
1432 typelib_typedescriptionreference_release(exceptions
[i
]);
1434 delete[] exceptions
;
1439 // frees anything except typelib_TypeDescription base!
1440 static inline void typelib_typedescription_destructExtendedMembers(
1441 typelib_TypeDescription
* pTD
)
1444 OSL_ASSERT( typelib_TypeClass_TYPEDEF
!= pTD
->eTypeClass
);
1446 switch( pTD
->eTypeClass
)
1448 case typelib_TypeClass_ARRAY
:
1449 if( ((typelib_IndirectTypeDescription
*)pTD
)->pType
)
1450 typelib_typedescriptionreference_release( ((typelib_IndirectTypeDescription
*)pTD
)->pType
);
1451 delete [] ((typelib_ArrayTypeDescription
*)pTD
)->pDimensions
;
1453 case typelib_TypeClass_SEQUENCE
:
1454 if( ((typelib_IndirectTypeDescription
*)pTD
)->pType
)
1455 typelib_typedescriptionreference_release( ((typelib_IndirectTypeDescription
*)pTD
)->pType
);
1457 case typelib_TypeClass_UNION
:
1459 typelib_UnionTypeDescription
* pUnionTD
= (typelib_UnionTypeDescription
*)pTD
;
1460 typelib_typedescriptionreference_release( pUnionTD
->pDiscriminantTypeRef
);
1461 typelib_typedescriptionreference_release( pUnionTD
->pDefaultTypeRef
);
1464 typelib_TypeDescriptionReference
** ppTypeRefs
= pUnionTD
->ppTypeRefs
;
1465 for ( nPos
= pUnionTD
->nMembers
; nPos
--; )
1467 typelib_typedescriptionreference_release( ppTypeRefs
[nPos
] );
1470 rtl_uString
** ppMemberNames
= pUnionTD
->ppMemberNames
;
1471 for ( nPos
= pUnionTD
->nMembers
; nPos
--; )
1473 rtl_uString_release( ppMemberNames
[nPos
] );
1475 delete [] pUnionTD
->ppMemberNames
;
1476 delete [] pUnionTD
->pDiscriminants
;
1477 delete [] pUnionTD
->ppTypeRefs
;
1480 case typelib_TypeClass_STRUCT
:
1481 delete[] reinterpret_cast< typelib_StructTypeDescription
* >(pTD
)->
1482 pParameterizedTypes
;
1483 // Fall-through intentional
1484 case typelib_TypeClass_EXCEPTION
:
1486 typelib_CompoundTypeDescription
* pCTD
= (typelib_CompoundTypeDescription
*)pTD
;
1487 if( pCTD
->pBaseTypeDescription
)
1488 typelib_typedescription_release( (typelib_TypeDescription
*)pCTD
->pBaseTypeDescription
);
1490 for( i
= 0; i
< pCTD
->nMembers
; i
++ )
1492 typelib_typedescriptionreference_release( pCTD
->ppTypeRefs
[i
] );
1494 if (pCTD
->ppMemberNames
)
1496 for ( i
= 0; i
< pCTD
->nMembers
; i
++ )
1498 rtl_uString_release( pCTD
->ppMemberNames
[i
] );
1500 delete [] pCTD
->ppMemberNames
;
1502 delete [] pCTD
->ppTypeRefs
;
1503 delete [] pCTD
->pMemberOffsets
;
1506 case typelib_TypeClass_INTERFACE
:
1508 typelib_InterfaceTypeDescription
* pITD
= (typelib_InterfaceTypeDescription
*)pTD
;
1509 for( sal_Int32 i
= 0; i
< pITD
->nAllMembers
; i
++ )
1511 typelib_typedescriptionreference_release( pITD
->ppAllMembers
[i
] );
1513 delete [] pITD
->ppAllMembers
;
1514 delete [] pITD
->pMapMemberIndexToFunctionIndex
;
1515 delete [] pITD
->pMapFunctionIndexToMemberIndex
;
1516 for (sal_Int32 i
= 0; i
< pITD
->nBaseTypes
; ++i
) {
1517 typelib_typedescription_release(
1518 reinterpret_cast< typelib_TypeDescription
* >(
1519 pITD
->ppBaseTypes
[i
]));
1521 delete[] pITD
->ppBaseTypes
;
1524 case typelib_TypeClass_INTERFACE_METHOD
:
1526 typelib_InterfaceMethodTypeDescription
* pIMTD
= (typelib_InterfaceMethodTypeDescription
*)pTD
;
1527 if( pIMTD
->pReturnTypeRef
)
1528 typelib_typedescriptionreference_release( pIMTD
->pReturnTypeRef
);
1529 for( sal_Int32 i
= 0; i
< pIMTD
->nParams
; i
++ )
1531 rtl_uString_release( pIMTD
->pParams
[ i
].pName
);
1532 typelib_typedescriptionreference_release( pIMTD
->pParams
[ i
].pTypeRef
);
1534 delete [] pIMTD
->pParams
;
1535 deleteExceptions(pIMTD
->nExceptions
, pIMTD
->ppExceptions
);
1536 rtl_uString_release( pIMTD
->aBase
.pMemberName
);
1537 typelib_typedescription_release(&pIMTD
->pInterface
->aBase
);
1538 if (pIMTD
->pBaseRef
!= 0) {
1539 typelib_typedescriptionreference_release(pIMTD
->pBaseRef
);
1543 case typelib_TypeClass_INTERFACE_ATTRIBUTE
:
1545 typelib_InterfaceAttributeTypeDescription
* pIATD
= (typelib_InterfaceAttributeTypeDescription
*)pTD
;
1546 deleteExceptions(pIATD
->nGetExceptions
, pIATD
->ppGetExceptions
);
1547 deleteExceptions(pIATD
->nSetExceptions
, pIATD
->ppSetExceptions
);
1548 if( pIATD
->pAttributeTypeRef
)
1549 typelib_typedescriptionreference_release( pIATD
->pAttributeTypeRef
);
1550 if( pIATD
->aBase
.pMemberName
)
1551 rtl_uString_release( pIATD
->aBase
.pMemberName
);
1552 typelib_typedescription_release(&pIATD
->pInterface
->aBase
);
1553 if (pIATD
->pBaseRef
!= 0) {
1554 typelib_typedescriptionreference_release(pIATD
->pBaseRef
);
1558 case typelib_TypeClass_ENUM
:
1560 typelib_EnumTypeDescription
* pEnum
= (typelib_EnumTypeDescription
*)pTD
;
1561 for ( sal_Int32 nPos
= pEnum
->nEnumValues
; nPos
--; )
1563 rtl_uString_release( pEnum
->ppEnumNames
[nPos
] );
1565 delete [] pEnum
->ppEnumNames
;
1566 delete [] pEnum
->pEnumValues
;
1574 //------------------------------------------------------------------------
1575 extern "C" CPPU_DLLPUBLIC
void SAL_CALL
typelib_typedescription_release(
1576 typelib_TypeDescription
* pTD
)
1577 SAL_THROW_EXTERN_C()
1579 sal_Int32 ref
= osl_atomic_decrement( &pTD
->nRefCount
);
1580 OSL_ASSERT(ref
>= 0);
1583 TypeDescriptor_Init_Impl
&rInit
= Init::get();
1584 if( reallyWeak( pTD
->eTypeClass
) )
1589 MutexGuard
aGuard( rInit
.getMutex() );
1590 // remove this description from the weak reference
1591 pTD
->pWeakRef
->pType
= 0;
1593 typelib_typedescriptionreference_release( pTD
->pWeakRef
);
1598 // this description is a reference too, so remove it from the hash table
1599 if( rInit
.pWeakMap
)
1601 MutexGuard
aGuard( rInit
.getMutex() );
1602 WeakMap_Impl::iterator aIt
= rInit
.pWeakMap
->find( (sal_Unicode
*)pTD
->pTypeName
->buffer
);
1603 if( aIt
!= rInit
.pWeakMap
->end() && (void *)(*aIt
).second
== (void *)pTD
)
1605 // remove only if it contains the same object
1606 rInit
.pWeakMap
->erase( aIt
);
1611 typelib_typedescription_destructExtendedMembers( pTD
);
1612 rtl_uString_release( pTD
->pTypeName
);
1614 #if OSL_DEBUG_LEVEL > 1
1615 switch( pTD
->eTypeClass
)
1617 case typelib_TypeClass_ARRAY
:
1618 osl_atomic_decrement( &rInit
.nArrayTypeDescriptionCount
);
1620 case typelib_TypeClass_SEQUENCE
:
1621 osl_atomic_decrement( &rInit
.nIndirectTypeDescriptionCount
);
1623 case typelib_TypeClass_UNION
:
1624 osl_atomic_decrement( &rInit
.nUnionTypeDescriptionCount
);
1626 case typelib_TypeClass_STRUCT
:
1627 case typelib_TypeClass_EXCEPTION
:
1628 osl_atomic_decrement( &rInit
.nCompoundTypeDescriptionCount
);
1630 case typelib_TypeClass_INTERFACE
:
1631 osl_atomic_decrement( &rInit
.nInterfaceTypeDescriptionCount
);
1633 case typelib_TypeClass_INTERFACE_METHOD
:
1634 osl_atomic_decrement( &rInit
.nInterfaceMethodTypeDescriptionCount
);
1636 case typelib_TypeClass_INTERFACE_ATTRIBUTE
:
1637 osl_atomic_decrement( &rInit
.nInterfaceAttributeTypeDescriptionCount
);
1639 case typelib_TypeClass_ENUM
:
1640 osl_atomic_decrement( &rInit
.nEnumTypeDescriptionCount
);
1643 osl_atomic_decrement( &rInit
.nTypeDescriptionCount
);
1651 //------------------------------------------------------------------------
1652 extern "C" CPPU_DLLPUBLIC
void SAL_CALL
typelib_typedescription_register(
1653 typelib_TypeDescription
** ppNewDescription
)
1654 SAL_THROW_EXTERN_C()
1656 // connect the description with the weak reference
1657 TypeDescriptor_Init_Impl
&rInit
= Init::get();
1658 ClearableMutexGuard
aGuard( rInit
.getMutex() );
1660 typelib_TypeDescriptionReference
* pTDR
= 0;
1661 typelib_typedescriptionreference_getByName( &pTDR
, (*ppNewDescription
)->pTypeName
);
1663 OSL_ASSERT( (*ppNewDescription
)->pWeakRef
|| reallyWeak( (*ppNewDescription
)->eTypeClass
) );
1666 OSL_ASSERT( (*ppNewDescription
)->eTypeClass
== pTDR
->eTypeClass
);
1669 if (reallyWeak( pTDR
->eTypeClass
))
1671 // pRef->pType->pWeakRef == 0 means that the description is empty
1672 if (pTDR
->pType
->pWeakRef
)
1674 if (osl_atomic_increment( &pTDR
->pType
->nRefCount
) > 1)
1676 // The refence is incremented. The object cannot be destroyed.
1677 // Release the guard at the earliest point.
1679 ::typelib_typedescription_release( *ppNewDescription
);
1680 *ppNewDescription
= pTDR
->pType
;
1681 ::typelib_typedescriptionreference_release( pTDR
);
1686 // destruction of this type in progress (another thread!)
1687 osl_atomic_decrement( &pTDR
->pType
->nRefCount
);
1691 pTDR
->pType
= *ppNewDescription
;
1692 OSL_ASSERT( ! (*ppNewDescription
)->pWeakRef
);
1693 (*ppNewDescription
)->pWeakRef
= pTDR
;
1698 if (((void *)pTDR
!= (void *)*ppNewDescription
) && // if different
1699 (!pTDR
->pType
->pWeakRef
|| // uninit: ref data only set
1700 // new one is complete:
1701 (!pTDR
->pType
->bComplete
&& (*ppNewDescription
)->bComplete
) ||
1702 // new one may be partly initialized interface (except of tables):
1703 (typelib_TypeClass_INTERFACE
== pTDR
->pType
->eTypeClass
&&
1704 !((typelib_InterfaceTypeDescription
*)pTDR
->pType
)->ppAllMembers
&&
1705 (*(typelib_InterfaceTypeDescription
**)ppNewDescription
)->ppAllMembers
)))
1707 // uninitialized or incomplete
1709 if (pTDR
->pType
->pWeakRef
) // if init
1711 typelib_typedescription_destructExtendedMembers( pTDR
->pType
);
1714 // pTDR->pType->pWeakRef == 0 means that the description is empty
1715 // description is not weak and the not the same
1716 sal_Int32 nSize
= getDescriptionSize( (*ppNewDescription
)->eTypeClass
);
1718 // copy all specific data for the descriptions
1721 *ppNewDescription
+1,
1722 nSize
- sizeof(typelib_TypeDescription
) );
1724 pTDR
->pType
->bComplete
= (*ppNewDescription
)->bComplete
;
1725 pTDR
->pType
->nSize
= (*ppNewDescription
)->nSize
;
1726 pTDR
->pType
->nAlignment
= (*ppNewDescription
)->nAlignment
;
1729 *ppNewDescription
+1,
1731 nSize
- sizeof( typelib_TypeDescription
) );
1733 if( pTDR
->pType
->bOnDemand
&& !(*ppNewDescription
)->bOnDemand
)
1735 // switch from OnDemand to !OnDemand, so the description must be acquired
1736 typelib_typedescription_acquire( pTDR
->pType
);
1738 else if( !pTDR
->pType
->bOnDemand
&& (*ppNewDescription
)->bOnDemand
)
1740 // switch from !OnDemand to OnDemand, so the description must be relesed
1741 typelib_typedescription_release( pTDR
->pType
);
1744 pTDR
->pType
->bOnDemand
= (*ppNewDescription
)->bOnDemand
;
1746 pTDR
->pType
->pWeakRef
= pTDR
;
1749 typelib_typedescription_release( *ppNewDescription
);
1750 // pTDR was acquired by getByName(), so it must not be acquired again
1751 *ppNewDescription
= pTDR
->pType
;
1755 else if( reallyWeak( (*ppNewDescription
)->eTypeClass
) )
1757 typelib_typedescriptionreference_new(
1758 &pTDR
, (*ppNewDescription
)->eTypeClass
, (*ppNewDescription
)->pTypeName
);
1762 pTDR
= (typelib_TypeDescriptionReference
*)*ppNewDescription
;
1763 if( !rInit
.pWeakMap
)
1764 rInit
.pWeakMap
= new WeakMap_Impl
;
1766 // description is the weak itself, so register it
1767 (*rInit
.pWeakMap
)[pTDR
->pTypeName
->buffer
] = pTDR
;
1768 OSL_ASSERT( (void *)*ppNewDescription
== (void *)pTDR
);
1771 // By default this reference is not really weak. The reference hold the description
1772 // and the description hold the reference.
1773 if( !(*ppNewDescription
)->bOnDemand
)
1775 // nor OnDemand so the description must be acquired if registered
1776 typelib_typedescription_acquire( *ppNewDescription
);
1779 pTDR
->pType
= *ppNewDescription
;
1780 (*ppNewDescription
)->pWeakRef
= pTDR
;
1781 OSL_ASSERT( rtl_ustr_compare( pTDR
->pTypeName
->buffer
, (*ppNewDescription
)->pTypeName
->buffer
) == 0 );
1782 OSL_ASSERT( pTDR
->eTypeClass
== (*ppNewDescription
)->eTypeClass
);
1785 //------------------------------------------------------------------------
1786 static inline sal_Bool
type_equals(
1787 typelib_TypeDescriptionReference
* p1
, typelib_TypeDescriptionReference
* p2
)
1791 (p1
->eTypeClass
== p2
->eTypeClass
&&
1792 p1
->pTypeName
->length
== p2
->pTypeName
->length
&&
1793 rtl_ustr_compare( p1
->pTypeName
->buffer
, p2
->pTypeName
->buffer
) == 0));
1795 extern "C" CPPU_DLLPUBLIC sal_Bool SAL_CALL
typelib_typedescription_equals(
1796 const typelib_TypeDescription
* p1
, const typelib_TypeDescription
* p2
)
1797 SAL_THROW_EXTERN_C()
1800 (typelib_TypeDescriptionReference
*)p1
, (typelib_TypeDescriptionReference
*)p2
);
1803 //------------------------------------------------------------------------
1804 extern "C" sal_Int32 SAL_CALL
typelib_typedescription_getAlignedUnoSize(
1805 const typelib_TypeDescription
* pTypeDescription
,
1806 sal_Int32 nOffset
, sal_Int32
& rMaxIntegralTypeSize
)
1807 SAL_THROW_EXTERN_C()
1810 if( pTypeDescription
->nSize
)
1812 // size and alignment are set
1813 rMaxIntegralTypeSize
= pTypeDescription
->nAlignment
;
1814 nSize
= pTypeDescription
->nSize
;
1819 rMaxIntegralTypeSize
= 1;
1821 OSL_ASSERT( typelib_TypeClass_TYPEDEF
!= pTypeDescription
->eTypeClass
);
1823 switch( pTypeDescription
->eTypeClass
)
1825 case typelib_TypeClass_INTERFACE
:
1826 // FEATURE_INTERFACE
1827 nSize
= rMaxIntegralTypeSize
= (sal_Int32
)(sizeof( void * ));
1829 case typelib_TypeClass_UNION
:
1831 nSize
= rMaxIntegralTypeSize
= (sal_Int32
)(sizeof(sal_Int64
));
1832 for ( sal_Int32 nPos
= ((typelib_UnionTypeDescription
*)pTypeDescription
)->nMembers
; nPos
--; )
1834 typelib_TypeDescription
* pTD
= 0;
1835 TYPELIB_DANGER_GET( &pTD
, ((typelib_UnionTypeDescription
*)pTypeDescription
)->ppTypeRefs
[nPos
] );
1836 sal_Int32 nMaxIntegralTypeSize
;
1837 sal_Int32 nMemberSize
= typelib_typedescription_getAlignedUnoSize( pTD
, (sal_Int32
)(sizeof(sal_Int64
)), nMaxIntegralTypeSize
);
1838 TYPELIB_DANGER_RELEASE( pTD
);
1839 if (nSize
< nMemberSize
)
1840 nSize
= nMemberSize
;
1841 if (rMaxIntegralTypeSize
< nMaxIntegralTypeSize
)
1842 rMaxIntegralTypeSize
= nMaxIntegralTypeSize
;
1844 ((typelib_UnionTypeDescription
*)pTypeDescription
)->nValueOffset
= rMaxIntegralTypeSize
;
1847 case typelib_TypeClass_ENUM
:
1848 nSize
= rMaxIntegralTypeSize
= (sal_Int32
)(sizeof( typelib_TypeClass
));
1850 case typelib_TypeClass_STRUCT
:
1851 case typelib_TypeClass_EXCEPTION
:
1852 // FEATURE_EMPTYCLASS
1854 typelib_CompoundTypeDescription
* pTmp
= (typelib_CompoundTypeDescription
*)pTypeDescription
;
1855 sal_Int32 nStructSize
= 0;
1856 if( pTmp
->pBaseTypeDescription
)
1858 // inherit structs extends the base struct.
1859 nStructSize
= pTmp
->pBaseTypeDescription
->aBase
.nSize
;
1860 rMaxIntegralTypeSize
= pTmp
->pBaseTypeDescription
->aBase
.nAlignment
;
1862 for( sal_Int32 i
= 0; i
< pTmp
->nMembers
; i
++ )
1864 typelib_TypeDescription
* pMemberType
= 0;
1865 typelib_TypeDescriptionReference
* pMemberRef
= pTmp
->ppTypeRefs
[i
];
1867 sal_Int32 nMaxIntegral
;
1868 if (pMemberRef
->eTypeClass
== typelib_TypeClass_INTERFACE
1869 || pMemberRef
->eTypeClass
== typelib_TypeClass_SEQUENCE
)
1871 nMaxIntegral
= (sal_Int32
)(sizeof(void *));
1872 nStructSize
= newAlignedSize( nStructSize
, nMaxIntegral
, nMaxIntegral
);
1876 TYPELIB_DANGER_GET( &pMemberType
, pMemberRef
);
1877 nStructSize
= typelib_typedescription_getAlignedUnoSize(
1878 pMemberType
, nStructSize
, nMaxIntegral
);
1879 TYPELIB_DANGER_RELEASE( pMemberType
);
1881 if( nMaxIntegral
> rMaxIntegralTypeSize
)
1882 rMaxIntegralTypeSize
= nMaxIntegral
;
1885 // Anything that is at least 16 bits wide is aligned on a 16-bit
1886 // boundary on the m68k default abi
1887 sal_Int32 nMaxAlign
= (rMaxIntegralTypeSize
> 2) ? 2 : rMaxIntegralTypeSize
;
1888 nStructSize
= (nStructSize
+ nMaxAlign
-1) / nMaxAlign
* nMaxAlign
;
1890 // Example: A { double; int; } structure has a size of 16 instead of 10. The
1891 // compiler must follow this rule if it is possible to access members in arrays through:
1892 // (Element *)((char *)pArray + sizeof( Element ) * ElementPos)
1893 nStructSize
= (nStructSize
+ rMaxIntegralTypeSize
-1)
1894 / rMaxIntegralTypeSize
* rMaxIntegralTypeSize
;
1896 nSize
+= nStructSize
;
1899 case typelib_TypeClass_ARRAY
:
1901 typelib_TypeDescription
* pTD
= 0;
1902 TYPELIB_DANGER_GET( &pTD
, ((typelib_IndirectTypeDescription
*)pTypeDescription
)->pType
);
1903 rMaxIntegralTypeSize
= pTD
->nSize
;
1904 TYPELIB_DANGER_RELEASE( pTD
);
1905 nSize
= ((typelib_ArrayTypeDescription
*)pTypeDescription
)->nTotalElements
* rMaxIntegralTypeSize
;
1908 case typelib_TypeClass_SEQUENCE
:
1909 nSize
= rMaxIntegralTypeSize
= (sal_Int32
)(sizeof( void * ));
1911 case typelib_TypeClass_ANY
:
1913 nSize
= (sal_Int32
)(sizeof( uno_Any
));
1914 rMaxIntegralTypeSize
= (sal_Int32
)(sizeof( void * ));
1916 case typelib_TypeClass_TYPE
:
1917 nSize
= rMaxIntegralTypeSize
= (sal_Int32
)(sizeof( typelib_TypeDescriptionReference
* ));
1919 case typelib_TypeClass_BOOLEAN
:
1920 nSize
= rMaxIntegralTypeSize
= (sal_Int32
)(sizeof( sal_Bool
));
1922 case typelib_TypeClass_CHAR
:
1923 nSize
= rMaxIntegralTypeSize
= (sal_Int32
)(sizeof( sal_Unicode
));
1925 case typelib_TypeClass_STRING
:
1927 nSize
= rMaxIntegralTypeSize
= (sal_Int32
)(sizeof( rtl_uString
* ));
1929 case typelib_TypeClass_FLOAT
:
1930 nSize
= rMaxIntegralTypeSize
= (sal_Int32
)(sizeof( float ));
1932 case typelib_TypeClass_DOUBLE
:
1934 //See previous AIX ifdef comment for an explanation
1935 nSize
= (sal_Int32
)(sizeof(double));
1936 rMaxIntegralTypeSize
= (sal_Int32
)(sizeof(void*));
1938 nSize
= rMaxIntegralTypeSize
= (sal_Int32
)(sizeof( double ));
1941 case typelib_TypeClass_BYTE
:
1942 nSize
= rMaxIntegralTypeSize
= (sal_Int32
)(sizeof( sal_Int8
));
1944 case typelib_TypeClass_SHORT
:
1945 case typelib_TypeClass_UNSIGNED_SHORT
:
1946 nSize
= rMaxIntegralTypeSize
= (sal_Int32
)(sizeof( sal_Int16
));
1948 case typelib_TypeClass_LONG
:
1949 case typelib_TypeClass_UNSIGNED_LONG
:
1950 nSize
= rMaxIntegralTypeSize
= (sal_Int32
)(sizeof( sal_Int32
));
1952 case typelib_TypeClass_HYPER
:
1953 case typelib_TypeClass_UNSIGNED_HYPER
:
1954 nSize
= rMaxIntegralTypeSize
= (sal_Int32
)(sizeof( sal_Int64
));
1956 case typelib_TypeClass_UNKNOWN
:
1957 case typelib_TypeClass_SERVICE
:
1958 case typelib_TypeClass_MODULE
:
1960 OSL_FAIL( "not convertible type" );
1964 return newAlignedSize( nOffset
, nSize
, rMaxIntegralTypeSize
);
1967 //------------------------------------------------------------------------
1971 typelib_TypeDescriptionReference
** copyExceptions(
1972 sal_Int32 count
, typelib_TypeDescriptionReference
** source
)
1974 typelib_TypeDescriptionReference
** p
1975 = new typelib_TypeDescriptionReference
*[count
];
1976 for (sal_Int32 i
= 0; i
< count
; ++i
) {
1977 typelib_typedescriptionreference_acquire(p
[i
] = source
[i
]);
1982 bool createDerivedInterfaceMemberDescription(
1983 typelib_TypeDescription
** result
, rtl::OUString
const & name
,
1984 typelib_TypeDescriptionReference
* baseRef
,
1985 typelib_TypeDescription
const * base
, typelib_TypeDescription
* interface
,
1986 sal_Int32 index
, sal_Int32 position
)
1988 if (baseRef
!= 0 && base
!= 0 && interface
!= 0) {
1989 switch (base
->eTypeClass
) {
1990 case typelib_TypeClass_INTERFACE_METHOD
:
1992 typelib_typedescription_newEmpty(
1993 result
, typelib_TypeClass_INTERFACE_METHOD
, name
.pData
);
1994 typelib_InterfaceMethodTypeDescription
const * baseMethod
1996 typelib_InterfaceMethodTypeDescription
const * >(base
);
1997 typelib_InterfaceMethodTypeDescription
* newMethod
1999 typelib_InterfaceMethodTypeDescription
* >(*result
);
2000 newMethod
->aBase
.nPosition
= position
;
2001 rtl_uString_acquire(
2002 newMethod
->aBase
.pMemberName
2003 = baseMethod
->aBase
.pMemberName
);
2004 typelib_typedescriptionreference_acquire(
2005 newMethod
->pReturnTypeRef
= baseMethod
->pReturnTypeRef
);
2006 newMethod
->nParams
= baseMethod
->nParams
;
2007 newMethod
->pParams
= new typelib_MethodParameter
[
2008 newMethod
->nParams
];
2009 for (sal_Int32 i
= 0; i
< newMethod
->nParams
; ++i
) {
2010 rtl_uString_acquire(
2011 newMethod
->pParams
[i
].pName
2012 = baseMethod
->pParams
[i
].pName
);
2013 typelib_typedescriptionreference_acquire(
2014 newMethod
->pParams
[i
].pTypeRef
2015 = baseMethod
->pParams
[i
].pTypeRef
);
2016 newMethod
->pParams
[i
].bIn
= baseMethod
->pParams
[i
].bIn
;
2017 newMethod
->pParams
[i
].bOut
= baseMethod
->pParams
[i
].bOut
;
2019 newMethod
->nExceptions
= baseMethod
->nExceptions
;
2020 newMethod
->ppExceptions
= copyExceptions(
2021 baseMethod
->nExceptions
, baseMethod
->ppExceptions
);
2022 newMethod
->bOneWay
= baseMethod
->bOneWay
;
2023 newMethod
->pInterface
2024 = reinterpret_cast< typelib_InterfaceTypeDescription
* >(
2026 newMethod
->pBaseRef
= baseRef
;
2027 newMethod
->nIndex
= index
;
2031 case typelib_TypeClass_INTERFACE_ATTRIBUTE
:
2033 typelib_typedescription_newEmpty(
2034 result
, typelib_TypeClass_INTERFACE_ATTRIBUTE
, name
.pData
);
2035 typelib_InterfaceAttributeTypeDescription
const * baseAttribute
2037 typelib_InterfaceAttributeTypeDescription
const * >(base
);
2038 typelib_InterfaceAttributeTypeDescription
* newAttribute
2040 typelib_InterfaceAttributeTypeDescription
* >(*result
);
2041 newAttribute
->aBase
.nPosition
= position
;
2042 rtl_uString_acquire(
2043 newAttribute
->aBase
.pMemberName
2044 = baseAttribute
->aBase
.pMemberName
);
2045 newAttribute
->bReadOnly
= baseAttribute
->bReadOnly
;
2046 typelib_typedescriptionreference_acquire(
2047 newAttribute
->pAttributeTypeRef
2048 = baseAttribute
->pAttributeTypeRef
);
2049 newAttribute
->pInterface
2050 = reinterpret_cast< typelib_InterfaceTypeDescription
* >(
2052 newAttribute
->pBaseRef
= baseRef
;
2053 newAttribute
->nIndex
= index
;
2054 newAttribute
->nGetExceptions
= baseAttribute
->nGetExceptions
;
2055 newAttribute
->ppGetExceptions
= copyExceptions(
2056 baseAttribute
->nGetExceptions
,
2057 baseAttribute
->ppGetExceptions
);
2058 newAttribute
->nSetExceptions
= baseAttribute
->nSetExceptions
;
2059 newAttribute
->ppSetExceptions
= copyExceptions(
2060 baseAttribute
->nSetExceptions
,
2061 baseAttribute
->ppSetExceptions
);
2074 extern "C" CPPU_DLLPUBLIC
void SAL_CALL
typelib_typedescription_getByName(
2075 typelib_TypeDescription
** ppRet
, rtl_uString
* pName
)
2076 SAL_THROW_EXTERN_C()
2080 typelib_typedescription_release( (*ppRet
) );
2084 static sal_Bool bInited
= sal_False
;
2085 TypeDescriptor_Init_Impl
&rInit
= Init::get();
2089 // guard against multi thread access
2090 MutexGuard
aGuard( rInit
.getMutex() );
2093 // avoid recursion during the next ...new calls
2096 rtl_uString
* pTypeName
= 0;
2097 typelib_TypeDescription
* pType
= 0;
2098 rtl_uString_newFromAscii( &pTypeName
, "type" );
2099 typelib_typedescription_new( &pType
, typelib_TypeClass_TYPE
, pTypeName
, 0, 0, 0 );
2100 typelib_typedescription_register( &pType
);
2101 rtl_uString_newFromAscii( &pTypeName
, "void" );
2102 typelib_typedescription_new( &pType
, typelib_TypeClass_VOID
, pTypeName
, 0, 0, 0 );
2103 typelib_typedescription_register( &pType
);
2104 rtl_uString_newFromAscii( &pTypeName
, "boolean" );
2105 typelib_typedescription_new( &pType
, typelib_TypeClass_BOOLEAN
, pTypeName
, 0, 0, 0 );
2106 typelib_typedescription_register( &pType
);
2107 rtl_uString_newFromAscii( &pTypeName
, "char" );
2108 typelib_typedescription_new( &pType
, typelib_TypeClass_CHAR
, pTypeName
, 0, 0, 0 );
2109 typelib_typedescription_register( &pType
);
2110 rtl_uString_newFromAscii( &pTypeName
, "byte" );
2111 typelib_typedescription_new( &pType
, typelib_TypeClass_BYTE
, pTypeName
, 0, 0, 0 );
2112 typelib_typedescription_register( &pType
);
2113 rtl_uString_newFromAscii( &pTypeName
, "string" );
2114 typelib_typedescription_new( &pType
, typelib_TypeClass_STRING
, pTypeName
, 0, 0, 0 );
2115 typelib_typedescription_register( &pType
);
2116 rtl_uString_newFromAscii( &pTypeName
, "short" );
2117 typelib_typedescription_new( &pType
, typelib_TypeClass_SHORT
, pTypeName
, 0, 0, 0 );
2118 typelib_typedescription_register( &pType
);
2119 rtl_uString_newFromAscii( &pTypeName
, "unsigned short" );
2120 typelib_typedescription_new( &pType
, typelib_TypeClass_UNSIGNED_SHORT
, pTypeName
, 0, 0, 0 );
2121 typelib_typedescription_register( &pType
);
2122 rtl_uString_newFromAscii( &pTypeName
, "long" );
2123 typelib_typedescription_new( &pType
, typelib_TypeClass_LONG
, pTypeName
, 0, 0, 0 );
2124 typelib_typedescription_register( &pType
);
2125 rtl_uString_newFromAscii( &pTypeName
, "unsigned long" );
2126 typelib_typedescription_new( &pType
, typelib_TypeClass_UNSIGNED_LONG
, pTypeName
, 0, 0, 0 );
2127 typelib_typedescription_register( &pType
);
2128 rtl_uString_newFromAscii( &pTypeName
, "hyper" );
2129 typelib_typedescription_new( &pType
, typelib_TypeClass_HYPER
, pTypeName
, 0, 0, 0 );
2130 typelib_typedescription_register( &pType
);
2131 rtl_uString_newFromAscii( &pTypeName
, "unsigned hyper" );
2132 typelib_typedescription_new( &pType
, typelib_TypeClass_UNSIGNED_HYPER
, pTypeName
, 0, 0, 0 );
2133 typelib_typedescription_register( &pType
);
2134 rtl_uString_newFromAscii( &pTypeName
, "float" );
2135 typelib_typedescription_new( &pType
, typelib_TypeClass_FLOAT
, pTypeName
, 0, 0, 0 );
2136 typelib_typedescription_register( &pType
);
2137 rtl_uString_newFromAscii( &pTypeName
, "double" );
2138 typelib_typedescription_new( &pType
, typelib_TypeClass_DOUBLE
, pTypeName
, 0, 0, 0 );
2139 typelib_typedescription_register( &pType
);
2140 rtl_uString_newFromAscii( &pTypeName
, "any" );
2141 typelib_typedescription_new( &pType
, typelib_TypeClass_ANY
, pTypeName
, 0, 0, 0 );
2142 typelib_typedescription_register( &pType
);
2143 typelib_typedescription_release( pType
);
2144 rtl_uString_release( pTypeName
);
2148 typelib_TypeDescriptionReference
* pTDR
= 0;
2149 typelib_typedescriptionreference_getByName( &pTDR
, pName
);
2153 // guard against multi thread access
2154 MutexGuard
aGuard( rInit
.getMutex() );
2155 // pTDR->pType->pWeakRef == 0 means that the description is empty
2156 if( pTDR
->pType
&& pTDR
->pType
->pWeakRef
)
2158 typelib_typedescription_acquire( pTDR
->pType
);
2159 *ppRet
= pTDR
->pType
;
2162 typelib_typedescriptionreference_release( pTDR
);
2167 // check for sequence
2168 OUString
const & name
= *reinterpret_cast< OUString
const * >( &pName
);
2169 if (2 < name
.getLength() && '[' == name
[ 0 ])
2171 OUString
element_name( name
.copy( 2 ) );
2172 typelib_TypeDescription
* element_td
= 0;
2173 typelib_typedescription_getByName( &element_td
, element_name
.pData
);
2174 if (0 != element_td
)
2176 typelib_typedescription_new(
2177 ppRet
, typelib_TypeClass_SEQUENCE
, pName
, element_td
->pWeakRef
, 0, 0 );
2179 typelib_typedescription_release( element_td
);
2184 // Check for derived interface member type:
2185 sal_Int32 i1
= name
.lastIndexOf(
2186 rtl::OUString(":@"));
2188 sal_Int32 i2
= i1
+ RTL_CONSTASCII_LENGTH(":@");
2189 sal_Int32 i3
= name
.indexOf(',', i2
);
2191 sal_Int32 i4
= name
.indexOf(':', i3
);
2193 typelib_TypeDescriptionReference
* pBaseRef
= 0;
2194 typelib_TypeDescription
* pBase
= 0;
2195 typelib_TypeDescription
* pInterface
= 0;
2196 typelib_typedescriptionreference_getByName(
2197 &pBaseRef
, name
.copy(0, i1
).pData
);
2198 if (pBaseRef
!= 0) {
2199 typelib_typedescriptionreference_getDescription(
2202 typelib_typedescription_getByName(
2203 &pInterface
, name
.copy(i4
+ 1).pData
);
2204 if (!createDerivedInterfaceMemberDescription(
2205 ppRet
, name
, pBaseRef
, pBase
, pInterface
,
2206 name
.copy(i2
, i3
- i2
).toInt32(),
2207 name
.copy(i3
+ 1, i4
- i3
- 1).toInt32()))
2209 if (pInterface
!= 0) {
2210 typelib_typedescription_release(pInterface
);
2213 typelib_typedescription_release(pBase
);
2215 if (pBaseRef
!= 0) {
2216 typelib_typedescriptionreference_release(
2227 rInit
.callChain( ppRet
, pName
);
2232 // typedescription found
2233 if (typelib_TypeClass_TYPEDEF
== (*ppRet
)->eTypeClass
)
2235 typelib_TypeDescription
* pTD
= 0;
2236 typelib_typedescriptionreference_getDescription(
2237 &pTD
, ((typelib_IndirectTypeDescription
*)*ppRet
)->pType
);
2238 typelib_typedescription_release( *ppRet
);
2244 (*ppRet
)->bOnDemand
= sal_True
;
2245 // The type description is hold by the reference until
2246 // on demand is activated.
2247 typelib_typedescription_register( ppRet
);
2249 // insert into the chache
2250 MutexGuard
aGuard( rInit
.getMutex() );
2252 rInit
.pCache
= new TypeDescriptionList_Impl
;
2253 if( (sal_Int32
)rInit
.pCache
->size() >= nCacheSize
)
2255 typelib_typedescription_release( rInit
.pCache
->front() );
2256 rInit
.pCache
->pop_front();
2258 // descriptions in the cache must be acquired!
2259 typelib_typedescription_acquire( *ppRet
);
2260 rInit
.pCache
->push_back( *ppRet
);
2266 extern "C" CPPU_DLLPUBLIC
void SAL_CALL
typelib_typedescriptionreference_newByAsciiName(
2267 typelib_TypeDescriptionReference
** ppTDR
,
2268 typelib_TypeClass eTypeClass
,
2269 const sal_Char
* pTypeName
)
2270 SAL_THROW_EXTERN_C()
2272 OUString
aTypeName( OUString::createFromAscii( pTypeName
) );
2273 typelib_typedescriptionreference_new( ppTDR
, eTypeClass
, aTypeName
.pData
);
2275 //------------------------------------------------------------------------
2276 extern "C" CPPU_DLLPUBLIC
void SAL_CALL
typelib_typedescriptionreference_new(
2277 typelib_TypeDescriptionReference
** ppTDR
,
2278 typelib_TypeClass eTypeClass
, rtl_uString
* pTypeName
)
2279 SAL_THROW_EXTERN_C()
2281 TypeDescriptor_Init_Impl
&rInit
= Init::get();
2282 if( eTypeClass
== typelib_TypeClass_TYPEDEF
)
2285 typelib_TypeDescription
* pRet
= 0;
2286 rInit
.callChain( &pRet
, pTypeName
);
2289 // typedescription found
2290 if (typelib_TypeClass_TYPEDEF
== pRet
->eTypeClass
)
2292 typelib_typedescriptionreference_acquire(
2293 ((typelib_IndirectTypeDescription
*)pRet
)->pType
);
2295 typelib_typedescriptionreference_release( *ppTDR
);
2296 *ppTDR
= ((typelib_IndirectTypeDescription
*)pRet
)->pType
;
2297 typelib_typedescription_release( pRet
);
2302 pRet
->bOnDemand
= sal_True
;
2303 // The type description is hold by the reference until
2304 // on demand is activated.
2305 typelib_typedescription_register( &pRet
);
2307 // insert into the chache
2308 MutexGuard
aGuard( rInit
.getMutex() );
2310 rInit
.pCache
= new TypeDescriptionList_Impl
;
2311 if( (sal_Int32
)rInit
.pCache
->size() >= nCacheSize
)
2313 typelib_typedescription_release( rInit
.pCache
->front() );
2314 rInit
.pCache
->pop_front();
2316 rInit
.pCache
->push_back( pRet
);
2317 // pRet kept acquired for cache
2319 typelib_typedescriptionreference_acquire( pRet
->pWeakRef
);
2321 typelib_typedescriptionreference_release( *ppTDR
);
2322 *ppTDR
= pRet
->pWeakRef
;
2327 #if OSL_DEBUG_LEVEL > 1
2328 OString
aStr( rtl::OUStringToOString( pTypeName
, RTL_TEXTENCODING_ASCII_US
) );
2329 OSL_ENSURE( !"### typedef not found: ", aStr
.getStr() );
2331 typelib_typedescriptionreference_release( *ppTDR
);
2337 MutexGuard
aGuard( rInit
.getMutex() );
2338 typelib_typedescriptionreference_getByName( ppTDR
, pTypeName
);
2342 if( reallyWeak( eTypeClass
) )
2344 typelib_TypeDescriptionReference
* pTDR
= new typelib_TypeDescriptionReference();
2345 #if OSL_DEBUG_LEVEL > 1
2346 osl_atomic_increment( &rInit
.nTypeDescriptionReferenceCount
);
2348 pTDR
->nRefCount
= 1;
2349 pTDR
->nStaticRefCount
= 0;
2350 pTDR
->eTypeClass
= eTypeClass
;
2351 pTDR
->pUniqueIdentifier
= 0;
2352 pTDR
->pReserved
= 0;
2353 rtl_uString_acquire( pTDR
->pTypeName
= pTypeName
);
2359 typelib_typedescription_newEmpty( (typelib_TypeDescription
** )ppTDR
, eTypeClass
, pTypeName
);
2360 // description will be registered but not acquired
2361 (*(typelib_TypeDescription
** )ppTDR
)->bOnDemand
= sal_True
;
2362 (*(typelib_TypeDescription
** )ppTDR
)->bComplete
= sal_False
;
2365 if( !rInit
.pWeakMap
)
2366 rInit
.pWeakMap
= new WeakMap_Impl
;
2367 // Heavy hack, the const sal_Unicode * is hold by the typedescription reference
2369 rInit
.pWeakMap
->operator[]( (*ppTDR
)->pTypeName
->buffer
) = *ppTDR
;
2372 //------------------------------------------------------------------------
2373 extern "C" CPPU_DLLPUBLIC
void SAL_CALL
typelib_typedescriptionreference_acquire(
2374 typelib_TypeDescriptionReference
* pRef
)
2375 SAL_THROW_EXTERN_C()
2377 osl_atomic_increment( &pRef
->nRefCount
);
2380 //------------------------------------------------------------------------
2381 extern "C" CPPU_DLLPUBLIC
void SAL_CALL
typelib_typedescriptionreference_release(
2382 typelib_TypeDescriptionReference
* pRef
)
2383 SAL_THROW_EXTERN_C()
2385 // Is it a type description?
2386 if( reallyWeak( pRef
->eTypeClass
) )
2388 if( ! osl_atomic_decrement( &pRef
->nRefCount
) )
2390 TypeDescriptor_Init_Impl
&rInit
= Init::get();
2391 if( rInit
.pWeakMap
)
2393 MutexGuard
aGuard( rInit
.getMutex() );
2394 WeakMap_Impl::iterator aIt
= rInit
.pWeakMap
->find( (sal_Unicode
*)pRef
->pTypeName
->buffer
);
2395 if( !(aIt
== rInit
.pWeakMap
->end()) && (*aIt
).second
== pRef
)
2397 // remove only if it contains the same object
2398 rInit
.pWeakMap
->erase( aIt
);
2402 rtl_uString_release( pRef
->pTypeName
);
2403 OSL_ASSERT( pRef
->pType
== 0 );
2404 #if OSL_DEBUG_LEVEL > 1
2405 osl_atomic_decrement( &rInit
.nTypeDescriptionReferenceCount
);
2412 typelib_typedescription_release( (typelib_TypeDescription
*)pRef
);
2416 //------------------------------------------------------------------------
2417 extern "C" CPPU_DLLPUBLIC
void SAL_CALL
typelib_typedescriptionreference_getDescription(
2418 typelib_TypeDescription
** ppRet
, typelib_TypeDescriptionReference
* pRef
)
2419 SAL_THROW_EXTERN_C()
2423 typelib_typedescription_release( *ppRet
);
2427 if( !reallyWeak( pRef
->eTypeClass
) && pRef
->pType
&& pRef
->pType
->pWeakRef
)
2429 // reference is a description and initialized
2430 osl_atomic_increment( &((typelib_TypeDescription
*)pRef
)->nRefCount
);
2431 *ppRet
= (typelib_TypeDescription
*)pRef
;
2436 MutexGuard
aGuard( Init::get().getMutex() );
2437 // pRef->pType->pWeakRef == 0 means that the description is empty
2438 if( pRef
->pType
&& pRef
->pType
->pWeakRef
)
2440 sal_Int32 n
= osl_atomic_increment( &pRef
->pType
->nRefCount
);
2443 // The refence is incremented. The object cannot be destroyed.
2444 // Release the guard at the earliest point.
2445 *ppRet
= pRef
->pType
;
2450 osl_atomic_decrement( &pRef
->pType
->nRefCount
);
2451 // detruction of this type in progress (another thread!)
2452 // no acces through this weak reference
2458 typelib_typedescription_getByName( ppRet
, pRef
->pTypeName
);
2459 OSL_ASSERT( !*ppRet
|| rtl_ustr_compare( pRef
->pTypeName
->buffer
, (*ppRet
)->pTypeName
->buffer
) == 0 );
2460 OSL_ASSERT( !*ppRet
|| pRef
->eTypeClass
== (*ppRet
)->eTypeClass
);
2461 OSL_ASSERT( !*ppRet
|| pRef
== (*ppRet
)->pWeakRef
);
2462 pRef
->pType
= *ppRet
;
2465 //------------------------------------------------------------------------
2466 extern "C" void SAL_CALL
typelib_typedescriptionreference_getByName(
2467 typelib_TypeDescriptionReference
** ppRet
, rtl_uString
* pName
)
2468 SAL_THROW_EXTERN_C()
2472 typelib_typedescriptionreference_release( *ppRet
);
2475 TypeDescriptor_Init_Impl
&rInit
= Init::get();
2476 if( rInit
.pWeakMap
)
2478 MutexGuard
aGuard( rInit
.getMutex() );
2479 WeakMap_Impl::const_iterator aIt
= rInit
.pWeakMap
->find( (sal_Unicode
*)pName
->buffer
);
2480 if( !(aIt
== rInit
.pWeakMap
->end()) ) // != failed on msc4.2
2482 sal_Int32 n
= osl_atomic_increment( &(*aIt
).second
->nRefCount
);
2485 // The refence is incremented. The object cannot be destroyed.
2486 // Release the guard at the earliest point.
2487 *ppRet
= (*aIt
).second
;
2491 // detruction of this type in progress (another thread!)
2492 // no acces through this weak reference
2493 osl_atomic_decrement( &(*aIt
).second
->nRefCount
);
2499 //------------------------------------------------------------------------
2500 extern "C" CPPU_DLLPUBLIC sal_Bool SAL_CALL
typelib_typedescriptionreference_equals(
2501 const typelib_TypeDescriptionReference
* p1
,
2502 const typelib_TypeDescriptionReference
* p2
)
2503 SAL_THROW_EXTERN_C()
2506 (p1
->eTypeClass
== p2
->eTypeClass
&&
2507 p1
->pTypeName
->length
== p2
->pTypeName
->length
&&
2508 rtl_ustr_compare( p1
->pTypeName
->buffer
, p2
->pTypeName
->buffer
) == 0));
2511 //##################################################################################################
2512 extern "C" CPPU_DLLPUBLIC
void SAL_CALL
typelib_typedescriptionreference_assign(
2513 typelib_TypeDescriptionReference
** ppDest
,
2514 typelib_TypeDescriptionReference
* pSource
)
2515 SAL_THROW_EXTERN_C()
2517 if (*ppDest
!= pSource
)
2519 ::typelib_typedescriptionreference_acquire( pSource
);
2520 ::typelib_typedescriptionreference_release( *ppDest
);
2525 //##################################################################################################
2526 extern "C" CPPU_DLLPUBLIC
void SAL_CALL
typelib_setCacheSize( sal_Int32 nNewSize
)
2527 SAL_THROW_EXTERN_C()
2529 OSL_ENSURE( nNewSize
>= 0, "### illegal cache size given!" );
2532 TypeDescriptor_Init_Impl
&rInit
= Init::get();
2533 MutexGuard
aGuard( rInit
.getMutex() );
2534 if ((nNewSize
< nCacheSize
) && rInit
.pCache
)
2536 while ((sal_Int32
)rInit
.pCache
->size() != nNewSize
)
2538 typelib_typedescription_release( rInit
.pCache
->front() );
2539 rInit
.pCache
->pop_front();
2542 nCacheSize
= nNewSize
;
2547 static sal_Bool s_aAssignableFromTab
[11][11] =
2549 /* from CH,BO,BY,SH,US,LO,UL,HY,UH,FL,DO */
2550 /* TypeClass_CHAR */ { 1, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0 },
2551 /* TypeClass_BOOLEAN */ { 0, 1, 0, 0, 0, 0, 0, 0, 0, 0, 0 },
2552 /* TypeClass_BYTE */ { 0, 0, 1, 0, 0, 0, 0, 0, 0, 0, 0 },
2553 /* TypeClass_SHORT */ { 0, 0, 1, 1, 1, 0, 0, 0, 0, 0, 0 },
2554 /* TypeClass_UNSIGNED_SHORT */ { 0, 0, 1, 1, 1, 0, 0, 0, 0, 0, 0 },
2555 /* TypeClass_LONG */ { 0, 0, 1, 1, 1, 1, 1, 0, 0, 0, 0 },
2556 /* TypeClass_UNSIGNED_LONG */ { 0, 0, 1, 1, 1, 1, 1, 0, 0, 0, 0 },
2557 /* TypeClass_HYPER */ { 0, 0, 1, 1, 1, 1, 1, 1, 1, 0, 0 },
2558 /* TypeClass_UNSIGNED_HYPER */ { 0, 0, 1, 1, 1, 1, 1, 1, 1, 0, 0 },
2559 /* TypeClass_FLOAT */ { 0, 0, 1, 1, 1, 0, 0, 0, 0, 1, 0 },
2560 /* TypeClass_DOUBLE */ { 0, 0, 1, 1, 1, 1, 1, 0, 0, 1, 1 }
2563 //##################################################################################################
2564 extern "C" CPPU_DLLPUBLIC sal_Bool SAL_CALL
typelib_typedescriptionreference_isAssignableFrom(
2565 typelib_TypeDescriptionReference
* pAssignable
,
2566 typelib_TypeDescriptionReference
* pFrom
)
2567 SAL_THROW_EXTERN_C()
2569 if (pAssignable
&& pFrom
)
2571 typelib_TypeClass eAssignable
= pAssignable
->eTypeClass
;
2572 typelib_TypeClass eFrom
= pFrom
->eTypeClass
;
2574 if (eAssignable
== typelib_TypeClass_ANY
) // anything can be assigned to an any .)
2576 if (eAssignable
== eFrom
)
2578 if (type_equals( pAssignable
, pFrom
)) // first shot
2584 switch (eAssignable
)
2586 case typelib_TypeClass_STRUCT
:
2587 case typelib_TypeClass_EXCEPTION
:
2589 typelib_TypeDescription
* pFromDescr
= 0;
2590 TYPELIB_DANGER_GET( &pFromDescr
, pFrom
);
2591 if (! ((typelib_CompoundTypeDescription
*)pFromDescr
)->pBaseTypeDescription
)
2593 TYPELIB_DANGER_RELEASE( pFromDescr
);
2596 sal_Bool bRet
= typelib_typedescriptionreference_isAssignableFrom(
2598 ((typelib_TypeDescription
*)((typelib_CompoundTypeDescription
*)pFromDescr
)->pBaseTypeDescription
)->pWeakRef
);
2599 TYPELIB_DANGER_RELEASE( pFromDescr
);
2602 case typelib_TypeClass_INTERFACE
:
2604 typelib_TypeDescription
* pFromDescr
= 0;
2605 TYPELIB_DANGER_GET( &pFromDescr
, pFrom
);
2606 typelib_InterfaceTypeDescription
* pFromIfc
2608 typelib_InterfaceTypeDescription
* >(pFromDescr
);
2610 for (sal_Int32 i
= 0; i
< pFromIfc
->nBaseTypes
; ++i
) {
2611 if (typelib_typedescriptionreference_isAssignableFrom(
2613 pFromIfc
->ppBaseTypes
[i
]->aBase
.pWeakRef
))
2619 TYPELIB_DANGER_RELEASE( pFromDescr
);
2629 return (eAssignable
>= typelib_TypeClass_CHAR
&& eAssignable
<= typelib_TypeClass_DOUBLE
&&
2630 eFrom
>= typelib_TypeClass_CHAR
&& eFrom
<= typelib_TypeClass_DOUBLE
&&
2631 s_aAssignableFromTab
[eAssignable
-1][eFrom
-1]);
2635 //##################################################################################################
2636 extern "C" CPPU_DLLPUBLIC sal_Bool SAL_CALL
typelib_typedescription_isAssignableFrom(
2637 typelib_TypeDescription
* pAssignable
,
2638 typelib_TypeDescription
* pFrom
)
2639 SAL_THROW_EXTERN_C()
2641 return typelib_typedescriptionreference_isAssignableFrom(
2642 pAssignable
->pWeakRef
, pFrom
->pWeakRef
);
2645 //##################################################################################################
2646 extern "C" CPPU_DLLPUBLIC sal_Bool SAL_CALL
typelib_typedescription_complete(
2647 typelib_TypeDescription
** ppTypeDescr
)
2648 SAL_THROW_EXTERN_C()
2650 return complete(ppTypeDescr
, true);
2653 /* vim:set shiftwidth=4 softtabstop=4 expandtab: */