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>
31 #include <sal/log.hxx>
32 #include <osl/interlck.h>
33 #include <osl/mutex.hxx>
34 #include <rtl/ustring.hxx>
35 #include <osl/diagnose.h>
36 #include <typelib/typedescription.h>
38 #include <o3tl/string_view.hxx>
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.
67 // the value of the maximal alignment
68 const sal_Int32 nMaxAlignment
= static_cast<sal_Int32
>( reinterpret_cast<sal_Size
>(&reinterpret_cast<AlignSize_Impl
*>(16)->dDouble
) - 16);
70 static sal_Int32
adjustAlignment( sal_Int32 nRequestedAlignment
)
72 if( nRequestedAlignment
> nMaxAlignment
)
73 nRequestedAlignment
= nMaxAlignment
;
74 return nRequestedAlignment
;
78 * Calculate the new size of the structure.
80 static sal_Int32
newAlignedSize(
81 sal_Int32 OldSize
, sal_Int32 ElementSize
, sal_Int32 NeededAlignment
)
83 NeededAlignment
= adjustAlignment( NeededAlignment
);
84 return (OldSize
+ NeededAlignment
-1) / NeededAlignment
* NeededAlignment
+ ElementSize
;
87 static sal_Int32
getDescriptionSize( typelib_TypeClass eTypeClass
)
89 OSL_ASSERT( typelib_TypeClass_TYPEDEF
!= eTypeClass
);
92 // The reference is the description
93 // if the description is empty, then it must be filled with
94 // the new description
97 case typelib_TypeClass_SEQUENCE
:
98 nSize
= sal_Int32(sizeof( typelib_IndirectTypeDescription
));
101 case typelib_TypeClass_STRUCT
:
102 nSize
= sal_Int32(sizeof( typelib_StructTypeDescription
));
105 case typelib_TypeClass_EXCEPTION
:
106 nSize
= sal_Int32(sizeof( typelib_CompoundTypeDescription
));
109 case typelib_TypeClass_ENUM
:
110 nSize
= sal_Int32(sizeof( typelib_EnumTypeDescription
));
113 case typelib_TypeClass_INTERFACE
:
114 nSize
= sal_Int32(sizeof( typelib_InterfaceTypeDescription
));
117 case typelib_TypeClass_INTERFACE_METHOD
:
118 nSize
= sal_Int32(sizeof( typelib_InterfaceMethodTypeDescription
));
121 case typelib_TypeClass_INTERFACE_ATTRIBUTE
:
122 nSize
= sal_Int32(sizeof( typelib_InterfaceAttributeTypeDescription
));
126 nSize
= sal_Int32(sizeof( typelib_TypeDescription
));
135 bool operator()(const sal_Unicode
* const & s1
, const sal_Unicode
* const & s2
) const
136 { return 0 == rtl_ustr_compare( s1
, s2
); }
142 size_t operator()(const sal_Unicode
* const & s
) const
143 { return rtl_ustr_hashCode( s
); }
148 // Heavy hack, the const sal_Unicode * is hold by the typedescription reference
149 typedef std::unordered_map
< const sal_Unicode
*, typelib_TypeDescriptionReference
*,
150 hashStr_Impl
, equalStr_Impl
> WeakMap_Impl
;
152 typedef std::pair
< void *, typelib_typedescription_Callback
> CallbackEntry
;
153 typedef std::list
< CallbackEntry
> CallbackSet_Impl
;
154 typedef std::list
< typelib_TypeDescription
* > TypeDescriptionList_Impl
;
156 // # of cached elements
157 constexpr auto nCacheSize
= 256;
161 struct TypeDescriptor_Init_Impl
163 // all type description references
164 WeakMap_Impl maWeakMap
;
165 // all type description callbacks
166 CallbackSet_Impl maCallbacks
;
167 // A cache to hold descriptions
168 TypeDescriptionList_Impl maCache
;
169 // The mutex to guard all type library accesses
172 inline void callChain( typelib_TypeDescription
** ppRet
, rtl_uString
* pName
);
174 #if OSL_DEBUG_LEVEL > 0
175 // only for debugging
176 sal_Int32 nTypeDescriptionCount
= 0;
177 sal_Int32 nCompoundTypeDescriptionCount
= 0;
178 sal_Int32 nIndirectTypeDescriptionCount
= 0;
179 sal_Int32 nEnumTypeDescriptionCount
= 0;
180 sal_Int32 nInterfaceMethodTypeDescriptionCount
= 0;
181 sal_Int32 nInterfaceAttributeTypeDescriptionCount
= 0;
182 sal_Int32 nInterfaceTypeDescriptionCount
= 0;
183 sal_Int32 nTypeDescriptionReferenceCount
= 0;
186 TypeDescriptor_Init_Impl() = default;
188 ~TypeDescriptor_Init_Impl();
193 inline void TypeDescriptor_Init_Impl::callChain(
194 typelib_TypeDescription
** ppRet
, rtl_uString
* pName
)
196 assert(ppRet
!= nullptr);
197 assert(*ppRet
== nullptr);
198 for( const CallbackEntry
& rEntry
: maCallbacks
)
200 (*rEntry
.second
)( rEntry
.first
, ppRet
, pName
);
207 TypeDescriptor_Init_Impl::~TypeDescriptor_Init_Impl()
209 for( typelib_TypeDescription
* pItem
: maCache
)
211 typelib_typedescription_release( pItem
);
215 std::vector
< typelib_TypeDescriptionReference
* > ppTDR
;
216 ppTDR
.reserve( maWeakMap
.size() );
218 // save all weak references
219 for( const auto& rEntry
: maWeakMap
)
221 ppTDR
.push_back( rEntry
.second
);
222 typelib_typedescriptionreference_acquire( ppTDR
.back() );
225 for( typelib_TypeDescriptionReference
* pTDR
: ppTDR
)
227 OSL_ASSERT( pTDR
->nRefCount
> pTDR
->nStaticRefCount
);
228 pTDR
->nRefCount
-= pTDR
->nStaticRefCount
;
230 if( pTDR
->pType
&& !pTDR
->pType
->bOnDemand
)
232 pTDR
->pType
->bOnDemand
= true;
233 typelib_typedescription_release( pTDR
->pType
);
235 typelib_typedescriptionreference_release( pTDR
);
238 #if defined SAL_LOG_INFO
239 for( const auto& rEntry
: maWeakMap
)
241 typelib_TypeDescriptionReference
* pTDR
= rEntry
.second
;
244 OString
aTypeName( OUStringToOString( OUString::unacquired(&pTDR
->pTypeName
), RTL_TEXTENCODING_ASCII_US
) );
245 SAL_INFO("cppu.typelib", "remaining type: " << aTypeName
<< "; ref count = " << pTDR
->nRefCount
);
249 SAL_INFO("cppu.typelib", "remaining null type entry!?");
254 #if OSL_DEBUG_LEVEL > 0
255 SAL_INFO_IF( nTypeDescriptionCount
, "cppu.typelib", "nTypeDescriptionCount is not zero" );
256 SAL_INFO_IF( nCompoundTypeDescriptionCount
, "cppu.typelib", "nCompoundTypeDescriptionCount is not zero" );
257 SAL_INFO_IF( nIndirectTypeDescriptionCount
, "cppu.typelib", "nIndirectTypeDescriptionCount is not zero" );
258 SAL_INFO_IF( nEnumTypeDescriptionCount
, "cppu.typelib", "nEnumTypeDescriptionCount is not zero" );
259 SAL_INFO_IF( nInterfaceMethodTypeDescriptionCount
, "cppu.typelib", "nInterfaceMethodTypeDescriptionCount is not zero" );
260 SAL_INFO_IF( nInterfaceAttributeTypeDescriptionCount
, "cppu.typelib", "nInterfaceAttributeTypeDescriptionCount is not zero" );
261 SAL_INFO_IF( nInterfaceTypeDescriptionCount
, "cppu.typelib", "nInterfaceTypeDescriptionCount is not zero" );
262 SAL_INFO_IF( nTypeDescriptionReferenceCount
, "cppu.typelib", "nTypeDescriptionReferenceCount is not zero" );
265 SAL_INFO_IF( !maCallbacks
.empty(), "cppu.typelib", "pCallbacks is not NULL or empty" );
269 TypeDescriptor_Init_Impl
& Init()
271 static TypeDescriptor_Init_Impl SINGLETON
;
276 extern "C" void SAL_CALL
typelib_typedescription_registerCallback(
277 void * pContext
, typelib_typedescription_Callback pCallback
)
280 // todo mt safe: guard is no solution, can not acquire while calling callback!
281 TypeDescriptor_Init_Impl
&rInit
= Init();
282 // OslGuard aGuard( rInit.getMutex() );
283 rInit
.maCallbacks
.push_back( CallbackEntry( pContext
, pCallback
) );
287 extern "C" void SAL_CALL
typelib_typedescription_revokeCallback(
288 void * pContext
, typelib_typedescription_Callback pCallback
)
291 TypeDescriptor_Init_Impl
&rInit
= Init();
293 // todo mt safe: guard is no solution, can not acquire while calling callback!
294 // OslGuard aGuard( rInit.getMutex() );
295 CallbackEntry
aEntry( pContext
, pCallback
);
296 rInit
.maCallbacks
.erase(std::remove(rInit
.maCallbacks
.begin(), rInit
.maCallbacks
.end(), aEntry
),
297 rInit
.maCallbacks
.end());
301 static void typelib_typedescription_initTables(
302 typelib_TypeDescription
* pTD
)
304 typelib_InterfaceTypeDescription
* pITD
= reinterpret_cast<typelib_InterfaceTypeDescription
*>(pTD
);
306 std::vector
<bool> aReadWriteAttributes(pITD
->nAllMembers
);
307 for ( sal_Int32 i
= pITD
->nAllMembers
; i
--; )
309 aReadWriteAttributes
[i
] = false;
310 if( typelib_TypeClass_INTERFACE_ATTRIBUTE
== pITD
->ppAllMembers
[i
]->eTypeClass
)
312 typelib_TypeDescription
* pM
= nullptr;
313 TYPELIB_DANGER_GET( &pM
, pITD
->ppAllMembers
[i
] );
317 aReadWriteAttributes
[i
] = !reinterpret_cast<typelib_InterfaceAttributeTypeDescription
*>(pM
)->bReadOnly
;
318 TYPELIB_DANGER_RELEASE( pM
);
322 SAL_INFO( "cppu.typelib", "cannot get attribute type description: " << pITD
->ppAllMembers
[i
]->pTypeName
);
327 MutexGuard
aGuard( Init().maMutex
);
331 // create the index table from member to function table
332 pITD
->pMapMemberIndexToFunctionIndex
= new sal_Int32
[ pITD
->nAllMembers
];
333 sal_Int32 nAdditionalOffset
= 0; // +1 for read/write attributes
335 for( i
= 0; i
< pITD
->nAllMembers
; i
++ )
337 // index to the get method of the attribute
338 pITD
->pMapMemberIndexToFunctionIndex
[i
] = i
+ nAdditionalOffset
;
339 // extra offset if it is a read/write attribute?
340 if (aReadWriteAttributes
[i
])
342 // a read/write attribute
347 // create the index table from function to member table
348 pITD
->pMapFunctionIndexToMemberIndex
= new sal_Int32
[ pITD
->nAllMembers
+ nAdditionalOffset
];
349 nAdditionalOffset
= 0; // +1 for read/write attributes
350 for( i
= 0; i
< pITD
->nAllMembers
; i
++ )
352 // index to the get method of the attribute
353 pITD
->pMapFunctionIndexToMemberIndex
[i
+ nAdditionalOffset
] = i
;
354 // extra offset if it is a read/write attribute?
355 if (aReadWriteAttributes
[i
])
357 // a read/write attribute
358 pITD
->pMapFunctionIndexToMemberIndex
[i
+ ++nAdditionalOffset
] = i
;
361 // must be the last action after all initialization is done
362 pITD
->nMapFunctionIndexToMemberIndex
= pITD
->nAllMembers
+ nAdditionalOffset
;
363 pTD
->bComplete
= true;
368 template<typename T
> T
* allocTypeDescription() {
369 return reinterpret_cast<T
*>(new char[sizeof (T
)]);
372 void freeTypeDescription(typelib_TypeDescription
const * desc
) {
373 delete[] reinterpret_cast<char const *>(desc
);
376 // In some situations (notably typelib_typedescription_newInterfaceMethod and
377 // typelib_typedescription_newInterfaceAttribute), only the members nMembers,
378 // ppMembers, nAllMembers, and ppAllMembers of an incomplete interface type
379 // description are necessary, but not the additional
380 // pMapMemberIndexToFunctionIndex, nMapFunctionIndexToMemberIndex, and
381 // pMapFunctionIndexToMemberIndex (which are computed by
382 // typelib_typedescription_initTables). Furthermore, in those situations, it
383 // might be illegal to compute those tables, as the creation of the interface
384 // member type descriptions would recursively require a complete interface type
385 // description. The parameter initTables controls whether or not to call
386 // typelib_typedescription_initTables in those situations.
387 bool complete(typelib_TypeDescription
** ppTypeDescr
, bool initTables
) {
388 if ((*ppTypeDescr
)->bComplete
)
391 OSL_ASSERT( (typelib_TypeClass_STRUCT
== (*ppTypeDescr
)->eTypeClass
||
392 typelib_TypeClass_EXCEPTION
== (*ppTypeDescr
)->eTypeClass
||
393 typelib_TypeClass_ENUM
== (*ppTypeDescr
)->eTypeClass
||
394 typelib_TypeClass_INTERFACE
== (*ppTypeDescr
)->eTypeClass
) &&
395 !TYPELIB_TYPEDESCRIPTIONREFERENCE_ISREALLYWEAK( (*ppTypeDescr
)->eTypeClass
) );
397 if (typelib_TypeClass_INTERFACE
== (*ppTypeDescr
)->eTypeClass
&&
398 reinterpret_cast<typelib_InterfaceTypeDescription
*>(*ppTypeDescr
)->ppAllMembers
)
401 typelib_typedescription_initTables( *ppTypeDescr
);
406 typelib_TypeDescription
* pTD
= nullptr;
407 // on demand access of complete td
408 TypeDescriptor_Init_Impl
&rInit
= Init();
409 rInit
.callChain( &pTD
, (*ppTypeDescr
)->pTypeName
);
412 if (typelib_TypeClass_TYPEDEF
== pTD
->eTypeClass
)
414 typelib_typedescriptionreference_getDescription(
415 &pTD
, reinterpret_cast<typelib_IndirectTypeDescription
*>(pTD
)->pType
);
421 OSL_ASSERT( typelib_TypeClass_TYPEDEF
!= pTD
->eTypeClass
);
422 // typedescription found
424 pTD
->bOnDemand
= true;
426 if (pTD
->eTypeClass
== typelib_TypeClass_INTERFACE
427 && !pTD
->bComplete
&& initTables
)
429 // mandatory info from callback chain
430 OSL_ASSERT( reinterpret_cast<typelib_InterfaceTypeDescription
*>(pTD
)->ppAllMembers
);
431 // complete except of tables init
432 typelib_typedescription_initTables( pTD
);
433 pTD
->bComplete
= true;
436 // The type description is hold by the reference until
437 // on demand is activated.
438 ::typelib_typedescription_register( &pTD
); // replaces incomplete one
439 OSL_ASSERT( pTD
== *ppTypeDescr
); // has to merge into existing one
441 // insert into the cache
442 MutexGuard
aGuard( rInit
.maMutex
);
443 if( rInit
.maCache
.size() >= nCacheSize
)
445 typelib_typedescription_release( rInit
.maCache
.front() );
446 rInit
.maCache
.pop_front();
448 // descriptions in the cache must be acquired!
449 typelib_typedescription_acquire( pTD
);
450 rInit
.maCache
.push_back( pTD
);
454 || (pTD
->eTypeClass
== typelib_TypeClass_INTERFACE
457 ::typelib_typedescription_release( *ppTypeDescr
);
464 "type cannot be completed: " << OUString::unacquired(&(*ppTypeDescr
)->pTypeName
));
473 extern "C" void typelib_typedescription_newEmpty(
474 typelib_TypeDescription
** ppRet
,
475 typelib_TypeClass eTypeClass
, rtl_uString
* pTypeName
)
480 typelib_typedescription_release( *ppRet
);
484 OSL_ASSERT( typelib_TypeClass_TYPEDEF
!= eTypeClass
);
486 typelib_TypeDescription
* pRet
;
489 case typelib_TypeClass_SEQUENCE
:
491 auto pTmp
= allocTypeDescription
<typelib_IndirectTypeDescription
>();
493 #if OSL_DEBUG_LEVEL > 0
494 osl_atomic_increment( &Init().nIndirectTypeDescriptionCount
);
496 pTmp
->pType
= nullptr;
497 // coverity[leaked_storage] - this is on purpose
501 case typelib_TypeClass_STRUCT
:
503 // FEATURE_EMPTYCLASS
504 auto pTmp
= allocTypeDescription
<typelib_StructTypeDescription
>();
505 pRet
= &pTmp
->aBase
.aBase
;
506 #if OSL_DEBUG_LEVEL > 0
507 osl_atomic_increment( &Init().nCompoundTypeDescriptionCount
);
509 pTmp
->aBase
.pBaseTypeDescription
= nullptr;
510 pTmp
->aBase
.nMembers
= 0;
511 pTmp
->aBase
.pMemberOffsets
= nullptr;
512 pTmp
->aBase
.ppTypeRefs
= nullptr;
513 pTmp
->aBase
.ppMemberNames
= nullptr;
514 pTmp
->pParameterizedTypes
= nullptr;
515 // coverity[leaked_storage] - this is on purpose
519 case typelib_TypeClass_EXCEPTION
:
521 // FEATURE_EMPTYCLASS
522 auto pTmp
= allocTypeDescription
<typelib_CompoundTypeDescription
>();
524 #if OSL_DEBUG_LEVEL > 0
525 osl_atomic_increment( &Init().nCompoundTypeDescriptionCount
);
527 pTmp
->pBaseTypeDescription
= nullptr;
529 pTmp
->pMemberOffsets
= nullptr;
530 pTmp
->ppTypeRefs
= nullptr;
531 pTmp
->ppMemberNames
= nullptr;
532 // coverity[leaked_storage] - this is on purpose
536 case typelib_TypeClass_ENUM
:
538 auto pTmp
= allocTypeDescription
<typelib_EnumTypeDescription
>();
540 #if OSL_DEBUG_LEVEL > 0
541 osl_atomic_increment( &Init().nEnumTypeDescriptionCount
);
543 pTmp
->nDefaultEnumValue
= 0;
544 pTmp
->nEnumValues
= 0;
545 pTmp
->ppEnumNames
= nullptr;
546 pTmp
->pEnumValues
= nullptr;
547 // coverity[leaked_storage] - this is on purpose
551 case typelib_TypeClass_INTERFACE
:
553 auto pTmp
= allocTypeDescription
<
554 typelib_InterfaceTypeDescription
>();
556 #if OSL_DEBUG_LEVEL > 0
557 osl_atomic_increment( &Init().nInterfaceTypeDescriptionCount
);
559 pTmp
->pBaseTypeDescription
= nullptr;
561 pTmp
->ppMembers
= nullptr;
562 pTmp
->nAllMembers
= 0;
563 pTmp
->ppAllMembers
= nullptr;
564 pTmp
->nMapFunctionIndexToMemberIndex
= 0;
565 pTmp
->pMapFunctionIndexToMemberIndex
= nullptr;
566 pTmp
->pMapMemberIndexToFunctionIndex
= nullptr;
567 pTmp
->nBaseTypes
= 0;
568 pTmp
->ppBaseTypes
= nullptr;
569 // coverity[leaked_storage] - this is on purpose
573 case typelib_TypeClass_INTERFACE_METHOD
:
575 auto pTmp
= allocTypeDescription
<
576 typelib_InterfaceMethodTypeDescription
>();
577 pRet
= &pTmp
->aBase
.aBase
;
578 #if OSL_DEBUG_LEVEL > 0
579 osl_atomic_increment( &Init().nInterfaceMethodTypeDescriptionCount
);
581 pTmp
->aBase
.pMemberName
= nullptr;
582 pTmp
->pReturnTypeRef
= nullptr;
584 pTmp
->pParams
= nullptr;
585 pTmp
->nExceptions
= 0;
586 pTmp
->ppExceptions
= nullptr;
587 pTmp
->pInterface
= nullptr;
588 pTmp
->pBaseRef
= nullptr;
590 // coverity[leaked_storage] - this is on purpose
594 case typelib_TypeClass_INTERFACE_ATTRIBUTE
:
596 auto * pTmp
= allocTypeDescription
<
597 typelib_InterfaceAttributeTypeDescription
>();
598 pRet
= &pTmp
->aBase
.aBase
;
599 #if OSL_DEBUG_LEVEL > 0
600 osl_atomic_increment( &Init().nInterfaceAttributeTypeDescriptionCount
);
602 pTmp
->aBase
.pMemberName
= nullptr;
603 pTmp
->pAttributeTypeRef
= nullptr;
604 pTmp
->pInterface
= nullptr;
605 pTmp
->pBaseRef
= nullptr;
607 pTmp
->nGetExceptions
= 0;
608 pTmp
->ppGetExceptions
= nullptr;
609 pTmp
->nSetExceptions
= 0;
610 pTmp
->ppSetExceptions
= nullptr;
611 // coverity[leaked_storage] - this is on purpose
617 pRet
= allocTypeDescription
<typelib_TypeDescription
>();
618 #if OSL_DEBUG_LEVEL > 0
619 osl_atomic_increment( &Init().nTypeDescriptionCount
);
624 pRet
->nRefCount
= 1; // reference count is initially 1
625 pRet
->nStaticRefCount
= 0;
626 pRet
->eTypeClass
= eTypeClass
;
627 pRet
->pUniqueIdentifier
= nullptr;
628 pRet
->pReserved
= nullptr;
629 pRet
->pTypeName
= pTypeName
;
630 rtl_uString_acquire( pRet
->pTypeName
);
632 pRet
->bComplete
= true;
634 pRet
->nAlignment
= 0;
635 pRet
->pWeakRef
= nullptr;
636 pRet
->bOnDemand
= false;
643 void newTypeDescription(
644 typelib_TypeDescription
** ppRet
, typelib_TypeClass eTypeClass
,
645 rtl_uString
* pTypeName
, typelib_TypeDescriptionReference
* pType
,
646 sal_Int32 nMembers
, typelib_CompoundMember_Init
* pCompoundMembers
,
647 typelib_StructMember_Init
* pStructMembers
)
650 (pCompoundMembers
== nullptr || pStructMembers
== nullptr)
651 && (pStructMembers
== nullptr || eTypeClass
== typelib_TypeClass_STRUCT
));
652 if (typelib_TypeClass_TYPEDEF
== eTypeClass
)
654 SAL_WARN("cppu.typelib", "unexpected typedef!" );
655 typelib_typedescriptionreference_getDescription( ppRet
, pType
);
659 typelib_typedescription_newEmpty( ppRet
, eTypeClass
, pTypeName
);
663 case typelib_TypeClass_SEQUENCE
:
665 OSL_ASSERT( nMembers
== 0 );
666 typelib_typedescriptionreference_acquire( pType
);
667 reinterpret_cast<typelib_IndirectTypeDescription
*>(*ppRet
)->pType
= pType
;
671 case typelib_TypeClass_EXCEPTION
:
672 case typelib_TypeClass_STRUCT
:
674 // FEATURE_EMPTYCLASS
675 typelib_CompoundTypeDescription
* pTmp
= reinterpret_cast<typelib_CompoundTypeDescription
*>(*ppRet
);
677 sal_Int32 nOffset
= 0;
680 typelib_typedescriptionreference_getDescription(
681 reinterpret_cast<typelib_TypeDescription
**>(&pTmp
->pBaseTypeDescription
), pType
);
682 nOffset
= pTmp
->pBaseTypeDescription
->aBase
.nSize
;
683 OSL_ENSURE( newAlignedSize( 0, pTmp
->pBaseTypeDescription
->aBase
.nSize
, pTmp
->pBaseTypeDescription
->aBase
.nAlignment
) == pTmp
->pBaseTypeDescription
->aBase
.nSize
, "### unexpected offset!" );
687 pTmp
->nMembers
= nMembers
;
688 pTmp
->pMemberOffsets
= new sal_Int32
[ nMembers
];
689 pTmp
->ppTypeRefs
= new typelib_TypeDescriptionReference
*[ nMembers
];
690 pTmp
->ppMemberNames
= new rtl_uString
*[ nMembers
];
691 bool polymorphic
= eTypeClass
== typelib_TypeClass_STRUCT
692 && OUString::unacquired(&pTypeName
).indexOf('<') >= 0;
693 OSL_ASSERT(!polymorphic
|| pStructMembers
!= nullptr);
695 reinterpret_cast< typelib_StructTypeDescription
* >(pTmp
)->
696 pParameterizedTypes
= new sal_Bool
[nMembers
];
698 for( sal_Int32 i
= 0 ; i
< nMembers
; i
++ )
700 // read the type and member names
701 pTmp
->ppTypeRefs
[i
] = nullptr;
702 if (pCompoundMembers
!= nullptr) {
703 typelib_typedescriptionreference_new(
704 pTmp
->ppTypeRefs
+i
, pCompoundMembers
[i
].eTypeClass
,
705 pCompoundMembers
[i
].pTypeName
);
706 pTmp
->ppMemberNames
[i
]
707 = pCompoundMembers
[i
].pMemberName
;
708 rtl_uString_acquire( pTmp
->ppMemberNames
[i
] );
710 typelib_typedescriptionreference_new(
712 pStructMembers
[i
].aBase
.eTypeClass
,
713 pStructMembers
[i
].aBase
.pTypeName
);
714 pTmp
->ppMemberNames
[i
]
715 = pStructMembers
[i
].aBase
.pMemberName
;
716 rtl_uString_acquire(pTmp
->ppMemberNames
[i
]);
721 if (pTmp
->ppTypeRefs
[i
]->eTypeClass
==
722 typelib_TypeClass_SEQUENCE
)
724 // Take care of recursion like
725 // struct S { sequence<S> x; };
726 size
= sizeof(void *);
727 alignment
= adjustAlignment(size
);
729 typelib_TypeDescription
* pTD
= nullptr;
730 TYPELIB_DANGER_GET( &pTD
, pTmp
->ppTypeRefs
[i
] );
731 OSL_ENSURE( pTD
->nSize
, "### void member?" );
733 alignment
= pTD
->nAlignment
;
734 TYPELIB_DANGER_RELEASE( pTD
);
736 nOffset
= newAlignedSize( nOffset
, size
, alignment
);
737 pTmp
->pMemberOffsets
[i
] = nOffset
- size
;
740 reinterpret_cast< typelib_StructTypeDescription
* >(
741 pTmp
)->pParameterizedTypes
[i
]
742 = pStructMembers
[i
].bParameterizedType
;
753 if( !TYPELIB_TYPEDESCRIPTIONREFERENCE_ISREALLYWEAK( eTypeClass
) )
754 (*ppRet
)->pWeakRef
= reinterpret_cast<typelib_TypeDescriptionReference
*>(*ppRet
);
755 if( eTypeClass
!= typelib_TypeClass_VOID
)
757 // sizeof(void) not allowed
758 (*ppRet
)->nSize
= typelib_typedescription_getAlignedUnoSize( (*ppRet
), 0, (*ppRet
)->nAlignment
);
759 (*ppRet
)->nAlignment
= adjustAlignment( (*ppRet
)->nAlignment
);
765 extern "C" void SAL_CALL
typelib_typedescription_new(
766 typelib_TypeDescription
** ppRet
,
767 typelib_TypeClass eTypeClass
,
768 rtl_uString
* pTypeName
,
769 typelib_TypeDescriptionReference
* pType
,
771 typelib_CompoundMember_Init
* pMembers
)
775 ppRet
, eTypeClass
, pTypeName
, pType
, nMembers
, pMembers
, nullptr);
778 extern "C" void SAL_CALL
typelib_typedescription_newStruct(
779 typelib_TypeDescription
** ppRet
,
780 rtl_uString
* pTypeName
,
781 typelib_TypeDescriptionReference
* pType
,
783 typelib_StructMember_Init
* pMembers
)
787 ppRet
, typelib_TypeClass_STRUCT
, pTypeName
, pType
, nMembers
, nullptr,
792 extern "C" void SAL_CALL
typelib_typedescription_newEnum(
793 typelib_TypeDescription
** ppRet
,
794 rtl_uString
* pTypeName
,
795 sal_Int32 nDefaultValue
,
796 sal_Int32 nEnumValues
,
797 rtl_uString
** ppEnumNames
,
798 sal_Int32
* pEnumValues
)
801 typelib_typedescription_newEmpty( ppRet
, typelib_TypeClass_ENUM
, pTypeName
);
802 typelib_EnumTypeDescription
* pEnum
= reinterpret_cast<typelib_EnumTypeDescription
*>(*ppRet
);
804 pEnum
->nDefaultEnumValue
= nDefaultValue
;
805 pEnum
->nEnumValues
= nEnumValues
;
806 pEnum
->ppEnumNames
= new rtl_uString
* [ nEnumValues
];
807 for ( sal_Int32 nPos
= nEnumValues
; nPos
--; )
809 pEnum
->ppEnumNames
[nPos
] = ppEnumNames
[nPos
];
810 rtl_uString_acquire( pEnum
->ppEnumNames
[nPos
] );
812 pEnum
->pEnumValues
= new sal_Int32
[ nEnumValues
];
813 ::memcpy( pEnum
->pEnumValues
, pEnumValues
, nEnumValues
* sizeof(sal_Int32
) );
815 static_assert(!TYPELIB_TYPEDESCRIPTIONREFERENCE_ISREALLYWEAK(typelib_TypeClass_ENUM
));
816 (*ppRet
)->pWeakRef
= reinterpret_cast<typelib_TypeDescriptionReference
*>(*ppRet
);
817 // sizeof(void) not allowed
818 (*ppRet
)->nSize
= typelib_typedescription_getAlignedUnoSize( (*ppRet
), 0, (*ppRet
)->nAlignment
);
819 (*ppRet
)->nAlignment
= adjustAlignment( (*ppRet
)->nAlignment
);
823 extern "C" void SAL_CALL
typelib_typedescription_newInterface(
824 typelib_InterfaceTypeDescription
** ppRet
,
825 rtl_uString
* pTypeName
,
826 SAL_UNUSED_PARAMETER sal_uInt32
, SAL_UNUSED_PARAMETER sal_uInt16
,
827 SAL_UNUSED_PARAMETER sal_uInt16
, SAL_UNUSED_PARAMETER sal_uInt32
,
828 SAL_UNUSED_PARAMETER sal_uInt32
,
829 typelib_TypeDescriptionReference
* pBaseInterface
,
831 typelib_TypeDescriptionReference
** ppMembers
)
834 // coverity[callee_ptr_arith] - not a bug
835 typelib_typedescription_newMIInterface(
836 ppRet
, pTypeName
, 0, 0, 0, 0, 0, pBaseInterface
== nullptr ? 0 : 1,
837 &pBaseInterface
, nMembers
, ppMembers
);
845 sal_Int32 memberOffset
;
846 sal_Int32 directBaseIndex
;
847 sal_Int32 directBaseMemberOffset
;
848 typelib_InterfaceTypeDescription
const * base
;
851 typedef std::vector
< Entry
> List
;
853 explicit BaseList(typelib_InterfaceTypeDescription
const * desc
);
855 List
const & getList() const { return list
; }
857 sal_Int32
getBaseMembers() const { return members
; }
860 typedef std::set
< OUString
> Set
;
864 sal_Int32 directBaseIndex
, Set
& directBaseSet
,
865 sal_Int32
* directBaseMembers
,
866 typelib_InterfaceTypeDescription
const * desc
);
872 BaseList::BaseList(typelib_InterfaceTypeDescription
const * desc
)
876 for (sal_Int32 i
= 0; i
< desc
->nBaseTypes
; ++i
) {
878 sal_Int32 directBaseMembers
= 0;
879 calculate(allSet
, i
, directBaseSet
, &directBaseMembers
, desc
->ppBaseTypes
[i
]);
883 void BaseList::calculate(
885 sal_Int32 directBaseIndex
, Set
& directBaseSet
,
886 sal_Int32
* directBaseMembers
,
887 typelib_InterfaceTypeDescription
const * desc
)
889 for (sal_Int32 i
= 0; i
< desc
->nBaseTypes
; ++i
) {
891 directBaseIndex
, directBaseSet
, directBaseMembers
,
892 desc
->ppBaseTypes
[i
]);
894 if (allSet
.insert(desc
->aBase
.pTypeName
).second
) {
896 e
.memberOffset
= members
;
897 e
.directBaseIndex
= directBaseIndex
;
898 e
.directBaseMemberOffset
= *directBaseMembers
;
901 OSL_ASSERT(desc
->ppAllMembers
!= nullptr);
902 members
+= desc
->nMembers
;
904 if (directBaseSet
.insert(desc
->aBase
.pTypeName
).second
) {
905 OSL_ASSERT(desc
->ppAllMembers
!= nullptr);
906 *directBaseMembers
+= desc
->nMembers
;
912 extern "C" void SAL_CALL
typelib_typedescription_newMIInterface(
913 typelib_InterfaceTypeDescription
** ppRet
,
914 rtl_uString
* pTypeName
,
915 SAL_UNUSED_PARAMETER sal_uInt32
, SAL_UNUSED_PARAMETER sal_uInt16
,
916 SAL_UNUSED_PARAMETER sal_uInt16
, SAL_UNUSED_PARAMETER sal_uInt32
,
917 SAL_UNUSED_PARAMETER sal_uInt32
,
918 sal_Int32 nBaseInterfaces
,
919 typelib_TypeDescriptionReference
** ppBaseInterfaces
,
921 typelib_TypeDescriptionReference
** ppMembers
)
924 if (*ppRet
!= nullptr) {
925 typelib_typedescription_release(&(*ppRet
)->aBase
);
929 typelib_InterfaceTypeDescription
* pITD
= nullptr;
930 typelib_typedescription_newEmpty(
931 reinterpret_cast<typelib_TypeDescription
**>(&pITD
), typelib_TypeClass_INTERFACE
, pTypeName
);
933 pITD
->nBaseTypes
= nBaseInterfaces
;
934 pITD
->ppBaseTypes
= new typelib_InterfaceTypeDescription
*[nBaseInterfaces
];
935 for (sal_Int32 i
= 0; i
< nBaseInterfaces
; ++i
) {
936 pITD
->ppBaseTypes
[i
] = nullptr;
937 typelib_typedescriptionreference_getDescription(
938 reinterpret_cast< typelib_TypeDescription
** >(
939 &pITD
->ppBaseTypes
[i
]),
940 ppBaseInterfaces
[i
]);
941 if (pITD
->ppBaseTypes
[i
] == nullptr
943 reinterpret_cast< typelib_TypeDescription
** >(
944 &pITD
->ppBaseTypes
[i
]),
950 OSL_ASSERT(pITD
->ppBaseTypes
[i
] != nullptr);
952 if (nBaseInterfaces
> 0) {
953 pITD
->pBaseTypeDescription
= pITD
->ppBaseTypes
[0];
956 pITD
->aUik
.m_Data1
= 0;
957 pITD
->aUik
.m_Data2
= 0;
958 pITD
->aUik
.m_Data3
= 0;
959 pITD
->aUik
.m_Data4
= 0;
960 pITD
->aUik
.m_Data5
= 0;
962 BaseList
aBaseList(pITD
);
963 pITD
->nAllMembers
= nMembers
+ aBaseList
.getBaseMembers();
964 pITD
->nMembers
= nMembers
;
966 if( pITD
->nAllMembers
)
968 // at minimum one member exist, allocate the memory
969 pITD
->ppAllMembers
= new typelib_TypeDescriptionReference
*[ pITD
->nAllMembers
];
972 BaseList::List
const & rList
= aBaseList
.getList();
973 for (const auto& rEntry
: rList
)
975 typelib_InterfaceTypeDescription
const * pBase
= rEntry
.base
;
976 typelib_InterfaceTypeDescription
const * pDirectBase
977 = pITD
->ppBaseTypes
[rEntry
.directBaseIndex
];
978 OSL_ASSERT(pBase
->ppAllMembers
!= nullptr);
979 for (sal_Int32 j
= 0; j
< pBase
->nMembers
; ++j
) {
980 typelib_TypeDescriptionReference
const * pDirectBaseMember
981 = pDirectBase
->ppAllMembers
[rEntry
.directBaseMemberOffset
+ j
];
982 OUString aName
= OUString::unacquired(&pDirectBaseMember
->pTypeName
) +
984 OUString::number(rEntry
.directBaseIndex
) +
986 OUString::number(rEntry
.memberOffset
+ j
) +
988 OUString::unacquired(&pITD
->aBase
.pTypeName
);
989 typelib_TypeDescriptionReference
* pDerivedMember
= nullptr;
990 typelib_typedescriptionreference_new(
991 &pDerivedMember
, pDirectBaseMember
->eTypeClass
,
993 pITD
->ppAllMembers
[n
++] = pDerivedMember
;
999 pITD
->ppMembers
= pITD
->ppAllMembers
+ aBaseList
.getBaseMembers();
1003 for( sal_Int32 i
= 0; i
< nMembers
; i
++ )
1005 typelib_typedescriptionreference_acquire( ppMembers
[i
] );
1006 pITD
->ppAllMembers
[n
++] = ppMembers
[i
];
1010 typelib_TypeDescription
* pTmp
= &pITD
->aBase
;
1011 static_assert( !TYPELIB_TYPEDESCRIPTIONREFERENCE_ISREALLYWEAK( typelib_TypeClass_INTERFACE
) );
1012 pTmp
->pWeakRef
= reinterpret_cast<typelib_TypeDescriptionReference
*>(pTmp
);
1013 pTmp
->nSize
= typelib_typedescription_getAlignedUnoSize( pTmp
, 0, pTmp
->nAlignment
);
1014 pTmp
->nAlignment
= adjustAlignment( pTmp
->nAlignment
);
1015 pTmp
->bComplete
= false;
1023 typelib_TypeDescriptionReference
** copyExceptions(
1024 sal_Int32 count
, rtl_uString
** typeNames
)
1026 OSL_ASSERT(count
>= 0);
1030 typelib_TypeDescriptionReference
** p
1031 = new typelib_TypeDescriptionReference
*[count
];
1032 for (sal_Int32 i
= 0; i
< count
; ++i
) {
1034 typelib_typedescriptionreference_new(
1035 p
+ i
, typelib_TypeClass_EXCEPTION
, typeNames
[i
]);
1042 extern "C" void SAL_CALL
typelib_typedescription_newInterfaceMethod(
1043 typelib_InterfaceMethodTypeDescription
** ppRet
,
1044 sal_Int32 nAbsolutePosition
,
1046 rtl_uString
* pTypeName
,
1047 typelib_TypeClass eReturnTypeClass
,
1048 rtl_uString
* pReturnTypeName
,
1050 typelib_Parameter_Init
* pParams
,
1051 sal_Int32 nExceptions
,
1052 rtl_uString
** ppExceptionNames
)
1053 SAL_THROW_EXTERN_C()
1055 if (*ppRet
!= nullptr) {
1056 typelib_typedescription_release(&(*ppRet
)->aBase
.aBase
);
1059 sal_Int32 nOffset
= rtl_ustr_lastIndexOfChar_WithLength(
1060 pTypeName
->buffer
, pTypeName
->length
, ':');
1061 if (nOffset
<= 0 || pTypeName
->buffer
[nOffset
- 1] != ':') {
1062 OSL_FAIL("Bad interface method type name");
1065 OUString
aInterfaceTypeName(pTypeName
->buffer
, nOffset
- 1);
1066 typelib_InterfaceTypeDescription
* pInterface
= nullptr;
1067 typelib_typedescription_getByName(
1068 reinterpret_cast< typelib_TypeDescription
** >(&pInterface
),
1069 aInterfaceTypeName
.pData
);
1070 if (pInterface
== nullptr
1071 || pInterface
->aBase
.eTypeClass
!= typelib_TypeClass_INTERFACE
1073 reinterpret_cast< typelib_TypeDescription
** >(&pInterface
), false))
1075 OSL_FAIL("No interface corresponding to interface method");
1079 typelib_typedescription_newEmpty(
1080 reinterpret_cast<typelib_TypeDescription
**>(ppRet
), typelib_TypeClass_INTERFACE_METHOD
, pTypeName
);
1082 rtl_uString_newFromStr_WithLength( &(*ppRet
)->aBase
.pMemberName
,
1083 pTypeName
->buffer
+ nOffset
+1,
1084 pTypeName
->length
- nOffset
-1 );
1085 (*ppRet
)->aBase
.nPosition
= nAbsolutePosition
;
1086 (*ppRet
)->bOneWay
= bOneWay
;
1087 typelib_typedescriptionreference_new( &(*ppRet
)->pReturnTypeRef
, eReturnTypeClass
, pReturnTypeName
);
1088 (*ppRet
)->nParams
= nParams
;
1091 (*ppRet
)->pParams
= new typelib_MethodParameter
[ nParams
];
1093 for( sal_Int32 i
= 0; i
< nParams
; i
++ )
1095 // get the name of the parameter
1096 (*ppRet
)->pParams
[ i
].pName
= pParams
[i
].pParamName
;
1097 rtl_uString_acquire( (*ppRet
)->pParams
[ i
].pName
);
1098 (*ppRet
)->pParams
[ i
].pTypeRef
= nullptr;
1099 // get the type name of the parameter and create the weak reference
1100 typelib_typedescriptionreference_new(
1101 &(*ppRet
)->pParams
[ i
].pTypeRef
, pParams
[i
].eTypeClass
, pParams
[i
].pTypeName
);
1102 (*ppRet
)->pParams
[ i
].bIn
= pParams
[i
].bIn
;
1103 (*ppRet
)->pParams
[ i
].bOut
= pParams
[i
].bOut
;
1106 (*ppRet
)->nExceptions
= nExceptions
;
1107 (*ppRet
)->ppExceptions
= copyExceptions(nExceptions
, ppExceptionNames
);
1108 (*ppRet
)->pInterface
= pInterface
;
1109 (*ppRet
)->pBaseRef
= nullptr;
1111 (nAbsolutePosition
>= pInterface
->nAllMembers
- pInterface
->nMembers
)
1112 && nAbsolutePosition
< pInterface
->nAllMembers
);
1113 (*ppRet
)->nIndex
= nAbsolutePosition
1114 - (pInterface
->nAllMembers
- pInterface
->nMembers
);
1115 static_assert( TYPELIB_TYPEDESCRIPTIONREFERENCE_ISREALLYWEAK( typelib_TypeClass_INTERFACE_METHOD
) );
1116 assert(reinterpret_cast<typelib_TypeDescription
*>(*ppRet
)->pWeakRef
== nullptr);
1120 extern "C" void SAL_CALL
typelib_typedescription_newInterfaceAttribute(
1121 typelib_InterfaceAttributeTypeDescription
** ppRet
,
1122 sal_Int32 nAbsolutePosition
,
1123 rtl_uString
* pTypeName
,
1124 typelib_TypeClass eAttributeTypeClass
,
1125 rtl_uString
* pAttributeTypeName
,
1126 sal_Bool bReadOnly
)
1127 SAL_THROW_EXTERN_C()
1129 typelib_typedescription_newExtendedInterfaceAttribute(
1130 ppRet
, nAbsolutePosition
, pTypeName
, eAttributeTypeClass
,
1131 pAttributeTypeName
, bReadOnly
, 0, nullptr, 0, nullptr);
1135 extern "C" void SAL_CALL
typelib_typedescription_newExtendedInterfaceAttribute(
1136 typelib_InterfaceAttributeTypeDescription
** ppRet
,
1137 sal_Int32 nAbsolutePosition
,
1138 rtl_uString
* pTypeName
,
1139 typelib_TypeClass eAttributeTypeClass
,
1140 rtl_uString
* pAttributeTypeName
,
1142 sal_Int32 nGetExceptions
, rtl_uString
** ppGetExceptionNames
,
1143 sal_Int32 nSetExceptions
, rtl_uString
** ppSetExceptionNames
)
1144 SAL_THROW_EXTERN_C()
1146 if (*ppRet
!= nullptr) {
1147 typelib_typedescription_release(&(*ppRet
)->aBase
.aBase
);
1150 sal_Int32 nOffset
= rtl_ustr_lastIndexOfChar_WithLength(
1151 pTypeName
->buffer
, pTypeName
->length
, ':');
1152 if (nOffset
<= 0 || pTypeName
->buffer
[nOffset
- 1] != ':') {
1153 OSL_FAIL("Bad interface attribute type name");
1156 OUString
aInterfaceTypeName(pTypeName
->buffer
, nOffset
- 1);
1157 typelib_InterfaceTypeDescription
* pInterface
= nullptr;
1158 typelib_typedescription_getByName(
1159 reinterpret_cast< typelib_TypeDescription
** >(&pInterface
),
1160 aInterfaceTypeName
.pData
);
1161 if (pInterface
== nullptr
1162 || pInterface
->aBase
.eTypeClass
!= typelib_TypeClass_INTERFACE
1164 reinterpret_cast< typelib_TypeDescription
** >(&pInterface
), false))
1166 OSL_FAIL("No interface corresponding to interface attribute");
1170 typelib_typedescription_newEmpty(
1171 reinterpret_cast<typelib_TypeDescription
**>(ppRet
), typelib_TypeClass_INTERFACE_ATTRIBUTE
, pTypeName
);
1173 rtl_uString_newFromStr_WithLength( &(*ppRet
)->aBase
.pMemberName
,
1174 pTypeName
->buffer
+ nOffset
+1,
1175 pTypeName
->length
- nOffset
-1 );
1176 (*ppRet
)->aBase
.nPosition
= nAbsolutePosition
;
1177 typelib_typedescriptionreference_new( &(*ppRet
)->pAttributeTypeRef
, eAttributeTypeClass
, pAttributeTypeName
);
1178 (*ppRet
)->bReadOnly
= bReadOnly
;
1179 (*ppRet
)->pInterface
= pInterface
;
1180 (*ppRet
)->pBaseRef
= nullptr;
1182 (nAbsolutePosition
>= pInterface
->nAllMembers
- pInterface
->nMembers
)
1183 && nAbsolutePosition
< pInterface
->nAllMembers
);
1184 (*ppRet
)->nIndex
= nAbsolutePosition
1185 - (pInterface
->nAllMembers
- pInterface
->nMembers
);
1186 (*ppRet
)->nGetExceptions
= nGetExceptions
;
1187 (*ppRet
)->ppGetExceptions
= copyExceptions(
1188 nGetExceptions
, ppGetExceptionNames
);
1189 (*ppRet
)->nSetExceptions
= nSetExceptions
;
1190 (*ppRet
)->ppSetExceptions
= copyExceptions(
1191 nSetExceptions
, ppSetExceptionNames
);
1192 static_assert( TYPELIB_TYPEDESCRIPTIONREFERENCE_ISREALLYWEAK( typelib_TypeClass_INTERFACE_ATTRIBUTE
) );
1193 assert(reinterpret_cast<typelib_TypeDescription
*>(*ppRet
)->pWeakRef
== nullptr);
1197 extern "C" void SAL_CALL
typelib_typedescription_acquire(
1198 typelib_TypeDescription
* pTypeDescription
)
1199 SAL_THROW_EXTERN_C()
1201 osl_atomic_increment( &pTypeDescription
->nRefCount
);
1207 void deleteExceptions(
1208 sal_Int32 count
, typelib_TypeDescriptionReference
** exceptions
)
1210 for (sal_Int32 i
= 0; i
< count
; ++i
) {
1211 typelib_typedescriptionreference_release(exceptions
[i
]);
1213 delete[] exceptions
;
1218 // frees anything except typelib_TypeDescription base!
1219 static void typelib_typedescription_destructExtendedMembers(
1220 typelib_TypeDescription
* pTD
)
1222 OSL_ASSERT( typelib_TypeClass_TYPEDEF
!= pTD
->eTypeClass
);
1224 switch( pTD
->eTypeClass
)
1226 case typelib_TypeClass_SEQUENCE
:
1227 if( reinterpret_cast<typelib_IndirectTypeDescription
*>(pTD
)->pType
)
1228 typelib_typedescriptionreference_release( reinterpret_cast<typelib_IndirectTypeDescription
*>(pTD
)->pType
);
1230 case typelib_TypeClass_STRUCT
:
1231 delete[] reinterpret_cast< typelib_StructTypeDescription
* >(pTD
)->
1232 pParameterizedTypes
;
1234 case typelib_TypeClass_EXCEPTION
:
1236 typelib_CompoundTypeDescription
* pCTD
= reinterpret_cast<typelib_CompoundTypeDescription
*>(pTD
);
1237 if( pCTD
->pBaseTypeDescription
)
1238 typelib_typedescription_release( &pCTD
->pBaseTypeDescription
->aBase
);
1240 for( i
= 0; i
< pCTD
->nMembers
; i
++ )
1242 typelib_typedescriptionreference_release( pCTD
->ppTypeRefs
[i
] );
1244 if (pCTD
->ppMemberNames
)
1246 for ( i
= 0; i
< pCTD
->nMembers
; i
++ )
1248 rtl_uString_release( pCTD
->ppMemberNames
[i
] );
1250 delete [] pCTD
->ppMemberNames
;
1252 delete [] pCTD
->ppTypeRefs
;
1253 delete [] pCTD
->pMemberOffsets
;
1256 case typelib_TypeClass_INTERFACE
:
1258 typelib_InterfaceTypeDescription
* pITD
= reinterpret_cast<typelib_InterfaceTypeDescription
*>(pTD
);
1259 for( sal_Int32 i
= 0; i
< pITD
->nAllMembers
; i
++ )
1261 typelib_typedescriptionreference_release( pITD
->ppAllMembers
[i
] );
1263 delete [] pITD
->ppAllMembers
;
1264 delete [] pITD
->pMapMemberIndexToFunctionIndex
;
1265 delete [] pITD
->pMapFunctionIndexToMemberIndex
;
1266 for (sal_Int32 i
= 0; i
< pITD
->nBaseTypes
; ++i
) {
1267 typelib_typedescription_release(
1268 reinterpret_cast< typelib_TypeDescription
* >(
1269 pITD
->ppBaseTypes
[i
]));
1271 delete[] pITD
->ppBaseTypes
;
1274 case typelib_TypeClass_INTERFACE_METHOD
:
1276 typelib_InterfaceMethodTypeDescription
* pIMTD
= reinterpret_cast<typelib_InterfaceMethodTypeDescription
*>(pTD
);
1277 if( pIMTD
->pReturnTypeRef
)
1278 typelib_typedescriptionreference_release( pIMTD
->pReturnTypeRef
);
1279 for( sal_Int32 i
= 0; i
< pIMTD
->nParams
; i
++ )
1281 rtl_uString_release( pIMTD
->pParams
[ i
].pName
);
1282 typelib_typedescriptionreference_release( pIMTD
->pParams
[ i
].pTypeRef
);
1284 delete [] pIMTD
->pParams
;
1285 deleteExceptions(pIMTD
->nExceptions
, pIMTD
->ppExceptions
);
1286 rtl_uString_release( pIMTD
->aBase
.pMemberName
);
1287 typelib_typedescription_release(&pIMTD
->pInterface
->aBase
);
1288 if (pIMTD
->pBaseRef
!= nullptr) {
1289 typelib_typedescriptionreference_release(pIMTD
->pBaseRef
);
1293 case typelib_TypeClass_INTERFACE_ATTRIBUTE
:
1295 typelib_InterfaceAttributeTypeDescription
* pIATD
= reinterpret_cast<typelib_InterfaceAttributeTypeDescription
*>(pTD
);
1296 deleteExceptions(pIATD
->nGetExceptions
, pIATD
->ppGetExceptions
);
1297 deleteExceptions(pIATD
->nSetExceptions
, pIATD
->ppSetExceptions
);
1298 if( pIATD
->pAttributeTypeRef
)
1299 typelib_typedescriptionreference_release( pIATD
->pAttributeTypeRef
);
1300 if( pIATD
->aBase
.pMemberName
)
1301 rtl_uString_release( pIATD
->aBase
.pMemberName
);
1302 typelib_typedescription_release(&pIATD
->pInterface
->aBase
);
1303 if (pIATD
->pBaseRef
!= nullptr) {
1304 typelib_typedescriptionreference_release(pIATD
->pBaseRef
);
1308 case typelib_TypeClass_ENUM
:
1310 typelib_EnumTypeDescription
* pEnum
= reinterpret_cast<typelib_EnumTypeDescription
*>(pTD
);
1311 for ( sal_Int32 nPos
= pEnum
->nEnumValues
; nPos
--; )
1313 rtl_uString_release( pEnum
->ppEnumNames
[nPos
] );
1315 delete [] pEnum
->ppEnumNames
;
1316 delete [] pEnum
->pEnumValues
;
1325 extern "C" void SAL_CALL
typelib_typedescription_release(
1326 typelib_TypeDescription
* pTD
)
1327 SAL_THROW_EXTERN_C()
1329 sal_Int32 ref
= osl_atomic_decrement( &pTD
->nRefCount
);
1330 OSL_ASSERT(ref
>= 0);
1334 TypeDescriptor_Init_Impl
&rInit
= Init();
1335 if( TYPELIB_TYPEDESCRIPTIONREFERENCE_ISREALLYWEAK( pTD
->eTypeClass
) )
1340 MutexGuard
aGuard( rInit
.maMutex
);
1341 // remove this description from the weak reference
1342 pTD
->pWeakRef
->pType
= nullptr;
1344 typelib_typedescriptionreference_release( pTD
->pWeakRef
);
1349 // this description is a reference too, so remove it from the hash table
1350 MutexGuard
aGuard( rInit
.maMutex
);
1351 WeakMap_Impl::iterator aIt
= rInit
.maWeakMap
.find( pTD
->pTypeName
->buffer
);
1352 if( aIt
!= rInit
.maWeakMap
.end() && static_cast<void *>((*aIt
).second
) == static_cast<void *>(pTD
) )
1354 // remove only if it contains the same object
1355 rInit
.maWeakMap
.erase( aIt
);
1359 typelib_typedescription_destructExtendedMembers( pTD
);
1360 rtl_uString_release( pTD
->pTypeName
);
1362 #if OSL_DEBUG_LEVEL > 0
1363 switch( pTD
->eTypeClass
)
1365 case typelib_TypeClass_SEQUENCE
:
1366 osl_atomic_decrement( &rInit
.nIndirectTypeDescriptionCount
);
1368 case typelib_TypeClass_STRUCT
:
1369 case typelib_TypeClass_EXCEPTION
:
1370 osl_atomic_decrement( &rInit
.nCompoundTypeDescriptionCount
);
1372 case typelib_TypeClass_INTERFACE
:
1373 osl_atomic_decrement( &rInit
.nInterfaceTypeDescriptionCount
);
1375 case typelib_TypeClass_INTERFACE_METHOD
:
1376 osl_atomic_decrement( &rInit
.nInterfaceMethodTypeDescriptionCount
);
1378 case typelib_TypeClass_INTERFACE_ATTRIBUTE
:
1379 osl_atomic_decrement( &rInit
.nInterfaceAttributeTypeDescriptionCount
);
1381 case typelib_TypeClass_ENUM
:
1382 osl_atomic_decrement( &rInit
.nEnumTypeDescriptionCount
);
1385 osl_atomic_decrement( &rInit
.nTypeDescriptionCount
);
1389 freeTypeDescription(pTD
);
1393 extern "C" void SAL_CALL
typelib_typedescription_register(
1394 typelib_TypeDescription
** ppNewDescription
)
1395 SAL_THROW_EXTERN_C()
1397 // connect the description with the weak reference
1398 TypeDescriptor_Init_Impl
&rInit
= Init();
1399 ClearableMutexGuard
aGuard( rInit
.maMutex
);
1401 typelib_TypeDescriptionReference
* pTDR
= nullptr;
1402 typelib_typedescriptionreference_getByName( &pTDR
, (*ppNewDescription
)->pTypeName
);
1404 OSL_ASSERT( (*ppNewDescription
)->pWeakRef
|| TYPELIB_TYPEDESCRIPTIONREFERENCE_ISREALLYWEAK( (*ppNewDescription
)->eTypeClass
) );
1407 OSL_ASSERT( (*ppNewDescription
)->eTypeClass
== pTDR
->eTypeClass
);
1410 if (TYPELIB_TYPEDESCRIPTIONREFERENCE_ISREALLYWEAK( pTDR
->eTypeClass
))
1412 // pRef->pType->pWeakRef == 0 means that the description is empty
1413 if (pTDR
->pType
->pWeakRef
)
1415 if (osl_atomic_increment( &pTDR
->pType
->nRefCount
) > 1)
1417 // The reference is incremented. The object cannot be destroyed.
1418 // Release the guard at the earliest point.
1420 ::typelib_typedescription_release( *ppNewDescription
);
1421 *ppNewDescription
= pTDR
->pType
;
1422 ::typelib_typedescriptionreference_release( pTDR
);
1425 // destruction of this type in progress (another thread!)
1426 (void)osl_atomic_decrement( &pTDR
->pType
->nRefCount
);
1429 pTDR
->pType
= *ppNewDescription
;
1430 OSL_ASSERT( ! (*ppNewDescription
)->pWeakRef
);
1431 (*ppNewDescription
)->pWeakRef
= pTDR
;
1436 if ((static_cast<void *>(pTDR
) != static_cast<void *>(*ppNewDescription
)) && // if different
1437 (!pTDR
->pType
->pWeakRef
|| // uninit: ref data only set
1438 // new one is complete:
1439 (!pTDR
->pType
->bComplete
&& (*ppNewDescription
)->bComplete
) ||
1440 // new one may be partly initialized interface (except of tables):
1441 (typelib_TypeClass_INTERFACE
== pTDR
->pType
->eTypeClass
&&
1442 !reinterpret_cast<typelib_InterfaceTypeDescription
*>(pTDR
->pType
)->ppAllMembers
&&
1443 (*reinterpret_cast<typelib_InterfaceTypeDescription
**>(ppNewDescription
))->ppAllMembers
)))
1445 // uninitialized or incomplete
1447 if (pTDR
->pType
->pWeakRef
) // if init
1449 switch (pTDR
->pType
->eTypeClass
) {
1450 case typelib_TypeClass_ENUM
:
1452 auto const src
= reinterpret_cast<typelib_EnumTypeDescription
*>(
1454 auto const dst
= reinterpret_cast<typelib_EnumTypeDescription
*>(
1456 assert(dst
->nEnumValues
== 0);
1457 assert(dst
->ppEnumNames
== nullptr);
1458 assert(dst
->pEnumValues
== nullptr);
1459 std::swap(src
->nEnumValues
, dst
->nEnumValues
);
1460 std::swap(src
->ppEnumNames
, dst
->ppEnumNames
);
1461 std::swap(src
->pEnumValues
, dst
->pEnumValues
);
1464 case typelib_TypeClass_STRUCT
:
1465 case typelib_TypeClass_EXCEPTION
:
1467 auto const src
= reinterpret_cast<typelib_CompoundTypeDescription
*>(
1469 auto const dst
= reinterpret_cast<typelib_CompoundTypeDescription
*>(
1472 (dst
->pBaseTypeDescription
== nullptr)
1473 == (src
->pBaseTypeDescription
== nullptr));
1474 assert(dst
->nMembers
== src
->nMembers
);
1475 assert((dst
->pMemberOffsets
== nullptr) == (dst
->nMembers
== 0));
1476 assert((dst
->ppTypeRefs
== nullptr) == (dst
->nMembers
== 0));
1477 assert(dst
->ppMemberNames
== nullptr);
1479 pTDR
->pType
->eTypeClass
!= typelib_TypeClass_STRUCT
1480 || ((reinterpret_cast<typelib_StructTypeDescription
*>(
1481 dst
)->pParameterizedTypes
1483 == (reinterpret_cast<typelib_StructTypeDescription
*>(
1484 src
)->pParameterizedTypes
1486 std::swap(src
->ppMemberNames
, dst
->ppMemberNames
);
1489 case typelib_TypeClass_INTERFACE
:
1491 auto const src
= reinterpret_cast<typelib_InterfaceTypeDescription
*>(
1493 auto const dst
= reinterpret_cast<typelib_InterfaceTypeDescription
*>(
1496 (dst
->pBaseTypeDescription
== nullptr)
1497 == (src
->pBaseTypeDescription
== nullptr));
1498 assert(dst
->nMembers
== 0);
1499 assert(dst
->ppMembers
== nullptr);
1500 assert(dst
->nAllMembers
== 0);
1501 assert(dst
->ppAllMembers
== nullptr);
1502 assert(dst
->pMapMemberIndexToFunctionIndex
== nullptr);
1503 assert(dst
->nMapFunctionIndexToMemberIndex
== 0);
1504 assert(dst
->pMapFunctionIndexToMemberIndex
== nullptr);
1505 assert(dst
->nBaseTypes
== src
->nBaseTypes
);
1506 assert((dst
->ppBaseTypes
== nullptr) == (src
->ppBaseTypes
== nullptr));
1507 std::swap(src
->nMembers
, dst
->nMembers
);
1508 std::swap(src
->ppMembers
, dst
->ppMembers
);
1509 std::swap(src
->nAllMembers
, dst
->nAllMembers
);
1510 std::swap(src
->ppAllMembers
, dst
->ppAllMembers
);
1512 src
->pMapMemberIndexToFunctionIndex
,
1513 dst
->pMapMemberIndexToFunctionIndex
);
1515 src
->nMapFunctionIndexToMemberIndex
,
1516 dst
->nMapFunctionIndexToMemberIndex
);
1518 src
->pMapFunctionIndexToMemberIndex
,
1519 dst
->pMapFunctionIndexToMemberIndex
);
1523 assert(false); // this cannot happen
1528 // pTDR->pType->pWeakRef == 0 means that the description is empty
1529 // description is not weak and the not the same
1530 sal_Int32 nSize
= getDescriptionSize( (*ppNewDescription
)->eTypeClass
);
1532 // copy all specific data for the descriptions
1535 *ppNewDescription
+1,
1536 nSize
- sizeof(typelib_TypeDescription
) );
1539 *ppNewDescription
+1,
1541 nSize
- sizeof( typelib_TypeDescription
) );
1544 pTDR
->pType
->bComplete
= (*ppNewDescription
)->bComplete
;
1545 pTDR
->pType
->nSize
= (*ppNewDescription
)->nSize
;
1546 pTDR
->pType
->nAlignment
= (*ppNewDescription
)->nAlignment
;
1548 if( pTDR
->pType
->bOnDemand
&& !(*ppNewDescription
)->bOnDemand
)
1550 // switch from OnDemand to !OnDemand, so the description must be acquired
1551 typelib_typedescription_acquire( pTDR
->pType
);
1553 else if( !pTDR
->pType
->bOnDemand
&& (*ppNewDescription
)->bOnDemand
)
1555 // switch from !OnDemand to OnDemand, so the description must be released
1556 assert(pTDR
->pType
->nRefCount
> 1);
1557 // coverity[freed_arg] - pType's nRefCount is > 1 here
1558 typelib_typedescription_release( pTDR
->pType
);
1561 pTDR
->pType
->bOnDemand
= (*ppNewDescription
)->bOnDemand
;
1563 pTDR
->pType
->pWeakRef
= pTDR
;
1566 typelib_typedescription_release( *ppNewDescription
);
1567 // pTDR was acquired by getByName(), so it must not be acquired again
1568 *ppNewDescription
= pTDR
->pType
;
1572 else if( TYPELIB_TYPEDESCRIPTIONREFERENCE_ISREALLYWEAK( (*ppNewDescription
)->eTypeClass
) )
1574 typelib_typedescriptionreference_new(
1575 &pTDR
, (*ppNewDescription
)->eTypeClass
, (*ppNewDescription
)->pTypeName
);
1579 pTDR
= reinterpret_cast<typelib_TypeDescriptionReference
*>(*ppNewDescription
);
1581 // description is the weak itself, so register it
1582 rInit
.maWeakMap
[pTDR
->pTypeName
->buffer
] = pTDR
;
1583 OSL_ASSERT( static_cast<void *>(*ppNewDescription
) == static_cast<void *>(pTDR
) );
1586 // By default this reference is not really weak. The reference hold the description
1587 // and the description hold the reference.
1588 if( !(*ppNewDescription
)->bOnDemand
)
1590 // nor OnDemand so the description must be acquired if registered
1591 typelib_typedescription_acquire( *ppNewDescription
);
1594 pTDR
->pType
= *ppNewDescription
;
1595 (*ppNewDescription
)->pWeakRef
= pTDR
;
1596 OSL_ASSERT( rtl_ustr_compare( pTDR
->pTypeName
->buffer
, (*ppNewDescription
)->pTypeName
->buffer
) == 0 );
1597 OSL_ASSERT( pTDR
->eTypeClass
== (*ppNewDescription
)->eTypeClass
);
1601 static bool type_equals(
1602 typelib_TypeDescriptionReference
const * p1
, typelib_TypeDescriptionReference
const * p2
)
1605 (p1
->eTypeClass
== p2
->eTypeClass
&&
1606 p1
->pTypeName
->length
== p2
->pTypeName
->length
&&
1607 rtl_ustr_compare( p1
->pTypeName
->buffer
, p2
->pTypeName
->buffer
) == 0));
1609 extern "C" sal_Bool SAL_CALL
typelib_typedescription_equals(
1610 const typelib_TypeDescription
* p1
, const typelib_TypeDescription
* p2
)
1611 SAL_THROW_EXTERN_C()
1614 reinterpret_cast<typelib_TypeDescriptionReference
const *>(p1
), reinterpret_cast<typelib_TypeDescriptionReference
const *>(p2
) );
1618 extern "C" sal_Int32
typelib_typedescription_getAlignedUnoSize(
1619 const typelib_TypeDescription
* pTypeDescription
,
1620 sal_Int32 nOffset
, sal_Int32
& rMaxIntegralTypeSize
)
1621 SAL_THROW_EXTERN_C()
1624 if( pTypeDescription
->nSize
)
1626 // size and alignment are set
1627 rMaxIntegralTypeSize
= pTypeDescription
->nAlignment
;
1628 nSize
= pTypeDescription
->nSize
;
1633 rMaxIntegralTypeSize
= 1;
1635 OSL_ASSERT( typelib_TypeClass_TYPEDEF
!= pTypeDescription
->eTypeClass
);
1637 switch( pTypeDescription
->eTypeClass
)
1639 case typelib_TypeClass_INTERFACE
:
1640 // FEATURE_INTERFACE
1641 nSize
= rMaxIntegralTypeSize
= sal_Int32(sizeof( void * ));
1643 case typelib_TypeClass_ENUM
:
1644 nSize
= rMaxIntegralTypeSize
= sal_Int32(sizeof( typelib_TypeClass
));
1646 case typelib_TypeClass_STRUCT
:
1647 case typelib_TypeClass_EXCEPTION
:
1648 // FEATURE_EMPTYCLASS
1650 typelib_CompoundTypeDescription
const * pTmp
= reinterpret_cast<typelib_CompoundTypeDescription
const *>(pTypeDescription
);
1651 sal_Int32 nStructSize
= 0;
1652 if( pTmp
->pBaseTypeDescription
)
1654 // inherit structs extends the base struct.
1655 nStructSize
= pTmp
->pBaseTypeDescription
->aBase
.nSize
;
1656 rMaxIntegralTypeSize
= pTmp
->pBaseTypeDescription
->aBase
.nAlignment
;
1658 for( sal_Int32 i
= 0; i
< pTmp
->nMembers
; i
++ )
1660 typelib_TypeDescription
* pMemberType
= nullptr;
1661 typelib_TypeDescriptionReference
* pMemberRef
= pTmp
->ppTypeRefs
[i
];
1663 sal_Int32 nMaxIntegral
;
1664 if (pMemberRef
->eTypeClass
== typelib_TypeClass_INTERFACE
1665 || pMemberRef
->eTypeClass
== typelib_TypeClass_SEQUENCE
)
1667 nMaxIntegral
= sal_Int32(sizeof(void *));
1668 nStructSize
= newAlignedSize( nStructSize
, nMaxIntegral
, nMaxIntegral
);
1672 TYPELIB_DANGER_GET( &pMemberType
, pMemberRef
);
1673 nStructSize
= typelib_typedescription_getAlignedUnoSize(
1674 pMemberType
, nStructSize
, nMaxIntegral
);
1675 TYPELIB_DANGER_RELEASE( pMemberType
);
1677 if( nMaxIntegral
> rMaxIntegralTypeSize
)
1678 rMaxIntegralTypeSize
= nMaxIntegral
;
1681 // Anything that is at least 16 bits wide is aligned on a 16-bit
1682 // boundary on the m68k default abi
1683 sal_Int32 nMaxAlign
= std::min(rMaxIntegralTypeSize
, sal_Int32( 2 ));
1684 nStructSize
= (nStructSize
+ nMaxAlign
-1) / nMaxAlign
* nMaxAlign
;
1686 // Example: A { double; int; } structure has a size of 16 instead of 10. The
1687 // compiler must follow this rule if it is possible to access members in arrays through:
1688 // (Element *)((char *)pArray + sizeof( Element ) * ElementPos)
1689 nStructSize
= (nStructSize
+ rMaxIntegralTypeSize
-1)
1690 / rMaxIntegralTypeSize
* rMaxIntegralTypeSize
;
1692 nSize
+= nStructSize
;
1695 case typelib_TypeClass_SEQUENCE
:
1696 nSize
= rMaxIntegralTypeSize
= sal_Int32(sizeof( void * ));
1698 case typelib_TypeClass_ANY
:
1700 nSize
= sal_Int32(sizeof( uno_Any
));
1701 rMaxIntegralTypeSize
= sal_Int32(sizeof( void * ));
1703 case typelib_TypeClass_TYPE
:
1704 nSize
= rMaxIntegralTypeSize
= sal_Int32(sizeof( typelib_TypeDescriptionReference
* ));
1706 case typelib_TypeClass_BOOLEAN
:
1707 nSize
= rMaxIntegralTypeSize
= sal_Int32(sizeof( sal_Bool
));
1709 case typelib_TypeClass_CHAR
:
1710 nSize
= rMaxIntegralTypeSize
= sal_Int32(sizeof( sal_Unicode
));
1712 case typelib_TypeClass_STRING
:
1714 nSize
= rMaxIntegralTypeSize
= sal_Int32(sizeof( rtl_uString
* ));
1716 case typelib_TypeClass_FLOAT
:
1717 nSize
= rMaxIntegralTypeSize
= sal_Int32(sizeof( float ));
1719 case typelib_TypeClass_DOUBLE
:
1720 nSize
= rMaxIntegralTypeSize
= sal_Int32(sizeof( double ));
1722 case typelib_TypeClass_BYTE
:
1723 nSize
= rMaxIntegralTypeSize
= sal_Int32(sizeof( sal_Int8
));
1725 case typelib_TypeClass_SHORT
:
1726 case typelib_TypeClass_UNSIGNED_SHORT
:
1727 nSize
= rMaxIntegralTypeSize
= sal_Int32(sizeof( sal_Int16
));
1729 case typelib_TypeClass_LONG
:
1730 case typelib_TypeClass_UNSIGNED_LONG
:
1731 nSize
= rMaxIntegralTypeSize
= sal_Int32(sizeof( sal_Int32
));
1733 case typelib_TypeClass_HYPER
:
1734 case typelib_TypeClass_UNSIGNED_HYPER
:
1735 nSize
= rMaxIntegralTypeSize
= sal_Int32(sizeof( sal_Int64
));
1737 case typelib_TypeClass_UNKNOWN
:
1738 case typelib_TypeClass_SERVICE
:
1739 case typelib_TypeClass_MODULE
:
1741 OSL_FAIL( "not convertible type" );
1745 return newAlignedSize( nOffset
, nSize
, rMaxIntegralTypeSize
);
1751 typelib_TypeDescriptionReference
** copyExceptions(
1752 sal_Int32 count
, typelib_TypeDescriptionReference
** source
)
1754 typelib_TypeDescriptionReference
** p
1755 = new typelib_TypeDescriptionReference
*[count
];
1756 for (sal_Int32 i
= 0; i
< count
; ++i
) {
1758 typelib_typedescriptionreference_acquire(p
[i
]);
1763 bool createDerivedInterfaceMemberDescription(
1764 typelib_TypeDescription
** result
, OUString
const & name
,
1765 typelib_TypeDescriptionReference
* baseRef
,
1766 typelib_TypeDescription
const * base
, typelib_TypeDescription
* interface
,
1767 sal_Int32 index
, sal_Int32 position
)
1769 if (!baseRef
|| !base
|| !interface
)
1772 switch (base
->eTypeClass
) {
1773 case typelib_TypeClass_INTERFACE_METHOD
:
1775 typelib_typedescription_newEmpty(
1776 result
, typelib_TypeClass_INTERFACE_METHOD
, name
.pData
);
1777 typelib_InterfaceMethodTypeDescription
const * baseMethod
1779 typelib_InterfaceMethodTypeDescription
const * >(base
);
1780 typelib_InterfaceMethodTypeDescription
* newMethod
1782 typelib_InterfaceMethodTypeDescription
* >(*result
);
1783 newMethod
->aBase
.nPosition
= position
;
1784 newMethod
->aBase
.pMemberName
1785 = baseMethod
->aBase
.pMemberName
;
1786 rtl_uString_acquire(
1787 newMethod
->aBase
.pMemberName
);
1788 newMethod
->pReturnTypeRef
= baseMethod
->pReturnTypeRef
;
1789 typelib_typedescriptionreference_acquire(
1790 newMethod
->pReturnTypeRef
);
1791 newMethod
->nParams
= baseMethod
->nParams
;
1792 newMethod
->pParams
= new typelib_MethodParameter
[
1793 newMethod
->nParams
];
1794 for (sal_Int32 i
= 0; i
< newMethod
->nParams
; ++i
) {
1795 newMethod
->pParams
[i
].pName
1796 = baseMethod
->pParams
[i
].pName
;
1797 rtl_uString_acquire(
1798 newMethod
->pParams
[i
].pName
);
1799 newMethod
->pParams
[i
].pTypeRef
1800 = baseMethod
->pParams
[i
].pTypeRef
;
1801 typelib_typedescriptionreference_acquire(
1802 newMethod
->pParams
[i
].pTypeRef
);
1803 newMethod
->pParams
[i
].bIn
= baseMethod
->pParams
[i
].bIn
;
1804 newMethod
->pParams
[i
].bOut
= baseMethod
->pParams
[i
].bOut
;
1806 newMethod
->nExceptions
= baseMethod
->nExceptions
;
1807 newMethod
->ppExceptions
= copyExceptions(
1808 baseMethod
->nExceptions
, baseMethod
->ppExceptions
);
1809 newMethod
->bOneWay
= baseMethod
->bOneWay
;
1810 newMethod
->pInterface
1811 = reinterpret_cast< typelib_InterfaceTypeDescription
* >(
1813 newMethod
->pBaseRef
= baseRef
;
1814 newMethod
->nIndex
= index
;
1818 case typelib_TypeClass_INTERFACE_ATTRIBUTE
:
1820 typelib_typedescription_newEmpty(
1821 result
, typelib_TypeClass_INTERFACE_ATTRIBUTE
, name
.pData
);
1822 typelib_InterfaceAttributeTypeDescription
const * baseAttribute
1824 typelib_InterfaceAttributeTypeDescription
const * >(base
);
1825 typelib_InterfaceAttributeTypeDescription
* newAttribute
1827 typelib_InterfaceAttributeTypeDescription
* >(*result
);
1828 newAttribute
->aBase
.nPosition
= position
;
1829 newAttribute
->aBase
.pMemberName
1830 = baseAttribute
->aBase
.pMemberName
;
1831 rtl_uString_acquire(newAttribute
->aBase
.pMemberName
);
1832 newAttribute
->bReadOnly
= baseAttribute
->bReadOnly
;
1833 newAttribute
->pAttributeTypeRef
1834 = baseAttribute
->pAttributeTypeRef
;
1835 typelib_typedescriptionreference_acquire(newAttribute
->pAttributeTypeRef
);
1836 newAttribute
->pInterface
1837 = reinterpret_cast< typelib_InterfaceTypeDescription
* >(
1839 newAttribute
->pBaseRef
= baseRef
;
1840 newAttribute
->nIndex
= index
;
1841 newAttribute
->nGetExceptions
= baseAttribute
->nGetExceptions
;
1842 newAttribute
->ppGetExceptions
= copyExceptions(
1843 baseAttribute
->nGetExceptions
,
1844 baseAttribute
->ppGetExceptions
);
1845 newAttribute
->nSetExceptions
= baseAttribute
->nSetExceptions
;
1846 newAttribute
->ppSetExceptions
= copyExceptions(
1847 baseAttribute
->nSetExceptions
,
1848 baseAttribute
->ppSetExceptions
);
1860 extern "C" void SAL_CALL
typelib_typedescription_getByName(
1861 typelib_TypeDescription
** ppRet
, rtl_uString
* pName
)
1862 SAL_THROW_EXTERN_C()
1866 typelib_typedescription_release( *ppRet
);
1870 static bool bInited
= false;
1871 TypeDescriptor_Init_Impl
&rInit
= Init();
1875 // guard against multi thread access
1876 MutexGuard
aGuard( rInit
.maMutex
);
1879 // avoid recursion during the next ...new calls
1882 typelib_TypeDescription
* pType
= nullptr;
1883 typelib_typedescription_new( &pType
, typelib_TypeClass_TYPE
, OUString("type").pData
, nullptr, 0, nullptr );
1884 typelib_typedescription_register( &pType
);
1885 typelib_typedescription_new( &pType
, typelib_TypeClass_VOID
, OUString("void").pData
, nullptr, 0, nullptr );
1886 typelib_typedescription_register( &pType
);
1887 typelib_typedescription_new( &pType
, typelib_TypeClass_BOOLEAN
, OUString("boolean").pData
, nullptr, 0, nullptr );
1888 typelib_typedescription_register( &pType
);
1889 typelib_typedescription_new( &pType
, typelib_TypeClass_CHAR
, OUString("char").pData
, nullptr, 0, nullptr );
1890 typelib_typedescription_register( &pType
);
1891 typelib_typedescription_new( &pType
, typelib_TypeClass_BYTE
, OUString("byte").pData
, nullptr, 0, nullptr );
1892 typelib_typedescription_register( &pType
);
1893 typelib_typedescription_new( &pType
, typelib_TypeClass_STRING
, OUString("string").pData
, nullptr, 0, nullptr );
1894 typelib_typedescription_register( &pType
);
1895 typelib_typedescription_new( &pType
, typelib_TypeClass_SHORT
, OUString("short").pData
, nullptr, 0, nullptr );
1896 typelib_typedescription_register( &pType
);
1897 typelib_typedescription_new( &pType
, typelib_TypeClass_UNSIGNED_SHORT
, OUString("unsigned short").pData
, nullptr, 0, nullptr );
1898 typelib_typedescription_register( &pType
);
1899 typelib_typedescription_new( &pType
, typelib_TypeClass_LONG
, OUString("long").pData
, nullptr, 0, nullptr );
1900 typelib_typedescription_register( &pType
);
1901 typelib_typedescription_new( &pType
, typelib_TypeClass_UNSIGNED_LONG
, OUString("unsigned long").pData
, nullptr, 0, nullptr );
1902 typelib_typedescription_register( &pType
);
1903 typelib_typedescription_new( &pType
, typelib_TypeClass_HYPER
, OUString("hyper").pData
, nullptr, 0, nullptr );
1904 typelib_typedescription_register( &pType
);
1905 typelib_typedescription_new( &pType
, typelib_TypeClass_UNSIGNED_HYPER
, OUString("unsigned hyper").pData
, nullptr, 0, nullptr );
1906 typelib_typedescription_register( &pType
);
1907 typelib_typedescription_new( &pType
, typelib_TypeClass_FLOAT
, OUString("float").pData
, nullptr, 0, nullptr );
1908 typelib_typedescription_register( &pType
);
1909 typelib_typedescription_new( &pType
, typelib_TypeClass_DOUBLE
, OUString("double").pData
, nullptr, 0, nullptr );
1910 typelib_typedescription_register( &pType
);
1911 typelib_typedescription_new( &pType
, typelib_TypeClass_ANY
, OUString("any").pData
, nullptr, 0, nullptr );
1912 typelib_typedescription_register( &pType
);
1913 typelib_typedescription_release( pType
);
1917 typelib_TypeDescriptionReference
* pTDR
= nullptr;
1918 typelib_typedescriptionreference_getByName( &pTDR
, pName
);
1922 // guard against multi thread access
1923 MutexGuard
aGuard( rInit
.maMutex
);
1924 // pTDR->pType->pWeakRef == 0 means that the description is empty
1925 if( pTDR
->pType
&& pTDR
->pType
->pWeakRef
)
1927 typelib_typedescription_acquire( pTDR
->pType
);
1928 *ppRet
= pTDR
->pType
;
1931 typelib_typedescriptionreference_release( pTDR
);
1934 if (nullptr != *ppRet
)
1937 // check for sequence
1938 OUString
const & name
= OUString::unacquired( &pName
);
1939 if (2 < name
.getLength() && '[' == name
[ 0 ])
1941 OUString
element_name( name
.copy( 2 ) );
1942 typelib_TypeDescription
* element_td
= nullptr;
1943 typelib_typedescription_getByName( &element_td
, element_name
.pData
);
1944 if (nullptr != element_td
)
1946 typelib_typedescription_new(
1947 ppRet
, typelib_TypeClass_SEQUENCE
, pName
, element_td
->pWeakRef
, 0, nullptr );
1949 typelib_typedescription_release( element_td
);
1952 if (nullptr == *ppRet
)
1954 // Check for derived interface member type:
1955 sal_Int32 i1
= name
.lastIndexOf(":@");
1957 sal_Int32 i2
= i1
+ RTL_CONSTASCII_LENGTH(":@");
1958 sal_Int32 i3
= name
.indexOf(',', i2
);
1960 sal_Int32 i4
= name
.indexOf(':', i3
);
1962 typelib_TypeDescriptionReference
* pBaseRef
= nullptr;
1963 typelib_TypeDescription
* pBase
= nullptr;
1964 typelib_TypeDescription
* pInterface
= nullptr;
1965 typelib_typedescriptionreference_getByName(
1966 &pBaseRef
, name
.copy(0, i1
).pData
);
1967 if (pBaseRef
!= nullptr) {
1968 typelib_typedescriptionreference_getDescription(
1971 typelib_typedescription_getByName(
1972 &pInterface
, name
.copy(i4
+ 1).pData
);
1973 if (!createDerivedInterfaceMemberDescription(
1974 ppRet
, name
, pBaseRef
, pBase
, pInterface
,
1975 o3tl::toInt32(name
.subView(i2
, i3
- i2
)),
1976 o3tl::toInt32(name
.subView(i3
+ 1, i4
- i3
- 1))))
1978 if (pInterface
!= nullptr) {
1979 typelib_typedescription_release(pInterface
);
1981 if (pBase
!= nullptr) {
1982 typelib_typedescription_release(pBase
);
1984 if (pBaseRef
!= nullptr) {
1985 typelib_typedescriptionreference_release(
1993 if (nullptr == *ppRet
)
1996 rInit
.callChain( ppRet
, pName
);
2002 // typedescription found
2003 if (typelib_TypeClass_TYPEDEF
== (*ppRet
)->eTypeClass
)
2005 typelib_TypeDescription
* pTD
= nullptr;
2006 typelib_typedescriptionreference_getDescription(
2007 &pTD
, reinterpret_cast<typelib_IndirectTypeDescription
*>(*ppRet
)->pType
);
2008 typelib_typedescription_release( *ppRet
);
2014 (*ppRet
)->bOnDemand
= true;
2015 // The type description is hold by the reference until
2016 // on demand is activated.
2017 typelib_typedescription_register( ppRet
);
2019 // insert into the cache
2020 MutexGuard
aGuard( rInit
.maMutex
);
2021 if( rInit
.maCache
.size() >= nCacheSize
)
2023 typelib_typedescription_release( rInit
.maCache
.front() );
2024 rInit
.maCache
.pop_front();
2026 // descriptions in the cache must be acquired!
2027 typelib_typedescription_acquire( *ppRet
);
2028 rInit
.maCache
.push_back( *ppRet
);
2032 extern "C" void SAL_CALL
typelib_typedescriptionreference_newByAsciiName(
2033 typelib_TypeDescriptionReference
** ppTDR
,
2034 typelib_TypeClass eTypeClass
,
2035 const char * pTypeName
)
2036 SAL_THROW_EXTERN_C()
2038 OUString
aTypeName( OUString::createFromAscii( pTypeName
) );
2039 typelib_typedescriptionreference_new( ppTDR
, eTypeClass
, aTypeName
.pData
);
2042 extern "C" void SAL_CALL
typelib_typedescriptionreference_new(
2043 typelib_TypeDescriptionReference
** ppTDR
,
2044 typelib_TypeClass eTypeClass
, rtl_uString
* pTypeName
)
2045 SAL_THROW_EXTERN_C()
2047 TypeDescriptor_Init_Impl
&rInit
= Init();
2048 if( eTypeClass
== typelib_TypeClass_TYPEDEF
)
2051 typelib_TypeDescription
* pRet
= nullptr;
2052 rInit
.callChain( &pRet
, pTypeName
);
2055 // typedescription found
2056 if (typelib_TypeClass_TYPEDEF
== pRet
->eTypeClass
)
2058 typelib_typedescriptionreference_acquire(
2059 reinterpret_cast<typelib_IndirectTypeDescription
*>(pRet
)->pType
);
2061 typelib_typedescriptionreference_release( *ppTDR
);
2062 *ppTDR
= reinterpret_cast<typelib_IndirectTypeDescription
*>(pRet
)->pType
;
2063 typelib_typedescription_release( pRet
);
2068 pRet
->bOnDemand
= true;
2069 // The type description is hold by the reference until
2070 // on demand is activated.
2071 typelib_typedescription_register( &pRet
);
2073 // insert into the cache
2074 MutexGuard
aGuard( rInit
.maMutex
);
2075 if( rInit
.maCache
.size() >= nCacheSize
)
2077 typelib_typedescription_release( rInit
.maCache
.front() );
2078 rInit
.maCache
.pop_front();
2080 rInit
.maCache
.push_back( pRet
);
2081 // pRet kept acquired for cache
2083 typelib_typedescriptionreference_acquire( pRet
->pWeakRef
);
2085 typelib_typedescriptionreference_release( *ppTDR
);
2086 *ppTDR
= pRet
->pWeakRef
;
2091 SAL_INFO("cppu.typelib", "typedef not found : " << pTypeName
);
2092 typelib_typedescriptionreference_release( *ppTDR
);
2098 MutexGuard
aGuard( rInit
.maMutex
);
2099 typelib_typedescriptionreference_getByName( ppTDR
, pTypeName
);
2103 if( TYPELIB_TYPEDESCRIPTIONREFERENCE_ISREALLYWEAK( eTypeClass
) )
2105 typelib_TypeDescriptionReference
* pTDR
= new typelib_TypeDescriptionReference
;
2106 #if OSL_DEBUG_LEVEL > 0
2107 osl_atomic_increment( &rInit
.nTypeDescriptionReferenceCount
);
2109 pTDR
->nRefCount
= 1;
2110 pTDR
->nStaticRefCount
= 0;
2111 pTDR
->eTypeClass
= eTypeClass
;
2112 pTDR
->pUniqueIdentifier
= nullptr;
2113 pTDR
->pReserved
= nullptr;
2114 pTDR
->pTypeName
= pTypeName
;
2115 rtl_uString_acquire( pTDR
->pTypeName
);
2116 pTDR
->pType
= nullptr;
2121 typelib_typedescription_newEmpty( reinterpret_cast<typelib_TypeDescription
** >(ppTDR
), eTypeClass
, pTypeName
);
2122 // description will be registered but not acquired
2123 (*reinterpret_cast<typelib_TypeDescription
**>(ppTDR
))->bOnDemand
= true;
2124 (*reinterpret_cast<typelib_TypeDescription
**>(ppTDR
))->bComplete
= false;
2127 // Heavy hack, the const sal_Unicode * is hold by the typedescription reference
2129 rInit
.maWeakMap
[ (*ppTDR
)->pTypeName
->buffer
] = *ppTDR
;
2133 extern "C" void SAL_CALL
typelib_typedescriptionreference_acquire(
2134 typelib_TypeDescriptionReference
* pRef
)
2135 SAL_THROW_EXTERN_C()
2137 osl_atomic_increment( &pRef
->nRefCount
);
2141 extern "C" void SAL_CALL
typelib_typedescriptionreference_release(
2142 typelib_TypeDescriptionReference
* pRef
)
2143 SAL_THROW_EXTERN_C()
2145 // Is it a type description?
2146 if( TYPELIB_TYPEDESCRIPTIONREFERENCE_ISREALLYWEAK( pRef
->eTypeClass
) )
2148 if( ! osl_atomic_decrement( &pRef
->nRefCount
) )
2150 TypeDescriptor_Init_Impl
&rInit
= Init();
2151 MutexGuard
aGuard( rInit
.maMutex
);
2152 WeakMap_Impl::iterator aIt
= rInit
.maWeakMap
.find( pRef
->pTypeName
->buffer
);
2153 if( aIt
!= rInit
.maWeakMap
.end() && (*aIt
).second
== pRef
)
2155 // remove only if it contains the same object
2156 rInit
.maWeakMap
.erase( aIt
);
2159 rtl_uString_release( pRef
->pTypeName
);
2160 OSL_ASSERT( pRef
->pType
== nullptr );
2161 #if OSL_DEBUG_LEVEL > 0
2162 osl_atomic_decrement( &rInit
.nTypeDescriptionReferenceCount
);
2169 typelib_typedescription_release( reinterpret_cast<typelib_TypeDescription
*>(pRef
) );
2174 extern "C" void SAL_CALL
typelib_typedescriptionreference_getDescription(
2175 typelib_TypeDescription
** ppRet
, typelib_TypeDescriptionReference
* pRef
)
2176 SAL_THROW_EXTERN_C()
2180 typelib_typedescription_release( *ppRet
);
2184 if( !TYPELIB_TYPEDESCRIPTIONREFERENCE_ISREALLYWEAK( pRef
->eTypeClass
) && pRef
->pType
&& pRef
->pType
->pWeakRef
)
2186 // reference is a description and initialized
2187 osl_atomic_increment( &reinterpret_cast<typelib_TypeDescription
*>(pRef
)->nRefCount
);
2188 *ppRet
= reinterpret_cast<typelib_TypeDescription
*>(pRef
);
2193 MutexGuard
aGuard( Init().maMutex
);
2194 // pRef->pType->pWeakRef == 0 means that the description is empty
2195 if( pRef
->pType
&& pRef
->pType
->pWeakRef
)
2197 sal_Int32 n
= osl_atomic_increment( &pRef
->pType
->nRefCount
);
2200 // The reference is incremented. The object cannot be destroyed.
2201 // Release the guard at the earliest point.
2202 *ppRet
= pRef
->pType
;
2205 (void)osl_atomic_decrement( &pRef
->pType
->nRefCount
);
2206 // destruction of this type in progress (another thread!)
2207 // no access through this weak reference
2208 pRef
->pType
= nullptr;
2212 typelib_typedescription_getByName( ppRet
, pRef
->pTypeName
);
2213 OSL_ASSERT( !*ppRet
|| rtl_ustr_compare( pRef
->pTypeName
->buffer
, (*ppRet
)->pTypeName
->buffer
) == 0 );
2214 OSL_ASSERT( !*ppRet
|| pRef
->eTypeClass
== (*ppRet
)->eTypeClass
);
2215 OSL_ASSERT( !*ppRet
|| pRef
== (*ppRet
)->pWeakRef
);
2216 pRef
->pType
= *ppRet
;
2220 extern "C" void typelib_typedescriptionreference_getByName(
2221 typelib_TypeDescriptionReference
** ppRet
, rtl_uString
const * pName
)
2222 SAL_THROW_EXTERN_C()
2226 typelib_typedescriptionreference_release( *ppRet
);
2229 TypeDescriptor_Init_Impl
&rInit
= Init();
2231 MutexGuard
aGuard( rInit
.maMutex
);
2232 WeakMap_Impl::const_iterator aIt
= rInit
.maWeakMap
.find( pName
->buffer
);
2233 if( aIt
== rInit
.maWeakMap
.end() )
2236 sal_Int32 n
= osl_atomic_increment( &(*aIt
).second
->nRefCount
);
2239 // The reference is incremented. The object cannot be destroyed.
2240 // Release the guard at the earliest point.
2241 *ppRet
= (*aIt
).second
;
2245 // destruction of this type in progress (another thread!)
2246 // no access through this weak reference
2247 (void)osl_atomic_decrement( &(*aIt
).second
->nRefCount
);
2252 extern "C" sal_Bool SAL_CALL
typelib_typedescriptionreference_equals(
2253 const typelib_TypeDescriptionReference
* p1
,
2254 const typelib_TypeDescriptionReference
* p2
)
2255 SAL_THROW_EXTERN_C()
2258 (p1
->eTypeClass
== p2
->eTypeClass
&&
2259 p1
->pTypeName
->length
== p2
->pTypeName
->length
&&
2260 rtl_ustr_compare( p1
->pTypeName
->buffer
, p2
->pTypeName
->buffer
) == 0));
2264 extern "C" void SAL_CALL
typelib_typedescriptionreference_assign(
2265 typelib_TypeDescriptionReference
** ppDest
,
2266 typelib_TypeDescriptionReference
* pSource
)
2267 SAL_THROW_EXTERN_C()
2269 if (*ppDest
!= pSource
)
2271 ::typelib_typedescriptionreference_acquire( pSource
);
2272 ::typelib_typedescriptionreference_release( *ppDest
);
2278 extern "C" void SAL_CALL
typelib_setCacheSize( sal_Int32
)
2279 SAL_THROW_EXTERN_C()
2284 const bool s_aAssignableFromTab
[11][11] =
2286 /* from CH, BO, BY, SH, US, LO, UL, HY, UH, FL, DO */
2287 /* TypeClass_CHAR */ { true, false, false, false, false, false, false, false, false, false, false },
2288 /* TypeClass_BOOLEAN */ { false, true, false, false, false, false, false, false, false, false, false },
2289 /* TypeClass_BYTE */ { false, false, true, false, false, false, false, false, false, false, false },
2290 /* TypeClass_SHORT */ { false, false, true, true, true, false, false, false, false, false, false },
2291 /* TypeClass_UNSIGNED_SHORT */ { false, false, true, true, true, false, false, false, false, false, false },
2292 /* TypeClass_LONG */ { false, false, true, true, true, true, true, false, false, false, false },
2293 /* TypeClass_UNSIGNED_LONG */ { false, false, true, true, true, true, true, false, false, false, false },
2294 /* TypeClass_HYPER */ { false, false, true, true, true, true, true, true, true, false, false },
2295 /* TypeClass_UNSIGNED_HYPER */ { false, false, true, true, true, true, true, true, true, false, false },
2296 /* TypeClass_FLOAT */ { false, false, true, true, true, false, false, false, false, true, false },
2297 /* TypeClass_DOUBLE */ { false, false, true, true, true, true, true, false, false, true, true }
2301 extern "C" sal_Bool SAL_CALL
typelib_typedescriptionreference_isAssignableFrom(
2302 typelib_TypeDescriptionReference
* pAssignable
,
2303 typelib_TypeDescriptionReference
* pFrom
)
2304 SAL_THROW_EXTERN_C()
2306 if (!pAssignable
|| !pFrom
)
2309 typelib_TypeClass eAssignable
= pAssignable
->eTypeClass
;
2310 typelib_TypeClass eFrom
= pFrom
->eTypeClass
;
2312 if (eAssignable
== typelib_TypeClass_ANY
) // anything can be assigned to an any .)
2314 if (eAssignable
== eFrom
)
2316 if (type_equals( pAssignable
, pFrom
)) // first shot
2320 switch (eAssignable
)
2322 case typelib_TypeClass_STRUCT
:
2323 case typelib_TypeClass_EXCEPTION
:
2325 typelib_TypeDescription
* pFromDescr
= nullptr;
2326 TYPELIB_DANGER_GET( &pFromDescr
, pFrom
);
2327 if (!reinterpret_cast<typelib_CompoundTypeDescription
*>(pFromDescr
)->pBaseTypeDescription
)
2329 TYPELIB_DANGER_RELEASE( pFromDescr
);
2332 bool bRet
= typelib_typedescriptionreference_isAssignableFrom(
2334 reinterpret_cast<typelib_CompoundTypeDescription
*>(pFromDescr
)->pBaseTypeDescription
->aBase
.pWeakRef
);
2335 TYPELIB_DANGER_RELEASE( pFromDescr
);
2338 case typelib_TypeClass_INTERFACE
:
2340 typelib_TypeDescription
* pFromDescr
= nullptr;
2341 TYPELIB_DANGER_GET( &pFromDescr
, pFrom
);
2342 typelib_InterfaceTypeDescription
* pFromIfc
2344 typelib_InterfaceTypeDescription
* >(pFromDescr
);
2346 for (sal_Int32 i
= 0; i
< pFromIfc
->nBaseTypes
; ++i
) {
2347 if (typelib_typedescriptionreference_isAssignableFrom(
2349 pFromIfc
->ppBaseTypes
[i
]->aBase
.pWeakRef
))
2355 TYPELIB_DANGER_RELEASE( pFromDescr
);
2364 return (eAssignable
>= typelib_TypeClass_CHAR
&& eAssignable
<= typelib_TypeClass_DOUBLE
&&
2365 eFrom
>= typelib_TypeClass_CHAR
&& eFrom
<= typelib_TypeClass_DOUBLE
&&
2366 s_aAssignableFromTab
[eAssignable
-1][eFrom
-1]);
2369 extern "C" sal_Bool SAL_CALL
typelib_typedescription_isAssignableFrom(
2370 typelib_TypeDescription
* pAssignable
,
2371 typelib_TypeDescription
* pFrom
)
2372 SAL_THROW_EXTERN_C()
2374 return typelib_typedescriptionreference_isAssignableFrom(
2375 pAssignable
->pWeakRef
, pFrom
->pWeakRef
);
2379 extern "C" sal_Bool SAL_CALL
typelib_typedescription_complete(
2380 typelib_TypeDescription
** ppTypeDescr
)
2381 SAL_THROW_EXTERN_C()
2383 return complete(ppTypeDescr
, true);
2386 /* vim:set shiftwidth=4 softtabstop=4 expandtab: */