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