xref: /aoo42x/main/cppu/source/uno/sequence.cxx (revision cdf0e10c)
1 /*************************************************************************
2  *
3  * DO NOT ALTER OR REMOVE COPYRIGHT NOTICES OR THIS FILE HEADER.
4  *
5  * Copyright 2000, 2010 Oracle and/or its affiliates.
6  *
7  * OpenOffice.org - a multi-platform office productivity suite
8  *
9  * This file is part of OpenOffice.org.
10  *
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.
14  *
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).
20  *
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.
25  *
26  ************************************************************************/
27 
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>
38 
39 #include "constr.hxx"
40 #include "copy.hxx"
41 #include "destr.hxx"
42 
43 
44 using namespace cppu;
45 
46 namespace cppu
47 {
48 
49 //------------------------------------------------------------------------------
50 static inline uno_Sequence * reallocSeq(
51 	uno_Sequence * pReallocate, sal_Size nElementSize, sal_Int32 nElements )
52 {
53     OSL_ASSERT( nElements >= 0 );
54     uno_Sequence * pNew = 0;
55     sal_uInt32 nSize = calcSeqMemSize( nElementSize, nElements );
56     if (nSize > 0)
57     {
58         if (pReallocate == 0)
59         {
60             pNew = (uno_Sequence *) rtl_allocateMemory( nSize );
61         }
62         else
63         {
64             pNew = (uno_Sequence *) rtl_reallocateMemory( pReallocate, nSize );
65         }
66         if (pNew != 0)
67         {
68             // header init
69             pNew->nRefCount = 1;
70             pNew->nElements = nElements;
71         }
72     }
73     return pNew;
74 }
75 
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
82 {
83     uno_Sequence * pSeq = *ppSeq;
84 	switch (pElementType->eTypeClass)
85 	{
86 	case typelib_TypeClass_CHAR:
87 		if (nAlloc >= 0)
88             pSeq = reallocSeq( pSeq, sizeof(sal_Unicode), nAlloc );
89         if (pSeq != 0)
90         {
91             ::rtl_zeroMemory(
92                 pSeq->elements + (sizeof(sal_Unicode) * nStartIndex),
93                 sizeof(sal_Unicode) * (nStopIndex - nStartIndex) );
94         }
95 		break;
96 	case typelib_TypeClass_BOOLEAN:
97 		if (nAlloc >= 0)
98             pSeq = reallocSeq( pSeq, sizeof(sal_Bool), nAlloc );
99         if (pSeq != 0)
100         {
101             ::rtl_zeroMemory(
102                 pSeq->elements + (sizeof(sal_Bool) * nStartIndex),
103                 sizeof(sal_Bool) * (nStopIndex - nStartIndex) );
104         }
105 		break;
106 	case typelib_TypeClass_BYTE:
107 		if (nAlloc >= 0)
108             pSeq = reallocSeq( pSeq, sizeof(sal_Int8), nAlloc );
109         if (pSeq != 0)
110         {
111             ::rtl_zeroMemory(
112                 pSeq->elements + (sizeof(sal_Int8) * nStartIndex),
113                 sizeof(sal_Int8) * (nStopIndex - nStartIndex) );
114         }
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)
121         {
122             ::rtl_zeroMemory(
123                 pSeq->elements + (sizeof(sal_Int16) * nStartIndex),
124                 sizeof(sal_Int16) * (nStopIndex - nStartIndex) );
125         }
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)
132         {
133             ::rtl_zeroMemory(
134                 pSeq->elements + (sizeof(sal_Int32) * nStartIndex),
135                 sizeof(sal_Int32) * (nStopIndex - nStartIndex) );
136         }
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)
143         {
144             ::rtl_zeroMemory(
145                 pSeq->elements + (sizeof(sal_Int64) * nStartIndex),
146                 sizeof(sal_Int64) * (nStopIndex - nStartIndex) );
147         }
148 		break;
149 	case typelib_TypeClass_FLOAT:
150 	{
151 		if (nAlloc >= 0)
152             pSeq = reallocSeq( pSeq, sizeof(float), nAlloc );
153         if (pSeq != 0)
154         {
155             float * pElements = (float *) pSeq->elements;
156             for ( sal_Int32 nPos = nStartIndex; nPos < nStopIndex; ++nPos )
157             {
158                 pElements[nPos] = 0.0;
159             }
160         }
161 		break;
162 	}
163 	case typelib_TypeClass_DOUBLE:
164 	{
165 		if (nAlloc >= 0)
166             pSeq = reallocSeq( pSeq, sizeof(double), nAlloc );
167         if (pSeq != 0)
168         {
169             double * pElements = (double *) pSeq->elements;
170             for ( sal_Int32 nPos = nStartIndex; nPos < nStopIndex; ++nPos )
171             {
172                 pElements[nPos] = 0.0;
173             }
174         }
175 		break;
176 	}
177 	case typelib_TypeClass_STRING:
178 	{
179 		if (nAlloc >= 0)
180             pSeq = reallocSeq( pSeq, sizeof(rtl_uString *), nAlloc );
181         if (pSeq != 0)
182         {
183             rtl_uString ** pElements = (rtl_uString **) pSeq->elements;
184             for ( sal_Int32 nPos = nStartIndex; nPos < nStopIndex; ++nPos )
185             {
186                 pElements[nPos] = 0;
187                 rtl_uString_new( &pElements[nPos] );
188             }
189         }
190 		break;
191 	}
192 	case typelib_TypeClass_TYPE:
193 	{
194 		if (nAlloc >= 0)
195         {
196             pSeq = reallocSeq(
197                 pSeq, sizeof(typelib_TypeDescriptionReference *), nAlloc );
198         }
199         if (pSeq != 0)
200         {
201             typelib_TypeDescriptionReference ** pElements =
202                 (typelib_TypeDescriptionReference **) pSeq->elements;
203             for ( sal_Int32 nPos = nStartIndex; nPos < nStopIndex; ++nPos )
204             {
205                 pElements[nPos] = _getVoidType();
206             }
207         }
208 		break;
209 	}
210 	case typelib_TypeClass_ANY:
211 	{
212 		if (nAlloc >= 0)
213             pSeq = reallocSeq( pSeq, sizeof(uno_Any), nAlloc );
214         if (pSeq != 0)
215         {
216             uno_Any * pElements = (uno_Any *) pSeq->elements;
217             for ( sal_Int32 nPos = nStartIndex; nPos < nStopIndex; ++nPos )
218             {
219                 CONSTRUCT_EMPTY_ANY( &pElements[nPos] );
220             }
221         }
222 		break;
223 	}
224 	case typelib_TypeClass_ENUM:
225 	{
226 		if (nAlloc >= 0)
227             pSeq = reallocSeq( pSeq, sizeof(sal_Int32), nAlloc );
228         if (pSeq != 0)
229         {
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 );
236 
237             sal_Int32 * pElements = (sal_Int32 *) pSeq->elements;
238             for ( sal_Int32 nPos = nStartIndex; nPos < nStopIndex; ++nPos )
239             {
240                 pElements[nPos] = eEnum;
241             }
242         }
243 		break;
244 	}
245 	case typelib_TypeClass_STRUCT:
246 	case typelib_TypeClass_EXCEPTION:
247 	{
248 		typelib_TypeDescription * pElementTypeDescr = 0;
249 		TYPELIB_DANGER_GET( &pElementTypeDescr, pElementType );
250 		sal_Int32 nElementSize = pElementTypeDescr->nSize;
251 
252 		if (nAlloc >= 0)
253             pSeq = reallocSeq( pSeq, nElementSize, nAlloc );
254         if (pSeq != 0)
255         {
256             char * pElements = pSeq->elements;
257             for ( sal_Int32 nPos = nStartIndex; nPos < nStopIndex; ++nPos )
258             {
259                 _defaultConstructStruct(
260                     pElements + (nElementSize * nPos),
261                     (typelib_CompoundTypeDescription *)pElementTypeDescr );
262             }
263         }
264 
265 		TYPELIB_DANGER_RELEASE( pElementTypeDescr );
266 		break;
267 	}
268 	case typelib_TypeClass_ARRAY:
269 	{
270 		typelib_TypeDescription * pElementTypeDescr = 0;
271 		TYPELIB_DANGER_GET( &pElementTypeDescr, pElementType );
272 		sal_Int32 nElementSize = pElementTypeDescr->nSize;
273 
274 		if (nAlloc >= 0)
275             pSeq = reallocSeq( pSeq, nElementSize, nAlloc );
276         if (pSeq != 0)
277         {
278             char * pElements = pSeq->elements;
279             for ( sal_Int32 nPos = nStartIndex; nPos < nStopIndex; ++nPos )
280             {
281                 _defaultConstructArray(
282                     pElements + (nElementSize * nPos),
283                     (typelib_ArrayTypeDescription *)pElementTypeDescr );
284             }
285         }
286 
287 		TYPELIB_DANGER_RELEASE( pElementTypeDescr );
288 		break;
289 	}
290 	case typelib_TypeClass_UNION:
291 	{
292 		typelib_TypeDescription * pElementTypeDescr = 0;
293 		TYPELIB_DANGER_GET( &pElementTypeDescr, pElementType );
294 		sal_Int32 nElementSize = pElementTypeDescr->nSize;
295 
296 		if (nAlloc >= 0)
297             pSeq = reallocSeq( pSeq, nElementSize, nAlloc );
298         if (pSeq != 0)
299         {
300             sal_Int32 nValueOffset =
301                 ((typelib_UnionTypeDescription *)
302                  pElementTypeDescr)->nValueOffset;
303             sal_Int64 nDefaultDiscr =
304                 ((typelib_UnionTypeDescription *)
305                  pElementTypeDescr)->nDefaultDiscriminant;
306 
307             typelib_TypeDescription * pDefaultTypeDescr = 0;
308             TYPELIB_DANGER_GET(
309                 &pDefaultTypeDescr,
310                 ((typelib_UnionTypeDescription *)
311                  pElementTypeDescr)->pDefaultTypeRef );
312 
313             char * pElements = pSeq->elements;
314             for ( sal_Int32 nPos = nStartIndex; nPos < nStopIndex; ++nPos )
315             {
316                 char * pMem = pElements + (nElementSize * nPos);
317                 ::uno_constructData(
318                     (char *)pMem + nValueOffset, pDefaultTypeDescr );
319                 *(sal_Int64 *)pMem = nDefaultDiscr;
320             }
321             TYPELIB_DANGER_RELEASE( pDefaultTypeDescr );
322         }
323 
324         TYPELIB_DANGER_RELEASE( pElementTypeDescr );
325 		break;
326 	}
327 	case typelib_TypeClass_SEQUENCE:
328 	{
329 		if (nAlloc >= 0)
330             pSeq = reallocSeq( pSeq, sizeof(uno_Sequence *), nAlloc );
331         if (pSeq != 0)
332         {
333             uno_Sequence ** pElements =
334                 (uno_Sequence **) pSeq->elements;
335             for ( sal_Int32 nPos = nStartIndex; nPos < nStopIndex; ++nPos )
336             {
337                 pElements[nPos] = createEmptySequence();
338             }
339         }
340 		break;
341 	}
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)
346         {
347             ::rtl_zeroMemory(
348                 pSeq->elements + (sizeof(void *) * nStartIndex),
349                 sizeof(void *) * (nStopIndex - nStartIndex) );
350         }
351 		break;
352     default:
353 		OSL_ENSURE( 0, "### unexpected element type!" );
354         pSeq = 0;
355 		break;
356 	}
357 
358     if (pSeq == 0)
359     {
360         OSL_ASSERT( nAlloc >= 0 ); // must have been an allocation failure
361         return false;
362     }
363     else
364     {
365         *ppSeq = pSeq;
366         return true;
367     }
368 }
369 
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
377 {
378     uno_Sequence * pSeq = *ppSeq;
379 	switch (pElementType->eTypeClass)
380 	{
381 	case typelib_TypeClass_CHAR:
382 		if (nAlloc >= 0)
383             pSeq = reallocSeq( pSeq, sizeof(sal_Unicode), nAlloc );
384         if (pSeq != 0)
385         {
386             ::rtl_copyMemory(
387                 pSeq->elements + (sizeof(sal_Unicode) * nStartIndex),
388                 (char *)pSourceElements + (sizeof(sal_Unicode) * nStartIndex),
389                 sizeof(sal_Unicode) * (nStopIndex - nStartIndex) );
390         }
391 		break;
392 	case typelib_TypeClass_BOOLEAN:
393 		if (nAlloc >= 0)
394             pSeq = reallocSeq( pSeq, sizeof(sal_Bool), nAlloc );
395         if (pSeq != 0)
396         {
397             ::rtl_copyMemory(
398                 pSeq->elements + (sizeof(sal_Bool) * nStartIndex),
399                 (char *)pSourceElements + (sizeof(sal_Bool) * nStartIndex),
400                 sizeof(sal_Bool) * (nStopIndex - nStartIndex) );
401         }
402 		break;
403 	case typelib_TypeClass_BYTE:
404 		if (nAlloc >= 0)
405             pSeq = reallocSeq( pSeq, sizeof(sal_Int8), nAlloc );
406         if (pSeq != 0)
407         {
408             ::rtl_copyMemory(
409                 pSeq->elements + (sizeof(sal_Int8) * nStartIndex),
410                 (char *)pSourceElements + (sizeof(sal_Int8) * nStartIndex),
411                 sizeof(sal_Int8) * (nStopIndex - nStartIndex) );
412         }
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)
419         {
420             ::rtl_copyMemory(
421                 pSeq->elements + (sizeof(sal_Int16) * nStartIndex),
422                 (char *)pSourceElements + (sizeof(sal_Int16) * nStartIndex),
423                 sizeof(sal_Int16) * (nStopIndex - nStartIndex) );
424         }
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)
431         {
432             ::rtl_copyMemory(
433                 pSeq->elements + (sizeof(sal_Int32) * nStartIndex),
434                 (char *)pSourceElements + (sizeof(sal_Int32) * nStartIndex),
435                 sizeof(sal_Int32) * (nStopIndex - nStartIndex) );
436         }
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)
443         {
444             ::rtl_copyMemory(
445                 pSeq->elements + (sizeof(sal_Int64) * nStartIndex),
446                 (char *)pSourceElements + (sizeof(sal_Int64) * nStartIndex),
447                 sizeof(sal_Int64) * (nStopIndex - nStartIndex) );
448         }
449 		break;
450 	case typelib_TypeClass_FLOAT:
451 		if (nAlloc >= 0)
452             pSeq = reallocSeq( pSeq, sizeof(float), nAlloc );
453         if (pSeq != 0)
454         {
455             ::rtl_copyMemory(
456                 pSeq->elements + (sizeof(float) * nStartIndex),
457                 (char *)pSourceElements + (sizeof(float) * nStartIndex),
458                 sizeof(float) * (nStopIndex - nStartIndex) );
459         }
460 		break;
461 	case typelib_TypeClass_DOUBLE:
462 		if (nAlloc >= 0)
463             pSeq = reallocSeq( pSeq, sizeof(double), nAlloc );
464         if (pSeq != 0)
465         {
466             ::rtl_copyMemory(
467                 pSeq->elements + (sizeof(double) * nStartIndex),
468                 (char *)pSourceElements + (sizeof(double) * nStartIndex),
469                 sizeof(double) * (nStopIndex - nStartIndex) );
470         }
471 		break;
472 	case typelib_TypeClass_ENUM:
473 		if (nAlloc >= 0)
474             pSeq = reallocSeq( pSeq, sizeof(sal_Int32), nAlloc );
475         if (pSeq != 0)
476         {
477             ::rtl_copyMemory(
478                 pSeq->elements + (sizeof(sal_Int32) * nStartIndex),
479                 (char *)pSourceElements + (sizeof(sal_Int32) * nStartIndex),
480                 sizeof(sal_Int32) * (nStopIndex - nStartIndex) );
481         }
482 		break;
483 	case typelib_TypeClass_STRING:
484 	{
485 		if (nAlloc >= 0)
486             pSeq = reallocSeq( pSeq, sizeof(rtl_uString *), nAlloc );
487         if (pSeq != 0)
488         {
489             rtl_uString ** pDestElements = (rtl_uString **) pSeq->elements;
490             for ( sal_Int32 nPos = nStartIndex; nPos < nStopIndex; ++nPos )
491             {
492                 ::rtl_uString_acquire(
493                     ((rtl_uString **)pSourceElements)[nPos] );
494                 pDestElements[nPos] = ((rtl_uString **)pSourceElements)[nPos];
495             }
496         }
497 		break;
498 	}
499 	case typelib_TypeClass_TYPE:
500 	{
501 		if (nAlloc >= 0)
502         {
503             pSeq = reallocSeq(
504                 pSeq, sizeof(typelib_TypeDescriptionReference *), nAlloc );
505         }
506         if (pSeq != 0)
507         {
508             typelib_TypeDescriptionReference ** pDestElements =
509                 (typelib_TypeDescriptionReference **) pSeq->elements;
510             for ( sal_Int32 nPos = nStartIndex; nPos < nStopIndex; ++nPos )
511             {
512                 TYPE_ACQUIRE(
513                     ((typelib_TypeDescriptionReference **)
514                      pSourceElements)[nPos] );
515                 pDestElements[nPos] =
516                     ((typelib_TypeDescriptionReference **)
517                      pSourceElements)[nPos];
518             }
519 		}
520 		break;
521 	}
522 	case typelib_TypeClass_ANY:
523 	{
524 		if (nAlloc >= 0)
525             pSeq = reallocSeq( pSeq, sizeof(uno_Any), nAlloc );
526         if (pSeq != 0)
527         {
528             uno_Any * pDestElements = (uno_Any *) pSeq->elements;
529             for ( sal_Int32 nPos = nStartIndex; nPos < nStopIndex; ++nPos )
530             {
531                 uno_Any * pSource = (uno_Any *)pSourceElements + nPos;
532                 _copyConstructAny(
533                     &pDestElements[nPos],
534                     pSource->pData,
535                     pSource->pType, 0,
536                     acquire, 0 );
537             }
538         }
539 		break;
540 	}
541 	case typelib_TypeClass_STRUCT:
542 	case typelib_TypeClass_EXCEPTION:
543 	{
544 		typelib_TypeDescription * pElementTypeDescr = 0;
545 		TYPELIB_DANGER_GET( &pElementTypeDescr, pElementType );
546 		sal_Int32 nElementSize = pElementTypeDescr->nSize;
547 
548 		if (nAlloc >= 0)
549             pSeq = reallocSeq( pSeq, nElementSize, nAlloc );
550         if (pSeq != 0)
551         {
552             char * pDestElements = pSeq->elements;
553 
554             typelib_CompoundTypeDescription * pTypeDescr =
555                 (typelib_CompoundTypeDescription *)pElementTypeDescr;
556             for ( sal_Int32 nPos = nStartIndex; nPos < nStopIndex; ++nPos )
557             {
558                 char * pDest =
559                     pDestElements + (nElementSize * nPos);
560                 char * pSource =
561                     (char *)pSourceElements + (nElementSize * nPos);
562 
563                 if (pTypeDescr->pBaseTypeDescription)
564                 {
565                     // copy base value
566                     _copyConstructStruct(
567                         pDest, pSource,
568                         pTypeDescr->pBaseTypeDescription, acquire, 0 );
569                 }
570 
571                 // then copy members
572                 typelib_TypeDescriptionReference ** ppTypeRefs =
573                     pTypeDescr->ppTypeRefs;
574                 sal_Int32 * pMemberOffsets = pTypeDescr->pMemberOffsets;
575                 sal_Int32 nDescr = pTypeDescr->nMembers;
576 
577                 while (nDescr--)
578                 {
579                     ::uno_type_copyData(
580                         pDest + pMemberOffsets[nDescr],
581                         pSource + pMemberOffsets[nDescr],
582                         ppTypeRefs[nDescr], acquire );
583                 }
584             }
585 		}
586 
587 		TYPELIB_DANGER_RELEASE( pElementTypeDescr );
588 		break;
589 	}
590 	case typelib_TypeClass_UNION:
591 	{
592 		typelib_TypeDescription * pElementTypeDescr = 0;
593 		TYPELIB_DANGER_GET( &pElementTypeDescr, pElementType );
594 		sal_Int32 nElementSize = pElementTypeDescr->nSize;
595 
596 		if (nAlloc >= 0)
597             pSeq = reallocSeq( pSeq, nElementSize, nAlloc );
598         if (pSeq != 0)
599         {
600             char * pDestElements = pSeq->elements;
601 
602             sal_Int32 nValueOffset =
603                 ((typelib_UnionTypeDescription *)
604                  pElementTypeDescr)->nValueOffset;
605             for ( sal_Int32 nPos = nStartIndex; nPos < nStopIndex; ++nPos )
606             {
607                 char * pDest =
608                     pDestElements + (nElementSize * nPos);
609                 char * pSource =
610                     (char *)pSourceElements + (nElementSize * nPos);
611 
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 );
620             }
621         }
622 
623 		TYPELIB_DANGER_RELEASE( pElementTypeDescr );
624 		break;
625 	}
626 	case typelib_TypeClass_SEQUENCE: // sequence of sequence
627 	{
628 		if (nAlloc >= 0)
629             pSeq = reallocSeq( pSeq, sizeof(uno_Sequence *), nAlloc );
630         if (pSeq != 0)
631         {
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 )
638             {
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;
646             }
647             TYPELIB_DANGER_RELEASE( pElementTypeDescr );
648         }
649 		break;
650 	}
651 	case typelib_TypeClass_INTERFACE:
652 	{
653 		if (nAlloc >= 0)
654             pSeq = reallocSeq( pSeq, sizeof(void *), nAlloc );
655         if (pSeq != 0)
656         {
657             void ** pDestElements = (void **) pSeq->elements;
658             for ( sal_Int32 nPos = nStartIndex; nPos < nStopIndex; ++nPos )
659             {
660                 _acquire( pDestElements[nPos] =
661                           ((void **)pSourceElements)[nPos], acquire );
662             }
663         }
664 		break;
665 	}
666     default:
667 		OSL_ENSURE( 0, "### unexpected element type!" );
668         pSeq = 0;
669 		break;
670 	}
671 
672     if (pSeq == 0)
673     {
674         OSL_ASSERT( nAlloc >= 0 ); // must have been an allocation failure
675         return false;
676     }
677     else
678     {
679         *ppSeq = pSeq;
680         return true;
681     }
682 }
683 
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 )
690 {
691     bool ret = true;
692 	uno_Sequence * pSeq = *ppSequence;
693 	sal_Int32 nElements = pSeq->nElements;
694 
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)
700 	{
701         // split sequence and construct new one from scratch
702 		uno_Sequence * pNew = 0;
703 
704 		sal_Int32 nRest = nSize - nElements;
705 		sal_Int32 nCopy = (nRest > 0 ? nElements : nSize);
706 
707 		if (nCopy >= 0)
708 		{
709 			ret = icopyConstructFromElements(
710 				&pNew, pSeq->elements, pElementType,
711 				0, nCopy, acquire,
712 				nSize ); // alloc to nSize
713 		}
714 		if (ret && nRest > 0)
715 		{
716 			ret = idefaultConstructElements(
717 				&pNew, pElementType,
718 				nCopy, nSize,
719 				nCopy >= 0 ? -1 /* no mem allocation */ : nSize );
720 		}
721 
722         if (ret)
723         {
724             // destruct sequence
725             if (osl_decrementInterlockedCount( &pSeq->nRefCount ) == 0)
726             {
727                 if (nElements > 0)
728                 {
729                     idestructElements(
730                         pSeq->elements, pElementType,
731                         0, nElements, release );
732                 }
733                 rtl_freeMemory( pSeq );
734             }
735             *ppSequence = pNew;
736         }
737 	}
738 	else
739 	{
740         OSL_ASSERT( pSeq->nRefCount == 1 );
741         if (nSize > nElements) // default construct the rest
742         {
743             ret = idefaultConstructElements(
744                 ppSequence, pElementType,
745                 nElements, nSize,
746                 nSize ); // realloc to nSize
747         }
748         else // or destruct the rest and realloc mem
749         {
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);
758         }
759 	}
760 
761     return ret;
762 }
763 
764 }
765 
766 extern "C"
767 {
768 
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()
775 {
776     bool ret;
777 	if (len)
778 	{
779 		typelib_TypeDescription * pTypeDescr = 0;
780 		TYPELIB_DANGER_GET( &pTypeDescr, pType );
781 
782 		typelib_TypeDescriptionReference * pElementType =
783 			((typelib_IndirectTypeDescription *)pTypeDescr)->pType;
784 
785         *ppSequence = 0;
786 		if (pElements == 0)
787 		{
788 			ret = idefaultConstructElements(
789 				ppSequence, pElementType,
790 				0, len,
791 				len ); // alloc to len
792 		}
793 		else
794 		{
795 			ret = icopyConstructFromElements(
796 				ppSequence, pElements, pElementType,
797 				0, len, acquire,
798 				len ); // alloc to len
799 		}
800 
801 		TYPELIB_DANGER_RELEASE( pTypeDescr );
802 	}
803 	else
804 	{
805 		*ppSequence = createEmptySequence();
806         ret = true;
807 	}
808 
809     OSL_ASSERT( (*ppSequence != 0) == ret );
810     return ret;
811 }
812 
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()
819 {
820     bool ret;
821 	if (len > 0)
822 	{
823 		typelib_TypeDescriptionReference * pElementType =
824 			((typelib_IndirectTypeDescription *)pTypeDescr)->pType;
825 
826         *ppSequence = 0;
827 		if (pElements == 0)
828 		{
829 			ret = idefaultConstructElements(
830 				ppSequence, pElementType,
831 				0, len,
832 				len ); // alloc to len
833 		}
834 		else
835 		{
836 			ret = icopyConstructFromElements(
837 				ppSequence, pElements, pElementType,
838 				0, len, acquire,
839 				len ); // alloc to len
840 		}
841 	}
842 	else
843 	{
844 		*ppSequence = createEmptySequence();
845         ret = true;
846 	}
847 
848     OSL_ASSERT( (*ppSequence != 0) == ret );
849     return ret;
850 }
851 
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()
857 {
858 	OSL_ENSURE( ppSequence, "### null ptr!" );
859 	OSL_ENSURE( nSize >= 0, "### new size must be at least 0!" );
860 
861     bool ret = true;
862 	if (nSize != (*ppSequence)->nElements)
863 	{
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 );
870 	}
871     return ret;
872 }
873 
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()
879 {
880 	OSL_ENSURE( ppSequence, "### null ptr!" );
881 	OSL_ENSURE( nSize >= 0, "### new size must be at least 0!" );
882 
883     bool ret = true;
884 	if (nSize != (*ppSequence)->nElements)
885 	{
886 		ret = ireallocSequence(
887 			ppSequence, ((typelib_IndirectTypeDescription *)pTypeDescr)->pType,
888 			nSize, acquire, release );
889 	}
890     return ret;
891 }
892 
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()
899 {
900 	OSL_ENSURE( ppSequence, "### null ptr!" );
901     bool ret = true;
902 	uno_Sequence * pSequence = *ppSequence;
903 	if (pSequence->nRefCount > 1)
904 	{
905         uno_Sequence * pNew = 0;
906 		if (pSequence->nElements > 0)
907 		{
908 			typelib_TypeDescription * pTypeDescr = 0;
909 			TYPELIB_DANGER_GET( &pTypeDescr, pType );
910 
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)
917             {
918                 idestructSequence( *ppSequence, pType, pTypeDescr, release );
919                 *ppSequence = pNew;
920             }
921 
922 			TYPELIB_DANGER_RELEASE( pTypeDescr );
923 		}
924 		else
925 		{
926 			pNew = allocSeq( 0, 0 );
927             ret = (pNew != 0);
928             if (ret)
929             {
930                 // easy destruction of empty sequence:
931                 if (osl_decrementInterlockedCount( &pSequence->nRefCount ) == 0)
932                     rtl_freeMemory( pSequence );
933                 *ppSequence = pNew;
934             }
935 		}
936 	}
937     return ret;
938 }
939 
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()
946 {
947 	OSL_ENSURE( ppSequence, "### null ptr!" );
948     bool ret = true;
949 	uno_Sequence * pSequence = *ppSequence;
950 	if (pSequence->nRefCount > 1)
951 	{
952         uno_Sequence * pNew = 0;
953 		if (pSequence->nElements > 0)
954 		{
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)
961             {
962                 idestructSequence(
963                     pSequence, pTypeDescr->pWeakRef, pTypeDescr, release );
964                 *ppSequence = pNew;
965             }
966         }
967         else
968         {
969 			pNew = allocSeq( 0, 0 );
970             ret = (pNew != 0);
971             if (ret)
972             {
973                 // easy destruction of empty sequence:
974                 if (osl_decrementInterlockedCount( &pSequence->nRefCount ) == 0)
975                     rtl_freeMemory( pSequence );
976                 *ppSequence = pNew;
977             }
978         }
979 
980 	}
981     return ret;
982 }
983 
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()
991 {
992 	if (*ppDest != pSource)
993 	{
994 		::osl_incrementInterlockedCount( &pSource->nRefCount );
995 		idestructSequence( *ppDest, pTypeDescr->pWeakRef, pTypeDescr, release );
996 		*ppDest = pSource;
997 	}
998 }
999 
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()
1007 {
1008 	if (*ppDest != pSource)
1009 	{
1010 		::osl_incrementInterlockedCount( &pSource->nRefCount );
1011 		idestructSequence( *ppDest, pType, 0, release );
1012 		*ppDest = pSource;
1013 	}
1014 }
1015 
1016 }
1017