Coverage Report

Created: 2026-10-17 06:10

next uncovered line (L), next uncovered region (R), next uncovered branch (B)
/src/S2OPC/src/ClientServer/services/b2c/util_variant.c
Line
Count
Source
1
/*
2
 * Licensed to Systerel under one or more contributor license
3
 * agreements. See the NOTICE file distributed with this work
4
 * for additional information regarding copyright ownership.
5
 * Systerel licenses this file to you under the Apache
6
 * License, Version 2.0 (the "License"); you may not use this
7
 * file except in compliance with the License. You may obtain
8
 * a copy of the License at
9
 *
10
 *   http://www.apache.org/licenses/LICENSE-2.0
11
 *
12
 * Unless required by applicable law or agreed to in writing,
13
 * software distributed under the License is distributed on an
14
 * "AS IS" BASIS, WITHOUT WARRANTIES OR CONDITIONS OF ANY
15
 * KIND, either express or implied.  See the License for the
16
 * specific language governing permissions and limitations
17
 * under the License.
18
 */
19
20
#include <inttypes.h>
21
#include <stdio.h>
22
#include <string.h>
23
24
#include "constants_statuscodes_bs.h"
25
#include "opcua_statuscodes.h"
26
#include "sopc_assert.h"
27
#include "sopc_macros.h"
28
#include "sopc_mem_alloc.h"
29
#include "util_b2c.h"
30
#include "util_variant.h"
31
32
#include "sopc_missing_c99.h"
33
34
SOPC_Variant* util_variant__new_Variant_from_NodeId(SOPC_NodeId* pnid, bool deepCopy)
35
0
{
36
0
    SOPC_Variant* pvar = SOPC_Variant_Create();
37
38
0
    if (NULL == pvar)
39
0
    {
40
0
        return NULL;
41
0
    }
42
43
0
    pvar->BuiltInTypeId = SOPC_NodeId_Id;
44
0
    pvar->ArrayType = SOPC_VariantArrayType_SingleValue;
45
0
    if (deepCopy)
46
0
    {
47
0
        pvar->Value.NodeId = SOPC_Calloc(sizeof(*pvar->Value.NodeId), 1);
48
0
        SOPC_ReturnStatus status = (NULL != pvar->Value.NodeId ? SOPC_STATUS_OK : SOPC_STATUS_OUT_OF_MEMORY);
49
0
        if (SOPC_STATUS_OK == status)
50
0
        {
51
0
            status = SOPC_NodeId_Copy(pvar->Value.NodeId, pnid);
52
0
            if (SOPC_STATUS_OK != status)
53
0
            {
54
0
                SOPC_Free(pvar->Value.NodeId);
55
0
            }
56
0
        }
57
0
        if (SOPC_STATUS_OK != status)
58
0
        {
59
0
            SOPC_Free(pvar);
60
0
            pvar = NULL;
61
0
        }
62
0
    }
63
0
    else
64
0
    {
65
0
        pvar->Value.NodeId = pnid;
66
0
        pvar->DoNotClear = true; // It is shallow copy of provided node
67
0
    }
68
0
    return pvar;
69
0
}
70
71
SOPC_Variant* util_variant__new_Variant_from_NodeClass(OpcUa_NodeClass ncl)
72
0
{
73
0
    SOPC_Variant* pvar = SOPC_Malloc(sizeof(SOPC_Variant));
74
75
0
    if (NULL == pvar)
76
0
        return NULL;
77
78
0
    SOPC_Variant_Initialize(pvar);
79
0
    pvar->BuiltInTypeId = SOPC_Int32_Id;
80
0
    pvar->ArrayType = SOPC_VariantArrayType_SingleValue;
81
0
    pvar->Value.Int32 = (int32_t) ncl;
82
83
0
    return pvar;
84
0
}
85
86
SOPC_Variant* util_variant__new_Variant_from_QualifiedName(SOPC_QualifiedName* qn, bool deepCopy)
87
0
{
88
0
    SOPC_Variant* pvar = SOPC_Variant_Create();
89
0
    if (NULL == pvar)
90
0
    {
91
0
        return NULL;
92
0
    }
93
94
0
    pvar->BuiltInTypeId = SOPC_QualifiedName_Id;
95
0
    pvar->ArrayType = SOPC_VariantArrayType_SingleValue;
96
0
    if (deepCopy)
97
0
    {
98
0
        pvar->Value.Qname = SOPC_Calloc(sizeof(*pvar->Value.Qname), 1);
99
0
        SOPC_ReturnStatus status = (NULL != pvar->Value.Qname ? SOPC_STATUS_OK : SOPC_STATUS_OUT_OF_MEMORY);
100
0
        if (SOPC_STATUS_OK == status)
101
0
        {
102
0
            status = SOPC_QualifiedName_Copy(pvar->Value.Qname, qn);
103
0
            if (SOPC_STATUS_OK != status)
104
0
            {
105
0
                SOPC_Free(pvar->Value.Qname);
106
0
            }
107
0
        }
108
0
        if (SOPC_STATUS_OK != status)
109
0
        {
110
0
            SOPC_Free(pvar);
111
0
            pvar = NULL;
112
0
        }
113
0
    }
114
0
    else
115
0
    {
116
0
        pvar->Value.Qname = qn;
117
0
        pvar->DoNotClear = true; // It is shallow copy of provided node
118
0
    }
119
120
0
    return pvar;
121
0
}
122
123
SOPC_Variant* util_variant__new_Variant_from_LocalizedText(SOPC_LocalizedText* lt, bool deepCopy)
124
0
{
125
0
    SOPC_Variant* pvar = SOPC_Variant_Create();
126
127
0
    if (NULL == pvar)
128
0
    {
129
0
        return NULL;
130
0
    }
131
132
0
    pvar->BuiltInTypeId = SOPC_LocalizedText_Id;
133
0
    pvar->ArrayType = SOPC_VariantArrayType_SingleValue;
134
0
    if (deepCopy)
135
0
    {
136
0
        pvar->Value.LocalizedText = SOPC_Calloc(sizeof(*pvar->Value.LocalizedText), 1);
137
0
        SOPC_ReturnStatus status = (NULL != pvar->Value.LocalizedText ? SOPC_STATUS_OK : SOPC_STATUS_OUT_OF_MEMORY);
138
0
        if (SOPC_STATUS_OK == status)
139
0
        {
140
0
            status = SOPC_LocalizedText_Copy(pvar->Value.LocalizedText, lt);
141
0
            if (SOPC_STATUS_OK != status)
142
0
            {
143
0
                SOPC_Free(pvar->Value.LocalizedText);
144
0
            }
145
0
        }
146
0
        if (SOPC_STATUS_OK != status)
147
0
        {
148
0
            SOPC_Free(pvar);
149
0
            pvar = NULL;
150
0
        }
151
0
    }
152
0
    else
153
0
    {
154
0
        pvar->Value.LocalizedText = lt;
155
0
        pvar->DoNotClear = true; // It is shallow copy of provided node
156
0
    }
157
158
0
    return pvar;
159
0
}
160
161
bool util_variant__copy_PreferredLocalizedText_from_LocalizedText_Variant(SOPC_Variant* dest,
162
                                                                          const SOPC_Variant* src,
163
                                                                          char** preferredLocales)
