1 /************************************************************************* 2 * 3 * DO NOT ALTER OR REMOVE COPYRIGHT NOTICES OR THIS FILE HEADER. 4 * 5 * Copyright 2000, 2010 Oracle and/or its affiliates. 6 * 7 * OpenOffice.org - a multi-platform office productivity suite 8 * 9 * This file is part of OpenOffice.org. 10 * 11 * OpenOffice.org is free software: you can redistribute it and/or modify 12 * it under the terms of the GNU Lesser General Public License version 3 13 * only, as published by the Free Software Foundation. 14 * 15 * OpenOffice.org is distributed in the hope that it will be useful, 16 * but WITHOUT ANY WARRANTY; without even the implied warranty of 17 * MERCHANTABILITY or FITNESS FOR A PARTICULAR PURPOSE. See the 18 * GNU Lesser General Public License version 3 for more details 19 * (a copy is included in the LICENSE file that accompanied this code). 20 * 21 * You should have received a copy of the GNU Lesser General Public License 22 * version 3 along with OpenOffice.org. If not, see 23 * <http://www.openoffice.org/license.html> 24 * for a copy of the LGPLv3 License. 25 * 26 ************************************************************************/ 27 #ifndef COPY_HXX 28 #define COPY_HXX 29 30 #include "prim.hxx" 31 #include "constr.hxx" 32 33 34 namespace cppu 35 { 36 37 //################################################################################################## 38 //#### copy construction ########################################################################### 39 //################################################################################################## 40 41 //------------------------------------------------------------------------------ 42 inline uno_Sequence * allocSeq( 43 sal_Int32 nElementSize, sal_Int32 nElements ) 44 { 45 OSL_ASSERT( nElements >= 0 && nElementSize >= 0 ); 46 uno_Sequence * pSeq = 0; 47 sal_uInt32 nSize = calcSeqMemSize( nElementSize, nElements ); 48 if (nSize > 0) 49 { 50 pSeq = (uno_Sequence *) rtl_allocateMemory( nSize ); 51 if (pSeq != 0) 52 { 53 // header init 54 pSeq->nRefCount = 1; 55 pSeq->nElements = nElements; 56 } 57 } 58 return pSeq; 59 } 60 61 //-------------------------------------------------------------------------------------------------- 62 void copyConstructStruct( 63 void * pDest, void * pSource, 64 typelib_CompoundTypeDescription * pTypeDescr, 65 uno_AcquireFunc acquire, uno_Mapping * mapping ) 66 SAL_THROW ( () ); 67 //-------------------------------------------------------------------------------------------------- 68 inline void _copyConstructStruct( 69 void * pDest, void * pSource, 70 typelib_CompoundTypeDescription * pTypeDescr, 71 uno_AcquireFunc acquire, uno_Mapping * mapping ) 72 SAL_THROW ( () ) 73 { 74 if (pTypeDescr->pBaseTypeDescription) 75 { 76 // copy base value 77 copyConstructStruct( pDest, pSource, pTypeDescr->pBaseTypeDescription, acquire, mapping ); 78 } 79 80 // then copy members 81 typelib_TypeDescriptionReference ** ppTypeRefs = pTypeDescr->ppTypeRefs; 82 sal_Int32 * pMemberOffsets = pTypeDescr->pMemberOffsets; 83 sal_Int32 nDescr = pTypeDescr->nMembers; 84 85 if (mapping) 86 { 87 while (nDescr--) 88 { 89 ::uno_type_copyAndConvertData( 90 (char *)pDest + pMemberOffsets[nDescr], 91 (char *)pSource + pMemberOffsets[nDescr], 92 ppTypeRefs[nDescr], mapping ); 93 } 94 } 95 else 96 { 97 while (nDescr--) 98 { 99 ::uno_type_copyData( 100 (char *)pDest + pMemberOffsets[nDescr], 101 (char *)pSource + pMemberOffsets[nDescr], 102 ppTypeRefs[nDescr], acquire ); 103 } 104 } 105 } 106 //-------------------------------------------------------------------------------------------------- 107 inline void _copyConstructArray( 108 void * pDest, void * pSource, 109 typelib_ArrayTypeDescription * pTypeDescr, 110 uno_AcquireFunc acquire, uno_Mapping * mapping ) 111 { 112 typelib_TypeDescriptionReference * pElementTypeRef = ((typelib_IndirectTypeDescription *)pTypeDescr)->pType; 113 typelib_TypeDescription * pElementTypeDescr = NULL; 114 TYPELIB_DANGER_GET( &pElementTypeDescr, pElementTypeRef ); 115 sal_Int32 nElementSize = ((typelib_TypeDescription*)pElementTypeDescr)->nSize; 116 TYPELIB_DANGER_RELEASE( pElementTypeDescr ); 117 sal_Int32 nTotalElements = pTypeDescr->nTotalElements; 118 119 if (mapping) 120 { 121 for(sal_Int32 i = 0; i < nTotalElements; i++) 122 { 123 ::uno_type_copyAndConvertData( 124 (sal_Char *)pDest + i * nElementSize, 125 (sal_Char *)pSource + i * nElementSize, 126 pElementTypeRef, mapping ); 127 } 128 } 129 else 130 { 131 for(sal_Int32 i = 0; i < nTotalElements; i++) 132 { 133 ::uno_type_copyData( 134 (sal_Char *)pDest + (i * nElementSize), 135 (sal_Char *)pSource + (i * nElementSize), 136 pElementTypeRef, acquire ); 137 } 138 } 139 } 140 //-------------------------------------------------------------------------------------------------- 141 inline void _copyConstructUnion( 142 void * pDest, void * pSource, 143 typelib_TypeDescription * pTypeDescr, 144 uno_AcquireFunc acquire, uno_Mapping * mapping ) 145 SAL_THROW ( () ) 146 { 147 typelib_TypeDescriptionReference * pSetType = _unionGetSetType( pSource, pTypeDescr ); 148 if (mapping) 149 { 150 ::uno_type_copyAndConvertData( 151 (char *)pDest + ((typelib_UnionTypeDescription *)pTypeDescr)->nValueOffset, 152 (char *)pSource + ((typelib_UnionTypeDescription *)pTypeDescr)->nValueOffset, 153 pSetType, mapping ); 154 } 155 else 156 { 157 ::uno_type_copyData( 158 (char *)pDest + ((typelib_UnionTypeDescription *)pTypeDescr)->nValueOffset, 159 (char *)pSource + ((typelib_UnionTypeDescription *)pTypeDescr)->nValueOffset, 160 pSetType, acquire ); 161 } 162 *(sal_Int64 *)pDest = *(sal_Int64 *)pSource; 163 typelib_typedescriptionreference_release( pSetType ); 164 } 165 166 //------------------------------------------------------------------------------ 167 uno_Sequence * copyConstructSequence( 168 uno_Sequence * pSource, 169 typelib_TypeDescriptionReference * pElementType, 170 uno_AcquireFunc acquire, uno_Mapping * mapping ); 171 172 //-------------------------------------------------------------------------------------------------- 173 inline void _copyConstructAnyFromData( 174 uno_Any * pDestAny, void * pSource, 175 typelib_TypeDescriptionReference * pType, typelib_TypeDescription * pTypeDescr, 176 uno_AcquireFunc acquire, uno_Mapping * mapping ) 177 SAL_THROW ( () ) 178 { 179 TYPE_ACQUIRE( pType ); 180 pDestAny->pType = pType; 181 182 switch (pType->eTypeClass) 183 { 184 case typelib_TypeClass_CHAR: 185 pDestAny->pData = &pDestAny->pReserved; 186 *(sal_Unicode *)&pDestAny->pReserved = *(sal_Unicode *)pSource; 187 break; 188 case typelib_TypeClass_BOOLEAN: 189 pDestAny->pData = &pDestAny->pReserved; 190 *(sal_Bool *)&pDestAny->pReserved = (*(sal_Bool *)pSource != sal_False); 191 break; 192 case typelib_TypeClass_BYTE: 193 pDestAny->pData = &pDestAny->pReserved; 194 *(sal_Int8 *)&pDestAny->pReserved = *(sal_Int8 *)pSource; 195 break; 196 case typelib_TypeClass_SHORT: 197 case typelib_TypeClass_UNSIGNED_SHORT: 198 pDestAny->pData = &pDestAny->pReserved; 199 *(sal_Int16 *)&pDestAny->pReserved = *(sal_Int16 *)pSource; 200 break; 201 case typelib_TypeClass_LONG: 202 case typelib_TypeClass_UNSIGNED_LONG: 203 pDestAny->pData = &pDestAny->pReserved; 204 *(sal_Int32 *)&pDestAny->pReserved = *(sal_Int32 *)pSource; 205 break; 206 case typelib_TypeClass_HYPER: 207 case typelib_TypeClass_UNSIGNED_HYPER: 208 if (sizeof(void *) >= sizeof(sal_Int64)) 209 { 210 pDestAny->pData = &pDestAny->pReserved; 211 *(sal_Int64 *)&pDestAny->pReserved = *(sal_Int64 *)pSource; 212 } 213 else 214 { 215 pDestAny->pData = ::rtl_allocateMemory( sizeof(sal_Int64) ); 216 *(sal_Int64 *)pDestAny->pData = *(sal_Int64 *)pSource; 217 } 218 break; 219 case typelib_TypeClass_FLOAT: 220 if (sizeof(void *) >= sizeof(float)) 221 { 222 pDestAny->pData = &pDestAny->pReserved; 223 *(float *)&pDestAny->pReserved = *(float *)pSource; 224 } 225 else 226 { 227 pDestAny->pData = ::rtl_allocateMemory( sizeof(float) ); 228 *(float *)pDestAny->pData = *(float *)pSource; 229 } 230 break; 231 case typelib_TypeClass_DOUBLE: 232 if (sizeof(void *) >= sizeof(double)) 233 { 234 pDestAny->pData = &pDestAny->pReserved; 235 *(double *)&pDestAny->pReserved = *(double *)pSource; 236 } 237 else 238 { 239 pDestAny->pData = ::rtl_allocateMemory( sizeof(double) ); 240 *(double *)pDestAny->pData = *(double *)pSource; 241 } 242 break; 243 case typelib_TypeClass_STRING: 244 ::rtl_uString_acquire( *(rtl_uString **)pSource ); 245 pDestAny->pData = &pDestAny->pReserved; 246 *(rtl_uString **)&pDestAny->pReserved = *(rtl_uString **)pSource; 247 break; 248 case typelib_TypeClass_TYPE: 249 TYPE_ACQUIRE( *(typelib_TypeDescriptionReference **)pSource ); 250 pDestAny->pData = &pDestAny->pReserved; 251 *(typelib_TypeDescriptionReference **)&pDestAny->pReserved = *(typelib_TypeDescriptionReference **)pSource; 252 break; 253 case typelib_TypeClass_ANY: 254 OSL_ENSURE( 0, "### unexpected nested any!" ); 255 break; 256 case typelib_TypeClass_ENUM: 257 pDestAny->pData = &pDestAny->pReserved; 258 // enum is forced to 32bit long 259 *(sal_Int32 *)&pDestAny->pReserved = *(sal_Int32 *)pSource; 260 break; 261 case typelib_TypeClass_STRUCT: 262 case typelib_TypeClass_EXCEPTION: 263 if (pTypeDescr) 264 { 265 pDestAny->pData = ::rtl_allocateMemory( pTypeDescr->nSize ); 266 _copyConstructStruct( 267 pDestAny->pData, pSource, 268 (typelib_CompoundTypeDescription *)pTypeDescr, 269 acquire, mapping ); 270 } 271 else 272 { 273 TYPELIB_DANGER_GET( &pTypeDescr, pType ); 274 pDestAny->pData = ::rtl_allocateMemory( pTypeDescr->nSize ); 275 _copyConstructStruct( 276 pDestAny->pData, pSource, 277 (typelib_CompoundTypeDescription *)pTypeDescr, 278 acquire, mapping ); 279 TYPELIB_DANGER_RELEASE( pTypeDescr ); 280 } 281 break; 282 case typelib_TypeClass_ARRAY: 283 if (pTypeDescr) 284 { 285 pDestAny->pData = ::rtl_allocateMemory( pTypeDescr->nSize ); 286 _copyConstructArray( 287 pDestAny->pData, pSource, 288 (typelib_ArrayTypeDescription *)pTypeDescr, 289 acquire, mapping ); 290 } 291 else 292 { 293 TYPELIB_DANGER_GET( &pTypeDescr, pType ); 294 pDestAny->pData = ::rtl_allocateMemory( pTypeDescr->nSize ); 295 _copyConstructArray( 296 pDestAny->pData, pSource, 297 (typelib_ArrayTypeDescription *)pTypeDescr, 298 acquire, mapping ); 299 TYPELIB_DANGER_RELEASE( pTypeDescr ); 300 } 301 break; 302 case typelib_TypeClass_UNION: 303 if (pTypeDescr) 304 { 305 pDestAny->pData = ::rtl_allocateMemory( pTypeDescr->nSize ); 306 _copyConstructUnion( pDestAny->pData, pSource, pTypeDescr, acquire, mapping ); 307 } 308 else 309 { 310 TYPELIB_DANGER_GET( &pTypeDescr, pType ); 311 pDestAny->pData = ::rtl_allocateMemory( pTypeDescr->nSize ); 312 _copyConstructUnion( pDestAny->pData, pSource, pTypeDescr, acquire, mapping ); 313 TYPELIB_DANGER_RELEASE( pTypeDescr ); 314 } 315 break; 316 case typelib_TypeClass_SEQUENCE: 317 pDestAny->pData = &pDestAny->pReserved; 318 if (pTypeDescr) 319 { 320 *(uno_Sequence **)&pDestAny->pReserved = copyConstructSequence( 321 *(uno_Sequence **)pSource, 322 ((typelib_IndirectTypeDescription *)pTypeDescr)->pType, 323 acquire, mapping ); 324 } 325 else 326 { 327 TYPELIB_DANGER_GET( &pTypeDescr, pType ); 328 *(uno_Sequence **)&pDestAny->pReserved = copyConstructSequence( 329 *(uno_Sequence **)pSource, 330 ((typelib_IndirectTypeDescription *)pTypeDescr)->pType, 331 acquire, mapping ); 332 TYPELIB_DANGER_RELEASE( pTypeDescr ); 333 } 334 break; 335 case typelib_TypeClass_INTERFACE: 336 pDestAny->pData = &pDestAny->pReserved; 337 if (mapping) 338 { 339 pDestAny->pReserved = _map( *(void **)pSource, pType, pTypeDescr, mapping ); 340 } 341 else 342 { 343 _acquire( pDestAny->pReserved = *(void **)pSource, acquire ); 344 } 345 break; 346 default: 347 OSL_ASSERT(false); 348 break; 349 } 350 } 351 //-------------------------------------------------------------------------------------------------- 352 inline void _copyConstructAny( 353 uno_Any * pDestAny, void * pSource, 354 typelib_TypeDescriptionReference * pType, typelib_TypeDescription * pTypeDescr, 355 uno_AcquireFunc acquire, uno_Mapping * mapping ) 356 SAL_THROW ( () ) 357 { 358 if (typelib_TypeClass_VOID == pType->eTypeClass) 359 { 360 CONSTRUCT_EMPTY_ANY( pDestAny ); 361 } 362 else 363 { 364 if (typelib_TypeClass_ANY == pType->eTypeClass) 365 { 366 if (pSource) 367 { 368 pType = ((uno_Any *)pSource)->pType; 369 if (typelib_TypeClass_VOID == pType->eTypeClass) 370 { 371 CONSTRUCT_EMPTY_ANY( pDestAny ); 372 return; 373 } 374 pTypeDescr = 0; 375 pSource = ((uno_Any *)pSource)->pData; 376 } 377 else 378 { 379 CONSTRUCT_EMPTY_ANY( pDestAny ); 380 return; 381 } 382 } 383 if (pSource) 384 { 385 _copyConstructAnyFromData( pDestAny, pSource, pType, pTypeDescr, acquire, mapping ); 386 } 387 else // default construct 388 { 389 TYPE_ACQUIRE( pType ); 390 pDestAny->pType = pType; 391 switch (pType->eTypeClass) 392 { 393 case typelib_TypeClass_CHAR: 394 pDestAny->pData = &pDestAny->pReserved; 395 *(sal_Unicode *)&pDestAny->pReserved = '\0'; 396 break; 397 case typelib_TypeClass_BOOLEAN: 398 pDestAny->pData = &pDestAny->pReserved; 399 *(sal_Bool *)&pDestAny->pReserved = sal_False; 400 break; 401 case typelib_TypeClass_BYTE: 402 pDestAny->pData = &pDestAny->pReserved; 403 *(sal_Int8 *)&pDestAny->pReserved = 0; 404 break; 405 case typelib_TypeClass_SHORT: 406 case typelib_TypeClass_UNSIGNED_SHORT: 407 pDestAny->pData = &pDestAny->pReserved; 408 *(sal_Int16 *)&pDestAny->pReserved = 0; 409 break; 410 case typelib_TypeClass_LONG: 411 case typelib_TypeClass_UNSIGNED_LONG: 412 pDestAny->pData = &pDestAny->pReserved; 413 *(sal_Int32 *)&pDestAny->pReserved = 0; 414 break; 415 case typelib_TypeClass_HYPER: 416 case typelib_TypeClass_UNSIGNED_HYPER: 417 if (sizeof(void *) >= sizeof(sal_Int64)) 418 { 419 pDestAny->pData = &pDestAny->pReserved; 420 *(sal_Int64 *)&pDestAny->pReserved = 0; 421 } 422 else 423 { 424 pDestAny->pData = ::rtl_allocateMemory( sizeof(sal_Int64) ); 425 *(sal_Int64 *)pDestAny->pData = 0; 426 } 427 break; 428 case typelib_TypeClass_FLOAT: 429 if (sizeof(void *) >= sizeof(float)) 430 { 431 pDestAny->pData = &pDestAny->pReserved; 432 *(float *)&pDestAny->pReserved = 0.0; 433 } 434 else 435 { 436 pDestAny->pData = ::rtl_allocateMemory( sizeof(float) ); 437 *(float *)pDestAny->pData = 0.0; 438 } 439 break; 440 case typelib_TypeClass_DOUBLE: 441 if (sizeof(void *) >= sizeof(double)) 442 { 443 pDestAny->pData = &pDestAny->pReserved; 444 *(double *)&pDestAny->pReserved = 0.0; 445 } 446 else 447 { 448 pDestAny->pData = ::rtl_allocateMemory( sizeof(double) ); 449 *(double *)pDestAny->pData = 0.0; 450 } 451 break; 452 case typelib_TypeClass_STRING: 453 pDestAny->pData = &pDestAny->pReserved; 454 *(rtl_uString **)&pDestAny->pReserved = 0; 455 ::rtl_uString_new( (rtl_uString **)&pDestAny->pReserved ); 456 break; 457 case typelib_TypeClass_TYPE: 458 pDestAny->pData = &pDestAny->pReserved; 459 *(typelib_TypeDescriptionReference **)&pDestAny->pReserved = _getVoidType(); 460 break; 461 case typelib_TypeClass_ENUM: 462 pDestAny->pData = &pDestAny->pReserved; 463 if (pTypeDescr) 464 { 465 *(sal_Int32 *)&pDestAny->pReserved = ((typelib_EnumTypeDescription *)pTypeDescr)->nDefaultEnumValue; 466 } 467 else 468 { 469 TYPELIB_DANGER_GET( &pTypeDescr, pType ); 470 *(sal_Int32 *)&pDestAny->pReserved = ((typelib_EnumTypeDescription *)pTypeDescr)->nDefaultEnumValue; 471 TYPELIB_DANGER_RELEASE( pTypeDescr ); 472 } 473 break; 474 case typelib_TypeClass_STRUCT: 475 case typelib_TypeClass_EXCEPTION: 476 if (pTypeDescr) 477 { 478 pDestAny->pData = ::rtl_allocateMemory( pTypeDescr->nSize ); 479 _defaultConstructStruct( 480 pDestAny->pData, (typelib_CompoundTypeDescription *)pTypeDescr ); 481 } 482 else 483 { 484 TYPELIB_DANGER_GET( &pTypeDescr, pType ); 485 pDestAny->pData = ::rtl_allocateMemory( pTypeDescr->nSize ); 486 _defaultConstructStruct( 487 pDestAny->pData, (typelib_CompoundTypeDescription *)pTypeDescr ); 488 TYPELIB_DANGER_RELEASE( pTypeDescr ); 489 } 490 break; 491 case typelib_TypeClass_ARRAY: 492 if (pTypeDescr) 493 { 494 pDestAny->pData = ::rtl_allocateMemory( pTypeDescr->nSize ); 495 _defaultConstructArray( 496 pDestAny->pData, (typelib_ArrayTypeDescription *)pTypeDescr ); 497 } 498 else 499 { 500 TYPELIB_DANGER_GET( &pTypeDescr, pType ); 501 pDestAny->pData = ::rtl_allocateMemory( pTypeDescr->nSize ); 502 _defaultConstructArray( 503 pDestAny->pData, (typelib_ArrayTypeDescription *)pTypeDescr ); 504 TYPELIB_DANGER_RELEASE( pTypeDescr ); 505 } 506 break; 507 case typelib_TypeClass_UNION: 508 if (pTypeDescr) 509 { 510 pDestAny->pData = ::rtl_allocateMemory( pTypeDescr->nSize ); 511 _defaultConstructUnion( pDestAny->pData, pTypeDescr ); 512 } 513 else 514 { 515 TYPELIB_DANGER_GET( &pTypeDescr, pType ); 516 pDestAny->pData = ::rtl_allocateMemory( pTypeDescr->nSize ); 517 _defaultConstructUnion( pDestAny->pData, pTypeDescr ); 518 TYPELIB_DANGER_RELEASE( pTypeDescr ); 519 } 520 break; 521 case typelib_TypeClass_SEQUENCE: 522 pDestAny->pData = &pDestAny->pReserved; 523 *(uno_Sequence **)&pDestAny->pReserved = createEmptySequence(); 524 break; 525 case typelib_TypeClass_INTERFACE: 526 pDestAny->pData = &pDestAny->pReserved; 527 pDestAny->pReserved = 0; // either cpp or c-uno interface 528 break; 529 default: 530 OSL_ASSERT(false); 531 break; 532 } 533 } 534 } 535 } 536 //------------------------------------------------------------------------------ 537 inline uno_Sequence * icopyConstructSequence( 538 uno_Sequence * pSource, 539 typelib_TypeDescriptionReference * pElementType, 540 uno_AcquireFunc acquire, uno_Mapping * mapping ) 541 { 542 typelib_TypeClass eTypeClass = pElementType->eTypeClass; 543 if (!mapping || 544 (eTypeClass <= typelib_TypeClass_ENUM && 545 eTypeClass != typelib_TypeClass_ANY)) 546 { 547 ::osl_incrementInterlockedCount( &pSource->nRefCount ); 548 return pSource; 549 } 550 else // create new sequence 551 { 552 uno_Sequence * pDest; 553 sal_Int32 nElements = pSource->nElements; 554 if (nElements) 555 { 556 switch (eTypeClass) 557 { 558 case typelib_TypeClass_ANY: 559 { 560 pDest = allocSeq( sizeof (uno_Any), nElements ); 561 if (pDest != 0) 562 { 563 uno_Any * pDestElements = (uno_Any *)pDest->elements; 564 uno_Any * pSourceElements = (uno_Any *)pSource->elements; 565 for ( sal_Int32 nPos = nElements; nPos--; ) 566 { 567 typelib_TypeDescriptionReference * pType = 568 pSourceElements[nPos].pType; 569 if (typelib_TypeClass_VOID == pType->eTypeClass) 570 { 571 CONSTRUCT_EMPTY_ANY( &pDestElements[nPos] ); 572 } 573 else 574 { 575 _copyConstructAnyFromData( 576 &pDestElements[nPos], 577 pSourceElements[nPos].pData, 578 pType, 0, 579 acquire, mapping ); 580 } 581 } 582 } 583 break; 584 } 585 case typelib_TypeClass_STRUCT: 586 case typelib_TypeClass_EXCEPTION: 587 { 588 typelib_TypeDescription * pElementTypeDescr = 0; 589 TYPELIB_DANGER_GET( &pElementTypeDescr, pElementType ); 590 sal_Int32 nElementSize = pElementTypeDescr->nSize; 591 char * pSourceElements = pSource->elements; 592 pDest = allocSeq( nElementSize, nElements ); 593 if (pDest != 0) 594 { 595 char * pElements = pDest->elements; 596 for ( sal_Int32 nPos = nElements; nPos--; ) 597 { 598 _copyConstructStruct( 599 pElements + (nPos * nElementSize), 600 pSourceElements + (nPos * nElementSize), 601 (typelib_CompoundTypeDescription *) 602 pElementTypeDescr, 603 acquire, mapping ); 604 } 605 } 606 TYPELIB_DANGER_RELEASE( pElementTypeDescr ); 607 break; 608 } 609 case typelib_TypeClass_ARRAY: 610 { 611 typelib_TypeDescription * pElementTypeDescr = 0; 612 TYPELIB_DANGER_GET( &pElementTypeDescr, pElementType ); 613 sal_Int32 nElementSize = pElementTypeDescr->nSize; 614 char * pSourceElements = pSource->elements; 615 pDest = allocSeq( nElementSize, nElements ); 616 if (pDest != 0) 617 { 618 char * pElements = pDest->elements; 619 for ( sal_Int32 nPos = nElements; nPos--; ) 620 { 621 _copyConstructArray( 622 pElements + (nPos * nElementSize), 623 pSourceElements + (nPos * nElementSize), 624 (typelib_ArrayTypeDescription *)pElementTypeDescr, 625 acquire, mapping ); 626 } 627 } 628 TYPELIB_DANGER_RELEASE( pElementTypeDescr ); 629 break; 630 } 631 case typelib_TypeClass_UNION: 632 { 633 typelib_TypeDescription * pElementTypeDescr = 0; 634 TYPELIB_DANGER_GET( &pElementTypeDescr, pElementType ); 635 sal_Int32 nElementSize = pElementTypeDescr->nSize; 636 sal_Int32 nValueOffset = 637 ((typelib_UnionTypeDescription *) 638 pElementTypeDescr)->nValueOffset; 639 pDest = allocSeq( nElementSize, nElements ); 640 if (pDest != 0) 641 { 642 char * pElements = pDest->elements; 643 char * pSourceElements = pSource->elements; 644 for ( sal_Int32 nPos = nElements; nPos--; ) 645 { 646 char * pDest2 = 647 pElements + (nPos * nElementSize); 648 char * pSource2 = 649 pSourceElements + (nPos * nElementSize); 650 651 typelib_TypeDescriptionReference * pSetType = 652 _unionGetSetType( pSource2, pElementTypeDescr ); 653 ::uno_type_copyAndConvertData( 654 pDest2 + nValueOffset, pSource2 + nValueOffset, 655 pSetType, mapping ); 656 *(sal_Int64 *)pDest2 = *(sal_Int64 *)pSource2; 657 ::typelib_typedescriptionreference_release( pSetType ); 658 } 659 } 660 TYPELIB_DANGER_RELEASE( pElementTypeDescr ); 661 break; 662 } 663 case typelib_TypeClass_SEQUENCE: // sequence of sequence 664 { 665 pDest = allocSeq( sizeof (uno_Sequence *), nElements ); 666 if (pDest != 0) 667 { 668 typelib_TypeDescription * pElementTypeDescr = 0; 669 TYPELIB_DANGER_GET( &pElementTypeDescr, pElementType ); 670 typelib_TypeDescriptionReference * pSeqElementType = 671 ((typelib_IndirectTypeDescription *) 672 pElementTypeDescr)->pType; 673 674 uno_Sequence ** pDestElements = 675 (uno_Sequence **) pDest->elements; 676 uno_Sequence ** pSourceElements = 677 (uno_Sequence **) pSource->elements; 678 for ( sal_Int32 nPos = nElements; nPos--; ) 679 { 680 uno_Sequence * pNew = copyConstructSequence( 681 pSourceElements[nPos], 682 pSeqElementType, 683 acquire, mapping ); 684 OSL_ASSERT( pNew != 0 ); 685 // ought never be a memory allocation problem, 686 // because of reference counted sequence handles 687 pDestElements[ nPos ] = pNew; 688 } 689 690 TYPELIB_DANGER_RELEASE( pElementTypeDescr ); 691 } 692 break; 693 } 694 case typelib_TypeClass_INTERFACE: 695 { 696 pDest = allocSeq( sizeof (void *), nElements ); 697 if (pDest != 0) 698 { 699 char * pElements = pDest->elements; 700 void ** pSourceElements = (void **)pSource->elements; 701 if (mapping) 702 { 703 typelib_TypeDescription * pElementTypeDescr = 0; 704 TYPELIB_DANGER_GET( &pElementTypeDescr, pElementType ); 705 for ( sal_Int32 nPos = nElements; nPos--; ) 706 { 707 ((void **)pElements)[nPos] = 0; 708 if (((void **)pSourceElements)[nPos]) 709 { 710 (*mapping->mapInterface)( 711 mapping, (void **)pElements + nPos, 712 pSourceElements[nPos], 713 (typelib_InterfaceTypeDescription *) 714 pElementTypeDescr ); 715 } 716 } 717 TYPELIB_DANGER_RELEASE( pElementTypeDescr ); 718 } 719 else 720 { 721 for ( sal_Int32 nPos = nElements; nPos--; ) 722 { 723 ((void **)pElements)[nPos] = pSourceElements[nPos]; 724 _acquire( ((void **)pElements)[nPos], acquire ); 725 } 726 } 727 } 728 break; 729 } 730 default: 731 OSL_ENSURE( 0, "### unexepcted sequence element type!" ); 732 pDest = 0; 733 break; 734 } 735 } 736 else // empty sequence 737 { 738 pDest = allocSeq( 0, 0 ); 739 } 740 741 return pDest; 742 } 743 } 744 745 //-------------------------------------------------------------------------------------------------- 746 inline void _copyConstructData( 747 void * pDest, void * pSource, 748 typelib_TypeDescriptionReference * pType, typelib_TypeDescription * pTypeDescr, 749 uno_AcquireFunc acquire, uno_Mapping * mapping ) 750 SAL_THROW ( () ) 751 { 752 switch (pType->eTypeClass) 753 { 754 case typelib_TypeClass_CHAR: 755 *(sal_Unicode *)pDest = *(sal_Unicode *)pSource; 756 break; 757 case typelib_TypeClass_BOOLEAN: 758 *(sal_Bool *)pDest = (*(sal_Bool *)pSource != sal_False); 759 break; 760 case typelib_TypeClass_BYTE: 761 *(sal_Int8 *)pDest = *(sal_Int8 *)pSource; 762 break; 763 case typelib_TypeClass_SHORT: 764 case typelib_TypeClass_UNSIGNED_SHORT: 765 *(sal_Int16 *)pDest = *(sal_Int16 *)pSource; 766 break; 767 case typelib_TypeClass_LONG: 768 case typelib_TypeClass_UNSIGNED_LONG: 769 *(sal_Int32 *)pDest = *(sal_Int32 *)pSource; 770 break; 771 case typelib_TypeClass_HYPER: 772 case typelib_TypeClass_UNSIGNED_HYPER: 773 *(sal_Int64 *)pDest = *(sal_Int64 *)pSource; 774 break; 775 case typelib_TypeClass_FLOAT: 776 *(float *)pDest = *(float *)pSource; 777 break; 778 case typelib_TypeClass_DOUBLE: 779 *(double *)pDest = *(double *)pSource; 780 break; 781 case typelib_TypeClass_STRING: 782 ::rtl_uString_acquire( *(rtl_uString **)pSource ); 783 *(rtl_uString **)pDest = *(rtl_uString **)pSource; 784 break; 785 case typelib_TypeClass_TYPE: 786 TYPE_ACQUIRE( *(typelib_TypeDescriptionReference **)pSource ); 787 *(typelib_TypeDescriptionReference **)pDest = *(typelib_TypeDescriptionReference **)pSource; 788 break; 789 case typelib_TypeClass_ANY: 790 _copyConstructAny( 791 (uno_Any *)pDest, ((uno_Any *)pSource)->pData, 792 ((uno_Any *)pSource)->pType, 0, 793 acquire, mapping ); 794 break; 795 case typelib_TypeClass_ENUM: 796 *(sal_Int32 *)pDest = *(sal_Int32 *)pSource; 797 break; 798 case typelib_TypeClass_STRUCT: 799 case typelib_TypeClass_EXCEPTION: 800 if (pTypeDescr) 801 { 802 _copyConstructStruct( 803 pDest, pSource, 804 (typelib_CompoundTypeDescription *)pTypeDescr, 805 acquire, mapping ); 806 } 807 else 808 { 809 TYPELIB_DANGER_GET( &pTypeDescr, pType ); 810 _copyConstructStruct( 811 pDest, pSource, 812 (typelib_CompoundTypeDescription *)pTypeDescr, 813 acquire, mapping ); 814 TYPELIB_DANGER_RELEASE( pTypeDescr ); 815 } 816 break; 817 case typelib_TypeClass_ARRAY: 818 if (pTypeDescr) 819 { 820 _copyConstructArray( 821 pDest, pSource, 822 (typelib_ArrayTypeDescription *)pTypeDescr, 823 acquire, mapping ); 824 } 825 else 826 { 827 TYPELIB_DANGER_GET( &pTypeDescr, pType ); 828 _copyConstructArray( 829 pDest, pSource, 830 (typelib_ArrayTypeDescription *)pTypeDescr, 831 acquire, mapping ); 832 TYPELIB_DANGER_RELEASE( pTypeDescr ); 833 } 834 break; 835 case typelib_TypeClass_UNION: 836 if (pTypeDescr) 837 { 838 _copyConstructUnion( pDest, pSource, pTypeDescr, acquire, mapping ); 839 } 840 else 841 { 842 TYPELIB_DANGER_GET( &pTypeDescr, pType ); 843 _copyConstructUnion( pDest, pSource, pTypeDescr, acquire, mapping ); 844 TYPELIB_DANGER_RELEASE( pTypeDescr ); 845 } 846 break; 847 case typelib_TypeClass_SEQUENCE: 848 if (mapping) 849 { 850 if (pTypeDescr) 851 { 852 *(uno_Sequence **)pDest = icopyConstructSequence( 853 *(uno_Sequence **)pSource, 854 ((typelib_IndirectTypeDescription *)pTypeDescr)->pType, 855 acquire, mapping ); 856 } 857 else 858 { 859 TYPELIB_DANGER_GET( &pTypeDescr, pType ); 860 *(uno_Sequence **)pDest = icopyConstructSequence( 861 *(uno_Sequence **)pSource, 862 ((typelib_IndirectTypeDescription *)pTypeDescr)->pType, 863 acquire, mapping ); 864 TYPELIB_DANGER_RELEASE( pTypeDescr ); 865 } 866 } 867 else 868 { 869 ::osl_incrementInterlockedCount( &(*(uno_Sequence **)pSource)->nRefCount ); 870 *(uno_Sequence **)pDest = *(uno_Sequence **)pSource; 871 } 872 break; 873 case typelib_TypeClass_INTERFACE: 874 if (mapping) 875 *(void **)pDest = _map( *(void **)pSource, pType, pTypeDescr, mapping ); 876 else 877 _acquire( *(void **)pDest = *(void **)pSource, acquire ); 878 break; 879 default: 880 break; 881 } 882 } 883 884 } 885 886 #endif 887