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 <stdarg.h>
28 #include <algorithm>
29 
30 #include <osl/mutex.hxx>
31 #include <osl/interlck.h>
32 #include <rtl/ustring.hxx>
33 #include <rtl/ustrbuf.hxx>
34 #include <rtl/memory.h>
35 #include <rtl/instance.hxx>
36 
37 #include <typelib/typedescription.h>
38 
39 
40 using namespace osl;
41 using namespace rtl;
42 
43 extern "C"
44 {
45 
46 //------------------------------------------------------------------------
47 sal_Int32 SAL_CALL typelib_typedescription_getAlignedUnoSize(
48 	const typelib_TypeDescription * pTypeDescription,
49 	sal_Int32 nOffset,
50 	sal_Int32 & rMaxIntegralTypeSize )
51 	SAL_THROW_EXTERN_C();
52 //------------------------------------------------------------------------
53 void SAL_CALL typelib_typedescription_newEmpty(
54 	typelib_TypeDescription ** ppRet,
55 	typelib_TypeClass eTypeClass,
56 	rtl_uString * pTypeName )
57 	SAL_THROW_EXTERN_C();
58 //-----------------------------------------------------------------------------
59 void SAL_CALL typelib_typedescriptionreference_getByName(
60 	typelib_TypeDescriptionReference ** ppRet,
61 	rtl_uString * pName )
62 	SAL_THROW_EXTERN_C();
63 
64 #ifdef SAL_W32
65 #pragma pack(push, 8)
66 #elif defined(SAL_OS2)
67 #pragma pack(8)
68 #endif
69 
70 /**
71  * The double member determin the alignment.
72  * Under Os2 and MS-Windows the Alignment is min( 8, sizeof( type ) ).
73  * The aligment of a strukture is min( 8, sizeof( max basic type ) ), the greatest basic type
74  * determine the aligment.
75  */
76 struct AlignSize_Impl
77 {
78 	sal_Int16	nInt16;
79 	double		dDouble;
80 };
81 
82 #ifdef SAL_W32
83 #pragma pack(pop)
84 #elif defined(SAL_OS2)
85 #pragma pack()
86 #endif
87 
88 // the value of the maximal alignment
89 static sal_Int32 nMaxAlignment = (sal_Int32)( (sal_Size)(&((AlignSize_Impl *) 16)->dDouble) - 16);
90 
adjustAlignment(sal_Int32 nRequestedAlignment)91 static inline sal_Int32 adjustAlignment( sal_Int32 nRequestedAlignment )
92 	SAL_THROW( () )
93 {
94 	if( nRequestedAlignment > nMaxAlignment )
95 		nRequestedAlignment = nMaxAlignment;
96 	return nRequestedAlignment;
97 }
98 
99 /**
100  * Calculate the new size of the struktur.
101  */
newAlignedSize(sal_Int32 OldSize,sal_Int32 ElementSize,sal_Int32 NeededAlignment)102 static inline sal_Int32 newAlignedSize(
103 	sal_Int32 OldSize, sal_Int32 ElementSize, sal_Int32 NeededAlignment )
104 	SAL_THROW( () )
105 {
106 	NeededAlignment = adjustAlignment( NeededAlignment );
107 	return (OldSize + NeededAlignment -1) / NeededAlignment * NeededAlignment + ElementSize;
108 }
109 
110 //--------------------------------------------------------------------------------------------------
111 
112 namespace
113 {
114     struct typelib_StaticInitMutex : public rtl::Static< Mutex, typelib_StaticInitMutex > {};
115 }
116 
117 // !for NOT REALLY WEAK TYPES only!
igetTypeByName(rtl_uString * pTypeName)118 static inline typelib_TypeDescriptionReference * igetTypeByName( rtl_uString * pTypeName )
119 	SAL_THROW( () )
120 {
121 	typelib_TypeDescriptionReference * pRef = 0;
122 	::typelib_typedescriptionreference_getByName( &pRef, pTypeName );
123 	if (pRef && pRef->pType && pRef->pType->pWeakRef) // found initialized td
124 	{
125 		return pRef;
126 	}
127 	else
128 	{
129 		return 0;
130 	}
131 }
132 
133 extern "C"
134 {
135 //##################################################################################################
typelib_static_type_getByTypeClass(typelib_TypeClass eTypeClass)136 typelib_TypeDescriptionReference ** SAL_CALL typelib_static_type_getByTypeClass(
137 	typelib_TypeClass eTypeClass )
138 	SAL_THROW_EXTERN_C()
139 {
140 	static typelib_TypeDescriptionReference * s_aTypes[] = {
141 		0, 0, 0, 0, 0, 0, 0, 0, 0, 0,
142 		0, 0, 0, 0, 0, 0, 0, 0, 0, 0,
143 		0, 0, 0 };
144 
145 	if (! s_aTypes[eTypeClass])
146 	{
147 		MutexGuard aGuard( typelib_StaticInitMutex::get() );
148 		if (! s_aTypes[eTypeClass])
149 		{
150 			static const char * s_aTypeNames[] = {
151 				"void", "char", "boolean", "byte",
152 				"short", "unsigned short", "long", "unsigned long",
153 				"hyper", "unsigned hyper", "float", "double",
154 				"string", "type", "any" };
155 
156 			switch (eTypeClass)
157 			{
158 			case typelib_TypeClass_EXCEPTION:
159 			case typelib_TypeClass_INTERFACE:
160 			{
161 				// type
162 				if (! s_aTypes[typelib_TypeClass_TYPE])
163 				{
164 					OUString sTypeName( RTL_CONSTASCII_USTRINGPARAM("type") );
165 					::typelib_typedescriptionreference_new(
166 						&s_aTypes[typelib_TypeClass_TYPE], typelib_TypeClass_TYPE, sTypeName.pData );
167 					// another static ref:
168 					++s_aTypes[typelib_TypeClass_TYPE]->nStaticRefCount;
169 				}
170 				// any
171 				if (! s_aTypes[typelib_TypeClass_ANY])
172 				{
173 					OUString sTypeName( RTL_CONSTASCII_USTRINGPARAM("any") );
174 					::typelib_typedescriptionreference_new(
175 						&s_aTypes[typelib_TypeClass_ANY], typelib_TypeClass_ANY, sTypeName.pData );
176 					// another static ref:
177 					++s_aTypes[typelib_TypeClass_ANY]->nStaticRefCount;
178 				}
179 				// string
180 				if (! s_aTypes[typelib_TypeClass_STRING])
181 				{
182 					OUString sTypeName( RTL_CONSTASCII_USTRINGPARAM("string") );
183 					::typelib_typedescriptionreference_new(
184 						&s_aTypes[typelib_TypeClass_STRING], typelib_TypeClass_STRING, sTypeName.pData );
185 					// another static ref:
186 					++s_aTypes[typelib_TypeClass_STRING]->nStaticRefCount;
187 				}
188 				// XInterface
189 				if (! s_aTypes[typelib_TypeClass_INTERFACE])
190 				{
191 					OUString sTypeName( RTL_CONSTASCII_USTRINGPARAM("com.sun.star.uno.XInterface") );
192 
193 					typelib_InterfaceTypeDescription * pTD = 0;
194 
195 					typelib_TypeDescriptionReference * pMembers[3] = { 0,0,0 };
196 					OUString sMethodName0( RTL_CONSTASCII_USTRINGPARAM("com.sun.star.uno.XInterface::queryInterface") );
197 					::typelib_typedescriptionreference_new(
198 						&pMembers[0], typelib_TypeClass_INTERFACE_METHOD, sMethodName0.pData );
199 					OUString sMethodName1( RTL_CONSTASCII_USTRINGPARAM("com.sun.star.uno.XInterface::acquire") );
200 					::typelib_typedescriptionreference_new(
201 						&pMembers[1], typelib_TypeClass_INTERFACE_METHOD, sMethodName1.pData );
202 					OUString sMethodName2( RTL_CONSTASCII_USTRINGPARAM("com.sun.star.uno.XInterface::release") );
203 					::typelib_typedescriptionreference_new(
204 						&pMembers[2], typelib_TypeClass_INTERFACE_METHOD, sMethodName2.pData );
205 
206 					::typelib_typedescription_newInterface(
207 						&pTD, sTypeName.pData, 0xe227a391, 0x33d6, 0x11d1, 0xaabe00a0, 0x249d5590,
208 						0, 3, pMembers );
209 
210 					::typelib_typedescription_register( (typelib_TypeDescription **)&pTD );
211 					::typelib_typedescriptionreference_acquire(
212 						s_aTypes[typelib_TypeClass_INTERFACE] = ((typelib_TypeDescription *)pTD)->pWeakRef );
213 					// another static ref:
214 					++s_aTypes[typelib_TypeClass_INTERFACE]->nStaticRefCount;
215 					::typelib_typedescription_release( (typelib_TypeDescription*)pTD );
216 
217 					::typelib_typedescriptionreference_release( pMembers[0] );
218 					::typelib_typedescriptionreference_release( pMembers[1] );
219 					::typelib_typedescriptionreference_release( pMembers[2] );
220 					// Exception
221 					OSL_ASSERT( ! s_aTypes[typelib_TypeClass_EXCEPTION] );
222 					{
223 					typelib_TypeDescription * pTD1 = 0;
224 					OUString sTypeName1( RTL_CONSTASCII_USTRINGPARAM("com.sun.star.uno.Exception") );
225 
226 					typelib_CompoundMember_Init aMembers[2];
227 					OUString sMemberType0( RTL_CONSTASCII_USTRINGPARAM("string") );
228 					OUString sMemberName0( RTL_CONSTASCII_USTRINGPARAM("Message") );
229 					aMembers[0].eTypeClass = typelib_TypeClass_STRING;
230 					aMembers[0].pTypeName = sMemberType0.pData;
231 					aMembers[0].pMemberName = sMemberName0.pData;
232 					OUString sMemberType1( RTL_CONSTASCII_USTRINGPARAM("com.sun.star.uno.XInterface") );
233 					OUString sMemberName1( RTL_CONSTASCII_USTRINGPARAM("Context") );
234 					aMembers[1].eTypeClass = typelib_TypeClass_INTERFACE;
235 					aMembers[1].pTypeName = sMemberType1.pData;
236 					aMembers[1].pMemberName = sMemberName1.pData;
237 
238 					::typelib_typedescription_new(
239 						&pTD1, typelib_TypeClass_EXCEPTION, sTypeName1.pData, 0, 2, aMembers );
240 					typelib_typedescription_register( &pTD1 );
241 					typelib_typedescriptionreference_acquire(
242 						s_aTypes[typelib_TypeClass_EXCEPTION] = pTD1->pWeakRef );
243 					// another static ref:
244 					++s_aTypes[typelib_TypeClass_EXCEPTION]->nStaticRefCount;
245 					// RuntimeException
246 					OUString sTypeName2( RTL_CONSTASCII_USTRINGPARAM("com.sun.star.uno.RuntimeException") );
247 					::typelib_typedescription_new(
248 						&pTD1, typelib_TypeClass_EXCEPTION, sTypeName2.pData, s_aTypes[typelib_TypeClass_EXCEPTION], 0, 0 );
249 					::typelib_typedescription_register( &pTD1 );
250 					::typelib_typedescription_release( pTD1 );
251 					}
252 					// XInterface members
253 					typelib_InterfaceMethodTypeDescription * pMethod = 0;
254 					typelib_Parameter_Init aParameters[1];
255 					OUString sParamName0( RTL_CONSTASCII_USTRINGPARAM("aType") );
256 					OUString sParamType0( RTL_CONSTASCII_USTRINGPARAM("type") );
257 					aParameters[0].pParamName = sParamName0.pData;
258 					aParameters[0].eTypeClass = typelib_TypeClass_TYPE;
259 					aParameters[0].pTypeName = sParamType0.pData;
260 					aParameters[0].bIn = sal_True;
261 					aParameters[0].bOut = sal_False;
262 					rtl_uString * pExceptions[1];
263 					OUString sExceptionName0( RTL_CONSTASCII_USTRINGPARAM("com.sun.star.uno.RuntimeException") );
264 					pExceptions[0] = sExceptionName0.pData;
265 					OUString sReturnType0( RTL_CONSTASCII_USTRINGPARAM("any") );
266 					typelib_typedescription_newInterfaceMethod(
267 						&pMethod, 0, sal_False, sMethodName0.pData,
268 						typelib_TypeClass_ANY, sReturnType0.pData,
269 						1, aParameters, 1, pExceptions );
270 					::typelib_typedescription_register( (typelib_TypeDescription**)&pMethod );
271 
272 					OUString sReturnType1( RTL_CONSTASCII_USTRINGPARAM("void") );
273 					::typelib_typedescription_newInterfaceMethod(
274 						&pMethod, 1, sal_True, sMethodName1.pData,
275 						typelib_TypeClass_VOID, sReturnType1.pData, 0, 0, 0, 0 );
276 					::typelib_typedescription_register( (typelib_TypeDescription**)&pMethod );
277 
278 					::typelib_typedescription_newInterfaceMethod(
279 						&pMethod, 2, sal_True, sMethodName2.pData,
280 						typelib_TypeClass_VOID, sReturnType1.pData,
281 						0, 0, 0, 0 );
282 					::typelib_typedescription_register( (typelib_TypeDescription**)&pMethod );
283 					::typelib_typedescription_release( (typelib_TypeDescription*)pMethod );
284 				}
285 				break;
286 			}
287 			default:
288 			{
289 				OUString aTypeName( OUString::createFromAscii( s_aTypeNames[eTypeClass] ) );
290 				::typelib_typedescriptionreference_new( &s_aTypes[eTypeClass], eTypeClass, aTypeName.pData );
291 				// another static ref:
292 				++s_aTypes[eTypeClass]->nStaticRefCount;
293 			}
294 			}
295 		}
296 	}
297 	return &s_aTypes[eTypeClass];
298 }
299 
300 //##################################################################################################
typelib_static_type_init(typelib_TypeDescriptionReference ** ppRef,typelib_TypeClass eTypeClass,const sal_Char * pTypeName)301 void SAL_CALL typelib_static_type_init(
302 	typelib_TypeDescriptionReference ** ppRef,
303 	typelib_TypeClass eTypeClass, const sal_Char * pTypeName )
304 	SAL_THROW_EXTERN_C()
305 {
306 	if (! *ppRef)
307 	{
308 		MutexGuard aGuard( typelib_StaticInitMutex::get() );
309 		if (! *ppRef)
310 		{
311 			OUString aTypeName( OUString::createFromAscii( pTypeName ) );
312 			::typelib_typedescriptionreference_new( ppRef, eTypeClass, aTypeName.pData );
313 
314 			// another static ref:
315 			++((*ppRef)->nStaticRefCount);
316 		}
317 	}
318 }
319 
320 //##################################################################################################
typelib_static_sequence_type_init(typelib_TypeDescriptionReference ** ppRef,typelib_TypeDescriptionReference * pElementType)321 void SAL_CALL typelib_static_sequence_type_init(
322 	typelib_TypeDescriptionReference ** ppRef,
323 	typelib_TypeDescriptionReference * pElementType )
324 	SAL_THROW_EXTERN_C()
325 {
326 	if (! *ppRef)
327 	{
328 		MutexGuard aGuard( typelib_StaticInitMutex::get() );
329 		if (! *ppRef)
330 		{
331 			OUStringBuffer aBuf( 32 );
332 			aBuf.appendAscii( "[]" );
333 			aBuf.append( pElementType->pTypeName );
334 			OUString aTypeName( aBuf.makeStringAndClear() );
335 
336 			OSL_ASSERT( ! TYPELIB_TYPEDESCRIPTIONREFERENCE_ISREALLYWEAK(typelib_TypeClass_SEQUENCE) );
337             *ppRef = igetTypeByName( aTypeName.pData );
338 			if (!*ppRef)
339 			{
340 				typelib_TypeDescription * pReg = 0;
341 				::typelib_typedescription_new(
342 					&pReg, typelib_TypeClass_SEQUENCE,
343 					aTypeName.pData, pElementType, 0, 0 );
344 
345 				::typelib_typedescription_register( &pReg );
346 				*ppRef = (typelib_TypeDescriptionReference *)pReg;
347 				OSL_ASSERT( *ppRef == pReg->pWeakRef );
348 			}
349 			// another static ref:
350 			++((*ppRef)->nStaticRefCount);
351 		}
352 	}
353 }
354 
355 //##################################################################################################
356 namespace {
357 
init(typelib_TypeDescriptionReference ** ppRef,typelib_TypeClass eTypeClass,const sal_Char * pTypeName,typelib_TypeDescriptionReference * pBaseType,sal_Int32 nMembers,typelib_TypeDescriptionReference ** ppMembers,sal_Bool const * pParameterizedTypes)358 void init(
359 	typelib_TypeDescriptionReference ** ppRef,
360 	typelib_TypeClass eTypeClass, const sal_Char * pTypeName,
361 	typelib_TypeDescriptionReference * pBaseType,
362 	sal_Int32 nMembers, typelib_TypeDescriptionReference ** ppMembers,
363     sal_Bool const * pParameterizedTypes)
364 {
365 	OSL_ENSURE( typelib_TypeClass_STRUCT == eTypeClass ||
366 				 typelib_TypeClass_EXCEPTION == eTypeClass, "### unexpected type class!" );
367 
368 	if (! *ppRef)
369 	{
370 		MutexGuard aGuard( typelib_StaticInitMutex::get() );
371 		if (! *ppRef)
372 		{
373 			OSL_ASSERT( ! TYPELIB_TYPEDESCRIPTIONREFERENCE_ISREALLYWEAK(eTypeClass) );
374 			OUString aTypeName( OUString::createFromAscii( pTypeName ) );
375             *ppRef = igetTypeByName( aTypeName.pData );
376 			if (!*ppRef)
377 			{
378 				typelib_CompoundTypeDescription * pComp = 0;
379 				::typelib_typedescription_newEmpty(
380 					(typelib_TypeDescription **)&pComp, eTypeClass, aTypeName.pData );
381 
382 				sal_Int32 nOffset = 0;
383 				if (pBaseType)
384 				{
385 					::typelib_typedescriptionreference_getDescription(
386 						(typelib_TypeDescription **)&pComp->pBaseTypeDescription, pBaseType );
387 					OSL_ASSERT( pComp->pBaseTypeDescription );
388 					nOffset = ((typelib_TypeDescription *)pComp->pBaseTypeDescription)->nSize;
389 					OSL_ENSURE( newAlignedSize( 0, ((typelib_TypeDescription *)pComp->pBaseTypeDescription)->nSize, ((typelib_TypeDescription *)pComp->pBaseTypeDescription)->nAlignment ) == ((typelib_TypeDescription *)pComp->pBaseTypeDescription)->nSize, "### unexpected offset!" );
390 				}
391 
392 				if (nMembers)
393 				{
394 					pComp->nMembers = nMembers;
395 					pComp->pMemberOffsets = new sal_Int32[ nMembers ];
396 					pComp->ppTypeRefs = new typelib_TypeDescriptionReference *[ nMembers ];
397                     if (pParameterizedTypes != 0) {
398                         reinterpret_cast< typelib_StructTypeDescription * >(
399                             pComp)->pParameterizedTypes
400                             = new sal_Bool[nMembers];
401                     }
402 					for ( sal_Int32 i = 0 ; i < nMembers; ++i )
403 					{
404 						::typelib_typedescriptionreference_acquire(
405 							pComp->ppTypeRefs[i] = ppMembers[i] );
406 						// write offset
407 						typelib_TypeDescription * pTD = 0;
408 						TYPELIB_DANGER_GET( &pTD, pComp->ppTypeRefs[i] );
409 						OSL_ENSURE( pTD->nSize, "### void member?" );
410 						nOffset = newAlignedSize( nOffset, pTD->nSize, pTD->nAlignment );
411 						pComp->pMemberOffsets[i] = nOffset - pTD->nSize;
412 						TYPELIB_DANGER_RELEASE( pTD );
413 
414                         if (pParameterizedTypes != 0) {
415                             reinterpret_cast< typelib_StructTypeDescription * >(
416                                 pComp)->pParameterizedTypes[i]
417                                 = pParameterizedTypes[i];
418                         }
419 					}
420 				}
421 
422 				typelib_TypeDescription * pReg = (typelib_TypeDescription *)pComp;
423 				pReg->pWeakRef = (typelib_TypeDescriptionReference *)pReg;
424 				// sizeof( void ) not allowed
425 				pReg->nSize = ::typelib_typedescription_getAlignedUnoSize( pReg, 0, pReg->nAlignment );
426 				pReg->nAlignment = adjustAlignment( pReg->nAlignment );
427 				pReg->bComplete = sal_False;
428 
429 				::typelib_typedescription_register( &pReg );
430 				*ppRef = (typelib_TypeDescriptionReference *)pReg;
431 				OSL_ASSERT( *ppRef == pReg->pWeakRef );
432 			}
433 			// another static ref:
434 			++((*ppRef)->nStaticRefCount);
435 		}
436 	}
437 }
438 
439 }
440 
typelib_static_compound_type_init(typelib_TypeDescriptionReference ** ppRef,typelib_TypeClass eTypeClass,const sal_Char * pTypeName,typelib_TypeDescriptionReference * pBaseType,sal_Int32 nMembers,typelib_TypeDescriptionReference ** ppMembers)441 void SAL_CALL typelib_static_compound_type_init(
442 	typelib_TypeDescriptionReference ** ppRef,
443 	typelib_TypeClass eTypeClass, const sal_Char * pTypeName,
444 	typelib_TypeDescriptionReference * pBaseType,
445 	sal_Int32 nMembers, typelib_TypeDescriptionReference ** ppMembers )
446 	SAL_THROW_EXTERN_C()
447 {
448     init(ppRef, eTypeClass, pTypeName, pBaseType, nMembers, ppMembers, 0);
449 }
450 
typelib_static_struct_type_init(typelib_TypeDescriptionReference ** ppRef,const sal_Char * pTypeName,typelib_TypeDescriptionReference * pBaseType,sal_Int32 nMembers,typelib_TypeDescriptionReference ** ppMembers,sal_Bool const * pParameterizedTypes)451 void SAL_CALL typelib_static_struct_type_init(
452 	typelib_TypeDescriptionReference ** ppRef, const sal_Char * pTypeName,
453 	typelib_TypeDescriptionReference * pBaseType,
454 	sal_Int32 nMembers, typelib_TypeDescriptionReference ** ppMembers,
455     sal_Bool const * pParameterizedTypes )
456 	SAL_THROW_EXTERN_C()
457 {
458     init(
459         ppRef, typelib_TypeClass_STRUCT, pTypeName, pBaseType, nMembers,
460         ppMembers, pParameterizedTypes);
461 }
462 
463 //##################################################################################################
typelib_static_interface_type_init(typelib_TypeDescriptionReference ** ppRef,const sal_Char * pTypeName,typelib_TypeDescriptionReference * pBaseType)464 void SAL_CALL typelib_static_interface_type_init(
465 	typelib_TypeDescriptionReference ** ppRef,
466 	const sal_Char * pTypeName,
467 	typelib_TypeDescriptionReference * pBaseType )
468 	SAL_THROW_EXTERN_C()
469 {
470     typelib_static_mi_interface_type_init(
471         ppRef, pTypeName, pBaseType == 0 ? 0 : 1, &pBaseType);
472 }
473 
474 //##################################################################################################
typelib_static_mi_interface_type_init(typelib_TypeDescriptionReference ** ppRef,const sal_Char * pTypeName,sal_Int32 nBaseTypes,typelib_TypeDescriptionReference ** ppBaseTypes)475 void SAL_CALL typelib_static_mi_interface_type_init(
476 	typelib_TypeDescriptionReference ** ppRef,
477 	const sal_Char * pTypeName,
478     sal_Int32 nBaseTypes,
479 	typelib_TypeDescriptionReference ** ppBaseTypes )
480 	SAL_THROW_EXTERN_C()
481 {
482 	if (! *ppRef)
483 	{
484 		MutexGuard aGuard( typelib_StaticInitMutex::get() );
485 		if (! *ppRef)
486 		{
487 			OSL_ASSERT( ! TYPELIB_TYPEDESCRIPTIONREFERENCE_ISREALLYWEAK(typelib_TypeClass_INTERFACE) );
488 			OUString aTypeName( OUString::createFromAscii( pTypeName ) );
489             *ppRef = igetTypeByName( aTypeName.pData );
490 			if (!*ppRef)
491 			{
492 				typelib_InterfaceTypeDescription * pIface = 0;
493 				::typelib_typedescription_newEmpty(
494 					(typelib_TypeDescription **)&pIface, typelib_TypeClass_INTERFACE, aTypeName.pData );
495 
496                 pIface->nBaseTypes = std::max< sal_Int32 >(nBaseTypes, 1);
497                 pIface->ppBaseTypes = new typelib_InterfaceTypeDescription *[
498                     pIface->nBaseTypes];
499 				if (nBaseTypes > 0)
500 				{
501                     for (sal_Int32 i = 0; i < nBaseTypes; ++i) {
502                         pIface->ppBaseTypes[i] = 0;
503                         ::typelib_typedescriptionreference_getDescription(
504                             (typelib_TypeDescription **)&pIface->ppBaseTypes[i], ppBaseTypes[i] );
505                         OSL_ASSERT( pIface->ppBaseTypes[i] );
506                     }
507 				}
508 				else
509 				{
510                     pIface->ppBaseTypes[0] = 0;
511 					::typelib_typedescriptionreference_getDescription(
512 						(typelib_TypeDescription **)&pIface->ppBaseTypes[0],
513 						* ::typelib_static_type_getByTypeClass( typelib_TypeClass_INTERFACE ) );
514                     OSL_ASSERT( pIface->ppBaseTypes[0] );
515 				}
516                 pIface->pBaseTypeDescription = pIface->ppBaseTypes[0];
517                 typelib_typedescription_acquire(
518                     &pIface->pBaseTypeDescription->aBase);
519 
520 				typelib_TypeDescription * pReg = (typelib_TypeDescription *)pIface;
521 				pReg->pWeakRef = (typelib_TypeDescriptionReference *)pReg;
522 				// sizeof( void ) not allowed
523 				pReg->nSize = ::typelib_typedescription_getAlignedUnoSize( pReg, 0, pReg->nAlignment );
524 
525 				pReg->nAlignment = adjustAlignment( pReg->nAlignment );
526 				pReg->bComplete = sal_False;
527 
528 				::typelib_typedescription_register( &pReg );
529 				*ppRef = (typelib_TypeDescriptionReference *)pReg;
530 				OSL_ASSERT( *ppRef == pReg->pWeakRef );
531 			}
532 			// another static ref:
533 			++((*ppRef)->nStaticRefCount);
534 		}
535 	}
536 }
537 
538 //##################################################################################################
typelib_static_enum_type_init(typelib_TypeDescriptionReference ** ppRef,const sal_Char * pTypeName,sal_Int32 nDefaultValue)539 void SAL_CALL typelib_static_enum_type_init(
540 	typelib_TypeDescriptionReference ** ppRef,
541 	const sal_Char * pTypeName,
542 	sal_Int32 nDefaultValue )
543 	SAL_THROW_EXTERN_C()
544 {
545 	if (! *ppRef)
546 	{
547 		MutexGuard aGuard( typelib_StaticInitMutex::get() );
548 		if (! *ppRef)
549 		{
550 			OSL_ASSERT( ! TYPELIB_TYPEDESCRIPTIONREFERENCE_ISREALLYWEAK(typelib_TypeClass_ENUM) );
551 			OUString aTypeName( OUString::createFromAscii( pTypeName ) );
552             *ppRef = igetTypeByName( aTypeName.pData );
553 			if (!*ppRef)
554 			{
555 				typelib_TypeDescription * pReg = 0;
556 				::typelib_typedescription_newEmpty(
557 					&pReg, typelib_TypeClass_ENUM, aTypeName.pData );
558 				typelib_EnumTypeDescription * pEnum = (typelib_EnumTypeDescription *)pReg;
559 
560 				pEnum->nDefaultEnumValue = nDefaultValue;
561 
562 				pReg->pWeakRef = (typelib_TypeDescriptionReference *)pReg;
563 				// sizeof( void ) not allowed
564 				pReg->nSize = ::typelib_typedescription_getAlignedUnoSize( pReg, 0, pReg->nAlignment );
565 				pReg->nAlignment = ::adjustAlignment( pReg->nAlignment );
566 				pReg->bComplete = sal_False;
567 
568 				::typelib_typedescription_register( &pReg );
569 				*ppRef = (typelib_TypeDescriptionReference *)pReg;
570 				OSL_ASSERT( *ppRef == pReg->pWeakRef );
571 			}
572 			// another static ref:
573 			++(*(sal_Int32 *)&(*ppRef)->pReserved);
574 		}
575 	}
576 }
577 
578 //##################################################################################################
typelib_static_array_type_init(typelib_TypeDescriptionReference ** ppRef,typelib_TypeDescriptionReference * pElementTypeRef,sal_Int32 nDimensions,...)579 void SAL_CALL typelib_static_array_type_init(
580 	typelib_TypeDescriptionReference ** ppRef,
581 	typelib_TypeDescriptionReference * pElementTypeRef,
582 	sal_Int32 nDimensions, ... )
583 	SAL_THROW_EXTERN_C()
584 {
585 	if (! *ppRef)
586 	{
587 		MutexGuard aGuard( typelib_StaticInitMutex::get() );
588 		if (! *ppRef)
589 		{
590 			OUStringBuffer aBuf( 32 );
591 			aBuf.append( pElementTypeRef->pTypeName );
592 
593 			va_list dimArgs;
594 			va_start( dimArgs, nDimensions );
595 			sal_Int32 dim = 0;
596 			sal_Int32 nElements = 1;
597 			sal_Int32* pDimensions = new sal_Int32[nDimensions];
598 			for (sal_Int32 i=0; i < nDimensions; i++)
599 			{
600 				dim = va_arg( dimArgs, int);
601 				pDimensions[i] = dim;
602 				aBuf.appendAscii("[");
603 				aBuf.append(dim);
604 				aBuf.appendAscii("]");
605 				nElements *= dim;
606 			}
607 			va_end( dimArgs );
608 			OUString aTypeName( aBuf.makeStringAndClear() );
609 
610 			OSL_ASSERT( ! TYPELIB_TYPEDESCRIPTIONREFERENCE_ISREALLYWEAK(typelib_TypeClass_ARRAY) );
611             *ppRef = igetTypeByName( aTypeName.pData );
612 			if (!*ppRef)
613 			{
614 				typelib_TypeDescription * pReg = 0;
615 				::typelib_typedescription_newEmpty(
616 					&pReg, typelib_TypeClass_ARRAY, aTypeName.pData );
617 				typelib_ArrayTypeDescription * pArray = (typelib_ArrayTypeDescription *)pReg;
618 
619 				pArray->nDimensions = nDimensions;
620 				pArray->nTotalElements = nElements;
621 				pArray->pDimensions = pDimensions;
622 
623 				typelib_typedescriptionreference_acquire(pElementTypeRef);
624 				((typelib_IndirectTypeDescription*)pArray)->pType = pElementTypeRef;
625 
626 				pReg->pWeakRef = (typelib_TypeDescriptionReference *)pReg;
627 				// sizeof( void ) not allowed
628 				pReg->nSize = ::typelib_typedescription_getAlignedUnoSize( pReg, 0, pReg->nAlignment );
629 				pReg->nAlignment = ::adjustAlignment( pReg->nAlignment );
630 				pReg->bComplete = sal_True;
631 
632 				::typelib_typedescription_register( &pReg );
633 				*ppRef = (typelib_TypeDescriptionReference *)pReg;
634 				OSL_ASSERT( *ppRef == pReg->pWeakRef );
635 			} else
636 				delete [] pDimensions;
637 			// another static ref:
638 			++((*ppRef)->nStaticRefCount);
639 		}
640 	}
641 }
642 
643 } // extern "C"
644 
645 }
646