164
0
{
165
0
    SOPC_ASSERT(NULL != src);
166
0
    SOPC_ASSERT(NULL != dest);
167
0
    SOPC_ASSERT(NULL != preferredLocales);
168
169
0
    SOPC_ASSERT(SOPC_LocalizedText_Id == src->BuiltInTypeId);
170
171
0
    SOPC_Variant* srcCopy = SOPC_Variant_Create();
172
0
    if (NULL == srcCopy)
173
0
    {
174
0
        return false;
175
0
    }
176
0
    SOPC_ReturnStatus status = SOPC_Variant_ShallowCopy(srcCopy, src);
177
178
0
    if (SOPC_STATUS_OK == status)
179
0
    {
180
0
        bool success = false;
181
0
        srcCopy =
182
0
            util_variant__set_PreferredLocalizedText_from_LocalizedText_Variant(&srcCopy, preferredLocales, &success);
183
0
        status = (success ? SOPC_STATUS_OK : SOPC_STATUS_NOK);
184
0
    }
185
0
    if (SOPC_STATUS_OK == status)
186
0
    {
187
0
        *dest = *srcCopy;
188
0
    }
189
0
    SOPC_Free(srcCopy);
190
0
    return (SOPC_STATUS_OK == status);
191
0
}
192
193
SOPC_Variant* util_variant__set_PreferredLocalizedText_from_LocalizedText_Variant(SOPC_Variant** v,
194
                                                                                  char** preferredLocales,
195
                                                                                  bool* success)
