/src/libreoffice/cppu/source/uno/sequence.cxx
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 | | |
20 | | #include <sal/config.h> |
21 | | |
22 | | #include <cassert> |
23 | | #include <cstdlib> |
24 | | #include <string.h> |
25 | | |
26 | | #include <osl/diagnose.h> |
27 | | #include <osl/interlck.h> |
28 | | #include <typelib/typedescription.h> |
29 | | #include <uno/data.h> |
30 | | #include <uno/sequence2.h> |
31 | | |
32 | | #include "constr.hxx" |
33 | | #include "copy.hxx" |
34 | | #include "destr.hxx" |
35 | | |
36 | | |
37 | | using namespace cppu; |
38 | | |
39 | | namespace cppu |
40 | | { |
41 | | |
42 | | |
43 | | static uno_Sequence * reallocSeq( |
44 | | uno_Sequence * pReallocate, std::size_t nElementSize, sal_Int32 nElements ) |
45 | 25.6M | { |
46 | 25.6M | OSL_ASSERT( nElements >= 0 ); |
47 | 25.6M | uno_Sequence * pNew = nullptr; |
48 | 25.6M | sal_uInt32 nSize = calcSeqMemSize( nElementSize, nElements ); |
49 | 25.6M | if (nSize > 0) |
50 | 25.6M | { |
51 | 25.6M | if (pReallocate == nullptr) |
52 | 24.8M | { |
53 | 24.8M | pNew = static_cast<uno_Sequence *>(std::malloc( nSize )); |
54 | 24.8M | } |
55 | 764k | else |
56 | 764k | { |
57 | 764k | pNew = static_cast<uno_Sequence *>(std::realloc( pReallocate, nSize )); |
58 | 764k | } |
59 | 25.6M | if (pNew != nullptr) |
60 | 25.6M | { |
61 | | // header init |
62 | 25.6M | pNew->nRefCount = 1; |
63 | 25.6M | pNew->nElements = nElements; |
64 | 25.6M | } |
65 | 25.6M | } |
66 | 25.6M | return pNew; |
67 | 25.6M | } |
68 | | |
69 | | |
70 | | static bool idefaultConstructElements( |
71 | | uno_Sequence ** ppSeq, |
72 | | typelib_TypeDescriptionReference * pElementType, |
73 | | sal_Int32 nStartIndex, sal_Int32 nStopIndex, |
74 | | sal_Int32 nAlloc ) // >= 0 means (re)alloc memory for nAlloc elements |
75 | 15.2M | { |
76 | 15.2M | uno_Sequence * pSeq = *ppSeq; |
77 | 15.2M | switch (pElementType->eTypeClass) |
78 | 15.2M | { |
79 | 11.3k | case typelib_TypeClass_CHAR: |
80 | 11.3k | if (nAlloc >= 0) |
81 | 11.3k | pSeq = reallocSeq( pSeq, sizeof(sal_Unicode), nAlloc ); |
82 | 11.3k | if (pSeq != nullptr) |
83 | 11.3k | { |
84 | 11.3k | memset( |
85 | 11.3k | pSeq->elements + (sizeof(sal_Unicode) * nStartIndex), |
86 | 11.3k | 0, |
87 | 11.3k | sizeof(sal_Unicode) * (nStopIndex - nStartIndex) ); |
88 | 11.3k | } |
89 | 11.3k | break; |
90 | 402 | case typelib_TypeClass_BOOLEAN: |
91 | 402 | if (nAlloc >= 0) |
92 | 402 | pSeq = reallocSeq( pSeq, sizeof(sal_Bool), nAlloc ); |
93 | 402 | if (pSeq != nullptr) |
94 | 402 | { |
95 | 402 | memset( |
96 | 402 | pSeq->elements + (sizeof(sal_Bool) * nStartIndex), |
97 | 402 | 0, |
98 | 402 | sizeof(sal_Bool) * (nStopIndex - nStartIndex) ); |
99 | 402 | } |
100 | 402 | break; |
101 | 1.29M | case typelib_TypeClass_BYTE: |
102 | 1.29M | if (nAlloc >= 0) |
103 | 986k | pSeq = reallocSeq( pSeq, sizeof(sal_Int8), nAlloc ); |
104 | 1.29M | if (pSeq != nullptr) |
105 | 1.29M | { |
106 | 1.29M | memset( |
107 | 1.29M | pSeq->elements + (sizeof(sal_Int8) * nStartIndex), |
108 | 1.29M | 0, |
109 | 1.29M | sizeof(sal_Int8) * (nStopIndex - nStartIndex) ); |
110 | 1.29M | } |
111 | 1.29M | break; |
112 | 740 | case typelib_TypeClass_SHORT: |
113 | 740 | case typelib_TypeClass_UNSIGNED_SHORT: |
114 | 740 | if (nAlloc >= 0) |
115 | 740 | pSeq = reallocSeq( pSeq, sizeof(sal_Int16), nAlloc ); |
116 | 740 | if (pSeq != nullptr) |
117 | 740 | { |
118 | 740 | memset( |
119 | 740 | pSeq->elements + (sizeof(sal_Int16) * nStartIndex), |
120 | 740 | 0, |
121 | 740 | sizeof(sal_Int16) * (nStopIndex - nStartIndex) ); |
122 | 740 | } |
123 | 740 | break; |
124 | 15.9k | case typelib_TypeClass_LONG: |
125 | 15.9k | case typelib_TypeClass_UNSIGNED_LONG: |
126 | 15.9k | if (nAlloc >= 0) |
127 | 15.9k | pSeq = reallocSeq( pSeq, sizeof(sal_Int32), nAlloc ); |
128 | 15.9k | if (pSeq != nullptr) |
129 | 15.9k | { |
130 | 15.9k | memset( |
131 | 15.9k | pSeq->elements + (sizeof(sal_Int32) * nStartIndex), |
132 | 15.9k | 0, |
133 | 15.9k | sizeof(sal_Int32) * (nStopIndex - nStartIndex) ); |
134 | 15.9k | } |
135 | 15.9k | break; |
136 | 0 | case typelib_TypeClass_HYPER: |
137 | 0 | case typelib_TypeClass_UNSIGNED_HYPER: |
138 | 0 | if (nAlloc >= 0) |
139 | 0 | pSeq = reallocSeq( pSeq, sizeof(sal_Int64), nAlloc ); |
140 | 0 | if (pSeq != nullptr) |
141 | 0 | { |
142 | 0 | memset( |
143 | 0 | pSeq->elements + (sizeof(sal_Int64) * nStartIndex), |
144 | 0 | 0, |
145 | 0 | sizeof(sal_Int64) * (nStopIndex - nStartIndex) ); |
146 | 0 | } |
147 | 0 | break; |
148 | 0 | case typelib_TypeClass_FLOAT: |
149 | 0 | { |
150 | 0 | if (nAlloc >= 0) |
151 | 0 | pSeq = reallocSeq( pSeq, sizeof(float), nAlloc ); |
152 | 0 | if (pSeq != nullptr) |
153 | 0 | { |
154 | 0 | float * pElements = reinterpret_cast<float *>(pSeq->elements); |
155 | 0 | for ( sal_Int32 nPos = nStartIndex; nPos < nStopIndex; ++nPos ) |
156 | 0 | { |
157 | 0 | pElements[nPos] = 0.0; |
158 | 0 | } |
159 | 0 | } |
160 | 0 | break; |
161 | 0 | } |
162 | 617 | case typelib_TypeClass_DOUBLE: |
163 | 617 | { |
164 | 617 | if (nAlloc >= 0) |
165 | 617 | pSeq = reallocSeq( pSeq, sizeof(double), nAlloc ); |
166 | 617 | if (pSeq != nullptr) |
167 | 617 | { |
168 | 617 | double * pElements = reinterpret_cast<double *>(pSeq->elements); |
169 | 1.82k | for ( sal_Int32 nPos = nStartIndex; nPos < nStopIndex; ++nPos ) |
170 | 1.20k | { |
171 | 1.20k | pElements[nPos] = 0.0; |
172 | 1.20k | } |
173 | 617 | } |
174 | 617 | break; |
175 | 0 | } |
176 | 1.64M | case typelib_TypeClass_STRING: |
177 | 1.64M | { |
178 | 1.64M | if (nAlloc >= 0) |
179 | 424k | pSeq = reallocSeq( pSeq, sizeof(rtl_uString *), nAlloc ); |
180 | 1.64M | if (pSeq != nullptr) |
181 | 1.64M | { |
182 | 1.64M | rtl_uString ** pElements = reinterpret_cast<rtl_uString **>(pSeq->elements); |
183 | 23.3M | for ( sal_Int32 nPos = nStartIndex; nPos < nStopIndex; ++nPos ) |
184 | 21.7M | { |
185 | 21.7M | pElements[nPos] = nullptr; |
186 | 21.7M | rtl_uString_new( &pElements[nPos] ); |
187 | 21.7M | } |
188 | 1.64M | } |
189 | 1.64M | break; |
190 | 0 | } |
191 | 9 | case typelib_TypeClass_TYPE: |
192 | 9 | { |
193 | 9 | if (nAlloc >= 0) |
194 | 9 | { |
195 | 9 | pSeq = reallocSeq( |
196 | 9 | pSeq, sizeof(typelib_TypeDescriptionReference *), nAlloc ); |
197 | 9 | } |
198 | 9 | if (pSeq != nullptr) |
199 | 9 | { |
200 | 9 | typelib_TypeDescriptionReference ** pElements = |
201 | 9 | reinterpret_cast<typelib_TypeDescriptionReference **>(pSeq->elements); |
202 | 78 | for ( sal_Int32 nPos = nStartIndex; nPos < nStopIndex; ++nPos ) |
203 | 69 | { |
204 | 69 | pElements[nPos] = _getVoidType(); |
205 | 69 | } |
206 | 9 | } |
207 | 9 | break; |
208 | 0 | } |
209 | 2.22M | case typelib_TypeClass_ANY: |
210 | 2.22M | { |
211 | 2.22M | if (nAlloc >= 0) |
212 | 1.09M | pSeq = reallocSeq( pSeq, sizeof(uno_Any), nAlloc ); |
213 | 2.22M | if (pSeq != nullptr) |
214 | 2.22M | { |
215 | 2.22M | uno_Any * pElements = reinterpret_cast<uno_Any *>(pSeq->elements); |
216 | 17.6M | for ( sal_Int32 nPos = nStartIndex; nPos < nStopIndex; ++nPos ) |
217 | 15.4M | { |
218 | 15.4M | CONSTRUCT_EMPTY_ANY( &pElements[nPos] ); |
219 | 15.4M | } |
220 | 2.22M | } |
221 | 2.22M | break; |
222 | 0 | } |
223 | 211k | case typelib_TypeClass_ENUM: |
224 | 211k | { |
225 | 211k | if (nAlloc >= 0) |
226 | 211k | pSeq = reallocSeq( pSeq, sizeof(sal_Int32), nAlloc ); |
227 | 211k | if (pSeq != nullptr) |
228 | 211k | { |
229 | 211k | typelib_TypeDescription * pElementTypeDescr = nullptr; |
230 | 211k | TYPELIB_DANGER_GET( &pElementTypeDescr, pElementType ); |
231 | 211k | if (pElementTypeDescr == nullptr) { |
232 | 0 | std::abort(); |
233 | 0 | } |
234 | 211k | sal_Int32 eEnum = |
235 | 211k | reinterpret_cast<typelib_EnumTypeDescription *>( |
236 | 211k | pElementTypeDescr)->nDefaultEnumValue; |
237 | 211k | TYPELIB_DANGER_RELEASE( pElementTypeDescr ); |
238 | | |
239 | 211k | sal_Int32 * pElements = reinterpret_cast<sal_Int32 *>(pSeq->elements); |
240 | 5.10M | for ( sal_Int32 nPos = nStartIndex; nPos < nStopIndex; ++nPos ) |
241 | 4.89M | { |
242 | 4.89M | pElements[nPos] = eEnum; |
243 | 4.89M | } |
244 | 211k | } |
245 | 211k | break; |
246 | 211k | } |
247 | 9.64M | case typelib_TypeClass_STRUCT: |
248 | 9.64M | case typelib_TypeClass_EXCEPTION: |
249 | 9.64M | { |
250 | 9.64M | typelib_TypeDescription * pElementTypeDescr = nullptr; |
251 | 9.64M | TYPELIB_DANGER_GET( &pElementTypeDescr, pElementType ); |
252 | 9.64M | if (pElementTypeDescr == nullptr) { |
253 | 0 | std::abort(); |
254 | 0 | } |
255 | 9.64M | sal_Int32 nElementSize = pElementTypeDescr->nSize; |
256 | | |
257 | 9.64M | if (nAlloc >= 0) |
258 | 5.20M | pSeq = reallocSeq( pSeq, nElementSize, nAlloc ); |
259 | 9.64M | if (pSeq != nullptr) |
260 | 9.64M | { |
261 | 9.64M | char * pElements = pSeq->elements; |
262 | 98.7M | for ( sal_Int32 nPos = nStartIndex; nPos < nStopIndex; ++nPos ) |
263 | 89.1M | { |
264 | 89.1M | _defaultConstructStruct( |
265 | 89.1M | pElements + (nElementSize * nPos), |
266 | 89.1M | reinterpret_cast<typelib_CompoundTypeDescription *>(pElementTypeDescr) ); |
267 | 89.1M | } |
268 | 9.64M | } |
269 | | |
270 | 9.64M | TYPELIB_DANGER_RELEASE( pElementTypeDescr ); |
271 | 9.64M | break; |
272 | 9.64M | } |
273 | 192k | case typelib_TypeClass_SEQUENCE: |
274 | 192k | { |
275 | 192k | if (nAlloc >= 0) |
276 | 150k | { |
277 | 150k | pSeq = reallocSeq(pSeq, sizeof(uno_Sequence*), nAlloc); |
278 | 150k | } |
279 | 192k | if (pSeq != nullptr) |
280 | 192k | { |
281 | 192k | uno_Sequence ** pElements = |
282 | 192k | reinterpret_cast<uno_Sequence **>(pSeq->elements); |
283 | 482k | for ( sal_Int32 nPos = nStartIndex; nPos < nStopIndex; ++nPos ) |
284 | 289k | { |
285 | 289k | pElements[nPos] = createEmptySequence(); |
286 | 289k | } |
287 | 192k | } |
288 | 192k | break; |
289 | 9.64M | } |
290 | 26.8k | case typelib_TypeClass_INTERFACE: // either C++ or C-UNO interface |
291 | 26.8k | if (nAlloc >= 0) |
292 | 26.6k | pSeq = reallocSeq( pSeq, sizeof(void *), nAlloc ); |
293 | 26.8k | if (pSeq != nullptr) |
294 | 26.8k | { |
295 | 26.8k | memset( |
296 | 26.8k | pSeq->elements + (sizeof(void *) * nStartIndex), |
297 | 26.8k | 0, |
298 | 26.8k | sizeof(void *) * (nStopIndex - nStartIndex) ); |
299 | 26.8k | } |
300 | 26.8k | break; |
301 | 0 | default: |
302 | 0 | OSL_FAIL( "### unexpected element type!" ); |
303 | 0 | pSeq = nullptr; |
304 | 0 | break; |
305 | 15.2M | } |
306 | | |
307 | 15.2M | if (pSeq == nullptr) |
308 | 7 | { |
309 | 7 | OSL_ASSERT( nAlloc >= 0 ); // must have been an allocation failure |
310 | 7 | return false; |
311 | 7 | } |
312 | 15.2M | *ppSeq = pSeq; |
313 | 15.2M | return true; |
314 | 15.2M | } |
315 | | |
316 | | // coverity[ -tainted_data_sink : arg-1 ] 2024.6.1 |
317 | | static bool icopyConstructFromElements( |
318 | | uno_Sequence ** ppSeq, void * pSourceElements, |
319 | | typelib_TypeDescriptionReference * pElementType, |
320 | | sal_Int32 nStopIndex, |
321 | | uno_AcquireFunc acquire, |
322 | | sal_Int32 nAlloc ) |
323 | 16.7M | { |
324 | 16.7M | uno_Sequence * pSeq = *ppSeq; |
325 | 16.7M | switch (pElementType->eTypeClass) |
326 | 16.7M | { |
327 | 800 | case typelib_TypeClass_CHAR: |
328 | 800 | pSeq = reallocSeq( pSeq, sizeof(sal_Unicode), nAlloc ); |
329 | 800 | if (pSeq != nullptr) |
330 | 800 | { |
331 | 800 | memcpy( |
332 | 800 | pSeq->elements, |
333 | 800 | pSourceElements, |
334 | 800 | sizeof(sal_Unicode) * nStopIndex ); |
335 | 800 | } |
336 | 800 | break; |
337 | 0 | case typelib_TypeClass_BOOLEAN: |
338 | 0 | pSeq = reallocSeq( pSeq, sizeof(sal_Bool), nAlloc ); |
339 | 0 | if (pSeq != nullptr) |
340 | 0 | { |
341 | 0 | memcpy( |
342 | 0 | pSeq->elements, |
343 | 0 | pSourceElements, |
344 | 0 | sizeof(sal_Bool) * nStopIndex ); |
345 | 0 | } |
346 | 0 | break; |
347 | 2.50M | case typelib_TypeClass_BYTE: |
348 | 2.50M | pSeq = reallocSeq( pSeq, sizeof(sal_Int8), nAlloc ); |
349 | 2.50M | if (pSeq != nullptr) |
350 | 2.50M | { |
351 | 2.50M | memcpy( |
352 | 2.50M | pSeq->elements, |
353 | 2.50M | pSourceElements, |
354 | 2.50M | sizeof(sal_Int8) * nStopIndex ); |
355 | 2.50M | } |
356 | 2.50M | break; |
357 | 0 | case typelib_TypeClass_SHORT: |
358 | 0 | case typelib_TypeClass_UNSIGNED_SHORT: |
359 | 0 | pSeq = reallocSeq( pSeq, sizeof(sal_Int16), nAlloc ); |
360 | 0 | if (pSeq != nullptr) |
361 | 0 | { |
362 | 0 | memcpy( |
363 | 0 | pSeq->elements, |
364 | 0 | pSourceElements, |
365 | 0 | sizeof(sal_Int16) * nStopIndex ); |
366 | 0 | } |
367 | 0 | break; |
368 | 13.6k | case typelib_TypeClass_LONG: |
369 | 13.6k | case typelib_TypeClass_UNSIGNED_LONG: |
370 | 13.6k | pSeq = reallocSeq( pSeq, sizeof(sal_Int32), nAlloc ); |
371 | 13.6k | if (pSeq != nullptr) |
372 | 13.6k | { |
373 | 13.6k | memcpy( |
374 | 13.6k | pSeq->elements, |
375 | 13.6k | pSourceElements, |
376 | 13.6k | sizeof(sal_Int32) * nStopIndex ); |
377 | 13.6k | } |
378 | 13.6k | break; |
379 | 0 | case typelib_TypeClass_HYPER: |
380 | 0 | case typelib_TypeClass_UNSIGNED_HYPER: |
381 | 0 | pSeq = reallocSeq( pSeq, sizeof(sal_Int64), nAlloc ); |
382 | 0 | if (pSeq != nullptr) |
383 | 0 | { |
384 | 0 | memcpy( |
385 | 0 | pSeq->elements, |
386 | 0 | pSourceElements, |
387 | 0 | sizeof(sal_Int64) * nStopIndex ); |
388 | 0 | } |
389 | 0 | break; |
390 | 0 | case typelib_TypeClass_FLOAT: |
391 | 0 | pSeq = reallocSeq( pSeq, sizeof(float), nAlloc ); |
392 | 0 | if (pSeq != nullptr) |
393 | 0 | { |
394 | 0 | memcpy( |
395 | 0 | pSeq->elements, |
396 | 0 | pSourceElements, |
397 | 0 | sizeof(float) * nStopIndex ); |
398 | 0 | } |
399 | 0 | break; |
400 | 80 | case typelib_TypeClass_DOUBLE: |
401 | 80 | pSeq = reallocSeq( pSeq, sizeof(double), nAlloc ); |
402 | 80 | if (pSeq != nullptr) |
403 | 80 | { |
404 | 80 | memcpy( |
405 | 80 | pSeq->elements, |
406 | 80 | pSourceElements, |
407 | 80 | sizeof(double) * nStopIndex ); |
408 | 80 | } |
409 | 80 | break; |
410 | 2.17k | case typelib_TypeClass_ENUM: |
411 | 2.17k | pSeq = reallocSeq( pSeq, sizeof(sal_Int32), nAlloc ); |
412 | 2.17k | if (pSeq != nullptr) |
413 | 2.17k | { |
414 | 2.17k | memcpy( |
415 | 2.17k | pSeq->elements, |
416 | 2.17k | pSourceElements, |
417 | 2.17k | sizeof(sal_Int32) * nStopIndex ); |
418 | 2.17k | } |
419 | 2.17k | break; |
420 | 2.76M | case typelib_TypeClass_STRING: |
421 | 2.76M | { |
422 | 2.76M | pSeq = reallocSeq( pSeq, sizeof(rtl_uString *), nAlloc ); |
423 | 2.76M | if (pSeq != nullptr) |
424 | 2.76M | { |
425 | 2.76M | rtl_uString ** pDestElements = reinterpret_cast<rtl_uString **>(pSeq->elements); |
426 | 8.32M | for ( sal_Int32 nPos = 0; nPos < nStopIndex; ++nPos ) |
427 | 5.56M | { |
428 | 5.56M | ::rtl_uString_acquire( |
429 | 5.56M | static_cast<rtl_uString **>(pSourceElements)[nPos] ); |
430 | 5.56M | pDestElements[nPos] = static_cast<rtl_uString **>(pSourceElements)[nPos]; |
431 | 5.56M | } |
432 | 2.76M | } |
433 | 2.76M | break; |
434 | 0 | } |
435 | 9.86k | case typelib_TypeClass_TYPE: |
436 | 9.86k | { |
437 | 9.86k | pSeq = reallocSeq( |
438 | 9.86k | pSeq, sizeof(typelib_TypeDescriptionReference *), nAlloc ); |
439 | 9.86k | if (pSeq != nullptr) |
440 | 9.86k | { |
441 | 9.86k | typelib_TypeDescriptionReference ** pDestElements = |
442 | 9.86k | reinterpret_cast<typelib_TypeDescriptionReference **>(pSeq->elements); |
443 | 138k | for ( sal_Int32 nPos = 0; nPos < nStopIndex; ++nPos ) |
444 | 128k | { |
445 | 128k | TYPE_ACQUIRE( |
446 | 128k | static_cast<typelib_TypeDescriptionReference **>( |
447 | 128k | pSourceElements)[nPos] ); |
448 | 128k | pDestElements[nPos] = |
449 | 128k | static_cast<typelib_TypeDescriptionReference **>( |
450 | 128k | pSourceElements)[nPos]; |
451 | 128k | } |
452 | 9.86k | } |
453 | 9.86k | break; |
454 | 0 | } |
455 | 1.84M | case typelib_TypeClass_ANY: |
456 | 1.84M | { |
457 | 1.84M | pSeq = reallocSeq( pSeq, sizeof(uno_Any), nAlloc ); |
458 | 1.84M | if (pSeq != nullptr) |
459 | 1.84M | { |
460 | 1.84M | uno_Any * pDestElements = reinterpret_cast<uno_Any *>(pSeq->elements); |
461 | 3.39M | for ( sal_Int32 nPos = 0; nPos < nStopIndex; ++nPos ) |
462 | 1.55M | { |
463 | 1.55M | uno_Any * pSource = static_cast<uno_Any *>(pSourceElements) + nPos; |
464 | 1.55M | _copyConstructAny( |
465 | 1.55M | &pDestElements[nPos], |
466 | 1.55M | pSource->pData, |
467 | 1.55M | pSource->pType, nullptr, |
468 | 1.55M | acquire, nullptr ); |
469 | 1.55M | } |
470 | 1.84M | } |
471 | 1.84M | break; |
472 | 0 | } |
473 | 9.52M | case typelib_TypeClass_STRUCT: |
474 | 9.52M | case typelib_TypeClass_EXCEPTION: |
475 | 9.52M | { |
476 | 9.52M | typelib_TypeDescription * pElementTypeDescr = nullptr; |
477 | 9.52M | TYPELIB_DANGER_GET( &pElementTypeDescr, pElementType ); |
478 | 9.52M | if (pElementTypeDescr == nullptr) { |
479 | 0 | std::abort(); |
480 | 0 | } |
481 | 9.52M | sal_Int32 nElementSize = pElementTypeDescr->nSize; |
482 | | |
483 | 9.52M | pSeq = reallocSeq( pSeq, nElementSize, nAlloc ); |
484 | 9.52M | if (pSeq != nullptr) |
485 | 9.52M | { |
486 | 9.52M | char * pDestElements = pSeq->elements; |
487 | | |
488 | 9.52M | typelib_CompoundTypeDescription * pTypeDescr = |
489 | 9.52M | reinterpret_cast<typelib_CompoundTypeDescription *>(pElementTypeDescr); |
490 | 83.2M | for ( sal_Int32 nPos = 0; nPos < nStopIndex; ++nPos ) |
491 | 73.7M | { |
492 | 73.7M | char * pDest = |
493 | 73.7M | pDestElements + (nElementSize * nPos); |
494 | 73.7M | char * pSource = |
495 | 73.7M | static_cast<char *>(pSourceElements) + (nElementSize * nPos); |
496 | | |
497 | 73.7M | if (pTypeDescr->pBaseTypeDescription) |
498 | 144k | { |
499 | | // copy base value |
500 | 144k | _copyConstructStruct( |
501 | 144k | pDest, pSource, |
502 | 144k | pTypeDescr->pBaseTypeDescription, acquire, nullptr ); |
503 | 144k | } |
504 | | |
505 | | // then copy members |
506 | 73.7M | typelib_TypeDescriptionReference ** ppTypeRefs = |
507 | 73.7M | pTypeDescr->ppTypeRefs; |
508 | 73.7M | sal_Int32 * pMemberOffsets = pTypeDescr->pMemberOffsets; |
509 | 73.7M | sal_Int32 nDescr = pTypeDescr->nMembers; |
510 | | |
511 | 449M | while (nDescr--) |
512 | 376M | { |
513 | 376M | ::uno_type_copyData( |
514 | 376M | pDest + pMemberOffsets[nDescr], |
515 | 376M | pSource + pMemberOffsets[nDescr], |
516 | 376M | ppTypeRefs[nDescr], acquire ); |
517 | 376M | } |
518 | 73.7M | } |
519 | 9.52M | } |
520 | | |
521 | 9.52M | TYPELIB_DANGER_RELEASE( pElementTypeDescr ); |
522 | 9.52M | break; |
523 | 9.52M | } |
524 | 69.7k | case typelib_TypeClass_SEQUENCE: // sequence of sequence |
525 | 69.7k | { |
526 | 69.7k | pSeq = reallocSeq(pSeq, sizeof(uno_Sequence*), nAlloc); |
527 | 69.7k | if (pSeq != nullptr) |
528 | 69.7k | { |
529 | 69.7k | typelib_TypeDescription * pElementTypeDescr = nullptr; |
530 | 69.7k | TYPELIB_DANGER_GET( &pElementTypeDescr, pElementType ); |
531 | 69.7k | if (pElementTypeDescr == nullptr) { |
532 | 0 | std::abort(); |
533 | 0 | } |
534 | 69.7k | typelib_TypeDescriptionReference * pSeqElementType = |
535 | 69.7k | reinterpret_cast<typelib_IndirectTypeDescription *>(pElementTypeDescr)->pType; |
536 | 69.7k | uno_Sequence ** pDestElements = reinterpret_cast<uno_Sequence **>(pSeq->elements); |
537 | 140k | for ( sal_Int32 nPos = 0; nPos < nStopIndex; ++nPos ) |
538 | 70.9k | { |
539 | 70.9k | uno_Sequence * pNew = icopyConstructSequence( |
540 | 70.9k | static_cast<uno_Sequence **>(pSourceElements)[nPos], |
541 | 70.9k | pSeqElementType, acquire, nullptr ); |
542 | 70.9k | OSL_ASSERT( pNew != nullptr ); |
543 | | // ought never be a memory allocation problem, |
544 | | // because of reference counted sequence handles |
545 | 70.9k | pDestElements[ nPos ] = pNew; |
546 | 70.9k | } |
547 | 69.7k | TYPELIB_DANGER_RELEASE( pElementTypeDescr ); |
548 | 69.7k | } |
549 | 69.7k | break; |
550 | 69.7k | } |
551 | 69.7k | case typelib_TypeClass_INTERFACE: |
552 | 39.6k | { |
553 | 39.6k | pSeq = reallocSeq( pSeq, sizeof(void *), nAlloc ); |
554 | 39.6k | if (pSeq != nullptr) |
555 | 39.6k | { |
556 | 39.6k | void ** pDestElements = reinterpret_cast<void **>(pSeq->elements); |
557 | 118k | for ( sal_Int32 nPos = 0; nPos < nStopIndex; ++nPos ) |
558 | 78.8k | { |
559 | 78.8k | pDestElements[nPos] = static_cast<void **>(pSourceElements)[nPos]; |
560 | 78.8k | _acquire( pDestElements[nPos], acquire ); |
561 | 78.8k | } |
562 | 39.6k | } |
563 | 39.6k | break; |
564 | 69.7k | } |
565 | 0 | default: |
566 | 0 | OSL_FAIL( "### unexpected element type!" ); |
567 | 0 | pSeq = nullptr; |
568 | 0 | break; |
569 | 16.7M | } |
570 | | |
571 | 16.7M | if (pSeq == nullptr) |
572 | 0 | { |
573 | 0 | return false; // allocation failure |
574 | 0 | } |
575 | 16.7M | *ppSeq = pSeq; |
576 | 16.7M | return true; |
577 | 16.7M | } |
578 | | |
579 | | |
580 | | static bool ireallocSequence( |
581 | | uno_Sequence ** ppSequence, |
582 | | typelib_TypeDescriptionReference * pElementType, |
583 | | sal_Int32 nSize, |
584 | | uno_AcquireFunc acquire, uno_ReleaseFunc release ) |
585 | 8.23M | { |
586 | 8.23M | bool ret = true; |
587 | 8.23M | uno_Sequence * pSeq = *ppSequence; |
588 | 8.23M | sal_Int32 nElements = pSeq->nElements; |
589 | | |
590 | 8.23M | if (pSeq->nRefCount > 1 || |
591 | | // not mem-copyable elements? |
592 | 1.87M | typelib_TypeClass_ANY == pElementType->eTypeClass || |
593 | 1.84M | typelib_TypeClass_STRUCT == pElementType->eTypeClass || |
594 | 764k | typelib_TypeClass_EXCEPTION == pElementType->eTypeClass) |
595 | 7.46M | { |
596 | | // split sequence and construct new one from scratch |
597 | 7.46M | uno_Sequence * pNew = nullptr; |
598 | | |
599 | 7.46M | sal_Int32 nRest = nSize - nElements; |
600 | 7.46M | sal_Int32 nCopy = (nRest > 0 ? nElements : nSize); |
601 | | |
602 | 7.46M | if (nCopy >= 0) |
603 | 7.46M | { |
604 | 7.46M | ret = icopyConstructFromElements( |
605 | 7.46M | &pNew, pSeq->elements, pElementType, |
606 | 7.46M | nCopy, acquire, |
607 | 7.46M | nSize ); // alloc to nSize |
608 | 7.46M | } |
609 | 7.46M | if (ret && nRest > 0) |
610 | 7.13M | { |
611 | 7.13M | ret = idefaultConstructElements( |
612 | 7.13M | &pNew, pElementType, |
613 | 7.13M | nCopy, nSize, |
614 | 7.13M | nCopy >= 0 ? -1 /* no mem allocation */ : nSize ); |
615 | 7.13M | } |
616 | | |
617 | 7.46M | if (ret) |
618 | 7.46M | { |
619 | | // destruct sequence |
620 | 7.46M | if (osl_atomic_decrement( &pSeq->nRefCount ) == 0) |
621 | 1.10M | { |
622 | 1.10M | if (nElements > 0) |
623 | 1.10M | { |
624 | 1.10M | idestructElements( |
625 | 1.10M | pSeq->elements, pElementType, |
626 | 1.10M | 0, nElements, release ); |
627 | 1.10M | } |
628 | 1.10M | std::free( pSeq ); |
629 | 1.10M | } |
630 | 7.46M | *ppSequence = pNew; |
631 | 7.46M | } |
632 | 7.46M | } |
633 | 764k | else |
634 | 764k | { |
635 | 764k | OSL_ASSERT( pSeq->nRefCount == 1 ); |
636 | 764k | if (nSize > nElements) // default construct the rest |
637 | 64.6k | { |
638 | 64.6k | ret = idefaultConstructElements( |
639 | 64.6k | ppSequence, pElementType, |
640 | 64.6k | nElements, nSize, |
641 | 64.6k | nSize ); // realloc to nSize |
642 | 64.6k | } |
643 | 699k | else // or destruct the rest and realloc mem |
644 | 699k | { |
645 | 699k | sal_Int32 nElementSize = idestructElements( |
646 | 699k | pSeq->elements, pElementType, |
647 | 699k | nSize, nElements, release ); |
648 | | // warning: it is assumed that the following will never fail, |
649 | | // else this leads to a sequence null handle |
650 | 699k | *ppSequence = reallocSeq( pSeq, nElementSize, nSize ); |
651 | 699k | OSL_ASSERT( *ppSequence != nullptr ); |
652 | 699k | ret = (*ppSequence != nullptr); |
653 | 699k | } |
654 | 764k | } |
655 | | |
656 | 8.23M | return ret; |
657 | 8.23M | } |
658 | | |
659 | | } |
660 | | |
661 | | extern "C" |
662 | | { |
663 | | |
664 | | sal_Bool SAL_CALL uno_type_sequence_construct( |
665 | | uno_Sequence ** ppSequence, typelib_TypeDescriptionReference * pType, |
666 | | void * pElements, sal_Int32 len, |
667 | | uno_AcquireFunc acquire ) noexcept |
668 | 247M | { |
669 | 247M | assert( len >= 0 ); |
670 | 247M | bool ret; |
671 | 247M | if (len) |
672 | 17.1M | { |
673 | 17.1M | typelib_TypeDescription * pTypeDescr = nullptr; |
674 | 17.1M | TYPELIB_DANGER_GET( &pTypeDescr, pType ); |
675 | 17.1M | if (pTypeDescr == nullptr) { |
676 | 0 | std::abort(); |
677 | 0 | } |
678 | | |
679 | 17.1M | typelib_TypeDescriptionReference * pElementType = |
680 | 17.1M | reinterpret_cast<typelib_IndirectTypeDescription *>(pTypeDescr)->pType; |
681 | | |
682 | 17.1M | *ppSequence = nullptr; |
683 | 17.1M | if (pElements == nullptr) |
684 | 8.06M | { |
685 | 8.06M | ret = idefaultConstructElements( |
686 | 8.06M | ppSequence, pElementType, |
687 | 8.06M | 0, len, |
688 | 8.06M | len ); // alloc to len |
689 | 8.06M | } |
690 | 9.03M | else |
691 | 9.03M | { |
692 | 9.03M | ret = icopyConstructFromElements( |
693 | 9.03M | ppSequence, pElements, pElementType, |
694 | 9.03M | len, acquire, |
695 | 9.03M | len ); // alloc to len |
696 | 9.03M | } |
697 | | |
698 | 17.1M | TYPELIB_DANGER_RELEASE( pTypeDescr ); |
699 | 17.1M | } |
700 | 230M | else |
701 | 230M | { |
702 | 230M | *ppSequence = createEmptySequence(); |
703 | 230M | ret = true; |
704 | 230M | } |
705 | | |
706 | 247M | OSL_ASSERT( (*ppSequence != nullptr) == ret ); |
707 | 247M | return ret; |
708 | 247M | } |
709 | | |
710 | | |
711 | | sal_Bool SAL_CALL uno_sequence_construct( |
712 | | uno_Sequence ** ppSequence, typelib_TypeDescription * pTypeDescr, |
713 | | void * pElements, sal_Int32 len, |
714 | | uno_AcquireFunc acquire ) noexcept |
715 | 0 | { |
716 | 0 | bool ret; |
717 | 0 | if (len > 0) |
718 | 0 | { |
719 | 0 | typelib_TypeDescriptionReference * pElementType = |
720 | 0 | reinterpret_cast<typelib_IndirectTypeDescription *>(pTypeDescr)->pType; |
721 | |
|
722 | 0 | *ppSequence = nullptr; |
723 | 0 | if (pElements == nullptr) |
724 | 0 | { |
725 | 0 | ret = idefaultConstructElements( |
726 | 0 | ppSequence, pElementType, |
727 | 0 | 0, len, |
728 | 0 | len ); // alloc to len |
729 | 0 | } |
730 | 0 | else |
731 | 0 | { |
732 | 0 | ret = icopyConstructFromElements( |
733 | 0 | ppSequence, pElements, pElementType, |
734 | 0 | len, acquire, |
735 | 0 | len ); // alloc to len |
736 | 0 | } |
737 | 0 | } |
738 | 0 | else |
739 | 0 | { |
740 | 0 | *ppSequence = createEmptySequence(); |
741 | 0 | ret = true; |
742 | 0 | } |
743 | |
|
744 | 0 | OSL_ASSERT( (*ppSequence != nullptr) == ret ); |
745 | 0 | return ret; |
746 | 0 | } |
747 | | |
748 | | |
749 | | sal_Bool SAL_CALL uno_type_sequence_realloc( |
750 | | uno_Sequence ** ppSequence, typelib_TypeDescriptionReference * pType, |
751 | | sal_Int32 nSize, uno_AcquireFunc acquire, uno_ReleaseFunc release ) noexcept |
752 | 9.20M | { |
753 | 9.20M | assert(ppSequence && "### null ptr!"); |
754 | 9.20M | assert(nSize >= 0 && "### new size must be at least 0!"); |
755 | | |
756 | 9.20M | bool ret = true; |
757 | 9.20M | if (nSize != (*ppSequence)->nElements) |
758 | 8.23M | { |
759 | 8.23M | typelib_TypeDescription * pTypeDescr = nullptr; |
760 | 8.23M | TYPELIB_DANGER_GET( &pTypeDescr, pType ); |
761 | 8.23M | ret = ireallocSequence( |
762 | 8.23M | ppSequence, reinterpret_cast<typelib_IndirectTypeDescription *>(pTypeDescr)->pType, |
763 | 8.23M | nSize, acquire, release ); |
764 | 8.23M | TYPELIB_DANGER_RELEASE( pTypeDescr ); |
765 | 8.23M | } |
766 | 9.20M | return ret; |
767 | 9.20M | } |
768 | | |
769 | | |
770 | | sal_Bool SAL_CALL uno_sequence_realloc( |
771 | | uno_Sequence ** ppSequence, typelib_TypeDescription * pTypeDescr, |
772 | | sal_Int32 nSize, uno_AcquireFunc acquire, uno_ReleaseFunc release ) noexcept |
773 | 0 | { |
774 | 0 | assert(ppSequence && "### null ptr!"); |
775 | 0 | OSL_ENSURE( nSize >= 0, "### new size must be at least 0!" ); |
776 | |
|
777 | 0 | bool ret = true; |
778 | 0 | if (nSize != (*ppSequence)->nElements) |
779 | 0 | { |
780 | 0 | ret = ireallocSequence( |
781 | 0 | ppSequence, reinterpret_cast<typelib_IndirectTypeDescription *>(pTypeDescr)->pType, |
782 | 0 | nSize, acquire, release ); |
783 | 0 | } |
784 | 0 | return ret; |
785 | 0 | } |
786 | | |
787 | | |
788 | | sal_Bool SAL_CALL uno_type_sequence_reference2One( |
789 | | uno_Sequence ** ppSequence, |
790 | | typelib_TypeDescriptionReference * pType, |
791 | | uno_AcquireFunc acquire, uno_ReleaseFunc release ) noexcept |
792 | 21.1M | { |
793 | 21.1M | assert(ppSequence && "### null ptr!"); |
794 | 21.1M | bool ret = true; |
795 | 21.1M | uno_Sequence * pSequence = *ppSequence; |
796 | 21.1M | if (pSequence->nRefCount > 1) |
797 | 1.96M | { |
798 | 1.96M | uno_Sequence * pNew = nullptr; |
799 | 1.96M | if (pSequence->nElements > 0) |
800 | 274k | { |
801 | 274k | typelib_TypeDescription * pTypeDescr = nullptr; |
802 | 274k | TYPELIB_DANGER_GET( &pTypeDescr, pType ); |
803 | | |
804 | 274k | ret = icopyConstructFromElements( |
805 | 274k | &pNew, pSequence->elements, |
806 | 274k | reinterpret_cast<typelib_IndirectTypeDescription *>(pTypeDescr)->pType, |
807 | 274k | pSequence->nElements, acquire, |
808 | 274k | pSequence->nElements ); // alloc nElements |
809 | 274k | if (ret) |
810 | 274k | { |
811 | 274k | idestructSequence( *ppSequence, pType, pTypeDescr, release ); |
812 | 274k | *ppSequence = pNew; |
813 | 274k | } |
814 | | |
815 | 274k | TYPELIB_DANGER_RELEASE( pTypeDescr ); |
816 | 274k | } |
817 | 1.69M | else |
818 | 1.69M | { |
819 | 1.69M | pNew = allocSeq( 0, 0 ); |
820 | 1.69M | ret = (pNew != nullptr); |
821 | 1.69M | if (ret) |
822 | 1.69M | { |
823 | | // easy destruction of empty sequence: |
824 | 1.69M | if (osl_atomic_decrement( &pSequence->nRefCount ) == 0) |
825 | 0 | std::free( pSequence ); |
826 | 1.69M | *ppSequence = pNew; |
827 | 1.69M | } |
828 | 1.69M | } |
829 | 1.96M | } |
830 | 21.1M | return ret; |
831 | 21.1M | } |
832 | | |
833 | | |
834 | | sal_Bool SAL_CALL uno_sequence_reference2One( |
835 | | uno_Sequence ** ppSequence, |
836 | | typelib_TypeDescription * pTypeDescr, |
837 | | uno_AcquireFunc acquire, uno_ReleaseFunc release ) noexcept |
838 | 0 | { |
839 | 0 | assert(ppSequence && "### null ptr!"); |
840 | 0 | bool ret = true; |
841 | 0 | uno_Sequence * pSequence = *ppSequence; |
842 | 0 | if (pSequence->nRefCount > 1) |
843 | 0 | { |
844 | 0 | uno_Sequence * pNew = nullptr; |
845 | 0 | if (pSequence->nElements > 0) |
846 | 0 | { |
847 | 0 | ret = icopyConstructFromElements( |
848 | 0 | &pNew, pSequence->elements, |
849 | 0 | reinterpret_cast<typelib_IndirectTypeDescription *>(pTypeDescr)->pType, |
850 | 0 | pSequence->nElements, acquire, |
851 | 0 | pSequence->nElements ); // alloc nElements |
852 | 0 | if (ret) |
853 | 0 | { |
854 | 0 | idestructSequence( |
855 | 0 | pSequence, pTypeDescr->pWeakRef, pTypeDescr, release ); |
856 | 0 | *ppSequence = pNew; |
857 | 0 | } |
858 | 0 | } |
859 | 0 | else |
860 | 0 | { |
861 | 0 | pNew = allocSeq( 0, 0 ); |
862 | 0 | ret = (pNew != nullptr); |
863 | 0 | if (ret) |
864 | 0 | { |
865 | | // easy destruction of empty sequence: |
866 | 0 | if (osl_atomic_decrement( &pSequence->nRefCount ) == 0) |
867 | 0 | std::free( pSequence ); |
868 | 0 | *ppSequence = pNew; |
869 | 0 | } |
870 | 0 | } |
871 | |
|
872 | 0 | } |
873 | 0 | return ret; |
874 | 0 | } |
875 | | |
876 | | |
877 | | void SAL_CALL uno_sequence_assign( |
878 | | uno_Sequence ** ppDest, |
879 | | uno_Sequence * pSource, |
880 | | typelib_TypeDescription * pTypeDescr, |
881 | | uno_ReleaseFunc release ) noexcept |
882 | 0 | { |
883 | 0 | if (*ppDest != pSource) |
884 | 0 | { |
885 | 0 | osl_atomic_increment( &pSource->nRefCount ); |
886 | 0 | idestructSequence( *ppDest, pTypeDescr->pWeakRef, pTypeDescr, release ); |
887 | 0 | *ppDest = pSource; |
888 | 0 | } |
889 | 0 | } |
890 | | |
891 | | |
892 | | void SAL_CALL uno_type_sequence_assign( |
893 | | uno_Sequence ** ppDest, |
894 | | uno_Sequence * pSource, |
895 | | typelib_TypeDescriptionReference * pType, |
896 | | uno_ReleaseFunc release ) noexcept |
897 | 15.8M | { |
898 | 15.8M | if (*ppDest != pSource) |
899 | 1.75M | { |
900 | 1.75M | osl_atomic_increment( &pSource->nRefCount ); |
901 | 1.75M | idestructSequence( *ppDest, pType, nullptr, release ); |
902 | 1.75M | *ppDest = pSource; |
903 | 1.75M | } |
904 | 15.8M | } |
905 | | |
906 | | void uno_type_sequence_destroy( |
907 | | uno_Sequence * sequence, typelib_TypeDescriptionReference * type, |
908 | | uno_ReleaseFunc release) noexcept |
909 | 20.6M | { |
910 | 20.6M | idestroySequence(sequence, type, nullptr, release); |
911 | 20.6M | } |
912 | | |
913 | | } |
914 | | |
915 | | /* vim:set shiftwidth=4 softtabstop=4 expandtab: */ |