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 #include <rtl/memory.h> 27 #include <rtl/alloc.h> 28 #include <osl/diagnose.h> 29 #include <osl/interlck.h> 30 #include <typelib/typedescription.h> 31 #include <uno/data.h> 32 #include <uno/dispatcher.h> 33 #include <uno/sequence2.h> 34 35 #include "constr.hxx" 36 #include "copy.hxx" 37 #include "destr.hxx" 38 39 40 using namespace cppu; 41 42 namespace cppu 43 { 44 45 //------------------------------------------------------------------------------ 46 static inline uno_Sequence * reallocSeq( 47 uno_Sequence * pReallocate, sal_Size nElementSize, sal_Int32 nElements ) 48 { 49 OSL_ASSERT( nElements >= 0 ); 50 uno_Sequence * pNew = 0; 51 sal_uInt32 nSize = calcSeqMemSize( nElementSize, nElements ); 52 if (nSize > 0) 53 { 54 if (pReallocate == 0) 55 { 56 pNew = (uno_Sequence *) rtl_allocateMemory( nSize ); 57 } 58 else 59 { 60 pNew = (uno_Sequence *) rtl_reallocateMemory( pReallocate, nSize ); 61 } 62 if (pNew != 0) 63 { 64 // header init 65 pNew->nRefCount = 1; 66 pNew->nElements = nElements; 67 } 68 } 69 return pNew; 70 } 71 72 //------------------------------------------------------------------------------ 73 static inline bool idefaultConstructElements( 74 uno_Sequence ** ppSeq, 75 typelib_TypeDescriptionReference * pElementType, 76 sal_Int32 nStartIndex, sal_Int32 nStopIndex, 77 sal_Int32 nAlloc = -1 ) // >= 0 means (re)alloc memory for nAlloc elements 78 { 79 uno_Sequence * pSeq = *ppSeq; 80 switch (pElementType->eTypeClass) 81 { 82 case typelib_TypeClass_CHAR: 83 if (nAlloc >= 0) 84 pSeq = reallocSeq( pSeq, sizeof(sal_Unicode), nAlloc ); 85 if (pSeq != 0) 86 { 87 ::rtl_zeroMemory( 88 pSeq->elements + (sizeof(sal_Unicode) * nStartIndex), 89 sizeof(sal_Unicode) * (nStopIndex - nStartIndex) ); 90 } 91 break; 92 case typelib_TypeClass_BOOLEAN: 93 if (nAlloc >= 0) 94 pSeq = reallocSeq( pSeq, sizeof(sal_Bool), nAlloc ); 95 if (pSeq != 0) 96 { 97 ::rtl_zeroMemory( 98 pSeq->elements + (sizeof(sal_Bool) * nStartIndex), 99 sizeof(sal_Bool) * (nStopIndex - nStartIndex) ); 100 } 101 break; 102 case typelib_TypeClass_BYTE: 103 if (nAlloc >= 0) 104 pSeq = reallocSeq( pSeq, sizeof(sal_Int8), nAlloc ); 105 if (pSeq != 0) 106 { 107 ::rtl_zeroMemory( 108 pSeq->elements + (sizeof(sal_Int8) * nStartIndex), 109 sizeof(sal_Int8) * (nStopIndex - nStartIndex) ); 110 } 111 break; 112 case typelib_TypeClass_SHORT: 113 case typelib_TypeClass_UNSIGNED_SHORT: 114 if (nAlloc >= 0) 115 pSeq = reallocSeq( pSeq, sizeof(sal_Int16), nAlloc ); 116 if (pSeq != 0) 117 { 118 ::rtl_zeroMemory( 119 pSeq->elements + (sizeof(sal_Int16) * nStartIndex), 120 sizeof(sal_Int16) * (nStopIndex - nStartIndex) ); 121 } 122 break; 123 case typelib_TypeClass_LONG: 124 case typelib_TypeClass_UNSIGNED_LONG: 125 if (nAlloc >= 0) 126 pSeq = reallocSeq( pSeq, sizeof(sal_Int32), nAlloc ); 127 if (pSeq != 0) 128 { 129 ::rtl_zeroMemory( 130 pSeq->elements + (sizeof(sal_Int32) * nStartIndex), 131 sizeof(sal_Int32) * (nStopIndex - nStartIndex) ); 132 } 133 break; 134 case typelib_TypeClass_HYPER: 135 case typelib_TypeClass_UNSIGNED_HYPER: 136 if (nAlloc >= 0) 137 pSeq = reallocSeq( pSeq, sizeof(sal_Int64), nAlloc ); 138 if (pSeq != 0) 139 { 140 ::rtl_zeroMemory( 141 pSeq->elements + (sizeof(sal_Int64) * nStartIndex), 142 sizeof(sal_Int64) * (nStopIndex - nStartIndex) ); 143 } 144 break; 145 case typelib_TypeClass_FLOAT: 146 { 147 if (nAlloc >= 0) 148 pSeq = reallocSeq( pSeq, sizeof(float), nAlloc ); 149 if (pSeq != 0) 150 { 151 float * pElements = (float *) pSeq->elements; 152 for ( sal_Int32 nPos = nStartIndex; nPos < nStopIndex; ++nPos ) 153 { 154 pElements[nPos] = 0.0; 155 } 156 } 157 break; 158 } 159 case typelib_TypeClass_DOUBLE: 160 { 161 if (nAlloc >= 0) 162 pSeq = reallocSeq( pSeq, sizeof(double), nAlloc ); 163 if (pSeq != 0) 164 { 165 double * pElements = (double *) pSeq->elements; 166 for ( sal_Int32 nPos = nStartIndex; nPos < nStopIndex; ++nPos ) 167 { 168 pElements[nPos] = 0.0; 169 } 170 } 171 break; 172 } 173 case typelib_TypeClass_STRING: 174 { 175 if (nAlloc >= 0) 176 pSeq = reallocSeq( pSeq, sizeof(rtl_uString *), nAlloc ); 177 if (pSeq != 0) 178 { 179 rtl_uString ** pElements = (rtl_uString **) pSeq->elements; 180 for ( sal_Int32 nPos = nStartIndex; nPos < nStopIndex; ++nPos ) 181 { 182 pElements[nPos] = 0; 183 rtl_uString_new( &pElements[nPos] ); 184 } 185 } 186 break; 187 } 188 case typelib_TypeClass_TYPE: 189 { 190 if (nAlloc >= 0) 191 { 192 pSeq = reallocSeq( 193 pSeq, sizeof(typelib_TypeDescriptionReference *), nAlloc ); 194 } 195 if (pSeq != 0) 196 { 197 typelib_TypeDescriptionReference ** pElements = 198 (typelib_TypeDescriptionReference **) pSeq->elements; 199 for ( sal_Int32 nPos = nStartIndex; nPos < nStopIndex; ++nPos ) 200 { 201 pElements[nPos] = _getVoidType(); 202 } 203 } 204 break; 205 } 206 case typelib_TypeClass_ANY: 207 { 208 if (nAlloc >= 0) 209 pSeq = reallocSeq( pSeq, sizeof(uno_Any), nAlloc ); 210 if (pSeq != 0) 211 { 212 uno_Any * pElements = (uno_Any *) pSeq->elements; 213 for ( sal_Int32 nPos = nStartIndex; nPos < nStopIndex; ++nPos ) 214 { 215 CONSTRUCT_EMPTY_ANY( &pElements[nPos] ); 216 } 217 } 218 break; 219 } 220 case typelib_TypeClass_ENUM: 221 { 222 if (nAlloc >= 0) 223 pSeq = reallocSeq( pSeq, sizeof(sal_Int32), nAlloc ); 224 if (pSeq != 0) 225 { 226 typelib_TypeDescription * pElementTypeDescr = 0; 227 TYPELIB_DANGER_GET( &pElementTypeDescr, pElementType ); 228 sal_Int32 eEnum = 229 ((typelib_EnumTypeDescription *) 230 pElementTypeDescr)->nDefaultEnumValue; 231 TYPELIB_DANGER_RELEASE( pElementTypeDescr ); 232 233 sal_Int32 * pElements = (sal_Int32 *) pSeq->elements; 234 for ( sal_Int32 nPos = nStartIndex; nPos < nStopIndex; ++nPos ) 235 { 236 pElements[nPos] = eEnum; 237 } 238 } 239 break; 240 } 241 case typelib_TypeClass_STRUCT: 242 case typelib_TypeClass_EXCEPTION: 243 { 244 typelib_TypeDescription * pElementTypeDescr = 0; 245 TYPELIB_DANGER_GET( &pElementTypeDescr, pElementType ); 246 sal_Int32 nElementSize = pElementTypeDescr->nSize; 247 248 if (nAlloc >= 0) 249 pSeq = reallocSeq( pSeq, nElementSize, nAlloc ); 250 if (pSeq != 0) 251 { 252 char * pElements = pSeq->elements; 253 for ( sal_Int32 nPos = nStartIndex; nPos < nStopIndex; ++nPos ) 254 { 255 _defaultConstructStruct( 256 pElements + (nElementSize * nPos), 257 (typelib_CompoundTypeDescription *)pElementTypeDescr ); 258 } 259 } 260 261 TYPELIB_DANGER_RELEASE( pElementTypeDescr ); 262 break; 263 } 264 case typelib_TypeClass_ARRAY: 265 { 266 typelib_TypeDescription * pElementTypeDescr = 0; 267 TYPELIB_DANGER_GET( &pElementTypeDescr, pElementType ); 268 sal_Int32 nElementSize = pElementTypeDescr->nSize; 269 270 if (nAlloc >= 0) 271 pSeq = reallocSeq( pSeq, nElementSize, nAlloc ); 272 if (pSeq != 0) 273 { 274 char * pElements = pSeq->elements; 275 for ( sal_Int32 nPos = nStartIndex; nPos < nStopIndex; ++nPos ) 276 { 277 _defaultConstructArray( 278 pElements + (nElementSize * nPos), 279 (typelib_ArrayTypeDescription *)pElementTypeDescr ); 280 } 281 } 282 283 TYPELIB_DANGER_RELEASE( pElementTypeDescr ); 284 break; 285 } 286 case typelib_TypeClass_UNION: 287 { 288 typelib_TypeDescription * pElementTypeDescr = 0; 289 TYPELIB_DANGER_GET( &pElementTypeDescr, pElementType ); 290 sal_Int32 nElementSize = pElementTypeDescr->nSize; 291 292 if (nAlloc >= 0) 293 pSeq = reallocSeq( pSeq, nElementSize, nAlloc ); 294 if (pSeq != 0) 295 { 296 sal_Int32 nValueOffset = 297 ((typelib_UnionTypeDescription *) 298 pElementTypeDescr)->nValueOffset; 299 sal_Int64 nDefaultDiscr = 300 ((typelib_UnionTypeDescription *) 301 pElementTypeDescr)->nDefaultDiscriminant; 302 303 typelib_TypeDescription * pDefaultTypeDescr = 0; 304 TYPELIB_DANGER_GET( 305 &pDefaultTypeDescr, 306 ((typelib_UnionTypeDescription *) 307 pElementTypeDescr)->pDefaultTypeRef ); 308 309 char * pElements = pSeq->elements; 310 for ( sal_Int32 nPos = nStartIndex; nPos < nStopIndex; ++nPos ) 311 { 312 char * pMem = pElements + (nElementSize * nPos); 313 ::uno_constructData( 314 (char *)pMem + nValueOffset, pDefaultTypeDescr ); 315 *(sal_Int64 *)pMem = nDefaultDiscr; 316 } 317 TYPELIB_DANGER_RELEASE( pDefaultTypeDescr ); 318 } 319 320 TYPELIB_DANGER_RELEASE( pElementTypeDescr ); 321 break; 322 } 323 case typelib_TypeClass_SEQUENCE: 324 { 325 if (nAlloc >= 0) 326 pSeq = reallocSeq( pSeq, sizeof(uno_Sequence *), nAlloc ); 327 if (pSeq != 0) 328 { 329 uno_Sequence ** pElements = 330 (uno_Sequence **) pSeq->elements; 331 for ( sal_Int32 nPos = nStartIndex; nPos < nStopIndex; ++nPos ) 332 { 333 pElements[nPos] = createEmptySequence(); 334 } 335 } 336 break; 337 } 338 case typelib_TypeClass_INTERFACE: // either C++ or C-UNO interface 339 if (nAlloc >= 0) 340 pSeq = reallocSeq( pSeq, sizeof(void *), nAlloc ); 341 if (pSeq != 0) 342 { 343 ::rtl_zeroMemory( 344 pSeq->elements + (sizeof(void *) * nStartIndex), 345 sizeof(void *) * (nStopIndex - nStartIndex) ); 346 } 347 break; 348 default: 349 OSL_ENSURE( 0, "### unexpected element type!" ); 350 pSeq = 0; 351 break; 352 } 353 354 if (pSeq == 0) 355 { 356 OSL_ASSERT( nAlloc >= 0 ); // must have been an allocation failure 357 return false; 358 } 359 else 360 { 361 *ppSeq = pSeq; 362 return true; 363 } 364 } 365 366 //------------------------------------------------------------------------------ 367 static inline bool icopyConstructFromElements( 368 uno_Sequence ** ppSeq, void * pSourceElements, 369 typelib_TypeDescriptionReference * pElementType, 370 sal_Int32 nStartIndex, sal_Int32 nStopIndex, 371 uno_AcquireFunc acquire, 372 sal_Int32 nAlloc = -1 ) // >= 0 means (re)alloc memory for nAlloc elements 373 { 374 uno_Sequence * pSeq = *ppSeq; 375 switch (pElementType->eTypeClass) 376 { 377 case typelib_TypeClass_CHAR: 378 if (nAlloc >= 0) 379 pSeq = reallocSeq( pSeq, sizeof(sal_Unicode), nAlloc ); 380 if (pSeq != 0) 381 { 382 ::rtl_copyMemory( 383 pSeq->elements + (sizeof(sal_Unicode) * nStartIndex), 384 (char *)pSourceElements + (sizeof(sal_Unicode) * nStartIndex), 385 sizeof(sal_Unicode) * (nStopIndex - nStartIndex) ); 386 } 387 break; 388 case typelib_TypeClass_BOOLEAN: 389 if (nAlloc >= 0) 390 pSeq = reallocSeq( pSeq, sizeof(sal_Bool), nAlloc ); 391 if (pSeq != 0) 392 { 393 ::rtl_copyMemory( 394 pSeq->elements + (sizeof(sal_Bool) * nStartIndex), 395 (char *)pSourceElements + (sizeof(sal_Bool) * nStartIndex), 396 sizeof(sal_Bool) * (nStopIndex - nStartIndex) ); 397 } 398 break; 399 case typelib_TypeClass_BYTE: 400 if (nAlloc >= 0) 401 pSeq = reallocSeq( pSeq, sizeof(sal_Int8), nAlloc ); 402 if (pSeq != 0) 403 { 404 ::rtl_copyMemory( 405 pSeq->elements + (sizeof(sal_Int8) * nStartIndex), 406 (char *)pSourceElements + (sizeof(sal_Int8) * nStartIndex), 407 sizeof(sal_Int8) * (nStopIndex - nStartIndex) ); 408 } 409 break; 410 case typelib_TypeClass_SHORT: 411 case typelib_TypeClass_UNSIGNED_SHORT: 412 if (nAlloc >= 0) 413 pSeq = reallocSeq( pSeq, sizeof(sal_Int16), nAlloc ); 414 if (pSeq != 0) 415 { 416 ::rtl_copyMemory( 417 pSeq->elements + (sizeof(sal_Int16) * nStartIndex), 418 (char *)pSourceElements + (sizeof(sal_Int16) * nStartIndex), 419 sizeof(sal_Int16) * (nStopIndex - nStartIndex) ); 420 } 421 break; 422 case typelib_TypeClass_LONG: 423 case typelib_TypeClass_UNSIGNED_LONG: 424 if (nAlloc >= 0) 425 pSeq = reallocSeq( pSeq, sizeof(sal_Int32), nAlloc ); 426 if (pSeq != 0) 427 { 428 ::rtl_copyMemory( 429 pSeq->elements + (sizeof(sal_Int32) * nStartIndex), 430 (char *)pSourceElements + (sizeof(sal_Int32) * nStartIndex), 431 sizeof(sal_Int32) * (nStopIndex - nStartIndex) ); 432 } 433 break; 434 case typelib_TypeClass_HYPER: 435 case typelib_TypeClass_UNSIGNED_HYPER: 436 if (nAlloc >= 0) 437 pSeq = reallocSeq( pSeq, sizeof(sal_Int64), nAlloc ); 438 if (pSeq != 0) 439 { 440 ::rtl_copyMemory( 441 pSeq->elements + (sizeof(sal_Int64) * nStartIndex), 442 (char *)pSourceElements + (sizeof(sal_Int64) * nStartIndex), 443 sizeof(sal_Int64) * (nStopIndex - nStartIndex) ); 444 } 445 break; 446 case typelib_TypeClass_FLOAT: 447 if (nAlloc >= 0) 448 pSeq = reallocSeq( pSeq, sizeof(float), nAlloc ); 449 if (pSeq != 0) 450 { 451 ::rtl_copyMemory( 452 pSeq->elements + (sizeof(float) * nStartIndex), 453 (char *)pSourceElements + (sizeof(float) * nStartIndex), 454 sizeof(float) * (nStopIndex - nStartIndex) ); 455 } 456 break; 457 case typelib_TypeClass_DOUBLE: 458 if (nAlloc >= 0) 459 pSeq = reallocSeq( pSeq, sizeof(double), nAlloc ); 460 if (pSeq != 0) 461 { 462 ::rtl_copyMemory( 463 pSeq->elements + (sizeof(double) * nStartIndex), 464 (char *)pSourceElements + (sizeof(double) * nStartIndex), 465 sizeof(double) * (nStopIndex - nStartIndex) ); 466 } 467 break; 468 case typelib_TypeClass_ENUM: 469 if (nAlloc >= 0) 470 pSeq = reallocSeq( pSeq, sizeof(sal_Int32), nAlloc ); 471 if (pSeq != 0) 472 { 473 ::rtl_copyMemory( 474 pSeq->elements + (sizeof(sal_Int32) * nStartIndex), 475 (char *)pSourceElements + (sizeof(sal_Int32) * nStartIndex), 476 sizeof(sal_Int32) * (nStopIndex - nStartIndex) ); 477 } 478 break; 479 case typelib_TypeClass_STRING: 480 { 481 if (nAlloc >= 0) 482 pSeq = reallocSeq( pSeq, sizeof(rtl_uString *), nAlloc ); 483 if (pSeq != 0) 484 { 485 rtl_uString ** pDestElements = (rtl_uString **) pSeq->elements; 486 for ( sal_Int32 nPos = nStartIndex; nPos < nStopIndex; ++nPos ) 487 { 488 ::rtl_uString_acquire( 489 ((rtl_uString **)pSourceElements)[nPos] ); 490 pDestElements[nPos] = ((rtl_uString **)pSourceElements)[nPos]; 491 } 492 } 493 break; 494 } 495 case typelib_TypeClass_TYPE: 496 { 497 if (nAlloc >= 0) 498 { 499 pSeq = reallocSeq( 500 pSeq, sizeof(typelib_TypeDescriptionReference *), nAlloc ); 501 } 502 if (pSeq != 0) 503 { 504 typelib_TypeDescriptionReference ** pDestElements = 505 (typelib_TypeDescriptionReference **) pSeq->elements; 506 for ( sal_Int32 nPos = nStartIndex; nPos < nStopIndex; ++nPos ) 507 { 508 TYPE_ACQUIRE( 509 ((typelib_TypeDescriptionReference **) 510 pSourceElements)[nPos] ); 511 pDestElements[nPos] = 512 ((typelib_TypeDescriptionReference **) 513 pSourceElements)[nPos]; 514 } 515 } 516 break; 517 } 518 case typelib_TypeClass_ANY: 519 { 520 if (nAlloc >= 0) 521 pSeq = reallocSeq( pSeq, sizeof(uno_Any), nAlloc ); 522 if (pSeq != 0) 523 { 524 uno_Any * pDestElements = (uno_Any *) pSeq->elements; 525 for ( sal_Int32 nPos = nStartIndex; nPos < nStopIndex; ++nPos ) 526 { 527 uno_Any * pSource = (uno_Any *)pSourceElements + nPos; 528 _copyConstructAny( 529 &pDestElements[nPos], 530 pSource->pData, 531 pSource->pType, 0, 532 acquire, 0 ); 533 } 534 } 535 break; 536 } 537 case typelib_TypeClass_STRUCT: 538 case typelib_TypeClass_EXCEPTION: 539 { 540 typelib_TypeDescription * pElementTypeDescr = 0; 541 TYPELIB_DANGER_GET( &pElementTypeDescr, pElementType ); 542 sal_Int32 nElementSize = pElementTypeDescr->nSize; 543 544 if (nAlloc >= 0) 545 pSeq = reallocSeq( pSeq, nElementSize, nAlloc ); 546 if (pSeq != 0) 547 { 548 char * pDestElements = pSeq->elements; 549 550 typelib_CompoundTypeDescription * pTypeDescr = 551 (typelib_CompoundTypeDescription *)pElementTypeDescr; 552 for ( sal_Int32 nPos = nStartIndex; nPos < nStopIndex; ++nPos ) 553 { 554 char * pDest = 555 pDestElements + (nElementSize * nPos); 556 char * pSource = 557 (char *)pSourceElements + (nElementSize * nPos); 558 559 if (pTypeDescr->pBaseTypeDescription) 560 { 561 // copy base value 562 _copyConstructStruct( 563 pDest, pSource, 564 pTypeDescr->pBaseTypeDescription, acquire, 0 ); 565 } 566 567 // then copy members 568 typelib_TypeDescriptionReference ** ppTypeRefs = 569 pTypeDescr->ppTypeRefs; 570 sal_Int32 * pMemberOffsets = pTypeDescr->pMemberOffsets; 571 sal_Int32 nDescr = pTypeDescr->nMembers; 572 573 while (nDescr--) 574 { 575 ::uno_type_copyData( 576 pDest + pMemberOffsets[nDescr], 577 pSource + pMemberOffsets[nDescr], 578 ppTypeRefs[nDescr], acquire ); 579 } 580 } 581 } 582 583 TYPELIB_DANGER_RELEASE( pElementTypeDescr ); 584 break; 585 } 586 case typelib_TypeClass_UNION: 587 { 588 typelib_TypeDescription * pElementTypeDescr = 0; 589 TYPELIB_DANGER_GET( &pElementTypeDescr, pElementType ); 590 sal_Int32 nElementSize = pElementTypeDescr->nSize; 591 592 if (nAlloc >= 0) 593 pSeq = reallocSeq( pSeq, nElementSize, nAlloc ); 594 if (pSeq != 0) 595 { 596 char * pDestElements = pSeq->elements; 597 598 sal_Int32 nValueOffset = 599 ((typelib_UnionTypeDescription *) 600 pElementTypeDescr)->nValueOffset; 601 for ( sal_Int32 nPos = nStartIndex; nPos < nStopIndex; ++nPos ) 602 { 603 char * pDest = 604 pDestElements + (nElementSize * nPos); 605 char * pSource = 606 (char *)pSourceElements + (nElementSize * nPos); 607 608 typelib_TypeDescriptionReference * pSetType = _unionGetSetType( 609 pSource, pElementTypeDescr ); 610 ::uno_type_copyData( 611 pDest + nValueOffset, 612 pSource + nValueOffset, 613 pSetType, acquire ); 614 *(sal_Int64 *)pDest = *(sal_Int64 *)pSource; 615 typelib_typedescriptionreference_release( pSetType ); 616 } 617 } 618 619 TYPELIB_DANGER_RELEASE( pElementTypeDescr ); 620 break; 621 } 622 case typelib_TypeClass_SEQUENCE: // sequence of sequence 623 { 624 if (nAlloc >= 0) 625 pSeq = reallocSeq( pSeq, sizeof(uno_Sequence *), nAlloc ); 626 if (pSeq != 0) 627 { 628 typelib_TypeDescription * pElementTypeDescr = 0; 629 TYPELIB_DANGER_GET( &pElementTypeDescr, pElementType ); 630 typelib_TypeDescriptionReference * pSeqElementType = 631 ((typelib_IndirectTypeDescription *) pElementTypeDescr)->pType; 632 uno_Sequence ** pDestElements = (uno_Sequence **) pSeq->elements; 633 for ( sal_Int32 nPos = nStartIndex; nPos < nStopIndex; ++nPos ) 634 { 635 uno_Sequence * pNew = icopyConstructSequence( 636 ((uno_Sequence **) pSourceElements)[nPos], 637 pSeqElementType, acquire, 0 ); 638 OSL_ASSERT( pNew != 0 ); 639 // ought never be a memory allocation problem, 640 // because of reference counted sequence handles 641 pDestElements[ nPos ] = pNew; 642 } 643 TYPELIB_DANGER_RELEASE( pElementTypeDescr ); 644 } 645 break; 646 } 647 case typelib_TypeClass_INTERFACE: 648 { 649 if (nAlloc >= 0) 650 pSeq = reallocSeq( pSeq, sizeof(void *), nAlloc ); 651 if (pSeq != 0) 652 { 653 void ** pDestElements = (void **) pSeq->elements; 654 for ( sal_Int32 nPos = nStartIndex; nPos < nStopIndex; ++nPos ) 655 { 656 _acquire( pDestElements[nPos] = 657 ((void **)pSourceElements)[nPos], acquire ); 658 } 659 } 660 break; 661 } 662 default: 663 OSL_ENSURE( 0, "### unexpected element type!" ); 664 pSeq = 0; 665 break; 666 } 667 668 if (pSeq == 0) 669 { 670 OSL_ASSERT( nAlloc >= 0 ); // must have been an allocation failure 671 return false; 672 } 673 else 674 { 675 *ppSeq = pSeq; 676 return true; 677 } 678 } 679 680 //------------------------------------------------------------------------------ 681 static inline bool ireallocSequence( 682 uno_Sequence ** ppSequence, 683 typelib_TypeDescriptionReference * pElementType, 684 sal_Int32 nSize, 685 uno_AcquireFunc acquire, uno_ReleaseFunc release ) 686 { 687 bool ret = true; 688 uno_Sequence * pSeq = *ppSequence; 689 sal_Int32 nElements = pSeq->nElements; 690 691 if (pSeq->nRefCount > 1 || 692 // not mem-copyable elements? 693 typelib_TypeClass_ANY == pElementType->eTypeClass || 694 typelib_TypeClass_STRUCT == pElementType->eTypeClass || 695 typelib_TypeClass_EXCEPTION == pElementType->eTypeClass) 696 { 697 // split sequence and construct new one from scratch 698 uno_Sequence * pNew = 0; 699 700 sal_Int32 nRest = nSize - nElements; 701 sal_Int32 nCopy = (nRest > 0 ? nElements : nSize); 702 703 if (nCopy >= 0) 704 { 705 ret = icopyConstructFromElements( 706 &pNew, pSeq->elements, pElementType, 707 0, nCopy, acquire, 708 nSize ); // alloc to nSize 709 } 710 if (ret && nRest > 0) 711 { 712 ret = idefaultConstructElements( 713 &pNew, pElementType, 714 nCopy, nSize, 715 nCopy >= 0 ? -1 /* no mem allocation */ : nSize ); 716 } 717 718 if (ret) 719 { 720 // destruct sequence 721 if (osl_decrementInterlockedCount( &pSeq->nRefCount ) == 0) 722 { 723 if (nElements > 0) 724 { 725 idestructElements( 726 pSeq->elements, pElementType, 727 0, nElements, release ); 728 } 729 rtl_freeMemory( pSeq ); 730 } 731 *ppSequence = pNew; 732 } 733 } 734 else 735 { 736 OSL_ASSERT( pSeq->nRefCount == 1 ); 737 if (nSize > nElements) // default construct the rest 738 { 739 ret = idefaultConstructElements( 740 ppSequence, pElementType, 741 nElements, nSize, 742 nSize ); // realloc to nSize 743 } 744 else // or destruct the rest and realloc mem 745 { 746 sal_Int32 nElementSize = idestructElements( 747 pSeq->elements, pElementType, 748 nSize, nElements, release ); 749 // warning: it is assumed that the following will never fail, 750 // else this leads to a sequence null handle 751 *ppSequence = reallocSeq( pSeq, nElementSize, nSize ); 752 OSL_ASSERT( *ppSequence != 0 ); 753 ret = (*ppSequence != 0); 754 } 755 } 756 757 return ret; 758 } 759 760 } 761 762 extern "C" 763 { 764 765 //############################################################################## 766 sal_Bool SAL_CALL uno_type_sequence_construct( 767 uno_Sequence ** ppSequence, typelib_TypeDescriptionReference * pType, 768 void * pElements, sal_Int32 len, 769 uno_AcquireFunc acquire ) 770 SAL_THROW_EXTERN_C() 771 { 772 bool ret; 773 if (len) 774 { 775 typelib_TypeDescription * pTypeDescr = 0; 776 TYPELIB_DANGER_GET( &pTypeDescr, pType ); 777 778 typelib_TypeDescriptionReference * pElementType = 779 ((typelib_IndirectTypeDescription *)pTypeDescr)->pType; 780 781 *ppSequence = 0; 782 if (pElements == 0) 783 { 784 ret = idefaultConstructElements( 785 ppSequence, pElementType, 786 0, len, 787 len ); // alloc to len 788 } 789 else 790 { 791 ret = icopyConstructFromElements( 792 ppSequence, pElements, pElementType, 793 0, len, acquire, 794 len ); // alloc to len 795 } 796 797 TYPELIB_DANGER_RELEASE( pTypeDescr ); 798 } 799 else 800 { 801 *ppSequence = createEmptySequence(); 802 ret = true; 803 } 804 805 OSL_ASSERT( (*ppSequence != 0) == ret ); 806 return ret; 807 } 808 809 //############################################################################## 810 sal_Bool SAL_CALL uno_sequence_construct( 811 uno_Sequence ** ppSequence, typelib_TypeDescription * pTypeDescr, 812 void * pElements, sal_Int32 len, 813 uno_AcquireFunc acquire ) 814 SAL_THROW_EXTERN_C() 815 { 816 bool ret; 817 if (len > 0) 818 { 819 typelib_TypeDescriptionReference * pElementType = 820 ((typelib_IndirectTypeDescription *)pTypeDescr)->pType; 821 822 *ppSequence = 0; 823 if (pElements == 0) 824 { 825 ret = idefaultConstructElements( 826 ppSequence, pElementType, 827 0, len, 828 len ); // alloc to len 829 } 830 else 831 { 832 ret = icopyConstructFromElements( 833 ppSequence, pElements, pElementType, 834 0, len, acquire, 835 len ); // alloc to len 836 } 837 } 838 else 839 { 840 *ppSequence = createEmptySequence(); 841 ret = true; 842 } 843 844 OSL_ASSERT( (*ppSequence != 0) == ret ); 845 return ret; 846 } 847 848 //############################################################################## 849 sal_Bool SAL_CALL uno_type_sequence_realloc( 850 uno_Sequence ** ppSequence, typelib_TypeDescriptionReference * pType, 851 sal_Int32 nSize, uno_AcquireFunc acquire, uno_ReleaseFunc release ) 852 SAL_THROW_EXTERN_C() 853 { 854 OSL_ENSURE( ppSequence, "### null ptr!" ); 855 OSL_ENSURE( nSize >= 0, "### new size must be at least 0!" ); 856 857 bool ret = true; 858 if (nSize != (*ppSequence)->nElements) 859 { 860 typelib_TypeDescription * pTypeDescr = 0; 861 TYPELIB_DANGER_GET( &pTypeDescr, pType ); 862 ret = ireallocSequence( 863 ppSequence, ((typelib_IndirectTypeDescription *)pTypeDescr)->pType, 864 nSize, acquire, release ); 865 TYPELIB_DANGER_RELEASE( pTypeDescr ); 866 } 867 return ret; 868 } 869 870 //############################################################################## 871 sal_Bool SAL_CALL uno_sequence_realloc( 872 uno_Sequence ** ppSequence, typelib_TypeDescription * pTypeDescr, 873 sal_Int32 nSize, uno_AcquireFunc acquire, uno_ReleaseFunc release ) 874 SAL_THROW_EXTERN_C() 875 { 876 OSL_ENSURE( ppSequence, "### null ptr!" ); 877 OSL_ENSURE( nSize >= 0, "### new size must be at least 0!" ); 878 879 bool ret = true; 880 if (nSize != (*ppSequence)->nElements) 881 { 882 ret = ireallocSequence( 883 ppSequence, ((typelib_IndirectTypeDescription *)pTypeDescr)->pType, 884 nSize, acquire, release ); 885 } 886 return ret; 887 } 888 889 //############################################################################## 890 sal_Bool SAL_CALL uno_type_sequence_reference2One( 891 uno_Sequence ** ppSequence, 892 typelib_TypeDescriptionReference * pType, 893 uno_AcquireFunc acquire, uno_ReleaseFunc release ) 894 SAL_THROW_EXTERN_C() 895 { 896 OSL_ENSURE( ppSequence, "### null ptr!" ); 897 bool ret = true; 898 uno_Sequence * pSequence = *ppSequence; 899 if (pSequence->nRefCount > 1) 900 { 901 uno_Sequence * pNew = 0; 902 if (pSequence->nElements > 0) 903 { 904 typelib_TypeDescription * pTypeDescr = 0; 905 TYPELIB_DANGER_GET( &pTypeDescr, pType ); 906 907 ret = icopyConstructFromElements( 908 &pNew, pSequence->elements, 909 ((typelib_IndirectTypeDescription *)pTypeDescr)->pType, 910 0, pSequence->nElements, acquire, 911 pSequence->nElements ); // alloc nElements 912 if (ret) 913 { 914 idestructSequence( *ppSequence, pType, pTypeDescr, release ); 915 *ppSequence = pNew; 916 } 917 918 TYPELIB_DANGER_RELEASE( pTypeDescr ); 919 } 920 else 921 { 922 pNew = allocSeq( 0, 0 ); 923 ret = (pNew != 0); 924 if (ret) 925 { 926 // easy destruction of empty sequence: 927 if (osl_decrementInterlockedCount( &pSequence->nRefCount ) == 0) 928 rtl_freeMemory( pSequence ); 929 *ppSequence = pNew; 930 } 931 } 932 } 933 return ret; 934 } 935 936 //############################################################################## 937 sal_Bool SAL_CALL uno_sequence_reference2One( 938 uno_Sequence ** ppSequence, 939 typelib_TypeDescription * pTypeDescr, 940 uno_AcquireFunc acquire, uno_ReleaseFunc release ) 941 SAL_THROW_EXTERN_C() 942 { 943 OSL_ENSURE( ppSequence, "### null ptr!" ); 944 bool ret = true; 945 uno_Sequence * pSequence = *ppSequence; 946 if (pSequence->nRefCount > 1) 947 { 948 uno_Sequence * pNew = 0; 949 if (pSequence->nElements > 0) 950 { 951 ret = icopyConstructFromElements( 952 &pNew, pSequence->elements, 953 ((typelib_IndirectTypeDescription *)pTypeDescr)->pType, 954 0, pSequence->nElements, acquire, 955 pSequence->nElements ); // alloc nElements 956 if (ret) 957 { 958 idestructSequence( 959 pSequence, pTypeDescr->pWeakRef, pTypeDescr, release ); 960 *ppSequence = pNew; 961 } 962 } 963 else 964 { 965 pNew = allocSeq( 0, 0 ); 966 ret = (pNew != 0); 967 if (ret) 968 { 969 // easy destruction of empty sequence: 970 if (osl_decrementInterlockedCount( &pSequence->nRefCount ) == 0) 971 rtl_freeMemory( pSequence ); 972 *ppSequence = pNew; 973 } 974 } 975 976 } 977 return ret; 978 } 979 980 //############################################################################## 981 void SAL_CALL uno_sequence_assign( 982 uno_Sequence ** ppDest, 983 uno_Sequence * pSource, 984 typelib_TypeDescription * pTypeDescr, 985 uno_ReleaseFunc release ) 986 SAL_THROW_EXTERN_C() 987 { 988 if (*ppDest != pSource) 989 { 990 ::osl_incrementInterlockedCount( &pSource->nRefCount ); 991 idestructSequence( *ppDest, pTypeDescr->pWeakRef, pTypeDescr, release ); 992 *ppDest = pSource; 993 } 994 } 995 996 //############################################################################## 997 void SAL_CALL uno_type_sequence_assign( 998 uno_Sequence ** ppDest, 999 uno_Sequence * pSource, 1000 typelib_TypeDescriptionReference * pType, 1001 uno_ReleaseFunc release ) 1002 SAL_THROW_EXTERN_C() 1003 { 1004 if (*ppDest != pSource) 1005 { 1006 ::osl_incrementInterlockedCount( &pSource->nRefCount ); 1007 idestructSequence( *ppDest, pType, 0, release ); 1008 *ppDest = pSource; 1009 } 1010 } 1011 1012 } 1013