Version 7.6.3.2-android, tag libreoffice-7.6.3.2-android
[LibreOffice.git] / cppu / source / uno / sequence.cxx
blobc467f2c387042dcc0631cfc2fcf64b70a92624db
1 /* -*- Mode: C++; tab-width: 4; indent-tabs-mode: nil; c-basic-offset: 4 -*- */
2 /*
3 * This file is part of the LibreOffice project.
5 * This Source Code Form is subject to the terms of the Mozilla Public
6 * License, v. 2.0. If a copy of the MPL was not distributed with this
7 * file, You can obtain one at http://mozilla.org/MPL/2.0/.
9 * This file incorporates work covered by the following license notice:
11 * Licensed to the Apache Software Foundation (ASF) under one or more
12 * contributor license agreements. See the NOTICE file distributed
13 * with this work for additional information regarding copyright
14 * ownership. The ASF licenses this file to you under the Apache
15 * License, Version 2.0 (the "License"); you may not use this file
16 * except in compliance with the License. You may obtain a copy of
17 * the License at http://www.apache.org/licenses/LICENSE-2.0 .
20 #include <sal/config.h>
22 #include <cassert>
23 #include <string.h>
25 #include <osl/diagnose.h>
26 #include <osl/interlck.h>
27 #include <typelib/typedescription.h>
28 #include <uno/data.h>
29 #include <uno/sequence2.h>
31 #include "constr.hxx"
32 #include "copy.hxx"
33 #include "destr.hxx"
36 using namespace cppu;
38 namespace cppu
42 static uno_Sequence * reallocSeq(
43 uno_Sequence * pReallocate, std::size_t nElementSize, sal_Int32 nElements )
45 OSL_ASSERT( nElements >= 0 );
46 uno_Sequence * pNew = nullptr;
47 sal_uInt32 nSize = calcSeqMemSize( nElementSize, nElements );
48 if (nSize > 0)
50 if (pReallocate == nullptr)
52 pNew = static_cast<uno_Sequence *>(std::malloc( nSize ));
54 else
56 pNew = static_cast<uno_Sequence *>(std::realloc( pReallocate, nSize ));
58 if (pNew != nullptr)
60 // header init
61 pNew->nRefCount = 1;
62 pNew->nElements = nElements;
65 return pNew;
69 static bool idefaultConstructElements(
70 uno_Sequence ** ppSeq,
71 typelib_TypeDescriptionReference * pElementType,
72 sal_Int32 nStartIndex, sal_Int32 nStopIndex,
73 sal_Int32 nAlloc ) // >= 0 means (re)alloc memory for nAlloc elements
75 uno_Sequence * pSeq = *ppSeq;
76 switch (pElementType->eTypeClass)
78 case typelib_TypeClass_CHAR:
79 if (nAlloc >= 0)
80 pSeq = reallocSeq( pSeq, sizeof(sal_Unicode), nAlloc );
81 if (pSeq != nullptr)
83 memset(
84 pSeq->elements + (sizeof(sal_Unicode) * nStartIndex),
86 sizeof(sal_Unicode) * (nStopIndex - nStartIndex) );
88 break;
89 case typelib_TypeClass_BOOLEAN:
90 if (nAlloc >= 0)
91 pSeq = reallocSeq( pSeq, sizeof(sal_Bool), nAlloc );
92 if (pSeq != nullptr)
94 memset(
95 pSeq->elements + (sizeof(sal_Bool) * nStartIndex),
97 sizeof(sal_Bool) * (nStopIndex - nStartIndex) );
99 break;
100 case typelib_TypeClass_BYTE:
101 if (nAlloc >= 0)
102 pSeq = reallocSeq( pSeq, sizeof(sal_Int8), nAlloc );
103 if (pSeq != nullptr)
105 memset(
106 pSeq->elements + (sizeof(sal_Int8) * nStartIndex),
108 sizeof(sal_Int8) * (nStopIndex - nStartIndex) );
110 break;
111 case typelib_TypeClass_SHORT:
112 case typelib_TypeClass_UNSIGNED_SHORT:
113 if (nAlloc >= 0)
114 pSeq = reallocSeq( pSeq, sizeof(sal_Int16), nAlloc );
115 if (pSeq != nullptr)
117 memset(
118 pSeq->elements + (sizeof(sal_Int16) * nStartIndex),
120 sizeof(sal_Int16) * (nStopIndex - nStartIndex) );
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 != nullptr)
129 memset(
130 pSeq->elements + (sizeof(sal_Int32) * nStartIndex),
132 sizeof(sal_Int32) * (nStopIndex - nStartIndex) );
134 break;
135 case typelib_TypeClass_HYPER:
136 case typelib_TypeClass_UNSIGNED_HYPER:
137 if (nAlloc >= 0)
138 pSeq = reallocSeq( pSeq, sizeof(sal_Int64), nAlloc );
139 if (pSeq != nullptr)
141 memset(
142 pSeq->elements + (sizeof(sal_Int64) * nStartIndex),
144 sizeof(sal_Int64) * (nStopIndex - nStartIndex) );
146 break;
147 case typelib_TypeClass_FLOAT:
149 if (nAlloc >= 0)
150 pSeq = reallocSeq( pSeq, sizeof(float), nAlloc );
151 if (pSeq != nullptr)
153 float * pElements = reinterpret_cast<float *>(pSeq->elements);
154 for ( sal_Int32 nPos = nStartIndex; nPos < nStopIndex; ++nPos )
156 pElements[nPos] = 0.0;
159 break;
161 case typelib_TypeClass_DOUBLE:
163 if (nAlloc >= 0)
164 pSeq = reallocSeq( pSeq, sizeof(double), nAlloc );
165 if (pSeq != nullptr)
167 double * pElements = reinterpret_cast<double *>(pSeq->elements);
168 for ( sal_Int32 nPos = nStartIndex; nPos < nStopIndex; ++nPos )
170 pElements[nPos] = 0.0;
173 break;
175 case typelib_TypeClass_STRING:
177 if (nAlloc >= 0)
178 pSeq = reallocSeq( pSeq, sizeof(rtl_uString *), nAlloc );
179 if (pSeq != nullptr)
181 rtl_uString ** pElements = reinterpret_cast<rtl_uString **>(pSeq->elements);
182 for ( sal_Int32 nPos = nStartIndex; nPos < nStopIndex; ++nPos )
184 pElements[nPos] = nullptr;
185 rtl_uString_new( &pElements[nPos] );
188 break;
190 case typelib_TypeClass_TYPE:
192 if (nAlloc >= 0)
194 pSeq = reallocSeq(
195 pSeq, sizeof(typelib_TypeDescriptionReference *), nAlloc );
197 if (pSeq != nullptr)
199 typelib_TypeDescriptionReference ** pElements =
200 reinterpret_cast<typelib_TypeDescriptionReference **>(pSeq->elements);
201 for ( sal_Int32 nPos = nStartIndex; nPos < nStopIndex; ++nPos )
203 pElements[nPos] = _getVoidType();
206 break;
208 case typelib_TypeClass_ANY:
210 if (nAlloc >= 0)
211 pSeq = reallocSeq( pSeq, sizeof(uno_Any), nAlloc );
212 if (pSeq != nullptr)
214 uno_Any * pElements = reinterpret_cast<uno_Any *>(pSeq->elements);
215 for ( sal_Int32 nPos = nStartIndex; nPos < nStopIndex; ++nPos )
217 CONSTRUCT_EMPTY_ANY( &pElements[nPos] );
220 break;
222 case typelib_TypeClass_ENUM:
224 if (nAlloc >= 0)
225 pSeq = reallocSeq( pSeq, sizeof(sal_Int32), nAlloc );
226 if (pSeq != nullptr)
228 typelib_TypeDescription * pElementTypeDescr = nullptr;
229 TYPELIB_DANGER_GET( &pElementTypeDescr, pElementType );
230 sal_Int32 eEnum =
231 reinterpret_cast<typelib_EnumTypeDescription *>(
232 pElementTypeDescr)->nDefaultEnumValue;
233 TYPELIB_DANGER_RELEASE( pElementTypeDescr );
235 sal_Int32 * pElements = reinterpret_cast<sal_Int32 *>(pSeq->elements);
236 for ( sal_Int32 nPos = nStartIndex; nPos < nStopIndex; ++nPos )
238 pElements[nPos] = eEnum;
241 break;
243 case typelib_TypeClass_STRUCT:
244 case typelib_TypeClass_EXCEPTION:
246 typelib_TypeDescription * pElementTypeDescr = nullptr;
247 TYPELIB_DANGER_GET( &pElementTypeDescr, pElementType );
248 sal_Int32 nElementSize = pElementTypeDescr->nSize;
250 if (nAlloc >= 0)
251 pSeq = reallocSeq( pSeq, nElementSize, nAlloc );
252 if (pSeq != nullptr)
254 char * pElements = pSeq->elements;
255 for ( sal_Int32 nPos = nStartIndex; nPos < nStopIndex; ++nPos )
257 _defaultConstructStruct(
258 pElements + (nElementSize * nPos),
259 reinterpret_cast<typelib_CompoundTypeDescription *>(pElementTypeDescr) );
263 TYPELIB_DANGER_RELEASE( pElementTypeDescr );
264 break;
266 case typelib_TypeClass_SEQUENCE:
268 if (nAlloc >= 0)
270 // coverity[suspicious_sizeof : FALSE] - sizeof(uno_Sequence*) is correct here
271 pSeq = reallocSeq(pSeq, sizeof(uno_Sequence*), nAlloc);
273 if (pSeq != nullptr)
275 uno_Sequence ** pElements =
276 reinterpret_cast<uno_Sequence **>(pSeq->elements);
277 for ( sal_Int32 nPos = nStartIndex; nPos < nStopIndex; ++nPos )
279 pElements[nPos] = createEmptySequence();
282 break;
284 case typelib_TypeClass_INTERFACE: // either C++ or C-UNO interface
285 if (nAlloc >= 0)
286 pSeq = reallocSeq( pSeq, sizeof(void *), nAlloc );
287 if (pSeq != nullptr)
289 memset(
290 pSeq->elements + (sizeof(void *) * nStartIndex),
292 sizeof(void *) * (nStopIndex - nStartIndex) );
294 break;
295 default:
296 OSL_FAIL( "### unexpected element type!" );
297 pSeq = nullptr;
298 break;
301 if (pSeq == nullptr)
303 OSL_ASSERT( nAlloc >= 0 ); // must have been an allocation failure
304 return false;
306 *ppSeq = pSeq;
307 return true;
310 // coverity[ -tainted_data_sink : arg-1 ]
311 static bool icopyConstructFromElements(
312 uno_Sequence ** ppSeq, void * pSourceElements,
313 typelib_TypeDescriptionReference * pElementType,
314 sal_Int32 nStopIndex,
315 uno_AcquireFunc acquire,
316 sal_Int32 nAlloc )
318 uno_Sequence * pSeq = *ppSeq;
319 switch (pElementType->eTypeClass)
321 case typelib_TypeClass_CHAR:
322 pSeq = reallocSeq( pSeq, sizeof(sal_Unicode), nAlloc );
323 if (pSeq != nullptr)
325 memcpy(
326 pSeq->elements,
327 pSourceElements,
328 sizeof(sal_Unicode) * nStopIndex );
330 break;
331 case typelib_TypeClass_BOOLEAN:
332 pSeq = reallocSeq( pSeq, sizeof(sal_Bool), nAlloc );
333 if (pSeq != nullptr)
335 memcpy(
336 pSeq->elements,
337 pSourceElements,
338 sizeof(sal_Bool) * nStopIndex );
340 break;
341 case typelib_TypeClass_BYTE:
342 pSeq = reallocSeq( pSeq, sizeof(sal_Int8), nAlloc );
343 if (pSeq != nullptr)
345 memcpy(
346 pSeq->elements,
347 pSourceElements,
348 sizeof(sal_Int8) * nStopIndex );
350 break;
351 case typelib_TypeClass_SHORT:
352 case typelib_TypeClass_UNSIGNED_SHORT:
353 pSeq = reallocSeq( pSeq, sizeof(sal_Int16), nAlloc );
354 if (pSeq != nullptr)
356 memcpy(
357 pSeq->elements,
358 pSourceElements,
359 sizeof(sal_Int16) * nStopIndex );
361 break;
362 case typelib_TypeClass_LONG:
363 case typelib_TypeClass_UNSIGNED_LONG:
364 pSeq = reallocSeq( pSeq, sizeof(sal_Int32), nAlloc );
365 if (pSeq != nullptr)
367 memcpy(
368 pSeq->elements,
369 pSourceElements,
370 sizeof(sal_Int32) * nStopIndex );
372 break;
373 case typelib_TypeClass_HYPER:
374 case typelib_TypeClass_UNSIGNED_HYPER:
375 pSeq = reallocSeq( pSeq, sizeof(sal_Int64), nAlloc );
376 if (pSeq != nullptr)
378 memcpy(
379 pSeq->elements,
380 pSourceElements,
381 sizeof(sal_Int64) * nStopIndex );
383 break;
384 case typelib_TypeClass_FLOAT:
385 pSeq = reallocSeq( pSeq, sizeof(float), nAlloc );
386 if (pSeq != nullptr)
388 memcpy(
389 pSeq->elements,
390 pSourceElements,
391 sizeof(float) * nStopIndex );
393 break;
394 case typelib_TypeClass_DOUBLE:
395 pSeq = reallocSeq( pSeq, sizeof(double), nAlloc );
396 if (pSeq != nullptr)
398 memcpy(
399 pSeq->elements,
400 pSourceElements,
401 sizeof(double) * nStopIndex );
403 break;
404 case typelib_TypeClass_ENUM:
405 pSeq = reallocSeq( pSeq, sizeof(sal_Int32), nAlloc );
406 if (pSeq != nullptr)
408 memcpy(
409 pSeq->elements,
410 pSourceElements,
411 sizeof(sal_Int32) * nStopIndex );
413 break;
414 case typelib_TypeClass_STRING:
416 pSeq = reallocSeq( pSeq, sizeof(rtl_uString *), nAlloc );
417 if (pSeq != nullptr)
419 rtl_uString ** pDestElements = reinterpret_cast<rtl_uString **>(pSeq->elements);
420 for ( sal_Int32 nPos = 0; nPos < nStopIndex; ++nPos )
422 // This code tends to trigger coverity's overrun-buffer-arg warning
423 // coverity[index_parm_via_loop_bound] - https://communities.coverity.com/thread/2993
424 ::rtl_uString_acquire(
425 static_cast<rtl_uString **>(pSourceElements)[nPos] );
426 pDestElements[nPos] = static_cast<rtl_uString **>(pSourceElements)[nPos];
429 break;
431 case typelib_TypeClass_TYPE:
433 pSeq = reallocSeq(
434 pSeq, sizeof(typelib_TypeDescriptionReference *), nAlloc );
435 if (pSeq != nullptr)
437 typelib_TypeDescriptionReference ** pDestElements =
438 reinterpret_cast<typelib_TypeDescriptionReference **>(pSeq->elements);
439 for ( sal_Int32 nPos = 0; nPos < nStopIndex; ++nPos )
441 TYPE_ACQUIRE(
442 static_cast<typelib_TypeDescriptionReference **>(
443 pSourceElements)[nPos] );
444 pDestElements[nPos] =
445 static_cast<typelib_TypeDescriptionReference **>(
446 pSourceElements)[nPos];
449 break;
451 case typelib_TypeClass_ANY:
453 pSeq = reallocSeq( pSeq, sizeof(uno_Any), nAlloc );
454 if (pSeq != nullptr)
456 uno_Any * pDestElements = reinterpret_cast<uno_Any *>(pSeq->elements);
457 for ( sal_Int32 nPos = 0; nPos < nStopIndex; ++nPos )
459 uno_Any * pSource = static_cast<uno_Any *>(pSourceElements) + nPos;
460 _copyConstructAny(
461 &pDestElements[nPos],
462 pSource->pData,
463 pSource->pType, nullptr,
464 acquire, nullptr );
467 break;
469 case typelib_TypeClass_STRUCT:
470 case typelib_TypeClass_EXCEPTION:
472 typelib_TypeDescription * pElementTypeDescr = nullptr;
473 TYPELIB_DANGER_GET( &pElementTypeDescr, pElementType );
474 sal_Int32 nElementSize = pElementTypeDescr->nSize;
476 pSeq = reallocSeq( pSeq, nElementSize, nAlloc );
477 if (pSeq != nullptr)
479 char * pDestElements = pSeq->elements;
481 typelib_CompoundTypeDescription * pTypeDescr =
482 reinterpret_cast<typelib_CompoundTypeDescription *>(pElementTypeDescr);
483 for ( sal_Int32 nPos = 0; nPos < nStopIndex; ++nPos )
485 char * pDest =
486 pDestElements + (nElementSize * nPos);
487 char * pSource =
488 static_cast<char *>(pSourceElements) + (nElementSize * nPos);
490 if (pTypeDescr->pBaseTypeDescription)
492 // copy base value
493 _copyConstructStruct(
494 pDest, pSource,
495 pTypeDescr->pBaseTypeDescription, acquire, nullptr );
498 // then copy members
499 typelib_TypeDescriptionReference ** ppTypeRefs =
500 pTypeDescr->ppTypeRefs;
501 sal_Int32 * pMemberOffsets = pTypeDescr->pMemberOffsets;
502 sal_Int32 nDescr = pTypeDescr->nMembers;
504 while (nDescr--)
506 ::uno_type_copyData(
507 pDest + pMemberOffsets[nDescr],
508 pSource + pMemberOffsets[nDescr],
509 ppTypeRefs[nDescr], acquire );
514 TYPELIB_DANGER_RELEASE( pElementTypeDescr );
515 break;
517 case typelib_TypeClass_SEQUENCE: // sequence of sequence
519 // coverity[suspicious_sizeof : FALSE] - sizeof(uno_Sequence*) is correct here
520 pSeq = reallocSeq(pSeq, sizeof(uno_Sequence*), nAlloc);
521 if (pSeq != nullptr)
523 typelib_TypeDescription * pElementTypeDescr = nullptr;
524 TYPELIB_DANGER_GET( &pElementTypeDescr, pElementType );
525 typelib_TypeDescriptionReference * pSeqElementType =
526 reinterpret_cast<typelib_IndirectTypeDescription *>(pElementTypeDescr)->pType;
527 uno_Sequence ** pDestElements = reinterpret_cast<uno_Sequence **>(pSeq->elements);
528 for ( sal_Int32 nPos = 0; nPos < nStopIndex; ++nPos )
530 uno_Sequence * pNew = icopyConstructSequence(
531 static_cast<uno_Sequence **>(pSourceElements)[nPos],
532 pSeqElementType, acquire, nullptr );
533 OSL_ASSERT( pNew != nullptr );
534 // ought never be a memory allocation problem,
535 // because of reference counted sequence handles
536 pDestElements[ nPos ] = pNew;
538 TYPELIB_DANGER_RELEASE( pElementTypeDescr );
540 break;
542 case typelib_TypeClass_INTERFACE:
544 pSeq = reallocSeq( pSeq, sizeof(void *), nAlloc );
545 if (pSeq != nullptr)
547 void ** pDestElements = reinterpret_cast<void **>(pSeq->elements);
548 for ( sal_Int32 nPos = 0; nPos < nStopIndex; ++nPos )
550 pDestElements[nPos] = static_cast<void **>(pSourceElements)[nPos];
551 _acquire( pDestElements[nPos], acquire );
554 break;
556 default:
557 OSL_FAIL( "### unexpected element type!" );
558 pSeq = nullptr;
559 break;
562 if (pSeq == nullptr)
564 return false; // allocation failure
566 *ppSeq = pSeq;
567 return true;
571 static bool ireallocSequence(
572 uno_Sequence ** ppSequence,
573 typelib_TypeDescriptionReference * pElementType,
574 sal_Int32 nSize,
575 uno_AcquireFunc acquire, uno_ReleaseFunc release )
577 bool ret = true;
578 uno_Sequence * pSeq = *ppSequence;
579 sal_Int32 nElements = pSeq->nElements;
581 if (pSeq->nRefCount > 1 ||
582 // not mem-copyable elements?
583 typelib_TypeClass_ANY == pElementType->eTypeClass ||
584 typelib_TypeClass_STRUCT == pElementType->eTypeClass ||
585 typelib_TypeClass_EXCEPTION == pElementType->eTypeClass)
587 // split sequence and construct new one from scratch
588 uno_Sequence * pNew = nullptr;
590 sal_Int32 nRest = nSize - nElements;
591 sal_Int32 nCopy = (nRest > 0 ? nElements : nSize);
593 if (nCopy >= 0)
595 ret = icopyConstructFromElements(
596 &pNew, pSeq->elements, pElementType,
597 nCopy, acquire,
598 nSize ); // alloc to nSize
600 if (ret && nRest > 0)
602 ret = idefaultConstructElements(
603 &pNew, pElementType,
604 nCopy, nSize,
605 nCopy >= 0 ? -1 /* no mem allocation */ : nSize );
608 if (ret)
610 // destruct sequence
611 if (osl_atomic_decrement( &pSeq->nRefCount ) == 0)
613 if (nElements > 0)
615 idestructElements(
616 pSeq->elements, pElementType,
617 0, nElements, release );
619 std::free( pSeq );
621 *ppSequence = pNew;
624 else
626 OSL_ASSERT( pSeq->nRefCount == 1 );
627 if (nSize > nElements) // default construct the rest
629 ret = idefaultConstructElements(
630 ppSequence, pElementType,
631 nElements, nSize,
632 nSize ); // realloc to nSize
634 else // or destruct the rest and realloc mem
636 sal_Int32 nElementSize = idestructElements(
637 pSeq->elements, pElementType,
638 nSize, nElements, release );
639 // warning: it is assumed that the following will never fail,
640 // else this leads to a sequence null handle
641 *ppSequence = reallocSeq( pSeq, nElementSize, nSize );
642 OSL_ASSERT( *ppSequence != nullptr );
643 ret = (*ppSequence != nullptr);
647 return ret;
652 extern "C"
655 sal_Bool SAL_CALL uno_type_sequence_construct(
656 uno_Sequence ** ppSequence, typelib_TypeDescriptionReference * pType,
657 void * pElements, sal_Int32 len,
658 uno_AcquireFunc acquire )
659 SAL_THROW_EXTERN_C()
661 assert( len >= 0 );
662 bool ret;
663 if (len)
665 typelib_TypeDescription * pTypeDescr = nullptr;
666 TYPELIB_DANGER_GET( &pTypeDescr, pType );
668 typelib_TypeDescriptionReference * pElementType =
669 reinterpret_cast<typelib_IndirectTypeDescription *>(pTypeDescr)->pType;
671 *ppSequence = nullptr;
672 if (pElements == nullptr)
674 ret = idefaultConstructElements(
675 ppSequence, pElementType,
676 0, len,
677 len ); // alloc to len
679 else
681 ret = icopyConstructFromElements(
682 ppSequence, pElements, pElementType,
683 len, acquire,
684 len ); // alloc to len
687 TYPELIB_DANGER_RELEASE( pTypeDescr );
689 else
691 *ppSequence = createEmptySequence();
692 ret = true;
695 OSL_ASSERT( (*ppSequence != nullptr) == ret );
696 return ret;
700 sal_Bool SAL_CALL uno_sequence_construct(
701 uno_Sequence ** ppSequence, typelib_TypeDescription * pTypeDescr,
702 void * pElements, sal_Int32 len,
703 uno_AcquireFunc acquire )
704 SAL_THROW_EXTERN_C()
706 bool ret;
707 if (len > 0)
709 typelib_TypeDescriptionReference * pElementType =
710 reinterpret_cast<typelib_IndirectTypeDescription *>(pTypeDescr)->pType;
712 *ppSequence = nullptr;
713 if (pElements == nullptr)
715 ret = idefaultConstructElements(
716 ppSequence, pElementType,
717 0, len,
718 len ); // alloc to len
720 else
722 ret = icopyConstructFromElements(
723 ppSequence, pElements, pElementType,
724 len, acquire,
725 len ); // alloc to len
728 else
730 *ppSequence = createEmptySequence();
731 ret = true;
734 OSL_ASSERT( (*ppSequence != nullptr) == ret );
735 return ret;
739 sal_Bool SAL_CALL uno_type_sequence_realloc(
740 uno_Sequence ** ppSequence, typelib_TypeDescriptionReference * pType,
741 sal_Int32 nSize, uno_AcquireFunc acquire, uno_ReleaseFunc release )
742 SAL_THROW_EXTERN_C()
744 assert(ppSequence && "### null ptr!");
745 assert(nSize >= 0 && "### new size must be at least 0!");
747 bool ret = true;
748 if (nSize != (*ppSequence)->nElements)
750 typelib_TypeDescription * pTypeDescr = nullptr;
751 TYPELIB_DANGER_GET( &pTypeDescr, pType );
752 ret = ireallocSequence(
753 ppSequence, reinterpret_cast<typelib_IndirectTypeDescription *>(pTypeDescr)->pType,
754 nSize, acquire, release );
755 TYPELIB_DANGER_RELEASE( pTypeDescr );
757 return ret;
761 sal_Bool SAL_CALL uno_sequence_realloc(
762 uno_Sequence ** ppSequence, typelib_TypeDescription * pTypeDescr,
763 sal_Int32 nSize, uno_AcquireFunc acquire, uno_ReleaseFunc release )
764 SAL_THROW_EXTERN_C()
766 OSL_ENSURE( ppSequence, "### null ptr!" );
767 OSL_ENSURE( nSize >= 0, "### new size must be at least 0!" );
769 bool ret = true;
770 if (nSize != (*ppSequence)->nElements)
772 ret = ireallocSequence(
773 ppSequence, reinterpret_cast<typelib_IndirectTypeDescription *>(pTypeDescr)->pType,
774 nSize, acquire, release );
776 return ret;
780 sal_Bool SAL_CALL uno_type_sequence_reference2One(
781 uno_Sequence ** ppSequence,
782 typelib_TypeDescriptionReference * pType,
783 uno_AcquireFunc acquire, uno_ReleaseFunc release )
784 SAL_THROW_EXTERN_C()
786 OSL_ENSURE( ppSequence, "### null ptr!" );
787 bool ret = true;
788 uno_Sequence * pSequence = *ppSequence;
789 if (pSequence->nRefCount > 1)
791 uno_Sequence * pNew = nullptr;
792 if (pSequence->nElements > 0)
794 typelib_TypeDescription * pTypeDescr = nullptr;
795 TYPELIB_DANGER_GET( &pTypeDescr, pType );
797 ret = icopyConstructFromElements(
798 &pNew, pSequence->elements,
799 reinterpret_cast<typelib_IndirectTypeDescription *>(pTypeDescr)->pType,
800 pSequence->nElements, acquire,
801 pSequence->nElements ); // alloc nElements
802 if (ret)
804 idestructSequence( *ppSequence, pType, pTypeDescr, release );
805 *ppSequence = pNew;
808 TYPELIB_DANGER_RELEASE( pTypeDescr );
810 else
812 pNew = allocSeq( 0, 0 );
813 ret = (pNew != nullptr);
814 if (ret)
816 // easy destruction of empty sequence:
817 if (osl_atomic_decrement( &pSequence->nRefCount ) == 0)
818 std::free( pSequence );
819 *ppSequence = pNew;
823 return ret;
827 sal_Bool SAL_CALL uno_sequence_reference2One(
828 uno_Sequence ** ppSequence,
829 typelib_TypeDescription * pTypeDescr,
830 uno_AcquireFunc acquire, uno_ReleaseFunc release )
831 SAL_THROW_EXTERN_C()
833 OSL_ENSURE( ppSequence, "### null ptr!" );
834 bool ret = true;
835 uno_Sequence * pSequence = *ppSequence;
836 if (pSequence->nRefCount > 1)
838 uno_Sequence * pNew = nullptr;
839 if (pSequence->nElements > 0)
841 ret = icopyConstructFromElements(
842 &pNew, pSequence->elements,
843 reinterpret_cast<typelib_IndirectTypeDescription *>(pTypeDescr)->pType,
844 pSequence->nElements, acquire,
845 pSequence->nElements ); // alloc nElements
846 if (ret)
848 idestructSequence(
849 pSequence, pTypeDescr->pWeakRef, pTypeDescr, release );
850 *ppSequence = pNew;
853 else
855 pNew = allocSeq( 0, 0 );
856 ret = (pNew != nullptr);
857 if (ret)
859 // easy destruction of empty sequence:
860 if (osl_atomic_decrement( &pSequence->nRefCount ) == 0)
861 std::free( pSequence );
862 *ppSequence = pNew;
867 return ret;
871 void SAL_CALL uno_sequence_assign(
872 uno_Sequence ** ppDest,
873 uno_Sequence * pSource,
874 typelib_TypeDescription * pTypeDescr,
875 uno_ReleaseFunc release )
876 SAL_THROW_EXTERN_C()
878 if (*ppDest != pSource)
880 osl_atomic_increment( &pSource->nRefCount );
881 idestructSequence( *ppDest, pTypeDescr->pWeakRef, pTypeDescr, release );
882 *ppDest = pSource;
887 void SAL_CALL uno_type_sequence_assign(
888 uno_Sequence ** ppDest,
889 uno_Sequence * pSource,
890 typelib_TypeDescriptionReference * pType,
891 uno_ReleaseFunc release )
892 SAL_THROW_EXTERN_C()
894 if (*ppDest != pSource)
896 osl_atomic_increment( &pSource->nRefCount );
897 idestructSequence( *ppDest, pType, nullptr, release );
898 *ppDest = pSource;
902 void uno_type_sequence_destroy(
903 uno_Sequence * sequence, typelib_TypeDescriptionReference * type,
904 uno_ReleaseFunc release)
905 SAL_THROW_EXTERN_C()
907 idestroySequence(sequence, type, nullptr, release);
912 /* vim:set shiftwidth=4 softtabstop=4 expandtab: */