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