Coverage Report

Created: 2026-10-14 09:33

next uncovered line (L), next uncovered region (R), next uncovered branch (B)
/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: */