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