1 /* -*- Mode: C++; tab-width: 4; indent-tabs-mode: nil; c-basic-offset: 4 -*- */
2 /*
3 * This file is part of the LibreOffice project.
4 *
5 * This Source Code Form is subject to the terms of the Mozilla Public
6 * License, v. 2.0. If a copy of the MPL was not distributed with this
7 * file, You can obtain one at http://mozilla.org/MPL/2.0/.
8 *
9 * This file incorporates work covered by the following license notice:
10 *
11 * Licensed to the Apache Software Foundation (ASF) under one or more
12 * contributor license agreements. See the NOTICE file distributed
13 * with this work for additional information regarding copyright
14 * ownership. The ASF licenses this file to you under the Apache
15 * License, Version 2.0 (the "License"); you may not use this file
16 * except in compliance with the License. You may obtain a copy of
17 * the License at http://www.apache.org/licenses/LICENSE-2.0 .
18 */
19
20 #include <sal/config.h>
21
22 #include <algorithm>
23 #include <cassert>
24
25 #include <osl/mutex.hxx>
26 #include <rtl/ustring.hxx>
27 #include <rtl/instance.hxx>
28
29 #include <typelib/typedescription.h>
30 #include "typelib.hxx"
31
32
33 using namespace osl;
34
35 extern "C"
36 {
37
38
39 #ifdef _WIN32
40 #pragma pack(push, 8)
41 #endif
42
43 namespace {
44
45 /**
46 * The double member determines the alignment.
47 * Under OS2 and MS-Windows the Alignment is min( 8, sizeof( type ) ).
48 * The alignment of a structure is min( 8, sizeof( max basic type ) ), the greatest basic type
49 * determines the alignment.
50 */
51 struct AlignSize_Impl
52 {
53 sal_Int16 nInt16;
54 #ifdef AIX
55 //double: doubleword aligned if -qalign=natural/-malign=natural
56 //which isn't the default ABI. Otherwise word aligned, While a long long int
57 //is always doubleword aligned, so use that instead.
58 sal_Int64 dDouble;
59 #else
60 double dDouble;
61 #endif
62 };
63
64 }
65
66 #ifdef _WIN32
67 #pragma pack(pop)
68 #endif
69
70 // the value of the maximal alignment
71 const sal_Int32 nMaxAlignment = static_cast<sal_Int32>( reinterpret_cast<sal_Size>(&reinterpret_cast<AlignSize_Impl *>(16)->dDouble) - 16);
72
adjustAlignment(sal_Int32 nRequestedAlignment)73 static sal_Int32 adjustAlignment( sal_Int32 nRequestedAlignment )
74 {
75 if( nRequestedAlignment > nMaxAlignment )
76 nRequestedAlignment = nMaxAlignment;
77 return nRequestedAlignment;
78 }
79
80 /**
81 * Calculate the new size of the struktur.
82 */
newAlignedSize(sal_Int32 OldSize,sal_Int32 ElementSize,sal_Int32 NeededAlignment)83 static sal_Int32 newAlignedSize(
84 sal_Int32 OldSize, sal_Int32 ElementSize, sal_Int32 NeededAlignment )
85 {
86 NeededAlignment = adjustAlignment( NeededAlignment );
87 return (OldSize + NeededAlignment -1) / NeededAlignment * NeededAlignment + ElementSize;
88 }
89
90
91 namespace
92 {
93 struct typelib_StaticInitMutex : public rtl::Static< Mutex, typelib_StaticInitMutex > {};
94 }
95
96 // !for NOT REALLY WEAK TYPES only!
igetTypeByName(rtl_uString const * pTypeName)97 static typelib_TypeDescriptionReference * igetTypeByName( rtl_uString const * pTypeName )
98 {
99 typelib_TypeDescriptionReference * pRef = nullptr;
100 ::typelib_typedescriptionreference_getByName( &pRef, pTypeName );
101 if (pRef && pRef->pType && pRef->pType->pWeakRef) // found initialized td
102 {
103 return pRef;
104 }
105 return nullptr;
106 }
107
108 extern "C"
109 {
110
typelib_static_type_getByTypeClass(typelib_TypeClass eTypeClass)111 typelib_TypeDescriptionReference ** SAL_CALL typelib_static_type_getByTypeClass(
112 typelib_TypeClass eTypeClass )
113 SAL_THROW_EXTERN_C()
114 {
115 static typelib_TypeDescriptionReference * s_aTypes[] = {
116 nullptr, nullptr, nullptr, nullptr, nullptr, nullptr, nullptr, nullptr, nullptr, nullptr,
117 nullptr, nullptr, nullptr, nullptr, nullptr, nullptr, nullptr, nullptr, nullptr, nullptr,
118 nullptr, nullptr, nullptr };
119
120 if (! s_aTypes[eTypeClass])
121 {
122 MutexGuard aGuard( typelib_StaticInitMutex::get() );
123 if (! s_aTypes[eTypeClass])
124 {
125 static const char * s_aTypeNames[] = {
126 "void", "char", "boolean", "byte",
127 "short", "unsigned short", "long", "unsigned long",
128 "hyper", "unsigned hyper", "float", "double",
129 "string", "type", "any" };
130
131 switch (eTypeClass)
132 {
133 case typelib_TypeClass_EXCEPTION:
134 case typelib_TypeClass_INTERFACE:
135 {
136 // type
137 if (! s_aTypes[typelib_TypeClass_TYPE])
138 {
139 OUString sTypeName("type");
140 ::typelib_typedescriptionreference_new(
141 &s_aTypes[typelib_TypeClass_TYPE], typelib_TypeClass_TYPE, sTypeName.pData );
142 // another static ref:
143 ++s_aTypes[typelib_TypeClass_TYPE]->nStaticRefCount;
144 }
145 // any
146 if (! s_aTypes[typelib_TypeClass_ANY])
147 {
148 OUString sTypeName("any");
149 ::typelib_typedescriptionreference_new(
150 &s_aTypes[typelib_TypeClass_ANY], typelib_TypeClass_ANY, sTypeName.pData );
151 // another static ref:
152 ++s_aTypes[typelib_TypeClass_ANY]->nStaticRefCount;
153 }
154 // string
155 if (! s_aTypes[typelib_TypeClass_STRING])
156 {
157 OUString sTypeName("string");
158 ::typelib_typedescriptionreference_new(
159 &s_aTypes[typelib_TypeClass_STRING], typelib_TypeClass_STRING, sTypeName.pData );
160 // another static ref:
161 ++s_aTypes[typelib_TypeClass_STRING]->nStaticRefCount;
162 }
163 // XInterface
164 if (! s_aTypes[typelib_TypeClass_INTERFACE])
165 {
166 OUString sTypeName("com.sun.star.uno.XInterface");
167
168 typelib_InterfaceTypeDescription * pTD = nullptr;
169
170 typelib_TypeDescriptionReference * pMembers[3] = { nullptr,nullptr,nullptr };
171 OUString sMethodName0("com.sun.star.uno.XInterface::queryInterface");
172 ::typelib_typedescriptionreference_new(
173 &pMembers[0], typelib_TypeClass_INTERFACE_METHOD, sMethodName0.pData );
174 OUString sMethodName1("com.sun.star.uno.XInterface::acquire");
175 ::typelib_typedescriptionreference_new(
176 &pMembers[1], typelib_TypeClass_INTERFACE_METHOD, sMethodName1.pData );
177 OUString sMethodName2("com.sun.star.uno.XInterface::release");
178 ::typelib_typedescriptionreference_new(
179 &pMembers[2], typelib_TypeClass_INTERFACE_METHOD, sMethodName2.pData );
180
181 ::typelib_typedescription_newInterface(
182 &pTD, sTypeName.pData, 0, 0, 0, 0, 0, nullptr, 3, pMembers );
183
184 ::typelib_typedescription_register( reinterpret_cast<typelib_TypeDescription **>(&pTD) );
185 s_aTypes[typelib_TypeClass_INTERFACE] = pTD->aBase.pWeakRef;
186 ::typelib_typedescriptionreference_acquire(
187 s_aTypes[typelib_TypeClass_INTERFACE] );
188 // another static ref:
189 ++s_aTypes[typelib_TypeClass_INTERFACE]->nStaticRefCount;
190 ::typelib_typedescription_release( &pTD->aBase );
191
192 ::typelib_typedescriptionreference_release( pMembers[0] );
193 ::typelib_typedescriptionreference_release( pMembers[1] );
194 ::typelib_typedescriptionreference_release( pMembers[2] );
195 // Exception
196 assert( ! s_aTypes[typelib_TypeClass_EXCEPTION] );
197 {
198 typelib_TypeDescription * pTD1 = nullptr;
199 OUString sTypeName1("com.sun.star.uno.Exception");
200
201 typelib_CompoundMember_Init aMembers[2];
202 OUString sMemberType0("string");
203 OUString sMemberName0("Message");
204 aMembers[0].eTypeClass = typelib_TypeClass_STRING;
205 aMembers[0].pTypeName = sMemberType0.pData;
206 aMembers[0].pMemberName = sMemberName0.pData;
207 OUString sMemberType1("com.sun.star.uno.XInterface");
208 OUString sMemberName1("Context");
209 aMembers[1].eTypeClass = typelib_TypeClass_INTERFACE;
210 aMembers[1].pTypeName = sMemberType1.pData;
211 aMembers[1].pMemberName = sMemberName1.pData;
212
213 ::typelib_typedescription_new(
214 &pTD1, typelib_TypeClass_EXCEPTION, sTypeName1.pData, nullptr, 2, aMembers );
215 typelib_typedescription_register( &pTD1 );
216 s_aTypes[typelib_TypeClass_EXCEPTION] = pTD1->pWeakRef;
217 typelib_typedescriptionreference_acquire(
218 s_aTypes[typelib_TypeClass_EXCEPTION]);
219 // another static ref:
220 ++s_aTypes[typelib_TypeClass_EXCEPTION]->nStaticRefCount;
221 // RuntimeException
222 OUString sTypeName2("com.sun.star.uno.RuntimeException");
223 ::typelib_typedescription_new(
224 &pTD1, typelib_TypeClass_EXCEPTION, sTypeName2.pData, s_aTypes[typelib_TypeClass_EXCEPTION], 0, nullptr );
225 ::typelib_typedescription_register( &pTD1 );
226 ::typelib_typedescription_release( pTD1 );
227 }
228 // XInterface members
229 typelib_InterfaceMethodTypeDescription * pMethod = nullptr;
230 typelib_Parameter_Init aParameters[1];
231 OUString sParamName0("aType");
232 OUString sParamType0("type");
233 aParameters[0].pParamName = sParamName0.pData;
234 aParameters[0].eTypeClass = typelib_TypeClass_TYPE;
235 aParameters[0].pTypeName = sParamType0.pData;
236 aParameters[0].bIn = true;
237 aParameters[0].bOut = false;
238 rtl_uString * pExceptions[1];
239 OUString sExceptionName0("com.sun.star.uno.RuntimeException");
240 pExceptions[0] = sExceptionName0.pData;
241 OUString sReturnType0("any");
242 typelib_typedescription_newInterfaceMethod(
243 &pMethod, 0, false, sMethodName0.pData,
244 typelib_TypeClass_ANY, sReturnType0.pData,
245 1, aParameters, 1, pExceptions );
246 ::typelib_typedescription_register( reinterpret_cast<typelib_TypeDescription**>(&pMethod) );
247
248 OUString sReturnType1("void");
249 ::typelib_typedescription_newInterfaceMethod(
250 &pMethod, 1, true, sMethodName1.pData,
251 typelib_TypeClass_VOID, sReturnType1.pData, 0, nullptr, 0, nullptr );
252 ::typelib_typedescription_register( reinterpret_cast<typelib_TypeDescription**>(&pMethod) );
253
254 ::typelib_typedescription_newInterfaceMethod(
255 &pMethod, 2, true, sMethodName2.pData,
256 typelib_TypeClass_VOID, sReturnType1.pData,
257 0, nullptr, 0, nullptr );
258 ::typelib_typedescription_register( reinterpret_cast<typelib_TypeDescription**>(&pMethod) );
259 ::typelib_typedescription_release( &pMethod->aBase.aBase );
260 }
261 break;
262 }
263 default:
264 {
265 OUString aTypeName( OUString::createFromAscii( s_aTypeNames[eTypeClass] ) );
266 ::typelib_typedescriptionreference_new( &s_aTypes[eTypeClass], eTypeClass, aTypeName.pData );
267 // another static ref:
268 ++s_aTypes[eTypeClass]->nStaticRefCount;
269 }
270 }
271 }
272 }
273 return &s_aTypes[eTypeClass];
274 }
275
typelib_static_type_init(typelib_TypeDescriptionReference ** ppRef,typelib_TypeClass eTypeClass,const char * pTypeName)276 void SAL_CALL typelib_static_type_init(
277 typelib_TypeDescriptionReference ** ppRef,
278 typelib_TypeClass eTypeClass, const char * pTypeName )
279 SAL_THROW_EXTERN_C()
280 {
281 if (! *ppRef)
282 {
283 MutexGuard aGuard( typelib_StaticInitMutex::get() );
284 if (! *ppRef)
285 {
286 OUString aTypeName( OUString::createFromAscii( pTypeName ) );
287 ::typelib_typedescriptionreference_new( ppRef, eTypeClass, aTypeName.pData );
288
289 assert(*ppRef && "coverity[var_deref_op] - shouldn't be possible");
290 ++((*ppRef)->nStaticRefCount);
291 }
292 }
293 }
294
typelib_static_sequence_type_init(typelib_TypeDescriptionReference ** ppRef,typelib_TypeDescriptionReference * pElementType)295 void SAL_CALL typelib_static_sequence_type_init(
296 typelib_TypeDescriptionReference ** ppRef,
297 typelib_TypeDescriptionReference * pElementType )
298 SAL_THROW_EXTERN_C()
299 {
300 if ( *ppRef)
301 return;
302
303 MutexGuard aGuard( typelib_StaticInitMutex::get() );
304 if ( *ppRef)
305 return;
306
307 OUString aTypeName = "[]" + OUString::unacquired(&pElementType->pTypeName);
308
309 static_assert( ! TYPELIB_TYPEDESCRIPTIONREFERENCE_ISREALLYWEAK(typelib_TypeClass_SEQUENCE) );
310 *ppRef = igetTypeByName( aTypeName.pData );
311 if (!*ppRef)
312 {
313 typelib_TypeDescription * pReg = nullptr;
314 ::typelib_typedescription_new(
315 &pReg, typelib_TypeClass_SEQUENCE,
316 aTypeName.pData, pElementType, 0, nullptr );
317
318 ::typelib_typedescription_register( &pReg );
319 *ppRef = reinterpret_cast<typelib_TypeDescriptionReference *>(pReg);
320 assert( *ppRef == pReg->pWeakRef );
321 }
322 // another static ref:
323 ++((*ppRef)->nStaticRefCount);
324 }
325
326
327 namespace {
328
init(typelib_TypeDescriptionReference ** ppRef,typelib_TypeClass eTypeClass,const char * pTypeName,typelib_TypeDescriptionReference * pBaseType,sal_Int32 nMembers,typelib_TypeDescriptionReference ** ppMembers,sal_Bool const * pParameterizedTypes)329 void init(
330 typelib_TypeDescriptionReference ** ppRef,
331 typelib_TypeClass eTypeClass, const char * pTypeName,
332 typelib_TypeDescriptionReference * pBaseType,
333 sal_Int32 nMembers, typelib_TypeDescriptionReference ** ppMembers,
334 sal_Bool const * pParameterizedTypes)
335 {
336 assert( eTypeClass == typelib_TypeClass_STRUCT || eTypeClass == typelib_TypeClass_EXCEPTION );
337
338 if ( *ppRef)
339 return;
340
341 MutexGuard aGuard( typelib_StaticInitMutex::get() );
342 if ( *ppRef)
343 return;
344
345 assert( ! TYPELIB_TYPEDESCRIPTIONREFERENCE_ISREALLYWEAK(eTypeClass) );
346 OUString aTypeName( OUString::createFromAscii( pTypeName ) );
347 *ppRef = igetTypeByName( aTypeName.pData );
348 if (!*ppRef)
349 {
350 typelib_CompoundTypeDescription * pComp = nullptr;
351 ::typelib_typedescription_newEmpty(
352 reinterpret_cast<typelib_TypeDescription **>(&pComp), eTypeClass, aTypeName.pData );
353
354 sal_Int32 nOffset = 0;
355 if (pBaseType)
356 {
357 ::typelib_typedescriptionreference_getDescription(
358 reinterpret_cast<typelib_TypeDescription **>(&pComp->pBaseTypeDescription), pBaseType );
359 assert( pComp->pBaseTypeDescription );
360 nOffset = pComp->pBaseTypeDescription->aBase.nSize;
361 assert( newAlignedSize( 0, pComp->pBaseTypeDescription->aBase.nSize, pComp->pBaseTypeDescription->aBase.nAlignment ) == pComp->pBaseTypeDescription->aBase.nSize ); // unexpected offset
362 }
363
364 if (nMembers)
365 {
366 pComp->nMembers = nMembers;
367 pComp->pMemberOffsets = new sal_Int32[ nMembers ];
368 pComp->ppTypeRefs = new typelib_TypeDescriptionReference *[ nMembers ];
369 if (pParameterizedTypes != nullptr) {
370 reinterpret_cast< typelib_StructTypeDescription * >(
371 pComp)->pParameterizedTypes
372 = new sal_Bool[nMembers];
373 }
374 for ( sal_Int32 i = 0 ; i < nMembers; ++i )
375 {
376 pComp->ppTypeRefs[i] = ppMembers[i];
377 ::typelib_typedescriptionreference_acquire(
378 pComp->ppTypeRefs[i] );
379 // write offset
380 typelib_TypeDescription * pTD = nullptr;
381 TYPELIB_DANGER_GET( &pTD, pComp->ppTypeRefs[i] );
382 assert( pTD->nSize ); // void member?
383 nOffset = newAlignedSize( nOffset, pTD->nSize, pTD->nAlignment );
384 pComp->pMemberOffsets[i] = nOffset - pTD->nSize;
385 TYPELIB_DANGER_RELEASE( pTD );
386
387 if (pParameterizedTypes != nullptr) {
388 reinterpret_cast< typelib_StructTypeDescription * >(
389 pComp)->pParameterizedTypes[i]
390 = pParameterizedTypes[i];
391 }
392 }
393 }
394
395 typelib_TypeDescription * pReg = &pComp->aBase;
396 pReg->pWeakRef = reinterpret_cast<typelib_TypeDescriptionReference *>(pReg);
397 // sizeof(void) not allowed
398 pReg->nSize = ::typelib_typedescription_getAlignedUnoSize( pReg, 0, pReg->nAlignment );
399 pReg->nAlignment = adjustAlignment( pReg->nAlignment );
400 pReg->bComplete = false;
401
402 ::typelib_typedescription_register( &pReg );
403 *ppRef = reinterpret_cast<typelib_TypeDescriptionReference *>(pReg);
404 assert( *ppRef == pReg->pWeakRef );
405 }
406 // another static ref:
407 ++((*ppRef)->nStaticRefCount);
408 }
409
410 }
411
typelib_static_compound_type_init(typelib_TypeDescriptionReference ** ppRef,typelib_TypeClass eTypeClass,const char * pTypeName,typelib_TypeDescriptionReference * pBaseType,sal_Int32 nMembers,typelib_TypeDescriptionReference ** ppMembers)412 void SAL_CALL typelib_static_compound_type_init(
413 typelib_TypeDescriptionReference ** ppRef,
414 typelib_TypeClass eTypeClass, const char * pTypeName,
415 typelib_TypeDescriptionReference * pBaseType,
416 sal_Int32 nMembers, typelib_TypeDescriptionReference ** ppMembers )
417 SAL_THROW_EXTERN_C()
418 {
419 init(ppRef, eTypeClass, pTypeName, pBaseType, nMembers, ppMembers, nullptr);
420 }
421
typelib_static_struct_type_init(typelib_TypeDescriptionReference ** ppRef,const char * pTypeName,typelib_TypeDescriptionReference * pBaseType,sal_Int32 nMembers,typelib_TypeDescriptionReference ** ppMembers,sal_Bool const * pParameterizedTypes)422 void SAL_CALL typelib_static_struct_type_init(
423 typelib_TypeDescriptionReference ** ppRef, const char * pTypeName,
424 typelib_TypeDescriptionReference * pBaseType,
425 sal_Int32 nMembers, typelib_TypeDescriptionReference ** ppMembers,
426 sal_Bool const * pParameterizedTypes )
427 SAL_THROW_EXTERN_C()
428 {
429 init(
430 ppRef, typelib_TypeClass_STRUCT, pTypeName, pBaseType, nMembers,
431 ppMembers, pParameterizedTypes);
432 }
433
typelib_static_interface_type_init(typelib_TypeDescriptionReference ** ppRef,const char * pTypeName,typelib_TypeDescriptionReference * pBaseType)434 void SAL_CALL typelib_static_interface_type_init(
435 typelib_TypeDescriptionReference ** ppRef,
436 const char * pTypeName,
437 typelib_TypeDescriptionReference * pBaseType )
438 SAL_THROW_EXTERN_C()
439 {
440 // coverity[callee_ptr_arith] - not a bug
441 typelib_static_mi_interface_type_init(
442 ppRef, pTypeName, pBaseType == nullptr ? 0 : 1, &pBaseType);
443 }
444
typelib_static_mi_interface_type_init(typelib_TypeDescriptionReference ** ppRef,const char * pTypeName,sal_Int32 nBaseTypes,typelib_TypeDescriptionReference ** ppBaseTypes)445 void SAL_CALL typelib_static_mi_interface_type_init(
446 typelib_TypeDescriptionReference ** ppRef,
447 const char * pTypeName,
448 sal_Int32 nBaseTypes,
449 typelib_TypeDescriptionReference ** ppBaseTypes )
450 SAL_THROW_EXTERN_C()
451 {
452 if ( *ppRef)
453 return;
454
455 MutexGuard aGuard( typelib_StaticInitMutex::get() );
456 if ( *ppRef)
457 return;
458
459 static_assert( ! TYPELIB_TYPEDESCRIPTIONREFERENCE_ISREALLYWEAK(typelib_TypeClass_INTERFACE) );
460 OUString aTypeName( OUString::createFromAscii( pTypeName ) );
461 *ppRef = igetTypeByName( aTypeName.pData );
462 if (!*ppRef)
463 {
464 typelib_InterfaceTypeDescription * pIface = nullptr;
465 ::typelib_typedescription_newEmpty(
466 reinterpret_cast<typelib_TypeDescription **>(&pIface), typelib_TypeClass_INTERFACE, aTypeName.pData );
467
468 pIface->nBaseTypes = std::max< sal_Int32 >(nBaseTypes, 1);
469 pIface->ppBaseTypes = new typelib_InterfaceTypeDescription *[
470 pIface->nBaseTypes];
471 if (nBaseTypes > 0)
472 {
473 for (sal_Int32 i = 0; i < nBaseTypes; ++i) {
474 pIface->ppBaseTypes[i] = nullptr;
475 ::typelib_typedescriptionreference_getDescription(
476 reinterpret_cast<typelib_TypeDescription **>(&pIface->ppBaseTypes[i]), ppBaseTypes[i] );
477 assert( pIface->ppBaseTypes[i] );
478 }
479 }
480 else
481 {
482 pIface->ppBaseTypes[0] = nullptr;
483 ::typelib_typedescriptionreference_getDescription(
484 reinterpret_cast<typelib_TypeDescription **>(&pIface->ppBaseTypes[0]),
485 * ::typelib_static_type_getByTypeClass( typelib_TypeClass_INTERFACE ) );
486 assert( pIface->ppBaseTypes[0] );
487 }
488 pIface->pBaseTypeDescription = pIface->ppBaseTypes[0];
489 typelib_typedescription_acquire(
490 &pIface->pBaseTypeDescription->aBase);
491
492 typelib_TypeDescription * pReg = &pIface->aBase;
493 pReg->pWeakRef = reinterpret_cast<typelib_TypeDescriptionReference *>(pReg);
494 // sizeof(void) not allowed
495 pReg->nSize = ::typelib_typedescription_getAlignedUnoSize( pReg, 0, pReg->nAlignment );
496
497 pReg->nAlignment = adjustAlignment( pReg->nAlignment );
498 pReg->bComplete = false;
499
500 ::typelib_typedescription_register( &pReg );
501 *ppRef = reinterpret_cast<typelib_TypeDescriptionReference *>(pReg);
502 assert( *ppRef == pReg->pWeakRef );
503 }
504 // another static ref:
505 ++((*ppRef)->nStaticRefCount);
506 }
507
508
typelib_static_enum_type_init(typelib_TypeDescriptionReference ** ppRef,const char * pTypeName,sal_Int32 nDefaultValue)509 void SAL_CALL typelib_static_enum_type_init(
510 typelib_TypeDescriptionReference ** ppRef,
511 const char * pTypeName,
512 sal_Int32 nDefaultValue )
513 SAL_THROW_EXTERN_C()
514 {
515 if ( *ppRef)
516 return;
517
518 MutexGuard aGuard( typelib_StaticInitMutex::get() );
519 if ( *ppRef)
520 return;
521
522 static_assert( ! TYPELIB_TYPEDESCRIPTIONREFERENCE_ISREALLYWEAK(typelib_TypeClass_ENUM) );
523 OUString aTypeName( OUString::createFromAscii( pTypeName ) );
524 *ppRef = igetTypeByName( aTypeName.pData );
525 if (!*ppRef)
526 {
527 typelib_TypeDescription * pReg = nullptr;
528 ::typelib_typedescription_newEmpty(
529 &pReg, typelib_TypeClass_ENUM, aTypeName.pData );
530 typelib_EnumTypeDescription * pEnum = reinterpret_cast<typelib_EnumTypeDescription *>(pReg);
531
532 pEnum->nDefaultEnumValue = nDefaultValue;
533
534 pReg->pWeakRef = reinterpret_cast<typelib_TypeDescriptionReference *>(pReg);
535 // sizeof(void) not allowed
536 pReg->nSize = ::typelib_typedescription_getAlignedUnoSize( pReg, 0, pReg->nAlignment );
537 pReg->nAlignment = ::adjustAlignment( pReg->nAlignment );
538 pReg->bComplete = false;
539
540 ::typelib_typedescription_register( &pReg );
541 *ppRef = reinterpret_cast<typelib_TypeDescriptionReference *>(pReg);
542 assert( *ppRef == pReg->pWeakRef );
543 }
544 // another static ref:
545 ++((*ppRef)->nStaticRefCount);
546 }
547
548 } // extern "C"
549
550 }
551
552 /* vim:set shiftwidth=4 softtabstop=4 expandtab: */
553