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.
71 // the value of the maximal alignment
72 const sal_Int32 nMaxAlignment
= static_cast<sal_Int32
>( reinterpret_cast<sal_Size
>(&reinterpret_cast<AlignSize_Impl
*>(16)->dDouble
) - 16);
74 static sal_Int32
adjustAlignment( sal_Int32 nRequestedAlignment
)
76 if( nRequestedAlignment
> nMaxAlignment
)
77 nRequestedAlignment
= nMaxAlignment
;
78 return nRequestedAlignment
;
82 * Calculate the new size of the struktur.
84 static sal_Int32
newAlignedSize(
85 sal_Int32 OldSize
, sal_Int32 ElementSize
, sal_Int32 NeededAlignment
)
87 NeededAlignment
= adjustAlignment( NeededAlignment
);
88 return (OldSize
+ NeededAlignment
-1) / NeededAlignment
* NeededAlignment
+ ElementSize
;
92 // !for NOT REALLY WEAK TYPES only!
93 static typelib_TypeDescriptionReference
* igetTypeByName( rtl_uString
const * pTypeName
)
95 typelib_TypeDescriptionReference
* pRef
= nullptr;
96 ::typelib_typedescriptionreference_getByName( &pRef
, pTypeName
);
97 if (pRef
&& pRef
->pType
&& pRef
->pType
->pWeakRef
) // found initialized td
107 typelib_TypeDescriptionReference
** SAL_CALL
typelib_static_type_getByTypeClass(
108 typelib_TypeClass eTypeClass
) noexcept
110 static typelib_TypeDescriptionReference
* s_aTypes
[] = {
111 nullptr, nullptr, nullptr, nullptr, nullptr, nullptr, nullptr, nullptr, nullptr, nullptr,
112 nullptr, nullptr, nullptr, nullptr, nullptr, nullptr, nullptr, nullptr, nullptr, nullptr,
113 nullptr, nullptr, nullptr };
115 if (! s_aTypes
[eTypeClass
])
117 MutexGuard
aGuard( typelib_StaticInitMutex() );
118 if (! s_aTypes
[eTypeClass
])
120 static constexpr OUString s_aTypeNames
[] = {
121 u
"void"_ustr
, u
"char"_ustr
, u
"boolean"_ustr
, u
"byte"_ustr
,
122 u
"short"_ustr
, u
"unsigned short"_ustr
, u
"long"_ustr
, u
"unsigned long"_ustr
,
123 u
"hyper"_ustr
, u
"unsigned hyper"_ustr
, u
"float"_ustr
, u
"double"_ustr
,
124 u
"string"_ustr
, u
"type"_ustr
, u
"any"_ustr
};
128 case typelib_TypeClass_EXCEPTION
:
129 case typelib_TypeClass_INTERFACE
:
132 if (! s_aTypes
[typelib_TypeClass_TYPE
])
134 OUString
sTypeName(u
"type"_ustr
);
135 ::typelib_typedescriptionreference_new(
136 &s_aTypes
[typelib_TypeClass_TYPE
], typelib_TypeClass_TYPE
, sTypeName
.pData
);
137 // another static ref:
138 ++s_aTypes
[typelib_TypeClass_TYPE
]->nStaticRefCount
;
141 if (! s_aTypes
[typelib_TypeClass_ANY
])
143 OUString
sTypeName(u
"any"_ustr
);
144 ::typelib_typedescriptionreference_new(
145 &s_aTypes
[typelib_TypeClass_ANY
], typelib_TypeClass_ANY
, sTypeName
.pData
);
146 // another static ref:
147 ++s_aTypes
[typelib_TypeClass_ANY
]->nStaticRefCount
;
150 if (! s_aTypes
[typelib_TypeClass_STRING
])
152 OUString
sTypeName(u
"string"_ustr
);
153 ::typelib_typedescriptionreference_new(
154 &s_aTypes
[typelib_TypeClass_STRING
], typelib_TypeClass_STRING
, sTypeName
.pData
);
155 // another static ref:
156 ++s_aTypes
[typelib_TypeClass_STRING
]->nStaticRefCount
;
159 if (! s_aTypes
[typelib_TypeClass_INTERFACE
])
161 OUString
sTypeName(u
"com.sun.star.uno.XInterface"_ustr
);
163 typelib_InterfaceTypeDescription
* pTD
= nullptr;
165 typelib_TypeDescriptionReference
* pMembers
[3] = { nullptr,nullptr,nullptr };
166 OUString
sMethodName0(u
"com.sun.star.uno.XInterface::queryInterface"_ustr
);
167 ::typelib_typedescriptionreference_new(
168 &pMembers
[0], typelib_TypeClass_INTERFACE_METHOD
, sMethodName0
.pData
);
169 OUString
sMethodName1(u
"com.sun.star.uno.XInterface::acquire"_ustr
);
170 ::typelib_typedescriptionreference_new(
171 &pMembers
[1], typelib_TypeClass_INTERFACE_METHOD
, sMethodName1
.pData
);
172 OUString
sMethodName2(u
"com.sun.star.uno.XInterface::release"_ustr
);
173 ::typelib_typedescriptionreference_new(
174 &pMembers
[2], typelib_TypeClass_INTERFACE_METHOD
, sMethodName2
.pData
);
176 ::typelib_typedescription_newInterface(
177 &pTD
, sTypeName
.pData
, 0, 0, 0, 0, 0, nullptr, 3, pMembers
);
179 ::typelib_typedescription_register( reinterpret_cast<typelib_TypeDescription
**>(&pTD
) );
180 s_aTypes
[typelib_TypeClass_INTERFACE
] = pTD
->aBase
.pWeakRef
;
181 ::typelib_typedescriptionreference_acquire(
182 s_aTypes
[typelib_TypeClass_INTERFACE
] );
183 // another static ref:
184 ++s_aTypes
[typelib_TypeClass_INTERFACE
]->nStaticRefCount
;
185 ::typelib_typedescription_release( &pTD
->aBase
);
187 ::typelib_typedescriptionreference_release( pMembers
[0] );
188 ::typelib_typedescriptionreference_release( pMembers
[1] );
189 ::typelib_typedescriptionreference_release( pMembers
[2] );
191 assert( ! s_aTypes
[typelib_TypeClass_EXCEPTION
] );
193 typelib_TypeDescription
* pTD1
= nullptr;
194 OUString
sTypeName1(u
"com.sun.star.uno.Exception"_ustr
);
196 typelib_CompoundMember_Init aMembers
[2];
197 OUString
sMemberType0(u
"string"_ustr
);
198 OUString
sMemberName0(u
"Message"_ustr
);
199 aMembers
[0].eTypeClass
= typelib_TypeClass_STRING
;
200 aMembers
[0].pTypeName
= sMemberType0
.pData
;
201 aMembers
[0].pMemberName
= sMemberName0
.pData
;
202 OUString
sMemberType1(u
"com.sun.star.uno.XInterface"_ustr
);
203 OUString
sMemberName1(u
"Context"_ustr
);
204 aMembers
[1].eTypeClass
= typelib_TypeClass_INTERFACE
;
205 aMembers
[1].pTypeName
= sMemberType1
.pData
;
206 aMembers
[1].pMemberName
= sMemberName1
.pData
;
208 ::typelib_typedescription_new(
209 &pTD1
, typelib_TypeClass_EXCEPTION
, sTypeName1
.pData
, nullptr, 2, aMembers
);
210 typelib_typedescription_register( &pTD1
);
211 s_aTypes
[typelib_TypeClass_EXCEPTION
] = pTD1
->pWeakRef
;
212 typelib_typedescriptionreference_acquire(
213 s_aTypes
[typelib_TypeClass_EXCEPTION
]);
214 // another static ref:
215 ++s_aTypes
[typelib_TypeClass_EXCEPTION
]->nStaticRefCount
;
217 OUString
sTypeName2(u
"com.sun.star.uno.RuntimeException"_ustr
);
218 ::typelib_typedescription_new(
219 &pTD1
, typelib_TypeClass_EXCEPTION
, sTypeName2
.pData
, s_aTypes
[typelib_TypeClass_EXCEPTION
], 0, nullptr );
220 ::typelib_typedescription_register( &pTD1
);
221 ::typelib_typedescription_release( pTD1
);
223 // XInterface members
224 typelib_InterfaceMethodTypeDescription
* pMethod
= nullptr;
225 typelib_Parameter_Init aParameters
[1];
226 OUString
sParamName0(u
"aType"_ustr
);
227 OUString
sParamType0(u
"type"_ustr
);
228 aParameters
[0].pParamName
= sParamName0
.pData
;
229 aParameters
[0].eTypeClass
= typelib_TypeClass_TYPE
;
230 aParameters
[0].pTypeName
= sParamType0
.pData
;
231 aParameters
[0].bIn
= true;
232 aParameters
[0].bOut
= false;
233 rtl_uString
* pExceptions
[1];
234 OUString
sExceptionName0(u
"com.sun.star.uno.RuntimeException"_ustr
);
235 pExceptions
[0] = sExceptionName0
.pData
;
236 OUString
sReturnType0(u
"any"_ustr
);
237 typelib_typedescription_newInterfaceMethod(
238 &pMethod
, 0, false, sMethodName0
.pData
,
239 typelib_TypeClass_ANY
, sReturnType0
.pData
,
240 1, aParameters
, 1, pExceptions
);
241 ::typelib_typedescription_register( reinterpret_cast<typelib_TypeDescription
**>(&pMethod
) );
243 OUString
sReturnType1(u
"void"_ustr
);
244 ::typelib_typedescription_newInterfaceMethod(
245 &pMethod
, 1, true, sMethodName1
.pData
,
246 typelib_TypeClass_VOID
, sReturnType1
.pData
, 0, nullptr, 0, nullptr );
247 ::typelib_typedescription_register( reinterpret_cast<typelib_TypeDescription
**>(&pMethod
) );
249 ::typelib_typedescription_newInterfaceMethod(
250 &pMethod
, 2, true, sMethodName2
.pData
,
251 typelib_TypeClass_VOID
, sReturnType1
.pData
,
252 0, nullptr, 0, nullptr );
253 ::typelib_typedescription_register( reinterpret_cast<typelib_TypeDescription
**>(&pMethod
) );
254 ::typelib_typedescription_release( &pMethod
->aBase
.aBase
);
260 OUString
aTypeName( s_aTypeNames
[eTypeClass
] );
261 ::typelib_typedescriptionreference_new( &s_aTypes
[eTypeClass
], eTypeClass
, aTypeName
.pData
);
262 // another static ref:
263 ++s_aTypes
[eTypeClass
]->nStaticRefCount
;
268 return &s_aTypes
[eTypeClass
];
271 void SAL_CALL
typelib_static_type_init(
272 typelib_TypeDescriptionReference
** ppRef
,
273 typelib_TypeClass eTypeClass
, const char * pTypeName
) noexcept
277 MutexGuard
aGuard( typelib_StaticInitMutex() );
280 OUString
aTypeName( OUString::createFromAscii( pTypeName
) );
281 ::typelib_typedescriptionreference_new( ppRef
, eTypeClass
, aTypeName
.pData
);
283 assert(*ppRef
&& "coverity[var_deref_op] - shouldn't be possible");
284 ++((*ppRef
)->nStaticRefCount
);
289 void SAL_CALL
typelib_static_sequence_type_init(
290 typelib_TypeDescriptionReference
** ppRef
,
291 typelib_TypeDescriptionReference
* pElementType
) noexcept
296 MutexGuard
aGuard( typelib_StaticInitMutex() );
300 OUString aTypeName
= "[]" + OUString::unacquired(&pElementType
->pTypeName
);
302 static_assert( ! TYPELIB_TYPEDESCRIPTIONREFERENCE_ISREALLYWEAK(typelib_TypeClass_SEQUENCE
) );
303 *ppRef
= igetTypeByName( aTypeName
.pData
);
306 typelib_TypeDescription
* pReg
= nullptr;
307 ::typelib_typedescription_new(
308 &pReg
, typelib_TypeClass_SEQUENCE
,
309 aTypeName
.pData
, pElementType
, 0, nullptr );
311 ::typelib_typedescription_register( &pReg
);
312 *ppRef
= reinterpret_cast<typelib_TypeDescriptionReference
*>(pReg
);
313 assert( *ppRef
== pReg
->pWeakRef
);
315 // another static ref:
316 ++((*ppRef
)->nStaticRefCount
);
323 typelib_TypeDescriptionReference
** ppRef
,
324 typelib_TypeClass eTypeClass
, const char * pTypeName
,
325 typelib_TypeDescriptionReference
* pBaseType
,
326 sal_Int32 nMembers
, typelib_TypeDescriptionReference
** ppMembers
,
327 sal_Bool
const * pParameterizedTypes
)
329 assert( eTypeClass
== typelib_TypeClass_STRUCT
|| eTypeClass
== typelib_TypeClass_EXCEPTION
);
334 MutexGuard
aGuard( typelib_StaticInitMutex() );
338 assert( ! TYPELIB_TYPEDESCRIPTIONREFERENCE_ISREALLYWEAK(eTypeClass
) );
339 OUString
aTypeName( OUString::createFromAscii( pTypeName
) );
340 *ppRef
= igetTypeByName( aTypeName
.pData
);
343 typelib_CompoundTypeDescription
* pComp
= nullptr;
344 ::typelib_typedescription_newEmpty(
345 reinterpret_cast<typelib_TypeDescription
**>(&pComp
), eTypeClass
, aTypeName
.pData
);
347 sal_Int32 nOffset
= 0;
350 ::typelib_typedescriptionreference_getDescription(
351 reinterpret_cast<typelib_TypeDescription
**>(&pComp
->pBaseTypeDescription
), pBaseType
);
352 assert( pComp
->pBaseTypeDescription
);
353 nOffset
= pComp
->pBaseTypeDescription
->aBase
.nSize
;
354 assert( newAlignedSize( 0, pComp
->pBaseTypeDescription
->aBase
.nSize
, pComp
->pBaseTypeDescription
->aBase
.nAlignment
) == pComp
->pBaseTypeDescription
->aBase
.nSize
); // unexpected offset
359 pComp
->nMembers
= nMembers
;
360 pComp
->pMemberOffsets
= new sal_Int32
[ nMembers
];
361 pComp
->ppTypeRefs
= new typelib_TypeDescriptionReference
*[ nMembers
];
362 if (pParameterizedTypes
!= nullptr) {
363 reinterpret_cast< typelib_StructTypeDescription
* >(
364 pComp
)->pParameterizedTypes
365 = new sal_Bool
[nMembers
];
367 for ( sal_Int32 i
= 0 ; i
< nMembers
; ++i
)
369 pComp
->ppTypeRefs
[i
] = ppMembers
[i
];
370 ::typelib_typedescriptionreference_acquire(
371 pComp
->ppTypeRefs
[i
] );
373 typelib_TypeDescription
* pTD
= nullptr;
374 TYPELIB_DANGER_GET( &pTD
, pComp
->ppTypeRefs
[i
] );
375 assert( pTD
->nSize
); // void member?
376 nOffset
= newAlignedSize( nOffset
, pTD
->nSize
, pTD
->nAlignment
);
377 pComp
->pMemberOffsets
[i
] = nOffset
- pTD
->nSize
;
378 TYPELIB_DANGER_RELEASE( pTD
);
380 if (pParameterizedTypes
!= nullptr) {
381 reinterpret_cast< typelib_StructTypeDescription
* >(
382 pComp
)->pParameterizedTypes
[i
]
383 = pParameterizedTypes
[i
];
388 typelib_TypeDescription
* pReg
= &pComp
->aBase
;
389 pReg
->pWeakRef
= reinterpret_cast<typelib_TypeDescriptionReference
*>(pReg
);
390 // sizeof(void) not allowed
391 pReg
->nSize
= ::typelib_typedescription_getAlignedUnoSize( pReg
, 0, pReg
->nAlignment
);
392 pReg
->nAlignment
= adjustAlignment( pReg
->nAlignment
);
393 pReg
->bComplete
= false;
395 ::typelib_typedescription_register( &pReg
);
396 *ppRef
= reinterpret_cast<typelib_TypeDescriptionReference
*>(pReg
);
397 assert( *ppRef
== pReg
->pWeakRef
);
399 // another static ref:
400 ++((*ppRef
)->nStaticRefCount
);
405 void SAL_CALL
typelib_static_compound_type_init(
406 typelib_TypeDescriptionReference
** ppRef
,
407 typelib_TypeClass eTypeClass
, const char * pTypeName
,
408 typelib_TypeDescriptionReference
* pBaseType
,
409 sal_Int32 nMembers
, typelib_TypeDescriptionReference
** ppMembers
) noexcept
411 init(ppRef
, eTypeClass
, pTypeName
, pBaseType
, nMembers
, ppMembers
, nullptr);
414 void SAL_CALL
typelib_static_struct_type_init(
415 typelib_TypeDescriptionReference
** ppRef
, const char * pTypeName
,
416 typelib_TypeDescriptionReference
* pBaseType
,
417 sal_Int32 nMembers
, typelib_TypeDescriptionReference
** ppMembers
,
418 sal_Bool
const * pParameterizedTypes
) noexcept
421 ppRef
, typelib_TypeClass_STRUCT
, pTypeName
, pBaseType
, nMembers
,
422 ppMembers
, pParameterizedTypes
);
425 void SAL_CALL
typelib_static_interface_type_init(
426 typelib_TypeDescriptionReference
** ppRef
,
427 const char * pTypeName
,
428 typelib_TypeDescriptionReference
* pBaseType
) noexcept
430 // coverity[callee_ptr_arith] - not a bug
431 typelib_static_mi_interface_type_init(
432 ppRef
, pTypeName
, pBaseType
== nullptr ? 0 : 1, &pBaseType
);
435 void SAL_CALL
typelib_static_mi_interface_type_init(
436 typelib_TypeDescriptionReference
** ppRef
,
437 const char * pTypeName
,
438 sal_Int32 nBaseTypes
,
439 typelib_TypeDescriptionReference
** ppBaseTypes
) noexcept
444 MutexGuard
aGuard( typelib_StaticInitMutex() );
448 static_assert( ! TYPELIB_TYPEDESCRIPTIONREFERENCE_ISREALLYWEAK(typelib_TypeClass_INTERFACE
) );
449 OUString
aTypeName( OUString::createFromAscii( pTypeName
) );
450 *ppRef
= igetTypeByName( aTypeName
.pData
);
453 typelib_InterfaceTypeDescription
* pIface
= nullptr;
454 ::typelib_typedescription_newEmpty(
455 reinterpret_cast<typelib_TypeDescription
**>(&pIface
), typelib_TypeClass_INTERFACE
, aTypeName
.pData
);
457 pIface
->nBaseTypes
= std::max
< sal_Int32
>(nBaseTypes
, 1);
458 pIface
->ppBaseTypes
= new typelib_InterfaceTypeDescription
*[
462 for (sal_Int32 i
= 0; i
< nBaseTypes
; ++i
) {
463 pIface
->ppBaseTypes
[i
] = nullptr;
464 ::typelib_typedescriptionreference_getDescription(
465 reinterpret_cast<typelib_TypeDescription
**>(&pIface
->ppBaseTypes
[i
]), ppBaseTypes
[i
] );
466 assert( pIface
->ppBaseTypes
[i
] );
471 pIface
->ppBaseTypes
[0] = nullptr;
472 ::typelib_typedescriptionreference_getDescription(
473 reinterpret_cast<typelib_TypeDescription
**>(&pIface
->ppBaseTypes
[0]),
474 * ::typelib_static_type_getByTypeClass( typelib_TypeClass_INTERFACE
) );
475 assert( pIface
->ppBaseTypes
[0] );
477 pIface
->pBaseTypeDescription
= pIface
->ppBaseTypes
[0];
478 typelib_typedescription_acquire(
479 &pIface
->pBaseTypeDescription
->aBase
);
481 typelib_TypeDescription
* pReg
= &pIface
->aBase
;
482 pReg
->pWeakRef
= reinterpret_cast<typelib_TypeDescriptionReference
*>(pReg
);
483 // sizeof(void) not allowed
484 pReg
->nSize
= ::typelib_typedescription_getAlignedUnoSize( pReg
, 0, pReg
->nAlignment
);
486 pReg
->nAlignment
= adjustAlignment( pReg
->nAlignment
);
487 pReg
->bComplete
= false;
489 ::typelib_typedescription_register( &pReg
);
490 *ppRef
= reinterpret_cast<typelib_TypeDescriptionReference
*>(pReg
);
491 assert( *ppRef
== pReg
->pWeakRef
);
493 // another static ref:
494 ++((*ppRef
)->nStaticRefCount
);
498 void SAL_CALL
typelib_static_enum_type_init(
499 typelib_TypeDescriptionReference
** ppRef
,
500 const char * pTypeName
,
501 sal_Int32 nDefaultValue
) noexcept
506 MutexGuard
aGuard( typelib_StaticInitMutex() );
510 static_assert( ! TYPELIB_TYPEDESCRIPTIONREFERENCE_ISREALLYWEAK(typelib_TypeClass_ENUM
) );
511 OUString
aTypeName( OUString::createFromAscii( pTypeName
) );
512 *ppRef
= igetTypeByName( aTypeName
.pData
);
515 typelib_TypeDescription
* pReg
= nullptr;
516 ::typelib_typedescription_newEmpty(
517 &pReg
, typelib_TypeClass_ENUM
, aTypeName
.pData
);
518 typelib_EnumTypeDescription
* pEnum
= reinterpret_cast<typelib_EnumTypeDescription
*>(pReg
);
520 pEnum
->nDefaultEnumValue
= nDefaultValue
;
522 pReg
->pWeakRef
= reinterpret_cast<typelib_TypeDescriptionReference
*>(pReg
);
523 // sizeof(void) not allowed
524 pReg
->nSize
= ::typelib_typedescription_getAlignedUnoSize( pReg
, 0, pReg
->nAlignment
);
525 pReg
->nAlignment
= ::adjustAlignment( pReg
->nAlignment
);
526 pReg
->bComplete
= false;
528 ::typelib_typedescription_register( &pReg
);
529 *ppRef
= reinterpret_cast<typelib_TypeDescriptionReference
*>(pReg
);
530 assert( *ppRef
== pReg
->pWeakRef
);
532 // another static ref:
533 ++((*ppRef
)->nStaticRefCount
);
540 /* vim:set shiftwidth=4 softtabstop=4 expandtab: */