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 .
22 #include <unordered_map>
32 #include <sal/log.hxx>
33 #include <osl/interlck.h>
34 #include <osl/mutex.hxx>
35 #include <rtl/ustring.hxx>
36 #include <osl/diagnose.h>
37 #include <typelib/typedescription.h>
39 #include "typelib.hxx"
50 * The double member determines the alignment.
51 * Under OS2 and MS-Windows the Alignment is min( 8, sizeof( type ) ).
52 * The alignment of a structure is min( 8, sizeof( max basic type ) ), the greatest basic type
53 * determines the alignment.
59 //double: doubleword aligned if -qalign=natural/-malign=natural
60 //which isn't the default ABI. Otherwise word aligned, While a long long int
61 //is always doubleword aligned, so use that instead.
74 // the value of the maximal alignment
75 const sal_Int32 nMaxAlignment
= static_cast<sal_Int32
>( reinterpret_cast<sal_Size
>(&reinterpret_cast<AlignSize_Impl
*>(16)->dDouble
) - 16);
77 static sal_Int32
adjustAlignment( sal_Int32 nRequestedAlignment
)
79 if( nRequestedAlignment
> nMaxAlignment
)
80 nRequestedAlignment
= nMaxAlignment
;
81 return nRequestedAlignment
;
85 * Calculate the new size of the structure.
87 static sal_Int32
newAlignedSize(
88 sal_Int32 OldSize
, sal_Int32 ElementSize
, sal_Int32 NeededAlignment
)
90 NeededAlignment
= adjustAlignment( NeededAlignment
);
91 return (OldSize
+ NeededAlignment
-1) / NeededAlignment
* NeededAlignment
+ ElementSize
;
94 static sal_Int32
getDescriptionSize( typelib_TypeClass eTypeClass
)
96 OSL_ASSERT( typelib_TypeClass_TYPEDEF
!= eTypeClass
);
99 // The reference is the description
100 // if the description is empty, then it must be filled with
101 // the new description
104 case typelib_TypeClass_SEQUENCE
:
105 nSize
= sal_Int32(sizeof( typelib_IndirectTypeDescription
));
108 case typelib_TypeClass_STRUCT
:
109 nSize
= sal_Int32(sizeof( typelib_StructTypeDescription
));
112 case typelib_TypeClass_EXCEPTION
:
113 nSize
= sal_Int32(sizeof( typelib_CompoundTypeDescription
));
116 case typelib_TypeClass_ENUM
:
117 nSize
= sal_Int32(sizeof( typelib_EnumTypeDescription
));
120 case typelib_TypeClass_INTERFACE
:
121 nSize
= sal_Int32(sizeof( typelib_InterfaceTypeDescription
));
124 case typelib_TypeClass_INTERFACE_METHOD
:
125 nSize
= sal_Int32(sizeof( typelib_InterfaceMethodTypeDescription
));
128 case typelib_TypeClass_INTERFACE_ATTRIBUTE
:
129 nSize
= sal_Int32(sizeof( typelib_InterfaceAttributeTypeDescription
));
133 nSize
= sal_Int32(sizeof( typelib_TypeDescription
));
142 bool operator()(const sal_Unicode
* const & s1
, const sal_Unicode
* const & s2
) const
143 { return 0 == rtl_ustr_compare( s1
, s2
); }
149 size_t operator()(const sal_Unicode
* const & s
) const
150 { return rtl_ustr_hashCode( s
); }
155 // Heavy hack, the const sal_Unicode * is hold by the typedescription reference
156 typedef std::unordered_map
< const sal_Unicode
*, typelib_TypeDescriptionReference
*,
157 hashStr_Impl
, equalStr_Impl
> WeakMap_Impl
;
159 typedef std::pair
< void *, typelib_typedescription_Callback
> CallbackEntry
;
160 typedef std::list
< CallbackEntry
> CallbackSet_Impl
;
161 typedef std::list
< typelib_TypeDescription
* > TypeDescriptionList_Impl
;
163 // # of cached elements
164 static sal_Int32 nCacheSize
= 256;
168 struct TypeDescriptor_Init_Impl
170 // all type description references
171 WeakMap_Impl maWeakMap
;
172 // all type description callbacks
173 CallbackSet_Impl maCallbacks
;
174 // A cache to hold descriptions
175 TypeDescriptionList_Impl maCache
;
176 // The mutex to guard all type library accesses
179 inline void callChain( typelib_TypeDescription
** ppRet
, rtl_uString
* pName
);
181 #if OSL_DEBUG_LEVEL > 0
182 // only for debugging
183 sal_Int32 nTypeDescriptionCount
= 0;
184 sal_Int32 nCompoundTypeDescriptionCount
= 0;
185 sal_Int32 nIndirectTypeDescriptionCount
= 0;
186 sal_Int32 nEnumTypeDescriptionCount
= 0;
187 sal_Int32 nInterfaceMethodTypeDescriptionCount
= 0;
188 sal_Int32 nInterfaceAttributeTypeDescriptionCount
= 0;
189 sal_Int32 nInterfaceTypeDescriptionCount
= 0;
190 sal_Int32 nTypeDescriptionReferenceCount
= 0;
193 TypeDescriptor_Init_Impl() = default;
195 ~TypeDescriptor_Init_Impl();
200 inline void TypeDescriptor_Init_Impl::callChain(
201 typelib_TypeDescription
** ppRet
, rtl_uString
* pName
)
203 assert(ppRet
!= nullptr);
204 assert(*ppRet
== nullptr);
205 for( const CallbackEntry
& rEntry
: maCallbacks
)
207 (*rEntry
.second
)( rEntry
.first
, ppRet
, pName
);
214 TypeDescriptor_Init_Impl::~TypeDescriptor_Init_Impl()
216 for( typelib_TypeDescription
* pItem
: maCache
)
218 typelib_typedescription_release( pItem
);
222 std::vector
< typelib_TypeDescriptionReference
* > ppTDR
;
223 ppTDR
.reserve( maWeakMap
.size() );
225 // save all weak references
226 for( const auto& rEntry
: maWeakMap
)
228 ppTDR
.push_back( rEntry
.second
);
229 typelib_typedescriptionreference_acquire( ppTDR
.back() );
232 for( typelib_TypeDescriptionReference
* pTDR
: ppTDR
)
234 OSL_ASSERT( pTDR
->nRefCount
> pTDR
->nStaticRefCount
);
235 pTDR
->nRefCount
-= pTDR
->nStaticRefCount
;
237 if( pTDR
->pType
&& !pTDR
->pType
->bOnDemand
)
239 pTDR
->pType
->bOnDemand
= true;
240 typelib_typedescription_release( pTDR
->pType
);
242 typelib_typedescriptionreference_release( pTDR
);
245 #if defined SAL_LOG_INFO
246 for( const auto& rEntry
: maWeakMap
)
248 typelib_TypeDescriptionReference
* pTDR
= rEntry
.second
;
251 OString
aTypeName( OUStringToOString( OUString::unacquired(&pTDR
->pTypeName
), RTL_TEXTENCODING_ASCII_US
) );
252 SAL_INFO("cppu.typelib", "remaining type: " << aTypeName
<< "; ref count = " << pTDR
->nRefCount
);
256 SAL_INFO("cppu.typelib", "remaining null type entry!?");
261 #if OSL_DEBUG_LEVEL > 0
262 SAL_INFO_IF( nTypeDescriptionCount
, "cppu.typelib", "nTypeDescriptionCount is not zero" );
263 SAL_INFO_IF( nCompoundTypeDescriptionCount
, "cppu.typelib", "nCompoundTypeDescriptionCount is not zero" );
264 SAL_INFO_IF( nIndirectTypeDescriptionCount
, "cppu.typelib", "nIndirectTypeDescriptionCount is not zero" );
265 SAL_INFO_IF( nEnumTypeDescriptionCount
, "cppu.typelib", "nEnumTypeDescriptionCount is not zero" );
266 SAL_INFO_IF( nInterfaceMethodTypeDescriptionCount
, "cppu.typelib", "nInterfaceMethodTypeDescriptionCount is not zero" );
267 SAL_INFO_IF( nInterfaceAttributeTypeDescriptionCount
, "cppu.typelib", "nInterfaceAttributeTypeDescriptionCount is not zero" );
268 SAL_INFO_IF( nInterfaceTypeDescriptionCount
, "cppu.typelib", "nInterfaceTypeDescriptionCount is not zero" );
269 SAL_INFO_IF( nTypeDescriptionReferenceCount
, "cppu.typelib", "nTypeDescriptionReferenceCount is not zero" );
272 SAL_INFO_IF( !maCallbacks
.empty(), "cppu.typelib", "pCallbacks is not NULL or empty" );
276 TypeDescriptor_Init_Impl
& Init()
278 static TypeDescriptor_Init_Impl SINGLETON
;
283 extern "C" void SAL_CALL
typelib_typedescription_registerCallback(
284 void * pContext
, typelib_typedescription_Callback pCallback
)
287 // todo mt safe: guard is no solution, can not acquire while calling callback!
288 TypeDescriptor_Init_Impl
&rInit
= Init();
289 // OslGuard aGuard( rInit.getMutex() );
290 rInit
.maCallbacks
.push_back( CallbackEntry( pContext
, pCallback
) );
294 extern "C" void SAL_CALL
typelib_typedescription_revokeCallback(
295 void * pContext
, typelib_typedescription_Callback pCallback
)
298 TypeDescriptor_Init_Impl
&rInit
= Init();
300 // todo mt safe: guard is no solution, can not acquire while calling callback!
301 // OslGuard aGuard( rInit.getMutex() );
302 CallbackEntry
aEntry( pContext
, pCallback
);
303 rInit
.maCallbacks
.erase(std::remove(rInit
.maCallbacks
.begin(), rInit
.maCallbacks
.end(), aEntry
),
304 rInit
.maCallbacks
.end());
308 static void typelib_typedescription_initTables(
309 typelib_TypeDescription
* pTD
)
311 typelib_InterfaceTypeDescription
* pITD
= reinterpret_cast<typelib_InterfaceTypeDescription
*>(pTD
);
313 std::vector
<bool> aReadWriteAttributes(pITD
->nAllMembers
);
314 for ( sal_Int32 i
= pITD
->nAllMembers
; i
--; )
316 aReadWriteAttributes
[i
] = false;
317 if( typelib_TypeClass_INTERFACE_ATTRIBUTE
== pITD
->ppAllMembers
[i
]->eTypeClass
)
319 typelib_TypeDescription
* pM
= nullptr;
320 TYPELIB_DANGER_GET( &pM
, pITD
->ppAllMembers
[i
] );
324 aReadWriteAttributes
[i
] = !reinterpret_cast<typelib_InterfaceAttributeTypeDescription
*>(pM
)->bReadOnly
;
325 TYPELIB_DANGER_RELEASE( pM
);
329 SAL_INFO( "cppu.typelib", "cannot get attribute type description: " << pITD
->ppAllMembers
[i
]->pTypeName
);
334 MutexGuard
aGuard( Init().maMutex
);
338 // create the index table from member to function table
339 pITD
->pMapMemberIndexToFunctionIndex
= new sal_Int32
[ pITD
->nAllMembers
];
340 sal_Int32 nAdditionalOffset
= 0; // +1 for read/write attributes
342 for( i
= 0; i
< pITD
->nAllMembers
; i
++ )
344 // index to the get method of the attribute
345 pITD
->pMapMemberIndexToFunctionIndex
[i
] = i
+ nAdditionalOffset
;
346 // extra offset if it is a read/write attribute?
347 if (aReadWriteAttributes
[i
])
349 // a read/write attribute
354 // create the index table from function to member table
355 pITD
->pMapFunctionIndexToMemberIndex
= new sal_Int32
[ pITD
->nAllMembers
+ nAdditionalOffset
];
356 nAdditionalOffset
= 0; // +1 for read/write attributes
357 for( i
= 0; i
< pITD
->nAllMembers
; i
++ )
359 // index to the get method of the attribute
360 pITD
->pMapFunctionIndexToMemberIndex
[i
+ nAdditionalOffset
] = i
;
361 // extra offset if it is a read/write attribute?
362 if (aReadWriteAttributes
[i
])
364 // a read/write attribute
365 pITD
->pMapFunctionIndexToMemberIndex
[i
+ ++nAdditionalOffset
] = i
;
368 // must be the last action after all initialization is done
369 pITD
->nMapFunctionIndexToMemberIndex
= pITD
->nAllMembers
+ nAdditionalOffset
;
370 pTD
->bComplete
= true;
375 template<typename T
> T
* allocTypeDescription() {
376 return reinterpret_cast<T
*>(new char[sizeof (T
)]);
379 void freeTypeDescription(typelib_TypeDescription
const * desc
) {
380 delete[] reinterpret_cast<char const *>(desc
);
383 // In some situations (notably typelib_typedescription_newInterfaceMethod and
384 // typelib_typedescription_newInterfaceAttribute), only the members nMembers,
385 // ppMembers, nAllMembers, and ppAllMembers of an incomplete interface type
386 // description are necessary, but not the additional
387 // pMapMemberIndexToFunctionIndex, nMapFunctionIndexToMemberIndex, and
388 // pMapFunctionIndexToMemberIndex (which are computed by
389 // typelib_typedescription_initTables). Furthermore, in those situations, it
390 // might be illegal to compute those tables, as the creation of the interface
391 // member type descriptions would recursively require a complete interface type
392 // description. The parameter initTables controls whether or not to call
393 // typelib_typedescription_initTables in those situations.
394 bool complete(typelib_TypeDescription
** ppTypeDescr
, bool initTables
) {
395 if (! (*ppTypeDescr
)->bComplete
)
397 OSL_ASSERT( (typelib_TypeClass_STRUCT
== (*ppTypeDescr
)->eTypeClass
||
398 typelib_TypeClass_EXCEPTION
== (*ppTypeDescr
)->eTypeClass
||
399 typelib_TypeClass_ENUM
== (*ppTypeDescr
)->eTypeClass
||
400 typelib_TypeClass_INTERFACE
== (*ppTypeDescr
)->eTypeClass
) &&
401 !TYPELIB_TYPEDESCRIPTIONREFERENCE_ISREALLYWEAK( (*ppTypeDescr
)->eTypeClass
) );
403 if (typelib_TypeClass_INTERFACE
== (*ppTypeDescr
)->eTypeClass
&&
404 reinterpret_cast<typelib_InterfaceTypeDescription
*>(*ppTypeDescr
)->ppAllMembers
)
407 typelib_typedescription_initTables( *ppTypeDescr
);
412 typelib_TypeDescription
* pTD
= nullptr;
413 // on demand access of complete td
414 TypeDescriptor_Init_Impl
&rInit
= Init();
415 rInit
.callChain( &pTD
, (*ppTypeDescr
)->pTypeName
);
418 if (typelib_TypeClass_TYPEDEF
== pTD
->eTypeClass
)
420 typelib_typedescriptionreference_getDescription(
421 &pTD
, reinterpret_cast<typelib_IndirectTypeDescription
*>(pTD
)->pType
);
427 OSL_ASSERT( typelib_TypeClass_TYPEDEF
!= pTD
->eTypeClass
);
428 // typedescription found
430 pTD
->bOnDemand
= true;
432 if (pTD
->eTypeClass
== typelib_TypeClass_INTERFACE
433 && !pTD
->bComplete
&& initTables
)
435 // mandatory info from callback chain
436 OSL_ASSERT( reinterpret_cast<typelib_InterfaceTypeDescription
*>(pTD
)->ppAllMembers
);
437 // complete except of tables init
438 typelib_typedescription_initTables( pTD
);
439 pTD
->bComplete
= true;
442 // The type description is hold by the reference until
443 // on demand is activated.
444 ::typelib_typedescription_register( &pTD
); // replaces incomplete one
445 OSL_ASSERT( pTD
== *ppTypeDescr
); // has to merge into existing one
447 // insert into the cache
448 MutexGuard
aGuard( rInit
.maMutex
);
449 if( static_cast<sal_Int32
>(rInit
.maCache
.size()) >= nCacheSize
)
451 typelib_typedescription_release( rInit
.maCache
.front() );
452 rInit
.maCache
.pop_front();
454 // descriptions in the cache must be acquired!
455 typelib_typedescription_acquire( pTD
);
456 rInit
.maCache
.push_back( pTD
);
460 || (pTD
->eTypeClass
== typelib_TypeClass_INTERFACE
463 ::typelib_typedescription_release( *ppTypeDescr
);
470 "type cannot be completed: " << OUString::unacquired(&(*ppTypeDescr
)->pTypeName
));
480 extern "C" void typelib_typedescription_newEmpty(
481 typelib_TypeDescription
** ppRet
,
482 typelib_TypeClass eTypeClass
, rtl_uString
* pTypeName
)
487 typelib_typedescription_release( *ppRet
);
491 OSL_ASSERT( typelib_TypeClass_TYPEDEF
!= eTypeClass
);
493 typelib_TypeDescription
* pRet
;
496 case typelib_TypeClass_SEQUENCE
:
498 auto pTmp
= allocTypeDescription
<typelib_IndirectTypeDescription
>();
500 #if OSL_DEBUG_LEVEL > 0
501 osl_atomic_increment( &Init().nIndirectTypeDescriptionCount
);
503 pTmp
->pType
= nullptr;
504 // coverity[leaked_storage] - this is on purpose
508 case typelib_TypeClass_STRUCT
:
510 // FEATURE_EMPTYCLASS
511 auto pTmp
= allocTypeDescription
<typelib_StructTypeDescription
>();
512 pRet
= &pTmp
->aBase
.aBase
;
513 #if OSL_DEBUG_LEVEL > 0
514 osl_atomic_increment( &Init().nCompoundTypeDescriptionCount
);
516 pTmp
->aBase
.pBaseTypeDescription
= nullptr;
517 pTmp
->aBase
.nMembers
= 0;
518 pTmp
->aBase
.pMemberOffsets
= nullptr;
519 pTmp
->aBase
.ppTypeRefs
= nullptr;
520 pTmp
->aBase
.ppMemberNames
= nullptr;
521 pTmp
->pParameterizedTypes
= nullptr;
522 // coverity[leaked_storage] - this is on purpose
526 case typelib_TypeClass_EXCEPTION
:
528 // FEATURE_EMPTYCLASS
529 auto pTmp
= allocTypeDescription
<typelib_CompoundTypeDescription
>();
531 #if OSL_DEBUG_LEVEL > 0
532 osl_atomic_increment( &Init().nCompoundTypeDescriptionCount
);
534 pTmp
->pBaseTypeDescription
= nullptr;
536 pTmp
->pMemberOffsets
= nullptr;
537 pTmp
->ppTypeRefs
= nullptr;
538 pTmp
->ppMemberNames
= nullptr;
539 // coverity[leaked_storage] - this is on purpose
543 case typelib_TypeClass_ENUM
:
545 auto pTmp
= allocTypeDescription
<typelib_EnumTypeDescription
>();
547 #if OSL_DEBUG_LEVEL > 0
548 osl_atomic_increment( &Init().nEnumTypeDescriptionCount
);
550 pTmp
->nDefaultEnumValue
= 0;
551 pTmp
->nEnumValues
= 0;
552 pTmp
->ppEnumNames
= nullptr;
553 pTmp
->pEnumValues
= nullptr;
554 // coverity[leaked_storage] - this is on purpose
558 case typelib_TypeClass_INTERFACE
:
560 auto pTmp
= allocTypeDescription
<
561 typelib_InterfaceTypeDescription
>();
563 #if OSL_DEBUG_LEVEL > 0
564 osl_atomic_increment( &Init().nInterfaceTypeDescriptionCount
);
566 pTmp
->pBaseTypeDescription
= nullptr;
568 pTmp
->ppMembers
= nullptr;
569 pTmp
->nAllMembers
= 0;
570 pTmp
->ppAllMembers
= nullptr;
571 pTmp
->nMapFunctionIndexToMemberIndex
= 0;
572 pTmp
->pMapFunctionIndexToMemberIndex
= nullptr;
573 pTmp
->pMapMemberIndexToFunctionIndex
= nullptr;
574 pTmp
->nBaseTypes
= 0;
575 pTmp
->ppBaseTypes
= nullptr;
576 // coverity[leaked_storage] - this is on purpose
580 case typelib_TypeClass_INTERFACE_METHOD
:
582 auto pTmp
= allocTypeDescription
<
583 typelib_InterfaceMethodTypeDescription
>();
584 pRet
= &pTmp
->aBase
.aBase
;
585 #if OSL_DEBUG_LEVEL > 0
586 osl_atomic_increment( &Init().nInterfaceMethodTypeDescriptionCount
);
588 pTmp
->aBase
.pMemberName
= nullptr;
589 pTmp
->pReturnTypeRef
= nullptr;
591 pTmp
->pParams
= nullptr;
592 pTmp
->nExceptions
= 0;
593 pTmp
->ppExceptions
= nullptr;
594 pTmp
->pInterface
= nullptr;
595 pTmp
->pBaseRef
= nullptr;
597 // coverity[leaked_storage] - this is on purpose
601 case typelib_TypeClass_INTERFACE_ATTRIBUTE
:
603 auto * pTmp
= allocTypeDescription
<
604 typelib_InterfaceAttributeTypeDescription
>();
605 pRet
= &pTmp
->aBase
.aBase
;
606 #if OSL_DEBUG_LEVEL > 0
607 osl_atomic_increment( &Init().nInterfaceAttributeTypeDescriptionCount
);
609 pTmp
->aBase
.pMemberName
= nullptr;
610 pTmp
->pAttributeTypeRef
= nullptr;
611 pTmp
->pInterface
= nullptr;
612 pTmp
->pBaseRef
= nullptr;
614 pTmp
->nGetExceptions
= 0;
615 pTmp
->ppGetExceptions
= nullptr;
616 pTmp
->nSetExceptions
= 0;
617 pTmp
->ppSetExceptions
= nullptr;
618 // coverity[leaked_storage] - this is on purpose
624 pRet
= allocTypeDescription
<typelib_TypeDescription
>();
625 #if OSL_DEBUG_LEVEL > 0
626 osl_atomic_increment( &Init().nTypeDescriptionCount
);
631 pRet
->nRefCount
= 1; // reference count is initially 1
632 pRet
->nStaticRefCount
= 0;
633 pRet
->eTypeClass
= eTypeClass
;
634 pRet
->pUniqueIdentifier
= nullptr;
635 pRet
->pReserved
= nullptr;
636 pRet
->pTypeName
= pTypeName
;
637 rtl_uString_acquire( pRet
->pTypeName
);
639 pRet
->bComplete
= true;
641 pRet
->nAlignment
= 0;
642 pRet
->pWeakRef
= nullptr;
643 pRet
->bOnDemand
= false;
650 void newTypeDescription(
651 typelib_TypeDescription
** ppRet
, typelib_TypeClass eTypeClass
,
652 rtl_uString
* pTypeName
, typelib_TypeDescriptionReference
* pType
,
653 sal_Int32 nMembers
, typelib_CompoundMember_Init
* pCompoundMembers
,
654 typelib_StructMember_Init
* pStructMembers
)
657 (pCompoundMembers
== nullptr || pStructMembers
== nullptr)
658 && (pStructMembers
== nullptr || eTypeClass
== typelib_TypeClass_STRUCT
));
659 if (typelib_TypeClass_TYPEDEF
== eTypeClass
)
661 SAL_WARN("cppu.typelib", "unexpected typedef!" );
662 typelib_typedescriptionreference_getDescription( ppRet
, pType
);
666 typelib_typedescription_newEmpty( ppRet
, eTypeClass
, pTypeName
);
670 case typelib_TypeClass_SEQUENCE
:
672 OSL_ASSERT( nMembers
== 0 );
673 typelib_typedescriptionreference_acquire( pType
);
674 reinterpret_cast<typelib_IndirectTypeDescription
*>(*ppRet
)->pType
= pType
;
678 case typelib_TypeClass_EXCEPTION
:
679 case typelib_TypeClass_STRUCT
:
681 // FEATURE_EMPTYCLASS
682 typelib_CompoundTypeDescription
* pTmp
= reinterpret_cast<typelib_CompoundTypeDescription
*>(*ppRet
);
684 sal_Int32 nOffset
= 0;
687 typelib_typedescriptionreference_getDescription(
688 reinterpret_cast<typelib_TypeDescription
**>(&pTmp
->pBaseTypeDescription
), pType
);
689 nOffset
= pTmp
->pBaseTypeDescription
->aBase
.nSize
;
690 OSL_ENSURE( newAlignedSize( 0, pTmp
->pBaseTypeDescription
->aBase
.nSize
, pTmp
->pBaseTypeDescription
->aBase
.nAlignment
) == pTmp
->pBaseTypeDescription
->aBase
.nSize
, "### unexpected offset!" );
694 pTmp
->nMembers
= nMembers
;
695 pTmp
->pMemberOffsets
= new sal_Int32
[ nMembers
];
696 pTmp
->ppTypeRefs
= new typelib_TypeDescriptionReference
*[ nMembers
];
697 pTmp
->ppMemberNames
= new rtl_uString
*[ nMembers
];
698 bool polymorphic
= eTypeClass
== typelib_TypeClass_STRUCT
699 && OUString::unacquired(&pTypeName
).indexOf('<') >= 0;
700 OSL_ASSERT(!polymorphic
|| pStructMembers
!= nullptr);
702 reinterpret_cast< typelib_StructTypeDescription
* >(pTmp
)->
703 pParameterizedTypes
= new sal_Bool
[nMembers
];
705 for( sal_Int32 i
= 0 ; i
< nMembers
; i
++ )
707 // read the type and member names
708 pTmp
->ppTypeRefs
[i
] = nullptr;
709 if (pCompoundMembers
!= nullptr) {
710 typelib_typedescriptionreference_new(
711 pTmp
->ppTypeRefs
+i
, pCompoundMembers
[i
].eTypeClass
,
712 pCompoundMembers
[i
].pTypeName
);
713 pTmp
->ppMemberNames
[i
]
714 = pCompoundMembers
[i
].pMemberName
;
715 rtl_uString_acquire( pTmp
->ppMemberNames
[i
] );
717 typelib_typedescriptionreference_new(
719 pStructMembers
[i
].aBase
.eTypeClass
,
720 pStructMembers
[i
].aBase
.pTypeName
);
721 pTmp
->ppMemberNames
[i
]
722 = pStructMembers
[i
].aBase
.pMemberName
;
723 rtl_uString_acquire(pTmp
->ppMemberNames
[i
]);
728 if (pTmp
->ppTypeRefs
[i
]->eTypeClass
==
729 typelib_TypeClass_SEQUENCE
)
731 // Take care of recursion like
732 // struct S { sequence<S> x; };
733 size
= sizeof(void *);
734 alignment
= adjustAlignment(size
);
736 typelib_TypeDescription
* pTD
= nullptr;
737 TYPELIB_DANGER_GET( &pTD
, pTmp
->ppTypeRefs
[i
] );
738 OSL_ENSURE( pTD
->nSize
, "### void member?" );
740 alignment
= pTD
->nAlignment
;
741 TYPELIB_DANGER_RELEASE( pTD
);
743 nOffset
= newAlignedSize( nOffset
, size
, alignment
);
744 pTmp
->pMemberOffsets
[i
] = nOffset
- size
;
747 reinterpret_cast< typelib_StructTypeDescription
* >(
748 pTmp
)->pParameterizedTypes
[i
]
749 = pStructMembers
[i
].bParameterizedType
;
760 if( !TYPELIB_TYPEDESCRIPTIONREFERENCE_ISREALLYWEAK( eTypeClass
) )
761 (*ppRet
)->pWeakRef
= reinterpret_cast<typelib_TypeDescriptionReference
*>(*ppRet
);
762 if( eTypeClass
!= typelib_TypeClass_VOID
)
764 // sizeof(void) not allowed
765 (*ppRet
)->nSize
= typelib_typedescription_getAlignedUnoSize( (*ppRet
), 0, (*ppRet
)->nAlignment
);
766 (*ppRet
)->nAlignment
= adjustAlignment( (*ppRet
)->nAlignment
);
772 extern "C" void SAL_CALL
typelib_typedescription_new(
773 typelib_TypeDescription
** ppRet
,
774 typelib_TypeClass eTypeClass
,
775 rtl_uString
* pTypeName
,
776 typelib_TypeDescriptionReference
* pType
,
778 typelib_CompoundMember_Init
* pMembers
)
782 ppRet
, eTypeClass
, pTypeName
, pType
, nMembers
, pMembers
, nullptr);
785 extern "C" void SAL_CALL
typelib_typedescription_newStruct(
786 typelib_TypeDescription
** ppRet
,
787 rtl_uString
* pTypeName
,
788 typelib_TypeDescriptionReference
* pType
,
790 typelib_StructMember_Init
* pMembers
)
794 ppRet
, typelib_TypeClass_STRUCT
, pTypeName
, pType
, nMembers
, nullptr,
799 extern "C" void SAL_CALL
typelib_typedescription_newEnum(
800 typelib_TypeDescription
** ppRet
,
801 rtl_uString
* pTypeName
,
802 sal_Int32 nDefaultValue
,
803 sal_Int32 nEnumValues
,
804 rtl_uString
** ppEnumNames
,
805 sal_Int32
* pEnumValues
)
808 typelib_typedescription_newEmpty( ppRet
, typelib_TypeClass_ENUM
, pTypeName
);
809 typelib_EnumTypeDescription
* pEnum
= reinterpret_cast<typelib_EnumTypeDescription
*>(*ppRet
);
811 pEnum
->nDefaultEnumValue
= nDefaultValue
;
812 pEnum
->nEnumValues
= nEnumValues
;
813 pEnum
->ppEnumNames
= new rtl_uString
* [ nEnumValues
];
814 for ( sal_Int32 nPos
= nEnumValues
; nPos
--; )
816 pEnum
->ppEnumNames
[nPos
] = ppEnumNames
[nPos
];
817 rtl_uString_acquire( pEnum
->ppEnumNames
[nPos
] );
819 pEnum
->pEnumValues
= new sal_Int32
[ nEnumValues
];
820 ::memcpy( pEnum
->pEnumValues
, pEnumValues
, nEnumValues
* sizeof(sal_Int32
) );
822 static_assert(!TYPELIB_TYPEDESCRIPTIONREFERENCE_ISREALLYWEAK(typelib_TypeClass_ENUM
));
823 (*ppRet
)->pWeakRef
= reinterpret_cast<typelib_TypeDescriptionReference
*>(*ppRet
);
824 // sizeof(void) not allowed
825 (*ppRet
)->nSize
= typelib_typedescription_getAlignedUnoSize( (*ppRet
), 0, (*ppRet
)->nAlignment
);
826 (*ppRet
)->nAlignment
= adjustAlignment( (*ppRet
)->nAlignment
);
830 extern "C" void SAL_CALL
typelib_typedescription_newInterface(
831 typelib_InterfaceTypeDescription
** ppRet
,
832 rtl_uString
* pTypeName
,
833 SAL_UNUSED_PARAMETER sal_uInt32
, SAL_UNUSED_PARAMETER sal_uInt16
,
834 SAL_UNUSED_PARAMETER sal_uInt16
, SAL_UNUSED_PARAMETER sal_uInt32
,
835 SAL_UNUSED_PARAMETER sal_uInt32
,
836 typelib_TypeDescriptionReference
* pBaseInterface
,
838 typelib_TypeDescriptionReference
** ppMembers
)
841 // coverity[callee_ptr_arith] - not a bug
842 typelib_typedescription_newMIInterface(
843 ppRet
, pTypeName
, 0, 0, 0, 0, 0, pBaseInterface
== nullptr ? 0 : 1,
844 &pBaseInterface
, nMembers
, ppMembers
);
852 sal_Int32 memberOffset
;
853 sal_Int32 directBaseIndex
;
854 sal_Int32 directBaseMemberOffset
;
855 typelib_InterfaceTypeDescription
const * base
;
858 typedef std::vector
< Entry
> List
;
860 explicit BaseList(typelib_InterfaceTypeDescription
const * desc
);
862 List
const & getList() const { return list
; }
864 sal_Int32
getBaseMembers() const { return members
; }
867 typedef std::set
< OUString
> Set
;
871 sal_Int32 directBaseIndex
, Set
& directBaseSet
,
872 sal_Int32
* directBaseMembers
,
873 typelib_InterfaceTypeDescription
const * desc
);
879 BaseList::BaseList(typelib_InterfaceTypeDescription
const * desc
)
883 for (sal_Int32 i
= 0; i
< desc
->nBaseTypes
; ++i
) {
885 sal_Int32 directBaseMembers
= 0;
886 calculate(allSet
, i
, directBaseSet
, &directBaseMembers
, desc
->ppBaseTypes
[i
]);
890 void BaseList::calculate(
892 sal_Int32 directBaseIndex
, Set
& directBaseSet
,
893 sal_Int32
* directBaseMembers
,
894 typelib_InterfaceTypeDescription
const * desc
)
896 for (sal_Int32 i
= 0; i
< desc
->nBaseTypes
; ++i
) {
898 directBaseIndex
, directBaseSet
, directBaseMembers
,
899 desc
->ppBaseTypes
[i
]);
901 if (allSet
.insert(desc
->aBase
.pTypeName
).second
) {
903 e
.memberOffset
= members
;
904 e
.directBaseIndex
= directBaseIndex
;
905 e
.directBaseMemberOffset
= *directBaseMembers
;
908 OSL_ASSERT(desc
->ppAllMembers
!= nullptr);
909 members
+= desc
->nMembers
;
911 if (directBaseSet
.insert(desc
->aBase
.pTypeName
).second
) {
912 OSL_ASSERT(desc
->ppAllMembers
!= nullptr);
913 *directBaseMembers
+= desc
->nMembers
;
919 extern "C" void SAL_CALL
typelib_typedescription_newMIInterface(
920 typelib_InterfaceTypeDescription
** ppRet
,
921 rtl_uString
* pTypeName
,
922 SAL_UNUSED_PARAMETER sal_uInt32
, SAL_UNUSED_PARAMETER sal_uInt16
,
923 SAL_UNUSED_PARAMETER sal_uInt16
, SAL_UNUSED_PARAMETER sal_uInt32
,
924 SAL_UNUSED_PARAMETER sal_uInt32
,
925 sal_Int32 nBaseInterfaces
,
926 typelib_TypeDescriptionReference
** ppBaseInterfaces
,
928 typelib_TypeDescriptionReference
** ppMembers
)
931 if (*ppRet
!= nullptr) {
932 typelib_typedescription_release(&(*ppRet
)->aBase
);
936 typelib_InterfaceTypeDescription
* pITD
= nullptr;
937 typelib_typedescription_newEmpty(
938 reinterpret_cast<typelib_TypeDescription
**>(&pITD
), typelib_TypeClass_INTERFACE
, pTypeName
);
940 pITD
->nBaseTypes
= nBaseInterfaces
;
941 pITD
->ppBaseTypes
= new typelib_InterfaceTypeDescription
*[nBaseInterfaces
];
942 for (sal_Int32 i
= 0; i
< nBaseInterfaces
; ++i
) {
943 pITD
->ppBaseTypes
[i
] = nullptr;
944 typelib_typedescriptionreference_getDescription(
945 reinterpret_cast< typelib_TypeDescription
** >(
946 &pITD
->ppBaseTypes
[i
]),
947 ppBaseInterfaces
[i
]);
948 if (pITD
->ppBaseTypes
[i
] == nullptr
950 reinterpret_cast< typelib_TypeDescription
** >(
951 &pITD
->ppBaseTypes
[i
]),
957 OSL_ASSERT(pITD
->ppBaseTypes
[i
] != nullptr);
959 if (nBaseInterfaces
> 0) {
960 pITD
->pBaseTypeDescription
= pITD
->ppBaseTypes
[0];
963 pITD
->aUik
.m_Data1
= 0;
964 pITD
->aUik
.m_Data2
= 0;
965 pITD
->aUik
.m_Data3
= 0;
966 pITD
->aUik
.m_Data4
= 0;
967 pITD
->aUik
.m_Data5
= 0;
969 BaseList
aBaseList(pITD
);
970 pITD
->nAllMembers
= nMembers
+ aBaseList
.getBaseMembers();
971 pITD
->nMembers
= nMembers
;
973 if( pITD
->nAllMembers
)
975 // at minimum one member exist, allocate the memory
976 pITD
->ppAllMembers
= new typelib_TypeDescriptionReference
*[ pITD
->nAllMembers
];
979 BaseList::List
const & rList
= aBaseList
.getList();
980 for (const auto& rEntry
: rList
)
982 typelib_InterfaceTypeDescription
const * pBase
= rEntry
.base
;
983 typelib_InterfaceTypeDescription
const * pDirectBase
984 = pITD
->ppBaseTypes
[rEntry
.directBaseIndex
];
985 OSL_ASSERT(pBase
->ppAllMembers
!= nullptr);
986 for (sal_Int32 j
= 0; j
< pBase
->nMembers
; ++j
) {
987 typelib_TypeDescriptionReference
const * pDirectBaseMember
988 = pDirectBase
->ppAllMembers
[rEntry
.directBaseMemberOffset
+ j
];
989 OUString aName
= OUString::unacquired(&pDirectBaseMember
->pTypeName
) +
991 OUString::number(rEntry
.directBaseIndex
) +
993 OUString::number(rEntry
.memberOffset
+ j
) +
995 OUString::unacquired(&pITD
->aBase
.pTypeName
);
996 typelib_TypeDescriptionReference
* pDerivedMember
= nullptr;
997 typelib_typedescriptionreference_new(
998 &pDerivedMember
, pDirectBaseMember
->eTypeClass
,
1000 pITD
->ppAllMembers
[n
++] = pDerivedMember
;
1006 pITD
->ppMembers
= pITD
->ppAllMembers
+ aBaseList
.getBaseMembers();
1010 for( sal_Int32 i
= 0; i
< nMembers
; i
++ )
1012 typelib_typedescriptionreference_acquire( ppMembers
[i
] );
1013 pITD
->ppAllMembers
[n
++] = ppMembers
[i
];
1017 typelib_TypeDescription
* pTmp
= &pITD
->aBase
;
1018 static_assert( !TYPELIB_TYPEDESCRIPTIONREFERENCE_ISREALLYWEAK( typelib_TypeClass_INTERFACE
) );
1019 pTmp
->pWeakRef
= reinterpret_cast<typelib_TypeDescriptionReference
*>(pTmp
);
1020 pTmp
->nSize
= typelib_typedescription_getAlignedUnoSize( pTmp
, 0, pTmp
->nAlignment
);
1021 pTmp
->nAlignment
= adjustAlignment( pTmp
->nAlignment
);
1022 pTmp
->bComplete
= false;
1030 typelib_TypeDescriptionReference
** copyExceptions(
1031 sal_Int32 count
, rtl_uString
** typeNames
)
1033 OSL_ASSERT(count
>= 0);
1037 typelib_TypeDescriptionReference
** p
1038 = new typelib_TypeDescriptionReference
*[count
];
1039 for (sal_Int32 i
= 0; i
< count
; ++i
) {
1041 typelib_typedescriptionreference_new(
1042 p
+ i
, typelib_TypeClass_EXCEPTION
, typeNames
[i
]);
1049 extern "C" void SAL_CALL
typelib_typedescription_newInterfaceMethod(
1050 typelib_InterfaceMethodTypeDescription
** ppRet
,
1051 sal_Int32 nAbsolutePosition
,
1053 rtl_uString
* pTypeName
,
1054 typelib_TypeClass eReturnTypeClass
,
1055 rtl_uString
* pReturnTypeName
,
1057 typelib_Parameter_Init
* pParams
,
1058 sal_Int32 nExceptions
,
1059 rtl_uString
** ppExceptionNames
)
1060 SAL_THROW_EXTERN_C()
1062 if (*ppRet
!= nullptr) {
1063 typelib_typedescription_release(&(*ppRet
)->aBase
.aBase
);
1066 sal_Int32 nOffset
= rtl_ustr_lastIndexOfChar_WithLength(
1067 pTypeName
->buffer
, pTypeName
->length
, ':');
1068 if (nOffset
<= 0 || pTypeName
->buffer
[nOffset
- 1] != ':') {
1069 OSL_FAIL("Bad interface method type name");
1072 OUString
aInterfaceTypeName(pTypeName
->buffer
, nOffset
- 1);
1073 typelib_InterfaceTypeDescription
* pInterface
= nullptr;
1074 typelib_typedescription_getByName(
1075 reinterpret_cast< typelib_TypeDescription
** >(&pInterface
),
1076 aInterfaceTypeName
.pData
);
1077 if (pInterface
== nullptr
1078 || pInterface
->aBase
.eTypeClass
!= typelib_TypeClass_INTERFACE
1080 reinterpret_cast< typelib_TypeDescription
** >(&pInterface
), false))
1082 OSL_FAIL("No interface corresponding to interface method");
1086 typelib_typedescription_newEmpty(
1087 reinterpret_cast<typelib_TypeDescription
**>(ppRet
), typelib_TypeClass_INTERFACE_METHOD
, pTypeName
);
1089 rtl_uString_newFromStr_WithLength( &(*ppRet
)->aBase
.pMemberName
,
1090 pTypeName
->buffer
+ nOffset
+1,
1091 pTypeName
->length
- nOffset
-1 );
1092 (*ppRet
)->aBase
.nPosition
= nAbsolutePosition
;
1093 (*ppRet
)->bOneWay
= bOneWay
;
1094 typelib_typedescriptionreference_new( &(*ppRet
)->pReturnTypeRef
, eReturnTypeClass
, pReturnTypeName
);
1095 (*ppRet
)->nParams
= nParams
;
1098 (*ppRet
)->pParams
= new typelib_MethodParameter
[ nParams
];
1100 for( sal_Int32 i
= 0; i
< nParams
; i
++ )
1102 // get the name of the parameter
1103 (*ppRet
)->pParams
[ i
].pName
= pParams
[i
].pParamName
;
1104 rtl_uString_acquire( (*ppRet
)->pParams
[ i
].pName
);
1105 (*ppRet
)->pParams
[ i
].pTypeRef
= nullptr;
1106 // get the type name of the parameter and create the weak reference
1107 typelib_typedescriptionreference_new(
1108 &(*ppRet
)->pParams
[ i
].pTypeRef
, pParams
[i
].eTypeClass
, pParams
[i
].pTypeName
);
1109 (*ppRet
)->pParams
[ i
].bIn
= pParams
[i
].bIn
;
1110 (*ppRet
)->pParams
[ i
].bOut
= pParams
[i
].bOut
;
1113 (*ppRet
)->nExceptions
= nExceptions
;
1114 (*ppRet
)->ppExceptions
= copyExceptions(nExceptions
, ppExceptionNames
);
1115 (*ppRet
)->pInterface
= pInterface
;
1116 (*ppRet
)->pBaseRef
= nullptr;
1118 (nAbsolutePosition
>= pInterface
->nAllMembers
- pInterface
->nMembers
)
1119 && nAbsolutePosition
< pInterface
->nAllMembers
);
1120 (*ppRet
)->nIndex
= nAbsolutePosition
1121 - (pInterface
->nAllMembers
- pInterface
->nMembers
);
1122 static_assert( TYPELIB_TYPEDESCRIPTIONREFERENCE_ISREALLYWEAK( typelib_TypeClass_INTERFACE_METHOD
) );
1123 assert(reinterpret_cast<typelib_TypeDescription
*>(*ppRet
)->pWeakRef
== nullptr);
1127 extern "C" void SAL_CALL
typelib_typedescription_newInterfaceAttribute(
1128 typelib_InterfaceAttributeTypeDescription
** ppRet
,
1129 sal_Int32 nAbsolutePosition
,
1130 rtl_uString
* pTypeName
,
1131 typelib_TypeClass eAttributeTypeClass
,
1132 rtl_uString
* pAttributeTypeName
,
1133 sal_Bool bReadOnly
)
1134 SAL_THROW_EXTERN_C()
1136 typelib_typedescription_newExtendedInterfaceAttribute(
1137 ppRet
, nAbsolutePosition
, pTypeName
, eAttributeTypeClass
,
1138 pAttributeTypeName
, bReadOnly
, 0, nullptr, 0, nullptr);
1142 extern "C" void SAL_CALL
typelib_typedescription_newExtendedInterfaceAttribute(
1143 typelib_InterfaceAttributeTypeDescription
** ppRet
,
1144 sal_Int32 nAbsolutePosition
,
1145 rtl_uString
* pTypeName
,
1146 typelib_TypeClass eAttributeTypeClass
,
1147 rtl_uString
* pAttributeTypeName
,
1149 sal_Int32 nGetExceptions
, rtl_uString
** ppGetExceptionNames
,
1150 sal_Int32 nSetExceptions
, rtl_uString
** ppSetExceptionNames
)
1151 SAL_THROW_EXTERN_C()
1153 if (*ppRet
!= nullptr) {
1154 typelib_typedescription_release(&(*ppRet
)->aBase
.aBase
);
1157 sal_Int32 nOffset
= rtl_ustr_lastIndexOfChar_WithLength(
1158 pTypeName
->buffer
, pTypeName
->length
, ':');
1159 if (nOffset
<= 0 || pTypeName
->buffer
[nOffset
- 1] != ':') {
1160 OSL_FAIL("Bad interface attribute type name");
1163 OUString
aInterfaceTypeName(pTypeName
->buffer
, nOffset
- 1);
1164 typelib_InterfaceTypeDescription
* pInterface
= nullptr;
1165 typelib_typedescription_getByName(
1166 reinterpret_cast< typelib_TypeDescription
** >(&pInterface
),
1167 aInterfaceTypeName
.pData
);
1168 if (pInterface
== nullptr
1169 || pInterface
->aBase
.eTypeClass
!= typelib_TypeClass_INTERFACE
1171 reinterpret_cast< typelib_TypeDescription
** >(&pInterface
), false))
1173 OSL_FAIL("No interface corresponding to interface attribute");
1177 typelib_typedescription_newEmpty(
1178 reinterpret_cast<typelib_TypeDescription
**>(ppRet
), typelib_TypeClass_INTERFACE_ATTRIBUTE
, pTypeName
);
1180 rtl_uString_newFromStr_WithLength( &(*ppRet
)->aBase
.pMemberName
,
1181 pTypeName
->buffer
+ nOffset
+1,
1182 pTypeName
->length
- nOffset
-1 );
1183 (*ppRet
)->aBase
.nPosition
= nAbsolutePosition
;
1184 typelib_typedescriptionreference_new( &(*ppRet
)->pAttributeTypeRef
, eAttributeTypeClass
, pAttributeTypeName
);
1185 (*ppRet
)->bReadOnly
= bReadOnly
;
1186 (*ppRet
)->pInterface
= pInterface
;
1187 (*ppRet
)->pBaseRef
= nullptr;
1189 (nAbsolutePosition
>= pInterface
->nAllMembers
- pInterface
->nMembers
)
1190 && nAbsolutePosition
< pInterface
->nAllMembers
);
1191 (*ppRet
)->nIndex
= nAbsolutePosition
1192 - (pInterface
->nAllMembers
- pInterface
->nMembers
);
1193 (*ppRet
)->nGetExceptions
= nGetExceptions
;
1194 (*ppRet
)->ppGetExceptions
= copyExceptions(
1195 nGetExceptions
, ppGetExceptionNames
);
1196 (*ppRet
)->nSetExceptions
= nSetExceptions
;
1197 (*ppRet
)->ppSetExceptions
= copyExceptions(
1198 nSetExceptions
, ppSetExceptionNames
);
1199 static_assert( TYPELIB_TYPEDESCRIPTIONREFERENCE_ISREALLYWEAK( typelib_TypeClass_INTERFACE_ATTRIBUTE
) );
1200 assert(reinterpret_cast<typelib_TypeDescription
*>(*ppRet
)->pWeakRef
== nullptr);
1204 extern "C" void SAL_CALL
typelib_typedescription_acquire(
1205 typelib_TypeDescription
* pTypeDescription
)
1206 SAL_THROW_EXTERN_C()
1208 osl_atomic_increment( &pTypeDescription
->nRefCount
);
1214 void deleteExceptions(
1215 sal_Int32 count
, typelib_TypeDescriptionReference
** exceptions
)
1217 for (sal_Int32 i
= 0; i
< count
; ++i
) {
1218 typelib_typedescriptionreference_release(exceptions
[i
]);
1220 delete[] exceptions
;
1225 // frees anything except typelib_TypeDescription base!
1226 static void typelib_typedescription_destructExtendedMembers(
1227 typelib_TypeDescription
* pTD
)
1229 OSL_ASSERT( typelib_TypeClass_TYPEDEF
!= pTD
->eTypeClass
);
1231 switch( pTD
->eTypeClass
)
1233 case typelib_TypeClass_SEQUENCE
:
1234 if( reinterpret_cast<typelib_IndirectTypeDescription
*>(pTD
)->pType
)
1235 typelib_typedescriptionreference_release( reinterpret_cast<typelib_IndirectTypeDescription
*>(pTD
)->pType
);
1237 case typelib_TypeClass_STRUCT
:
1238 delete[] reinterpret_cast< typelib_StructTypeDescription
* >(pTD
)->
1239 pParameterizedTypes
;
1241 case typelib_TypeClass_EXCEPTION
:
1243 typelib_CompoundTypeDescription
* pCTD
= reinterpret_cast<typelib_CompoundTypeDescription
*>(pTD
);
1244 if( pCTD
->pBaseTypeDescription
)
1245 typelib_typedescription_release( &pCTD
->pBaseTypeDescription
->aBase
);
1247 for( i
= 0; i
< pCTD
->nMembers
; i
++ )
1249 typelib_typedescriptionreference_release( pCTD
->ppTypeRefs
[i
] );
1251 if (pCTD
->ppMemberNames
)
1253 for ( i
= 0; i
< pCTD
->nMembers
; i
++ )
1255 rtl_uString_release( pCTD
->ppMemberNames
[i
] );
1257 delete [] pCTD
->ppMemberNames
;
1259 delete [] pCTD
->ppTypeRefs
;
1260 delete [] pCTD
->pMemberOffsets
;
1263 case typelib_TypeClass_INTERFACE
:
1265 typelib_InterfaceTypeDescription
* pITD
= reinterpret_cast<typelib_InterfaceTypeDescription
*>(pTD
);
1266 for( sal_Int32 i
= 0; i
< pITD
->nAllMembers
; i
++ )
1268 typelib_typedescriptionreference_release( pITD
->ppAllMembers
[i
] );
1270 delete [] pITD
->ppAllMembers
;
1271 delete [] pITD
->pMapMemberIndexToFunctionIndex
;
1272 delete [] pITD
->pMapFunctionIndexToMemberIndex
;
1273 for (sal_Int32 i
= 0; i
< pITD
->nBaseTypes
; ++i
) {
1274 typelib_typedescription_release(
1275 reinterpret_cast< typelib_TypeDescription
* >(
1276 pITD
->ppBaseTypes
[i
]));
1278 delete[] pITD
->ppBaseTypes
;
1281 case typelib_TypeClass_INTERFACE_METHOD
:
1283 typelib_InterfaceMethodTypeDescription
* pIMTD
= reinterpret_cast<typelib_InterfaceMethodTypeDescription
*>(pTD
);
1284 if( pIMTD
->pReturnTypeRef
)
1285 typelib_typedescriptionreference_release( pIMTD
->pReturnTypeRef
);
1286 for( sal_Int32 i
= 0; i
< pIMTD
->nParams
; i
++ )
1288 rtl_uString_release( pIMTD
->pParams
[ i
].pName
);
1289 typelib_typedescriptionreference_release( pIMTD
->pParams
[ i
].pTypeRef
);
1291 delete [] pIMTD
->pParams
;
1292 deleteExceptions(pIMTD
->nExceptions
, pIMTD
->ppExceptions
);
1293 rtl_uString_release( pIMTD
->aBase
.pMemberName
);
1294 typelib_typedescription_release(&pIMTD
->pInterface
->aBase
);
1295 if (pIMTD
->pBaseRef
!= nullptr) {
1296 typelib_typedescriptionreference_release(pIMTD
->pBaseRef
);
1300 case typelib_TypeClass_INTERFACE_ATTRIBUTE
:
1302 typelib_InterfaceAttributeTypeDescription
* pIATD
= reinterpret_cast<typelib_InterfaceAttributeTypeDescription
*>(pTD
);
1303 deleteExceptions(pIATD
->nGetExceptions
, pIATD
->ppGetExceptions
);
1304 deleteExceptions(pIATD
->nSetExceptions
, pIATD
->ppSetExceptions
);
1305 if( pIATD
->pAttributeTypeRef
)
1306 typelib_typedescriptionreference_release( pIATD
->pAttributeTypeRef
);
1307 if( pIATD
->aBase
.pMemberName
)
1308 rtl_uString_release( pIATD
->aBase
.pMemberName
);
1309 typelib_typedescription_release(&pIATD
->pInterface
->aBase
);
1310 if (pIATD
->pBaseRef
!= nullptr) {
1311 typelib_typedescriptionreference_release(pIATD
->pBaseRef
);
1315 case typelib_TypeClass_ENUM
:
1317 typelib_EnumTypeDescription
* pEnum
= reinterpret_cast<typelib_EnumTypeDescription
*>(pTD
);
1318 for ( sal_Int32 nPos
= pEnum
->nEnumValues
; nPos
--; )
1320 rtl_uString_release( pEnum
->ppEnumNames
[nPos
] );
1322 delete [] pEnum
->ppEnumNames
;
1323 delete [] pEnum
->pEnumValues
;
1332 extern "C" void SAL_CALL
typelib_typedescription_release(
1333 typelib_TypeDescription
* pTD
)
1334 SAL_THROW_EXTERN_C()
1336 sal_Int32 ref
= osl_atomic_decrement( &pTD
->nRefCount
);
1337 OSL_ASSERT(ref
>= 0);
1341 TypeDescriptor_Init_Impl
&rInit
= Init();
1342 if( TYPELIB_TYPEDESCRIPTIONREFERENCE_ISREALLYWEAK( pTD
->eTypeClass
) )
1347 MutexGuard
aGuard( rInit
.maMutex
);
1348 // remove this description from the weak reference
1349 pTD
->pWeakRef
->pType
= nullptr;
1351 typelib_typedescriptionreference_release( pTD
->pWeakRef
);
1356 // this description is a reference too, so remove it from the hash table
1357 MutexGuard
aGuard( rInit
.maMutex
);
1358 WeakMap_Impl::iterator aIt
= rInit
.maWeakMap
.find( pTD
->pTypeName
->buffer
);
1359 if( aIt
!= rInit
.maWeakMap
.end() && static_cast<void *>((*aIt
).second
) == static_cast<void *>(pTD
) )
1361 // remove only if it contains the same object
1362 rInit
.maWeakMap
.erase( aIt
);
1366 typelib_typedescription_destructExtendedMembers( pTD
);
1367 rtl_uString_release( pTD
->pTypeName
);
1369 #if OSL_DEBUG_LEVEL > 0
1370 switch( pTD
->eTypeClass
)
1372 case typelib_TypeClass_SEQUENCE
:
1373 osl_atomic_decrement( &rInit
.nIndirectTypeDescriptionCount
);
1375 case typelib_TypeClass_STRUCT
:
1376 case typelib_TypeClass_EXCEPTION
:
1377 osl_atomic_decrement( &rInit
.nCompoundTypeDescriptionCount
);
1379 case typelib_TypeClass_INTERFACE
:
1380 osl_atomic_decrement( &rInit
.nInterfaceTypeDescriptionCount
);
1382 case typelib_TypeClass_INTERFACE_METHOD
:
1383 osl_atomic_decrement( &rInit
.nInterfaceMethodTypeDescriptionCount
);
1385 case typelib_TypeClass_INTERFACE_ATTRIBUTE
:
1386 osl_atomic_decrement( &rInit
.nInterfaceAttributeTypeDescriptionCount
);
1388 case typelib_TypeClass_ENUM
:
1389 osl_atomic_decrement( &rInit
.nEnumTypeDescriptionCount
);
1392 osl_atomic_decrement( &rInit
.nTypeDescriptionCount
);
1396 freeTypeDescription(pTD
);
1400 extern "C" void SAL_CALL
typelib_typedescription_register(
1401 typelib_TypeDescription
** ppNewDescription
)
1402 SAL_THROW_EXTERN_C()
1404 // connect the description with the weak reference
1405 TypeDescriptor_Init_Impl
&rInit
= Init();
1406 ClearableMutexGuard
aGuard( rInit
.maMutex
);
1408 typelib_TypeDescriptionReference
* pTDR
= nullptr;
1409 typelib_typedescriptionreference_getByName( &pTDR
, (*ppNewDescription
)->pTypeName
);
1411 OSL_ASSERT( (*ppNewDescription
)->pWeakRef
|| TYPELIB_TYPEDESCRIPTIONREFERENCE_ISREALLYWEAK( (*ppNewDescription
)->eTypeClass
) );
1414 OSL_ASSERT( (*ppNewDescription
)->eTypeClass
== pTDR
->eTypeClass
);
1417 if (TYPELIB_TYPEDESCRIPTIONREFERENCE_ISREALLYWEAK( pTDR
->eTypeClass
))
1419 // pRef->pType->pWeakRef == 0 means that the description is empty
1420 if (pTDR
->pType
->pWeakRef
)
1422 if (osl_atomic_increment( &pTDR
->pType
->nRefCount
) > 1)
1424 // The reference is incremented. The object cannot be destroyed.
1425 // Release the guard at the earliest point.
1427 ::typelib_typedescription_release( *ppNewDescription
);
1428 *ppNewDescription
= pTDR
->pType
;
1429 ::typelib_typedescriptionreference_release( pTDR
);
1432 // destruction of this type in progress (another thread!)
1433 (void)osl_atomic_decrement( &pTDR
->pType
->nRefCount
);
1436 pTDR
->pType
= *ppNewDescription
;
1437 OSL_ASSERT( ! (*ppNewDescription
)->pWeakRef
);
1438 (*ppNewDescription
)->pWeakRef
= pTDR
;
1443 if ((static_cast<void *>(pTDR
) != static_cast<void *>(*ppNewDescription
)) && // if different
1444 (!pTDR
->pType
->pWeakRef
|| // uninit: ref data only set
1445 // new one is complete:
1446 (!pTDR
->pType
->bComplete
&& (*ppNewDescription
)->bComplete
) ||
1447 // new one may be partly initialized interface (except of tables):
1448 (typelib_TypeClass_INTERFACE
== pTDR
->pType
->eTypeClass
&&
1449 !reinterpret_cast<typelib_InterfaceTypeDescription
*>(pTDR
->pType
)->ppAllMembers
&&
1450 (*reinterpret_cast<typelib_InterfaceTypeDescription
**>(ppNewDescription
))->ppAllMembers
)))
1452 // uninitialized or incomplete
1454 if (pTDR
->pType
->pWeakRef
) // if init
1456 switch (pTDR
->pType
->eTypeClass
) {
1457 case typelib_TypeClass_ENUM
:
1459 auto const src
= reinterpret_cast<typelib_EnumTypeDescription
*>(
1461 auto const dst
= reinterpret_cast<typelib_EnumTypeDescription
*>(
1463 assert(dst
->nEnumValues
== 0);
1464 assert(dst
->ppEnumNames
== nullptr);
1465 assert(dst
->pEnumValues
== nullptr);
1466 std::swap(src
->nEnumValues
, dst
->nEnumValues
);
1467 std::swap(src
->ppEnumNames
, dst
->ppEnumNames
);
1468 std::swap(src
->pEnumValues
, dst
->pEnumValues
);
1471 case typelib_TypeClass_STRUCT
:
1472 case typelib_TypeClass_EXCEPTION
:
1474 auto const src
= reinterpret_cast<typelib_CompoundTypeDescription
*>(
1476 auto const dst
= reinterpret_cast<typelib_CompoundTypeDescription
*>(
1479 (dst
->pBaseTypeDescription
== nullptr)
1480 == (src
->pBaseTypeDescription
== nullptr));
1481 assert(dst
->nMembers
== src
->nMembers
);
1482 assert((dst
->pMemberOffsets
== nullptr) == (dst
->nMembers
== 0));
1483 assert((dst
->ppTypeRefs
== nullptr) == (dst
->nMembers
== 0));
1484 assert(dst
->ppMemberNames
== nullptr);
1486 pTDR
->pType
->eTypeClass
!= typelib_TypeClass_STRUCT
1487 || ((reinterpret_cast<typelib_StructTypeDescription
*>(
1488 dst
)->pParameterizedTypes
1490 == (reinterpret_cast<typelib_StructTypeDescription
*>(
1491 src
)->pParameterizedTypes
1493 std::swap(src
->ppMemberNames
, dst
->ppMemberNames
);
1496 case typelib_TypeClass_INTERFACE
:
1498 auto const src
= reinterpret_cast<typelib_InterfaceTypeDescription
*>(
1500 auto const dst
= reinterpret_cast<typelib_InterfaceTypeDescription
*>(
1503 (dst
->pBaseTypeDescription
== nullptr)
1504 == (src
->pBaseTypeDescription
== nullptr));
1505 assert(dst
->nMembers
== 0);
1506 assert(dst
->ppMembers
== nullptr);
1507 assert(dst
->nAllMembers
== 0);
1508 assert(dst
->ppAllMembers
== nullptr);
1509 assert(dst
->pMapMemberIndexToFunctionIndex
== nullptr);
1510 assert(dst
->nMapFunctionIndexToMemberIndex
== 0);
1511 assert(dst
->pMapFunctionIndexToMemberIndex
== nullptr);
1512 assert(dst
->nBaseTypes
== src
->nBaseTypes
);
1513 assert((dst
->ppBaseTypes
== nullptr) == (src
->ppBaseTypes
== nullptr));
1514 std::swap(src
->nMembers
, dst
->nMembers
);
1515 std::swap(src
->ppMembers
, dst
->ppMembers
);
1516 std::swap(src
->nAllMembers
, dst
->nAllMembers
);
1517 std::swap(src
->ppAllMembers
, dst
->ppAllMembers
);
1519 src
->pMapMemberIndexToFunctionIndex
,
1520 dst
->pMapMemberIndexToFunctionIndex
);
1522 src
->nMapFunctionIndexToMemberIndex
,
1523 dst
->nMapFunctionIndexToMemberIndex
);
1525 src
->pMapFunctionIndexToMemberIndex
,
1526 dst
->pMapFunctionIndexToMemberIndex
);
1530 assert(false); // this cannot happen
1535 // pTDR->pType->pWeakRef == 0 means that the description is empty
1536 // description is not weak and the not the same
1537 sal_Int32 nSize
= getDescriptionSize( (*ppNewDescription
)->eTypeClass
);
1539 // copy all specific data for the descriptions
1542 *ppNewDescription
+1,
1543 nSize
- sizeof(typelib_TypeDescription
) );
1546 *ppNewDescription
+1,
1548 nSize
- sizeof( typelib_TypeDescription
) );
1551 pTDR
->pType
->bComplete
= (*ppNewDescription
)->bComplete
;
1552 pTDR
->pType
->nSize
= (*ppNewDescription
)->nSize
;
1553 pTDR
->pType
->nAlignment
= (*ppNewDescription
)->nAlignment
;
1555 if( pTDR
->pType
->bOnDemand
&& !(*ppNewDescription
)->bOnDemand
)
1557 // switch from OnDemand to !OnDemand, so the description must be acquired
1558 typelib_typedescription_acquire( pTDR
->pType
);
1560 else if( !pTDR
->pType
->bOnDemand
&& (*ppNewDescription
)->bOnDemand
)
1562 // switch from !OnDemand to OnDemand, so the description must be released
1563 assert(pTDR
->pType
->nRefCount
> 1);
1564 // coverity[freed_arg] - pType's nRefCount is > 1 here
1565 typelib_typedescription_release( pTDR
->pType
);
1568 pTDR
->pType
->bOnDemand
= (*ppNewDescription
)->bOnDemand
;
1570 pTDR
->pType
->pWeakRef
= pTDR
;
1573 typelib_typedescription_release( *ppNewDescription
);
1574 // pTDR was acquired by getByName(), so it must not be acquired again
1575 *ppNewDescription
= pTDR
->pType
;
1579 else if( TYPELIB_TYPEDESCRIPTIONREFERENCE_ISREALLYWEAK( (*ppNewDescription
)->eTypeClass
) )
1581 typelib_typedescriptionreference_new(
1582 &pTDR
, (*ppNewDescription
)->eTypeClass
, (*ppNewDescription
)->pTypeName
);
1586 pTDR
= reinterpret_cast<typelib_TypeDescriptionReference
*>(*ppNewDescription
);
1588 // description is the weak itself, so register it
1589 rInit
.maWeakMap
[pTDR
->pTypeName
->buffer
] = pTDR
;
1590 OSL_ASSERT( static_cast<void *>(*ppNewDescription
) == static_cast<void *>(pTDR
) );
1593 // By default this reference is not really weak. The reference hold the description
1594 // and the description hold the reference.
1595 if( !(*ppNewDescription
)->bOnDemand
)
1597 // nor OnDemand so the description must be acquired if registered
1598 typelib_typedescription_acquire( *ppNewDescription
);
1601 pTDR
->pType
= *ppNewDescription
;
1602 (*ppNewDescription
)->pWeakRef
= pTDR
;
1603 OSL_ASSERT( rtl_ustr_compare( pTDR
->pTypeName
->buffer
, (*ppNewDescription
)->pTypeName
->buffer
) == 0 );
1604 OSL_ASSERT( pTDR
->eTypeClass
== (*ppNewDescription
)->eTypeClass
);
1608 static bool type_equals(
1609 typelib_TypeDescriptionReference
const * p1
, typelib_TypeDescriptionReference
const * p2
)
1612 (p1
->eTypeClass
== p2
->eTypeClass
&&
1613 p1
->pTypeName
->length
== p2
->pTypeName
->length
&&
1614 rtl_ustr_compare( p1
->pTypeName
->buffer
, p2
->pTypeName
->buffer
) == 0));
1616 extern "C" sal_Bool SAL_CALL
typelib_typedescription_equals(
1617 const typelib_TypeDescription
* p1
, const typelib_TypeDescription
* p2
)
1618 SAL_THROW_EXTERN_C()
1621 reinterpret_cast<typelib_TypeDescriptionReference
const *>(p1
), reinterpret_cast<typelib_TypeDescriptionReference
const *>(p2
) );
1625 extern "C" sal_Int32
typelib_typedescription_getAlignedUnoSize(
1626 const typelib_TypeDescription
* pTypeDescription
,
1627 sal_Int32 nOffset
, sal_Int32
& rMaxIntegralTypeSize
)
1628 SAL_THROW_EXTERN_C()
1631 if( pTypeDescription
->nSize
)
1633 // size and alignment are set
1634 rMaxIntegralTypeSize
= pTypeDescription
->nAlignment
;
1635 nSize
= pTypeDescription
->nSize
;
1640 rMaxIntegralTypeSize
= 1;
1642 OSL_ASSERT( typelib_TypeClass_TYPEDEF
!= pTypeDescription
->eTypeClass
);
1644 switch( pTypeDescription
->eTypeClass
)
1646 case typelib_TypeClass_INTERFACE
:
1647 // FEATURE_INTERFACE
1648 nSize
= rMaxIntegralTypeSize
= sal_Int32(sizeof( void * ));
1650 case typelib_TypeClass_ENUM
:
1651 nSize
= rMaxIntegralTypeSize
= sal_Int32(sizeof( typelib_TypeClass
));
1653 case typelib_TypeClass_STRUCT
:
1654 case typelib_TypeClass_EXCEPTION
:
1655 // FEATURE_EMPTYCLASS
1657 typelib_CompoundTypeDescription
const * pTmp
= reinterpret_cast<typelib_CompoundTypeDescription
const *>(pTypeDescription
);
1658 sal_Int32 nStructSize
= 0;
1659 if( pTmp
->pBaseTypeDescription
)
1661 // inherit structs extends the base struct.
1662 nStructSize
= pTmp
->pBaseTypeDescription
->aBase
.nSize
;
1663 rMaxIntegralTypeSize
= pTmp
->pBaseTypeDescription
->aBase
.nAlignment
;
1665 for( sal_Int32 i
= 0; i
< pTmp
->nMembers
; i
++ )
1667 typelib_TypeDescription
* pMemberType
= nullptr;
1668 typelib_TypeDescriptionReference
* pMemberRef
= pTmp
->ppTypeRefs
[i
];
1670 sal_Int32 nMaxIntegral
;
1671 if (pMemberRef
->eTypeClass
== typelib_TypeClass_INTERFACE
1672 || pMemberRef
->eTypeClass
== typelib_TypeClass_SEQUENCE
)
1674 nMaxIntegral
= sal_Int32(sizeof(void *));
1675 nStructSize
= newAlignedSize( nStructSize
, nMaxIntegral
, nMaxIntegral
);
1679 TYPELIB_DANGER_GET( &pMemberType
, pMemberRef
);
1680 nStructSize
= typelib_typedescription_getAlignedUnoSize(
1681 pMemberType
, nStructSize
, nMaxIntegral
);
1682 TYPELIB_DANGER_RELEASE( pMemberType
);
1684 if( nMaxIntegral
> rMaxIntegralTypeSize
)
1685 rMaxIntegralTypeSize
= nMaxIntegral
;
1688 // Anything that is at least 16 bits wide is aligned on a 16-bit
1689 // boundary on the m68k default abi
1690 sal_Int32 nMaxAlign
= std::min(rMaxIntegralTypeSize
, sal_Int32( 2 ));
1691 nStructSize
= (nStructSize
+ nMaxAlign
-1) / nMaxAlign
* nMaxAlign
;
1693 // Example: A { double; int; } structure has a size of 16 instead of 10. The
1694 // compiler must follow this rule if it is possible to access members in arrays through:
1695 // (Element *)((char *)pArray + sizeof( Element ) * ElementPos)
1696 nStructSize
= (nStructSize
+ rMaxIntegralTypeSize
-1)
1697 / rMaxIntegralTypeSize
* rMaxIntegralTypeSize
;
1699 nSize
+= nStructSize
;
1702 case typelib_TypeClass_SEQUENCE
:
1703 nSize
= rMaxIntegralTypeSize
= sal_Int32(sizeof( void * ));
1705 case typelib_TypeClass_ANY
:
1707 nSize
= sal_Int32(sizeof( uno_Any
));
1708 rMaxIntegralTypeSize
= sal_Int32(sizeof( void * ));
1710 case typelib_TypeClass_TYPE
:
1711 nSize
= rMaxIntegralTypeSize
= sal_Int32(sizeof( typelib_TypeDescriptionReference
* ));
1713 case typelib_TypeClass_BOOLEAN
:
1714 nSize
= rMaxIntegralTypeSize
= sal_Int32(sizeof( sal_Bool
));
1716 case typelib_TypeClass_CHAR
:
1717 nSize
= rMaxIntegralTypeSize
= sal_Int32(sizeof( sal_Unicode
));
1719 case typelib_TypeClass_STRING
:
1721 nSize
= rMaxIntegralTypeSize
= sal_Int32(sizeof( rtl_uString
* ));
1723 case typelib_TypeClass_FLOAT
:
1724 nSize
= rMaxIntegralTypeSize
= sal_Int32(sizeof( float ));
1726 case typelib_TypeClass_DOUBLE
:
1728 //See previous AIX ifdef comment for an explanation
1729 nSize
= (sal_Int32
)(sizeof(double));
1730 rMaxIntegralTypeSize
= (sal_Int32
)(sizeof(void*));
1732 nSize
= rMaxIntegralTypeSize
= sal_Int32(sizeof( double ));
1735 case typelib_TypeClass_BYTE
:
1736 nSize
= rMaxIntegralTypeSize
= sal_Int32(sizeof( sal_Int8
));
1738 case typelib_TypeClass_SHORT
:
1739 case typelib_TypeClass_UNSIGNED_SHORT
:
1740 nSize
= rMaxIntegralTypeSize
= sal_Int32(sizeof( sal_Int16
));
1742 case typelib_TypeClass_LONG
:
1743 case typelib_TypeClass_UNSIGNED_LONG
:
1744 nSize
= rMaxIntegralTypeSize
= sal_Int32(sizeof( sal_Int32
));
1746 case typelib_TypeClass_HYPER
:
1747 case typelib_TypeClass_UNSIGNED_HYPER
:
1748 nSize
= rMaxIntegralTypeSize
= sal_Int32(sizeof( sal_Int64
));
1750 case typelib_TypeClass_UNKNOWN
:
1751 case typelib_TypeClass_SERVICE
:
1752 case typelib_TypeClass_MODULE
:
1754 OSL_FAIL( "not convertible type" );
1758 return newAlignedSize( nOffset
, nSize
, rMaxIntegralTypeSize
);
1764 typelib_TypeDescriptionReference
** copyExceptions(
1765 sal_Int32 count
, typelib_TypeDescriptionReference
** source
)
1767 typelib_TypeDescriptionReference
** p
1768 = new typelib_TypeDescriptionReference
*[count
];
1769 for (sal_Int32 i
= 0; i
< count
; ++i
) {
1771 typelib_typedescriptionreference_acquire(p
[i
]);
1776 bool createDerivedInterfaceMemberDescription(
1777 typelib_TypeDescription
** result
, OUString
const & name
,
1778 typelib_TypeDescriptionReference
* baseRef
,
1779 typelib_TypeDescription
const * base
, typelib_TypeDescription
* interface
,
1780 sal_Int32 index
, sal_Int32 position
)
1782 if (baseRef
!= nullptr && base
!= nullptr && interface
!= nullptr) {
1783 switch (base
->eTypeClass
) {
1784 case typelib_TypeClass_INTERFACE_METHOD
:
1786 typelib_typedescription_newEmpty(
1787 result
, typelib_TypeClass_INTERFACE_METHOD
, name
.pData
);
1788 typelib_InterfaceMethodTypeDescription
const * baseMethod
1790 typelib_InterfaceMethodTypeDescription
const * >(base
);
1791 typelib_InterfaceMethodTypeDescription
* newMethod
1793 typelib_InterfaceMethodTypeDescription
* >(*result
);
1794 newMethod
->aBase
.nPosition
= position
;
1795 newMethod
->aBase
.pMemberName
1796 = baseMethod
->aBase
.pMemberName
;
1797 rtl_uString_acquire(
1798 newMethod
->aBase
.pMemberName
);
1799 newMethod
->pReturnTypeRef
= baseMethod
->pReturnTypeRef
;
1800 typelib_typedescriptionreference_acquire(
1801 newMethod
->pReturnTypeRef
);
1802 newMethod
->nParams
= baseMethod
->nParams
;
1803 newMethod
->pParams
= new typelib_MethodParameter
[
1804 newMethod
->nParams
];
1805 for (sal_Int32 i
= 0; i
< newMethod
->nParams
; ++i
) {
1806 newMethod
->pParams
[i
].pName
1807 = baseMethod
->pParams
[i
].pName
;
1808 rtl_uString_acquire(
1809 newMethod
->pParams
[i
].pName
);
1810 newMethod
->pParams
[i
].pTypeRef
1811 = baseMethod
->pParams
[i
].pTypeRef
;
1812 typelib_typedescriptionreference_acquire(
1813 newMethod
->pParams
[i
].pTypeRef
);
1814 newMethod
->pParams
[i
].bIn
= baseMethod
->pParams
[i
].bIn
;
1815 newMethod
->pParams
[i
].bOut
= baseMethod
->pParams
[i
].bOut
;
1817 newMethod
->nExceptions
= baseMethod
->nExceptions
;
1818 newMethod
->ppExceptions
= copyExceptions(
1819 baseMethod
->nExceptions
, baseMethod
->ppExceptions
);
1820 newMethod
->bOneWay
= baseMethod
->bOneWay
;
1821 newMethod
->pInterface
1822 = reinterpret_cast< typelib_InterfaceTypeDescription
* >(
1824 newMethod
->pBaseRef
= baseRef
;
1825 newMethod
->nIndex
= index
;
1829 case typelib_TypeClass_INTERFACE_ATTRIBUTE
:
1831 typelib_typedescription_newEmpty(
1832 result
, typelib_TypeClass_INTERFACE_ATTRIBUTE
, name
.pData
);
1833 typelib_InterfaceAttributeTypeDescription
const * baseAttribute
1835 typelib_InterfaceAttributeTypeDescription
const * >(base
);
1836 typelib_InterfaceAttributeTypeDescription
* newAttribute
1838 typelib_InterfaceAttributeTypeDescription
* >(*result
);
1839 newAttribute
->aBase
.nPosition
= position
;
1840 newAttribute
->aBase
.pMemberName
1841 = baseAttribute
->aBase
.pMemberName
;
1842 rtl_uString_acquire(newAttribute
->aBase
.pMemberName
);
1843 newAttribute
->bReadOnly
= baseAttribute
->bReadOnly
;
1844 newAttribute
->pAttributeTypeRef
1845 = baseAttribute
->pAttributeTypeRef
;
1846 typelib_typedescriptionreference_acquire(newAttribute
->pAttributeTypeRef
);
1847 newAttribute
->pInterface
1848 = reinterpret_cast< typelib_InterfaceTypeDescription
* >(
1850 newAttribute
->pBaseRef
= baseRef
;
1851 newAttribute
->nIndex
= index
;
1852 newAttribute
->nGetExceptions
= baseAttribute
->nGetExceptions
;
1853 newAttribute
->ppGetExceptions
= copyExceptions(
1854 baseAttribute
->nGetExceptions
,
1855 baseAttribute
->ppGetExceptions
);
1856 newAttribute
->nSetExceptions
= baseAttribute
->nSetExceptions
;
1857 newAttribute
->ppSetExceptions
= copyExceptions(
1858 baseAttribute
->nSetExceptions
,
1859 baseAttribute
->ppSetExceptions
);
1872 extern "C" void SAL_CALL
typelib_typedescription_getByName(
1873 typelib_TypeDescription
** ppRet
, rtl_uString
* pName
)
1874 SAL_THROW_EXTERN_C()
1878 typelib_typedescription_release( *ppRet
);
1882 static bool bInited
= false;
1883 TypeDescriptor_Init_Impl
&rInit
= Init();
1887 // guard against multi thread access
1888 MutexGuard
aGuard( rInit
.maMutex
);
1891 // avoid recursion during the next ...new calls
1894 typelib_TypeDescription
* pType
= nullptr;
1895 typelib_typedescription_new( &pType
, typelib_TypeClass_TYPE
, OUString("type").pData
, nullptr, 0, nullptr );
1896 typelib_typedescription_register( &pType
);
1897 typelib_typedescription_new( &pType
, typelib_TypeClass_VOID
, OUString("void").pData
, nullptr, 0, nullptr );
1898 typelib_typedescription_register( &pType
);
1899 typelib_typedescription_new( &pType
, typelib_TypeClass_BOOLEAN
, OUString("boolean").pData
, nullptr, 0, nullptr );
1900 typelib_typedescription_register( &pType
);
1901 typelib_typedescription_new( &pType
, typelib_TypeClass_CHAR
, OUString("char").pData
, nullptr, 0, nullptr );
1902 typelib_typedescription_register( &pType
);
1903 typelib_typedescription_new( &pType
, typelib_TypeClass_BYTE
, OUString("byte").pData
, nullptr, 0, nullptr );
1904 typelib_typedescription_register( &pType
);
1905 typelib_typedescription_new( &pType
, typelib_TypeClass_STRING
, OUString("string").pData
, nullptr, 0, nullptr );
1906 typelib_typedescription_register( &pType
);
1907 typelib_typedescription_new( &pType
, typelib_TypeClass_SHORT
, OUString("short").pData
, nullptr, 0, nullptr );
1908 typelib_typedescription_register( &pType
);
1909 typelib_typedescription_new( &pType
, typelib_TypeClass_UNSIGNED_SHORT
, OUString("unsigned short").pData
, nullptr, 0, nullptr );
1910 typelib_typedescription_register( &pType
);
1911 typelib_typedescription_new( &pType
, typelib_TypeClass_LONG
, OUString("long").pData
, nullptr, 0, nullptr );
1912 typelib_typedescription_register( &pType
);
1913 typelib_typedescription_new( &pType
, typelib_TypeClass_UNSIGNED_LONG
, OUString("unsigned long").pData
, nullptr, 0, nullptr );
1914 typelib_typedescription_register( &pType
);
1915 typelib_typedescription_new( &pType
, typelib_TypeClass_HYPER
, OUString("hyper").pData
, nullptr, 0, nullptr );
1916 typelib_typedescription_register( &pType
);
1917 typelib_typedescription_new( &pType
, typelib_TypeClass_UNSIGNED_HYPER
, OUString("unsigned hyper").pData
, nullptr, 0, nullptr );
1918 typelib_typedescription_register( &pType
);
1919 typelib_typedescription_new( &pType
, typelib_TypeClass_FLOAT
, OUString("float").pData
, nullptr, 0, nullptr );
1920 typelib_typedescription_register( &pType
);
1921 typelib_typedescription_new( &pType
, typelib_TypeClass_DOUBLE
, OUString("double").pData
, nullptr, 0, nullptr );
1922 typelib_typedescription_register( &pType
);
1923 typelib_typedescription_new( &pType
, typelib_TypeClass_ANY
, OUString("any").pData
, nullptr, 0, nullptr );
1924 typelib_typedescription_register( &pType
);
1925 typelib_typedescription_release( pType
);
1929 typelib_TypeDescriptionReference
* pTDR
= nullptr;
1930 typelib_typedescriptionreference_getByName( &pTDR
, pName
);
1934 // guard against multi thread access
1935 MutexGuard
aGuard( rInit
.maMutex
);
1936 // pTDR->pType->pWeakRef == 0 means that the description is empty
1937 if( pTDR
->pType
&& pTDR
->pType
->pWeakRef
)
1939 typelib_typedescription_acquire( pTDR
->pType
);
1940 *ppRet
= pTDR
->pType
;
1943 typelib_typedescriptionreference_release( pTDR
);
1946 if (nullptr != *ppRet
)
1949 // check for sequence
1950 OUString
const & name
= OUString::unacquired( &pName
);
1951 if (2 < name
.getLength() && '[' == name
[ 0 ])
1953 OUString
element_name( name
.copy( 2 ) );
1954 typelib_TypeDescription
* element_td
= nullptr;
1955 typelib_typedescription_getByName( &element_td
, element_name
.pData
);
1956 if (nullptr != element_td
)
1958 typelib_typedescription_new(
1959 ppRet
, typelib_TypeClass_SEQUENCE
, pName
, element_td
->pWeakRef
, 0, nullptr );
1961 typelib_typedescription_release( element_td
);
1964 if (nullptr == *ppRet
)
1966 // Check for derived interface member type:
1967 sal_Int32 i1
= name
.lastIndexOf(":@");
1969 sal_Int32 i2
= i1
+ RTL_CONSTASCII_LENGTH(":@");
1970 sal_Int32 i3
= name
.indexOf(',', i2
);
1972 sal_Int32 i4
= name
.indexOf(':', i3
);
1974 typelib_TypeDescriptionReference
* pBaseRef
= nullptr;
1975 typelib_TypeDescription
* pBase
= nullptr;
1976 typelib_TypeDescription
* pInterface
= nullptr;
1977 typelib_typedescriptionreference_getByName(
1978 &pBaseRef
, name
.copy(0, i1
).pData
);
1979 if (pBaseRef
!= nullptr) {
1980 typelib_typedescriptionreference_getDescription(
1983 typelib_typedescription_getByName(
1984 &pInterface
, name
.copy(i4
+ 1).pData
);
1985 if (!createDerivedInterfaceMemberDescription(
1986 ppRet
, name
, pBaseRef
, pBase
, pInterface
,
1987 name
.copy(i2
, i3
- i2
).toInt32(),
1988 name
.copy(i3
+ 1, i4
- i3
- 1).toInt32()))
1990 if (pInterface
!= nullptr) {
1991 typelib_typedescription_release(pInterface
);
1993 if (pBase
!= nullptr) {
1994 typelib_typedescription_release(pBase
);
1996 if (pBaseRef
!= nullptr) {
1997 typelib_typedescriptionreference_release(
2005 if (nullptr == *ppRet
)
2008 rInit
.callChain( ppRet
, pName
);
2014 // typedescription found
2015 if (typelib_TypeClass_TYPEDEF
== (*ppRet
)->eTypeClass
)
2017 typelib_TypeDescription
* pTD
= nullptr;
2018 typelib_typedescriptionreference_getDescription(
2019 &pTD
, reinterpret_cast<typelib_IndirectTypeDescription
*>(*ppRet
)->pType
);
2020 typelib_typedescription_release( *ppRet
);
2026 (*ppRet
)->bOnDemand
= true;
2027 // The type description is hold by the reference until
2028 // on demand is activated.
2029 typelib_typedescription_register( ppRet
);
2031 // insert into the cache
2032 MutexGuard
aGuard( rInit
.maMutex
);
2033 if( static_cast<sal_Int32
>(rInit
.maCache
.size()) >= nCacheSize
)
2035 typelib_typedescription_release( rInit
.maCache
.front() );
2036 rInit
.maCache
.pop_front();
2038 // descriptions in the cache must be acquired!
2039 typelib_typedescription_acquire( *ppRet
);
2040 rInit
.maCache
.push_back( *ppRet
);
2044 extern "C" void SAL_CALL
typelib_typedescriptionreference_newByAsciiName(
2045 typelib_TypeDescriptionReference
** ppTDR
,
2046 typelib_TypeClass eTypeClass
,
2047 const char * pTypeName
)
2048 SAL_THROW_EXTERN_C()
2050 OUString
aTypeName( OUString::createFromAscii( pTypeName
) );
2051 typelib_typedescriptionreference_new( ppTDR
, eTypeClass
, aTypeName
.pData
);
2054 extern "C" void SAL_CALL
typelib_typedescriptionreference_new(
2055 typelib_TypeDescriptionReference
** ppTDR
,
2056 typelib_TypeClass eTypeClass
, rtl_uString
* pTypeName
)
2057 SAL_THROW_EXTERN_C()
2059 TypeDescriptor_Init_Impl
&rInit
= Init();
2060 if( eTypeClass
== typelib_TypeClass_TYPEDEF
)
2063 typelib_TypeDescription
* pRet
= nullptr;
2064 rInit
.callChain( &pRet
, pTypeName
);
2067 // typedescription found
2068 if (typelib_TypeClass_TYPEDEF
== pRet
->eTypeClass
)
2070 typelib_typedescriptionreference_acquire(
2071 reinterpret_cast<typelib_IndirectTypeDescription
*>(pRet
)->pType
);
2073 typelib_typedescriptionreference_release( *ppTDR
);
2074 *ppTDR
= reinterpret_cast<typelib_IndirectTypeDescription
*>(pRet
)->pType
;
2075 typelib_typedescription_release( pRet
);
2080 pRet
->bOnDemand
= true;
2081 // The type description is hold by the reference until
2082 // on demand is activated.
2083 typelib_typedescription_register( &pRet
);
2085 // insert into the cache
2086 MutexGuard
aGuard( rInit
.maMutex
);
2087 if( static_cast<sal_Int32
>(rInit
.maCache
.size()) >= nCacheSize
)
2089 typelib_typedescription_release( rInit
.maCache
.front() );
2090 rInit
.maCache
.pop_front();
2092 rInit
.maCache
.push_back( pRet
);
2093 // pRet kept acquired for cache
2095 typelib_typedescriptionreference_acquire( pRet
->pWeakRef
);
2097 typelib_typedescriptionreference_release( *ppTDR
);
2098 *ppTDR
= pRet
->pWeakRef
;
2103 SAL_INFO("cppu.typelib", "typedef not found : " << pTypeName
);
2104 typelib_typedescriptionreference_release( *ppTDR
);
2110 MutexGuard
aGuard( rInit
.maMutex
);
2111 typelib_typedescriptionreference_getByName( ppTDR
, pTypeName
);
2115 if( TYPELIB_TYPEDESCRIPTIONREFERENCE_ISREALLYWEAK( eTypeClass
) )
2117 typelib_TypeDescriptionReference
* pTDR
= new typelib_TypeDescriptionReference
;
2118 #if OSL_DEBUG_LEVEL > 0
2119 osl_atomic_increment( &rInit
.nTypeDescriptionReferenceCount
);
2121 pTDR
->nRefCount
= 1;
2122 pTDR
->nStaticRefCount
= 0;
2123 pTDR
->eTypeClass
= eTypeClass
;
2124 pTDR
->pUniqueIdentifier
= nullptr;
2125 pTDR
->pReserved
= nullptr;
2126 pTDR
->pTypeName
= pTypeName
;
2127 rtl_uString_acquire( pTDR
->pTypeName
);
2128 pTDR
->pType
= nullptr;
2133 typelib_typedescription_newEmpty( reinterpret_cast<typelib_TypeDescription
** >(ppTDR
), eTypeClass
, pTypeName
);
2134 // description will be registered but not acquired
2135 (*reinterpret_cast<typelib_TypeDescription
**>(ppTDR
))->bOnDemand
= true;
2136 (*reinterpret_cast<typelib_TypeDescription
**>(ppTDR
))->bComplete
= false;
2139 // Heavy hack, the const sal_Unicode * is hold by the typedescription reference
2141 rInit
.maWeakMap
[ (*ppTDR
)->pTypeName
->buffer
] = *ppTDR
;
2145 extern "C" void SAL_CALL
typelib_typedescriptionreference_acquire(
2146 typelib_TypeDescriptionReference
* pRef
)
2147 SAL_THROW_EXTERN_C()
2149 osl_atomic_increment( &pRef
->nRefCount
);
2153 extern "C" void SAL_CALL
typelib_typedescriptionreference_release(
2154 typelib_TypeDescriptionReference
* pRef
)
2155 SAL_THROW_EXTERN_C()
2157 // Is it a type description?
2158 if( TYPELIB_TYPEDESCRIPTIONREFERENCE_ISREALLYWEAK( pRef
->eTypeClass
) )
2160 if( ! osl_atomic_decrement( &pRef
->nRefCount
) )
2162 TypeDescriptor_Init_Impl
&rInit
= Init();
2163 MutexGuard
aGuard( rInit
.maMutex
);
2164 WeakMap_Impl::iterator aIt
= rInit
.maWeakMap
.find( pRef
->pTypeName
->buffer
);
2165 if( aIt
!= rInit
.maWeakMap
.end() && (*aIt
).second
== pRef
)
2167 // remove only if it contains the same object
2168 rInit
.maWeakMap
.erase( aIt
);
2171 rtl_uString_release( pRef
->pTypeName
);
2172 OSL_ASSERT( pRef
->pType
== nullptr );
2173 #if OSL_DEBUG_LEVEL > 0
2174 osl_atomic_decrement( &rInit
.nTypeDescriptionReferenceCount
);
2181 typelib_typedescription_release( reinterpret_cast<typelib_TypeDescription
*>(pRef
) );
2186 extern "C" void SAL_CALL
typelib_typedescriptionreference_getDescription(
2187 typelib_TypeDescription
** ppRet
, typelib_TypeDescriptionReference
* pRef
)
2188 SAL_THROW_EXTERN_C()
2192 typelib_typedescription_release( *ppRet
);
2196 if( !TYPELIB_TYPEDESCRIPTIONREFERENCE_ISREALLYWEAK( pRef
->eTypeClass
) && pRef
->pType
&& pRef
->pType
->pWeakRef
)
2198 // reference is a description and initialized
2199 osl_atomic_increment( &reinterpret_cast<typelib_TypeDescription
*>(pRef
)->nRefCount
);
2200 *ppRet
= reinterpret_cast<typelib_TypeDescription
*>(pRef
);
2205 MutexGuard
aGuard( Init().maMutex
);
2206 // pRef->pType->pWeakRef == 0 means that the description is empty
2207 if( pRef
->pType
&& pRef
->pType
->pWeakRef
)
2209 sal_Int32 n
= osl_atomic_increment( &pRef
->pType
->nRefCount
);
2212 // The reference is incremented. The object cannot be destroyed.
2213 // Release the guard at the earliest point.
2214 *ppRet
= pRef
->pType
;
2217 (void)osl_atomic_decrement( &pRef
->pType
->nRefCount
);
2218 // destruction of this type in progress (another thread!)
2219 // no access through this weak reference
2220 pRef
->pType
= nullptr;
2224 typelib_typedescription_getByName( ppRet
, pRef
->pTypeName
);
2225 OSL_ASSERT( !*ppRet
|| rtl_ustr_compare( pRef
->pTypeName
->buffer
, (*ppRet
)->pTypeName
->buffer
) == 0 );
2226 OSL_ASSERT( !*ppRet
|| pRef
->eTypeClass
== (*ppRet
)->eTypeClass
);
2227 OSL_ASSERT( !*ppRet
|| pRef
== (*ppRet
)->pWeakRef
);
2228 pRef
->pType
= *ppRet
;
2232 extern "C" void typelib_typedescriptionreference_getByName(
2233 typelib_TypeDescriptionReference
** ppRet
, rtl_uString
const * pName
)
2234 SAL_THROW_EXTERN_C()
2238 typelib_typedescriptionreference_release( *ppRet
);
2241 TypeDescriptor_Init_Impl
&rInit
= Init();
2243 MutexGuard
aGuard( rInit
.maMutex
);
2244 WeakMap_Impl::const_iterator aIt
= rInit
.maWeakMap
.find( pName
->buffer
);
2245 if( aIt
== rInit
.maWeakMap
.end() )
2248 sal_Int32 n
= osl_atomic_increment( &(*aIt
).second
->nRefCount
);
2251 // The reference is incremented. The object cannot be destroyed.
2252 // Release the guard at the earliest point.
2253 *ppRet
= (*aIt
).second
;
2257 // destruction of this type in progress (another thread!)
2258 // no access through this weak reference
2259 (void)osl_atomic_decrement( &(*aIt
).second
->nRefCount
);
2264 extern "C" sal_Bool SAL_CALL
typelib_typedescriptionreference_equals(
2265 const typelib_TypeDescriptionReference
* p1
,
2266 const typelib_TypeDescriptionReference
* p2
)
2267 SAL_THROW_EXTERN_C()
2270 (p1
->eTypeClass
== p2
->eTypeClass
&&
2271 p1
->pTypeName
->length
== p2
->pTypeName
->length
&&
2272 rtl_ustr_compare( p1
->pTypeName
->buffer
, p2
->pTypeName
->buffer
) == 0));
2276 extern "C" void SAL_CALL
typelib_typedescriptionreference_assign(
2277 typelib_TypeDescriptionReference
** ppDest
,
2278 typelib_TypeDescriptionReference
* pSource
)
2279 SAL_THROW_EXTERN_C()
2281 if (*ppDest
!= pSource
)
2283 ::typelib_typedescriptionreference_acquire( pSource
);
2284 ::typelib_typedescriptionreference_release( *ppDest
);
2290 extern "C" void SAL_CALL
typelib_setCacheSize( sal_Int32 nNewSize
)
2291 SAL_THROW_EXTERN_C()
2293 OSL_ENSURE( nNewSize
>= 0, "### illegal cache size given!" );
2297 TypeDescriptor_Init_Impl
&rInit
= Init();
2298 MutexGuard
aGuard( rInit
.maMutex
);
2299 if (nNewSize
< nCacheSize
)
2301 while (static_cast<sal_Int32
>(rInit
.maCache
.size()) != nNewSize
)
2303 typelib_typedescription_release( rInit
.maCache
.front() );
2304 rInit
.maCache
.pop_front();
2307 nCacheSize
= nNewSize
;
2311 const bool s_aAssignableFromTab
[11][11] =
2313 /* from CH, BO, BY, SH, US, LO, UL, HY, UH, FL, DO */
2314 /* TypeClass_CHAR */ { true, false, false, false, false, false, false, false, false, false, false },
2315 /* TypeClass_BOOLEAN */ { false, true, false, false, false, false, false, false, false, false, false },
2316 /* TypeClass_BYTE */ { false, false, true, false, false, false, false, false, false, false, false },
2317 /* TypeClass_SHORT */ { false, false, true, true, true, false, false, false, false, false, false },
2318 /* TypeClass_UNSIGNED_SHORT */ { false, false, true, true, true, false, false, false, false, false, false },
2319 /* TypeClass_LONG */ { false, false, true, true, true, true, true, false, false, false, false },
2320 /* TypeClass_UNSIGNED_LONG */ { false, false, true, true, true, true, true, false, false, false, false },
2321 /* TypeClass_HYPER */ { false, false, true, true, true, true, true, true, true, false, false },
2322 /* TypeClass_UNSIGNED_HYPER */ { false, false, true, true, true, true, true, true, true, false, false },
2323 /* TypeClass_FLOAT */ { false, false, true, true, true, false, false, false, false, true, false },
2324 /* TypeClass_DOUBLE */ { false, false, true, true, true, true, true, false, false, true, true }
2328 extern "C" sal_Bool SAL_CALL
typelib_typedescriptionreference_isAssignableFrom(
2329 typelib_TypeDescriptionReference
* pAssignable
,
2330 typelib_TypeDescriptionReference
* pFrom
)
2331 SAL_THROW_EXTERN_C()
2333 if (pAssignable
&& pFrom
)
2335 typelib_TypeClass eAssignable
= pAssignable
->eTypeClass
;
2336 typelib_TypeClass eFrom
= pFrom
->eTypeClass
;
2338 if (eAssignable
== typelib_TypeClass_ANY
) // anything can be assigned to an any .)
2340 if (eAssignable
== eFrom
)
2342 if (type_equals( pAssignable
, pFrom
)) // first shot
2346 switch (eAssignable
)
2348 case typelib_TypeClass_STRUCT
:
2349 case typelib_TypeClass_EXCEPTION
:
2351 typelib_TypeDescription
* pFromDescr
= nullptr;
2352 TYPELIB_DANGER_GET( &pFromDescr
, pFrom
);
2353 if (!reinterpret_cast<typelib_CompoundTypeDescription
*>(pFromDescr
)->pBaseTypeDescription
)
2355 TYPELIB_DANGER_RELEASE( pFromDescr
);
2358 bool bRet
= typelib_typedescriptionreference_isAssignableFrom(
2360 reinterpret_cast<typelib_CompoundTypeDescription
*>(pFromDescr
)->pBaseTypeDescription
->aBase
.pWeakRef
);
2361 TYPELIB_DANGER_RELEASE( pFromDescr
);
2364 case typelib_TypeClass_INTERFACE
:
2366 typelib_TypeDescription
* pFromDescr
= nullptr;
2367 TYPELIB_DANGER_GET( &pFromDescr
, pFrom
);
2368 typelib_InterfaceTypeDescription
* pFromIfc
2370 typelib_InterfaceTypeDescription
* >(pFromDescr
);
2372 for (sal_Int32 i
= 0; i
< pFromIfc
->nBaseTypes
; ++i
) {
2373 if (typelib_typedescriptionreference_isAssignableFrom(
2375 pFromIfc
->ppBaseTypes
[i
]->aBase
.pWeakRef
))
2381 TYPELIB_DANGER_RELEASE( pFromDescr
);
2390 return (eAssignable
>= typelib_TypeClass_CHAR
&& eAssignable
<= typelib_TypeClass_DOUBLE
&&
2391 eFrom
>= typelib_TypeClass_CHAR
&& eFrom
<= typelib_TypeClass_DOUBLE
&&
2392 s_aAssignableFromTab
[eAssignable
-1][eFrom
-1]);
2397 extern "C" sal_Bool SAL_CALL
typelib_typedescription_isAssignableFrom(
2398 typelib_TypeDescription
* pAssignable
,
2399 typelib_TypeDescription
* pFrom
)
2400 SAL_THROW_EXTERN_C()
2402 return typelib_typedescriptionreference_isAssignableFrom(
2403 pAssignable
->pWeakRef
, pFrom
->pWeakRef
);
2407 extern "C" sal_Bool SAL_CALL
typelib_typedescription_complete(
2408 typelib_TypeDescription
** ppTypeDescr
)
2409 SAL_THROW_EXTERN_C()
2411 return complete(ppTypeDescr
, true);
2414 /* vim:set shiftwidth=4 softtabstop=4 expandtab: */