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