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