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 #ifndef COPY_HXX
24 #define COPY_HXX
25
26 #include "prim.hxx"
27 #include "constr.hxx"
28
29
30 namespace cppu
31 {
32
33 //##################################################################################################
34 //#### copy construction ###########################################################################
35 //##################################################################################################
36
37 //------------------------------------------------------------------------------
allocSeq(sal_Int32 nElementSize,sal_Int32 nElements)38 inline uno_Sequence * allocSeq(
39 sal_Int32 nElementSize, sal_Int32 nElements )
40 {
41 OSL_ASSERT( nElements >= 0 && nElementSize >= 0 );
42 uno_Sequence * pSeq = 0;
43 sal_uInt32 nSize = calcSeqMemSize( nElementSize, nElements );
44 if (nSize > 0)
45 {
46 pSeq = (uno_Sequence *) rtl_allocateMemory( nSize );
47 if (pSeq != 0)
48 {
49 // header init
50 pSeq->nRefCount = 1;
51 pSeq->nElements = nElements;
52 }
53 }
54 return pSeq;
55 }
56
57 //--------------------------------------------------------------------------------------------------
58 void copyConstructStruct(
59 void * pDest, void * pSource,
60 typelib_CompoundTypeDescription * pTypeDescr,
61 uno_AcquireFunc acquire, uno_Mapping * mapping )
62 SAL_THROW ( () );
63 //--------------------------------------------------------------------------------------------------
_copyConstructStruct(void * pDest,void * pSource,typelib_CompoundTypeDescription * pTypeDescr,uno_AcquireFunc acquire,uno_Mapping * mapping)64 inline void _copyConstructStruct(
65 void * pDest, void * pSource,
66 typelib_CompoundTypeDescription * pTypeDescr,
67 uno_AcquireFunc acquire, uno_Mapping * mapping )
68 SAL_THROW ( () )
69 {
70 if (pTypeDescr->pBaseTypeDescription)
71 {
72 // copy base value
73 copyConstructStruct( pDest, pSource, pTypeDescr->pBaseTypeDescription, acquire, mapping );
74 }
75
76 // then copy members
77 typelib_TypeDescriptionReference ** ppTypeRefs = pTypeDescr->ppTypeRefs;
78 sal_Int32 * pMemberOffsets = pTypeDescr->pMemberOffsets;
79 sal_Int32 nDescr = pTypeDescr->nMembers;
80
81 if (mapping)
82 {
83 while (nDescr--)
84 {
85 ::uno_type_copyAndConvertData(
86 (char *)pDest + pMemberOffsets[nDescr],
87 (char *)pSource + pMemberOffsets[nDescr],
88 ppTypeRefs[nDescr], mapping );
89 }
90 }
91 else
92 {
93 while (nDescr--)
94 {
95 ::uno_type_copyData(
96 (char *)pDest + pMemberOffsets[nDescr],
97 (char *)pSource + pMemberOffsets[nDescr],
98 ppTypeRefs[nDescr], acquire );
99 }
100 }
101 }
102 //--------------------------------------------------------------------------------------------------
_copyConstructArray(void * pDest,void * pSource,typelib_ArrayTypeDescription * pTypeDescr,uno_AcquireFunc acquire,uno_Mapping * mapping)103 inline void _copyConstructArray(
104 void * pDest, void * pSource,
105 typelib_ArrayTypeDescription * pTypeDescr,
106 uno_AcquireFunc acquire, uno_Mapping * mapping )
107 {
108 typelib_TypeDescriptionReference * pElementTypeRef = ((typelib_IndirectTypeDescription *)pTypeDescr)->pType;
109 typelib_TypeDescription * pElementTypeDescr = NULL;
110 TYPELIB_DANGER_GET( &pElementTypeDescr, pElementTypeRef );
111 sal_Int32 nElementSize = ((typelib_TypeDescription*)pElementTypeDescr)->nSize;
112 TYPELIB_DANGER_RELEASE( pElementTypeDescr );
113 sal_Int32 nTotalElements = pTypeDescr->nTotalElements;
114
115 if (mapping)
116 {
117 for(sal_Int32 i = 0; i < nTotalElements; i++)
118 {
119 ::uno_type_copyAndConvertData(
120 (sal_Char *)pDest + i * nElementSize,
121 (sal_Char *)pSource + i * nElementSize,
122 pElementTypeRef, mapping );
123 }
124 }
125 else
126 {
127 for(sal_Int32 i = 0; i < nTotalElements; i++)
128 {
129 ::uno_type_copyData(
130 (sal_Char *)pDest + (i * nElementSize),
131 (sal_Char *)pSource + (i * nElementSize),
132 pElementTypeRef, acquire );
133 }
134 }
135 }
136 //--------------------------------------------------------------------------------------------------
_copyConstructUnion(void * pDest,void * pSource,typelib_TypeDescription * pTypeDescr,uno_AcquireFunc acquire,uno_Mapping * mapping)137 inline void _copyConstructUnion(
138 void * pDest, void * pSource,
139 typelib_TypeDescription * pTypeDescr,
140 uno_AcquireFunc acquire, uno_Mapping * mapping )
141 SAL_THROW ( () )
142 {
143 typelib_TypeDescriptionReference * pSetType = _unionGetSetType( pSource, pTypeDescr );
144 if (mapping)
145 {
146 ::uno_type_copyAndConvertData(
147 (char *)pDest + ((typelib_UnionTypeDescription *)pTypeDescr)->nValueOffset,
148 (char *)pSource + ((typelib_UnionTypeDescription *)pTypeDescr)->nValueOffset,
149 pSetType, mapping );
150 }
151 else
152 {
153 ::uno_type_copyData(
154 (char *)pDest + ((typelib_UnionTypeDescription *)pTypeDescr)->nValueOffset,
155 (char *)pSource + ((typelib_UnionTypeDescription *)pTypeDescr)->nValueOffset,
156 pSetType, acquire );
157 }
158 *(sal_Int64 *)pDest = *(sal_Int64 *)pSource;
159 typelib_typedescriptionreference_release( pSetType );
160 }
161
162 //------------------------------------------------------------------------------
163 uno_Sequence * copyConstructSequence(
164 uno_Sequence * pSource,
165 typelib_TypeDescriptionReference * pElementType,
166 uno_AcquireFunc acquire, uno_Mapping * mapping );
167
168 //--------------------------------------------------------------------------------------------------
_copyConstructAnyFromData(uno_Any * pDestAny,void * pSource,typelib_TypeDescriptionReference * pType,typelib_TypeDescription * pTypeDescr,uno_AcquireFunc acquire,uno_Mapping * mapping)169 inline void _copyConstructAnyFromData(
170 uno_Any * pDestAny, void * pSource,
171 typelib_TypeDescriptionReference * pType, typelib_TypeDescription * pTypeDescr,
172 uno_AcquireFunc acquire, uno_Mapping * mapping )
173 SAL_THROW ( () )
174 {
175 TYPE_ACQUIRE( pType );
176 pDestAny->pType = pType;
177
178 switch (pType->eTypeClass)
179 {
180 case typelib_TypeClass_CHAR:
181 pDestAny->pData = &pDestAny->pReserved;
182 *(sal_Unicode *)&pDestAny->pReserved = *(sal_Unicode *)pSource;
183 break;
184 case typelib_TypeClass_BOOLEAN:
185 pDestAny->pData = &pDestAny->pReserved;
186 *(sal_Bool *)&pDestAny->pReserved = (*(sal_Bool *)pSource != sal_False);
187 break;
188 case typelib_TypeClass_BYTE:
189 pDestAny->pData = &pDestAny->pReserved;
190 *(sal_Int8 *)&pDestAny->pReserved = *(sal_Int8 *)pSource;
191 break;
192 case typelib_TypeClass_SHORT:
193 case typelib_TypeClass_UNSIGNED_SHORT:
194 pDestAny->pData = &pDestAny->pReserved;
195 *(sal_Int16 *)&pDestAny->pReserved = *(sal_Int16 *)pSource;
196 break;
197 case typelib_TypeClass_LONG:
198 case typelib_TypeClass_UNSIGNED_LONG:
199 pDestAny->pData = &pDestAny->pReserved;
200 *(sal_Int32 *)&pDestAny->pReserved = *(sal_Int32 *)pSource;
201 break;
202 case typelib_TypeClass_HYPER:
203 case typelib_TypeClass_UNSIGNED_HYPER:
204 if (sizeof(void *) >= sizeof(sal_Int64))
205 {
206 pDestAny->pData = &pDestAny->pReserved;
207 *(sal_Int64 *)&pDestAny->pReserved = *(sal_Int64 *)pSource;
208 }
209 else
210 {
211 pDestAny->pData = ::rtl_allocateMemory( sizeof(sal_Int64) );
212 *(sal_Int64 *)pDestAny->pData = *(sal_Int64 *)pSource;
213 }
214 break;
215 case typelib_TypeClass_FLOAT:
216 if (sizeof(void *) >= sizeof(float))
217 {
218 pDestAny->pData = &pDestAny->pReserved;
219 *(float *)&pDestAny->pReserved = *(float *)pSource;
220 }
221 else
222 {
223 pDestAny->pData = ::rtl_allocateMemory( sizeof(float) );
224 *(float *)pDestAny->pData = *(float *)pSource;
225 }
226 break;
227 case typelib_TypeClass_DOUBLE:
228 if (sizeof(void *) >= sizeof(double))
229 {
230 pDestAny->pData = &pDestAny->pReserved;
231 *(double *)&pDestAny->pReserved = *(double *)pSource;
232 }
233 else
234 {
235 pDestAny->pData = ::rtl_allocateMemory( sizeof(double) );
236 *(double *)pDestAny->pData = *(double *)pSource;
237 }
238 break;
239 case typelib_TypeClass_STRING:
240 ::rtl_uString_acquire( *(rtl_uString **)pSource );
241 pDestAny->pData = &pDestAny->pReserved;
242 *(rtl_uString **)&pDestAny->pReserved = *(rtl_uString **)pSource;
243 break;
244 case typelib_TypeClass_TYPE:
245 TYPE_ACQUIRE( *(typelib_TypeDescriptionReference **)pSource );
246 pDestAny->pData = &pDestAny->pReserved;
247 *(typelib_TypeDescriptionReference **)&pDestAny->pReserved = *(typelib_TypeDescriptionReference **)pSource;
248 break;
249 case typelib_TypeClass_ANY:
250 OSL_ENSURE( 0, "### unexpected nested any!" );
251 break;
252 case typelib_TypeClass_ENUM:
253 pDestAny->pData = &pDestAny->pReserved;
254 // enum is forced to 32bit long
255 *(sal_Int32 *)&pDestAny->pReserved = *(sal_Int32 *)pSource;
256 break;
257 case typelib_TypeClass_STRUCT:
258 case typelib_TypeClass_EXCEPTION:
259 if (pTypeDescr)
260 {
261 pDestAny->pData = ::rtl_allocateMemory( pTypeDescr->nSize );
262 _copyConstructStruct(
263 pDestAny->pData, pSource,
264 (typelib_CompoundTypeDescription *)pTypeDescr,
265 acquire, mapping );
266 }
267 else
268 {
269 TYPELIB_DANGER_GET( &pTypeDescr, pType );
270 pDestAny->pData = ::rtl_allocateMemory( pTypeDescr->nSize );
271 _copyConstructStruct(
272 pDestAny->pData, pSource,
273 (typelib_CompoundTypeDescription *)pTypeDescr,
274 acquire, mapping );
275 TYPELIB_DANGER_RELEASE( pTypeDescr );
276 }
277 break;
278 case typelib_TypeClass_ARRAY:
279 if (pTypeDescr)
280 {
281 pDestAny->pData = ::rtl_allocateMemory( pTypeDescr->nSize );
282 _copyConstructArray(
283 pDestAny->pData, pSource,
284 (typelib_ArrayTypeDescription *)pTypeDescr,
285 acquire, mapping );
286 }
287 else
288 {
289 TYPELIB_DANGER_GET( &pTypeDescr, pType );
290 pDestAny->pData = ::rtl_allocateMemory( pTypeDescr->nSize );
291 _copyConstructArray(
292 pDestAny->pData, pSource,
293 (typelib_ArrayTypeDescription *)pTypeDescr,
294 acquire, mapping );
295 TYPELIB_DANGER_RELEASE( pTypeDescr );
296 }
297 break;
298 case typelib_TypeClass_UNION:
299 if (pTypeDescr)
300 {
301 pDestAny->pData = ::rtl_allocateMemory( pTypeDescr->nSize );
302 _copyConstructUnion( pDestAny->pData, pSource, pTypeDescr, acquire, mapping );
303 }
304 else
305 {
306 TYPELIB_DANGER_GET( &pTypeDescr, pType );
307 pDestAny->pData = ::rtl_allocateMemory( pTypeDescr->nSize );
308 _copyConstructUnion( pDestAny->pData, pSource, pTypeDescr, acquire, mapping );
309 TYPELIB_DANGER_RELEASE( pTypeDescr );
310 }
311 break;
312 case typelib_TypeClass_SEQUENCE:
313 pDestAny->pData = &pDestAny->pReserved;
314 if (pTypeDescr)
315 {
316 *(uno_Sequence **)&pDestAny->pReserved = copyConstructSequence(
317 *(uno_Sequence **)pSource,
318 ((typelib_IndirectTypeDescription *)pTypeDescr)->pType,
319 acquire, mapping );
320 }
321 else
322 {
323 TYPELIB_DANGER_GET( &pTypeDescr, pType );
324 *(uno_Sequence **)&pDestAny->pReserved = copyConstructSequence(
325 *(uno_Sequence **)pSource,
326 ((typelib_IndirectTypeDescription *)pTypeDescr)->pType,
327 acquire, mapping );
328 TYPELIB_DANGER_RELEASE( pTypeDescr );
329 }
330 break;
331 case typelib_TypeClass_INTERFACE:
332 pDestAny->pData = &pDestAny->pReserved;
333 if (mapping)
334 {
335 pDestAny->pReserved = _map( *(void **)pSource, pType, pTypeDescr, mapping );
336 }
337 else
338 {
339 _acquire( pDestAny->pReserved = *(void **)pSource, acquire );
340 }
341 break;
342 default:
343 OSL_ASSERT(false);
344 break;
345 }
346 }
347 //--------------------------------------------------------------------------------------------------
_copyConstructAny(uno_Any * pDestAny,void * pSource,typelib_TypeDescriptionReference * pType,typelib_TypeDescription * pTypeDescr,uno_AcquireFunc acquire,uno_Mapping * mapping)348 inline void _copyConstructAny(
349 uno_Any * pDestAny, void * pSource,
350 typelib_TypeDescriptionReference * pType, typelib_TypeDescription * pTypeDescr,
351 uno_AcquireFunc acquire, uno_Mapping * mapping )
352 SAL_THROW ( () )
353 {
354 if (typelib_TypeClass_VOID == pType->eTypeClass)
355 {
356 CONSTRUCT_EMPTY_ANY( pDestAny );
357 }
358 else
359 {
360 if (typelib_TypeClass_ANY == pType->eTypeClass)
361 {
362 if (pSource)
363 {
364 pType = ((uno_Any *)pSource)->pType;
365 if (typelib_TypeClass_VOID == pType->eTypeClass)
366 {
367 CONSTRUCT_EMPTY_ANY( pDestAny );
368 return;
369 }
370 pTypeDescr = 0;
371 pSource = ((uno_Any *)pSource)->pData;
372 }
373 else
374 {
375 CONSTRUCT_EMPTY_ANY( pDestAny );
376 return;
377 }
378 }
379 if (pSource)
380 {
381 _copyConstructAnyFromData( pDestAny, pSource, pType, pTypeDescr, acquire, mapping );
382 }
383 else // default construct
384 {
385 TYPE_ACQUIRE( pType );
386 pDestAny->pType = pType;
387 switch (pType->eTypeClass)
388 {
389 case typelib_TypeClass_CHAR:
390 pDestAny->pData = &pDestAny->pReserved;
391 *(sal_Unicode *)&pDestAny->pReserved = '\0';
392 break;
393 case typelib_TypeClass_BOOLEAN:
394 pDestAny->pData = &pDestAny->pReserved;
395 *(sal_Bool *)&pDestAny->pReserved = sal_False;
396 break;
397 case typelib_TypeClass_BYTE:
398 pDestAny->pData = &pDestAny->pReserved;
399 *(sal_Int8 *)&pDestAny->pReserved = 0;
400 break;
401 case typelib_TypeClass_SHORT:
402 case typelib_TypeClass_UNSIGNED_SHORT:
403 pDestAny->pData = &pDestAny->pReserved;
404 *(sal_Int16 *)&pDestAny->pReserved = 0;
405 break;
406 case typelib_TypeClass_LONG:
407 case typelib_TypeClass_UNSIGNED_LONG:
408 pDestAny->pData = &pDestAny->pReserved;
409 *(sal_Int32 *)&pDestAny->pReserved = 0;
410 break;
411 case typelib_TypeClass_HYPER:
412 case typelib_TypeClass_UNSIGNED_HYPER:
413 if (sizeof(void *) >= sizeof(sal_Int64))
414 {
415 pDestAny->pData = &pDestAny->pReserved;
416 *(sal_Int64 *)&pDestAny->pReserved = 0;
417 }
418 else
419 {
420 pDestAny->pData = ::rtl_allocateMemory( sizeof(sal_Int64) );
421 *(sal_Int64 *)pDestAny->pData = 0;
422 }
423 break;
424 case typelib_TypeClass_FLOAT:
425 if (sizeof(void *) >= sizeof(float))
426 {
427 pDestAny->pData = &pDestAny->pReserved;
428 *(float *)&pDestAny->pReserved = 0.0;
429 }
430 else
431 {
432 pDestAny->pData = ::rtl_allocateMemory( sizeof(float) );
433 *(float *)pDestAny->pData = 0.0;
434 }
435 break;
436 case typelib_TypeClass_DOUBLE:
437 if (sizeof(void *) >= sizeof(double))
438 {
439 pDestAny->pData = &pDestAny->pReserved;
440 *(double *)&pDestAny->pReserved = 0.0;
441 }
442 else
443 {
444 pDestAny->pData = ::rtl_allocateMemory( sizeof(double) );
445 *(double *)pDestAny->pData = 0.0;
446 }
447 break;
448 case typelib_TypeClass_STRING:
449 pDestAny->pData = &pDestAny->pReserved;
450 *(rtl_uString **)&pDestAny->pReserved = 0;
451 ::rtl_uString_new( (rtl_uString **)&pDestAny->pReserved );
452 break;
453 case typelib_TypeClass_TYPE:
454 pDestAny->pData = &pDestAny->pReserved;
455 *(typelib_TypeDescriptionReference **)&pDestAny->pReserved = _getVoidType();
456 break;
457 case typelib_TypeClass_ENUM:
458 pDestAny->pData = &pDestAny->pReserved;
459 if (pTypeDescr)
460 {
461 *(sal_Int32 *)&pDestAny->pReserved = ((typelib_EnumTypeDescription *)pTypeDescr)->nDefaultEnumValue;
462 }
463 else
464 {
465 TYPELIB_DANGER_GET( &pTypeDescr, pType );
466 *(sal_Int32 *)&pDestAny->pReserved = ((typelib_EnumTypeDescription *)pTypeDescr)->nDefaultEnumValue;
467 TYPELIB_DANGER_RELEASE( pTypeDescr );
468 }
469 break;
470 case typelib_TypeClass_STRUCT:
471 case typelib_TypeClass_EXCEPTION:
472 if (pTypeDescr)
473 {
474 pDestAny->pData = ::rtl_allocateMemory( pTypeDescr->nSize );
475 _defaultConstructStruct(
476 pDestAny->pData, (typelib_CompoundTypeDescription *)pTypeDescr );
477 }
478 else
479 {
480 TYPELIB_DANGER_GET( &pTypeDescr, pType );
481 pDestAny->pData = ::rtl_allocateMemory( pTypeDescr->nSize );
482 _defaultConstructStruct(
483 pDestAny->pData, (typelib_CompoundTypeDescription *)pTypeDescr );
484 TYPELIB_DANGER_RELEASE( pTypeDescr );
485 }
486 break;
487 case typelib_TypeClass_ARRAY:
488 if (pTypeDescr)
489 {
490 pDestAny->pData = ::rtl_allocateMemory( pTypeDescr->nSize );
491 _defaultConstructArray(
492 pDestAny->pData, (typelib_ArrayTypeDescription *)pTypeDescr );
493 }
494 else
495 {
496 TYPELIB_DANGER_GET( &pTypeDescr, pType );
497 pDestAny->pData = ::rtl_allocateMemory( pTypeDescr->nSize );
498 _defaultConstructArray(
499 pDestAny->pData, (typelib_ArrayTypeDescription *)pTypeDescr );
500 TYPELIB_DANGER_RELEASE( pTypeDescr );
501 }
502 break;
503 case typelib_TypeClass_UNION:
504 if (pTypeDescr)
505 {
506 pDestAny->pData = ::rtl_allocateMemory( pTypeDescr->nSize );
507 _defaultConstructUnion( pDestAny->pData, pTypeDescr );
508 }
509 else
510 {
511 TYPELIB_DANGER_GET( &pTypeDescr, pType );
512 pDestAny->pData = ::rtl_allocateMemory( pTypeDescr->nSize );
513 _defaultConstructUnion( pDestAny->pData, pTypeDescr );
514 TYPELIB_DANGER_RELEASE( pTypeDescr );
515 }
516 break;
517 case typelib_TypeClass_SEQUENCE:
518 pDestAny->pData = &pDestAny->pReserved;
519 *(uno_Sequence **)&pDestAny->pReserved = createEmptySequence();
520 break;
521 case typelib_TypeClass_INTERFACE:
522 pDestAny->pData = &pDestAny->pReserved;
523 pDestAny->pReserved = 0; // either cpp or c-uno interface
524 break;
525 default:
526 OSL_ASSERT(false);
527 break;
528 }
529 }
530 }
531 }
532 //------------------------------------------------------------------------------
icopyConstructSequence(uno_Sequence * pSource,typelib_TypeDescriptionReference * pElementType,uno_AcquireFunc acquire,uno_Mapping * mapping)533 inline uno_Sequence * icopyConstructSequence(
534 uno_Sequence * pSource,
535 typelib_TypeDescriptionReference * pElementType,
536 uno_AcquireFunc acquire, uno_Mapping * mapping )
537 {
538 typelib_TypeClass eTypeClass = pElementType->eTypeClass;
539 if (!mapping ||
540 (eTypeClass <= typelib_TypeClass_ENUM &&
541 eTypeClass != typelib_TypeClass_ANY))
542 {
543 ::osl_incrementInterlockedCount( &pSource->nRefCount );
544 return pSource;
545 }
546 else // create new sequence
547 {
548 uno_Sequence * pDest;
549 sal_Int32 nElements = pSource->nElements;
550 if (nElements)
551 {
552 switch (eTypeClass)
553 {
554 case typelib_TypeClass_ANY:
555 {
556 pDest = allocSeq( sizeof (uno_Any), nElements );
557 if (pDest != 0)
558 {
559 uno_Any * pDestElements = (uno_Any *)pDest->elements;
560 uno_Any * pSourceElements = (uno_Any *)pSource->elements;
561 for ( sal_Int32 nPos = nElements; nPos--; )
562 {
563 typelib_TypeDescriptionReference * pType =
564 pSourceElements[nPos].pType;
565 if (typelib_TypeClass_VOID == pType->eTypeClass)
566 {
567 CONSTRUCT_EMPTY_ANY( &pDestElements[nPos] );
568 }
569 else
570 {
571 _copyConstructAnyFromData(
572 &pDestElements[nPos],
573 pSourceElements[nPos].pData,
574 pType, 0,
575 acquire, mapping );
576 }
577 }
578 }
579 break;
580 }
581 case typelib_TypeClass_STRUCT:
582 case typelib_TypeClass_EXCEPTION:
583 {
584 typelib_TypeDescription * pElementTypeDescr = 0;
585 TYPELIB_DANGER_GET( &pElementTypeDescr, pElementType );
586 sal_Int32 nElementSize = pElementTypeDescr->nSize;
587 char * pSourceElements = pSource->elements;
588 pDest = allocSeq( nElementSize, nElements );
589 if (pDest != 0)
590 {
591 char * pElements = pDest->elements;
592 for ( sal_Int32 nPos = nElements; nPos--; )
593 {
594 _copyConstructStruct(
595 pElements + (nPos * nElementSize),
596 pSourceElements + (nPos * nElementSize),
597 (typelib_CompoundTypeDescription *)
598 pElementTypeDescr,
599 acquire, mapping );
600 }
601 }
602 TYPELIB_DANGER_RELEASE( pElementTypeDescr );
603 break;
604 }
605 case typelib_TypeClass_ARRAY:
606 {
607 typelib_TypeDescription * pElementTypeDescr = 0;
608 TYPELIB_DANGER_GET( &pElementTypeDescr, pElementType );
609 sal_Int32 nElementSize = pElementTypeDescr->nSize;
610 char * pSourceElements = pSource->elements;
611 pDest = allocSeq( nElementSize, nElements );
612 if (pDest != 0)
613 {
614 char * pElements = pDest->elements;
615 for ( sal_Int32 nPos = nElements; nPos--; )
616 {
617 _copyConstructArray(
618 pElements + (nPos * nElementSize),
619 pSourceElements + (nPos * nElementSize),
620 (typelib_ArrayTypeDescription *)pElementTypeDescr,
621 acquire, mapping );
622 }
623 }
624 TYPELIB_DANGER_RELEASE( pElementTypeDescr );
625 break;
626 }
627 case typelib_TypeClass_UNION:
628 {
629 typelib_TypeDescription * pElementTypeDescr = 0;
630 TYPELIB_DANGER_GET( &pElementTypeDescr, pElementType );
631 sal_Int32 nElementSize = pElementTypeDescr->nSize;
632 sal_Int32 nValueOffset =
633 ((typelib_UnionTypeDescription *)
634 pElementTypeDescr)->nValueOffset;
635 pDest = allocSeq( nElementSize, nElements );
636 if (pDest != 0)
637 {
638 char * pElements = pDest->elements;
639 char * pSourceElements = pSource->elements;
640 for ( sal_Int32 nPos = nElements; nPos--; )
641 {
642 char * pDest2 =
643 pElements + (nPos * nElementSize);
644 char * pSource2 =
645 pSourceElements + (nPos * nElementSize);
646
647 typelib_TypeDescriptionReference * pSetType =
648 _unionGetSetType( pSource2, pElementTypeDescr );
649 ::uno_type_copyAndConvertData(
650 pDest2 + nValueOffset, pSource2 + nValueOffset,
651 pSetType, mapping );
652 *(sal_Int64 *)pDest2 = *(sal_Int64 *)pSource2;
653 ::typelib_typedescriptionreference_release( pSetType );
654 }
655 }
656 TYPELIB_DANGER_RELEASE( pElementTypeDescr );
657 break;
658 }
659 case typelib_TypeClass_SEQUENCE: // sequence of sequence
660 {
661 pDest = allocSeq( sizeof (uno_Sequence *), nElements );
662 if (pDest != 0)
663 {
664 typelib_TypeDescription * pElementTypeDescr = 0;
665 TYPELIB_DANGER_GET( &pElementTypeDescr, pElementType );
666 typelib_TypeDescriptionReference * pSeqElementType =
667 ((typelib_IndirectTypeDescription *)
668 pElementTypeDescr)->pType;
669
670 uno_Sequence ** pDestElements =
671 (uno_Sequence **) pDest->elements;
672 uno_Sequence ** pSourceElements =
673 (uno_Sequence **) pSource->elements;
674 for ( sal_Int32 nPos = nElements; nPos--; )
675 {
676 uno_Sequence * pNew = copyConstructSequence(
677 pSourceElements[nPos],
678 pSeqElementType,
679 acquire, mapping );
680 OSL_ASSERT( pNew != 0 );
681 // ought never be a memory allocation problem,
682 // because of reference counted sequence handles
683 pDestElements[ nPos ] = pNew;
684 }
685
686 TYPELIB_DANGER_RELEASE( pElementTypeDescr );
687 }
688 break;
689 }
690 case typelib_TypeClass_INTERFACE:
691 {
692 pDest = allocSeq( sizeof (void *), nElements );
693 if (pDest != 0)
694 {
695 char * pElements = pDest->elements;
696 void ** pSourceElements = (void **)pSource->elements;
697 if (mapping)
698 {
699 typelib_TypeDescription * pElementTypeDescr = 0;
700 TYPELIB_DANGER_GET( &pElementTypeDescr, pElementType );
701 for ( sal_Int32 nPos = nElements; nPos--; )
702 {
703 ((void **)pElements)[nPos] = 0;
704 if (((void **)pSourceElements)[nPos])
705 {
706 (*mapping->mapInterface)(
707 mapping, (void **)pElements + nPos,
708 pSourceElements[nPos],
709 (typelib_InterfaceTypeDescription *)
710 pElementTypeDescr );
711 }
712 }
713 TYPELIB_DANGER_RELEASE( pElementTypeDescr );
714 }
715 else
716 {
717 for ( sal_Int32 nPos = nElements; nPos--; )
718 {
719 ((void **)pElements)[nPos] = pSourceElements[nPos];
720 _acquire( ((void **)pElements)[nPos], acquire );
721 }
722 }
723 }
724 break;
725 }
726 default:
727 OSL_ENSURE( 0, "### unexepcted sequence element type!" );
728 pDest = 0;
729 break;
730 }
731 }
732 else // empty sequence
733 {
734 pDest = allocSeq( 0, 0 );
735 }
736
737 return pDest;
738 }
739 }
740
741 //--------------------------------------------------------------------------------------------------
_copyConstructData(void * pDest,void * pSource,typelib_TypeDescriptionReference * pType,typelib_TypeDescription * pTypeDescr,uno_AcquireFunc acquire,uno_Mapping * mapping)742 inline void _copyConstructData(
743 void * pDest, void * pSource,
744 typelib_TypeDescriptionReference * pType, typelib_TypeDescription * pTypeDescr,
745 uno_AcquireFunc acquire, uno_Mapping * mapping )
746 SAL_THROW ( () )
747 {
748 switch (pType->eTypeClass)
749 {
750 case typelib_TypeClass_CHAR:
751 *(sal_Unicode *)pDest = *(sal_Unicode *)pSource;
752 break;
753 case typelib_TypeClass_BOOLEAN:
754 *(sal_Bool *)pDest = (*(sal_Bool *)pSource != sal_False);
755 break;
756 case typelib_TypeClass_BYTE:
757 *(sal_Int8 *)pDest = *(sal_Int8 *)pSource;
758 break;
759 case typelib_TypeClass_SHORT:
760 case typelib_TypeClass_UNSIGNED_SHORT:
761 *(sal_Int16 *)pDest = *(sal_Int16 *)pSource;
762 break;
763 case typelib_TypeClass_LONG:
764 case typelib_TypeClass_UNSIGNED_LONG:
765 *(sal_Int32 *)pDest = *(sal_Int32 *)pSource;
766 break;
767 case typelib_TypeClass_HYPER:
768 case typelib_TypeClass_UNSIGNED_HYPER:
769 *(sal_Int64 *)pDest = *(sal_Int64 *)pSource;
770 break;
771 case typelib_TypeClass_FLOAT:
772 *(float *)pDest = *(float *)pSource;
773 break;
774 case typelib_TypeClass_DOUBLE:
775 *(double *)pDest = *(double *)pSource;
776 break;
777 case typelib_TypeClass_STRING:
778 ::rtl_uString_acquire( *(rtl_uString **)pSource );
779 *(rtl_uString **)pDest = *(rtl_uString **)pSource;
780 break;
781 case typelib_TypeClass_TYPE:
782 TYPE_ACQUIRE( *(typelib_TypeDescriptionReference **)pSource );
783 *(typelib_TypeDescriptionReference **)pDest = *(typelib_TypeDescriptionReference **)pSource;
784 break;
785 case typelib_TypeClass_ANY:
786 _copyConstructAny(
787 (uno_Any *)pDest, ((uno_Any *)pSource)->pData,
788 ((uno_Any *)pSource)->pType, 0,
789 acquire, mapping );
790 break;
791 case typelib_TypeClass_ENUM:
792 *(sal_Int32 *)pDest = *(sal_Int32 *)pSource;
793 break;
794 case typelib_TypeClass_STRUCT:
795 case typelib_TypeClass_EXCEPTION:
796 if (pTypeDescr)
797 {
798 _copyConstructStruct(
799 pDest, pSource,
800 (typelib_CompoundTypeDescription *)pTypeDescr,
801 acquire, mapping );
802 }
803 else
804 {
805 TYPELIB_DANGER_GET( &pTypeDescr, pType );
806 _copyConstructStruct(
807 pDest, pSource,
808 (typelib_CompoundTypeDescription *)pTypeDescr,
809 acquire, mapping );
810 TYPELIB_DANGER_RELEASE( pTypeDescr );
811 }
812 break;
813 case typelib_TypeClass_ARRAY:
814 if (pTypeDescr)
815 {
816 _copyConstructArray(
817 pDest, pSource,
818 (typelib_ArrayTypeDescription *)pTypeDescr,
819 acquire, mapping );
820 }
821 else
822 {
823 TYPELIB_DANGER_GET( &pTypeDescr, pType );
824 _copyConstructArray(
825 pDest, pSource,
826 (typelib_ArrayTypeDescription *)pTypeDescr,
827 acquire, mapping );
828 TYPELIB_DANGER_RELEASE( pTypeDescr );
829 }
830 break;
831 case typelib_TypeClass_UNION:
832 if (pTypeDescr)
833 {
834 _copyConstructUnion( pDest, pSource, pTypeDescr, acquire, mapping );
835 }
836 else
837 {
838 TYPELIB_DANGER_GET( &pTypeDescr, pType );
839 _copyConstructUnion( pDest, pSource, pTypeDescr, acquire, mapping );
840 TYPELIB_DANGER_RELEASE( pTypeDescr );
841 }
842 break;
843 case typelib_TypeClass_SEQUENCE:
844 if (mapping)
845 {
846 if (pTypeDescr)
847 {
848 *(uno_Sequence **)pDest = icopyConstructSequence(
849 *(uno_Sequence **)pSource,
850 ((typelib_IndirectTypeDescription *)pTypeDescr)->pType,
851 acquire, mapping );
852 }
853 else
854 {
855 TYPELIB_DANGER_GET( &pTypeDescr, pType );
856 *(uno_Sequence **)pDest = icopyConstructSequence(
857 *(uno_Sequence **)pSource,
858 ((typelib_IndirectTypeDescription *)pTypeDescr)->pType,
859 acquire, mapping );
860 TYPELIB_DANGER_RELEASE( pTypeDescr );
861 }
862 }
863 else
864 {
865 ::osl_incrementInterlockedCount( &(*(uno_Sequence **)pSource)->nRefCount );
866 *(uno_Sequence **)pDest = *(uno_Sequence **)pSource;
867 }
868 break;
869 case typelib_TypeClass_INTERFACE:
870 if (mapping)
871 *(void **)pDest = _map( *(void **)pSource, pType, pTypeDescr, mapping );
872 else
873 _acquire( *(void **)pDest = *(void **)pSource, acquire );
874 break;
875 default:
876 break;
877 }
878 }
879
880 }
881
882 #endif
883