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