bump product version to 5.0.4.1
[LibreOffice.git] / cppu / source / uno / sequence.cxx
blobcd536a85361406f034f55b24daf1792ab2fb8e84
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 <rtl/alloc.h>
26 #include <osl/diagnose.h>
27 #include <osl/interlck.h>
28 #include <typelib/typedescription.h>
29 #include <uno/data.h>
30 #include <uno/dispatcher.h>
31 #include <uno/sequence2.h>
33 #include "constr.hxx"
34 #include "copy.hxx"
35 #include "destr.hxx"
38 using namespace cppu;
40 namespace cppu
44 static inline uno_Sequence * reallocSeq(
45 uno_Sequence * pReallocate, sal_Size nElementSize, sal_Int32 nElements )
47 OSL_ASSERT( nElements >= 0 );
48 uno_Sequence * pNew = 0;
49 sal_uInt32 nSize = calcSeqMemSize( nElementSize, nElements );
50 if (nSize > 0)
52 if (pReallocate == 0)
54 pNew = static_cast<uno_Sequence *>(rtl_allocateMemory( nSize ));
56 else
58 pNew = static_cast<uno_Sequence *>(rtl_reallocateMemory( pReallocate, nSize ));
60 if (pNew != 0)
62 // header init
63 pNew->nRefCount = 1;
64 pNew->nElements = nElements;
67 return pNew;
71 static inline bool idefaultConstructElements(
72 uno_Sequence ** ppSeq,
73 typelib_TypeDescriptionReference * pElementType,
74 sal_Int32 nStartIndex, sal_Int32 nStopIndex,
75 sal_Int32 nAlloc = -1 ) // >= 0 means (re)alloc memory for nAlloc elements
77 uno_Sequence * pSeq = *ppSeq;
78 switch (pElementType->eTypeClass)
80 case typelib_TypeClass_CHAR:
81 if (nAlloc >= 0)
82 pSeq = reallocSeq( pSeq, sizeof(sal_Unicode), nAlloc );
83 if (pSeq != 0)
85 memset(
86 pSeq->elements + (sizeof(sal_Unicode) * nStartIndex),
88 sizeof(sal_Unicode) * (nStopIndex - nStartIndex) );
90 break;
91 case typelib_TypeClass_BOOLEAN:
92 if (nAlloc >= 0)
93 pSeq = reallocSeq( pSeq, sizeof(sal_Bool), nAlloc );
94 if (pSeq != 0)
96 memset(
97 pSeq->elements + (sizeof(sal_Bool) * nStartIndex),
99 sizeof(sal_Bool) * (nStopIndex - nStartIndex) );
101 break;
102 case typelib_TypeClass_BYTE:
103 if (nAlloc >= 0)
104 pSeq = reallocSeq( pSeq, sizeof(sal_Int8), nAlloc );
105 if (pSeq != 0)
107 memset(
108 pSeq->elements + (sizeof(sal_Int8) * nStartIndex),
110 sizeof(sal_Int8) * (nStopIndex - nStartIndex) );
112 break;
113 case typelib_TypeClass_SHORT:
114 case typelib_TypeClass_UNSIGNED_SHORT:
115 if (nAlloc >= 0)
116 pSeq = reallocSeq( pSeq, sizeof(sal_Int16), nAlloc );
117 if (pSeq != 0)
119 memset(
120 pSeq->elements + (sizeof(sal_Int16) * nStartIndex),
122 sizeof(sal_Int16) * (nStopIndex - nStartIndex) );
124 break;
125 case typelib_TypeClass_LONG:
126 case typelib_TypeClass_UNSIGNED_LONG:
127 if (nAlloc >= 0)
128 pSeq = reallocSeq( pSeq, sizeof(sal_Int32), nAlloc );
129 if (pSeq != 0)
131 memset(
132 pSeq->elements + (sizeof(sal_Int32) * nStartIndex),
134 sizeof(sal_Int32) * (nStopIndex - nStartIndex) );
136 break;
137 case typelib_TypeClass_HYPER:
138 case typelib_TypeClass_UNSIGNED_HYPER:
139 if (nAlloc >= 0)
140 pSeq = reallocSeq( pSeq, sizeof(sal_Int64), nAlloc );
141 if (pSeq != 0)
143 memset(
144 pSeq->elements + (sizeof(sal_Int64) * nStartIndex),
146 sizeof(sal_Int64) * (nStopIndex - nStartIndex) );
148 break;
149 case typelib_TypeClass_FLOAT:
151 if (nAlloc >= 0)
152 pSeq = reallocSeq( pSeq, sizeof(float), nAlloc );
153 if (pSeq != 0)
155 float * pElements = reinterpret_cast<float *>(pSeq->elements);
156 for ( sal_Int32 nPos = nStartIndex; nPos < nStopIndex; ++nPos )
158 pElements[nPos] = 0.0;
161 break;
163 case typelib_TypeClass_DOUBLE:
165 if (nAlloc >= 0)
166 pSeq = reallocSeq( pSeq, sizeof(double), nAlloc );
167 if (pSeq != 0)
169 double * pElements = reinterpret_cast<double *>(pSeq->elements);
170 for ( sal_Int32 nPos = nStartIndex; nPos < nStopIndex; ++nPos )
172 pElements[nPos] = 0.0;
175 break;
177 case typelib_TypeClass_STRING:
179 if (nAlloc >= 0)
180 pSeq = reallocSeq( pSeq, sizeof(rtl_uString *), nAlloc );
181 if (pSeq != 0)
183 rtl_uString ** pElements = reinterpret_cast<rtl_uString **>(pSeq->elements);
184 for ( sal_Int32 nPos = nStartIndex; nPos < nStopIndex; ++nPos )
186 pElements[nPos] = 0;
187 rtl_uString_new( &pElements[nPos] );
190 break;
192 case typelib_TypeClass_TYPE:
194 if (nAlloc >= 0)
196 pSeq = reallocSeq(
197 pSeq, sizeof(typelib_TypeDescriptionReference *), nAlloc );
199 if (pSeq != 0)
201 typelib_TypeDescriptionReference ** pElements =
202 reinterpret_cast<typelib_TypeDescriptionReference **>(pSeq->elements);
203 for ( sal_Int32 nPos = nStartIndex; nPos < nStopIndex; ++nPos )
205 pElements[nPos] = _getVoidType();
208 break;
210 case typelib_TypeClass_ANY:
212 if (nAlloc >= 0)
213 pSeq = reallocSeq( pSeq, sizeof(uno_Any), nAlloc );
214 if (pSeq != 0)
216 uno_Any * pElements = reinterpret_cast<uno_Any *>(pSeq->elements);
217 for ( sal_Int32 nPos = nStartIndex; nPos < nStopIndex; ++nPos )
219 CONSTRUCT_EMPTY_ANY( &pElements[nPos] );
222 break;
224 case typelib_TypeClass_ENUM:
226 if (nAlloc >= 0)
227 pSeq = reallocSeq( pSeq, sizeof(sal_Int32), nAlloc );
228 if (pSeq != 0)
230 typelib_TypeDescription * pElementTypeDescr = 0;
231 TYPELIB_DANGER_GET( &pElementTypeDescr, pElementType );
232 sal_Int32 eEnum =
233 reinterpret_cast<typelib_EnumTypeDescription *>(
234 pElementTypeDescr)->nDefaultEnumValue;
235 TYPELIB_DANGER_RELEASE( pElementTypeDescr );
237 sal_Int32 * pElements = reinterpret_cast<sal_Int32 *>(pSeq->elements);
238 for ( sal_Int32 nPos = nStartIndex; nPos < nStopIndex; ++nPos )
240 pElements[nPos] = eEnum;
243 break;
245 case typelib_TypeClass_STRUCT:
246 case typelib_TypeClass_EXCEPTION:
248 typelib_TypeDescription * pElementTypeDescr = 0;
249 TYPELIB_DANGER_GET( &pElementTypeDescr, pElementType );
250 sal_Int32 nElementSize = pElementTypeDescr->nSize;
252 if (nAlloc >= 0)
253 pSeq = reallocSeq( pSeq, nElementSize, nAlloc );
254 if (pSeq != 0)
256 char * pElements = pSeq->elements;
257 for ( sal_Int32 nPos = nStartIndex; nPos < nStopIndex; ++nPos )
259 _defaultConstructStruct(
260 pElements + (nElementSize * nPos),
261 reinterpret_cast<typelib_CompoundTypeDescription *>(pElementTypeDescr) );
265 TYPELIB_DANGER_RELEASE( pElementTypeDescr );
266 break;
268 case typelib_TypeClass_SEQUENCE:
270 if (nAlloc >= 0)
272 // coverity[suspicious_sizeof] - sizeof(uno_Sequence*) is correct here
273 pSeq = reallocSeq(pSeq, sizeof(uno_Sequence*), nAlloc);
275 if (pSeq != 0)
277 uno_Sequence ** pElements =
278 reinterpret_cast<uno_Sequence **>(pSeq->elements);
279 for ( sal_Int32 nPos = nStartIndex; nPos < nStopIndex; ++nPos )
281 pElements[nPos] = createEmptySequence();
284 break;
286 case typelib_TypeClass_INTERFACE: // either C++ or C-UNO interface
287 if (nAlloc >= 0)
288 pSeq = reallocSeq( pSeq, sizeof(void *), nAlloc );
289 if (pSeq != 0)
291 memset(
292 pSeq->elements + (sizeof(void *) * nStartIndex),
294 sizeof(void *) * (nStopIndex - nStartIndex) );
296 break;
297 default:
298 OSL_FAIL( "### unexpected element type!" );
299 pSeq = 0;
300 break;
303 if (pSeq == 0)
305 OSL_ASSERT( nAlloc >= 0 ); // must have been an allocation failure
306 return false;
308 else
310 *ppSeq = pSeq;
311 return true;
316 static inline bool icopyConstructFromElements(
317 uno_Sequence ** ppSeq, void * pSourceElements,
318 typelib_TypeDescriptionReference * pElementType,
319 sal_Int32 nStartIndex, sal_Int32 nStopIndex,
320 uno_AcquireFunc acquire,
321 sal_Int32 nAlloc = -1 ) // >= 0 means (re)alloc memory for nAlloc elements
323 uno_Sequence * pSeq = *ppSeq;
324 switch (pElementType->eTypeClass)
326 case typelib_TypeClass_CHAR:
327 if (nAlloc >= 0)
328 pSeq = reallocSeq( pSeq, sizeof(sal_Unicode), nAlloc );
329 if (pSeq != 0)
331 memcpy(
332 pSeq->elements + (sizeof(sal_Unicode) * nStartIndex),
333 static_cast<char *>(pSourceElements) + (sizeof(sal_Unicode) * nStartIndex),
334 sizeof(sal_Unicode) * (nStopIndex - nStartIndex) );
336 break;
337 case typelib_TypeClass_BOOLEAN:
338 if (nAlloc >= 0)
339 pSeq = reallocSeq( pSeq, sizeof(sal_Bool), nAlloc );
340 if (pSeq != 0)
342 memcpy(
343 pSeq->elements + (sizeof(sal_Bool) * nStartIndex),
344 static_cast<char *>(pSourceElements) + (sizeof(sal_Bool) * nStartIndex),
345 sizeof(sal_Bool) * (nStopIndex - nStartIndex) );
347 break;
348 case typelib_TypeClass_BYTE:
349 if (nAlloc >= 0)
350 pSeq = reallocSeq( pSeq, sizeof(sal_Int8), nAlloc );
351 if (pSeq != 0)
353 memcpy(
354 pSeq->elements + (sizeof(sal_Int8) * nStartIndex),
355 static_cast<char *>(pSourceElements) + (sizeof(sal_Int8) * nStartIndex),
356 sizeof(sal_Int8) * (nStopIndex - nStartIndex) );
358 break;
359 case typelib_TypeClass_SHORT:
360 case typelib_TypeClass_UNSIGNED_SHORT:
361 if (nAlloc >= 0)
362 pSeq = reallocSeq( pSeq, sizeof(sal_Int16), nAlloc );
363 if (pSeq != 0)
365 memcpy(
366 pSeq->elements + (sizeof(sal_Int16) * nStartIndex),
367 static_cast<char *>(pSourceElements) + (sizeof(sal_Int16) * nStartIndex),
368 sizeof(sal_Int16) * (nStopIndex - nStartIndex) );
370 break;
371 case typelib_TypeClass_LONG:
372 case typelib_TypeClass_UNSIGNED_LONG:
373 if (nAlloc >= 0)
374 pSeq = reallocSeq( pSeq, sizeof(sal_Int32), nAlloc );
375 if (pSeq != 0)
377 memcpy(
378 pSeq->elements + (sizeof(sal_Int32) * nStartIndex),
379 static_cast<char *>(pSourceElements) + (sizeof(sal_Int32) * nStartIndex),
380 sizeof(sal_Int32) * (nStopIndex - nStartIndex) );
382 break;
383 case typelib_TypeClass_HYPER:
384 case typelib_TypeClass_UNSIGNED_HYPER:
385 if (nAlloc >= 0)
386 pSeq = reallocSeq( pSeq, sizeof(sal_Int64), nAlloc );
387 if (pSeq != 0)
389 memcpy(
390 pSeq->elements + (sizeof(sal_Int64) * nStartIndex),
391 static_cast<char *>(pSourceElements) + (sizeof(sal_Int64) * nStartIndex),
392 sizeof(sal_Int64) * (nStopIndex - nStartIndex) );
394 break;
395 case typelib_TypeClass_FLOAT:
396 if (nAlloc >= 0)
397 pSeq = reallocSeq( pSeq, sizeof(float), nAlloc );
398 if (pSeq != 0)
400 memcpy(
401 pSeq->elements + (sizeof(float) * nStartIndex),
402 static_cast<char *>(pSourceElements) + (sizeof(float) * nStartIndex),
403 sizeof(float) * (nStopIndex - nStartIndex) );
405 break;
406 case typelib_TypeClass_DOUBLE:
407 if (nAlloc >= 0)
408 pSeq = reallocSeq( pSeq, sizeof(double), nAlloc );
409 if (pSeq != 0)
411 memcpy(
412 pSeq->elements + (sizeof(double) * nStartIndex),
413 static_cast<char *>(pSourceElements) + (sizeof(double) * nStartIndex),
414 sizeof(double) * (nStopIndex - nStartIndex) );
416 break;
417 case typelib_TypeClass_ENUM:
418 if (nAlloc >= 0)
419 pSeq = reallocSeq( pSeq, sizeof(sal_Int32), nAlloc );
420 if (pSeq != 0)
422 memcpy(
423 pSeq->elements + (sizeof(sal_Int32) * nStartIndex),
424 static_cast<char *>(pSourceElements) + (sizeof(sal_Int32) * nStartIndex),
425 sizeof(sal_Int32) * (nStopIndex - nStartIndex) );
427 break;
428 case typelib_TypeClass_STRING:
430 if (nAlloc >= 0)
431 pSeq = reallocSeq( pSeq, sizeof(rtl_uString *), nAlloc );
432 if (pSeq != 0)
434 rtl_uString ** pDestElements = reinterpret_cast<rtl_uString **>(pSeq->elements);
435 for ( sal_Int32 nPos = nStartIndex; nPos < nStopIndex; ++nPos )
437 // This code tends to trigger coverity's overrun-buffer-arg warning
438 // coverity[index_parm_via_loop_bound] - https://communities.coverity.com/thread/2993
439 ::rtl_uString_acquire(
440 static_cast<rtl_uString **>(pSourceElements)[nPos] );
441 pDestElements[nPos] = static_cast<rtl_uString **>(pSourceElements)[nPos];
444 break;
446 case typelib_TypeClass_TYPE:
448 if (nAlloc >= 0)
450 pSeq = reallocSeq(
451 pSeq, sizeof(typelib_TypeDescriptionReference *), nAlloc );
453 if (pSeq != 0)
455 typelib_TypeDescriptionReference ** pDestElements =
456 reinterpret_cast<typelib_TypeDescriptionReference **>(pSeq->elements);
457 for ( sal_Int32 nPos = nStartIndex; nPos < nStopIndex; ++nPos )
459 TYPE_ACQUIRE(
460 static_cast<typelib_TypeDescriptionReference **>(
461 pSourceElements)[nPos] );
462 pDestElements[nPos] =
463 static_cast<typelib_TypeDescriptionReference **>(
464 pSourceElements)[nPos];
467 break;
469 case typelib_TypeClass_ANY:
471 if (nAlloc >= 0)
472 pSeq = reallocSeq( pSeq, sizeof(uno_Any), nAlloc );
473 if (pSeq != 0)
475 uno_Any * pDestElements = reinterpret_cast<uno_Any *>(pSeq->elements);
476 for ( sal_Int32 nPos = nStartIndex; nPos < nStopIndex; ++nPos )
478 uno_Any * pSource = static_cast<uno_Any *>(pSourceElements) + nPos;
479 _copyConstructAny(
480 &pDestElements[nPos],
481 pSource->pData,
482 pSource->pType, 0,
483 acquire, 0 );
486 break;
488 case typelib_TypeClass_STRUCT:
489 case typelib_TypeClass_EXCEPTION:
491 typelib_TypeDescription * pElementTypeDescr = 0;
492 TYPELIB_DANGER_GET( &pElementTypeDescr, pElementType );
493 sal_Int32 nElementSize = pElementTypeDescr->nSize;
495 if (nAlloc >= 0)
496 pSeq = reallocSeq( pSeq, nElementSize, nAlloc );
497 if (pSeq != 0)
499 char * pDestElements = pSeq->elements;
501 typelib_CompoundTypeDescription * pTypeDescr =
502 reinterpret_cast<typelib_CompoundTypeDescription *>(pElementTypeDescr);
503 for ( sal_Int32 nPos = nStartIndex; nPos < nStopIndex; ++nPos )
505 char * pDest =
506 pDestElements + (nElementSize * nPos);
507 char * pSource =
508 static_cast<char *>(pSourceElements) + (nElementSize * nPos);
510 if (pTypeDescr->pBaseTypeDescription)
512 // copy base value
513 _copyConstructStruct(
514 pDest, pSource,
515 pTypeDescr->pBaseTypeDescription, acquire, 0 );
518 // then copy members
519 typelib_TypeDescriptionReference ** ppTypeRefs =
520 pTypeDescr->ppTypeRefs;
521 sal_Int32 * pMemberOffsets = pTypeDescr->pMemberOffsets;
522 sal_Int32 nDescr = pTypeDescr->nMembers;
524 while (nDescr--)
526 ::uno_type_copyData(
527 pDest + pMemberOffsets[nDescr],
528 pSource + pMemberOffsets[nDescr],
529 ppTypeRefs[nDescr], acquire );
534 TYPELIB_DANGER_RELEASE( pElementTypeDescr );
535 break;
537 case typelib_TypeClass_SEQUENCE: // sequence of sequence
539 if (nAlloc >= 0)
541 // coverity[suspicious_sizeof] - sizeof(uno_Sequence*) is correct here
542 pSeq = reallocSeq(pSeq, sizeof(uno_Sequence*), nAlloc);
544 if (pSeq != 0)
546 typelib_TypeDescription * pElementTypeDescr = 0;
547 TYPELIB_DANGER_GET( &pElementTypeDescr, pElementType );
548 typelib_TypeDescriptionReference * pSeqElementType =
549 reinterpret_cast<typelib_IndirectTypeDescription *>(pElementTypeDescr)->pType;
550 uno_Sequence ** pDestElements = reinterpret_cast<uno_Sequence **>(pSeq->elements);
551 for ( sal_Int32 nPos = nStartIndex; nPos < nStopIndex; ++nPos )
553 uno_Sequence * pNew = icopyConstructSequence(
554 static_cast<uno_Sequence **>(pSourceElements)[nPos],
555 pSeqElementType, acquire, 0 );
556 OSL_ASSERT( pNew != 0 );
557 // ought never be a memory allocation problem,
558 // because of reference counted sequence handles
559 pDestElements[ nPos ] = pNew;
561 TYPELIB_DANGER_RELEASE( pElementTypeDescr );
563 break;
565 case typelib_TypeClass_INTERFACE:
567 if (nAlloc >= 0)
568 pSeq = reallocSeq( pSeq, sizeof(void *), nAlloc );
569 if (pSeq != 0)
571 void ** pDestElements = reinterpret_cast<void **>(pSeq->elements);
572 for ( sal_Int32 nPos = nStartIndex; nPos < nStopIndex; ++nPos )
574 _acquire( pDestElements[nPos] =
575 static_cast<void **>(pSourceElements)[nPos], acquire );
578 break;
580 default:
581 OSL_FAIL( "### unexpected element type!" );
582 pSeq = 0;
583 break;
586 if (pSeq == 0)
588 OSL_ASSERT( nAlloc >= 0 ); // must have been an allocation failure
589 return false;
591 else
593 *ppSeq = pSeq;
594 return true;
599 static inline bool ireallocSequence(
600 uno_Sequence ** ppSequence,
601 typelib_TypeDescriptionReference * pElementType,
602 sal_Int32 nSize,
603 uno_AcquireFunc acquire, uno_ReleaseFunc release )
605 bool ret = true;
606 uno_Sequence * pSeq = *ppSequence;
607 sal_Int32 nElements = pSeq->nElements;
609 if (pSeq->nRefCount > 1 ||
610 // not mem-copyable elements?
611 typelib_TypeClass_ANY == pElementType->eTypeClass ||
612 typelib_TypeClass_STRUCT == pElementType->eTypeClass ||
613 typelib_TypeClass_EXCEPTION == pElementType->eTypeClass)
615 // split sequence and construct new one from scratch
616 uno_Sequence * pNew = 0;
618 sal_Int32 nRest = nSize - nElements;
619 sal_Int32 nCopy = (nRest > 0 ? nElements : nSize);
621 if (nCopy >= 0)
623 ret = icopyConstructFromElements(
624 &pNew, pSeq->elements, pElementType,
625 0, nCopy, acquire,
626 nSize ); // alloc to nSize
628 if (ret && nRest > 0)
630 ret = idefaultConstructElements(
631 &pNew, pElementType,
632 nCopy, nSize,
633 nCopy >= 0 ? -1 /* no mem allocation */ : nSize );
636 if (ret)
638 // destruct sequence
639 if (osl_atomic_decrement( &pSeq->nRefCount ) == 0)
641 if (nElements > 0)
643 idestructElements(
644 pSeq->elements, pElementType,
645 0, nElements, release );
647 rtl_freeMemory( pSeq );
649 *ppSequence = pNew;
652 else
654 OSL_ASSERT( pSeq->nRefCount == 1 );
655 if (nSize > nElements) // default construct the rest
657 ret = idefaultConstructElements(
658 ppSequence, pElementType,
659 nElements, nSize,
660 nSize ); // realloc to nSize
662 else // or destruct the rest and realloc mem
664 sal_Int32 nElementSize = idestructElements(
665 pSeq->elements, pElementType,
666 nSize, nElements, release );
667 // warning: it is assumed that the following will never fail,
668 // else this leads to a sequence null handle
669 *ppSequence = reallocSeq( pSeq, nElementSize, nSize );
670 OSL_ASSERT( *ppSequence != 0 );
671 ret = (*ppSequence != 0);
675 return ret;
680 extern "C"
684 sal_Bool SAL_CALL uno_type_sequence_construct(
685 uno_Sequence ** ppSequence, typelib_TypeDescriptionReference * pType,
686 void * pElements, sal_Int32 len,
687 uno_AcquireFunc acquire )
688 SAL_THROW_EXTERN_C()
690 assert( len >= 0 );
691 bool ret;
692 if (len)
694 typelib_TypeDescription * pTypeDescr = 0;
695 TYPELIB_DANGER_GET( &pTypeDescr, pType );
697 typelib_TypeDescriptionReference * pElementType =
698 reinterpret_cast<typelib_IndirectTypeDescription *>(pTypeDescr)->pType;
700 *ppSequence = 0;
701 if (pElements == 0)
703 ret = idefaultConstructElements(
704 ppSequence, pElementType,
705 0, len,
706 len ); // alloc to len
708 else
710 ret = icopyConstructFromElements(
711 ppSequence, pElements, pElementType,
712 0, len, acquire,
713 len ); // alloc to len
716 TYPELIB_DANGER_RELEASE( pTypeDescr );
718 else
720 *ppSequence = createEmptySequence();
721 ret = true;
724 OSL_ASSERT( (*ppSequence != 0) == ret );
725 return ret;
729 sal_Bool SAL_CALL uno_sequence_construct(
730 uno_Sequence ** ppSequence, typelib_TypeDescription * pTypeDescr,
731 void * pElements, sal_Int32 len,
732 uno_AcquireFunc acquire )
733 SAL_THROW_EXTERN_C()
735 bool ret;
736 if (len > 0)
738 typelib_TypeDescriptionReference * pElementType =
739 reinterpret_cast<typelib_IndirectTypeDescription *>(pTypeDescr)->pType;
741 *ppSequence = 0;
742 if (pElements == 0)
744 ret = idefaultConstructElements(
745 ppSequence, pElementType,
746 0, len,
747 len ); // alloc to len
749 else
751 ret = icopyConstructFromElements(
752 ppSequence, pElements, pElementType,
753 0, len, acquire,
754 len ); // alloc to len
757 else
759 *ppSequence = createEmptySequence();
760 ret = true;
763 OSL_ASSERT( (*ppSequence != 0) == ret );
764 return ret;
768 sal_Bool SAL_CALL uno_type_sequence_realloc(
769 uno_Sequence ** ppSequence, typelib_TypeDescriptionReference * pType,
770 sal_Int32 nSize, uno_AcquireFunc acquire, uno_ReleaseFunc release )
771 SAL_THROW_EXTERN_C()
773 OSL_ENSURE( ppSequence, "### null ptr!" );
774 OSL_ENSURE( nSize >= 0, "### new size must be at least 0!" );
776 bool ret = true;
777 if (nSize != (*ppSequence)->nElements)
779 typelib_TypeDescription * pTypeDescr = 0;
780 TYPELIB_DANGER_GET( &pTypeDescr, pType );
781 ret = ireallocSequence(
782 ppSequence, reinterpret_cast<typelib_IndirectTypeDescription *>(pTypeDescr)->pType,
783 nSize, acquire, release );
784 TYPELIB_DANGER_RELEASE( pTypeDescr );
786 return ret;
790 sal_Bool SAL_CALL uno_sequence_realloc(
791 uno_Sequence ** ppSequence, typelib_TypeDescription * pTypeDescr,
792 sal_Int32 nSize, uno_AcquireFunc acquire, uno_ReleaseFunc release )
793 SAL_THROW_EXTERN_C()
795 OSL_ENSURE( ppSequence, "### null ptr!" );
796 OSL_ENSURE( nSize >= 0, "### new size must be at least 0!" );
798 bool ret = true;
799 if (nSize != (*ppSequence)->nElements)
801 ret = ireallocSequence(
802 ppSequence, reinterpret_cast<typelib_IndirectTypeDescription *>(pTypeDescr)->pType,
803 nSize, acquire, release );
805 return ret;
809 sal_Bool SAL_CALL uno_type_sequence_reference2One(
810 uno_Sequence ** ppSequence,
811 typelib_TypeDescriptionReference * pType,
812 uno_AcquireFunc acquire, uno_ReleaseFunc release )
813 SAL_THROW_EXTERN_C()
815 OSL_ENSURE( ppSequence, "### null ptr!" );
816 bool ret = true;
817 uno_Sequence * pSequence = *ppSequence;
818 if (pSequence->nRefCount > 1)
820 uno_Sequence * pNew = 0;
821 if (pSequence->nElements > 0)
823 typelib_TypeDescription * pTypeDescr = 0;
824 TYPELIB_DANGER_GET( &pTypeDescr, pType );
826 ret = icopyConstructFromElements(
827 &pNew, pSequence->elements,
828 reinterpret_cast<typelib_IndirectTypeDescription *>(pTypeDescr)->pType,
829 0, pSequence->nElements, acquire,
830 pSequence->nElements ); // alloc nElements
831 if (ret)
833 idestructSequence( *ppSequence, pType, pTypeDescr, release );
834 *ppSequence = pNew;
837 TYPELIB_DANGER_RELEASE( pTypeDescr );
839 else
841 pNew = allocSeq( 0, 0 );
842 ret = (pNew != 0);
843 if (ret)
845 // easy destruction of empty sequence:
846 if (osl_atomic_decrement( &pSequence->nRefCount ) == 0)
847 rtl_freeMemory( pSequence );
848 *ppSequence = pNew;
852 return ret;
856 sal_Bool SAL_CALL uno_sequence_reference2One(
857 uno_Sequence ** ppSequence,
858 typelib_TypeDescription * pTypeDescr,
859 uno_AcquireFunc acquire, uno_ReleaseFunc release )
860 SAL_THROW_EXTERN_C()
862 OSL_ENSURE( ppSequence, "### null ptr!" );
863 bool ret = true;
864 uno_Sequence * pSequence = *ppSequence;
865 if (pSequence->nRefCount > 1)
867 uno_Sequence * pNew = 0;
868 if (pSequence->nElements > 0)
870 ret = icopyConstructFromElements(
871 &pNew, pSequence->elements,
872 reinterpret_cast<typelib_IndirectTypeDescription *>(pTypeDescr)->pType,
873 0, pSequence->nElements, acquire,
874 pSequence->nElements ); // alloc nElements
875 if (ret)
877 idestructSequence(
878 pSequence, pTypeDescr->pWeakRef, pTypeDescr, release );
879 *ppSequence = pNew;
882 else
884 pNew = allocSeq( 0, 0 );
885 ret = (pNew != 0);
886 if (ret)
888 // easy destruction of empty sequence:
889 if (osl_atomic_decrement( &pSequence->nRefCount ) == 0)
890 rtl_freeMemory( pSequence );
891 *ppSequence = pNew;
896 return ret;
900 void SAL_CALL uno_sequence_assign(
901 uno_Sequence ** ppDest,
902 uno_Sequence * pSource,
903 typelib_TypeDescription * pTypeDescr,
904 uno_ReleaseFunc release )
905 SAL_THROW_EXTERN_C()
907 if (*ppDest != pSource)
909 osl_atomic_increment( &pSource->nRefCount );
910 idestructSequence( *ppDest, pTypeDescr->pWeakRef, pTypeDescr, release );
911 *ppDest = pSource;
916 void SAL_CALL uno_type_sequence_assign(
917 uno_Sequence ** ppDest,
918 uno_Sequence * pSource,
919 typelib_TypeDescriptionReference * pType,
920 uno_ReleaseFunc release )
921 SAL_THROW_EXTERN_C()
923 if (*ppDest != pSource)
925 osl_atomic_increment( &pSource->nRefCount );
926 idestructSequence( *ppDest, pType, 0, release );
927 *ppDest = pSource;
931 void uno_type_sequence_destroy(
932 uno_Sequence * sequence, typelib_TypeDescriptionReference * type,
933 uno_ReleaseFunc release)
934 SAL_THROW_EXTERN_C()
936 idestroySequence(sequence, type, nullptr, release);
941 /* vim:set shiftwidth=4 softtabstop=4 expandtab: */