Version 4.0.2.1, tag libreoffice-4.0.2.1
[LibreOffice.git] / cppu / source / uno / copy.hxx
blobce46492bfce48bf6990be0b758572e0754b1892c
1 /* -*- Mode: C++; tab-width: 4; indent-tabs-mode: nil; c-basic-offset: 4 -*- */
2 /*
3 * This file is part of the LibreOffice project.
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/.
9 * This file incorporates work covered by the following license notice:
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 .
19 #ifndef COPY_HXX
20 #define COPY_HXX
22 #include "prim.hxx"
23 #include "constr.hxx"
26 namespace cppu
29 //##################################################################################################
30 //#### copy construction ###########################################################################
31 //##################################################################################################
33 //------------------------------------------------------------------------------
34 inline uno_Sequence * allocSeq(
35 sal_Int32 nElementSize, sal_Int32 nElements )
37 OSL_ASSERT( nElements >= 0 && nElementSize >= 0 );
38 uno_Sequence * pSeq = 0;
39 sal_uInt32 nSize = calcSeqMemSize( nElementSize, nElements );
40 if (nSize > 0)
42 pSeq = (uno_Sequence *) rtl_allocateMemory( nSize );
43 if (pSeq != 0)
45 // header init
46 pSeq->nRefCount = 1;
47 pSeq->nElements = nElements;
50 return pSeq;
53 //--------------------------------------------------------------------------------------------------
54 void copyConstructStruct(
55 void * pDest, void * pSource,
56 typelib_CompoundTypeDescription * pTypeDescr,
57 uno_AcquireFunc acquire, uno_Mapping * mapping )
58 SAL_THROW (());
59 //--------------------------------------------------------------------------------------------------
60 inline void _copyConstructStruct(
61 void * pDest, void * pSource,
62 typelib_CompoundTypeDescription * pTypeDescr,
63 uno_AcquireFunc acquire, uno_Mapping * mapping )
64 SAL_THROW (())
66 if (pTypeDescr->pBaseTypeDescription)
68 // copy base value
69 copyConstructStruct( pDest, pSource, pTypeDescr->pBaseTypeDescription, acquire, mapping );
72 // then copy members
73 typelib_TypeDescriptionReference ** ppTypeRefs = pTypeDescr->ppTypeRefs;
74 sal_Int32 * pMemberOffsets = pTypeDescr->pMemberOffsets;
75 sal_Int32 nDescr = pTypeDescr->nMembers;
77 if (mapping)
79 while (nDescr--)
81 ::uno_type_copyAndConvertData(
82 (char *)pDest + pMemberOffsets[nDescr],
83 (char *)pSource + pMemberOffsets[nDescr],
84 ppTypeRefs[nDescr], mapping );
87 else
89 while (nDescr--)
91 ::uno_type_copyData(
92 (char *)pDest + pMemberOffsets[nDescr],
93 (char *)pSource + pMemberOffsets[nDescr],
94 ppTypeRefs[nDescr], acquire );
98 //--------------------------------------------------------------------------------------------------
99 inline void _copyConstructArray(
100 void * pDest, void * pSource,
101 typelib_ArrayTypeDescription * pTypeDescr,
102 uno_AcquireFunc acquire, uno_Mapping * mapping )
104 typelib_TypeDescriptionReference * pElementTypeRef = ((typelib_IndirectTypeDescription *)pTypeDescr)->pType;
105 typelib_TypeDescription * pElementTypeDescr = NULL;
106 TYPELIB_DANGER_GET( &pElementTypeDescr, pElementTypeRef );
107 sal_Int32 nElementSize = ((typelib_TypeDescription*)pElementTypeDescr)->nSize;
108 TYPELIB_DANGER_RELEASE( pElementTypeDescr );
109 sal_Int32 nTotalElements = pTypeDescr->nTotalElements;
111 if (mapping)
113 for(sal_Int32 i = 0; i < nTotalElements; i++)
115 ::uno_type_copyAndConvertData(
116 (sal_Char *)pDest + i * nElementSize,
117 (sal_Char *)pSource + i * nElementSize,
118 pElementTypeRef, mapping );
121 else
123 for(sal_Int32 i = 0; i < nTotalElements; i++)
125 ::uno_type_copyData(
126 (sal_Char *)pDest + (i * nElementSize),
127 (sal_Char *)pSource + (i * nElementSize),
128 pElementTypeRef, acquire );
132 //--------------------------------------------------------------------------------------------------
133 inline void _copyConstructUnion(
134 void * pDest, void * pSource,
135 typelib_TypeDescription * pTypeDescr,
136 uno_AcquireFunc acquire, uno_Mapping * mapping )
137 SAL_THROW (())
139 typelib_TypeDescriptionReference * pSetType = _unionGetSetType( pSource, pTypeDescr );
140 if (mapping)
142 ::uno_type_copyAndConvertData(
143 (char *)pDest + ((typelib_UnionTypeDescription *)pTypeDescr)->nValueOffset,
144 (char *)pSource + ((typelib_UnionTypeDescription *)pTypeDescr)->nValueOffset,
145 pSetType, mapping );
147 else
149 ::uno_type_copyData(
150 (char *)pDest + ((typelib_UnionTypeDescription *)pTypeDescr)->nValueOffset,
151 (char *)pSource + ((typelib_UnionTypeDescription *)pTypeDescr)->nValueOffset,
152 pSetType, acquire );
154 *(sal_Int64 *)pDest = *(sal_Int64 *)pSource;
155 typelib_typedescriptionreference_release( pSetType );
158 //------------------------------------------------------------------------------
159 uno_Sequence * copyConstructSequence(
160 uno_Sequence * pSource,
161 typelib_TypeDescriptionReference * pElementType,
162 uno_AcquireFunc acquire, uno_Mapping * mapping );
164 //--------------------------------------------------------------------------------------------------
165 inline void _copyConstructAnyFromData(
166 uno_Any * pDestAny, void * pSource,
167 typelib_TypeDescriptionReference * pType, typelib_TypeDescription * pTypeDescr,
168 uno_AcquireFunc acquire, uno_Mapping * mapping )
169 SAL_THROW (())
171 TYPE_ACQUIRE( pType );
172 pDestAny->pType = pType;
174 switch (pType->eTypeClass)
176 case typelib_TypeClass_CHAR:
177 pDestAny->pData = &pDestAny->pReserved;
178 *(sal_Unicode *)pDestAny->pData = *(sal_Unicode *)pSource;
179 break;
180 case typelib_TypeClass_BOOLEAN:
181 pDestAny->pData = &pDestAny->pReserved;
182 *(sal_Bool *)pDestAny->pData = (*(sal_Bool *)pSource != sal_False);
183 break;
184 case typelib_TypeClass_BYTE:
185 pDestAny->pData = &pDestAny->pReserved;
186 *(sal_Int8 *)pDestAny->pData = *(sal_Int8 *)pSource;
187 break;
188 case typelib_TypeClass_SHORT:
189 case typelib_TypeClass_UNSIGNED_SHORT:
190 pDestAny->pData = &pDestAny->pReserved;
191 *(sal_Int16 *)pDestAny->pData = *(sal_Int16 *)pSource;
192 break;
193 case typelib_TypeClass_LONG:
194 case typelib_TypeClass_UNSIGNED_LONG:
195 pDestAny->pData = &pDestAny->pReserved;
196 *(sal_Int32 *)pDestAny->pData = *(sal_Int32 *)pSource;
197 break;
198 case typelib_TypeClass_HYPER:
199 case typelib_TypeClass_UNSIGNED_HYPER:
200 if (sizeof(void *) >= sizeof(sal_Int64))
201 pDestAny->pData = &pDestAny->pReserved;
202 else
203 pDestAny->pData = ::rtl_allocateMemory( sizeof(sal_Int64) );
204 *(sal_Int64 *)pDestAny->pData = *(sal_Int64 *)pSource;
205 break;
206 case typelib_TypeClass_FLOAT:
207 if (sizeof(void *) >= sizeof(float))
208 pDestAny->pData = &pDestAny->pReserved;
209 else
210 pDestAny->pData = ::rtl_allocateMemory( sizeof(float) );
211 *(float *)pDestAny->pData = *(float *)pSource;
212 break;
213 case typelib_TypeClass_DOUBLE:
214 if (sizeof(void *) >= sizeof(double))
215 pDestAny->pData = &pDestAny->pReserved;
216 else
217 pDestAny->pData = ::rtl_allocateMemory( sizeof(double) );
218 *(double *)pDestAny->pData = *(double *)pSource;
219 break;
220 case typelib_TypeClass_STRING:
221 ::rtl_uString_acquire( *(rtl_uString **)pSource );
222 pDestAny->pData = &pDestAny->pReserved;
223 *(rtl_uString **)pDestAny->pData = *(rtl_uString **)pSource;
224 break;
225 case typelib_TypeClass_TYPE:
226 TYPE_ACQUIRE( *(typelib_TypeDescriptionReference **)pSource );
227 pDestAny->pData = &pDestAny->pReserved;
228 *(typelib_TypeDescriptionReference **)pDestAny->pData = *(typelib_TypeDescriptionReference **)pSource;
229 break;
230 case typelib_TypeClass_ANY:
231 OSL_FAIL( "### unexpected nested any!" );
232 break;
233 case typelib_TypeClass_ENUM:
234 pDestAny->pData = &pDestAny->pReserved;
235 // enum is forced to 32bit long
236 *(sal_Int32 *)pDestAny->pData = *(sal_Int32 *)pSource;
237 break;
238 case typelib_TypeClass_STRUCT:
239 case typelib_TypeClass_EXCEPTION:
240 if (pTypeDescr)
242 pDestAny->pData = ::rtl_allocateMemory( pTypeDescr->nSize );
243 _copyConstructStruct(
244 pDestAny->pData, pSource,
245 (typelib_CompoundTypeDescription *)pTypeDescr,
246 acquire, mapping );
248 else
250 TYPELIB_DANGER_GET( &pTypeDescr, pType );
251 pDestAny->pData = ::rtl_allocateMemory( pTypeDescr->nSize );
252 _copyConstructStruct(
253 pDestAny->pData, pSource,
254 (typelib_CompoundTypeDescription *)pTypeDescr,
255 acquire, mapping );
256 TYPELIB_DANGER_RELEASE( pTypeDescr );
258 break;
259 case typelib_TypeClass_ARRAY:
260 if (pTypeDescr)
262 pDestAny->pData = ::rtl_allocateMemory( pTypeDescr->nSize );
263 _copyConstructArray(
264 pDestAny->pData, pSource,
265 (typelib_ArrayTypeDescription *)pTypeDescr,
266 acquire, mapping );
268 else
270 TYPELIB_DANGER_GET( &pTypeDescr, pType );
271 pDestAny->pData = ::rtl_allocateMemory( pTypeDescr->nSize );
272 _copyConstructArray(
273 pDestAny->pData, pSource,
274 (typelib_ArrayTypeDescription *)pTypeDescr,
275 acquire, mapping );
276 TYPELIB_DANGER_RELEASE( pTypeDescr );
278 break;
279 case typelib_TypeClass_UNION:
280 if (pTypeDescr)
282 pDestAny->pData = ::rtl_allocateMemory( pTypeDescr->nSize );
283 _copyConstructUnion( pDestAny->pData, pSource, pTypeDescr, acquire, mapping );
285 else
287 TYPELIB_DANGER_GET( &pTypeDescr, pType );
288 pDestAny->pData = ::rtl_allocateMemory( pTypeDescr->nSize );
289 _copyConstructUnion( pDestAny->pData, pSource, pTypeDescr, acquire, mapping );
290 TYPELIB_DANGER_RELEASE( pTypeDescr );
292 break;
293 case typelib_TypeClass_SEQUENCE:
294 pDestAny->pData = &pDestAny->pReserved;
295 if (pTypeDescr)
297 *(uno_Sequence **)pDestAny->pData = copyConstructSequence(
298 *(uno_Sequence **)pSource,
299 ((typelib_IndirectTypeDescription *)pTypeDescr)->pType,
300 acquire, mapping );
302 else
304 TYPELIB_DANGER_GET( &pTypeDescr, pType );
305 *(uno_Sequence **)pDestAny->pData = copyConstructSequence(
306 *(uno_Sequence **)pSource,
307 ((typelib_IndirectTypeDescription *)pTypeDescr)->pType,
308 acquire, mapping );
309 TYPELIB_DANGER_RELEASE( pTypeDescr );
311 break;
312 case typelib_TypeClass_INTERFACE:
313 pDestAny->pData = &pDestAny->pReserved;
314 if (mapping)
316 pDestAny->pReserved = _map( *(void **)pSource, pType, pTypeDescr, mapping );
318 else
320 _acquire( pDestAny->pReserved = *(void **)pSource, acquire );
322 break;
323 default:
324 OSL_ASSERT(false);
325 break;
328 //--------------------------------------------------------------------------------------------------
329 inline void _copyConstructAny(
330 uno_Any * pDestAny, void * pSource,
331 typelib_TypeDescriptionReference * pType, typelib_TypeDescription * pTypeDescr,
332 uno_AcquireFunc acquire, uno_Mapping * mapping )
333 SAL_THROW (())
335 if (typelib_TypeClass_VOID == pType->eTypeClass)
337 CONSTRUCT_EMPTY_ANY( pDestAny );
339 else
341 if (typelib_TypeClass_ANY == pType->eTypeClass)
343 if (pSource)
345 pType = ((uno_Any *)pSource)->pType;
346 if (typelib_TypeClass_VOID == pType->eTypeClass)
348 CONSTRUCT_EMPTY_ANY( pDestAny );
349 return;
351 pTypeDescr = 0;
352 pSource = ((uno_Any *)pSource)->pData;
354 else
356 CONSTRUCT_EMPTY_ANY( pDestAny );
357 return;
360 if (pSource)
362 _copyConstructAnyFromData( pDestAny, pSource, pType, pTypeDescr, acquire, mapping );
364 else // default construct
366 TYPE_ACQUIRE( pType );
367 pDestAny->pType = pType;
368 switch (pType->eTypeClass)
370 case typelib_TypeClass_CHAR:
371 pDestAny->pData = &pDestAny->pReserved;
372 *(sal_Unicode *)pDestAny->pData = '\0';
373 break;
374 case typelib_TypeClass_BOOLEAN:
375 pDestAny->pData = &pDestAny->pReserved;
376 *(sal_Bool *)pDestAny->pData = sal_False;
377 break;
378 case typelib_TypeClass_BYTE:
379 pDestAny->pData = &pDestAny->pReserved;
380 *(sal_Int8 *)pDestAny->pData = 0;
381 break;
382 case typelib_TypeClass_SHORT:
383 case typelib_TypeClass_UNSIGNED_SHORT:
384 pDestAny->pData = &pDestAny->pReserved;
385 *(sal_Int16 *)pDestAny->pData = 0;
386 break;
387 case typelib_TypeClass_LONG:
388 case typelib_TypeClass_UNSIGNED_LONG:
389 pDestAny->pData = &pDestAny->pReserved;
390 *(sal_Int32 *)pDestAny->pData = 0;
391 break;
392 case typelib_TypeClass_HYPER:
393 case typelib_TypeClass_UNSIGNED_HYPER:
394 if (sizeof(void *) >= sizeof(sal_Int64))
395 pDestAny->pData = &pDestAny->pReserved;
396 else
397 pDestAny->pData = ::rtl_allocateMemory( sizeof(sal_Int64) );
398 *(sal_Int64 *)pDestAny->pData = 0;
399 break;
400 case typelib_TypeClass_FLOAT:
401 if (sizeof(void *) >= sizeof(float))
402 pDestAny->pData = &pDestAny->pReserved;
403 else
404 pDestAny->pData = ::rtl_allocateMemory( sizeof(float) );
405 *(float *)pDestAny->pData = 0.0;
406 break;
407 case typelib_TypeClass_DOUBLE:
408 if (sizeof(void *) >= sizeof(double))
409 pDestAny->pData = &pDestAny->pReserved;
410 else
411 pDestAny->pData = ::rtl_allocateMemory( sizeof(double) );
412 *(double *)pDestAny->pData = 0.0;
413 break;
414 case typelib_TypeClass_STRING:
415 pDestAny->pData = &pDestAny->pReserved;
416 *(rtl_uString **)pDestAny->pData = 0;
417 ::rtl_uString_new( (rtl_uString **)pDestAny->pData );
418 break;
419 case typelib_TypeClass_TYPE:
420 pDestAny->pData = &pDestAny->pReserved;
421 *(typelib_TypeDescriptionReference **)pDestAny->pData = _getVoidType();
422 break;
423 case typelib_TypeClass_ENUM:
424 pDestAny->pData = &pDestAny->pReserved;
425 if (pTypeDescr)
427 *(sal_Int32 *)pDestAny->pData = ((typelib_EnumTypeDescription *)pTypeDescr)->nDefaultEnumValue;
429 else
431 TYPELIB_DANGER_GET( &pTypeDescr, pType );
432 *(sal_Int32 *)pDestAny->pData = ((typelib_EnumTypeDescription *)pTypeDescr)->nDefaultEnumValue;
433 TYPELIB_DANGER_RELEASE( pTypeDescr );
435 break;
436 case typelib_TypeClass_STRUCT:
437 case typelib_TypeClass_EXCEPTION:
438 if (pTypeDescr)
440 pDestAny->pData = ::rtl_allocateMemory( pTypeDescr->nSize );
441 _defaultConstructStruct(
442 pDestAny->pData, (typelib_CompoundTypeDescription *)pTypeDescr );
444 else
446 TYPELIB_DANGER_GET( &pTypeDescr, pType );
447 pDestAny->pData = ::rtl_allocateMemory( pTypeDescr->nSize );
448 _defaultConstructStruct(
449 pDestAny->pData, (typelib_CompoundTypeDescription *)pTypeDescr );
450 TYPELIB_DANGER_RELEASE( pTypeDescr );
452 break;
453 case typelib_TypeClass_ARRAY:
454 if (pTypeDescr)
456 pDestAny->pData = ::rtl_allocateMemory( pTypeDescr->nSize );
457 _defaultConstructArray(
458 pDestAny->pData, (typelib_ArrayTypeDescription *)pTypeDescr );
460 else
462 TYPELIB_DANGER_GET( &pTypeDescr, pType );
463 pDestAny->pData = ::rtl_allocateMemory( pTypeDescr->nSize );
464 _defaultConstructArray(
465 pDestAny->pData, (typelib_ArrayTypeDescription *)pTypeDescr );
466 TYPELIB_DANGER_RELEASE( pTypeDescr );
468 break;
469 case typelib_TypeClass_UNION:
470 if (pTypeDescr)
472 pDestAny->pData = ::rtl_allocateMemory( pTypeDescr->nSize );
473 _defaultConstructUnion( pDestAny->pData, pTypeDescr );
475 else
477 TYPELIB_DANGER_GET( &pTypeDescr, pType );
478 pDestAny->pData = ::rtl_allocateMemory( pTypeDescr->nSize );
479 _defaultConstructUnion( pDestAny->pData, pTypeDescr );
480 TYPELIB_DANGER_RELEASE( pTypeDescr );
482 break;
483 case typelib_TypeClass_SEQUENCE:
484 pDestAny->pData = &pDestAny->pReserved;
485 *(uno_Sequence **)pDestAny->pData = createEmptySequence();
486 break;
487 case typelib_TypeClass_INTERFACE:
488 pDestAny->pData = &pDestAny->pReserved;
489 pDestAny->pReserved = 0; // either cpp or c-uno interface
490 break;
491 default:
492 OSL_ASSERT(false);
493 break;
498 //------------------------------------------------------------------------------
499 inline uno_Sequence * icopyConstructSequence(
500 uno_Sequence * pSource,
501 typelib_TypeDescriptionReference * pElementType,
502 uno_AcquireFunc acquire, uno_Mapping * mapping )
504 typelib_TypeClass eTypeClass = pElementType->eTypeClass;
505 if (!mapping ||
506 (eTypeClass <= typelib_TypeClass_ENUM &&
507 eTypeClass != typelib_TypeClass_ANY))
509 osl_atomic_increment( &pSource->nRefCount );
510 return pSource;
512 else // create new sequence
514 uno_Sequence * pDest;
515 sal_Int32 nElements = pSource->nElements;
516 if (nElements)
518 switch (eTypeClass)
520 case typelib_TypeClass_ANY:
522 pDest = allocSeq( sizeof (uno_Any), nElements );
523 if (pDest != 0)
525 uno_Any * pDestElements = (uno_Any *)pDest->elements;
526 uno_Any * pSourceElements = (uno_Any *)pSource->elements;
527 for ( sal_Int32 nPos = nElements; nPos--; )
529 typelib_TypeDescriptionReference * pType =
530 pSourceElements[nPos].pType;
531 if (typelib_TypeClass_VOID == pType->eTypeClass)
533 CONSTRUCT_EMPTY_ANY( &pDestElements[nPos] );
535 else
537 _copyConstructAnyFromData(
538 &pDestElements[nPos],
539 pSourceElements[nPos].pData,
540 pType, 0,
541 acquire, mapping );
545 break;
547 case typelib_TypeClass_STRUCT:
548 case typelib_TypeClass_EXCEPTION:
550 typelib_TypeDescription * pElementTypeDescr = 0;
551 TYPELIB_DANGER_GET( &pElementTypeDescr, pElementType );
552 sal_Int32 nElementSize = pElementTypeDescr->nSize;
553 char * pSourceElements = pSource->elements;
554 pDest = allocSeq( nElementSize, nElements );
555 if (pDest != 0)
557 char * pElements = pDest->elements;
558 for ( sal_Int32 nPos = nElements; nPos--; )
560 _copyConstructStruct(
561 pElements + (nPos * nElementSize),
562 pSourceElements + (nPos * nElementSize),
563 (typelib_CompoundTypeDescription *)
564 pElementTypeDescr,
565 acquire, mapping );
568 TYPELIB_DANGER_RELEASE( pElementTypeDescr );
569 break;
571 case typelib_TypeClass_ARRAY:
573 typelib_TypeDescription * pElementTypeDescr = 0;
574 TYPELIB_DANGER_GET( &pElementTypeDescr, pElementType );
575 sal_Int32 nElementSize = pElementTypeDescr->nSize;
576 char * pSourceElements = pSource->elements;
577 pDest = allocSeq( nElementSize, nElements );
578 if (pDest != 0)
580 char * pElements = pDest->elements;
581 for ( sal_Int32 nPos = nElements; nPos--; )
583 _copyConstructArray(
584 pElements + (nPos * nElementSize),
585 pSourceElements + (nPos * nElementSize),
586 (typelib_ArrayTypeDescription *)pElementTypeDescr,
587 acquire, mapping );
590 TYPELIB_DANGER_RELEASE( pElementTypeDescr );
591 break;
593 case typelib_TypeClass_UNION:
595 typelib_TypeDescription * pElementTypeDescr = 0;
596 TYPELIB_DANGER_GET( &pElementTypeDescr, pElementType );
597 sal_Int32 nElementSize = pElementTypeDescr->nSize;
598 sal_Int32 nValueOffset =
599 ((typelib_UnionTypeDescription *)
600 pElementTypeDescr)->nValueOffset;
601 pDest = allocSeq( nElementSize, nElements );
602 if (pDest != 0)
604 char * pElements = pDest->elements;
605 char * pSourceElements = pSource->elements;
606 for ( sal_Int32 nPos = nElements; nPos--; )
608 char * pDest2 =
609 pElements + (nPos * nElementSize);
610 char * pSource2 =
611 pSourceElements + (nPos * nElementSize);
613 typelib_TypeDescriptionReference * pSetType =
614 _unionGetSetType( pSource2, pElementTypeDescr );
615 ::uno_type_copyAndConvertData(
616 pDest2 + nValueOffset, pSource2 + nValueOffset,
617 pSetType, mapping );
618 *(sal_Int64 *)pDest2 = *(sal_Int64 *)pSource2;
619 ::typelib_typedescriptionreference_release( pSetType );
622 TYPELIB_DANGER_RELEASE( pElementTypeDescr );
623 break;
625 case typelib_TypeClass_SEQUENCE: // sequence of sequence
627 pDest = allocSeq( sizeof (uno_Sequence *), nElements );
628 if (pDest != 0)
630 typelib_TypeDescription * pElementTypeDescr = 0;
631 TYPELIB_DANGER_GET( &pElementTypeDescr, pElementType );
632 typelib_TypeDescriptionReference * pSeqElementType =
633 ((typelib_IndirectTypeDescription *)
634 pElementTypeDescr)->pType;
636 uno_Sequence ** pDestElements =
637 (uno_Sequence **) pDest->elements;
638 uno_Sequence ** pSourceElements =
639 (uno_Sequence **) pSource->elements;
640 for ( sal_Int32 nPos = nElements; nPos--; )
642 uno_Sequence * pNew = copyConstructSequence(
643 pSourceElements[nPos],
644 pSeqElementType,
645 acquire, mapping );
646 OSL_ASSERT( pNew != 0 );
647 // ought never be a memory allocation problem,
648 // because of reference counted sequence handles
649 pDestElements[ nPos ] = pNew;
652 TYPELIB_DANGER_RELEASE( pElementTypeDescr );
654 break;
656 case typelib_TypeClass_INTERFACE:
658 pDest = allocSeq( sizeof (void *), nElements );
659 if (pDest != 0)
661 char * pElements = pDest->elements;
662 void ** pSourceElements = (void **)pSource->elements;
663 if (mapping)
665 typelib_TypeDescription * pElementTypeDescr = 0;
666 TYPELIB_DANGER_GET( &pElementTypeDescr, pElementType );
667 for ( sal_Int32 nPos = nElements; nPos--; )
669 ((void **)pElements)[nPos] = 0;
670 if (((void **)pSourceElements)[nPos])
672 (*mapping->mapInterface)(
673 mapping, (void **)pElements + nPos,
674 pSourceElements[nPos],
675 (typelib_InterfaceTypeDescription *)
676 pElementTypeDescr );
679 TYPELIB_DANGER_RELEASE( pElementTypeDescr );
681 else
683 for ( sal_Int32 nPos = nElements; nPos--; )
685 ((void **)pElements)[nPos] = pSourceElements[nPos];
686 _acquire( ((void **)pElements)[nPos], acquire );
690 break;
692 default:
693 OSL_FAIL( "### unexepcted sequence element type!" );
694 pDest = 0;
695 break;
698 else // empty sequence
700 pDest = allocSeq( 0, 0 );
703 return pDest;
707 //--------------------------------------------------------------------------------------------------
708 inline void _copyConstructData(
709 void * pDest, void * pSource,
710 typelib_TypeDescriptionReference * pType, typelib_TypeDescription * pTypeDescr,
711 uno_AcquireFunc acquire, uno_Mapping * mapping )
712 SAL_THROW (())
714 switch (pType->eTypeClass)
716 case typelib_TypeClass_CHAR:
717 *(sal_Unicode *)pDest = *(sal_Unicode *)pSource;
718 break;
719 case typelib_TypeClass_BOOLEAN:
720 *(sal_Bool *)pDest = (*(sal_Bool *)pSource != sal_False);
721 break;
722 case typelib_TypeClass_BYTE:
723 *(sal_Int8 *)pDest = *(sal_Int8 *)pSource;
724 break;
725 case typelib_TypeClass_SHORT:
726 case typelib_TypeClass_UNSIGNED_SHORT:
727 *(sal_Int16 *)pDest = *(sal_Int16 *)pSource;
728 break;
729 case typelib_TypeClass_LONG:
730 case typelib_TypeClass_UNSIGNED_LONG:
731 *(sal_Int32 *)pDest = *(sal_Int32 *)pSource;
732 break;
733 case typelib_TypeClass_HYPER:
734 case typelib_TypeClass_UNSIGNED_HYPER:
735 *(sal_Int64 *)pDest = *(sal_Int64 *)pSource;
736 break;
737 case typelib_TypeClass_FLOAT:
738 *(float *)pDest = *(float *)pSource;
739 break;
740 case typelib_TypeClass_DOUBLE:
741 *(double *)pDest = *(double *)pSource;
742 break;
743 case typelib_TypeClass_STRING:
744 ::rtl_uString_acquire( *(rtl_uString **)pSource );
745 *(rtl_uString **)pDest = *(rtl_uString **)pSource;
746 break;
747 case typelib_TypeClass_TYPE:
748 TYPE_ACQUIRE( *(typelib_TypeDescriptionReference **)pSource );
749 *(typelib_TypeDescriptionReference **)pDest = *(typelib_TypeDescriptionReference **)pSource;
750 break;
751 case typelib_TypeClass_ANY:
752 _copyConstructAny(
753 (uno_Any *)pDest, ((uno_Any *)pSource)->pData,
754 ((uno_Any *)pSource)->pType, 0,
755 acquire, mapping );
756 break;
757 case typelib_TypeClass_ENUM:
758 *(sal_Int32 *)pDest = *(sal_Int32 *)pSource;
759 break;
760 case typelib_TypeClass_STRUCT:
761 case typelib_TypeClass_EXCEPTION:
762 if (pTypeDescr)
764 _copyConstructStruct(
765 pDest, pSource,
766 (typelib_CompoundTypeDescription *)pTypeDescr,
767 acquire, mapping );
769 else
771 TYPELIB_DANGER_GET( &pTypeDescr, pType );
772 _copyConstructStruct(
773 pDest, pSource,
774 (typelib_CompoundTypeDescription *)pTypeDescr,
775 acquire, mapping );
776 TYPELIB_DANGER_RELEASE( pTypeDescr );
778 break;
779 case typelib_TypeClass_ARRAY:
780 if (pTypeDescr)
782 _copyConstructArray(
783 pDest, pSource,
784 (typelib_ArrayTypeDescription *)pTypeDescr,
785 acquire, mapping );
787 else
789 TYPELIB_DANGER_GET( &pTypeDescr, pType );
790 _copyConstructArray(
791 pDest, pSource,
792 (typelib_ArrayTypeDescription *)pTypeDescr,
793 acquire, mapping );
794 TYPELIB_DANGER_RELEASE( pTypeDescr );
796 break;
797 case typelib_TypeClass_UNION:
798 if (pTypeDescr)
800 _copyConstructUnion( pDest, pSource, pTypeDescr, acquire, mapping );
802 else
804 TYPELIB_DANGER_GET( &pTypeDescr, pType );
805 _copyConstructUnion( pDest, pSource, pTypeDescr, acquire, mapping );
806 TYPELIB_DANGER_RELEASE( pTypeDescr );
808 break;
809 case typelib_TypeClass_SEQUENCE:
810 if (mapping)
812 if (pTypeDescr)
814 *(uno_Sequence **)pDest = icopyConstructSequence(
815 *(uno_Sequence **)pSource,
816 ((typelib_IndirectTypeDescription *)pTypeDescr)->pType,
817 acquire, mapping );
819 else
821 TYPELIB_DANGER_GET( &pTypeDescr, pType );
822 *(uno_Sequence **)pDest = icopyConstructSequence(
823 *(uno_Sequence **)pSource,
824 ((typelib_IndirectTypeDescription *)pTypeDescr)->pType,
825 acquire, mapping );
826 TYPELIB_DANGER_RELEASE( pTypeDescr );
829 else
831 osl_atomic_increment( &(*(uno_Sequence **)pSource)->nRefCount );
832 *(uno_Sequence **)pDest = *(uno_Sequence **)pSource;
834 break;
835 case typelib_TypeClass_INTERFACE:
836 if (mapping)
837 *(void **)pDest = _map( *(void **)pSource, pType, pTypeDescr, mapping );
838 else
839 _acquire( *(void **)pDest = *(void **)pSource, acquire );
840 break;
841 default:
842 break;
848 #endif
850 /* vim:set shiftwidth=4 softtabstop=4 expandtab: */