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"
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"
38 using ::rtl::OUString
;
39 using ::rtl::OUStringBuffer
;
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.
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.
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
;
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
;
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
117 typelib_TypeDescriptionReference
** SAL_CALL
typelib_static_type_getByTypeClass(
118 typelib_TypeClass eTypeClass
)
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,
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" };
139 case typelib_TypeClass_EXCEPTION
:
140 case typelib_TypeClass_INTERFACE
:
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
;
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
;
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
;
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] );
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
;
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
,
262 ::typelib_typedescription_register( reinterpret_cast<typelib_TypeDescription
**>(&pMethod
) );
263 ::typelib_typedescription_release( &pMethod
->aBase
.aBase
);
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
)
287 MutexGuard
aGuard( typelib_StaticInitMutex::get() );
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
)
306 MutexGuard
aGuard( typelib_StaticInitMutex::get() );
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
);
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
);
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
);
347 MutexGuard
aGuard( typelib_StaticInitMutex::get() );
350 assert( ! TYPELIB_TYPEDESCRIPTIONREFERENCE_ISREALLYWEAK(eTypeClass
) );
351 OUString
aTypeName( OUString::createFromAscii( pTypeName
) );
352 *ppRef
= igetTypeByName( aTypeName
.pData
);
355 typelib_CompoundTypeDescription
* pComp
= 0;
356 ::typelib_typedescription_newEmpty(
357 reinterpret_cast<typelib_TypeDescription
**>(&pComp
), eTypeClass
, aTypeName
.pData
);
359 sal_Int32 nOffset
= 0;
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
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
] );
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
)
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
)
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
)
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
)
460 MutexGuard
aGuard( typelib_StaticInitMutex::get() );
463 assert( ! TYPELIB_TYPEDESCRIPTIONREFERENCE_ISREALLYWEAK(typelib_TypeClass_INTERFACE
) );
464 OUString
aTypeName( OUString::createFromAscii( pTypeName
) );
465 *ppRef
= igetTypeByName( aTypeName
.pData
);
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
*[
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
] );
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
)
523 MutexGuard
aGuard( typelib_StaticInitMutex::get() );
526 assert( ! TYPELIB_TYPEDESCRIPTIONREFERENCE_ISREALLYWEAK(typelib_TypeClass_ENUM
) );
527 OUString
aTypeName( OUString::createFromAscii( pTypeName
) );
528 *ppRef
= igetTypeByName( aTypeName
.pData
);
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
);
558 /* vim:set shiftwidth=4 softtabstop=4 expandtab: */