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