update dev300-m58
[ooovba.git] / cppu / source / uno / sequence.cxx
blobc7667569142ec0c854a0708885f7cb3746aab656
1 /*************************************************************************
3 * DO NOT ALTER OR REMOVE COPYRIGHT NOTICES OR THIS FILE HEADER.
4 *
5 * Copyright 2008 by Sun Microsystems, Inc.
7 * OpenOffice.org - a multi-platform office productivity suite
9 * $RCSfile: sequence.cxx,v $
10 * $Revision: 1.20 $
12 * This file is part of OpenOffice.org.
14 * OpenOffice.org is free software: you can redistribute it and/or modify
15 * it under the terms of the GNU Lesser General Public License version 3
16 * only, as published by the Free Software Foundation.
18 * OpenOffice.org is distributed in the hope that it will be useful,
19 * but WITHOUT ANY WARRANTY; without even the implied warranty of
20 * MERCHANTABILITY or FITNESS FOR A PARTICULAR PURPOSE. See the
21 * GNU Lesser General Public License version 3 for more details
22 * (a copy is included in the LICENSE file that accompanied this code).
24 * You should have received a copy of the GNU Lesser General Public License
25 * version 3 along with OpenOffice.org. If not, see
26 * <http://www.openoffice.org/license.html>
27 * for a copy of the LGPLv3 License.
29 ************************************************************************/
31 // MARKER(update_precomp.py): autogen include statement, do not remove
32 #include "precompiled_cppu.hxx"
33 #include <rtl/memory.h>
34 #include <rtl/alloc.h>
35 #include <osl/diagnose.h>
36 #include <osl/interlck.h>
37 #include <typelib/typedescription.h>
38 #include <uno/data.h>
39 #include <uno/dispatcher.h>
40 #include <uno/sequence2.h>
42 #include "constr.hxx"
43 #include "copy.hxx"
44 #include "destr.hxx"
47 using namespace cppu;
49 namespace cppu
52 //------------------------------------------------------------------------------
53 static inline uno_Sequence * reallocSeq(
54 uno_Sequence * pReallocate, sal_Size nElementSize, sal_Int32 nElements )
56 OSL_ASSERT( nElements >= 0 );
57 uno_Sequence * pNew = 0;
58 sal_uInt32 nSize = calcSeqMemSize( nElementSize, nElements );
59 if (nSize > 0)
61 if (pReallocate == 0)
63 pNew = (uno_Sequence *) rtl_allocateMemory( nSize );
65 else
67 pNew = (uno_Sequence *) rtl_reallocateMemory( pReallocate, nSize );
69 if (pNew != 0)
71 // header init
72 pNew->nRefCount = 1;
73 pNew->nElements = nElements;
76 return pNew;
79 //------------------------------------------------------------------------------
80 static inline bool idefaultConstructElements(
81 uno_Sequence ** ppSeq,
82 typelib_TypeDescriptionReference * pElementType,
83 sal_Int32 nStartIndex, sal_Int32 nStopIndex,
84 sal_Int32 nAlloc = -1 ) // >= 0 means (re)alloc memory for nAlloc elements
86 uno_Sequence * pSeq = *ppSeq;
87 switch (pElementType->eTypeClass)
89 case typelib_TypeClass_CHAR:
90 if (nAlloc >= 0)
91 pSeq = reallocSeq( pSeq, sizeof(sal_Unicode), nAlloc );
92 if (pSeq != 0)
94 ::rtl_zeroMemory(
95 pSeq->elements + (sizeof(sal_Unicode) * nStartIndex),
96 sizeof(sal_Unicode) * (nStopIndex - nStartIndex) );
98 break;
99 case typelib_TypeClass_BOOLEAN:
100 if (nAlloc >= 0)
101 pSeq = reallocSeq( pSeq, sizeof(sal_Bool), nAlloc );
102 if (pSeq != 0)
104 ::rtl_zeroMemory(
105 pSeq->elements + (sizeof(sal_Bool) * nStartIndex),
106 sizeof(sal_Bool) * (nStopIndex - nStartIndex) );
108 break;
109 case typelib_TypeClass_BYTE:
110 if (nAlloc >= 0)
111 pSeq = reallocSeq( pSeq, sizeof(sal_Int8), nAlloc );
112 if (pSeq != 0)
114 ::rtl_zeroMemory(
115 pSeq->elements + (sizeof(sal_Int8) * nStartIndex),
116 sizeof(sal_Int8) * (nStopIndex - nStartIndex) );
118 break;
119 case typelib_TypeClass_SHORT:
120 case typelib_TypeClass_UNSIGNED_SHORT:
121 if (nAlloc >= 0)
122 pSeq = reallocSeq( pSeq, sizeof(sal_Int16), nAlloc );
123 if (pSeq != 0)
125 ::rtl_zeroMemory(
126 pSeq->elements + (sizeof(sal_Int16) * nStartIndex),
127 sizeof(sal_Int16) * (nStopIndex - nStartIndex) );
129 break;
130 case typelib_TypeClass_LONG:
131 case typelib_TypeClass_UNSIGNED_LONG:
132 if (nAlloc >= 0)
133 pSeq = reallocSeq( pSeq, sizeof(sal_Int32), nAlloc );
134 if (pSeq != 0)
136 ::rtl_zeroMemory(
137 pSeq->elements + (sizeof(sal_Int32) * nStartIndex),
138 sizeof(sal_Int32) * (nStopIndex - nStartIndex) );
140 break;
141 case typelib_TypeClass_HYPER:
142 case typelib_TypeClass_UNSIGNED_HYPER:
143 if (nAlloc >= 0)
144 pSeq = reallocSeq( pSeq, sizeof(sal_Int64), nAlloc );
145 if (pSeq != 0)
147 ::rtl_zeroMemory(
148 pSeq->elements + (sizeof(sal_Int64) * nStartIndex),
149 sizeof(sal_Int64) * (nStopIndex - nStartIndex) );
151 break;
152 case typelib_TypeClass_FLOAT:
154 if (nAlloc >= 0)
155 pSeq = reallocSeq( pSeq, sizeof(float), nAlloc );
156 if (pSeq != 0)
158 float * pElements = (float *) pSeq->elements;
159 for ( sal_Int32 nPos = nStartIndex; nPos < nStopIndex; ++nPos )
161 pElements[nPos] = 0.0;
164 break;
166 case typelib_TypeClass_DOUBLE:
168 if (nAlloc >= 0)
169 pSeq = reallocSeq( pSeq, sizeof(double), nAlloc );
170 if (pSeq != 0)
172 double * pElements = (double *) pSeq->elements;
173 for ( sal_Int32 nPos = nStartIndex; nPos < nStopIndex; ++nPos )
175 pElements[nPos] = 0.0;
178 break;
180 case typelib_TypeClass_STRING:
182 if (nAlloc >= 0)
183 pSeq = reallocSeq( pSeq, sizeof(rtl_uString *), nAlloc );
184 if (pSeq != 0)
186 rtl_uString ** pElements = (rtl_uString **) pSeq->elements;
187 for ( sal_Int32 nPos = nStartIndex; nPos < nStopIndex; ++nPos )
189 pElements[nPos] = 0;
190 rtl_uString_new( &pElements[nPos] );
193 break;
195 case typelib_TypeClass_TYPE:
197 if (nAlloc >= 0)
199 pSeq = reallocSeq(
200 pSeq, sizeof(typelib_TypeDescriptionReference *), nAlloc );
202 if (pSeq != 0)
204 typelib_TypeDescriptionReference ** pElements =
205 (typelib_TypeDescriptionReference **) pSeq->elements;
206 for ( sal_Int32 nPos = nStartIndex; nPos < nStopIndex; ++nPos )
208 pElements[nPos] = _getVoidType();
211 break;
213 case typelib_TypeClass_ANY:
215 if (nAlloc >= 0)
216 pSeq = reallocSeq( pSeq, sizeof(uno_Any), nAlloc );
217 if (pSeq != 0)
219 uno_Any * pElements = (uno_Any *) pSeq->elements;
220 for ( sal_Int32 nPos = nStartIndex; nPos < nStopIndex; ++nPos )
222 CONSTRUCT_EMPTY_ANY( &pElements[nPos] );
225 break;
227 case typelib_TypeClass_ENUM:
229 if (nAlloc >= 0)
230 pSeq = reallocSeq( pSeq, sizeof(sal_Int32), nAlloc );
231 if (pSeq != 0)
233 typelib_TypeDescription * pElementTypeDescr = 0;
234 TYPELIB_DANGER_GET( &pElementTypeDescr, pElementType );
235 sal_Int32 eEnum =
236 ((typelib_EnumTypeDescription *)
237 pElementTypeDescr)->nDefaultEnumValue;
238 TYPELIB_DANGER_RELEASE( pElementTypeDescr );
240 sal_Int32 * pElements = (sal_Int32 *) pSeq->elements;
241 for ( sal_Int32 nPos = nStartIndex; nPos < nStopIndex; ++nPos )
243 pElements[nPos] = eEnum;
246 break;
248 case typelib_TypeClass_STRUCT:
249 case typelib_TypeClass_EXCEPTION:
251 typelib_TypeDescription * pElementTypeDescr = 0;
252 TYPELIB_DANGER_GET( &pElementTypeDescr, pElementType );
253 sal_Int32 nElementSize = pElementTypeDescr->nSize;
255 if (nAlloc >= 0)
256 pSeq = reallocSeq( pSeq, nElementSize, nAlloc );
257 if (pSeq != 0)
259 char * pElements = pSeq->elements;
260 for ( sal_Int32 nPos = nStartIndex; nPos < nStopIndex; ++nPos )
262 _defaultConstructStruct(
263 pElements + (nElementSize * nPos),
264 (typelib_CompoundTypeDescription *)pElementTypeDescr );
268 TYPELIB_DANGER_RELEASE( pElementTypeDescr );
269 break;
271 case typelib_TypeClass_ARRAY:
273 typelib_TypeDescription * pElementTypeDescr = 0;
274 TYPELIB_DANGER_GET( &pElementTypeDescr, pElementType );
275 sal_Int32 nElementSize = pElementTypeDescr->nSize;
277 if (nAlloc >= 0)
278 pSeq = reallocSeq( pSeq, nElementSize, nAlloc );
279 if (pSeq != 0)
281 char * pElements = pSeq->elements;
282 for ( sal_Int32 nPos = nStartIndex; nPos < nStopIndex; ++nPos )
284 _defaultConstructArray(
285 pElements + (nElementSize * nPos),
286 (typelib_ArrayTypeDescription *)pElementTypeDescr );
290 TYPELIB_DANGER_RELEASE( pElementTypeDescr );
291 break;
293 case typelib_TypeClass_UNION:
295 typelib_TypeDescription * pElementTypeDescr = 0;
296 TYPELIB_DANGER_GET( &pElementTypeDescr, pElementType );
297 sal_Int32 nElementSize = pElementTypeDescr->nSize;
299 if (nAlloc >= 0)
300 pSeq = reallocSeq( pSeq, nElementSize, nAlloc );
301 if (pSeq != 0)
303 sal_Int32 nValueOffset =
304 ((typelib_UnionTypeDescription *)
305 pElementTypeDescr)->nValueOffset;
306 sal_Int64 nDefaultDiscr =
307 ((typelib_UnionTypeDescription *)
308 pElementTypeDescr)->nDefaultDiscriminant;
310 typelib_TypeDescription * pDefaultTypeDescr = 0;
311 TYPELIB_DANGER_GET(
312 &pDefaultTypeDescr,
313 ((typelib_UnionTypeDescription *)
314 pElementTypeDescr)->pDefaultTypeRef );
316 char * pElements = pSeq->elements;
317 for ( sal_Int32 nPos = nStartIndex; nPos < nStopIndex; ++nPos )
319 char * pMem = pElements + (nElementSize * nPos);
320 ::uno_constructData(
321 (char *)pMem + nValueOffset, pDefaultTypeDescr );
322 *(sal_Int64 *)pMem = nDefaultDiscr;
324 TYPELIB_DANGER_RELEASE( pDefaultTypeDescr );
327 TYPELIB_DANGER_RELEASE( pElementTypeDescr );
328 break;
330 case typelib_TypeClass_SEQUENCE:
332 if (nAlloc >= 0)
333 pSeq = reallocSeq( pSeq, sizeof(uno_Sequence *), nAlloc );
334 if (pSeq != 0)
336 uno_Sequence ** pElements =
337 (uno_Sequence **) pSeq->elements;
338 for ( sal_Int32 nPos = nStartIndex; nPos < nStopIndex; ++nPos )
340 pElements[nPos] = createEmptySequence();
343 break;
345 case typelib_TypeClass_INTERFACE: // either C++ or C-UNO interface
346 if (nAlloc >= 0)
347 pSeq = reallocSeq( pSeq, sizeof(void *), nAlloc );
348 if (pSeq != 0)
350 ::rtl_zeroMemory(
351 pSeq->elements + (sizeof(void *) * nStartIndex),
352 sizeof(void *) * (nStopIndex - nStartIndex) );
354 break;
355 default:
356 OSL_ENSURE( 0, "### unexpected element type!" );
357 pSeq = 0;
358 break;
361 if (pSeq == 0)
363 OSL_ASSERT( nAlloc >= 0 ); // must have been an allocation failure
364 return false;
366 else
368 *ppSeq = pSeq;
369 return true;
373 //------------------------------------------------------------------------------
374 static inline bool icopyConstructFromElements(
375 uno_Sequence ** ppSeq, void * pSourceElements,
376 typelib_TypeDescriptionReference * pElementType,
377 sal_Int32 nStartIndex, sal_Int32 nStopIndex,
378 uno_AcquireFunc acquire,
379 sal_Int32 nAlloc = -1 ) // >= 0 means (re)alloc memory for nAlloc elements
381 uno_Sequence * pSeq = *ppSeq;
382 switch (pElementType->eTypeClass)
384 case typelib_TypeClass_CHAR:
385 if (nAlloc >= 0)
386 pSeq = reallocSeq( pSeq, sizeof(sal_Unicode), nAlloc );
387 if (pSeq != 0)
389 ::rtl_copyMemory(
390 pSeq->elements + (sizeof(sal_Unicode) * nStartIndex),
391 (char *)pSourceElements + (sizeof(sal_Unicode) * nStartIndex),
392 sizeof(sal_Unicode) * (nStopIndex - nStartIndex) );
394 break;
395 case typelib_TypeClass_BOOLEAN:
396 if (nAlloc >= 0)
397 pSeq = reallocSeq( pSeq, sizeof(sal_Bool), nAlloc );
398 if (pSeq != 0)
400 ::rtl_copyMemory(
401 pSeq->elements + (sizeof(sal_Bool) * nStartIndex),
402 (char *)pSourceElements + (sizeof(sal_Bool) * nStartIndex),
403 sizeof(sal_Bool) * (nStopIndex - nStartIndex) );
405 break;
406 case typelib_TypeClass_BYTE:
407 if (nAlloc >= 0)
408 pSeq = reallocSeq( pSeq, sizeof(sal_Int8), nAlloc );
409 if (pSeq != 0)
411 ::rtl_copyMemory(
412 pSeq->elements + (sizeof(sal_Int8) * nStartIndex),
413 (char *)pSourceElements + (sizeof(sal_Int8) * nStartIndex),
414 sizeof(sal_Int8) * (nStopIndex - nStartIndex) );
416 break;
417 case typelib_TypeClass_SHORT:
418 case typelib_TypeClass_UNSIGNED_SHORT:
419 if (nAlloc >= 0)
420 pSeq = reallocSeq( pSeq, sizeof(sal_Int16), nAlloc );
421 if (pSeq != 0)
423 ::rtl_copyMemory(
424 pSeq->elements + (sizeof(sal_Int16) * nStartIndex),
425 (char *)pSourceElements + (sizeof(sal_Int16) * nStartIndex),
426 sizeof(sal_Int16) * (nStopIndex - nStartIndex) );
428 break;
429 case typelib_TypeClass_LONG:
430 case typelib_TypeClass_UNSIGNED_LONG:
431 if (nAlloc >= 0)
432 pSeq = reallocSeq( pSeq, sizeof(sal_Int32), nAlloc );
433 if (pSeq != 0)
435 ::rtl_copyMemory(
436 pSeq->elements + (sizeof(sal_Int32) * nStartIndex),
437 (char *)pSourceElements + (sizeof(sal_Int32) * nStartIndex),
438 sizeof(sal_Int32) * (nStopIndex - nStartIndex) );
440 break;
441 case typelib_TypeClass_HYPER:
442 case typelib_TypeClass_UNSIGNED_HYPER:
443 if (nAlloc >= 0)
444 pSeq = reallocSeq( pSeq, sizeof(sal_Int64), nAlloc );
445 if (pSeq != 0)
447 ::rtl_copyMemory(
448 pSeq->elements + (sizeof(sal_Int64) * nStartIndex),
449 (char *)pSourceElements + (sizeof(sal_Int64) * nStartIndex),
450 sizeof(sal_Int64) * (nStopIndex - nStartIndex) );
452 break;
453 case typelib_TypeClass_FLOAT:
454 if (nAlloc >= 0)
455 pSeq = reallocSeq( pSeq, sizeof(float), nAlloc );
456 if (pSeq != 0)
458 ::rtl_copyMemory(
459 pSeq->elements + (sizeof(float) * nStartIndex),
460 (char *)pSourceElements + (sizeof(float) * nStartIndex),
461 sizeof(float) * (nStopIndex - nStartIndex) );
463 break;
464 case typelib_TypeClass_DOUBLE:
465 if (nAlloc >= 0)
466 pSeq = reallocSeq( pSeq, sizeof(double), nAlloc );
467 if (pSeq != 0)
469 ::rtl_copyMemory(
470 pSeq->elements + (sizeof(double) * nStartIndex),
471 (char *)pSourceElements + (sizeof(double) * nStartIndex),
472 sizeof(double) * (nStopIndex - nStartIndex) );
474 break;
475 case typelib_TypeClass_ENUM:
476 if (nAlloc >= 0)
477 pSeq = reallocSeq( pSeq, sizeof(sal_Int32), nAlloc );
478 if (pSeq != 0)
480 ::rtl_copyMemory(
481 pSeq->elements + (sizeof(sal_Int32) * nStartIndex),
482 (char *)pSourceElements + (sizeof(sal_Int32) * nStartIndex),
483 sizeof(sal_Int32) * (nStopIndex - nStartIndex) );
485 break;
486 case typelib_TypeClass_STRING:
488 if (nAlloc >= 0)
489 pSeq = reallocSeq( pSeq, sizeof(rtl_uString *), nAlloc );
490 if (pSeq != 0)
492 rtl_uString ** pDestElements = (rtl_uString **) pSeq->elements;
493 for ( sal_Int32 nPos = nStartIndex; nPos < nStopIndex; ++nPos )
495 ::rtl_uString_acquire(
496 ((rtl_uString **)pSourceElements)[nPos] );
497 pDestElements[nPos] = ((rtl_uString **)pSourceElements)[nPos];
500 break;
502 case typelib_TypeClass_TYPE:
504 if (nAlloc >= 0)
506 pSeq = reallocSeq(
507 pSeq, sizeof(typelib_TypeDescriptionReference *), nAlloc );
509 if (pSeq != 0)
511 typelib_TypeDescriptionReference ** pDestElements =
512 (typelib_TypeDescriptionReference **) pSeq->elements;
513 for ( sal_Int32 nPos = nStartIndex; nPos < nStopIndex; ++nPos )
515 TYPE_ACQUIRE(
516 ((typelib_TypeDescriptionReference **)
517 pSourceElements)[nPos] );
518 pDestElements[nPos] =
519 ((typelib_TypeDescriptionReference **)
520 pSourceElements)[nPos];
523 break;
525 case typelib_TypeClass_ANY:
527 if (nAlloc >= 0)
528 pSeq = reallocSeq( pSeq, sizeof(uno_Any), nAlloc );
529 if (pSeq != 0)
531 uno_Any * pDestElements = (uno_Any *) pSeq->elements;
532 for ( sal_Int32 nPos = nStartIndex; nPos < nStopIndex; ++nPos )
534 uno_Any * pSource = (uno_Any *)pSourceElements + nPos;
535 _copyConstructAny(
536 &pDestElements[nPos],
537 pSource->pData,
538 pSource->pType, 0,
539 acquire, 0 );
542 break;
544 case typelib_TypeClass_STRUCT:
545 case typelib_TypeClass_EXCEPTION:
547 typelib_TypeDescription * pElementTypeDescr = 0;
548 TYPELIB_DANGER_GET( &pElementTypeDescr, pElementType );
549 sal_Int32 nElementSize = pElementTypeDescr->nSize;
551 if (nAlloc >= 0)
552 pSeq = reallocSeq( pSeq, nElementSize, nAlloc );
553 if (pSeq != 0)
555 char * pDestElements = pSeq->elements;
557 typelib_CompoundTypeDescription * pTypeDescr =
558 (typelib_CompoundTypeDescription *)pElementTypeDescr;
559 for ( sal_Int32 nPos = nStartIndex; nPos < nStopIndex; ++nPos )
561 char * pDest =
562 pDestElements + (nElementSize * nPos);
563 char * pSource =
564 (char *)pSourceElements + (nElementSize * nPos);
566 if (pTypeDescr->pBaseTypeDescription)
568 // copy base value
569 _copyConstructStruct(
570 pDest, pSource,
571 pTypeDescr->pBaseTypeDescription, acquire, 0 );
574 // then copy members
575 typelib_TypeDescriptionReference ** ppTypeRefs =
576 pTypeDescr->ppTypeRefs;
577 sal_Int32 * pMemberOffsets = pTypeDescr->pMemberOffsets;
578 sal_Int32 nDescr = pTypeDescr->nMembers;
580 while (nDescr--)
582 ::uno_type_copyData(
583 pDest + pMemberOffsets[nDescr],
584 pSource + pMemberOffsets[nDescr],
585 ppTypeRefs[nDescr], acquire );
590 TYPELIB_DANGER_RELEASE( pElementTypeDescr );
591 break;
593 case typelib_TypeClass_UNION:
595 typelib_TypeDescription * pElementTypeDescr = 0;
596 TYPELIB_DANGER_GET( &pElementTypeDescr, pElementType );
597 sal_Int32 nElementSize = pElementTypeDescr->nSize;
599 if (nAlloc >= 0)
600 pSeq = reallocSeq( pSeq, nElementSize, nAlloc );
601 if (pSeq != 0)
603 char * pDestElements = pSeq->elements;
605 sal_Int32 nValueOffset =
606 ((typelib_UnionTypeDescription *)
607 pElementTypeDescr)->nValueOffset;
608 for ( sal_Int32 nPos = nStartIndex; nPos < nStopIndex; ++nPos )
610 char * pDest =
611 pDestElements + (nElementSize * nPos);
612 char * pSource =
613 (char *)pSourceElements + (nElementSize * nPos);
615 typelib_TypeDescriptionReference * pSetType = _unionGetSetType(
616 pSource, pElementTypeDescr );
617 ::uno_type_copyData(
618 pDest + nValueOffset,
619 pSource + nValueOffset,
620 pSetType, acquire );
621 *(sal_Int64 *)pDest = *(sal_Int64 *)pSource;
622 typelib_typedescriptionreference_release( pSetType );
626 TYPELIB_DANGER_RELEASE( pElementTypeDescr );
627 break;
629 case typelib_TypeClass_SEQUENCE: // sequence of sequence
631 if (nAlloc >= 0)
632 pSeq = reallocSeq( pSeq, sizeof(uno_Sequence *), nAlloc );
633 if (pSeq != 0)
635 typelib_TypeDescription * pElementTypeDescr = 0;
636 TYPELIB_DANGER_GET( &pElementTypeDescr, pElementType );
637 typelib_TypeDescriptionReference * pSeqElementType =
638 ((typelib_IndirectTypeDescription *) pElementTypeDescr)->pType;
639 uno_Sequence ** pDestElements = (uno_Sequence **) pSeq->elements;
640 for ( sal_Int32 nPos = nStartIndex; nPos < nStopIndex; ++nPos )
642 uno_Sequence * pNew = icopyConstructSequence(
643 ((uno_Sequence **) pSourceElements)[nPos],
644 pSeqElementType, acquire, 0 );
645 OSL_ASSERT( pNew != 0 );
646 // ought never be a memory allocation problem,
647 // because of reference counted sequence handles
648 pDestElements[ nPos ] = pNew;
650 TYPELIB_DANGER_RELEASE( pElementTypeDescr );
652 break;
654 case typelib_TypeClass_INTERFACE:
656 if (nAlloc >= 0)
657 pSeq = reallocSeq( pSeq, sizeof(void *), nAlloc );
658 if (pSeq != 0)
660 void ** pDestElements = (void **) pSeq->elements;
661 for ( sal_Int32 nPos = nStartIndex; nPos < nStopIndex; ++nPos )
663 _acquire( pDestElements[nPos] =
664 ((void **)pSourceElements)[nPos], acquire );
667 break;
669 default:
670 OSL_ENSURE( 0, "### unexpected element type!" );
671 pSeq = 0;
672 break;
675 if (pSeq == 0)
677 OSL_ASSERT( nAlloc >= 0 ); // must have been an allocation failure
678 return false;
680 else
682 *ppSeq = pSeq;
683 return true;
687 //------------------------------------------------------------------------------
688 static inline bool ireallocSequence(
689 uno_Sequence ** ppSequence,
690 typelib_TypeDescriptionReference * pElementType,
691 sal_Int32 nSize,
692 uno_AcquireFunc acquire, uno_ReleaseFunc release )
694 bool ret = true;
695 uno_Sequence * pSeq = *ppSequence;
696 sal_Int32 nElements = pSeq->nElements;
698 if (pSeq->nRefCount > 1 ||
699 // not mem-copyable elements?
700 typelib_TypeClass_ANY == pElementType->eTypeClass ||
701 typelib_TypeClass_STRUCT == pElementType->eTypeClass ||
702 typelib_TypeClass_EXCEPTION == pElementType->eTypeClass)
704 // split sequence and construct new one from scratch
705 uno_Sequence * pNew = 0;
707 sal_Int32 nRest = nSize - nElements;
708 sal_Int32 nCopy = (nRest > 0 ? nElements : nSize);
710 if (nCopy >= 0)
712 ret = icopyConstructFromElements(
713 &pNew, pSeq->elements, pElementType,
714 0, nCopy, acquire,
715 nSize ); // alloc to nSize
717 if (ret && nRest > 0)
719 ret = idefaultConstructElements(
720 &pNew, pElementType,
721 nCopy, nSize,
722 nCopy >= 0 ? -1 /* no mem allocation */ : nSize );
725 if (ret)
727 // destruct sequence
728 if (osl_decrementInterlockedCount( &pSeq->nRefCount ) == 0)
730 if (nElements > 0)
732 idestructElements(
733 pSeq->elements, pElementType,
734 0, nElements, release );
736 rtl_freeMemory( pSeq );
738 *ppSequence = pNew;
741 else
743 OSL_ASSERT( pSeq->nRefCount == 1 );
744 if (nSize > nElements) // default construct the rest
746 ret = idefaultConstructElements(
747 ppSequence, pElementType,
748 nElements, nSize,
749 nSize ); // realloc to nSize
751 else // or destruct the rest and realloc mem
753 sal_Int32 nElementSize = idestructElements(
754 pSeq->elements, pElementType,
755 nSize, nElements, release );
756 // warning: it is assumed that the following will never fail,
757 // else this leads to a sequence null handle
758 *ppSequence = reallocSeq( pSeq, nElementSize, nSize );
759 OSL_ASSERT( *ppSequence != 0 );
760 ret = (*ppSequence != 0);
764 return ret;
769 extern "C"
772 //##############################################################################
773 sal_Bool SAL_CALL uno_type_sequence_construct(
774 uno_Sequence ** ppSequence, typelib_TypeDescriptionReference * pType,
775 void * pElements, sal_Int32 len,
776 uno_AcquireFunc acquire )
777 SAL_THROW_EXTERN_C()
779 bool ret;
780 if (len)
782 typelib_TypeDescription * pTypeDescr = 0;
783 TYPELIB_DANGER_GET( &pTypeDescr, pType );
785 typelib_TypeDescriptionReference * pElementType =
786 ((typelib_IndirectTypeDescription *)pTypeDescr)->pType;
788 *ppSequence = 0;
789 if (pElements == 0)
791 ret = idefaultConstructElements(
792 ppSequence, pElementType,
793 0, len,
794 len ); // alloc to len
796 else
798 ret = icopyConstructFromElements(
799 ppSequence, pElements, pElementType,
800 0, len, acquire,
801 len ); // alloc to len
804 TYPELIB_DANGER_RELEASE( pTypeDescr );
806 else
808 *ppSequence = createEmptySequence();
809 ret = true;
812 OSL_ASSERT( (*ppSequence != 0) == ret );
813 return ret;
816 //##############################################################################
817 sal_Bool SAL_CALL uno_sequence_construct(
818 uno_Sequence ** ppSequence, typelib_TypeDescription * pTypeDescr,
819 void * pElements, sal_Int32 len,
820 uno_AcquireFunc acquire )
821 SAL_THROW_EXTERN_C()
823 bool ret;
824 if (len > 0)
826 typelib_TypeDescriptionReference * pElementType =
827 ((typelib_IndirectTypeDescription *)pTypeDescr)->pType;
829 *ppSequence = 0;
830 if (pElements == 0)
832 ret = idefaultConstructElements(
833 ppSequence, pElementType,
834 0, len,
835 len ); // alloc to len
837 else
839 ret = icopyConstructFromElements(
840 ppSequence, pElements, pElementType,
841 0, len, acquire,
842 len ); // alloc to len
845 else
847 *ppSequence = createEmptySequence();
848 ret = true;
851 OSL_ASSERT( (*ppSequence != 0) == ret );
852 return ret;
855 //##############################################################################
856 sal_Bool SAL_CALL uno_type_sequence_realloc(
857 uno_Sequence ** ppSequence, typelib_TypeDescriptionReference * pType,
858 sal_Int32 nSize, uno_AcquireFunc acquire, uno_ReleaseFunc release )
859 SAL_THROW_EXTERN_C()
861 OSL_ENSURE( ppSequence, "### null ptr!" );
862 OSL_ENSURE( nSize >= 0, "### new size must be at least 0!" );
864 bool ret = true;
865 if (nSize != (*ppSequence)->nElements)
867 typelib_TypeDescription * pTypeDescr = 0;
868 TYPELIB_DANGER_GET( &pTypeDescr, pType );
869 ret = ireallocSequence(
870 ppSequence, ((typelib_IndirectTypeDescription *)pTypeDescr)->pType,
871 nSize, acquire, release );
872 TYPELIB_DANGER_RELEASE( pTypeDescr );
874 return ret;
877 //##############################################################################
878 sal_Bool SAL_CALL uno_sequence_realloc(
879 uno_Sequence ** ppSequence, typelib_TypeDescription * pTypeDescr,
880 sal_Int32 nSize, uno_AcquireFunc acquire, uno_ReleaseFunc release )
881 SAL_THROW_EXTERN_C()
883 OSL_ENSURE( ppSequence, "### null ptr!" );
884 OSL_ENSURE( nSize >= 0, "### new size must be at least 0!" );
886 bool ret = true;
887 if (nSize != (*ppSequence)->nElements)
889 ret = ireallocSequence(
890 ppSequence, ((typelib_IndirectTypeDescription *)pTypeDescr)->pType,
891 nSize, acquire, release );
893 return ret;
896 //##############################################################################
897 sal_Bool SAL_CALL uno_type_sequence_reference2One(
898 uno_Sequence ** ppSequence,
899 typelib_TypeDescriptionReference * pType,
900 uno_AcquireFunc acquire, uno_ReleaseFunc release )
901 SAL_THROW_EXTERN_C()
903 OSL_ENSURE( ppSequence, "### null ptr!" );
904 bool ret = true;
905 uno_Sequence * pSequence = *ppSequence;
906 if (pSequence->nRefCount > 1)
908 uno_Sequence * pNew = 0;
909 if (pSequence->nElements > 0)
911 typelib_TypeDescription * pTypeDescr = 0;
912 TYPELIB_DANGER_GET( &pTypeDescr, pType );
914 ret = icopyConstructFromElements(
915 &pNew, pSequence->elements,
916 ((typelib_IndirectTypeDescription *)pTypeDescr)->pType,
917 0, pSequence->nElements, acquire,
918 pSequence->nElements ); // alloc nElements
919 if (ret)
921 idestructSequence( *ppSequence, pType, pTypeDescr, release );
922 *ppSequence = pNew;
925 TYPELIB_DANGER_RELEASE( pTypeDescr );
927 else
929 pNew = allocSeq( 0, 0 );
930 ret = (pNew != 0);
931 if (ret)
933 // easy destruction of empty sequence:
934 if (osl_decrementInterlockedCount( &pSequence->nRefCount ) == 0)
935 rtl_freeMemory( pSequence );
936 *ppSequence = pNew;
940 return ret;
943 //##############################################################################
944 sal_Bool SAL_CALL uno_sequence_reference2One(
945 uno_Sequence ** ppSequence,
946 typelib_TypeDescription * pTypeDescr,
947 uno_AcquireFunc acquire, uno_ReleaseFunc release )
948 SAL_THROW_EXTERN_C()
950 OSL_ENSURE( ppSequence, "### null ptr!" );
951 bool ret = true;
952 uno_Sequence * pSequence = *ppSequence;
953 if (pSequence->nRefCount > 1)
955 uno_Sequence * pNew = 0;
956 if (pSequence->nElements > 0)
958 ret = icopyConstructFromElements(
959 &pNew, pSequence->elements,
960 ((typelib_IndirectTypeDescription *)pTypeDescr)->pType,
961 0, pSequence->nElements, acquire,
962 pSequence->nElements ); // alloc nElements
963 if (ret)
965 idestructSequence(
966 pSequence, pTypeDescr->pWeakRef, pTypeDescr, release );
967 *ppSequence = pNew;
970 else
972 pNew = allocSeq( 0, 0 );
973 ret = (pNew != 0);
974 if (ret)
976 // easy destruction of empty sequence:
977 if (osl_decrementInterlockedCount( &pSequence->nRefCount ) == 0)
978 rtl_freeMemory( pSequence );
979 *ppSequence = pNew;
984 return ret;
987 //##############################################################################
988 void SAL_CALL uno_sequence_assign(
989 uno_Sequence ** ppDest,
990 uno_Sequence * pSource,
991 typelib_TypeDescription * pTypeDescr,
992 uno_ReleaseFunc release )
993 SAL_THROW_EXTERN_C()
995 if (*ppDest != pSource)
997 ::osl_incrementInterlockedCount( &pSource->nRefCount );
998 idestructSequence( *ppDest, pTypeDescr->pWeakRef, pTypeDescr, release );
999 *ppDest = pSource;
1003 //##############################################################################
1004 void SAL_CALL uno_type_sequence_assign(
1005 uno_Sequence ** ppDest,
1006 uno_Sequence * pSource,
1007 typelib_TypeDescriptionReference * pType,
1008 uno_ReleaseFunc release )
1009 SAL_THROW_EXTERN_C()
1011 if (*ppDest != pSource)
1013 ::osl_incrementInterlockedCount( &pSource->nRefCount );
1014 idestructSequence( *ppDest, pType, 0, release );
1015 *ppDest = pSource;