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