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), static_cast<int>(n) ); abort(); } 370 371 #if OSL_DEBUG_LEVEL > 1 372 #define BINTEST_VERIFYSIZE( s, n ) \ 373 if (sizeof(s) != n) { fprintf( stderr, "### sizeof(" #s ") = %d instead of expected %d!!!\n", (int)sizeof(s), n ); abort(); } 374 #endif 375 376 struct C1 377 { 378 sal_Int16 n1; 379 }; 380 struct C2 : public C1 381 { 382 sal_Int32 n2 CPPU_GCC3_ALIGN( C1 ); 383 }; 384 struct C3 : public C2 385 { 386 double d3; 387 sal_Int32 n3; 388 }; 389 struct C4 : public C3 390 { 391 sal_Int32 n4 CPPU_GCC3_ALIGN( C3 ); 392 double d4; 393 }; 394 struct C5 : public C4 395 { 396 sal_Int64 n5; 397 sal_Bool b5; 398 }; 399 struct C6 : public C1 400 { 401 C5 c6 CPPU_GCC3_ALIGN( C1 ); 402 sal_Bool b6; 403 }; 404 405 struct D 406 { 407 sal_Int16 d; 408 sal_Int32 e; 409 }; 410 struct E 411 { 412 sal_Bool a; 413 sal_Bool b; 414 sal_Bool c; 415 sal_Int16 d; 416 sal_Int32 e; 417 }; 418 419 struct M 420 { 421 sal_Int32 n; 422 sal_Int16 o; 423 }; 424 425 struct N : public M 426 { 427 sal_Int16 p CPPU_GCC3_ALIGN( M ); 428 }; 429 struct N2 430 { 431 M m; 432 sal_Int16 p; 433 }; 434 435 struct O : public M 436 { 437 double p; 438 sal_Int16 q; 439 }; 440 struct O2 : public O 441 { 442 sal_Int16 p2 CPPU_GCC3_ALIGN( O ); 443 }; 444 445 struct P : public N 446 { 447 double p2; 448 }; 449 450 struct empty 451 { 452 }; 453 struct second : public empty 454 { 455 int a; 456 }; 457 458 struct AlignSize_Impl 459 { 460 sal_Int16 nInt16; 461 double dDouble; 462 }; 463 464 struct Char1 465 { 466 char c1; 467 }; 468 struct Char2 : public Char1 469 { 470 char c2 CPPU_GCC3_ALIGN( Char1 ); 471 }; 472 struct Char3 : public Char2 473 { 474 char c3 CPPU_GCC3_ALIGN( Char2 ); 475 }; 476 struct Char4 477 { 478 Char3 chars; 479 char c; 480 }; 481 class Ref 482 { 483 void * p; 484 }; 485 enum Enum 486 { 487 v = SAL_MAX_ENUM 488 }; 489 490 491 class BinaryCompatible_Impl 492 { 493 public: 494 BinaryCompatible_Impl(); 495 }; 496 BinaryCompatible_Impl::BinaryCompatible_Impl() 497 { 498 BOOST_STATIC_ASSERT( ((sal_Bool) true) == sal_True && 499 (1 != 0) == sal_True ); 500 BOOST_STATIC_ASSERT( ((sal_Bool) false) == sal_False && 501 (1 == 0) == sal_False ); 502 #ifdef MAX_ALIGNMENT_4 503 // max alignment is 4 504 BINTEST_VERIFYOFFSET( AlignSize_Impl, dDouble, 4 ); 505 BINTEST_VERIFYSIZE( AlignSize_Impl, 12 ); 506 #else 507 // max alignment is 8 508 BINTEST_VERIFYOFFSET( AlignSize_Impl, dDouble, 8 ); 509 BINTEST_VERIFYSIZE( AlignSize_Impl, 16 ); 510 #endif 511 512 // sequence 513 BINTEST_VERIFY( (SAL_SEQUENCE_HEADER_SIZE % 8) == 0 ); 514 // enum 515 BINTEST_VERIFY( sizeof( Enum ) == sizeof( sal_Int32 ) ); 516 // any 517 BINTEST_VERIFY( sizeof(void *) >= sizeof(sal_Int32) ); 518 BINTEST_VERIFY( sizeof( uno_Any ) == sizeof( void * ) * 3 ); 519 BINTEST_VERIFYOFFSET( uno_Any, pType, 0 ); 520 BINTEST_VERIFYOFFSET( uno_Any, pData, 1 * sizeof (void *) ); 521 BINTEST_VERIFYOFFSET( uno_Any, pReserved, 2 * sizeof (void *) ); 522 // interface 523 BINTEST_VERIFY( sizeof( Ref ) == sizeof( void * ) ); 524 // string 525 BINTEST_VERIFY( sizeof( OUString ) == sizeof( rtl_uString * ) ); 526 // struct 527 BINTEST_VERIFYSIZE( M, 8 ); 528 BINTEST_VERIFYOFFSET( M, o, 4 ); 529 BINTEST_VERIFYSIZE( N, 12 ); 530 BINTEST_VERIFYOFFSET( N, p, 8 ); 531 BINTEST_VERIFYSIZE( N2, 12 ); 532 BINTEST_VERIFYOFFSET( N2, p, 8 ); 533 #ifdef MAX_ALIGNMENT_4 534 BINTEST_VERIFYSIZE( O, 20 ); 535 #else 536 BINTEST_VERIFYSIZE( O, 24 ); 537 #endif 538 BINTEST_VERIFYSIZE( D, 8 ); 539 BINTEST_VERIFYOFFSET( D, e, 4 ); 540 BINTEST_VERIFYOFFSET( E, d, 4 ); 541 BINTEST_VERIFYOFFSET( E, e, 8 ); 542 543 BINTEST_VERIFYSIZE( C1, 2 ); 544 BINTEST_VERIFYSIZE( C2, 8 ); 545 BINTEST_VERIFYOFFSET( C2, n2, 4 ); 546 547 #ifdef MAX_ALIGNMENT_4 548 BINTEST_VERIFYSIZE( C3, 20 ); 549 BINTEST_VERIFYOFFSET( C3, d3, 8 ); 550 BINTEST_VERIFYOFFSET( C3, n3, 16 ); 551 BINTEST_VERIFYSIZE( C4, 32 ); 552 BINTEST_VERIFYOFFSET( C4, n4, 20 ); 553 BINTEST_VERIFYOFFSET( C4, d4, 24 ); 554 BINTEST_VERIFYSIZE( C5, 44 ); 555 BINTEST_VERIFYOFFSET( C5, n5, 32 ); 556 BINTEST_VERIFYOFFSET( C5, b5, 40 ); 557 BINTEST_VERIFYSIZE( C6, 52 ); 558 BINTEST_VERIFYOFFSET( C6, c6, 4 ); 559 BINTEST_VERIFYOFFSET( C6, b6, 48 ); 560 561 BINTEST_VERIFYSIZE( O2, 24 ); 562 BINTEST_VERIFYOFFSET( O2, p2, 20 ); 563 #else 564 BINTEST_VERIFYSIZE( C3, 24 ); 565 BINTEST_VERIFYOFFSET( C3, d3, 8 ); 566 BINTEST_VERIFYOFFSET( C3, n3, 16 ); 567 BINTEST_VERIFYSIZE( C4, 40 ); 568 BINTEST_VERIFYOFFSET( C4, n4, 24 ); 569 BINTEST_VERIFYOFFSET( C4, d4, 32 ); 570 BINTEST_VERIFYSIZE( C5, 56 ); 571 BINTEST_VERIFYOFFSET( C5, n5, 40 ); 572 BINTEST_VERIFYOFFSET( C5, b5, 48 ); 573 BINTEST_VERIFYSIZE( C6, 72 ); 574 BINTEST_VERIFYOFFSET( C6, c6, 8 ); 575 BINTEST_VERIFYOFFSET( C6, b6, 64 ); 576 577 BINTEST_VERIFYSIZE( O2, 32 ); 578 BINTEST_VERIFYOFFSET( O2, p2, 24 ); 579 #endif 580 581 BINTEST_VERIFYSIZE( Char3, 3 ); 582 BINTEST_VERIFYOFFSET( Char4, c, 3 ); 583 584 #ifdef MAX_ALIGNMENT_4 585 // max alignment is 4 586 BINTEST_VERIFYSIZE( P, 20 ); 587 #else 588 // alignment of P is 8, because of P[] ... 589 BINTEST_VERIFYSIZE( P, 24 ); 590 BINTEST_VERIFYSIZE( second, sizeof( int ) ); 591 #endif 592 } 593 594 #ifdef SAL_W32 595 # pragma pack(pop) 596 #elif defined(SAL_OS2) 597 # pragma pack() 598 #endif 599 600 static BinaryCompatible_Impl aTest; 601 602 #endif 603 604 } 605