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 44590456 : static inline uno_Sequence * reallocSeq(
45 : uno_Sequence * pReallocate, sal_Size nElementSize, sal_Int32 nElements )
46 : {
47 : OSL_ASSERT( nElements >= 0 );
48 44590456 : uno_Sequence * pNew = 0;
49 44590456 : sal_uInt32 nSize = calcSeqMemSize( nElementSize, nElements );
50 44590456 : if (nSize > 0)
51 : {
52 44590458 : if (pReallocate == 0)
53 : {
54 37068942 : pNew = (uno_Sequence *) rtl_allocateMemory( nSize );
55 : }
56 : else
57 : {
58 7521516 : pNew = (uno_Sequence *) rtl_reallocateMemory( pReallocate, nSize );
59 : }
60 44590520 : if (pNew != 0)
61 : {
62 : // header init
63 44590517 : pNew->nRefCount = 1;
64 44590517 : pNew->nElements = nElements;
65 : }
66 : }
67 44590518 : return pNew;
68 : }
69 :
70 :
71 37517422 : 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 37517422 : uno_Sequence * pSeq = *ppSeq;
78 37517422 : 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 102834 : if (nAlloc >= 0)
93 102746 : pSeq = reallocSeq( pSeq, sizeof(sal_Bool), nAlloc );
94 102834 : if (pSeq != 0)
95 : {
96 : memset(
97 102834 : pSeq->elements + (sizeof(sal_Bool) * nStartIndex),
98 : 0,
99 205668 : sizeof(sal_Bool) * (nStopIndex - nStartIndex) );
100 : }
101 102834 : break;
102 : case typelib_TypeClass_BYTE:
103 3156045 : if (nAlloc >= 0)
104 1550806 : pSeq = reallocSeq( pSeq, sizeof(sal_Int8), nAlloc );
105 3156044 : if (pSeq != 0)
106 : {
107 : memset(
108 3156044 : pSeq->elements + (sizeof(sal_Int8) * nStartIndex),
109 : 0,
110 6312088 : sizeof(sal_Int8) * (nStopIndex - nStartIndex) );
111 : }
112 3156044 : break;
113 : case typelib_TypeClass_SHORT:
114 : case typelib_TypeClass_UNSIGNED_SHORT:
115 3553 : if (nAlloc >= 0)
116 1983 : pSeq = reallocSeq( pSeq, sizeof(sal_Int16), nAlloc );
117 3553 : if (pSeq != 0)
118 : {
119 : memset(
120 3553 : pSeq->elements + (sizeof(sal_Int16) * nStartIndex),
121 : 0,
122 7106 : sizeof(sal_Int16) * (nStopIndex - nStartIndex) );
123 : }
124 3553 : break;
125 : case typelib_TypeClass_LONG:
126 : case typelib_TypeClass_UNSIGNED_LONG:
127 185336 : if (nAlloc >= 0)
128 144238 : pSeq = reallocSeq( pSeq, sizeof(sal_Int32), nAlloc );
129 185336 : if (pSeq != 0)
130 : {
131 : memset(
132 185336 : pSeq->elements + (sizeof(sal_Int32) * nStartIndex),
133 : 0,
134 370672 : sizeof(sal_Int32) * (nStopIndex - nStartIndex) );
135 : }
136 185336 : break;
137 : case typelib_TypeClass_HYPER:
138 : case typelib_TypeClass_UNSIGNED_HYPER:
139 5313 : if (nAlloc >= 0)
140 4684 : pSeq = reallocSeq( pSeq, sizeof(sal_Int64), nAlloc );
141 5313 : if (pSeq != 0)
142 : {
143 : memset(
144 5313 : pSeq->elements + (sizeof(sal_Int64) * nStartIndex),
145 : 0,
146 10626 : sizeof(sal_Int64) * (nStopIndex - nStartIndex) );
147 : }
148 5313 : break;
149 : case typelib_TypeClass_FLOAT:
150 : {
151 2 : if (nAlloc >= 0)
152 2 : pSeq = reallocSeq( pSeq, sizeof(float), nAlloc );
153 2 : if (pSeq != 0)
154 : {
155 2 : float * pElements = (float *) pSeq->elements;
156 4 : for ( sal_Int32 nPos = nStartIndex; nPos < nStopIndex; ++nPos )
157 : {
158 2 : pElements[nPos] = 0.0;
159 : }
160 : }
161 2 : break;
162 : }
163 : case typelib_TypeClass_DOUBLE:
164 : {
165 462614 : if (nAlloc >= 0)
166 415977 : pSeq = reallocSeq( pSeq, sizeof(double), nAlloc );
167 462614 : if (pSeq != 0)
168 : {
169 462614 : double * pElements = (double *) pSeq->elements;
170 3337724 : for ( sal_Int32 nPos = nStartIndex; nPos < nStopIndex; ++nPos )
171 : {
172 2875110 : pElements[nPos] = 0.0;
173 : }
174 : }
175 462614 : break;
176 : }
177 : case typelib_TypeClass_STRING:
178 : {
179 2702931 : if (nAlloc >= 0)
180 1857708 : pSeq = reallocSeq( pSeq, sizeof(rtl_uString *), nAlloc );
181 2702929 : if (pSeq != 0)
182 : {
183 2702929 : rtl_uString ** pElements = (rtl_uString **) pSeq->elements;
184 16279843 : for ( sal_Int32 nPos = nStartIndex; nPos < nStopIndex; ++nPos )
185 : {
186 13576912 : pElements[nPos] = 0;
187 13576912 : rtl_uString_new( &pElements[nPos] );
188 : }
189 : }
190 2702931 : break;
191 : }
192 : case typelib_TypeClass_TYPE:
193 : {
194 103114 : if (nAlloc >= 0)
195 : {
196 : pSeq = reallocSeq(
197 102500 : pSeq, sizeof(typelib_TypeDescriptionReference *), nAlloc );
198 : }
199 103114 : if (pSeq != 0)
200 : {
201 : typelib_TypeDescriptionReference ** pElements =
202 103114 : (typelib_TypeDescriptionReference **) pSeq->elements;
203 2436192 : for ( sal_Int32 nPos = nStartIndex; nPos < nStopIndex; ++nPos )
204 : {
205 2333078 : pElements[nPos] = _getVoidType();
206 : }
207 : }
208 103114 : break;
209 : }
210 : case typelib_TypeClass_ANY:
211 : {
212 2125959 : if (nAlloc >= 0)
213 1723007 : pSeq = reallocSeq( pSeq, sizeof(uno_Any), nAlloc );
214 2125959 : if (pSeq != 0)
215 : {
216 2125959 : uno_Any * pElements = (uno_Any *) pSeq->elements;
217 9842775 : for ( sal_Int32 nPos = nStartIndex; nPos < nStopIndex; ++nPos )
218 : {
219 7716816 : CONSTRUCT_EMPTY_ANY( &pElements[nPos] );
220 : }
221 : }
222 2125959 : break;
223 : }
224 : case typelib_TypeClass_ENUM:
225 : {
226 78844 : if (nAlloc >= 0)
227 63880 : pSeq = reallocSeq( pSeq, sizeof(sal_Int32), nAlloc );
228 78844 : if (pSeq != 0)
229 : {
230 78844 : typelib_TypeDescription * pElementTypeDescr = 0;
231 78844 : TYPELIB_DANGER_GET( &pElementTypeDescr, pElementType );
232 : sal_Int32 eEnum =
233 : ((typelib_EnumTypeDescription *)
234 78844 : pElementTypeDescr)->nDefaultEnumValue;
235 78844 : TYPELIB_DANGER_RELEASE( pElementTypeDescr );
236 :
237 78844 : sal_Int32 * pElements = (sal_Int32 *) pSeq->elements;
238 4863000 : for ( sal_Int32 nPos = nStartIndex; nPos < nStopIndex; ++nPos )
239 : {
240 4784156 : pElements[nPos] = eEnum;
241 : }
242 : }
243 78844 : break;
244 : }
245 : case typelib_TypeClass_STRUCT:
246 : case typelib_TypeClass_EXCEPTION:
247 : {
248 7555434 : typelib_TypeDescription * pElementTypeDescr = 0;
249 7555434 : TYPELIB_DANGER_GET( &pElementTypeDescr, pElementType );
250 7555434 : sal_Int32 nElementSize = pElementTypeDescr->nSize;
251 :
252 7555434 : if (nAlloc >= 0)
253 3126339 : pSeq = reallocSeq( pSeq, nElementSize, nAlloc );
254 7555434 : if (pSeq != 0)
255 : {
256 7555434 : char * pElements = pSeq->elements;
257 29929764 : for ( sal_Int32 nPos = nStartIndex; nPos < nStopIndex; ++nPos )
258 : {
259 : _defaultConstructStruct(
260 44748660 : pElements + (nElementSize * nPos),
261 67122990 : (typelib_CompoundTypeDescription *)pElementTypeDescr );
262 : }
263 : }
264 :
265 7555434 : TYPELIB_DANGER_RELEASE( pElementTypeDescr );
266 7555434 : break;
267 : }
268 : case typelib_TypeClass_SEQUENCE:
269 : {
270 250515 : if (nAlloc >= 0)
271 144687 : pSeq = reallocSeq( pSeq, sizeof(uno_Sequence *), nAlloc );
272 250515 : if (pSeq != 0)
273 : {
274 : uno_Sequence ** pElements =
275 250515 : (uno_Sequence **) pSeq->elements;
276 736291 : for ( sal_Int32 nPos = nStartIndex; nPos < nStopIndex; ++nPos )
277 : {
278 485776 : pElements[nPos] = createEmptySequence();
279 : }
280 : }
281 250515 : break;
282 : }
283 : case typelib_TypeClass_INTERFACE: // either C++ or C-UNO interface
284 20784928 : if (nAlloc >= 0)
285 20523183 : pSeq = reallocSeq( pSeq, sizeof(void *), nAlloc );
286 20784928 : if (pSeq != 0)
287 : {
288 : memset(
289 20784928 : pSeq->elements + (sizeof(void *) * nStartIndex),
290 : 0,
291 41569856 : sizeof(void *) * (nStopIndex - nStartIndex) );
292 : }
293 20784928 : break;
294 : default:
295 : OSL_FAIL( "### unexpected element type!" );
296 0 : pSeq = 0;
297 0 : break;
298 : }
299 :
300 37517397 : if (pSeq == 0)
301 : {
302 : OSL_ASSERT( nAlloc >= 0 ); // must have been an allocation failure
303 0 : return false;
304 : }
305 : else
306 : {
307 37517397 : *ppSeq = pSeq;
308 37517397 : return true;
309 : }
310 : }
311 :
312 :
313 13979909 : static inline bool icopyConstructFromElements(
314 : uno_Sequence ** ppSeq, void * pSourceElements,
315 : typelib_TypeDescriptionReference * pElementType,
316 : sal_Int32 nStartIndex, sal_Int32 nStopIndex,
317 : uno_AcquireFunc acquire,
318 : sal_Int32 nAlloc = -1 ) // >= 0 means (re)alloc memory for nAlloc elements
319 : {
320 13979909 : uno_Sequence * pSeq = *ppSeq;
321 13979909 : switch (pElementType->eTypeClass)
322 : {
323 : case typelib_TypeClass_CHAR:
324 0 : if (nAlloc >= 0)
325 0 : pSeq = reallocSeq( pSeq, sizeof(sal_Unicode), nAlloc );
326 0 : if (pSeq != 0)
327 : {
328 : memcpy(
329 0 : pSeq->elements + (sizeof(sal_Unicode) * nStartIndex),
330 0 : (char *)pSourceElements + (sizeof(sal_Unicode) * nStartIndex),
331 0 : sizeof(sal_Unicode) * (nStopIndex - nStartIndex) );
332 : }
333 0 : break;
334 : case typelib_TypeClass_BOOLEAN:
335 102 : if (nAlloc >= 0)
336 102 : pSeq = reallocSeq( pSeq, sizeof(sal_Bool), nAlloc );
337 102 : if (pSeq != 0)
338 : {
339 : memcpy(
340 102 : pSeq->elements + (sizeof(sal_Bool) * nStartIndex),
341 102 : (char *)pSourceElements + (sizeof(sal_Bool) * nStartIndex),
342 306 : sizeof(sal_Bool) * (nStopIndex - nStartIndex) );
343 : }
344 102 : break;
345 : case typelib_TypeClass_BYTE:
346 3593275 : if (nAlloc >= 0)
347 3593275 : pSeq = reallocSeq( pSeq, sizeof(sal_Int8), nAlloc );
348 3593275 : if (pSeq != 0)
349 : {
350 : memcpy(
351 3593275 : pSeq->elements + (sizeof(sal_Int8) * nStartIndex),
352 3593275 : (char *)pSourceElements + (sizeof(sal_Int8) * nStartIndex),
353 10779825 : sizeof(sal_Int8) * (nStopIndex - nStartIndex) );
354 : }
355 3593275 : break;
356 : case typelib_TypeClass_SHORT:
357 : case typelib_TypeClass_UNSIGNED_SHORT:
358 1596 : if (nAlloc >= 0)
359 1596 : pSeq = reallocSeq( pSeq, sizeof(sal_Int16), nAlloc );
360 1596 : if (pSeq != 0)
361 : {
362 : memcpy(
363 1596 : pSeq->elements + (sizeof(sal_Int16) * nStartIndex),
364 1596 : (char *)pSourceElements + (sizeof(sal_Int16) * nStartIndex),
365 4788 : sizeof(sal_Int16) * (nStopIndex - nStartIndex) );
366 : }
367 1596 : break;
368 : case typelib_TypeClass_LONG:
369 : case typelib_TypeClass_UNSIGNED_LONG:
370 44024 : if (nAlloc >= 0)
371 44024 : pSeq = reallocSeq( pSeq, sizeof(sal_Int32), nAlloc );
372 44024 : if (pSeq != 0)
373 : {
374 : memcpy(
375 44024 : pSeq->elements + (sizeof(sal_Int32) * nStartIndex),
376 44024 : (char *)pSourceElements + (sizeof(sal_Int32) * nStartIndex),
377 132072 : sizeof(sal_Int32) * (nStopIndex - nStartIndex) );
378 : }
379 44024 : break;
380 : case typelib_TypeClass_HYPER:
381 : case typelib_TypeClass_UNSIGNED_HYPER:
382 687 : if (nAlloc >= 0)
383 687 : pSeq = reallocSeq( pSeq, sizeof(sal_Int64), nAlloc );
384 687 : if (pSeq != 0)
385 : {
386 : memcpy(
387 687 : pSeq->elements + (sizeof(sal_Int64) * nStartIndex),
388 687 : (char *)pSourceElements + (sizeof(sal_Int64) * nStartIndex),
389 2061 : sizeof(sal_Int64) * (nStopIndex - nStartIndex) );
390 : }
391 687 : break;
392 : case typelib_TypeClass_FLOAT:
393 10 : if (nAlloc >= 0)
394 10 : pSeq = reallocSeq( pSeq, sizeof(float), nAlloc );
395 10 : if (pSeq != 0)
396 : {
397 : memcpy(
398 10 : pSeq->elements + (sizeof(float) * nStartIndex),
399 10 : (char *)pSourceElements + (sizeof(float) * nStartIndex),
400 30 : sizeof(float) * (nStopIndex - nStartIndex) );
401 : }
402 10 : break;
403 : case typelib_TypeClass_DOUBLE:
404 66384 : if (nAlloc >= 0)
405 66384 : pSeq = reallocSeq( pSeq, sizeof(double), nAlloc );
406 66384 : if (pSeq != 0)
407 : {
408 : memcpy(
409 66384 : pSeq->elements + (sizeof(double) * nStartIndex),
410 66384 : (char *)pSourceElements + (sizeof(double) * nStartIndex),
411 199152 : sizeof(double) * (nStopIndex - nStartIndex) );
412 : }
413 66384 : break;
414 : case typelib_TypeClass_ENUM:
415 16914 : if (nAlloc >= 0)
416 16914 : pSeq = reallocSeq( pSeq, sizeof(sal_Int32), nAlloc );
417 16914 : if (pSeq != 0)
418 : {
419 : memcpy(
420 16914 : pSeq->elements + (sizeof(sal_Int32) * nStartIndex),
421 16914 : (char *)pSourceElements + (sizeof(sal_Int32) * nStartIndex),
422 50742 : sizeof(sal_Int32) * (nStopIndex - nStartIndex) );
423 : }
424 16914 : break;
425 : case typelib_TypeClass_STRING:
426 : {
427 1931390 : if (nAlloc >= 0)
428 1931390 : pSeq = reallocSeq( pSeq, sizeof(rtl_uString *), nAlloc );
429 1931390 : if (pSeq != 0)
430 : {
431 1931390 : rtl_uString ** pDestElements = (rtl_uString **) pSeq->elements;
432 4195831 : for ( sal_Int32 nPos = nStartIndex; nPos < nStopIndex; ++nPos )
433 : {
434 : // https://communities.coverity.com/thread/2993
435 : /* coverity[overrun-buffer-arg] */
436 : ::rtl_uString_acquire(
437 2264441 : ((rtl_uString **)pSourceElements)[nPos] );
438 2264441 : pDestElements[nPos] = ((rtl_uString **)pSourceElements)[nPos];
439 : }
440 : }
441 1931390 : break;
442 : }
443 : case typelib_TypeClass_TYPE:
444 : {
445 682 : if (nAlloc >= 0)
446 : {
447 : pSeq = reallocSeq(
448 682 : pSeq, sizeof(typelib_TypeDescriptionReference *), nAlloc );
449 : }
450 682 : if (pSeq != 0)
451 : {
452 : typelib_TypeDescriptionReference ** pDestElements =
453 682 : (typelib_TypeDescriptionReference **) pSeq->elements;
454 974 : for ( sal_Int32 nPos = nStartIndex; nPos < nStopIndex; ++nPos )
455 : {
456 292 : TYPE_ACQUIRE(
457 : ((typelib_TypeDescriptionReference **)
458 : pSourceElements)[nPos] );
459 292 : pDestElements[nPos] =
460 : ((typelib_TypeDescriptionReference **)
461 292 : pSourceElements)[nPos];
462 : }
463 : }
464 682 : break;
465 : }
466 : case typelib_TypeClass_ANY:
467 : {
468 1132614 : if (nAlloc >= 0)
469 1132614 : pSeq = reallocSeq( pSeq, sizeof(uno_Any), nAlloc );
470 1132614 : if (pSeq != 0)
471 : {
472 1132614 : uno_Any * pDestElements = (uno_Any *) pSeq->elements;
473 2734246 : for ( sal_Int32 nPos = nStartIndex; nPos < nStopIndex; ++nPos )
474 : {
475 1601632 : uno_Any * pSource = (uno_Any *)pSourceElements + nPos;
476 : _copyConstructAny(
477 : &pDestElements[nPos],
478 : pSource->pData,
479 : pSource->pType, 0,
480 1601632 : acquire, 0 );
481 : }
482 : }
483 1132614 : break;
484 : }
485 : case typelib_TypeClass_STRUCT:
486 : case typelib_TypeClass_EXCEPTION:
487 : {
488 6379474 : typelib_TypeDescription * pElementTypeDescr = 0;
489 6379474 : TYPELIB_DANGER_GET( &pElementTypeDescr, pElementType );
490 6379474 : sal_Int32 nElementSize = pElementTypeDescr->nSize;
491 :
492 6379474 : if (nAlloc >= 0)
493 6379474 : pSeq = reallocSeq( pSeq, nElementSize, nAlloc );
494 6379474 : if (pSeq != 0)
495 : {
496 6379474 : char * pDestElements = pSeq->elements;
497 :
498 : typelib_CompoundTypeDescription * pTypeDescr =
499 6379474 : (typelib_CompoundTypeDescription *)pElementTypeDescr;
500 44139231 : for ( sal_Int32 nPos = nStartIndex; nPos < nStopIndex; ++nPos )
501 : {
502 : char * pDest =
503 37759757 : pDestElements + (nElementSize * nPos);
504 : char * pSource =
505 37759757 : (char *)pSourceElements + (nElementSize * nPos);
506 :
507 37759757 : if (pTypeDescr->pBaseTypeDescription)
508 : {
509 : // copy base value
510 : _copyConstructStruct(
511 : pDest, pSource,
512 82287 : pTypeDescr->pBaseTypeDescription, acquire, 0 );
513 : }
514 :
515 : // then copy members
516 : typelib_TypeDescriptionReference ** ppTypeRefs =
517 37759757 : pTypeDescr->ppTypeRefs;
518 37759757 : sal_Int32 * pMemberOffsets = pTypeDescr->pMemberOffsets;
519 37759757 : sal_Int32 nDescr = pTypeDescr->nMembers;
520 :
521 207436109 : while (nDescr--)
522 : {
523 : ::uno_type_copyData(
524 263833190 : pDest + pMemberOffsets[nDescr],
525 263833190 : pSource + pMemberOffsets[nDescr],
526 527666380 : ppTypeRefs[nDescr], acquire );
527 : }
528 : }
529 : }
530 :
531 6379474 : TYPELIB_DANGER_RELEASE( pElementTypeDescr );
532 6379474 : break;
533 : }
534 : case typelib_TypeClass_SEQUENCE: // sequence of sequence
535 : {
536 251611 : if (nAlloc >= 0)
537 251611 : pSeq = reallocSeq( pSeq, sizeof(uno_Sequence *), nAlloc );
538 251611 : if (pSeq != 0)
539 : {
540 251611 : typelib_TypeDescription * pElementTypeDescr = 0;
541 251611 : TYPELIB_DANGER_GET( &pElementTypeDescr, pElementType );
542 : typelib_TypeDescriptionReference * pSeqElementType =
543 251611 : ((typelib_IndirectTypeDescription *) pElementTypeDescr)->pType;
544 251611 : uno_Sequence ** pDestElements = (uno_Sequence **) pSeq->elements;
545 10445548 : for ( sal_Int32 nPos = nStartIndex; nPos < nStopIndex; ++nPos )
546 : {
547 : uno_Sequence * pNew = icopyConstructSequence(
548 10193937 : ((uno_Sequence **) pSourceElements)[nPos],
549 10193937 : pSeqElementType, acquire, 0 );
550 : OSL_ASSERT( pNew != 0 );
551 : // ought never be a memory allocation problem,
552 : // because of reference counted sequence handles
553 10193937 : pDestElements[ nPos ] = pNew;
554 : }
555 251611 : TYPELIB_DANGER_RELEASE( pElementTypeDescr );
556 : }
557 251611 : break;
558 : }
559 : case typelib_TypeClass_INTERFACE:
560 : {
561 561146 : if (nAlloc >= 0)
562 561146 : pSeq = reallocSeq( pSeq, sizeof(void *), nAlloc );
563 561146 : if (pSeq != 0)
564 : {
565 561146 : void ** pDestElements = (void **) pSeq->elements;
566 917564 : for ( sal_Int32 nPos = nStartIndex; nPos < nStopIndex; ++nPos )
567 : {
568 712836 : _acquire( pDestElements[nPos] =
569 712836 : ((void **)pSourceElements)[nPos], acquire );
570 : }
571 : }
572 561146 : break;
573 : }
574 : default:
575 : OSL_FAIL( "### unexpected element type!" );
576 0 : pSeq = 0;
577 0 : break;
578 : }
579 :
580 13979905 : if (pSeq == 0)
581 : {
582 : OSL_ASSERT( nAlloc >= 0 ); // must have been an allocation failure
583 0 : return false;
584 : }
585 : else
586 : {
587 13979905 : *ppSeq = pSeq;
588 13979905 : return true;
589 : }
590 : }
591 :
592 :
593 15454170 : static inline bool ireallocSequence(
594 : uno_Sequence ** ppSequence,
595 : typelib_TypeDescriptionReference * pElementType,
596 : sal_Int32 nSize,
597 : uno_AcquireFunc acquire, uno_ReleaseFunc release )
598 : {
599 15454170 : bool ret = true;
600 15454170 : uno_Sequence * pSeq = *ppSequence;
601 15454170 : sal_Int32 nElements = pSeq->nElements;
602 :
603 26364765 : if (pSeq->nRefCount > 1 ||
604 : // not mem-copyable elements?
605 21787806 : typelib_TypeClass_ANY == pElementType->eTypeClass ||
606 18398727 : typelib_TypeClass_STRUCT == pElementType->eTypeClass ||
607 7521516 : typelib_TypeClass_EXCEPTION == pElementType->eTypeClass)
608 : {
609 : // split sequence and construct new one from scratch
610 7932654 : uno_Sequence * pNew = 0;
611 :
612 7932654 : sal_Int32 nRest = nSize - nElements;
613 7932654 : sal_Int32 nCopy = (nRest > 0 ? nElements : nSize);
614 :
615 7932654 : if (nCopy >= 0)
616 : {
617 : ret = icopyConstructFromElements(
618 : &pNew, pSeq->elements, pElementType,
619 : 0, nCopy, acquire,
620 7932656 : nSize ); // alloc to nSize
621 : }
622 7932655 : if (ret && nRest > 0)
623 : {
624 : ret = idefaultConstructElements(
625 : &pNew, pElementType,
626 : nCopy, nSize,
627 7755685 : nCopy >= 0 ? -1 /* no mem allocation */ : nSize );
628 : }
629 :
630 7932651 : if (ret)
631 : {
632 : // destruct sequence
633 7932653 : if (osl_atomic_decrement( &pSeq->nRefCount ) == 0)
634 : {
635 3389079 : if (nElements > 0)
636 : {
637 : idestructElements(
638 : pSeq->elements, pElementType,
639 3384744 : 0, nElements, release );
640 : }
641 3389079 : rtl_freeMemory( pSeq );
642 : }
643 7932658 : *ppSequence = pNew;
644 7932656 : }
645 : }
646 : else
647 : {
648 : OSL_ASSERT( pSeq->nRefCount == 1 );
649 7521516 : if (nSize > nElements) // default construct the rest
650 : {
651 : ret = idefaultConstructElements(
652 : ppSequence, pElementType,
653 : nElements, nSize,
654 6672645 : nSize ); // realloc to nSize
655 : }
656 : else // or destruct the rest and realloc mem
657 : {
658 : sal_Int32 nElementSize = idestructElements(
659 : pSeq->elements, pElementType,
660 848871 : nSize, nElements, release );
661 : // warning: it is assumed that the following will never fail,
662 : // else this leads to a sequence null handle
663 848871 : *ppSequence = reallocSeq( pSeq, nElementSize, nSize );
664 : OSL_ASSERT( *ppSequence != 0 );
665 848871 : ret = (*ppSequence != 0);
666 : }
667 : }
668 :
669 15454172 : return ret;
670 : }
671 :
672 : }
673 :
674 : extern "C"
675 : {
676 :
677 :
678 58339639 : sal_Bool SAL_CALL uno_type_sequence_construct(
679 : uno_Sequence ** ppSequence, typelib_TypeDescriptionReference * pType,
680 : void * pElements, sal_Int32 len,
681 : uno_AcquireFunc acquire )
682 : SAL_THROW_EXTERN_C()
683 : {
684 : assert( len >= 0 );
685 : bool ret;
686 58339639 : if (len)
687 : {
688 26881720 : typelib_TypeDescription * pTypeDescr = 0;
689 26881720 : TYPELIB_DANGER_GET( &pTypeDescr, pType );
690 :
691 : typelib_TypeDescriptionReference * pElementType =
692 26881722 : ((typelib_IndirectTypeDescription *)pTypeDescr)->pType;
693 :
694 26881722 : *ppSequence = 0;
695 26881722 : if (pElements == 0)
696 : {
697 : ret = idefaultConstructElements(
698 : ppSequence, pElementType,
699 : 0, len,
700 23088834 : len ); // alloc to len
701 : }
702 : else
703 : {
704 : ret = icopyConstructFromElements(
705 : ppSequence, pElements, pElementType,
706 : 0, len, acquire,
707 3792888 : len ); // alloc to len
708 : }
709 :
710 26881726 : TYPELIB_DANGER_RELEASE( pTypeDescr );
711 : }
712 : else
713 : {
714 31457919 : *ppSequence = createEmptySequence();
715 31457922 : ret = true;
716 : }
717 :
718 : OSL_ASSERT( (*ppSequence != 0) == ret );
719 58339609 : return ret;
720 : }
721 :
722 :
723 264 : sal_Bool SAL_CALL uno_sequence_construct(
724 : uno_Sequence ** ppSequence, typelib_TypeDescription * pTypeDescr,
725 : void * pElements, sal_Int32 len,
726 : uno_AcquireFunc acquire )
727 : SAL_THROW_EXTERN_C()
728 : {
729 : bool ret;
730 264 : if (len > 0)
731 : {
732 : typelib_TypeDescriptionReference * pElementType =
733 258 : ((typelib_IndirectTypeDescription *)pTypeDescr)->pType;
734 :
735 258 : *ppSequence = 0;
736 258 : if (pElements == 0)
737 : {
738 : ret = idefaultConstructElements(
739 : ppSequence, pElementType,
740 : 0, len,
741 258 : len ); // alloc to len
742 : }
743 : else
744 : {
745 : ret = icopyConstructFromElements(
746 : ppSequence, pElements, pElementType,
747 : 0, len, acquire,
748 0 : len ); // alloc to len
749 : }
750 : }
751 : else
752 : {
753 6 : *ppSequence = createEmptySequence();
754 6 : ret = true;
755 : }
756 :
757 : OSL_ASSERT( (*ppSequence != 0) == ret );
758 264 : return ret;
759 : }
760 :
761 :
762 17364730 : sal_Bool SAL_CALL uno_type_sequence_realloc(
763 : uno_Sequence ** ppSequence, typelib_TypeDescriptionReference * pType,
764 : sal_Int32 nSize, uno_AcquireFunc acquire, uno_ReleaseFunc release )
765 : SAL_THROW_EXTERN_C()
766 : {
767 : OSL_ENSURE( ppSequence, "### null ptr!" );
768 : OSL_ENSURE( nSize >= 0, "### new size must be at least 0!" );
769 :
770 17364730 : bool ret = true;
771 17364730 : if (nSize != (*ppSequence)->nElements)
772 : {
773 15454093 : typelib_TypeDescription * pTypeDescr = 0;
774 15454093 : TYPELIB_DANGER_GET( &pTypeDescr, pType );
775 : ret = ireallocSequence(
776 : ppSequence, ((typelib_IndirectTypeDescription *)pTypeDescr)->pType,
777 15454092 : nSize, acquire, release );
778 15454092 : TYPELIB_DANGER_RELEASE( pTypeDescr );
779 : }
780 17364729 : return ret;
781 : }
782 :
783 :
784 90 : sal_Bool SAL_CALL uno_sequence_realloc(
785 : uno_Sequence ** ppSequence, typelib_TypeDescription * pTypeDescr,
786 : sal_Int32 nSize, uno_AcquireFunc acquire, uno_ReleaseFunc release )
787 : SAL_THROW_EXTERN_C()
788 : {
789 : OSL_ENSURE( ppSequence, "### null ptr!" );
790 : OSL_ENSURE( nSize >= 0, "### new size must be at least 0!" );
791 :
792 90 : bool ret = true;
793 90 : if (nSize != (*ppSequence)->nElements)
794 : {
795 : ret = ireallocSequence(
796 : ppSequence, ((typelib_IndirectTypeDescription *)pTypeDescr)->pType,
797 80 : nSize, acquire, release );
798 : }
799 90 : return ret;
800 : }
801 :
802 :
803 168771234 : sal_Bool SAL_CALL uno_type_sequence_reference2One(
804 : uno_Sequence ** ppSequence,
805 : typelib_TypeDescriptionReference * pType,
806 : uno_AcquireFunc acquire, uno_ReleaseFunc release )
807 : SAL_THROW_EXTERN_C()
808 : {
809 : OSL_ENSURE( ppSequence, "### null ptr!" );
810 168771234 : bool ret = true;
811 168771234 : uno_Sequence * pSequence = *ppSequence;
812 168771234 : if (pSequence->nRefCount > 1)
813 : {
814 3650466 : uno_Sequence * pNew = 0;
815 3650466 : if (pSequence->nElements > 0)
816 : {
817 2254363 : typelib_TypeDescription * pTypeDescr = 0;
818 2254363 : TYPELIB_DANGER_GET( &pTypeDescr, pType );
819 :
820 : ret = icopyConstructFromElements(
821 : &pNew, pSequence->elements,
822 : ((typelib_IndirectTypeDescription *)pTypeDescr)->pType,
823 : 0, pSequence->nElements, acquire,
824 2254363 : pSequence->nElements ); // alloc nElements
825 2254363 : if (ret)
826 : {
827 2254363 : idestructSequence( *ppSequence, pType, pTypeDescr, release );
828 2254363 : *ppSequence = pNew;
829 : }
830 :
831 2254363 : TYPELIB_DANGER_RELEASE( pTypeDescr );
832 : }
833 : else
834 : {
835 1396103 : pNew = allocSeq( 0, 0 );
836 1396103 : ret = (pNew != 0);
837 1396103 : if (ret)
838 : {
839 : // easy destruction of empty sequence:
840 1396103 : if (osl_atomic_decrement( &pSequence->nRefCount ) == 0)
841 0 : rtl_freeMemory( pSequence );
842 1396103 : *ppSequence = pNew;
843 : }
844 : }
845 : }
846 168771234 : return ret;
847 : }
848 :
849 :
850 162 : sal_Bool SAL_CALL uno_sequence_reference2One(
851 : uno_Sequence ** ppSequence,
852 : typelib_TypeDescription * pTypeDescr,
853 : uno_AcquireFunc acquire, uno_ReleaseFunc release )
854 : SAL_THROW_EXTERN_C()
855 : {
856 : OSL_ENSURE( ppSequence, "### null ptr!" );
857 162 : bool ret = true;
858 162 : uno_Sequence * pSequence = *ppSequence;
859 162 : if (pSequence->nRefCount > 1)
860 : {
861 0 : uno_Sequence * pNew = 0;
862 0 : if (pSequence->nElements > 0)
863 : {
864 : ret = icopyConstructFromElements(
865 : &pNew, pSequence->elements,
866 : ((typelib_IndirectTypeDescription *)pTypeDescr)->pType,
867 : 0, pSequence->nElements, acquire,
868 0 : pSequence->nElements ); // alloc nElements
869 0 : if (ret)
870 : {
871 : idestructSequence(
872 0 : pSequence, pTypeDescr->pWeakRef, pTypeDescr, release );
873 0 : *ppSequence = pNew;
874 : }
875 : }
876 : else
877 : {
878 0 : pNew = allocSeq( 0, 0 );
879 0 : ret = (pNew != 0);
880 0 : if (ret)
881 : {
882 : // easy destruction of empty sequence:
883 0 : if (osl_atomic_decrement( &pSequence->nRefCount ) == 0)
884 0 : rtl_freeMemory( pSequence );
885 0 : *ppSequence = pNew;
886 : }
887 : }
888 :
889 : }
890 162 : return ret;
891 : }
892 :
893 :
894 0 : void SAL_CALL uno_sequence_assign(
895 : uno_Sequence ** ppDest,
896 : uno_Sequence * pSource,
897 : typelib_TypeDescription * pTypeDescr,
898 : uno_ReleaseFunc release )
899 : SAL_THROW_EXTERN_C()
900 : {
901 0 : if (*ppDest != pSource)
902 : {
903 0 : osl_atomic_increment( &pSource->nRefCount );
904 0 : idestructSequence( *ppDest, pTypeDescr->pWeakRef, pTypeDescr, release );
905 0 : *ppDest = pSource;
906 : }
907 0 : }
908 :
909 :
910 13272525 : void SAL_CALL uno_type_sequence_assign(
911 : uno_Sequence ** ppDest,
912 : uno_Sequence * pSource,
913 : typelib_TypeDescriptionReference * pType,
914 : uno_ReleaseFunc release )
915 : SAL_THROW_EXTERN_C()
916 : {
917 13272525 : if (*ppDest != pSource)
918 : {
919 12277018 : osl_atomic_increment( &pSource->nRefCount );
920 12277018 : idestructSequence( *ppDest, pType, 0, release );
921 12277018 : *ppDest = pSource;
922 : }
923 13272525 : }
924 :
925 23783737 : void uno_type_sequence_destroy(
926 : uno_Sequence * sequence, typelib_TypeDescriptionReference * type,
927 : uno_ReleaseFunc release)
928 : SAL_THROW_EXTERN_C()
929 : {
930 23783737 : idestroySequence(sequence, type, nullptr, release);
931 23783769 : }
932 :
933 : }
934 :
935 : /* vim:set shiftwidth=4 softtabstop=4 expandtab: */
|