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 <unordered_map>
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>
45 #include "typelib.hxx"
50 using ::rtl::OUString
;
51 using ::rtl::OUStringBuffer
;
59 * The double member determines the alignment.
60 * Under OS2 and MS-Windows the Alignment is min( 8, sizeof( type ) ).
61 * The alignment of a structure is min( 8, sizeof( max basic type ) ), the greatest basic type
62 * determines the alignment.
68 //double: doubleword aligned if -qalign=natural/-malign=natural
69 //which isn't the default ABI. Otherwise word aligned, While a long long int
70 //is always doubleword aligned, so use that instead.
81 // the value of the maximal alignment
82 static sal_Int32 nMaxAlignment
= (sal_Int32
)( reinterpret_cast<sal_Size
>(&(reinterpret_cast<AlignSize_Impl
*>(16))->dDouble
) - 16);
84 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 structure.
94 static inline sal_Int32
newAlignedSize(
95 sal_Int32 OldSize
, sal_Int32 ElementSize
, sal_Int32 NeededAlignment
)
97 NeededAlignment
= adjustAlignment( NeededAlignment
);
98 return (OldSize
+ NeededAlignment
-1) / NeededAlignment
* NeededAlignment
+ ElementSize
;
101 static inline bool reallyWeak( typelib_TypeClass eTypeClass
)
103 return TYPELIB_TYPEDESCRIPTIONREFERENCE_ISREALLYWEAK( eTypeClass
);
106 static inline sal_Int32
getDescriptionSize( typelib_TypeClass eTypeClass
)
108 OSL_ASSERT( typelib_TypeClass_TYPEDEF
!= eTypeClass
);
111 // The reference is the description
112 // if the description is empty, than it must be filled with
113 // the new description
116 case typelib_TypeClass_SEQUENCE
:
117 nSize
= (sal_Int32
)sizeof( typelib_IndirectTypeDescription
);
120 case typelib_TypeClass_STRUCT
:
121 nSize
= (sal_Int32
)sizeof( typelib_StructTypeDescription
);
124 case typelib_TypeClass_EXCEPTION
:
125 nSize
= (sal_Int32
)sizeof( typelib_CompoundTypeDescription
);
128 case typelib_TypeClass_ENUM
:
129 nSize
= (sal_Int32
)sizeof( typelib_EnumTypeDescription
);
132 case typelib_TypeClass_INTERFACE
:
133 nSize
= (sal_Int32
)sizeof( typelib_InterfaceTypeDescription
);
136 case typelib_TypeClass_INTERFACE_METHOD
:
137 nSize
= (sal_Int32
)sizeof( typelib_InterfaceMethodTypeDescription
);
140 case typelib_TypeClass_INTERFACE_ATTRIBUTE
:
141 nSize
= (sal_Int32
)sizeof( typelib_InterfaceAttributeTypeDescription
);
145 nSize
= (sal_Int32
)sizeof( typelib_TypeDescription
);
154 bool operator()(const sal_Unicode
* const & s1
, const sal_Unicode
* const & s2
) const
155 { return 0 == rtl_ustr_compare( s1
, s2
); }
161 size_t operator()(const sal_Unicode
* const & s
) const
162 { return rtl_ustr_hashCode( s
); }
167 // Heavy hack, the const sal_Unicode * is hold by the typedescription reference
168 typedef std::unordered_map
< const sal_Unicode
*, typelib_TypeDescriptionReference
*,
169 hashStr_Impl
, equalStr_Impl
> WeakMap_Impl
;
171 typedef pair
< void *, typelib_typedescription_Callback
> CallbackEntry
;
172 typedef list
< CallbackEntry
> CallbackSet_Impl
;
173 typedef list
< typelib_TypeDescription
* > TypeDescriptionList_Impl
;
175 // # of cached elements
176 static sal_Int32 nCacheSize
= 256;
178 struct TypeDescriptor_Init_Impl
180 //sal_Bool bDesctructorCalled;
181 // all type description references
182 WeakMap_Impl
* pWeakMap
;
183 // all type description callbacks
184 CallbackSet_Impl
* pCallbacks
;
185 // A cache to hold descriptions
186 TypeDescriptionList_Impl
* pCache
;
187 // The mutex to guard all type library accesses
190 inline Mutex
& getMutex();
192 inline void callChain( typelib_TypeDescription
** ppRet
, rtl_uString
* pName
);
194 #if OSL_DEBUG_LEVEL > 1
195 // only for debugging
196 sal_Int32 nTypeDescriptionCount
;
197 sal_Int32 nCompoundTypeDescriptionCount
;
198 sal_Int32 nIndirectTypeDescriptionCount
;
199 sal_Int32 nEnumTypeDescriptionCount
;
200 sal_Int32 nInterfaceMethodTypeDescriptionCount
;
201 sal_Int32 nInterfaceAttributeTypeDescriptionCount
;
202 sal_Int32 nInterfaceTypeDescriptionCount
;
203 sal_Int32 nTypeDescriptionReferenceCount
;
206 TypeDescriptor_Init_Impl():
207 pWeakMap(0), pCallbacks(0), pCache(0), pMutex(0)
208 #if OSL_DEBUG_LEVEL > 1
209 , nTypeDescriptionCount(0), nCompoundTypeDescriptionCount(0),
210 nIndirectTypeDescriptionCount(0),
211 nEnumTypeDescriptionCount(0),
212 nInterfaceMethodTypeDescriptionCount(0),
213 nInterfaceAttributeTypeDescriptionCount(0),
214 nInterfaceTypeDescriptionCount(0), nTypeDescriptionReferenceCount(0)
218 ~TypeDescriptor_Init_Impl();
221 inline Mutex
& TypeDescriptor_Init_Impl::getMutex()
225 MutexGuard
aGuard( Mutex::getGlobalMutex() );
227 pMutex
= new Mutex();
232 inline void TypeDescriptor_Init_Impl::callChain(
233 typelib_TypeDescription
** ppRet
, rtl_uString
* pName
)
239 CallbackSet_Impl::const_iterator aIt
= pCallbacks
->begin();
240 while( aIt
!= pCallbacks
->end() )
242 const CallbackEntry
& rEntry
= *aIt
;
243 (*rEntry
.second
)( rEntry
.first
, ppRet
, pName
);
252 TypeDescriptor_Init_Impl::~TypeDescriptor_Init_Impl()
256 TypeDescriptionList_Impl::const_iterator aIt
= pCache
->begin();
257 while( aIt
!= pCache
->end() )
259 typelib_typedescription_release( (*aIt
) );
268 std::vector
< typelib_TypeDescriptionReference
* > ppTDR
;
269 ppTDR
.reserve( pWeakMap
->size() );
271 // save all weak references
272 WeakMap_Impl::const_iterator aIt
= pWeakMap
->begin();
273 while( aIt
!= pWeakMap
->end() )
275 ppTDR
.push_back( (*aIt
).second
);
276 typelib_typedescriptionreference_acquire( ppTDR
.back() );
280 for( std::vector
< typelib_TypeDescriptionReference
* >::iterator
i(
282 i
!= ppTDR
.end(); ++i
)
284 typelib_TypeDescriptionReference
* pTDR
= *i
;
285 OSL_ASSERT( pTDR
->nRefCount
> pTDR
->nStaticRefCount
);
286 pTDR
->nRefCount
-= pTDR
->nStaticRefCount
;
288 if( pTDR
->pType
&& !pTDR
->pType
->bOnDemand
)
290 pTDR
->pType
->bOnDemand
= sal_True
;
291 typelib_typedescription_release( pTDR
->pType
);
293 typelib_typedescriptionreference_release( pTDR
);
296 #if OSL_DEBUG_LEVEL > 1
297 aIt
= pWeakMap
->begin();
298 while( aIt
!= pWeakMap
->end() )
300 typelib_TypeDescriptionReference
* pTDR
= (*aIt
).second
;
303 OString
aTypeName( rtl::OUStringToOString( pTDR
->pTypeName
, RTL_TEXTENCODING_ASCII_US
) );
305 "### remaining type: %s; ref count = %d", aTypeName
.getStr(), pTDR
->nRefCount
);
309 OSL_TRACE( "### remaining null type entry!?" );
318 #if OSL_DEBUG_LEVEL > 1
319 OSL_ENSURE( !nTypeDescriptionCount
, "### nTypeDescriptionCount is not zero" );
320 OSL_ENSURE( !nCompoundTypeDescriptionCount
, "### nCompoundTypeDescriptionCount is not zero" );
321 OSL_ENSURE( !nIndirectTypeDescriptionCount
, "### nIndirectTypeDescriptionCount is not zero" );
322 OSL_ENSURE( !nEnumTypeDescriptionCount
, "### nEnumTypeDescriptionCount is not zero" );
323 OSL_ENSURE( !nInterfaceMethodTypeDescriptionCount
, "### nInterfaceMethodTypeDescriptionCount is not zero" );
324 OSL_ENSURE( !nInterfaceAttributeTypeDescriptionCount
, "### nInterfaceAttributeTypeDescriptionCount is not zero" );
325 OSL_ENSURE( !nInterfaceTypeDescriptionCount
, "### nInterfaceTypeDescriptionCount is not zero" );
326 OSL_ENSURE( !nTypeDescriptionReferenceCount
, "### nTypeDescriptionReferenceCount is not zero" );
328 OSL_ENSURE( !pCallbacks
|| pCallbacks
->empty(), "### pCallbacks is not NULL or empty" );
341 namespace { struct Init
: public rtl::Static
< TypeDescriptor_Init_Impl
, Init
> {}; }
343 extern "C" void SAL_CALL
typelib_typedescription_registerCallback(
344 void * pContext
, typelib_typedescription_Callback pCallback
)
347 // todo mt safe: guard is no solution, can not acquire while calling callback!
348 TypeDescriptor_Init_Impl
&rInit
= Init::get();
349 // OslGuard aGuard( rInit.getMutex() );
350 if( !rInit
.pCallbacks
)
351 rInit
.pCallbacks
= new CallbackSet_Impl
;
352 rInit
.pCallbacks
->push_back( CallbackEntry( pContext
, pCallback
) );
356 extern "C" void SAL_CALL
typelib_typedescription_revokeCallback(
357 void * pContext
, typelib_typedescription_Callback pCallback
)
360 TypeDescriptor_Init_Impl
&rInit
= Init::get();
361 if( rInit
.pCallbacks
)
363 // todo mt safe: guard is no solution, can not acquire while calling callback!
364 // OslGuard aGuard( rInit.getMutex() );
365 CallbackEntry
aEntry( pContext
, pCallback
);
366 CallbackSet_Impl::iterator
iPos( rInit
.pCallbacks
->begin() );
367 while (!(iPos
== rInit
.pCallbacks
->end()))
371 rInit
.pCallbacks
->erase( iPos
);
372 iPos
= rInit
.pCallbacks
->begin();
382 static inline void typelib_typedescription_initTables(
383 typelib_TypeDescription
* pTD
)
385 typelib_InterfaceTypeDescription
* pITD
= reinterpret_cast<typelib_InterfaceTypeDescription
*>(pTD
);
387 sal_Bool
* pReadWriteAttributes
= static_cast<sal_Bool
*>(alloca( pITD
->nAllMembers
));
388 for ( sal_Int32 i
= pITD
->nAllMembers
; i
--; )
390 pReadWriteAttributes
[i
] = sal_False
;
391 if( typelib_TypeClass_INTERFACE_ATTRIBUTE
== pITD
->ppAllMembers
[i
]->eTypeClass
)
393 typelib_TypeDescription
* pM
= 0;
394 TYPELIB_DANGER_GET( &pM
, pITD
->ppAllMembers
[i
] );
398 pReadWriteAttributes
[i
] = !reinterpret_cast<typelib_InterfaceAttributeTypeDescription
*>(pM
)->bReadOnly
;
399 TYPELIB_DANGER_RELEASE( pM
);
401 #if OSL_DEBUG_LEVEL > 1
404 OString
aStr( rtl::OUStringToOString( pITD
->ppAllMembers
[i
]->pTypeName
, RTL_TEXTENCODING_ASCII_US
) );
405 OSL_TRACE( "\n### cannot get attribute type description: %s", aStr
.getStr() );
411 MutexGuard
aGuard( Init::get().getMutex() );
412 if( !pTD
->bComplete
)
414 // create the index table from member to function table
415 pITD
->pMapMemberIndexToFunctionIndex
= new sal_Int32
[ pITD
->nAllMembers
];
416 sal_Int32 nAdditionalOffset
= 0; // +1 for read/write attributes
418 for( i
= 0; i
< pITD
->nAllMembers
; i
++ )
420 // index to the get method of the attribute
421 pITD
->pMapMemberIndexToFunctionIndex
[i
] = i
+ nAdditionalOffset
;
422 // extra offset if it is a read/write attribute?
423 if( pReadWriteAttributes
[i
] )
425 // a read/write attribute
430 // create the index table from function to member table
431 pITD
->pMapFunctionIndexToMemberIndex
= new sal_Int32
[ pITD
->nAllMembers
+ nAdditionalOffset
];
432 nAdditionalOffset
= 0; // +1 for read/write attributes
433 for( i
= 0; i
< pITD
->nAllMembers
; i
++ )
435 // index to the get method of the attribute
436 pITD
->pMapFunctionIndexToMemberIndex
[i
+ nAdditionalOffset
] = i
;
437 // extra offset if it is a read/write attribute?
438 if( pReadWriteAttributes
[i
] )
440 // a read/write attribute
441 pITD
->pMapFunctionIndexToMemberIndex
[i
+ ++nAdditionalOffset
] = i
;
444 // must be the last action after all initialization is done
445 pITD
->nMapFunctionIndexToMemberIndex
= pITD
->nAllMembers
+ nAdditionalOffset
;
446 pTD
->bComplete
= sal_True
;
452 // In some situations (notably typelib_typedescription_newInterfaceMethod and
453 // typelib_typedescription_newInterfaceAttribute), only the members nMembers,
454 // ppMembers, nAllMembers, and ppAllMembers of an incomplete interface type
455 // description are necessary, but not the additional
456 // pMapMemberIndexToFunctionIndex, nMapFunctionIndexToMemberIndex, and
457 // pMapFunctionIndexToMemberIndex (which are computed by
458 // typelib_typedescription_initTables). Furthermore, in those situations, it
459 // might be illegal to compute those tables, as the creation of the interface
460 // member type descriptions would recursively require a complete interface type
461 // description. The parameter initTables controls whether or not to call
462 // typelib_typedescription_initTables in those situations.
463 bool complete(typelib_TypeDescription
** ppTypeDescr
, bool initTables
) {
464 if (! (*ppTypeDescr
)->bComplete
)
466 OSL_ASSERT( (typelib_TypeClass_STRUCT
== (*ppTypeDescr
)->eTypeClass
||
467 typelib_TypeClass_EXCEPTION
== (*ppTypeDescr
)->eTypeClass
||
468 typelib_TypeClass_ENUM
== (*ppTypeDescr
)->eTypeClass
||
469 typelib_TypeClass_INTERFACE
== (*ppTypeDescr
)->eTypeClass
) &&
470 !reallyWeak( (*ppTypeDescr
)->eTypeClass
) );
472 if (typelib_TypeClass_INTERFACE
== (*ppTypeDescr
)->eTypeClass
&&
473 reinterpret_cast<typelib_InterfaceTypeDescription
*>(*ppTypeDescr
)->ppAllMembers
)
476 typelib_typedescription_initTables( *ppTypeDescr
);
481 typelib_TypeDescription
* pTD
= 0;
482 // on demand access of complete td
483 TypeDescriptor_Init_Impl
&rInit
= Init::get();
484 rInit
.callChain( &pTD
, (*ppTypeDescr
)->pTypeName
);
487 if (typelib_TypeClass_TYPEDEF
== pTD
->eTypeClass
)
489 typelib_typedescriptionreference_getDescription(
490 &pTD
, reinterpret_cast<typelib_IndirectTypeDescription
*>(pTD
)->pType
);
496 OSL_ASSERT( typelib_TypeClass_TYPEDEF
!= pTD
->eTypeClass
);
497 // typedescription found
499 pTD
->bOnDemand
= sal_True
;
501 if (pTD
->eTypeClass
== typelib_TypeClass_INTERFACE
502 && !pTD
->bComplete
&& initTables
)
504 // mandatory info from callback chain
505 OSL_ASSERT( reinterpret_cast<typelib_InterfaceTypeDescription
*>(pTD
)->ppAllMembers
);
506 // complete except of tables init
507 typelib_typedescription_initTables( pTD
);
508 pTD
->bComplete
= sal_True
;
511 // The type description is hold by the reference until
512 // on demand is activated.
513 ::typelib_typedescription_register( &pTD
); // replaces incomplete one
514 OSL_ASSERT( pTD
== *ppTypeDescr
); // has to merge into existing one
516 // insert into the chache
517 MutexGuard
aGuard( rInit
.getMutex() );
519 rInit
.pCache
= new TypeDescriptionList_Impl
;
520 if( (sal_Int32
)rInit
.pCache
->size() >= nCacheSize
)
522 typelib_typedescription_release( rInit
.pCache
->front() );
523 rInit
.pCache
->pop_front();
525 // descriptions in the cache must be acquired!
526 typelib_typedescription_acquire( pTD
);
527 rInit
.pCache
->push_back( pTD
);
531 || (pTD
->eTypeClass
== typelib_TypeClass_INTERFACE
534 ::typelib_typedescription_release( *ppTypeDescr
);
539 #if OSL_DEBUG_LEVEL > 1
541 rtl::OUStringToOString( (*ppTypeDescr
)->pTypeName
, RTL_TEXTENCODING_ASCII_US
) );
542 OSL_TRACE( "\n### type cannot be completed: %s", aStr
.getStr() );
553 extern "C" void SAL_CALL
typelib_typedescription_newEmpty(
554 typelib_TypeDescription
** ppRet
,
555 typelib_TypeClass eTypeClass
, rtl_uString
* pTypeName
)
560 typelib_typedescription_release( *ppRet
);
564 OSL_ASSERT( typelib_TypeClass_TYPEDEF
!= eTypeClass
);
566 typelib_TypeDescription
* pRet
;
569 case typelib_TypeClass_SEQUENCE
:
571 typelib_IndirectTypeDescription
* pTmp
= new typelib_IndirectTypeDescription();
573 #if OSL_DEBUG_LEVEL > 1
574 osl_atomic_increment( &Init::get().nIndirectTypeDescriptionCount
);
580 case typelib_TypeClass_STRUCT
:
582 // FEATURE_EMPTYCLASS
583 typelib_StructTypeDescription
* pTmp
;
584 pTmp
= new typelib_StructTypeDescription();
585 pRet
= &pTmp
->aBase
.aBase
;
586 #if OSL_DEBUG_LEVEL > 1
587 osl_atomic_increment( &Init::get().nCompoundTypeDescriptionCount
);
589 pTmp
->aBase
.pBaseTypeDescription
= 0;
590 pTmp
->aBase
.nMembers
= 0;
591 pTmp
->aBase
.pMemberOffsets
= 0;
592 pTmp
->aBase
.ppTypeRefs
= 0;
593 pTmp
->aBase
.ppMemberNames
= 0;
594 pTmp
->pParameterizedTypes
= 0;
598 case typelib_TypeClass_EXCEPTION
:
600 // FEATURE_EMPTYCLASS
601 typelib_CompoundTypeDescription
* pTmp
;
602 pTmp
= new typelib_CompoundTypeDescription();
604 #if OSL_DEBUG_LEVEL > 1
605 osl_atomic_increment( &Init::get().nCompoundTypeDescriptionCount
);
607 pTmp
->pBaseTypeDescription
= 0;
609 pTmp
->pMemberOffsets
= 0;
610 pTmp
->ppTypeRefs
= 0;
611 pTmp
->ppMemberNames
= 0;
615 case typelib_TypeClass_ENUM
:
617 typelib_EnumTypeDescription
* pTmp
= new typelib_EnumTypeDescription();
619 #if OSL_DEBUG_LEVEL > 1
620 osl_atomic_increment( &Init::get().nEnumTypeDescriptionCount
);
622 pTmp
->nDefaultEnumValue
= 0;
623 pTmp
->nEnumValues
= 0;
624 pTmp
->ppEnumNames
= 0;
625 pTmp
->pEnumValues
= 0;
629 case typelib_TypeClass_INTERFACE
:
631 typelib_InterfaceTypeDescription
* pTmp
= new typelib_InterfaceTypeDescription();
633 #if OSL_DEBUG_LEVEL > 1
634 osl_atomic_increment( &Init::get().nInterfaceTypeDescriptionCount
);
636 pTmp
->pBaseTypeDescription
= 0;
639 pTmp
->nAllMembers
= 0;
640 pTmp
->ppAllMembers
= 0;
641 pTmp
->nMapFunctionIndexToMemberIndex
= 0;
642 pTmp
->pMapFunctionIndexToMemberIndex
= 0;
643 pTmp
->pMapMemberIndexToFunctionIndex
= 0;
644 pTmp
->nBaseTypes
= 0;
645 pTmp
->ppBaseTypes
= 0;
649 case typelib_TypeClass_INTERFACE_METHOD
:
651 typelib_InterfaceMethodTypeDescription
* pTmp
= new typelib_InterfaceMethodTypeDescription();
652 pRet
= &pTmp
->aBase
.aBase
;
653 #if OSL_DEBUG_LEVEL > 1
654 osl_atomic_increment( &Init::get().nInterfaceMethodTypeDescriptionCount
);
656 pTmp
->aBase
.pMemberName
= 0;
657 pTmp
->pReturnTypeRef
= 0;
660 pTmp
->nExceptions
= 0;
661 pTmp
->ppExceptions
= 0;
662 pTmp
->pInterface
= 0;
668 case typelib_TypeClass_INTERFACE_ATTRIBUTE
:
670 typelib_InterfaceAttributeTypeDescription
* pTmp
= new typelib_InterfaceAttributeTypeDescription();
671 pRet
= &pTmp
->aBase
.aBase
;
672 #if OSL_DEBUG_LEVEL > 1
673 osl_atomic_increment( &Init::get().nInterfaceAttributeTypeDescriptionCount
);
675 pTmp
->aBase
.pMemberName
= 0;
676 pTmp
->pAttributeTypeRef
= 0;
677 pTmp
->pInterface
= 0;
680 pTmp
->nGetExceptions
= 0;
681 pTmp
->ppGetExceptions
= 0;
682 pTmp
->nSetExceptions
= 0;
683 pTmp
->ppSetExceptions
= 0;
689 pRet
= new typelib_TypeDescription();
690 #if OSL_DEBUG_LEVEL > 1
691 osl_atomic_increment( &Init::get().nTypeDescriptionCount
);
696 pRet
->nRefCount
= 1; // reference count is initially 1
697 pRet
->nStaticRefCount
= 0;
698 pRet
->eTypeClass
= eTypeClass
;
700 pRet
->pUniqueIdentifier
= 0;
702 rtl_uString_acquire( pRet
->pTypeName
= pTypeName
);
704 pRet
->bComplete
= sal_True
;
706 pRet
->nAlignment
= 0;
708 pRet
->bOnDemand
= sal_False
;
715 void newTypeDescription(
716 typelib_TypeDescription
** ppRet
, typelib_TypeClass eTypeClass
,
717 rtl_uString
* pTypeName
, typelib_TypeDescriptionReference
* pType
,
718 sal_Int32 nMembers
, typelib_CompoundMember_Init
* pCompoundMembers
,
719 typelib_StructMember_Init
* pStructMembers
)
722 (pCompoundMembers
== 0 || pStructMembers
== 0)
723 && (pStructMembers
== 0 || eTypeClass
== typelib_TypeClass_STRUCT
));
724 if (typelib_TypeClass_TYPEDEF
== eTypeClass
)
726 OSL_TRACE( "### unexpected typedef!" );
727 typelib_typedescriptionreference_getDescription( ppRet
, pType
);
731 typelib_typedescription_newEmpty( ppRet
, eTypeClass
, pTypeName
);
735 case typelib_TypeClass_SEQUENCE
:
737 OSL_ASSERT( nMembers
== 0 );
738 typelib_typedescriptionreference_acquire( pType
);
739 reinterpret_cast<typelib_IndirectTypeDescription
*>(*ppRet
)->pType
= pType
;
743 case typelib_TypeClass_EXCEPTION
:
744 case typelib_TypeClass_STRUCT
:
746 // FEATURE_EMPTYCLASS
747 typelib_CompoundTypeDescription
* pTmp
= reinterpret_cast<typelib_CompoundTypeDescription
*>(*ppRet
);
749 sal_Int32 nOffset
= 0;
752 typelib_typedescriptionreference_getDescription(
753 reinterpret_cast<typelib_TypeDescription
**>(&pTmp
->pBaseTypeDescription
), pType
);
754 nOffset
= pTmp
->pBaseTypeDescription
->aBase
.nSize
;
755 OSL_ENSURE( newAlignedSize( 0, pTmp
->pBaseTypeDescription
->aBase
.nSize
, pTmp
->pBaseTypeDescription
->aBase
.nAlignment
) == pTmp
->pBaseTypeDescription
->aBase
.nSize
, "### unexpected offset!" );
759 pTmp
->nMembers
= nMembers
;
760 pTmp
->pMemberOffsets
= new sal_Int32
[ nMembers
];
761 pTmp
->ppTypeRefs
= new typelib_TypeDescriptionReference
*[ nMembers
];
762 pTmp
->ppMemberNames
= new rtl_uString
*[ nMembers
];
763 bool polymorphic
= eTypeClass
== typelib_TypeClass_STRUCT
764 && rtl::OUString::unacquired(&pTypeName
).indexOf('<') >= 0;
765 OSL_ASSERT(!polymorphic
|| pStructMembers
!= 0);
767 reinterpret_cast< typelib_StructTypeDescription
* >(pTmp
)->
768 pParameterizedTypes
= new sal_Bool
[nMembers
];
770 for( sal_Int32 i
= 0 ; i
< nMembers
; i
++ )
772 // read the type and member names
773 pTmp
->ppTypeRefs
[i
] = 0;
774 if (pCompoundMembers
!= 0) {
775 typelib_typedescriptionreference_new(
776 pTmp
->ppTypeRefs
+i
, pCompoundMembers
[i
].eTypeClass
,
777 pCompoundMembers
[i
].pTypeName
);
779 pTmp
->ppMemberNames
[i
]
780 = pCompoundMembers
[i
].pMemberName
);
782 typelib_typedescriptionreference_new(
784 pStructMembers
[i
].aBase
.eTypeClass
,
785 pStructMembers
[i
].aBase
.pTypeName
);
787 pTmp
->ppMemberNames
[i
]
788 = pStructMembers
[i
].aBase
.pMemberName
);
793 if (pTmp
->ppTypeRefs
[i
]->eTypeClass
==
794 typelib_TypeClass_SEQUENCE
)
796 // Take care of recursion like
797 // struct S { sequence<S> x; };
798 size
= sizeof(void *);
799 alignment
= adjustAlignment(size
);
801 typelib_TypeDescription
* pTD
= 0;
802 TYPELIB_DANGER_GET( &pTD
, pTmp
->ppTypeRefs
[i
] );
803 OSL_ENSURE( pTD
->nSize
, "### void member?" );
805 alignment
= pTD
->nAlignment
;
806 TYPELIB_DANGER_RELEASE( pTD
);
808 nOffset
= newAlignedSize( nOffset
, size
, alignment
);
809 pTmp
->pMemberOffsets
[i
] = nOffset
- size
;
812 reinterpret_cast< typelib_StructTypeDescription
* >(
813 pTmp
)->pParameterizedTypes
[i
]
814 = pStructMembers
[i
].bParameterizedType
;
825 if( !reallyWeak( eTypeClass
) )
826 (*ppRet
)->pWeakRef
= reinterpret_cast<typelib_TypeDescriptionReference
*>(*ppRet
);
827 if( eTypeClass
!= typelib_TypeClass_VOID
)
829 // sizeof(void) not allowed
830 (*ppRet
)->nSize
= typelib_typedescription_getAlignedUnoSize( (*ppRet
), 0, (*ppRet
)->nAlignment
);
831 (*ppRet
)->nAlignment
= adjustAlignment( (*ppRet
)->nAlignment
);
837 extern "C" void SAL_CALL
typelib_typedescription_new(
838 typelib_TypeDescription
** ppRet
,
839 typelib_TypeClass eTypeClass
,
840 rtl_uString
* pTypeName
,
841 typelib_TypeDescriptionReference
* pType
,
843 typelib_CompoundMember_Init
* pMembers
)
847 ppRet
, eTypeClass
, pTypeName
, pType
, nMembers
, pMembers
, 0);
850 extern "C" void SAL_CALL
typelib_typedescription_newStruct(
851 typelib_TypeDescription
** ppRet
,
852 rtl_uString
* pTypeName
,
853 typelib_TypeDescriptionReference
* pType
,
855 typelib_StructMember_Init
* pMembers
)
859 ppRet
, typelib_TypeClass_STRUCT
, pTypeName
, pType
, nMembers
, 0,
864 extern "C" void SAL_CALL
typelib_typedescription_newEnum(
865 typelib_TypeDescription
** ppRet
,
866 rtl_uString
* pTypeName
,
867 sal_Int32 nDefaultValue
,
868 sal_Int32 nEnumValues
,
869 rtl_uString
** ppEnumNames
,
870 sal_Int32
* pEnumValues
)
873 typelib_typedescription_newEmpty( ppRet
, typelib_TypeClass_ENUM
, pTypeName
);
874 typelib_EnumTypeDescription
* pEnum
= reinterpret_cast<typelib_EnumTypeDescription
*>(*ppRet
);
876 pEnum
->nDefaultEnumValue
= nDefaultValue
;
877 pEnum
->nEnumValues
= nEnumValues
;
878 pEnum
->ppEnumNames
= new rtl_uString
* [ nEnumValues
];
879 for ( sal_Int32 nPos
= nEnumValues
; nPos
--; )
881 rtl_uString_acquire( pEnum
->ppEnumNames
[nPos
] = ppEnumNames
[nPos
] );
883 pEnum
->pEnumValues
= new sal_Int32
[ nEnumValues
];
884 ::memcpy( pEnum
->pEnumValues
, pEnumValues
, nEnumValues
* sizeof(sal_Int32
) );
886 (*ppRet
)->pWeakRef
= reinterpret_cast<typelib_TypeDescriptionReference
*>(*ppRet
);
887 // sizeof(void) not allowed
888 (*ppRet
)->nSize
= typelib_typedescription_getAlignedUnoSize( (*ppRet
), 0, (*ppRet
)->nAlignment
);
889 (*ppRet
)->nAlignment
= adjustAlignment( (*ppRet
)->nAlignment
);
893 extern "C" void SAL_CALL
typelib_typedescription_newInterface(
894 typelib_InterfaceTypeDescription
** ppRet
,
895 rtl_uString
* pTypeName
,
896 SAL_UNUSED_PARAMETER sal_uInt32
, SAL_UNUSED_PARAMETER sal_uInt16
,
897 SAL_UNUSED_PARAMETER sal_uInt16
, SAL_UNUSED_PARAMETER sal_uInt32
,
898 SAL_UNUSED_PARAMETER sal_uInt32
,
899 typelib_TypeDescriptionReference
* pBaseInterface
,
901 typelib_TypeDescriptionReference
** ppMembers
)
904 // coverity[callee_ptr_arith]
905 typelib_typedescription_newMIInterface(
906 ppRet
, pTypeName
, 0, 0, 0, 0, 0, pBaseInterface
== 0 ? 0 : 1,
907 &pBaseInterface
, nMembers
, ppMembers
);
915 sal_Int32 memberOffset
;
916 sal_Int32 directBaseIndex
;
917 sal_Int32 directBaseMemberOffset
;
918 typelib_InterfaceTypeDescription
const * base
;
921 typedef std::vector
< Entry
> List
;
923 BaseList(typelib_InterfaceTypeDescription
const * desc
);
925 List
const & getList() const { return list
; }
927 sal_Int32
getBaseMembers() const { return members
; }
930 typedef std::set
< rtl::OUString
> Set
;
933 sal_Int32 directBaseIndex
, Set
& directBaseSet
,
934 sal_Int32
* directBaseMembers
,
935 typelib_InterfaceTypeDescription
const * desc
);
942 BaseList::BaseList(typelib_InterfaceTypeDescription
const * desc
) {
944 for (sal_Int32 i
= 0; i
< desc
->nBaseTypes
; ++i
) {
946 sal_Int32 directBaseMembers
= 0;
947 calculate(i
, directBaseSet
, &directBaseMembers
, desc
->ppBaseTypes
[i
]);
951 void BaseList::calculate(
952 sal_Int32 directBaseIndex
, Set
& directBaseSet
,
953 sal_Int32
* directBaseMembers
,
954 typelib_InterfaceTypeDescription
const * desc
)
956 for (sal_Int32 i
= 0; i
< desc
->nBaseTypes
; ++i
) {
958 directBaseIndex
, directBaseSet
, directBaseMembers
,
959 desc
->ppBaseTypes
[i
]);
961 if (set
.insert(desc
->aBase
.pTypeName
).second
) {
963 e
.memberOffset
= members
;
964 e
.directBaseIndex
= directBaseIndex
;
965 e
.directBaseMemberOffset
= *directBaseMembers
;
968 OSL_ASSERT(desc
->ppAllMembers
!= 0);
969 members
+= desc
->nMembers
;
971 if (directBaseSet
.insert(desc
->aBase
.pTypeName
).second
) {
972 OSL_ASSERT(desc
->ppAllMembers
!= 0);
973 *directBaseMembers
+= desc
->nMembers
;
979 extern "C" void SAL_CALL
typelib_typedescription_newMIInterface(
980 typelib_InterfaceTypeDescription
** ppRet
,
981 rtl_uString
* pTypeName
,
982 SAL_UNUSED_PARAMETER sal_uInt32
, SAL_UNUSED_PARAMETER sal_uInt16
,
983 SAL_UNUSED_PARAMETER sal_uInt16
, SAL_UNUSED_PARAMETER sal_uInt32
,
984 SAL_UNUSED_PARAMETER sal_uInt32
,
985 sal_Int32 nBaseInterfaces
,
986 typelib_TypeDescriptionReference
** ppBaseInterfaces
,
988 typelib_TypeDescriptionReference
** ppMembers
)
992 typelib_typedescription_release(&(*ppRet
)->aBase
);
996 typelib_InterfaceTypeDescription
* pITD
= 0;
997 typelib_typedescription_newEmpty(
998 reinterpret_cast<typelib_TypeDescription
**>(&pITD
), typelib_TypeClass_INTERFACE
, pTypeName
);
1000 pITD
->nBaseTypes
= nBaseInterfaces
;
1001 pITD
->ppBaseTypes
= new typelib_InterfaceTypeDescription
*[nBaseInterfaces
];
1002 for (sal_Int32 i
= 0; i
< nBaseInterfaces
; ++i
) {
1003 pITD
->ppBaseTypes
[i
] = 0;
1004 typelib_typedescriptionreference_getDescription(
1005 reinterpret_cast< typelib_TypeDescription
** >(
1006 &pITD
->ppBaseTypes
[i
]),
1007 ppBaseInterfaces
[i
]);
1008 if (pITD
->ppBaseTypes
[i
] == 0
1010 reinterpret_cast< typelib_TypeDescription
** >(
1011 &pITD
->ppBaseTypes
[i
]),
1017 OSL_ASSERT(pITD
->ppBaseTypes
[i
] != 0);
1019 if (nBaseInterfaces
> 0) {
1020 pITD
->pBaseTypeDescription
= pITD
->ppBaseTypes
[0];
1023 pITD
->aUik
.m_Data1
= 0;
1024 pITD
->aUik
.m_Data2
= 0;
1025 pITD
->aUik
.m_Data3
= 0;
1026 pITD
->aUik
.m_Data4
= 0;
1027 pITD
->aUik
.m_Data5
= 0;
1029 BaseList
aBaseList(pITD
);
1030 pITD
->nAllMembers
= nMembers
+ aBaseList
.getBaseMembers();
1031 pITD
->nMembers
= nMembers
;
1033 if( pITD
->nAllMembers
)
1035 // at minimum one member exist, allocate the memory
1036 pITD
->ppAllMembers
= new typelib_TypeDescriptionReference
*[ pITD
->nAllMembers
];
1039 BaseList::List
const & rList
= aBaseList
.getList();
1040 for (BaseList::List::const_iterator
i(rList
.begin()); i
!= rList
.end();
1043 typelib_InterfaceTypeDescription
const * pBase
= i
->base
;
1044 typelib_InterfaceTypeDescription
const * pDirectBase
1045 = pITD
->ppBaseTypes
[i
->directBaseIndex
];
1046 OSL_ASSERT(pBase
->ppAllMembers
!= 0);
1047 for (sal_Int32 j
= 0; j
< pBase
->nMembers
; ++j
) {
1048 typelib_TypeDescriptionReference
const * pDirectBaseMember
1049 = pDirectBase
->ppAllMembers
[i
->directBaseMemberOffset
+ j
];
1050 rtl::OUStringBuffer
aBuf(pDirectBaseMember
->pTypeName
);
1052 aBuf
.append(i
->directBaseIndex
);
1054 aBuf
.append(i
->memberOffset
+ j
);
1056 aBuf
.append(pITD
->aBase
.pTypeName
);
1057 rtl::OUString
aName(aBuf
.makeStringAndClear());
1058 typelib_TypeDescriptionReference
* pDerivedMember
= 0;
1059 typelib_typedescriptionreference_new(
1060 &pDerivedMember
, pDirectBaseMember
->eTypeClass
,
1062 pITD
->ppAllMembers
[n
++] = pDerivedMember
;
1068 pITD
->ppMembers
= pITD
->ppAllMembers
+ aBaseList
.getBaseMembers();
1072 for( sal_Int32 i
= 0; i
< nMembers
; i
++ )
1074 typelib_typedescriptionreference_acquire( ppMembers
[i
] );
1075 pITD
->ppAllMembers
[n
++] = ppMembers
[i
];
1079 typelib_TypeDescription
* pTmp
= &pITD
->aBase
;
1080 if( !reallyWeak( typelib_TypeClass_INTERFACE
) )
1081 pTmp
->pWeakRef
= reinterpret_cast<typelib_TypeDescriptionReference
*>(pTmp
);
1082 pTmp
->nSize
= typelib_typedescription_getAlignedUnoSize( pTmp
, 0, pTmp
->nAlignment
);
1083 pTmp
->nAlignment
= adjustAlignment( pTmp
->nAlignment
);
1084 pTmp
->bComplete
= sal_False
;
1093 typelib_TypeDescriptionReference
** copyExceptions(
1094 sal_Int32 count
, rtl_uString
** typeNames
)
1096 OSL_ASSERT(count
>= 0);
1100 typelib_TypeDescriptionReference
** p
1101 = new typelib_TypeDescriptionReference
*[count
];
1102 for (sal_Int32 i
= 0; i
< count
; ++i
) {
1104 typelib_typedescriptionreference_new(
1105 p
+ i
, typelib_TypeClass_EXCEPTION
, typeNames
[i
]);
1112 extern "C" void SAL_CALL
typelib_typedescription_newInterfaceMethod(
1113 typelib_InterfaceMethodTypeDescription
** ppRet
,
1114 sal_Int32 nAbsolutePosition
,
1116 rtl_uString
* pTypeName
,
1117 typelib_TypeClass eReturnTypeClass
,
1118 rtl_uString
* pReturnTypeName
,
1120 typelib_Parameter_Init
* pParams
,
1121 sal_Int32 nExceptions
,
1122 rtl_uString
** ppExceptionNames
)
1123 SAL_THROW_EXTERN_C()
1126 typelib_typedescription_release(&(*ppRet
)->aBase
.aBase
);
1129 sal_Int32 nOffset
= rtl_ustr_lastIndexOfChar_WithLength(
1130 pTypeName
->buffer
, pTypeName
->length
, ':');
1131 if (nOffset
<= 0 || pTypeName
->buffer
[nOffset
- 1] != ':') {
1132 OSL_FAIL("Bad interface method type name");
1135 rtl::OUString
aInterfaceTypeName(pTypeName
->buffer
, nOffset
- 1);
1136 typelib_InterfaceTypeDescription
* pInterface
= 0;
1137 typelib_typedescription_getByName(
1138 reinterpret_cast< typelib_TypeDescription
** >(&pInterface
),
1139 aInterfaceTypeName
.pData
);
1141 || pInterface
->aBase
.eTypeClass
!= typelib_TypeClass_INTERFACE
1143 reinterpret_cast< typelib_TypeDescription
** >(&pInterface
), false))
1145 OSL_FAIL("No interface corresponding to interface method");
1149 typelib_typedescription_newEmpty(
1150 reinterpret_cast<typelib_TypeDescription
**>(ppRet
), typelib_TypeClass_INTERFACE_METHOD
, pTypeName
);
1151 typelib_TypeDescription
* pTmp
= reinterpret_cast<typelib_TypeDescription
*>(*ppRet
);
1153 rtl_uString_newFromStr_WithLength( &(*ppRet
)->aBase
.pMemberName
,
1154 pTypeName
->buffer
+ nOffset
+1,
1155 pTypeName
->length
- nOffset
-1 );
1156 (*ppRet
)->aBase
.nPosition
= nAbsolutePosition
;
1157 (*ppRet
)->bOneWay
= bOneWay
;
1158 typelib_typedescriptionreference_new( &(*ppRet
)->pReturnTypeRef
, eReturnTypeClass
, pReturnTypeName
);
1159 (*ppRet
)->nParams
= nParams
;
1162 (*ppRet
)->pParams
= new typelib_MethodParameter
[ nParams
];
1164 for( sal_Int32 i
= 0; i
< nParams
; i
++ )
1166 // get the name of the parameter
1167 (*ppRet
)->pParams
[ i
].pName
= 0;
1168 rtl_uString_acquire( (*ppRet
)->pParams
[ i
].pName
= pParams
[i
].pParamName
);
1169 (*ppRet
)->pParams
[ i
].pTypeRef
= 0;
1170 // get the type name of the parameter and create the weak reference
1171 typelib_typedescriptionreference_new(
1172 &(*ppRet
)->pParams
[ i
].pTypeRef
, pParams
[i
].eTypeClass
, pParams
[i
].pTypeName
);
1173 (*ppRet
)->pParams
[ i
].bIn
= pParams
[i
].bIn
;
1174 (*ppRet
)->pParams
[ i
].bOut
= pParams
[i
].bOut
;
1177 (*ppRet
)->nExceptions
= nExceptions
;
1178 (*ppRet
)->ppExceptions
= copyExceptions(nExceptions
, ppExceptionNames
);
1179 (*ppRet
)->pInterface
= pInterface
;
1180 (*ppRet
)->pBaseRef
= 0;
1182 (nAbsolutePosition
>= pInterface
->nAllMembers
- pInterface
->nMembers
)
1183 && nAbsolutePosition
< pInterface
->nAllMembers
);
1184 (*ppRet
)->nIndex
= nAbsolutePosition
1185 - (pInterface
->nAllMembers
- pInterface
->nMembers
);
1186 if( !reallyWeak( typelib_TypeClass_INTERFACE_METHOD
) )
1187 pTmp
->pWeakRef
= reinterpret_cast<typelib_TypeDescriptionReference
*>(pTmp
);
1192 extern "C" void SAL_CALL
typelib_typedescription_newInterfaceAttribute(
1193 typelib_InterfaceAttributeTypeDescription
** ppRet
,
1194 sal_Int32 nAbsolutePosition
,
1195 rtl_uString
* pTypeName
,
1196 typelib_TypeClass eAttributeTypeClass
,
1197 rtl_uString
* pAttributeTypeName
,
1198 sal_Bool bReadOnly
)
1199 SAL_THROW_EXTERN_C()
1201 typelib_typedescription_newExtendedInterfaceAttribute(
1202 ppRet
, nAbsolutePosition
, pTypeName
, eAttributeTypeClass
,
1203 pAttributeTypeName
, bReadOnly
, 0, 0, 0, 0);
1207 extern "C" void SAL_CALL
typelib_typedescription_newExtendedInterfaceAttribute(
1208 typelib_InterfaceAttributeTypeDescription
** ppRet
,
1209 sal_Int32 nAbsolutePosition
,
1210 rtl_uString
* pTypeName
,
1211 typelib_TypeClass eAttributeTypeClass
,
1212 rtl_uString
* pAttributeTypeName
,
1214 sal_Int32 nGetExceptions
, rtl_uString
** ppGetExceptionNames
,
1215 sal_Int32 nSetExceptions
, rtl_uString
** ppSetExceptionNames
)
1216 SAL_THROW_EXTERN_C()
1219 typelib_typedescription_release(&(*ppRet
)->aBase
.aBase
);
1222 sal_Int32 nOffset
= rtl_ustr_lastIndexOfChar_WithLength(
1223 pTypeName
->buffer
, pTypeName
->length
, ':');
1224 if (nOffset
<= 0 || pTypeName
->buffer
[nOffset
- 1] != ':') {
1225 OSL_FAIL("Bad interface attribute type name");
1228 rtl::OUString
aInterfaceTypeName(pTypeName
->buffer
, nOffset
- 1);
1229 typelib_InterfaceTypeDescription
* pInterface
= 0;
1230 typelib_typedescription_getByName(
1231 reinterpret_cast< typelib_TypeDescription
** >(&pInterface
),
1232 aInterfaceTypeName
.pData
);
1234 || pInterface
->aBase
.eTypeClass
!= typelib_TypeClass_INTERFACE
1236 reinterpret_cast< typelib_TypeDescription
** >(&pInterface
), false))
1238 OSL_FAIL("No interface corresponding to interface attribute");
1242 typelib_typedescription_newEmpty(
1243 reinterpret_cast<typelib_TypeDescription
**>(ppRet
), typelib_TypeClass_INTERFACE_ATTRIBUTE
, pTypeName
);
1244 typelib_TypeDescription
* pTmp
= reinterpret_cast<typelib_TypeDescription
*>(*ppRet
);
1246 rtl_uString_newFromStr_WithLength( &(*ppRet
)->aBase
.pMemberName
,
1247 pTypeName
->buffer
+ nOffset
+1,
1248 pTypeName
->length
- nOffset
-1 );
1249 (*ppRet
)->aBase
.nPosition
= nAbsolutePosition
;
1250 typelib_typedescriptionreference_new( &(*ppRet
)->pAttributeTypeRef
, eAttributeTypeClass
, pAttributeTypeName
);
1251 (*ppRet
)->bReadOnly
= bReadOnly
;
1252 (*ppRet
)->pInterface
= pInterface
;
1253 (*ppRet
)->pBaseRef
= 0;
1255 (nAbsolutePosition
>= pInterface
->nAllMembers
- pInterface
->nMembers
)
1256 && nAbsolutePosition
< pInterface
->nAllMembers
);
1257 (*ppRet
)->nIndex
= nAbsolutePosition
1258 - (pInterface
->nAllMembers
- pInterface
->nMembers
);
1259 (*ppRet
)->nGetExceptions
= nGetExceptions
;
1260 (*ppRet
)->ppGetExceptions
= copyExceptions(
1261 nGetExceptions
, ppGetExceptionNames
);
1262 (*ppRet
)->nSetExceptions
= nSetExceptions
;
1263 (*ppRet
)->ppSetExceptions
= copyExceptions(
1264 nSetExceptions
, ppSetExceptionNames
);
1265 if( !reallyWeak( typelib_TypeClass_INTERFACE_ATTRIBUTE
) )
1266 pTmp
->pWeakRef
= reinterpret_cast<typelib_TypeDescriptionReference
*>(pTmp
);
1270 extern "C" void SAL_CALL
typelib_typedescription_acquire(
1271 typelib_TypeDescription
* pTypeDescription
)
1272 SAL_THROW_EXTERN_C()
1274 osl_atomic_increment( &pTypeDescription
->nRefCount
);
1281 void deleteExceptions(
1282 sal_Int32 count
, typelib_TypeDescriptionReference
** exceptions
)
1284 for (sal_Int32 i
= 0; i
< count
; ++i
) {
1285 typelib_typedescriptionreference_release(exceptions
[i
]);
1287 delete[] exceptions
;
1292 // frees anything except typelib_TypeDescription base!
1293 static inline void typelib_typedescription_destructExtendedMembers(
1294 typelib_TypeDescription
* pTD
)
1296 OSL_ASSERT( typelib_TypeClass_TYPEDEF
!= pTD
->eTypeClass
);
1298 switch( pTD
->eTypeClass
)
1300 case typelib_TypeClass_SEQUENCE
:
1301 if( reinterpret_cast<typelib_IndirectTypeDescription
*>(pTD
)->pType
)
1302 typelib_typedescriptionreference_release( reinterpret_cast<typelib_IndirectTypeDescription
*>(pTD
)->pType
);
1304 case typelib_TypeClass_STRUCT
:
1305 delete[] reinterpret_cast< typelib_StructTypeDescription
* >(pTD
)->
1306 pParameterizedTypes
;
1307 // Fall-through intentional
1308 case typelib_TypeClass_EXCEPTION
:
1310 typelib_CompoundTypeDescription
* pCTD
= reinterpret_cast<typelib_CompoundTypeDescription
*>(pTD
);
1311 if( pCTD
->pBaseTypeDescription
)
1312 typelib_typedescription_release( &pCTD
->pBaseTypeDescription
->aBase
);
1314 for( i
= 0; i
< pCTD
->nMembers
; i
++ )
1316 typelib_typedescriptionreference_release( pCTD
->ppTypeRefs
[i
] );
1318 if (pCTD
->ppMemberNames
)
1320 for ( i
= 0; i
< pCTD
->nMembers
; i
++ )
1322 rtl_uString_release( pCTD
->ppMemberNames
[i
] );
1324 delete [] pCTD
->ppMemberNames
;
1326 delete [] pCTD
->ppTypeRefs
;
1327 delete [] pCTD
->pMemberOffsets
;
1330 case typelib_TypeClass_INTERFACE
:
1332 typelib_InterfaceTypeDescription
* pITD
= reinterpret_cast<typelib_InterfaceTypeDescription
*>(pTD
);
1333 for( sal_Int32 i
= 0; i
< pITD
->nAllMembers
; i
++ )
1335 typelib_typedescriptionreference_release( pITD
->ppAllMembers
[i
] );
1337 delete [] pITD
->ppAllMembers
;
1338 delete [] pITD
->pMapMemberIndexToFunctionIndex
;
1339 delete [] pITD
->pMapFunctionIndexToMemberIndex
;
1340 for (sal_Int32 i
= 0; i
< pITD
->nBaseTypes
; ++i
) {
1341 typelib_typedescription_release(
1342 reinterpret_cast< typelib_TypeDescription
* >(
1343 pITD
->ppBaseTypes
[i
]));
1345 delete[] pITD
->ppBaseTypes
;
1348 case typelib_TypeClass_INTERFACE_METHOD
:
1350 typelib_InterfaceMethodTypeDescription
* pIMTD
= reinterpret_cast<typelib_InterfaceMethodTypeDescription
*>(pTD
);
1351 if( pIMTD
->pReturnTypeRef
)
1352 typelib_typedescriptionreference_release( pIMTD
->pReturnTypeRef
);
1353 for( sal_Int32 i
= 0; i
< pIMTD
->nParams
; i
++ )
1355 rtl_uString_release( pIMTD
->pParams
[ i
].pName
);
1356 typelib_typedescriptionreference_release( pIMTD
->pParams
[ i
].pTypeRef
);
1358 delete [] pIMTD
->pParams
;
1359 deleteExceptions(pIMTD
->nExceptions
, pIMTD
->ppExceptions
);
1360 rtl_uString_release( pIMTD
->aBase
.pMemberName
);
1361 typelib_typedescription_release(&pIMTD
->pInterface
->aBase
);
1362 if (pIMTD
->pBaseRef
!= 0) {
1363 typelib_typedescriptionreference_release(pIMTD
->pBaseRef
);
1367 case typelib_TypeClass_INTERFACE_ATTRIBUTE
:
1369 typelib_InterfaceAttributeTypeDescription
* pIATD
= reinterpret_cast<typelib_InterfaceAttributeTypeDescription
*>(pTD
);
1370 deleteExceptions(pIATD
->nGetExceptions
, pIATD
->ppGetExceptions
);
1371 deleteExceptions(pIATD
->nSetExceptions
, pIATD
->ppSetExceptions
);
1372 if( pIATD
->pAttributeTypeRef
)
1373 typelib_typedescriptionreference_release( pIATD
->pAttributeTypeRef
);
1374 if( pIATD
->aBase
.pMemberName
)
1375 rtl_uString_release( pIATD
->aBase
.pMemberName
);
1376 typelib_typedescription_release(&pIATD
->pInterface
->aBase
);
1377 if (pIATD
->pBaseRef
!= 0) {
1378 typelib_typedescriptionreference_release(pIATD
->pBaseRef
);
1382 case typelib_TypeClass_ENUM
:
1384 typelib_EnumTypeDescription
* pEnum
= reinterpret_cast<typelib_EnumTypeDescription
*>(pTD
);
1385 for ( sal_Int32 nPos
= pEnum
->nEnumValues
; nPos
--; )
1387 rtl_uString_release( pEnum
->ppEnumNames
[nPos
] );
1389 delete [] pEnum
->ppEnumNames
;
1390 delete [] pEnum
->pEnumValues
;
1399 extern "C" void SAL_CALL
typelib_typedescription_release(
1400 typelib_TypeDescription
* pTD
)
1401 SAL_THROW_EXTERN_C()
1403 sal_Int32 ref
= osl_atomic_decrement( &pTD
->nRefCount
);
1404 OSL_ASSERT(ref
>= 0);
1407 TypeDescriptor_Init_Impl
&rInit
= Init::get();
1408 if( reallyWeak( pTD
->eTypeClass
) )
1413 MutexGuard
aGuard( rInit
.getMutex() );
1414 // remove this description from the weak reference
1415 pTD
->pWeakRef
->pType
= 0;
1417 typelib_typedescriptionreference_release( pTD
->pWeakRef
);
1422 // this description is a reference too, so remove it from the hash table
1423 if( rInit
.pWeakMap
)
1425 MutexGuard
aGuard( rInit
.getMutex() );
1426 WeakMap_Impl::iterator aIt
= rInit
.pWeakMap
->find( (sal_Unicode
*)pTD
->pTypeName
->buffer
);
1427 if( aIt
!= rInit
.pWeakMap
->end() && (void *)(*aIt
).second
== (void *)pTD
)
1429 // remove only if it contains the same object
1430 rInit
.pWeakMap
->erase( aIt
);
1435 typelib_typedescription_destructExtendedMembers( pTD
);
1436 rtl_uString_release( pTD
->pTypeName
);
1438 #if OSL_DEBUG_LEVEL > 1
1439 switch( pTD
->eTypeClass
)
1441 case typelib_TypeClass_SEQUENCE
:
1442 osl_atomic_decrement( &rInit
.nIndirectTypeDescriptionCount
);
1444 case typelib_TypeClass_STRUCT
:
1445 case typelib_TypeClass_EXCEPTION
:
1446 osl_atomic_decrement( &rInit
.nCompoundTypeDescriptionCount
);
1448 case typelib_TypeClass_INTERFACE
:
1449 osl_atomic_decrement( &rInit
.nInterfaceTypeDescriptionCount
);
1451 case typelib_TypeClass_INTERFACE_METHOD
:
1452 osl_atomic_decrement( &rInit
.nInterfaceMethodTypeDescriptionCount
);
1454 case typelib_TypeClass_INTERFACE_ATTRIBUTE
:
1455 osl_atomic_decrement( &rInit
.nInterfaceAttributeTypeDescriptionCount
);
1457 case typelib_TypeClass_ENUM
:
1458 osl_atomic_decrement( &rInit
.nEnumTypeDescriptionCount
);
1461 osl_atomic_decrement( &rInit
.nTypeDescriptionCount
);
1470 extern "C" void SAL_CALL
typelib_typedescription_register(
1471 typelib_TypeDescription
** ppNewDescription
)
1472 SAL_THROW_EXTERN_C()
1474 // connect the description with the weak reference
1475 TypeDescriptor_Init_Impl
&rInit
= Init::get();
1476 ClearableMutexGuard
aGuard( rInit
.getMutex() );
1478 typelib_TypeDescriptionReference
* pTDR
= 0;
1479 typelib_typedescriptionreference_getByName( &pTDR
, (*ppNewDescription
)->pTypeName
);
1481 OSL_ASSERT( (*ppNewDescription
)->pWeakRef
|| reallyWeak( (*ppNewDescription
)->eTypeClass
) );
1484 OSL_ASSERT( (*ppNewDescription
)->eTypeClass
== pTDR
->eTypeClass
);
1487 if (reallyWeak( pTDR
->eTypeClass
))
1489 // pRef->pType->pWeakRef == 0 means that the description is empty
1490 if (pTDR
->pType
->pWeakRef
)
1492 if (osl_atomic_increment( &pTDR
->pType
->nRefCount
) > 1)
1494 // The refence is incremented. The object cannot be destroyed.
1495 // Release the guard at the earliest point.
1497 ::typelib_typedescription_release( *ppNewDescription
);
1498 *ppNewDescription
= pTDR
->pType
;
1499 ::typelib_typedescriptionreference_release( pTDR
);
1504 // destruction of this type in progress (another thread!)
1505 (void)osl_atomic_decrement( &pTDR
->pType
->nRefCount
);
1509 pTDR
->pType
= *ppNewDescription
;
1510 OSL_ASSERT( ! (*ppNewDescription
)->pWeakRef
);
1511 (*ppNewDescription
)->pWeakRef
= pTDR
;
1516 if (((void *)pTDR
!= (void *)*ppNewDescription
) && // if different
1517 (!pTDR
->pType
->pWeakRef
|| // uninit: ref data only set
1518 // new one is complete:
1519 (!pTDR
->pType
->bComplete
&& (*ppNewDescription
)->bComplete
) ||
1520 // new one may be partly initialized interface (except of tables):
1521 (typelib_TypeClass_INTERFACE
== pTDR
->pType
->eTypeClass
&&
1522 !reinterpret_cast<typelib_InterfaceTypeDescription
*>(pTDR
->pType
)->ppAllMembers
&&
1523 (*reinterpret_cast<typelib_InterfaceTypeDescription
**>(ppNewDescription
))->ppAllMembers
)))
1525 // uninitialized or incomplete
1527 if (pTDR
->pType
->pWeakRef
) // if init
1529 typelib_typedescription_destructExtendedMembers( pTDR
->pType
);
1532 // pTDR->pType->pWeakRef == 0 means that the description is empty
1533 // description is not weak and the not the same
1534 sal_Int32 nSize
= getDescriptionSize( (*ppNewDescription
)->eTypeClass
);
1536 // copy all specific data for the descriptions
1539 *ppNewDescription
+1,
1540 nSize
- sizeof(typelib_TypeDescription
) );
1542 pTDR
->pType
->bComplete
= (*ppNewDescription
)->bComplete
;
1543 pTDR
->pType
->nSize
= (*ppNewDescription
)->nSize
;
1544 pTDR
->pType
->nAlignment
= (*ppNewDescription
)->nAlignment
;
1547 *ppNewDescription
+1,
1549 nSize
- sizeof( typelib_TypeDescription
) );
1551 if( pTDR
->pType
->bOnDemand
&& !(*ppNewDescription
)->bOnDemand
)
1553 // switch from OnDemand to !OnDemand, so the description must be acquired
1554 typelib_typedescription_acquire( pTDR
->pType
);
1556 else if( !pTDR
->pType
->bOnDemand
&& (*ppNewDescription
)->bOnDemand
)
1558 // switch from !OnDemand to OnDemand, so the description must be relesed
1559 assert(pTDR
->pType
->nRefCount
> 1);
1560 // coverity[freed_arg] - pType's nRefCount is > 1 here
1561 typelib_typedescription_release( pTDR
->pType
);
1564 pTDR
->pType
->bOnDemand
= (*ppNewDescription
)->bOnDemand
;
1566 pTDR
->pType
->pWeakRef
= pTDR
;
1569 typelib_typedescription_release( *ppNewDescription
);
1570 // pTDR was acquired by getByName(), so it must not be acquired again
1571 *ppNewDescription
= pTDR
->pType
;
1575 else if( reallyWeak( (*ppNewDescription
)->eTypeClass
) )
1577 typelib_typedescriptionreference_new(
1578 &pTDR
, (*ppNewDescription
)->eTypeClass
, (*ppNewDescription
)->pTypeName
);
1582 pTDR
= reinterpret_cast<typelib_TypeDescriptionReference
*>(*ppNewDescription
);
1583 if( !rInit
.pWeakMap
)
1584 rInit
.pWeakMap
= new WeakMap_Impl
;
1586 // description is the weak itself, so register it
1587 (*rInit
.pWeakMap
)[pTDR
->pTypeName
->buffer
] = pTDR
;
1588 OSL_ASSERT( (void *)*ppNewDescription
== (void *)pTDR
);
1591 // By default this reference is not really weak. The reference hold the description
1592 // and the description hold the reference.
1593 if( !(*ppNewDescription
)->bOnDemand
)
1595 // nor OnDemand so the description must be acquired if registered
1596 typelib_typedescription_acquire( *ppNewDescription
);
1599 pTDR
->pType
= *ppNewDescription
;
1600 (*ppNewDescription
)->pWeakRef
= pTDR
;
1601 OSL_ASSERT( rtl_ustr_compare( pTDR
->pTypeName
->buffer
, (*ppNewDescription
)->pTypeName
->buffer
) == 0 );
1602 OSL_ASSERT( pTDR
->eTypeClass
== (*ppNewDescription
)->eTypeClass
);
1606 static inline bool type_equals(
1607 typelib_TypeDescriptionReference
const * p1
, typelib_TypeDescriptionReference
const * p2
)
1610 (p1
->eTypeClass
== p2
->eTypeClass
&&
1611 p1
->pTypeName
->length
== p2
->pTypeName
->length
&&
1612 rtl_ustr_compare( p1
->pTypeName
->buffer
, p2
->pTypeName
->buffer
) == 0));
1614 extern "C" sal_Bool SAL_CALL
typelib_typedescription_equals(
1615 const typelib_TypeDescription
* p1
, const typelib_TypeDescription
* p2
)
1616 SAL_THROW_EXTERN_C()
1619 reinterpret_cast<typelib_TypeDescriptionReference
const *>(p1
), reinterpret_cast<typelib_TypeDescriptionReference
const *>(p2
) );
1623 extern "C" sal_Int32 SAL_CALL
typelib_typedescription_getAlignedUnoSize(
1624 const typelib_TypeDescription
* pTypeDescription
,
1625 sal_Int32 nOffset
, sal_Int32
& rMaxIntegralTypeSize
)
1626 SAL_THROW_EXTERN_C()
1629 if( pTypeDescription
->nSize
)
1631 // size and alignment are set
1632 rMaxIntegralTypeSize
= pTypeDescription
->nAlignment
;
1633 nSize
= pTypeDescription
->nSize
;
1638 rMaxIntegralTypeSize
= 1;
1640 OSL_ASSERT( typelib_TypeClass_TYPEDEF
!= pTypeDescription
->eTypeClass
);
1642 switch( pTypeDescription
->eTypeClass
)
1644 case typelib_TypeClass_INTERFACE
:
1645 // FEATURE_INTERFACE
1646 nSize
= rMaxIntegralTypeSize
= (sal_Int32
)(sizeof( void * ));
1648 case typelib_TypeClass_ENUM
:
1649 nSize
= rMaxIntegralTypeSize
= (sal_Int32
)(sizeof( typelib_TypeClass
));
1651 case typelib_TypeClass_STRUCT
:
1652 case typelib_TypeClass_EXCEPTION
:
1653 // FEATURE_EMPTYCLASS
1655 typelib_CompoundTypeDescription
const * pTmp
= reinterpret_cast<typelib_CompoundTypeDescription
const *>(pTypeDescription
);
1656 sal_Int32 nStructSize
= 0;
1657 if( pTmp
->pBaseTypeDescription
)
1659 // inherit structs extends the base struct.
1660 nStructSize
= pTmp
->pBaseTypeDescription
->aBase
.nSize
;
1661 rMaxIntegralTypeSize
= pTmp
->pBaseTypeDescription
->aBase
.nAlignment
;
1663 for( sal_Int32 i
= 0; i
< pTmp
->nMembers
; i
++ )
1665 typelib_TypeDescription
* pMemberType
= 0;
1666 typelib_TypeDescriptionReference
* pMemberRef
= pTmp
->ppTypeRefs
[i
];
1668 sal_Int32 nMaxIntegral
;
1669 if (pMemberRef
->eTypeClass
== typelib_TypeClass_INTERFACE
1670 || pMemberRef
->eTypeClass
== typelib_TypeClass_SEQUENCE
)
1672 nMaxIntegral
= (sal_Int32
)(sizeof(void *));
1673 nStructSize
= newAlignedSize( nStructSize
, nMaxIntegral
, nMaxIntegral
);
1677 TYPELIB_DANGER_GET( &pMemberType
, pMemberRef
);
1678 nStructSize
= typelib_typedescription_getAlignedUnoSize(
1679 pMemberType
, nStructSize
, nMaxIntegral
);
1680 TYPELIB_DANGER_RELEASE( pMemberType
);
1682 if( nMaxIntegral
> rMaxIntegralTypeSize
)
1683 rMaxIntegralTypeSize
= nMaxIntegral
;
1686 // Anything that is at least 16 bits wide is aligned on a 16-bit
1687 // boundary on the m68k default abi
1688 sal_Int32 nMaxAlign
= (rMaxIntegralTypeSize
> 2) ? 2 : rMaxIntegralTypeSize
;
1689 nStructSize
= (nStructSize
+ nMaxAlign
-1) / nMaxAlign
* nMaxAlign
;
1691 // Example: A { double; int; } structure has a size of 16 instead of 10. The
1692 // compiler must follow this rule if it is possible to access members in arrays through:
1693 // (Element *)((char *)pArray + sizeof( Element ) * ElementPos)
1694 nStructSize
= (nStructSize
+ rMaxIntegralTypeSize
-1)
1695 / rMaxIntegralTypeSize
* rMaxIntegralTypeSize
;
1697 nSize
+= nStructSize
;
1700 case typelib_TypeClass_SEQUENCE
:
1701 nSize
= rMaxIntegralTypeSize
= (sal_Int32
)(sizeof( void * ));
1703 case typelib_TypeClass_ANY
:
1705 nSize
= (sal_Int32
)(sizeof( uno_Any
));
1706 rMaxIntegralTypeSize
= (sal_Int32
)(sizeof( void * ));
1708 case typelib_TypeClass_TYPE
:
1709 nSize
= rMaxIntegralTypeSize
= (sal_Int32
)(sizeof( typelib_TypeDescriptionReference
* ));
1711 case typelib_TypeClass_BOOLEAN
:
1712 nSize
= rMaxIntegralTypeSize
= (sal_Int32
)(sizeof( sal_Bool
));
1714 case typelib_TypeClass_CHAR
:
1715 nSize
= rMaxIntegralTypeSize
= (sal_Int32
)(sizeof( sal_Unicode
));
1717 case typelib_TypeClass_STRING
:
1719 nSize
= rMaxIntegralTypeSize
= (sal_Int32
)(sizeof( rtl_uString
* ));
1721 case typelib_TypeClass_FLOAT
:
1722 nSize
= rMaxIntegralTypeSize
= (sal_Int32
)(sizeof( float ));
1724 case typelib_TypeClass_DOUBLE
:
1726 //See previous AIX ifdef comment for an explanation
1727 nSize
= (sal_Int32
)(sizeof(double));
1728 rMaxIntegralTypeSize
= (sal_Int32
)(sizeof(void*));
1730 nSize
= rMaxIntegralTypeSize
= (sal_Int32
)(sizeof( double ));
1733 case typelib_TypeClass_BYTE
:
1734 nSize
= rMaxIntegralTypeSize
= (sal_Int32
)(sizeof( sal_Int8
));
1736 case typelib_TypeClass_SHORT
:
1737 case typelib_TypeClass_UNSIGNED_SHORT
:
1738 nSize
= rMaxIntegralTypeSize
= (sal_Int32
)(sizeof( sal_Int16
));
1740 case typelib_TypeClass_LONG
:
1741 case typelib_TypeClass_UNSIGNED_LONG
:
1742 nSize
= rMaxIntegralTypeSize
= (sal_Int32
)(sizeof( sal_Int32
));
1744 case typelib_TypeClass_HYPER
:
1745 case typelib_TypeClass_UNSIGNED_HYPER
:
1746 nSize
= rMaxIntegralTypeSize
= (sal_Int32
)(sizeof( sal_Int64
));
1748 case typelib_TypeClass_UNKNOWN
:
1749 case typelib_TypeClass_SERVICE
:
1750 case typelib_TypeClass_MODULE
:
1752 OSL_FAIL( "not convertible type" );
1756 return newAlignedSize( nOffset
, nSize
, rMaxIntegralTypeSize
);
1763 typelib_TypeDescriptionReference
** copyExceptions(
1764 sal_Int32 count
, typelib_TypeDescriptionReference
** source
)
1766 typelib_TypeDescriptionReference
** p
1767 = new typelib_TypeDescriptionReference
*[count
];
1768 for (sal_Int32 i
= 0; i
< count
; ++i
) {
1769 typelib_typedescriptionreference_acquire(p
[i
] = source
[i
]);
1774 bool createDerivedInterfaceMemberDescription(
1775 typelib_TypeDescription
** result
, rtl::OUString
const & name
,
1776 typelib_TypeDescriptionReference
* baseRef
,
1777 typelib_TypeDescription
const * base
, typelib_TypeDescription
* interface
,
1778 sal_Int32 index
, sal_Int32 position
)
1780 if (baseRef
!= 0 && base
!= 0 && interface
!= 0) {
1781 switch (base
->eTypeClass
) {
1782 case typelib_TypeClass_INTERFACE_METHOD
:
1784 typelib_typedescription_newEmpty(
1785 result
, typelib_TypeClass_INTERFACE_METHOD
, name
.pData
);
1786 typelib_InterfaceMethodTypeDescription
const * baseMethod
1788 typelib_InterfaceMethodTypeDescription
const * >(base
);
1789 typelib_InterfaceMethodTypeDescription
* newMethod
1791 typelib_InterfaceMethodTypeDescription
* >(*result
);
1792 newMethod
->aBase
.nPosition
= position
;
1793 rtl_uString_acquire(
1794 newMethod
->aBase
.pMemberName
1795 = baseMethod
->aBase
.pMemberName
);
1796 typelib_typedescriptionreference_acquire(
1797 newMethod
->pReturnTypeRef
= baseMethod
->pReturnTypeRef
);
1798 newMethod
->nParams
= baseMethod
->nParams
;
1799 newMethod
->pParams
= new typelib_MethodParameter
[
1800 newMethod
->nParams
];
1801 for (sal_Int32 i
= 0; i
< newMethod
->nParams
; ++i
) {
1802 rtl_uString_acquire(
1803 newMethod
->pParams
[i
].pName
1804 = baseMethod
->pParams
[i
].pName
);
1805 typelib_typedescriptionreference_acquire(
1806 newMethod
->pParams
[i
].pTypeRef
1807 = baseMethod
->pParams
[i
].pTypeRef
);
1808 newMethod
->pParams
[i
].bIn
= baseMethod
->pParams
[i
].bIn
;
1809 newMethod
->pParams
[i
].bOut
= baseMethod
->pParams
[i
].bOut
;
1811 newMethod
->nExceptions
= baseMethod
->nExceptions
;
1812 newMethod
->ppExceptions
= copyExceptions(
1813 baseMethod
->nExceptions
, baseMethod
->ppExceptions
);
1814 newMethod
->bOneWay
= baseMethod
->bOneWay
;
1815 newMethod
->pInterface
1816 = reinterpret_cast< typelib_InterfaceTypeDescription
* >(
1818 newMethod
->pBaseRef
= baseRef
;
1819 newMethod
->nIndex
= index
;
1823 case typelib_TypeClass_INTERFACE_ATTRIBUTE
:
1825 typelib_typedescription_newEmpty(
1826 result
, typelib_TypeClass_INTERFACE_ATTRIBUTE
, name
.pData
);
1827 typelib_InterfaceAttributeTypeDescription
const * baseAttribute
1829 typelib_InterfaceAttributeTypeDescription
const * >(base
);
1830 typelib_InterfaceAttributeTypeDescription
* newAttribute
1832 typelib_InterfaceAttributeTypeDescription
* >(*result
);
1833 newAttribute
->aBase
.nPosition
= position
;
1834 rtl_uString_acquire(
1835 newAttribute
->aBase
.pMemberName
1836 = baseAttribute
->aBase
.pMemberName
);
1837 newAttribute
->bReadOnly
= baseAttribute
->bReadOnly
;
1838 typelib_typedescriptionreference_acquire(
1839 newAttribute
->pAttributeTypeRef
1840 = baseAttribute
->pAttributeTypeRef
);
1841 newAttribute
->pInterface
1842 = reinterpret_cast< typelib_InterfaceTypeDescription
* >(
1844 newAttribute
->pBaseRef
= baseRef
;
1845 newAttribute
->nIndex
= index
;
1846 newAttribute
->nGetExceptions
= baseAttribute
->nGetExceptions
;
1847 newAttribute
->ppGetExceptions
= copyExceptions(
1848 baseAttribute
->nGetExceptions
,
1849 baseAttribute
->ppGetExceptions
);
1850 newAttribute
->nSetExceptions
= baseAttribute
->nSetExceptions
;
1851 newAttribute
->ppSetExceptions
= copyExceptions(
1852 baseAttribute
->nSetExceptions
,
1853 baseAttribute
->ppSetExceptions
);
1866 extern "C" void SAL_CALL
typelib_typedescription_getByName(
1867 typelib_TypeDescription
** ppRet
, rtl_uString
* pName
)
1868 SAL_THROW_EXTERN_C()
1872 typelib_typedescription_release( (*ppRet
) );
1876 static bool bInited
= false;
1877 TypeDescriptor_Init_Impl
&rInit
= Init::get();
1881 // guard against multi thread access
1882 MutexGuard
aGuard( rInit
.getMutex() );
1885 // avoid recursion during the next ...new calls
1888 rtl_uString
* pTypeName
= 0;
1889 typelib_TypeDescription
* pType
= 0;
1890 rtl_uString_newFromAscii( &pTypeName
, "type" );
1891 typelib_typedescription_new( &pType
, typelib_TypeClass_TYPE
, pTypeName
, 0, 0, 0 );
1892 typelib_typedescription_register( &pType
);
1893 rtl_uString_newFromAscii( &pTypeName
, "void" );
1894 typelib_typedescription_new( &pType
, typelib_TypeClass_VOID
, pTypeName
, 0, 0, 0 );
1895 typelib_typedescription_register( &pType
);
1896 rtl_uString_newFromAscii( &pTypeName
, "boolean" );
1897 typelib_typedescription_new( &pType
, typelib_TypeClass_BOOLEAN
, pTypeName
, 0, 0, 0 );
1898 typelib_typedescription_register( &pType
);
1899 rtl_uString_newFromAscii( &pTypeName
, "char" );
1900 typelib_typedescription_new( &pType
, typelib_TypeClass_CHAR
, pTypeName
, 0, 0, 0 );
1901 typelib_typedescription_register( &pType
);
1902 rtl_uString_newFromAscii( &pTypeName
, "byte" );
1903 typelib_typedescription_new( &pType
, typelib_TypeClass_BYTE
, pTypeName
, 0, 0, 0 );
1904 typelib_typedescription_register( &pType
);
1905 rtl_uString_newFromAscii( &pTypeName
, "string" );
1906 typelib_typedescription_new( &pType
, typelib_TypeClass_STRING
, pTypeName
, 0, 0, 0 );
1907 typelib_typedescription_register( &pType
);
1908 rtl_uString_newFromAscii( &pTypeName
, "short" );
1909 typelib_typedescription_new( &pType
, typelib_TypeClass_SHORT
, pTypeName
, 0, 0, 0 );
1910 typelib_typedescription_register( &pType
);
1911 rtl_uString_newFromAscii( &pTypeName
, "unsigned short" );
1912 typelib_typedescription_new( &pType
, typelib_TypeClass_UNSIGNED_SHORT
, pTypeName
, 0, 0, 0 );
1913 typelib_typedescription_register( &pType
);
1914 rtl_uString_newFromAscii( &pTypeName
, "long" );
1915 typelib_typedescription_new( &pType
, typelib_TypeClass_LONG
, pTypeName
, 0, 0, 0 );
1916 typelib_typedescription_register( &pType
);
1917 rtl_uString_newFromAscii( &pTypeName
, "unsigned long" );
1918 typelib_typedescription_new( &pType
, typelib_TypeClass_UNSIGNED_LONG
, pTypeName
, 0, 0, 0 );
1919 typelib_typedescription_register( &pType
);
1920 rtl_uString_newFromAscii( &pTypeName
, "hyper" );
1921 typelib_typedescription_new( &pType
, typelib_TypeClass_HYPER
, pTypeName
, 0, 0, 0 );
1922 typelib_typedescription_register( &pType
);
1923 rtl_uString_newFromAscii( &pTypeName
, "unsigned hyper" );
1924 typelib_typedescription_new( &pType
, typelib_TypeClass_UNSIGNED_HYPER
, pTypeName
, 0, 0, 0 );
1925 typelib_typedescription_register( &pType
);
1926 rtl_uString_newFromAscii( &pTypeName
, "float" );
1927 typelib_typedescription_new( &pType
, typelib_TypeClass_FLOAT
, pTypeName
, 0, 0, 0 );
1928 typelib_typedescription_register( &pType
);
1929 rtl_uString_newFromAscii( &pTypeName
, "double" );
1930 typelib_typedescription_new( &pType
, typelib_TypeClass_DOUBLE
, pTypeName
, 0, 0, 0 );
1931 typelib_typedescription_register( &pType
);
1932 rtl_uString_newFromAscii( &pTypeName
, "any" );
1933 typelib_typedescription_new( &pType
, typelib_TypeClass_ANY
, pTypeName
, 0, 0, 0 );
1934 typelib_typedescription_register( &pType
);
1935 typelib_typedescription_release( pType
);
1936 rtl_uString_release( pTypeName
);
1940 typelib_TypeDescriptionReference
* pTDR
= 0;
1941 typelib_typedescriptionreference_getByName( &pTDR
, pName
);
1945 // guard against multi thread access
1946 MutexGuard
aGuard( rInit
.getMutex() );
1947 // pTDR->pType->pWeakRef == 0 means that the description is empty
1948 if( pTDR
->pType
&& pTDR
->pType
->pWeakRef
)
1950 typelib_typedescription_acquire( pTDR
->pType
);
1951 *ppRet
= pTDR
->pType
;
1954 typelib_typedescriptionreference_release( pTDR
);
1959 // check for sequence
1960 OUString
const & name
= OUString::unacquired( &pName
);
1961 if (2 < name
.getLength() && '[' == name
[ 0 ])
1963 OUString
element_name( name
.copy( 2 ) );
1964 typelib_TypeDescription
* element_td
= 0;
1965 typelib_typedescription_getByName( &element_td
, element_name
.pData
);
1966 if (0 != element_td
)
1968 typelib_typedescription_new(
1969 ppRet
, typelib_TypeClass_SEQUENCE
, pName
, element_td
->pWeakRef
, 0, 0 );
1971 typelib_typedescription_release( element_td
);
1976 // Check for derived interface member type:
1977 sal_Int32 i1
= name
.lastIndexOf(
1978 rtl::OUString(":@"));
1980 sal_Int32 i2
= i1
+ RTL_CONSTASCII_LENGTH(":@");
1981 sal_Int32 i3
= name
.indexOf(',', i2
);
1983 sal_Int32 i4
= name
.indexOf(':', i3
);
1985 typelib_TypeDescriptionReference
* pBaseRef
= 0;
1986 typelib_TypeDescription
* pBase
= 0;
1987 typelib_TypeDescription
* pInterface
= 0;
1988 typelib_typedescriptionreference_getByName(
1989 &pBaseRef
, name
.copy(0, i1
).pData
);
1990 if (pBaseRef
!= 0) {
1991 typelib_typedescriptionreference_getDescription(
1994 typelib_typedescription_getByName(
1995 &pInterface
, name
.copy(i4
+ 1).pData
);
1996 if (!createDerivedInterfaceMemberDescription(
1997 ppRet
, name
, pBaseRef
, pBase
, pInterface
,
1998 name
.copy(i2
, i3
- i2
).toInt32(),
1999 name
.copy(i3
+ 1, i4
- i3
- 1).toInt32()))
2001 if (pInterface
!= 0) {
2002 typelib_typedescription_release(pInterface
);
2005 typelib_typedescription_release(pBase
);
2007 if (pBaseRef
!= 0) {
2008 typelib_typedescriptionreference_release(
2019 rInit
.callChain( ppRet
, pName
);
2024 // typedescription found
2025 if (typelib_TypeClass_TYPEDEF
== (*ppRet
)->eTypeClass
)
2027 typelib_TypeDescription
* pTD
= 0;
2028 typelib_typedescriptionreference_getDescription(
2029 &pTD
, reinterpret_cast<typelib_IndirectTypeDescription
*>(*ppRet
)->pType
);
2030 typelib_typedescription_release( *ppRet
);
2036 (*ppRet
)->bOnDemand
= sal_True
;
2037 // The type description is hold by the reference until
2038 // on demand is activated.
2039 typelib_typedescription_register( ppRet
);
2041 // insert into the chache
2042 MutexGuard
aGuard( rInit
.getMutex() );
2044 rInit
.pCache
= new TypeDescriptionList_Impl
;
2045 if( (sal_Int32
)rInit
.pCache
->size() >= nCacheSize
)
2047 typelib_typedescription_release( rInit
.pCache
->front() );
2048 rInit
.pCache
->pop_front();
2050 // descriptions in the cache must be acquired!
2051 typelib_typedescription_acquire( *ppRet
);
2052 rInit
.pCache
->push_back( *ppRet
);
2058 extern "C" void SAL_CALL
typelib_typedescriptionreference_newByAsciiName(
2059 typelib_TypeDescriptionReference
** ppTDR
,
2060 typelib_TypeClass eTypeClass
,
2061 const sal_Char
* pTypeName
)
2062 SAL_THROW_EXTERN_C()
2064 OUString
aTypeName( OUString::createFromAscii( pTypeName
) );
2065 typelib_typedescriptionreference_new( ppTDR
, eTypeClass
, aTypeName
.pData
);
2068 extern "C" void SAL_CALL
typelib_typedescriptionreference_new(
2069 typelib_TypeDescriptionReference
** ppTDR
,
2070 typelib_TypeClass eTypeClass
, rtl_uString
* pTypeName
)
2071 SAL_THROW_EXTERN_C()
2073 TypeDescriptor_Init_Impl
&rInit
= Init::get();
2074 if( eTypeClass
== typelib_TypeClass_TYPEDEF
)
2077 typelib_TypeDescription
* pRet
= 0;
2078 rInit
.callChain( &pRet
, pTypeName
);
2081 // typedescription found
2082 if (typelib_TypeClass_TYPEDEF
== pRet
->eTypeClass
)
2084 typelib_typedescriptionreference_acquire(
2085 reinterpret_cast<typelib_IndirectTypeDescription
*>(pRet
)->pType
);
2087 typelib_typedescriptionreference_release( *ppTDR
);
2088 *ppTDR
= reinterpret_cast<typelib_IndirectTypeDescription
*>(pRet
)->pType
;
2089 typelib_typedescription_release( pRet
);
2094 pRet
->bOnDemand
= sal_True
;
2095 // The type description is hold by the reference until
2096 // on demand is activated.
2097 typelib_typedescription_register( &pRet
);
2099 // insert into the chache
2100 MutexGuard
aGuard( rInit
.getMutex() );
2102 rInit
.pCache
= new TypeDescriptionList_Impl
;
2103 if( (sal_Int32
)rInit
.pCache
->size() >= nCacheSize
)
2105 typelib_typedescription_release( rInit
.pCache
->front() );
2106 rInit
.pCache
->pop_front();
2108 rInit
.pCache
->push_back( pRet
);
2109 // pRet kept acquired for cache
2111 typelib_typedescriptionreference_acquire( pRet
->pWeakRef
);
2113 typelib_typedescriptionreference_release( *ppTDR
);
2114 *ppTDR
= pRet
->pWeakRef
;
2119 #if OSL_DEBUG_LEVEL > 1
2120 OString
aStr( rtl::OUStringToOString( pTypeName
, RTL_TEXTENCODING_ASCII_US
) );
2121 OSL_ENSURE( !"### typedef not found: ", aStr
.getStr() );
2123 typelib_typedescriptionreference_release( *ppTDR
);
2129 MutexGuard
aGuard( rInit
.getMutex() );
2130 typelib_typedescriptionreference_getByName( ppTDR
, pTypeName
);
2134 if( reallyWeak( eTypeClass
) )
2136 typelib_TypeDescriptionReference
* pTDR
= new typelib_TypeDescriptionReference();
2137 #if OSL_DEBUG_LEVEL > 1
2138 osl_atomic_increment( &rInit
.nTypeDescriptionReferenceCount
);
2140 pTDR
->nRefCount
= 1;
2141 pTDR
->nStaticRefCount
= 0;
2142 pTDR
->eTypeClass
= eTypeClass
;
2143 pTDR
->pUniqueIdentifier
= 0;
2144 pTDR
->pReserved
= 0;
2145 rtl_uString_acquire( pTDR
->pTypeName
= pTypeName
);
2151 typelib_typedescription_newEmpty( reinterpret_cast<typelib_TypeDescription
** >(ppTDR
), eTypeClass
, pTypeName
);
2152 // description will be registered but not acquired
2153 (*reinterpret_cast<typelib_TypeDescription
**>(ppTDR
))->bOnDemand
= sal_True
;
2154 (*reinterpret_cast<typelib_TypeDescription
**>(ppTDR
))->bComplete
= sal_False
;
2157 if( !rInit
.pWeakMap
)
2158 rInit
.pWeakMap
= new WeakMap_Impl
;
2159 // Heavy hack, the const sal_Unicode * is hold by the typedescription reference
2161 rInit
.pWeakMap
->operator[]( (*ppTDR
)->pTypeName
->buffer
) = *ppTDR
;
2165 extern "C" void SAL_CALL
typelib_typedescriptionreference_acquire(
2166 typelib_TypeDescriptionReference
* pRef
)
2167 SAL_THROW_EXTERN_C()
2169 osl_atomic_increment( &pRef
->nRefCount
);
2173 extern "C" void SAL_CALL
typelib_typedescriptionreference_release(
2174 typelib_TypeDescriptionReference
* pRef
)
2175 SAL_THROW_EXTERN_C()
2177 // Is it a type description?
2178 if( reallyWeak( pRef
->eTypeClass
) )
2180 if( ! osl_atomic_decrement( &pRef
->nRefCount
) )
2182 TypeDescriptor_Init_Impl
&rInit
= Init::get();
2183 if( rInit
.pWeakMap
)
2185 MutexGuard
aGuard( rInit
.getMutex() );
2186 WeakMap_Impl::iterator aIt
= rInit
.pWeakMap
->find( (sal_Unicode
*)pRef
->pTypeName
->buffer
);
2187 if( !(aIt
== rInit
.pWeakMap
->end()) && (*aIt
).second
== pRef
)
2189 // remove only if it contains the same object
2190 rInit
.pWeakMap
->erase( aIt
);
2194 rtl_uString_release( pRef
->pTypeName
);
2195 OSL_ASSERT( pRef
->pType
== 0 );
2196 #if OSL_DEBUG_LEVEL > 1
2197 osl_atomic_decrement( &rInit
.nTypeDescriptionReferenceCount
);
2204 typelib_typedescription_release( reinterpret_cast<typelib_TypeDescription
*>(pRef
) );
2209 extern "C" void SAL_CALL
typelib_typedescriptionreference_getDescription(
2210 typelib_TypeDescription
** ppRet
, typelib_TypeDescriptionReference
* pRef
)
2211 SAL_THROW_EXTERN_C()
2215 typelib_typedescription_release( *ppRet
);
2219 if( !reallyWeak( pRef
->eTypeClass
) && pRef
->pType
&& pRef
->pType
->pWeakRef
)
2221 // reference is a description and initialized
2222 osl_atomic_increment( &reinterpret_cast<typelib_TypeDescription
*>(pRef
)->nRefCount
);
2223 *ppRet
= reinterpret_cast<typelib_TypeDescription
*>(pRef
);
2228 MutexGuard
aGuard( Init::get().getMutex() );
2229 // pRef->pType->pWeakRef == 0 means that the description is empty
2230 if( pRef
->pType
&& pRef
->pType
->pWeakRef
)
2232 sal_Int32 n
= osl_atomic_increment( &pRef
->pType
->nRefCount
);
2235 // The refence is incremented. The object cannot be destroyed.
2236 // Release the guard at the earliest point.
2237 *ppRet
= pRef
->pType
;
2242 (void)osl_atomic_decrement( &pRef
->pType
->nRefCount
);
2243 // destruction of this type in progress (another thread!)
2244 // no access through this weak reference
2250 typelib_typedescription_getByName( ppRet
, pRef
->pTypeName
);
2251 OSL_ASSERT( !*ppRet
|| rtl_ustr_compare( pRef
->pTypeName
->buffer
, (*ppRet
)->pTypeName
->buffer
) == 0 );
2252 OSL_ASSERT( !*ppRet
|| pRef
->eTypeClass
== (*ppRet
)->eTypeClass
);
2253 OSL_ASSERT( !*ppRet
|| pRef
== (*ppRet
)->pWeakRef
);
2254 pRef
->pType
= *ppRet
;
2258 extern "C" void SAL_CALL
typelib_typedescriptionreference_getByName(
2259 typelib_TypeDescriptionReference
** ppRet
, rtl_uString
* pName
)
2260 SAL_THROW_EXTERN_C()
2264 typelib_typedescriptionreference_release( *ppRet
);
2267 TypeDescriptor_Init_Impl
&rInit
= Init::get();
2268 if( rInit
.pWeakMap
)
2270 MutexGuard
aGuard( rInit
.getMutex() );
2271 WeakMap_Impl::const_iterator aIt
= rInit
.pWeakMap
->find( (sal_Unicode
*)pName
->buffer
);
2272 if( !(aIt
== rInit
.pWeakMap
->end()) ) // != failed on msc4.2
2274 sal_Int32 n
= osl_atomic_increment( &(*aIt
).second
->nRefCount
);
2277 // The refence is incremented. The object cannot be destroyed.
2278 // Release the guard at the earliest point.
2279 *ppRet
= (*aIt
).second
;
2283 // destruction of this type in progress (another thread!)
2284 // no access through this weak reference
2285 (void)osl_atomic_decrement( &(*aIt
).second
->nRefCount
);
2292 extern "C" sal_Bool SAL_CALL
typelib_typedescriptionreference_equals(
2293 const typelib_TypeDescriptionReference
* p1
,
2294 const typelib_TypeDescriptionReference
* p2
)
2295 SAL_THROW_EXTERN_C()
2298 (p1
->eTypeClass
== p2
->eTypeClass
&&
2299 p1
->pTypeName
->length
== p2
->pTypeName
->length
&&
2300 rtl_ustr_compare( p1
->pTypeName
->buffer
, p2
->pTypeName
->buffer
) == 0));
2304 extern "C" void SAL_CALL
typelib_typedescriptionreference_assign(
2305 typelib_TypeDescriptionReference
** ppDest
,
2306 typelib_TypeDescriptionReference
* pSource
)
2307 SAL_THROW_EXTERN_C()
2309 if (*ppDest
!= pSource
)
2311 ::typelib_typedescriptionreference_acquire( pSource
);
2312 ::typelib_typedescriptionreference_release( *ppDest
);
2318 extern "C" void SAL_CALL
typelib_setCacheSize( sal_Int32 nNewSize
)
2319 SAL_THROW_EXTERN_C()
2321 OSL_ENSURE( nNewSize
>= 0, "### illegal cache size given!" );
2324 TypeDescriptor_Init_Impl
&rInit
= Init::get();
2325 MutexGuard
aGuard( rInit
.getMutex() );
2326 if ((nNewSize
< nCacheSize
) && rInit
.pCache
)
2328 while ((sal_Int32
)rInit
.pCache
->size() != nNewSize
)
2330 typelib_typedescription_release( rInit
.pCache
->front() );
2331 rInit
.pCache
->pop_front();
2334 nCacheSize
= nNewSize
;
2339 static const sal_Bool s_aAssignableFromTab
[11][11] =
2341 /* from CH,BO,BY,SH,US,LO,UL,HY,UH,FL,DO */
2342 /* TypeClass_CHAR */ { 1, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0 },
2343 /* TypeClass_BOOLEAN */ { 0, 1, 0, 0, 0, 0, 0, 0, 0, 0, 0 },
2344 /* TypeClass_BYTE */ { 0, 0, 1, 0, 0, 0, 0, 0, 0, 0, 0 },
2345 /* TypeClass_SHORT */ { 0, 0, 1, 1, 1, 0, 0, 0, 0, 0, 0 },
2346 /* TypeClass_UNSIGNED_SHORT */ { 0, 0, 1, 1, 1, 0, 0, 0, 0, 0, 0 },
2347 /* TypeClass_LONG */ { 0, 0, 1, 1, 1, 1, 1, 0, 0, 0, 0 },
2348 /* TypeClass_UNSIGNED_LONG */ { 0, 0, 1, 1, 1, 1, 1, 0, 0, 0, 0 },
2349 /* TypeClass_HYPER */ { 0, 0, 1, 1, 1, 1, 1, 1, 1, 0, 0 },
2350 /* TypeClass_UNSIGNED_HYPER */ { 0, 0, 1, 1, 1, 1, 1, 1, 1, 0, 0 },
2351 /* TypeClass_FLOAT */ { 0, 0, 1, 1, 1, 0, 0, 0, 0, 1, 0 },
2352 /* TypeClass_DOUBLE */ { 0, 0, 1, 1, 1, 1, 1, 0, 0, 1, 1 }
2356 extern "C" sal_Bool SAL_CALL
typelib_typedescriptionreference_isAssignableFrom(
2357 typelib_TypeDescriptionReference
* pAssignable
,
2358 typelib_TypeDescriptionReference
* pFrom
)
2359 SAL_THROW_EXTERN_C()
2361 if (pAssignable
&& pFrom
)
2363 typelib_TypeClass eAssignable
= pAssignable
->eTypeClass
;
2364 typelib_TypeClass eFrom
= pFrom
->eTypeClass
;
2366 if (eAssignable
== typelib_TypeClass_ANY
) // anything can be assigned to an any .)
2368 if (eAssignable
== eFrom
)
2370 if (type_equals( pAssignable
, pFrom
)) // first shot
2376 switch (eAssignable
)
2378 case typelib_TypeClass_STRUCT
:
2379 case typelib_TypeClass_EXCEPTION
:
2381 typelib_TypeDescription
* pFromDescr
= 0;
2382 TYPELIB_DANGER_GET( &pFromDescr
, pFrom
);
2383 if (!reinterpret_cast<typelib_CompoundTypeDescription
*>(pFromDescr
)->pBaseTypeDescription
)
2385 TYPELIB_DANGER_RELEASE( pFromDescr
);
2388 bool bRet
= typelib_typedescriptionreference_isAssignableFrom(
2390 reinterpret_cast<typelib_CompoundTypeDescription
*>(pFromDescr
)->pBaseTypeDescription
->aBase
.pWeakRef
);
2391 TYPELIB_DANGER_RELEASE( pFromDescr
);
2394 case typelib_TypeClass_INTERFACE
:
2396 typelib_TypeDescription
* pFromDescr
= 0;
2397 TYPELIB_DANGER_GET( &pFromDescr
, pFrom
);
2398 typelib_InterfaceTypeDescription
* pFromIfc
2400 typelib_InterfaceTypeDescription
* >(pFromDescr
);
2402 for (sal_Int32 i
= 0; i
< pFromIfc
->nBaseTypes
; ++i
) {
2403 if (typelib_typedescriptionreference_isAssignableFrom(
2405 pFromIfc
->ppBaseTypes
[i
]->aBase
.pWeakRef
))
2411 TYPELIB_DANGER_RELEASE( pFromDescr
);
2421 return (eAssignable
>= typelib_TypeClass_CHAR
&& eAssignable
<= typelib_TypeClass_DOUBLE
&&
2422 eFrom
>= typelib_TypeClass_CHAR
&& eFrom
<= typelib_TypeClass_DOUBLE
&&
2423 s_aAssignableFromTab
[eAssignable
-1][eFrom
-1]);
2428 extern "C" sal_Bool SAL_CALL
typelib_typedescription_isAssignableFrom(
2429 typelib_TypeDescription
* pAssignable
,
2430 typelib_TypeDescription
* pFrom
)
2431 SAL_THROW_EXTERN_C()
2433 return typelib_typedescriptionreference_isAssignableFrom(
2434 pAssignable
->pWeakRef
, pFrom
->pWeakRef
);
2438 extern "C" sal_Bool SAL_CALL
typelib_typedescription_complete(
2439 typelib_TypeDescription
** ppTypeDescr
)
2440 SAL_THROW_EXTERN_C()
2442 return complete(ppTypeDescr
, true);
2445 /* vim:set shiftwidth=4 softtabstop=4 expandtab: */