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