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