xref: /trunk/main/cppu/source/typelib/typelib.cxx (revision dcaf07f7f98db08cc6cf8841292bf500f56d5f1d)
1 /**************************************************************
2  *
3  * Licensed to the Apache Software Foundation (ASF) under one
4  * or more contributor license agreements.  See the NOTICE file
5  * distributed with this work for additional information
6  * regarding copyright ownership.  The ASF licenses this file
7  * to you under the Apache License, Version 2.0 (the
8  * "License"); you may not use this file except in compliance
9  * with the License.  You may obtain a copy of the License at
10  *
11  *   http://www.apache.org/licenses/LICENSE-2.0
12  *
13  * Unless required by applicable law or agreed to in writing,
14  * software distributed under the License is distributed on an
15  * "AS IS" BASIS, WITHOUT WARRANTIES OR CONDITIONS OF ANY
16  * KIND, either express or implied.  See the License for the
17  * specific language governing permissions and limitations
18  * under the License.
19  *
20  *************************************************************/
21 
22 
23 
24 // MARKER(update_precomp.py): autogen include statement, do not remove
25 #include "precompiled_cppu.hxx"
26 
27 #include <hash_map>
28 #include <list>
29 #include <set>
30 #include <vector>
31 
32 #include <stdarg.h>
33 #include <stdlib.h>
34 #include <string.h>
35 #include <sal/alloca.h>
36 #include <new>
37 #include <osl/interlck.h>
38 #include <osl/mutex.hxx>
39 #include <rtl/ustring.hxx>
40 #include <rtl/ustrbuf.hxx>
41 #include <rtl/alloc.h>
42 #include <rtl/instance.hxx>
43 #include <osl/diagnose.h>
44 #include <typelib/typedescription.h>
45 #include <uno/any2.h>
46 
47 using namespace rtl;
48 using namespace std;
49 using namespace osl;
50 
51 
52 //------------------------------------------------------------------------
53 //------------------------------------------------------------------------
54 #ifdef SAL_W32
55 #pragma pack(push, 8)
56 #elif defined(SAL_OS2)
57 #pragma pack(8)
58 #endif
59 
60 /**
61  * The double member determine the alignment.
62  * Under OS/2 and Windows the Alignment is min( 8, sizeof( type ) ).
63  * The alignment of a structure is min( 8, sizeof( max basic type ) ), the greatest basic type
64  * determines the alignment.
65  */
66 struct AlignSize_Impl
67 {
68     sal_Int16   nInt16;
69     double      dDouble;
70 };
71 
72 #ifdef SAL_W32
73 #pragma pack(pop)
74 #elif defined(SAL_OS2)
75 #pragma pack()
76 #endif
77 
78 // The value of the maximal alignment
79 static sal_Int32 nMaxAlignment = (sal_Int32)( (sal_Size)(&((AlignSize_Impl *) 16)->dDouble) - 16);
80 
adjustAlignment(sal_Int32 nRequestedAlignment)81 static inline sal_Int32 adjustAlignment( sal_Int32 nRequestedAlignment )
82     SAL_THROW( () )
83 {
84     if( nRequestedAlignment > nMaxAlignment )
85         nRequestedAlignment = nMaxAlignment;
86     return nRequestedAlignment;
87 }
88 
89 // Calculate the new size of the structure
newAlignedSize(sal_Int32 OldSize,sal_Int32 ElementSize,sal_Int32 NeededAlignment)90 static inline sal_Int32 newAlignedSize(
91     sal_Int32 OldSize, sal_Int32 ElementSize, sal_Int32 NeededAlignment )
92     SAL_THROW( () )
93 {
94     NeededAlignment = adjustAlignment( NeededAlignment );
95     return (OldSize + NeededAlignment -1) / NeededAlignment * NeededAlignment + ElementSize;
96 }
97 
reallyWeak(typelib_TypeClass eTypeClass)98 static inline sal_Bool reallyWeak( typelib_TypeClass eTypeClass )
99     SAL_THROW( () )
100 {
101     return TYPELIB_TYPEDESCRIPTIONREFERENCE_ISREALLYWEAK( eTypeClass );
102 }
103 
getDescriptionSize(typelib_TypeClass eTypeClass)104 static inline sal_Int32 getDescriptionSize( typelib_TypeClass eTypeClass )
105     SAL_THROW( () )
106 {
107     OSL_ASSERT( typelib_TypeClass_TYPEDEF != eTypeClass );
108 
109     sal_Int32 nSize;
110     // The reference is the description
111     // if the description is empty, then it must be filled with
112     // the new description
113     switch( eTypeClass )
114     {
115         case typelib_TypeClass_ARRAY:
116             nSize = (sal_Int32)sizeof( typelib_ArrayTypeDescription );
117         break;
118 
119         case typelib_TypeClass_SEQUENCE:
120             nSize = (sal_Int32)sizeof( typelib_IndirectTypeDescription );
121         break;
122 
123         case typelib_TypeClass_UNION:
124             nSize = (sal_Int32)sizeof( typelib_UnionTypeDescription );
125         break;
126 
127         case typelib_TypeClass_STRUCT:
128             nSize = (sal_Int32)sizeof( typelib_StructTypeDescription );
129         break;
130 
131         case typelib_TypeClass_EXCEPTION:
132             nSize = (sal_Int32)sizeof( typelib_CompoundTypeDescription );
133         break;
134 
135         case typelib_TypeClass_ENUM:
136             nSize = (sal_Int32)sizeof( typelib_EnumTypeDescription );
137         break;
138 
139         case typelib_TypeClass_INTERFACE:
140             nSize = (sal_Int32)sizeof( typelib_InterfaceTypeDescription );
141         break;
142 
143         case typelib_TypeClass_INTERFACE_METHOD:
144             nSize = (sal_Int32)sizeof( typelib_InterfaceMethodTypeDescription );
145         break;
146 
147         case typelib_TypeClass_INTERFACE_ATTRIBUTE:
148             nSize = (sal_Int32)sizeof( typelib_InterfaceAttributeTypeDescription );
149         break;
150 
151         default:
152             nSize = (sal_Int32)sizeof( typelib_TypeDescription );
153     }
154     return nSize;
155 }
156 
157 
158 //-----------------------------------------------------------------------------
159 extern "C" void SAL_CALL typelib_typedescriptionreference_getByName(
160     typelib_TypeDescriptionReference ** ppRet, rtl_uString * pName )
161     SAL_THROW_EXTERN_C();
162 
163 //-----------------------------------------------------------------------------
164 struct equalStr_Impl
165 {
operator ()equalStr_Impl166     sal_Bool operator()(const sal_Unicode * const & s1, const sal_Unicode * const & s2) const SAL_THROW( () )
167         { return 0 == rtl_ustr_compare( s1, s2 ); }
168 };
169 
170 //-----------------------------------------------------------------------------
171 struct hashStr_Impl
172 {
operator ()hashStr_Impl173     size_t operator()(const sal_Unicode * const & s) const SAL_THROW( () )
174         { return rtl_ustr_hashCode( s ); }
175 };
176 
177 
178 //-----------------------------------------------------------------------------
179 // Heavy hack, the const sal_Unicode * is held by the type description reference
180 typedef hash_map< const sal_Unicode *, typelib_TypeDescriptionReference *,
181                   hashStr_Impl, equalStr_Impl > WeakMap_Impl;
182 
183 typedef pair< void *, typelib_typedescription_Callback > CallbackEntry;
184 typedef list< CallbackEntry > CallbackSet_Impl;
185 typedef list< typelib_TypeDescription * > TypeDescriptionList_Impl;
186 
187 // # of cached elements
188 static sal_Int32 nCacheSize = 256;
189 
190 //-----------------------------------------------------------------------------
191 /**
192  * All members must set initial to 0 and no constructor is needed. So it
193  * doesn't care, when this class is static initialized.
194  */
195 struct TypeDescriptor_Init_Impl
196 {
197     //sal_Bool          bDesctructorCalled;
198     // all type description references
199     WeakMap_Impl *              pWeakMap;
200     // all type description callbacks
201     CallbackSet_Impl *          pCallbacks;
202     // A cache to hold descriptions
203     TypeDescriptionList_Impl *  pCache;
204     // The mutex to guard all type library accesses
205     Mutex *                     pMutex;
206 
207     inline Mutex & getMutex() SAL_THROW( () );
208 
209     inline void callChain( typelib_TypeDescription ** ppRet, rtl_uString * pName ) SAL_THROW( () );
210 
211 #if OSL_DEBUG_LEVEL > 1
212     // only for debugging
213     sal_Int32           nTypeDescriptionCount;
214     sal_Int32           nCompoundTypeDescriptionCount;
215     sal_Int32           nUnionTypeDescriptionCount;
216     sal_Int32           nIndirectTypeDescriptionCount;
217     sal_Int32           nArrayTypeDescriptionCount;
218     sal_Int32           nEnumTypeDescriptionCount;
219     sal_Int32           nInterfaceMethodTypeDescriptionCount;
220     sal_Int32           nInterfaceAttributeTypeDescriptionCount;
221     sal_Int32           nInterfaceTypeDescriptionCount;
222     sal_Int32           nTypeDescriptionReferenceCount;
223 #endif
224     ~TypeDescriptor_Init_Impl() SAL_THROW( () );
225 };
226 //__________________________________________________________________________________________________
getMutex()227 inline Mutex & TypeDescriptor_Init_Impl::getMutex() SAL_THROW( () )
228 {
229     if( !pMutex )
230     {
231         MutexGuard aGuard( Mutex::getGlobalMutex() );
232         if( !pMutex )
233             pMutex = new Mutex();
234     }
235     return * pMutex;
236 }
237 //__________________________________________________________________________________________________
callChain(typelib_TypeDescription ** ppRet,rtl_uString * pName)238 inline void TypeDescriptor_Init_Impl::callChain(
239     typelib_TypeDescription ** ppRet, rtl_uString * pName )
240     SAL_THROW( () )
241 {
242     if (pCallbacks)
243     {
244         CallbackSet_Impl::const_iterator aIt = pCallbacks->begin();
245         while( aIt != pCallbacks->end() )
246         {
247             const CallbackEntry & rEntry = *aIt;
248             (*rEntry.second)( rEntry.first, ppRet, pName );
249             if( *ppRet )
250                 return;
251             ++aIt;
252         }
253     }
254     if (*ppRet)
255     {
256         typelib_typedescription_release( *ppRet );
257         *ppRet = 0;
258     }
259 }
260 
261 //__________________________________________________________________________________________________
~TypeDescriptor_Init_Impl()262 TypeDescriptor_Init_Impl::~TypeDescriptor_Init_Impl() SAL_THROW( () )
263 {
264     if( pCache )
265     {
266         TypeDescriptionList_Impl::const_iterator aIt = pCache->begin();
267         while( aIt != pCache->end() )
268         {
269             typelib_typedescription_release( (*aIt) );
270             aIt++;
271         }
272         delete pCache;
273         pCache = 0;
274     }
275 
276     if( pWeakMap )
277     {
278         sal_Int32 nSize = pWeakMap->size();
279         typelib_TypeDescriptionReference ** ppTDR = new typelib_TypeDescriptionReference *[ nSize ];
280         // save all weak references
281         WeakMap_Impl::const_iterator aIt = pWeakMap->begin();
282         sal_Int32 i = 0;
283         while( aIt != pWeakMap->end() )
284         {
285             typelib_typedescriptionreference_acquire( ppTDR[i++] = (*aIt).second );
286             ++aIt;
287         }
288 
289         for( i = 0; i < nSize; i++ )
290         {
291             typelib_TypeDescriptionReference * pTDR = ppTDR[i];
292             OSL_ASSERT( pTDR->nRefCount > pTDR->nStaticRefCount );
293             pTDR->nRefCount -= pTDR->nStaticRefCount;
294 
295             if( pTDR->pType && !pTDR->pType->bOnDemand )
296             {
297                 pTDR->pType->bOnDemand = sal_True;
298                 typelib_typedescription_release( pTDR->pType );
299             }
300             typelib_typedescriptionreference_release( pTDR );
301         }
302 
303         delete [] ppTDR;
304 
305 #if OSL_DEBUG_LEVEL > 1
306         aIt = pWeakMap->begin();
307         while( aIt != pWeakMap->end() )
308         {
309             typelib_TypeDescriptionReference * pTDR = (*aIt).second;
310             if (pTDR)
311             {
312                 OString aTypeName( OUStringToOString( pTDR->pTypeName, RTL_TEXTENCODING_ASCII_US ) );
313                 OSL_TRACE(
314                     "### remaining type: %s; ref count = %d", aTypeName.getStr(), pTDR->nRefCount );
315             }
316             else
317             {
318                 OSL_TRACE( "### remaining null type entry!?" );
319             }
320             ++aIt;
321         }
322 #endif
323 
324         delete pWeakMap;
325         pWeakMap = 0;
326     }
327     delete pCallbacks;
328     pCallbacks = 0;
329 
330     if( pMutex )
331     {
332         delete pMutex;
333         pMutex = 0;
334     }
335 };
336 
337 namespace { struct Init : public rtl::Static< TypeDescriptor_Init_Impl, Init > {}; }
338 
339 //------------------------------------------------------------------------
340 //------------------------------------------------------------------------
341 //------------------------------------------------------------------------
342 //------------------------------------------------------------------------
typelib_typedescription_registerCallback(void * pContext,typelib_typedescription_Callback pCallback)343 extern "C" void SAL_CALL typelib_typedescription_registerCallback(
344     void * pContext, typelib_typedescription_Callback pCallback )
345     SAL_THROW_EXTERN_C()
346 {
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 ) );
353 }
354 
355 //------------------------------------------------------------------------
typelib_typedescription_revokeCallback(void * pContext,typelib_typedescription_Callback pCallback)356 extern "C" void SAL_CALL typelib_typedescription_revokeCallback(
357     void * pContext, typelib_typedescription_Callback pCallback )
358     SAL_THROW_EXTERN_C()
359 {
360     TypeDescriptor_Init_Impl &rInit = Init::get();
361     if( rInit.pCallbacks )
362     {
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()))
368         {
369             if (*iPos == aEntry)
370             {
371                 rInit.pCallbacks->erase( iPos );
372                 iPos = rInit.pCallbacks->begin();
373             }
374             else
375             {
376                 ++iPos;
377             }
378         }
379     }
380 }
381 
382 
383 //------------------------------------------------------------------------
384 //------------------------------------------------------------------------
385 //------------------------------------------------------------------------
386 extern "C" sal_Int32 SAL_CALL typelib_typedescription_getAlignedUnoSize(
387     const typelib_TypeDescription * pTypeDescription,
388     sal_Int32 nOffset, sal_Int32 & rMaxIntegralTypeSize )
389     SAL_THROW_EXTERN_C();
390 
391 //------------------------------------------------------------------------
typelib_typedescription_initTables(typelib_TypeDescription * pTD)392 static inline void typelib_typedescription_initTables(
393     typelib_TypeDescription * pTD )
394     SAL_THROW( () )
395 {
396     typelib_InterfaceTypeDescription * pITD = (typelib_InterfaceTypeDescription *)pTD;
397 
398     sal_Bool * pReadWriteAttributes = (sal_Bool *)alloca( pITD->nAllMembers );
399     for ( sal_Int32 i = pITD->nAllMembers; i--; )
400     {
401         pReadWriteAttributes[i] = sal_False;
402         if( typelib_TypeClass_INTERFACE_ATTRIBUTE == pITD->ppAllMembers[i]->eTypeClass )
403         {
404             typelib_TypeDescription * pM = 0;
405             TYPELIB_DANGER_GET( &pM, pITD->ppAllMembers[i] );
406             OSL_ASSERT( pM );
407             if (pM)
408             {
409                 pReadWriteAttributes[i] = !((typelib_InterfaceAttributeTypeDescription *)pM)->bReadOnly;
410                 TYPELIB_DANGER_RELEASE( pM );
411             }
412 #if OSL_DEBUG_LEVEL > 1
413             else
414             {
415                 OString aStr( OUStringToOString( pITD->ppAllMembers[i]->pTypeName, RTL_TEXTENCODING_ASCII_US ) );
416                 OSL_TRACE( "\n### cannot get attribute type description: %s", aStr.getStr() );
417             }
418 #endif
419         }
420     }
421 
422     MutexGuard aGuard( Init::get().getMutex() );
423     if( !pTD->bComplete )
424     {
425         // create the index table from member to function table
426         pITD->pMapMemberIndexToFunctionIndex = new sal_Int32[ pITD->nAllMembers ];
427         sal_Int32 nAdditionalOffset = 0; // +1 for read/write attributes
428         sal_Int32 i;
429         for( i = 0; i < pITD->nAllMembers; i++ )
430         {
431             // index to the get method of the attribute
432             pITD->pMapMemberIndexToFunctionIndex[i] = i + nAdditionalOffset;
433             // extra offset if it is a read/write attribute?
434             if( pReadWriteAttributes[i] )
435             {
436                 // a read/write attribute
437                 nAdditionalOffset++;
438             }
439         }
440 
441         // create the index table from function to member table
442         pITD->pMapFunctionIndexToMemberIndex = new sal_Int32[ pITD->nAllMembers + nAdditionalOffset ];
443         nAdditionalOffset = 0; // +1 for read/write attributes
444         for( i = 0; i < pITD->nAllMembers; i++ )
445         {
446             // index to the get method of the attribute
447             pITD->pMapFunctionIndexToMemberIndex[i + nAdditionalOffset] = i;
448             // extra offset if it is a read/write attribute?
449             if( pReadWriteAttributes[i] )
450             {
451                 // a read/write attribute
452                 pITD->pMapFunctionIndexToMemberIndex[i + ++nAdditionalOffset] = i;
453             }
454         }
455         // must be the last action after all initialization is done
456         pITD->nMapFunctionIndexToMemberIndex = pITD->nAllMembers + nAdditionalOffset;
457         pTD->bComplete = sal_True;
458     }
459 }
460 
461 namespace {
462 
463 // In some situations (notably typelib_typedescription_newInterfaceMethod and
464 // typelib_typedescription_newInterfaceAttribute), only the members nMembers,
465 // ppMembers, nAllMembers, and ppAllMembers of an incomplete interface type
466 // description are necessary, but not the additional
467 // pMapMemberIndexToFunctionIndex, nMapFunctionIndexToMemberIndex, and
468 // pMapFunctionIndexToMemberIndex (which are computed by
469 // typelib_typedescription_initTables). Furthermore, in those situations, it
470 // might be illegal to compute those tables, as the creation of the interface
471 // member type descriptions would recursively require a complete interface type
472 // description. The parameter initTables controls whether or not to call
473 // typelib_typedescription_initTables in those situations.
complete(typelib_TypeDescription ** ppTypeDescr,bool initTables)474 bool complete(typelib_TypeDescription ** ppTypeDescr, bool initTables) {
475     if (! (*ppTypeDescr)->bComplete)
476     {
477         OSL_ASSERT( (typelib_TypeClass_STRUCT == (*ppTypeDescr)->eTypeClass ||
478                      typelib_TypeClass_EXCEPTION == (*ppTypeDescr)->eTypeClass ||
479                      typelib_TypeClass_UNION == (*ppTypeDescr)->eTypeClass ||
480                      typelib_TypeClass_ENUM == (*ppTypeDescr)->eTypeClass ||
481                      typelib_TypeClass_INTERFACE == (*ppTypeDescr)->eTypeClass) &&
482                     !reallyWeak( (*ppTypeDescr)->eTypeClass ) );
483 
484         if (typelib_TypeClass_INTERFACE == (*ppTypeDescr)->eTypeClass &&
485             ((typelib_InterfaceTypeDescription *)*ppTypeDescr)->ppAllMembers)
486         {
487             if (initTables) {
488                 typelib_typedescription_initTables( *ppTypeDescr );
489             }
490             return true;
491         }
492 
493         typelib_TypeDescription * pTD = 0;
494         // on demand access of complete td
495         TypeDescriptor_Init_Impl &rInit = Init::get();
496         rInit.callChain( &pTD, (*ppTypeDescr)->pTypeName );
497         if (pTD)
498         {
499             if (typelib_TypeClass_TYPEDEF == pTD->eTypeClass)
500             {
501                 typelib_typedescriptionreference_getDescription(
502                     &pTD, ((typelib_IndirectTypeDescription *)pTD)->pType );
503                 OSL_ASSERT( pTD );
504                 if (! pTD)
505                     return false;
506             }
507 
508             OSL_ASSERT( typelib_TypeClass_TYPEDEF != pTD->eTypeClass );
509             // type description found
510             // set to on demand
511             pTD->bOnDemand = sal_True;
512 
513             if (pTD->eTypeClass == typelib_TypeClass_INTERFACE
514                 && !pTD->bComplete && initTables)
515             {
516                 // mandatory info from callback chain
517                 OSL_ASSERT( ((typelib_InterfaceTypeDescription *)pTD)->ppAllMembers );
518                 // complete except of tables init
519                 typelib_typedescription_initTables( pTD );
520                 pTD->bComplete = sal_True;
521             }
522 
523             // The type description is held by the reference until
524             // on demand is activated.
525             ::typelib_typedescription_register( &pTD ); // replaces incomplete one
526             OSL_ASSERT( pTD == *ppTypeDescr ); // has to merge into existing one
527 
528             // insert into the cache
529             MutexGuard aGuard( rInit.getMutex() );
530             if( !rInit.pCache )
531                 rInit.pCache = new TypeDescriptionList_Impl;
532             if( (sal_Int32)rInit.pCache->size() >= nCacheSize )
533             {
534                 typelib_typedescription_release( rInit.pCache->front() );
535                 rInit.pCache->pop_front();
536             }
537             // descriptions in the cache must be acquired!
538             typelib_typedescription_acquire( pTD );
539             rInit.pCache->push_back( pTD );
540 
541             OSL_ASSERT(
542                 pTD->bComplete
543                 || (pTD->eTypeClass == typelib_TypeClass_INTERFACE
544                     && !initTables));
545 
546             ::typelib_typedescription_release( *ppTypeDescr );
547             *ppTypeDescr = pTD;
548         }
549         else
550         {
551 #if OSL_DEBUG_LEVEL > 1
552             OString aStr(
553                 OUStringToOString( (*ppTypeDescr)->pTypeName, RTL_TEXTENCODING_ASCII_US ) );
554             OSL_TRACE( "\n### type cannot be completed: %s", aStr.getStr() );
555 #endif
556             return false;
557         }
558     }
559     return true;
560 }
561 
562 }
563 
564 //------------------------------------------------------------------------
typelib_typedescription_newEmpty(typelib_TypeDescription ** ppRet,typelib_TypeClass eTypeClass,rtl_uString * pTypeName)565 extern "C" void SAL_CALL typelib_typedescription_newEmpty(
566     typelib_TypeDescription ** ppRet,
567     typelib_TypeClass eTypeClass, rtl_uString * pTypeName )
568     SAL_THROW_EXTERN_C()
569 {
570     if( *ppRet )
571     {
572         typelib_typedescription_release( *ppRet );
573         *ppRet = 0;
574     }
575 
576     OSL_ASSERT( typelib_TypeClass_TYPEDEF != eTypeClass );
577 
578     typelib_TypeDescription * pRet;
579     switch( eTypeClass )
580     {
581         case typelib_TypeClass_ARRAY:
582         {
583             typelib_ArrayTypeDescription * pTmp = new typelib_ArrayTypeDescription();
584             typelib_IndirectTypeDescription * pIndirect = (typelib_IndirectTypeDescription *)pTmp;
585             pRet = (typelib_TypeDescription *)pTmp;
586 #if OSL_DEBUG_LEVEL > 1
587             osl_incrementInterlockedCount(
588                 &Init::get().nArrayTypeDescriptionCount );
589 #endif
590             pIndirect->pType = 0;
591             pTmp->nDimensions = 0;
592             pTmp->nTotalElements = 0;
593             pTmp->pDimensions = 0;
594         }
595         break;
596 
597         case typelib_TypeClass_SEQUENCE:
598         {
599             typelib_IndirectTypeDescription * pTmp = new typelib_IndirectTypeDescription();
600             pRet = (typelib_TypeDescription *)pTmp;
601 #if OSL_DEBUG_LEVEL > 1
602             osl_incrementInterlockedCount(
603                 &Init::get().nIndirectTypeDescriptionCount );
604 #endif
605             pTmp->pType = 0;
606         }
607         break;
608 
609         case typelib_TypeClass_UNION:
610         {
611             typelib_UnionTypeDescription * pTmp;
612             pTmp = new typelib_UnionTypeDescription();
613             pRet = (typelib_TypeDescription *)pTmp;
614 #if OSL_DEBUG_LEVEL > 1
615             osl_incrementInterlockedCount(
616                 &Init::get().nUnionTypeDescriptionCount );
617 #endif
618             pTmp->nMembers = 0;
619             pTmp->pDiscriminantTypeRef = 0;
620             pTmp->pDiscriminants = 0;
621             pTmp->ppTypeRefs = 0;
622             pTmp->ppMemberNames = 0;
623             pTmp->pDefaultTypeRef = 0;
624         }
625         break;
626 
627         case typelib_TypeClass_STRUCT:
628         {
629             // FEATURE_EMPTYCLASS
630             typelib_StructTypeDescription * pTmp;
631             pTmp = new typelib_StructTypeDescription();
632             pRet = (typelib_TypeDescription *)pTmp;
633 #if OSL_DEBUG_LEVEL > 1
634             osl_incrementInterlockedCount(
635                 &Init::get().nCompoundTypeDescriptionCount );
636 #endif
637             pTmp->aBase.pBaseTypeDescription = 0;
638             pTmp->aBase.nMembers = 0;
639             pTmp->aBase.pMemberOffsets = 0;
640             pTmp->aBase.ppTypeRefs = 0;
641             pTmp->aBase.ppMemberNames = 0;
642             pTmp->pParameterizedTypes = 0;
643         }
644         break;
645 
646         case typelib_TypeClass_EXCEPTION:
647         {
648             // FEATURE_EMPTYCLASS
649             typelib_CompoundTypeDescription * pTmp;
650             pTmp = new typelib_CompoundTypeDescription();
651             pRet = (typelib_TypeDescription *)pTmp;
652 #if OSL_DEBUG_LEVEL > 1
653             osl_incrementInterlockedCount(
654                 &Init::get().nCompoundTypeDescriptionCount );
655 #endif
656             pTmp->pBaseTypeDescription = 0;
657             pTmp->nMembers = 0;
658             pTmp->pMemberOffsets = 0;
659             pTmp->ppTypeRefs = 0;
660             pTmp->ppMemberNames = 0;
661         }
662         break;
663 
664         case typelib_TypeClass_ENUM:
665         {
666             typelib_EnumTypeDescription * pTmp = new typelib_EnumTypeDescription();
667             pRet = (typelib_TypeDescription *)pTmp;
668 #if OSL_DEBUG_LEVEL > 1
669             osl_incrementInterlockedCount(
670                 &Init::get().nEnumTypeDescriptionCount );
671 #endif
672             pTmp->nDefaultEnumValue = 0;
673             pTmp->nEnumValues       = 0;
674             pTmp->ppEnumNames       = 0;
675             pTmp->pEnumValues       = 0;
676         }
677         break;
678 
679         case typelib_TypeClass_INTERFACE:
680         {
681             typelib_InterfaceTypeDescription * pTmp = new typelib_InterfaceTypeDescription();
682             pRet = (typelib_TypeDescription *)pTmp;
683 #if OSL_DEBUG_LEVEL > 1
684             osl_incrementInterlockedCount(
685                 &Init::get().nInterfaceTypeDescriptionCount );
686 #endif
687             pTmp->pBaseTypeDescription = 0;
688             pTmp->nMembers = 0;
689             pTmp->ppMembers = 0;
690             pTmp->nAllMembers = 0;
691             pTmp->ppAllMembers = 0;
692             pTmp->nMapFunctionIndexToMemberIndex = 0;
693             pTmp->pMapFunctionIndexToMemberIndex = 0;
694             pTmp->pMapMemberIndexToFunctionIndex= 0;
695             pTmp->nBaseTypes = 0;
696             pTmp->ppBaseTypes = 0;
697         }
698         break;
699 
700         case typelib_TypeClass_INTERFACE_METHOD:
701         {
702             typelib_InterfaceMethodTypeDescription * pTmp = new typelib_InterfaceMethodTypeDescription();
703             pRet = (typelib_TypeDescription *)pTmp;
704 #if OSL_DEBUG_LEVEL > 1
705             osl_incrementInterlockedCount(
706                 &Init::get().nInterfaceMethodTypeDescriptionCount );
707 #endif
708             pTmp->aBase.pMemberName = 0;
709             pTmp->pReturnTypeRef = 0;
710             pTmp->nParams = 0;
711             pTmp->pParams = 0;
712             pTmp->nExceptions = 0;
713             pTmp->ppExceptions = 0;
714             pTmp->pInterface = 0;
715             pTmp->pBaseRef = 0;
716             pTmp->nIndex = 0;
717         }
718         break;
719 
720         case typelib_TypeClass_INTERFACE_ATTRIBUTE:
721         {
722             typelib_InterfaceAttributeTypeDescription * pTmp = new typelib_InterfaceAttributeTypeDescription();
723             pRet = (typelib_TypeDescription *)pTmp;
724 #if OSL_DEBUG_LEVEL > 1
725             osl_incrementInterlockedCount(
726                 &Init::get().nInterfaceAttributeTypeDescriptionCount );
727 #endif
728             pTmp->aBase.pMemberName = 0;
729             pTmp->pAttributeTypeRef = 0;
730             pTmp->pInterface = 0;
731             pTmp->pBaseRef = 0;
732             pTmp->nIndex = 0;
733             pTmp->nGetExceptions = 0;
734             pTmp->ppGetExceptions = 0;
735             pTmp->nSetExceptions = 0;
736             pTmp->ppSetExceptions = 0;
737         }
738         break;
739 
740         default:
741         {
742             pRet = new typelib_TypeDescription();
743 #if OSL_DEBUG_LEVEL > 1
744             osl_incrementInterlockedCount( &Init::get().nTypeDescriptionCount );
745 #endif
746         }
747     }
748 
749     pRet->nRefCount = 1; // reference count is initially 1
750     pRet->nStaticRefCount = 0;
751     pRet->eTypeClass = eTypeClass;
752     pRet->pTypeName = 0;
753     pRet->pUniqueIdentifier = 0;
754     pRet->pReserved = 0;
755     rtl_uString_acquire( pRet->pTypeName = pTypeName );
756     pRet->pSelf = pRet;
757     pRet->bComplete = sal_True;
758     pRet->nSize = 0;
759     pRet->nAlignment = 0;
760     pRet->pWeakRef = 0;
761     pRet->bOnDemand = sal_False;
762     *ppRet = pRet;
763 }
764 
765 //------------------------------------------------------------------------
766 namespace {
767 
newTypeDescription(typelib_TypeDescription ** ppRet,typelib_TypeClass eTypeClass,rtl_uString * pTypeName,typelib_TypeDescriptionReference * pType,sal_Int32 nMembers,typelib_CompoundMember_Init * pCompoundMembers,typelib_StructMember_Init * pStructMembers)768 void newTypeDescription(
769     typelib_TypeDescription ** ppRet, typelib_TypeClass eTypeClass,
770     rtl_uString * pTypeName, typelib_TypeDescriptionReference * pType,
771     sal_Int32 nMembers, typelib_CompoundMember_Init * pCompoundMembers,
772     typelib_StructMember_Init * pStructMembers)
773 {
774     OSL_ASSERT(
775         (pCompoundMembers == 0 || pStructMembers == 0)
776         && (pStructMembers == 0 || eTypeClass == typelib_TypeClass_STRUCT));
777     if (typelib_TypeClass_TYPEDEF == eTypeClass)
778     {
779         OSL_TRACE( "### unexpected typedef!" );
780         typelib_typedescriptionreference_getDescription( ppRet, pType );
781         return;
782     }
783 
784     typelib_typedescription_newEmpty( ppRet, eTypeClass, pTypeName );
785 
786     switch( eTypeClass )
787     {
788         case typelib_TypeClass_SEQUENCE:
789         {
790             OSL_ASSERT( nMembers == 0 );
791             typelib_typedescriptionreference_acquire( pType );
792             ((typelib_IndirectTypeDescription *)*ppRet)->pType = pType;
793         }
794         break;
795 
796         case typelib_TypeClass_EXCEPTION:
797         case typelib_TypeClass_STRUCT:
798         {
799             // FEATURE_EMPTYCLASS
800             typelib_CompoundTypeDescription * pTmp = (typelib_CompoundTypeDescription*)*ppRet;
801 
802             sal_Int32 nOffset = 0;
803             if( pType )
804             {
805                 typelib_typedescriptionreference_getDescription(
806                     (typelib_TypeDescription **)&pTmp->pBaseTypeDescription, pType );
807                 nOffset = ((typelib_TypeDescription *)pTmp->pBaseTypeDescription)->nSize;
808                 OSL_ENSURE( newAlignedSize( 0, ((typelib_TypeDescription *)pTmp->pBaseTypeDescription)->nSize, ((typelib_TypeDescription *)pTmp->pBaseTypeDescription)->nAlignment ) == ((typelib_TypeDescription *)pTmp->pBaseTypeDescription)->nSize, "### unexpected offset!" );
809             }
810             if( nMembers )
811             {
812                 pTmp->nMembers = nMembers;
813                 pTmp->pMemberOffsets = new sal_Int32[ nMembers ];
814                 pTmp->ppTypeRefs = new typelib_TypeDescriptionReference *[ nMembers ];
815                 pTmp->ppMemberNames = new rtl_uString *[ nMembers ];
816                 bool polymorphic = eTypeClass == typelib_TypeClass_STRUCT
817                     && rtl::OUString::unacquired(&pTypeName).indexOf('<') >= 0;
818                 OSL_ASSERT(!polymorphic || pStructMembers != 0);
819                 if (polymorphic) {
820                     reinterpret_cast< typelib_StructTypeDescription * >(pTmp)->
821                         pParameterizedTypes = new sal_Bool[nMembers];
822                 }
823                 for( sal_Int32 i = 0 ; i < nMembers; i++ )
824                 {
825                     // read the type and member names
826                     pTmp->ppTypeRefs[i] = 0;
827                     if (pCompoundMembers != 0) {
828                         typelib_typedescriptionreference_new(
829                             pTmp->ppTypeRefs +i, pCompoundMembers[i].eTypeClass,
830                             pCompoundMembers[i].pTypeName );
831                         rtl_uString_acquire(
832                             pTmp->ppMemberNames[i]
833                             = pCompoundMembers[i].pMemberName );
834                     } else {
835                         typelib_typedescriptionreference_new(
836                             pTmp->ppTypeRefs +i,
837                             pStructMembers[i].aBase.eTypeClass,
838                             pStructMembers[i].aBase.pTypeName );
839                         rtl_uString_acquire(
840                             pTmp->ppMemberNames[i]
841                             = pStructMembers[i].aBase.pMemberName );
842                     }
843                     // write offset
844                     sal_Int32 size;
845                     sal_Int32 alignment;
846                     if (pTmp->ppTypeRefs[i]->eTypeClass ==
847                         typelib_TypeClass_SEQUENCE)
848                     {
849                         // Take care of recursion like
850                         // struct S { sequence<S> x; };
851                         size = sizeof(void *);
852                         alignment = adjustAlignment(size);
853                     } else {
854                         typelib_TypeDescription * pTD = 0;
855                         TYPELIB_DANGER_GET( &pTD, pTmp->ppTypeRefs[i] );
856                         OSL_ENSURE( pTD->nSize, "### void member?" );
857                         size = pTD->nSize;
858                         alignment = pTD->nAlignment;
859                         TYPELIB_DANGER_RELEASE( pTD );
860                     }
861                     nOffset = newAlignedSize( nOffset, size, alignment );
862                     pTmp->pMemberOffsets[i] = nOffset - size;
863 
864                     if (polymorphic) {
865                         reinterpret_cast< typelib_StructTypeDescription * >(
866                             pTmp)->pParameterizedTypes[i]
867                             = pStructMembers[i].bParameterizedType;
868                     }
869                 }
870             }
871         }
872         break;
873 
874         default:
875         break;
876     }
877 
878     if( !reallyWeak( eTypeClass ) )
879         (*ppRet)->pWeakRef = (typelib_TypeDescriptionReference *)*ppRet;
880     if( eTypeClass != typelib_TypeClass_VOID )
881     {
882         // sizeof( void ) not allowed
883         (*ppRet)->nSize = typelib_typedescription_getAlignedUnoSize( (*ppRet), 0, (*ppRet)->nAlignment );
884         (*ppRet)->nAlignment = adjustAlignment( (*ppRet)->nAlignment );
885     }
886 }
887 
888 }
889 
typelib_typedescription_new(typelib_TypeDescription ** ppRet,typelib_TypeClass eTypeClass,rtl_uString * pTypeName,typelib_TypeDescriptionReference * pType,sal_Int32 nMembers,typelib_CompoundMember_Init * pMembers)890 extern "C" void SAL_CALL typelib_typedescription_new(
891     typelib_TypeDescription ** ppRet,
892     typelib_TypeClass eTypeClass,
893     rtl_uString * pTypeName,
894     typelib_TypeDescriptionReference * pType,
895     sal_Int32 nMembers,
896     typelib_CompoundMember_Init * pMembers )
897     SAL_THROW_EXTERN_C()
898 {
899     newTypeDescription(
900         ppRet, eTypeClass, pTypeName, pType, nMembers, pMembers, 0);
901 }
902 
typelib_typedescription_newStruct(typelib_TypeDescription ** ppRet,rtl_uString * pTypeName,typelib_TypeDescriptionReference * pType,sal_Int32 nMembers,typelib_StructMember_Init * pMembers)903 extern "C" void SAL_CALL typelib_typedescription_newStruct(
904     typelib_TypeDescription ** ppRet,
905     rtl_uString * pTypeName,
906     typelib_TypeDescriptionReference * pType,
907     sal_Int32 nMembers,
908     typelib_StructMember_Init * pMembers )
909     SAL_THROW_EXTERN_C()
910 {
911     newTypeDescription(
912         ppRet, typelib_TypeClass_STRUCT, pTypeName, pType, nMembers, 0,
913         pMembers);
914 }
915 
916 //------------------------------------------------------------------------
typelib_typedescription_newUnion(typelib_TypeDescription ** ppRet,rtl_uString * pTypeName,typelib_TypeDescriptionReference * pDiscriminantTypeRef,sal_Int64 nDefaultDiscriminant,typelib_TypeDescriptionReference * pDefaultTypeRef,sal_Int32 nMembers,typelib_Union_Init * pMembers)917 extern "C" void SAL_CALL typelib_typedescription_newUnion(
918     typelib_TypeDescription ** ppRet,
919     rtl_uString * pTypeName,
920     typelib_TypeDescriptionReference * pDiscriminantTypeRef,
921     sal_Int64 nDefaultDiscriminant,
922     typelib_TypeDescriptionReference * pDefaultTypeRef,
923     sal_Int32 nMembers,
924     typelib_Union_Init * pMembers )
925     SAL_THROW_EXTERN_C()
926 {
927     typelib_typedescription_newEmpty( ppRet, typelib_TypeClass_UNION, pTypeName );
928     // discriminant type
929     typelib_UnionTypeDescription * pTmp = (typelib_UnionTypeDescription *)*ppRet;
930     typelib_typedescriptionreference_acquire( pTmp->pDiscriminantTypeRef = pDiscriminantTypeRef );
931 
932     sal_Int32 nPos;
933 
934     pTmp->nMembers = nMembers;
935     // default discriminant
936     if (nMembers)
937     {
938         pTmp->pDiscriminants = new sal_Int64[ nMembers ];
939         for ( nPos = nMembers; nPos--; )
940         {
941             pTmp->pDiscriminants[nPos] = pMembers[nPos].nDiscriminant;
942         }
943     }
944     // default default discriminant
945     pTmp->nDefaultDiscriminant = nDefaultDiscriminant;
946 
947     // union member types
948     pTmp->ppTypeRefs = new typelib_TypeDescriptionReference *[ nMembers ];
949     for ( nPos = nMembers; nPos--; )
950     {
951         typelib_typedescriptionreference_acquire( pTmp->ppTypeRefs[nPos] = pMembers[nPos].pTypeRef );
952     }
953     // union member names
954     pTmp->ppMemberNames = new rtl_uString *[ nMembers ];
955     for ( nPos = nMembers; nPos--; )
956     {
957         rtl_uString_acquire( pTmp->ppMemberNames[nPos] = pMembers[nPos].pMemberName );
958     }
959 
960     // default union type
961     typelib_typedescriptionreference_acquire( pTmp->pDefaultTypeRef = pDefaultTypeRef );
962 
963     if (! reallyWeak( typelib_TypeClass_UNION ))
964         (*ppRet)->pWeakRef = (typelib_TypeDescriptionReference *)*ppRet;
965     (*ppRet)->nSize = typelib_typedescription_getAlignedUnoSize( (*ppRet), 0, (*ppRet)->nAlignment );
966     (*ppRet)->nAlignment = adjustAlignment( (*ppRet)->nAlignment );
967 }
968 
969 //------------------------------------------------------------------------
typelib_typedescription_newEnum(typelib_TypeDescription ** ppRet,rtl_uString * pTypeName,sal_Int32 nDefaultValue,sal_Int32 nEnumValues,rtl_uString ** ppEnumNames,sal_Int32 * pEnumValues)970 extern "C" void SAL_CALL typelib_typedescription_newEnum(
971     typelib_TypeDescription ** ppRet,
972     rtl_uString * pTypeName,
973     sal_Int32 nDefaultValue,
974     sal_Int32 nEnumValues,
975     rtl_uString ** ppEnumNames,
976     sal_Int32 * pEnumValues )
977     SAL_THROW_EXTERN_C()
978 {
979     typelib_typedescription_newEmpty( ppRet, typelib_TypeClass_ENUM, pTypeName );
980     typelib_EnumTypeDescription * pEnum = (typelib_EnumTypeDescription *)*ppRet;
981 
982     pEnum->nDefaultEnumValue = nDefaultValue;
983     pEnum->nEnumValues       = nEnumValues;
984     pEnum->ppEnumNames       = new rtl_uString * [ nEnumValues ];
985     for ( sal_Int32 nPos = nEnumValues; nPos--; )
986     {
987         rtl_uString_acquire( pEnum->ppEnumNames[nPos] = ppEnumNames[nPos] );
988     }
989     pEnum->pEnumValues      = new sal_Int32[ nEnumValues ];
990     ::memcpy( pEnum->pEnumValues, pEnumValues, nEnumValues * sizeof(sal_Int32) );
991 
992     (*ppRet)->pWeakRef = (typelib_TypeDescriptionReference *)*ppRet;
993     // sizeof( void ) not allowed
994     (*ppRet)->nSize = typelib_typedescription_getAlignedUnoSize( (*ppRet), 0, (*ppRet)->nAlignment );
995     (*ppRet)->nAlignment = adjustAlignment( (*ppRet)->nAlignment );
996 }
997 
998 //------------------------------------------------------------------------
typelib_typedescription_newArray(typelib_TypeDescription ** ppRet,typelib_TypeDescriptionReference * pElementTypeRef,sal_Int32 nDimensions,sal_Int32 * pDimensions)999 extern "C" void SAL_CALL typelib_typedescription_newArray(
1000     typelib_TypeDescription ** ppRet,
1001     typelib_TypeDescriptionReference * pElementTypeRef,
1002     sal_Int32 nDimensions,
1003     sal_Int32 * pDimensions )
1004     SAL_THROW_EXTERN_C ()
1005 {
1006     OUStringBuffer aBuf( 32 );
1007     aBuf.append( pElementTypeRef->pTypeName );
1008     sal_Int32 nElements = 1;
1009     for (sal_Int32 i=0; i < nDimensions; i++)
1010     {
1011         aBuf.appendAscii("[");
1012         aBuf.append(pDimensions[i]);
1013         aBuf.appendAscii("]");
1014         nElements *= pDimensions[i];
1015     }
1016     OUString aTypeName( aBuf.makeStringAndClear() );
1017 
1018 
1019     typelib_typedescription_newEmpty( ppRet, typelib_TypeClass_ARRAY, aTypeName.pData );
1020     typelib_ArrayTypeDescription * pArray = (typelib_ArrayTypeDescription *)*ppRet;
1021 
1022     pArray->nDimensions = nDimensions;
1023     pArray->nTotalElements = nElements;
1024     pArray->pDimensions = new sal_Int32[ nDimensions ];
1025     ::memcpy( pArray->pDimensions, pDimensions, nDimensions * sizeof(sal_Int32) );
1026 
1027     typelib_typedescriptionreference_acquire(pElementTypeRef);
1028     ((typelib_IndirectTypeDescription*)pArray)->pType = pElementTypeRef;
1029 
1030     (*ppRet)->pWeakRef = (typelib_TypeDescriptionReference *)*ppRet;
1031     // sizeof( void ) not allowed
1032     (*ppRet)->nSize = typelib_typedescription_getAlignedUnoSize( *ppRet, 0, (*ppRet)->nAlignment );
1033     (*ppRet)->nAlignment = adjustAlignment( (*ppRet)->nAlignment );
1034 }
1035 
1036 //------------------------------------------------------------------------
typelib_typedescription_newInterface(typelib_InterfaceTypeDescription ** ppRet,rtl_uString * pTypeName,sal_uInt32 nUik1,sal_uInt16 nUik2,sal_uInt16 nUik3,sal_uInt32 nUik4,sal_uInt32 nUik5,typelib_TypeDescriptionReference * pBaseInterface,sal_Int32 nMembers,typelib_TypeDescriptionReference ** ppMembers)1037 extern "C" void SAL_CALL typelib_typedescription_newInterface(
1038     typelib_InterfaceTypeDescription ** ppRet,
1039     rtl_uString * pTypeName,
1040     sal_uInt32 nUik1, sal_uInt16 nUik2, sal_uInt16 nUik3, sal_uInt32 nUik4, sal_uInt32 nUik5,
1041     typelib_TypeDescriptionReference * pBaseInterface,
1042     sal_Int32 nMembers,
1043     typelib_TypeDescriptionReference ** ppMembers )
1044     SAL_THROW_EXTERN_C()
1045 {
1046     typelib_typedescription_newMIInterface(
1047         ppRet, pTypeName, nUik1, nUik2, nUik3, nUik4, nUik5,
1048         pBaseInterface == 0 ? 0 : 1, &pBaseInterface, nMembers, ppMembers);
1049 }
1050 
1051 //------------------------------------------------------------------------
1052 
1053 namespace {
1054 
1055 class BaseList {
1056 public:
1057     struct Entry {
1058         sal_Int32 memberOffset;
1059         sal_Int32 directBaseIndex;
1060         sal_Int32 directBaseMemberOffset;
1061         typelib_InterfaceTypeDescription const * base;
1062     };
1063 
1064     typedef std::vector< Entry > List;
1065 
1066     BaseList(typelib_InterfaceTypeDescription const * desc);
1067 
getList() const1068     List const & getList() const { return list; }
1069 
getBaseMembers() const1070     sal_Int32 getBaseMembers() const { return members; }
1071 
1072 private:
1073     typedef std::set< rtl::OUString > Set;
1074 
1075     void calculate(
1076         sal_Int32 directBaseIndex, Set & directBaseSet,
1077         sal_Int32 * directBaseMembers,
1078         typelib_InterfaceTypeDescription const * desc);
1079 
1080     Set set;
1081     List list;
1082     sal_Int32 members;
1083 };
1084 
BaseList(typelib_InterfaceTypeDescription const * desc)1085 BaseList::BaseList(typelib_InterfaceTypeDescription const * desc) {
1086     members = 0;
1087     for (sal_Int32 i = 0; i < desc->nBaseTypes; ++i) {
1088         Set directBaseSet;
1089         sal_Int32 directBaseMembers = 0;
1090         calculate(i, directBaseSet, &directBaseMembers, desc->ppBaseTypes[i]);
1091     }
1092 }
1093 
calculate(sal_Int32 directBaseIndex,Set & directBaseSet,sal_Int32 * directBaseMembers,typelib_InterfaceTypeDescription const * desc)1094 void BaseList::calculate(
1095     sal_Int32 directBaseIndex, Set & directBaseSet,
1096     sal_Int32 * directBaseMembers,
1097     typelib_InterfaceTypeDescription const * desc)
1098 {
1099     for (sal_Int32 i = 0; i < desc->nBaseTypes; ++i) {
1100         calculate(
1101             directBaseIndex, directBaseSet, directBaseMembers,
1102             desc->ppBaseTypes[i]);
1103     }
1104     if (set.insert(desc->aBase.pTypeName).second) {
1105         Entry e;
1106         e.memberOffset = members;
1107         e.directBaseIndex = directBaseIndex;
1108         e.directBaseMemberOffset = *directBaseMembers;
1109         e.base = desc;
1110         list.push_back(e);
1111         OSL_ASSERT(desc->ppAllMembers != 0);
1112         members += desc->nMembers;
1113     }
1114     if (directBaseSet.insert(desc->aBase.pTypeName).second) {
1115         OSL_ASSERT(desc->ppAllMembers != 0);
1116         *directBaseMembers += desc->nMembers;
1117     }
1118 }
1119 
1120 }
1121 
typelib_typedescription_newMIInterface(typelib_InterfaceTypeDescription ** ppRet,rtl_uString * pTypeName,sal_uInt32 nUik1,sal_uInt16 nUik2,sal_uInt16 nUik3,sal_uInt32 nUik4,sal_uInt32 nUik5,sal_Int32 nBaseInterfaces,typelib_TypeDescriptionReference ** ppBaseInterfaces,sal_Int32 nMembers,typelib_TypeDescriptionReference ** ppMembers)1122 extern "C" void SAL_CALL typelib_typedescription_newMIInterface(
1123     typelib_InterfaceTypeDescription ** ppRet,
1124     rtl_uString * pTypeName,
1125     sal_uInt32 nUik1, sal_uInt16 nUik2, sal_uInt16 nUik3, sal_uInt32 nUik4, sal_uInt32 nUik5,
1126     sal_Int32 nBaseInterfaces,
1127     typelib_TypeDescriptionReference ** ppBaseInterfaces,
1128     sal_Int32 nMembers,
1129     typelib_TypeDescriptionReference ** ppMembers )
1130     SAL_THROW_EXTERN_C()
1131 {
1132     if (*ppRet != 0) {
1133         typelib_typedescription_release(&(*ppRet)->aBase);
1134         *ppRet = 0;
1135     }
1136 
1137     typelib_InterfaceTypeDescription * pITD = 0;
1138     typelib_typedescription_newEmpty(
1139         (typelib_TypeDescription **)&pITD, typelib_TypeClass_INTERFACE, pTypeName );
1140 
1141     pITD->nBaseTypes = nBaseInterfaces;
1142     pITD->ppBaseTypes = new typelib_InterfaceTypeDescription *[nBaseInterfaces];
1143     for (sal_Int32 i = 0; i < nBaseInterfaces; ++i) {
1144         pITD->ppBaseTypes[i] = 0;
1145         typelib_typedescriptionreference_getDescription(
1146             reinterpret_cast< typelib_TypeDescription ** >(
1147                 &pITD->ppBaseTypes[i]),
1148             ppBaseInterfaces[i]);
1149         if (pITD->ppBaseTypes[i] == 0
1150             || !complete(
1151                 reinterpret_cast< typelib_TypeDescription ** >(
1152                     &pITD->ppBaseTypes[i]),
1153                 false))
1154         {
1155             OSL_ASSERT(false);
1156             return;
1157         }
1158         OSL_ASSERT(pITD->ppBaseTypes[i] != 0);
1159     }
1160     if (nBaseInterfaces > 0) {
1161         pITD->pBaseTypeDescription = pITD->ppBaseTypes[0];
1162     }
1163     // set the
1164     pITD->aUik.m_Data1 = nUik1;
1165     pITD->aUik.m_Data2 = nUik2;
1166     pITD->aUik.m_Data3 = nUik3;
1167     pITD->aUik.m_Data4 = nUik4;
1168     pITD->aUik.m_Data5 = nUik5;
1169 
1170     BaseList aBaseList(pITD);
1171     pITD->nAllMembers = nMembers + aBaseList.getBaseMembers();
1172     pITD->nMembers = nMembers;
1173 
1174     if( pITD->nAllMembers )
1175     {
1176         // at minimum one member exist, allocate the memory
1177         pITD->ppAllMembers = new typelib_TypeDescriptionReference *[ pITD->nAllMembers ];
1178         sal_Int32 n = 0;
1179 
1180         BaseList::List const & rList = aBaseList.getList();
1181         {for (BaseList::List::const_iterator i(rList.begin()); i != rList.end();
1182               ++i)
1183         {
1184             typelib_InterfaceTypeDescription const * pBase = i->base;
1185             typelib_InterfaceTypeDescription const * pDirectBase
1186                 = pITD->ppBaseTypes[i->directBaseIndex];
1187             OSL_ASSERT(pBase->ppAllMembers != 0);
1188             for (sal_Int32 j = 0; j < pBase->nMembers; ++j) {
1189                 typelib_TypeDescriptionReference const * pDirectBaseMember
1190                     = pDirectBase->ppAllMembers[i->directBaseMemberOffset + j];
1191                 rtl::OUStringBuffer aBuf(pDirectBaseMember->pTypeName);
1192                 aBuf.appendAscii(RTL_CONSTASCII_STRINGPARAM(":@"));
1193                 aBuf.append(i->directBaseIndex);
1194                 aBuf.append(static_cast< sal_Unicode >(','));
1195                 aBuf.append(i->memberOffset + j);
1196                 aBuf.append(static_cast< sal_Unicode >(':'));
1197                 aBuf.append(pITD->aBase.pTypeName);
1198                 rtl::OUString aName(aBuf.makeStringAndClear());
1199                 typelib_TypeDescriptionReference * pDerivedMember = 0;
1200                 typelib_typedescriptionreference_new(
1201                     &pDerivedMember, pDirectBaseMember->eTypeClass,
1202                     aName.pData);
1203                 pITD->ppAllMembers[n++] = pDerivedMember;
1204             }
1205         }}
1206 
1207         if( nMembers )
1208         {
1209             pITD->ppMembers = pITD->ppAllMembers + aBaseList.getBaseMembers();
1210         }
1211 
1212         // add own members
1213         {for( sal_Int32 i = 0; i < nMembers; i++ )
1214         {
1215             typelib_typedescriptionreference_acquire( ppMembers[i] );
1216             pITD->ppAllMembers[n++] = ppMembers[i];
1217         }}
1218     }
1219 
1220     typelib_TypeDescription * pTmp = (typelib_TypeDescription *)pITD;
1221     if( !reallyWeak( typelib_TypeClass_INTERFACE ) )
1222         pTmp->pWeakRef = (typelib_TypeDescriptionReference *)pTmp;
1223     pTmp->nSize = typelib_typedescription_getAlignedUnoSize( pTmp, 0, pTmp->nAlignment );
1224     pTmp->nAlignment = adjustAlignment( pTmp->nAlignment );
1225     pTmp->bComplete = sal_False;
1226 
1227     *ppRet = pITD;
1228 }
1229 
1230 //------------------------------------------------------------------------
1231 
1232 namespace {
1233 
copyExceptions(sal_Int32 count,rtl_uString ** typeNames)1234 typelib_TypeDescriptionReference ** copyExceptions(
1235     sal_Int32 count, rtl_uString ** typeNames)
1236 {
1237     OSL_ASSERT(count >= 0);
1238     if (count == 0) {
1239         return 0;
1240     }
1241     typelib_TypeDescriptionReference ** p
1242         = new typelib_TypeDescriptionReference *[count];
1243     for (sal_Int32 i = 0; i < count; ++i) {
1244         p[i] = 0;
1245         typelib_typedescriptionreference_new(
1246             p + i, typelib_TypeClass_EXCEPTION, typeNames[i]);
1247     }
1248     return p;
1249 }
1250 
1251 }
1252 
typelib_typedescription_newInterfaceMethod(typelib_InterfaceMethodTypeDescription ** ppRet,sal_Int32 nAbsolutePosition,sal_Bool bOneWay,rtl_uString * pTypeName,typelib_TypeClass eReturnTypeClass,rtl_uString * pReturnTypeName,sal_Int32 nParams,typelib_Parameter_Init * pParams,sal_Int32 nExceptions,rtl_uString ** ppExceptionNames)1253 extern "C" void SAL_CALL typelib_typedescription_newInterfaceMethod(
1254     typelib_InterfaceMethodTypeDescription ** ppRet,
1255     sal_Int32 nAbsolutePosition,
1256     sal_Bool bOneWay,
1257     rtl_uString * pTypeName,
1258     typelib_TypeClass eReturnTypeClass,
1259     rtl_uString * pReturnTypeName,
1260     sal_Int32 nParams,
1261     typelib_Parameter_Init * pParams,
1262     sal_Int32 nExceptions,
1263     rtl_uString ** ppExceptionNames )
1264     SAL_THROW_EXTERN_C()
1265 {
1266     if (*ppRet != 0) {
1267         typelib_typedescription_release(&(*ppRet)->aBase.aBase);
1268         *ppRet = 0;
1269     }
1270     sal_Int32 nOffset = rtl_ustr_lastIndexOfChar_WithLength(
1271         pTypeName->buffer, pTypeName->length, ':');
1272     if (nOffset <= 0 || pTypeName->buffer[nOffset - 1] != ':') {
1273         OSL_ENSURE(false, "Bad interface method type name");
1274         return;
1275     }
1276     rtl::OUString aInterfaceTypeName(pTypeName->buffer, nOffset - 1);
1277     typelib_InterfaceTypeDescription * pInterface = 0;
1278     typelib_typedescription_getByName(
1279         reinterpret_cast< typelib_TypeDescription ** >(&pInterface),
1280         aInterfaceTypeName.pData);
1281     if (pInterface == 0
1282         || pInterface->aBase.eTypeClass != typelib_TypeClass_INTERFACE
1283         || !complete(
1284             reinterpret_cast< typelib_TypeDescription ** >(&pInterface), false))
1285     {
1286         OSL_ENSURE(false, "No interface corresponding to interface method");
1287         return;
1288     }
1289 
1290     typelib_typedescription_newEmpty(
1291         (typelib_TypeDescription **)ppRet, typelib_TypeClass_INTERFACE_METHOD, pTypeName );
1292     typelib_TypeDescription * pTmp = (typelib_TypeDescription *)*ppRet;
1293 
1294     rtl_uString_newFromStr_WithLength( &(*ppRet)->aBase.pMemberName,
1295                                        pTypeName->buffer + nOffset +1,
1296                                        pTypeName->length - nOffset -1 );
1297     (*ppRet)->aBase.nPosition = nAbsolutePosition;
1298     (*ppRet)->bOneWay = bOneWay;
1299     typelib_typedescriptionreference_new( &(*ppRet)->pReturnTypeRef, eReturnTypeClass, pReturnTypeName );
1300     (*ppRet)->nParams = nParams;
1301     if( nParams )
1302     {
1303         (*ppRet)->pParams = new typelib_MethodParameter[ nParams ];
1304 
1305         for( sal_Int32 i = 0; i < nParams; i++ )
1306         {
1307             // get the name of the parameter
1308             (*ppRet)->pParams[ i ].pName = 0;
1309             rtl_uString_acquire( (*ppRet)->pParams[ i ].pName = pParams[i].pParamName );
1310             (*ppRet)->pParams[ i ].pTypeRef = 0;
1311             // get the type name of the parameter and create the weak reference
1312             typelib_typedescriptionreference_new(
1313                 &(*ppRet)->pParams[ i ].pTypeRef, pParams[i].eTypeClass, pParams[i].pTypeName );
1314             (*ppRet)->pParams[ i ].bIn = pParams[i].bIn;
1315             (*ppRet)->pParams[ i ].bOut = pParams[i].bOut;
1316         }
1317     }
1318     (*ppRet)->nExceptions = nExceptions;
1319     (*ppRet)->ppExceptions = copyExceptions(nExceptions, ppExceptionNames);
1320     (*ppRet)->pInterface = pInterface;
1321     (*ppRet)->pBaseRef = 0;
1322     OSL_ASSERT(
1323         (nAbsolutePosition >= pInterface->nAllMembers - pInterface->nMembers)
1324         && nAbsolutePosition < pInterface->nAllMembers);
1325     (*ppRet)->nIndex = nAbsolutePosition
1326         - (pInterface->nAllMembers - pInterface->nMembers);
1327     if( !reallyWeak( typelib_TypeClass_INTERFACE_METHOD ) )
1328         pTmp->pWeakRef = (typelib_TypeDescriptionReference *)pTmp;
1329 }
1330 
1331 
1332 //------------------------------------------------------------------------
typelib_typedescription_newInterfaceAttribute(typelib_InterfaceAttributeTypeDescription ** ppRet,sal_Int32 nAbsolutePosition,rtl_uString * pTypeName,typelib_TypeClass eAttributeTypeClass,rtl_uString * pAttributeTypeName,sal_Bool bReadOnly)1333 extern "C" void SAL_CALL typelib_typedescription_newInterfaceAttribute(
1334     typelib_InterfaceAttributeTypeDescription ** ppRet,
1335     sal_Int32 nAbsolutePosition,
1336     rtl_uString * pTypeName,
1337     typelib_TypeClass eAttributeTypeClass,
1338     rtl_uString * pAttributeTypeName,
1339     sal_Bool bReadOnly )
1340     SAL_THROW_EXTERN_C()
1341 {
1342     typelib_typedescription_newExtendedInterfaceAttribute(
1343         ppRet, nAbsolutePosition, pTypeName, eAttributeTypeClass,
1344         pAttributeTypeName, bReadOnly, 0, 0, 0, 0);
1345 }
1346 
1347 //------------------------------------------------------------------------
typelib_typedescription_newExtendedInterfaceAttribute(typelib_InterfaceAttributeTypeDescription ** ppRet,sal_Int32 nAbsolutePosition,rtl_uString * pTypeName,typelib_TypeClass eAttributeTypeClass,rtl_uString * pAttributeTypeName,sal_Bool bReadOnly,sal_Int32 nGetExceptions,rtl_uString ** ppGetExceptionNames,sal_Int32 nSetExceptions,rtl_uString ** ppSetExceptionNames)1348 extern "C" void SAL_CALL typelib_typedescription_newExtendedInterfaceAttribute(
1349     typelib_InterfaceAttributeTypeDescription ** ppRet,
1350     sal_Int32 nAbsolutePosition,
1351     rtl_uString * pTypeName,
1352     typelib_TypeClass eAttributeTypeClass,
1353     rtl_uString * pAttributeTypeName,
1354     sal_Bool bReadOnly,
1355     sal_Int32 nGetExceptions, rtl_uString ** ppGetExceptionNames,
1356     sal_Int32 nSetExceptions, rtl_uString ** ppSetExceptionNames )
1357     SAL_THROW_EXTERN_C()
1358 {
1359     if (*ppRet != 0) {
1360         typelib_typedescription_release(&(*ppRet)->aBase.aBase);
1361         *ppRet = 0;
1362     }
1363     sal_Int32 nOffset = rtl_ustr_lastIndexOfChar_WithLength(
1364         pTypeName->buffer, pTypeName->length, ':');
1365     if (nOffset <= 0 || pTypeName->buffer[nOffset - 1] != ':') {
1366         OSL_ENSURE(false, "Bad interface attribute type name");
1367         return;
1368     }
1369     rtl::OUString aInterfaceTypeName(pTypeName->buffer, nOffset - 1);
1370     typelib_InterfaceTypeDescription * pInterface = 0;
1371     typelib_typedescription_getByName(
1372         reinterpret_cast< typelib_TypeDescription ** >(&pInterface),
1373         aInterfaceTypeName.pData);
1374     if (pInterface == 0
1375         || pInterface->aBase.eTypeClass != typelib_TypeClass_INTERFACE
1376         || !complete(
1377             reinterpret_cast< typelib_TypeDescription ** >(&pInterface), false))
1378     {
1379         OSL_ENSURE(false, "No interface corresponding to interface attribute");
1380         return;
1381     }
1382 
1383     typelib_typedescription_newEmpty(
1384         (typelib_TypeDescription **)ppRet, typelib_TypeClass_INTERFACE_ATTRIBUTE, pTypeName );
1385     typelib_TypeDescription * pTmp = (typelib_TypeDescription *)*ppRet;
1386 
1387     rtl_uString_newFromStr_WithLength( &(*ppRet)->aBase.pMemberName,
1388                                        pTypeName->buffer + nOffset +1,
1389                                        pTypeName->length - nOffset -1 );
1390     (*ppRet)->aBase.nPosition = nAbsolutePosition;
1391     typelib_typedescriptionreference_new( &(*ppRet)->pAttributeTypeRef, eAttributeTypeClass, pAttributeTypeName );
1392     (*ppRet)->bReadOnly = bReadOnly;
1393     (*ppRet)->pInterface = pInterface;
1394     (*ppRet)->pBaseRef = 0;
1395     OSL_ASSERT(
1396         (nAbsolutePosition >= pInterface->nAllMembers - pInterface->nMembers)
1397         && nAbsolutePosition < pInterface->nAllMembers);
1398     (*ppRet)->nIndex = nAbsolutePosition
1399         - (pInterface->nAllMembers - pInterface->nMembers);
1400     (*ppRet)->nGetExceptions = nGetExceptions;
1401     (*ppRet)->ppGetExceptions = copyExceptions(
1402         nGetExceptions, ppGetExceptionNames);
1403     (*ppRet)->nSetExceptions = nSetExceptions;
1404     (*ppRet)->ppSetExceptions = copyExceptions(
1405         nSetExceptions, ppSetExceptionNames);
1406     if( !reallyWeak( typelib_TypeClass_INTERFACE_ATTRIBUTE ) )
1407         pTmp->pWeakRef = (typelib_TypeDescriptionReference *)pTmp;
1408 }
1409 
1410 //------------------------------------------------------------------------
typelib_typedescription_acquire(typelib_TypeDescription * pTypeDescription)1411 extern "C" void SAL_CALL typelib_typedescription_acquire(
1412     typelib_TypeDescription * pTypeDescription )
1413     SAL_THROW_EXTERN_C()
1414 {
1415     ::osl_incrementInterlockedCount( &pTypeDescription->nRefCount );
1416 }
1417 
1418 //------------------------------------------------------------------------
1419 
1420 namespace {
1421 
deleteExceptions(sal_Int32 count,typelib_TypeDescriptionReference ** exceptions)1422 void deleteExceptions(
1423     sal_Int32 count, typelib_TypeDescriptionReference ** exceptions)
1424 {
1425     for (sal_Int32 i = 0; i < count; ++i) {
1426         typelib_typedescriptionreference_release(exceptions[i]);
1427     }
1428     delete[] exceptions;
1429 }
1430 
1431 }
1432 
1433 // frees anything except typelib_TypeDescription base!
typelib_typedescription_destructExtendedMembers(typelib_TypeDescription * pTD)1434 static inline void typelib_typedescription_destructExtendedMembers(
1435     typelib_TypeDescription * pTD )
1436     SAL_THROW( () )
1437 {
1438     OSL_ASSERT( typelib_TypeClass_TYPEDEF != pTD->eTypeClass );
1439 
1440     switch( pTD->eTypeClass )
1441     {
1442     case typelib_TypeClass_ARRAY:
1443         if( ((typelib_IndirectTypeDescription*)pTD)->pType )
1444             typelib_typedescriptionreference_release( ((typelib_IndirectTypeDescription*)pTD)->pType );
1445         delete [] ((typelib_ArrayTypeDescription *)pTD)->pDimensions;
1446         break;
1447     case typelib_TypeClass_SEQUENCE:
1448         if( ((typelib_IndirectTypeDescription*)pTD)->pType )
1449             typelib_typedescriptionreference_release( ((typelib_IndirectTypeDescription*)pTD)->pType );
1450         break;
1451     case typelib_TypeClass_UNION:
1452     {
1453         typelib_UnionTypeDescription * pUnionTD = (typelib_UnionTypeDescription *)pTD;
1454         typelib_typedescriptionreference_release( pUnionTD->pDiscriminantTypeRef );
1455         typelib_typedescriptionreference_release( pUnionTD->pDefaultTypeRef );
1456 
1457         sal_Int32 nPos;
1458         typelib_TypeDescriptionReference ** ppTypeRefs = pUnionTD->ppTypeRefs;
1459         for ( nPos = pUnionTD->nMembers; nPos--; )
1460         {
1461             typelib_typedescriptionreference_release( ppTypeRefs[nPos] );
1462         }
1463 
1464         rtl_uString ** ppMemberNames = pUnionTD->ppMemberNames;
1465         for ( nPos = pUnionTD->nMembers; nPos--; )
1466         {
1467             rtl_uString_release( ppMemberNames[nPos] );
1468         }
1469         delete [] pUnionTD->ppMemberNames;
1470         delete [] pUnionTD->pDiscriminants;
1471         delete [] pUnionTD->ppTypeRefs;
1472     }
1473     break;
1474     case typelib_TypeClass_STRUCT:
1475         delete[] reinterpret_cast< typelib_StructTypeDescription * >(pTD)->
1476             pParameterizedTypes;
1477     case typelib_TypeClass_EXCEPTION:
1478     {
1479         typelib_CompoundTypeDescription * pCTD = (typelib_CompoundTypeDescription*)pTD;
1480         if( pCTD->pBaseTypeDescription )
1481             typelib_typedescription_release( (typelib_TypeDescription *)pCTD->pBaseTypeDescription );
1482         sal_Int32 i;
1483         for( i = 0; i < pCTD->nMembers; i++ )
1484         {
1485             typelib_typedescriptionreference_release( pCTD->ppTypeRefs[i] );
1486         }
1487         if (pCTD->ppMemberNames)
1488         {
1489             for ( i = 0; i < pCTD->nMembers; i++ )
1490             {
1491                 rtl_uString_release( pCTD->ppMemberNames[i] );
1492             }
1493             delete [] pCTD->ppMemberNames;
1494         }
1495         delete [] pCTD->ppTypeRefs;
1496         delete [] pCTD->pMemberOffsets;
1497     }
1498     break;
1499     case typelib_TypeClass_INTERFACE:
1500     {
1501         typelib_InterfaceTypeDescription * pITD = (typelib_InterfaceTypeDescription*)pTD;
1502         {for( sal_Int32 i = 0; i < pITD->nAllMembers; i++ )
1503         {
1504             typelib_typedescriptionreference_release( pITD->ppAllMembers[i] );
1505         }}
1506         delete [] pITD->ppAllMembers;
1507         delete [] pITD->pMapMemberIndexToFunctionIndex;
1508         delete [] pITD->pMapFunctionIndexToMemberIndex;
1509         {for (sal_Int32 i = 0; i < pITD->nBaseTypes; ++i) {
1510             typelib_typedescription_release(
1511                 reinterpret_cast< typelib_TypeDescription * >(
1512                     pITD->ppBaseTypes[i]));
1513         }}
1514         delete[] pITD->ppBaseTypes;
1515         break;
1516     }
1517     case typelib_TypeClass_INTERFACE_METHOD:
1518     {
1519         typelib_InterfaceMethodTypeDescription * pIMTD = (typelib_InterfaceMethodTypeDescription*)pTD;
1520         if( pIMTD->pReturnTypeRef )
1521             typelib_typedescriptionreference_release( pIMTD->pReturnTypeRef );
1522         for( sal_Int32 i = 0; i < pIMTD->nParams; i++ )
1523         {
1524             rtl_uString_release( pIMTD->pParams[ i ].pName );
1525             typelib_typedescriptionreference_release( pIMTD->pParams[ i ].pTypeRef );
1526         }
1527         delete [] pIMTD->pParams;
1528         deleteExceptions(pIMTD->nExceptions, pIMTD->ppExceptions);
1529         rtl_uString_release( pIMTD->aBase.pMemberName );
1530         typelib_typedescription_release(&pIMTD->pInterface->aBase);
1531         if (pIMTD->pBaseRef != 0) {
1532             typelib_typedescriptionreference_release(pIMTD->pBaseRef);
1533         }
1534     }
1535     break;
1536     case typelib_TypeClass_INTERFACE_ATTRIBUTE:
1537     {
1538         typelib_InterfaceAttributeTypeDescription * pIATD = (typelib_InterfaceAttributeTypeDescription*)pTD;
1539         deleteExceptions(pIATD->nGetExceptions, pIATD->ppGetExceptions);
1540         deleteExceptions(pIATD->nSetExceptions, pIATD->ppSetExceptions);
1541         if( pIATD->pAttributeTypeRef )
1542             typelib_typedescriptionreference_release( pIATD->pAttributeTypeRef );
1543         if( pIATD->aBase.pMemberName )
1544             rtl_uString_release( pIATD->aBase.pMemberName );
1545         typelib_typedescription_release(&pIATD->pInterface->aBase);
1546         if (pIATD->pBaseRef != 0) {
1547             typelib_typedescriptionreference_release(pIATD->pBaseRef);
1548         }
1549     }
1550     break;
1551     case typelib_TypeClass_ENUM:
1552     {
1553         typelib_EnumTypeDescription * pEnum = (typelib_EnumTypeDescription *)pTD;
1554         for ( sal_Int32 nPos = pEnum->nEnumValues; nPos--; )
1555         {
1556             rtl_uString_release( pEnum->ppEnumNames[nPos] );
1557         }
1558         delete [] pEnum->ppEnumNames;
1559         delete [] pEnum->pEnumValues;
1560     }
1561     break;
1562     default:
1563     break;
1564     }
1565 }
1566 
1567 //------------------------------------------------------------------------
typelib_typedescription_release(typelib_TypeDescription * pTD)1568 extern "C" void SAL_CALL typelib_typedescription_release(
1569     typelib_TypeDescription * pTD )
1570     SAL_THROW_EXTERN_C()
1571 {
1572     sal_Int32 ref = ::osl_decrementInterlockedCount( &pTD->nRefCount );
1573     OSL_ASSERT(ref >= 0);
1574     if (0 == ref)
1575     {
1576         TypeDescriptor_Init_Impl &rInit = Init::get();
1577         if( reallyWeak( pTD->eTypeClass ) )
1578         {
1579             if( pTD->pWeakRef )
1580             {
1581                 {
1582                 MutexGuard aGuard( rInit.getMutex() );
1583                 // remove this description from the weak reference
1584                 pTD->pWeakRef->pType = 0;
1585                 }
1586                 typelib_typedescriptionreference_release( pTD->pWeakRef );
1587             }
1588         }
1589         else
1590         {
1591             // this description is a reference too, so remove it from the hash table
1592             if( rInit.pWeakMap )
1593             {
1594                 MutexGuard aGuard( rInit.getMutex() );
1595                 WeakMap_Impl::iterator aIt = rInit.pWeakMap->find( (sal_Unicode*)pTD->pTypeName->buffer );
1596                 if( aIt != rInit.pWeakMap->end() && (void *)(*aIt).second == (void *)pTD )
1597                 {
1598                     // remove only if it contains the same object
1599                     rInit.pWeakMap->erase( aIt );
1600                 }
1601             }
1602         }
1603 
1604         typelib_typedescription_destructExtendedMembers( pTD );
1605         rtl_uString_release( pTD->pTypeName );
1606 
1607 #if OSL_DEBUG_LEVEL > 1
1608         switch( pTD->eTypeClass )
1609         {
1610         case typelib_TypeClass_ARRAY:
1611             osl_decrementInterlockedCount( &rInit.nArrayTypeDescriptionCount );
1612             break;
1613         case typelib_TypeClass_SEQUENCE:
1614             osl_decrementInterlockedCount( &rInit.nIndirectTypeDescriptionCount );
1615             break;
1616         case typelib_TypeClass_UNION:
1617             osl_decrementInterlockedCount( &rInit.nUnionTypeDescriptionCount );
1618             break;
1619         case typelib_TypeClass_STRUCT:
1620         case typelib_TypeClass_EXCEPTION:
1621             osl_decrementInterlockedCount( &rInit.nCompoundTypeDescriptionCount );
1622             break;
1623         case typelib_TypeClass_INTERFACE:
1624             osl_decrementInterlockedCount( &rInit.nInterfaceTypeDescriptionCount );
1625             break;
1626         case typelib_TypeClass_INTERFACE_METHOD:
1627             osl_decrementInterlockedCount( &rInit.nInterfaceMethodTypeDescriptionCount );
1628             break;
1629         case typelib_TypeClass_INTERFACE_ATTRIBUTE:
1630             osl_decrementInterlockedCount( &rInit.nInterfaceAttributeTypeDescriptionCount );
1631             break;
1632         case typelib_TypeClass_ENUM:
1633             osl_decrementInterlockedCount( &rInit.nEnumTypeDescriptionCount );
1634             break;
1635         default:
1636             osl_decrementInterlockedCount( &rInit.nTypeDescriptionCount );
1637         }
1638 #endif
1639 
1640         delete pTD;
1641     }
1642 }
1643 
1644 //------------------------------------------------------------------------
typelib_typedescription_register(typelib_TypeDescription ** ppNewDescription)1645 extern "C" void SAL_CALL typelib_typedescription_register(
1646     typelib_TypeDescription ** ppNewDescription )
1647     SAL_THROW_EXTERN_C()
1648 {
1649     // connect the description with the weak reference
1650     TypeDescriptor_Init_Impl &rInit = Init::get();
1651     ClearableMutexGuard aGuard( rInit.getMutex() );
1652 
1653     typelib_TypeDescriptionReference * pTDR = 0;
1654     typelib_typedescriptionreference_getByName( &pTDR, (*ppNewDescription)->pTypeName );
1655 
1656     OSL_ASSERT( (*ppNewDescription)->pWeakRef || reallyWeak( (*ppNewDescription)->eTypeClass ) );
1657     if( pTDR )
1658     {
1659         OSL_ASSERT( (*ppNewDescription)->eTypeClass == pTDR->eTypeClass );
1660         if( pTDR->pType )
1661         {
1662             if (reallyWeak( pTDR->eTypeClass ))
1663             {
1664                 // pRef->pType->pWeakRef == 0 means that the description is empty
1665                 if (pTDR->pType->pWeakRef)
1666                 {
1667                     if (osl_incrementInterlockedCount( &pTDR->pType->nRefCount ) > 1)
1668                     {
1669                         // The reference is incremented. The object cannot be destroyed.
1670                         // Release the guard at the earliest point.
1671                         aGuard.clear();
1672                         ::typelib_typedescription_release( *ppNewDescription );
1673                         *ppNewDescription = pTDR->pType;
1674                         ::typelib_typedescriptionreference_release( pTDR );
1675                         return;
1676                     }
1677                     else
1678                     {
1679                         // destruction of this type in progress (another thread!)
1680                         osl_decrementInterlockedCount( &pTDR->pType->nRefCount );
1681                     }
1682                 }
1683                 // take new descr
1684                 pTDR->pType = *ppNewDescription;
1685                 OSL_ASSERT( ! (*ppNewDescription)->pWeakRef );
1686                 (*ppNewDescription)->pWeakRef = pTDR;
1687                 return;
1688             }
1689             // !reallyWeak
1690 
1691             if (((void *)pTDR != (void *)*ppNewDescription) && // if different
1692                 (!pTDR->pType->pWeakRef || // uninit: ref data only set
1693                  // new one is complete:
1694                  (!pTDR->pType->bComplete && (*ppNewDescription)->bComplete) ||
1695                  // new one may be partly initialized interface (except of tables):
1696                  (typelib_TypeClass_INTERFACE == pTDR->pType->eTypeClass &&
1697                   !((typelib_InterfaceTypeDescription *)pTDR->pType)->ppAllMembers &&
1698                   (*(typelib_InterfaceTypeDescription **)ppNewDescription)->ppAllMembers)))
1699             {
1700                 // uninitialized or incomplete
1701 
1702                 if (pTDR->pType->pWeakRef) // if init
1703                 {
1704                     typelib_typedescription_destructExtendedMembers( pTDR->pType );
1705                 }
1706 
1707                 // pTDR->pType->pWeakRef == 0 means that the description is empty
1708                 // description is not weak and the not the same
1709                 sal_Int32 nSize = getDescriptionSize( (*ppNewDescription)->eTypeClass );
1710 
1711                 // copy all specific data for the descriptions
1712                 ::rtl_copyMemory(
1713                     pTDR->pType +1,
1714                     *ppNewDescription +1,
1715                     nSize - sizeof(typelib_TypeDescription) );
1716 
1717                 pTDR->pType->bComplete = (*ppNewDescription)->bComplete;
1718                 pTDR->pType->nSize = (*ppNewDescription)->nSize;
1719                 pTDR->pType->nAlignment = (*ppNewDescription)->nAlignment;
1720 
1721                 ::rtl_zeroMemory(
1722                     *ppNewDescription +1, nSize - sizeof( typelib_TypeDescription ) );
1723 
1724                 if( pTDR->pType->bOnDemand && !(*ppNewDescription)->bOnDemand )
1725                 {
1726                     // switch from OnDemand to !OnDemand, so the description must be acquired
1727                     typelib_typedescription_acquire( pTDR->pType );
1728                 }
1729                 else if( !pTDR->pType->bOnDemand && (*ppNewDescription)->bOnDemand )
1730                 {
1731                     // switch from !OnDemand to OnDemand, so the description must be released
1732                     typelib_typedescription_release( pTDR->pType );
1733                 }
1734 
1735                 pTDR->pType->bOnDemand = (*ppNewDescription)->bOnDemand;
1736                 // initialized
1737                 pTDR->pType->pWeakRef = pTDR;
1738             }
1739 
1740             typelib_typedescription_release( *ppNewDescription );
1741             // pTDR was acquired by getByName(), so it must not be acquired again
1742             *ppNewDescription = pTDR->pType;
1743             return;
1744         }
1745     }
1746     else if( reallyWeak( (*ppNewDescription)->eTypeClass) )
1747     {
1748         typelib_typedescriptionreference_new(
1749             &pTDR, (*ppNewDescription)->eTypeClass, (*ppNewDescription)->pTypeName );
1750     }
1751     else
1752     {
1753         pTDR = (typelib_TypeDescriptionReference *)*ppNewDescription;
1754         if( !rInit.pWeakMap )
1755             rInit.pWeakMap = new WeakMap_Impl;
1756 
1757         // description is the weak itself, so register it
1758         (*rInit.pWeakMap)[pTDR->pTypeName->buffer] = pTDR;
1759         OSL_ASSERT( (void *)*ppNewDescription == (void *)pTDR );
1760     }
1761 
1762     // By default this reference is not really weak. The reference holds the description
1763     // and the description holds the reference.
1764     if( !(*ppNewDescription)->bOnDemand )
1765     {
1766         // nor OnDemand so the description must be acquired if registered
1767         typelib_typedescription_acquire( *ppNewDescription );
1768     }
1769 
1770     pTDR->pType = *ppNewDescription;
1771     (*ppNewDescription)->pWeakRef = pTDR;
1772     OSL_ASSERT( rtl_ustr_compare( pTDR->pTypeName->buffer, (*ppNewDescription)->pTypeName->buffer ) == 0 );
1773     OSL_ASSERT( pTDR->eTypeClass == (*ppNewDescription)->eTypeClass );
1774 }
1775 
1776 //------------------------------------------------------------------------
type_equals(typelib_TypeDescriptionReference * p1,typelib_TypeDescriptionReference * p2)1777 static inline sal_Bool type_equals(
1778     typelib_TypeDescriptionReference * p1, typelib_TypeDescriptionReference * p2 )
1779     SAL_THROW( () )
1780 {
1781     return (p1 == p2 ||
1782             (p1->eTypeClass == p2->eTypeClass &&
1783              p1->pTypeName->length == p2->pTypeName->length &&
1784              rtl_ustr_compare( p1->pTypeName->buffer, p2->pTypeName->buffer ) == 0));
1785 }
typelib_typedescription_equals(const typelib_TypeDescription * p1,const typelib_TypeDescription * p2)1786 extern "C" sal_Bool SAL_CALL typelib_typedescription_equals(
1787     const typelib_TypeDescription * p1, const typelib_TypeDescription * p2 )
1788     SAL_THROW_EXTERN_C()
1789 {
1790     return type_equals(
1791         (typelib_TypeDescriptionReference *)p1, (typelib_TypeDescriptionReference *)p2 );
1792 }
1793 
1794 //------------------------------------------------------------------------
typelib_typedescription_getAlignedUnoSize(const typelib_TypeDescription * pTypeDescription,sal_Int32 nOffset,sal_Int32 & rMaxIntegralTypeSize)1795 extern "C" sal_Int32 SAL_CALL typelib_typedescription_getAlignedUnoSize(
1796     const typelib_TypeDescription * pTypeDescription,
1797     sal_Int32 nOffset, sal_Int32 & rMaxIntegralTypeSize )
1798     SAL_THROW_EXTERN_C()
1799 {
1800     sal_Int32 nSize;
1801     if( pTypeDescription->nSize )
1802     {
1803         // size and alignment are set
1804         rMaxIntegralTypeSize = pTypeDescription->nAlignment;
1805         nSize = pTypeDescription->nSize;
1806     }
1807     else
1808     {
1809         nSize = 0;
1810         rMaxIntegralTypeSize = 1;
1811 
1812         OSL_ASSERT( typelib_TypeClass_TYPEDEF != pTypeDescription->eTypeClass );
1813 
1814         switch( pTypeDescription->eTypeClass )
1815         {
1816             case typelib_TypeClass_INTERFACE:
1817                 // FEATURE_INTERFACE
1818                 nSize = rMaxIntegralTypeSize = (sal_Int32)(sizeof( void * ));
1819                 break;
1820             case typelib_TypeClass_UNION:
1821                 {
1822                 nSize = rMaxIntegralTypeSize = (sal_Int32)(sizeof(sal_Int64));
1823                 for ( sal_Int32 nPos = ((typelib_UnionTypeDescription *)pTypeDescription)->nMembers; nPos--; )
1824                 {
1825                     typelib_TypeDescription * pTD = 0;
1826                     TYPELIB_DANGER_GET( &pTD, ((typelib_UnionTypeDescription *)pTypeDescription)->ppTypeRefs[nPos] );
1827                     sal_Int32 nMaxIntegralTypeSize;
1828                     sal_Int32 nMemberSize = typelib_typedescription_getAlignedUnoSize( pTD, (sal_Int32)(sizeof(sal_Int64)), nMaxIntegralTypeSize );
1829                     TYPELIB_DANGER_RELEASE( pTD );
1830                     if (nSize < nMemberSize)
1831                         nSize = nMemberSize;
1832                     if (rMaxIntegralTypeSize < nMaxIntegralTypeSize)
1833                         rMaxIntegralTypeSize = nMaxIntegralTypeSize;
1834                 }
1835                 ((typelib_UnionTypeDescription *)pTypeDescription)->nValueOffset = rMaxIntegralTypeSize;
1836                 }
1837                 break;
1838             case typelib_TypeClass_ENUM:
1839                 nSize = rMaxIntegralTypeSize = (sal_Int32)(sizeof( typelib_TypeClass ));
1840                 break;
1841             case typelib_TypeClass_STRUCT:
1842             case typelib_TypeClass_EXCEPTION:
1843                 // FEATURE_EMPTYCLASS
1844                 {
1845                 typelib_CompoundTypeDescription * pTmp = (typelib_CompoundTypeDescription *)pTypeDescription;
1846                 sal_Int32 nStructSize = 0;
1847                 if( pTmp->pBaseTypeDescription )
1848                 {
1849                     // inherit structs extends the base struct.
1850                     nStructSize = pTmp->pBaseTypeDescription->aBase.nSize;
1851                     rMaxIntegralTypeSize = pTmp->pBaseTypeDescription->aBase.nAlignment;
1852                 }
1853                 for( sal_Int32 i = 0; i < pTmp->nMembers; i++ )
1854                 {
1855                     typelib_TypeDescription * pMemberType = 0;
1856                     typelib_TypeDescriptionReference * pMemberRef = pTmp->ppTypeRefs[i];
1857 
1858                     sal_Int32 nMaxIntegral;
1859                     if (pMemberRef->eTypeClass == typelib_TypeClass_INTERFACE
1860                         || pMemberRef->eTypeClass == typelib_TypeClass_SEQUENCE)
1861                     {
1862                         nMaxIntegral = (sal_Int32)(sizeof(void *));
1863                         nStructSize = newAlignedSize( nStructSize, nMaxIntegral, nMaxIntegral );
1864                     }
1865                     else
1866                     {
1867                         TYPELIB_DANGER_GET( &pMemberType, pMemberRef );
1868                         nStructSize = typelib_typedescription_getAlignedUnoSize(
1869                             pMemberType, nStructSize, nMaxIntegral );
1870                         TYPELIB_DANGER_RELEASE( pMemberType );
1871                     }
1872                     if( nMaxIntegral > rMaxIntegralTypeSize )
1873                         rMaxIntegralTypeSize = nMaxIntegral;
1874                 }
1875 #ifdef __m68k__
1876                 // Anything that is at least 16 bits wide is aligned on a 16-bit
1877                 // boundary on the m68k default abi
1878                 sal_Int32 nMaxAlign = (rMaxIntegralTypeSize > 2) ? 2 : rMaxIntegralTypeSize;
1879                 nStructSize = (nStructSize + nMaxAlign -1) / nMaxAlign * nMaxAlign;
1880 #else
1881                 // Example: A { double; int; } structure has a size of 16 instead of 10. The
1882                 // compiler must follow this rule if it is possible to access members in arrays through:
1883                 // (Element *)((char *)pArray + sizeof( Element ) * ElementPos)
1884                 nStructSize = (nStructSize + rMaxIntegralTypeSize -1)
1885                                 / rMaxIntegralTypeSize * rMaxIntegralTypeSize;
1886 #endif
1887                 nSize += nStructSize;
1888                 }
1889                 break;
1890             case typelib_TypeClass_ARRAY:
1891                 {
1892                 typelib_TypeDescription * pTD = 0;
1893                 TYPELIB_DANGER_GET( &pTD, ((typelib_IndirectTypeDescription *)pTypeDescription)->pType );
1894                 rMaxIntegralTypeSize = pTD->nSize;
1895                 TYPELIB_DANGER_RELEASE( pTD );
1896                 nSize = ((typelib_ArrayTypeDescription *)pTypeDescription)->nTotalElements * rMaxIntegralTypeSize;
1897                 }
1898                 break;
1899             case typelib_TypeClass_SEQUENCE:
1900                 nSize = rMaxIntegralTypeSize = (sal_Int32)(sizeof( void * ));
1901                 break;
1902             case typelib_TypeClass_ANY:
1903                 // FEATURE_ANY
1904                 nSize = (sal_Int32)(sizeof( uno_Any ));
1905                 rMaxIntegralTypeSize = (sal_Int32)(sizeof( void * ));
1906                 break;
1907             case typelib_TypeClass_TYPE:
1908                 nSize = rMaxIntegralTypeSize = (sal_Int32)(sizeof( typelib_TypeDescriptionReference * ));
1909                 break;
1910             case typelib_TypeClass_BOOLEAN:
1911                 nSize = rMaxIntegralTypeSize = (sal_Int32)(sizeof( sal_Bool ));
1912                 break;
1913             case typelib_TypeClass_CHAR:
1914                 nSize = rMaxIntegralTypeSize = (sal_Int32)(sizeof( sal_Unicode ));
1915                 break;
1916             case typelib_TypeClass_STRING:
1917                 // FEATURE_STRING
1918                 nSize = rMaxIntegralTypeSize = (sal_Int32)(sizeof( rtl_uString * ));
1919                 break;
1920             case typelib_TypeClass_FLOAT:
1921                 nSize = rMaxIntegralTypeSize = (sal_Int32)(sizeof( float ));
1922                 break;
1923             case typelib_TypeClass_DOUBLE:
1924                 nSize = rMaxIntegralTypeSize = (sal_Int32)(sizeof( double ));
1925                 break;
1926             case typelib_TypeClass_BYTE:
1927                 nSize = rMaxIntegralTypeSize = (sal_Int32)(sizeof( sal_Int8 ));
1928                 break;
1929             case typelib_TypeClass_SHORT:
1930             case typelib_TypeClass_UNSIGNED_SHORT:
1931                 nSize = rMaxIntegralTypeSize = (sal_Int32)(sizeof( sal_Int16 ));
1932                 break;
1933             case typelib_TypeClass_LONG:
1934             case typelib_TypeClass_UNSIGNED_LONG:
1935                 nSize = rMaxIntegralTypeSize = (sal_Int32)(sizeof( sal_Int32 ));
1936                 break;
1937             case typelib_TypeClass_HYPER:
1938             case typelib_TypeClass_UNSIGNED_HYPER:
1939                 nSize = rMaxIntegralTypeSize = (sal_Int32)(sizeof( sal_Int64 ));
1940                 break;
1941             case typelib_TypeClass_UNKNOWN:
1942             case typelib_TypeClass_SERVICE:
1943             case typelib_TypeClass_MODULE:
1944             default:
1945                 OSL_ENSURE( sal_False, "not convertable type" );
1946         };
1947     }
1948 
1949     return newAlignedSize( nOffset, nSize, rMaxIntegralTypeSize );
1950 }
1951 
1952 //------------------------------------------------------------------------
1953 
1954 namespace {
1955 
copyExceptions(sal_Int32 count,typelib_TypeDescriptionReference ** source)1956 typelib_TypeDescriptionReference ** copyExceptions(
1957     sal_Int32 count, typelib_TypeDescriptionReference ** source)
1958 {
1959     typelib_TypeDescriptionReference ** p
1960         = new typelib_TypeDescriptionReference *[count];
1961     for (sal_Int32 i = 0; i < count; ++i) {
1962         typelib_typedescriptionreference_acquire(p[i] = source[i]);
1963     }
1964     return p;
1965 }
1966 
createDerivedInterfaceMemberDescription(typelib_TypeDescription ** result,rtl::OUString const & name,typelib_TypeDescriptionReference * baseRef,typelib_TypeDescription const * base,typelib_TypeDescription * interface,sal_Int32 index,sal_Int32 position)1967 bool createDerivedInterfaceMemberDescription(
1968     typelib_TypeDescription ** result, rtl::OUString const & name,
1969     typelib_TypeDescriptionReference * baseRef,
1970     typelib_TypeDescription const * base, typelib_TypeDescription * interface,
1971     sal_Int32 index, sal_Int32 position)
1972 {
1973     if (baseRef != 0 && base != 0 && interface != 0) {
1974         switch (base->eTypeClass) {
1975         case typelib_TypeClass_INTERFACE_METHOD:
1976             {
1977                 typelib_typedescription_newEmpty(
1978                     result, typelib_TypeClass_INTERFACE_METHOD, name.pData);
1979                 typelib_InterfaceMethodTypeDescription const * baseMethod
1980                     = reinterpret_cast<
1981                     typelib_InterfaceMethodTypeDescription const * >(base);
1982                 typelib_InterfaceMethodTypeDescription * newMethod
1983                     = reinterpret_cast<
1984                     typelib_InterfaceMethodTypeDescription * >(*result);
1985                 newMethod->aBase.nPosition = position;
1986                 rtl_uString_acquire(
1987                     newMethod->aBase.pMemberName
1988                     = baseMethod->aBase.pMemberName);
1989                 typelib_typedescriptionreference_acquire(
1990                     newMethod->pReturnTypeRef = baseMethod->pReturnTypeRef);
1991                 newMethod->nParams = baseMethod->nParams;
1992                 newMethod->pParams = new typelib_MethodParameter[
1993                     newMethod->nParams];
1994                 for (sal_Int32 i = 0; i < newMethod->nParams; ++i) {
1995                     rtl_uString_acquire(
1996                         newMethod->pParams[i].pName
1997                         = baseMethod->pParams[i].pName);
1998                     typelib_typedescriptionreference_acquire(
1999                         newMethod->pParams[i].pTypeRef
2000                         = baseMethod->pParams[i].pTypeRef);
2001                     newMethod->pParams[i].bIn = baseMethod->pParams[i].bIn;
2002                     newMethod->pParams[i].bOut = baseMethod->pParams[i].bOut;
2003                 }
2004                 newMethod->nExceptions = baseMethod->nExceptions;
2005                 newMethod->ppExceptions = copyExceptions(
2006                     baseMethod->nExceptions, baseMethod->ppExceptions);
2007                 newMethod->bOneWay = baseMethod->bOneWay;
2008                 newMethod->pInterface
2009                     = reinterpret_cast< typelib_InterfaceTypeDescription * >(
2010                         interface);
2011                 newMethod->pBaseRef = baseRef;
2012                 newMethod->nIndex = index;
2013                 return true;
2014             }
2015 
2016         case typelib_TypeClass_INTERFACE_ATTRIBUTE:
2017             {
2018                 typelib_typedescription_newEmpty(
2019                     result, typelib_TypeClass_INTERFACE_ATTRIBUTE, name.pData);
2020                 typelib_InterfaceAttributeTypeDescription const * baseAttribute
2021                     = reinterpret_cast<
2022                     typelib_InterfaceAttributeTypeDescription const * >(base);
2023                 typelib_InterfaceAttributeTypeDescription * newAttribute
2024                     = reinterpret_cast<
2025                     typelib_InterfaceAttributeTypeDescription * >(*result);
2026                 newAttribute->aBase.nPosition = position;
2027                 rtl_uString_acquire(
2028                     newAttribute->aBase.pMemberName
2029                     = baseAttribute->aBase.pMemberName);
2030                 newAttribute->bReadOnly = baseAttribute->bReadOnly;
2031                 typelib_typedescriptionreference_acquire(
2032                     newAttribute->pAttributeTypeRef
2033                     = baseAttribute->pAttributeTypeRef);
2034                 newAttribute->pInterface
2035                     = reinterpret_cast< typelib_InterfaceTypeDescription * >(
2036                         interface);
2037                 newAttribute->pBaseRef = baseRef;
2038                 newAttribute->nIndex = index;
2039                 newAttribute->nGetExceptions = baseAttribute->nGetExceptions;
2040                 newAttribute->ppGetExceptions = copyExceptions(
2041                     baseAttribute->nGetExceptions,
2042                     baseAttribute->ppGetExceptions);
2043                 newAttribute->nSetExceptions = baseAttribute->nSetExceptions;
2044                 newAttribute->ppSetExceptions = copyExceptions(
2045                     baseAttribute->nSetExceptions,
2046                     baseAttribute->ppSetExceptions);
2047                 return true;
2048             }
2049 
2050         default:
2051             break;
2052         }
2053     }
2054     return false;
2055 }
2056 
2057 }
2058 
typelib_typedescription_getByName(typelib_TypeDescription ** ppRet,rtl_uString * pName)2059 extern "C" void SAL_CALL typelib_typedescription_getByName(
2060     typelib_TypeDescription ** ppRet, rtl_uString * pName )
2061     SAL_THROW_EXTERN_C()
2062 {
2063     if( *ppRet )
2064     {
2065         typelib_typedescription_release( (*ppRet) );
2066         *ppRet = 0;
2067     }
2068 
2069     static sal_Bool bInited = sal_False;
2070     TypeDescriptor_Init_Impl &rInit = Init::get();
2071 
2072     if( !bInited )
2073     {
2074         // guard against multi thread access
2075         MutexGuard aGuard( rInit.getMutex() );
2076         if( !bInited )
2077         {
2078             // avoid recursion during the next ...new calls
2079             bInited = sal_True;
2080 
2081             rtl_uString * pTypeName = 0;
2082             typelib_TypeDescription * pType = 0;
2083             rtl_uString_newFromAscii( &pTypeName, "type" );
2084             typelib_typedescription_new( &pType, typelib_TypeClass_TYPE, pTypeName, 0, 0, 0 );
2085             typelib_typedescription_register( &pType );
2086             rtl_uString_newFromAscii( &pTypeName, "void" );
2087             typelib_typedescription_new( &pType, typelib_TypeClass_VOID, pTypeName, 0, 0, 0 );
2088             typelib_typedescription_register( &pType );
2089             rtl_uString_newFromAscii( &pTypeName, "boolean" );
2090             typelib_typedescription_new( &pType, typelib_TypeClass_BOOLEAN, pTypeName, 0, 0, 0 );
2091             typelib_typedescription_register( &pType );
2092             rtl_uString_newFromAscii( &pTypeName, "char" );
2093             typelib_typedescription_new( &pType, typelib_TypeClass_CHAR, pTypeName, 0, 0, 0 );
2094             typelib_typedescription_register( &pType );
2095             rtl_uString_newFromAscii( &pTypeName, "byte" );
2096             typelib_typedescription_new( &pType, typelib_TypeClass_BYTE, pTypeName, 0, 0, 0 );
2097             typelib_typedescription_register( &pType );
2098             rtl_uString_newFromAscii( &pTypeName, "string" );
2099             typelib_typedescription_new( &pType, typelib_TypeClass_STRING, pTypeName, 0, 0, 0 );
2100             typelib_typedescription_register( &pType );
2101             rtl_uString_newFromAscii( &pTypeName, "short" );
2102             typelib_typedescription_new( &pType, typelib_TypeClass_SHORT, pTypeName, 0, 0, 0 );
2103             typelib_typedescription_register( &pType );
2104             rtl_uString_newFromAscii( &pTypeName, "unsigned short" );
2105             typelib_typedescription_new( &pType, typelib_TypeClass_UNSIGNED_SHORT, pTypeName, 0, 0, 0 );
2106             typelib_typedescription_register( &pType );
2107             rtl_uString_newFromAscii( &pTypeName, "long" );
2108             typelib_typedescription_new( &pType, typelib_TypeClass_LONG, pTypeName, 0, 0, 0 );
2109             typelib_typedescription_register( &pType );
2110             rtl_uString_newFromAscii( &pTypeName, "unsigned long" );
2111             typelib_typedescription_new( &pType, typelib_TypeClass_UNSIGNED_LONG, pTypeName, 0, 0, 0 );
2112             typelib_typedescription_register( &pType );
2113             rtl_uString_newFromAscii( &pTypeName, "hyper" );
2114             typelib_typedescription_new( &pType, typelib_TypeClass_HYPER, pTypeName, 0, 0, 0 );
2115             typelib_typedescription_register( &pType );
2116             rtl_uString_newFromAscii( &pTypeName, "unsigned hyper" );
2117             typelib_typedescription_new( &pType, typelib_TypeClass_UNSIGNED_HYPER, pTypeName, 0, 0, 0 );
2118             typelib_typedescription_register( &pType );
2119             rtl_uString_newFromAscii( &pTypeName, "float" );
2120             typelib_typedescription_new( &pType, typelib_TypeClass_FLOAT, pTypeName, 0, 0, 0 );
2121             typelib_typedescription_register( &pType );
2122             rtl_uString_newFromAscii( &pTypeName, "double" );
2123             typelib_typedescription_new( &pType, typelib_TypeClass_DOUBLE, pTypeName, 0, 0, 0 );
2124             typelib_typedescription_register( &pType );
2125             rtl_uString_newFromAscii( &pTypeName, "any" );
2126             typelib_typedescription_new( &pType, typelib_TypeClass_ANY, pTypeName, 0, 0, 0 );
2127             typelib_typedescription_register( &pType );
2128             typelib_typedescription_release( pType );
2129             rtl_uString_release( pTypeName );
2130         }
2131     }
2132 
2133     typelib_TypeDescriptionReference * pTDR = 0;
2134     typelib_typedescriptionreference_getByName( &pTDR, pName );
2135     if( pTDR )
2136     {
2137         {
2138         // guard against multi thread access
2139         MutexGuard aGuard( rInit.getMutex() );
2140         // pTDR->pType->pWeakRef == 0 means that the description is empty
2141         if( pTDR->pType && pTDR->pType->pWeakRef )
2142         {
2143             typelib_typedescription_acquire( pTDR->pType );
2144             *ppRet = pTDR->pType;
2145         }
2146         }
2147         typelib_typedescriptionreference_release( pTDR );
2148     }
2149 
2150     if (0 == *ppRet)
2151     {
2152         // check for sequence
2153         OUString const & name = *reinterpret_cast< OUString const * >( &pName );
2154         if (2 < name.getLength() && '[' == name[ 0 ])
2155         {
2156             OUString element_name( name.copy( 2 ) );
2157             typelib_TypeDescription * element_td = 0;
2158             typelib_typedescription_getByName( &element_td, element_name.pData );
2159             if (0 != element_td)
2160             {
2161                 typelib_typedescription_new(
2162                     ppRet, typelib_TypeClass_SEQUENCE, pName, element_td->pWeakRef, 0, 0 );
2163                 // register?
2164                 typelib_typedescription_release( element_td );
2165             }
2166         }
2167         if (0 == *ppRet)
2168         {
2169             // Check for derived interface member type:
2170             sal_Int32 i1 = name.lastIndexOf(
2171                 rtl::OUString::createFromAscii(":@"));
2172             if (i1 >= 0) {
2173                 sal_Int32 i2 = i1 + RTL_CONSTASCII_LENGTH(":@");
2174                 sal_Int32 i3 = name.indexOf(',', i2);
2175                 if (i3 >= 0) {
2176                     sal_Int32 i4 = name.indexOf(':', i3);
2177                     if (i4 >= 0) {
2178                         typelib_TypeDescriptionReference * pBaseRef = 0;
2179                         typelib_TypeDescription * pBase = 0;
2180                         typelib_TypeDescription * pInterface = 0;
2181                         typelib_typedescriptionreference_getByName(
2182                             &pBaseRef, name.copy(0, i1).pData);
2183                         if (pBaseRef != 0) {
2184                             typelib_typedescriptionreference_getDescription(
2185                                 &pBase, pBaseRef);
2186                         }
2187                         typelib_typedescription_getByName(
2188                             &pInterface, name.copy(i4 + 1).pData);
2189                         if (!createDerivedInterfaceMemberDescription(
2190                                 ppRet, name, pBaseRef, pBase, pInterface,
2191                                 name.copy(i2, i3 - i2).toInt32(),
2192                                 name.copy(i3 + 1, i4 - i3 - 1).toInt32()))
2193                         {
2194                             if (pInterface != 0) {
2195                                 typelib_typedescription_release(pInterface);
2196                             }
2197                             if (pBase != 0) {
2198                                 typelib_typedescription_release(pBase);
2199                             }
2200                             if (pBaseRef != 0) {
2201                                 typelib_typedescriptionreference_release(
2202                                     pBaseRef);
2203                             }
2204                         }
2205                     }
2206                 }
2207             }
2208         }
2209         if (0 == *ppRet)
2210         {
2211             // on demand access
2212             rInit.callChain( ppRet, pName );
2213         }
2214 
2215         if( *ppRet )
2216         {
2217             // type description found
2218             if (typelib_TypeClass_TYPEDEF == (*ppRet)->eTypeClass)
2219             {
2220                 typelib_TypeDescription * pTD = 0;
2221                 typelib_typedescriptionreference_getDescription(
2222                     &pTD, ((typelib_IndirectTypeDescription *)*ppRet)->pType );
2223                 typelib_typedescription_release( *ppRet );
2224                 *ppRet = pTD;
2225             }
2226             else
2227             {
2228                 // set to on demand
2229                 (*ppRet)->bOnDemand = sal_True;
2230                 // The type description is held by the reference until
2231                 // on demand is activated.
2232                 typelib_typedescription_register( ppRet );
2233 
2234                 // insert into the cache
2235                 MutexGuard aGuard( rInit.getMutex() );
2236                 if( !rInit.pCache )
2237                     rInit.pCache = new TypeDescriptionList_Impl;
2238                 if( (sal_Int32)rInit.pCache->size() >= nCacheSize )
2239                 {
2240                     typelib_typedescription_release( rInit.pCache->front() );
2241                     rInit.pCache->pop_front();
2242                 }
2243                 // descriptions in the cache must be acquired!
2244                 typelib_typedescription_acquire( *ppRet );
2245                 rInit.pCache->push_back( *ppRet );
2246             }
2247         }
2248     }
2249 }
2250 
2251 
2252 //------------------------------------------------------------------------
2253 //------------------------------------------------------------------------
2254 //------------------------------------------------------------------------
typelib_typedescriptionreference_newByAsciiName(typelib_TypeDescriptionReference ** ppTDR,typelib_TypeClass eTypeClass,const sal_Char * pTypeName)2255 extern "C" void SAL_CALL typelib_typedescriptionreference_newByAsciiName(
2256     typelib_TypeDescriptionReference ** ppTDR,
2257     typelib_TypeClass eTypeClass,
2258     const sal_Char * pTypeName )
2259     SAL_THROW_EXTERN_C()
2260 {
2261     OUString aTypeName( OUString::createFromAscii( pTypeName ) );
2262     typelib_typedescriptionreference_new( ppTDR, eTypeClass, aTypeName.pData );
2263 }
2264 //------------------------------------------------------------------------
typelib_typedescriptionreference_new(typelib_TypeDescriptionReference ** ppTDR,typelib_TypeClass eTypeClass,rtl_uString * pTypeName)2265 extern "C" void SAL_CALL typelib_typedescriptionreference_new(
2266     typelib_TypeDescriptionReference ** ppTDR,
2267     typelib_TypeClass eTypeClass, rtl_uString * pTypeName )
2268     SAL_THROW_EXTERN_C()
2269 {
2270     TypeDescriptor_Init_Impl &rInit = Init::get();
2271     if( eTypeClass == typelib_TypeClass_TYPEDEF )
2272     {
2273         // on demand access
2274         typelib_TypeDescription * pRet = 0;
2275         rInit.callChain( &pRet, pTypeName );
2276         if( pRet )
2277         {
2278             // type description found
2279             if (typelib_TypeClass_TYPEDEF == pRet->eTypeClass)
2280             {
2281                 typelib_typedescriptionreference_acquire(
2282                     ((typelib_IndirectTypeDescription *)pRet)->pType );
2283                 if (*ppTDR)
2284                     typelib_typedescriptionreference_release( *ppTDR );
2285                 *ppTDR = ((typelib_IndirectTypeDescription *)pRet)->pType;
2286                 typelib_typedescription_release( pRet );
2287             }
2288             else
2289             {
2290                 // set to on demand
2291                 pRet->bOnDemand = sal_True;
2292                 // The type description is held by the reference until
2293                 // on demand is activated.
2294                 typelib_typedescription_register( &pRet );
2295 
2296                 // insert into the cache
2297                 MutexGuard aGuard( rInit.getMutex() );
2298                 if( !rInit.pCache )
2299                     rInit.pCache = new TypeDescriptionList_Impl;
2300                 if( (sal_Int32)rInit.pCache->size() >= nCacheSize )
2301                 {
2302                     typelib_typedescription_release( rInit.pCache->front() );
2303                     rInit.pCache->pop_front();
2304                 }
2305                 rInit.pCache->push_back( pRet );
2306                 // pRet kept acquired for cache
2307 
2308                 typelib_typedescriptionreference_acquire( pRet->pWeakRef );
2309                 if (*ppTDR)
2310                     typelib_typedescriptionreference_release( *ppTDR );
2311                 *ppTDR = pRet->pWeakRef;
2312             }
2313         }
2314         else if (*ppTDR)
2315         {
2316 #if OSL_DEBUG_LEVEL > 1
2317             OString aStr( OUStringToOString( pTypeName, RTL_TEXTENCODING_ASCII_US ) );
2318             OSL_ENSURE( !"### typedef not found: ", aStr.getStr() );
2319 #endif
2320             typelib_typedescriptionreference_release( *ppTDR );
2321             *ppTDR = 0;
2322         }
2323         return;
2324     }
2325 
2326     MutexGuard aGuard( rInit.getMutex() );
2327     typelib_typedescriptionreference_getByName( ppTDR, pTypeName );
2328     if( *ppTDR )
2329         return;
2330 
2331     if( reallyWeak( eTypeClass ) )
2332     {
2333         typelib_TypeDescriptionReference * pTDR = new typelib_TypeDescriptionReference();
2334 #if OSL_DEBUG_LEVEL > 1
2335         osl_incrementInterlockedCount( &rInit.nTypeDescriptionReferenceCount );
2336 #endif
2337         pTDR->nRefCount = 1;
2338         pTDR->nStaticRefCount = 0;
2339         pTDR->eTypeClass = eTypeClass;
2340         pTDR->pUniqueIdentifier = 0;
2341         pTDR->pReserved = 0;
2342         rtl_uString_acquire( pTDR->pTypeName = pTypeName );
2343         pTDR->pType = 0;
2344         *ppTDR = pTDR;
2345     }
2346     else
2347     {
2348         typelib_typedescription_newEmpty( (typelib_TypeDescription ** )ppTDR, eTypeClass, pTypeName );
2349         // description will be registered but not acquired
2350         (*(typelib_TypeDescription ** )ppTDR)->bOnDemand = sal_True;
2351         (*(typelib_TypeDescription ** )ppTDR)->bComplete = sal_False;
2352     }
2353 
2354     if( !rInit.pWeakMap )
2355         rInit.pWeakMap = new WeakMap_Impl;
2356     // Heavy hack, the const sal_Unicode * is held by the type description reference
2357     // not registered
2358     rInit.pWeakMap->operator[]( (*ppTDR)->pTypeName->buffer ) = *ppTDR;
2359 }
2360 
2361 //------------------------------------------------------------------------
typelib_typedescriptionreference_acquire(typelib_TypeDescriptionReference * pRef)2362 extern "C" void SAL_CALL typelib_typedescriptionreference_acquire(
2363     typelib_TypeDescriptionReference * pRef )
2364     SAL_THROW_EXTERN_C()
2365 {
2366     ::osl_incrementInterlockedCount( &pRef->nRefCount );
2367 }
2368 
2369 //------------------------------------------------------------------------
typelib_typedescriptionreference_release(typelib_TypeDescriptionReference * pRef)2370 extern "C" void SAL_CALL typelib_typedescriptionreference_release(
2371     typelib_TypeDescriptionReference * pRef )
2372     SAL_THROW_EXTERN_C()
2373 {
2374     // Is it a type description?
2375     if( reallyWeak( pRef->eTypeClass ) )
2376     {
2377         if( ! ::osl_decrementInterlockedCount( &pRef->nRefCount ) )
2378         {
2379             TypeDescriptor_Init_Impl &rInit = Init::get();
2380             if( rInit.pWeakMap )
2381             {
2382                 MutexGuard aGuard( rInit.getMutex() );
2383                 WeakMap_Impl::iterator aIt = rInit.pWeakMap->find( (sal_Unicode*)pRef->pTypeName->buffer );
2384                 if( !(aIt == rInit.pWeakMap->end()) && (*aIt).second == pRef )
2385                 {
2386                     // remove only if it contains the same object
2387                     rInit.pWeakMap->erase( aIt );
2388                 }
2389             }
2390 
2391             rtl_uString_release( pRef->pTypeName );
2392             OSL_ASSERT( pRef->pType == 0 );
2393 #if OSL_DEBUG_LEVEL > 1
2394             osl_decrementInterlockedCount( &rInit.nTypeDescriptionReferenceCount );
2395 #endif
2396             delete pRef;
2397         }
2398     }
2399     else
2400     {
2401         typelib_typedescription_release( (typelib_TypeDescription *)pRef );
2402     }
2403 }
2404 
2405 //------------------------------------------------------------------------
typelib_typedescriptionreference_getDescription(typelib_TypeDescription ** ppRet,typelib_TypeDescriptionReference * pRef)2406 extern "C" void SAL_CALL typelib_typedescriptionreference_getDescription(
2407     typelib_TypeDescription ** ppRet, typelib_TypeDescriptionReference * pRef )
2408     SAL_THROW_EXTERN_C()
2409 {
2410     if( *ppRet )
2411     {
2412         typelib_typedescription_release( *ppRet );
2413         *ppRet = 0;
2414     }
2415 
2416     if( !reallyWeak( pRef->eTypeClass ) && pRef->pType && pRef->pType->pWeakRef )
2417     {
2418         // reference is a description and initialized
2419         osl_incrementInterlockedCount( &((typelib_TypeDescription *)pRef)->nRefCount );
2420         *ppRet = (typelib_TypeDescription *)pRef;
2421         return;
2422     }
2423 
2424     {
2425     MutexGuard aGuard( Init::get().getMutex() );
2426     // pRef->pType->pWeakRef == 0 means that the description is empty
2427     if( pRef->pType && pRef->pType->pWeakRef )
2428     {
2429         sal_Int32 n = ::osl_incrementInterlockedCount( &pRef->pType->nRefCount );
2430         if( n > 1 )
2431         {
2432             // The reference is incremented. The object cannot be destroyed.
2433             // Release the guard at the earliest point.
2434             *ppRet = pRef->pType;
2435             return;
2436         }
2437         else
2438         {
2439             ::osl_decrementInterlockedCount( &pRef->pType->nRefCount );
2440             // destruction of this type in progress (another thread!)
2441             // no access through this weak reference
2442             pRef->pType = 0;
2443         }
2444     }
2445     }
2446 
2447     typelib_typedescription_getByName( ppRet, pRef->pTypeName );
2448     OSL_ASSERT( !*ppRet || rtl_ustr_compare( pRef->pTypeName->buffer, (*ppRet)->pTypeName->buffer ) == 0 );
2449     OSL_ASSERT( !*ppRet || pRef->eTypeClass == (*ppRet)->eTypeClass );
2450     OSL_ASSERT( !*ppRet || pRef == (*ppRet)->pWeakRef );
2451     pRef->pType = *ppRet;
2452 }
2453 
2454 //------------------------------------------------------------------------
typelib_typedescriptionreference_getByName(typelib_TypeDescriptionReference ** ppRet,rtl_uString * pName)2455 extern "C" void SAL_CALL typelib_typedescriptionreference_getByName(
2456     typelib_TypeDescriptionReference ** ppRet, rtl_uString * pName )
2457     SAL_THROW_EXTERN_C()
2458 {
2459     if( *ppRet )
2460     {
2461         typelib_typedescriptionreference_release( *ppRet );
2462         *ppRet = 0;
2463     }
2464     TypeDescriptor_Init_Impl &rInit = Init::get();
2465     if( rInit.pWeakMap )
2466     {
2467         MutexGuard aGuard( rInit.getMutex() );
2468         WeakMap_Impl::const_iterator aIt = rInit.pWeakMap->find( (sal_Unicode*)pName->buffer );
2469         if( !(aIt == rInit.pWeakMap->end()) ) // != failed on msc4.2
2470         {
2471             sal_Int32 n = ::osl_incrementInterlockedCount( &(*aIt).second->nRefCount );
2472             if( n > 1 )
2473             {
2474                 // The reference is incremented. The object cannot be destroyed.
2475                 // Release the guard at the earliest point.
2476                 *ppRet = (*aIt).second;
2477             }
2478             else
2479             {
2480                 // destruction of this type in progress (another thread!)
2481                 // no access through this weak reference
2482                 ::osl_decrementInterlockedCount( &(*aIt).second->nRefCount );
2483             }
2484         }
2485     }
2486 }
2487 
2488 //------------------------------------------------------------------------
typelib_typedescriptionreference_equals(const typelib_TypeDescriptionReference * p1,const typelib_TypeDescriptionReference * p2)2489 extern "C" sal_Bool SAL_CALL typelib_typedescriptionreference_equals(
2490     const typelib_TypeDescriptionReference * p1,
2491     const typelib_TypeDescriptionReference * p2 )
2492     SAL_THROW_EXTERN_C()
2493 {
2494     return (p1 == p2 ||
2495             (p1->eTypeClass == p2->eTypeClass &&
2496              p1->pTypeName->length == p2->pTypeName->length &&
2497              rtl_ustr_compare( p1->pTypeName->buffer, p2->pTypeName->buffer ) == 0));
2498 }
2499 
2500 //##################################################################################################
typelib_typedescriptionreference_assign(typelib_TypeDescriptionReference ** ppDest,typelib_TypeDescriptionReference * pSource)2501 extern "C" void SAL_CALL typelib_typedescriptionreference_assign(
2502     typelib_TypeDescriptionReference ** ppDest,
2503     typelib_TypeDescriptionReference * pSource )
2504     SAL_THROW_EXTERN_C()
2505 {
2506     if (*ppDest != pSource)
2507     {
2508         ::typelib_typedescriptionreference_acquire( pSource );
2509         ::typelib_typedescriptionreference_release( *ppDest );
2510         *ppDest = pSource;
2511     }
2512 }
2513 
2514 //##################################################################################################
typelib_setCacheSize(sal_Int32 nNewSize)2515 extern "C" void SAL_CALL typelib_setCacheSize( sal_Int32 nNewSize )
2516     SAL_THROW_EXTERN_C()
2517 {
2518     OSL_ENSURE( nNewSize >= 0, "### illegal cache size given!" );
2519     if (nNewSize >= 0)
2520     {
2521         TypeDescriptor_Init_Impl &rInit = Init::get();
2522         MutexGuard aGuard( rInit.getMutex() );
2523         if ((nNewSize < nCacheSize) && rInit.pCache)
2524         {
2525             while ((sal_Int32)rInit.pCache->size() != nNewSize)
2526             {
2527                 typelib_typedescription_release( rInit.pCache->front() );
2528                 rInit.pCache->pop_front();
2529             }
2530         }
2531         nCacheSize = nNewSize;
2532     }
2533 }
2534 
2535 
2536 static sal_Bool s_aAssignableFromTab[11][11] =
2537 {
2538                          /* from CH,BO,BY,SH,US,LO,UL,HY,UH,FL,DO */
2539 /* TypeClass_CHAR */            { 1, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0 },
2540 /* TypeClass_BOOLEAN */         { 0, 1, 0, 0, 0, 0, 0, 0, 0, 0, 0 },
2541 /* TypeClass_BYTE */            { 0, 0, 1, 0, 0, 0, 0, 0, 0, 0, 0 },
2542 /* TypeClass_SHORT */           { 0, 0, 1, 1, 1, 0, 0, 0, 0, 0, 0 },
2543 /* TypeClass_UNSIGNED_SHORT */  { 0, 0, 1, 1, 1, 0, 0, 0, 0, 0, 0 },
2544 /* TypeClass_LONG */            { 0, 0, 1, 1, 1, 1, 1, 0, 0, 0, 0 },
2545 /* TypeClass_UNSIGNED_LONG */   { 0, 0, 1, 1, 1, 1, 1, 0, 0, 0, 0 },
2546 /* TypeClass_HYPER */           { 0, 0, 1, 1, 1, 1, 1, 1, 1, 0, 0 },
2547 /* TypeClass_UNSIGNED_HYPER */  { 0, 0, 1, 1, 1, 1, 1, 1, 1, 0, 0 },
2548 /* TypeClass_FLOAT */           { 0, 0, 1, 1, 1, 0, 0, 0, 0, 1, 0 },
2549 /* TypeClass_DOUBLE */          { 0, 0, 1, 1, 1, 1, 1, 0, 0, 1, 1 }
2550 };
2551 
2552 //##################################################################################################
typelib_typedescriptionreference_isAssignableFrom(typelib_TypeDescriptionReference * pAssignable,typelib_TypeDescriptionReference * pFrom)2553 extern "C" sal_Bool SAL_CALL typelib_typedescriptionreference_isAssignableFrom(
2554     typelib_TypeDescriptionReference * pAssignable,
2555     typelib_TypeDescriptionReference * pFrom )
2556     SAL_THROW_EXTERN_C()
2557 {
2558     if (pAssignable && pFrom)
2559     {
2560         typelib_TypeClass eAssignable = pAssignable->eTypeClass;
2561         typelib_TypeClass eFrom       = pFrom->eTypeClass;
2562 
2563         if (eAssignable == typelib_TypeClass_ANY) // anything can be assigned to an any .)
2564             return sal_True;
2565         if (eAssignable == eFrom)
2566         {
2567             if (type_equals( pAssignable, pFrom )) // first shot
2568             {
2569                 return sal_True;
2570             }
2571             else
2572             {
2573                 switch (eAssignable)
2574                 {
2575                 case typelib_TypeClass_STRUCT:
2576                 case typelib_TypeClass_EXCEPTION:
2577                 {
2578                     typelib_TypeDescription * pFromDescr = 0;
2579                     TYPELIB_DANGER_GET( &pFromDescr, pFrom );
2580                     if (! ((typelib_CompoundTypeDescription *)pFromDescr)->pBaseTypeDescription)
2581                     {
2582                         TYPELIB_DANGER_RELEASE( pFromDescr );
2583                         return sal_False;
2584                     }
2585                     sal_Bool bRet = typelib_typedescriptionreference_isAssignableFrom(
2586                         pAssignable,
2587                         ((typelib_TypeDescription *)((typelib_CompoundTypeDescription *)pFromDescr)->pBaseTypeDescription)->pWeakRef );
2588                     TYPELIB_DANGER_RELEASE( pFromDescr );
2589                     return bRet;
2590                 }
2591                 case typelib_TypeClass_INTERFACE:
2592                 {
2593                     typelib_TypeDescription * pFromDescr = 0;
2594                     TYPELIB_DANGER_GET( &pFromDescr, pFrom );
2595                     typelib_InterfaceTypeDescription * pFromIfc
2596                         = reinterpret_cast<
2597                             typelib_InterfaceTypeDescription * >(pFromDescr);
2598                     bool bRet = false;
2599                     for (sal_Int32 i = 0; i < pFromIfc->nBaseTypes; ++i) {
2600                         if (typelib_typedescriptionreference_isAssignableFrom(
2601                                 pAssignable,
2602                                 pFromIfc->ppBaseTypes[i]->aBase.pWeakRef))
2603                         {
2604                             bRet = true;
2605                             break;
2606                         }
2607                     }
2608                     TYPELIB_DANGER_RELEASE( pFromDescr );
2609                     return bRet;
2610                 }
2611                 default:
2612                 {
2613                     return sal_False;
2614                 }
2615                 }
2616             }
2617         }
2618         return (eAssignable >= typelib_TypeClass_CHAR && eAssignable <= typelib_TypeClass_DOUBLE &&
2619                 eFrom >= typelib_TypeClass_CHAR && eFrom <= typelib_TypeClass_DOUBLE &&
2620                 s_aAssignableFromTab[eAssignable-1][eFrom-1]);
2621     }
2622     return sal_False;
2623 }
2624 //##################################################################################################
typelib_typedescription_isAssignableFrom(typelib_TypeDescription * pAssignable,typelib_TypeDescription * pFrom)2625 extern "C" sal_Bool SAL_CALL typelib_typedescription_isAssignableFrom(
2626     typelib_TypeDescription * pAssignable,
2627     typelib_TypeDescription * pFrom )
2628     SAL_THROW_EXTERN_C()
2629 {
2630     return typelib_typedescriptionreference_isAssignableFrom(
2631         pAssignable->pWeakRef, pFrom->pWeakRef );
2632 }
2633 
2634 //##################################################################################################
typelib_typedescription_complete(typelib_TypeDescription ** ppTypeDescr)2635 extern "C" sal_Bool SAL_CALL typelib_typedescription_complete(
2636     typelib_TypeDescription ** ppTypeDescr )
2637     SAL_THROW_EXTERN_C()
2638 {
2639     return complete(ppTypeDescr, true);
2640 }
2641