1 /************************************************************** 2 * 3 * Licensed to the Apache Software Foundation (ASF) under one 4 * or more contributor license agreements. See the NOTICE file 5 * distributed with this work for additional information 6 * regarding copyright ownership. The ASF licenses this file 7 * to you under the Apache License, Version 2.0 (the 8 * "License"); you may not use this file except in compliance 9 * with the License. You may obtain a copy of the License at 10 * 11 * http://www.apache.org/licenses/LICENSE-2.0 12 * 13 * Unless required by applicable law or agreed to in writing, 14 * software distributed under the License is distributed on an 15 * "AS IS" BASIS, WITHOUT WARRANTIES OR CONDITIONS OF ANY 16 * KIND, either express or implied. See the License for the 17 * specific language governing permissions and limitations 18 * under the License. 19 * 20 *************************************************************/ 21 22 23 24 // MARKER(update_precomp.py): autogen include statement, do not remove 25 #include "precompiled_cppu.hxx" 26 27 #include <cstddef> 28 #include <stdio.h> 29 30 #include "cppu/macros.hxx" 31 32 #include "osl/mutex.hxx" 33 34 #include "constr.hxx" 35 #include "destr.hxx" 36 #include "copy.hxx" 37 #include "assign.hxx" 38 #include "eq.hxx" 39 40 #include "boost/static_assert.hpp" 41 42 43 using namespace ::cppu; 44 using namespace ::rtl; 45 using namespace ::osl; 46 47 48 namespace cppu 49 { 50 51 // Sequence<>() (default ctor) relies on this being static: 52 uno_Sequence g_emptySeq = { 1, 0, { 0 } }; 53 typelib_TypeDescriptionReference * g_pVoidType = 0; 54 55 //-------------------------------------------------------------------------------------------------- 56 void * binuno_queryInterface( void * pUnoI, typelib_TypeDescriptionReference * pDestType ) 57 { 58 // init queryInterface() td 59 static typelib_TypeDescription * g_pQITD = 0; 60 if (0 == g_pQITD) 61 { 62 MutexGuard aGuard( Mutex::getGlobalMutex() ); 63 if (0 == g_pQITD) 64 { 65 typelib_TypeDescriptionReference * type_XInterface = 66 * typelib_static_type_getByTypeClass( typelib_TypeClass_INTERFACE ); 67 typelib_InterfaceTypeDescription * pTXInterfaceDescr = 0; 68 TYPELIB_DANGER_GET( (typelib_TypeDescription **) &pTXInterfaceDescr, type_XInterface ); 69 OSL_ASSERT( pTXInterfaceDescr->ppAllMembers ); 70 typelib_typedescriptionreference_getDescription( 71 &g_pQITD, pTXInterfaceDescr->ppAllMembers[ 0 ] ); 72 TYPELIB_DANGER_RELEASE( (typelib_TypeDescription *) pTXInterfaceDescr ); 73 } 74 } 75 76 uno_Any aRet, aExc; 77 uno_Any * pExc = &aExc; 78 void * aArgs[ 1 ]; 79 aArgs[ 0 ] = &pDestType; 80 (*((uno_Interface *) pUnoI)->pDispatcher)( 81 (uno_Interface *) pUnoI, g_pQITD, &aRet, aArgs, &pExc ); 82 83 uno_Interface * ret = 0; 84 if (0 == pExc) 85 { 86 typelib_TypeDescriptionReference * ret_type = aRet.pType; 87 switch (ret_type->eTypeClass) 88 { 89 case typelib_TypeClass_VOID: // common case 90 typelib_typedescriptionreference_release( ret_type ); 91 break; 92 case typelib_TypeClass_INTERFACE: 93 // tweaky... avoiding acquire/ release pair 94 typelib_typedescriptionreference_release( ret_type ); 95 ret = (uno_Interface *) aRet.pReserved; // serving acquired interface 96 break; 97 default: 98 _destructAny( &aRet, 0 ); 99 break; 100 } 101 } 102 else 103 { 104 #if OSL_DEBUG_LEVEL > 1 105 OUStringBuffer buf( 128 ); 106 buf.appendAscii( 107 RTL_CONSTASCII_STRINGPARAM("### exception occured querying for interface ") ); 108 buf.append( * reinterpret_cast< OUString const * >( &pDestType->pTypeName ) ); 109 buf.appendAscii( RTL_CONSTASCII_STRINGPARAM(": [") ); 110 buf.append( * reinterpret_cast< OUString const * >( &pExc->pType->pTypeName ) ); 111 buf.appendAscii( RTL_CONSTASCII_STRINGPARAM("] ") ); 112 // Message is very first member 113 buf.append( * reinterpret_cast< OUString const * >( pExc->pData ) ); 114 OString cstr( 115 OUStringToOString( buf.makeStringAndClear(), RTL_TEXTENCODING_ASCII_US ) ); 116 OSL_ENSURE( 0, cstr.getStr() ); 117 #endif 118 uno_any_destruct( pExc, 0 ); 119 } 120 return ret; 121 } 122 123 //================================================================================================== 124 void defaultConstructStruct( 125 void * pMem, 126 typelib_CompoundTypeDescription * pCompType ) 127 SAL_THROW( () ) 128 { 129 _defaultConstructStruct( pMem, pCompType ); 130 } 131 //================================================================================================== 132 void copyConstructStruct( 133 void * pDest, void * pSource, 134 typelib_CompoundTypeDescription * pTypeDescr, 135 uno_AcquireFunc acquire, uno_Mapping * mapping ) 136 SAL_THROW( () ) 137 { 138 _copyConstructStruct( pDest, pSource, pTypeDescr, acquire, mapping ); 139 } 140 //================================================================================================== 141 void destructStruct( 142 void * pValue, 143 typelib_CompoundTypeDescription * pTypeDescr, 144 uno_ReleaseFunc release ) 145 SAL_THROW( () ) 146 { 147 _destructStruct( pValue, pTypeDescr, release ); 148 } 149 //================================================================================================== 150 sal_Bool equalStruct( 151 void * pDest, void *pSource, 152 typelib_CompoundTypeDescription * pTypeDescr, 153 uno_QueryInterfaceFunc queryInterface, uno_ReleaseFunc release ) 154 SAL_THROW( () ) 155 { 156 return _equalStruct( pDest, pSource, pTypeDescr, queryInterface, release ); 157 } 158 //================================================================================================== 159 sal_Bool assignStruct( 160 void * pDest, void * pSource, 161 typelib_CompoundTypeDescription * pTypeDescr, 162 uno_QueryInterfaceFunc queryInterface, uno_AcquireFunc acquire, uno_ReleaseFunc release ) 163 SAL_THROW( () ) 164 { 165 return _assignStruct( pDest, pSource, pTypeDescr, queryInterface, acquire, release ); 166 } 167 168 //============================================================================== 169 uno_Sequence * copyConstructSequence( 170 uno_Sequence * pSource, 171 typelib_TypeDescriptionReference * pElementType, 172 uno_AcquireFunc acquire, uno_Mapping * mapping ) 173 { 174 return icopyConstructSequence( pSource, pElementType, acquire, mapping ); 175 } 176 177 //============================================================================== 178 void destructSequence( 179 uno_Sequence * pSequence, 180 typelib_TypeDescriptionReference * pType, 181 typelib_TypeDescription * pTypeDescr, 182 uno_ReleaseFunc release ) 183 { 184 idestructSequence( pSequence, pType, pTypeDescr, release ); 185 } 186 187 //================================================================================================== 188 sal_Bool equalSequence( 189 uno_Sequence * pDest, uno_Sequence * pSource, 190 typelib_TypeDescriptionReference * pElementType, 191 uno_QueryInterfaceFunc queryInterface, uno_ReleaseFunc release ) 192 SAL_THROW( () ) 193 { 194 return _equalSequence( pDest, pSource, pElementType, queryInterface, release ); 195 } 196 197 extern "C" 198 { 199 //################################################################################################## 200 void SAL_CALL uno_type_constructData( 201 void * pMem, typelib_TypeDescriptionReference * pType ) 202 SAL_THROW_EXTERN_C() 203 { 204 _defaultConstructData( pMem, pType, 0 ); 205 } 206 //################################################################################################## 207 void SAL_CALL uno_constructData( 208 void * pMem, typelib_TypeDescription * pTypeDescr ) 209 SAL_THROW_EXTERN_C() 210 { 211 _defaultConstructData( pMem, pTypeDescr->pWeakRef, pTypeDescr ); 212 } 213 //################################################################################################## 214 void SAL_CALL uno_type_destructData( 215 void * pValue, typelib_TypeDescriptionReference * pType, 216 uno_ReleaseFunc release ) 217 SAL_THROW_EXTERN_C() 218 { 219 _destructData( pValue, pType, 0, release ); 220 } 221 //################################################################################################## 222 void SAL_CALL uno_destructData( 223 void * pValue, 224 typelib_TypeDescription * pTypeDescr, 225 uno_ReleaseFunc release ) 226 SAL_THROW_EXTERN_C() 227 { 228 _destructData( pValue, pTypeDescr->pWeakRef, pTypeDescr, release ); 229 } 230 //################################################################################################## 231 void SAL_CALL uno_type_copyData( 232 void * pDest, void * pSource, 233 typelib_TypeDescriptionReference * pType, 234 uno_AcquireFunc acquire ) 235 SAL_THROW_EXTERN_C() 236 { 237 _copyConstructData( pDest, pSource, pType, 0, acquire, 0 ); 238 } 239 //################################################################################################## 240 void SAL_CALL uno_copyData( 241 void * pDest, void * pSource, 242 typelib_TypeDescription * pTypeDescr, 243 uno_AcquireFunc acquire ) 244 SAL_THROW_EXTERN_C() 245 { 246 _copyConstructData( pDest, pSource, pTypeDescr->pWeakRef, pTypeDescr, acquire, 0 ); 247 } 248 //################################################################################################## 249 void SAL_CALL uno_type_copyAndConvertData( 250 void * pDest, void * pSource, 251 typelib_TypeDescriptionReference * pType, 252 uno_Mapping * mapping ) 253 SAL_THROW_EXTERN_C() 254 { 255 _copyConstructData( pDest, pSource, pType, 0, 0, mapping ); 256 } 257 //################################################################################################## 258 void SAL_CALL uno_copyAndConvertData( 259 void * pDest, void * pSource, 260 typelib_TypeDescription * pTypeDescr, 261 uno_Mapping * mapping ) 262 SAL_THROW_EXTERN_C() 263 { 264 _copyConstructData( pDest, pSource, pTypeDescr->pWeakRef, pTypeDescr, 0, mapping ); 265 } 266 //################################################################################################## 267 sal_Bool SAL_CALL uno_type_equalData( 268 void * pVal1, typelib_TypeDescriptionReference * pVal1Type, 269 void * pVal2, typelib_TypeDescriptionReference * pVal2Type, 270 uno_QueryInterfaceFunc queryInterface, uno_ReleaseFunc release ) 271 SAL_THROW_EXTERN_C() 272 { 273 return _equalData( 274 pVal1, pVal1Type, 0, 275 pVal2, pVal2Type, 0, 276 queryInterface, release ); 277 } 278 //################################################################################################## 279 sal_Bool SAL_CALL uno_equalData( 280 void * pVal1, typelib_TypeDescription * pVal1TD, 281 void * pVal2, typelib_TypeDescription * pVal2TD, 282 uno_QueryInterfaceFunc queryInterface, uno_ReleaseFunc release ) 283 SAL_THROW_EXTERN_C() 284 { 285 return _equalData( 286 pVal1, pVal1TD->pWeakRef, pVal1TD, 287 pVal2, pVal2TD->pWeakRef, pVal2TD, 288 queryInterface, release ); 289 } 290 //################################################################################################## 291 sal_Bool SAL_CALL uno_type_assignData( 292 void * pDest, typelib_TypeDescriptionReference * pDestType, 293 void * pSource, typelib_TypeDescriptionReference * pSourceType, 294 uno_QueryInterfaceFunc queryInterface, uno_AcquireFunc acquire, uno_ReleaseFunc release ) 295 SAL_THROW_EXTERN_C() 296 { 297 return _assignData( 298 pDest, pDestType, 0, 299 pSource, pSourceType, 0, 300 queryInterface, acquire, release ); 301 } 302 //################################################################################################## 303 sal_Bool SAL_CALL uno_assignData( 304 void * pDest, typelib_TypeDescription * pDestTD, 305 void * pSource, typelib_TypeDescription * pSourceTD, 306 uno_QueryInterfaceFunc queryInterface, uno_AcquireFunc acquire, uno_ReleaseFunc release ) 307 SAL_THROW_EXTERN_C() 308 { 309 return _assignData( 310 pDest, pDestTD->pWeakRef, pDestTD, 311 pSource, pSourceTD->pWeakRef, pSourceTD, 312 queryInterface, acquire, release ); 313 } 314 //################################################################################################## 315 sal_Bool SAL_CALL uno_type_isAssignableFromData( 316 typelib_TypeDescriptionReference * pAssignable, 317 void * pFrom, typelib_TypeDescriptionReference * pFromType, 318 uno_QueryInterfaceFunc queryInterface, uno_ReleaseFunc release ) 319 SAL_THROW_EXTERN_C() 320 { 321 if (::typelib_typedescriptionreference_isAssignableFrom( pAssignable, pFromType )) 322 return sal_True; 323 if (typelib_TypeClass_INTERFACE != pFromType->eTypeClass || 324 typelib_TypeClass_INTERFACE != pAssignable->eTypeClass) 325 { 326 return sal_False; 327 } 328 329 // query 330 if (0 == pFrom) 331 return sal_False; 332 void * pInterface = *(void **)pFrom; 333 if (0 == pInterface) 334 return sal_False; 335 336 if (0 == queryInterface) 337 queryInterface = binuno_queryInterface; 338 void * p = (*queryInterface)( pInterface, pAssignable ); 339 _release( p, release ); 340 return (0 != p); 341 } 342 } 343 344 345 //################################################################################################## 346 //################################################################################################## 347 //################################################################################################## 348 349 350 #if OSL_DEBUG_LEVEL > 1 351 352 #if defined( SAL_W32) 353 #pragma pack(push, 8) 354 #elif defined(SAL_OS2) 355 #pragma pack(push, 4) 356 #endif 357 358 #if defined(INTEL) \ 359 && (defined(__GNUC__) && (defined(LINUX) || defined(FREEBSD) || defined(OS2)) || defined(MACOSX) \ 360 || defined(__SUNPRO_CC) && defined(SOLARIS)) 361 #define MAX_ALIGNMENT_4 362 #endif 363 364 #define OFFSET_OF( s, m ) reinterpret_cast< std::size_t >((char *)&((s *)16)->m -16) 365 366 #define BINTEST_VERIFY( c ) \ 367 if (! (c)) { fprintf( stderr, "### binary compatibility test failed: %s [line %d]!!!\n", #c, __LINE__ ); abort(); } 368 #define BINTEST_VERIFYOFFSET( s, m, n ) \ 369 if (OFFSET_OF(s, m) != n) { fprintf( stderr, "### OFFSET_OF(" #s ", " #m ") = %" SAL_PRI_SIZET "u instead of expected %d!!!\n", OFFSET_OF(s, m), n ); abort(); } 370 371 #if OSL_DEBUG_LEVEL > 1 372 #if defined(__GNUC__) && (defined(LINUX) || defined(FREEBSD)) && (defined(INTEL) || defined(POWERPC) || defined(X86_64) || defined(S390)) 373 #define BINTEST_VERIFYSIZE( s, n ) \ 374 fprintf( stderr, "> sizeof(" #s ") = %d; __alignof__ (" #s ") = %d\n", sizeof(s), __alignof__ (s) ); \ 375 if (sizeof(s) != n) { fprintf( stderr, "### sizeof(" #s ") = %d instead of expected %d!!!\n", sizeof(s), n ); abort(); } 376 #else // ! GNUC 377 #define BINTEST_VERIFYSIZE( s, n ) \ 378 fprintf( stderr, "> sizeof(" #s ") = %d\n", sizeof(s) ); \ 379 if (sizeof(s) != n) { fprintf( stderr, "### sizeof(" #s ") = %d instead of expected %d!!!\n", sizeof(s), n ); abort(); } 380 #endif 381 #else // ! OSL_DEBUG_LEVEL 382 #define BINTEST_VERIFYSIZE( s, n ) \ 383 if (sizeof(s) != n) { fprintf( stderr, "### sizeof(" #s ") = %d instead of expected %d!!!\n", sizeof(s), n ); abort(); } 384 #endif 385 386 struct C1 387 { 388 sal_Int16 n1; 389 }; 390 struct C2 : public C1 391 { 392 sal_Int32 n2 CPPU_GCC3_ALIGN( C1 ); 393 }; 394 struct C3 : public C2 395 { 396 double d3; 397 sal_Int32 n3; 398 }; 399 struct C4 : public C3 400 { 401 sal_Int32 n4 CPPU_GCC3_ALIGN( C3 ); 402 double d4; 403 }; 404 struct C5 : public C4 405 { 406 sal_Int64 n5; 407 sal_Bool b5; 408 }; 409 struct C6 : public C1 410 { 411 C5 c6 CPPU_GCC3_ALIGN( C1 ); 412 sal_Bool b6; 413 }; 414 415 struct D 416 { 417 sal_Int16 d; 418 sal_Int32 e; 419 }; 420 struct E 421 { 422 sal_Bool a; 423 sal_Bool b; 424 sal_Bool c; 425 sal_Int16 d; 426 sal_Int32 e; 427 }; 428 429 struct M 430 { 431 sal_Int32 n; 432 sal_Int16 o; 433 }; 434 435 struct N : public M 436 { 437 sal_Int16 p CPPU_GCC3_ALIGN( M ); 438 }; 439 struct N2 440 { 441 M m; 442 sal_Int16 p; 443 }; 444 445 struct O : public M 446 { 447 double p; 448 sal_Int16 q; 449 }; 450 struct O2 : public O 451 { 452 sal_Int16 p2 CPPU_GCC3_ALIGN( O ); 453 }; 454 455 struct P : public N 456 { 457 double p2; 458 }; 459 460 struct empty 461 { 462 }; 463 struct second : public empty 464 { 465 int a; 466 }; 467 468 struct AlignSize_Impl 469 { 470 sal_Int16 nInt16; 471 double dDouble; 472 }; 473 474 struct Char1 475 { 476 char c1; 477 }; 478 struct Char2 : public Char1 479 { 480 char c2 CPPU_GCC3_ALIGN( Char1 ); 481 }; 482 struct Char3 : public Char2 483 { 484 char c3 CPPU_GCC3_ALIGN( Char2 ); 485 }; 486 struct Char4 487 { 488 Char3 chars; 489 char c; 490 }; 491 class Ref 492 { 493 void * p; 494 }; 495 enum Enum 496 { 497 v = SAL_MAX_ENUM 498 }; 499 500 501 class BinaryCompatible_Impl 502 { 503 public: 504 BinaryCompatible_Impl(); 505 }; 506 BinaryCompatible_Impl::BinaryCompatible_Impl() 507 { 508 BOOST_STATIC_ASSERT( ((sal_Bool) true) == sal_True && 509 (1 != 0) == sal_True ); 510 BOOST_STATIC_ASSERT( ((sal_Bool) false) == sal_False && 511 (1 == 0) == sal_False ); 512 #ifdef MAX_ALIGNMENT_4 513 // max alignment is 4 514 BINTEST_VERIFYOFFSET( AlignSize_Impl, dDouble, 4 ); 515 BINTEST_VERIFYSIZE( AlignSize_Impl, 12 ); 516 #else 517 // max alignment is 8 518 BINTEST_VERIFYOFFSET( AlignSize_Impl, dDouble, 8 ); 519 BINTEST_VERIFYSIZE( AlignSize_Impl, 16 ); 520 #endif 521 522 // sequence 523 BINTEST_VERIFY( (SAL_SEQUENCE_HEADER_SIZE % 8) == 0 ); 524 // enum 525 BINTEST_VERIFY( sizeof( Enum ) == sizeof( sal_Int32 ) ); 526 // any 527 BINTEST_VERIFY( sizeof(void *) >= sizeof(sal_Int32) ); 528 BINTEST_VERIFY( sizeof( uno_Any ) == sizeof( void * ) * 3 ); 529 BINTEST_VERIFYOFFSET( uno_Any, pType, 0 ); 530 BINTEST_VERIFYOFFSET( uno_Any, pData, 1 * sizeof (void *) ); 531 BINTEST_VERIFYOFFSET( uno_Any, pReserved, 2 * sizeof (void *) ); 532 // interface 533 BINTEST_VERIFY( sizeof( Ref ) == sizeof( void * ) ); 534 // string 535 BINTEST_VERIFY( sizeof( OUString ) == sizeof( rtl_uString * ) ); 536 // struct 537 BINTEST_VERIFYSIZE( M, 8 ); 538 BINTEST_VERIFYOFFSET( M, o, 4 ); 539 BINTEST_VERIFYSIZE( N, 12 ); 540 BINTEST_VERIFYOFFSET( N, p, 8 ); 541 BINTEST_VERIFYSIZE( N2, 12 ); 542 BINTEST_VERIFYOFFSET( N2, p, 8 ); 543 #ifdef MAX_ALIGNMENT_4 544 BINTEST_VERIFYSIZE( O, 20 ); 545 #else 546 BINTEST_VERIFYSIZE( O, 24 ); 547 #endif 548 BINTEST_VERIFYSIZE( D, 8 ); 549 BINTEST_VERIFYOFFSET( D, e, 4 ); 550 BINTEST_VERIFYOFFSET( E, d, 4 ); 551 BINTEST_VERIFYOFFSET( E, e, 8 ); 552 553 BINTEST_VERIFYSIZE( C1, 2 ); 554 BINTEST_VERIFYSIZE( C2, 8 ); 555 BINTEST_VERIFYOFFSET( C2, n2, 4 ); 556 557 #ifdef MAX_ALIGNMENT_4 558 BINTEST_VERIFYSIZE( C3, 20 ); 559 BINTEST_VERIFYOFFSET( C3, d3, 8 ); 560 BINTEST_VERIFYOFFSET( C3, n3, 16 ); 561 BINTEST_VERIFYSIZE( C4, 32 ); 562 BINTEST_VERIFYOFFSET( C4, n4, 20 ); 563 BINTEST_VERIFYOFFSET( C4, d4, 24 ); 564 BINTEST_VERIFYSIZE( C5, 44 ); 565 BINTEST_VERIFYOFFSET( C5, n5, 32 ); 566 BINTEST_VERIFYOFFSET( C5, b5, 40 ); 567 BINTEST_VERIFYSIZE( C6, 52 ); 568 BINTEST_VERIFYOFFSET( C6, c6, 4 ); 569 BINTEST_VERIFYOFFSET( C6, b6, 48 ); 570 571 BINTEST_VERIFYSIZE( O2, 24 ); 572 BINTEST_VERIFYOFFSET( O2, p2, 20 ); 573 #else 574 BINTEST_VERIFYSIZE( C3, 24 ); 575 BINTEST_VERIFYOFFSET( C3, d3, 8 ); 576 BINTEST_VERIFYOFFSET( C3, n3, 16 ); 577 BINTEST_VERIFYSIZE( C4, 40 ); 578 BINTEST_VERIFYOFFSET( C4, n4, 24 ); 579 BINTEST_VERIFYOFFSET( C4, d4, 32 ); 580 BINTEST_VERIFYSIZE( C5, 56 ); 581 BINTEST_VERIFYOFFSET( C5, n5, 40 ); 582 BINTEST_VERIFYOFFSET( C5, b5, 48 ); 583 BINTEST_VERIFYSIZE( C6, 72 ); 584 BINTEST_VERIFYOFFSET( C6, c6, 8 ); 585 BINTEST_VERIFYOFFSET( C6, b6, 64 ); 586 587 BINTEST_VERIFYSIZE( O2, 32 ); 588 BINTEST_VERIFYOFFSET( O2, p2, 24 ); 589 #endif 590 591 BINTEST_VERIFYSIZE( Char3, 3 ); 592 BINTEST_VERIFYOFFSET( Char4, c, 3 ); 593 594 #ifdef MAX_ALIGNMENT_4 595 // max alignment is 4 596 BINTEST_VERIFYSIZE( P, 20 ); 597 #else 598 // alignment of P is 8, because of P[] ... 599 BINTEST_VERIFYSIZE( P, 24 ); 600 BINTEST_VERIFYSIZE( second, sizeof( int ) ); 601 #endif 602 } 603 604 #ifdef SAL_W32 605 # pragma pack(pop) 606 #elif defined(SAL_OS2) 607 # pragma pack() 608 #endif 609 610 static BinaryCompatible_Impl aTest; 611 612 #endif 613 614 } 615