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