196
0
{
197
0
    SOPC_ASSERT(NULL != v);
198
0
    SOPC_Variant* value = *v;
199
0
    SOPC_ASSERT(SOPC_LocalizedText_Id == value->BuiltInTypeId);
200
201
0
    bool res = false;
202
    // If the caller wants to know the final result.
203
0
    if (NULL != success)
204
0
    {
205
0
        *success = res;
206
0
    }
207
208
    // Create a variant that will be a deep copy of *v
209
0
    SOPC_Variant* result = SOPC_Variant_Create();
210
0
    if (NULL == result)
211
0
    {
212
0
        return value;
213
0
    }
214
215
0
    if (SOPC_VariantArrayType_SingleValue == value->ArrayType)
216
0
    {
217
0
        SOPC_LocalizedText* newLt = SOPC_Malloc(sizeof(*newLt));
218
0
        SOPC_LocalizedText_Initialize(newLt);
219
0
        SOPC_ReturnStatus status =
220
0
            SOPC_LocalizedText_GetPreferredLocale(newLt, preferredLocales, value->Value.LocalizedText);
221
0
        if (SOPC_STATUS_OK != status)
222
0
        {
223
0
            SOPC_Free(newLt);
224
0
            SOPC_Variant_Clear(result);
225
0
            SOPC_Free(result);
226
0
            result = value;
227
0
        }
228
0
        else
229
0
        {
230
0
            result->ArrayType = SOPC_VariantArrayType_SingleValue;
231
0
            result->BuiltInTypeId = SOPC_LocalizedText_Id;
232
0
            result->Value.LocalizedText = newLt;
233
0
            res = true;
234
0
            SOPC_Variant_Clear(value);
235
0
            SOPC_Free(value);
236
0
            *v = NULL;
237
0
        }
238
0
    }
239
0
    else if (SOPC_VariantArrayType_Array == value->ArrayType || SOPC_VariantArrayType_Matrix == value->ArrayType)
240
0
    {
241
0
        SOPC_ReturnStatus status = SOPC_Variant_Copy(result, value);
242
243
0
        if (SOPC_STATUS_OK == status)
244
0
        {
245
0
            int32_t length = SOPC_Variant_GetArrayOrMatrixLength(value);
246
0
            const SOPC_LocalizedText* dest = NULL;
247
0
            const SOPC_LocalizedText* src = NULL;
248
0
            for (int32_t i = 0; SOPC_STATUS_OK == status && i < length; i++)
249
0
            {
250
0
                dest = SOPC_Variant_Get_ArrayValue(result, SOPC_LocalizedText_Id, i);
251
0
                src = SOPC_Variant_Get_ArrayValue(value, SOPC_LocalizedText_Id, i);
252
0
                SOPC_GCC_DIAGNOSTIC_IGNORE_CAST_CONST
253
0
                SOPC_LocalizedText_Clear(
254
0
                    (SOPC_LocalizedText*) dest); // Clear the initial copy and retrieved preferred locale
255
0
                status = SOPC_LocalizedText_GetPreferredLocale((SOPC_LocalizedText*) dest, preferredLocales, src);
256
0
                SOPC_GCC_DIAGNOSTIC_RESTORE
257
0
            }
258
0
        }
259
260
0
        if (SOPC_STATUS_OK == status)
261
0
        {
262
            // Preferred localized text array created, remove source one
263
0
            res = true;
264
0
            SOPC_Variant_Clear(value);
265
0
            SOPC_Free(value);
266
0
            *v = NULL;
267
0
        }
268
0
        else
269
0
        {
270
            // Do not compute preferred localized texts and keep default ones
271
0
            SOPC_Variant_Clear(result);
272
0
            SOPC_Free(result);
273
0
            result = value;
274
0
        }
275
0
    }
276
0
    else
277
0
    {
278
0
        SOPC_ASSERT(false);
279
0
    }
280
281
    // Update final result status
282
0
    if (NULL != success)
283
0
    {
284
0
        *success = res;
285
0
    }
286
287
0
    return result;
288
0
}
289
290
SOPC_Variant* util_variant__new_Variant_from_Indet(void)
291
0
{
292
0
    SOPC_Variant* pvar = SOPC_Malloc(sizeof(SOPC_Variant));
293
294
0
    if (NULL == pvar)
295
0
        return NULL;
296
297
0
    SOPC_Variant_Initialize(pvar);
298
0
    pvar->BuiltInTypeId = SOPC_Null_Id;
299
0
    pvar->ArrayType = SOPC_VariantArrayType_SingleValue;
300
301
0
    return pvar;
302
0
}
303
304
SOPC_Variant* util_variant__new_Variant_from_Variant(const SOPC_Variant* pvara, bool deepCopy)
305
0
{
306
0
    SOPC_ReturnStatus retStatus = SOPC_STATUS_OK;
307
0
    SOPC_Variant* pvar;
308
0
    if (NULL == pvara)
309
0
        return util_variant__new_Variant_from_Indet();
310
311
0
    pvar = SOPC_Variant_Create();
312
313
0
    if (NULL == pvar)
314
0
        return NULL;
315
316
0
    if (deepCopy)
317
0
    {
318
0
        retStatus = SOPC_Variant_Copy(pvar, pvara);
319
0
    }
320
0
    else
321
0
    {
322
0
        retStatus = SOPC_Variant_ShallowCopy(pvar, pvara);
323
0
    }
324
325
0
    if (retStatus != SOPC_STATUS_OK)
326
0
    {
327
0
        if (pvar != NULL)
328
0
        {
329
0
            SOPC_Free(pvar);
330
0
        }
331
0
        pvar = NULL;
332
0
    }
333
334
0
    return pvar;
335
0
}
336
337
SOPC_Variant* util_variant__new_Variant_from_Bool(bool b)
338
0
{
339
0
    SOPC_Variant* pvar = SOPC_Malloc(sizeof(SOPC_Variant));
340
341
0
    if (NULL != pvar)
342
0
    {
343
0
        SOPC_Variant_Initialize(pvar);
344
0
        pvar->BuiltInTypeId = SOPC_Boolean_Id;
345
0
        pvar->ArrayType = SOPC_VariantArrayType_SingleValue;
346
0
        pvar->Value.Byte = b;
347
0
    }
348
349
0
    return pvar;
350
0
}
351
352
SOPC_Variant* util_variant__new_Variant_from_Byte(uint8_t i)
353
0
{
354
0
    SOPC_Variant* pvar = SOPC_Malloc(sizeof(SOPC_Variant));
355
356
0
    if (NULL != pvar)
357
0
    {
358
0
        SOPC_Variant_Initialize(pvar);
359
0
        pvar->BuiltInTypeId = SOPC_Byte_Id;
360
0
        pvar->ArrayType = SOPC_VariantArrayType_SingleValue;
361
0
        pvar->Value.Byte = i;
362
0
    }
363
364
0
    return pvar;
365
0
}
366
367
SOPC_Variant* util_variant__new_Variant_from_uint32(uint32_t i)
368
0
{
369
0
    SOPC_Variant* pvar = SOPC_Malloc(sizeof(SOPC_Variant));
370
371
0
    if (NULL == pvar)
372
0
        return NULL;
373
374
0
    SOPC_Variant_Initialize(pvar);
375
0
    pvar->BuiltInTypeId = SOPC_UInt32_Id;
376
0
    pvar->ArrayType = SOPC_VariantArrayType_SingleValue;
377
0
    pvar->Value.Uint32 = i;
378
379
0
    return pvar;
380
0
}
381
382
SOPC_Variant* util_variant__new_Variant_from_int64(int64_t i)
383
0
{
384
0
    SOPC_Variant* pvar = SOPC_Malloc(sizeof(SOPC_Variant));
385
386
0
    if (NULL == pvar)
387
0
        return NULL;
388
389
0
    SOPC_Variant_Initialize(pvar);
390
0
    pvar->BuiltInTypeId = SOPC_Int64_Id;
391
0
    pvar->ArrayType = SOPC_VariantArrayType_SingleValue;
392
0
    pvar->Value.Int64 = i;
393
394
0
    return pvar;
395
0
}
396
397
SOPC_Variant* util_variant__new_Variant_from_int32(int32_t i)
398
0
{
399
0
    SOPC_Variant* pvar = SOPC_Malloc(sizeof(SOPC_Variant));
400
401
0
    if (NULL == pvar)
402
0
        return NULL;
403
404
0
    SOPC_Variant_Initialize(pvar);
405
0
    pvar->BuiltInTypeId = SOPC_Int32_Id;
406
0
    pvar->ArrayType = SOPC_VariantArrayType_SingleValue;
407
0
    pvar->Value.Int32 = i;
408
409
0
    return pvar;
410
0
}
411
412
SOPC_Variant* util_variant__new_Variant_from_double(double f)
413
0
{
414
0
    SOPC_Variant* pvar = SOPC_Malloc(sizeof(SOPC_Variant));
415
416
0
    if (NULL == pvar)
417
0
        return NULL;
418
419
0
    SOPC_Variant_Initialize(pvar);
420
0
    pvar->BuiltInTypeId = SOPC_Double_Id;
421
0
    pvar->ArrayType = SOPC_VariantArrayType_SingleValue;
422
0
    pvar->Value.Doublev = f;
423
424
0
    return pvar;
425
0
}
426
427
SOPC_Variant* util_variant__new_Variant_from_ByteString(SOPC_ByteString* bs, bool deepCopy)
428
0
{
429
0
    SOPC_ASSERT(NULL != bs);
430
0
    SOPC_Variant* pvar = SOPC_Variant_Create();
431
0
    if (NULL == pvar)
432
0
    {
433
0
        return NULL;
434
0
    }
435
436
0
    pvar->BuiltInTypeId = SOPC_ByteString_Id;
437
0
    pvar->ArrayType = SOPC_VariantArrayType_SingleValue;
438
0
    if (deepCopy)
439
0
    {
440
0
        SOPC_ByteString_Initialize(&pvar->Value.Bstring);
441
0
        SOPC_ReturnStatus status = SOPC_ByteString_Copy(&pvar->Value.Bstring, bs);
442
0
        if (SOPC_STATUS_OK != status)
443
0
        {
444
0
            SOPC_Free(pvar);
445
0
            pvar = NULL;
446
0
        }
447
0
    }
448
0
    else
449
0
    {
450
0
        pvar->Value.Bstring = *bs;
451
0
        pvar->DoNotClear = true; // It is shallow copy of provided node
452
0
    }
453
454
0
    return pvar;
455
0
}
456
457
SOPC_Variant* util_variant__new_Variant_from_ExtensionObject(SOPC_ExtensionObject* extObj, bool deepCopy)
458
0
{
459
0
    SOPC_Variant* pvar = SOPC_Variant_Create();
460
461
0
    if (NULL == pvar)
462
0
        return NULL;
463
464
0
    pvar->BuiltInTypeId = SOPC_ExtensionObject_Id;
465
0
    pvar->ArrayType = SOPC_VariantArrayType_SingleValue;
466
0
    if (deepCopy)
467
0
    {
468
0
        pvar->Value.ExtObject = SOPC_Calloc(sizeof(*pvar->Value.ExtObject), 1);
469
0
        SOPC_ReturnStatus status = (NULL != pvar->Value.ExtObject ? SOPC_STATUS_OK : SOPC_STATUS_OUT_OF_MEMORY);
470
0
        if (SOPC_STATUS_OK == status)
471
0
        {
472
0
            status = SOPC_ExtensionObject_Copy(pvar->Value.ExtObject, extObj);
473
0
            if (SOPC_STATUS_OK != status)
474
0
            {
475
0
                SOPC_Free(pvar->Value.ExtObject);
476
0
            }
477
0
        }
478
0
        if (SOPC_STATUS_OK != status)
479
0
        {
480
0
            SOPC_Free(pvar);
481
0
            pvar = NULL;
482
0
        }
483
0
    }
484
0
    else
485
0
    {
486
0
        pvar->Value.ExtObject = extObj;
487
0
        pvar->DoNotClear = true; // It is shallow copy of provided node
488
0
    }
489
490
0
    return pvar;
491
0
}
492
493
SOPC_ReturnStatus util_variant__copy_and_apply_locales_and_index_range(SOPC_Variant* destVal,
494
                                                                       const SOPC_Variant* source,
495
                                                                       char** preferredLocalesIds,
496
                                                                       const SOPC_NumericRange* indexRange)
