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