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