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