Version 4.0.2.1, tag libreoffice-4.0.2.1
[LibreOffice.git] / cppu / source / uno / sequence.cxx
blobd9e28fb7f9ad7b95c500bf73b50cc8a9111a9b9e
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 <string.h>
22 #include <rtl/alloc.h>
23 #include <osl/diagnose.h>
24 #include <osl/interlck.h>
25 #include <typelib/typedescription.h>
26 #include <uno/data.h>
27 #include <uno/dispatcher.h>
28 #include <uno/sequence2.h>
30 #include "constr.hxx"
31 #include "copy.hxx"
32 #include "destr.hxx"
35 using namespace cppu;
37 namespace cppu
40 //------------------------------------------------------------------------------
41 static inline uno_Sequence * reallocSeq(
42 uno_Sequence * pReallocate, sal_Size nElementSize, sal_Int32 nElements )
44 OSL_ASSERT( nElements >= 0 );
45 uno_Sequence * pNew = 0;
46 sal_uInt32 nSize = calcSeqMemSize( nElementSize, nElements );
47 if (nSize > 0)
49 if (pReallocate == 0)
51 pNew = (uno_Sequence *) rtl_allocateMemory( nSize );
53 else
55 pNew = (uno_Sequence *) rtl_reallocateMemory( pReallocate, nSize );
57 if (pNew != 0)
59 // header init
60 pNew->nRefCount = 1;
61 pNew->nElements = nElements;
64 return pNew;
67 //------------------------------------------------------------------------------
68 static inline bool idefaultConstructElements(
69 uno_Sequence ** ppSeq,
70 typelib_TypeDescriptionReference * pElementType,
71 sal_Int32 nStartIndex, sal_Int32 nStopIndex,
72 sal_Int32 nAlloc = -1 ) // >= 0 means (re)alloc memory for nAlloc elements
74 uno_Sequence * pSeq = *ppSeq;
75 switch (pElementType->eTypeClass)
77 case typelib_TypeClass_CHAR:
78 if (nAlloc >= 0)
79 pSeq = reallocSeq( pSeq, sizeof(sal_Unicode), nAlloc );
80 if (pSeq != 0)
82 memset(
83 pSeq->elements + (sizeof(sal_Unicode) * nStartIndex),
85 sizeof(sal_Unicode) * (nStopIndex - nStartIndex) );
87 break;
88 case typelib_TypeClass_BOOLEAN:
89 if (nAlloc >= 0)
90 pSeq = reallocSeq( pSeq, sizeof(sal_Bool), nAlloc );
91 if (pSeq != 0)
93 memset(
94 pSeq->elements + (sizeof(sal_Bool) * nStartIndex),
96 sizeof(sal_Bool) * (nStopIndex - nStartIndex) );
98 break;
99 case typelib_TypeClass_BYTE:
100 if (nAlloc >= 0)
101 pSeq = reallocSeq( pSeq, sizeof(sal_Int8), nAlloc );
102 if (pSeq != 0)
104 memset(
105 pSeq->elements + (sizeof(sal_Int8) * nStartIndex),
107 sizeof(sal_Int8) * (nStopIndex - nStartIndex) );
109 break;
110 case typelib_TypeClass_SHORT:
111 case typelib_TypeClass_UNSIGNED_SHORT:
112 if (nAlloc >= 0)
113 pSeq = reallocSeq( pSeq, sizeof(sal_Int16), nAlloc );
114 if (pSeq != 0)
116 memset(
117 pSeq->elements + (sizeof(sal_Int16) * nStartIndex),
119 sizeof(sal_Int16) * (nStopIndex - nStartIndex) );
121 break;
122 case typelib_TypeClass_LONG:
123 case typelib_TypeClass_UNSIGNED_LONG:
124 if (nAlloc >= 0)
125 pSeq = reallocSeq( pSeq, sizeof(sal_Int32), nAlloc );
126 if (pSeq != 0)
128 memset(
129 pSeq->elements + (sizeof(sal_Int32) * nStartIndex),
131 sizeof(sal_Int32) * (nStopIndex - nStartIndex) );
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)
140 memset(
141 pSeq->elements + (sizeof(sal_Int64) * nStartIndex),
143 sizeof(sal_Int64) * (nStopIndex - nStartIndex) );
145 break;
146 case typelib_TypeClass_FLOAT:
148 if (nAlloc >= 0)
149 pSeq = reallocSeq( pSeq, sizeof(float), nAlloc );
150 if (pSeq != 0)
152 float * pElements = (float *) pSeq->elements;
153 for ( sal_Int32 nPos = nStartIndex; nPos < nStopIndex; ++nPos )
155 pElements[nPos] = 0.0;
158 break;
160 case typelib_TypeClass_DOUBLE:
162 if (nAlloc >= 0)
163 pSeq = reallocSeq( pSeq, sizeof(double), nAlloc );
164 if (pSeq != 0)
166 double * pElements = (double *) pSeq->elements;
167 for ( sal_Int32 nPos = nStartIndex; nPos < nStopIndex; ++nPos )
169 pElements[nPos] = 0.0;
172 break;
174 case typelib_TypeClass_STRING:
176 if (nAlloc >= 0)
177 pSeq = reallocSeq( pSeq, sizeof(rtl_uString *), nAlloc );
178 if (pSeq != 0)
180 rtl_uString ** pElements = (rtl_uString **) pSeq->elements;
181 for ( sal_Int32 nPos = nStartIndex; nPos < nStopIndex; ++nPos )
183 pElements[nPos] = 0;
184 rtl_uString_new( &pElements[nPos] );
187 break;
189 case typelib_TypeClass_TYPE:
191 if (nAlloc >= 0)
193 pSeq = reallocSeq(
194 pSeq, sizeof(typelib_TypeDescriptionReference *), nAlloc );
196 if (pSeq != 0)
198 typelib_TypeDescriptionReference ** pElements =
199 (typelib_TypeDescriptionReference **) pSeq->elements;
200 for ( sal_Int32 nPos = nStartIndex; nPos < nStopIndex; ++nPos )
202 pElements[nPos] = _getVoidType();
205 break;
207 case typelib_TypeClass_ANY:
209 if (nAlloc >= 0)
210 pSeq = reallocSeq( pSeq, sizeof(uno_Any), nAlloc );
211 if (pSeq != 0)
213 uno_Any * pElements = (uno_Any *) pSeq->elements;
214 for ( sal_Int32 nPos = nStartIndex; nPos < nStopIndex; ++nPos )
216 CONSTRUCT_EMPTY_ANY( &pElements[nPos] );
219 break;
221 case typelib_TypeClass_ENUM:
223 if (nAlloc >= 0)
224 pSeq = reallocSeq( pSeq, sizeof(sal_Int32), nAlloc );
225 if (pSeq != 0)
227 typelib_TypeDescription * pElementTypeDescr = 0;
228 TYPELIB_DANGER_GET( &pElementTypeDescr, pElementType );
229 sal_Int32 eEnum =
230 ((typelib_EnumTypeDescription *)
231 pElementTypeDescr)->nDefaultEnumValue;
232 TYPELIB_DANGER_RELEASE( pElementTypeDescr );
234 sal_Int32 * pElements = (sal_Int32 *) pSeq->elements;
235 for ( sal_Int32 nPos = nStartIndex; nPos < nStopIndex; ++nPos )
237 pElements[nPos] = eEnum;
240 break;
242 case typelib_TypeClass_STRUCT:
243 case typelib_TypeClass_EXCEPTION:
245 typelib_TypeDescription * pElementTypeDescr = 0;
246 TYPELIB_DANGER_GET( &pElementTypeDescr, pElementType );
247 sal_Int32 nElementSize = pElementTypeDescr->nSize;
249 if (nAlloc >= 0)
250 pSeq = reallocSeq( pSeq, nElementSize, nAlloc );
251 if (pSeq != 0)
253 char * pElements = pSeq->elements;
254 for ( sal_Int32 nPos = nStartIndex; nPos < nStopIndex; ++nPos )
256 _defaultConstructStruct(
257 pElements + (nElementSize * nPos),
258 (typelib_CompoundTypeDescription *)pElementTypeDescr );
262 TYPELIB_DANGER_RELEASE( pElementTypeDescr );
263 break;
265 case typelib_TypeClass_ARRAY:
267 typelib_TypeDescription * pElementTypeDescr = 0;
268 TYPELIB_DANGER_GET( &pElementTypeDescr, pElementType );
269 sal_Int32 nElementSize = pElementTypeDescr->nSize;
271 if (nAlloc >= 0)
272 pSeq = reallocSeq( pSeq, nElementSize, nAlloc );
273 if (pSeq != 0)
275 char * pElements = pSeq->elements;
276 for ( sal_Int32 nPos = nStartIndex; nPos < nStopIndex; ++nPos )
278 _defaultConstructArray(
279 pElements + (nElementSize * nPos),
280 (typelib_ArrayTypeDescription *)pElementTypeDescr );
284 TYPELIB_DANGER_RELEASE( pElementTypeDescr );
285 break;
287 case typelib_TypeClass_UNION:
289 typelib_TypeDescription * pElementTypeDescr = 0;
290 TYPELIB_DANGER_GET( &pElementTypeDescr, pElementType );
291 sal_Int32 nElementSize = pElementTypeDescr->nSize;
293 if (nAlloc >= 0)
294 pSeq = reallocSeq( pSeq, nElementSize, nAlloc );
295 if (pSeq != 0)
297 sal_Int32 nValueOffset =
298 ((typelib_UnionTypeDescription *)
299 pElementTypeDescr)->nValueOffset;
300 sal_Int64 nDefaultDiscr =
301 ((typelib_UnionTypeDescription *)
302 pElementTypeDescr)->nDefaultDiscriminant;
304 typelib_TypeDescription * pDefaultTypeDescr = 0;
305 TYPELIB_DANGER_GET(
306 &pDefaultTypeDescr,
307 ((typelib_UnionTypeDescription *)
308 pElementTypeDescr)->pDefaultTypeRef );
310 char * pElements = pSeq->elements;
311 for ( sal_Int32 nPos = nStartIndex; nPos < nStopIndex; ++nPos )
313 char * pMem = pElements + (nElementSize * nPos);
314 ::uno_constructData(
315 (char *)pMem + nValueOffset, pDefaultTypeDescr );
316 *(sal_Int64 *)pMem = nDefaultDiscr;
318 TYPELIB_DANGER_RELEASE( pDefaultTypeDescr );
321 TYPELIB_DANGER_RELEASE( pElementTypeDescr );
322 break;
324 case typelib_TypeClass_SEQUENCE:
326 if (nAlloc >= 0)
327 pSeq = reallocSeq( pSeq, sizeof(uno_Sequence *), nAlloc );
328 if (pSeq != 0)
330 uno_Sequence ** pElements =
331 (uno_Sequence **) pSeq->elements;
332 for ( sal_Int32 nPos = nStartIndex; nPos < nStopIndex; ++nPos )
334 pElements[nPos] = createEmptySequence();
337 break;
339 case typelib_TypeClass_INTERFACE: // either C++ or C-UNO interface
340 if (nAlloc >= 0)
341 pSeq = reallocSeq( pSeq, sizeof(void *), nAlloc );
342 if (pSeq != 0)
344 memset(
345 pSeq->elements + (sizeof(void *) * nStartIndex),
347 sizeof(void *) * (nStopIndex - nStartIndex) );
349 break;
350 default:
351 OSL_FAIL( "### unexpected element type!" );
352 pSeq = 0;
353 break;
356 if (pSeq == 0)
358 OSL_ASSERT( nAlloc >= 0 ); // must have been an allocation failure
359 return false;
361 else
363 *ppSeq = pSeq;
364 return true;
368 //------------------------------------------------------------------------------
369 static inline bool icopyConstructFromElements(
370 uno_Sequence ** ppSeq, void * pSourceElements,
371 typelib_TypeDescriptionReference * pElementType,
372 sal_Int32 nStartIndex, sal_Int32 nStopIndex,
373 uno_AcquireFunc acquire,
374 sal_Int32 nAlloc = -1 ) // >= 0 means (re)alloc memory for nAlloc elements
376 uno_Sequence * pSeq = *ppSeq;
377 switch (pElementType->eTypeClass)
379 case typelib_TypeClass_CHAR:
380 if (nAlloc >= 0)
381 pSeq = reallocSeq( pSeq, sizeof(sal_Unicode), nAlloc );
382 if (pSeq != 0)
384 memcpy(
385 pSeq->elements + (sizeof(sal_Unicode) * nStartIndex),
386 (char *)pSourceElements + (sizeof(sal_Unicode) * nStartIndex),
387 sizeof(sal_Unicode) * (nStopIndex - nStartIndex) );
389 break;
390 case typelib_TypeClass_BOOLEAN:
391 if (nAlloc >= 0)
392 pSeq = reallocSeq( pSeq, sizeof(sal_Bool), nAlloc );
393 if (pSeq != 0)
395 memcpy(
396 pSeq->elements + (sizeof(sal_Bool) * nStartIndex),
397 (char *)pSourceElements + (sizeof(sal_Bool) * nStartIndex),
398 sizeof(sal_Bool) * (nStopIndex - nStartIndex) );
400 break;
401 case typelib_TypeClass_BYTE:
402 if (nAlloc >= 0)
403 pSeq = reallocSeq( pSeq, sizeof(sal_Int8), nAlloc );
404 if (pSeq != 0)
406 memcpy(
407 pSeq->elements + (sizeof(sal_Int8) * nStartIndex),
408 (char *)pSourceElements + (sizeof(sal_Int8) * nStartIndex),
409 sizeof(sal_Int8) * (nStopIndex - nStartIndex) );
411 break;
412 case typelib_TypeClass_SHORT:
413 case typelib_TypeClass_UNSIGNED_SHORT:
414 if (nAlloc >= 0)
415 pSeq = reallocSeq( pSeq, sizeof(sal_Int16), nAlloc );
416 if (pSeq != 0)
418 memcpy(
419 pSeq->elements + (sizeof(sal_Int16) * nStartIndex),
420 (char *)pSourceElements + (sizeof(sal_Int16) * nStartIndex),
421 sizeof(sal_Int16) * (nStopIndex - nStartIndex) );
423 break;
424 case typelib_TypeClass_LONG:
425 case typelib_TypeClass_UNSIGNED_LONG:
426 if (nAlloc >= 0)
427 pSeq = reallocSeq( pSeq, sizeof(sal_Int32), nAlloc );
428 if (pSeq != 0)
430 memcpy(
431 pSeq->elements + (sizeof(sal_Int32) * nStartIndex),
432 (char *)pSourceElements + (sizeof(sal_Int32) * nStartIndex),
433 sizeof(sal_Int32) * (nStopIndex - nStartIndex) );
435 break;
436 case typelib_TypeClass_HYPER:
437 case typelib_TypeClass_UNSIGNED_HYPER:
438 if (nAlloc >= 0)
439 pSeq = reallocSeq( pSeq, sizeof(sal_Int64), nAlloc );
440 if (pSeq != 0)
442 memcpy(
443 pSeq->elements + (sizeof(sal_Int64) * nStartIndex),
444 (char *)pSourceElements + (sizeof(sal_Int64) * nStartIndex),
445 sizeof(sal_Int64) * (nStopIndex - nStartIndex) );
447 break;
448 case typelib_TypeClass_FLOAT:
449 if (nAlloc >= 0)
450 pSeq = reallocSeq( pSeq, sizeof(float), nAlloc );
451 if (pSeq != 0)
453 memcpy(
454 pSeq->elements + (sizeof(float) * nStartIndex),
455 (char *)pSourceElements + (sizeof(float) * nStartIndex),
456 sizeof(float) * (nStopIndex - nStartIndex) );
458 break;
459 case typelib_TypeClass_DOUBLE:
460 if (nAlloc >= 0)
461 pSeq = reallocSeq( pSeq, sizeof(double), nAlloc );
462 if (pSeq != 0)
464 memcpy(
465 pSeq->elements + (sizeof(double) * nStartIndex),
466 (char *)pSourceElements + (sizeof(double) * nStartIndex),
467 sizeof(double) * (nStopIndex - nStartIndex) );
469 break;
470 case typelib_TypeClass_ENUM:
471 if (nAlloc >= 0)
472 pSeq = reallocSeq( pSeq, sizeof(sal_Int32), nAlloc );
473 if (pSeq != 0)
475 memcpy(
476 pSeq->elements + (sizeof(sal_Int32) * nStartIndex),
477 (char *)pSourceElements + (sizeof(sal_Int32) * nStartIndex),
478 sizeof(sal_Int32) * (nStopIndex - nStartIndex) );
480 break;
481 case typelib_TypeClass_STRING:
483 if (nAlloc >= 0)
484 pSeq = reallocSeq( pSeq, sizeof(rtl_uString *), nAlloc );
485 if (pSeq != 0)
487 rtl_uString ** pDestElements = (rtl_uString **) pSeq->elements;
488 for ( sal_Int32 nPos = nStartIndex; nPos < nStopIndex; ++nPos )
490 ::rtl_uString_acquire(
491 ((rtl_uString **)pSourceElements)[nPos] );
492 pDestElements[nPos] = ((rtl_uString **)pSourceElements)[nPos];
495 break;
497 case typelib_TypeClass_TYPE:
499 if (nAlloc >= 0)
501 pSeq = reallocSeq(
502 pSeq, sizeof(typelib_TypeDescriptionReference *), nAlloc );
504 if (pSeq != 0)
506 typelib_TypeDescriptionReference ** pDestElements =
507 (typelib_TypeDescriptionReference **) pSeq->elements;
508 for ( sal_Int32 nPos = nStartIndex; nPos < nStopIndex; ++nPos )
510 TYPE_ACQUIRE(
511 ((typelib_TypeDescriptionReference **)
512 pSourceElements)[nPos] );
513 pDestElements[nPos] =
514 ((typelib_TypeDescriptionReference **)
515 pSourceElements)[nPos];
518 break;
520 case typelib_TypeClass_ANY:
522 if (nAlloc >= 0)
523 pSeq = reallocSeq( pSeq, sizeof(uno_Any), nAlloc );
524 if (pSeq != 0)
526 uno_Any * pDestElements = (uno_Any *) pSeq->elements;
527 for ( sal_Int32 nPos = nStartIndex; nPos < nStopIndex; ++nPos )
529 uno_Any * pSource = (uno_Any *)pSourceElements + nPos;
530 _copyConstructAny(
531 &pDestElements[nPos],
532 pSource->pData,
533 pSource->pType, 0,
534 acquire, 0 );
537 break;
539 case typelib_TypeClass_STRUCT:
540 case typelib_TypeClass_EXCEPTION:
542 typelib_TypeDescription * pElementTypeDescr = 0;
543 TYPELIB_DANGER_GET( &pElementTypeDescr, pElementType );
544 sal_Int32 nElementSize = pElementTypeDescr->nSize;
546 if (nAlloc >= 0)
547 pSeq = reallocSeq( pSeq, nElementSize, nAlloc );
548 if (pSeq != 0)
550 char * pDestElements = pSeq->elements;
552 typelib_CompoundTypeDescription * pTypeDescr =
553 (typelib_CompoundTypeDescription *)pElementTypeDescr;
554 for ( sal_Int32 nPos = nStartIndex; nPos < nStopIndex; ++nPos )
556 char * pDest =
557 pDestElements + (nElementSize * nPos);
558 char * pSource =
559 (char *)pSourceElements + (nElementSize * nPos);
561 if (pTypeDescr->pBaseTypeDescription)
563 // copy base value
564 _copyConstructStruct(
565 pDest, pSource,
566 pTypeDescr->pBaseTypeDescription, acquire, 0 );
569 // then copy members
570 typelib_TypeDescriptionReference ** ppTypeRefs =
571 pTypeDescr->ppTypeRefs;
572 sal_Int32 * pMemberOffsets = pTypeDescr->pMemberOffsets;
573 sal_Int32 nDescr = pTypeDescr->nMembers;
575 while (nDescr--)
577 ::uno_type_copyData(
578 pDest + pMemberOffsets[nDescr],
579 pSource + pMemberOffsets[nDescr],
580 ppTypeRefs[nDescr], acquire );
585 TYPELIB_DANGER_RELEASE( pElementTypeDescr );
586 break;
588 case typelib_TypeClass_UNION:
590 typelib_TypeDescription * pElementTypeDescr = 0;
591 TYPELIB_DANGER_GET( &pElementTypeDescr, pElementType );
592 sal_Int32 nElementSize = pElementTypeDescr->nSize;
594 if (nAlloc >= 0)
595 pSeq = reallocSeq( pSeq, nElementSize, nAlloc );
596 if (pSeq != 0)
598 char * pDestElements = pSeq->elements;
600 sal_Int32 nValueOffset =
601 ((typelib_UnionTypeDescription *)
602 pElementTypeDescr)->nValueOffset;
603 for ( sal_Int32 nPos = nStartIndex; nPos < nStopIndex; ++nPos )
605 char * pDest =
606 pDestElements + (nElementSize * nPos);
607 char * pSource =
608 (char *)pSourceElements + (nElementSize * nPos);
610 typelib_TypeDescriptionReference * pSetType = _unionGetSetType(
611 pSource, pElementTypeDescr );
612 ::uno_type_copyData(
613 pDest + nValueOffset,
614 pSource + nValueOffset,
615 pSetType, acquire );
616 *(sal_Int64 *)pDest = *(sal_Int64 *)pSource;
617 typelib_typedescriptionreference_release( pSetType );
621 TYPELIB_DANGER_RELEASE( pElementTypeDescr );
622 break;
624 case typelib_TypeClass_SEQUENCE: // sequence of sequence
626 if (nAlloc >= 0)
627 pSeq = reallocSeq( pSeq, sizeof(uno_Sequence *), nAlloc );
628 if (pSeq != 0)
630 typelib_TypeDescription * pElementTypeDescr = 0;
631 TYPELIB_DANGER_GET( &pElementTypeDescr, pElementType );
632 typelib_TypeDescriptionReference * pSeqElementType =
633 ((typelib_IndirectTypeDescription *) pElementTypeDescr)->pType;
634 uno_Sequence ** pDestElements = (uno_Sequence **) pSeq->elements;
635 for ( sal_Int32 nPos = nStartIndex; nPos < nStopIndex; ++nPos )
637 uno_Sequence * pNew = icopyConstructSequence(
638 ((uno_Sequence **) pSourceElements)[nPos],
639 pSeqElementType, acquire, 0 );
640 OSL_ASSERT( pNew != 0 );
641 // ought never be a memory allocation problem,
642 // because of reference counted sequence handles
643 pDestElements[ nPos ] = pNew;
645 TYPELIB_DANGER_RELEASE( pElementTypeDescr );
647 break;
649 case typelib_TypeClass_INTERFACE:
651 if (nAlloc >= 0)
652 pSeq = reallocSeq( pSeq, sizeof(void *), nAlloc );
653 if (pSeq != 0)
655 void ** pDestElements = (void **) pSeq->elements;
656 for ( sal_Int32 nPos = nStartIndex; nPos < nStopIndex; ++nPos )
658 _acquire( pDestElements[nPos] =
659 ((void **)pSourceElements)[nPos], acquire );
662 break;
664 default:
665 OSL_FAIL( "### unexpected element type!" );
666 pSeq = 0;
667 break;
670 if (pSeq == 0)
672 OSL_ASSERT( nAlloc >= 0 ); // must have been an allocation failure
673 return false;
675 else
677 *ppSeq = pSeq;
678 return true;
682 //------------------------------------------------------------------------------
683 static inline bool ireallocSequence(
684 uno_Sequence ** ppSequence,
685 typelib_TypeDescriptionReference * pElementType,
686 sal_Int32 nSize,
687 uno_AcquireFunc acquire, uno_ReleaseFunc release )
689 bool ret = true;
690 uno_Sequence * pSeq = *ppSequence;
691 sal_Int32 nElements = pSeq->nElements;
693 if (pSeq->nRefCount > 1 ||
694 // not mem-copyable elements?
695 typelib_TypeClass_ANY == pElementType->eTypeClass ||
696 typelib_TypeClass_STRUCT == pElementType->eTypeClass ||
697 typelib_TypeClass_EXCEPTION == pElementType->eTypeClass)
699 // split sequence and construct new one from scratch
700 uno_Sequence * pNew = 0;
702 sal_Int32 nRest = nSize - nElements;
703 sal_Int32 nCopy = (nRest > 0 ? nElements : nSize);
705 if (nCopy >= 0)
707 ret = icopyConstructFromElements(
708 &pNew, pSeq->elements, pElementType,
709 0, nCopy, acquire,
710 nSize ); // alloc to nSize
712 if (ret && nRest > 0)
714 ret = idefaultConstructElements(
715 &pNew, pElementType,
716 nCopy, nSize,
717 nCopy >= 0 ? -1 /* no mem allocation */ : nSize );
720 if (ret)
722 // destruct sequence
723 if (osl_atomic_decrement( &pSeq->nRefCount ) == 0)
725 if (nElements > 0)
727 idestructElements(
728 pSeq->elements, pElementType,
729 0, nElements, release );
731 rtl_freeMemory( pSeq );
733 *ppSequence = pNew;
736 else
738 OSL_ASSERT( pSeq->nRefCount == 1 );
739 if (nSize > nElements) // default construct the rest
741 ret = idefaultConstructElements(
742 ppSequence, pElementType,
743 nElements, nSize,
744 nSize ); // realloc to nSize
746 else // or destruct the rest and realloc mem
748 sal_Int32 nElementSize = idestructElements(
749 pSeq->elements, pElementType,
750 nSize, nElements, release );
751 // warning: it is assumed that the following will never fail,
752 // else this leads to a sequence null handle
753 *ppSequence = reallocSeq( pSeq, nElementSize, nSize );
754 OSL_ASSERT( *ppSequence != 0 );
755 ret = (*ppSequence != 0);
759 return ret;
764 extern "C"
767 //##############################################################################
768 sal_Bool SAL_CALL uno_type_sequence_construct(
769 uno_Sequence ** ppSequence, typelib_TypeDescriptionReference * pType,
770 void * pElements, sal_Int32 len,
771 uno_AcquireFunc acquire )
772 SAL_THROW_EXTERN_C()
774 bool ret;
775 if (len)
777 typelib_TypeDescription * pTypeDescr = 0;
778 TYPELIB_DANGER_GET( &pTypeDescr, pType );
780 typelib_TypeDescriptionReference * pElementType =
781 ((typelib_IndirectTypeDescription *)pTypeDescr)->pType;
783 *ppSequence = 0;
784 if (pElements == 0)
786 ret = idefaultConstructElements(
787 ppSequence, pElementType,
788 0, len,
789 len ); // alloc to len
791 else
793 ret = icopyConstructFromElements(
794 ppSequence, pElements, pElementType,
795 0, len, acquire,
796 len ); // alloc to len
799 TYPELIB_DANGER_RELEASE( pTypeDescr );
801 else
803 *ppSequence = createEmptySequence();
804 ret = true;
807 OSL_ASSERT( (*ppSequence != 0) == ret );
808 return ret;
811 //##############################################################################
812 sal_Bool SAL_CALL uno_sequence_construct(
813 uno_Sequence ** ppSequence, typelib_TypeDescription * pTypeDescr,
814 void * pElements, sal_Int32 len,
815 uno_AcquireFunc acquire )
816 SAL_THROW_EXTERN_C()
818 bool ret;
819 if (len > 0)
821 typelib_TypeDescriptionReference * pElementType =
822 ((typelib_IndirectTypeDescription *)pTypeDescr)->pType;
824 *ppSequence = 0;
825 if (pElements == 0)
827 ret = idefaultConstructElements(
828 ppSequence, pElementType,
829 0, len,
830 len ); // alloc to len
832 else
834 ret = icopyConstructFromElements(
835 ppSequence, pElements, pElementType,
836 0, len, acquire,
837 len ); // alloc to len
840 else
842 *ppSequence = createEmptySequence();
843 ret = true;
846 OSL_ASSERT( (*ppSequence != 0) == ret );
847 return ret;
850 //##############################################################################
851 sal_Bool SAL_CALL uno_type_sequence_realloc(
852 uno_Sequence ** ppSequence, typelib_TypeDescriptionReference * pType,
853 sal_Int32 nSize, uno_AcquireFunc acquire, uno_ReleaseFunc release )
854 SAL_THROW_EXTERN_C()
856 OSL_ENSURE( ppSequence, "### null ptr!" );
857 OSL_ENSURE( nSize >= 0, "### new size must be at least 0!" );
859 bool ret = true;
860 if (nSize != (*ppSequence)->nElements)
862 typelib_TypeDescription * pTypeDescr = 0;
863 TYPELIB_DANGER_GET( &pTypeDescr, pType );
864 ret = ireallocSequence(
865 ppSequence, ((typelib_IndirectTypeDescription *)pTypeDescr)->pType,
866 nSize, acquire, release );
867 TYPELIB_DANGER_RELEASE( pTypeDescr );
869 return ret;
872 //##############################################################################
873 sal_Bool SAL_CALL uno_sequence_realloc(
874 uno_Sequence ** ppSequence, typelib_TypeDescription * pTypeDescr,
875 sal_Int32 nSize, uno_AcquireFunc acquire, uno_ReleaseFunc release )
876 SAL_THROW_EXTERN_C()
878 OSL_ENSURE( ppSequence, "### null ptr!" );
879 OSL_ENSURE( nSize >= 0, "### new size must be at least 0!" );
881 bool ret = true;
882 if (nSize != (*ppSequence)->nElements)
884 ret = ireallocSequence(
885 ppSequence, ((typelib_IndirectTypeDescription *)pTypeDescr)->pType,
886 nSize, acquire, release );
888 return ret;
891 //##############################################################################
892 sal_Bool SAL_CALL uno_type_sequence_reference2One(
893 uno_Sequence ** ppSequence,
894 typelib_TypeDescriptionReference * pType,
895 uno_AcquireFunc acquire, uno_ReleaseFunc release )
896 SAL_THROW_EXTERN_C()
898 OSL_ENSURE( ppSequence, "### null ptr!" );
899 bool ret = true;
900 uno_Sequence * pSequence = *ppSequence;
901 if (pSequence->nRefCount > 1)
903 uno_Sequence * pNew = 0;
904 if (pSequence->nElements > 0)
906 typelib_TypeDescription * pTypeDescr = 0;
907 TYPELIB_DANGER_GET( &pTypeDescr, pType );
909 ret = icopyConstructFromElements(
910 &pNew, pSequence->elements,
911 ((typelib_IndirectTypeDescription *)pTypeDescr)->pType,
912 0, pSequence->nElements, acquire,
913 pSequence->nElements ); // alloc nElements
914 if (ret)
916 idestructSequence( *ppSequence, pType, pTypeDescr, release );
917 *ppSequence = pNew;
920 TYPELIB_DANGER_RELEASE( pTypeDescr );
922 else
924 pNew = allocSeq( 0, 0 );
925 ret = (pNew != 0);
926 if (ret)
928 // easy destruction of empty sequence:
929 if (osl_atomic_decrement( &pSequence->nRefCount ) == 0)
930 rtl_freeMemory( pSequence );
931 *ppSequence = pNew;
935 return ret;
938 //##############################################################################
939 sal_Bool SAL_CALL uno_sequence_reference2One(
940 uno_Sequence ** ppSequence,
941 typelib_TypeDescription * pTypeDescr,
942 uno_AcquireFunc acquire, uno_ReleaseFunc release )
943 SAL_THROW_EXTERN_C()
945 OSL_ENSURE( ppSequence, "### null ptr!" );
946 bool ret = true;
947 uno_Sequence * pSequence = *ppSequence;
948 if (pSequence->nRefCount > 1)
950 uno_Sequence * pNew = 0;
951 if (pSequence->nElements > 0)
953 ret = icopyConstructFromElements(
954 &pNew, pSequence->elements,
955 ((typelib_IndirectTypeDescription *)pTypeDescr)->pType,
956 0, pSequence->nElements, acquire,
957 pSequence->nElements ); // alloc nElements
958 if (ret)
960 idestructSequence(
961 pSequence, pTypeDescr->pWeakRef, pTypeDescr, release );
962 *ppSequence = pNew;
965 else
967 pNew = allocSeq( 0, 0 );
968 ret = (pNew != 0);
969 if (ret)
971 // easy destruction of empty sequence:
972 if (osl_atomic_decrement( &pSequence->nRefCount ) == 0)
973 rtl_freeMemory( pSequence );
974 *ppSequence = pNew;
979 return ret;
982 //##############################################################################
983 void SAL_CALL uno_sequence_assign(
984 uno_Sequence ** ppDest,
985 uno_Sequence * pSource,
986 typelib_TypeDescription * pTypeDescr,
987 uno_ReleaseFunc release )
988 SAL_THROW_EXTERN_C()
990 if (*ppDest != pSource)
992 osl_atomic_increment( &pSource->nRefCount );
993 idestructSequence( *ppDest, pTypeDescr->pWeakRef, pTypeDescr, release );
994 *ppDest = pSource;
998 //##############################################################################
999 void SAL_CALL uno_type_sequence_assign(
1000 uno_Sequence ** ppDest,
1001 uno_Sequence * pSource,
1002 typelib_TypeDescriptionReference * pType,
1003 uno_ReleaseFunc release )
1004 SAL_THROW_EXTERN_C()
1006 if (*ppDest != pSource)
1008 osl_atomic_increment( &pSource->nRefCount );
1009 idestructSequence( *ppDest, pType, 0, release );
1010 *ppDest = pSource;
1016 /* vim:set shiftwidth=4 softtabstop=4 expandtab: */