xref: /AOO41X/main/cppu/source/uno/copy.hxx (revision c6ed87c9b37761ea466ee21111c4a4a314092829)
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