bump product version to 5.0.4.1
[LibreOffice.git] / cppu / source / uno / data.cxx
blob9ae11151a0065a2045681b671c7dcca7ffb79e76
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 .
21 #include <cstddef>
22 #include <stdio.h>
24 #include "cppu/macros.hxx"
25 #include "osl/mutex.hxx"
26 #include "sal/log.hxx"
27 #include "uno/data.h"
29 #include "constr.hxx"
30 #include "destr.hxx"
31 #include "copy.hxx"
32 #include "assign.hxx"
33 #include "eq.hxx"
35 using namespace ::cppu;
36 using namespace ::osl;
38 namespace cppu
41 // Sequence<>() (default ctor) relies on this being static:
42 uno_Sequence g_emptySeq = { 1, 0, { 0 } };
43 typelib_TypeDescriptionReference * g_pVoidType = 0;
46 void * binuno_queryInterface( void * pUnoI, typelib_TypeDescriptionReference * pDestType )
48 // init queryInterface() td
49 static typelib_TypeDescription * g_pQITD = 0;
50 if (0 == g_pQITD)
52 MutexGuard aGuard( Mutex::getGlobalMutex() );
53 if (0 == g_pQITD)
55 typelib_TypeDescriptionReference * type_XInterface =
56 * typelib_static_type_getByTypeClass( typelib_TypeClass_INTERFACE );
57 typelib_InterfaceTypeDescription * pTXInterfaceDescr = 0;
58 TYPELIB_DANGER_GET( reinterpret_cast<typelib_TypeDescription **>(&pTXInterfaceDescr), type_XInterface );
59 assert(pTXInterfaceDescr->ppAllMembers);
60 typelib_typedescriptionreference_getDescription(
61 &g_pQITD, pTXInterfaceDescr->ppAllMembers[ 0 ] );
62 TYPELIB_DANGER_RELEASE( &pTXInterfaceDescr->aBase );
66 uno_Any aRet, aExc;
67 uno_Any * pExc = &aExc;
68 void * aArgs[ 1 ];
69 aArgs[ 0 ] = &pDestType;
70 (*static_cast<uno_Interface *>(pUnoI)->pDispatcher)(
71 static_cast<uno_Interface *>(pUnoI), g_pQITD, &aRet, aArgs, &pExc );
73 uno_Interface * ret = 0;
74 if (0 == pExc)
76 typelib_TypeDescriptionReference * ret_type = aRet.pType;
77 switch (ret_type->eTypeClass)
79 case typelib_TypeClass_VOID: // common case
80 typelib_typedescriptionreference_release( ret_type );
81 break;
82 case typelib_TypeClass_INTERFACE:
83 // tweaky... avoiding acquire/ release pair
84 typelib_typedescriptionreference_release( ret_type );
85 ret = static_cast<uno_Interface *>(aRet.pReserved); // serving acquired interface
86 break;
87 default:
88 _destructAny( &aRet, 0 );
89 break;
92 else
94 SAL_WARN(
95 "cppu",
96 "exception occurred querying for interface "
97 << OUString(pDestType->pTypeName) << ": ["
98 << OUString(pExc->pType->pTypeName) << "] "
99 << *static_cast<OUString const *>(pExc->pData));
100 // Message is very first member
101 uno_any_destruct( pExc, 0 );
103 return ret;
107 void defaultConstructStruct(
108 void * pMem,
109 typelib_CompoundTypeDescription * pCompType )
111 _defaultConstructStruct( pMem, pCompType );
114 void copyConstructStruct(
115 void * pDest, void * pSource,
116 typelib_CompoundTypeDescription * pTypeDescr,
117 uno_AcquireFunc acquire, uno_Mapping * mapping )
119 _copyConstructStruct( pDest, pSource, pTypeDescr, acquire, mapping );
122 void destructStruct(
123 void * pValue,
124 typelib_CompoundTypeDescription * pTypeDescr,
125 uno_ReleaseFunc release )
127 _destructStruct( pValue, pTypeDescr, release );
130 bool equalStruct(
131 void * pDest, void *pSource,
132 typelib_CompoundTypeDescription * pTypeDescr,
133 uno_QueryInterfaceFunc queryInterface, uno_ReleaseFunc release )
135 return _equalStruct( pDest, pSource, pTypeDescr, queryInterface, release );
138 bool assignStruct(
139 void * pDest, void * pSource,
140 typelib_CompoundTypeDescription * pTypeDescr,
141 uno_QueryInterfaceFunc queryInterface, uno_AcquireFunc acquire, uno_ReleaseFunc release )
143 return _assignStruct( pDest, pSource, pTypeDescr, queryInterface, acquire, release );
147 uno_Sequence * copyConstructSequence(
148 uno_Sequence * pSource,
149 typelib_TypeDescriptionReference * pElementType,
150 uno_AcquireFunc acquire, uno_Mapping * mapping )
152 return icopyConstructSequence( pSource, pElementType, acquire, mapping );
156 void destructSequence(
157 uno_Sequence * pSequence,
158 typelib_TypeDescriptionReference * pType,
159 typelib_TypeDescription * pTypeDescr,
160 uno_ReleaseFunc release )
162 idestructSequence( pSequence, pType, pTypeDescr, release );
166 bool equalSequence(
167 uno_Sequence * pDest, uno_Sequence * pSource,
168 typelib_TypeDescriptionReference * pElementType,
169 uno_QueryInterfaceFunc queryInterface, uno_ReleaseFunc release )
171 return _equalSequence( pDest, pSource, pElementType, queryInterface, release );
176 extern "C"
179 void SAL_CALL uno_type_constructData(
180 void * pMem, typelib_TypeDescriptionReference * pType )
181 SAL_THROW_EXTERN_C()
183 _defaultConstructData( pMem, pType, 0 );
186 void SAL_CALL uno_constructData(
187 void * pMem, typelib_TypeDescription * pTypeDescr )
188 SAL_THROW_EXTERN_C()
190 _defaultConstructData( pMem, pTypeDescr->pWeakRef, pTypeDescr );
193 void SAL_CALL uno_type_destructData(
194 void * pValue, typelib_TypeDescriptionReference * pType,
195 uno_ReleaseFunc release )
196 SAL_THROW_EXTERN_C()
198 _destructData( pValue, pType, 0, release );
201 void SAL_CALL uno_destructData(
202 void * pValue,
203 typelib_TypeDescription * pTypeDescr,
204 uno_ReleaseFunc release )
205 SAL_THROW_EXTERN_C()
207 _destructData( pValue, pTypeDescr->pWeakRef, pTypeDescr, release );
210 void SAL_CALL uno_type_copyData(
211 void * pDest, void * pSource,
212 typelib_TypeDescriptionReference * pType,
213 uno_AcquireFunc acquire )
214 SAL_THROW_EXTERN_C()
216 _copyConstructData( pDest, pSource, pType, 0, acquire, 0 );
219 void SAL_CALL uno_copyData(
220 void * pDest, void * pSource,
221 typelib_TypeDescription * pTypeDescr,
222 uno_AcquireFunc acquire )
223 SAL_THROW_EXTERN_C()
225 _copyConstructData( pDest, pSource, pTypeDescr->pWeakRef, pTypeDescr, acquire, 0 );
228 void SAL_CALL uno_type_copyAndConvertData(
229 void * pDest, void * pSource,
230 typelib_TypeDescriptionReference * pType,
231 uno_Mapping * mapping )
232 SAL_THROW_EXTERN_C()
234 _copyConstructData( pDest, pSource, pType, 0, 0, mapping );
237 void SAL_CALL uno_copyAndConvertData(
238 void * pDest, void * pSource,
239 typelib_TypeDescription * pTypeDescr,
240 uno_Mapping * mapping )
241 SAL_THROW_EXTERN_C()
243 _copyConstructData( pDest, pSource, pTypeDescr->pWeakRef, pTypeDescr, 0, mapping );
246 sal_Bool SAL_CALL uno_type_equalData(
247 void * pVal1, typelib_TypeDescriptionReference * pVal1Type,
248 void * pVal2, typelib_TypeDescriptionReference * pVal2Type,
249 uno_QueryInterfaceFunc queryInterface, uno_ReleaseFunc release )
250 SAL_THROW_EXTERN_C()
252 return _equalData(
253 pVal1, pVal1Type, 0,
254 pVal2, pVal2Type,
255 queryInterface, release );
258 sal_Bool SAL_CALL uno_equalData(
259 void * pVal1, typelib_TypeDescription * pVal1TD,
260 void * pVal2, typelib_TypeDescription * pVal2TD,
261 uno_QueryInterfaceFunc queryInterface, uno_ReleaseFunc release )
262 SAL_THROW_EXTERN_C()
264 return _equalData(
265 pVal1, pVal1TD->pWeakRef, pVal1TD,
266 pVal2, pVal2TD->pWeakRef,
267 queryInterface, release );
270 sal_Bool SAL_CALL uno_type_assignData(
271 void * pDest, typelib_TypeDescriptionReference * pDestType,
272 void * pSource, typelib_TypeDescriptionReference * pSourceType,
273 uno_QueryInterfaceFunc queryInterface, uno_AcquireFunc acquire, uno_ReleaseFunc release )
274 SAL_THROW_EXTERN_C()
276 return _assignData(
277 pDest, pDestType, 0,
278 pSource, pSourceType, 0,
279 queryInterface, acquire, release );
282 sal_Bool SAL_CALL uno_assignData(
283 void * pDest, typelib_TypeDescription * pDestTD,
284 void * pSource, typelib_TypeDescription * pSourceTD,
285 uno_QueryInterfaceFunc queryInterface, uno_AcquireFunc acquire, uno_ReleaseFunc release )
286 SAL_THROW_EXTERN_C()
288 return _assignData(
289 pDest, pDestTD->pWeakRef, pDestTD,
290 pSource, pSourceTD->pWeakRef, pSourceTD,
291 queryInterface, acquire, release );
294 sal_Bool SAL_CALL uno_type_isAssignableFromData(
295 typelib_TypeDescriptionReference * pAssignable,
296 void * pFrom, typelib_TypeDescriptionReference * pFromType,
297 uno_QueryInterfaceFunc queryInterface, uno_ReleaseFunc release )
298 SAL_THROW_EXTERN_C()
300 if (::typelib_typedescriptionreference_isAssignableFrom( pAssignable, pFromType ))
301 return sal_True;
302 if (typelib_TypeClass_INTERFACE != pFromType->eTypeClass ||
303 typelib_TypeClass_INTERFACE != pAssignable->eTypeClass)
305 return sal_False;
308 // query
309 if (0 == pFrom)
310 return sal_False;
311 void * pInterface = *static_cast<void **>(pFrom);
312 if (0 == pInterface)
313 return sal_False;
315 if (0 == queryInterface)
316 queryInterface = binuno_queryInterface;
317 void * p = (*queryInterface)( pInterface, pAssignable );
318 _release( p, release );
319 return (0 != p);
324 #if OSL_DEBUG_LEVEL > 1
326 namespace cppu {
328 #if defined( SAL_W32)
329 #pragma pack(push, 8)
330 #endif
332 // Why hardcode like this instead of using the (generated)
333 // <sal/typesizes.h> ?
335 #if (defined(INTEL) \
336 && (defined(__GNUC__) && (defined(LINUX) || defined(FREEBSD) || defined(NETBSD) || defined(OPENBSD)) \
337 || defined(MACOSX) || defined(DRAGONFLY))) \
338 || defined(IOS)
339 #define MAX_ALIGNMENT_4
340 #endif
342 #define OFFSET_OF( s, m ) reinterpret_cast< size_t >((char *)&((s *)16)->m -16)
344 #define BINTEST_VERIFY( c ) \
345 if (! (c)) \
347 fprintf( stderr, "### binary compatibility test failed: %s [line %d]!!!\n", #c, __LINE__ ); \
348 abort(); \
351 #define BINTEST_VERIFYOFFSET( s, m, n ) \
352 if (OFFSET_OF(s, m) != static_cast<size_t>(n)) \
354 fprintf(stderr, "### OFFSET_OF(" #s ", " #m ") = %" SAL_PRI_SIZET "u instead of expected %" SAL_PRI_SIZET "u!!!\n", \
355 OFFSET_OF(s, m), static_cast<size_t>(n)); \
356 abort(); \
359 #define BINTEST_VERIFYSIZE( s, n ) \
360 if (sizeof(s) != static_cast<size_t>(n)) \
362 fprintf(stderr, "### sizeof(" #s ") = %" SAL_PRI_SIZET "u instead of expected %" SAL_PRI_SIZET "u!!!\n", \
363 sizeof(s), static_cast<size_t>(n)); \
364 abort(); \
367 struct C1
369 sal_Int16 n1;
371 struct C2 : public C1
373 sal_Int32 n2 CPPU_GCC3_ALIGN( C1 );
375 struct C3 : public C2
377 double d3;
378 sal_Int32 n3;
380 struct C4 : public C3
382 sal_Int32 n4 CPPU_GCC3_ALIGN( C3 );
383 double d4;
385 struct C5 : public C4
387 sal_Int64 n5;
388 sal_Bool b5;
390 struct C6 : public C1
392 C5 c6 CPPU_GCC3_ALIGN( C1 );
393 sal_Bool b6;
396 struct D
398 sal_Int16 d;
399 sal_Int32 e;
401 struct E
403 sal_Bool a;
404 sal_Bool b;
405 sal_Bool c;
406 sal_Int16 d;
407 sal_Int32 e;
410 struct M
412 sal_Int32 n;
413 sal_Int16 o;
416 struct N : public M
418 sal_Int16 p CPPU_GCC3_ALIGN( M );
420 struct N2
422 M m;
423 sal_Int16 p;
426 struct O : public M
428 double p;
429 sal_Int16 q;
431 struct O2 : public O
433 sal_Int16 p2 CPPU_GCC3_ALIGN( O );
436 struct P : public N
438 double p2;
441 struct empty
444 struct second : public empty
446 int a;
449 struct AlignSize_Impl
451 sal_Int16 nInt16;
452 double dDouble;
455 struct Char1
457 char c1;
459 struct Char2 : public Char1
461 char c2 CPPU_GCC3_ALIGN( Char1 );
463 struct Char3 : public Char2
465 char c3 CPPU_GCC3_ALIGN( Char2 );
467 struct Char4
469 Char3 chars;
470 char c;
472 class Ref
474 void * p;
476 enum Enum
478 v = SAL_MAX_ENUM
482 class BinaryCompatible_Impl
484 public:
485 BinaryCompatible_Impl();
487 BinaryCompatible_Impl::BinaryCompatible_Impl()
489 static_assert( ((sal_Bool) true) == sal_True &&
490 (1 != 0) == sal_True, "must be binary compatible" );
491 static_assert( ((sal_Bool) false) == sal_False &&
492 (1 == 0) == sal_False, "must be binary compatible" );
493 #ifdef MAX_ALIGNMENT_4
494 // max alignment is 4
495 BINTEST_VERIFYOFFSET( AlignSize_Impl, dDouble, 4 );
496 BINTEST_VERIFYSIZE( AlignSize_Impl, 12 );
497 #else
498 // max alignment is 8
499 BINTEST_VERIFYOFFSET( AlignSize_Impl, dDouble, 8 );
500 BINTEST_VERIFYSIZE( AlignSize_Impl, 16 );
501 #endif
503 // sequence
504 BINTEST_VERIFY( (SAL_SEQUENCE_HEADER_SIZE % 8) == 0 );
505 // enum
506 BINTEST_VERIFY( sizeof( Enum ) == sizeof( sal_Int32 ) );
507 // any
508 BINTEST_VERIFY( sizeof(void *) >= sizeof(sal_Int32) );
509 BINTEST_VERIFY( sizeof( uno_Any ) == sizeof( void * ) * 3 );
510 BINTEST_VERIFYOFFSET( uno_Any, pType, 0 );
511 BINTEST_VERIFYOFFSET( uno_Any, pData, 1 * sizeof (void *) );
512 BINTEST_VERIFYOFFSET( uno_Any, pReserved, 2 * sizeof (void *) );
513 // interface
514 BINTEST_VERIFY( sizeof( Ref ) == sizeof( void * ) );
515 // string
516 BINTEST_VERIFY( sizeof( OUString ) == sizeof( rtl_uString * ) );
517 // struct
518 BINTEST_VERIFYSIZE( M, 8 );
519 BINTEST_VERIFYOFFSET( M, o, 4 );
520 BINTEST_VERIFYSIZE( N, 12 );
521 BINTEST_VERIFYOFFSET( N, p, 8 );
522 BINTEST_VERIFYSIZE( N2, 12 );
523 BINTEST_VERIFYOFFSET( N2, p, 8 );
524 #ifdef MAX_ALIGNMENT_4
525 BINTEST_VERIFYSIZE( O, 20 );
526 #else
527 BINTEST_VERIFYSIZE( O, 24 );
528 #endif
529 BINTEST_VERIFYSIZE( D, 8 );
530 BINTEST_VERIFYOFFSET( D, e, 4 );
531 BINTEST_VERIFYOFFSET( E, d, 4 );
532 BINTEST_VERIFYOFFSET( E, e, 8 );
534 BINTEST_VERIFYSIZE( C1, 2 );
535 BINTEST_VERIFYSIZE( C2, 8 );
536 BINTEST_VERIFYOFFSET( C2, n2, 4 );
538 #ifdef MAX_ALIGNMENT_4
539 BINTEST_VERIFYSIZE( C3, 20 );
540 BINTEST_VERIFYOFFSET( C3, d3, 8 );
541 BINTEST_VERIFYOFFSET( C3, n3, 16 );
542 BINTEST_VERIFYSIZE( C4, 32 );
543 BINTEST_VERIFYOFFSET( C4, n4, 20 );
544 BINTEST_VERIFYOFFSET( C4, d4, 24 );
545 BINTEST_VERIFYSIZE( C5, 44 );
546 BINTEST_VERIFYOFFSET( C5, n5, 32 );
547 BINTEST_VERIFYOFFSET( C5, b5, 40 );
548 BINTEST_VERIFYSIZE( C6, 52 );
549 BINTEST_VERIFYOFFSET( C6, c6, 4 );
550 BINTEST_VERIFYOFFSET( C6, b6, 48 );
552 BINTEST_VERIFYSIZE( O2, 24 );
553 BINTEST_VERIFYOFFSET( O2, p2, 20 );
554 #else
555 BINTEST_VERIFYSIZE( C3, 24 );
556 BINTEST_VERIFYOFFSET( C3, d3, 8 );
557 BINTEST_VERIFYOFFSET( C3, n3, 16 );
558 BINTEST_VERIFYSIZE( C4, 40 );
559 BINTEST_VERIFYOFFSET( C4, n4, 24 );
560 BINTEST_VERIFYOFFSET( C4, d4, 32 );
561 BINTEST_VERIFYSIZE( C5, 56 );
562 BINTEST_VERIFYOFFSET( C5, n5, 40 );
563 BINTEST_VERIFYOFFSET( C5, b5, 48 );
564 BINTEST_VERIFYSIZE( C6, 72 );
565 BINTEST_VERIFYOFFSET( C6, c6, 8 );
566 BINTEST_VERIFYOFFSET( C6, b6, 64 );
568 BINTEST_VERIFYSIZE( O2, 32 );
569 BINTEST_VERIFYOFFSET( O2, p2, 24 );
570 #endif
572 BINTEST_VERIFYSIZE( Char3, 3 );
573 BINTEST_VERIFYOFFSET( Char4, c, 3 );
575 #ifdef MAX_ALIGNMENT_4
576 // max alignment is 4
577 BINTEST_VERIFYSIZE( P, 20 );
578 #else
579 // alignment of P is 8, because of P[] ...
580 BINTEST_VERIFYSIZE( P, 24 );
581 BINTEST_VERIFYSIZE( second, sizeof( int ) );
582 #endif
585 #ifdef SAL_W32
586 # pragma pack(pop)
587 #endif
589 static BinaryCompatible_Impl aTest;
593 #endif
595 /* vim:set shiftwidth=4 softtabstop=4 expandtab: */