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