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