remove assert looking for new compatibilityMode DOCX
[LibreOffice.git] / cppu / source / typelib / typelib.cxx
blob034a1819db91c92b70c6f2c7fd137db6512c7ccf
1 /* -*- Mode: C++; tab-width: 4; indent-tabs-mode: nil; c-basic-offset: 4 -*- */
2 /*
3 * This file is part of the LibreOffice project.
5 * This Source Code Form is subject to the terms of the Mozilla Public
6 * License, v. 2.0. If a copy of the MPL was not distributed with this
7 * file, You can obtain one at http://mozilla.org/MPL/2.0/.
9 * This file incorporates work covered by the following license notice:
11 * Licensed to the Apache Software Foundation (ASF) under one or more
12 * contributor license agreements. See the NOTICE file distributed
13 * with this work for additional information regarding copyright
14 * ownership. The ASF licenses this file to you under the Apache
15 * License, Version 2.0 (the "License"); you may not use this file
16 * except in compliance with the License. You may obtain a copy of
17 * the License at http://www.apache.org/licenses/LICENSE-2.0 .
21 #include <algorithm>
22 #include <unordered_map>
23 #include <cassert>
24 #include <list>
25 #include <set>
26 #include <utility>
27 #include <vector>
29 #include <stdlib.h>
30 #include <string.h>
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>
37 #include <uno/any2.h>
38 #include <o3tl/string_view.hxx>
39 #include "typelib.hxx"
41 using namespace osl;
43 #ifdef _WIN32
44 #pragma pack(push, 8)
45 #endif
47 namespace {
49 /**
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.
55 struct AlignSize_Impl
57 sal_Int16 nInt16;
58 double dDouble;
63 #ifdef _WIN32
64 #pragma pack(pop)
65 #endif
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;
77 /**
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 );
91 sal_Int32 nSize;
92 // The reference is the description
93 // if the description is empty, then it must be filled with
94 // the new description
95 switch( eTypeClass )
97 case typelib_TypeClass_SEQUENCE:
98 nSize = sal_Int32(sizeof( typelib_IndirectTypeDescription ));
99 break;
101 case typelib_TypeClass_STRUCT:
102 nSize = sal_Int32(sizeof( typelib_StructTypeDescription ));
103 break;
105 case typelib_TypeClass_EXCEPTION:
106 nSize = sal_Int32(sizeof( typelib_CompoundTypeDescription ));
107 break;
109 case typelib_TypeClass_ENUM:
110 nSize = sal_Int32(sizeof( typelib_EnumTypeDescription ));
111 break;
113 case typelib_TypeClass_INTERFACE:
114 nSize = sal_Int32(sizeof( typelib_InterfaceTypeDescription ));
115 break;
117 case typelib_TypeClass_INTERFACE_METHOD:
118 nSize = sal_Int32(sizeof( typelib_InterfaceMethodTypeDescription ));
119 break;
121 case typelib_TypeClass_INTERFACE_ATTRIBUTE:
122 nSize = sal_Int32(sizeof( typelib_InterfaceAttributeTypeDescription ));
123 break;
125 default:
126 nSize = sal_Int32(sizeof( typelib_TypeDescription ));
128 return nSize;
131 namespace {
133 struct equalStr_Impl
135 bool operator()(const sal_Unicode * const & s1, const sal_Unicode * const & s2) const
136 { return 0 == rtl_ustr_compare( s1, s2 ); }
140 struct hashStr_Impl
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;
159 namespace {
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
170 Mutex maMutex;
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;
184 #endif
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 );
201 if( *ppRet )
202 return;
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;
242 if (pTDR)
244 OString aTypeName( OUStringToOString( OUString::unacquired(&pTDR->pTypeName), RTL_TEXTENCODING_ASCII_US ) );
245 SAL_INFO("cppu.typelib", "remaining type: " << aTypeName << "; ref count = " << pTDR->nRefCount);
247 else
249 SAL_INFO("cppu.typelib", "remaining null type entry!?");
252 #endif
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" );
263 #endif
265 SAL_INFO_IF( !maCallbacks.empty(), "cppu.typelib", "pCallbacks is not NULL or empty" );
268 namespace {
269 TypeDescriptor_Init_Impl& Init()
271 static TypeDescriptor_Init_Impl SINGLETON;
272 return SINGLETON;
276 extern "C" void SAL_CALL typelib_typedescription_registerCallback(
277 void * pContext, typelib_typedescription_Callback pCallback ) noexcept
279 // todo mt safe: guard is no solution, can not acquire while calling callback!
280 TypeDescriptor_Init_Impl &rInit = Init();
281 // OslGuard aGuard( rInit.getMutex() );
282 rInit.maCallbacks.push_back( CallbackEntry( pContext, pCallback ) );
286 extern "C" void SAL_CALL typelib_typedescription_revokeCallback(
287 void * pContext, typelib_typedescription_Callback pCallback ) noexcept
289 TypeDescriptor_Init_Impl &rInit = Init();
291 // todo mt safe: guard is no solution, can not acquire while calling callback!
292 // OslGuard aGuard( rInit.getMutex() );
293 CallbackEntry aEntry( pContext, pCallback );
294 std::erase(rInit.maCallbacks, aEntry);
298 static void typelib_typedescription_initTables(
299 typelib_TypeDescription * pTD )
301 typelib_InterfaceTypeDescription * pITD = reinterpret_cast<typelib_InterfaceTypeDescription *>(pTD);
303 std::vector<bool> aReadWriteAttributes(pITD->nAllMembers);
304 for ( sal_Int32 i = pITD->nAllMembers; i--; )
306 aReadWriteAttributes[i] = false;
307 if( typelib_TypeClass_INTERFACE_ATTRIBUTE == pITD->ppAllMembers[i]->eTypeClass )
309 typelib_TypeDescription * pM = nullptr;
310 TYPELIB_DANGER_GET( &pM, pITD->ppAllMembers[i] );
311 OSL_ASSERT( pM );
312 if (pM)
314 aReadWriteAttributes[i] = !reinterpret_cast<typelib_InterfaceAttributeTypeDescription *>(pM)->bReadOnly;
315 TYPELIB_DANGER_RELEASE( pM );
317 else
319 SAL_INFO( "cppu.typelib", "cannot get attribute type description: " << pITD->ppAllMembers[i]->pTypeName );
324 MutexGuard aGuard( Init().maMutex );
325 if( pTD->bComplete )
326 return;
328 // create the index table from member to function table
329 pITD->pMapMemberIndexToFunctionIndex = new sal_Int32[ pITD->nAllMembers ];
330 sal_Int32 nAdditionalOffset = 0; // +1 for read/write attributes
331 sal_Int32 i;
332 for( i = 0; i < pITD->nAllMembers; i++ )
334 // index to the get method of the attribute
335 pITD->pMapMemberIndexToFunctionIndex[i] = i + nAdditionalOffset;
336 // extra offset if it is a read/write attribute?
337 if (aReadWriteAttributes[i])
339 // a read/write attribute
340 nAdditionalOffset++;
344 // create the index table from function to member table
345 pITD->pMapFunctionIndexToMemberIndex = new sal_Int32[ pITD->nAllMembers + nAdditionalOffset ];
346 nAdditionalOffset = 0; // +1 for read/write attributes
347 for( i = 0; i < pITD->nAllMembers; i++ )
349 // index to the get method of the attribute
350 pITD->pMapFunctionIndexToMemberIndex[i + nAdditionalOffset] = i;
351 // extra offset if it is a read/write attribute?
352 if (aReadWriteAttributes[i])
354 // a read/write attribute
355 pITD->pMapFunctionIndexToMemberIndex[i + ++nAdditionalOffset] = i;
358 // must be the last action after all initialization is done
359 pITD->nMapFunctionIndexToMemberIndex = pITD->nAllMembers + nAdditionalOffset;
360 pTD->bComplete = true;
363 namespace {
365 template<typename T> T * allocTypeDescription() {
366 return reinterpret_cast<T *>(new char[sizeof (T)]);
369 void freeTypeDescription(typelib_TypeDescription const * desc) {
370 delete[] reinterpret_cast<char const *>(desc);
373 // In some situations (notably typelib_typedescription_newInterfaceMethod and
374 // typelib_typedescription_newInterfaceAttribute), only the members nMembers,
375 // ppMembers, nAllMembers, and ppAllMembers of an incomplete interface type
376 // description are necessary, but not the additional
377 // pMapMemberIndexToFunctionIndex, nMapFunctionIndexToMemberIndex, and
378 // pMapFunctionIndexToMemberIndex (which are computed by
379 // typelib_typedescription_initTables). Furthermore, in those situations, it
380 // might be illegal to compute those tables, as the creation of the interface
381 // member type descriptions would recursively require a complete interface type
382 // description. The parameter initTables controls whether or not to call
383 // typelib_typedescription_initTables in those situations.
384 bool complete(typelib_TypeDescription ** ppTypeDescr, bool initTables) {
385 if ((*ppTypeDescr)->bComplete)
386 return true;
388 OSL_ASSERT( (typelib_TypeClass_STRUCT == (*ppTypeDescr)->eTypeClass ||
389 typelib_TypeClass_EXCEPTION == (*ppTypeDescr)->eTypeClass ||
390 typelib_TypeClass_ENUM == (*ppTypeDescr)->eTypeClass ||
391 typelib_TypeClass_INTERFACE == (*ppTypeDescr)->eTypeClass) &&
392 !TYPELIB_TYPEDESCRIPTIONREFERENCE_ISREALLYWEAK( (*ppTypeDescr)->eTypeClass ) );
394 if (typelib_TypeClass_INTERFACE == (*ppTypeDescr)->eTypeClass &&
395 reinterpret_cast<typelib_InterfaceTypeDescription *>(*ppTypeDescr)->ppAllMembers)
397 if (initTables) {
398 typelib_typedescription_initTables( *ppTypeDescr );
400 return true;
403 typelib_TypeDescription * pTD = nullptr;
404 // on demand access of complete td
405 TypeDescriptor_Init_Impl &rInit = Init();
406 rInit.callChain( &pTD, (*ppTypeDescr)->pTypeName );
407 if (pTD)
409 if (typelib_TypeClass_TYPEDEF == pTD->eTypeClass)
411 typelib_typedescriptionreference_getDescription(
412 &pTD, reinterpret_cast<typelib_IndirectTypeDescription *>(pTD)->pType );
413 OSL_ASSERT( pTD );
414 if (! pTD)
415 return false;
418 OSL_ASSERT( typelib_TypeClass_TYPEDEF != pTD->eTypeClass );
419 // typedescription found
420 // set to on demand
421 pTD->bOnDemand = true;
423 if (pTD->eTypeClass == typelib_TypeClass_INTERFACE
424 && !pTD->bComplete && initTables)
426 // mandatory info from callback chain
427 OSL_ASSERT( reinterpret_cast<typelib_InterfaceTypeDescription *>(pTD)->ppAllMembers );
428 // complete except of tables init
429 typelib_typedescription_initTables( pTD );
430 pTD->bComplete = true;
433 // The type description is hold by the reference until
434 // on demand is activated.
435 ::typelib_typedescription_register( &pTD ); // replaces incomplete one
436 OSL_ASSERT( pTD == *ppTypeDescr ); // has to merge into existing one
438 // insert into the cache
439 MutexGuard aGuard( rInit.maMutex );
440 if( rInit.maCache.size() >= nCacheSize )
442 typelib_typedescription_release( rInit.maCache.front() );
443 rInit.maCache.pop_front();
445 // descriptions in the cache must be acquired!
446 typelib_typedescription_acquire( pTD );
447 rInit.maCache.push_back( pTD );
449 OSL_ASSERT(
450 pTD->bComplete
451 || (pTD->eTypeClass == typelib_TypeClass_INTERFACE
452 && !initTables));
454 ::typelib_typedescription_release( *ppTypeDescr );
455 *ppTypeDescr = pTD;
457 else
459 SAL_INFO(
460 "cppu.typelib",
461 "type cannot be completed: " << OUString::unacquired(&(*ppTypeDescr)->pTypeName));
462 return false;
464 return true;
470 extern "C" void typelib_typedescription_newEmpty(
471 typelib_TypeDescription ** ppRet,
472 typelib_TypeClass eTypeClass, rtl_uString * pTypeName ) noexcept
474 if( *ppRet )
476 typelib_typedescription_release( *ppRet );
477 *ppRet = nullptr;
480 OSL_ASSERT( typelib_TypeClass_TYPEDEF != eTypeClass );
482 typelib_TypeDescription * pRet;
483 switch( eTypeClass )
485 case typelib_TypeClass_SEQUENCE:
487 auto pTmp = allocTypeDescription<typelib_IndirectTypeDescription>();
488 pRet = &pTmp->aBase;
489 #if OSL_DEBUG_LEVEL > 0
490 osl_atomic_increment( &Init().nIndirectTypeDescriptionCount );
491 #endif
492 pTmp->pType = nullptr;
493 // coverity[leaked_storage] - this is on purpose
495 break;
497 case typelib_TypeClass_STRUCT:
499 // FEATURE_EMPTYCLASS
500 auto pTmp = allocTypeDescription<typelib_StructTypeDescription>();
501 pRet = &pTmp->aBase.aBase;
502 #if OSL_DEBUG_LEVEL > 0
503 osl_atomic_increment( &Init().nCompoundTypeDescriptionCount );
504 #endif
505 pTmp->aBase.pBaseTypeDescription = nullptr;
506 pTmp->aBase.nMembers = 0;
507 pTmp->aBase.pMemberOffsets = nullptr;
508 pTmp->aBase.ppTypeRefs = nullptr;
509 pTmp->aBase.ppMemberNames = nullptr;
510 pTmp->pParameterizedTypes = nullptr;
511 // coverity[leaked_storage] - this is on purpose
513 break;
515 case typelib_TypeClass_EXCEPTION:
517 // FEATURE_EMPTYCLASS
518 auto pTmp = allocTypeDescription<typelib_CompoundTypeDescription>();
519 pRet = &pTmp->aBase;
520 #if OSL_DEBUG_LEVEL > 0
521 osl_atomic_increment( &Init().nCompoundTypeDescriptionCount );
522 #endif
523 pTmp->pBaseTypeDescription = nullptr;
524 pTmp->nMembers = 0;
525 pTmp->pMemberOffsets = nullptr;
526 pTmp->ppTypeRefs = nullptr;
527 pTmp->ppMemberNames = nullptr;
528 // coverity[leaked_storage] - this is on purpose
530 break;
532 case typelib_TypeClass_ENUM:
534 auto pTmp = allocTypeDescription<typelib_EnumTypeDescription>();
535 pRet = &pTmp->aBase;
536 #if OSL_DEBUG_LEVEL > 0
537 osl_atomic_increment( &Init().nEnumTypeDescriptionCount );
538 #endif
539 pTmp->nDefaultEnumValue = 0;
540 pTmp->nEnumValues = 0;
541 pTmp->ppEnumNames = nullptr;
542 pTmp->pEnumValues = nullptr;
543 // coverity[leaked_storage] - this is on purpose
545 break;
547 case typelib_TypeClass_INTERFACE:
549 auto pTmp = allocTypeDescription<
550 typelib_InterfaceTypeDescription>();
551 pRet = &pTmp->aBase;
552 #if OSL_DEBUG_LEVEL > 0
553 osl_atomic_increment( &Init().nInterfaceTypeDescriptionCount );
554 #endif
555 pTmp->pBaseTypeDescription = nullptr;
556 pTmp->nMembers = 0;
557 pTmp->ppMembers = nullptr;
558 pTmp->nAllMembers = 0;
559 pTmp->ppAllMembers = nullptr;
560 pTmp->nMapFunctionIndexToMemberIndex = 0;
561 pTmp->pMapFunctionIndexToMemberIndex = nullptr;
562 pTmp->pMapMemberIndexToFunctionIndex= nullptr;
563 pTmp->nBaseTypes = 0;
564 pTmp->ppBaseTypes = nullptr;
565 // coverity[leaked_storage] - this is on purpose
567 break;
569 case typelib_TypeClass_INTERFACE_METHOD:
571 auto pTmp = allocTypeDescription<
572 typelib_InterfaceMethodTypeDescription>();
573 pRet = &pTmp->aBase.aBase;
574 #if OSL_DEBUG_LEVEL > 0
575 osl_atomic_increment( &Init().nInterfaceMethodTypeDescriptionCount );
576 #endif
577 pTmp->aBase.pMemberName = nullptr;
578 pTmp->pReturnTypeRef = nullptr;
579 pTmp->nParams = 0;
580 pTmp->pParams = nullptr;
581 pTmp->nExceptions = 0;
582 pTmp->ppExceptions = nullptr;
583 pTmp->pInterface = nullptr;
584 pTmp->pBaseRef = nullptr;
585 pTmp->nIndex = 0;
586 // coverity[leaked_storage] - this is on purpose
588 break;
590 case typelib_TypeClass_INTERFACE_ATTRIBUTE:
592 auto * pTmp = allocTypeDescription<
593 typelib_InterfaceAttributeTypeDescription>();
594 pRet = &pTmp->aBase.aBase;
595 #if OSL_DEBUG_LEVEL > 0
596 osl_atomic_increment( &Init().nInterfaceAttributeTypeDescriptionCount );
597 #endif
598 pTmp->aBase.pMemberName = nullptr;
599 pTmp->pAttributeTypeRef = nullptr;
600 pTmp->pInterface = nullptr;
601 pTmp->pBaseRef = nullptr;
602 pTmp->nIndex = 0;
603 pTmp->nGetExceptions = 0;
604 pTmp->ppGetExceptions = nullptr;
605 pTmp->nSetExceptions = 0;
606 pTmp->ppSetExceptions = nullptr;
607 // coverity[leaked_storage] - this is on purpose
609 break;
611 default:
613 pRet = allocTypeDescription<typelib_TypeDescription>();
614 #if OSL_DEBUG_LEVEL > 0
615 osl_atomic_increment( &Init().nTypeDescriptionCount );
616 #endif
620 pRet->nRefCount = 1; // reference count is initially 1
621 pRet->nStaticRefCount = 0;
622 pRet->eTypeClass = eTypeClass;
623 pRet->pUniqueIdentifier = nullptr;
624 pRet->pReserved = nullptr;
625 pRet->pTypeName = pTypeName;
626 rtl_uString_acquire( pRet->pTypeName );
627 pRet->pSelf = pRet;
628 pRet->bComplete = true;
629 pRet->nSize = 0;
630 pRet->nAlignment = 0;
631 pRet->pWeakRef = nullptr;
632 pRet->bOnDemand = false;
633 *ppRet = pRet;
637 namespace {
639 void newTypeDescription(
640 typelib_TypeDescription ** ppRet, typelib_TypeClass eTypeClass,
641 rtl_uString * pTypeName, typelib_TypeDescriptionReference * pType,
642 sal_Int32 nMembers, typelib_CompoundMember_Init * pCompoundMembers,
643 typelib_StructMember_Init * pStructMembers)
645 OSL_ASSERT(
646 (pCompoundMembers == nullptr || pStructMembers == nullptr)
647 && (pStructMembers == nullptr || eTypeClass == typelib_TypeClass_STRUCT));
648 if (typelib_TypeClass_TYPEDEF == eTypeClass)
650 SAL_WARN("cppu.typelib", "unexpected typedef!" );
651 typelib_typedescriptionreference_getDescription( ppRet, pType );
652 return;
655 typelib_typedescription_newEmpty( ppRet, eTypeClass, pTypeName );
657 switch( eTypeClass )
659 case typelib_TypeClass_SEQUENCE:
661 OSL_ASSERT( nMembers == 0 );
662 typelib_typedescriptionreference_acquire( pType );
663 reinterpret_cast<typelib_IndirectTypeDescription *>(*ppRet)->pType = pType;
665 break;
667 case typelib_TypeClass_EXCEPTION:
668 case typelib_TypeClass_STRUCT:
670 // FEATURE_EMPTYCLASS
671 typelib_CompoundTypeDescription * pTmp = reinterpret_cast<typelib_CompoundTypeDescription*>(*ppRet);
673 sal_Int32 nOffset = 0;
674 if( pType )
676 typelib_typedescriptionreference_getDescription(
677 reinterpret_cast<typelib_TypeDescription **>(&pTmp->pBaseTypeDescription), pType );
678 nOffset = pTmp->pBaseTypeDescription->aBase.nSize;
679 OSL_ENSURE( newAlignedSize( 0, pTmp->pBaseTypeDescription->aBase.nSize, pTmp->pBaseTypeDescription->aBase.nAlignment ) == pTmp->pBaseTypeDescription->aBase.nSize, "### unexpected offset!" );
681 if( nMembers )
683 pTmp->nMembers = nMembers;
684 pTmp->pMemberOffsets = new sal_Int32[ nMembers ];
685 pTmp->ppTypeRefs = new typelib_TypeDescriptionReference *[ nMembers ];
686 pTmp->ppMemberNames = new rtl_uString *[ nMembers ];
687 bool polymorphic = eTypeClass == typelib_TypeClass_STRUCT
688 && OUString::unacquired(&pTypeName).indexOf('<') >= 0;
689 assert(!polymorphic || pStructMembers != nullptr);
690 if (polymorphic) {
691 reinterpret_cast< typelib_StructTypeDescription * >(pTmp)->
692 pParameterizedTypes = new sal_Bool[nMembers];
694 for( sal_Int32 i = 0 ; i < nMembers; i++ )
696 // read the type and member names
697 pTmp->ppTypeRefs[i] = nullptr;
698 if (pCompoundMembers != nullptr) {
699 typelib_typedescriptionreference_new(
700 pTmp->ppTypeRefs +i, pCompoundMembers[i].eTypeClass,
701 pCompoundMembers[i].pTypeName );
702 pTmp->ppMemberNames[i]
703 = pCompoundMembers[i].pMemberName;
704 rtl_uString_acquire( pTmp->ppMemberNames[i] );
705 } else {
706 typelib_typedescriptionreference_new(
707 pTmp->ppTypeRefs +i,
708 pStructMembers[i].aBase.eTypeClass,
709 pStructMembers[i].aBase.pTypeName );
710 pTmp->ppMemberNames[i]
711 = pStructMembers[i].aBase.pMemberName;
712 rtl_uString_acquire(pTmp->ppMemberNames[i]);
714 assert(pTmp->ppTypeRefs[i]);
715 // write offset
716 sal_Int32 size;
717 sal_Int32 alignment;
718 if (pTmp->ppTypeRefs[i]->eTypeClass ==
719 typelib_TypeClass_SEQUENCE)
721 // Take care of recursion like
722 // struct S { sequence<S> x; };
723 size = sizeof(void *);
724 alignment = adjustAlignment(size);
725 } else {
726 typelib_TypeDescription * pTD = nullptr;
727 TYPELIB_DANGER_GET( &pTD, pTmp->ppTypeRefs[i] );
728 OSL_ENSURE( pTD->nSize, "### void member?" );
729 size = pTD->nSize;
730 alignment = pTD->nAlignment;
731 TYPELIB_DANGER_RELEASE( pTD );
733 nOffset = newAlignedSize( nOffset, size, alignment );
734 pTmp->pMemberOffsets[i] = nOffset - size;
736 if (polymorphic) {
737 reinterpret_cast< typelib_StructTypeDescription * >(
738 pTmp)->pParameterizedTypes[i]
739 = pStructMembers[i].bParameterizedType;
744 break;
746 default:
747 break;
750 if( !TYPELIB_TYPEDESCRIPTIONREFERENCE_ISREALLYWEAK( eTypeClass ) )
751 (*ppRet)->pWeakRef = reinterpret_cast<typelib_TypeDescriptionReference *>(*ppRet);
752 if( eTypeClass != typelib_TypeClass_VOID )
754 // sizeof(void) not allowed
755 (*ppRet)->nSize = typelib_typedescription_getAlignedUnoSize( (*ppRet), 0, (*ppRet)->nAlignment );
756 (*ppRet)->nAlignment = adjustAlignment( (*ppRet)->nAlignment );
762 extern "C" void SAL_CALL typelib_typedescription_new(
763 typelib_TypeDescription ** ppRet,
764 typelib_TypeClass eTypeClass,
765 rtl_uString * pTypeName,
766 typelib_TypeDescriptionReference * pType,
767 sal_Int32 nMembers,
768 typelib_CompoundMember_Init * pMembers ) noexcept
770 newTypeDescription(
771 ppRet, eTypeClass, pTypeName, pType, nMembers, pMembers, nullptr);
774 extern "C" void SAL_CALL typelib_typedescription_newStruct(
775 typelib_TypeDescription ** ppRet,
776 rtl_uString * pTypeName,
777 typelib_TypeDescriptionReference * pType,
778 sal_Int32 nMembers,
779 typelib_StructMember_Init * pMembers ) noexcept
781 newTypeDescription(
782 ppRet, typelib_TypeClass_STRUCT, pTypeName, pType, nMembers, nullptr,
783 pMembers);
787 extern "C" void SAL_CALL typelib_typedescription_newEnum(
788 typelib_TypeDescription ** ppRet,
789 rtl_uString * pTypeName,
790 sal_Int32 nDefaultValue,
791 sal_Int32 nEnumValues,
792 rtl_uString ** ppEnumNames,
793 sal_Int32 * pEnumValues ) noexcept
795 typelib_typedescription_newEmpty( ppRet, typelib_TypeClass_ENUM, pTypeName );
796 typelib_EnumTypeDescription * pEnum = reinterpret_cast<typelib_EnumTypeDescription *>(*ppRet);
798 pEnum->nDefaultEnumValue = nDefaultValue;
799 pEnum->nEnumValues = nEnumValues;
800 pEnum->ppEnumNames = new rtl_uString * [ nEnumValues ];
801 for ( sal_Int32 nPos = nEnumValues; nPos--; )
803 pEnum->ppEnumNames[nPos] = ppEnumNames[nPos];
804 rtl_uString_acquire( pEnum->ppEnumNames[nPos] );
806 pEnum->pEnumValues = new sal_Int32[ nEnumValues ];
807 ::memcpy( pEnum->pEnumValues, pEnumValues, nEnumValues * sizeof(sal_Int32) );
809 static_assert(!TYPELIB_TYPEDESCRIPTIONREFERENCE_ISREALLYWEAK(typelib_TypeClass_ENUM));
810 (*ppRet)->pWeakRef = reinterpret_cast<typelib_TypeDescriptionReference *>(*ppRet);
811 // sizeof(void) not allowed
812 (*ppRet)->nSize = typelib_typedescription_getAlignedUnoSize( (*ppRet), 0, (*ppRet)->nAlignment );
813 (*ppRet)->nAlignment = adjustAlignment( (*ppRet)->nAlignment );
817 extern "C" void SAL_CALL typelib_typedescription_newInterface(
818 typelib_InterfaceTypeDescription ** ppRet,
819 rtl_uString * pTypeName,
820 SAL_UNUSED_PARAMETER sal_uInt32, SAL_UNUSED_PARAMETER sal_uInt16,
821 SAL_UNUSED_PARAMETER sal_uInt16, SAL_UNUSED_PARAMETER sal_uInt32,
822 SAL_UNUSED_PARAMETER sal_uInt32,
823 typelib_TypeDescriptionReference * pBaseInterface,
824 sal_Int32 nMembers,
825 typelib_TypeDescriptionReference ** ppMembers ) noexcept
827 // coverity[callee_ptr_arith] - not a bug
828 typelib_typedescription_newMIInterface(
829 ppRet, pTypeName, 0, 0, 0, 0, 0, pBaseInterface == nullptr ? 0 : 1,
830 &pBaseInterface, nMembers, ppMembers);
833 namespace {
835 class BaseList {
836 public:
837 struct Entry {
838 sal_Int32 memberOffset;
839 sal_Int32 directBaseIndex;
840 sal_Int32 directBaseMemberOffset;
841 typelib_InterfaceTypeDescription const * base;
844 typedef std::vector< Entry > List;
846 explicit BaseList(typelib_InterfaceTypeDescription const * desc);
848 List const & getList() const { return list; }
850 sal_Int32 getBaseMembers() const { return members; }
852 private:
853 typedef std::set< OUString > Set;
855 void calculate(
856 Set& allSet,
857 sal_Int32 directBaseIndex, Set & directBaseSet,
858 sal_Int32 * directBaseMembers,
859 typelib_InterfaceTypeDescription const * desc);
861 List list;
862 sal_Int32 members;
865 BaseList::BaseList(typelib_InterfaceTypeDescription const * desc)
866 : members(0)
868 Set allSet;
869 for (sal_Int32 i = 0; i < desc->nBaseTypes; ++i) {
870 Set directBaseSet;
871 sal_Int32 directBaseMembers = 0;
872 calculate(allSet, i, directBaseSet, &directBaseMembers, desc->ppBaseTypes[i]);
876 void BaseList::calculate(
877 Set& allSet,
878 sal_Int32 directBaseIndex, Set & directBaseSet,
879 sal_Int32 * directBaseMembers,
880 typelib_InterfaceTypeDescription const * desc)
882 for (sal_Int32 i = 0; i < desc->nBaseTypes; ++i) {
883 calculate(allSet,
884 directBaseIndex, directBaseSet, directBaseMembers,
885 desc->ppBaseTypes[i]);
887 if (allSet.insert(desc->aBase.pTypeName).second) {
888 Entry e;
889 e.memberOffset = members;
890 e.directBaseIndex = directBaseIndex;
891 e.directBaseMemberOffset = *directBaseMembers;
892 e.base = desc;
893 list.push_back(e);
894 OSL_ASSERT(desc->ppAllMembers != nullptr);
895 members += desc->nMembers;
897 if (directBaseSet.insert(desc->aBase.pTypeName).second) {
898 OSL_ASSERT(desc->ppAllMembers != nullptr);
899 *directBaseMembers += desc->nMembers;
905 extern "C" void SAL_CALL typelib_typedescription_newMIInterface(
906 typelib_InterfaceTypeDescription ** ppRet,
907 rtl_uString * pTypeName,
908 SAL_UNUSED_PARAMETER sal_uInt32, SAL_UNUSED_PARAMETER sal_uInt16,
909 SAL_UNUSED_PARAMETER sal_uInt16, SAL_UNUSED_PARAMETER sal_uInt32,
910 SAL_UNUSED_PARAMETER sal_uInt32,
911 sal_Int32 nBaseInterfaces,
912 typelib_TypeDescriptionReference ** ppBaseInterfaces,
913 sal_Int32 nMembers,
914 typelib_TypeDescriptionReference ** ppMembers ) noexcept
916 if (*ppRet != nullptr) {
917 typelib_typedescription_release(&(*ppRet)->aBase);
918 *ppRet = nullptr;
921 typelib_InterfaceTypeDescription * pITD = nullptr;
922 typelib_typedescription_newEmpty(
923 reinterpret_cast<typelib_TypeDescription **>(&pITD), typelib_TypeClass_INTERFACE, pTypeName );
925 pITD->nBaseTypes = nBaseInterfaces;
926 pITD->ppBaseTypes = new typelib_InterfaceTypeDescription *[nBaseInterfaces];
927 for (sal_Int32 i = 0; i < nBaseInterfaces; ++i) {
928 pITD->ppBaseTypes[i] = nullptr;
929 typelib_typedescriptionreference_getDescription(
930 reinterpret_cast< typelib_TypeDescription ** >(
931 &pITD->ppBaseTypes[i]),
932 ppBaseInterfaces[i]);
933 if (pITD->ppBaseTypes[i] == nullptr
934 || !complete(
935 reinterpret_cast< typelib_TypeDescription ** >(
936 &pITD->ppBaseTypes[i]),
937 false))
939 OSL_ASSERT(false);
940 return;
942 OSL_ASSERT(pITD->ppBaseTypes[i] != nullptr);
944 if (nBaseInterfaces > 0) {
945 pITD->pBaseTypeDescription = pITD->ppBaseTypes[0];
947 // set the
948 pITD->aUik.m_Data1 = 0;
949 pITD->aUik.m_Data2 = 0;
950 pITD->aUik.m_Data3 = 0;
951 pITD->aUik.m_Data4 = 0;
952 pITD->aUik.m_Data5 = 0;
954 BaseList aBaseList(pITD);
955 pITD->nAllMembers = nMembers + aBaseList.getBaseMembers();
956 pITD->nMembers = nMembers;
958 if( pITD->nAllMembers )
960 // at minimum one member exist, allocate the memory
961 pITD->ppAllMembers = new typelib_TypeDescriptionReference *[ pITD->nAllMembers ];
962 sal_Int32 n = 0;
964 BaseList::List const & rList = aBaseList.getList();
965 for (const auto& rEntry : rList)
967 typelib_InterfaceTypeDescription const * pBase = rEntry.base;
968 typelib_InterfaceTypeDescription const * pDirectBase
969 = pITD->ppBaseTypes[rEntry.directBaseIndex];
970 OSL_ASSERT(pBase->ppAllMembers != nullptr);
971 for (sal_Int32 j = 0; j < pBase->nMembers; ++j) {
972 typelib_TypeDescriptionReference const * pDirectBaseMember
973 = pDirectBase->ppAllMembers[rEntry.directBaseMemberOffset + j];
974 OUString aName = OUString::unacquired(&pDirectBaseMember->pTypeName) +
975 ":@" +
976 OUString::number(rEntry.directBaseIndex) +
977 "," +
978 OUString::number(rEntry.memberOffset + j) +
979 ":" +
980 OUString::unacquired(&pITD->aBase.pTypeName);
981 typelib_TypeDescriptionReference * pDerivedMember = nullptr;
982 typelib_typedescriptionreference_new(
983 &pDerivedMember, pDirectBaseMember->eTypeClass,
984 aName.pData);
985 pITD->ppAllMembers[n++] = pDerivedMember;
989 if( nMembers )
991 pITD->ppMembers = pITD->ppAllMembers + aBaseList.getBaseMembers();
994 // add own members
995 for( sal_Int32 i = 0; i < nMembers; i++ )
997 typelib_typedescriptionreference_acquire( ppMembers[i] );
998 pITD->ppAllMembers[n++] = ppMembers[i];
1002 typelib_TypeDescription * pTmp = &pITD->aBase;
1003 static_assert( !TYPELIB_TYPEDESCRIPTIONREFERENCE_ISREALLYWEAK( typelib_TypeClass_INTERFACE ) );
1004 pTmp->pWeakRef = reinterpret_cast<typelib_TypeDescriptionReference *>(pTmp);
1005 pTmp->nSize = typelib_typedescription_getAlignedUnoSize( pTmp, 0, pTmp->nAlignment );
1006 pTmp->nAlignment = adjustAlignment( pTmp->nAlignment );
1007 pTmp->bComplete = false;
1009 *ppRet = pITD;
1013 namespace {
1015 typelib_TypeDescriptionReference ** copyExceptions(
1016 sal_Int32 count, rtl_uString ** typeNames)
1018 OSL_ASSERT(count >= 0);
1019 if (count == 0) {
1020 return nullptr;
1022 typelib_TypeDescriptionReference ** p
1023 = new typelib_TypeDescriptionReference *[count];
1024 for (sal_Int32 i = 0; i < count; ++i) {
1025 p[i] = nullptr;
1026 typelib_typedescriptionreference_new(
1027 p + i, typelib_TypeClass_EXCEPTION, typeNames[i]);
1029 return p;
1034 extern "C" void SAL_CALL typelib_typedescription_newInterfaceMethod(
1035 typelib_InterfaceMethodTypeDescription ** ppRet,
1036 sal_Int32 nAbsolutePosition,
1037 sal_Bool bOneWay,
1038 rtl_uString * pTypeName,
1039 typelib_TypeClass eReturnTypeClass,
1040 rtl_uString * pReturnTypeName,
1041 sal_Int32 nParams,
1042 typelib_Parameter_Init * pParams,
1043 sal_Int32 nExceptions,
1044 rtl_uString ** ppExceptionNames ) noexcept
1046 if (*ppRet != nullptr) {
1047 typelib_typedescription_release(&(*ppRet)->aBase.aBase);
1048 *ppRet = nullptr;
1050 sal_Int32 nOffset = rtl_ustr_lastIndexOfChar_WithLength(
1051 pTypeName->buffer, pTypeName->length, ':');
1052 if (nOffset <= 0 || pTypeName->buffer[nOffset - 1] != ':') {
1053 OSL_FAIL("Bad interface method type name");
1054 return;
1056 OUString aInterfaceTypeName(pTypeName->buffer, nOffset - 1);
1057 typelib_InterfaceTypeDescription * pInterface = nullptr;
1058 typelib_typedescription_getByName(
1059 reinterpret_cast< typelib_TypeDescription ** >(&pInterface),
1060 aInterfaceTypeName.pData);
1061 if (pInterface == nullptr
1062 || pInterface->aBase.eTypeClass != typelib_TypeClass_INTERFACE
1063 || !complete(
1064 reinterpret_cast< typelib_TypeDescription ** >(&pInterface), false))
1066 OSL_FAIL("No interface corresponding to interface method");
1067 return;
1070 typelib_typedescription_newEmpty(
1071 reinterpret_cast<typelib_TypeDescription **>(ppRet), typelib_TypeClass_INTERFACE_METHOD, pTypeName );
1073 rtl_uString_newFromStr_WithLength( &(*ppRet)->aBase.pMemberName,
1074 pTypeName->buffer + nOffset +1,
1075 pTypeName->length - nOffset -1 );
1076 (*ppRet)->aBase.nPosition = nAbsolutePosition;
1077 (*ppRet)->bOneWay = bOneWay;
1078 typelib_typedescriptionreference_new( &(*ppRet)->pReturnTypeRef, eReturnTypeClass, pReturnTypeName );
1079 (*ppRet)->nParams = nParams;
1080 if( nParams )
1082 (*ppRet)->pParams = new typelib_MethodParameter[ nParams ];
1084 for( sal_Int32 i = 0; i < nParams; i++ )
1086 // get the name of the parameter
1087 (*ppRet)->pParams[ i ].pName = pParams[i].pParamName;
1088 rtl_uString_acquire( (*ppRet)->pParams[ i ].pName );
1089 (*ppRet)->pParams[ i ].pTypeRef = nullptr;
1090 // get the type name of the parameter and create the weak reference
1091 typelib_typedescriptionreference_new(
1092 &(*ppRet)->pParams[ i ].pTypeRef, pParams[i].eTypeClass, pParams[i].pTypeName );
1093 (*ppRet)->pParams[ i ].bIn = pParams[i].bIn;
1094 (*ppRet)->pParams[ i ].bOut = pParams[i].bOut;
1097 (*ppRet)->nExceptions = nExceptions;
1098 (*ppRet)->ppExceptions = copyExceptions(nExceptions, ppExceptionNames);
1099 (*ppRet)->pInterface = pInterface;
1100 (*ppRet)->pBaseRef = nullptr;
1101 OSL_ASSERT(
1102 (nAbsolutePosition >= pInterface->nAllMembers - pInterface->nMembers)
1103 && nAbsolutePosition < pInterface->nAllMembers);
1104 (*ppRet)->nIndex = nAbsolutePosition
1105 - (pInterface->nAllMembers - pInterface->nMembers);
1106 static_assert( TYPELIB_TYPEDESCRIPTIONREFERENCE_ISREALLYWEAK( typelib_TypeClass_INTERFACE_METHOD ) );
1107 assert(reinterpret_cast<typelib_TypeDescription *>(*ppRet)->pWeakRef == nullptr);
1111 extern "C" void SAL_CALL typelib_typedescription_newInterfaceAttribute(
1112 typelib_InterfaceAttributeTypeDescription ** ppRet,
1113 sal_Int32 nAbsolutePosition,
1114 rtl_uString * pTypeName,
1115 typelib_TypeClass eAttributeTypeClass,
1116 rtl_uString * pAttributeTypeName,
1117 sal_Bool bReadOnly ) noexcept
1119 typelib_typedescription_newExtendedInterfaceAttribute(
1120 ppRet, nAbsolutePosition, pTypeName, eAttributeTypeClass,
1121 pAttributeTypeName, bReadOnly, 0, nullptr, 0, nullptr);
1125 extern "C" void SAL_CALL typelib_typedescription_newExtendedInterfaceAttribute(
1126 typelib_InterfaceAttributeTypeDescription ** ppRet,
1127 sal_Int32 nAbsolutePosition,
1128 rtl_uString * pTypeName,
1129 typelib_TypeClass eAttributeTypeClass,
1130 rtl_uString * pAttributeTypeName,
1131 sal_Bool bReadOnly,
1132 sal_Int32 nGetExceptions, rtl_uString ** ppGetExceptionNames,
1133 sal_Int32 nSetExceptions, rtl_uString ** ppSetExceptionNames ) noexcept
1135 if (*ppRet != nullptr) {
1136 typelib_typedescription_release(&(*ppRet)->aBase.aBase);
1137 *ppRet = nullptr;
1139 sal_Int32 nOffset = rtl_ustr_lastIndexOfChar_WithLength(
1140 pTypeName->buffer, pTypeName->length, ':');
1141 if (nOffset <= 0 || pTypeName->buffer[nOffset - 1] != ':') {
1142 OSL_FAIL("Bad interface attribute type name");
1143 return;
1145 OUString aInterfaceTypeName(pTypeName->buffer, nOffset - 1);
1146 typelib_InterfaceTypeDescription * pInterface = nullptr;
1147 typelib_typedescription_getByName(
1148 reinterpret_cast< typelib_TypeDescription ** >(&pInterface),
1149 aInterfaceTypeName.pData);
1150 if (pInterface == nullptr
1151 || pInterface->aBase.eTypeClass != typelib_TypeClass_INTERFACE
1152 || !complete(
1153 reinterpret_cast< typelib_TypeDescription ** >(&pInterface), false))
1155 OSL_FAIL("No interface corresponding to interface attribute");
1156 return;
1159 typelib_typedescription_newEmpty(
1160 reinterpret_cast<typelib_TypeDescription **>(ppRet), typelib_TypeClass_INTERFACE_ATTRIBUTE, pTypeName );
1162 rtl_uString_newFromStr_WithLength( &(*ppRet)->aBase.pMemberName,
1163 pTypeName->buffer + nOffset +1,
1164 pTypeName->length - nOffset -1 );
1165 (*ppRet)->aBase.nPosition = nAbsolutePosition;
1166 typelib_typedescriptionreference_new( &(*ppRet)->pAttributeTypeRef, eAttributeTypeClass, pAttributeTypeName );
1167 (*ppRet)->bReadOnly = bReadOnly;
1168 (*ppRet)->pInterface = pInterface;
1169 (*ppRet)->pBaseRef = nullptr;
1170 OSL_ASSERT(
1171 (nAbsolutePosition >= pInterface->nAllMembers - pInterface->nMembers)
1172 && nAbsolutePosition < pInterface->nAllMembers);
1173 (*ppRet)->nIndex = nAbsolutePosition
1174 - (pInterface->nAllMembers - pInterface->nMembers);
1175 (*ppRet)->nGetExceptions = nGetExceptions;
1176 (*ppRet)->ppGetExceptions = copyExceptions(
1177 nGetExceptions, ppGetExceptionNames);
1178 (*ppRet)->nSetExceptions = nSetExceptions;
1179 (*ppRet)->ppSetExceptions = copyExceptions(
1180 nSetExceptions, ppSetExceptionNames);
1181 static_assert( TYPELIB_TYPEDESCRIPTIONREFERENCE_ISREALLYWEAK( typelib_TypeClass_INTERFACE_ATTRIBUTE ) );
1182 assert(reinterpret_cast<typelib_TypeDescription *>(*ppRet)->pWeakRef == nullptr);
1186 extern "C" void SAL_CALL typelib_typedescription_acquire(
1187 typelib_TypeDescription * pTypeDescription ) noexcept
1189 osl_atomic_increment( &pTypeDescription->nRefCount );
1193 namespace {
1195 void deleteExceptions(
1196 sal_Int32 count, typelib_TypeDescriptionReference ** exceptions)
1198 for (sal_Int32 i = 0; i < count; ++i) {
1199 typelib_typedescriptionreference_release(exceptions[i]);
1201 delete[] exceptions;
1206 // frees anything except typelib_TypeDescription base!
1207 static void typelib_typedescription_destructExtendedMembers(
1208 typelib_TypeDescription * pTD )
1210 OSL_ASSERT( typelib_TypeClass_TYPEDEF != pTD->eTypeClass );
1212 switch( pTD->eTypeClass )
1214 case typelib_TypeClass_SEQUENCE:
1215 if( reinterpret_cast<typelib_IndirectTypeDescription*>(pTD)->pType )
1216 typelib_typedescriptionreference_release( reinterpret_cast<typelib_IndirectTypeDescription*>(pTD)->pType );
1217 break;
1218 case typelib_TypeClass_STRUCT:
1219 delete[] reinterpret_cast< typelib_StructTypeDescription * >(pTD)->
1220 pParameterizedTypes;
1221 [[fallthrough]];
1222 case typelib_TypeClass_EXCEPTION:
1224 typelib_CompoundTypeDescription * pCTD = reinterpret_cast<typelib_CompoundTypeDescription*>(pTD);
1225 if( pCTD->pBaseTypeDescription )
1226 typelib_typedescription_release( &pCTD->pBaseTypeDescription->aBase );
1227 sal_Int32 i;
1228 for( i = 0; i < pCTD->nMembers; i++ )
1230 typelib_typedescriptionreference_release( pCTD->ppTypeRefs[i] );
1232 if (pCTD->ppMemberNames)
1234 for ( i = 0; i < pCTD->nMembers; i++ )
1236 rtl_uString_release( pCTD->ppMemberNames[i] );
1238 delete [] pCTD->ppMemberNames;
1240 delete [] pCTD->ppTypeRefs;
1241 delete [] pCTD->pMemberOffsets;
1243 break;
1244 case typelib_TypeClass_INTERFACE:
1246 typelib_InterfaceTypeDescription * pITD = reinterpret_cast<typelib_InterfaceTypeDescription*>(pTD);
1247 for( sal_Int32 i = 0; i < pITD->nAllMembers; i++ )
1249 typelib_typedescriptionreference_release( pITD->ppAllMembers[i] );
1251 delete [] pITD->ppAllMembers;
1252 delete [] pITD->pMapMemberIndexToFunctionIndex;
1253 delete [] pITD->pMapFunctionIndexToMemberIndex;
1254 for (sal_Int32 i = 0; i < pITD->nBaseTypes; ++i) {
1255 typelib_typedescription_release(
1256 reinterpret_cast< typelib_TypeDescription * >(
1257 pITD->ppBaseTypes[i]));
1259 delete[] pITD->ppBaseTypes;
1260 break;
1262 case typelib_TypeClass_INTERFACE_METHOD:
1264 typelib_InterfaceMethodTypeDescription * pIMTD = reinterpret_cast<typelib_InterfaceMethodTypeDescription*>(pTD);
1265 if( pIMTD->pReturnTypeRef )
1266 typelib_typedescriptionreference_release( pIMTD->pReturnTypeRef );
1267 for( sal_Int32 i = 0; i < pIMTD->nParams; i++ )
1269 rtl_uString_release( pIMTD->pParams[ i ].pName );
1270 typelib_typedescriptionreference_release( pIMTD->pParams[ i ].pTypeRef );
1272 delete [] pIMTD->pParams;
1273 deleteExceptions(pIMTD->nExceptions, pIMTD->ppExceptions);
1274 rtl_uString_release( pIMTD->aBase.pMemberName );
1275 typelib_typedescription_release(&pIMTD->pInterface->aBase);
1276 if (pIMTD->pBaseRef != nullptr) {
1277 typelib_typedescriptionreference_release(pIMTD->pBaseRef);
1280 break;
1281 case typelib_TypeClass_INTERFACE_ATTRIBUTE:
1283 typelib_InterfaceAttributeTypeDescription * pIATD = reinterpret_cast<typelib_InterfaceAttributeTypeDescription*>(pTD);
1284 deleteExceptions(pIATD->nGetExceptions, pIATD->ppGetExceptions);
1285 deleteExceptions(pIATD->nSetExceptions, pIATD->ppSetExceptions);
1286 if( pIATD->pAttributeTypeRef )
1287 typelib_typedescriptionreference_release( pIATD->pAttributeTypeRef );
1288 if( pIATD->aBase.pMemberName )
1289 rtl_uString_release( pIATD->aBase.pMemberName );
1290 typelib_typedescription_release(&pIATD->pInterface->aBase);
1291 if (pIATD->pBaseRef != nullptr) {
1292 typelib_typedescriptionreference_release(pIATD->pBaseRef);
1295 break;
1296 case typelib_TypeClass_ENUM:
1298 typelib_EnumTypeDescription * pEnum = reinterpret_cast<typelib_EnumTypeDescription *>(pTD);
1299 for ( sal_Int32 nPos = pEnum->nEnumValues; nPos--; )
1301 rtl_uString_release( pEnum->ppEnumNames[nPos] );
1303 delete [] pEnum->ppEnumNames;
1304 delete [] pEnum->pEnumValues;
1306 break;
1307 default:
1308 break;
1313 extern "C" void SAL_CALL typelib_typedescription_release(
1314 typelib_TypeDescription * pTD ) noexcept
1316 sal_Int32 ref = osl_atomic_decrement( &pTD->nRefCount );
1317 OSL_ASSERT(ref >= 0);
1318 if (0 != ref)
1319 return;
1321 TypeDescriptor_Init_Impl &rInit = Init();
1322 if( TYPELIB_TYPEDESCRIPTIONREFERENCE_ISREALLYWEAK( pTD->eTypeClass ) )
1324 if( pTD->pWeakRef )
1327 MutexGuard aGuard( rInit.maMutex );
1328 // remove this description from the weak reference
1329 pTD->pWeakRef->pType = nullptr;
1331 typelib_typedescriptionreference_release( pTD->pWeakRef );
1334 else
1336 // this description is a reference too, so remove it from the hash table
1337 MutexGuard aGuard( rInit.maMutex );
1338 WeakMap_Impl::iterator aIt = rInit.maWeakMap.find( pTD->pTypeName->buffer );
1339 if( aIt != rInit.maWeakMap.end() && static_cast<void *>((*aIt).second) == static_cast<void *>(pTD) )
1341 // remove only if it contains the same object
1342 rInit.maWeakMap.erase( aIt );
1346 typelib_typedescription_destructExtendedMembers( pTD );
1347 rtl_uString_release( pTD->pTypeName );
1349 #if OSL_DEBUG_LEVEL > 0
1350 switch( pTD->eTypeClass )
1352 case typelib_TypeClass_SEQUENCE:
1353 osl_atomic_decrement( &rInit.nIndirectTypeDescriptionCount );
1354 break;
1355 case typelib_TypeClass_STRUCT:
1356 case typelib_TypeClass_EXCEPTION:
1357 osl_atomic_decrement( &rInit.nCompoundTypeDescriptionCount );
1358 break;
1359 case typelib_TypeClass_INTERFACE:
1360 osl_atomic_decrement( &rInit.nInterfaceTypeDescriptionCount );
1361 break;
1362 case typelib_TypeClass_INTERFACE_METHOD:
1363 osl_atomic_decrement( &rInit.nInterfaceMethodTypeDescriptionCount );
1364 break;
1365 case typelib_TypeClass_INTERFACE_ATTRIBUTE:
1366 osl_atomic_decrement( &rInit.nInterfaceAttributeTypeDescriptionCount );
1367 break;
1368 case typelib_TypeClass_ENUM:
1369 osl_atomic_decrement( &rInit.nEnumTypeDescriptionCount );
1370 break;
1371 default:
1372 osl_atomic_decrement( &rInit.nTypeDescriptionCount );
1374 #endif
1376 freeTypeDescription(pTD);
1380 extern "C" void SAL_CALL typelib_typedescription_register(
1381 typelib_TypeDescription ** ppNewDescription ) noexcept
1383 // connect the description with the weak reference
1384 TypeDescriptor_Init_Impl &rInit = Init();
1385 ClearableMutexGuard aGuard( rInit.maMutex );
1387 typelib_TypeDescriptionReference * pTDR = nullptr;
1388 typelib_typedescriptionreference_getByName( &pTDR, (*ppNewDescription)->pTypeName );
1390 OSL_ASSERT( (*ppNewDescription)->pWeakRef || TYPELIB_TYPEDESCRIPTIONREFERENCE_ISREALLYWEAK( (*ppNewDescription)->eTypeClass ) );
1391 if( pTDR )
1393 OSL_ASSERT( (*ppNewDescription)->eTypeClass == pTDR->eTypeClass );
1394 if( pTDR->pType )
1396 if (TYPELIB_TYPEDESCRIPTIONREFERENCE_ISREALLYWEAK( pTDR->eTypeClass ))
1398 // pRef->pType->pWeakRef == 0 means that the description is empty
1399 if (pTDR->pType->pWeakRef)
1401 if (osl_atomic_increment( &pTDR->pType->nRefCount ) > 1)
1403 // The reference is incremented. The object cannot be destroyed.
1404 // Release the guard at the earliest point.
1405 aGuard.clear();
1406 ::typelib_typedescription_release( *ppNewDescription );
1407 *ppNewDescription = pTDR->pType;
1408 ::typelib_typedescriptionreference_release( pTDR );
1409 return;
1411 // destruction of this type in progress (another thread!)
1412 (void)osl_atomic_decrement( &pTDR->pType->nRefCount );
1414 // take new descr
1415 pTDR->pType = *ppNewDescription;
1416 OSL_ASSERT( ! (*ppNewDescription)->pWeakRef );
1417 (*ppNewDescription)->pWeakRef = pTDR;
1418 return;
1420 // !reallyWeak
1422 if ((static_cast<void *>(pTDR) != static_cast<void *>(*ppNewDescription)) && // if different
1423 (!pTDR->pType->pWeakRef || // uninit: ref data only set
1424 // new one is complete:
1425 (!pTDR->pType->bComplete && (*ppNewDescription)->bComplete) ||
1426 // new one may be partly initialized interface (except of tables):
1427 (typelib_TypeClass_INTERFACE == pTDR->pType->eTypeClass &&
1428 !reinterpret_cast<typelib_InterfaceTypeDescription *>(pTDR->pType)->ppAllMembers &&
1429 (*reinterpret_cast<typelib_InterfaceTypeDescription **>(ppNewDescription))->ppAllMembers)))
1431 // uninitialized or incomplete
1433 if (pTDR->pType->pWeakRef) // if init
1435 switch (pTDR->pType->eTypeClass) {
1436 case typelib_TypeClass_ENUM:
1438 auto const src = reinterpret_cast<typelib_EnumTypeDescription *>(
1439 *ppNewDescription);
1440 auto const dst = reinterpret_cast<typelib_EnumTypeDescription *>(
1441 pTDR->pType);
1442 assert(dst->nEnumValues == 0);
1443 assert(dst->ppEnumNames == nullptr);
1444 assert(dst->pEnumValues == nullptr);
1445 std::swap(src->nEnumValues, dst->nEnumValues);
1446 std::swap(src->ppEnumNames, dst->ppEnumNames);
1447 std::swap(src->pEnumValues, dst->pEnumValues);
1448 break;
1450 case typelib_TypeClass_STRUCT:
1451 case typelib_TypeClass_EXCEPTION:
1453 auto const src = reinterpret_cast<typelib_CompoundTypeDescription *>(
1454 *ppNewDescription);
1455 auto const dst = reinterpret_cast<typelib_CompoundTypeDescription *>(
1456 pTDR->pType);
1457 assert(
1458 (dst->pBaseTypeDescription == nullptr)
1459 == (src->pBaseTypeDescription == nullptr));
1460 assert(dst->nMembers == src->nMembers);
1461 assert((dst->pMemberOffsets == nullptr) == (dst->nMembers == 0));
1462 assert((dst->ppTypeRefs == nullptr) == (dst->nMembers == 0));
1463 assert(dst->ppMemberNames == nullptr);
1464 assert(
1465 pTDR->pType->eTypeClass != typelib_TypeClass_STRUCT
1466 || ((reinterpret_cast<typelib_StructTypeDescription *>(
1467 dst)->pParameterizedTypes
1468 == nullptr)
1469 == (reinterpret_cast<typelib_StructTypeDescription *>(
1470 src)->pParameterizedTypes
1471 == nullptr)));
1472 std::swap(src->ppMemberNames, dst->ppMemberNames);
1473 break;
1475 case typelib_TypeClass_INTERFACE:
1477 auto const src = reinterpret_cast<typelib_InterfaceTypeDescription *>(
1478 *ppNewDescription);
1479 auto const dst = reinterpret_cast<typelib_InterfaceTypeDescription *>(
1480 pTDR->pType);
1481 assert(
1482 (dst->pBaseTypeDescription == nullptr)
1483 == (src->pBaseTypeDescription == nullptr));
1484 assert(dst->nMembers == 0);
1485 assert(dst->ppMembers == nullptr);
1486 assert(dst->nAllMembers == 0);
1487 assert(dst->ppAllMembers == nullptr);
1488 assert(dst->pMapMemberIndexToFunctionIndex == nullptr);
1489 assert(dst->nMapFunctionIndexToMemberIndex == 0);
1490 assert(dst->pMapFunctionIndexToMemberIndex == nullptr);
1491 assert(dst->nBaseTypes == src->nBaseTypes);
1492 assert((dst->ppBaseTypes == nullptr) == (src->ppBaseTypes == nullptr));
1493 std::swap(src->nMembers, dst->nMembers);
1494 std::swap(src->ppMembers, dst->ppMembers);
1495 std::swap(src->nAllMembers, dst->nAllMembers);
1496 std::swap(src->ppAllMembers, dst->ppAllMembers);
1497 std::swap(
1498 src->pMapMemberIndexToFunctionIndex,
1499 dst->pMapMemberIndexToFunctionIndex);
1500 std::swap(
1501 src->nMapFunctionIndexToMemberIndex,
1502 dst->nMapFunctionIndexToMemberIndex);
1503 std::swap(
1504 src->pMapFunctionIndexToMemberIndex,
1505 dst->pMapFunctionIndexToMemberIndex);
1506 break;
1508 default:
1509 assert(false); // this cannot happen
1512 else
1514 // pTDR->pType->pWeakRef == 0 means that the description is empty
1515 // description is not weak and the not the same
1516 sal_Int32 nSize = getDescriptionSize( (*ppNewDescription)->eTypeClass );
1518 // copy all specific data for the descriptions
1519 memcpy(
1520 pTDR->pType +1,
1521 *ppNewDescription +1,
1522 nSize - sizeof(typelib_TypeDescription) );
1524 memset(
1525 *ppNewDescription +1,
1527 nSize - sizeof( typelib_TypeDescription ) );
1530 pTDR->pType->bComplete = (*ppNewDescription)->bComplete;
1531 pTDR->pType->nSize = (*ppNewDescription)->nSize;
1532 pTDR->pType->nAlignment = (*ppNewDescription)->nAlignment;
1534 if( pTDR->pType->bOnDemand && !(*ppNewDescription)->bOnDemand )
1536 // switch from OnDemand to !OnDemand, so the description must be acquired
1537 typelib_typedescription_acquire( pTDR->pType );
1539 else if( !pTDR->pType->bOnDemand && (*ppNewDescription)->bOnDemand )
1541 // switch from !OnDemand to OnDemand, so the description must be released
1542 assert(pTDR->pType->nRefCount > 1);
1543 // coverity[freed_arg] - pType's nRefCount is > 1 here
1544 typelib_typedescription_release( pTDR->pType );
1547 pTDR->pType->bOnDemand = (*ppNewDescription)->bOnDemand;
1548 // initialized
1549 pTDR->pType->pWeakRef = pTDR;
1552 typelib_typedescription_release( *ppNewDescription );
1553 // pTDR was acquired by getByName(), so it must not be acquired again
1554 *ppNewDescription = pTDR->pType;
1555 return;
1558 else if( TYPELIB_TYPEDESCRIPTIONREFERENCE_ISREALLYWEAK( (*ppNewDescription)->eTypeClass) )
1560 typelib_typedescriptionreference_new(
1561 &pTDR, (*ppNewDescription)->eTypeClass, (*ppNewDescription)->pTypeName );
1563 else
1565 pTDR = reinterpret_cast<typelib_TypeDescriptionReference *>(*ppNewDescription);
1567 // description is the weak itself, so register it
1568 rInit.maWeakMap[pTDR->pTypeName->buffer] = pTDR;
1569 OSL_ASSERT( static_cast<void *>(*ppNewDescription) == static_cast<void *>(pTDR) );
1572 // By default this reference is not really weak. The reference hold the description
1573 // and the description hold the reference.
1574 if( !(*ppNewDescription)->bOnDemand )
1576 // nor OnDemand so the description must be acquired if registered
1577 typelib_typedescription_acquire( *ppNewDescription );
1580 pTDR->pType = *ppNewDescription;
1581 (*ppNewDescription)->pWeakRef = pTDR;
1582 OSL_ASSERT( rtl_ustr_compare( pTDR->pTypeName->buffer, (*ppNewDescription)->pTypeName->buffer ) == 0 );
1583 OSL_ASSERT( pTDR->eTypeClass == (*ppNewDescription)->eTypeClass );
1587 static bool type_equals(
1588 typelib_TypeDescriptionReference const * p1, typelib_TypeDescriptionReference const * p2 )
1590 return (p1 == p2 ||
1591 (p1->eTypeClass == p2->eTypeClass &&
1592 p1->pTypeName->length == p2->pTypeName->length &&
1593 rtl_ustr_compare( p1->pTypeName->buffer, p2->pTypeName->buffer ) == 0));
1595 extern "C" sal_Bool SAL_CALL typelib_typedescription_equals(
1596 const typelib_TypeDescription * p1, const typelib_TypeDescription * p2 ) noexcept
1598 return type_equals(
1599 reinterpret_cast<typelib_TypeDescriptionReference const *>(p1), reinterpret_cast<typelib_TypeDescriptionReference const *>(p2) );
1603 extern "C" sal_Int32 typelib_typedescription_getAlignedUnoSize(
1604 const typelib_TypeDescription * pTypeDescription,
1605 sal_Int32 nOffset, sal_Int32 & rMaxIntegralTypeSize ) noexcept
1607 sal_Int32 nSize;
1608 if( pTypeDescription->nSize )
1610 // size and alignment are set
1611 rMaxIntegralTypeSize = pTypeDescription->nAlignment;
1612 nSize = pTypeDescription->nSize;
1614 else
1616 nSize = 0;
1617 rMaxIntegralTypeSize = 1;
1619 OSL_ASSERT( typelib_TypeClass_TYPEDEF != pTypeDescription->eTypeClass );
1621 switch( pTypeDescription->eTypeClass )
1623 case typelib_TypeClass_INTERFACE:
1624 // FEATURE_INTERFACE
1625 nSize = rMaxIntegralTypeSize = sal_Int32(sizeof( void * ));
1626 break;
1627 case typelib_TypeClass_ENUM:
1628 nSize = rMaxIntegralTypeSize = sal_Int32(sizeof( typelib_TypeClass ));
1629 break;
1630 case typelib_TypeClass_STRUCT:
1631 case typelib_TypeClass_EXCEPTION:
1632 // FEATURE_EMPTYCLASS
1634 typelib_CompoundTypeDescription const * pTmp = reinterpret_cast<typelib_CompoundTypeDescription const *>(pTypeDescription);
1635 sal_Int32 nStructSize = 0;
1636 if( pTmp->pBaseTypeDescription )
1638 // inherit structs extends the base struct.
1639 nStructSize = pTmp->pBaseTypeDescription->aBase.nSize;
1640 rMaxIntegralTypeSize = pTmp->pBaseTypeDescription->aBase.nAlignment;
1642 for( sal_Int32 i = 0; i < pTmp->nMembers; i++ )
1644 typelib_TypeDescription * pMemberType = nullptr;
1645 typelib_TypeDescriptionReference * pMemberRef = pTmp->ppTypeRefs[i];
1647 sal_Int32 nMaxIntegral;
1648 if (pMemberRef->eTypeClass == typelib_TypeClass_INTERFACE
1649 || pMemberRef->eTypeClass == typelib_TypeClass_SEQUENCE)
1651 nMaxIntegral = sal_Int32(sizeof(void *));
1652 nStructSize = newAlignedSize( nStructSize, nMaxIntegral, nMaxIntegral );
1654 else
1656 TYPELIB_DANGER_GET( &pMemberType, pMemberRef );
1657 nStructSize = typelib_typedescription_getAlignedUnoSize(
1658 pMemberType, nStructSize, nMaxIntegral );
1659 TYPELIB_DANGER_RELEASE( pMemberType );
1661 if( nMaxIntegral > rMaxIntegralTypeSize )
1662 rMaxIntegralTypeSize = nMaxIntegral;
1664 #ifdef __m68k__
1665 // Anything that is at least 16 bits wide is aligned on a 16-bit
1666 // boundary on the m68k default abi
1667 sal_Int32 nMaxAlign = std::min(rMaxIntegralTypeSize, sal_Int32( 2 ));
1668 nStructSize = (nStructSize + nMaxAlign -1) / nMaxAlign * nMaxAlign;
1669 #else
1670 // Example: A { double; int; } structure has a size of 16 instead of 10. The
1671 // compiler must follow this rule if it is possible to access members in arrays through:
1672 // (Element *)((char *)pArray + sizeof( Element ) * ElementPos)
1673 nStructSize = (nStructSize + rMaxIntegralTypeSize -1)
1674 / rMaxIntegralTypeSize * rMaxIntegralTypeSize;
1675 #endif
1676 nSize += nStructSize;
1678 break;
1679 case typelib_TypeClass_SEQUENCE:
1680 nSize = rMaxIntegralTypeSize = sal_Int32(sizeof( void * ));
1681 break;
1682 case typelib_TypeClass_ANY:
1683 // FEATURE_ANY
1684 nSize = sal_Int32(sizeof( uno_Any ));
1685 rMaxIntegralTypeSize = sal_Int32(sizeof( void * ));
1686 break;
1687 case typelib_TypeClass_TYPE:
1688 nSize = rMaxIntegralTypeSize = sal_Int32(sizeof( typelib_TypeDescriptionReference * ));
1689 break;
1690 case typelib_TypeClass_BOOLEAN:
1691 nSize = rMaxIntegralTypeSize = sal_Int32(sizeof( sal_Bool ));
1692 break;
1693 case typelib_TypeClass_CHAR:
1694 nSize = rMaxIntegralTypeSize = sal_Int32(sizeof( sal_Unicode ));
1695 break;
1696 case typelib_TypeClass_STRING:
1697 // FEATURE_STRING
1698 nSize = rMaxIntegralTypeSize = sal_Int32(sizeof( rtl_uString * ));
1699 break;
1700 case typelib_TypeClass_FLOAT:
1701 nSize = rMaxIntegralTypeSize = sal_Int32(sizeof( float ));
1702 break;
1703 case typelib_TypeClass_DOUBLE:
1704 nSize = rMaxIntegralTypeSize = sal_Int32(sizeof( double ));
1705 break;
1706 case typelib_TypeClass_BYTE:
1707 nSize = rMaxIntegralTypeSize = sal_Int32(sizeof( sal_Int8 ));
1708 break;
1709 case typelib_TypeClass_SHORT:
1710 case typelib_TypeClass_UNSIGNED_SHORT:
1711 nSize = rMaxIntegralTypeSize = sal_Int32(sizeof( sal_Int16 ));
1712 break;
1713 case typelib_TypeClass_LONG:
1714 case typelib_TypeClass_UNSIGNED_LONG:
1715 nSize = rMaxIntegralTypeSize = sal_Int32(sizeof( sal_Int32 ));
1716 break;
1717 case typelib_TypeClass_HYPER:
1718 case typelib_TypeClass_UNSIGNED_HYPER:
1719 nSize = rMaxIntegralTypeSize = sal_Int32(sizeof( sal_Int64 ));
1720 break;
1721 case typelib_TypeClass_UNKNOWN:
1722 case typelib_TypeClass_SERVICE:
1723 case typelib_TypeClass_MODULE:
1724 default:
1725 OSL_FAIL( "not convertible type" );
1729 return newAlignedSize( nOffset, nSize, rMaxIntegralTypeSize );
1733 namespace {
1735 typelib_TypeDescriptionReference ** copyExceptions(
1736 sal_Int32 count, typelib_TypeDescriptionReference ** source)
1738 typelib_TypeDescriptionReference ** p
1739 = new typelib_TypeDescriptionReference *[count];
1740 for (sal_Int32 i = 0; i < count; ++i) {
1741 p[i] = source[i];
1742 typelib_typedescriptionreference_acquire(p[i]);
1744 return p;
1747 bool createDerivedInterfaceMemberDescription(
1748 typelib_TypeDescription ** result, OUString const & name,
1749 typelib_TypeDescriptionReference * baseRef,
1750 typelib_TypeDescription const * base, typelib_TypeDescription * interface,
1751 sal_Int32 index, sal_Int32 position)
1753 if (!baseRef || !base || !interface)
1754 return false;
1756 switch (base->eTypeClass) {
1757 case typelib_TypeClass_INTERFACE_METHOD:
1759 typelib_typedescription_newEmpty(
1760 result, typelib_TypeClass_INTERFACE_METHOD, name.pData);
1761 typelib_InterfaceMethodTypeDescription const * baseMethod
1762 = reinterpret_cast<
1763 typelib_InterfaceMethodTypeDescription const * >(base);
1764 typelib_InterfaceMethodTypeDescription * newMethod
1765 = reinterpret_cast<
1766 typelib_InterfaceMethodTypeDescription * >(*result);
1767 newMethod->aBase.nPosition = position;
1768 newMethod->aBase.pMemberName
1769 = baseMethod->aBase.pMemberName;
1770 rtl_uString_acquire(
1771 newMethod->aBase.pMemberName);
1772 newMethod->pReturnTypeRef = baseMethod->pReturnTypeRef;
1773 typelib_typedescriptionreference_acquire(
1774 newMethod->pReturnTypeRef);
1775 newMethod->nParams = baseMethod->nParams;
1776 newMethod->pParams = new typelib_MethodParameter[
1777 newMethod->nParams];
1778 for (sal_Int32 i = 0; i < newMethod->nParams; ++i) {
1779 newMethod->pParams[i].pName
1780 = baseMethod->pParams[i].pName;
1781 rtl_uString_acquire(
1782 newMethod->pParams[i].pName);
1783 newMethod->pParams[i].pTypeRef
1784 = baseMethod->pParams[i].pTypeRef;
1785 typelib_typedescriptionreference_acquire(
1786 newMethod->pParams[i].pTypeRef);
1787 newMethod->pParams[i].bIn = baseMethod->pParams[i].bIn;
1788 newMethod->pParams[i].bOut = baseMethod->pParams[i].bOut;
1790 newMethod->nExceptions = baseMethod->nExceptions;
1791 newMethod->ppExceptions = copyExceptions(
1792 baseMethod->nExceptions, baseMethod->ppExceptions);
1793 newMethod->bOneWay = baseMethod->bOneWay;
1794 newMethod->pInterface
1795 = reinterpret_cast< typelib_InterfaceTypeDescription * >(
1796 interface);
1797 newMethod->pBaseRef = baseRef;
1798 newMethod->nIndex = index;
1799 return true;
1802 case typelib_TypeClass_INTERFACE_ATTRIBUTE:
1804 typelib_typedescription_newEmpty(
1805 result, typelib_TypeClass_INTERFACE_ATTRIBUTE, name.pData);
1806 typelib_InterfaceAttributeTypeDescription const * baseAttribute
1807 = reinterpret_cast<
1808 typelib_InterfaceAttributeTypeDescription const * >(base);
1809 typelib_InterfaceAttributeTypeDescription * newAttribute
1810 = reinterpret_cast<
1811 typelib_InterfaceAttributeTypeDescription * >(*result);
1812 newAttribute->aBase.nPosition = position;
1813 newAttribute->aBase.pMemberName
1814 = baseAttribute->aBase.pMemberName;
1815 rtl_uString_acquire(newAttribute->aBase.pMemberName);
1816 newAttribute->bReadOnly = baseAttribute->bReadOnly;
1817 newAttribute->pAttributeTypeRef
1818 = baseAttribute->pAttributeTypeRef;
1819 typelib_typedescriptionreference_acquire(newAttribute->pAttributeTypeRef);
1820 newAttribute->pInterface
1821 = reinterpret_cast< typelib_InterfaceTypeDescription * >(
1822 interface);
1823 newAttribute->pBaseRef = baseRef;
1824 newAttribute->nIndex = index;
1825 newAttribute->nGetExceptions = baseAttribute->nGetExceptions;
1826 newAttribute->ppGetExceptions = copyExceptions(
1827 baseAttribute->nGetExceptions,
1828 baseAttribute->ppGetExceptions);
1829 newAttribute->nSetExceptions = baseAttribute->nSetExceptions;
1830 newAttribute->ppSetExceptions = copyExceptions(
1831 baseAttribute->nSetExceptions,
1832 baseAttribute->ppSetExceptions);
1833 return true;
1836 default:
1837 break;
1839 return false;
1844 extern "C" void SAL_CALL typelib_typedescription_getByName(
1845 typelib_TypeDescription ** ppRet, rtl_uString * pName ) noexcept
1847 if( *ppRet )
1849 typelib_typedescription_release( *ppRet );
1850 *ppRet = nullptr;
1853 static bool bInited = false;
1854 TypeDescriptor_Init_Impl &rInit = Init();
1856 if( !bInited )
1858 // guard against multi thread access
1859 MutexGuard aGuard( rInit.maMutex );
1860 if( !bInited )
1862 // avoid recursion during the next ...new calls
1863 bInited = true;
1865 typelib_TypeDescription * pType = nullptr;
1866 typelib_typedescription_new( &pType, typelib_TypeClass_TYPE, u"type"_ustr.pData, nullptr, 0, nullptr );
1867 typelib_typedescription_register( &pType );
1868 typelib_typedescription_new( &pType, typelib_TypeClass_VOID, u"void"_ustr.pData, nullptr, 0, nullptr );
1869 typelib_typedescription_register( &pType );
1870 typelib_typedescription_new( &pType, typelib_TypeClass_BOOLEAN, u"boolean"_ustr.pData, nullptr, 0, nullptr );
1871 typelib_typedescription_register( &pType );
1872 typelib_typedescription_new( &pType, typelib_TypeClass_CHAR, u"char"_ustr.pData, nullptr, 0, nullptr );
1873 typelib_typedescription_register( &pType );
1874 typelib_typedescription_new( &pType, typelib_TypeClass_BYTE, u"byte"_ustr.pData, nullptr, 0, nullptr );
1875 typelib_typedescription_register( &pType );
1876 typelib_typedescription_new( &pType, typelib_TypeClass_STRING, u"string"_ustr.pData, nullptr, 0, nullptr );
1877 typelib_typedescription_register( &pType );
1878 typelib_typedescription_new( &pType, typelib_TypeClass_SHORT, u"short"_ustr.pData, nullptr, 0, nullptr );
1879 typelib_typedescription_register( &pType );
1880 typelib_typedescription_new( &pType, typelib_TypeClass_UNSIGNED_SHORT, u"unsigned short"_ustr.pData, nullptr, 0, nullptr );
1881 typelib_typedescription_register( &pType );
1882 typelib_typedescription_new( &pType, typelib_TypeClass_LONG, u"long"_ustr.pData, nullptr, 0, nullptr );
1883 typelib_typedescription_register( &pType );
1884 typelib_typedescription_new( &pType, typelib_TypeClass_UNSIGNED_LONG, u"unsigned long"_ustr.pData, nullptr, 0, nullptr );
1885 typelib_typedescription_register( &pType );
1886 typelib_typedescription_new( &pType, typelib_TypeClass_HYPER, u"hyper"_ustr.pData, nullptr, 0, nullptr );
1887 typelib_typedescription_register( &pType );
1888 typelib_typedescription_new( &pType, typelib_TypeClass_UNSIGNED_HYPER, u"unsigned hyper"_ustr.pData, nullptr, 0, nullptr );
1889 typelib_typedescription_register( &pType );
1890 typelib_typedescription_new( &pType, typelib_TypeClass_FLOAT, u"float"_ustr.pData, nullptr, 0, nullptr );
1891 typelib_typedescription_register( &pType );
1892 typelib_typedescription_new( &pType, typelib_TypeClass_DOUBLE, u"double"_ustr.pData, nullptr, 0, nullptr );
1893 typelib_typedescription_register( &pType );
1894 typelib_typedescription_new( &pType, typelib_TypeClass_ANY, u"any"_ustr.pData, nullptr, 0, nullptr );
1895 typelib_typedescription_register( &pType );
1896 typelib_typedescription_release( pType );
1900 typelib_TypeDescriptionReference * pTDR = nullptr;
1901 typelib_typedescriptionreference_getByName( &pTDR, pName );
1902 if( pTDR )
1905 // guard against multi thread access
1906 MutexGuard aGuard( rInit.maMutex );
1907 // pTDR->pType->pWeakRef == 0 means that the description is empty
1908 if( pTDR->pType && pTDR->pType->pWeakRef )
1910 typelib_typedescription_acquire( pTDR->pType );
1911 *ppRet = pTDR->pType;
1914 typelib_typedescriptionreference_release( pTDR );
1917 if (nullptr != *ppRet)
1918 return;
1920 // check for sequence
1921 OUString const & name = OUString::unacquired( &pName );
1922 if (2 < name.getLength() && '[' == name[ 0 ])
1924 OUString element_name( name.copy( 2 ) );
1925 typelib_TypeDescription * element_td = nullptr;
1926 typelib_typedescription_getByName( &element_td, element_name.pData );
1927 if (nullptr != element_td)
1929 typelib_typedescription_new(
1930 ppRet, typelib_TypeClass_SEQUENCE, pName, element_td->pWeakRef, 0, nullptr );
1931 // register?
1932 typelib_typedescription_release( element_td );
1935 if (nullptr == *ppRet)
1937 // Check for derived interface member type:
1938 sal_Int32 i1 = name.lastIndexOf(":@");
1939 if (i1 >= 0) {
1940 sal_Int32 i2 = i1 + RTL_CONSTASCII_LENGTH(":@");
1941 sal_Int32 i3 = name.indexOf(',', i2);
1942 if (i3 >= 0) {
1943 sal_Int32 i4 = name.indexOf(':', i3);
1944 if (i4 >= 0) {
1945 typelib_TypeDescriptionReference * pBaseRef = nullptr;
1946 typelib_TypeDescription * pBase = nullptr;
1947 typelib_TypeDescription * pInterface = nullptr;
1948 typelib_typedescriptionreference_getByName(
1949 &pBaseRef, name.copy(0, i1).pData);
1950 if (pBaseRef != nullptr) {
1951 typelib_typedescriptionreference_getDescription(
1952 &pBase, pBaseRef);
1954 typelib_typedescription_getByName(
1955 &pInterface, name.copy(i4 + 1).pData);
1956 if (!createDerivedInterfaceMemberDescription(
1957 ppRet, name, pBaseRef, pBase, pInterface,
1958 o3tl::toInt32(name.subView(i2, i3 - i2)),
1959 o3tl::toInt32(name.subView(i3 + 1, i4 - i3 - 1))))
1961 if (pInterface != nullptr) {
1962 typelib_typedescription_release(pInterface);
1964 if (pBase != nullptr) {
1965 typelib_typedescription_release(pBase);
1967 if (pBaseRef != nullptr) {
1968 typelib_typedescriptionreference_release(
1969 pBaseRef);
1976 if (nullptr == *ppRet)
1978 // on demand access
1979 rInit.callChain( ppRet, pName );
1982 if( !(*ppRet) )
1983 return;
1985 // typedescription found
1986 if (typelib_TypeClass_TYPEDEF == (*ppRet)->eTypeClass)
1988 typelib_TypeDescription * pTD = nullptr;
1989 typelib_typedescriptionreference_getDescription(
1990 &pTD, reinterpret_cast<typelib_IndirectTypeDescription *>(*ppRet)->pType );
1991 typelib_typedescription_release( *ppRet );
1992 *ppRet = pTD;
1994 else
1996 // set to on demand
1997 (*ppRet)->bOnDemand = true;
1998 // The type description is hold by the reference until
1999 // on demand is activated.
2000 typelib_typedescription_register( ppRet );
2002 // insert into the cache
2003 MutexGuard aGuard( rInit.maMutex );
2004 if( rInit.maCache.size() >= nCacheSize )
2006 typelib_typedescription_release( rInit.maCache.front() );
2007 rInit.maCache.pop_front();
2009 // descriptions in the cache must be acquired!
2010 typelib_typedescription_acquire( *ppRet );
2011 rInit.maCache.push_back( *ppRet );
2015 extern "C" void SAL_CALL typelib_typedescriptionreference_newByAsciiName(
2016 typelib_TypeDescriptionReference ** ppTDR,
2017 typelib_TypeClass eTypeClass,
2018 const char * pTypeName ) noexcept
2020 OUString aTypeName( OUString::createFromAscii( pTypeName ) );
2021 typelib_typedescriptionreference_new( ppTDR, eTypeClass, aTypeName.pData );
2024 extern "C" void SAL_CALL typelib_typedescriptionreference_new(
2025 typelib_TypeDescriptionReference ** ppTDR,
2026 typelib_TypeClass eTypeClass, rtl_uString * pTypeName ) noexcept
2028 TypeDescriptor_Init_Impl &rInit = Init();
2029 if( eTypeClass == typelib_TypeClass_TYPEDEF )
2031 // on demand access
2032 typelib_TypeDescription * pRet = nullptr;
2033 rInit.callChain( &pRet, pTypeName );
2034 if( pRet )
2036 // typedescription found
2037 if (typelib_TypeClass_TYPEDEF == pRet->eTypeClass)
2039 typelib_typedescriptionreference_acquire(
2040 reinterpret_cast<typelib_IndirectTypeDescription *>(pRet)->pType );
2041 if (*ppTDR)
2042 typelib_typedescriptionreference_release( *ppTDR );
2043 *ppTDR = reinterpret_cast<typelib_IndirectTypeDescription *>(pRet)->pType;
2044 typelib_typedescription_release( pRet );
2046 else
2048 // set to on demand
2049 pRet->bOnDemand = true;
2050 // The type description is hold by the reference until
2051 // on demand is activated.
2052 typelib_typedescription_register( &pRet );
2054 // insert into the cache
2055 MutexGuard aGuard( rInit.maMutex );
2056 if( rInit.maCache.size() >= nCacheSize )
2058 typelib_typedescription_release( rInit.maCache.front() );
2059 rInit.maCache.pop_front();
2061 rInit.maCache.push_back( pRet );
2062 // pRet kept acquired for cache
2064 typelib_typedescriptionreference_acquire( pRet->pWeakRef );
2065 if (*ppTDR)
2066 typelib_typedescriptionreference_release( *ppTDR );
2067 *ppTDR = pRet->pWeakRef;
2070 else if (*ppTDR)
2072 SAL_INFO("cppu.typelib", "typedef not found : " << pTypeName);
2073 typelib_typedescriptionreference_release( *ppTDR );
2074 *ppTDR = nullptr;
2076 return;
2079 MutexGuard aGuard( rInit.maMutex );
2080 typelib_typedescriptionreference_getByName( ppTDR, pTypeName );
2081 if( *ppTDR )
2082 return;
2084 if( TYPELIB_TYPEDESCRIPTIONREFERENCE_ISREALLYWEAK( eTypeClass ) )
2086 typelib_TypeDescriptionReference * pTDR = new typelib_TypeDescriptionReference;
2087 #if OSL_DEBUG_LEVEL > 0
2088 osl_atomic_increment( &rInit.nTypeDescriptionReferenceCount );
2089 #endif
2090 pTDR->nRefCount = 1;
2091 pTDR->nStaticRefCount = 0;
2092 pTDR->eTypeClass = eTypeClass;
2093 pTDR->pUniqueIdentifier = nullptr;
2094 pTDR->pReserved = nullptr;
2095 pTDR->pTypeName = pTypeName;
2096 rtl_uString_acquire( pTDR->pTypeName );
2097 pTDR->pType = nullptr;
2098 *ppTDR = pTDR;
2100 else
2102 typelib_typedescription_newEmpty( reinterpret_cast<typelib_TypeDescription ** >(ppTDR), eTypeClass, pTypeName );
2103 // description will be registered but not acquired
2104 (*reinterpret_cast<typelib_TypeDescription **>(ppTDR))->bOnDemand = true;
2105 (*reinterpret_cast<typelib_TypeDescription **>(ppTDR))->bComplete = false;
2108 // Heavy hack, the const sal_Unicode * is hold by the typedescription reference
2109 // not registered
2110 rInit.maWeakMap[ (*ppTDR)->pTypeName->buffer ] = *ppTDR;
2114 extern "C" void SAL_CALL typelib_typedescriptionreference_acquire(
2115 typelib_TypeDescriptionReference * pRef ) noexcept
2117 osl_atomic_increment( &pRef->nRefCount );
2121 extern "C" void SAL_CALL typelib_typedescriptionreference_release(
2122 typelib_TypeDescriptionReference * pRef ) noexcept
2124 // Is it a type description?
2125 if( TYPELIB_TYPEDESCRIPTIONREFERENCE_ISREALLYWEAK( pRef->eTypeClass ) )
2127 if( ! osl_atomic_decrement( &pRef->nRefCount ) )
2129 TypeDescriptor_Init_Impl &rInit = Init();
2130 MutexGuard aGuard( rInit.maMutex );
2131 WeakMap_Impl::iterator aIt = rInit.maWeakMap.find( pRef->pTypeName->buffer );
2132 if( aIt != rInit.maWeakMap.end() && (*aIt).second == pRef )
2134 // remove only if it contains the same object
2135 rInit.maWeakMap.erase( aIt );
2138 rtl_uString_release( pRef->pTypeName );
2139 OSL_ASSERT( pRef->pType == nullptr );
2140 #if OSL_DEBUG_LEVEL > 0
2141 osl_atomic_decrement( &rInit.nTypeDescriptionReferenceCount );
2142 #endif
2143 delete pRef;
2146 else
2148 typelib_typedescription_release( reinterpret_cast<typelib_TypeDescription *>(pRef) );
2153 extern "C" void SAL_CALL typelib_typedescriptionreference_getDescription(
2154 typelib_TypeDescription ** ppRet, typelib_TypeDescriptionReference * pRef ) noexcept
2156 if( *ppRet )
2158 typelib_typedescription_release( *ppRet );
2159 *ppRet = nullptr;
2162 if( !TYPELIB_TYPEDESCRIPTIONREFERENCE_ISREALLYWEAK( pRef->eTypeClass ) && pRef->pType && pRef->pType->pWeakRef )
2164 // reference is a description and initialized
2165 osl_atomic_increment( &reinterpret_cast<typelib_TypeDescription *>(pRef)->nRefCount );
2166 *ppRet = reinterpret_cast<typelib_TypeDescription *>(pRef);
2167 return;
2171 MutexGuard aGuard( Init().maMutex );
2172 // pRef->pType->pWeakRef == 0 means that the description is empty
2173 if( pRef->pType && pRef->pType->pWeakRef )
2175 sal_Int32 n = osl_atomic_increment( &pRef->pType->nRefCount );
2176 if( n > 1 )
2178 // The reference is incremented. The object cannot be destroyed.
2179 // Release the guard at the earliest point.
2180 *ppRet = pRef->pType;
2181 return;
2183 (void)osl_atomic_decrement( &pRef->pType->nRefCount );
2184 // destruction of this type in progress (another thread!)
2185 // no access through this weak reference
2186 pRef->pType = nullptr;
2190 typelib_typedescription_getByName( ppRet, pRef->pTypeName );
2191 OSL_ASSERT( !*ppRet || rtl_ustr_compare( pRef->pTypeName->buffer, (*ppRet)->pTypeName->buffer ) == 0 );
2192 OSL_ASSERT( !*ppRet || pRef->eTypeClass == (*ppRet)->eTypeClass );
2193 OSL_ASSERT( !*ppRet || pRef == (*ppRet)->pWeakRef );
2194 pRef->pType = *ppRet;
2198 extern "C" void typelib_typedescriptionreference_getByName(
2199 typelib_TypeDescriptionReference ** ppRet, rtl_uString const * pName ) noexcept
2201 if( *ppRet )
2203 typelib_typedescriptionreference_release( *ppRet );
2204 *ppRet = nullptr;
2206 TypeDescriptor_Init_Impl &rInit = Init();
2208 MutexGuard aGuard( rInit.maMutex );
2209 WeakMap_Impl::const_iterator aIt = rInit.maWeakMap.find( pName->buffer );
2210 if( aIt == rInit.maWeakMap.end() )
2211 return;
2213 sal_Int32 n = osl_atomic_increment( &(*aIt).second->nRefCount );
2214 if( n > 1 )
2216 // The reference is incremented. The object cannot be destroyed.
2217 // Release the guard at the earliest point.
2218 *ppRet = (*aIt).second;
2220 else
2222 // destruction of this type in progress (another thread!)
2223 // no access through this weak reference
2224 (void)osl_atomic_decrement( &(*aIt).second->nRefCount );
2229 extern "C" sal_Bool SAL_CALL typelib_typedescriptionreference_equals(
2230 const typelib_TypeDescriptionReference * p1,
2231 const typelib_TypeDescriptionReference * p2 ) noexcept
2233 return (p1 == p2 ||
2234 (p1->eTypeClass == p2->eTypeClass &&
2235 p1->pTypeName->length == p2->pTypeName->length &&
2236 rtl_ustr_compare( p1->pTypeName->buffer, p2->pTypeName->buffer ) == 0));
2240 extern "C" void SAL_CALL typelib_typedescriptionreference_assign(
2241 typelib_TypeDescriptionReference ** ppDest,
2242 typelib_TypeDescriptionReference * pSource ) noexcept
2244 if (*ppDest != pSource)
2246 ::typelib_typedescriptionreference_acquire( pSource );
2247 ::typelib_typedescriptionreference_release( *ppDest );
2248 *ppDest = pSource;
2253 extern "C" void SAL_CALL typelib_setCacheSize( sal_Int32 ) noexcept
2258 const bool s_aAssignableFromTab[11][11] =
2260 /* from CH, BO, BY, SH, US, LO, UL, HY, UH, FL, DO */
2261 /* TypeClass_CHAR */ { true, false, false, false, false, false, false, false, false, false, false },
2262 /* TypeClass_BOOLEAN */ { false, true, false, false, false, false, false, false, false, false, false },
2263 /* TypeClass_BYTE */ { false, false, true, false, false, false, false, false, false, false, false },
2264 /* TypeClass_SHORT */ { false, false, true, true, true, false, false, false, false, false, false },
2265 /* TypeClass_UNSIGNED_SHORT */ { false, false, true, true, true, false, false, false, false, false, false },
2266 /* TypeClass_LONG */ { false, false, true, true, true, true, true, false, false, false, false },
2267 /* TypeClass_UNSIGNED_LONG */ { false, false, true, true, true, true, true, false, false, false, false },
2268 /* TypeClass_HYPER */ { false, false, true, true, true, true, true, true, true, false, false },
2269 /* TypeClass_UNSIGNED_HYPER */ { false, false, true, true, true, true, true, true, true, false, false },
2270 /* TypeClass_FLOAT */ { false, false, true, true, true, false, false, false, false, true, false },
2271 /* TypeClass_DOUBLE */ { false, false, true, true, true, true, true, false, false, true, true }
2275 extern "C" sal_Bool SAL_CALL typelib_typedescriptionreference_isAssignableFrom(
2276 typelib_TypeDescriptionReference * pAssignable,
2277 typelib_TypeDescriptionReference * pFrom ) noexcept
2279 if (!pAssignable || !pFrom)
2280 return false;
2282 typelib_TypeClass eAssignable = pAssignable->eTypeClass;
2283 typelib_TypeClass eFrom = pFrom->eTypeClass;
2285 if (eAssignable == typelib_TypeClass_ANY) // anything can be assigned to an any .)
2286 return true;
2287 if (eAssignable == eFrom)
2289 if (type_equals( pAssignable, pFrom )) // first shot
2291 return true;
2293 switch (eAssignable)
2295 case typelib_TypeClass_STRUCT:
2296 case typelib_TypeClass_EXCEPTION:
2298 typelib_TypeDescription * pFromDescr = nullptr;
2299 TYPELIB_DANGER_GET( &pFromDescr, pFrom );
2300 if (!reinterpret_cast<typelib_CompoundTypeDescription *>(pFromDescr)->pBaseTypeDescription)
2302 TYPELIB_DANGER_RELEASE( pFromDescr );
2303 return false;
2305 bool bRet = typelib_typedescriptionreference_isAssignableFrom(
2306 pAssignable,
2307 reinterpret_cast<typelib_CompoundTypeDescription *>(pFromDescr)->pBaseTypeDescription->aBase.pWeakRef );
2308 TYPELIB_DANGER_RELEASE( pFromDescr );
2309 return bRet;
2311 case typelib_TypeClass_INTERFACE:
2313 typelib_TypeDescription * pFromDescr = nullptr;
2314 TYPELIB_DANGER_GET( &pFromDescr, pFrom );
2315 typelib_InterfaceTypeDescription * pFromIfc
2316 = reinterpret_cast<
2317 typelib_InterfaceTypeDescription * >(pFromDescr);
2318 bool bRet = false;
2319 for (sal_Int32 i = 0; i < pFromIfc->nBaseTypes; ++i) {
2320 if (typelib_typedescriptionreference_isAssignableFrom(
2321 pAssignable,
2322 pFromIfc->ppBaseTypes[i]->aBase.pWeakRef))
2324 bRet = true;
2325 break;
2328 TYPELIB_DANGER_RELEASE( pFromDescr );
2329 return bRet;
2331 default:
2333 return false;
2337 return (eAssignable >= typelib_TypeClass_CHAR && eAssignable <= typelib_TypeClass_DOUBLE &&
2338 eFrom >= typelib_TypeClass_CHAR && eFrom <= typelib_TypeClass_DOUBLE &&
2339 s_aAssignableFromTab[eAssignable-1][eFrom-1]);
2342 extern "C" sal_Bool SAL_CALL typelib_typedescription_isAssignableFrom(
2343 typelib_TypeDescription * pAssignable,
2344 typelib_TypeDescription * pFrom ) noexcept
2346 return typelib_typedescriptionreference_isAssignableFrom(
2347 pAssignable->pWeakRef, pFrom->pWeakRef );
2351 extern "C" sal_Bool SAL_CALL typelib_typedescription_complete(
2352 typelib_TypeDescription ** ppTypeDescr ) noexcept
2354 return complete(ppTypeDescr, true);
2357 /* vim:set shiftwidth=4 softtabstop=4 expandtab: */