1 /* -*- Mode: C++; tab-width: 4; indent-tabs-mode: nil; c-basic-offset: 4 -*- */
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>
25 #include <osl/mutex.hxx>
26 #include <rtl/ustring.hxx>
28 #include <typelib/typedescription.h>
29 #include "typelib.hxx"
36 Mutex
& typelib_StaticInitMutex()
38 static Mutex SINGLETON
;
54 * The double member determines the alignment.
55 * Under OS2 and MS-Windows the Alignment is min( 8, sizeof( type ) ).
56 * The alignment of a structure is min( 8, sizeof( max basic type ) ), the greatest basic type
57 * determines the alignment.
63 //double: doubleword aligned if -qalign=natural/-malign=natural
64 //which isn't the default ABI. Otherwise word aligned, While a long long int
65 //is always doubleword aligned, so use that instead.
78 // the value of the maximal alignment
79 const sal_Int32 nMaxAlignment
= static_cast<sal_Int32
>( reinterpret_cast<sal_Size
>(&reinterpret_cast<AlignSize_Impl
*>(16)->dDouble
) - 16);
81 static sal_Int32
adjustAlignment( sal_Int32 nRequestedAlignment
)
83 if( nRequestedAlignment
> nMaxAlignment
)
84 nRequestedAlignment
= nMaxAlignment
;
85 return nRequestedAlignment
;
89 * Calculate the new size of the struktur.
91 static sal_Int32
newAlignedSize(
92 sal_Int32 OldSize
, sal_Int32 ElementSize
, sal_Int32 NeededAlignment
)
94 NeededAlignment
= adjustAlignment( NeededAlignment
);
95 return (OldSize
+ NeededAlignment
-1) / NeededAlignment
* NeededAlignment
+ ElementSize
;
99 // !for NOT REALLY WEAK TYPES only!
100 static typelib_TypeDescriptionReference
* igetTypeByName( rtl_uString
const * pTypeName
)
102 typelib_TypeDescriptionReference
* pRef
= nullptr;
103 ::typelib_typedescriptionreference_getByName( &pRef
, pTypeName
);
104 if (pRef
&& pRef
->pType
&& pRef
->pType
->pWeakRef
) // found initialized td
114 typelib_TypeDescriptionReference
** SAL_CALL
typelib_static_type_getByTypeClass(
115 typelib_TypeClass eTypeClass
)
118 static typelib_TypeDescriptionReference
* s_aTypes
[] = {
119 nullptr, nullptr, nullptr, nullptr, nullptr, nullptr, nullptr, nullptr, nullptr, nullptr,
120 nullptr, nullptr, nullptr, nullptr, nullptr, nullptr, nullptr, nullptr, nullptr, nullptr,
121 nullptr, nullptr, nullptr };
123 if (! s_aTypes
[eTypeClass
])
125 MutexGuard
aGuard( typelib_StaticInitMutex() );
126 if (! s_aTypes
[eTypeClass
])
128 static const char * s_aTypeNames
[] = {
129 "void", "char", "boolean", "byte",
130 "short", "unsigned short", "long", "unsigned long",
131 "hyper", "unsigned hyper", "float", "double",
132 "string", "type", "any" };
136 case typelib_TypeClass_EXCEPTION
:
137 case typelib_TypeClass_INTERFACE
:
140 if (! s_aTypes
[typelib_TypeClass_TYPE
])
142 OUString
sTypeName("type");
143 ::typelib_typedescriptionreference_new(
144 &s_aTypes
[typelib_TypeClass_TYPE
], typelib_TypeClass_TYPE
, sTypeName
.pData
);
145 // another static ref:
146 ++s_aTypes
[typelib_TypeClass_TYPE
]->nStaticRefCount
;
149 if (! s_aTypes
[typelib_TypeClass_ANY
])
151 OUString
sTypeName("any");
152 ::typelib_typedescriptionreference_new(
153 &s_aTypes
[typelib_TypeClass_ANY
], typelib_TypeClass_ANY
, sTypeName
.pData
);
154 // another static ref:
155 ++s_aTypes
[typelib_TypeClass_ANY
]->nStaticRefCount
;
158 if (! s_aTypes
[typelib_TypeClass_STRING
])
160 OUString
sTypeName("string");
161 ::typelib_typedescriptionreference_new(
162 &s_aTypes
[typelib_TypeClass_STRING
], typelib_TypeClass_STRING
, sTypeName
.pData
);
163 // another static ref:
164 ++s_aTypes
[typelib_TypeClass_STRING
]->nStaticRefCount
;
167 if (! s_aTypes
[typelib_TypeClass_INTERFACE
])
169 OUString
sTypeName("com.sun.star.uno.XInterface");
171 typelib_InterfaceTypeDescription
* pTD
= nullptr;
173 typelib_TypeDescriptionReference
* pMembers
[3] = { nullptr,nullptr,nullptr };
174 OUString
sMethodName0("com.sun.star.uno.XInterface::queryInterface");
175 ::typelib_typedescriptionreference_new(
176 &pMembers
[0], typelib_TypeClass_INTERFACE_METHOD
, sMethodName0
.pData
);
177 OUString
sMethodName1("com.sun.star.uno.XInterface::acquire");
178 ::typelib_typedescriptionreference_new(
179 &pMembers
[1], typelib_TypeClass_INTERFACE_METHOD
, sMethodName1
.pData
);
180 OUString
sMethodName2("com.sun.star.uno.XInterface::release");
181 ::typelib_typedescriptionreference_new(
182 &pMembers
[2], typelib_TypeClass_INTERFACE_METHOD
, sMethodName2
.pData
);
184 ::typelib_typedescription_newInterface(
185 &pTD
, sTypeName
.pData
, 0, 0, 0, 0, 0, nullptr, 3, pMembers
);
187 ::typelib_typedescription_register( reinterpret_cast<typelib_TypeDescription
**>(&pTD
) );
188 s_aTypes
[typelib_TypeClass_INTERFACE
] = pTD
->aBase
.pWeakRef
;
189 ::typelib_typedescriptionreference_acquire(
190 s_aTypes
[typelib_TypeClass_INTERFACE
] );
191 // another static ref:
192 ++s_aTypes
[typelib_TypeClass_INTERFACE
]->nStaticRefCount
;
193 ::typelib_typedescription_release( &pTD
->aBase
);
195 ::typelib_typedescriptionreference_release( pMembers
[0] );
196 ::typelib_typedescriptionreference_release( pMembers
[1] );
197 ::typelib_typedescriptionreference_release( pMembers
[2] );
199 assert( ! s_aTypes
[typelib_TypeClass_EXCEPTION
] );
201 typelib_TypeDescription
* pTD1
= nullptr;
202 OUString
sTypeName1("com.sun.star.uno.Exception");
204 typelib_CompoundMember_Init aMembers
[2];
205 OUString
sMemberType0("string");
206 OUString
sMemberName0("Message");
207 aMembers
[0].eTypeClass
= typelib_TypeClass_STRING
;
208 aMembers
[0].pTypeName
= sMemberType0
.pData
;
209 aMembers
[0].pMemberName
= sMemberName0
.pData
;
210 OUString
sMemberType1("com.sun.star.uno.XInterface");
211 OUString
sMemberName1("Context");
212 aMembers
[1].eTypeClass
= typelib_TypeClass_INTERFACE
;
213 aMembers
[1].pTypeName
= sMemberType1
.pData
;
214 aMembers
[1].pMemberName
= sMemberName1
.pData
;
216 ::typelib_typedescription_new(
217 &pTD1
, typelib_TypeClass_EXCEPTION
, sTypeName1
.pData
, nullptr, 2, aMembers
);
218 typelib_typedescription_register( &pTD1
);
219 s_aTypes
[typelib_TypeClass_EXCEPTION
] = pTD1
->pWeakRef
;
220 typelib_typedescriptionreference_acquire(
221 s_aTypes
[typelib_TypeClass_EXCEPTION
]);
222 // another static ref:
223 ++s_aTypes
[typelib_TypeClass_EXCEPTION
]->nStaticRefCount
;
225 OUString
sTypeName2("com.sun.star.uno.RuntimeException");
226 ::typelib_typedescription_new(
227 &pTD1
, typelib_TypeClass_EXCEPTION
, sTypeName2
.pData
, s_aTypes
[typelib_TypeClass_EXCEPTION
], 0, nullptr );
228 ::typelib_typedescription_register( &pTD1
);
229 ::typelib_typedescription_release( pTD1
);
231 // XInterface members
232 typelib_InterfaceMethodTypeDescription
* pMethod
= nullptr;
233 typelib_Parameter_Init aParameters
[1];
234 OUString
sParamName0("aType");
235 OUString
sParamType0("type");
236 aParameters
[0].pParamName
= sParamName0
.pData
;
237 aParameters
[0].eTypeClass
= typelib_TypeClass_TYPE
;
238 aParameters
[0].pTypeName
= sParamType0
.pData
;
239 aParameters
[0].bIn
= true;
240 aParameters
[0].bOut
= false;
241 rtl_uString
* pExceptions
[1];
242 OUString
sExceptionName0("com.sun.star.uno.RuntimeException");
243 pExceptions
[0] = sExceptionName0
.pData
;
244 OUString
sReturnType0("any");
245 typelib_typedescription_newInterfaceMethod(
246 &pMethod
, 0, false, sMethodName0
.pData
,
247 typelib_TypeClass_ANY
, sReturnType0
.pData
,
248 1, aParameters
, 1, pExceptions
);
249 ::typelib_typedescription_register( reinterpret_cast<typelib_TypeDescription
**>(&pMethod
) );
251 OUString
sReturnType1("void");
252 ::typelib_typedescription_newInterfaceMethod(
253 &pMethod
, 1, true, sMethodName1
.pData
,
254 typelib_TypeClass_VOID
, sReturnType1
.pData
, 0, nullptr, 0, nullptr );
255 ::typelib_typedescription_register( reinterpret_cast<typelib_TypeDescription
**>(&pMethod
) );
257 ::typelib_typedescription_newInterfaceMethod(
258 &pMethod
, 2, true, sMethodName2
.pData
,
259 typelib_TypeClass_VOID
, sReturnType1
.pData
,
260 0, nullptr, 0, nullptr );
261 ::typelib_typedescription_register( reinterpret_cast<typelib_TypeDescription
**>(&pMethod
) );
262 ::typelib_typedescription_release( &pMethod
->aBase
.aBase
);
268 OUString
aTypeName( OUString::createFromAscii( s_aTypeNames
[eTypeClass
] ) );
269 ::typelib_typedescriptionreference_new( &s_aTypes
[eTypeClass
], eTypeClass
, aTypeName
.pData
);
270 // another static ref:
271 ++s_aTypes
[eTypeClass
]->nStaticRefCount
;
276 return &s_aTypes
[eTypeClass
];
279 void SAL_CALL
typelib_static_type_init(
280 typelib_TypeDescriptionReference
** ppRef
,
281 typelib_TypeClass eTypeClass
, const char * pTypeName
)
286 MutexGuard
aGuard( typelib_StaticInitMutex() );
289 OUString
aTypeName( OUString::createFromAscii( pTypeName
) );
290 ::typelib_typedescriptionreference_new( ppRef
, eTypeClass
, aTypeName
.pData
);
292 assert(*ppRef
&& "coverity[var_deref_op] - shouldn't be possible");
293 ++((*ppRef
)->nStaticRefCount
);
298 void SAL_CALL
typelib_static_sequence_type_init(
299 typelib_TypeDescriptionReference
** ppRef
,
300 typelib_TypeDescriptionReference
* pElementType
)
306 MutexGuard
aGuard( typelib_StaticInitMutex() );
310 OUString aTypeName
= "[]" + OUString::unacquired(&pElementType
->pTypeName
);
312 static_assert( ! TYPELIB_TYPEDESCRIPTIONREFERENCE_ISREALLYWEAK(typelib_TypeClass_SEQUENCE
) );
313 *ppRef
= igetTypeByName( aTypeName
.pData
);
316 typelib_TypeDescription
* pReg
= nullptr;
317 ::typelib_typedescription_new(
318 &pReg
, typelib_TypeClass_SEQUENCE
,
319 aTypeName
.pData
, pElementType
, 0, nullptr );
321 ::typelib_typedescription_register( &pReg
);
322 *ppRef
= reinterpret_cast<typelib_TypeDescriptionReference
*>(pReg
);
323 assert( *ppRef
== pReg
->pWeakRef
);
325 // another static ref:
326 ++((*ppRef
)->nStaticRefCount
);
333 typelib_TypeDescriptionReference
** ppRef
,
334 typelib_TypeClass eTypeClass
, const char * pTypeName
,
335 typelib_TypeDescriptionReference
* pBaseType
,
336 sal_Int32 nMembers
, typelib_TypeDescriptionReference
** ppMembers
,
337 sal_Bool
const * pParameterizedTypes
)
339 assert( eTypeClass
== typelib_TypeClass_STRUCT
|| eTypeClass
== typelib_TypeClass_EXCEPTION
);
344 MutexGuard
aGuard( typelib_StaticInitMutex() );
348 assert( ! TYPELIB_TYPEDESCRIPTIONREFERENCE_ISREALLYWEAK(eTypeClass
) );
349 OUString
aTypeName( OUString::createFromAscii( pTypeName
) );
350 *ppRef
= igetTypeByName( aTypeName
.pData
);
353 typelib_CompoundTypeDescription
* pComp
= nullptr;
354 ::typelib_typedescription_newEmpty(
355 reinterpret_cast<typelib_TypeDescription
**>(&pComp
), eTypeClass
, aTypeName
.pData
);
357 sal_Int32 nOffset
= 0;
360 ::typelib_typedescriptionreference_getDescription(
361 reinterpret_cast<typelib_TypeDescription
**>(&pComp
->pBaseTypeDescription
), pBaseType
);
362 assert( pComp
->pBaseTypeDescription
);
363 nOffset
= pComp
->pBaseTypeDescription
->aBase
.nSize
;
364 assert( newAlignedSize( 0, pComp
->pBaseTypeDescription
->aBase
.nSize
, pComp
->pBaseTypeDescription
->aBase
.nAlignment
) == pComp
->pBaseTypeDescription
->aBase
.nSize
); // unexpected offset
369 pComp
->nMembers
= nMembers
;
370 pComp
->pMemberOffsets
= new sal_Int32
[ nMembers
];
371 pComp
->ppTypeRefs
= new typelib_TypeDescriptionReference
*[ nMembers
];
372 if (pParameterizedTypes
!= nullptr) {
373 reinterpret_cast< typelib_StructTypeDescription
* >(
374 pComp
)->pParameterizedTypes
375 = new sal_Bool
[nMembers
];
377 for ( sal_Int32 i
= 0 ; i
< nMembers
; ++i
)
379 pComp
->ppTypeRefs
[i
] = ppMembers
[i
];
380 ::typelib_typedescriptionreference_acquire(
381 pComp
->ppTypeRefs
[i
] );
383 typelib_TypeDescription
* pTD
= nullptr;
384 TYPELIB_DANGER_GET( &pTD
, pComp
->ppTypeRefs
[i
] );
385 assert( pTD
->nSize
); // void member?
386 nOffset
= newAlignedSize( nOffset
, pTD
->nSize
, pTD
->nAlignment
);
387 pComp
->pMemberOffsets
[i
] = nOffset
- pTD
->nSize
;
388 TYPELIB_DANGER_RELEASE( pTD
);
390 if (pParameterizedTypes
!= nullptr) {
391 reinterpret_cast< typelib_StructTypeDescription
* >(
392 pComp
)->pParameterizedTypes
[i
]
393 = pParameterizedTypes
[i
];
398 typelib_TypeDescription
* pReg
= &pComp
->aBase
;
399 pReg
->pWeakRef
= reinterpret_cast<typelib_TypeDescriptionReference
*>(pReg
);
400 // sizeof(void) not allowed
401 pReg
->nSize
= ::typelib_typedescription_getAlignedUnoSize( pReg
, 0, pReg
->nAlignment
);
402 pReg
->nAlignment
= adjustAlignment( pReg
->nAlignment
);
403 pReg
->bComplete
= false;
405 ::typelib_typedescription_register( &pReg
);
406 *ppRef
= reinterpret_cast<typelib_TypeDescriptionReference
*>(pReg
);
407 assert( *ppRef
== pReg
->pWeakRef
);
409 // another static ref:
410 ++((*ppRef
)->nStaticRefCount
);
415 void SAL_CALL
typelib_static_compound_type_init(
416 typelib_TypeDescriptionReference
** ppRef
,
417 typelib_TypeClass eTypeClass
, const char * pTypeName
,
418 typelib_TypeDescriptionReference
* pBaseType
,
419 sal_Int32 nMembers
, typelib_TypeDescriptionReference
** ppMembers
)
422 init(ppRef
, eTypeClass
, pTypeName
, pBaseType
, nMembers
, ppMembers
, nullptr);
425 void SAL_CALL
typelib_static_struct_type_init(
426 typelib_TypeDescriptionReference
** ppRef
, const char * pTypeName
,
427 typelib_TypeDescriptionReference
* pBaseType
,
428 sal_Int32 nMembers
, typelib_TypeDescriptionReference
** ppMembers
,
429 sal_Bool
const * pParameterizedTypes
)
433 ppRef
, typelib_TypeClass_STRUCT
, pTypeName
, pBaseType
, nMembers
,
434 ppMembers
, pParameterizedTypes
);
437 void SAL_CALL
typelib_static_interface_type_init(
438 typelib_TypeDescriptionReference
** ppRef
,
439 const char * pTypeName
,
440 typelib_TypeDescriptionReference
* pBaseType
)
443 // coverity[callee_ptr_arith] - not a bug
444 typelib_static_mi_interface_type_init(
445 ppRef
, pTypeName
, pBaseType
== nullptr ? 0 : 1, &pBaseType
);
448 void SAL_CALL
typelib_static_mi_interface_type_init(
449 typelib_TypeDescriptionReference
** ppRef
,
450 const char * pTypeName
,
451 sal_Int32 nBaseTypes
,
452 typelib_TypeDescriptionReference
** ppBaseTypes
)
458 MutexGuard
aGuard( typelib_StaticInitMutex() );
462 static_assert( ! TYPELIB_TYPEDESCRIPTIONREFERENCE_ISREALLYWEAK(typelib_TypeClass_INTERFACE
) );
463 OUString
aTypeName( OUString::createFromAscii( pTypeName
) );
464 *ppRef
= igetTypeByName( aTypeName
.pData
);
467 typelib_InterfaceTypeDescription
* pIface
= nullptr;
468 ::typelib_typedescription_newEmpty(
469 reinterpret_cast<typelib_TypeDescription
**>(&pIface
), typelib_TypeClass_INTERFACE
, aTypeName
.pData
);
471 pIface
->nBaseTypes
= std::max
< sal_Int32
>(nBaseTypes
, 1);
472 pIface
->ppBaseTypes
= new typelib_InterfaceTypeDescription
*[
476 for (sal_Int32 i
= 0; i
< nBaseTypes
; ++i
) {
477 pIface
->ppBaseTypes
[i
] = nullptr;
478 ::typelib_typedescriptionreference_getDescription(
479 reinterpret_cast<typelib_TypeDescription
**>(&pIface
->ppBaseTypes
[i
]), ppBaseTypes
[i
] );
480 assert( pIface
->ppBaseTypes
[i
] );
485 pIface
->ppBaseTypes
[0] = nullptr;
486 ::typelib_typedescriptionreference_getDescription(
487 reinterpret_cast<typelib_TypeDescription
**>(&pIface
->ppBaseTypes
[0]),
488 * ::typelib_static_type_getByTypeClass( typelib_TypeClass_INTERFACE
) );
489 assert( pIface
->ppBaseTypes
[0] );
491 pIface
->pBaseTypeDescription
= pIface
->ppBaseTypes
[0];
492 typelib_typedescription_acquire(
493 &pIface
->pBaseTypeDescription
->aBase
);
495 typelib_TypeDescription
* pReg
= &pIface
->aBase
;
496 pReg
->pWeakRef
= reinterpret_cast<typelib_TypeDescriptionReference
*>(pReg
);
497 // sizeof(void) not allowed
498 pReg
->nSize
= ::typelib_typedescription_getAlignedUnoSize( pReg
, 0, pReg
->nAlignment
);
500 pReg
->nAlignment
= adjustAlignment( pReg
->nAlignment
);
501 pReg
->bComplete
= false;
503 ::typelib_typedescription_register( &pReg
);
504 *ppRef
= reinterpret_cast<typelib_TypeDescriptionReference
*>(pReg
);
505 assert( *ppRef
== pReg
->pWeakRef
);
507 // another static ref:
508 ++((*ppRef
)->nStaticRefCount
);
512 void SAL_CALL
typelib_static_enum_type_init(
513 typelib_TypeDescriptionReference
** ppRef
,
514 const char * pTypeName
,
515 sal_Int32 nDefaultValue
)
521 MutexGuard
aGuard( typelib_StaticInitMutex() );
525 static_assert( ! TYPELIB_TYPEDESCRIPTIONREFERENCE_ISREALLYWEAK(typelib_TypeClass_ENUM
) );
526 OUString
aTypeName( OUString::createFromAscii( pTypeName
) );
527 *ppRef
= igetTypeByName( aTypeName
.pData
);
530 typelib_TypeDescription
* pReg
= nullptr;
531 ::typelib_typedescription_newEmpty(
532 &pReg
, typelib_TypeClass_ENUM
, aTypeName
.pData
);
533 typelib_EnumTypeDescription
* pEnum
= reinterpret_cast<typelib_EnumTypeDescription
*>(pReg
);
535 pEnum
->nDefaultEnumValue
= nDefaultValue
;
537 pReg
->pWeakRef
= reinterpret_cast<typelib_TypeDescriptionReference
*>(pReg
);
538 // sizeof(void) not allowed
539 pReg
->nSize
= ::typelib_typedescription_getAlignedUnoSize( pReg
, 0, pReg
->nAlignment
);
540 pReg
->nAlignment
= ::adjustAlignment( pReg
->nAlignment
);
541 pReg
->bComplete
= false;
543 ::typelib_typedescription_register( &pReg
);
544 *ppRef
= reinterpret_cast<typelib_TypeDescriptionReference
*>(pReg
);
545 assert( *ppRef
== pReg
->pWeakRef
);
547 // another static ref:
548 ++((*ppRef
)->nStaticRefCount
);
555 /* vim:set shiftwidth=4 softtabstop=4 expandtab: */