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