xref: /AOO41X/main/cppu/source/uno/sequence.cxx (revision 129fa3d1fc5edc85a690d91de1660cefa4e8a95b)
1 /**************************************************************
2  *
3  * Licensed to the Apache Software Foundation (ASF) under one
4  * or more contributor license agreements.  See the NOTICE file
5  * distributed with this work for additional information
6  * regarding copyright ownership.  The ASF licenses this file
7  * to you under the Apache License, Version 2.0 (the
8  * "License"); you may not use this file except in compliance
9  * with the License.  You may obtain a copy of the License at
10  *
11  *   http://www.apache.org/licenses/LICENSE-2.0
12  *
13  * Unless required by applicable law or agreed to in writing,
14  * software distributed under the License is distributed on an
15  * "AS IS" BASIS, WITHOUT WARRANTIES OR CONDITIONS OF ANY
16  * KIND, either express or implied.  See the License for the
17  * specific language governing permissions and limitations
18  * under the License.
19  *
20  *************************************************************/
21 
22 
23 
24 // MARKER(update_precomp.py): autogen include statement, do not remove
25 #include "precompiled_cppu.hxx"
26 #include <rtl/memory.h>
27 #include <rtl/alloc.h>
28 #include <osl/diagnose.h>
29 #include <osl/interlck.h>
30 #include <typelib/typedescription.h>
31 #include <uno/data.h>
32 #include <uno/dispatcher.h>
33 #include <uno/sequence2.h>
34 
35 #include "constr.hxx"
36 #include "copy.hxx"
37 #include "destr.hxx"
38 
39 
40 using namespace cppu;
41 
42 namespace cppu
43 {
44 
45 //------------------------------------------------------------------------------
reallocSeq(uno_Sequence * pReallocate,sal_Size nElementSize,sal_Int32 nElements)46 static inline uno_Sequence * reallocSeq(
47     uno_Sequence * pReallocate, sal_Size nElementSize, sal_Int32 nElements )
48 {
49     OSL_ASSERT( nElements >= 0 );
50     uno_Sequence * pNew = 0;
51     sal_uInt32 nSize = calcSeqMemSize( nElementSize, nElements );
52     if (nSize > 0)
53     {
54         if (pReallocate == 0)
55         {
56             pNew = (uno_Sequence *) rtl_allocateMemory( nSize );
57         }
58         else
59         {
60             pNew = (uno_Sequence *) rtl_reallocateMemory( pReallocate, nSize );
61         }
62         if (pNew != 0)
63         {
64             // header init
65             pNew->nRefCount = 1;
66             pNew->nElements = nElements;
67         }
68     }
69     return pNew;
70 }
71 
72 //------------------------------------------------------------------------------
idefaultConstructElements(uno_Sequence ** ppSeq,typelib_TypeDescriptionReference * pElementType,sal_Int32 nStartIndex,sal_Int32 nStopIndex,sal_Int32 nAlloc=-1)73 static inline bool idefaultConstructElements(
74     uno_Sequence ** ppSeq,
75     typelib_TypeDescriptionReference * pElementType,
76     sal_Int32 nStartIndex, sal_Int32 nStopIndex,
77     sal_Int32 nAlloc = -1 ) // >= 0 means (re)alloc memory for nAlloc elements
78 {
79     uno_Sequence * pSeq = *ppSeq;
80     switch (pElementType->eTypeClass)
81     {
82     case typelib_TypeClass_CHAR:
83         if (nAlloc >= 0)
84             pSeq = reallocSeq( pSeq, sizeof(sal_Unicode), nAlloc );
85         if (pSeq != 0)
86         {
87             ::rtl_zeroMemory(
88                 pSeq->elements + (sizeof(sal_Unicode) * nStartIndex),
89                 sizeof(sal_Unicode) * (nStopIndex - nStartIndex) );
90         }
91         break;
92     case typelib_TypeClass_BOOLEAN:
93         if (nAlloc >= 0)
94             pSeq = reallocSeq( pSeq, sizeof(sal_Bool), nAlloc );
95         if (pSeq != 0)
96         {
97             ::rtl_zeroMemory(
98                 pSeq->elements + (sizeof(sal_Bool) * nStartIndex),
99                 sizeof(sal_Bool) * (nStopIndex - nStartIndex) );
100         }
101         break;
102     case typelib_TypeClass_BYTE:
103         if (nAlloc >= 0)
104             pSeq = reallocSeq( pSeq, sizeof(sal_Int8), nAlloc );
105         if (pSeq != 0)
106         {
107             ::rtl_zeroMemory(
108                 pSeq->elements + (sizeof(sal_Int8) * nStartIndex),
109                 sizeof(sal_Int8) * (nStopIndex - nStartIndex) );
110         }
111         break;
112     case typelib_TypeClass_SHORT:
113     case typelib_TypeClass_UNSIGNED_SHORT:
114         if (nAlloc >= 0)
115             pSeq = reallocSeq( pSeq, sizeof(sal_Int16), nAlloc );
116         if (pSeq != 0)
117         {
118             ::rtl_zeroMemory(
119                 pSeq->elements + (sizeof(sal_Int16) * nStartIndex),
120                 sizeof(sal_Int16) * (nStopIndex - nStartIndex) );
121         }
122         break;
123     case typelib_TypeClass_LONG:
124     case typelib_TypeClass_UNSIGNED_LONG:
125         if (nAlloc >= 0)
126             pSeq = reallocSeq( pSeq, sizeof(sal_Int32), nAlloc );
127         if (pSeq != 0)
128         {
129             ::rtl_zeroMemory(
130                 pSeq->elements + (sizeof(sal_Int32) * nStartIndex),
131                 sizeof(sal_Int32) * (nStopIndex - nStartIndex) );
132         }
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)
139         {
140             ::rtl_zeroMemory(
141                 pSeq->elements + (sizeof(sal_Int64) * nStartIndex),
142                 sizeof(sal_Int64) * (nStopIndex - nStartIndex) );
143         }
144         break;
145     case typelib_TypeClass_FLOAT:
146     {
147         if (nAlloc >= 0)
148             pSeq = reallocSeq( pSeq, sizeof(float), nAlloc );
149         if (pSeq != 0)
150         {
151             float * pElements = (float *) pSeq->elements;
152             for ( sal_Int32 nPos = nStartIndex; nPos < nStopIndex; ++nPos )
153             {
154                 pElements[nPos] = 0.0;
155             }
156         }
157         break;
158     }
159     case typelib_TypeClass_DOUBLE:
160     {
161         if (nAlloc >= 0)
162             pSeq = reallocSeq( pSeq, sizeof(double), nAlloc );
163         if (pSeq != 0)
164         {
165             double * pElements = (double *) pSeq->elements;
166             for ( sal_Int32 nPos = nStartIndex; nPos < nStopIndex; ++nPos )
167             {
168                 pElements[nPos] = 0.0;
169             }
170         }
171         break;
172     }
173     case typelib_TypeClass_STRING:
174     {
175         if (nAlloc >= 0)
176             pSeq = reallocSeq( pSeq, sizeof(rtl_uString *), nAlloc );
177         if (pSeq != 0)
178         {
179             rtl_uString ** pElements = (rtl_uString **) pSeq->elements;
180             for ( sal_Int32 nPos = nStartIndex; nPos < nStopIndex; ++nPos )
181             {
182                 pElements[nPos] = 0;
183                 rtl_uString_new( &pElements[nPos] );
184             }
185         }
186         break;
187     }
188     case typelib_TypeClass_TYPE:
189     {
190         if (nAlloc >= 0)
191         {
192             pSeq = reallocSeq(
193                 pSeq, sizeof(typelib_TypeDescriptionReference *), nAlloc );
194         }
195         if (pSeq != 0)
196         {
197             typelib_TypeDescriptionReference ** pElements =
198                 (typelib_TypeDescriptionReference **) pSeq->elements;
199             for ( sal_Int32 nPos = nStartIndex; nPos < nStopIndex; ++nPos )
200             {
201                 pElements[nPos] = _getVoidType();
202             }
203         }
204         break;
205     }
206     case typelib_TypeClass_ANY:
207     {
208         if (nAlloc >= 0)
209             pSeq = reallocSeq( pSeq, sizeof(uno_Any), nAlloc );
210         if (pSeq != 0)
211         {
212             uno_Any * pElements = (uno_Any *) pSeq->elements;
213             for ( sal_Int32 nPos = nStartIndex; nPos < nStopIndex; ++nPos )
214             {
215                 CONSTRUCT_EMPTY_ANY( &pElements[nPos] );
216             }
217         }
218         break;
219     }
220     case typelib_TypeClass_ENUM:
221     {
222         if (nAlloc >= 0)
223             pSeq = reallocSeq( pSeq, sizeof(sal_Int32), nAlloc );
224         if (pSeq != 0)
225         {
226             typelib_TypeDescription * pElementTypeDescr = 0;
227             TYPELIB_DANGER_GET( &pElementTypeDescr, pElementType );
228             sal_Int32 eEnum =
229                 ((typelib_EnumTypeDescription *)
230                  pElementTypeDescr)->nDefaultEnumValue;
231             TYPELIB_DANGER_RELEASE( pElementTypeDescr );
232 
233             sal_Int32 * pElements = (sal_Int32 *) pSeq->elements;
234             for ( sal_Int32 nPos = nStartIndex; nPos < nStopIndex; ++nPos )
235             {
236                 pElements[nPos] = eEnum;
237             }
238         }
239         break;
240     }
241     case typelib_TypeClass_STRUCT:
242     case typelib_TypeClass_EXCEPTION:
243     {
244         typelib_TypeDescription * pElementTypeDescr = 0;
245         TYPELIB_DANGER_GET( &pElementTypeDescr, pElementType );
246         sal_Int32 nElementSize = pElementTypeDescr->nSize;
247 
248         if (nAlloc >= 0)
249             pSeq = reallocSeq( pSeq, nElementSize, nAlloc );
250         if (pSeq != 0)
251         {
252             char * pElements = pSeq->elements;
253             for ( sal_Int32 nPos = nStartIndex; nPos < nStopIndex; ++nPos )
254             {
255                 _defaultConstructStruct(
256                     pElements + (nElementSize * nPos),
257                     (typelib_CompoundTypeDescription *)pElementTypeDescr );
258             }
259         }
260 
261         TYPELIB_DANGER_RELEASE( pElementTypeDescr );
262         break;
263     }
264     case typelib_TypeClass_ARRAY:
265     {
266         typelib_TypeDescription * pElementTypeDescr = 0;
267         TYPELIB_DANGER_GET( &pElementTypeDescr, pElementType );
268         sal_Int32 nElementSize = pElementTypeDescr->nSize;
269 
270         if (nAlloc >= 0)
271             pSeq = reallocSeq( pSeq, nElementSize, nAlloc );
272         if (pSeq != 0)
273         {
274             char * pElements = pSeq->elements;
275             for ( sal_Int32 nPos = nStartIndex; nPos < nStopIndex; ++nPos )
276             {
277                 _defaultConstructArray(
278                     pElements + (nElementSize * nPos),
279                     (typelib_ArrayTypeDescription *)pElementTypeDescr );
280             }
281         }
282 
283         TYPELIB_DANGER_RELEASE( pElementTypeDescr );
284         break;
285     }
286     case typelib_TypeClass_UNION:
287     {
288         typelib_TypeDescription * pElementTypeDescr = 0;
289         TYPELIB_DANGER_GET( &pElementTypeDescr, pElementType );
290         sal_Int32 nElementSize = pElementTypeDescr->nSize;
291 
292         if (nAlloc >= 0)
293             pSeq = reallocSeq( pSeq, nElementSize, nAlloc );
294         if (pSeq != 0)
295         {
296             sal_Int32 nValueOffset =
297                 ((typelib_UnionTypeDescription *)
298                  pElementTypeDescr)->nValueOffset;
299             sal_Int64 nDefaultDiscr =
300                 ((typelib_UnionTypeDescription *)
301                  pElementTypeDescr)->nDefaultDiscriminant;
302 
303             typelib_TypeDescription * pDefaultTypeDescr = 0;
304             TYPELIB_DANGER_GET(
305                 &pDefaultTypeDescr,
306                 ((typelib_UnionTypeDescription *)
307                  pElementTypeDescr)->pDefaultTypeRef );
308 
309             char * pElements = pSeq->elements;
310             for ( sal_Int32 nPos = nStartIndex; nPos < nStopIndex; ++nPos )
311             {
312                 char * pMem = pElements + (nElementSize * nPos);
313                 ::uno_constructData(
314                     (char *)pMem + nValueOffset, pDefaultTypeDescr );
315                 *(sal_Int64 *)pMem = nDefaultDiscr;
316             }
317             TYPELIB_DANGER_RELEASE( pDefaultTypeDescr );
318         }
319 
320         TYPELIB_DANGER_RELEASE( pElementTypeDescr );
321         break;
322     }
323     case typelib_TypeClass_SEQUENCE:
324     {
325         if (nAlloc >= 0)
326             pSeq = reallocSeq( pSeq, sizeof(uno_Sequence *), nAlloc );
327         if (pSeq != 0)
328         {
329             uno_Sequence ** pElements =
330                 (uno_Sequence **) pSeq->elements;
331             for ( sal_Int32 nPos = nStartIndex; nPos < nStopIndex; ++nPos )
332             {
333                 pElements[nPos] = createEmptySequence();
334             }
335         }
336         break;
337     }
338     case typelib_TypeClass_INTERFACE: // either C++ or C-UNO interface
339         if (nAlloc >= 0)
340             pSeq = reallocSeq( pSeq, sizeof(void *), nAlloc );
341         if (pSeq != 0)
342         {
343             ::rtl_zeroMemory(
344                 pSeq->elements + (sizeof(void *) * nStartIndex),
345                 sizeof(void *) * (nStopIndex - nStartIndex) );
346         }
347         break;
348     default:
349         OSL_ENSURE( 0, "### unexpected element type!" );
350         pSeq = 0;
351         break;
352     }
353 
354     if (pSeq == 0)
355     {
356         OSL_ASSERT( nAlloc >= 0 ); // must have been an allocation failure
357         return false;
358     }
359     else
360     {
361         *ppSeq = pSeq;
362         return true;
363     }
364 }
365 
366 //------------------------------------------------------------------------------
icopyConstructFromElements(uno_Sequence ** ppSeq,void * pSourceElements,typelib_TypeDescriptionReference * pElementType,sal_Int32 nStartIndex,sal_Int32 nStopIndex,uno_AcquireFunc acquire,sal_Int32 nAlloc=-1)367 static inline bool icopyConstructFromElements(
368     uno_Sequence ** ppSeq, void * pSourceElements,
369     typelib_TypeDescriptionReference * pElementType,
370     sal_Int32 nStartIndex, sal_Int32 nStopIndex,
371     uno_AcquireFunc acquire,
372     sal_Int32 nAlloc = -1 ) // >= 0 means (re)alloc memory for nAlloc elements
373 {
374     uno_Sequence * pSeq = *ppSeq;
375     switch (pElementType->eTypeClass)
376     {
377     case typelib_TypeClass_CHAR:
378         if (nAlloc >= 0)
379             pSeq = reallocSeq( pSeq, sizeof(sal_Unicode), nAlloc );
380         if (pSeq != 0)
381         {
382             ::rtl_copyMemory(
383                 pSeq->elements + (sizeof(sal_Unicode) * nStartIndex),
384                 (char *)pSourceElements + (sizeof(sal_Unicode) * nStartIndex),
385                 sizeof(sal_Unicode) * (nStopIndex - nStartIndex) );
386         }
387         break;
388     case typelib_TypeClass_BOOLEAN:
389         if (nAlloc >= 0)
390             pSeq = reallocSeq( pSeq, sizeof(sal_Bool), nAlloc );
391         if (pSeq != 0)
392         {
393             ::rtl_copyMemory(
394                 pSeq->elements + (sizeof(sal_Bool) * nStartIndex),
395                 (char *)pSourceElements + (sizeof(sal_Bool) * nStartIndex),
396                 sizeof(sal_Bool) * (nStopIndex - nStartIndex) );
397         }
398         break;
399     case typelib_TypeClass_BYTE:
400         if (nAlloc >= 0)
401             pSeq = reallocSeq( pSeq, sizeof(sal_Int8), nAlloc );
402         if (pSeq != 0)
403         {
404             ::rtl_copyMemory(
405                 pSeq->elements + (sizeof(sal_Int8) * nStartIndex),
406                 (char *)pSourceElements + (sizeof(sal_Int8) * nStartIndex),
407                 sizeof(sal_Int8) * (nStopIndex - nStartIndex) );
408         }
409         break;
410     case typelib_TypeClass_SHORT:
411     case typelib_TypeClass_UNSIGNED_SHORT:
412         if (nAlloc >= 0)
413             pSeq = reallocSeq( pSeq, sizeof(sal_Int16), nAlloc );
414         if (pSeq != 0)
415         {
416             ::rtl_copyMemory(
417                 pSeq->elements + (sizeof(sal_Int16) * nStartIndex),
418                 (char *)pSourceElements + (sizeof(sal_Int16) * nStartIndex),
419                 sizeof(sal_Int16) * (nStopIndex - nStartIndex) );
420         }
421         break;
422     case typelib_TypeClass_LONG:
423     case typelib_TypeClass_UNSIGNED_LONG:
424         if (nAlloc >= 0)
425             pSeq = reallocSeq( pSeq, sizeof(sal_Int32), nAlloc );
426         if (pSeq != 0)
427         {
428             ::rtl_copyMemory(
429                 pSeq->elements + (sizeof(sal_Int32) * nStartIndex),
430                 (char *)pSourceElements + (sizeof(sal_Int32) * nStartIndex),
431                 sizeof(sal_Int32) * (nStopIndex - nStartIndex) );
432         }
433         break;
434     case typelib_TypeClass_HYPER:
435     case typelib_TypeClass_UNSIGNED_HYPER:
436         if (nAlloc >= 0)
437             pSeq = reallocSeq( pSeq, sizeof(sal_Int64), nAlloc );
438         if (pSeq != 0)
439         {
440             ::rtl_copyMemory(
441                 pSeq->elements + (sizeof(sal_Int64) * nStartIndex),
442                 (char *)pSourceElements + (sizeof(sal_Int64) * nStartIndex),
443                 sizeof(sal_Int64) * (nStopIndex - nStartIndex) );
444         }
445         break;
446     case typelib_TypeClass_FLOAT:
447         if (nAlloc >= 0)
448             pSeq = reallocSeq( pSeq, sizeof(float), nAlloc );
449         if (pSeq != 0)
450         {
451             ::rtl_copyMemory(
452                 pSeq->elements + (sizeof(float) * nStartIndex),
453                 (char *)pSourceElements + (sizeof(float) * nStartIndex),
454                 sizeof(float) * (nStopIndex - nStartIndex) );
455         }
456         break;
457     case typelib_TypeClass_DOUBLE:
458         if (nAlloc >= 0)
459             pSeq = reallocSeq( pSeq, sizeof(double), nAlloc );
460         if (pSeq != 0)
461         {
462             ::rtl_copyMemory(
463                 pSeq->elements + (sizeof(double) * nStartIndex),
464                 (char *)pSourceElements + (sizeof(double) * nStartIndex),
465                 sizeof(double) * (nStopIndex - nStartIndex) );
466         }
467         break;
468     case typelib_TypeClass_ENUM:
469         if (nAlloc >= 0)
470             pSeq = reallocSeq( pSeq, sizeof(sal_Int32), nAlloc );
471         if (pSeq != 0)
472         {
473             ::rtl_copyMemory(
474                 pSeq->elements + (sizeof(sal_Int32) * nStartIndex),
475                 (char *)pSourceElements + (sizeof(sal_Int32) * nStartIndex),
476                 sizeof(sal_Int32) * (nStopIndex - nStartIndex) );
477         }
478         break;
479     case typelib_TypeClass_STRING:
480     {
481         if (nAlloc >= 0)
482             pSeq = reallocSeq( pSeq, sizeof(rtl_uString *), nAlloc );
483         if (pSeq != 0)
484         {
485             rtl_uString ** pDestElements = (rtl_uString **) pSeq->elements;
486             for ( sal_Int32 nPos = nStartIndex; nPos < nStopIndex; ++nPos )
487             {
488                 ::rtl_uString_acquire(
489                     ((rtl_uString **)pSourceElements)[nPos] );
490                 pDestElements[nPos] = ((rtl_uString **)pSourceElements)[nPos];
491             }
492         }
493         break;
494     }
495     case typelib_TypeClass_TYPE:
496     {
497         if (nAlloc >= 0)
498         {
499             pSeq = reallocSeq(
500                 pSeq, sizeof(typelib_TypeDescriptionReference *), nAlloc );
501         }
502         if (pSeq != 0)
503         {
504             typelib_TypeDescriptionReference ** pDestElements =
505                 (typelib_TypeDescriptionReference **) pSeq->elements;
506             for ( sal_Int32 nPos = nStartIndex; nPos < nStopIndex; ++nPos )
507             {
508                 TYPE_ACQUIRE(
509                     ((typelib_TypeDescriptionReference **)
510                      pSourceElements)[nPos] );
511                 pDestElements[nPos] =
512                     ((typelib_TypeDescriptionReference **)
513                      pSourceElements)[nPos];
514             }
515         }
516         break;
517     }
518     case typelib_TypeClass_ANY:
519     {
520         if (nAlloc >= 0)
521             pSeq = reallocSeq( pSeq, sizeof(uno_Any), nAlloc );
522         if (pSeq != 0)
523         {
524             uno_Any * pDestElements = (uno_Any *) pSeq->elements;
525             for ( sal_Int32 nPos = nStartIndex; nPos < nStopIndex; ++nPos )
526             {
527                 uno_Any * pSource = (uno_Any *)pSourceElements + nPos;
528                 _copyConstructAny(
529                     &pDestElements[nPos],
530                     pSource->pData,
531                     pSource->pType, 0,
532                     acquire, 0 );
533             }
534         }
535         break;
536     }
537     case typelib_TypeClass_STRUCT:
538     case typelib_TypeClass_EXCEPTION:
539     {
540         typelib_TypeDescription * pElementTypeDescr = 0;
541         TYPELIB_DANGER_GET( &pElementTypeDescr, pElementType );
542         sal_Int32 nElementSize = pElementTypeDescr->nSize;
543 
544         if (nAlloc >= 0)
545             pSeq = reallocSeq( pSeq, nElementSize, nAlloc );
546         if (pSeq != 0)
547         {
548             char * pDestElements = pSeq->elements;
549 
550             typelib_CompoundTypeDescription * pTypeDescr =
551                 (typelib_CompoundTypeDescription *)pElementTypeDescr;
552             for ( sal_Int32 nPos = nStartIndex; nPos < nStopIndex; ++nPos )
553             {
554                 char * pDest =
555                     pDestElements + (nElementSize * nPos);
556                 char * pSource =
557                     (char *)pSourceElements + (nElementSize * nPos);
558 
559                 if (pTypeDescr->pBaseTypeDescription)
560                 {
561                     // copy base value
562                     _copyConstructStruct(
563                         pDest, pSource,
564                         pTypeDescr->pBaseTypeDescription, acquire, 0 );
565                 }
566 
567                 // then copy members
568                 typelib_TypeDescriptionReference ** ppTypeRefs =
569                     pTypeDescr->ppTypeRefs;
570                 sal_Int32 * pMemberOffsets = pTypeDescr->pMemberOffsets;
571                 sal_Int32 nDescr = pTypeDescr->nMembers;
572 
573                 while (nDescr--)
574                 {
575                     ::uno_type_copyData(
576                         pDest + pMemberOffsets[nDescr],
577                         pSource + pMemberOffsets[nDescr],
578                         ppTypeRefs[nDescr], acquire );
579                 }
580             }
581         }
582 
583         TYPELIB_DANGER_RELEASE( pElementTypeDescr );
584         break;
585     }
586     case typelib_TypeClass_UNION:
587     {
588         typelib_TypeDescription * pElementTypeDescr = 0;
589         TYPELIB_DANGER_GET( &pElementTypeDescr, pElementType );
590         sal_Int32 nElementSize = pElementTypeDescr->nSize;
591 
592         if (nAlloc >= 0)
593             pSeq = reallocSeq( pSeq, nElementSize, nAlloc );
594         if (pSeq != 0)
595         {
596             char * pDestElements = pSeq->elements;
597 
598             sal_Int32 nValueOffset =
599                 ((typelib_UnionTypeDescription *)
600                  pElementTypeDescr)->nValueOffset;
601             for ( sal_Int32 nPos = nStartIndex; nPos < nStopIndex; ++nPos )
602             {
603                 char * pDest =
604                     pDestElements + (nElementSize * nPos);
605                 char * pSource =
606                     (char *)pSourceElements + (nElementSize * nPos);
607 
608                 typelib_TypeDescriptionReference * pSetType = _unionGetSetType(
609                     pSource, pElementTypeDescr );
610                 ::uno_type_copyData(
611                     pDest + nValueOffset,
612                     pSource + nValueOffset,
613                     pSetType, acquire );
614                 *(sal_Int64 *)pDest = *(sal_Int64 *)pSource;
615                 typelib_typedescriptionreference_release( pSetType );
616             }
617         }
618 
619         TYPELIB_DANGER_RELEASE( pElementTypeDescr );
620         break;
621     }
622     case typelib_TypeClass_SEQUENCE: // sequence of sequence
623     {
624         if (nAlloc >= 0)
625             pSeq = reallocSeq( pSeq, sizeof(uno_Sequence *), nAlloc );
626         if (pSeq != 0)
627         {
628             typelib_TypeDescription * pElementTypeDescr = 0;
629             TYPELIB_DANGER_GET( &pElementTypeDescr, pElementType );
630             typelib_TypeDescriptionReference * pSeqElementType =
631                 ((typelib_IndirectTypeDescription *) pElementTypeDescr)->pType;
632             uno_Sequence ** pDestElements = (uno_Sequence **) pSeq->elements;
633             for ( sal_Int32 nPos = nStartIndex; nPos < nStopIndex; ++nPos )
634             {
635                 uno_Sequence * pNew = icopyConstructSequence(
636                     ((uno_Sequence **) pSourceElements)[nPos],
637                     pSeqElementType, acquire, 0 );
638                 OSL_ASSERT( pNew != 0 );
639                 // ought never be a memory allocation problem,
640                 // because of reference counted sequence handles
641                 pDestElements[ nPos ] = pNew;
642             }
643             TYPELIB_DANGER_RELEASE( pElementTypeDescr );
644         }
645         break;
646     }
647     case typelib_TypeClass_INTERFACE:
648     {
649         if (nAlloc >= 0)
650             pSeq = reallocSeq( pSeq, sizeof(void *), nAlloc );
651         if (pSeq != 0)
652         {
653             void ** pDestElements = (void **) pSeq->elements;
654             for ( sal_Int32 nPos = nStartIndex; nPos < nStopIndex; ++nPos )
655             {
656                 _acquire( pDestElements[nPos] =
657                           ((void **)pSourceElements)[nPos], acquire );
658             }
659         }
660         break;
661     }
662     default:
663         OSL_ENSURE( 0, "### unexpected element type!" );
664         pSeq = 0;
665         break;
666     }
667 
668     if (pSeq == 0)
669     {
670         OSL_ASSERT( nAlloc >= 0 ); // must have been an allocation failure
671         return false;
672     }
673     else
674     {
675         *ppSeq = pSeq;
676         return true;
677     }
678 }
679 
680 //------------------------------------------------------------------------------
ireallocSequence(uno_Sequence ** ppSequence,typelib_TypeDescriptionReference * pElementType,sal_Int32 nSize,uno_AcquireFunc acquire,uno_ReleaseFunc release)681 static inline bool ireallocSequence(
682     uno_Sequence ** ppSequence,
683     typelib_TypeDescriptionReference * pElementType,
684     sal_Int32 nSize,
685     uno_AcquireFunc acquire, uno_ReleaseFunc release )
686 {
687     bool ret = true;
688     uno_Sequence * pSeq = *ppSequence;
689     sal_Int32 nElements = pSeq->nElements;
690 
691     if (pSeq->nRefCount > 1 ||
692         // not mem-copyable elements?
693         typelib_TypeClass_ANY == pElementType->eTypeClass ||
694         typelib_TypeClass_STRUCT == pElementType->eTypeClass ||
695         typelib_TypeClass_EXCEPTION == pElementType->eTypeClass)
696     {
697         // split sequence and construct new one from scratch
698         uno_Sequence * pNew = 0;
699 
700         sal_Int32 nRest = nSize - nElements;
701         sal_Int32 nCopy = (nRest > 0 ? nElements : nSize);
702 
703         if (nCopy >= 0)
704         {
705             ret = icopyConstructFromElements(
706                 &pNew, pSeq->elements, pElementType,
707                 0, nCopy, acquire,
708                 nSize ); // alloc to nSize
709         }
710         if (ret && nRest > 0)
711         {
712             ret = idefaultConstructElements(
713                 &pNew, pElementType,
714                 nCopy, nSize,
715                 nCopy >= 0 ? -1 /* no mem allocation */ : nSize );
716         }
717 
718         if (ret)
719         {
720             // destruct sequence
721             if (osl_decrementInterlockedCount( &pSeq->nRefCount ) == 0)
722             {
723                 if (nElements > 0)
724                 {
725                     idestructElements(
726                         pSeq->elements, pElementType,
727                         0, nElements, release );
728                 }
729                 rtl_freeMemory( pSeq );
730             }
731             *ppSequence = pNew;
732         }
733     }
734     else
735     {
736         OSL_ASSERT( pSeq->nRefCount == 1 );
737         if (nSize > nElements) // default construct the rest
738         {
739             ret = idefaultConstructElements(
740                 ppSequence, pElementType,
741                 nElements, nSize,
742                 nSize ); // realloc to nSize
743         }
744         else // or destruct the rest and realloc mem
745         {
746             sal_Int32 nElementSize = idestructElements(
747                 pSeq->elements, pElementType,
748                 nSize, nElements, release );
749             // warning: it is assumed that the following will never fail,
750             //          else this leads to a sequence null handle
751             *ppSequence = reallocSeq( pSeq, nElementSize, nSize );
752             OSL_ASSERT( *ppSequence != 0 );
753             ret = (*ppSequence != 0);
754         }
755     }
756 
757     return ret;
758 }
759 
760 }
761 
762 extern "C"
763 {
764 
765 //##############################################################################
uno_type_sequence_construct(uno_Sequence ** ppSequence,typelib_TypeDescriptionReference * pType,void * pElements,sal_Int32 len,uno_AcquireFunc acquire)766 sal_Bool SAL_CALL uno_type_sequence_construct(
767     uno_Sequence ** ppSequence, typelib_TypeDescriptionReference * pType,
768     void * pElements, sal_Int32 len,
769     uno_AcquireFunc acquire )
770     SAL_THROW_EXTERN_C()
771 {
772     bool ret;
773     if (len)
774     {
775         typelib_TypeDescription * pTypeDescr = 0;
776         TYPELIB_DANGER_GET( &pTypeDescr, pType );
777 
778         typelib_TypeDescriptionReference * pElementType =
779             ((typelib_IndirectTypeDescription *)pTypeDescr)->pType;
780 
781         *ppSequence = 0;
782         if (pElements == 0)
783         {
784             ret = idefaultConstructElements(
785                 ppSequence, pElementType,
786                 0, len,
787                 len ); // alloc to len
788         }
789         else
790         {
791             ret = icopyConstructFromElements(
792                 ppSequence, pElements, pElementType,
793                 0, len, acquire,
794                 len ); // alloc to len
795         }
796 
797         TYPELIB_DANGER_RELEASE( pTypeDescr );
798     }
799     else
800     {
801         *ppSequence = createEmptySequence();
802         ret = true;
803     }
804 
805     OSL_ASSERT( (*ppSequence != 0) == ret );
806     return ret;
807 }
808 
809 //##############################################################################
uno_sequence_construct(uno_Sequence ** ppSequence,typelib_TypeDescription * pTypeDescr,void * pElements,sal_Int32 len,uno_AcquireFunc acquire)810 sal_Bool SAL_CALL uno_sequence_construct(
811     uno_Sequence ** ppSequence, typelib_TypeDescription * pTypeDescr,
812     void * pElements, sal_Int32 len,
813     uno_AcquireFunc acquire )
814     SAL_THROW_EXTERN_C()
815 {
816     bool ret;
817     if (len > 0)
818     {
819         typelib_TypeDescriptionReference * pElementType =
820             ((typelib_IndirectTypeDescription *)pTypeDescr)->pType;
821 
822         *ppSequence = 0;
823         if (pElements == 0)
824         {
825             ret = idefaultConstructElements(
826                 ppSequence, pElementType,
827                 0, len,
828                 len ); // alloc to len
829         }
830         else
831         {
832             ret = icopyConstructFromElements(
833                 ppSequence, pElements, pElementType,
834                 0, len, acquire,
835                 len ); // alloc to len
836         }
837     }
838     else
839     {
840         *ppSequence = createEmptySequence();
841         ret = true;
842     }
843 
844     OSL_ASSERT( (*ppSequence != 0) == ret );
845     return ret;
846 }
847 
848 //##############################################################################
uno_type_sequence_realloc(uno_Sequence ** ppSequence,typelib_TypeDescriptionReference * pType,sal_Int32 nSize,uno_AcquireFunc acquire,uno_ReleaseFunc release)849 sal_Bool SAL_CALL uno_type_sequence_realloc(
850     uno_Sequence ** ppSequence, typelib_TypeDescriptionReference * pType,
851     sal_Int32 nSize, uno_AcquireFunc acquire, uno_ReleaseFunc release )
852     SAL_THROW_EXTERN_C()
853 {
854     OSL_ENSURE( ppSequence, "### null ptr!" );
855     OSL_ENSURE( nSize >= 0, "### new size must be at least 0!" );
856 
857     bool ret = true;
858     if (nSize != (*ppSequence)->nElements)
859     {
860         typelib_TypeDescription * pTypeDescr = 0;
861         TYPELIB_DANGER_GET( &pTypeDescr, pType );
862         ret = ireallocSequence(
863             ppSequence, ((typelib_IndirectTypeDescription *)pTypeDescr)->pType,
864             nSize, acquire, release );
865         TYPELIB_DANGER_RELEASE( pTypeDescr );
866     }
867     return ret;
868 }
869 
870 //##############################################################################
uno_sequence_realloc(uno_Sequence ** ppSequence,typelib_TypeDescription * pTypeDescr,sal_Int32 nSize,uno_AcquireFunc acquire,uno_ReleaseFunc release)871 sal_Bool SAL_CALL uno_sequence_realloc(
872     uno_Sequence ** ppSequence, typelib_TypeDescription * pTypeDescr,
873     sal_Int32 nSize, uno_AcquireFunc acquire, uno_ReleaseFunc release )
874     SAL_THROW_EXTERN_C()
875 {
876     OSL_ENSURE( ppSequence, "### null ptr!" );
877     OSL_ENSURE( nSize >= 0, "### new size must be at least 0!" );
878 
879     bool ret = true;
880     if (nSize != (*ppSequence)->nElements)
881     {
882         ret = ireallocSequence(
883             ppSequence, ((typelib_IndirectTypeDescription *)pTypeDescr)->pType,
884             nSize, acquire, release );
885     }
886     return ret;
887 }
888 
889 //##############################################################################
uno_type_sequence_reference2One(uno_Sequence ** ppSequence,typelib_TypeDescriptionReference * pType,uno_AcquireFunc acquire,uno_ReleaseFunc release)890 sal_Bool SAL_CALL uno_type_sequence_reference2One(
891     uno_Sequence ** ppSequence,
892     typelib_TypeDescriptionReference * pType,
893     uno_AcquireFunc acquire, uno_ReleaseFunc release )
894     SAL_THROW_EXTERN_C()
895 {
896     OSL_ENSURE( ppSequence, "### null ptr!" );
897     bool ret = true;
898     uno_Sequence * pSequence = *ppSequence;
899     if (pSequence->nRefCount > 1)
900     {
901         uno_Sequence * pNew = 0;
902         if (pSequence->nElements > 0)
903         {
904             typelib_TypeDescription * pTypeDescr = 0;
905             TYPELIB_DANGER_GET( &pTypeDescr, pType );
906 
907             ret = icopyConstructFromElements(
908                 &pNew, pSequence->elements,
909                 ((typelib_IndirectTypeDescription *)pTypeDescr)->pType,
910                 0, pSequence->nElements, acquire,
911                 pSequence->nElements ); // alloc nElements
912             if (ret)
913             {
914                 idestructSequence( *ppSequence, pType, pTypeDescr, release );
915                 *ppSequence = pNew;
916             }
917 
918             TYPELIB_DANGER_RELEASE( pTypeDescr );
919         }
920         else
921         {
922             pNew = allocSeq( 0, 0 );
923             ret = (pNew != 0);
924             if (ret)
925             {
926                 // easy destruction of empty sequence:
927                 if (osl_decrementInterlockedCount( &pSequence->nRefCount ) == 0)
928                     rtl_freeMemory( pSequence );
929                 *ppSequence = pNew;
930             }
931         }
932     }
933     return ret;
934 }
935 
936 //##############################################################################
uno_sequence_reference2One(uno_Sequence ** ppSequence,typelib_TypeDescription * pTypeDescr,uno_AcquireFunc acquire,uno_ReleaseFunc release)937 sal_Bool SAL_CALL uno_sequence_reference2One(
938     uno_Sequence ** ppSequence,
939     typelib_TypeDescription * pTypeDescr,
940     uno_AcquireFunc acquire, uno_ReleaseFunc release )
941     SAL_THROW_EXTERN_C()
942 {
943     OSL_ENSURE( ppSequence, "### null ptr!" );
944     bool ret = true;
945     uno_Sequence * pSequence = *ppSequence;
946     if (pSequence->nRefCount > 1)
947     {
948         uno_Sequence * pNew = 0;
949         if (pSequence->nElements > 0)
950         {
951             ret = icopyConstructFromElements(
952                 &pNew, pSequence->elements,
953                 ((typelib_IndirectTypeDescription *)pTypeDescr)->pType,
954                 0, pSequence->nElements, acquire,
955                 pSequence->nElements ); // alloc nElements
956             if (ret)
957             {
958                 idestructSequence(
959                     pSequence, pTypeDescr->pWeakRef, pTypeDescr, release );
960                 *ppSequence = pNew;
961             }
962         }
963         else
964         {
965             pNew = allocSeq( 0, 0 );
966             ret = (pNew != 0);
967             if (ret)
968             {
969                 // easy destruction of empty sequence:
970                 if (osl_decrementInterlockedCount( &pSequence->nRefCount ) == 0)
971                     rtl_freeMemory( pSequence );
972                 *ppSequence = pNew;
973             }
974         }
975 
976     }
977     return ret;
978 }
979 
980 //##############################################################################
uno_sequence_assign(uno_Sequence ** ppDest,uno_Sequence * pSource,typelib_TypeDescription * pTypeDescr,uno_ReleaseFunc release)981 void SAL_CALL uno_sequence_assign(
982     uno_Sequence ** ppDest,
983     uno_Sequence * pSource,
984     typelib_TypeDescription * pTypeDescr,
985     uno_ReleaseFunc release )
986     SAL_THROW_EXTERN_C()
987 {
988     if (*ppDest != pSource)
989     {
990         ::osl_incrementInterlockedCount( &pSource->nRefCount );
991         idestructSequence( *ppDest, pTypeDescr->pWeakRef, pTypeDescr, release );
992         *ppDest = pSource;
993     }
994 }
995 
996 //##############################################################################
uno_type_sequence_assign(uno_Sequence ** ppDest,uno_Sequence * pSource,typelib_TypeDescriptionReference * pType,uno_ReleaseFunc release)997 void SAL_CALL uno_type_sequence_assign(
998     uno_Sequence ** ppDest,
999     uno_Sequence * pSource,
1000     typelib_TypeDescriptionReference * pType,
1001     uno_ReleaseFunc release )
1002     SAL_THROW_EXTERN_C()
1003 {
1004     if (*ppDest != pSource)
1005     {
1006         ::osl_incrementInterlockedCount( &pSource->nRefCount );
1007         idestructSequence( *ppDest, pType, 0, release );
1008         *ppDest = pSource;
1009     }
1010 }
1011 
1012 }
1013