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