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