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 <unordered_map>
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 527278 : static inline sal_Int32 adjustAlignment( sal_Int32 nRequestedAlignment )
85 : {
86 527278 : if( nRequestedAlignment > nMaxAlignment )
87 0 : nRequestedAlignment = nMaxAlignment;
88 527278 : return nRequestedAlignment;
89 : }
90 :
91 : /**
92 : * Calculate the new size of the structure.
93 : */
94 312942 : static inline sal_Int32 newAlignedSize(
95 : sal_Int32 OldSize, sal_Int32 ElementSize, sal_Int32 NeededAlignment )
96 : {
97 312942 : NeededAlignment = adjustAlignment( NeededAlignment );
98 312942 : return (OldSize + NeededAlignment -1) / NeededAlignment * NeededAlignment + ElementSize;
99 : }
100 :
101 4033099082 : static inline bool reallyWeak( typelib_TypeClass eTypeClass )
102 : {
103 4033099082 : return TYPELIB_TYPEDESCRIPTIONREFERENCE_ISREALLYWEAK( eTypeClass );
104 : }
105 :
106 47233 : 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 47233 : switch( eTypeClass )
115 : {
116 : case typelib_TypeClass_SEQUENCE:
117 2910 : nSize = (sal_Int32)sizeof( typelib_IndirectTypeDescription );
118 2910 : break;
119 :
120 : case typelib_TypeClass_STRUCT:
121 5517 : nSize = (sal_Int32)sizeof( typelib_StructTypeDescription );
122 5517 : break;
123 :
124 : case typelib_TypeClass_EXCEPTION:
125 555 : nSize = (sal_Int32)sizeof( typelib_CompoundTypeDescription );
126 555 : break;
127 :
128 : case typelib_TypeClass_ENUM:
129 980 : nSize = (sal_Int32)sizeof( typelib_EnumTypeDescription );
130 980 : break;
131 :
132 : case typelib_TypeClass_INTERFACE:
133 35214 : nSize = (sal_Int32)sizeof( typelib_InterfaceTypeDescription );
134 35214 : 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 2057 : nSize = (sal_Int32)sizeof( typelib_TypeDescription );
146 : }
147 47233 : return nSize;
148 : }
149 :
150 :
151 :
152 : struct equalStr_Impl
153 : {
154 3013758 : bool operator()(const sal_Unicode * const & s1, const sal_Unicode * const & s2) const
155 3013758 : { return 0 == rtl_ustr_compare( s1, s2 ); }
156 : };
157 :
158 :
159 : struct hashStr_Impl
160 : {
161 4252054 : size_t operator()(const sal_Unicode * const & s) const
162 4252054 : { return rtl_ustr_hashCode( s ); }
163 : };
164 :
165 :
166 :
167 : // Heavy hack, the const sal_Unicode * is hold by the typedescription reference
168 : typedef std::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 517 : TypeDescriptor_Init_Impl():
207 517 : 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 517 : {}
217 :
218 : ~TypeDescriptor_Init_Impl();
219 : };
220 :
221 8292913 : inline Mutex & TypeDescriptor_Init_Impl::getMutex()
222 : {
223 8292913 : if( !pMutex )
224 : {
225 517 : MutexGuard aGuard( Mutex::getGlobalMutex() );
226 517 : if( !pMutex )
227 517 : pMutex = new Mutex();
228 : }
229 8292913 : return * pMutex;
230 : }
231 :
232 66922 : inline void TypeDescriptor_Init_Impl::callChain(
233 : typelib_TypeDescription ** ppRet, rtl_uString * pName )
234 : {
235 : assert(ppRet != 0);
236 : assert(*ppRet == 0);
237 66922 : if (pCallbacks)
238 : {
239 66922 : CallbackSet_Impl::const_iterator aIt = pCallbacks->begin();
240 134101 : while( aIt != pCallbacks->end() )
241 : {
242 66922 : const CallbackEntry & rEntry = *aIt;
243 66922 : (*rEntry.second)( rEntry.first, ppRet, pName );
244 66922 : if( *ppRet )
245 133330 : return;
246 257 : ++aIt;
247 : }
248 : }
249 : }
250 :
251 :
252 517 : TypeDescriptor_Init_Impl::~TypeDescriptor_Init_Impl()
253 : {
254 517 : if( pCache )
255 : {
256 255 : TypeDescriptionList_Impl::const_iterator aIt = pCache->begin();
257 36462 : while( aIt != pCache->end() )
258 : {
259 35952 : typelib_typedescription_release( (*aIt) );
260 35952 : ++aIt;
261 : }
262 255 : delete pCache;
263 255 : pCache = 0;
264 : }
265 :
266 517 : if( pWeakMap )
267 : {
268 517 : std::vector< typelib_TypeDescriptionReference * > ppTDR;
269 517 : ppTDR.reserve( pWeakMap->size() );
270 :
271 : // save all weak references
272 517 : WeakMap_Impl::const_iterator aIt = pWeakMap->begin();
273 606687 : while( aIt != pWeakMap->end() )
274 : {
275 605653 : ppTDR.push_back( (*aIt).second );
276 605653 : typelib_typedescriptionreference_acquire( ppTDR.back() );
277 605653 : ++aIt;
278 : }
279 :
280 1818510 : for( std::vector< typelib_TypeDescriptionReference * >::iterator i(
281 517 : ppTDR.begin() );
282 1212340 : i != ppTDR.end(); ++i )
283 : {
284 605653 : typelib_TypeDescriptionReference * pTDR = *i;
285 : OSL_ASSERT( pTDR->nRefCount > pTDR->nStaticRefCount );
286 605653 : pTDR->nRefCount -= pTDR->nStaticRefCount;
287 :
288 605653 : if( pTDR->pType && !pTDR->pType->bOnDemand )
289 : {
290 95592 : pTDR->pType->bOnDemand = sal_True;
291 95592 : typelib_typedescription_release( pTDR->pType );
292 : }
293 605653 : 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 517 : delete pWeakMap;
316 517 : 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 517 : delete pCallbacks;
332 517 : pCallbacks = 0;
333 :
334 517 : if( pMutex )
335 : {
336 517 : delete pMutex;
337 517 : pMutex = 0;
338 : }
339 517 : };
340 :
341 : namespace { struct Init : public rtl::Static< TypeDescriptor_Init_Impl, Init > {}; }
342 :
343 519 : extern "C" void SAL_CALL typelib_typedescription_registerCallback(
344 : void * pContext, typelib_typedescription_Callback pCallback )
345 : SAL_THROW_EXTERN_C()
346 : {
347 : // todo mt safe: guard is no solution, can not acquire while calling callback!
348 519 : TypeDescriptor_Init_Impl &rInit = Init::get();
349 : // OslGuard aGuard( rInit.getMutex() );
350 519 : if( !rInit.pCallbacks )
351 506 : rInit.pCallbacks = new CallbackSet_Impl;
352 519 : rInit.pCallbacks->push_back( CallbackEntry( pContext, pCallback ) );
353 519 : }
354 :
355 :
356 515 : extern "C" void SAL_CALL typelib_typedescription_revokeCallback(
357 : void * pContext, typelib_typedescription_Callback pCallback )
358 : SAL_THROW_EXTERN_C()
359 : {
360 515 : TypeDescriptor_Init_Impl &rInit = Init::get();
361 515 : if( rInit.pCallbacks )
362 : {
363 : // todo mt safe: guard is no solution, can not acquire while calling callback!
364 : // OslGuard aGuard( rInit.getMutex() );
365 515 : CallbackEntry aEntry( pContext, pCallback );
366 515 : CallbackSet_Impl::iterator iPos( rInit.pCallbacks->begin() );
367 1599 : while (!(iPos == rInit.pCallbacks->end()))
368 : {
369 569 : if (*iPos == aEntry)
370 : {
371 515 : rInit.pCallbacks->erase( iPos );
372 515 : iPos = rInit.pCallbacks->begin();
373 : }
374 : else
375 : {
376 54 : ++iPos;
377 : }
378 : }
379 : }
380 515 : }
381 :
382 14294 : static inline void typelib_typedescription_initTables(
383 : typelib_TypeDescription * pTD )
384 : {
385 14294 : typelib_InterfaceTypeDescription * pITD = reinterpret_cast<typelib_InterfaceTypeDescription *>(pTD);
386 :
387 14294 : sal_Bool * pReadWriteAttributes = static_cast<sal_Bool *>(alloca( pITD->nAllMembers ));
388 142555 : for ( sal_Int32 i = pITD->nAllMembers; i--; )
389 : {
390 113967 : pReadWriteAttributes[i] = sal_False;
391 113967 : if( typelib_TypeClass_INTERFACE_ATTRIBUTE == pITD->ppAllMembers[i]->eTypeClass )
392 : {
393 5676 : typelib_TypeDescription * pM = 0;
394 5676 : TYPELIB_DANGER_GET( &pM, pITD->ppAllMembers[i] );
395 : OSL_ASSERT( pM );
396 5676 : if (pM)
397 : {
398 5676 : pReadWriteAttributes[i] = !reinterpret_cast<typelib_InterfaceAttributeTypeDescription *>(pM)->bReadOnly;
399 5676 : 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 14294 : MutexGuard aGuard( Init::get().getMutex() );
412 14294 : if( !pTD->bComplete )
413 : {
414 : // create the index table from member to function table
415 14294 : pITD->pMapMemberIndexToFunctionIndex = new sal_Int32[ pITD->nAllMembers ];
416 14294 : sal_Int32 nAdditionalOffset = 0; // +1 for read/write attributes
417 : sal_Int32 i;
418 128261 : for( i = 0; i < pITD->nAllMembers; i++ )
419 : {
420 : // index to the get method of the attribute
421 113967 : pITD->pMapMemberIndexToFunctionIndex[i] = i + nAdditionalOffset;
422 : // extra offset if it is a read/write attribute?
423 113967 : if( pReadWriteAttributes[i] )
424 : {
425 : // a read/write attribute
426 3648 : nAdditionalOffset++;
427 : }
428 : }
429 :
430 : // create the index table from function to member table
431 14294 : pITD->pMapFunctionIndexToMemberIndex = new sal_Int32[ pITD->nAllMembers + nAdditionalOffset ];
432 14294 : nAdditionalOffset = 0; // +1 for read/write attributes
433 128261 : for( i = 0; i < pITD->nAllMembers; i++ )
434 : {
435 : // index to the get method of the attribute
436 113967 : pITD->pMapFunctionIndexToMemberIndex[i + nAdditionalOffset] = i;
437 : // extra offset if it is a read/write attribute?
438 113967 : if( pReadWriteAttributes[i] )
439 : {
440 : // a read/write attribute
441 3648 : pITD->pMapFunctionIndexToMemberIndex[i + ++nAdditionalOffset] = i;
442 : }
443 : }
444 : // must be the last action after all initialization is done
445 14294 : pITD->nMapFunctionIndexToMemberIndex = pITD->nAllMembers + nAdditionalOffset;
446 14294 : pTD->bComplete = sal_True;
447 14294 : }
448 14294 : }
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 1565120 : bool complete(typelib_TypeDescription ** ppTypeDescr, bool initTables) {
464 1565120 : 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 251912 : if (typelib_TypeClass_INTERFACE == (*ppTypeDescr)->eTypeClass &&
473 : reinterpret_cast<typelib_InterfaceTypeDescription *>(*ppTypeDescr)->ppAllMembers)
474 : {
475 251912 : if (initTables) {
476 14294 : typelib_typedescription_initTables( *ppTypeDescr );
477 : }
478 503824 : 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, reinterpret_cast<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( reinterpret_cast<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 1313208 : return true;
548 : }
549 :
550 : }
551 :
552 :
553 549757 : 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 549757 : if( *ppRet )
559 : {
560 7695 : typelib_typedescription_release( *ppRet );
561 7695 : *ppRet = 0;
562 : }
563 :
564 : OSL_ASSERT( typelib_TypeClass_TYPEDEF != eTypeClass );
565 :
566 : typelib_TypeDescription * pRet;
567 549757 : switch( eTypeClass )
568 : {
569 : case typelib_TypeClass_SEQUENCE:
570 : {
571 15351 : typelib_IndirectTypeDescription * pTmp = new typelib_IndirectTypeDescription();
572 15351 : pRet = &pTmp->aBase;
573 : #if OSL_DEBUG_LEVEL > 1
574 : osl_atomic_increment( &Init::get().nIndirectTypeDescriptionCount );
575 : #endif
576 15351 : pTmp->pType = 0;
577 : }
578 15351 : break;
579 :
580 : case typelib_TypeClass_STRUCT:
581 : {
582 : // FEATURE_EMPTYCLASS
583 : typelib_StructTypeDescription * pTmp;
584 21400 : pTmp = new typelib_StructTypeDescription();
585 21400 : pRet = &pTmp->aBase.aBase;
586 : #if OSL_DEBUG_LEVEL > 1
587 : osl_atomic_increment( &Init::get().nCompoundTypeDescriptionCount );
588 : #endif
589 21400 : pTmp->aBase.pBaseTypeDescription = 0;
590 21400 : pTmp->aBase.nMembers = 0;
591 21400 : pTmp->aBase.pMemberOffsets = 0;
592 21400 : pTmp->aBase.ppTypeRefs = 0;
593 21400 : pTmp->aBase.ppMemberNames = 0;
594 21400 : pTmp->pParameterizedTypes = 0;
595 : }
596 21400 : break;
597 :
598 : case typelib_TypeClass_EXCEPTION:
599 : {
600 : // FEATURE_EMPTYCLASS
601 : typelib_CompoundTypeDescription * pTmp;
602 18183 : pTmp = new typelib_CompoundTypeDescription();
603 18183 : pRet = &pTmp->aBase;
604 : #if OSL_DEBUG_LEVEL > 1
605 : osl_atomic_increment( &Init::get().nCompoundTypeDescriptionCount );
606 : #endif
607 18183 : pTmp->pBaseTypeDescription = 0;
608 18183 : pTmp->nMembers = 0;
609 18183 : pTmp->pMemberOffsets = 0;
610 18183 : pTmp->ppTypeRefs = 0;
611 18183 : pTmp->ppMemberNames = 0;
612 : }
613 18183 : break;
614 :
615 : case typelib_TypeClass_ENUM:
616 : {
617 10715 : typelib_EnumTypeDescription * pTmp = new typelib_EnumTypeDescription();
618 10715 : pRet = &pTmp->aBase;
619 : #if OSL_DEBUG_LEVEL > 1
620 : osl_atomic_increment( &Init::get().nEnumTypeDescriptionCount );
621 : #endif
622 10715 : pTmp->nDefaultEnumValue = 0;
623 10715 : pTmp->nEnumValues = 0;
624 10715 : pTmp->ppEnumNames = 0;
625 10715 : pTmp->pEnumValues = 0;
626 : }
627 10715 : break;
628 :
629 : case typelib_TypeClass_INTERFACE:
630 : {
631 224573 : typelib_InterfaceTypeDescription * pTmp = new typelib_InterfaceTypeDescription();
632 224573 : pRet = &pTmp->aBase;
633 : #if OSL_DEBUG_LEVEL > 1
634 : osl_atomic_increment( &Init::get().nInterfaceTypeDescriptionCount );
635 : #endif
636 224573 : pTmp->pBaseTypeDescription = 0;
637 224573 : pTmp->nMembers = 0;
638 224573 : pTmp->ppMembers = 0;
639 224573 : pTmp->nAllMembers = 0;
640 224573 : pTmp->ppAllMembers = 0;
641 224573 : pTmp->nMapFunctionIndexToMemberIndex = 0;
642 224573 : pTmp->pMapFunctionIndexToMemberIndex = 0;
643 224573 : pTmp->pMapMemberIndexToFunctionIndex= 0;
644 224573 : pTmp->nBaseTypes = 0;
645 224573 : pTmp->ppBaseTypes = 0;
646 : }
647 224573 : break;
648 :
649 : case typelib_TypeClass_INTERFACE_METHOD:
650 : {
651 243090 : typelib_InterfaceMethodTypeDescription * pTmp = new typelib_InterfaceMethodTypeDescription();
652 243090 : pRet = &pTmp->aBase.aBase;
653 : #if OSL_DEBUG_LEVEL > 1
654 : osl_atomic_increment( &Init::get().nInterfaceMethodTypeDescriptionCount );
655 : #endif
656 243090 : pTmp->aBase.pMemberName = 0;
657 243090 : pTmp->pReturnTypeRef = 0;
658 243090 : pTmp->nParams = 0;
659 243090 : pTmp->pParams = 0;
660 243090 : pTmp->nExceptions = 0;
661 243090 : pTmp->ppExceptions = 0;
662 243090 : pTmp->pInterface = 0;
663 243090 : pTmp->pBaseRef = 0;
664 243090 : pTmp->nIndex = 0;
665 : }
666 243090 : break;
667 :
668 : case typelib_TypeClass_INTERFACE_ATTRIBUTE:
669 : {
670 6148 : typelib_InterfaceAttributeTypeDescription * pTmp = new typelib_InterfaceAttributeTypeDescription();
671 6148 : pRet = &pTmp->aBase.aBase;
672 : #if OSL_DEBUG_LEVEL > 1
673 : osl_atomic_increment( &Init::get().nInterfaceAttributeTypeDescriptionCount );
674 : #endif
675 6148 : pTmp->aBase.pMemberName = 0;
676 6148 : pTmp->pAttributeTypeRef = 0;
677 6148 : pTmp->pInterface = 0;
678 6148 : pTmp->pBaseRef = 0;
679 6148 : pTmp->nIndex = 0;
680 6148 : pTmp->nGetExceptions = 0;
681 6148 : pTmp->ppGetExceptions = 0;
682 6148 : pTmp->nSetExceptions = 0;
683 6148 : pTmp->ppSetExceptions = 0;
684 : }
685 6148 : break;
686 :
687 : default:
688 : {
689 10297 : pRet = new typelib_TypeDescription();
690 : #if OSL_DEBUG_LEVEL > 1
691 : osl_atomic_increment( &Init::get().nTypeDescriptionCount );
692 : #endif
693 : }
694 : }
695 :
696 549757 : pRet->nRefCount = 1; // reference count is initially 1
697 549757 : pRet->nStaticRefCount = 0;
698 549757 : pRet->eTypeClass = eTypeClass;
699 549757 : pRet->pTypeName = 0;
700 549757 : pRet->pUniqueIdentifier = 0;
701 549757 : pRet->pReserved = 0;
702 549757 : rtl_uString_acquire( pRet->pTypeName = pTypeName );
703 549757 : pRet->pSelf = pRet;
704 549757 : pRet->bComplete = sal_True;
705 549757 : pRet->nSize = 0;
706 549757 : pRet->nAlignment = 0;
707 549757 : pRet->pWeakRef = 0;
708 549757 : pRet->bOnDemand = sal_False;
709 549757 : *ppRet = pRet;
710 549757 : }
711 :
712 :
713 : namespace {
714 :
715 47907 : 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 47907 : if (typelib_TypeClass_TYPEDEF == eTypeClass)
725 : {
726 : OSL_TRACE( "### unexpected typedef!" );
727 0 : typelib_typedescriptionreference_getDescription( ppRet, pType );
728 47907 : return;
729 : }
730 :
731 47907 : typelib_typedescription_newEmpty( ppRet, eTypeClass, pTypeName );
732 :
733 47907 : switch( eTypeClass )
734 : {
735 : case typelib_TypeClass_SEQUENCE:
736 : {
737 : OSL_ASSERT( nMembers == 0 );
738 10962 : typelib_typedescriptionreference_acquire( pType );
739 10962 : reinterpret_cast<typelib_IndirectTypeDescription *>(*ppRet)->pType = pType;
740 : }
741 10962 : break;
742 :
743 : case typelib_TypeClass_EXCEPTION:
744 : case typelib_TypeClass_STRUCT:
745 : {
746 : // FEATURE_EMPTYCLASS
747 28708 : typelib_CompoundTypeDescription * pTmp = reinterpret_cast<typelib_CompoundTypeDescription*>(*ppRet);
748 :
749 28708 : sal_Int32 nOffset = 0;
750 28708 : if( pType )
751 : {
752 : typelib_typedescriptionreference_getDescription(
753 16382 : reinterpret_cast<typelib_TypeDescription **>(&pTmp->pBaseTypeDescription), pType );
754 16382 : nOffset = pTmp->pBaseTypeDescription->aBase.nSize;
755 : OSL_ENSURE( newAlignedSize( 0, pTmp->pBaseTypeDescription->aBase.nSize, pTmp->pBaseTypeDescription->aBase.nAlignment ) == pTmp->pBaseTypeDescription->aBase.nSize, "### unexpected offset!" );
756 : }
757 28708 : if( nMembers )
758 : {
759 15283 : pTmp->nMembers = nMembers;
760 15283 : pTmp->pMemberOffsets = new sal_Int32[ nMembers ];
761 15283 : pTmp->ppTypeRefs = new typelib_TypeDescriptionReference *[ nMembers ];
762 15283 : pTmp->ppMemberNames = new rtl_uString *[ nMembers ];
763 : bool polymorphic = eTypeClass == typelib_TypeClass_STRUCT
764 15283 : && rtl::OUString::unacquired(&pTypeName).indexOf('<') >= 0;
765 : OSL_ASSERT(!polymorphic || pStructMembers != 0);
766 15283 : if (polymorphic) {
767 : reinterpret_cast< typelib_StructTypeDescription * >(pTmp)->
768 219 : pParameterizedTypes = new sal_Bool[nMembers];
769 : }
770 65276 : for( sal_Int32 i = 0 ; i < nMembers; i++ )
771 : {
772 : // read the type and member names
773 49993 : pTmp->ppTypeRefs[i] = 0;
774 49993 : if (pCompoundMembers != 0) {
775 : typelib_typedescriptionreference_new(
776 4201 : pTmp->ppTypeRefs +i, pCompoundMembers[i].eTypeClass,
777 8402 : pCompoundMembers[i].pTypeName );
778 : rtl_uString_acquire(
779 8402 : pTmp->ppMemberNames[i]
780 8402 : = pCompoundMembers[i].pMemberName );
781 : } else {
782 : typelib_typedescriptionreference_new(
783 : pTmp->ppTypeRefs +i,
784 45792 : pStructMembers[i].aBase.eTypeClass,
785 91584 : pStructMembers[i].aBase.pTypeName );
786 : rtl_uString_acquire(
787 91584 : pTmp->ppMemberNames[i]
788 91584 : = pStructMembers[i].aBase.pMemberName );
789 : }
790 : // write offset
791 : sal_Int32 size;
792 : sal_Int32 alignment;
793 49993 : if (pTmp->ppTypeRefs[i]->eTypeClass ==
794 : typelib_TypeClass_SEQUENCE)
795 : {
796 : // Take care of recursion like
797 : // struct S { sequence<S> x; };
798 1398 : size = sizeof(void *);
799 1398 : alignment = adjustAlignment(size);
800 : } else {
801 48595 : typelib_TypeDescription * pTD = 0;
802 48595 : TYPELIB_DANGER_GET( &pTD, pTmp->ppTypeRefs[i] );
803 : OSL_ENSURE( pTD->nSize, "### void member?" );
804 48595 : size = pTD->nSize;
805 48595 : alignment = pTD->nAlignment;
806 48595 : TYPELIB_DANGER_RELEASE( pTD );
807 : }
808 49993 : nOffset = newAlignedSize( nOffset, size, alignment );
809 49993 : pTmp->pMemberOffsets[i] = nOffset - size;
810 :
811 49993 : if (polymorphic) {
812 : reinterpret_cast< typelib_StructTypeDescription * >(
813 401 : pTmp)->pParameterizedTypes[i]
814 401 : = pStructMembers[i].bParameterizedType;
815 : }
816 : }
817 : }
818 : }
819 28708 : break;
820 :
821 : default:
822 8237 : break;
823 : }
824 :
825 47907 : if( !reallyWeak( eTypeClass ) )
826 47907 : (*ppRet)->pWeakRef = reinterpret_cast<typelib_TypeDescriptionReference *>(*ppRet);
827 47907 : if( eTypeClass != typelib_TypeClass_VOID )
828 : {
829 : // sizeof(void) not allowed
830 47394 : (*ppRet)->nSize = typelib_typedescription_getAlignedUnoSize( (*ppRet), 0, (*ppRet)->nAlignment );
831 47394 : (*ppRet)->nAlignment = adjustAlignment( (*ppRet)->nAlignment );
832 : }
833 : }
834 :
835 : }
836 :
837 35747 : extern "C" 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 35747 : ppRet, eTypeClass, pTypeName, pType, nMembers, pMembers, 0);
848 35747 : }
849 :
850 12160 : extern "C" 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 12160 : pMembers);
861 12160 : }
862 :
863 :
864 4903 : extern "C" 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 4903 : typelib_typedescription_newEmpty( ppRet, typelib_TypeClass_ENUM, pTypeName );
874 4903 : typelib_EnumTypeDescription * pEnum = reinterpret_cast<typelib_EnumTypeDescription *>(*ppRet);
875 :
876 4903 : pEnum->nDefaultEnumValue = nDefaultValue;
877 4903 : pEnum->nEnumValues = nEnumValues;
878 4903 : pEnum->ppEnumNames = new rtl_uString * [ nEnumValues ];
879 32724 : for ( sal_Int32 nPos = nEnumValues; nPos--; )
880 : {
881 22918 : rtl_uString_acquire( pEnum->ppEnumNames[nPos] = ppEnumNames[nPos] );
882 : }
883 4903 : pEnum->pEnumValues = new sal_Int32[ nEnumValues ];
884 4903 : ::memcpy( pEnum->pEnumValues, pEnumValues, nEnumValues * sizeof(sal_Int32) );
885 :
886 4903 : (*ppRet)->pWeakRef = reinterpret_cast<typelib_TypeDescriptionReference *>(*ppRet);
887 : // sizeof(void) not allowed
888 4903 : (*ppRet)->nSize = typelib_typedescription_getAlignedUnoSize( (*ppRet), 0, (*ppRet)->nAlignment );
889 4903 : (*ppRet)->nAlignment = adjustAlignment( (*ppRet)->nAlignment );
890 4903 : }
891 :
892 :
893 647 : extern "C" 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[callee_ptr_arith]
905 : typelib_typedescription_newMIInterface(
906 : ppRet, pTypeName, 0, 0, 0, 0, 0, pBaseInterface == 0 ? 0 : 1,
907 647 : &pBaseInterface, nMembers, ppMembers);
908 647 : }
909 :
910 : namespace {
911 :
912 160641 : class BaseList {
913 : public:
914 : struct Entry {
915 : sal_Int32 memberOffset;
916 : sal_Int32 directBaseIndex;
917 : sal_Int32 directBaseMemberOffset;
918 : typelib_InterfaceTypeDescription const * base;
919 : };
920 :
921 : typedef std::vector< Entry > List;
922 :
923 : explicit BaseList(typelib_InterfaceTypeDescription const * desc);
924 :
925 160641 : List const & getList() const { return list; }
926 :
927 318583 : sal_Int32 getBaseMembers() const { return members; }
928 :
929 : private:
930 : typedef std::set< rtl::OUString > Set;
931 :
932 : void calculate(
933 : sal_Int32 directBaseIndex, Set & directBaseSet,
934 : sal_Int32 * directBaseMembers,
935 : typelib_InterfaceTypeDescription const * desc);
936 :
937 : Set set;
938 : List list;
939 : sal_Int32 members;
940 : };
941 :
942 160641 : BaseList::BaseList(typelib_InterfaceTypeDescription const * desc) {
943 160641 : members = 0;
944 289899 : for (sal_Int32 i = 0; i < desc->nBaseTypes; ++i) {
945 129258 : Set directBaseSet;
946 129258 : sal_Int32 directBaseMembers = 0;
947 129258 : calculate(i, directBaseSet, &directBaseMembers, desc->ppBaseTypes[i]);
948 129258 : }
949 160641 : }
950 :
951 186583 : void BaseList::calculate(
952 : sal_Int32 directBaseIndex, Set & directBaseSet,
953 : sal_Int32 * directBaseMembers,
954 : typelib_InterfaceTypeDescription const * desc)
955 : {
956 243908 : for (sal_Int32 i = 0; i < desc->nBaseTypes; ++i) {
957 : calculate(
958 : directBaseIndex, directBaseSet, directBaseMembers,
959 57325 : desc->ppBaseTypes[i]);
960 : }
961 186583 : if (set.insert(desc->aBase.pTypeName).second) {
962 : Entry e;
963 178481 : e.memberOffset = members;
964 178481 : e.directBaseIndex = directBaseIndex;
965 178481 : e.directBaseMemberOffset = *directBaseMembers;
966 178481 : e.base = desc;
967 178481 : list.push_back(e);
968 : OSL_ASSERT(desc->ppAllMembers != 0);
969 178481 : members += desc->nMembers;
970 : }
971 186583 : if (directBaseSet.insert(desc->aBase.pTypeName).second) {
972 : OSL_ASSERT(desc->ppAllMembers != 0);
973 185808 : *directBaseMembers += desc->nMembers;
974 : }
975 186583 : }
976 :
977 : }
978 :
979 160641 : extern "C" void SAL_CALL typelib_typedescription_newMIInterface(
980 : typelib_InterfaceTypeDescription ** ppRet,
981 : rtl_uString * pTypeName,
982 : SAL_UNUSED_PARAMETER sal_uInt32, SAL_UNUSED_PARAMETER sal_uInt16,
983 : SAL_UNUSED_PARAMETER sal_uInt16, SAL_UNUSED_PARAMETER sal_uInt32,
984 : SAL_UNUSED_PARAMETER sal_uInt32,
985 : sal_Int32 nBaseInterfaces,
986 : typelib_TypeDescriptionReference ** ppBaseInterfaces,
987 : sal_Int32 nMembers,
988 : typelib_TypeDescriptionReference ** ppMembers )
989 : SAL_THROW_EXTERN_C()
990 : {
991 160641 : if (*ppRet != 0) {
992 0 : typelib_typedescription_release(&(*ppRet)->aBase);
993 0 : *ppRet = 0;
994 : }
995 :
996 160641 : typelib_InterfaceTypeDescription * pITD = 0;
997 : typelib_typedescription_newEmpty(
998 160641 : reinterpret_cast<typelib_TypeDescription **>(&pITD), typelib_TypeClass_INTERFACE, pTypeName );
999 :
1000 160641 : pITD->nBaseTypes = nBaseInterfaces;
1001 160641 : pITD->ppBaseTypes = new typelib_InterfaceTypeDescription *[nBaseInterfaces];
1002 289899 : for (sal_Int32 i = 0; i < nBaseInterfaces; ++i) {
1003 129258 : pITD->ppBaseTypes[i] = 0;
1004 : typelib_typedescriptionreference_getDescription(
1005 : reinterpret_cast< typelib_TypeDescription ** >(
1006 : &pITD->ppBaseTypes[i]),
1007 129258 : ppBaseInterfaces[i]);
1008 258516 : if (pITD->ppBaseTypes[i] == 0
1009 258516 : || !complete(
1010 : reinterpret_cast< typelib_TypeDescription ** >(
1011 : &pITD->ppBaseTypes[i]),
1012 129258 : false))
1013 : {
1014 : OSL_ASSERT(false);
1015 0 : return;
1016 : }
1017 : OSL_ASSERT(pITD->ppBaseTypes[i] != 0);
1018 : }
1019 160641 : if (nBaseInterfaces > 0) {
1020 122229 : pITD->pBaseTypeDescription = pITD->ppBaseTypes[0];
1021 : }
1022 : // set the
1023 160641 : pITD->aUik.m_Data1 = 0;
1024 160641 : pITD->aUik.m_Data2 = 0;
1025 160641 : pITD->aUik.m_Data3 = 0;
1026 160641 : pITD->aUik.m_Data4 = 0;
1027 160641 : pITD->aUik.m_Data5 = 0;
1028 :
1029 160641 : BaseList aBaseList(pITD);
1030 160641 : pITD->nAllMembers = nMembers + aBaseList.getBaseMembers();
1031 160641 : pITD->nMembers = nMembers;
1032 :
1033 160641 : if( pITD->nAllMembers )
1034 : {
1035 : // at minimum one member exist, allocate the memory
1036 160641 : pITD->ppAllMembers = new typelib_TypeDescriptionReference *[ pITD->nAllMembers ];
1037 160641 : sal_Int32 n = 0;
1038 :
1039 160641 : BaseList::List const & rList = aBaseList.getList();
1040 339122 : for (BaseList::List::const_iterator i(rList.begin()); i != rList.end();
1041 : ++i)
1042 : {
1043 178481 : typelib_InterfaceTypeDescription const * pBase = i->base;
1044 : typelib_InterfaceTypeDescription const * pDirectBase
1045 178481 : = pITD->ppBaseTypes[i->directBaseIndex];
1046 : OSL_ASSERT(pBase->ppAllMembers != 0);
1047 711819 : for (sal_Int32 j = 0; j < pBase->nMembers; ++j) {
1048 : typelib_TypeDescriptionReference const * pDirectBaseMember
1049 533338 : = pDirectBase->ppAllMembers[i->directBaseMemberOffset + j];
1050 533338 : rtl::OUStringBuffer aBuf(pDirectBaseMember->pTypeName);
1051 533338 : aBuf.append(":@");
1052 533338 : aBuf.append(i->directBaseIndex);
1053 533338 : aBuf.append(',');
1054 533338 : aBuf.append(i->memberOffset + j);
1055 533338 : aBuf.append(':');
1056 533338 : aBuf.append(pITD->aBase.pTypeName);
1057 1066676 : rtl::OUString aName(aBuf.makeStringAndClear());
1058 533338 : typelib_TypeDescriptionReference * pDerivedMember = 0;
1059 : typelib_typedescriptionreference_new(
1060 : &pDerivedMember, pDirectBaseMember->eTypeClass,
1061 533338 : aName.pData);
1062 533338 : pITD->ppAllMembers[n++] = pDerivedMember;
1063 533338 : }
1064 : }
1065 :
1066 160641 : if( nMembers )
1067 : {
1068 157942 : pITD->ppMembers = pITD->ppAllMembers + aBaseList.getBaseMembers();
1069 : }
1070 :
1071 : // add own members
1072 645393 : for( sal_Int32 i = 0; i < nMembers; i++ )
1073 : {
1074 484752 : typelib_typedescriptionreference_acquire( ppMembers[i] );
1075 484752 : pITD->ppAllMembers[n++] = ppMembers[i];
1076 : }
1077 : }
1078 :
1079 160641 : typelib_TypeDescription * pTmp = &pITD->aBase;
1080 160641 : if( !reallyWeak( typelib_TypeClass_INTERFACE ) )
1081 160641 : pTmp->pWeakRef = reinterpret_cast<typelib_TypeDescriptionReference *>(pTmp);
1082 160641 : pTmp->nSize = typelib_typedescription_getAlignedUnoSize( pTmp, 0, pTmp->nAlignment );
1083 160641 : pTmp->nAlignment = adjustAlignment( pTmp->nAlignment );
1084 160641 : pTmp->bComplete = sal_False;
1085 :
1086 160641 : *ppRet = pITD;
1087 : }
1088 :
1089 :
1090 :
1091 : namespace {
1092 :
1093 213932 : typelib_TypeDescriptionReference ** copyExceptions(
1094 : sal_Int32 count, rtl_uString ** typeNames)
1095 : {
1096 : OSL_ASSERT(count >= 0);
1097 213932 : if (count == 0) {
1098 25061 : return 0;
1099 : }
1100 : typelib_TypeDescriptionReference ** p
1101 188871 : = new typelib_TypeDescriptionReference *[count];
1102 509546 : for (sal_Int32 i = 0; i < count; ++i) {
1103 320675 : p[i] = 0;
1104 : typelib_typedescriptionreference_new(
1105 320675 : p + i, typelib_TypeClass_EXCEPTION, typeNames[i]);
1106 : }
1107 188871 : return p;
1108 : }
1109 :
1110 : }
1111 :
1112 204380 : extern "C" void SAL_CALL typelib_typedescription_newInterfaceMethod(
1113 : typelib_InterfaceMethodTypeDescription ** ppRet,
1114 : sal_Int32 nAbsolutePosition,
1115 : sal_Bool bOneWay,
1116 : rtl_uString * pTypeName,
1117 : typelib_TypeClass eReturnTypeClass,
1118 : rtl_uString * pReturnTypeName,
1119 : sal_Int32 nParams,
1120 : typelib_Parameter_Init * pParams,
1121 : sal_Int32 nExceptions,
1122 : rtl_uString ** ppExceptionNames )
1123 : SAL_THROW_EXTERN_C()
1124 : {
1125 204380 : if (*ppRet != 0) {
1126 112899 : typelib_typedescription_release(&(*ppRet)->aBase.aBase);
1127 112899 : *ppRet = 0;
1128 : }
1129 : sal_Int32 nOffset = rtl_ustr_lastIndexOfChar_WithLength(
1130 204380 : pTypeName->buffer, pTypeName->length, ':');
1131 204380 : if (nOffset <= 0 || pTypeName->buffer[nOffset - 1] != ':') {
1132 : OSL_FAIL("Bad interface method type name");
1133 0 : return;
1134 : }
1135 204380 : rtl::OUString aInterfaceTypeName(pTypeName->buffer, nOffset - 1);
1136 204380 : typelib_InterfaceTypeDescription * pInterface = 0;
1137 : typelib_typedescription_getByName(
1138 : reinterpret_cast< typelib_TypeDescription ** >(&pInterface),
1139 204380 : aInterfaceTypeName.pData);
1140 408760 : if (pInterface == 0
1141 204380 : || pInterface->aBase.eTypeClass != typelib_TypeClass_INTERFACE
1142 408760 : || !complete(
1143 204380 : reinterpret_cast< typelib_TypeDescription ** >(&pInterface), false))
1144 : {
1145 : OSL_FAIL("No interface corresponding to interface method");
1146 0 : return;
1147 : }
1148 :
1149 : typelib_typedescription_newEmpty(
1150 204380 : reinterpret_cast<typelib_TypeDescription **>(ppRet), typelib_TypeClass_INTERFACE_METHOD, pTypeName );
1151 204380 : typelib_TypeDescription * pTmp = reinterpret_cast<typelib_TypeDescription *>(*ppRet);
1152 :
1153 : rtl_uString_newFromStr_WithLength( &(*ppRet)->aBase.pMemberName,
1154 204380 : pTypeName->buffer + nOffset +1,
1155 408760 : pTypeName->length - nOffset -1 );
1156 204380 : (*ppRet)->aBase.nPosition = nAbsolutePosition;
1157 204380 : (*ppRet)->bOneWay = bOneWay;
1158 204380 : typelib_typedescriptionreference_new( &(*ppRet)->pReturnTypeRef, eReturnTypeClass, pReturnTypeName );
1159 204380 : (*ppRet)->nParams = nParams;
1160 204380 : if( nParams )
1161 : {
1162 117821 : (*ppRet)->pParams = new typelib_MethodParameter[ nParams ];
1163 :
1164 287664 : for( sal_Int32 i = 0; i < nParams; i++ )
1165 : {
1166 : // get the name of the parameter
1167 169843 : (*ppRet)->pParams[ i ].pName = 0;
1168 169843 : rtl_uString_acquire( (*ppRet)->pParams[ i ].pName = pParams[i].pParamName );
1169 169843 : (*ppRet)->pParams[ i ].pTypeRef = 0;
1170 : // get the type name of the parameter and create the weak reference
1171 : typelib_typedescriptionreference_new(
1172 169843 : &(*ppRet)->pParams[ i ].pTypeRef, pParams[i].eTypeClass, pParams[i].pTypeName );
1173 169843 : (*ppRet)->pParams[ i ].bIn = pParams[i].bIn;
1174 169843 : (*ppRet)->pParams[ i ].bOut = pParams[i].bOut;
1175 : }
1176 : }
1177 204380 : (*ppRet)->nExceptions = nExceptions;
1178 204380 : (*ppRet)->ppExceptions = copyExceptions(nExceptions, ppExceptionNames);
1179 204380 : (*ppRet)->pInterface = pInterface;
1180 204380 : (*ppRet)->pBaseRef = 0;
1181 : OSL_ASSERT(
1182 : (nAbsolutePosition >= pInterface->nAllMembers - pInterface->nMembers)
1183 : && nAbsolutePosition < pInterface->nAllMembers);
1184 : (*ppRet)->nIndex = nAbsolutePosition
1185 204380 : - (pInterface->nAllMembers - pInterface->nMembers);
1186 204380 : if( !reallyWeak( typelib_TypeClass_INTERFACE_METHOD ) )
1187 0 : pTmp->pWeakRef = reinterpret_cast<typelib_TypeDescriptionReference *>(pTmp);
1188 : }
1189 :
1190 :
1191 :
1192 0 : extern "C" void SAL_CALL typelib_typedescription_newInterfaceAttribute(
1193 : typelib_InterfaceAttributeTypeDescription ** ppRet,
1194 : sal_Int32 nAbsolutePosition,
1195 : rtl_uString * pTypeName,
1196 : typelib_TypeClass eAttributeTypeClass,
1197 : rtl_uString * pAttributeTypeName,
1198 : sal_Bool bReadOnly )
1199 : SAL_THROW_EXTERN_C()
1200 : {
1201 : typelib_typedescription_newExtendedInterfaceAttribute(
1202 : ppRet, nAbsolutePosition, pTypeName, eAttributeTypeClass,
1203 0 : pAttributeTypeName, bReadOnly, 0, 0, 0, 0);
1204 0 : }
1205 :
1206 :
1207 4776 : extern "C" void SAL_CALL typelib_typedescription_newExtendedInterfaceAttribute(
1208 : typelib_InterfaceAttributeTypeDescription ** ppRet,
1209 : sal_Int32 nAbsolutePosition,
1210 : rtl_uString * pTypeName,
1211 : typelib_TypeClass eAttributeTypeClass,
1212 : rtl_uString * pAttributeTypeName,
1213 : sal_Bool bReadOnly,
1214 : sal_Int32 nGetExceptions, rtl_uString ** ppGetExceptionNames,
1215 : sal_Int32 nSetExceptions, rtl_uString ** ppSetExceptionNames )
1216 : SAL_THROW_EXTERN_C()
1217 : {
1218 4776 : if (*ppRet != 0) {
1219 0 : typelib_typedescription_release(&(*ppRet)->aBase.aBase);
1220 0 : *ppRet = 0;
1221 : }
1222 : sal_Int32 nOffset = rtl_ustr_lastIndexOfChar_WithLength(
1223 4776 : pTypeName->buffer, pTypeName->length, ':');
1224 4776 : if (nOffset <= 0 || pTypeName->buffer[nOffset - 1] != ':') {
1225 : OSL_FAIL("Bad interface attribute type name");
1226 0 : return;
1227 : }
1228 4776 : rtl::OUString aInterfaceTypeName(pTypeName->buffer, nOffset - 1);
1229 4776 : typelib_InterfaceTypeDescription * pInterface = 0;
1230 : typelib_typedescription_getByName(
1231 : reinterpret_cast< typelib_TypeDescription ** >(&pInterface),
1232 4776 : aInterfaceTypeName.pData);
1233 9552 : if (pInterface == 0
1234 4776 : || pInterface->aBase.eTypeClass != typelib_TypeClass_INTERFACE
1235 9552 : || !complete(
1236 4776 : reinterpret_cast< typelib_TypeDescription ** >(&pInterface), false))
1237 : {
1238 : OSL_FAIL("No interface corresponding to interface attribute");
1239 0 : return;
1240 : }
1241 :
1242 : typelib_typedescription_newEmpty(
1243 4776 : reinterpret_cast<typelib_TypeDescription **>(ppRet), typelib_TypeClass_INTERFACE_ATTRIBUTE, pTypeName );
1244 4776 : typelib_TypeDescription * pTmp = reinterpret_cast<typelib_TypeDescription *>(*ppRet);
1245 :
1246 : rtl_uString_newFromStr_WithLength( &(*ppRet)->aBase.pMemberName,
1247 4776 : pTypeName->buffer + nOffset +1,
1248 9552 : pTypeName->length - nOffset -1 );
1249 4776 : (*ppRet)->aBase.nPosition = nAbsolutePosition;
1250 4776 : typelib_typedescriptionreference_new( &(*ppRet)->pAttributeTypeRef, eAttributeTypeClass, pAttributeTypeName );
1251 4776 : (*ppRet)->bReadOnly = bReadOnly;
1252 4776 : (*ppRet)->pInterface = pInterface;
1253 4776 : (*ppRet)->pBaseRef = 0;
1254 : OSL_ASSERT(
1255 : (nAbsolutePosition >= pInterface->nAllMembers - pInterface->nMembers)
1256 : && nAbsolutePosition < pInterface->nAllMembers);
1257 : (*ppRet)->nIndex = nAbsolutePosition
1258 4776 : - (pInterface->nAllMembers - pInterface->nMembers);
1259 4776 : (*ppRet)->nGetExceptions = nGetExceptions;
1260 : (*ppRet)->ppGetExceptions = copyExceptions(
1261 4776 : nGetExceptions, ppGetExceptionNames);
1262 4776 : (*ppRet)->nSetExceptions = nSetExceptions;
1263 : (*ppRet)->ppSetExceptions = copyExceptions(
1264 4776 : nSetExceptions, ppSetExceptionNames);
1265 4776 : if( !reallyWeak( typelib_TypeClass_INTERFACE_ATTRIBUTE ) )
1266 0 : pTmp->pWeakRef = reinterpret_cast<typelib_TypeDescriptionReference *>(pTmp);
1267 : }
1268 :
1269 :
1270 3957243 : extern "C" void SAL_CALL typelib_typedescription_acquire(
1271 : typelib_TypeDescription * pTypeDescription )
1272 : SAL_THROW_EXTERN_C()
1273 : {
1274 3957243 : osl_atomic_increment( &pTypeDescription->nRefCount );
1275 3957243 : }
1276 :
1277 :
1278 :
1279 : namespace {
1280 :
1281 236068 : void deleteExceptions(
1282 : sal_Int32 count, typelib_TypeDescriptionReference ** exceptions)
1283 : {
1284 561959 : for (sal_Int32 i = 0; i < count; ++i) {
1285 325891 : typelib_typedescriptionreference_release(exceptions[i]);
1286 : }
1287 236068 : delete[] exceptions;
1288 236068 : }
1289 :
1290 : }
1291 :
1292 : // frees anything except typelib_TypeDescription base!
1293 496266 : static inline void typelib_typedescription_destructExtendedMembers(
1294 : typelib_TypeDescription * pTD )
1295 : {
1296 : OSL_ASSERT( typelib_TypeClass_TYPEDEF != pTD->eTypeClass );
1297 :
1298 496266 : switch( pTD->eTypeClass )
1299 : {
1300 : case typelib_TypeClass_SEQUENCE:
1301 12386 : if( reinterpret_cast<typelib_IndirectTypeDescription*>(pTD)->pType )
1302 8007 : typelib_typedescriptionreference_release( reinterpret_cast<typelib_IndirectTypeDescription*>(pTD)->pType );
1303 12386 : break;
1304 : case typelib_TypeClass_STRUCT:
1305 : delete[] reinterpret_cast< typelib_StructTypeDescription * >(pTD)->
1306 20054 : pParameterizedTypes;
1307 : // Fall-through intentional
1308 : case typelib_TypeClass_EXCEPTION:
1309 : {
1310 32670 : typelib_CompoundTypeDescription * pCTD = reinterpret_cast<typelib_CompoundTypeDescription*>(pTD);
1311 32670 : if( pCTD->pBaseTypeDescription )
1312 11271 : typelib_typedescription_release( &pCTD->pBaseTypeDescription->aBase );
1313 : sal_Int32 i;
1314 75681 : for( i = 0; i < pCTD->nMembers; i++ )
1315 : {
1316 43011 : typelib_typedescriptionreference_release( pCTD->ppTypeRefs[i] );
1317 : }
1318 32670 : if (pCTD->ppMemberNames)
1319 : {
1320 55421 : for ( i = 0; i < pCTD->nMembers; i++ )
1321 : {
1322 43010 : rtl_uString_release( pCTD->ppMemberNames[i] );
1323 : }
1324 12411 : delete [] pCTD->ppMemberNames;
1325 : }
1326 32670 : delete [] pCTD->ppTypeRefs;
1327 32670 : delete [] pCTD->pMemberOffsets;
1328 : }
1329 32670 : break;
1330 : case typelib_TypeClass_INTERFACE:
1331 : {
1332 203047 : typelib_InterfaceTypeDescription * pITD = reinterpret_cast<typelib_InterfaceTypeDescription*>(pTD);
1333 1070777 : for( sal_Int32 i = 0; i < pITD->nAllMembers; i++ )
1334 : {
1335 867730 : typelib_typedescriptionreference_release( pITD->ppAllMembers[i] );
1336 : }
1337 203047 : delete [] pITD->ppAllMembers;
1338 203047 : delete [] pITD->pMapMemberIndexToFunctionIndex;
1339 203047 : delete [] pITD->pMapFunctionIndexToMemberIndex;
1340 311090 : for (sal_Int32 i = 0; i < pITD->nBaseTypes; ++i) {
1341 : typelib_typedescription_release(
1342 : reinterpret_cast< typelib_TypeDescription * >(
1343 108043 : pITD->ppBaseTypes[i]));
1344 : }
1345 203047 : delete[] pITD->ppBaseTypes;
1346 203047 : break;
1347 : }
1348 : case typelib_TypeClass_INTERFACE_METHOD:
1349 : {
1350 226024 : typelib_InterfaceMethodTypeDescription * pIMTD = reinterpret_cast<typelib_InterfaceMethodTypeDescription*>(pTD);
1351 226024 : if( pIMTD->pReturnTypeRef )
1352 226024 : typelib_typedescriptionreference_release( pIMTD->pReturnTypeRef );
1353 399337 : for( sal_Int32 i = 0; i < pIMTD->nParams; i++ )
1354 : {
1355 173313 : rtl_uString_release( pIMTD->pParams[ i ].pName );
1356 173313 : typelib_typedescriptionreference_release( pIMTD->pParams[ i ].pTypeRef );
1357 : }
1358 226024 : delete [] pIMTD->pParams;
1359 226024 : deleteExceptions(pIMTD->nExceptions, pIMTD->ppExceptions);
1360 226024 : rtl_uString_release( pIMTD->aBase.pMemberName );
1361 226024 : typelib_typedescription_release(&pIMTD->pInterface->aBase);
1362 226024 : if (pIMTD->pBaseRef != 0) {
1363 28981 : typelib_typedescriptionreference_release(pIMTD->pBaseRef);
1364 : }
1365 : }
1366 226024 : break;
1367 : case typelib_TypeClass_INTERFACE_ATTRIBUTE:
1368 : {
1369 5022 : typelib_InterfaceAttributeTypeDescription * pIATD = reinterpret_cast<typelib_InterfaceAttributeTypeDescription*>(pTD);
1370 5022 : deleteExceptions(pIATD->nGetExceptions, pIATD->ppGetExceptions);
1371 5022 : deleteExceptions(pIATD->nSetExceptions, pIATD->ppSetExceptions);
1372 5022 : if( pIATD->pAttributeTypeRef )
1373 5022 : typelib_typedescriptionreference_release( pIATD->pAttributeTypeRef );
1374 5022 : if( pIATD->aBase.pMemberName )
1375 5022 : rtl_uString_release( pIATD->aBase.pMemberName );
1376 5022 : typelib_typedescription_release(&pIATD->pInterface->aBase);
1377 5022 : if (pIATD->pBaseRef != 0) {
1378 1007 : typelib_typedescriptionreference_release(pIATD->pBaseRef);
1379 : }
1380 : }
1381 5022 : break;
1382 : case typelib_TypeClass_ENUM:
1383 : {
1384 10185 : typelib_EnumTypeDescription * pEnum = reinterpret_cast<typelib_EnumTypeDescription *>(pTD);
1385 41690 : for ( sal_Int32 nPos = pEnum->nEnumValues; nPos--; )
1386 : {
1387 21320 : rtl_uString_release( pEnum->ppEnumNames[nPos] );
1388 : }
1389 10185 : delete [] pEnum->ppEnumNames;
1390 10185 : delete [] pEnum->pEnumValues;
1391 : }
1392 10185 : break;
1393 : default:
1394 6932 : break;
1395 : }
1396 496266 : }
1397 :
1398 :
1399 4033577994 : extern "C" void SAL_CALL typelib_typedescription_release(
1400 : typelib_TypeDescription * pTD )
1401 : SAL_THROW_EXTERN_C()
1402 : {
1403 4033577994 : sal_Int32 ref = osl_atomic_decrement( &pTD->nRefCount );
1404 : OSL_ASSERT(ref >= 0);
1405 4033577994 : if (0 == ref)
1406 : {
1407 496262 : TypeDescriptor_Init_Impl &rInit = Init::get();
1408 496262 : if( reallyWeak( pTD->eTypeClass ) )
1409 : {
1410 231046 : if( pTD->pWeakRef )
1411 : {
1412 : {
1413 93943 : MutexGuard aGuard( rInit.getMutex() );
1414 : // remove this description from the weak reference
1415 93943 : pTD->pWeakRef->pType = 0;
1416 : }
1417 93943 : typelib_typedescriptionreference_release( pTD->pWeakRef );
1418 : }
1419 : }
1420 : else
1421 : {
1422 : // this description is a reference too, so remove it from the hash table
1423 265216 : if( rInit.pWeakMap )
1424 : {
1425 265216 : MutexGuard aGuard( rInit.getMutex() );
1426 265216 : WeakMap_Impl::iterator aIt = rInit.pWeakMap->find( pTD->pTypeName->buffer );
1427 265216 : if( aIt != rInit.pWeakMap->end() && static_cast<void *>((*aIt).second) == static_cast<void *>(pTD) )
1428 : {
1429 : // remove only if it contains the same object
1430 94534 : rInit.pWeakMap->erase( aIt );
1431 265216 : }
1432 : }
1433 : }
1434 :
1435 496262 : typelib_typedescription_destructExtendedMembers( pTD );
1436 496262 : rtl_uString_release( pTD->pTypeName );
1437 :
1438 : #if OSL_DEBUG_LEVEL > 1
1439 : switch( pTD->eTypeClass )
1440 : {
1441 : case typelib_TypeClass_SEQUENCE:
1442 : osl_atomic_decrement( &rInit.nIndirectTypeDescriptionCount );
1443 : break;
1444 : case typelib_TypeClass_STRUCT:
1445 : case typelib_TypeClass_EXCEPTION:
1446 : osl_atomic_decrement( &rInit.nCompoundTypeDescriptionCount );
1447 : break;
1448 : case typelib_TypeClass_INTERFACE:
1449 : osl_atomic_decrement( &rInit.nInterfaceTypeDescriptionCount );
1450 : break;
1451 : case typelib_TypeClass_INTERFACE_METHOD:
1452 : osl_atomic_decrement( &rInit.nInterfaceMethodTypeDescriptionCount );
1453 : break;
1454 : case typelib_TypeClass_INTERFACE_ATTRIBUTE:
1455 : osl_atomic_decrement( &rInit.nInterfaceAttributeTypeDescriptionCount );
1456 : break;
1457 : case typelib_TypeClass_ENUM:
1458 : osl_atomic_decrement( &rInit.nEnumTypeDescriptionCount );
1459 : break;
1460 : default:
1461 : osl_atomic_decrement( &rInit.nTypeDescriptionCount );
1462 : }
1463 : #endif
1464 :
1465 496262 : delete pTD;
1466 : }
1467 4033577994 : }
1468 :
1469 :
1470 462706 : extern "C" void SAL_CALL typelib_typedescription_register(
1471 : typelib_TypeDescription ** ppNewDescription )
1472 : SAL_THROW_EXTERN_C()
1473 : {
1474 : // connect the description with the weak reference
1475 462706 : TypeDescriptor_Init_Impl &rInit = Init::get();
1476 462706 : ClearableMutexGuard aGuard( rInit.getMutex() );
1477 :
1478 462706 : typelib_TypeDescriptionReference * pTDR = 0;
1479 462706 : typelib_typedescriptionreference_getByName( &pTDR, (*ppNewDescription)->pTypeName );
1480 :
1481 : OSL_ASSERT( (*ppNewDescription)->pWeakRef || reallyWeak( (*ppNewDescription)->eTypeClass ) );
1482 462706 : if( pTDR )
1483 : {
1484 : OSL_ASSERT( (*ppNewDescription)->eTypeClass == pTDR->eTypeClass );
1485 419920 : if( pTDR->pType )
1486 : {
1487 307785 : if (reallyWeak( pTDR->eTypeClass ))
1488 : {
1489 : // pRef->pType->pWeakRef == 0 means that the description is empty
1490 137103 : if (pTDR->pType->pWeakRef)
1491 : {
1492 137103 : if (osl_atomic_increment( &pTDR->pType->nRefCount ) > 1)
1493 : {
1494 : // The refence is incremented. The object cannot be destroyed.
1495 : // Release the guard at the earliest point.
1496 137103 : aGuard.clear();
1497 137103 : ::typelib_typedescription_release( *ppNewDescription );
1498 137103 : *ppNewDescription = pTDR->pType;
1499 137103 : ::typelib_typedescriptionreference_release( pTDR );
1500 137103 : return;
1501 : }
1502 : else
1503 : {
1504 : // destruction of this type in progress (another thread!)
1505 0 : (void)osl_atomic_decrement( &pTDR->pType->nRefCount );
1506 : }
1507 : }
1508 : // take new descr
1509 0 : pTDR->pType = *ppNewDescription;
1510 : OSL_ASSERT( ! (*ppNewDescription)->pWeakRef );
1511 0 : (*ppNewDescription)->pWeakRef = pTDR;
1512 0 : return;
1513 : }
1514 : // !reallyWeak
1515 :
1516 341364 : if ((static_cast<void *>(pTDR) != static_cast<void *>(*ppNewDescription)) && // if different
1517 294135 : (!pTDR->pType->pWeakRef || // uninit: ref data only set
1518 : // new one is complete:
1519 309331 : (!pTDR->pType->bComplete && (*ppNewDescription)->bComplete) ||
1520 : // new one may be partly initialized interface (except of tables):
1521 226606 : (typelib_TypeClass_INTERFACE == pTDR->pType->eTypeClass &&
1522 103157 : !reinterpret_cast<typelib_InterfaceTypeDescription *>(pTDR->pType)->ppAllMembers &&
1523 : (*reinterpret_cast<typelib_InterfaceTypeDescription **>(ppNewDescription))->ppAllMembers)))
1524 : {
1525 : // uninitialized or incomplete
1526 :
1527 47233 : if (pTDR->pType->pWeakRef) // if init
1528 : {
1529 4 : typelib_typedescription_destructExtendedMembers( pTDR->pType );
1530 : }
1531 :
1532 : // pTDR->pType->pWeakRef == 0 means that the description is empty
1533 : // description is not weak and the not the same
1534 47233 : sal_Int32 nSize = getDescriptionSize( (*ppNewDescription)->eTypeClass );
1535 :
1536 : // copy all specific data for the descriptions
1537 : memcpy(
1538 47233 : pTDR->pType +1,
1539 : *ppNewDescription +1,
1540 94466 : nSize - sizeof(typelib_TypeDescription) );
1541 :
1542 47233 : pTDR->pType->bComplete = (*ppNewDescription)->bComplete;
1543 47233 : pTDR->pType->nSize = (*ppNewDescription)->nSize;
1544 47233 : pTDR->pType->nAlignment = (*ppNewDescription)->nAlignment;
1545 :
1546 : memset(
1547 47233 : *ppNewDescription +1,
1548 : 0,
1549 94466 : nSize - sizeof( typelib_TypeDescription ) );
1550 :
1551 47233 : if( pTDR->pType->bOnDemand && !(*ppNewDescription)->bOnDemand )
1552 : {
1553 : // switch from OnDemand to !OnDemand, so the description must be acquired
1554 9902 : typelib_typedescription_acquire( pTDR->pType );
1555 : }
1556 37331 : else if( !pTDR->pType->bOnDemand && (*ppNewDescription)->bOnDemand )
1557 : {
1558 : // switch from !OnDemand to OnDemand, so the description must be relesed
1559 : assert(pTDR->pType->nRefCount > 1);
1560 : // coverity[freed_arg] - pType's nRefCount is > 1 here
1561 0 : typelib_typedescription_release( pTDR->pType );
1562 : }
1563 :
1564 47233 : pTDR->pType->bOnDemand = (*ppNewDescription)->bOnDemand;
1565 : // initialized
1566 47233 : pTDR->pType->pWeakRef = pTDR;
1567 : }
1568 :
1569 170682 : typelib_typedescription_release( *ppNewDescription );
1570 : // pTDR was acquired by getByName(), so it must not be acquired again
1571 170682 : *ppNewDescription = pTDR->pType;
1572 170682 : return;
1573 : }
1574 : }
1575 42786 : else if( reallyWeak( (*ppNewDescription)->eTypeClass) )
1576 : {
1577 : typelib_typedescriptionreference_new(
1578 0 : &pTDR, (*ppNewDescription)->eTypeClass, (*ppNewDescription)->pTypeName );
1579 : }
1580 : else
1581 : {
1582 42786 : pTDR = reinterpret_cast<typelib_TypeDescriptionReference *>(*ppNewDescription);
1583 42786 : if( !rInit.pWeakMap )
1584 0 : rInit.pWeakMap = new WeakMap_Impl;
1585 :
1586 : // description is the weak itself, so register it
1587 42786 : (*rInit.pWeakMap)[pTDR->pTypeName->buffer] = pTDR;
1588 : OSL_ASSERT( static_cast<void *>(*ppNewDescription) == static_cast<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 154921 : if( !(*ppNewDescription)->bOnDemand )
1594 : {
1595 : // nor OnDemand so the description must be acquired if registered
1596 85690 : typelib_typedescription_acquire( *ppNewDescription );
1597 : }
1598 :
1599 154921 : pTDR->pType = *ppNewDescription;
1600 154921 : (*ppNewDescription)->pWeakRef = pTDR;
1601 : OSL_ASSERT( rtl_ustr_compare( pTDR->pTypeName->buffer, (*ppNewDescription)->pTypeName->buffer ) == 0 );
1602 154921 : OSL_ASSERT( pTDR->eTypeClass == (*ppNewDescription)->eTypeClass );
1603 : }
1604 :
1605 :
1606 134931 : static inline bool type_equals(
1607 : typelib_TypeDescriptionReference const * p1, typelib_TypeDescriptionReference const * p2 )
1608 : {
1609 269862 : return (p1 == p2 ||
1610 44546 : (p1->eTypeClass == p2->eTypeClass &&
1611 22207 : p1->pTypeName->length == p2->pTypeName->length &&
1612 135347 : rtl_ustr_compare( p1->pTypeName->buffer, p2->pTypeName->buffer ) == 0));
1613 : }
1614 24656 : extern "C" 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 24656 : reinterpret_cast<typelib_TypeDescriptionReference const *>(p1), reinterpret_cast<typelib_TypeDescriptionReference const *>(p2) );
1620 : }
1621 :
1622 :
1623 259590 : 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 259590 : if( pTypeDescription->nSize )
1630 : {
1631 : // size and alignment are set
1632 46635 : rMaxIntegralTypeSize = pTypeDescription->nAlignment;
1633 46635 : nSize = pTypeDescription->nSize;
1634 : }
1635 : else
1636 : {
1637 212955 : nSize = 0;
1638 212955 : rMaxIntegralTypeSize = 1;
1639 :
1640 : OSL_ASSERT( typelib_TypeClass_TYPEDEF != pTypeDescription->eTypeClass );
1641 :
1642 212955 : switch( pTypeDescription->eTypeClass )
1643 : {
1644 : case typelib_TypeClass_INTERFACE:
1645 : // FEATURE_INTERFACE
1646 160644 : nSize = rMaxIntegralTypeSize = (sal_Int32)(sizeof( void * ));
1647 160644 : break;
1648 : case typelib_TypeClass_ENUM:
1649 4903 : nSize = rMaxIntegralTypeSize = (sal_Int32)(sizeof( typelib_TypeClass ));
1650 4903 : break;
1651 : case typelib_TypeClass_STRUCT:
1652 : case typelib_TypeClass_EXCEPTION:
1653 : // FEATURE_EMPTYCLASS
1654 : {
1655 28722 : typelib_CompoundTypeDescription const * pTmp = reinterpret_cast<typelib_CompoundTypeDescription const *>(pTypeDescription);
1656 28722 : sal_Int32 nStructSize = 0;
1657 28722 : if( pTmp->pBaseTypeDescription )
1658 : {
1659 : // inherit structs extends the base struct.
1660 16396 : nStructSize = pTmp->pBaseTypeDescription->aBase.nSize;
1661 16396 : rMaxIntegralTypeSize = pTmp->pBaseTypeDescription->aBase.nAlignment;
1662 : }
1663 78716 : for( sal_Int32 i = 0; i < pTmp->nMembers; i++ )
1664 : {
1665 49994 : typelib_TypeDescription * pMemberType = 0;
1666 49994 : typelib_TypeDescriptionReference * pMemberRef = pTmp->ppTypeRefs[i];
1667 :
1668 : sal_Int32 nMaxIntegral;
1669 49994 : if (pMemberRef->eTypeClass == typelib_TypeClass_INTERFACE
1670 48033 : || pMemberRef->eTypeClass == typelib_TypeClass_SEQUENCE)
1671 : {
1672 3359 : nMaxIntegral = (sal_Int32)(sizeof(void *));
1673 3359 : nStructSize = newAlignedSize( nStructSize, nMaxIntegral, nMaxIntegral );
1674 : }
1675 : else
1676 : {
1677 46635 : TYPELIB_DANGER_GET( &pMemberType, pMemberRef );
1678 : nStructSize = typelib_typedescription_getAlignedUnoSize(
1679 46635 : pMemberType, nStructSize, nMaxIntegral );
1680 46635 : TYPELIB_DANGER_RELEASE( pMemberType );
1681 : }
1682 49994 : if( nMaxIntegral > rMaxIntegralTypeSize )
1683 12920 : 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 28722 : nStructSize = (nStructSize + rMaxIntegralTypeSize -1)
1695 28722 : / rMaxIntegralTypeSize * rMaxIntegralTypeSize;
1696 : #endif
1697 28722 : nSize += nStructSize;
1698 : }
1699 28722 : break;
1700 : case typelib_TypeClass_SEQUENCE:
1701 10962 : nSize = rMaxIntegralTypeSize = (sal_Int32)(sizeof( void * ));
1702 10962 : break;
1703 : case typelib_TypeClass_ANY:
1704 : // FEATURE_ANY
1705 513 : nSize = (sal_Int32)(sizeof( uno_Any ));
1706 513 : rMaxIntegralTypeSize = (sal_Int32)(sizeof( void * ));
1707 513 : break;
1708 : case typelib_TypeClass_TYPE:
1709 513 : nSize = rMaxIntegralTypeSize = (sal_Int32)(sizeof( typelib_TypeDescriptionReference * ));
1710 513 : break;
1711 : case typelib_TypeClass_BOOLEAN:
1712 513 : nSize = rMaxIntegralTypeSize = (sal_Int32)(sizeof( sal_Bool ));
1713 513 : break;
1714 : case typelib_TypeClass_CHAR:
1715 513 : nSize = rMaxIntegralTypeSize = (sal_Int32)(sizeof( sal_Unicode ));
1716 513 : break;
1717 : case typelib_TypeClass_STRING:
1718 : // FEATURE_STRING
1719 513 : nSize = rMaxIntegralTypeSize = (sal_Int32)(sizeof( rtl_uString * ));
1720 513 : break;
1721 : case typelib_TypeClass_FLOAT:
1722 513 : nSize = rMaxIntegralTypeSize = (sal_Int32)(sizeof( float ));
1723 513 : 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 539 : nSize = rMaxIntegralTypeSize = (sal_Int32)(sizeof( double ));
1731 : #endif
1732 539 : break;
1733 : case typelib_TypeClass_BYTE:
1734 513 : nSize = rMaxIntegralTypeSize = (sal_Int32)(sizeof( sal_Int8 ));
1735 513 : break;
1736 : case typelib_TypeClass_SHORT:
1737 : case typelib_TypeClass_UNSIGNED_SHORT:
1738 1026 : nSize = rMaxIntegralTypeSize = (sal_Int32)(sizeof( sal_Int16 ));
1739 1026 : break;
1740 : case typelib_TypeClass_LONG:
1741 : case typelib_TypeClass_UNSIGNED_LONG:
1742 1542 : nSize = rMaxIntegralTypeSize = (sal_Int32)(sizeof( sal_Int32 ));
1743 1542 : break;
1744 : case typelib_TypeClass_HYPER:
1745 : case typelib_TypeClass_UNSIGNED_HYPER:
1746 1026 : nSize = rMaxIntegralTypeSize = (sal_Int32)(sizeof( sal_Int64 ));
1747 1026 : 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 259590 : return newAlignedSize( nOffset, nSize, rMaxIntegralTypeSize );
1757 : }
1758 :
1759 :
1760 :
1761 : namespace {
1762 :
1763 41454 : typelib_TypeDescriptionReference ** copyExceptions(
1764 : sal_Int32 count, typelib_TypeDescriptionReference ** source)
1765 : {
1766 : typelib_TypeDescriptionReference ** p
1767 41454 : = new typelib_TypeDescriptionReference *[count];
1768 58695 : for (sal_Int32 i = 0; i < count; ++i) {
1769 17241 : typelib_typedescriptionreference_acquire(p[i] = source[i]);
1770 : }
1771 41454 : return p;
1772 : }
1773 :
1774 40082 : 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 40082 : if (baseRef != 0 && base != 0 && interface != 0) {
1781 40082 : switch (base->eTypeClass) {
1782 : case typelib_TypeClass_INTERFACE_METHOD:
1783 : {
1784 : typelib_typedescription_newEmpty(
1785 38710 : result, typelib_TypeClass_INTERFACE_METHOD, name.pData);
1786 : typelib_InterfaceMethodTypeDescription const * baseMethod
1787 : = reinterpret_cast<
1788 38710 : typelib_InterfaceMethodTypeDescription const * >(base);
1789 : typelib_InterfaceMethodTypeDescription * newMethod
1790 : = reinterpret_cast<
1791 38710 : typelib_InterfaceMethodTypeDescription * >(*result);
1792 38710 : newMethod->aBase.nPosition = position;
1793 : rtl_uString_acquire(
1794 : newMethod->aBase.pMemberName
1795 38710 : = baseMethod->aBase.pMemberName);
1796 : typelib_typedescriptionreference_acquire(
1797 38710 : newMethod->pReturnTypeRef = baseMethod->pReturnTypeRef);
1798 38710 : newMethod->nParams = baseMethod->nParams;
1799 : newMethod->pParams = new typelib_MethodParameter[
1800 38710 : newMethod->nParams];
1801 54916 : for (sal_Int32 i = 0; i < newMethod->nParams; ++i) {
1802 : rtl_uString_acquire(
1803 16206 : newMethod->pParams[i].pName
1804 16206 : = baseMethod->pParams[i].pName);
1805 : typelib_typedescriptionreference_acquire(
1806 16206 : newMethod->pParams[i].pTypeRef
1807 16206 : = baseMethod->pParams[i].pTypeRef);
1808 16206 : newMethod->pParams[i].bIn = baseMethod->pParams[i].bIn;
1809 16206 : newMethod->pParams[i].bOut = baseMethod->pParams[i].bOut;
1810 : }
1811 38710 : newMethod->nExceptions = baseMethod->nExceptions;
1812 : newMethod->ppExceptions = copyExceptions(
1813 38710 : baseMethod->nExceptions, baseMethod->ppExceptions);
1814 38710 : newMethod->bOneWay = baseMethod->bOneWay;
1815 : newMethod->pInterface
1816 : = reinterpret_cast< typelib_InterfaceTypeDescription * >(
1817 38710 : interface);
1818 38710 : newMethod->pBaseRef = baseRef;
1819 38710 : newMethod->nIndex = index;
1820 38710 : return true;
1821 : }
1822 :
1823 : case typelib_TypeClass_INTERFACE_ATTRIBUTE:
1824 : {
1825 : typelib_typedescription_newEmpty(
1826 1372 : result, typelib_TypeClass_INTERFACE_ATTRIBUTE, name.pData);
1827 : typelib_InterfaceAttributeTypeDescription const * baseAttribute
1828 : = reinterpret_cast<
1829 1372 : typelib_InterfaceAttributeTypeDescription const * >(base);
1830 : typelib_InterfaceAttributeTypeDescription * newAttribute
1831 : = reinterpret_cast<
1832 1372 : typelib_InterfaceAttributeTypeDescription * >(*result);
1833 1372 : newAttribute->aBase.nPosition = position;
1834 : rtl_uString_acquire(
1835 : newAttribute->aBase.pMemberName
1836 1372 : = baseAttribute->aBase.pMemberName);
1837 1372 : newAttribute->bReadOnly = baseAttribute->bReadOnly;
1838 : typelib_typedescriptionreference_acquire(
1839 : newAttribute->pAttributeTypeRef
1840 1372 : = baseAttribute->pAttributeTypeRef);
1841 : newAttribute->pInterface
1842 : = reinterpret_cast< typelib_InterfaceTypeDescription * >(
1843 1372 : interface);
1844 1372 : newAttribute->pBaseRef = baseRef;
1845 1372 : newAttribute->nIndex = index;
1846 1372 : newAttribute->nGetExceptions = baseAttribute->nGetExceptions;
1847 : newAttribute->ppGetExceptions = copyExceptions(
1848 : baseAttribute->nGetExceptions,
1849 1372 : baseAttribute->ppGetExceptions);
1850 1372 : newAttribute->nSetExceptions = baseAttribute->nSetExceptions;
1851 : newAttribute->ppSetExceptions = copyExceptions(
1852 : baseAttribute->nSetExceptions,
1853 1372 : baseAttribute->ppSetExceptions);
1854 1372 : return true;
1855 : }
1856 :
1857 : default:
1858 0 : break;
1859 : }
1860 : }
1861 0 : return false;
1862 : }
1863 :
1864 : }
1865 :
1866 411106 : extern "C" void SAL_CALL typelib_typedescription_getByName(
1867 : typelib_TypeDescription ** ppRet, rtl_uString * pName )
1868 : SAL_THROW_EXTERN_C()
1869 : {
1870 411106 : if( *ppRet )
1871 : {
1872 4 : typelib_typedescription_release( (*ppRet) );
1873 4 : *ppRet = 0;
1874 : }
1875 :
1876 : static bool bInited = false;
1877 411106 : TypeDescriptor_Init_Impl &rInit = Init::get();
1878 :
1879 411106 : if( !bInited )
1880 : {
1881 : // guard against multi thread access
1882 513 : MutexGuard aGuard( rInit.getMutex() );
1883 513 : if( !bInited )
1884 : {
1885 : // avoid recursion during the next ...new calls
1886 513 : bInited = true;
1887 :
1888 513 : rtl_uString * pTypeName = 0;
1889 513 : typelib_TypeDescription * pType = 0;
1890 513 : rtl_uString_newFromAscii( &pTypeName, "type" );
1891 513 : typelib_typedescription_new( &pType, typelib_TypeClass_TYPE, pTypeName, 0, 0, 0 );
1892 513 : typelib_typedescription_register( &pType );
1893 513 : rtl_uString_newFromAscii( &pTypeName, "void" );
1894 513 : typelib_typedescription_new( &pType, typelib_TypeClass_VOID, pTypeName, 0, 0, 0 );
1895 513 : typelib_typedescription_register( &pType );
1896 513 : rtl_uString_newFromAscii( &pTypeName, "boolean" );
1897 513 : typelib_typedescription_new( &pType, typelib_TypeClass_BOOLEAN, pTypeName, 0, 0, 0 );
1898 513 : typelib_typedescription_register( &pType );
1899 513 : rtl_uString_newFromAscii( &pTypeName, "char" );
1900 513 : typelib_typedescription_new( &pType, typelib_TypeClass_CHAR, pTypeName, 0, 0, 0 );
1901 513 : typelib_typedescription_register( &pType );
1902 513 : rtl_uString_newFromAscii( &pTypeName, "byte" );
1903 513 : typelib_typedescription_new( &pType, typelib_TypeClass_BYTE, pTypeName, 0, 0, 0 );
1904 513 : typelib_typedescription_register( &pType );
1905 513 : rtl_uString_newFromAscii( &pTypeName, "string" );
1906 513 : typelib_typedescription_new( &pType, typelib_TypeClass_STRING, pTypeName, 0, 0, 0 );
1907 513 : typelib_typedescription_register( &pType );
1908 513 : rtl_uString_newFromAscii( &pTypeName, "short" );
1909 513 : typelib_typedescription_new( &pType, typelib_TypeClass_SHORT, pTypeName, 0, 0, 0 );
1910 513 : typelib_typedescription_register( &pType );
1911 513 : rtl_uString_newFromAscii( &pTypeName, "unsigned short" );
1912 513 : typelib_typedescription_new( &pType, typelib_TypeClass_UNSIGNED_SHORT, pTypeName, 0, 0, 0 );
1913 513 : typelib_typedescription_register( &pType );
1914 513 : rtl_uString_newFromAscii( &pTypeName, "long" );
1915 513 : typelib_typedescription_new( &pType, typelib_TypeClass_LONG, pTypeName, 0, 0, 0 );
1916 513 : typelib_typedescription_register( &pType );
1917 513 : rtl_uString_newFromAscii( &pTypeName, "unsigned long" );
1918 513 : typelib_typedescription_new( &pType, typelib_TypeClass_UNSIGNED_LONG, pTypeName, 0, 0, 0 );
1919 513 : typelib_typedescription_register( &pType );
1920 513 : rtl_uString_newFromAscii( &pTypeName, "hyper" );
1921 513 : typelib_typedescription_new( &pType, typelib_TypeClass_HYPER, pTypeName, 0, 0, 0 );
1922 513 : typelib_typedescription_register( &pType );
1923 513 : rtl_uString_newFromAscii( &pTypeName, "unsigned hyper" );
1924 513 : typelib_typedescription_new( &pType, typelib_TypeClass_UNSIGNED_HYPER, pTypeName, 0, 0, 0 );
1925 513 : typelib_typedescription_register( &pType );
1926 513 : rtl_uString_newFromAscii( &pTypeName, "float" );
1927 513 : typelib_typedescription_new( &pType, typelib_TypeClass_FLOAT, pTypeName, 0, 0, 0 );
1928 513 : typelib_typedescription_register( &pType );
1929 513 : rtl_uString_newFromAscii( &pTypeName, "double" );
1930 513 : typelib_typedescription_new( &pType, typelib_TypeClass_DOUBLE, pTypeName, 0, 0, 0 );
1931 513 : typelib_typedescription_register( &pType );
1932 513 : rtl_uString_newFromAscii( &pTypeName, "any" );
1933 513 : typelib_typedescription_new( &pType, typelib_TypeClass_ANY, pTypeName, 0, 0, 0 );
1934 513 : typelib_typedescription_register( &pType );
1935 513 : typelib_typedescription_release( pType );
1936 513 : rtl_uString_release( pTypeName );
1937 513 : }
1938 : }
1939 :
1940 411106 : typelib_TypeDescriptionReference * pTDR = 0;
1941 411106 : typelib_typedescriptionreference_getByName( &pTDR, pName );
1942 411106 : if( pTDR )
1943 : {
1944 : {
1945 : // guard against multi thread access
1946 410422 : MutexGuard aGuard( rInit.getMutex() );
1947 : // pTDR->pType->pWeakRef == 0 means that the description is empty
1948 410422 : if( pTDR->pType && pTDR->pType->pWeakRef )
1949 : {
1950 304389 : typelib_typedescription_acquire( pTDR->pType );
1951 304389 : *ppRet = pTDR->pType;
1952 410422 : }
1953 : }
1954 410422 : typelib_typedescriptionreference_release( pTDR );
1955 : }
1956 :
1957 411106 : if (0 == *ppRet)
1958 : {
1959 : // check for sequence
1960 106717 : OUString const & name = OUString::unacquired( &pName );
1961 106717 : if (2 < name.getLength() && '[' == name[ 0 ])
1962 : {
1963 365 : OUString element_name( name.copy( 2 ) );
1964 365 : typelib_TypeDescription * element_td = 0;
1965 365 : typelib_typedescription_getByName( &element_td, element_name.pData );
1966 365 : if (0 != element_td)
1967 : {
1968 : typelib_typedescription_new(
1969 365 : ppRet, typelib_TypeClass_SEQUENCE, pName, element_td->pWeakRef, 0, 0 );
1970 : // register?
1971 365 : typelib_typedescription_release( element_td );
1972 365 : }
1973 : }
1974 106717 : if (0 == *ppRet)
1975 : {
1976 : // Check for derived interface member type:
1977 : sal_Int32 i1 = name.lastIndexOf(
1978 106352 : rtl::OUString(":@"));
1979 106352 : if (i1 >= 0) {
1980 40082 : sal_Int32 i2 = i1 + RTL_CONSTASCII_LENGTH(":@");
1981 40082 : sal_Int32 i3 = name.indexOf(',', i2);
1982 40082 : if (i3 >= 0) {
1983 40082 : sal_Int32 i4 = name.indexOf(':', i3);
1984 40082 : if (i4 >= 0) {
1985 40082 : typelib_TypeDescriptionReference * pBaseRef = 0;
1986 40082 : typelib_TypeDescription * pBase = 0;
1987 40082 : typelib_TypeDescription * pInterface = 0;
1988 : typelib_typedescriptionreference_getByName(
1989 40082 : &pBaseRef, name.copy(0, i1).pData);
1990 40082 : if (pBaseRef != 0) {
1991 : typelib_typedescriptionreference_getDescription(
1992 40082 : &pBase, pBaseRef);
1993 : }
1994 : typelib_typedescription_getByName(
1995 40082 : &pInterface, name.copy(i4 + 1).pData);
1996 80164 : if (!createDerivedInterfaceMemberDescription(
1997 : ppRet, name, pBaseRef, pBase, pInterface,
1998 : name.copy(i2, i3 - i2).toInt32(),
1999 80164 : 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 106717 : if (0 == *ppRet)
2017 : {
2018 : // on demand access
2019 66270 : rInit.callChain( ppRet, pName );
2020 : }
2021 :
2022 106717 : if( *ppRet )
2023 : {
2024 : // typedescription found
2025 106460 : if (typelib_TypeClass_TYPEDEF == (*ppRet)->eTypeClass)
2026 : {
2027 0 : typelib_TypeDescription * pTD = 0;
2028 : typelib_typedescriptionreference_getDescription(
2029 0 : &pTD, reinterpret_cast<typelib_IndirectTypeDescription *>(*ppRet)->pType );
2030 0 : typelib_typedescription_release( *ppRet );
2031 0 : *ppRet = pTD;
2032 : }
2033 : else
2034 : {
2035 : // set to on demand
2036 106460 : (*ppRet)->bOnDemand = sal_True;
2037 : // The type description is hold by the reference until
2038 : // on demand is activated.
2039 106460 : typelib_typedescription_register( ppRet );
2040 :
2041 : // insert into the chache
2042 106460 : MutexGuard aGuard( rInit.getMutex() );
2043 106460 : if( !rInit.pCache )
2044 255 : rInit.pCache = new TypeDescriptionList_Impl;
2045 106460 : if( (sal_Int32)rInit.pCache->size() >= nCacheSize )
2046 : {
2047 70790 : typelib_typedescription_release( rInit.pCache->front() );
2048 70790 : rInit.pCache->pop_front();
2049 : }
2050 : // descriptions in the cache must be acquired!
2051 106460 : typelib_typedescription_acquire( *ppRet );
2052 106460 : rInit.pCache->push_back( *ppRet );
2053 : }
2054 : }
2055 : }
2056 411106 : }
2057 :
2058 0 : extern "C" 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 2083013 : extern "C" void SAL_CALL typelib_typedescriptionreference_new(
2069 : typelib_TypeDescriptionReference ** ppTDR,
2070 : typelib_TypeClass eTypeClass, rtl_uString * pTypeName )
2071 : SAL_THROW_EXTERN_C()
2072 : {
2073 2083013 : TypeDescriptor_Init_Impl &rInit = Init::get();
2074 2083013 : if( eTypeClass == typelib_TypeClass_TYPEDEF )
2075 : {
2076 : // on demand access
2077 652 : typelib_TypeDescription * pRet = 0;
2078 652 : rInit.callChain( &pRet, pTypeName );
2079 652 : if( pRet )
2080 : {
2081 : // typedescription found
2082 652 : if (typelib_TypeClass_TYPEDEF == pRet->eTypeClass)
2083 : {
2084 : typelib_typedescriptionreference_acquire(
2085 0 : reinterpret_cast<typelib_IndirectTypeDescription *>(pRet)->pType );
2086 0 : if (*ppTDR)
2087 0 : typelib_typedescriptionreference_release( *ppTDR );
2088 0 : *ppTDR = reinterpret_cast<typelib_IndirectTypeDescription *>(pRet)->pType;
2089 0 : typelib_typedescription_release( pRet );
2090 : }
2091 : else
2092 : {
2093 : // set to on demand
2094 652 : pRet->bOnDemand = sal_True;
2095 : // The type description is hold by the reference until
2096 : // on demand is activated.
2097 652 : typelib_typedescription_register( &pRet );
2098 :
2099 : // insert into the chache
2100 652 : MutexGuard aGuard( rInit.getMutex() );
2101 652 : if( !rInit.pCache )
2102 0 : rInit.pCache = new TypeDescriptionList_Impl;
2103 652 : if( (sal_Int32)rInit.pCache->size() >= nCacheSize )
2104 : {
2105 370 : typelib_typedescription_release( rInit.pCache->front() );
2106 370 : rInit.pCache->pop_front();
2107 : }
2108 652 : rInit.pCache->push_back( pRet );
2109 : // pRet kept acquired for cache
2110 :
2111 652 : typelib_typedescriptionreference_acquire( pRet->pWeakRef );
2112 652 : if (*ppTDR)
2113 0 : typelib_typedescriptionreference_release( *ppTDR );
2114 652 : *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 652 : return;
2127 : }
2128 :
2129 2082361 : MutexGuard aGuard( rInit.getMutex() );
2130 2082361 : typelib_typedescriptionreference_getByName( ppTDR, pTypeName );
2131 2082361 : if( *ppTDR )
2132 1509988 : return;
2133 :
2134 572373 : if( reallyWeak( eTypeClass ) )
2135 : {
2136 485322 : typelib_TypeDescriptionReference * pTDR = new typelib_TypeDescriptionReference();
2137 : #if OSL_DEBUG_LEVEL > 1
2138 : osl_atomic_increment( &rInit.nTypeDescriptionReferenceCount );
2139 : #endif
2140 485322 : pTDR->nRefCount = 1;
2141 485322 : pTDR->nStaticRefCount = 0;
2142 485322 : pTDR->eTypeClass = eTypeClass;
2143 485322 : pTDR->pUniqueIdentifier = 0;
2144 485322 : pTDR->pReserved = 0;
2145 485322 : rtl_uString_acquire( pTDR->pTypeName = pTypeName );
2146 485322 : pTDR->pType = 0;
2147 485322 : *ppTDR = pTDR;
2148 : }
2149 : else
2150 : {
2151 87051 : typelib_typedescription_newEmpty( reinterpret_cast<typelib_TypeDescription ** >(ppTDR), eTypeClass, pTypeName );
2152 : // description will be registered but not acquired
2153 87051 : (*reinterpret_cast<typelib_TypeDescription **>(ppTDR))->bOnDemand = sal_True;
2154 87051 : (*reinterpret_cast<typelib_TypeDescription **>(ppTDR))->bComplete = sal_False;
2155 : }
2156 :
2157 572373 : if( !rInit.pWeakMap )
2158 517 : rInit.pWeakMap = new WeakMap_Impl;
2159 : // Heavy hack, the const sal_Unicode * is hold by the typedescription reference
2160 : // not registered
2161 572373 : rInit.pWeakMap->operator[]( (*ppTDR)->pTypeName->buffer ) = *ppTDR;
2162 : }
2163 :
2164 :
2165 910495714 : extern "C" void SAL_CALL typelib_typedescriptionreference_acquire(
2166 : typelib_TypeDescriptionReference * pRef )
2167 : SAL_THROW_EXTERN_C()
2168 : {
2169 910495714 : osl_atomic_increment( &pRef->nRefCount );
2170 910495714 : }
2171 :
2172 :
2173 4027927313 : extern "C" void SAL_CALL typelib_typedescriptionreference_release(
2174 : typelib_TypeDescriptionReference * pRef )
2175 : SAL_THROW_EXTERN_C()
2176 : {
2177 : // Is it a type description?
2178 4027927313 : if( reallyWeak( pRef->eTypeClass ) )
2179 : {
2180 2177374 : if( ! osl_atomic_decrement( &pRef->nRefCount ) )
2181 : {
2182 334962 : TypeDescriptor_Init_Impl &rInit = Init::get();
2183 334962 : if( rInit.pWeakMap )
2184 : {
2185 334962 : MutexGuard aGuard( rInit.getMutex() );
2186 334962 : WeakMap_Impl::iterator aIt = rInit.pWeakMap->find( pRef->pTypeName->buffer );
2187 334962 : if( !(aIt == rInit.pWeakMap->end()) && (*aIt).second == pRef )
2188 : {
2189 : // remove only if it contains the same object
2190 334962 : rInit.pWeakMap->erase( aIt );
2191 334962 : }
2192 : }
2193 :
2194 334962 : 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 334962 : delete pRef;
2200 : }
2201 : }
2202 : else
2203 : {
2204 4025749516 : typelib_typedescription_release( reinterpret_cast<typelib_TypeDescription *>(pRef) );
2205 : }
2206 4027928449 : }
2207 :
2208 :
2209 3335609 : extern "C" void SAL_CALL typelib_typedescriptionreference_getDescription(
2210 : typelib_TypeDescription ** ppRet, typelib_TypeDescriptionReference * pRef )
2211 : SAL_THROW_EXTERN_C()
2212 : {
2213 3335609 : if( *ppRet )
2214 : {
2215 0 : typelib_typedescription_release( *ppRet );
2216 0 : *ppRet = 0;
2217 : }
2218 :
2219 3335609 : if( !reallyWeak( pRef->eTypeClass ) && pRef->pType && pRef->pType->pWeakRef )
2220 : {
2221 : // reference is a description and initialized
2222 1850963 : osl_atomic_increment( &reinterpret_cast<typelib_TypeDescription *>(pRef)->nRefCount );
2223 1850963 : *ppRet = reinterpret_cast<typelib_TypeDescription *>(pRef);
2224 1850963 : return;
2225 : }
2226 :
2227 : {
2228 1484670 : MutexGuard aGuard( Init::get().getMutex() );
2229 : // pRef->pType->pWeakRef == 0 means that the description is empty
2230 1484681 : if( pRef->pType && pRef->pType->pWeakRef )
2231 : {
2232 1379462 : sal_Int32 n = osl_atomic_increment( &pRef->pType->nRefCount );
2233 1379462 : if( n > 1 )
2234 : {
2235 : // The refence is incremented. The object cannot be destroyed.
2236 : // Release the guard at the earliest point.
2237 1379462 : *ppRet = pRef->pType;
2238 1379462 : return;
2239 : }
2240 : else
2241 : {
2242 0 : (void)osl_atomic_decrement( &pRef->pType->nRefCount );
2243 : // destruction of this type in progress (another thread!)
2244 : // no access through this weak reference
2245 0 : pRef->pType = 0;
2246 : }
2247 105219 : }
2248 : }
2249 :
2250 105219 : 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 105219 : pRef->pType = *ppRet;
2255 : }
2256 :
2257 :
2258 3037234 : extern "C" void SAL_CALL typelib_typedescriptionreference_getByName(
2259 : typelib_TypeDescriptionReference ** ppRet, rtl_uString * pName )
2260 : SAL_THROW_EXTERN_C()
2261 : {
2262 3037234 : if( *ppRet )
2263 : {
2264 0 : typelib_typedescriptionreference_release( *ppRet );
2265 0 : *ppRet = 0;
2266 : }
2267 3037234 : TypeDescriptor_Init_Impl &rInit = Init::get();
2268 3037234 : if( rInit.pWeakMap )
2269 : {
2270 3036717 : MutexGuard aGuard( rInit.getMutex() );
2271 3036717 : WeakMap_Impl::const_iterator aIt = rInit.pWeakMap->find( pName->buffer );
2272 3036717 : if( !(aIt == rInit.pWeakMap->end()) ) // != failed on msc4.2
2273 : {
2274 2413580 : sal_Int32 n = osl_atomic_increment( &(*aIt).second->nRefCount );
2275 2413580 : if( n > 1 )
2276 : {
2277 : // The refence is incremented. The object cannot be destroyed.
2278 : // Release the guard at the earliest point.
2279 2413580 : *ppRet = (*aIt).second;
2280 : }
2281 : else
2282 : {
2283 : // destruction of this type in progress (another thread!)
2284 : // no access through this weak reference
2285 0 : (void)osl_atomic_decrement( &(*aIt).second->nRefCount );
2286 : }
2287 3036717 : }
2288 : }
2289 3037234 : }
2290 :
2291 :
2292 1817586712 : extern "C" sal_Bool SAL_CALL typelib_typedescriptionreference_equals(
2293 : const typelib_TypeDescriptionReference * p1,
2294 : const typelib_TypeDescriptionReference * p2 )
2295 : SAL_THROW_EXTERN_C()
2296 : {
2297 3635173355 : return (p1 == p2 ||
2298 3374363209 : (p1->eTypeClass == p2->eTypeClass &&
2299 1744711410 : p1->pTypeName->length == p2->pTypeName->length &&
2300 1875329691 : rtl_ustr_compare( p1->pTypeName->buffer, p2->pTypeName->buffer ) == 0));
2301 : }
2302 :
2303 :
2304 11565041 : extern "C" void SAL_CALL typelib_typedescriptionreference_assign(
2305 : typelib_TypeDescriptionReference ** ppDest,
2306 : typelib_TypeDescriptionReference * pSource )
2307 : SAL_THROW_EXTERN_C()
2308 : {
2309 11565041 : if (*ppDest != pSource)
2310 : {
2311 11107199 : ::typelib_typedescriptionreference_acquire( pSource );
2312 11107199 : ::typelib_typedescriptionreference_release( *ppDest );
2313 11107199 : *ppDest = pSource;
2314 : }
2315 11565041 : }
2316 :
2317 :
2318 0 : extern "C" 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 115534 : extern "C" sal_Bool SAL_CALL typelib_typedescriptionreference_isAssignableFrom(
2357 : typelib_TypeDescriptionReference * pAssignable,
2358 : typelib_TypeDescriptionReference * pFrom )
2359 : SAL_THROW_EXTERN_C()
2360 : {
2361 115534 : if (pAssignable && pFrom)
2362 : {
2363 115534 : typelib_TypeClass eAssignable = pAssignable->eTypeClass;
2364 115534 : typelib_TypeClass eFrom = pFrom->eTypeClass;
2365 :
2366 115534 : if (eAssignable == typelib_TypeClass_ANY) // anything can be assigned to an any .)
2367 0 : return sal_True;
2368 115534 : if (eAssignable == eFrom)
2369 : {
2370 110275 : if (type_equals( pAssignable, pFrom )) // first shot
2371 : {
2372 96504 : return sal_True;
2373 : }
2374 : else
2375 : {
2376 13771 : switch (eAssignable)
2377 : {
2378 : case typelib_TypeClass_STRUCT:
2379 : case typelib_TypeClass_EXCEPTION:
2380 : {
2381 388 : typelib_TypeDescription * pFromDescr = 0;
2382 388 : TYPELIB_DANGER_GET( &pFromDescr, pFrom );
2383 388 : if (!reinterpret_cast<typelib_CompoundTypeDescription *>(pFromDescr)->pBaseTypeDescription)
2384 : {
2385 17 : TYPELIB_DANGER_RELEASE( pFromDescr );
2386 17 : return sal_False;
2387 : }
2388 : bool bRet = typelib_typedescriptionreference_isAssignableFrom(
2389 : pAssignable,
2390 371 : reinterpret_cast<typelib_CompoundTypeDescription *>(pFromDescr)->pBaseTypeDescription->aBase.pWeakRef );
2391 371 : TYPELIB_DANGER_RELEASE( pFromDescr );
2392 371 : return bRet;
2393 : }
2394 : case typelib_TypeClass_INTERFACE:
2395 : {
2396 13383 : typelib_TypeDescription * pFromDescr = 0;
2397 13383 : TYPELIB_DANGER_GET( &pFromDescr, pFrom );
2398 : typelib_InterfaceTypeDescription * pFromIfc
2399 : = reinterpret_cast<
2400 13383 : typelib_InterfaceTypeDescription * >(pFromDescr);
2401 13383 : bool bRet = false;
2402 17839 : for (sal_Int32 i = 0; i < pFromIfc->nBaseTypes; ++i) {
2403 7521 : if (typelib_typedescriptionreference_isAssignableFrom(
2404 : pAssignable,
2405 7521 : pFromIfc->ppBaseTypes[i]->aBase.pWeakRef))
2406 : {
2407 3065 : bRet = true;
2408 3065 : break;
2409 : }
2410 : }
2411 13383 : TYPELIB_DANGER_RELEASE( pFromDescr );
2412 13383 : return bRet;
2413 : }
2414 : default:
2415 : {
2416 0 : return sal_False;
2417 : }
2418 : }
2419 : }
2420 : }
2421 12990 : return (eAssignable >= typelib_TypeClass_CHAR && eAssignable <= typelib_TypeClass_DOUBLE &&
2422 12157 : eFrom >= typelib_TypeClass_CHAR && eFrom <= typelib_TypeClass_DOUBLE &&
2423 7471 : s_aAssignableFromTab[eAssignable-1][eFrom-1]);
2424 : }
2425 0 : return sal_False;
2426 : }
2427 :
2428 8086 : extern "C" 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 8086 : pAssignable->pWeakRef, pFrom->pWeakRef );
2435 : }
2436 :
2437 :
2438 1226706 : extern "C" sal_Bool SAL_CALL typelib_typedescription_complete(
2439 : typelib_TypeDescription ** ppTypeDescr )
2440 : SAL_THROW_EXTERN_C()
2441 : {
2442 1226706 : return complete(ppTypeDescr, true);
2443 : }
2444 :
2445 : /* vim:set shiftwidth=4 softtabstop=4 expandtab: */
|