1 /* -*- Mode: C++; tab-width: 4; indent-tabs-mode: nil; c-basic-offset: 4 -*- */
3 * This file is part of the LibreOffice project.
5 * This Source Code Form is subject to the terms of the Mozilla Public
6 * License, v. 2.0. If a copy of the MPL was not distributed with this
7 * file, You can obtain one at http://mozilla.org/MPL/2.0/.
9 * This file incorporates work covered by the following license notice:
11 * Licensed to the Apache Software Foundation (ASF) under one or more
12 * contributor license agreements. See the NOTICE file distributed
13 * with this work for additional information regarding copyright
14 * ownership. The ASF licenses this file to you under the Apache
15 * License, Version 2.0 (the "License"); you may not use this file
16 * except in compliance with the License. You may obtain a copy of
17 * the License at http://www.apache.org/licenses/LICENSE-2.0 .
19 #ifndef INCLUDED_CPPU_SOURCE_UNO_COPY_HXX
20 #define INCLUDED_CPPU_SOURCE_UNO_COPY_HXX
30 //#### copy construction ###########################################################################
34 inline uno_Sequence
* allocSeq(
35 sal_Int32 nElementSize
, sal_Int32 nElements
)
37 OSL_ASSERT( nElements
>= 0 && nElementSize
>= 0 );
38 uno_Sequence
* pSeq
= 0;
39 sal_uInt32 nSize
= calcSeqMemSize( nElementSize
, nElements
);
42 pSeq
= static_cast<uno_Sequence
*>(rtl_allocateMemory( nSize
));
47 pSeq
->nElements
= nElements
;
54 void copyConstructStruct(
55 void * pDest
, void * pSource
,
56 typelib_CompoundTypeDescription
* pTypeDescr
,
57 uno_AcquireFunc acquire
, uno_Mapping
* mapping
);
59 inline void _copyConstructStruct(
60 void * pDest
, void * pSource
,
61 typelib_CompoundTypeDescription
* pTypeDescr
,
62 uno_AcquireFunc acquire
, uno_Mapping
* mapping
)
64 if (pTypeDescr
->pBaseTypeDescription
)
67 copyConstructStruct( pDest
, pSource
, pTypeDescr
->pBaseTypeDescription
, acquire
, mapping
);
71 typelib_TypeDescriptionReference
** ppTypeRefs
= pTypeDescr
->ppTypeRefs
;
72 sal_Int32
* pMemberOffsets
= pTypeDescr
->pMemberOffsets
;
73 sal_Int32 nDescr
= pTypeDescr
->nMembers
;
79 ::uno_type_copyAndConvertData(
80 static_cast<char *>(pDest
) + pMemberOffsets
[nDescr
],
81 static_cast<char *>(pSource
) + pMemberOffsets
[nDescr
],
82 ppTypeRefs
[nDescr
], mapping
);
90 static_cast<char *>(pDest
) + pMemberOffsets
[nDescr
],
91 static_cast<char *>(pSource
) + pMemberOffsets
[nDescr
],
92 ppTypeRefs
[nDescr
], acquire
);
98 uno_Sequence
* copyConstructSequence(
99 uno_Sequence
* pSource
,
100 typelib_TypeDescriptionReference
* pElementType
,
101 uno_AcquireFunc acquire
, uno_Mapping
* mapping
);
104 inline void _copyConstructAnyFromData(
105 uno_Any
* pDestAny
, void * pSource
,
106 typelib_TypeDescriptionReference
* pType
, typelib_TypeDescription
* pTypeDescr
,
107 uno_AcquireFunc acquire
, uno_Mapping
* mapping
)
109 TYPE_ACQUIRE( pType
);
110 pDestAny
->pType
= pType
;
112 switch (pType
->eTypeClass
)
114 case typelib_TypeClass_CHAR
:
115 pDestAny
->pData
= &pDestAny
->pReserved
;
116 *static_cast<sal_Unicode
*>(pDestAny
->pData
) = *static_cast<sal_Unicode
*>(pSource
);
118 case typelib_TypeClass_BOOLEAN
:
119 pDestAny
->pData
= &pDestAny
->pReserved
;
120 *static_cast<sal_Bool
*>(pDestAny
->pData
) = (*static_cast<sal_Bool
*>(pSource
) != sal_False
);
122 case typelib_TypeClass_BYTE
:
123 pDestAny
->pData
= &pDestAny
->pReserved
;
124 *static_cast<sal_Int8
*>(pDestAny
->pData
) = *static_cast<sal_Int8
*>(pSource
);
126 case typelib_TypeClass_SHORT
:
127 case typelib_TypeClass_UNSIGNED_SHORT
:
128 pDestAny
->pData
= &pDestAny
->pReserved
;
129 *static_cast<sal_Int16
*>(pDestAny
->pData
) = *static_cast<sal_Int16
*>(pSource
);
131 case typelib_TypeClass_LONG
:
132 case typelib_TypeClass_UNSIGNED_LONG
:
133 pDestAny
->pData
= &pDestAny
->pReserved
;
134 *static_cast<sal_Int32
*>(pDestAny
->pData
) = *static_cast<sal_Int32
*>(pSource
);
136 case typelib_TypeClass_HYPER
:
137 case typelib_TypeClass_UNSIGNED_HYPER
:
138 if (sizeof(void *) >= sizeof(sal_Int64
))
139 pDestAny
->pData
= &pDestAny
->pReserved
;
141 pDestAny
->pData
= ::rtl_allocateMemory( sizeof(sal_Int64
) );
142 *static_cast<sal_Int64
*>(pDestAny
->pData
) = *static_cast<sal_Int64
*>(pSource
);
144 case typelib_TypeClass_FLOAT
:
145 if (sizeof(void *) >= sizeof(float))
146 pDestAny
->pData
= &pDestAny
->pReserved
;
148 pDestAny
->pData
= ::rtl_allocateMemory( sizeof(float) );
149 *static_cast<float *>(pDestAny
->pData
) = *static_cast<float *>(pSource
);
151 case typelib_TypeClass_DOUBLE
:
152 if (sizeof(void *) >= sizeof(double))
153 pDestAny
->pData
= &pDestAny
->pReserved
;
155 pDestAny
->pData
= ::rtl_allocateMemory( sizeof(double) );
156 *static_cast<double *>(pDestAny
->pData
) = *static_cast<double *>(pSource
);
158 case typelib_TypeClass_STRING
:
159 ::rtl_uString_acquire( *static_cast<rtl_uString
**>(pSource
) );
160 pDestAny
->pData
= &pDestAny
->pReserved
;
161 *static_cast<rtl_uString
**>(pDestAny
->pData
) = *static_cast<rtl_uString
**>(pSource
);
163 case typelib_TypeClass_TYPE
:
164 TYPE_ACQUIRE( *static_cast<typelib_TypeDescriptionReference
**>(pSource
) );
165 pDestAny
->pData
= &pDestAny
->pReserved
;
166 *static_cast<typelib_TypeDescriptionReference
**>(pDestAny
->pData
) = *static_cast<typelib_TypeDescriptionReference
**>(pSource
);
168 case typelib_TypeClass_ANY
:
169 OSL_FAIL( "### unexpected nested any!" );
171 case typelib_TypeClass_ENUM
:
172 pDestAny
->pData
= &pDestAny
->pReserved
;
173 // enum is forced to 32bit long
174 *static_cast<sal_Int32
*>(pDestAny
->pData
) = *static_cast<sal_Int32
*>(pSource
);
176 case typelib_TypeClass_STRUCT
:
177 case typelib_TypeClass_EXCEPTION
:
180 pDestAny
->pData
= ::rtl_allocateMemory( pTypeDescr
->nSize
);
181 _copyConstructStruct(
182 pDestAny
->pData
, pSource
,
183 reinterpret_cast<typelib_CompoundTypeDescription
*>(pTypeDescr
),
188 TYPELIB_DANGER_GET( &pTypeDescr
, pType
);
189 pDestAny
->pData
= ::rtl_allocateMemory( pTypeDescr
->nSize
);
190 _copyConstructStruct(
191 pDestAny
->pData
, pSource
,
192 reinterpret_cast<typelib_CompoundTypeDescription
*>(pTypeDescr
),
194 TYPELIB_DANGER_RELEASE( pTypeDescr
);
197 case typelib_TypeClass_SEQUENCE
:
198 pDestAny
->pData
= &pDestAny
->pReserved
;
201 *static_cast<uno_Sequence
**>(pDestAny
->pData
) = copyConstructSequence(
202 *static_cast<uno_Sequence
**>(pSource
),
203 reinterpret_cast<typelib_IndirectTypeDescription
*>(pTypeDescr
)->pType
,
208 TYPELIB_DANGER_GET( &pTypeDescr
, pType
);
209 *static_cast<uno_Sequence
**>(pDestAny
->pData
) = copyConstructSequence(
210 *static_cast<uno_Sequence
**>(pSource
),
211 reinterpret_cast<typelib_IndirectTypeDescription
*>(pTypeDescr
)->pType
,
213 TYPELIB_DANGER_RELEASE( pTypeDescr
);
216 case typelib_TypeClass_INTERFACE
:
217 pDestAny
->pData
= &pDestAny
->pReserved
;
220 pDestAny
->pReserved
= _map( *static_cast<void **>(pSource
), pType
, pTypeDescr
, mapping
);
224 _acquire( pDestAny
->pReserved
= *static_cast<void **>(pSource
), acquire
);
233 inline void _copyConstructAny(
234 uno_Any
* pDestAny
, void * pSource
,
235 typelib_TypeDescriptionReference
* pType
, typelib_TypeDescription
* pTypeDescr
,
236 uno_AcquireFunc acquire
, uno_Mapping
* mapping
)
238 if (typelib_TypeClass_VOID
== pType
->eTypeClass
)
240 CONSTRUCT_EMPTY_ANY( pDestAny
);
244 if (typelib_TypeClass_ANY
== pType
->eTypeClass
)
248 pType
= static_cast<uno_Any
*>(pSource
)->pType
;
249 if (typelib_TypeClass_VOID
== pType
->eTypeClass
)
251 CONSTRUCT_EMPTY_ANY( pDestAny
);
255 pSource
= static_cast<uno_Any
*>(pSource
)->pData
;
259 CONSTRUCT_EMPTY_ANY( pDestAny
);
265 _copyConstructAnyFromData( pDestAny
, pSource
, pType
, pTypeDescr
, acquire
, mapping
);
267 else // default construct
269 TYPE_ACQUIRE( pType
);
270 pDestAny
->pType
= pType
;
271 switch (pType
->eTypeClass
)
273 case typelib_TypeClass_CHAR
:
274 pDestAny
->pData
= &pDestAny
->pReserved
;
275 *static_cast<sal_Unicode
*>(pDestAny
->pData
) = '\0';
277 case typelib_TypeClass_BOOLEAN
:
278 pDestAny
->pData
= &pDestAny
->pReserved
;
279 *static_cast<sal_Bool
*>(pDestAny
->pData
) = sal_False
;
281 case typelib_TypeClass_BYTE
:
282 pDestAny
->pData
= &pDestAny
->pReserved
;
283 *static_cast<sal_Int8
*>(pDestAny
->pData
) = 0;
285 case typelib_TypeClass_SHORT
:
286 case typelib_TypeClass_UNSIGNED_SHORT
:
287 pDestAny
->pData
= &pDestAny
->pReserved
;
288 *static_cast<sal_Int16
*>(pDestAny
->pData
) = 0;
290 case typelib_TypeClass_LONG
:
291 case typelib_TypeClass_UNSIGNED_LONG
:
292 pDestAny
->pData
= &pDestAny
->pReserved
;
293 *static_cast<sal_Int32
*>(pDestAny
->pData
) = 0;
295 case typelib_TypeClass_HYPER
:
296 case typelib_TypeClass_UNSIGNED_HYPER
:
297 if (sizeof(void *) >= sizeof(sal_Int64
))
298 pDestAny
->pData
= &pDestAny
->pReserved
;
300 pDestAny
->pData
= ::rtl_allocateMemory( sizeof(sal_Int64
) );
301 *static_cast<sal_Int64
*>(pDestAny
->pData
) = 0;
303 case typelib_TypeClass_FLOAT
:
304 if (sizeof(void *) >= sizeof(float))
305 pDestAny
->pData
= &pDestAny
->pReserved
;
307 pDestAny
->pData
= ::rtl_allocateMemory( sizeof(float) );
308 *static_cast<float *>(pDestAny
->pData
) = 0.0;
310 case typelib_TypeClass_DOUBLE
:
311 if (sizeof(void *) >= sizeof(double))
312 pDestAny
->pData
= &pDestAny
->pReserved
;
314 pDestAny
->pData
= ::rtl_allocateMemory( sizeof(double) );
315 *static_cast<double *>(pDestAny
->pData
) = 0.0;
317 case typelib_TypeClass_STRING
:
318 pDestAny
->pData
= &pDestAny
->pReserved
;
319 *static_cast<rtl_uString
**>(pDestAny
->pData
) = 0;
320 ::rtl_uString_new( static_cast<rtl_uString
**>(pDestAny
->pData
) );
322 case typelib_TypeClass_TYPE
:
323 pDestAny
->pData
= &pDestAny
->pReserved
;
324 *static_cast<typelib_TypeDescriptionReference
**>(pDestAny
->pData
) = _getVoidType();
326 case typelib_TypeClass_ENUM
:
327 pDestAny
->pData
= &pDestAny
->pReserved
;
330 *static_cast<sal_Int32
*>(pDestAny
->pData
) = reinterpret_cast<typelib_EnumTypeDescription
*>(pTypeDescr
)->nDefaultEnumValue
;
334 TYPELIB_DANGER_GET( &pTypeDescr
, pType
);
335 *static_cast<sal_Int32
*>(pDestAny
->pData
) = reinterpret_cast<typelib_EnumTypeDescription
*>(pTypeDescr
)->nDefaultEnumValue
;
336 TYPELIB_DANGER_RELEASE( pTypeDescr
);
339 case typelib_TypeClass_STRUCT
:
340 case typelib_TypeClass_EXCEPTION
:
343 pDestAny
->pData
= ::rtl_allocateMemory( pTypeDescr
->nSize
);
344 _defaultConstructStruct(
345 pDestAny
->pData
, reinterpret_cast<typelib_CompoundTypeDescription
*>(pTypeDescr
) );
349 TYPELIB_DANGER_GET( &pTypeDescr
, pType
);
350 pDestAny
->pData
= ::rtl_allocateMemory( pTypeDescr
->nSize
);
351 _defaultConstructStruct(
352 pDestAny
->pData
, reinterpret_cast<typelib_CompoundTypeDescription
*>(pTypeDescr
) );
353 TYPELIB_DANGER_RELEASE( pTypeDescr
);
356 case typelib_TypeClass_SEQUENCE
:
357 pDestAny
->pData
= &pDestAny
->pReserved
;
358 *static_cast<uno_Sequence
**>(pDestAny
->pData
) = createEmptySequence();
360 case typelib_TypeClass_INTERFACE
:
361 pDestAny
->pData
= &pDestAny
->pReserved
;
362 pDestAny
->pReserved
= 0; // either cpp or c-uno interface
372 inline uno_Sequence
* icopyConstructSequence(
373 uno_Sequence
* pSource
,
374 typelib_TypeDescriptionReference
* pElementType
,
375 uno_AcquireFunc acquire
, uno_Mapping
* mapping
)
377 typelib_TypeClass eTypeClass
= pElementType
->eTypeClass
;
379 (eTypeClass
<= typelib_TypeClass_ENUM
&&
380 eTypeClass
!= typelib_TypeClass_ANY
))
382 osl_atomic_increment( &pSource
->nRefCount
);
385 else // create new sequence
387 uno_Sequence
* pDest
;
388 sal_Int32 nElements
= pSource
->nElements
;
393 case typelib_TypeClass_ANY
:
395 pDest
= allocSeq( sizeof (uno_Any
), nElements
);
398 uno_Any
* pDestElements
= reinterpret_cast<uno_Any
*>(pDest
->elements
);
399 uno_Any
* pSourceElements
= reinterpret_cast<uno_Any
*>(pSource
->elements
);
400 for ( sal_Int32 nPos
= nElements
; nPos
--; )
402 typelib_TypeDescriptionReference
* pType
=
403 pSourceElements
[nPos
].pType
;
404 if (typelib_TypeClass_VOID
== pType
->eTypeClass
)
406 CONSTRUCT_EMPTY_ANY( &pDestElements
[nPos
] );
410 _copyConstructAnyFromData(
411 &pDestElements
[nPos
],
412 pSourceElements
[nPos
].pData
,
420 case typelib_TypeClass_STRUCT
:
421 case typelib_TypeClass_EXCEPTION
:
423 typelib_TypeDescription
* pElementTypeDescr
= 0;
424 TYPELIB_DANGER_GET( &pElementTypeDescr
, pElementType
);
425 sal_Int32 nElementSize
= pElementTypeDescr
->nSize
;
426 char * pSourceElements
= pSource
->elements
;
427 pDest
= allocSeq( nElementSize
, nElements
);
430 char * pElements
= pDest
->elements
;
431 for ( sal_Int32 nPos
= nElements
; nPos
--; )
433 _copyConstructStruct(
434 pElements
+ (nPos
* nElementSize
),
435 pSourceElements
+ (nPos
* nElementSize
),
436 reinterpret_cast<typelib_CompoundTypeDescription
*>(
441 TYPELIB_DANGER_RELEASE( pElementTypeDescr
);
444 case typelib_TypeClass_SEQUENCE
: // sequence of sequence
446 // coverity[suspicious_sizeof] - sizeof(uno_Sequence*) is correct here
447 pDest
= allocSeq( sizeof (uno_Sequence
*), nElements
);
450 typelib_TypeDescription
* pElementTypeDescr
= 0;
451 TYPELIB_DANGER_GET( &pElementTypeDescr
, pElementType
);
452 typelib_TypeDescriptionReference
* pSeqElementType
=
453 reinterpret_cast<typelib_IndirectTypeDescription
*>(
454 pElementTypeDescr
)->pType
;
456 uno_Sequence
** pDestElements
=
457 reinterpret_cast<uno_Sequence
**>(pDest
->elements
);
458 uno_Sequence
** pSourceElements
=
459 reinterpret_cast<uno_Sequence
**>(pSource
->elements
);
460 for ( sal_Int32 nPos
= nElements
; nPos
--; )
462 uno_Sequence
* pNew
= copyConstructSequence(
463 pSourceElements
[nPos
],
466 OSL_ASSERT( pNew
!= 0 );
467 // ought never be a memory allocation problem,
468 // because of reference counted sequence handles
469 pDestElements
[ nPos
] = pNew
;
472 TYPELIB_DANGER_RELEASE( pElementTypeDescr
);
476 case typelib_TypeClass_INTERFACE
:
478 pDest
= allocSeq( sizeof (void *), nElements
);
481 char * pElements
= pDest
->elements
;
482 void ** pSourceElements
= reinterpret_cast<void **>(pSource
->elements
);
483 typelib_TypeDescription
* pElementTypeDescr
= 0;
484 TYPELIB_DANGER_GET( &pElementTypeDescr
, pElementType
);
485 for ( sal_Int32 nPos
= nElements
; nPos
--; )
487 reinterpret_cast<void **>(pElements
)[nPos
] = 0;
488 if (pSourceElements
[nPos
])
490 (*mapping
->mapInterface
)(
491 mapping
, reinterpret_cast<void **>(pElements
) + nPos
,
492 pSourceElements
[nPos
],
493 reinterpret_cast<typelib_InterfaceTypeDescription
*>(
494 pElementTypeDescr
) );
497 TYPELIB_DANGER_RELEASE( pElementTypeDescr
);
502 OSL_FAIL( "### unexepcted sequence element type!" );
507 else // empty sequence
509 pDest
= allocSeq( 0, 0 );
517 inline void _copyConstructData(
518 void * pDest
, void * pSource
,
519 typelib_TypeDescriptionReference
* pType
, typelib_TypeDescription
* pTypeDescr
,
520 uno_AcquireFunc acquire
, uno_Mapping
* mapping
)
522 switch (pType
->eTypeClass
)
524 case typelib_TypeClass_CHAR
:
525 *static_cast<sal_Unicode
*>(pDest
) = *static_cast<sal_Unicode
*>(pSource
);
527 case typelib_TypeClass_BOOLEAN
:
528 *static_cast<sal_Bool
*>(pDest
) = (*static_cast<sal_Bool
*>(pSource
) != sal_False
);
530 case typelib_TypeClass_BYTE
:
531 *static_cast<sal_Int8
*>(pDest
) = *static_cast<sal_Int8
*>(pSource
);
533 case typelib_TypeClass_SHORT
:
534 case typelib_TypeClass_UNSIGNED_SHORT
:
535 *static_cast<sal_Int16
*>(pDest
) = *static_cast<sal_Int16
*>(pSource
);
537 case typelib_TypeClass_LONG
:
538 case typelib_TypeClass_UNSIGNED_LONG
:
539 *static_cast<sal_Int32
*>(pDest
) = *static_cast<sal_Int32
*>(pSource
);
541 case typelib_TypeClass_HYPER
:
542 case typelib_TypeClass_UNSIGNED_HYPER
:
543 *static_cast<sal_Int64
*>(pDest
) = *static_cast<sal_Int64
*>(pSource
);
545 case typelib_TypeClass_FLOAT
:
546 *static_cast<float *>(pDest
) = *static_cast<float *>(pSource
);
548 case typelib_TypeClass_DOUBLE
:
549 *static_cast<double *>(pDest
) = *static_cast<double *>(pSource
);
551 case typelib_TypeClass_STRING
:
552 ::rtl_uString_acquire( *static_cast<rtl_uString
**>(pSource
) );
553 *static_cast<rtl_uString
**>(pDest
) = *static_cast<rtl_uString
**>(pSource
);
555 case typelib_TypeClass_TYPE
:
556 TYPE_ACQUIRE( *static_cast<typelib_TypeDescriptionReference
**>(pSource
) );
557 *static_cast<typelib_TypeDescriptionReference
**>(pDest
) = *static_cast<typelib_TypeDescriptionReference
**>(pSource
);
559 case typelib_TypeClass_ANY
:
561 static_cast<uno_Any
*>(pDest
), static_cast<uno_Any
*>(pSource
)->pData
,
562 static_cast<uno_Any
*>(pSource
)->pType
, 0,
565 case typelib_TypeClass_ENUM
:
566 *static_cast<sal_Int32
*>(pDest
) = *static_cast<sal_Int32
*>(pSource
);
568 case typelib_TypeClass_STRUCT
:
569 case typelib_TypeClass_EXCEPTION
:
572 _copyConstructStruct(
574 reinterpret_cast<typelib_CompoundTypeDescription
*>(pTypeDescr
),
579 TYPELIB_DANGER_GET( &pTypeDescr
, pType
);
580 _copyConstructStruct(
582 reinterpret_cast<typelib_CompoundTypeDescription
*>(pTypeDescr
),
584 TYPELIB_DANGER_RELEASE( pTypeDescr
);
587 case typelib_TypeClass_SEQUENCE
:
592 *static_cast<uno_Sequence
**>(pDest
) = icopyConstructSequence(
593 *static_cast<uno_Sequence
**>(pSource
),
594 reinterpret_cast<typelib_IndirectTypeDescription
*>(pTypeDescr
)->pType
,
599 TYPELIB_DANGER_GET( &pTypeDescr
, pType
);
600 *static_cast<uno_Sequence
**>(pDest
) = icopyConstructSequence(
601 *static_cast<uno_Sequence
**>(pSource
),
602 reinterpret_cast<typelib_IndirectTypeDescription
*>(pTypeDescr
)->pType
,
604 TYPELIB_DANGER_RELEASE( pTypeDescr
);
609 osl_atomic_increment( &(*static_cast<uno_Sequence
**>(pSource
))->nRefCount
);
610 *static_cast<uno_Sequence
**>(pDest
) = *static_cast<uno_Sequence
**>(pSource
);
613 case typelib_TypeClass_INTERFACE
:
615 *static_cast<void **>(pDest
) = _map( *static_cast<void **>(pSource
), pType
, pTypeDescr
, mapping
);
617 _acquire( *static_cast<void **>(pDest
) = *static_cast<void **>(pSource
), acquire
);
628 /* vim:set shiftwidth=4 softtabstop=4 expandtab: */