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 "sal/config.h"
21 :
22 : #include <cassert>
23 : #include <string.h>
24 :
25 : #include <rtl/alloc.h>
26 : #include <osl/diagnose.h>
27 : #include <osl/interlck.h>
28 : #include <typelib/typedescription.h>
29 : #include <uno/data.h>
30 : #include <uno/dispatcher.h>
31 : #include <uno/sequence2.h>
32 :
33 : #include "constr.hxx"
34 : #include "copy.hxx"
35 : #include "destr.hxx"
36 :
37 :
38 : using namespace cppu;
39 :
40 : namespace cppu
41 : {
42 :
43 :
44 247428744 : static inline uno_Sequence * reallocSeq(
45 : uno_Sequence * pReallocate, sal_Size nElementSize, sal_Int32 nElements )
46 : {
47 : OSL_ASSERT( nElements >= 0 );
48 247428744 : uno_Sequence * pNew = 0;
49 247428744 : sal_uInt32 nSize = calcSeqMemSize( nElementSize, nElements );
50 247428740 : if (nSize > 0)
51 : {
52 247428740 : if (pReallocate == 0)
53 : {
54 243044931 : pNew = static_cast<uno_Sequence *>(rtl_allocateMemory( nSize ));
55 : }
56 : else
57 : {
58 4383809 : pNew = static_cast<uno_Sequence *>(rtl_reallocateMemory( pReallocate, nSize ));
59 : }
60 247428759 : if (pNew != 0)
61 : {
62 : // header init
63 247428759 : pNew->nRefCount = 1;
64 247428759 : pNew->nElements = nElements;
65 : }
66 : }
67 247428759 : return pNew;
68 : }
69 :
70 :
71 242550231 : static inline bool idefaultConstructElements(
72 : uno_Sequence ** ppSeq,
73 : typelib_TypeDescriptionReference * pElementType,
74 : sal_Int32 nStartIndex, sal_Int32 nStopIndex,
75 : sal_Int32 nAlloc = -1 ) // >= 0 means (re)alloc memory for nAlloc elements
76 : {
77 242550231 : uno_Sequence * pSeq = *ppSeq;
78 242550231 : switch (pElementType->eTypeClass)
79 : {
80 : case typelib_TypeClass_CHAR:
81 0 : if (nAlloc >= 0)
82 0 : pSeq = reallocSeq( pSeq, sizeof(sal_Unicode), nAlloc );
83 0 : if (pSeq != 0)
84 : {
85 : memset(
86 0 : pSeq->elements + (sizeof(sal_Unicode) * nStartIndex),
87 : 0,
88 0 : sizeof(sal_Unicode) * (nStopIndex - nStartIndex) );
89 : }
90 0 : break;
91 : case typelib_TypeClass_BOOLEAN:
92 55881 : if (nAlloc >= 0)
93 55807 : pSeq = reallocSeq( pSeq, sizeof(sal_Bool), nAlloc );
94 55881 : if (pSeq != 0)
95 : {
96 : memset(
97 55881 : pSeq->elements + (sizeof(sal_Bool) * nStartIndex),
98 : 0,
99 111762 : sizeof(sal_Bool) * (nStopIndex - nStartIndex) );
100 : }
101 55881 : break;
102 : case typelib_TypeClass_BYTE:
103 1849459 : if (nAlloc >= 0)
104 884699 : pSeq = reallocSeq( pSeq, sizeof(sal_Int8), nAlloc );
105 1849458 : if (pSeq != 0)
106 : {
107 : memset(
108 1849458 : pSeq->elements + (sizeof(sal_Int8) * nStartIndex),
109 : 0,
110 3698916 : sizeof(sal_Int8) * (nStopIndex - nStartIndex) );
111 : }
112 1849458 : break;
113 : case typelib_TypeClass_SHORT:
114 : case typelib_TypeClass_UNSIGNED_SHORT:
115 2054 : if (nAlloc >= 0)
116 1135 : pSeq = reallocSeq( pSeq, sizeof(sal_Int16), nAlloc );
117 2054 : if (pSeq != 0)
118 : {
119 : memset(
120 2054 : pSeq->elements + (sizeof(sal_Int16) * nStartIndex),
121 : 0,
122 4108 : sizeof(sal_Int16) * (nStopIndex - nStartIndex) );
123 : }
124 2054 : break;
125 : case typelib_TypeClass_LONG:
126 : case typelib_TypeClass_UNSIGNED_LONG:
127 112949 : if (nAlloc >= 0)
128 89171 : pSeq = reallocSeq( pSeq, sizeof(sal_Int32), nAlloc );
129 112949 : if (pSeq != 0)
130 : {
131 : memset(
132 112949 : pSeq->elements + (sizeof(sal_Int32) * nStartIndex),
133 : 0,
134 225898 : sizeof(sal_Int32) * (nStopIndex - nStartIndex) );
135 : }
136 112949 : break;
137 : case typelib_TypeClass_HYPER:
138 : case typelib_TypeClass_UNSIGNED_HYPER:
139 926 : if (nAlloc >= 0)
140 856 : pSeq = reallocSeq( pSeq, sizeof(sal_Int64), nAlloc );
141 926 : if (pSeq != 0)
142 : {
143 : memset(
144 926 : pSeq->elements + (sizeof(sal_Int64) * nStartIndex),
145 : 0,
146 1852 : sizeof(sal_Int64) * (nStopIndex - nStartIndex) );
147 : }
148 926 : break;
149 : case typelib_TypeClass_FLOAT:
150 : {
151 1 : if (nAlloc >= 0)
152 1 : pSeq = reallocSeq( pSeq, sizeof(float), nAlloc );
153 1 : if (pSeq != 0)
154 : {
155 1 : float * pElements = reinterpret_cast<float *>(pSeq->elements);
156 2 : for ( sal_Int32 nPos = nStartIndex; nPos < nStopIndex; ++nPos )
157 : {
158 1 : pElements[nPos] = 0.0;
159 : }
160 : }
161 1 : break;
162 : }
163 : case typelib_TypeClass_DOUBLE:
164 : {
165 555227 : if (nAlloc >= 0)
166 487790 : pSeq = reallocSeq( pSeq, sizeof(double), nAlloc );
167 555227 : if (pSeq != 0)
168 : {
169 555227 : double * pElements = reinterpret_cast<double *>(pSeq->elements);
170 2891534 : for ( sal_Int32 nPos = nStartIndex; nPos < nStopIndex; ++nPos )
171 : {
172 2336307 : pElements[nPos] = 0.0;
173 : }
174 : }
175 555227 : break;
176 : }
177 : case typelib_TypeClass_STRING:
178 : {
179 1175610 : if (nAlloc >= 0)
180 1039193 : pSeq = reallocSeq( pSeq, sizeof(rtl_uString *), nAlloc );
181 1175610 : if (pSeq != 0)
182 : {
183 1175610 : rtl_uString ** pElements = reinterpret_cast<rtl_uString **>(pSeq->elements);
184 5887863 : for ( sal_Int32 nPos = nStartIndex; nPos < nStopIndex; ++nPos )
185 : {
186 4712253 : pElements[nPos] = 0;
187 4712253 : rtl_uString_new( &pElements[nPos] );
188 : }
189 : }
190 1175610 : break;
191 : }
192 : case typelib_TypeClass_TYPE:
193 : {
194 58738 : if (nAlloc >= 0)
195 : {
196 : pSeq = reallocSeq(
197 58387 : pSeq, sizeof(typelib_TypeDescriptionReference *), nAlloc );
198 : }
199 58738 : if (pSeq != 0)
200 : {
201 : typelib_TypeDescriptionReference ** pElements =
202 58738 : reinterpret_cast<typelib_TypeDescriptionReference **>(pSeq->elements);
203 1409405 : for ( sal_Int32 nPos = nStartIndex; nPos < nStopIndex; ++nPos )
204 : {
205 1350667 : pElements[nPos] = _getVoidType();
206 : }
207 : }
208 58738 : break;
209 : }
210 : case typelib_TypeClass_ANY:
211 : {
212 28018706 : if (nAlloc >= 0)
213 27792701 : pSeq = reallocSeq( pSeq, sizeof(uno_Any), nAlloc );
214 28018706 : if (pSeq != 0)
215 : {
216 28018706 : uno_Any * pElements = reinterpret_cast<uno_Any *>(pSeq->elements);
217 59656658 : for ( sal_Int32 nPos = nStartIndex; nPos < nStopIndex; ++nPos )
218 : {
219 31637952 : CONSTRUCT_EMPTY_ANY( &pElements[nPos] );
220 : }
221 : }
222 28018706 : break;
223 : }
224 : case typelib_TypeClass_ENUM:
225 : {
226 47608 : if (nAlloc >= 0)
227 39687 : pSeq = reallocSeq( pSeq, sizeof(sal_Int32), nAlloc );
228 47608 : if (pSeq != 0)
229 : {
230 47608 : typelib_TypeDescription * pElementTypeDescr = 0;
231 47608 : TYPELIB_DANGER_GET( &pElementTypeDescr, pElementType );
232 : sal_Int32 eEnum =
233 : reinterpret_cast<typelib_EnumTypeDescription *>(
234 47608 : pElementTypeDescr)->nDefaultEnumValue;
235 47608 : TYPELIB_DANGER_RELEASE( pElementTypeDescr );
236 :
237 47608 : sal_Int32 * pElements = reinterpret_cast<sal_Int32 *>(pSeq->elements);
238 2991806 : for ( sal_Int32 nPos = nStartIndex; nPos < nStopIndex; ++nPos )
239 : {
240 2944198 : pElements[nPos] = eEnum;
241 : }
242 : }
243 47608 : break;
244 : }
245 : case typelib_TypeClass_STRUCT:
246 : case typelib_TypeClass_EXCEPTION:
247 : {
248 4119426 : typelib_TypeDescription * pElementTypeDescr = 0;
249 4119426 : TYPELIB_DANGER_GET( &pElementTypeDescr, pElementType );
250 4119426 : sal_Int32 nElementSize = pElementTypeDescr->nSize;
251 :
252 4119426 : if (nAlloc >= 0)
253 1767226 : pSeq = reallocSeq( pSeq, nElementSize, nAlloc );
254 4119425 : if (pSeq != 0)
255 : {
256 4119425 : char * pElements = pSeq->elements;
257 15952209 : for ( sal_Int32 nPos = nStartIndex; nPos < nStopIndex; ++nPos )
258 : {
259 : _defaultConstructStruct(
260 23665566 : pElements + (nElementSize * nPos),
261 35498349 : reinterpret_cast<typelib_CompoundTypeDescription *>(pElementTypeDescr) );
262 : }
263 : }
264 :
265 4119426 : TYPELIB_DANGER_RELEASE( pElementTypeDescr );
266 4119426 : break;
267 : }
268 : case typelib_TypeClass_SEQUENCE:
269 : {
270 185074 : if (nAlloc >= 0)
271 : {
272 : // coverity[suspicious_sizeof] - sizeof(uno_Sequence*) is correct here
273 84257 : pSeq = reallocSeq(pSeq, sizeof(uno_Sequence*), nAlloc);
274 : }
275 185074 : if (pSeq != 0)
276 : {
277 : uno_Sequence ** pElements =
278 185074 : reinterpret_cast<uno_Sequence **>(pSeq->elements);
279 514327 : for ( sal_Int32 nPos = nStartIndex; nPos < nStopIndex; ++nPos )
280 : {
281 329253 : pElements[nPos] = createEmptySequence();
282 : }
283 : }
284 185074 : break;
285 : }
286 : case typelib_TypeClass_INTERFACE: // either C++ or C-UNO interface
287 206368572 : if (nAlloc >= 0)
288 206161174 : pSeq = reallocSeq( pSeq, sizeof(void *), nAlloc );
289 206368573 : if (pSeq != 0)
290 : {
291 : memset(
292 206368573 : pSeq->elements + (sizeof(void *) * nStartIndex),
293 : 0,
294 412737146 : sizeof(void *) * (nStopIndex - nStartIndex) );
295 : }
296 206368573 : break;
297 : default:
298 : OSL_FAIL( "### unexpected element type!" );
299 0 : pSeq = 0;
300 0 : break;
301 : }
302 :
303 242550228 : if (pSeq == 0)
304 : {
305 : OSL_ASSERT( nAlloc >= 0 ); // must have been an allocation failure
306 0 : return false;
307 : }
308 : else
309 : {
310 242550228 : *ppSeq = pSeq;
311 242550228 : return true;
312 : }
313 : }
314 :
315 :
316 8460287 : static inline bool icopyConstructFromElements(
317 : uno_Sequence ** ppSeq, void * pSourceElements,
318 : typelib_TypeDescriptionReference * pElementType,
319 : sal_Int32 nStartIndex, sal_Int32 nStopIndex,
320 : uno_AcquireFunc acquire,
321 : sal_Int32 nAlloc = -1 ) // >= 0 means (re)alloc memory for nAlloc elements
322 : {
323 8460287 : uno_Sequence * pSeq = *ppSeq;
324 8460287 : switch (pElementType->eTypeClass)
325 : {
326 : case typelib_TypeClass_CHAR:
327 1 : if (nAlloc >= 0)
328 1 : pSeq = reallocSeq( pSeq, sizeof(sal_Unicode), nAlloc );
329 0 : if (pSeq != 0)
330 : {
331 : memcpy(
332 1 : pSeq->elements + (sizeof(sal_Unicode) * nStartIndex),
333 1 : static_cast<char *>(pSourceElements) + (sizeof(sal_Unicode) * nStartIndex),
334 3 : sizeof(sal_Unicode) * (nStopIndex - nStartIndex) );
335 : }
336 0 : break;
337 : case typelib_TypeClass_BOOLEAN:
338 90 : if (nAlloc >= 0)
339 90 : pSeq = reallocSeq( pSeq, sizeof(sal_Bool), nAlloc );
340 90 : if (pSeq != 0)
341 : {
342 : memcpy(
343 90 : pSeq->elements + (sizeof(sal_Bool) * nStartIndex),
344 90 : static_cast<char *>(pSourceElements) + (sizeof(sal_Bool) * nStartIndex),
345 270 : sizeof(sal_Bool) * (nStopIndex - nStartIndex) );
346 : }
347 90 : break;
348 : case typelib_TypeClass_BYTE:
349 2147737 : if (nAlloc >= 0)
350 2147737 : pSeq = reallocSeq( pSeq, sizeof(sal_Int8), nAlloc );
351 2147737 : if (pSeq != 0)
352 : {
353 : memcpy(
354 2147737 : pSeq->elements + (sizeof(sal_Int8) * nStartIndex),
355 2147737 : static_cast<char *>(pSourceElements) + (sizeof(sal_Int8) * nStartIndex),
356 6443211 : sizeof(sal_Int8) * (nStopIndex - nStartIndex) );
357 : }
358 2147737 : break;
359 : case typelib_TypeClass_SHORT:
360 : case typelib_TypeClass_UNSIGNED_SHORT:
361 931 : if (nAlloc >= 0)
362 931 : pSeq = reallocSeq( pSeq, sizeof(sal_Int16), nAlloc );
363 931 : if (pSeq != 0)
364 : {
365 : memcpy(
366 931 : pSeq->elements + (sizeof(sal_Int16) * nStartIndex),
367 931 : static_cast<char *>(pSourceElements) + (sizeof(sal_Int16) * nStartIndex),
368 2793 : sizeof(sal_Int16) * (nStopIndex - nStartIndex) );
369 : }
370 931 : break;
371 : case typelib_TypeClass_LONG:
372 : case typelib_TypeClass_UNSIGNED_LONG:
373 26181 : if (nAlloc >= 0)
374 26181 : pSeq = reallocSeq( pSeq, sizeof(sal_Int32), nAlloc );
375 26181 : if (pSeq != 0)
376 : {
377 : memcpy(
378 26181 : pSeq->elements + (sizeof(sal_Int32) * nStartIndex),
379 26181 : static_cast<char *>(pSourceElements) + (sizeof(sal_Int32) * nStartIndex),
380 78543 : sizeof(sal_Int32) * (nStopIndex - nStartIndex) );
381 : }
382 26181 : break;
383 : case typelib_TypeClass_HYPER:
384 : case typelib_TypeClass_UNSIGNED_HYPER:
385 351 : if (nAlloc >= 0)
386 351 : pSeq = reallocSeq( pSeq, sizeof(sal_Int64), nAlloc );
387 351 : if (pSeq != 0)
388 : {
389 : memcpy(
390 351 : pSeq->elements + (sizeof(sal_Int64) * nStartIndex),
391 351 : static_cast<char *>(pSourceElements) + (sizeof(sal_Int64) * nStartIndex),
392 1053 : sizeof(sal_Int64) * (nStopIndex - nStartIndex) );
393 : }
394 351 : break;
395 : case typelib_TypeClass_FLOAT:
396 5 : if (nAlloc >= 0)
397 5 : pSeq = reallocSeq( pSeq, sizeof(float), nAlloc );
398 5 : if (pSeq != 0)
399 : {
400 : memcpy(
401 5 : pSeq->elements + (sizeof(float) * nStartIndex),
402 5 : static_cast<char *>(pSourceElements) + (sizeof(float) * nStartIndex),
403 15 : sizeof(float) * (nStopIndex - nStartIndex) );
404 : }
405 5 : break;
406 : case typelib_TypeClass_DOUBLE:
407 90076 : if (nAlloc >= 0)
408 90076 : pSeq = reallocSeq( pSeq, sizeof(double), nAlloc );
409 90076 : if (pSeq != 0)
410 : {
411 : memcpy(
412 90076 : pSeq->elements + (sizeof(double) * nStartIndex),
413 90076 : static_cast<char *>(pSourceElements) + (sizeof(double) * nStartIndex),
414 270228 : sizeof(double) * (nStopIndex - nStartIndex) );
415 : }
416 90076 : break;
417 : case typelib_TypeClass_ENUM:
418 8936 : if (nAlloc >= 0)
419 8936 : pSeq = reallocSeq( pSeq, sizeof(sal_Int32), nAlloc );
420 8936 : if (pSeq != 0)
421 : {
422 : memcpy(
423 8936 : pSeq->elements + (sizeof(sal_Int32) * nStartIndex),
424 8936 : static_cast<char *>(pSourceElements) + (sizeof(sal_Int32) * nStartIndex),
425 26808 : sizeof(sal_Int32) * (nStopIndex - nStartIndex) );
426 : }
427 8936 : break;
428 : case typelib_TypeClass_STRING:
429 : {
430 1107805 : if (nAlloc >= 0)
431 1107805 : pSeq = reallocSeq( pSeq, sizeof(rtl_uString *), nAlloc );
432 1107805 : if (pSeq != 0)
433 : {
434 1107805 : rtl_uString ** pDestElements = reinterpret_cast<rtl_uString **>(pSeq->elements);
435 6235351 : for ( sal_Int32 nPos = nStartIndex; nPos < nStopIndex; ++nPos )
436 : {
437 : // This code tends to trigger coverity's overrun-buffer-arg warning
438 : // coverity[index_parm_via_loop_bound] - https://communities.coverity.com/thread/2993
439 : ::rtl_uString_acquire(
440 5127546 : static_cast<rtl_uString **>(pSourceElements)[nPos] );
441 5127546 : pDestElements[nPos] = static_cast<rtl_uString **>(pSourceElements)[nPos];
442 : }
443 : }
444 1107805 : break;
445 : }
446 : case typelib_TypeClass_TYPE:
447 : {
448 829 : if (nAlloc >= 0)
449 : {
450 : pSeq = reallocSeq(
451 829 : pSeq, sizeof(typelib_TypeDescriptionReference *), nAlloc );
452 : }
453 829 : if (pSeq != 0)
454 : {
455 : typelib_TypeDescriptionReference ** pDestElements =
456 829 : reinterpret_cast<typelib_TypeDescriptionReference **>(pSeq->elements);
457 2787 : for ( sal_Int32 nPos = nStartIndex; nPos < nStopIndex; ++nPos )
458 : {
459 1958 : TYPE_ACQUIRE(
460 : static_cast<typelib_TypeDescriptionReference **>(
461 : pSourceElements)[nPos] );
462 1958 : pDestElements[nPos] =
463 : static_cast<typelib_TypeDescriptionReference **>(
464 1958 : pSourceElements)[nPos];
465 : }
466 : }
467 829 : break;
468 : }
469 : case typelib_TypeClass_ANY:
470 : {
471 657848 : if (nAlloc >= 0)
472 657848 : pSeq = reallocSeq( pSeq, sizeof(uno_Any), nAlloc );
473 657848 : if (pSeq != 0)
474 : {
475 657848 : uno_Any * pDestElements = reinterpret_cast<uno_Any *>(pSeq->elements);
476 1668613 : for ( sal_Int32 nPos = nStartIndex; nPos < nStopIndex; ++nPos )
477 : {
478 1010765 : uno_Any * pSource = static_cast<uno_Any *>(pSourceElements) + nPos;
479 : _copyConstructAny(
480 : &pDestElements[nPos],
481 : pSource->pData,
482 : pSource->pType, 0,
483 1010765 : acquire, 0 );
484 : }
485 : }
486 657848 : break;
487 : }
488 : case typelib_TypeClass_STRUCT:
489 : case typelib_TypeClass_EXCEPTION:
490 : {
491 3661986 : typelib_TypeDescription * pElementTypeDescr = 0;
492 3661986 : TYPELIB_DANGER_GET( &pElementTypeDescr, pElementType );
493 3661986 : sal_Int32 nElementSize = pElementTypeDescr->nSize;
494 :
495 3661986 : if (nAlloc >= 0)
496 3661986 : pSeq = reallocSeq( pSeq, nElementSize, nAlloc );
497 3661986 : if (pSeq != 0)
498 : {
499 3661986 : char * pDestElements = pSeq->elements;
500 :
501 : typelib_CompoundTypeDescription * pTypeDescr =
502 3661986 : reinterpret_cast<typelib_CompoundTypeDescription *>(pElementTypeDescr);
503 26148715 : for ( sal_Int32 nPos = nStartIndex; nPos < nStopIndex; ++nPos )
504 : {
505 : char * pDest =
506 22486729 : pDestElements + (nElementSize * nPos);
507 : char * pSource =
508 22486729 : static_cast<char *>(pSourceElements) + (nElementSize * nPos);
509 :
510 22486729 : if (pTypeDescr->pBaseTypeDescription)
511 : {
512 : // copy base value
513 : _copyConstructStruct(
514 : pDest, pSource,
515 43689 : pTypeDescr->pBaseTypeDescription, acquire, 0 );
516 : }
517 :
518 : // then copy members
519 : typelib_TypeDescriptionReference ** ppTypeRefs =
520 22486729 : pTypeDescr->ppTypeRefs;
521 22486729 : sal_Int32 * pMemberOffsets = pTypeDescr->pMemberOffsets;
522 22486729 : sal_Int32 nDescr = pTypeDescr->nMembers;
523 :
524 124380866 : while (nDescr--)
525 : {
526 : ::uno_type_copyData(
527 158814816 : pDest + pMemberOffsets[nDescr],
528 158814816 : pSource + pMemberOffsets[nDescr],
529 317629632 : ppTypeRefs[nDescr], acquire );
530 : }
531 : }
532 : }
533 :
534 3661986 : TYPELIB_DANGER_RELEASE( pElementTypeDescr );
535 3661986 : break;
536 : }
537 : case typelib_TypeClass_SEQUENCE: // sequence of sequence
538 : {
539 190270 : if (nAlloc >= 0)
540 : {
541 : // coverity[suspicious_sizeof] - sizeof(uno_Sequence*) is correct here
542 190270 : pSeq = reallocSeq(pSeq, sizeof(uno_Sequence*), nAlloc);
543 : }
544 190270 : if (pSeq != 0)
545 : {
546 190270 : typelib_TypeDescription * pElementTypeDescr = 0;
547 190270 : TYPELIB_DANGER_GET( &pElementTypeDescr, pElementType );
548 : typelib_TypeDescriptionReference * pSeqElementType =
549 190270 : reinterpret_cast<typelib_IndirectTypeDescription *>(pElementTypeDescr)->pType;
550 190270 : uno_Sequence ** pDestElements = reinterpret_cast<uno_Sequence **>(pSeq->elements);
551 5331259 : for ( sal_Int32 nPos = nStartIndex; nPos < nStopIndex; ++nPos )
552 : {
553 : uno_Sequence * pNew = icopyConstructSequence(
554 5140989 : static_cast<uno_Sequence **>(pSourceElements)[nPos],
555 5140989 : pSeqElementType, acquire, 0 );
556 : OSL_ASSERT( pNew != 0 );
557 : // ought never be a memory allocation problem,
558 : // because of reference counted sequence handles
559 5140989 : pDestElements[ nPos ] = pNew;
560 : }
561 190270 : TYPELIB_DANGER_RELEASE( pElementTypeDescr );
562 : }
563 190270 : break;
564 : }
565 : case typelib_TypeClass_INTERFACE:
566 : {
567 567241 : if (nAlloc >= 0)
568 567241 : pSeq = reallocSeq( pSeq, sizeof(void *), nAlloc );
569 567241 : if (pSeq != 0)
570 : {
571 567241 : void ** pDestElements = reinterpret_cast<void **>(pSeq->elements);
572 982464 : for ( sal_Int32 nPos = nStartIndex; nPos < nStopIndex; ++nPos )
573 : {
574 830446 : _acquire( pDestElements[nPos] =
575 830446 : static_cast<void **>(pSourceElements)[nPos], acquire );
576 : }
577 : }
578 567241 : break;
579 : }
580 : default:
581 : OSL_FAIL( "### unexpected element type!" );
582 0 : pSeq = 0;
583 0 : break;
584 : }
585 :
586 8460286 : if (pSeq == 0)
587 : {
588 : OSL_ASSERT( nAlloc >= 0 ); // must have been an allocation failure
589 0 : return false;
590 : }
591 : else
592 : {
593 8460286 : *ppSeq = pSeq;
594 8460286 : return true;
595 : }
596 : }
597 :
598 :
599 8576868 : static inline bool ireallocSequence(
600 : uno_Sequence ** ppSequence,
601 : typelib_TypeDescriptionReference * pElementType,
602 : sal_Int32 nSize,
603 : uno_AcquireFunc acquire, uno_ReleaseFunc release )
604 : {
605 8576868 : bool ret = true;
606 8576868 : uno_Sequence * pSeq = *ppSequence;
607 8576868 : sal_Int32 nElements = pSeq->nElements;
608 :
609 14930939 : if (pSeq->nRefCount > 1 ||
610 : // not mem-copyable elements?
611 12687071 : typelib_TypeClass_ANY == pElementType->eTypeClass ||
612 10716809 : typelib_TypeClass_STRUCT == pElementType->eTypeClass ||
613 4383809 : typelib_TypeClass_EXCEPTION == pElementType->eTypeClass)
614 : {
615 : // split sequence and construct new one from scratch
616 4193059 : uno_Sequence * pNew = 0;
617 :
618 4193059 : sal_Int32 nRest = nSize - nElements;
619 4193059 : sal_Int32 nCopy = (nRest > 0 ? nElements : nSize);
620 :
621 4193059 : if (nCopy >= 0)
622 : {
623 : ret = icopyConstructFromElements(
624 : &pNew, pSeq->elements, pElementType,
625 : 0, nCopy, acquire,
626 4193059 : nSize ); // alloc to nSize
627 : }
628 4193058 : if (ret && nRest > 0)
629 : {
630 : ret = idefaultConstructElements(
631 : &pNew, pElementType,
632 : nCopy, nSize,
633 4088150 : nCopy >= 0 ? -1 /* no mem allocation */ : nSize );
634 : }
635 :
636 4193059 : if (ret)
637 : {
638 : // destruct sequence
639 4193059 : if (osl_atomic_decrement( &pSeq->nRefCount ) == 0)
640 : {
641 1970262 : if (nElements > 0)
642 : {
643 : idestructElements(
644 : pSeq->elements, pElementType,
645 1968825 : 0, nElements, release );
646 : }
647 1970262 : rtl_freeMemory( pSeq );
648 : }
649 4193057 : *ppSequence = pNew;
650 4193057 : }
651 : }
652 : else
653 : {
654 : OSL_ASSERT( pSeq->nRefCount == 1 );
655 4383809 : if (nSize > nElements) // default construct the rest
656 : {
657 : ret = idefaultConstructElements(
658 : ppSequence, pElementType,
659 : nElements, nSize,
660 3877420 : nSize ); // realloc to nSize
661 : }
662 : else // or destruct the rest and realloc mem
663 : {
664 : sal_Int32 nElementSize = idestructElements(
665 : pSeq->elements, pElementType,
666 506389 : nSize, nElements, release );
667 : // warning: it is assumed that the following will never fail,
668 : // else this leads to a sequence null handle
669 506389 : *ppSequence = reallocSeq( pSeq, nElementSize, nSize );
670 : OSL_ASSERT( *ppSequence != 0 );
671 506389 : ret = (*ppSequence != 0);
672 : }
673 : }
674 :
675 8576866 : return ret;
676 : }
677 :
678 : }
679 :
680 : extern "C"
681 : {
682 :
683 :
684 380734270 : sal_Bool SAL_CALL uno_type_sequence_construct(
685 : uno_Sequence ** ppSequence, typelib_TypeDescriptionReference * pType,
686 : void * pElements, sal_Int32 len,
687 : uno_AcquireFunc acquire )
688 : SAL_THROW_EXTERN_C()
689 : {
690 : assert( len >= 0 );
691 : bool ret;
692 380734270 : if (len)
693 : {
694 237680373 : typelib_TypeDescription * pTypeDescr = 0;
695 237680373 : TYPELIB_DANGER_GET( &pTypeDescr, pType );
696 :
697 : typelib_TypeDescriptionReference * pElementType =
698 237680375 : reinterpret_cast<typelib_IndirectTypeDescription *>(pTypeDescr)->pType;
699 :
700 237680375 : *ppSequence = 0;
701 237680375 : if (pElements == 0)
702 : {
703 : ret = idefaultConstructElements(
704 : ppSequence, pElementType,
705 : 0, len,
706 234584458 : len ); // alloc to len
707 : }
708 : else
709 : {
710 : ret = icopyConstructFromElements(
711 : ppSequence, pElements, pElementType,
712 : 0, len, acquire,
713 3095917 : len ); // alloc to len
714 : }
715 :
716 237680377 : TYPELIB_DANGER_RELEASE( pTypeDescr );
717 : }
718 : else
719 : {
720 143053897 : *ppSequence = createEmptySequence();
721 143053898 : ret = true;
722 : }
723 :
724 : OSL_ASSERT( (*ppSequence != 0) == ret );
725 380734249 : return ret;
726 : }
727 :
728 :
729 228 : sal_Bool SAL_CALL uno_sequence_construct(
730 : uno_Sequence ** ppSequence, typelib_TypeDescription * pTypeDescr,
731 : void * pElements, sal_Int32 len,
732 : uno_AcquireFunc acquire )
733 : SAL_THROW_EXTERN_C()
734 : {
735 : bool ret;
736 228 : if (len > 0)
737 : {
738 : typelib_TypeDescriptionReference * pElementType =
739 205 : reinterpret_cast<typelib_IndirectTypeDescription *>(pTypeDescr)->pType;
740 :
741 205 : *ppSequence = 0;
742 205 : if (pElements == 0)
743 : {
744 : ret = idefaultConstructElements(
745 : ppSequence, pElementType,
746 : 0, len,
747 205 : len ); // alloc to len
748 : }
749 : else
750 : {
751 : ret = icopyConstructFromElements(
752 : ppSequence, pElements, pElementType,
753 : 0, len, acquire,
754 0 : len ); // alloc to len
755 : }
756 : }
757 : else
758 : {
759 23 : *ppSequence = createEmptySequence();
760 23 : ret = true;
761 : }
762 :
763 : OSL_ASSERT( (*ppSequence != 0) == ret );
764 228 : return ret;
765 : }
766 :
767 :
768 9616640 : sal_Bool SAL_CALL uno_type_sequence_realloc(
769 : uno_Sequence ** ppSequence, typelib_TypeDescriptionReference * pType,
770 : sal_Int32 nSize, uno_AcquireFunc acquire, uno_ReleaseFunc release )
771 : SAL_THROW_EXTERN_C()
772 : {
773 : OSL_ENSURE( ppSequence, "### null ptr!" );
774 : OSL_ENSURE( nSize >= 0, "### new size must be at least 0!" );
775 :
776 9616640 : bool ret = true;
777 9616640 : if (nSize != (*ppSequence)->nElements)
778 : {
779 8576826 : typelib_TypeDescription * pTypeDescr = 0;
780 8576826 : TYPELIB_DANGER_GET( &pTypeDescr, pType );
781 : ret = ireallocSequence(
782 : ppSequence, reinterpret_cast<typelib_IndirectTypeDescription *>(pTypeDescr)->pType,
783 8576827 : nSize, acquire, release );
784 8576826 : TYPELIB_DANGER_RELEASE( pTypeDescr );
785 : }
786 9616638 : return ret;
787 : }
788 :
789 :
790 45 : sal_Bool SAL_CALL uno_sequence_realloc(
791 : uno_Sequence ** ppSequence, typelib_TypeDescription * pTypeDescr,
792 : sal_Int32 nSize, uno_AcquireFunc acquire, uno_ReleaseFunc release )
793 : SAL_THROW_EXTERN_C()
794 : {
795 : OSL_ENSURE( ppSequence, "### null ptr!" );
796 : OSL_ENSURE( nSize >= 0, "### new size must be at least 0!" );
797 :
798 45 : bool ret = true;
799 45 : if (nSize != (*ppSequence)->nElements)
800 : {
801 : ret = ireallocSequence(
802 : ppSequence, reinterpret_cast<typelib_IndirectTypeDescription *>(pTypeDescr)->pType,
803 40 : nSize, acquire, release );
804 : }
805 45 : return ret;
806 : }
807 :
808 :
809 320326616 : sal_Bool SAL_CALL uno_type_sequence_reference2One(
810 : uno_Sequence ** ppSequence,
811 : typelib_TypeDescriptionReference * pType,
812 : uno_AcquireFunc acquire, uno_ReleaseFunc release )
813 : SAL_THROW_EXTERN_C()
814 : {
815 : OSL_ENSURE( ppSequence, "### null ptr!" );
816 320326616 : bool ret = true;
817 320326616 : uno_Sequence * pSequence = *ppSequence;
818 320326616 : if (pSequence->nRefCount > 1)
819 : {
820 1862210 : uno_Sequence * pNew = 0;
821 1862210 : if (pSequence->nElements > 0)
822 : {
823 1171311 : typelib_TypeDescription * pTypeDescr = 0;
824 1171311 : TYPELIB_DANGER_GET( &pTypeDescr, pType );
825 :
826 : ret = icopyConstructFromElements(
827 : &pNew, pSequence->elements,
828 : reinterpret_cast<typelib_IndirectTypeDescription *>(pTypeDescr)->pType,
829 : 0, pSequence->nElements, acquire,
830 1171311 : pSequence->nElements ); // alloc nElements
831 1171311 : if (ret)
832 : {
833 1171311 : idestructSequence( *ppSequence, pType, pTypeDescr, release );
834 1171311 : *ppSequence = pNew;
835 : }
836 :
837 1171311 : TYPELIB_DANGER_RELEASE( pTypeDescr );
838 : }
839 : else
840 : {
841 690899 : pNew = allocSeq( 0, 0 );
842 690899 : ret = (pNew != 0);
843 690899 : if (ret)
844 : {
845 : // easy destruction of empty sequence:
846 690899 : if (osl_atomic_decrement( &pSequence->nRefCount ) == 0)
847 0 : rtl_freeMemory( pSequence );
848 690899 : *ppSequence = pNew;
849 : }
850 : }
851 : }
852 320326616 : return ret;
853 : }
854 :
855 :
856 81 : sal_Bool SAL_CALL uno_sequence_reference2One(
857 : uno_Sequence ** ppSequence,
858 : typelib_TypeDescription * pTypeDescr,
859 : uno_AcquireFunc acquire, uno_ReleaseFunc release )
860 : SAL_THROW_EXTERN_C()
861 : {
862 : OSL_ENSURE( ppSequence, "### null ptr!" );
863 81 : bool ret = true;
864 81 : uno_Sequence * pSequence = *ppSequence;
865 81 : if (pSequence->nRefCount > 1)
866 : {
867 0 : uno_Sequence * pNew = 0;
868 0 : if (pSequence->nElements > 0)
869 : {
870 : ret = icopyConstructFromElements(
871 : &pNew, pSequence->elements,
872 : reinterpret_cast<typelib_IndirectTypeDescription *>(pTypeDescr)->pType,
873 : 0, pSequence->nElements, acquire,
874 0 : pSequence->nElements ); // alloc nElements
875 0 : if (ret)
876 : {
877 : idestructSequence(
878 0 : pSequence, pTypeDescr->pWeakRef, pTypeDescr, release );
879 0 : *ppSequence = pNew;
880 : }
881 : }
882 : else
883 : {
884 0 : pNew = allocSeq( 0, 0 );
885 0 : ret = (pNew != 0);
886 0 : if (ret)
887 : {
888 : // easy destruction of empty sequence:
889 0 : if (osl_atomic_decrement( &pSequence->nRefCount ) == 0)
890 0 : rtl_freeMemory( pSequence );
891 0 : *ppSequence = pNew;
892 : }
893 : }
894 :
895 : }
896 81 : return ret;
897 : }
898 :
899 :
900 0 : void SAL_CALL uno_sequence_assign(
901 : uno_Sequence ** ppDest,
902 : uno_Sequence * pSource,
903 : typelib_TypeDescription * pTypeDescr,
904 : uno_ReleaseFunc release )
905 : SAL_THROW_EXTERN_C()
906 : {
907 0 : if (*ppDest != pSource)
908 : {
909 0 : osl_atomic_increment( &pSource->nRefCount );
910 0 : idestructSequence( *ppDest, pTypeDescr->pWeakRef, pTypeDescr, release );
911 0 : *ppDest = pSource;
912 : }
913 0 : }
914 :
915 :
916 7935918 : void SAL_CALL uno_type_sequence_assign(
917 : uno_Sequence ** ppDest,
918 : uno_Sequence * pSource,
919 : typelib_TypeDescriptionReference * pType,
920 : uno_ReleaseFunc release )
921 : SAL_THROW_EXTERN_C()
922 : {
923 7935918 : if (*ppDest != pSource)
924 : {
925 7232391 : osl_atomic_increment( &pSource->nRefCount );
926 7232391 : idestructSequence( *ppDest, pType, 0, release );
927 7232391 : *ppDest = pSource;
928 : }
929 7935918 : }
930 :
931 235262993 : void uno_type_sequence_destroy(
932 : uno_Sequence * sequence, typelib_TypeDescriptionReference * type,
933 : uno_ReleaseFunc release)
934 : SAL_THROW_EXTERN_C()
935 : {
936 235262993 : idestroySequence(sequence, type, nullptr, release);
937 235263005 : }
938 :
939 : }
940 :
941 : /* vim:set shiftwidth=4 softtabstop=4 expandtab: */
|