497
0
{
498
0
    SOPC_ASSERT(NULL != destVal);
499
0
    SOPC_ASSERT(NULL != source);
500
0
    SOPC_ReturnStatus status = SOPC_STATUS_OK;
501
0
    SOPC_Variant ltEventVar;
502
0
    SOPC_Variant_Initialize(&ltEventVar);
503
0
    SOPC_StatusCode valueStatus = SOPC_GoodGenericStatus;
504
505
    /* Set the preferred locale in case of LT value */
506
0
    if (SOPC_LocalizedText_Id == source->BuiltInTypeId && NULL != preferredLocalesIds)
507
0
    {
508
0
        bool res = util_variant__copy_PreferredLocalizedText_from_LocalizedText_Variant(&ltEventVar, source,
509
0
                                                                                        preferredLocalesIds);
510
0
        if (!res)
511
0
        {
512
0
            status = SOPC_STATUS_OUT_OF_MEMORY;
513
0
            valueStatus = OpcUa_BadOutOfMemory;
514
0
        }
515
0
        source = &ltEventVar;
516
0
    }
517
518
    /* IndexRange filtering */
519
0
    constants_statuscodes_bs__t_StatusCode_i readSC = constants_statuscodes_bs__c_StatusCode_indet;
520
0
    if (SOPC_STATUS_OK == status)
521
0
    {
522
0
        if (NULL != indexRange)
523
0
        {
524
0
            readSC = util_read_value_indexed_helper(destVal, source, indexRange);
525
0
            if (constants_statuscodes_bs__e_sc_ok != readSC)
526
0
            {
527
                /* note: index range syntax error shall have occurred on createMI but the specification state any error
528
                 * might be returned as value:
529
                 * "Servers should return all other errors as CreateMonitoredItems results
530
                 *  but all possible errors are allowed to be returned in the Publish response."
531
                 */
532
0
                util_status_code__B_to_C(readSC, &valueStatus);
533
0
                status = SOPC_STATUS_NOK;
534
0
            }
535
0
        }
536
0
        else
537
0
        {
538
0
            status = SOPC_Variant_Copy(destVal, source);
539
0
            if (SOPC_STATUS_OK != status)
540
0
            {
541
0
                SOPC_ASSERT(SOPC_STATUS_OUT_OF_MEMORY == status);
542
0
                valueStatus = OpcUa_BadOutOfMemory;
543
0
            }
544
0
        }
545
0
    }
546
547
0
    SOPC_Variant_Clear(&ltEventVar);
548
0
    if (SOPC_STATUS_OK != status)
549
0
    {
550
0
        SOPC_ASSERT(!SOPC_IsGoodStatus(valueStatus));
551
0
        SOPC_Variant_Clear(destVal);
552
0
        destVal->BuiltInTypeId = SOPC_StatusCode_Id;
553
0
        destVal->Value.Status = valueStatus;
554
0
    }
555
0
    return status;
556
0
}
557
558
SOPC_ReturnStatus util_variant__update_applying_supported_locales(SOPC_Variant* valToUpdate,
559
                                                                  const SOPC_Variant* newVal,
560
                                                                  char** supportedLocales)
