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