GCC Code Coverage Report
Directory: ./ Exec Total Coverage
File: gx_binres_language_table_load.c Lines: 144 144 100.0 %
Date: 2026-03-06 19:21:09 Branches: 52 52 100.0 %

Line Branch Exec Source
1
/***************************************************************************
2
 * Copyright (c) 2024 Microsoft Corporation
3
 * Copyright (c) 2026-present Eclipse ThreadX contributors
4
 *
5
 * This program and the accompanying materials are made available under the
6
 * terms of the MIT License which is available at
7
 * https://opensource.org/licenses/MIT.
8
 *
9
 * SPDX-License-Identifier: MIT
10
 **************************************************************************/
11
12
13
/**************************************************************************/
14
/**************************************************************************/
15
/**                                                                       */
16
/** GUIX Component                                                        */
17
/**                                                                       */
18
/**   Binres Loader Management (Binres Loader)                            */
19
/**                                                                       */
20
/**************************************************************************/
21
22
#define GX_SOURCE_CODE
23
24
25
/* Include necessary system files.  */
26
27
#include "gx_api.h"
28
#include "gx_binres_loader.h"
29
#include "gx_system.h"
30
#include "gx_utility.h"
31
32
/**************************************************************************/
33
/*                                                                        */
34
/*  FUNCTION                                               RELEASE        */
35
/*                                                                        */
36
/*    _gx_binres_resource_header_load                     PORTABLE C      */
37
/*                                                           6.1          */
38
/*  AUTHOR                                                                */
39
/*                                                                        */
40
/*    Kenneth Maxwell, Microsoft Corporation                              */
41
/*                                                                        */
42
/*  DESCRIPTION                                                           */
43
/*                                                                        */
44
/*    This function reads resource header from a binary data buffer.      */
45
/*                                                                        */
46
/*  INPUT                                                                 */
47
/*                                                                        */
48
/*    info                                  Binary read control block     */
49
/*    header                                Returned resource header      */
50
/*                                                                        */
51
/*  OUTPUT                                                                */
52
/*                                                                        */
53
/*    Status                                Completion status             */
54
/*                                                                        */
55
/*  CALLS                                                                 */
56
/*                                                                        */
57
/*    None                                                                */
58
/*                                                                        */
59
/*  CALLED BY                                                             */
60
/*                                                                        */
61
/*    GUIX Internal Code                                                  */
62
/*                                                                        */
63
/**************************************************************************/
64
#ifdef GX_BINARY_RESOURCE_SUPPORT
65
189
UINT _gx_binres_resource_header_load(GX_BINRES_DATA_INFO *info, GX_RESOURCE_HEADER *header)
66
{
67
189
    GX_BINRES_READ_USHORT(header -> gx_resource_header_magic_number, info -> gx_binres_root_address + info -> gx_binres_read_offset);
68
189
    info -> gx_binres_read_offset += sizeof(USHORT);
69
70
189
    GX_BINRES_READ_USHORT(header -> gx_resource_header_version, info -> gx_binres_root_address + info -> gx_binres_read_offset);
71
189
    info -> gx_binres_read_offset += sizeof(USHORT);
72
73
189
    GX_BINRES_READ_USHORT(header -> gx_resource_header_theme_count, info -> gx_binres_root_address + info -> gx_binres_read_offset);
74
189
    info -> gx_binres_read_offset += sizeof(USHORT);
75
76
189
    GX_BINRES_READ_USHORT(header -> gx_resource_header_language_count, info -> gx_binres_root_address + info -> gx_binres_read_offset);
77
189
    info -> gx_binres_read_offset += sizeof(USHORT);
78
79
189
    GX_BINRES_READ_ULONG(header -> gx_resource_header_theme_data_size, info -> gx_binres_root_address + info -> gx_binres_read_offset);
80
189
    info -> gx_binres_read_offset += sizeof(ULONG);
81
82
189
    GX_BINRES_READ_ULONG(header -> gx_resource_header_string_data_size, info -> gx_binres_root_address + info -> gx_binres_read_offset);
83
189
    info -> gx_binres_read_offset += sizeof(ULONG);
84
85
189
    GX_BINRES_READ_ULONG(header -> gx_resource_header_data_size, info -> gx_binres_root_address + info -> gx_binres_read_offset);
86
189
    info -> gx_binres_read_offset += sizeof(ULONG);
87
88
189
    return GX_SUCCESS;
89
}
90
#endif
91
92
/**************************************************************************/
93
/*                                                                        */
94
/*  FUNCTION                                               RELEASE        */
95
/*                                                                        */
96
/*    _gx_binres_string_header_load                       PORTABLE C      */
97
/*                                                           6.1          */
98
/*  AUTHOR                                                                */
99
/*                                                                        */
100
/*    Kenneth Maxwell, Microsoft Corporation                              */
101
/*                                                                        */
102
/*  DESCRIPTION                                                           */
103
/*                                                                        */
104
/*    This function reads string header from a binary data buffer.        */
105
/*                                                                        */
106
/*  INPUT                                                                 */
107
/*                                                                        */
108
/*    info                                  Binary read control block     */
109
/*    header                                Returned string header        */
110
/*                                                                        */
111
/*  OUTPUT                                                                */
112
/*                                                                        */
113
/*    Status                                Completion status             */
114
/*                                                                        */
115
/*  CALLS                                                                 */
116
/*                                                                        */
117
/*    None                                                                */
118
/*                                                                        */
119
/*  CALLED BY                                                             */
120
/*                                                                        */
121
/*    GUIX Internal Code                                                  */
122
/*                                                                        */
123
/**************************************************************************/
124
#ifdef GX_BINARY_RESOURCE_SUPPORT
125
83
UINT _gx_binres_string_header_load(GX_BINRES_DATA_INFO *info, GX_STRING_HEADER *header)
126
{
127
83
    GX_BINRES_READ_USHORT(header -> gx_string_header_magic_number, info -> gx_binres_root_address + info -> gx_binres_read_offset);
128
83
    info -> gx_binres_read_offset += sizeof(USHORT);
129
130
83
    GX_BINRES_READ_USHORT(header -> gx_string_header_language_count, info -> gx_binres_root_address + info -> gx_binres_read_offset);
131
83
    info -> gx_binres_read_offset += sizeof(USHORT);
132
133
83
    GX_BINRES_READ_USHORT(header -> gx_string_header_string_count, info -> gx_binres_root_address + info -> gx_binres_read_offset);
134
83
    info -> gx_binres_read_offset += sizeof(USHORT);
135
136
83
    GX_BINRES_READ_ULONG(header -> gx_string_header_data_size, info -> gx_binres_root_address + info -> gx_binres_read_offset);
137
83
    info -> gx_binres_read_offset += sizeof(ULONG);
138
139
83
    return GX_SUCCESS;
140
}
141
#endif
142
143
/**************************************************************************/
144
/*                                                                        */
145
/*  FUNCTION                                               RELEASE        */
146
/*                                                                        */
147
/*    _gx_binres_language_header_load                     PORTABLE C      */
148
/*                                                           6.1          */
149
/*  AUTHOR                                                                */
150
/*                                                                        */
151
/*    Kenneth Maxwell, Microsoft Corporation                              */
152
/*                                                                        */
153
/*  DESCRIPTION                                                           */
154
/*                                                                        */
155
/*    This function reads language header from a binary data buffer.      */
156
/*                                                                        */
157
/*  INPUT                                                                 */
158
/*                                                                        */
159
/*    info                                  Binary read control block     */
160
/*    header                                Returned language header      */
161
/*                                                                        */
162
/*  OUTPUT                                                                */
163
/*                                                                        */
164
/*    Status                                Completion status             */
165
/*                                                                        */
166
/*  CALLS                                                                 */
167
/*                                                                        */
168
/*    None                                                                */
169
/*                                                                        */
170
/*  CALLED BY                                                             */
171
/*                                                                        */
172
/*    GUIX Internal Code                                                  */
173
/*                                                                        */
174
/**************************************************************************/
175
#ifdef GX_BINARY_RESOURCE_SUPPORT
176
36
UINT _gx_binres_language_header_load(GX_BINRES_DATA_INFO *info, GX_LANGUAGE_HEADER *header)
177
{
178
36
    GX_BINRES_READ_USHORT(header -> gx_language_header_magic_number, info -> gx_binres_root_address + info -> gx_binres_read_offset);
179
36
    info -> gx_binres_read_offset += sizeof(USHORT);
180
181
36
    GX_BINRES_READ_USHORT(header -> gx_language_header_index, info -> gx_binres_root_address + info -> gx_binres_read_offset);
182
36
    info -> gx_binres_read_offset += sizeof(USHORT);
183
184
36
    memcpy(&header->gx_language_header_name, info->gx_binres_root_address + info->gx_binres_read_offset, sizeof(header->gx_language_header_name)); /* Use case of memcpy is verified. */
185
36
    info -> gx_binres_read_offset += sizeof(header -> gx_language_header_name);
186
187
36
    GX_BINRES_READ_ULONG(header -> gx_language_header_data_size, info -> gx_binres_root_address + info -> gx_binres_read_offset);
188
36
    info -> gx_binres_read_offset += sizeof(ULONG);
189
190
36
    return GX_SUCCESS;
191
}
192
#endif
193
194
/**************************************************************************/
195
/*                                                                        */
196
/*  FUNCTION                                               RELEASE        */
197
/*                                                                        */
198
/*    _gx_binres_language_table_buffer_allocate           PORTABLE C      */
199
/*                                                           6.1.7        */
200
/*  AUTHOR                                                                */
201
/*                                                                        */
202
/*    Kenneth Maxwell, Microsoft Corporation                              */
203
/*                                                                        */
204
/*  DESCRIPTION                                                           */
205
/*                                                                        */
206
/*    This function allocates needed memory buffer for loading language   */
207
/*    table.                                                              */
208
/*                                                                        */
209
/*  INPUT                                                                 */
210
/*                                                                        */
211
/*    info                                  Binary resource control block */
212
/*    language_table_type_size              Size of language table type   */
213
/*    string_table_type_size                Size of string table type     */
214
/*                                                                        */
215
/*  OUTPUT                                                                */
216
/*                                                                        */
217
/*    Status                                Completion status             */
218
/*                                                                        */
219
/*  CALLS                                                                 */
220
/*                                                                        */
221
/*    _gx_system_memory_allocator           Application defined memory    */
222
/*                                            allocation function         */
223
/*    _gx_binres_resource_header_load       Read binary resource header   */
224
/*    _gx_binres_string_header_load         Read string data header       */
225
/*                                                                        */
226
/*  CALLED BY                                                             */
227
/*                                                                        */
228
/*    GUIX Internal Code                                                  */
229
/*                                                                        */
230
/**************************************************************************/
231
#ifdef GX_BINARY_RESOURCE_SUPPORT
232
46
static UINT _gx_binres_language_table_buffer_allocate(GX_BINRES_DATA_INFO *info, GX_UBYTE language_table_type_size, GX_UBYTE string_table_type_size)
233
{
234
GX_RESOURCE_HEADER res_header;
235
GX_STRING_HEADER   string_header;
236
USHORT             language_count;
237
USHORT             string_count;
238
UINT               language_table_size;
239
UINT               string_table_size;
240
241
46
    info -> gx_binres_read_offset = 0;
242
243
    /* Read resource header.  */
244
46
    _gx_binres_resource_header_load(info, &res_header);
245
46
    info -> gx_binres_read_offset += res_header.gx_resource_header_theme_data_size;
246
247
46
    if (res_header.gx_resource_header_magic_number != GX_MAGIC_NUMBER)
248
    {
249
2
        return GX_INVALID_FORMAT;
250
    }
251
252
44
    _gx_binres_string_header_load(info, &string_header);
253
254
44
    if (string_header.gx_string_header_magic_number != GX_MAGIC_NUMBER)
255
    {
256
2
        return GX_INVALID_FORMAT;
257
    }
258
259
42
    language_count = string_header.gx_string_header_language_count;
260
261
42
    if (language_count == 0)
262
    {
263
2
        return GX_INVALID_FORMAT;
264
    }
265
40
    string_count = string_header.gx_string_header_string_count;
266
267
    /* Calcualte memory size needed for string tables. */
268
40
    string_table_size = (UINT)(string_count * string_table_type_size);
269
40
    GX_UTILITY_MATH_UINT_MULT(string_table_size, language_count, string_table_size)
270
271
    /* Calculate memory size needed for language table. */
272
38
    language_table_size = (UINT)(language_table_type_size * language_count);
273
274
    /* Calculate memory size needed.  */
275
38
    GX_UTILITY_MATH_UINT_ADD(string_table_size, language_table_size, info -> gx_binres_buffer_size)
276
277
37
    info -> gx_binres_buffer = (GX_UBYTE *)_gx_system_memory_allocator(info -> gx_binres_buffer_size);
278
279
37
    if (!info -> gx_binres_buffer)
280
    {
281
3
        return GX_SYSTEM_MEMORY_ERROR;
282
    }
283
284
34
    memset(info -> gx_binres_buffer, 0, info -> gx_binres_buffer_size);
285
34
    info -> gx_binres_buffer_index = 0;
286
287
34
    return GX_SUCCESS;
288
}
289
#endif
290
291
/**************************************************************************/
292
/*                                                                        */
293
/*  FUNCTION                                               RELEASE        */
294
/*                                                                        */
295
/*    _gx_binres_language_table_load                      PORTABLE C      */
296
/*                                                           6.1          */
297
/*  AUTHOR                                                                */
298
/*                                                                        */
299
/*    Kenneth Maxwell, Microsoft Corporation                              */
300
/*                                                                        */
301
/*  DESCRIPTION (deprecated)                                              */
302
/*                                                                        */
303
/*    This service loads a language table from a binary data buffer.      */
304
/*                                                                        */
305
/*  INPUT                                                                 */
306
/*                                                                        */
307
/*    root_address                          Root address of binary        */
308
/*                                            resource data               */
309
/*    returned_language_table               Pointer to loaded language    */
310
/*                                           table                        */
311
/*                                                                        */
312
/*  OUTPUT                                                                */
313
/*                                                                        */
314
/*    Status                                Completion status             */
315
/*                                                                        */
316
/*  CALLS                                                                 */
317
/*                                                                        */
318
/*    _gx_binres_language_table_buffer_allocate                           */
319
/*                                          Allocate needed buffer for    */
320
/*                                            loading language table      */
321
/*    _gx_binres_resource_header_load                                     */
322
/*                                          Read resource header          */
323
/*    _gx_binres_string_header_load         Read string data header       */
324
/*    _gx_binres_language_header_load       Read language data header     */
325
/*    _gx_system_memory_free                Application defined memory    */
326
/*                                            free function               */
327
/*                                                                        */
328
/*  CALLED BY                                                             */
329
/*                                                                        */
330
/*    Application Code                                                    */
331
/*                                                                        */
332
/**************************************************************************/
333
#ifdef GX_BINARY_RESOURCE_SUPPORT
334
#ifdef GX_ENABLE_DEPRECATED_STRING_API
335
12
UINT _gx_binres_language_table_load(GX_UBYTE *root_address, GX_UBYTE ****returned_language_table)
336
{
337
UINT                status;
338
GX_BINRES_DATA_INFO info;
339
GX_RESOURCE_HEADER  header;
340
GX_STRING_HEADER    string_header;
341
GX_LANGUAGE_HEADER  language_header;
342
GX_UBYTE         ***language_table;
343
UINT                lang_index;
344
UINT                string_index;
345
USHORT              string_length;
346
GX_CHAR             get_char;
347
348
12
    memset(&info, 0, sizeof(GX_BINRES_DATA_INFO));
349
350
12
    info.gx_binres_root_address = root_address;
351
352
    /* Allocate memory that needed for language table.  */
353
12
    status = _gx_binres_language_table_buffer_allocate(&info, sizeof(GX_UBYTE * *), sizeof(GX_UBYTE *));
354
355
    /* Read Resource header. */
356
12
    info.gx_binres_read_offset = 0;
357
12
    _gx_binres_resource_header_load(&info, &header);
358
359
    /* Skip theme info.  */
360
12
    info.gx_binres_read_offset += header.gx_resource_header_theme_data_size;
361
362
12
    if (header.gx_resource_header_magic_number != GX_MAGIC_NUMBER)
363
    {
364
1
        return GX_INVALID_FORMAT;
365
    }
366
367
11
    language_table = GX_NULL;
368
369
    /* Read language table.  */
370
11
    if (status == GX_SUCCESS)
371
    {
372
        /* Read string header. */
373
6
        _gx_binres_string_header_load(&info, &string_header);
374
375
6
        language_table = (GX_UBYTE ***)(info.gx_binres_buffer + info.gx_binres_buffer_index);
376
6
        info.gx_binres_buffer_index += sizeof(GX_UBYTE * *) * string_header.gx_string_header_language_count;
377
378
11
        for (lang_index = 0; lang_index < string_header.gx_string_header_language_count; lang_index++)
379
        {
380
            /* Read language header.  */
381
6
            _gx_binres_language_header_load(&info, &language_header);
382
383
6
            if (language_header.gx_language_header_magic_number != GX_MAGIC_NUMBER)
384
            {
385
1
                status = GX_INVALID_FORMAT;
386
1
                break;
387
            }
388
389
            /* Read string table.  */
390
5
            language_table[lang_index] = (GX_UBYTE **)(info.gx_binres_buffer + info.gx_binres_buffer_index);
391
5
            info.gx_binres_buffer_index += sizeof(GX_UBYTE *) * string_header.gx_string_header_string_count;
392
393
5
            if (header.gx_resource_header_version >= GX_BINRES_VERSION_ADD_STRING_LENGTH)
394
            {
395
72
                for (string_index = 1; string_index < string_header.gx_string_header_string_count; string_index++)
396
                {
397
                    /* Read string length. */
398
68
                    GX_BINRES_READ_USHORT(string_length, info.gx_binres_root_address + info.gx_binres_read_offset);
399
68
                    info.gx_binres_read_offset += sizeof(USHORT);
400
401
68
                    if (string_length == 0)
402
                    {
403
20
                        language_table[lang_index][string_index] = GX_NULL;
404
                    }
405
                    else
406
                    {
407
48
                        language_table[lang_index][string_index] = (GX_UBYTE *)(info.gx_binres_root_address + info.gx_binres_read_offset);
408
48
                        info.gx_binres_read_offset += (UINT)(string_length + 1);
409
                    }
410
                }
411
            }
412
            else
413
            {
414
1
                string_index = 1;
415
1
                string_length = 0;
416
132
                while (string_index < string_header.gx_string_header_string_count)
417
                {
418
130
                    string_length++;
419
420
130
                    get_char = (GX_CHAR)info.gx_binres_root_address[info.gx_binres_read_offset];
421
130
                    info.gx_binres_read_offset++;
422
423
130
                    if (get_char == '\0')
424
                    {
425
17
                        if (string_length == 1)
426
                        {
427
5
                            language_table[lang_index][string_index] = GX_NULL;
428
                        }
429
                        else
430
                        {
431
12
                            language_table[lang_index][string_index] = (GX_UBYTE *)(info.gx_binres_root_address + info.gx_binres_read_offset - string_length);
432
                        }
433
434
17
                        string_length = 0;
435
17
                        string_index++;
436
                    }
437
                }
438
            }
439
        }
440
    }
441
442
11
    if (status == GX_SUCCESS)
443
    {
444
5
        *returned_language_table = language_table;
445
    }
446
    else
447
    {
448
        /* Free allocated memory when language loading failed. */
449
6
        if (info.gx_binres_buffer)
450
        {
451
1
            _gx_system_memory_free(info.gx_binres_buffer);
452
        }
453
454
6
        *returned_language_table = GX_NULL;
455
    }
456
457
458
11
    return status;
459
}
460
#endif
461
#endif
462
463
/**************************************************************************/
464
/*                                                                        */
465
/*  FUNCTION                                               RELEASE        */
466
/*                                                                        */
467
/*    _gx_binres_language_table_load_ext                  PORTABLE C      */
468
/*                                                           6.1          */
469
/*  AUTHOR                                                                */
470
/*                                                                        */
471
/*    Kenneth Maxwell, Microsoft Corporation                              */
472
/*                                                                        */
473
/*  DESCRIPTION                                                           */
474
/*                                                                        */
475
/*    This service loads a language table from a binary data buffer.      */
476
/*                                                                        */
477
/*  INPUT                                                                 */
478
/*                                                                        */
479
/*    root_address                          Root address of binary        */
480
/*                                            resource data               */
481
/*    returned_language_table               Pointer to loaded language    */
482
/*                                           table                        */
483
/*                                                                        */
484
/*  OUTPUT                                                                */
485
/*                                                                        */
486
/*    Status                                Completion status             */
487
/*                                                                        */
488
/*  CALLS                                                                 */
489
/*                                                                        */
490
/*    _gx_binres_language_table_buffer_allocate                           */
491
/*                                          Allocate needed buffer for    */
492
/*                                            loading language table      */
493
/*    _gx_binres_resource_header_load                                     */
494
/*                                          Read resource header          */
495
/*    _gx_binres_string_header_load         Read string data header       */
496
/*    _gx_binres_language_header_load       Read language data header     */
497
/*    _gx_system_memory_free                Application defined memory    */
498
/*                                            free function               */
499
/*                                                                        */
500
/*  CALLED BY                                                             */
501
/*                                                                        */
502
/*    Application Code                                                    */
503
/*                                                                        */
504
/**************************************************************************/
505
#ifdef GX_BINARY_RESOURCE_SUPPORT
506
34
UINT _gx_binres_language_table_load_ext(GX_UBYTE *root_address, GX_STRING ***returned_language_table)
507
{
508
UINT                status;
509
GX_BINRES_DATA_INFO info;
510
GX_RESOURCE_HEADER  header;
511
GX_STRING_HEADER    string_header;
512
GX_LANGUAGE_HEADER  language_header;
513
GX_STRING         **language_table;
514
UINT                lang_index;
515
UINT                string_index;
516
USHORT              string_length;
517
GX_UBYTE           *get_data;
518
519
34
    memset(&info, 0, sizeof(GX_BINRES_DATA_INFO));
520
521
34
    info.gx_binres_root_address = root_address;
522
523
    /* Allocate memory that needed for language table.  */
524
34
    status = _gx_binres_language_table_buffer_allocate(&info, sizeof(GX_STRING *), sizeof(GX_STRING));
525
526
    /* Read Resource header. */
527
34
    info.gx_binres_read_offset = 0;
528
34
    _gx_binres_resource_header_load(&info, &header);
529
530
    /* Skip theme info.  */
531
34
    info.gx_binres_read_offset += header.gx_resource_header_theme_data_size;
532
533
34
    if (header.gx_resource_header_magic_number != GX_MAGIC_NUMBER)
534
    {
535
1
        return GX_INVALID_FORMAT;
536
    }
537
538
33
    language_table = GX_NULL;
539
540
    /* Read language table.  */
541
33
    if (status == GX_SUCCESS)
542
    {
543
        /* Read string header. */
544
28
        _gx_binres_string_header_load(&info, &string_header);
545
546
28
        language_table = (GX_STRING **)(info.gx_binres_buffer + info.gx_binres_buffer_index);
547
28
        info.gx_binres_buffer_index += sizeof(GX_STRING *) * string_header.gx_string_header_language_count;
548
549
55
        for (lang_index = 0; lang_index < string_header.gx_string_header_language_count; lang_index++)
550
        {
551
            /* Read language header.  */
552
28
            _gx_binres_language_header_load(&info, &language_header);
553
554
28
            if (language_header.gx_language_header_magic_number != GX_MAGIC_NUMBER)
555
            {
556
1
                status = GX_INVALID_FORMAT;
557
1
                break;
558
            }
559
560
            /* Read string table.  */
561
27
            language_table[lang_index] = (GX_STRING *)(info.gx_binres_buffer + info.gx_binres_buffer_index);
562
27
            info.gx_binres_buffer_index += sizeof(GX_STRING) * string_header.gx_string_header_string_count;
563
564
2176
            for (string_index = 1; string_index < string_header.gx_string_header_string_count; string_index++)
565
            {
566
                /* Read string length. */
567
2149
                get_data = info.gx_binres_root_address + info.gx_binres_read_offset;
568
2149
                string_length = *(get_data + 1);
569
2149
                string_length = (USHORT)(string_length << 8);
570
2149
                string_length = (USHORT)(string_length | (*get_data));
571
2149
                info.gx_binres_read_offset += sizeof(USHORT);
572
573
2149
                if (string_length)
574
                {
575
2098
                    language_table[lang_index][string_index].gx_string_ptr = (GX_CHAR *)(info.gx_binres_root_address + info.gx_binres_read_offset);
576
                }
577
                else
578
                {
579
51
                    language_table[lang_index][string_index].gx_string_ptr = GX_NULL;
580
                }
581
582
2149
                language_table[lang_index][string_index].gx_string_length = string_length;
583
2149
                info.gx_binres_read_offset += (UINT)(string_length + 1);
584
            }
585
        }
586
    }
587
588
33
    if (status == GX_SUCCESS)
589
    {
590
27
        *returned_language_table = language_table;
591
    }
592
    else
593
    {
594
        /* Free allocated memory when language loading failed. */
595
6
        if (info.gx_binres_buffer)
596
        {
597
1
            _gx_system_memory_free(info.gx_binres_buffer);
598
        }
599
600
6
        *returned_language_table = GX_NULL;
601
    }
602
603
604
33
    return status;
605
}
606
#endif
607