561
0
{
562
0
    SOPC_ASSERT(NULL != valToUpdate);
563
0
    SOPC_ASSERT(NULL != newVal);
564
0
    SOPC_ASSERT(NULL != supportedLocales);
565
0
    SOPC_ReturnStatus status = SOPC_STATUS_OK;
566
567
0
    if (valToUpdate->ArrayType != newVal->ArrayType || SOPC_LocalizedText_Id != valToUpdate->BuiltInTypeId ||
568
0
        valToUpdate->BuiltInTypeId != newVal->BuiltInTypeId)
569
0
    {
570
0
        return SOPC_STATUS_INVALID_PARAMETERS;
571
0
    }
572
573
0
    if (SOPC_VariantArrayType_SingleValue == valToUpdate->ArrayType)
574
0
    {
575
0
        status = SOPC_LocalizedText_AddOrSetLocale(valToUpdate->Value.LocalizedText, supportedLocales,
576
0
                                                   newVal->Value.LocalizedText);
577
0
    }
578
0
    else if (SOPC_VariantArrayType_Array == valToUpdate->ArrayType)
579
0
    {
580
0
        SOPC_ASSERT(valToUpdate->Value.Array.Length == newVal->Value.Array.Length);
581
0
        for (int32_t i = 0; SOPC_STATUS_OK == status && i < newVal->Value.Array.Length; i++)
582
0
        {
583
0
            status =
584
0
                SOPC_LocalizedText_AddOrSetLocale(&valToUpdate->Value.Array.Content.LocalizedTextArr[i],
585
0
                                                  supportedLocales, &newVal->Value.Array.Content.LocalizedTextArr[i]);
586
0
        }
587
0
    }
588
0
    else if (SOPC_VariantArrayType_Matrix == valToUpdate->ArrayType)
589
0
    {
590
0
        SOPC_ASSERT(valToUpdate->Value.Matrix.Dimensions == newVal->Value.Matrix.Dimensions);
591
0
        int32_t matrixLength = 1;
592
0
        for (int32_t i = 0; i < newVal->Value.Matrix.Dimensions; i++)
593
0
        {
594
0
            SOPC_ASSERT(valToUpdate->Value.Matrix.ArrayDimensions[i] == newVal->Value.Matrix.ArrayDimensions[i]);
595
0
            matrixLength *= valToUpdate->Value.Matrix.ArrayDimensions[i];
596
0
        }
597
0
        for (int32_t i = 0; SOPC_STATUS_OK == status && i < matrixLength; i++)
598
0
        {
599
0
            status =
600
0
                SOPC_LocalizedText_AddOrSetLocale(&valToUpdate->Value.Matrix.Content.LocalizedTextArr[i],
601
0
                                                  supportedLocales, &newVal->Value.Matrix.Content.LocalizedTextArr[i]);
602
0
        }
603
0
    }
604
0
    else
605
0
    {
606
0
        status = SOPC_STATUS_INVALID_PARAMETERS;
607
0
    }
608
0
    return status;
609
0
}