GCC Code Coverage Report
Directory: ./ Exec Total Coverage
File: gx_utility_utf8_string_character_get.c Lines: 69 69 100.0 %
Date: 2026-03-06 19:21:09 Branches: 50 50 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
/**   Utility (Utility)                                                   */
19
/**                                                                       */
20
/**************************************************************************/
21
22
#define GX_SOURCE_CODE
23
24
/* Include necessary system files.  */
25
26
#include "gx_api.h"
27
#include "gx_utility.h"
28
29
30
/**************************************************************************/
31
/*                                                                        */
32
/*  FUNCTION                                               RELEASE        */
33
/*                                                                        */
34
/*    _gx_utility_utf8_string_character_get               PORTABLE C      */
35
/*                                                           6.1          */
36
/*  AUTHOR                                                                */
37
/*                                                                        */
38
/*    Kenneth Maxwell, Microsoft Corporation                              */
39
/*                                                                        */
40
/*  DESCRIPTION                                                           */
41
/*                                                                        */
42
/*    This function parses utf8 string to multibyte glyph.                */
43
/*                                                                        */
44
/*  INPUT                                                                 */
45
/*                                                                        */
46
/*    utf8_str                              UTF-8 string                  */
47
/*    glyph_value                           Multibyte value of glyph      */
48
/*    byte_count                            Length of UTF-8 string in byte*/
49
/*    glyph_len                             Length of glyph value in byte */
50
/*                                                                        */
51
/*  OUTPUT                                                                */
52
/*                                                                        */
53
/*    status                                Completion status             */
54
/*                                                                        */
55
/*  CALLS                                                                 */
56
/*                                                                        */
57
/*                                                                        */
58
/*  CALLED BY                                                             */
59
/*                                                                        */
60
/*    _gx_system_string_width_get                                         */
61
/*    _gx_display_driver_indexed_color_text_draw                          */
62
/*                                                                        */
63
/**************************************************************************/
64
#ifdef GX_UTF8_SUPPORT
65
32293962
UINT  _gx_utility_utf8_string_character_get(GX_STRING *utf8_str, GX_CHAR_CODE *glyph_value, UINT *glyph_len)
66
{
67
GX_CONST GX_CHAR *ch;
68
UINT              bytes;
69
32293962
GX_CHAR_CODE      value = 0;
70
UINT              len;
71
UINT              byte_count;
72
73
32293962
    ch = utf8_str -> gx_string_ptr;
74
32293962
    byte_count = utf8_str -> gx_string_length;
75
76
    /* BOM check. */
77


32293962
    if ((byte_count >= 3) && (*ch == (char)0xEF) && (*(ch + 1) == (char)0xBB) && (*(ch + 2) == (char)0xBF))
78
    {
79
        /* It is BOM. Skip it. */
80
1
        ch += 3;
81
1
        byte_count -= 3;
82
    }
83
84
32293962
    if (byte_count == 0)
85
    {
86
        /* Zero length string. Return error. */
87
7
        if (glyph_value)
88
        {
89
1
            *glyph_value = 0;
90
        }
91
92
7
        if (glyph_len)
93
        {
94
6
            *glyph_len = 0;
95
        }
96
7
        return GX_INVALID_VALUE;
97
    }
98
99
    /* Reset glyph length to 1. */
100
32293955
    len = 1;
101
102
    /* Check the first byte */
103
32293955
    if ((*ch & 0x80) == 0)
104
    {
105
106
32113647
        utf8_str -> gx_string_ptr = ch + 1;
107
32113647
        utf8_str -> gx_string_length -= 1;
108
109
        /* One byte glyph. */
110
32113647
        if (glyph_value)
111
        {
112
30737550
            *glyph_value = (*ch & ~0x80) & 0xFF;
113
        }
114
115
32113647
        if (glyph_len)
116
        {
117
1410684
            *glyph_len = 1;
118
        }
119
120
32113647
        return GX_SUCCESS;
121
    }
122
180308
    else if ((*ch & 0xE0) == 0xC0)
123
    {
124
125
        /* Two bytes glyph. */
126
9099
        bytes = 2;
127
9099
        value = (*ch & ~0xE0) & 0xFF;
128
    }
129
171209
    else if ((*ch & 0xF0) == 0xE0)
130
    {
131
132
        /* Three bytes glyph. */
133
171142
        bytes = 3;
134
171142
        value = (*ch & ~0xF0) & 0xFF;
135
    }
136
67
    else if ((*ch & 0xF8) == 0xF0)
137
    {
138
139
        /* Four bytes glyph. */
140
1
        bytes = 4;
141
1
        value = (*ch & ~0xF8) & 0xFF;
142
    }
143
66
    else if ((*ch & 0xFC) == 0xF8)
144
    {
145
146
        /* Five bytes glyph. */
147
1
        bytes = 5;
148
1
        value = (*ch & ~0xFC) & 0xFF;
149
    }
150
65
    else if ((*ch & 0xFE) == 0xFC)
151
    {
152
153
        /* Six bytes glyph. */
154
4
        bytes = 6;
155
4
        value = (*ch & ~0xFE) & 0xFF;
156
    }
157
    else
158
    {
159
        /* Not a valid utf8 glyph. */
160
61
        utf8_str -> gx_string_ptr = ch + 1;
161
61
        utf8_str -> gx_string_length -= 1;
162
163
61
        if (glyph_value)
164
        {
165
55
            *glyph_value = 0;
166
        }
167
168
61
        if (glyph_len)
169
        {
170
6
            *glyph_len = 1;
171
        }
172
173
61
        return GX_INVALID_VALUE;
174
    }
175
176
180247
    if (byte_count < bytes)
177
    {
178
        /* Not a valid utf8 glyph. */
179
4
        if (glyph_value)
180
        {
181
1
            *glyph_value = 0;
182
        }
183
184
4
        if (glyph_len)
185
        {
186
3
            *glyph_len = bytes;
187
        }
188
4
        utf8_str -> gx_string_length -= bytes;
189
190
4
        return GX_INVALID_VALUE;
191
    }
192
193
531620
    while (len < bytes)
194
    {
195
351383
        ch++;
196
351383
        len++;
197
198
351383
        if ((*ch & 0xC0) != 0x80)
199
        {
200
201
            /* Not a valid utf8 glyph. */
202
6
            if (glyph_len)
203
            {
204
1
                *glyph_len = len;
205
            }
206
207
6
            utf8_str -> gx_string_ptr = ch;
208
6
            utf8_str -> gx_string_length -= len;
209
210
6
            return GX_INVALID_VALUE;
211
        }
212
213
351377
        value = (GX_CHAR_CODE)(value << 6);
214
351377
        value = (GX_CHAR_CODE)(value + ((*ch & ~0xC0) & 0xFF));
215
    }
216
217
180237
    if (glyph_value)
218
    {
219
172699
        *glyph_value = value;
220
    }
221
222
180237
    if (glyph_len)
223
    {
224
7544
        *glyph_len = len;
225
    }
226
227
180237
    utf8_str -> gx_string_ptr = ch + 1;
228
180237
    utf8_str -> gx_string_length -= len;
229
230
180237
    return GX_SUCCESS;
231
}
232
233
#endif /* GX_UTF8_SUPPORT */
234