Coverage Report

Created: 2026-07-10 11:04

next uncovered line (L), next uncovered region (R), next uncovered branch (B)
/src/libreoffice/cppu/source/uno/assign.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 "destr.hxx"
23
#include "constr.hxx"
24
#include "copy.hxx"
25
26
27
namespace cppu
28
{
29
30
31
//#### assignment ##################################################################################
32
33
34
inline void _assignInterface(
35
    void ** ppDest, void * pSource,
36
    uno_AcquireFunc acquire, uno_ReleaseFunc release )
37
38
22.5M
{
39
22.5M
    _acquire( pSource, acquire );
40
22.5M
    void * const pToBeReleased = *ppDest;
41
22.5M
    *ppDest = pSource;
42
22.5M
    _release( pToBeReleased, release );
43
22.5M
}
44
45
inline void * _queryInterface(
46
    void * pSource,
47
    typelib_TypeDescriptionReference * pDestType,
48
    uno_QueryInterfaceFunc queryInterface )
49
1.58M
{
50
1.58M
    if (pSource)
51
1.58M
    {
52
1.58M
        if (nullptr == queryInterface)
53
0
            queryInterface = binuno_queryInterface;
54
1.58M
        pSource = (*queryInterface)( pSource, pDestType );
55
1.58M
    }
56
1.58M
    return pSource;
57
1.58M
}
58
59
bool assignStruct(
60
    void * pDest, void * pSource,
61
    typelib_CompoundTypeDescription * pTypeDescr,
62
    uno_QueryInterfaceFunc queryInterface, uno_AcquireFunc acquire, uno_ReleaseFunc release );
63
64
inline bool _assignStruct(
65
    void * pDest, void * pSource,
66
    typelib_CompoundTypeDescription * pTypeDescr,
67
    uno_QueryInterfaceFunc queryInterface, uno_AcquireFunc acquire, uno_ReleaseFunc release )
68
3.15M
{
69
3.15M
    if (pTypeDescr->pBaseTypeDescription)
70
259k
    {
71
        // copy base value
72
259k
        if (! assignStruct( pDest, pSource, pTypeDescr->pBaseTypeDescription,
73
259k
                            queryInterface, acquire, release ))
74
0
        {
75
0
            return false;
76
0
        }
77
259k
    }
78
    // then copy members
79
3.15M
    typelib_TypeDescriptionReference ** ppTypeRefs = pTypeDescr->ppTypeRefs;
80
3.15M
    sal_Int32 * pMemberOffsets = pTypeDescr->pMemberOffsets;
81
3.15M
    sal_Int32 nDescr = pTypeDescr->nMembers;
82
16.4M
    while (nDescr--)
83
13.2M
    {
84
13.2M
        if (! ::uno_type_assignData( static_cast<char *>(pDest) + pMemberOffsets[nDescr],
85
13.2M
                                     ppTypeRefs[nDescr],
86
13.2M
                                     static_cast<char *>(pSource) + pMemberOffsets[nDescr],
87
13.2M
                                     ppTypeRefs[nDescr],
88
13.2M
                                     queryInterface, acquire, release ))
89
0
        {
90
0
            return false;
91
0
        }
92
13.2M
    }
93
3.15M
    return true;
94
3.15M
}
95
96
inline bool _assignData(
97
    void * pDest,
98
    typelib_TypeDescriptionReference * pDestType, typelib_TypeDescription * pDestTypeDescr,
99
    void * pSource,
100
    typelib_TypeDescriptionReference * pSourceType, typelib_TypeDescription * pSourceTypeDescr,
101
    uno_QueryInterfaceFunc queryInterface, uno_AcquireFunc acquire, uno_ReleaseFunc release )
102
47.7M
{
103
47.7M
    if (pDest == pSource)
104
0
        return _type_equals( pDestType, pSourceType );
105
106
47.7M
    if (! pSource)
107
0
    {
108
0
        _destructData( pDest, pDestType, pDestTypeDescr, release );
109
0
        _defaultConstructData( pDest, pDestType, pDestTypeDescr );
110
0
        return true;
111
0
    }
112
47.9M
    while (typelib_TypeClass_ANY == pSourceType->eTypeClass)
113
217k
    {
114
217k
        pSourceTypeDescr = nullptr;
115
217k
        pSourceType = static_cast<uno_Any *>(pSource)->pType;
116
217k
        pSource = static_cast<uno_Any *>(pSource)->pData;
117
217k
        if (pDest == pSource)
118
0
            return true;
119
217k
    }
120
121
47.7M
    switch (pDestType->eTypeClass)
122
47.7M
    {
123
0
    case typelib_TypeClass_VOID:
124
0
        return pSourceType->eTypeClass == typelib_TypeClass_VOID;
125
0
    case typelib_TypeClass_CHAR:
126
0
        switch (pSourceType->eTypeClass)
127
0
        {
128
0
        case typelib_TypeClass_CHAR:
129
0
            *static_cast<sal_Unicode *>(pDest) = *static_cast<sal_Unicode *>(pSource);
130
0
            return true;
131
0
        default:
132
0
            return false;
133
0
        }
134
835k
    case typelib_TypeClass_BOOLEAN:
135
835k
        switch (pSourceType->eTypeClass)
136
835k
        {
137
835k
        case typelib_TypeClass_BOOLEAN:
138
835k
            *static_cast<sal_Bool *>(pDest) = bool(*static_cast<sal_Bool *>(pSource));
139
835k
            return true;
140
0
        default:
141
0
            return false;
142
835k
        }
143
0
    case typelib_TypeClass_BYTE:
144
0
        switch (pSourceType->eTypeClass)
145
0
        {
146
0
        case typelib_TypeClass_BYTE:
147
0
            *static_cast<sal_Int8 *>(pDest) = *static_cast<sal_Int8 *>(pSource);
148
0
            return true;
149
0
        default:
150
0
            return false;
151
0
        }
152
4.92M
    case typelib_TypeClass_SHORT:
153
4.92M
        switch (pSourceType->eTypeClass)
154
4.92M
        {
155
0
        case typelib_TypeClass_BYTE:
156
0
            *static_cast<sal_Int16 *>(pDest) = *static_cast<sal_Int8 *>(pSource);
157
0
            return true;
158
4.92M
        case typelib_TypeClass_SHORT:
159
4.92M
        case typelib_TypeClass_UNSIGNED_SHORT:
160
4.92M
            *static_cast<sal_Int16 *>(pDest) = *static_cast<sal_Int16 *>(pSource);
161
4.92M
            return true;
162
0
        default:
163
0
            return false;
164
4.92M
        }
165
68.7k
    case typelib_TypeClass_UNSIGNED_SHORT:
166
68.7k
        switch (pSourceType->eTypeClass)
167
68.7k
        {
168
0
        case typelib_TypeClass_BYTE:
169
0
            *static_cast<sal_uInt16 *>(pDest) = *static_cast<sal_Int8 *>(pSource);
170
0
            return true;
171
0
        case typelib_TypeClass_SHORT:
172
68.7k
        case typelib_TypeClass_UNSIGNED_SHORT:
173
68.7k
            *static_cast<sal_uInt16 *>(pDest) = *static_cast<sal_uInt16 *>(pSource);
174
68.7k
            return true;
175
0
        default:
176
0
            return false;
177
68.7k
        }
178
3.47M
    case typelib_TypeClass_LONG:
179
3.47M
        switch (pSourceType->eTypeClass)
180
3.47M
        {
181
0
        case typelib_TypeClass_BYTE:
182
0
            *static_cast<sal_Int32 *>(pDest) = *static_cast<sal_Int8 *>(pSource);
183
0
            return true;
184
0
        case typelib_TypeClass_SHORT:
185
0
            *static_cast<sal_Int32 *>(pDest) = *static_cast<sal_Int16 *>(pSource);
186
0
            return true;
187
0
        case typelib_TypeClass_UNSIGNED_SHORT:
188
0
            *static_cast<sal_Int32 *>(pDest) = *static_cast<sal_uInt16 *>(pSource);
189
0
            return true;
190
2.50M
        case typelib_TypeClass_LONG:
191
2.50M
        case typelib_TypeClass_UNSIGNED_LONG:
192
2.50M
            *static_cast<sal_Int32 *>(pDest) = *static_cast<sal_Int32 *>(pSource);
193
2.50M
            return true;
194
972k
        default:
195
972k
            return false;
196
3.47M
        }
197
106k
    case typelib_TypeClass_UNSIGNED_LONG:
198
106k
        switch (pSourceType->eTypeClass)
199
106k
        {
200
0
        case typelib_TypeClass_BYTE:
201
0
            *static_cast<sal_uInt32 *>(pDest) = *static_cast<sal_Int8 *>(pSource);
202
0
            return true;
203
0
        case typelib_TypeClass_SHORT:
204
0
            *static_cast<sal_uInt32 *>(pDest) = *static_cast<sal_Int16 *>(pSource);
205
0
            return true;
206
0
        case typelib_TypeClass_UNSIGNED_SHORT:
207
0
            *static_cast<sal_uInt32 *>(pDest) = *static_cast<sal_uInt16 *>(pSource);
208
0
            return true;
209
0
        case typelib_TypeClass_LONG:
210
106k
        case typelib_TypeClass_UNSIGNED_LONG:
211
106k
            *static_cast<sal_uInt32 *>(pDest) = *static_cast<sal_uInt32 *>(pSource);
212
106k
            return true;
213
0
        default:
214
0
            return false;
215
106k
        }
216
0
    case typelib_TypeClass_HYPER:
217
0
        switch (pSourceType->eTypeClass)
218
0
        {
219
0
        case typelib_TypeClass_BYTE:
220
0
            *static_cast<sal_Int64 *>(pDest) = *static_cast<sal_Int8 *>(pSource);
221
0
            return true;
222
0
        case typelib_TypeClass_SHORT:
223
0
            *static_cast<sal_Int64 *>(pDest) = *static_cast<sal_Int16 *>(pSource);
224
0
            return true;
225
0
        case typelib_TypeClass_UNSIGNED_SHORT:
226
0
            *static_cast<sal_Int64 *>(pDest) = *static_cast<sal_uInt16 *>(pSource);
227
0
            return true;
228
0
        case typelib_TypeClass_LONG:
229
0
            *static_cast<sal_Int64 *>(pDest) = *static_cast<sal_Int32 *>(pSource);
230
0
            return true;
231
0
        case typelib_TypeClass_UNSIGNED_LONG:
232
0
            *static_cast<sal_Int64 *>(pDest) = *static_cast<sal_uInt32 *>(pSource);
233
0
            return true;
234
0
        case typelib_TypeClass_HYPER:
235
0
        case typelib_TypeClass_UNSIGNED_HYPER:
236
0
            *static_cast<sal_Int64 *>(pDest) = *static_cast<sal_Int64 *>(pSource);
237
0
            return true;
238
0
        default:
239
0
            return false;
240
0
        }
241
0
    case typelib_TypeClass_UNSIGNED_HYPER:
242
0
        switch (pSourceType->eTypeClass)
243
0
        {
244
0
        case typelib_TypeClass_BYTE:
245
0
            *static_cast<sal_uInt64 *>(pDest) = *static_cast<sal_Int8 *>(pSource);
246
0
            return true;
247
0
        case typelib_TypeClass_SHORT:
248
0
            *static_cast<sal_uInt64 *>(pDest) = *static_cast<sal_Int16 *>(pSource);
249
0
            return true;
250
0
        case typelib_TypeClass_UNSIGNED_SHORT:
251
0
            *static_cast<sal_uInt64 *>(pDest) = *static_cast<sal_uInt16 *>(pSource);
252
0
            return true;
253
0
        case typelib_TypeClass_LONG:
254
0
            *static_cast<sal_uInt64 *>(pDest) = *static_cast<sal_Int32 *>(pSource);
255
0
            return true;
256
0
        case typelib_TypeClass_UNSIGNED_LONG:
257
0
            *static_cast<sal_uInt64 *>(pDest) = *static_cast<sal_uInt32 *>(pSource);
258
0
            return true;
259
0
        case typelib_TypeClass_HYPER:
260
0
        case typelib_TypeClass_UNSIGNED_HYPER:
261
0
            *static_cast<sal_uInt64 *>(pDest) = *static_cast<sal_uInt64 *>(pSource);
262
0
            return true;
263
0
        default:
264
0
            return false;
265
0
        }
266
1.12M
    case typelib_TypeClass_FLOAT:
267
1.12M
        switch (pSourceType->eTypeClass)
268
1.12M
        {
269
0
        case typelib_TypeClass_BYTE:
270
0
            *static_cast<float *>(pDest) = *static_cast<sal_Int8 *>(pSource);
271
0
            return true;
272
0
        case typelib_TypeClass_SHORT:
273
0
            *static_cast<float *>(pDest) = *static_cast<sal_Int16 *>(pSource);
274
0
            return true;
275
0
        case typelib_TypeClass_UNSIGNED_SHORT:
276
0
            *static_cast<float *>(pDest) = *static_cast<sal_uInt16 *>(pSource);
277
0
            return true;
278
1.12M
        case typelib_TypeClass_FLOAT:
279
1.12M
            *static_cast<float *>(pDest) = *static_cast<float *>(pSource);
280
1.12M
            return true;
281
0
        default:
282
0
            return false;
283
1.12M
        }
284
687k
    case typelib_TypeClass_DOUBLE:
285
687k
        switch (pSourceType->eTypeClass)
286
687k
        {
287
0
        case typelib_TypeClass_BYTE:
288
0
            *static_cast<double *>(pDest) = *static_cast<sal_Int8 *>(pSource);
289
0
            return true;
290
0
        case typelib_TypeClass_SHORT:
291
0
            *static_cast<double *>(pDest) = *static_cast<sal_Int16 *>(pSource);
292
0
            return true;
293
0
        case typelib_TypeClass_UNSIGNED_SHORT:
294
0
            *static_cast<double *>(pDest) = *static_cast<sal_uInt16 *>(pSource);
295
0
            return true;
296
0
        case typelib_TypeClass_LONG:
297
0
            *static_cast<double *>(pDest) = *static_cast<sal_Int32 *>(pSource);
298
0
            return true;
299
0
        case typelib_TypeClass_UNSIGNED_LONG:
300
0
            *static_cast<double *>(pDest) = *static_cast<sal_uInt32 *>(pSource);
301
0
            return true;
302
0
        case typelib_TypeClass_FLOAT:
303
0
            *static_cast<double *>(pDest) = *static_cast<float *>(pSource);
304
0
            return true;
305
687k
        case typelib_TypeClass_DOUBLE:
306
687k
            *static_cast<double *>(pDest) = *static_cast<double *>(pSource);
307
687k
            return true;
308
0
        default:
309
0
            return false;
310
687k
        }
311
2.20M
    case typelib_TypeClass_STRING:
312
2.20M
        switch (pSourceType->eTypeClass)
313
2.20M
        {
314
1.55M
        case typelib_TypeClass_STRING:
315
1.55M
            ::rtl_uString_assign( static_cast<rtl_uString **>(pDest), *static_cast<rtl_uString **>(pSource) );
316
1.55M
            return true;
317
648k
        default:
318
648k
            return false;
319
2.20M
        }
320
0
    case typelib_TypeClass_TYPE:
321
0
        switch (pSourceType->eTypeClass)
322
0
        {
323
0
        case typelib_TypeClass_TYPE:
324
0
        {
325
0
            typelib_TypeDescriptionReference ** pp = static_cast<typelib_TypeDescriptionReference **>(pDest);
326
0
            ::typelib_typedescriptionreference_release( *pp );
327
0
            *pp = *static_cast<typelib_TypeDescriptionReference **>(pSource);
328
0
            TYPE_ACQUIRE( *pp );
329
0
            return true;
330
0
        }
331
0
        default:
332
0
            return false;
333
0
        }
334
217k
    case typelib_TypeClass_ANY:
335
217k
        _destructAny( static_cast<uno_Any *>(pDest), release );
336
217k
        _copyConstructAny( static_cast<uno_Any *>(pDest), pSource, pSourceType, pSourceTypeDescr, acquire, nullptr );
337
217k
        return true;
338
2.39M
    case typelib_TypeClass_ENUM:
339
2.39M
        if (_type_equals( pDestType, pSourceType ))
340
2.31M
        {
341
2.31M
            *static_cast<sal_Int32 *>(pDest) = *static_cast<sal_Int32 *>(pSource);
342
2.31M
            return true;
343
2.31M
        }
344
80.0k
        return false;
345
3.12M
    case typelib_TypeClass_STRUCT:
346
3.12M
    case typelib_TypeClass_EXCEPTION:
347
3.12M
        if (typelib_TypeClass_STRUCT == pSourceType->eTypeClass ||
348
138k
            typelib_TypeClass_EXCEPTION == pSourceType->eTypeClass)
349
2.99M
        {
350
2.99M
            bool bRet = false;
351
2.99M
            if (pSourceTypeDescr)
352
0
            {
353
0
                typelib_CompoundTypeDescription * pTypeDescr =
354
0
                    reinterpret_cast<typelib_CompoundTypeDescription *>(pSourceTypeDescr);
355
0
                while (pTypeDescr &&
356
0
                       !_type_equals(pTypeDescr->aBase.pWeakRef, pDestType))
357
0
                {
358
0
                    pTypeDescr = pTypeDescr->pBaseTypeDescription;
359
0
                }
360
0
                if (pTypeDescr)
361
0
                {
362
0
                    bRet = _assignStruct(
363
0
                        pDest, pSource, pTypeDescr, queryInterface, acquire, release );
364
0
                }
365
0
            }
366
2.99M
            else
367
2.99M
            {
368
2.99M
                TYPELIB_DANGER_GET( &pSourceTypeDescr, pSourceType );
369
2.99M
                typelib_CompoundTypeDescription * pTypeDescr =
370
2.99M
                    reinterpret_cast<typelib_CompoundTypeDescription *>(pSourceTypeDescr);
371
3.08M
                while (pTypeDescr &&
372
2.99M
                       !_type_equals(pTypeDescr->aBase.pWeakRef, pDestType))
373
98.2k
                {
374
98.2k
                    pTypeDescr = pTypeDescr->pBaseTypeDescription;
375
98.2k
                }
376
2.99M
                if (pTypeDescr)
377
2.89M
                {
378
2.89M
                    bRet = _assignStruct(
379
2.89M
                        pDest, pSource, pTypeDescr, queryInterface, acquire, release );
380
2.89M
                }
381
2.99M
                TYPELIB_DANGER_RELEASE( pSourceTypeDescr );
382
2.99M
            }
383
2.99M
            return bRet;
384
2.99M
        }
385
135k
        return false;
386
4.16M
    case typelib_TypeClass_SEQUENCE:
387
4.16M
        if (!_type_equals( pDestType, pSourceType ))
388
822k
            return false;
389
        // check self assignment (only after _type_equals, to account for shared static empty):
390
3.34M
        if (*static_cast<uno_Sequence **>(pSource) != *static_cast<uno_Sequence **>(pDest))
391
2.75M
        {
392
2.75M
            osl_atomic_increment( &(*static_cast<uno_Sequence **>(pSource))->nRefCount );
393
2.75M
            idestructSequence(
394
2.75M
                *static_cast<uno_Sequence **>(pDest), pDestType, pDestTypeDescr, release );
395
2.75M
            *static_cast<uno_Sequence **>(pDest) = *static_cast<uno_Sequence **>(pSource);
396
2.75M
        }
397
3.34M
        return true;
398
24.4M
    case typelib_TypeClass_INTERFACE:
399
24.4M
        if (typelib_TypeClass_INTERFACE != pSourceType->eTypeClass)
400
301k
            return false;
401
24.1M
        if (_type_equals( pDestType, pSourceType ))
402
22.5M
        {
403
22.5M
            _assignInterface( static_cast<void **>(pDest), *static_cast<void **>(pSource), acquire, release );
404
22.5M
            return true;
405
22.5M
        }
406
1.58M
        else if (*static_cast< void ** >(pSource) == nullptr)
407
3.64k
        {
408
            // A null reference of any interface type can be converted to a null
409
            // reference of any other interface type:
410
3.64k
            void * const pToBeReleased = *static_cast< void ** >(pDest);
411
3.64k
            *static_cast< void ** >(pDest) = nullptr;
412
3.64k
            _release( pToBeReleased, release );
413
3.64k
            return true;
414
3.64k
        }
415
1.58M
        else
416
1.58M
        {
417
1.58M
            if (pSourceTypeDescr)
418
0
            {
419
0
                typelib_TypeDescription * pTD = pSourceTypeDescr;
420
0
                while (pTD && !_type_equals( pTD->pWeakRef, pDestType ))
421
0
                {
422
0
                    pTD = &reinterpret_cast<typelib_InterfaceTypeDescription *>(pTD)->pBaseTypeDescription->aBase;
423
0
                }
424
0
                if (pTD) // is base of dest
425
0
                {
426
0
                    _assignInterface( static_cast<void **>(pDest), *static_cast<void **>(pSource), acquire, release );
427
0
                    return true;
428
0
                }
429
0
            }
430
431
            // query for interface:
432
1.58M
            void * pQueried = _queryInterface( *static_cast<void **>(pSource),
433
1.58M
                                               pDestType, queryInterface );
434
1.58M
            if (pQueried != nullptr) {
435
1.51M
                void * const pToBeReleased = *static_cast<void **>(pDest);
436
1.51M
                *static_cast<void **>(pDest) = pQueried;
437
1.51M
                _release( pToBeReleased, release );
438
1.51M
            }
439
1.58M
            return (pQueried != nullptr);
440
1.58M
        }
441
0
    default:
442
0
        OSL_ASSERT(false);
443
0
        return false;
444
47.7M
    }
445
47.7M
}
446
447
}
448
449
/* vim:set shiftwidth=4 softtabstop=4 expandtab: */