Coverage Report

Created: 2026-03-31 11:00

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