/src/libreoffice/cppu/source/uno/copy.hxx
Line | Count | Source |
1 | | /* -*- Mode: C++; tab-width: 4; indent-tabs-mode: nil; c-basic-offset: 4 -*- */ |
2 | | /* |
3 | | * This file is part of the LibreOffice project. |
4 | | * |
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/. |
8 | | * |
9 | | * This file incorporates work covered by the following license notice: |
10 | | * |
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 . |
18 | | */ |
19 | | #pragma once |
20 | | |
21 | | #include "prim.hxx" |
22 | | #include "constr.hxx" |
23 | | #include <cassert> |
24 | | #include <cstddef> |
25 | | #include <cstdlib> |
26 | | #include <type_traits> |
27 | | |
28 | | namespace cppu |
29 | | { |
30 | | |
31 | | |
32 | | //#### copy construction ########################################################################### |
33 | | |
34 | | namespace { |
35 | | |
36 | | // The non-dynamic prefix of sal_Sequence (aka uno_Sequence): |
37 | | struct SequencePrefix { |
38 | | sal_Int32 nRefCount; |
39 | | sal_Int32 nElements; |
40 | | }; |
41 | | static_assert(sizeof (SequencePrefix) < sizeof (uno_Sequence)); |
42 | | static_assert(offsetof(SequencePrefix, nRefCount) == offsetof(uno_Sequence, nRefCount)); |
43 | | static_assert( |
44 | | std::is_same_v<decltype(SequencePrefix::nRefCount), decltype(uno_Sequence::nRefCount)>); |
45 | | static_assert(offsetof(SequencePrefix, nElements) == offsetof(uno_Sequence, nElements)); |
46 | | static_assert( |
47 | | std::is_same_v<decltype(SequencePrefix::nElements), decltype(uno_Sequence::nElements)>); |
48 | | |
49 | | } |
50 | | |
51 | | inline uno_Sequence * allocSeq( |
52 | | sal_Int32 nElementSize, sal_Int32 nElements ) |
53 | 1.10M | { |
54 | 1.10M | OSL_ASSERT( nElements >= 0 && nElementSize >= 0 ); |
55 | 1.10M | uno_Sequence * pSeq = nullptr; |
56 | 1.10M | sal_uInt32 nSize = calcSeqMemSize( nElementSize, nElements ); |
57 | 1.10M | if (nSize > 0) |
58 | 1.10M | { |
59 | 1.10M | pSeq = static_cast<uno_Sequence *>(std::malloc( nSize )); |
60 | 1.10M | if (pSeq != nullptr) |
61 | 1.10M | { |
62 | | // header init, going via SequencePrefix to avoid UBSan insufficient-object-size |
63 | | // warnings when `nElements == 0` and thus `nSize < sizeof (uno_Sequence)`: |
64 | 1.10M | auto const header = reinterpret_cast<SequencePrefix *>(pSeq); |
65 | 1.10M | header->nRefCount = 1; |
66 | 1.10M | header->nElements = nElements; |
67 | 1.10M | } |
68 | 1.10M | } |
69 | 1.10M | return pSeq; |
70 | 1.10M | } |
71 | | |
72 | | |
73 | | void copyConstructStruct( |
74 | | void * pDest, void * pSource, |
75 | | typelib_CompoundTypeDescription * pTypeDescr, |
76 | | uno_AcquireFunc acquire, uno_Mapping * mapping ); |
77 | | |
78 | | inline void _copyConstructStruct( |
79 | | void * pDest, void * pSource, |
80 | | typelib_CompoundTypeDescription * pTypeDescr, |
81 | | uno_AcquireFunc acquire, uno_Mapping * mapping ) |
82 | 35.4M | { |
83 | 35.4M | if (pTypeDescr->pBaseTypeDescription) |
84 | 4.86M | { |
85 | | // copy base value |
86 | 4.86M | copyConstructStruct( pDest, pSource, pTypeDescr->pBaseTypeDescription, acquire, mapping ); |
87 | 4.86M | } |
88 | | |
89 | | // then copy members |
90 | 35.4M | typelib_TypeDescriptionReference ** ppTypeRefs = pTypeDescr->ppTypeRefs; |
91 | 35.4M | sal_Int32 * pMemberOffsets = pTypeDescr->pMemberOffsets; |
92 | 35.4M | sal_Int32 nDescr = pTypeDescr->nMembers; |
93 | | |
94 | 35.4M | if (mapping) |
95 | 322k | { |
96 | 717k | while (nDescr--) |
97 | 394k | { |
98 | 394k | ::uno_type_copyAndConvertData( |
99 | 394k | static_cast<char *>(pDest) + pMemberOffsets[nDescr], |
100 | 394k | static_cast<char *>(pSource) + pMemberOffsets[nDescr], |
101 | 394k | ppTypeRefs[nDescr], mapping ); |
102 | 394k | } |
103 | 322k | } |
104 | 35.1M | else |
105 | 35.1M | { |
106 | 161M | while (nDescr--) |
107 | 126M | { |
108 | 126M | ::uno_type_copyData( |
109 | 126M | static_cast<char *>(pDest) + pMemberOffsets[nDescr], |
110 | 126M | static_cast<char *>(pSource) + pMemberOffsets[nDescr], |
111 | 126M | ppTypeRefs[nDescr], acquire ); |
112 | 126M | } |
113 | 35.1M | } |
114 | 35.4M | } |
115 | | |
116 | | |
117 | | uno_Sequence * copyConstructSequence( |
118 | | uno_Sequence * pSource, |
119 | | typelib_TypeDescriptionReference * pElementType, |
120 | | uno_AcquireFunc acquire, uno_Mapping * mapping ); |
121 | | |
122 | | |
123 | | inline void _copyConstructAnyFromData( |
124 | | uno_Any * pDestAny, void * pSource, |
125 | | typelib_TypeDescriptionReference * pType, typelib_TypeDescription * pTypeDescr, |
126 | | uno_AcquireFunc acquire, uno_Mapping * mapping ) |
127 | 861M | { |
128 | 861M | TYPE_ACQUIRE( pType ); |
129 | 861M | pDestAny->pType = pType; |
130 | | |
131 | 861M | switch (pType->eTypeClass) |
132 | 861M | { |
133 | 15 | case typelib_TypeClass_CHAR: |
134 | 15 | pDestAny->pData = &pDestAny->pReserved; |
135 | 15 | *static_cast<sal_Unicode *>(pDestAny->pData) = *static_cast<sal_Unicode *>(pSource); |
136 | 15 | break; |
137 | 103M | case typelib_TypeClass_BOOLEAN: |
138 | 103M | pDestAny->pData = &pDestAny->pReserved; |
139 | 103M | *static_cast<sal_Bool *>(pDestAny->pData) = bool(*static_cast<sal_Bool *>(pSource)); |
140 | 103M | break; |
141 | 1.79M | case typelib_TypeClass_BYTE: |
142 | 1.79M | pDestAny->pData = &pDestAny->pReserved; |
143 | 1.79M | *static_cast<sal_Int8 *>(pDestAny->pData) = *static_cast<sal_Int8 *>(pSource); |
144 | 1.79M | break; |
145 | 26.1M | case typelib_TypeClass_SHORT: |
146 | 32.8M | case typelib_TypeClass_UNSIGNED_SHORT: |
147 | 32.8M | pDestAny->pData = &pDestAny->pReserved; |
148 | 32.8M | *static_cast<sal_Int16 *>(pDestAny->pData) = *static_cast<sal_Int16 *>(pSource); |
149 | 32.8M | break; |
150 | 56.6M | case typelib_TypeClass_LONG: |
151 | 56.6M | case typelib_TypeClass_UNSIGNED_LONG: |
152 | 66.0M | case typelib_TypeClass_ENUM: // enum is forced to 32bit long |
153 | 66.0M | pDestAny->pData = &pDestAny->pReserved; |
154 | 66.0M | *static_cast<sal_Int32 *>(pDestAny->pData) = *static_cast<sal_Int32 *>(pSource); |
155 | 66.0M | break; |
156 | 512k | case typelib_TypeClass_HYPER: |
157 | 513k | case typelib_TypeClass_UNSIGNED_HYPER: |
158 | 513k | if (sizeof(void *) >= sizeof(sal_Int64)) |
159 | 513k | pDestAny->pData = &pDestAny->pReserved; |
160 | 0 | else |
161 | 0 | pDestAny->pData = std::malloc( sizeof(sal_Int64) ); |
162 | 513k | assert(pDestAny->pData); |
163 | 513k | *static_cast<sal_Int64 *>(pDestAny->pData) = *static_cast<sal_Int64 *>(pSource); |
164 | 513k | break; |
165 | 7.83M | case typelib_TypeClass_FLOAT: |
166 | 7.83M | if (sizeof(void *) >= sizeof(float)) |
167 | 7.83M | pDestAny->pData = &pDestAny->pReserved; |
168 | 0 | else |
169 | 0 | pDestAny->pData = std::malloc( sizeof(float) ); |
170 | 7.83M | assert(pDestAny->pData); |
171 | 7.83M | *static_cast<float *>(pDestAny->pData) = *static_cast<float *>(pSource); |
172 | 7.83M | break; |
173 | 2.56M | case typelib_TypeClass_DOUBLE: |
174 | 2.56M | if (sizeof(void *) >= sizeof(double)) |
175 | 2.56M | pDestAny->pData = &pDestAny->pReserved; |
176 | 0 | else |
177 | 0 | pDestAny->pData = std::malloc( sizeof(double) ); |
178 | 2.56M | assert(pDestAny->pData); |
179 | 2.56M | *static_cast<double *>(pDestAny->pData) = *static_cast<double *>(pSource); |
180 | 2.56M | break; |
181 | 371M | case typelib_TypeClass_STRING: |
182 | 371M | ::rtl_uString_acquire( *static_cast<rtl_uString **>(pSource) ); |
183 | 371M | pDestAny->pData = &pDestAny->pReserved; |
184 | 371M | *static_cast<rtl_uString **>(pDestAny->pData) = *static_cast<rtl_uString **>(pSource); |
185 | 371M | break; |
186 | 0 | case typelib_TypeClass_TYPE: |
187 | 0 | TYPE_ACQUIRE( *static_cast<typelib_TypeDescriptionReference **>(pSource) ); |
188 | 0 | pDestAny->pData = &pDestAny->pReserved; |
189 | 0 | *static_cast<typelib_TypeDescriptionReference **>(pDestAny->pData) = *static_cast<typelib_TypeDescriptionReference **>(pSource); |
190 | 0 | break; |
191 | 0 | case typelib_TypeClass_ANY: |
192 | 0 | OSL_FAIL( "### unexpected nested any!" ); |
193 | 0 | break; |
194 | 13.4M | case typelib_TypeClass_STRUCT: |
195 | 15.7M | case typelib_TypeClass_EXCEPTION: |
196 | 15.7M | if (pTypeDescr) |
197 | 71.6k | { |
198 | 71.6k | pDestAny->pData = std::malloc( pTypeDescr->nSize ); |
199 | 71.6k | _copyConstructStruct( |
200 | 71.6k | pDestAny->pData, pSource, |
201 | 71.6k | reinterpret_cast<typelib_CompoundTypeDescription *>(pTypeDescr), |
202 | 71.6k | acquire, mapping ); |
203 | 71.6k | } |
204 | 15.7M | else |
205 | 15.7M | { |
206 | 15.7M | TYPELIB_DANGER_GET( &pTypeDescr, pType ); |
207 | 15.7M | pDestAny->pData = std::malloc( pTypeDescr->nSize ); |
208 | 15.7M | _copyConstructStruct( |
209 | 15.7M | pDestAny->pData, pSource, |
210 | 15.7M | reinterpret_cast<typelib_CompoundTypeDescription *>(pTypeDescr), |
211 | 15.7M | acquire, mapping ); |
212 | 15.7M | TYPELIB_DANGER_RELEASE( pTypeDescr ); |
213 | 15.7M | } |
214 | 15.7M | break; |
215 | 7.22M | case typelib_TypeClass_SEQUENCE: |
216 | 7.22M | pDestAny->pData = &pDestAny->pReserved; |
217 | 7.22M | if (pTypeDescr) |
218 | 0 | { |
219 | 0 | *static_cast<uno_Sequence **>(pDestAny->pData) = copyConstructSequence( |
220 | 0 | *static_cast<uno_Sequence **>(pSource), |
221 | 0 | reinterpret_cast<typelib_IndirectTypeDescription *>(pTypeDescr)->pType, |
222 | 0 | acquire, mapping ); |
223 | 0 | } |
224 | 7.22M | else |
225 | 7.22M | { |
226 | 7.22M | TYPELIB_DANGER_GET( &pTypeDescr, pType ); |
227 | 7.22M | *static_cast<uno_Sequence **>(pDestAny->pData) = copyConstructSequence( |
228 | 7.22M | *static_cast<uno_Sequence **>(pSource), |
229 | 7.22M | reinterpret_cast<typelib_IndirectTypeDescription *>(pTypeDescr)->pType, |
230 | 7.22M | acquire, mapping ); |
231 | 7.22M | TYPELIB_DANGER_RELEASE( pTypeDescr ); |
232 | 7.22M | } |
233 | 7.22M | break; |
234 | 252M | case typelib_TypeClass_INTERFACE: |
235 | 252M | pDestAny->pData = &pDestAny->pReserved; |
236 | 252M | if (mapping) |
237 | 3.49k | { |
238 | 3.49k | pDestAny->pReserved = _map( *static_cast<void **>(pSource), pType, pTypeDescr, mapping ); |
239 | 3.49k | } |
240 | 252M | else |
241 | 252M | { |
242 | 252M | pDestAny->pReserved = *static_cast<void **>(pSource); |
243 | 252M | _acquire( pDestAny->pReserved, acquire ); |
244 | 252M | } |
245 | 252M | break; |
246 | 0 | default: |
247 | 0 | OSL_ASSERT(false); |
248 | 0 | break; |
249 | 861M | } |
250 | 861M | } |
251 | | |
252 | | inline void _copyConstructAny( |
253 | | uno_Any * pDestAny, void * pSource, |
254 | | typelib_TypeDescriptionReference * pType, typelib_TypeDescription * pTypeDescr, |
255 | | uno_AcquireFunc acquire, uno_Mapping * mapping ) |
256 | 934M | { |
257 | 934M | if (typelib_TypeClass_VOID == pType->eTypeClass) |
258 | 71.2M | { |
259 | 71.2M | CONSTRUCT_EMPTY_ANY( pDestAny ); |
260 | 71.2M | } |
261 | 863M | else |
262 | 863M | { |
263 | 863M | if (typelib_TypeClass_ANY == pType->eTypeClass) |
264 | 4.01k | { |
265 | 4.01k | if (pSource) |
266 | 4.01k | { |
267 | 4.01k | pType = static_cast<uno_Any *>(pSource)->pType; |
268 | 4.01k | if (typelib_TypeClass_VOID == pType->eTypeClass) |
269 | 0 | { |
270 | 0 | CONSTRUCT_EMPTY_ANY( pDestAny ); |
271 | 0 | return; |
272 | 0 | } |
273 | 4.01k | pTypeDescr = nullptr; |
274 | 4.01k | pSource = static_cast<uno_Any *>(pSource)->pData; |
275 | 4.01k | } |
276 | 0 | else |
277 | 0 | { |
278 | 0 | CONSTRUCT_EMPTY_ANY( pDestAny ); |
279 | 0 | return; |
280 | 0 | } |
281 | 4.01k | } |
282 | 863M | if (pSource) |
283 | 861M | { |
284 | 861M | _copyConstructAnyFromData( pDestAny, pSource, pType, pTypeDescr, acquire, mapping ); |
285 | 861M | } |
286 | 1.14M | else // default construct |
287 | 1.14M | { |
288 | 1.14M | TYPE_ACQUIRE( pType ); |
289 | 1.14M | pDestAny->pType = pType; |
290 | 1.14M | switch (pType->eTypeClass) |
291 | 1.14M | { |
292 | 0 | case typelib_TypeClass_CHAR: |
293 | 0 | pDestAny->pData = &pDestAny->pReserved; |
294 | 0 | *static_cast<sal_Unicode *>(pDestAny->pData) = '\0'; |
295 | 0 | break; |
296 | 0 | case typelib_TypeClass_BOOLEAN: |
297 | 0 | pDestAny->pData = &pDestAny->pReserved; |
298 | 0 | *static_cast<sal_Bool *>(pDestAny->pData) = false; |
299 | 0 | break; |
300 | 0 | case typelib_TypeClass_BYTE: |
301 | 0 | pDestAny->pData = &pDestAny->pReserved; |
302 | 0 | *static_cast<sal_Int8 *>(pDestAny->pData) = 0; |
303 | 0 | break; |
304 | 0 | case typelib_TypeClass_SHORT: |
305 | 0 | case typelib_TypeClass_UNSIGNED_SHORT: |
306 | 0 | pDestAny->pData = &pDestAny->pReserved; |
307 | 0 | *static_cast<sal_Int16 *>(pDestAny->pData) = 0; |
308 | 0 | break; |
309 | 956k | case typelib_TypeClass_LONG: |
310 | 956k | case typelib_TypeClass_UNSIGNED_LONG: |
311 | 956k | pDestAny->pData = &pDestAny->pReserved; |
312 | 956k | *static_cast<sal_Int32 *>(pDestAny->pData) = 0; |
313 | 956k | break; |
314 | 0 | case typelib_TypeClass_HYPER: |
315 | 0 | case typelib_TypeClass_UNSIGNED_HYPER: |
316 | 0 | if (sizeof(void *) >= sizeof(sal_Int64)) |
317 | 0 | pDestAny->pData = &pDestAny->pReserved; |
318 | 0 | else |
319 | 0 | pDestAny->pData = std::malloc( sizeof(sal_Int64) ); |
320 | 0 | assert(pDestAny->pData); |
321 | 0 | *static_cast<sal_Int64 *>(pDestAny->pData) = 0; |
322 | 0 | break; |
323 | 0 | case typelib_TypeClass_FLOAT: |
324 | 0 | if (sizeof(void *) >= sizeof(float)) |
325 | 0 | pDestAny->pData = &pDestAny->pReserved; |
326 | 0 | else |
327 | 0 | pDestAny->pData = std::malloc( sizeof(float) ); |
328 | 0 | assert(pDestAny->pData); |
329 | 0 | *static_cast<float *>(pDestAny->pData) = 0.0; |
330 | 0 | break; |
331 | 0 | case typelib_TypeClass_DOUBLE: |
332 | 0 | if (sizeof(void *) >= sizeof(double)) |
333 | 0 | pDestAny->pData = &pDestAny->pReserved; |
334 | 0 | else |
335 | 0 | pDestAny->pData = std::malloc( sizeof(double) ); |
336 | 0 | assert(pDestAny->pData); |
337 | 0 | *static_cast<double *>(pDestAny->pData) = 0.0; |
338 | 0 | break; |
339 | 637k | case typelib_TypeClass_STRING: |
340 | 637k | pDestAny->pData = &pDestAny->pReserved; |
341 | 637k | *static_cast<rtl_uString **>(pDestAny->pData) = nullptr; |
342 | 637k | ::rtl_uString_new( static_cast<rtl_uString **>(pDestAny->pData) ); |
343 | 637k | break; |
344 | 0 | case typelib_TypeClass_TYPE: |
345 | 0 | pDestAny->pData = &pDestAny->pReserved; |
346 | 0 | *static_cast<typelib_TypeDescriptionReference **>(pDestAny->pData) = _getVoidType(); |
347 | 0 | break; |
348 | 0 | case typelib_TypeClass_ENUM: |
349 | 0 | pDestAny->pData = &pDestAny->pReserved; |
350 | 0 | if (pTypeDescr) |
351 | 0 | { |
352 | 0 | *static_cast<sal_Int32 *>(pDestAny->pData) = reinterpret_cast<typelib_EnumTypeDescription *>(pTypeDescr)->nDefaultEnumValue; |
353 | 0 | } |
354 | 0 | else |
355 | 0 | { |
356 | 0 | TYPELIB_DANGER_GET( &pTypeDescr, pType ); |
357 | 0 | *static_cast<sal_Int32 *>(pDestAny->pData) = reinterpret_cast<typelib_EnumTypeDescription *>(pTypeDescr)->nDefaultEnumValue; |
358 | 0 | TYPELIB_DANGER_RELEASE( pTypeDescr ); |
359 | 0 | } |
360 | 0 | break; |
361 | 0 | case typelib_TypeClass_STRUCT: |
362 | 0 | case typelib_TypeClass_EXCEPTION: |
363 | 0 | if (pTypeDescr) |
364 | 0 | { |
365 | 0 | pDestAny->pData = std::malloc( pTypeDescr->nSize ); |
366 | 0 | _defaultConstructStruct( |
367 | 0 | pDestAny->pData, reinterpret_cast<typelib_CompoundTypeDescription *>(pTypeDescr) ); |
368 | 0 | } |
369 | 0 | else |
370 | 0 | { |
371 | 0 | TYPELIB_DANGER_GET( &pTypeDescr, pType ); |
372 | 0 | pDestAny->pData = std::malloc( pTypeDescr->nSize ); |
373 | 0 | _defaultConstructStruct( |
374 | 0 | pDestAny->pData, reinterpret_cast<typelib_CompoundTypeDescription *>(pTypeDescr) ); |
375 | 0 | TYPELIB_DANGER_RELEASE( pTypeDescr ); |
376 | 0 | } |
377 | 0 | break; |
378 | 0 | case typelib_TypeClass_SEQUENCE: |
379 | 0 | pDestAny->pData = &pDestAny->pReserved; |
380 | 0 | *static_cast<uno_Sequence **>(pDestAny->pData) = createEmptySequence(); |
381 | 0 | break; |
382 | 0 | case typelib_TypeClass_INTERFACE: |
383 | 0 | pDestAny->pData = &pDestAny->pReserved; |
384 | 0 | pDestAny->pReserved = nullptr; // either cpp or c-uno interface |
385 | 0 | break; |
386 | 0 | default: |
387 | 0 | OSL_ASSERT(false); |
388 | 0 | break; |
389 | 1.14M | } |
390 | 1.14M | } |
391 | 863M | } |
392 | 934M | } |
393 | | |
394 | | inline uno_Sequence * icopyConstructSequence( |
395 | | uno_Sequence * pSource, |
396 | | typelib_TypeDescriptionReference * pElementType, |
397 | | uno_AcquireFunc acquire, uno_Mapping * mapping ) |
398 | 7.28M | { |
399 | 7.28M | typelib_TypeClass eTypeClass = pElementType->eTypeClass; |
400 | 7.28M | if (!mapping || |
401 | 72 | (eTypeClass <= typelib_TypeClass_ENUM && |
402 | 60 | eTypeClass != typelib_TypeClass_ANY)) |
403 | 7.28M | { |
404 | 7.28M | osl_atomic_increment( &pSource->nRefCount ); |
405 | 7.28M | return pSource; |
406 | 7.28M | } |
407 | 12 | else // create new sequence |
408 | 12 | { |
409 | 12 | uno_Sequence * pDest; |
410 | 12 | sal_Int32 nElements = pSource->nElements; |
411 | 12 | if (nElements) |
412 | 12 | { |
413 | 12 | switch (eTypeClass) |
414 | 12 | { |
415 | 0 | case typelib_TypeClass_ANY: |
416 | 0 | { |
417 | 0 | pDest = allocSeq( sizeof (uno_Any), nElements ); |
418 | 0 | if (pDest != nullptr) |
419 | 0 | { |
420 | 0 | uno_Any * pDestElements = reinterpret_cast<uno_Any *>(pDest->elements); |
421 | 0 | uno_Any * pSourceElements = reinterpret_cast<uno_Any *>(pSource->elements); |
422 | 0 | for ( sal_Int32 nPos = nElements; nPos--; ) |
423 | 0 | { |
424 | 0 | typelib_TypeDescriptionReference * pType = |
425 | 0 | pSourceElements[nPos].pType; |
426 | 0 | if (typelib_TypeClass_VOID == pType->eTypeClass) |
427 | 0 | { |
428 | 0 | CONSTRUCT_EMPTY_ANY( &pDestElements[nPos] ); |
429 | 0 | } |
430 | 0 | else |
431 | 0 | { |
432 | 0 | _copyConstructAnyFromData( |
433 | 0 | &pDestElements[nPos], |
434 | 0 | pSourceElements[nPos].pData, |
435 | 0 | pType, nullptr, |
436 | 0 | acquire, mapping ); |
437 | 0 | } |
438 | 0 | } |
439 | 0 | } |
440 | 0 | break; |
441 | 0 | } |
442 | 0 | case typelib_TypeClass_STRUCT: |
443 | 0 | case typelib_TypeClass_EXCEPTION: |
444 | 0 | { |
445 | 0 | typelib_TypeDescription * pElementTypeDescr = nullptr; |
446 | 0 | TYPELIB_DANGER_GET( &pElementTypeDescr, pElementType ); |
447 | 0 | sal_Int32 nElementSize = pElementTypeDescr->nSize; |
448 | 0 | char * pSourceElements = pSource->elements; |
449 | 0 | pDest = allocSeq( nElementSize, nElements ); |
450 | 0 | if (pDest != nullptr) |
451 | 0 | { |
452 | 0 | char * pElements = pDest->elements; |
453 | 0 | for ( sal_Int32 nPos = nElements; nPos--; ) |
454 | 0 | { |
455 | 0 | _copyConstructStruct( |
456 | 0 | pElements + (nPos * nElementSize), |
457 | 0 | pSourceElements + (nPos * nElementSize), |
458 | 0 | reinterpret_cast<typelib_CompoundTypeDescription *>( |
459 | 0 | pElementTypeDescr), |
460 | 0 | acquire, mapping ); |
461 | 0 | } |
462 | 0 | } |
463 | 0 | TYPELIB_DANGER_RELEASE( pElementTypeDescr ); |
464 | 0 | break; |
465 | 0 | } |
466 | 12 | case typelib_TypeClass_SEQUENCE: // sequence of sequence |
467 | 12 | { |
468 | 12 | pDest = allocSeq( sizeof (uno_Sequence *), nElements ); |
469 | 12 | if (pDest != nullptr) |
470 | 12 | { |
471 | 12 | typelib_TypeDescription * pElementTypeDescr = nullptr; |
472 | 12 | TYPELIB_DANGER_GET( &pElementTypeDescr, pElementType ); |
473 | 12 | typelib_TypeDescriptionReference * pSeqElementType = |
474 | 12 | reinterpret_cast<typelib_IndirectTypeDescription *>( |
475 | 12 | pElementTypeDescr)->pType; |
476 | | |
477 | 12 | uno_Sequence ** pDestElements = |
478 | 12 | reinterpret_cast<uno_Sequence **>(pDest->elements); |
479 | 12 | uno_Sequence ** pSourceElements = |
480 | 12 | reinterpret_cast<uno_Sequence **>(pSource->elements); |
481 | 72 | for ( sal_Int32 nPos = nElements; nPos--; ) |
482 | 60 | { |
483 | 60 | uno_Sequence * pNew = copyConstructSequence( |
484 | 60 | pSourceElements[nPos], |
485 | 60 | pSeqElementType, |
486 | 60 | acquire, mapping ); |
487 | 60 | OSL_ASSERT( pNew != nullptr ); |
488 | | // ought never be a memory allocation problem, |
489 | | // because of reference counted sequence handles |
490 | 60 | pDestElements[ nPos ] = pNew; |
491 | 60 | } |
492 | | |
493 | 12 | TYPELIB_DANGER_RELEASE( pElementTypeDescr ); |
494 | 12 | } |
495 | 12 | break; |
496 | 0 | } |
497 | 0 | case typelib_TypeClass_INTERFACE: |
498 | 0 | { |
499 | 0 | pDest = allocSeq( sizeof (void *), nElements ); |
500 | 0 | if (pDest != nullptr) |
501 | 0 | { |
502 | 0 | char * pElements = pDest->elements; |
503 | 0 | void ** pSourceElements = reinterpret_cast<void **>(pSource->elements); |
504 | 0 | typelib_TypeDescription * pElementTypeDescr = nullptr; |
505 | 0 | TYPELIB_DANGER_GET( &pElementTypeDescr, pElementType ); |
506 | 0 | for ( sal_Int32 nPos = nElements; nPos--; ) |
507 | 0 | { |
508 | 0 | reinterpret_cast<void **>(pElements)[nPos] = nullptr; |
509 | 0 | if (pSourceElements[nPos]) |
510 | 0 | { |
511 | 0 | (*mapping->mapInterface)( |
512 | 0 | mapping, reinterpret_cast<void **>(pElements) + nPos, |
513 | 0 | pSourceElements[nPos], |
514 | 0 | reinterpret_cast<typelib_InterfaceTypeDescription *>( |
515 | 0 | pElementTypeDescr) ); |
516 | 0 | } |
517 | 0 | } |
518 | 0 | TYPELIB_DANGER_RELEASE( pElementTypeDescr ); |
519 | 0 | } |
520 | 0 | break; |
521 | 0 | } |
522 | 0 | default: |
523 | 0 | OSL_FAIL( "### unexpected sequence element type!" ); |
524 | 0 | pDest = nullptr; |
525 | 0 | break; |
526 | 12 | } |
527 | 12 | } |
528 | 0 | else // empty sequence |
529 | 0 | { |
530 | 0 | pDest = allocSeq( 0, 0 ); |
531 | 0 | } |
532 | | |
533 | 12 | return pDest; |
534 | 12 | } |
535 | 7.28M | } |
536 | | |
537 | | |
538 | | inline void _copyConstructData( |
539 | | void * pDest, void * pSource, |
540 | | typelib_TypeDescriptionReference * pType, typelib_TypeDescription * pTypeDescr, |
541 | | uno_AcquireFunc acquire, uno_Mapping * mapping ) |
542 | 485M | { |
543 | 485M | switch (pType->eTypeClass) |
544 | 485M | { |
545 | 149k | case typelib_TypeClass_CHAR: |
546 | 149k | *static_cast<sal_Unicode *>(pDest) = *static_cast<sal_Unicode *>(pSource); |
547 | 149k | break; |
548 | 46.0M | case typelib_TypeClass_BOOLEAN: |
549 | 46.0M | *static_cast<sal_Bool *>(pDest) = bool(*static_cast<sal_Bool *>(pSource)); |
550 | 46.0M | break; |
551 | 48 | case typelib_TypeClass_BYTE: |
552 | 48 | *static_cast<sal_Int8 *>(pDest) = *static_cast<sal_Int8 *>(pSource); |
553 | 48 | break; |
554 | 149M | case typelib_TypeClass_SHORT: |
555 | 150M | case typelib_TypeClass_UNSIGNED_SHORT: |
556 | 150M | *static_cast<sal_Int16 *>(pDest) = *static_cast<sal_Int16 *>(pSource); |
557 | 150M | break; |
558 | 41.9M | case typelib_TypeClass_LONG: |
559 | 42.7M | case typelib_TypeClass_UNSIGNED_LONG: |
560 | 64.5M | case typelib_TypeClass_ENUM: |
561 | 64.5M | *static_cast<sal_Int32 *>(pDest) = *static_cast<sal_Int32 *>(pSource); |
562 | 64.5M | break; |
563 | 0 | case typelib_TypeClass_HYPER: |
564 | 0 | case typelib_TypeClass_UNSIGNED_HYPER: |
565 | 0 | *static_cast<sal_Int64 *>(pDest) = *static_cast<sal_Int64 *>(pSource); |
566 | 0 | break; |
567 | 10.5M | case typelib_TypeClass_FLOAT: |
568 | 10.5M | *static_cast<float *>(pDest) = *static_cast<float *>(pSource); |
569 | 10.5M | break; |
570 | 1.99M | case typelib_TypeClass_DOUBLE: |
571 | 1.99M | *static_cast<double *>(pDest) = *static_cast<double *>(pSource); |
572 | 1.99M | break; |
573 | 161M | case typelib_TypeClass_STRING: |
574 | 161M | ::rtl_uString_acquire( *static_cast<rtl_uString **>(pSource) ); |
575 | 161M | *static_cast<rtl_uString **>(pDest) = *static_cast<rtl_uString **>(pSource); |
576 | 161M | break; |
577 | 844k | case typelib_TypeClass_TYPE: |
578 | 844k | TYPE_ACQUIRE( *static_cast<typelib_TypeDescriptionReference **>(pSource) ); |
579 | 844k | *static_cast<typelib_TypeDescriptionReference **>(pDest) = *static_cast<typelib_TypeDescriptionReference **>(pSource); |
580 | 844k | break; |
581 | 31.2M | case typelib_TypeClass_ANY: |
582 | 31.2M | _copyConstructAny( |
583 | 31.2M | static_cast<uno_Any *>(pDest), static_cast<uno_Any *>(pSource)->pData, |
584 | 31.2M | static_cast<uno_Any *>(pSource)->pType, nullptr, |
585 | 31.2M | acquire, mapping ); |
586 | 31.2M | break; |
587 | 14.7M | case typelib_TypeClass_STRUCT: |
588 | 14.7M | case typelib_TypeClass_EXCEPTION: |
589 | 14.7M | if (pTypeDescr) |
590 | 0 | { |
591 | 0 | _copyConstructStruct( |
592 | 0 | pDest, pSource, |
593 | 0 | reinterpret_cast<typelib_CompoundTypeDescription *>(pTypeDescr), |
594 | 0 | acquire, mapping ); |
595 | 0 | } |
596 | 14.7M | else |
597 | 14.7M | { |
598 | 14.7M | TYPELIB_DANGER_GET( &pTypeDescr, pType ); |
599 | 14.7M | _copyConstructStruct( |
600 | 14.7M | pDest, pSource, |
601 | 14.7M | reinterpret_cast<typelib_CompoundTypeDescription *>(pTypeDescr), |
602 | 14.7M | acquire, mapping ); |
603 | 14.7M | TYPELIB_DANGER_RELEASE( pTypeDescr ); |
604 | 14.7M | } |
605 | 14.7M | break; |
606 | 496k | case typelib_TypeClass_SEQUENCE: |
607 | 496k | if (mapping) |
608 | 12 | { |
609 | 12 | if (pTypeDescr) |
610 | 0 | { |
611 | 0 | *static_cast<uno_Sequence **>(pDest) = icopyConstructSequence( |
612 | 0 | *static_cast<uno_Sequence **>(pSource), |
613 | 0 | reinterpret_cast<typelib_IndirectTypeDescription *>(pTypeDescr)->pType, |
614 | 0 | acquire, mapping ); |
615 | 0 | } |
616 | 12 | else |
617 | 12 | { |
618 | 12 | TYPELIB_DANGER_GET( &pTypeDescr, pType ); |
619 | 12 | *static_cast<uno_Sequence **>(pDest) = icopyConstructSequence( |
620 | 12 | *static_cast<uno_Sequence **>(pSource), |
621 | 12 | reinterpret_cast<typelib_IndirectTypeDescription *>(pTypeDescr)->pType, |
622 | 12 | acquire, mapping ); |
623 | 12 | TYPELIB_DANGER_RELEASE( pTypeDescr ); |
624 | 12 | } |
625 | 12 | } |
626 | 496k | else |
627 | 496k | { |
628 | 496k | osl_atomic_increment( &(*static_cast<uno_Sequence **>(pSource))->nRefCount ); |
629 | 496k | *static_cast<uno_Sequence **>(pDest) = *static_cast<uno_Sequence **>(pSource); |
630 | 496k | } |
631 | 496k | break; |
632 | 3.40M | case typelib_TypeClass_INTERFACE: |
633 | 3.40M | if (mapping) |
634 | 171k | *static_cast<void **>(pDest) = _map( *static_cast<void **>(pSource), pType, pTypeDescr, mapping ); |
635 | 3.23M | else |
636 | 3.23M | { |
637 | 3.23M | *static_cast<void **>(pDest) = *static_cast<void **>(pSource); |
638 | 3.23M | _acquire( *static_cast<void **>(pDest), acquire ); |
639 | 3.23M | } |
640 | 3.40M | break; |
641 | 0 | default: |
642 | 0 | break; |
643 | 485M | } |
644 | 485M | } |
645 | | |
646 | | } |
647 | | |
648 | | /* vim:set shiftwidth=4 softtabstop=4 expandtab: */ |