fix baseline build (old cairo) - 'cairo_rectangle_int_t' does not name a type
[LibreOffice.git] / cppu / source / typelib / static_types.cxx
blob446671afd09ac74c6e0a48c670e2e289fcff7949
1 /* -*- Mode: C++; tab-width: 4; indent-tabs-mode: nil; c-basic-offset: 4 -*- */
2 /*
3 * This file is part of the LibreOffice project.
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/.
9 * This file incorporates work covered by the following license notice:
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 .
20 #include "sal/config.h"
22 #include <algorithm>
23 #include <cassert>
24 #include <stdarg.h>
26 #include <osl/mutex.hxx>
27 #include <osl/interlck.h>
28 #include <rtl/ustring.hxx>
29 #include <rtl/ustrbuf.hxx>
30 #include <rtl/instance.hxx>
32 #include <typelib/typedescription.h>
33 #include "typelib.hxx"
36 using namespace osl;
38 using ::rtl::OUString;
39 using ::rtl::OUStringBuffer;
41 extern "C"
45 #ifdef SAL_W32
46 #pragma pack(push, 8)
47 #endif
49 /**
50 * The double member determines the alignment.
51 * Under OS2 and MS-Windows the Alignment is min( 8, sizeof( type ) ).
52 * The alignment of a structure is min( 8, sizeof( max basic type ) ), the greatest basic type
53 * determines the alignment.
55 struct AlignSize_Impl
57 sal_Int16 nInt16;
58 #ifdef AIX
59 //double: doubleword aligned if -qalign=natural/-malign=natural
60 //which isn't the default ABI. Otherwise word aligned, While a long long int
61 //is always doubleword aligned, so use that instead.
62 sal_Int64 dDouble;
63 #else
64 double dDouble;
65 #endif
68 #ifdef SAL_W32
69 #pragma pack(pop)
70 #endif
72 // the value of the maximal alignment
73 static sal_Int32 nMaxAlignment = (sal_Int32)( reinterpret_cast<sal_Size>(&(reinterpret_cast<AlignSize_Impl *>(16))->dDouble) - 16);
75 static inline sal_Int32 adjustAlignment( sal_Int32 nRequestedAlignment )
77 if( nRequestedAlignment > nMaxAlignment )
78 nRequestedAlignment = nMaxAlignment;
79 return nRequestedAlignment;
82 /**
83 * Calculate the new size of the struktur.
85 static inline sal_Int32 newAlignedSize(
86 sal_Int32 OldSize, sal_Int32 ElementSize, sal_Int32 NeededAlignment )
88 NeededAlignment = adjustAlignment( NeededAlignment );
89 return (OldSize + NeededAlignment -1) / NeededAlignment * NeededAlignment + ElementSize;
94 namespace
96 struct typelib_StaticInitMutex : public rtl::Static< Mutex, typelib_StaticInitMutex > {};
99 // !for NOT REALLY WEAK TYPES only!
100 static inline typelib_TypeDescriptionReference * igetTypeByName( rtl_uString * pTypeName )
102 typelib_TypeDescriptionReference * pRef = 0;
103 ::typelib_typedescriptionreference_getByName( &pRef, pTypeName );
104 if (pRef && pRef->pType && pRef->pType->pWeakRef) // found initialized td
106 return pRef;
108 else
110 return 0;
114 extern "C"
117 typelib_TypeDescriptionReference ** SAL_CALL typelib_static_type_getByTypeClass(
118 typelib_TypeClass eTypeClass )
119 SAL_THROW_EXTERN_C()
121 static typelib_TypeDescriptionReference * s_aTypes[] = {
122 0, 0, 0, 0, 0, 0, 0, 0, 0, 0,
123 0, 0, 0, 0, 0, 0, 0, 0, 0, 0,
124 0, 0, 0 };
126 if (! s_aTypes[eTypeClass])
128 MutexGuard aGuard( typelib_StaticInitMutex::get() );
129 if (! s_aTypes[eTypeClass])
131 static const char * s_aTypeNames[] = {
132 "void", "char", "boolean", "byte",
133 "short", "unsigned short", "long", "unsigned long",
134 "hyper", "unsigned hyper", "float", "double",
135 "string", "type", "any" };
137 switch (eTypeClass)
139 case typelib_TypeClass_EXCEPTION:
140 case typelib_TypeClass_INTERFACE:
142 // type
143 if (! s_aTypes[typelib_TypeClass_TYPE])
145 OUString sTypeName("type");
146 ::typelib_typedescriptionreference_new(
147 &s_aTypes[typelib_TypeClass_TYPE], typelib_TypeClass_TYPE, sTypeName.pData );
148 // another static ref:
149 ++s_aTypes[typelib_TypeClass_TYPE]->nStaticRefCount;
151 // any
152 if (! s_aTypes[typelib_TypeClass_ANY])
154 OUString sTypeName("any");
155 ::typelib_typedescriptionreference_new(
156 &s_aTypes[typelib_TypeClass_ANY], typelib_TypeClass_ANY, sTypeName.pData );
157 // another static ref:
158 ++s_aTypes[typelib_TypeClass_ANY]->nStaticRefCount;
160 // string
161 if (! s_aTypes[typelib_TypeClass_STRING])
163 OUString sTypeName("string");
164 ::typelib_typedescriptionreference_new(
165 &s_aTypes[typelib_TypeClass_STRING], typelib_TypeClass_STRING, sTypeName.pData );
166 // another static ref:
167 ++s_aTypes[typelib_TypeClass_STRING]->nStaticRefCount;
169 // XInterface
170 if (! s_aTypes[typelib_TypeClass_INTERFACE])
172 OUString sTypeName("com.sun.star.uno.XInterface");
174 typelib_InterfaceTypeDescription * pTD = 0;
176 typelib_TypeDescriptionReference * pMembers[3] = { 0,0,0 };
177 OUString sMethodName0("com.sun.star.uno.XInterface::queryInterface");
178 ::typelib_typedescriptionreference_new(
179 &pMembers[0], typelib_TypeClass_INTERFACE_METHOD, sMethodName0.pData );
180 OUString sMethodName1("com.sun.star.uno.XInterface::acquire");
181 ::typelib_typedescriptionreference_new(
182 &pMembers[1], typelib_TypeClass_INTERFACE_METHOD, sMethodName1.pData );
183 OUString sMethodName2("com.sun.star.uno.XInterface::release");
184 ::typelib_typedescriptionreference_new(
185 &pMembers[2], typelib_TypeClass_INTERFACE_METHOD, sMethodName2.pData );
187 ::typelib_typedescription_newInterface(
188 &pTD, sTypeName.pData, 0, 0, 0, 0, 0, 0, 3, pMembers );
190 ::typelib_typedescription_register( reinterpret_cast<typelib_TypeDescription **>(&pTD) );
191 ::typelib_typedescriptionreference_acquire(
192 s_aTypes[typelib_TypeClass_INTERFACE] = pTD->aBase.pWeakRef );
193 // another static ref:
194 ++s_aTypes[typelib_TypeClass_INTERFACE]->nStaticRefCount;
195 ::typelib_typedescription_release( &pTD->aBase );
197 ::typelib_typedescriptionreference_release( pMembers[0] );
198 ::typelib_typedescriptionreference_release( pMembers[1] );
199 ::typelib_typedescriptionreference_release( pMembers[2] );
200 // Exception
201 assert( ! s_aTypes[typelib_TypeClass_EXCEPTION] );
203 typelib_TypeDescription * pTD1 = 0;
204 OUString sTypeName1("com.sun.star.uno.Exception");
206 typelib_CompoundMember_Init aMembers[2];
207 OUString sMemberType0("string");
208 OUString sMemberName0("Message");
209 aMembers[0].eTypeClass = typelib_TypeClass_STRING;
210 aMembers[0].pTypeName = sMemberType0.pData;
211 aMembers[0].pMemberName = sMemberName0.pData;
212 OUString sMemberType1("com.sun.star.uno.XInterface");
213 OUString sMemberName1("Context");
214 aMembers[1].eTypeClass = typelib_TypeClass_INTERFACE;
215 aMembers[1].pTypeName = sMemberType1.pData;
216 aMembers[1].pMemberName = sMemberName1.pData;
218 ::typelib_typedescription_new(
219 &pTD1, typelib_TypeClass_EXCEPTION, sTypeName1.pData, 0, 2, aMembers );
220 typelib_typedescription_register( &pTD1 );
221 typelib_typedescriptionreference_acquire(
222 s_aTypes[typelib_TypeClass_EXCEPTION] = pTD1->pWeakRef );
223 // another static ref:
224 ++s_aTypes[typelib_TypeClass_EXCEPTION]->nStaticRefCount;
225 // RuntimeException
226 OUString sTypeName2("com.sun.star.uno.RuntimeException");
227 ::typelib_typedescription_new(
228 &pTD1, typelib_TypeClass_EXCEPTION, sTypeName2.pData, s_aTypes[typelib_TypeClass_EXCEPTION], 0, 0 );
229 ::typelib_typedescription_register( &pTD1 );
230 ::typelib_typedescription_release( pTD1 );
232 // XInterface members
233 typelib_InterfaceMethodTypeDescription * pMethod = 0;
234 typelib_Parameter_Init aParameters[1];
235 OUString sParamName0("aType");
236 OUString sParamType0("type");
237 aParameters[0].pParamName = sParamName0.pData;
238 aParameters[0].eTypeClass = typelib_TypeClass_TYPE;
239 aParameters[0].pTypeName = sParamType0.pData;
240 aParameters[0].bIn = sal_True;
241 aParameters[0].bOut = sal_False;
242 rtl_uString * pExceptions[1];
243 OUString sExceptionName0("com.sun.star.uno.RuntimeException");
244 pExceptions[0] = sExceptionName0.pData;
245 OUString sReturnType0("any");
246 typelib_typedescription_newInterfaceMethod(
247 &pMethod, 0, sal_False, sMethodName0.pData,
248 typelib_TypeClass_ANY, sReturnType0.pData,
249 1, aParameters, 1, pExceptions );
250 ::typelib_typedescription_register( reinterpret_cast<typelib_TypeDescription**>(&pMethod) );
252 OUString sReturnType1("void");
253 ::typelib_typedescription_newInterfaceMethod(
254 &pMethod, 1, sal_True, sMethodName1.pData,
255 typelib_TypeClass_VOID, sReturnType1.pData, 0, 0, 0, 0 );
256 ::typelib_typedescription_register( reinterpret_cast<typelib_TypeDescription**>(&pMethod) );
258 ::typelib_typedescription_newInterfaceMethod(
259 &pMethod, 2, sal_True, sMethodName2.pData,
260 typelib_TypeClass_VOID, sReturnType1.pData,
261 0, 0, 0, 0 );
262 ::typelib_typedescription_register( reinterpret_cast<typelib_TypeDescription**>(&pMethod) );
263 ::typelib_typedescription_release( &pMethod->aBase.aBase );
265 break;
267 default:
269 OUString aTypeName( OUString::createFromAscii( s_aTypeNames[eTypeClass] ) );
270 ::typelib_typedescriptionreference_new( &s_aTypes[eTypeClass], eTypeClass, aTypeName.pData );
271 // another static ref:
272 ++s_aTypes[eTypeClass]->nStaticRefCount;
277 return &s_aTypes[eTypeClass];
280 void SAL_CALL typelib_static_type_init(
281 typelib_TypeDescriptionReference ** ppRef,
282 typelib_TypeClass eTypeClass, const sal_Char * pTypeName )
283 SAL_THROW_EXTERN_C()
285 if (! *ppRef)
287 MutexGuard aGuard( typelib_StaticInitMutex::get() );
288 if (! *ppRef)
290 OUString aTypeName( OUString::createFromAscii( pTypeName ) );
291 ::typelib_typedescriptionreference_new( ppRef, eTypeClass, aTypeName.pData );
293 // coverity[var_deref_op] - another static ref
294 ++((*ppRef)->nStaticRefCount);
299 void SAL_CALL typelib_static_sequence_type_init(
300 typelib_TypeDescriptionReference ** ppRef,
301 typelib_TypeDescriptionReference * pElementType )
302 SAL_THROW_EXTERN_C()
304 if (! *ppRef)
306 MutexGuard aGuard( typelib_StaticInitMutex::get() );
307 if (! *ppRef)
309 OUStringBuffer aBuf( 32 );
310 aBuf.appendAscii( "[]" );
311 aBuf.append( pElementType->pTypeName );
312 OUString aTypeName( aBuf.makeStringAndClear() );
314 assert( ! TYPELIB_TYPEDESCRIPTIONREFERENCE_ISREALLYWEAK(typelib_TypeClass_SEQUENCE) );
315 *ppRef = igetTypeByName( aTypeName.pData );
316 if (!*ppRef)
318 typelib_TypeDescription * pReg = 0;
319 ::typelib_typedescription_new(
320 &pReg, typelib_TypeClass_SEQUENCE,
321 aTypeName.pData, pElementType, 0, 0 );
323 ::typelib_typedescription_register( &pReg );
324 *ppRef = reinterpret_cast<typelib_TypeDescriptionReference *>(pReg);
325 assert( *ppRef == pReg->pWeakRef );
327 // another static ref:
328 ++((*ppRef)->nStaticRefCount);
334 namespace {
336 void init(
337 typelib_TypeDescriptionReference ** ppRef,
338 typelib_TypeClass eTypeClass, const sal_Char * pTypeName,
339 typelib_TypeDescriptionReference * pBaseType,
340 sal_Int32 nMembers, typelib_TypeDescriptionReference ** ppMembers,
341 sal_Bool const * pParameterizedTypes)
343 assert( eTypeClass == typelib_TypeClass_STRUCT || eTypeClass == typelib_TypeClass_EXCEPTION );
345 if (! *ppRef)
347 MutexGuard aGuard( typelib_StaticInitMutex::get() );
348 if (! *ppRef)
350 assert( ! TYPELIB_TYPEDESCRIPTIONREFERENCE_ISREALLYWEAK(eTypeClass) );
351 OUString aTypeName( OUString::createFromAscii( pTypeName ) );
352 *ppRef = igetTypeByName( aTypeName.pData );
353 if (!*ppRef)
355 typelib_CompoundTypeDescription * pComp = 0;
356 ::typelib_typedescription_newEmpty(
357 reinterpret_cast<typelib_TypeDescription **>(&pComp), eTypeClass, aTypeName.pData );
359 sal_Int32 nOffset = 0;
360 if (pBaseType)
362 ::typelib_typedescriptionreference_getDescription(
363 reinterpret_cast<typelib_TypeDescription **>(&pComp->pBaseTypeDescription), pBaseType );
364 assert( pComp->pBaseTypeDescription );
365 nOffset = pComp->pBaseTypeDescription->aBase.nSize;
366 assert( newAlignedSize( 0, pComp->pBaseTypeDescription->aBase.nSize, pComp->pBaseTypeDescription->aBase.nAlignment ) == pComp->pBaseTypeDescription->aBase.nSize ); // unexpected offset
369 if (nMembers)
371 pComp->nMembers = nMembers;
372 pComp->pMemberOffsets = new sal_Int32[ nMembers ];
373 pComp->ppTypeRefs = new typelib_TypeDescriptionReference *[ nMembers ];
374 if (pParameterizedTypes != 0) {
375 reinterpret_cast< typelib_StructTypeDescription * >(
376 pComp)->pParameterizedTypes
377 = new sal_Bool[nMembers];
379 for ( sal_Int32 i = 0 ; i < nMembers; ++i )
381 ::typelib_typedescriptionreference_acquire(
382 pComp->ppTypeRefs[i] = ppMembers[i] );
383 // write offset
384 typelib_TypeDescription * pTD = 0;
385 TYPELIB_DANGER_GET( &pTD, pComp->ppTypeRefs[i] );
386 assert( pTD->nSize ); // void member?
387 nOffset = newAlignedSize( nOffset, pTD->nSize, pTD->nAlignment );
388 pComp->pMemberOffsets[i] = nOffset - pTD->nSize;
389 TYPELIB_DANGER_RELEASE( pTD );
391 if (pParameterizedTypes != 0) {
392 reinterpret_cast< typelib_StructTypeDescription * >(
393 pComp)->pParameterizedTypes[i]
394 = pParameterizedTypes[i];
399 typelib_TypeDescription * pReg = &pComp->aBase;
400 pReg->pWeakRef = reinterpret_cast<typelib_TypeDescriptionReference *>(pReg);
401 // sizeof(void) not allowed
402 pReg->nSize = ::typelib_typedescription_getAlignedUnoSize( pReg, 0, pReg->nAlignment );
403 pReg->nAlignment = adjustAlignment( pReg->nAlignment );
404 pReg->bComplete = sal_False;
406 ::typelib_typedescription_register( &pReg );
407 *ppRef = reinterpret_cast<typelib_TypeDescriptionReference *>(pReg);
408 assert( *ppRef == pReg->pWeakRef );
410 // another static ref:
411 ++((*ppRef)->nStaticRefCount);
418 void SAL_CALL typelib_static_compound_type_init(
419 typelib_TypeDescriptionReference ** ppRef,
420 typelib_TypeClass eTypeClass, const sal_Char * pTypeName,
421 typelib_TypeDescriptionReference * pBaseType,
422 sal_Int32 nMembers, typelib_TypeDescriptionReference ** ppMembers )
423 SAL_THROW_EXTERN_C()
425 init(ppRef, eTypeClass, pTypeName, pBaseType, nMembers, ppMembers, 0);
428 void SAL_CALL typelib_static_struct_type_init(
429 typelib_TypeDescriptionReference ** ppRef, const sal_Char * pTypeName,
430 typelib_TypeDescriptionReference * pBaseType,
431 sal_Int32 nMembers, typelib_TypeDescriptionReference ** ppMembers,
432 sal_Bool const * pParameterizedTypes )
433 SAL_THROW_EXTERN_C()
435 init(
436 ppRef, typelib_TypeClass_STRUCT, pTypeName, pBaseType, nMembers,
437 ppMembers, pParameterizedTypes);
440 void SAL_CALL typelib_static_interface_type_init(
441 typelib_TypeDescriptionReference ** ppRef,
442 const sal_Char * pTypeName,
443 typelib_TypeDescriptionReference * pBaseType )
444 SAL_THROW_EXTERN_C()
446 // coverity[callee_ptr_arith]
447 typelib_static_mi_interface_type_init(
448 ppRef, pTypeName, pBaseType == 0 ? 0 : 1, &pBaseType);
451 void SAL_CALL typelib_static_mi_interface_type_init(
452 typelib_TypeDescriptionReference ** ppRef,
453 const sal_Char * pTypeName,
454 sal_Int32 nBaseTypes,
455 typelib_TypeDescriptionReference ** ppBaseTypes )
456 SAL_THROW_EXTERN_C()
458 if (! *ppRef)
460 MutexGuard aGuard( typelib_StaticInitMutex::get() );
461 if (! *ppRef)
463 assert( ! TYPELIB_TYPEDESCRIPTIONREFERENCE_ISREALLYWEAK(typelib_TypeClass_INTERFACE) );
464 OUString aTypeName( OUString::createFromAscii( pTypeName ) );
465 *ppRef = igetTypeByName( aTypeName.pData );
466 if (!*ppRef)
468 typelib_InterfaceTypeDescription * pIface = 0;
469 ::typelib_typedescription_newEmpty(
470 reinterpret_cast<typelib_TypeDescription **>(&pIface), typelib_TypeClass_INTERFACE, aTypeName.pData );
472 pIface->nBaseTypes = std::max< sal_Int32 >(nBaseTypes, 1);
473 pIface->ppBaseTypes = new typelib_InterfaceTypeDescription *[
474 pIface->nBaseTypes];
475 if (nBaseTypes > 0)
477 for (sal_Int32 i = 0; i < nBaseTypes; ++i) {
478 pIface->ppBaseTypes[i] = 0;
479 ::typelib_typedescriptionreference_getDescription(
480 reinterpret_cast<typelib_TypeDescription **>(&pIface->ppBaseTypes[i]), ppBaseTypes[i] );
481 assert( pIface->ppBaseTypes[i] );
484 else
486 pIface->ppBaseTypes[0] = 0;
487 ::typelib_typedescriptionreference_getDescription(
488 reinterpret_cast<typelib_TypeDescription **>(&pIface->ppBaseTypes[0]),
489 * ::typelib_static_type_getByTypeClass( typelib_TypeClass_INTERFACE ) );
490 assert( pIface->ppBaseTypes[0] );
492 pIface->pBaseTypeDescription = pIface->ppBaseTypes[0];
493 typelib_typedescription_acquire(
494 &pIface->pBaseTypeDescription->aBase);
496 typelib_TypeDescription * pReg = &pIface->aBase;
497 pReg->pWeakRef = reinterpret_cast<typelib_TypeDescriptionReference *>(pReg);
498 // sizeof(void) not allowed
499 pReg->nSize = ::typelib_typedescription_getAlignedUnoSize( pReg, 0, pReg->nAlignment );
501 pReg->nAlignment = adjustAlignment( pReg->nAlignment );
502 pReg->bComplete = sal_False;
504 ::typelib_typedescription_register( &pReg );
505 *ppRef = reinterpret_cast<typelib_TypeDescriptionReference *>(pReg);
506 assert( *ppRef == pReg->pWeakRef );
508 // another static ref:
509 ++((*ppRef)->nStaticRefCount);
515 void SAL_CALL typelib_static_enum_type_init(
516 typelib_TypeDescriptionReference ** ppRef,
517 const sal_Char * pTypeName,
518 sal_Int32 nDefaultValue )
519 SAL_THROW_EXTERN_C()
521 if (! *ppRef)
523 MutexGuard aGuard( typelib_StaticInitMutex::get() );
524 if (! *ppRef)
526 assert( ! TYPELIB_TYPEDESCRIPTIONREFERENCE_ISREALLYWEAK(typelib_TypeClass_ENUM) );
527 OUString aTypeName( OUString::createFromAscii( pTypeName ) );
528 *ppRef = igetTypeByName( aTypeName.pData );
529 if (!*ppRef)
531 typelib_TypeDescription * pReg = 0;
532 ::typelib_typedescription_newEmpty(
533 &pReg, typelib_TypeClass_ENUM, aTypeName.pData );
534 typelib_EnumTypeDescription * pEnum = reinterpret_cast<typelib_EnumTypeDescription *>(pReg);
536 pEnum->nDefaultEnumValue = nDefaultValue;
538 pReg->pWeakRef = reinterpret_cast<typelib_TypeDescriptionReference *>(pReg);
539 // sizeof(void) not allowed
540 pReg->nSize = ::typelib_typedescription_getAlignedUnoSize( pReg, 0, pReg->nAlignment );
541 pReg->nAlignment = ::adjustAlignment( pReg->nAlignment );
542 pReg->bComplete = sal_False;
544 ::typelib_typedescription_register( &pReg );
545 *ppRef = reinterpret_cast<typelib_TypeDescriptionReference *>(pReg);
546 assert( *ppRef == pReg->pWeakRef );
548 // another static ref:
549 ++((*ppRef)->nStaticRefCount);
554 } // extern "C"
558 /* vim:set shiftwidth=4 softtabstop=4 expandtab: */