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 2226203 : static inline uno_Sequence * reallocSeq(
42 : uno_Sequence * pReallocate, sal_Size nElementSize, sal_Int32 nElements )
43 : {
44 : OSL_ASSERT( nElements >= 0 );
45 2226203 : uno_Sequence * pNew = 0;
46 2226203 : sal_uInt32 nSize = calcSeqMemSize( nElementSize, nElements );
47 2226202 : if (nSize > 0)
48 : {
49 2226203 : if (pReallocate == 0)
50 : {
51 1896824 : pNew = (uno_Sequence *) rtl_allocateMemory( nSize );
52 : }
53 : else
54 : {
55 329379 : pNew = (uno_Sequence *) rtl_reallocateMemory( pReallocate, nSize );
56 : }
57 2226204 : if (pNew != 0)
58 : {
59 : // header init
60 2226203 : pNew->nRefCount = 1;
61 2226203 : pNew->nElements = nElements;
62 : }
63 : }
64 2226203 : return pNew;
65 : }
66 :
67 : //------------------------------------------------------------------------------
68 1704946 : 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 1704946 : uno_Sequence * pSeq = *ppSeq;
75 1704946 : 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 472 : if (nAlloc >= 0)
90 472 : pSeq = reallocSeq( pSeq, sizeof(sal_Bool), nAlloc );
91 472 : if (pSeq != 0)
92 : {
93 : memset(
94 472 : pSeq->elements + (sizeof(sal_Bool) * nStartIndex),
95 : 0,
96 944 : sizeof(sal_Bool) * (nStopIndex - nStartIndex) );
97 : }
98 472 : break;
99 : case typelib_TypeClass_BYTE:
100 177456 : if (nAlloc >= 0)
101 123664 : pSeq = reallocSeq( pSeq, sizeof(sal_Int8), nAlloc );
102 177456 : if (pSeq != 0)
103 : {
104 : memset(
105 177456 : pSeq->elements + (sizeof(sal_Int8) * nStartIndex),
106 : 0,
107 354912 : sizeof(sal_Int8) * (nStopIndex - nStartIndex) );
108 : }
109 177456 : break;
110 : case typelib_TypeClass_SHORT:
111 : case typelib_TypeClass_UNSIGNED_SHORT:
112 1399 : if (nAlloc >= 0)
113 1063 : pSeq = reallocSeq( pSeq, sizeof(sal_Int16), nAlloc );
114 1399 : if (pSeq != 0)
115 : {
116 : memset(
117 1399 : pSeq->elements + (sizeof(sal_Int16) * nStartIndex),
118 : 0,
119 2798 : sizeof(sal_Int16) * (nStopIndex - nStartIndex) );
120 : }
121 1399 : break;
122 : case typelib_TypeClass_LONG:
123 : case typelib_TypeClass_UNSIGNED_LONG:
124 22564 : if (nAlloc >= 0)
125 15171 : pSeq = reallocSeq( pSeq, sizeof(sal_Int32), nAlloc );
126 22564 : if (pSeq != 0)
127 : {
128 : memset(
129 22564 : pSeq->elements + (sizeof(sal_Int32) * nStartIndex),
130 : 0,
131 45128 : sizeof(sal_Int32) * (nStopIndex - nStartIndex) );
132 : }
133 22564 : break;
134 : case typelib_TypeClass_HYPER:
135 : case typelib_TypeClass_UNSIGNED_HYPER:
136 1179 : if (nAlloc >= 0)
137 1040 : pSeq = reallocSeq( pSeq, sizeof(sal_Int64), nAlloc );
138 1179 : if (pSeq != 0)
139 : {
140 : memset(
141 1179 : pSeq->elements + (sizeof(sal_Int64) * nStartIndex),
142 : 0,
143 2358 : sizeof(sal_Int64) * (nStopIndex - nStartIndex) );
144 : }
145 1179 : break;
146 : case typelib_TypeClass_FLOAT:
147 : {
148 2 : if (nAlloc >= 0)
149 2 : pSeq = reallocSeq( pSeq, sizeof(float), nAlloc );
150 2 : if (pSeq != 0)
151 : {
152 2 : float * pElements = (float *) pSeq->elements;
153 4 : for ( sal_Int32 nPos = nStartIndex; nPos < nStopIndex; ++nPos )
154 : {
155 2 : pElements[nPos] = 0.0;
156 : }
157 : }
158 2 : break;
159 : }
160 : case typelib_TypeClass_DOUBLE:
161 : {
162 36170 : if (nAlloc >= 0)
163 32152 : pSeq = reallocSeq( pSeq, sizeof(double), nAlloc );
164 36170 : if (pSeq != 0)
165 : {
166 36170 : double * pElements = (double *) pSeq->elements;
167 121230 : for ( sal_Int32 nPos = nStartIndex; nPos < nStopIndex; ++nPos )
168 : {
169 85060 : pElements[nPos] = 0.0;
170 : }
171 : }
172 36170 : break;
173 : }
174 : case typelib_TypeClass_STRING:
175 : {
176 220222 : if (nAlloc >= 0)
177 124053 : pSeq = reallocSeq( pSeq, sizeof(rtl_uString *), nAlloc );
178 220222 : if (pSeq != 0)
179 : {
180 220222 : rtl_uString ** pElements = (rtl_uString **) pSeq->elements;
181 1095722 : for ( sal_Int32 nPos = nStartIndex; nPos < nStopIndex; ++nPos )
182 : {
183 875500 : pElements[nPos] = 0;
184 875500 : rtl_uString_new( &pElements[nPos] );
185 : }
186 : }
187 220222 : break;
188 : }
189 : case typelib_TypeClass_TYPE:
190 : {
191 6357 : if (nAlloc >= 0)
192 : {
193 : pSeq = reallocSeq(
194 6307 : pSeq, sizeof(typelib_TypeDescriptionReference *), nAlloc );
195 : }
196 6357 : if (pSeq != 0)
197 : {
198 : typelib_TypeDescriptionReference ** pElements =
199 6357 : (typelib_TypeDescriptionReference **) pSeq->elements;
200 85133 : for ( sal_Int32 nPos = nStartIndex; nPos < nStopIndex; ++nPos )
201 : {
202 78776 : pElements[nPos] = _getVoidType();
203 : }
204 : }
205 6357 : break;
206 : }
207 : case typelib_TypeClass_ANY:
208 : {
209 134511 : if (nAlloc >= 0)
210 113658 : pSeq = reallocSeq( pSeq, sizeof(uno_Any), nAlloc );
211 134511 : if (pSeq != 0)
212 : {
213 134511 : uno_Any * pElements = (uno_Any *) pSeq->elements;
214 461159 : for ( sal_Int32 nPos = nStartIndex; nPos < nStopIndex; ++nPos )
215 : {
216 326648 : CONSTRUCT_EMPTY_ANY( &pElements[nPos] );
217 : }
218 : }
219 134511 : break;
220 : }
221 : case typelib_TypeClass_ENUM:
222 : {
223 556 : if (nAlloc >= 0)
224 548 : pSeq = reallocSeq( pSeq, sizeof(sal_Int32), nAlloc );
225 556 : if (pSeq != 0)
226 : {
227 556 : typelib_TypeDescription * pElementTypeDescr = 0;
228 556 : TYPELIB_DANGER_GET( &pElementTypeDescr, pElementType );
229 : sal_Int32 eEnum =
230 : ((typelib_EnumTypeDescription *)
231 556 : pElementTypeDescr)->nDefaultEnumValue;
232 556 : TYPELIB_DANGER_RELEASE( pElementTypeDescr );
233 :
234 556 : sal_Int32 * pElements = (sal_Int32 *) pSeq->elements;
235 24178 : for ( sal_Int32 nPos = nStartIndex; nPos < nStopIndex; ++nPos )
236 : {
237 23622 : pElements[nPos] = eEnum;
238 : }
239 : }
240 556 : break;
241 : }
242 : case typelib_TypeClass_STRUCT:
243 : case typelib_TypeClass_EXCEPTION:
244 : {
245 539994 : typelib_TypeDescription * pElementTypeDescr = 0;
246 539994 : TYPELIB_DANGER_GET( &pElementTypeDescr, pElementType );
247 539994 : sal_Int32 nElementSize = pElementTypeDescr->nSize;
248 :
249 539994 : if (nAlloc >= 0)
250 182586 : pSeq = reallocSeq( pSeq, nElementSize, nAlloc );
251 539994 : if (pSeq != 0)
252 : {
253 539994 : char * pElements = pSeq->elements;
254 2646172 : for ( sal_Int32 nPos = nStartIndex; nPos < nStopIndex; ++nPos )
255 : {
256 : _defaultConstructStruct(
257 2106178 : pElements + (nElementSize * nPos),
258 4212356 : (typelib_CompoundTypeDescription *)pElementTypeDescr );
259 : }
260 : }
261 :
262 539994 : 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 13695 : if (nAlloc >= 0)
327 6647 : pSeq = reallocSeq( pSeq, sizeof(uno_Sequence *), nAlloc );
328 13695 : if (pSeq != 0)
329 : {
330 : uno_Sequence ** pElements =
331 13695 : (uno_Sequence **) pSeq->elements;
332 34202 : for ( sal_Int32 nPos = nStartIndex; nPos < nStopIndex; ++nPos )
333 : {
334 20507 : pElements[nPos] = createEmptySequence();
335 : }
336 : }
337 13695 : break;
338 : }
339 : case typelib_TypeClass_INTERFACE: // either C++ or C-UNO interface
340 550369 : if (nAlloc >= 0)
341 495982 : pSeq = reallocSeq( pSeq, sizeof(void *), nAlloc );
342 550369 : if (pSeq != 0)
343 : {
344 : memset(
345 550369 : pSeq->elements + (sizeof(void *) * nStartIndex),
346 : 0,
347 1100738 : sizeof(void *) * (nStopIndex - nStartIndex) );
348 : }
349 550369 : break;
350 : default:
351 : OSL_FAIL( "### unexpected element type!" );
352 0 : pSeq = 0;
353 0 : break;
354 : }
355 :
356 1704946 : if (pSeq == 0)
357 : {
358 : OSL_ASSERT( nAlloc >= 0 ); // must have been an allocation failure
359 0 : return false;
360 : }
361 : else
362 : {
363 1704946 : *ppSeq = pSeq;
364 1704946 : return true;
365 : }
366 : }
367 :
368 : //------------------------------------------------------------------------------
369 1057328 : 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 1057328 : uno_Sequence * pSeq = *ppSeq;
377 1057328 : 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 14 : if (nAlloc >= 0)
392 14 : pSeq = reallocSeq( pSeq, sizeof(sal_Bool), nAlloc );
393 14 : if (pSeq != 0)
394 : {
395 : memcpy(
396 14 : pSeq->elements + (sizeof(sal_Bool) * nStartIndex),
397 : (char *)pSourceElements + (sizeof(sal_Bool) * nStartIndex),
398 28 : sizeof(sal_Bool) * (nStopIndex - nStartIndex) );
399 : }
400 14 : break;
401 : case typelib_TypeClass_BYTE:
402 358652 : if (nAlloc >= 0)
403 358652 : pSeq = reallocSeq( pSeq, sizeof(sal_Int8), nAlloc );
404 358652 : if (pSeq != 0)
405 : {
406 : memcpy(
407 358652 : pSeq->elements + (sizeof(sal_Int8) * nStartIndex),
408 : (char *)pSourceElements + (sizeof(sal_Int8) * nStartIndex),
409 717304 : sizeof(sal_Int8) * (nStopIndex - nStartIndex) );
410 : }
411 358652 : break;
412 : case typelib_TypeClass_SHORT:
413 : case typelib_TypeClass_UNSIGNED_SHORT:
414 358 : if (nAlloc >= 0)
415 358 : pSeq = reallocSeq( pSeq, sizeof(sal_Int16), nAlloc );
416 358 : if (pSeq != 0)
417 : {
418 : memcpy(
419 358 : pSeq->elements + (sizeof(sal_Int16) * nStartIndex),
420 : (char *)pSourceElements + (sizeof(sal_Int16) * nStartIndex),
421 716 : sizeof(sal_Int16) * (nStopIndex - nStartIndex) );
422 : }
423 358 : break;
424 : case typelib_TypeClass_LONG:
425 : case typelib_TypeClass_UNSIGNED_LONG:
426 7479 : if (nAlloc >= 0)
427 7479 : pSeq = reallocSeq( pSeq, sizeof(sal_Int32), nAlloc );
428 7479 : if (pSeq != 0)
429 : {
430 : memcpy(
431 7479 : pSeq->elements + (sizeof(sal_Int32) * nStartIndex),
432 : (char *)pSourceElements + (sizeof(sal_Int32) * nStartIndex),
433 14958 : sizeof(sal_Int32) * (nStopIndex - nStartIndex) );
434 : }
435 7479 : break;
436 : case typelib_TypeClass_HYPER:
437 : case typelib_TypeClass_UNSIGNED_HYPER:
438 239 : if (nAlloc >= 0)
439 239 : pSeq = reallocSeq( pSeq, sizeof(sal_Int64), nAlloc );
440 239 : if (pSeq != 0)
441 : {
442 : memcpy(
443 239 : pSeq->elements + (sizeof(sal_Int64) * nStartIndex),
444 : (char *)pSourceElements + (sizeof(sal_Int64) * nStartIndex),
445 478 : sizeof(sal_Int64) * (nStopIndex - nStartIndex) );
446 : }
447 239 : break;
448 : case typelib_TypeClass_FLOAT:
449 10 : if (nAlloc >= 0)
450 10 : pSeq = reallocSeq( pSeq, sizeof(float), nAlloc );
451 10 : if (pSeq != 0)
452 : {
453 : memcpy(
454 10 : pSeq->elements + (sizeof(float) * nStartIndex),
455 : (char *)pSourceElements + (sizeof(float) * nStartIndex),
456 20 : sizeof(float) * (nStopIndex - nStartIndex) );
457 : }
458 10 : break;
459 : case typelib_TypeClass_DOUBLE:
460 4192 : if (nAlloc >= 0)
461 4192 : pSeq = reallocSeq( pSeq, sizeof(double), nAlloc );
462 4192 : if (pSeq != 0)
463 : {
464 : memcpy(
465 4192 : pSeq->elements + (sizeof(double) * nStartIndex),
466 : (char *)pSourceElements + (sizeof(double) * nStartIndex),
467 8384 : sizeof(double) * (nStopIndex - nStartIndex) );
468 : }
469 4192 : break;
470 : case typelib_TypeClass_ENUM:
471 100 : if (nAlloc >= 0)
472 100 : pSeq = reallocSeq( pSeq, sizeof(sal_Int32), nAlloc );
473 100 : if (pSeq != 0)
474 : {
475 : memcpy(
476 100 : pSeq->elements + (sizeof(sal_Int32) * nStartIndex),
477 : (char *)pSourceElements + (sizeof(sal_Int32) * nStartIndex),
478 200 : sizeof(sal_Int32) * (nStopIndex - nStartIndex) );
479 : }
480 100 : break;
481 : case typelib_TypeClass_STRING:
482 : {
483 118304 : if (nAlloc >= 0)
484 118304 : pSeq = reallocSeq( pSeq, sizeof(rtl_uString *), nAlloc );
485 118304 : if (pSeq != 0)
486 : {
487 118304 : rtl_uString ** pDestElements = (rtl_uString **) pSeq->elements;
488 186841 : for ( sal_Int32 nPos = nStartIndex; nPos < nStopIndex; ++nPos )
489 : {
490 : ::rtl_uString_acquire(
491 68537 : ((rtl_uString **)pSourceElements)[nPos] );
492 68537 : pDestElements[nPos] = ((rtl_uString **)pSourceElements)[nPos];
493 : }
494 : }
495 118304 : break;
496 : }
497 : case typelib_TypeClass_TYPE:
498 : {
499 60 : if (nAlloc >= 0)
500 : {
501 : pSeq = reallocSeq(
502 60 : pSeq, sizeof(typelib_TypeDescriptionReference *), nAlloc );
503 : }
504 60 : if (pSeq != 0)
505 : {
506 : typelib_TypeDescriptionReference ** pDestElements =
507 60 : (typelib_TypeDescriptionReference **) pSeq->elements;
508 70 : for ( sal_Int32 nPos = nStartIndex; nPos < nStopIndex; ++nPos )
509 : {
510 10 : TYPE_ACQUIRE(
511 : ((typelib_TypeDescriptionReference **)
512 : pSourceElements)[nPos] );
513 10 : pDestElements[nPos] =
514 : ((typelib_TypeDescriptionReference **)
515 10 : pSourceElements)[nPos];
516 : }
517 : }
518 60 : break;
519 : }
520 : case typelib_TypeClass_ANY:
521 : {
522 25135 : if (nAlloc >= 0)
523 25135 : pSeq = reallocSeq( pSeq, sizeof(uno_Any), nAlloc );
524 25135 : if (pSeq != 0)
525 : {
526 25135 : uno_Any * pDestElements = (uno_Any *) pSeq->elements;
527 39078 : for ( sal_Int32 nPos = nStartIndex; nPos < nStopIndex; ++nPos )
528 : {
529 13943 : uno_Any * pSource = (uno_Any *)pSourceElements + nPos;
530 : _copyConstructAny(
531 : &pDestElements[nPos],
532 : pSource->pData,
533 : pSource->pType, 0,
534 13943 : acquire, 0 );
535 : }
536 : }
537 25135 : break;
538 : }
539 : case typelib_TypeClass_STRUCT:
540 : case typelib_TypeClass_EXCEPTION:
541 : {
542 410980 : typelib_TypeDescription * pElementTypeDescr = 0;
543 410980 : TYPELIB_DANGER_GET( &pElementTypeDescr, pElementType );
544 410980 : sal_Int32 nElementSize = pElementTypeDescr->nSize;
545 :
546 410980 : if (nAlloc >= 0)
547 410980 : pSeq = reallocSeq( pSeq, nElementSize, nAlloc );
548 410980 : if (pSeq != 0)
549 : {
550 410980 : char * pDestElements = pSeq->elements;
551 :
552 : typelib_CompoundTypeDescription * pTypeDescr =
553 410980 : (typelib_CompoundTypeDescription *)pElementTypeDescr;
554 2323426 : for ( sal_Int32 nPos = nStartIndex; nPos < nStopIndex; ++nPos )
555 : {
556 : char * pDest =
557 1912446 : pDestElements + (nElementSize * nPos);
558 : char * pSource =
559 1912446 : (char *)pSourceElements + (nElementSize * nPos);
560 :
561 1912446 : if (pTypeDescr->pBaseTypeDescription)
562 : {
563 : // copy base value
564 : _copyConstructStruct(
565 : pDest, pSource,
566 4246 : pTypeDescr->pBaseTypeDescription, acquire, 0 );
567 : }
568 :
569 : // then copy members
570 : typelib_TypeDescriptionReference ** ppTypeRefs =
571 1912446 : pTypeDescr->ppTypeRefs;
572 1912446 : sal_Int32 * pMemberOffsets = pTypeDescr->pMemberOffsets;
573 1912446 : sal_Int32 nDescr = pTypeDescr->nMembers;
574 :
575 11323458 : while (nDescr--)
576 : {
577 : ::uno_type_copyData(
578 14997132 : pDest + pMemberOffsets[nDescr],
579 14997132 : pSource + pMemberOffsets[nDescr],
580 29994264 : ppTypeRefs[nDescr], acquire );
581 : }
582 : }
583 : }
584 :
585 410980 : 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 9590 : if (nAlloc >= 0)
627 9590 : pSeq = reallocSeq( pSeq, sizeof(uno_Sequence *), nAlloc );
628 9590 : if (pSeq != 0)
629 : {
630 9590 : typelib_TypeDescription * pElementTypeDescr = 0;
631 9590 : TYPELIB_DANGER_GET( &pElementTypeDescr, pElementType );
632 : typelib_TypeDescriptionReference * pSeqElementType =
633 9590 : ((typelib_IndirectTypeDescription *) pElementTypeDescr)->pType;
634 9590 : uno_Sequence ** pDestElements = (uno_Sequence **) pSeq->elements;
635 19388 : for ( sal_Int32 nPos = nStartIndex; nPos < nStopIndex; ++nPos )
636 : {
637 : uno_Sequence * pNew = icopyConstructSequence(
638 9798 : ((uno_Sequence **) pSourceElements)[nPos],
639 9798 : pSeqElementType, acquire, 0 );
640 : OSL_ASSERT( pNew != 0 );
641 : // ought never be a memory allocation problem,
642 : // because of reference counted sequence handles
643 9798 : pDestElements[ nPos ] = pNew;
644 : }
645 9590 : TYPELIB_DANGER_RELEASE( pElementTypeDescr );
646 : }
647 9590 : break;
648 : }
649 : case typelib_TypeClass_INTERFACE:
650 : {
651 122215 : if (nAlloc >= 0)
652 122215 : pSeq = reallocSeq( pSeq, sizeof(void *), nAlloc );
653 122215 : if (pSeq != 0)
654 : {
655 122215 : void ** pDestElements = (void **) pSeq->elements;
656 231614 : for ( sal_Int32 nPos = nStartIndex; nPos < nStopIndex; ++nPos )
657 : {
658 218798 : _acquire( pDestElements[nPos] =
659 218798 : ((void **)pSourceElements)[nPos], acquire );
660 : }
661 : }
662 122215 : break;
663 : }
664 : default:
665 : OSL_FAIL( "### unexpected element type!" );
666 0 : pSeq = 0;
667 0 : break;
668 : }
669 :
670 1057328 : if (pSeq == 0)
671 : {
672 : OSL_ASSERT( nAlloc >= 0 ); // must have been an allocation failure
673 0 : return false;
674 : }
675 : else
676 : {
677 1057328 : *ppSeq = pSeq;
678 1057328 : return true;
679 : }
680 : }
681 :
682 : //------------------------------------------------------------------------------
683 944210 : 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 944210 : bool ret = true;
690 944210 : uno_Sequence * pSeq = *ppSequence;
691 944210 : sal_Int32 nElements = pSeq->nElements;
692 :
693 944210 : 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 614831 : uno_Sequence * pNew = 0;
701 :
702 614831 : sal_Int32 nRest = nSize - nElements;
703 614831 : sal_Int32 nCopy = (nRest > 0 ? nElements : nSize);
704 :
705 614831 : if (nCopy >= 0)
706 : {
707 : ret = icopyConstructFromElements(
708 : &pNew, pSeq->elements, pElementType,
709 : 0, nCopy, acquire,
710 614831 : nSize ); // alloc to nSize
711 : }
712 614831 : if (ret && nRest > 0)
713 : {
714 : ret = idefaultConstructElements(
715 : &pNew, pElementType,
716 : nCopy, nSize,
717 601601 : nCopy >= 0 ? -1 /* no mem allocation */ : nSize );
718 : }
719 :
720 614831 : if (ret)
721 : {
722 : // destruct sequence
723 614831 : if (osl_atomic_decrement( &pSeq->nRefCount ) == 0)
724 : {
725 295250 : if (nElements > 0)
726 : {
727 : idestructElements(
728 : pSeq->elements, pElementType,
729 294862 : 0, nElements, release );
730 : }
731 295250 : rtl_freeMemory( pSeq );
732 : }
733 614831 : *ppSequence = pNew;
734 614831 : }
735 : }
736 : else
737 : {
738 : OSL_ASSERT( pSeq->nRefCount == 1 );
739 329379 : if (nSize > nElements) // default construct the rest
740 : {
741 : ret = idefaultConstructElements(
742 : ppSequence, pElementType,
743 : nElements, nSize,
744 263849 : 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 65530 : nSize, nElements, release );
751 : // warning: it is assumed that the following will never fail,
752 : // else this leads to a sequence null handle
753 65530 : *ppSequence = reallocSeq( pSeq, nElementSize, nSize );
754 : OSL_ASSERT( *ppSequence != 0 );
755 65530 : ret = (*ppSequence != 0);
756 : }
757 : }
758 :
759 944210 : return ret;
760 : }
761 :
762 : }
763 :
764 : extern "C"
765 : {
766 :
767 : //##############################################################################
768 3505125 : 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 3505125 : if (len)
776 : {
777 1163703 : typelib_TypeDescription * pTypeDescr = 0;
778 1163703 : TYPELIB_DANGER_GET( &pTypeDescr, pType );
779 :
780 : typelib_TypeDescriptionReference * pElementType =
781 1163703 : ((typelib_IndirectTypeDescription *)pTypeDescr)->pType;
782 :
783 1163703 : *ppSequence = 0;
784 1163703 : if (pElements == 0)
785 : {
786 : ret = idefaultConstructElements(
787 : ppSequence, pElementType,
788 : 0, len,
789 839460 : len ); // alloc to len
790 : }
791 : else
792 : {
793 : ret = icopyConstructFromElements(
794 : ppSequence, pElements, pElementType,
795 : 0, len, acquire,
796 324243 : len ); // alloc to len
797 : }
798 :
799 1163703 : TYPELIB_DANGER_RELEASE( pTypeDescr );
800 : }
801 : else
802 : {
803 2341422 : *ppSequence = createEmptySequence();
804 2341422 : ret = true;
805 : }
806 :
807 : OSL_ASSERT( (*ppSequence != 0) == ret );
808 3505125 : return ret;
809 : }
810 :
811 : //##############################################################################
812 151 : 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 151 : if (len > 0)
820 : {
821 : typelib_TypeDescriptionReference * pElementType =
822 36 : ((typelib_IndirectTypeDescription *)pTypeDescr)->pType;
823 :
824 36 : *ppSequence = 0;
825 36 : if (pElements == 0)
826 : {
827 : ret = idefaultConstructElements(
828 : ppSequence, pElementType,
829 : 0, len,
830 36 : 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 115 : *ppSequence = createEmptySequence();
843 115 : ret = true;
844 : }
845 :
846 : OSL_ASSERT( (*ppSequence != 0) == ret );
847 151 : return ret;
848 : }
849 :
850 : //##############################################################################
851 1089744 : 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 1089744 : bool ret = true;
860 1089744 : if (nSize != (*ppSequence)->nElements)
861 : {
862 944210 : typelib_TypeDescription * pTypeDescr = 0;
863 944210 : TYPELIB_DANGER_GET( &pTypeDescr, pType );
864 : ret = ireallocSequence(
865 : ppSequence, ((typelib_IndirectTypeDescription *)pTypeDescr)->pType,
866 944210 : nSize, acquire, release );
867 944210 : TYPELIB_DANGER_RELEASE( pTypeDescr );
868 : }
869 1089744 : 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 11060006 : 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 11060006 : bool ret = true;
900 11060006 : uno_Sequence * pSequence = *ppSequence;
901 11060006 : if (pSequence->nRefCount > 1)
902 : {
903 201605 : uno_Sequence * pNew = 0;
904 201605 : if (pSequence->nElements > 0)
905 : {
906 118254 : typelib_TypeDescription * pTypeDescr = 0;
907 118254 : TYPELIB_DANGER_GET( &pTypeDescr, pType );
908 :
909 : ret = icopyConstructFromElements(
910 : &pNew, pSequence->elements,
911 : ((typelib_IndirectTypeDescription *)pTypeDescr)->pType,
912 : 0, pSequence->nElements, acquire,
913 118254 : pSequence->nElements ); // alloc nElements
914 118254 : if (ret)
915 : {
916 118254 : idestructSequence( *ppSequence, pType, pTypeDescr, release );
917 118254 : *ppSequence = pNew;
918 : }
919 :
920 118254 : TYPELIB_DANGER_RELEASE( pTypeDescr );
921 : }
922 : else
923 : {
924 83351 : pNew = allocSeq( 0, 0 );
925 83351 : ret = (pNew != 0);
926 83351 : if (ret)
927 : {
928 : // easy destruction of empty sequence:
929 83351 : if (osl_atomic_decrement( &pSequence->nRefCount ) == 0)
930 0 : rtl_freeMemory( pSequence );
931 83351 : *ppSequence = pNew;
932 : }
933 : }
934 : }
935 11060006 : 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 535737 : 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 535737 : if (*ppDest != pSource)
1007 : {
1008 489620 : osl_atomic_increment( &pSource->nRefCount );
1009 489620 : idestructSequence( *ppDest, pType, 0, release );
1010 489620 : *ppDest = pSource;
1011 : }
1012 535737 : }
1013 :
1014 : }
1015 :
1016 : /* vim:set shiftwidth=4 softtabstop=4 expandtab: */
|