xref: /AOO41X/main/cppu/source/typelib/static_types.cxx (revision 129fa3d1fc5edc85a690d91de1660cefa4e8a95b)
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