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