merged tag ooo/DEV300_m102
[LibreOffice.git] / cppu / source / uno / sequence.cxx
blob933d38fc6b4f5e24600089d067843a5407066023
1 /*************************************************************************
3 * DO NOT ALTER OR REMOVE COPYRIGHT NOTICES OR THIS FILE HEADER.
5 * Copyright 2000, 2010 Oracle and/or its affiliates.
7 * OpenOffice.org - a multi-platform office productivity suite
9 * This file is part of OpenOffice.org.
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.
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).
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.
26 ************************************************************************/
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>
39 #include "constr.hxx"
40 #include "copy.hxx"
41 #include "destr.hxx"
44 using namespace cppu;
46 namespace cppu
49 //------------------------------------------------------------------------------
50 static inline uno_Sequence * reallocSeq(
51 uno_Sequence * pReallocate, sal_Size nElementSize, sal_Int32 nElements )
53 OSL_ASSERT( nElements >= 0 );
54 uno_Sequence * pNew = 0;
55 sal_uInt32 nSize = calcSeqMemSize( nElementSize, nElements );
56 if (nSize > 0)
58 if (pReallocate == 0)
60 pNew = (uno_Sequence *) rtl_allocateMemory( nSize );
62 else
64 pNew = (uno_Sequence *) rtl_reallocateMemory( pReallocate, nSize );
66 if (pNew != 0)
68 // header init
69 pNew->nRefCount = 1;
70 pNew->nElements = nElements;
73 return pNew;
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
83 uno_Sequence * pSeq = *ppSeq;
84 switch (pElementType->eTypeClass)
86 case typelib_TypeClass_CHAR:
87 if (nAlloc >= 0)
88 pSeq = reallocSeq( pSeq, sizeof(sal_Unicode), nAlloc );
89 if (pSeq != 0)
91 ::rtl_zeroMemory(
92 pSeq->elements + (sizeof(sal_Unicode) * nStartIndex),
93 sizeof(sal_Unicode) * (nStopIndex - nStartIndex) );
95 break;
96 case typelib_TypeClass_BOOLEAN:
97 if (nAlloc >= 0)
98 pSeq = reallocSeq( pSeq, sizeof(sal_Bool), nAlloc );
99 if (pSeq != 0)
101 ::rtl_zeroMemory(
102 pSeq->elements + (sizeof(sal_Bool) * nStartIndex),
103 sizeof(sal_Bool) * (nStopIndex - nStartIndex) );
105 break;
106 case typelib_TypeClass_BYTE:
107 if (nAlloc >= 0)
108 pSeq = reallocSeq( pSeq, sizeof(sal_Int8), nAlloc );
109 if (pSeq != 0)
111 ::rtl_zeroMemory(
112 pSeq->elements + (sizeof(sal_Int8) * nStartIndex),
113 sizeof(sal_Int8) * (nStopIndex - nStartIndex) );
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)
122 ::rtl_zeroMemory(
123 pSeq->elements + (sizeof(sal_Int16) * nStartIndex),
124 sizeof(sal_Int16) * (nStopIndex - nStartIndex) );
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)
133 ::rtl_zeroMemory(
134 pSeq->elements + (sizeof(sal_Int32) * nStartIndex),
135 sizeof(sal_Int32) * (nStopIndex - nStartIndex) );
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)
144 ::rtl_zeroMemory(
145 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 = (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 = (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 = (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 (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 = (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 ((typelib_EnumTypeDescription *)
234 pElementTypeDescr)->nDefaultEnumValue;
235 TYPELIB_DANGER_RELEASE( pElementTypeDescr );
237 sal_Int32 * pElements = (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 (typelib_CompoundTypeDescription *)pElementTypeDescr );
265 TYPELIB_DANGER_RELEASE( pElementTypeDescr );
266 break;
268 case typelib_TypeClass_ARRAY:
270 typelib_TypeDescription * pElementTypeDescr = 0;
271 TYPELIB_DANGER_GET( &pElementTypeDescr, pElementType );
272 sal_Int32 nElementSize = pElementTypeDescr->nSize;
274 if (nAlloc >= 0)
275 pSeq = reallocSeq( pSeq, nElementSize, nAlloc );
276 if (pSeq != 0)
278 char * pElements = pSeq->elements;
279 for ( sal_Int32 nPos = nStartIndex; nPos < nStopIndex; ++nPos )
281 _defaultConstructArray(
282 pElements + (nElementSize * nPos),
283 (typelib_ArrayTypeDescription *)pElementTypeDescr );
287 TYPELIB_DANGER_RELEASE( pElementTypeDescr );
288 break;
290 case typelib_TypeClass_UNION:
292 typelib_TypeDescription * pElementTypeDescr = 0;
293 TYPELIB_DANGER_GET( &pElementTypeDescr, pElementType );
294 sal_Int32 nElementSize = pElementTypeDescr->nSize;
296 if (nAlloc >= 0)
297 pSeq = reallocSeq( pSeq, nElementSize, nAlloc );
298 if (pSeq != 0)
300 sal_Int32 nValueOffset =
301 ((typelib_UnionTypeDescription *)
302 pElementTypeDescr)->nValueOffset;
303 sal_Int64 nDefaultDiscr =
304 ((typelib_UnionTypeDescription *)
305 pElementTypeDescr)->nDefaultDiscriminant;
307 typelib_TypeDescription * pDefaultTypeDescr = 0;
308 TYPELIB_DANGER_GET(
309 &pDefaultTypeDescr,
310 ((typelib_UnionTypeDescription *)
311 pElementTypeDescr)->pDefaultTypeRef );
313 char * pElements = pSeq->elements;
314 for ( sal_Int32 nPos = nStartIndex; nPos < nStopIndex; ++nPos )
316 char * pMem = pElements + (nElementSize * nPos);
317 ::uno_constructData(
318 (char *)pMem + nValueOffset, pDefaultTypeDescr );
319 *(sal_Int64 *)pMem = nDefaultDiscr;
321 TYPELIB_DANGER_RELEASE( pDefaultTypeDescr );
324 TYPELIB_DANGER_RELEASE( pElementTypeDescr );
325 break;
327 case typelib_TypeClass_SEQUENCE:
329 if (nAlloc >= 0)
330 pSeq = reallocSeq( pSeq, sizeof(uno_Sequence *), nAlloc );
331 if (pSeq != 0)
333 uno_Sequence ** pElements =
334 (uno_Sequence **) pSeq->elements;
335 for ( sal_Int32 nPos = nStartIndex; nPos < nStopIndex; ++nPos )
337 pElements[nPos] = createEmptySequence();
340 break;
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)
347 ::rtl_zeroMemory(
348 pSeq->elements + (sizeof(void *) * nStartIndex),
349 sizeof(void *) * (nStopIndex - nStartIndex) );
351 break;
352 default:
353 OSL_ENSURE( 0, "### unexpected element type!" );
354 pSeq = 0;
355 break;
358 if (pSeq == 0)
360 OSL_ASSERT( nAlloc >= 0 ); // must have been an allocation failure
361 return false;
363 else
365 *ppSeq = pSeq;
366 return true;
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
378 uno_Sequence * pSeq = *ppSeq;
379 switch (pElementType->eTypeClass)
381 case typelib_TypeClass_CHAR:
382 if (nAlloc >= 0)
383 pSeq = reallocSeq( pSeq, sizeof(sal_Unicode), nAlloc );
384 if (pSeq != 0)
386 ::rtl_copyMemory(
387 pSeq->elements + (sizeof(sal_Unicode) * nStartIndex),
388 (char *)pSourceElements + (sizeof(sal_Unicode) * nStartIndex),
389 sizeof(sal_Unicode) * (nStopIndex - nStartIndex) );
391 break;
392 case typelib_TypeClass_BOOLEAN:
393 if (nAlloc >= 0)
394 pSeq = reallocSeq( pSeq, sizeof(sal_Bool), nAlloc );
395 if (pSeq != 0)
397 ::rtl_copyMemory(
398 pSeq->elements + (sizeof(sal_Bool) * nStartIndex),
399 (char *)pSourceElements + (sizeof(sal_Bool) * nStartIndex),
400 sizeof(sal_Bool) * (nStopIndex - nStartIndex) );
402 break;
403 case typelib_TypeClass_BYTE:
404 if (nAlloc >= 0)
405 pSeq = reallocSeq( pSeq, sizeof(sal_Int8), nAlloc );
406 if (pSeq != 0)
408 ::rtl_copyMemory(
409 pSeq->elements + (sizeof(sal_Int8) * nStartIndex),
410 (char *)pSourceElements + (sizeof(sal_Int8) * nStartIndex),
411 sizeof(sal_Int8) * (nStopIndex - nStartIndex) );
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)
420 ::rtl_copyMemory(
421 pSeq->elements + (sizeof(sal_Int16) * nStartIndex),
422 (char *)pSourceElements + (sizeof(sal_Int16) * nStartIndex),
423 sizeof(sal_Int16) * (nStopIndex - nStartIndex) );
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)
432 ::rtl_copyMemory(
433 pSeq->elements + (sizeof(sal_Int32) * nStartIndex),
434 (char *)pSourceElements + (sizeof(sal_Int32) * nStartIndex),
435 sizeof(sal_Int32) * (nStopIndex - nStartIndex) );
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)
444 ::rtl_copyMemory(
445 pSeq->elements + (sizeof(sal_Int64) * nStartIndex),
446 (char *)pSourceElements + (sizeof(sal_Int64) * nStartIndex),
447 sizeof(sal_Int64) * (nStopIndex - nStartIndex) );
449 break;
450 case typelib_TypeClass_FLOAT:
451 if (nAlloc >= 0)
452 pSeq = reallocSeq( pSeq, sizeof(float), nAlloc );
453 if (pSeq != 0)
455 ::rtl_copyMemory(
456 pSeq->elements + (sizeof(float) * nStartIndex),
457 (char *)pSourceElements + (sizeof(float) * nStartIndex),
458 sizeof(float) * (nStopIndex - nStartIndex) );
460 break;
461 case typelib_TypeClass_DOUBLE:
462 if (nAlloc >= 0)
463 pSeq = reallocSeq( pSeq, sizeof(double), nAlloc );
464 if (pSeq != 0)
466 ::rtl_copyMemory(
467 pSeq->elements + (sizeof(double) * nStartIndex),
468 (char *)pSourceElements + (sizeof(double) * nStartIndex),
469 sizeof(double) * (nStopIndex - nStartIndex) );
471 break;
472 case typelib_TypeClass_ENUM:
473 if (nAlloc >= 0)
474 pSeq = reallocSeq( pSeq, sizeof(sal_Int32), nAlloc );
475 if (pSeq != 0)
477 ::rtl_copyMemory(
478 pSeq->elements + (sizeof(sal_Int32) * nStartIndex),
479 (char *)pSourceElements + (sizeof(sal_Int32) * nStartIndex),
480 sizeof(sal_Int32) * (nStopIndex - nStartIndex) );
482 break;
483 case typelib_TypeClass_STRING:
485 if (nAlloc >= 0)
486 pSeq = reallocSeq( pSeq, sizeof(rtl_uString *), nAlloc );
487 if (pSeq != 0)
489 rtl_uString ** pDestElements = (rtl_uString **) pSeq->elements;
490 for ( sal_Int32 nPos = nStartIndex; nPos < nStopIndex; ++nPos )
492 ::rtl_uString_acquire(
493 ((rtl_uString **)pSourceElements)[nPos] );
494 pDestElements[nPos] = ((rtl_uString **)pSourceElements)[nPos];
497 break;
499 case typelib_TypeClass_TYPE:
501 if (nAlloc >= 0)
503 pSeq = reallocSeq(
504 pSeq, sizeof(typelib_TypeDescriptionReference *), nAlloc );
506 if (pSeq != 0)
508 typelib_TypeDescriptionReference ** pDestElements =
509 (typelib_TypeDescriptionReference **) pSeq->elements;
510 for ( sal_Int32 nPos = nStartIndex; nPos < nStopIndex; ++nPos )
512 TYPE_ACQUIRE(
513 ((typelib_TypeDescriptionReference **)
514 pSourceElements)[nPos] );
515 pDestElements[nPos] =
516 ((typelib_TypeDescriptionReference **)
517 pSourceElements)[nPos];
520 break;
522 case typelib_TypeClass_ANY:
524 if (nAlloc >= 0)
525 pSeq = reallocSeq( pSeq, sizeof(uno_Any), nAlloc );
526 if (pSeq != 0)
528 uno_Any * pDestElements = (uno_Any *) pSeq->elements;
529 for ( sal_Int32 nPos = nStartIndex; nPos < nStopIndex; ++nPos )
531 uno_Any * pSource = (uno_Any *)pSourceElements + nPos;
532 _copyConstructAny(
533 &pDestElements[nPos],
534 pSource->pData,
535 pSource->pType, 0,
536 acquire, 0 );
539 break;
541 case typelib_TypeClass_STRUCT:
542 case typelib_TypeClass_EXCEPTION:
544 typelib_TypeDescription * pElementTypeDescr = 0;
545 TYPELIB_DANGER_GET( &pElementTypeDescr, pElementType );
546 sal_Int32 nElementSize = pElementTypeDescr->nSize;
548 if (nAlloc >= 0)
549 pSeq = reallocSeq( pSeq, nElementSize, nAlloc );
550 if (pSeq != 0)
552 char * pDestElements = pSeq->elements;
554 typelib_CompoundTypeDescription * pTypeDescr =
555 (typelib_CompoundTypeDescription *)pElementTypeDescr;
556 for ( sal_Int32 nPos = nStartIndex; nPos < nStopIndex; ++nPos )
558 char * pDest =
559 pDestElements + (nElementSize * nPos);
560 char * pSource =
561 (char *)pSourceElements + (nElementSize * nPos);
563 if (pTypeDescr->pBaseTypeDescription)
565 // copy base value
566 _copyConstructStruct(
567 pDest, pSource,
568 pTypeDescr->pBaseTypeDescription, acquire, 0 );
571 // then copy members
572 typelib_TypeDescriptionReference ** ppTypeRefs =
573 pTypeDescr->ppTypeRefs;
574 sal_Int32 * pMemberOffsets = pTypeDescr->pMemberOffsets;
575 sal_Int32 nDescr = pTypeDescr->nMembers;
577 while (nDescr--)
579 ::uno_type_copyData(
580 pDest + pMemberOffsets[nDescr],
581 pSource + pMemberOffsets[nDescr],
582 ppTypeRefs[nDescr], acquire );
587 TYPELIB_DANGER_RELEASE( pElementTypeDescr );
588 break;
590 case typelib_TypeClass_UNION:
592 typelib_TypeDescription * pElementTypeDescr = 0;
593 TYPELIB_DANGER_GET( &pElementTypeDescr, pElementType );
594 sal_Int32 nElementSize = pElementTypeDescr->nSize;
596 if (nAlloc >= 0)
597 pSeq = reallocSeq( pSeq, nElementSize, nAlloc );
598 if (pSeq != 0)
600 char * pDestElements = pSeq->elements;
602 sal_Int32 nValueOffset =
603 ((typelib_UnionTypeDescription *)
604 pElementTypeDescr)->nValueOffset;
605 for ( sal_Int32 nPos = nStartIndex; nPos < nStopIndex; ++nPos )
607 char * pDest =
608 pDestElements + (nElementSize * nPos);
609 char * pSource =
610 (char *)pSourceElements + (nElementSize * nPos);
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 );
623 TYPELIB_DANGER_RELEASE( pElementTypeDescr );
624 break;
626 case typelib_TypeClass_SEQUENCE: // sequence of sequence
628 if (nAlloc >= 0)
629 pSeq = reallocSeq( pSeq, sizeof(uno_Sequence *), nAlloc );
630 if (pSeq != 0)
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 )
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;
647 TYPELIB_DANGER_RELEASE( pElementTypeDescr );
649 break;
651 case typelib_TypeClass_INTERFACE:
653 if (nAlloc >= 0)
654 pSeq = reallocSeq( pSeq, sizeof(void *), nAlloc );
655 if (pSeq != 0)
657 void ** pDestElements = (void **) pSeq->elements;
658 for ( sal_Int32 nPos = nStartIndex; nPos < nStopIndex; ++nPos )
660 _acquire( pDestElements[nPos] =
661 ((void **)pSourceElements)[nPos], acquire );
664 break;
666 default:
667 OSL_ENSURE( 0, "### unexpected element type!" );
668 pSeq = 0;
669 break;
672 if (pSeq == 0)
674 OSL_ASSERT( nAlloc >= 0 ); // must have been an allocation failure
675 return false;
677 else
679 *ppSeq = pSeq;
680 return true;
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 )
691 bool ret = true;
692 uno_Sequence * pSeq = *ppSequence;
693 sal_Int32 nElements = pSeq->nElements;
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)
701 // split sequence and construct new one from scratch
702 uno_Sequence * pNew = 0;
704 sal_Int32 nRest = nSize - nElements;
705 sal_Int32 nCopy = (nRest > 0 ? nElements : nSize);
707 if (nCopy >= 0)
709 ret = icopyConstructFromElements(
710 &pNew, pSeq->elements, pElementType,
711 0, nCopy, acquire,
712 nSize ); // alloc to nSize
714 if (ret && nRest > 0)
716 ret = idefaultConstructElements(
717 &pNew, pElementType,
718 nCopy, nSize,
719 nCopy >= 0 ? -1 /* no mem allocation */ : nSize );
722 if (ret)
724 // destruct sequence
725 if (osl_decrementInterlockedCount( &pSeq->nRefCount ) == 0)
727 if (nElements > 0)
729 idestructElements(
730 pSeq->elements, pElementType,
731 0, nElements, release );
733 rtl_freeMemory( pSeq );
735 *ppSequence = pNew;
738 else
740 OSL_ASSERT( pSeq->nRefCount == 1 );
741 if (nSize > nElements) // default construct the rest
743 ret = idefaultConstructElements(
744 ppSequence, pElementType,
745 nElements, nSize,
746 nSize ); // realloc to nSize
748 else // or destruct the rest and realloc mem
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);
761 return ret;
766 extern "C"
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()
776 bool ret;
777 if (len)
779 typelib_TypeDescription * pTypeDescr = 0;
780 TYPELIB_DANGER_GET( &pTypeDescr, pType );
782 typelib_TypeDescriptionReference * pElementType =
783 ((typelib_IndirectTypeDescription *)pTypeDescr)->pType;
785 *ppSequence = 0;
786 if (pElements == 0)
788 ret = idefaultConstructElements(
789 ppSequence, pElementType,
790 0, len,
791 len ); // alloc to len
793 else
795 ret = icopyConstructFromElements(
796 ppSequence, pElements, pElementType,
797 0, len, acquire,
798 len ); // alloc to len
801 TYPELIB_DANGER_RELEASE( pTypeDescr );
803 else
805 *ppSequence = createEmptySequence();
806 ret = true;
809 OSL_ASSERT( (*ppSequence != 0) == ret );
810 return ret;
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()
820 bool ret;
821 if (len > 0)
823 typelib_TypeDescriptionReference * pElementType =
824 ((typelib_IndirectTypeDescription *)pTypeDescr)->pType;
826 *ppSequence = 0;
827 if (pElements == 0)
829 ret = idefaultConstructElements(
830 ppSequence, pElementType,
831 0, len,
832 len ); // alloc to len
834 else
836 ret = icopyConstructFromElements(
837 ppSequence, pElements, pElementType,
838 0, len, acquire,
839 len ); // alloc to len
842 else
844 *ppSequence = createEmptySequence();
845 ret = true;
848 OSL_ASSERT( (*ppSequence != 0) == ret );
849 return ret;
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()
858 OSL_ENSURE( ppSequence, "### null ptr!" );
859 OSL_ENSURE( nSize >= 0, "### new size must be at least 0!" );
861 bool ret = true;
862 if (nSize != (*ppSequence)->nElements)
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 );
871 return ret;
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()
880 OSL_ENSURE( ppSequence, "### null ptr!" );
881 OSL_ENSURE( nSize >= 0, "### new size must be at least 0!" );
883 bool ret = true;
884 if (nSize != (*ppSequence)->nElements)
886 ret = ireallocSequence(
887 ppSequence, ((typelib_IndirectTypeDescription *)pTypeDescr)->pType,
888 nSize, acquire, release );
890 return ret;
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()
900 OSL_ENSURE( ppSequence, "### null ptr!" );
901 bool ret = true;
902 uno_Sequence * pSequence = *ppSequence;
903 if (pSequence->nRefCount > 1)
905 uno_Sequence * pNew = 0;
906 if (pSequence->nElements > 0)
908 typelib_TypeDescription * pTypeDescr = 0;
909 TYPELIB_DANGER_GET( &pTypeDescr, pType );
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)
918 idestructSequence( *ppSequence, pType, pTypeDescr, release );
919 *ppSequence = pNew;
922 TYPELIB_DANGER_RELEASE( pTypeDescr );
924 else
926 pNew = allocSeq( 0, 0 );
927 ret = (pNew != 0);
928 if (ret)
930 // easy destruction of empty sequence:
931 if (osl_decrementInterlockedCount( &pSequence->nRefCount ) == 0)
932 rtl_freeMemory( pSequence );
933 *ppSequence = pNew;
937 return ret;
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()
947 OSL_ENSURE( ppSequence, "### null ptr!" );
948 bool ret = true;
949 uno_Sequence * pSequence = *ppSequence;
950 if (pSequence->nRefCount > 1)
952 uno_Sequence * pNew = 0;
953 if (pSequence->nElements > 0)
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)
962 idestructSequence(
963 pSequence, pTypeDescr->pWeakRef, pTypeDescr, release );
964 *ppSequence = pNew;
967 else
969 pNew = allocSeq( 0, 0 );
970 ret = (pNew != 0);
971 if (ret)
973 // easy destruction of empty sequence:
974 if (osl_decrementInterlockedCount( &pSequence->nRefCount ) == 0)
975 rtl_freeMemory( pSequence );
976 *ppSequence = pNew;
981 return ret;
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()
992 if (*ppDest != pSource)
994 ::osl_incrementInterlockedCount( &pSource->nRefCount );
995 idestructSequence( *ppDest, pTypeDescr->pWeakRef, pTypeDescr, release );
996 *ppDest = pSource;
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()
1008 if (*ppDest != pSource)
1010 ::osl_incrementInterlockedCount( &pSource->nRefCount );
1011 idestructSequence( *ppDest, pType, 0, release );
1012 *ppDest = pSource;