Rev 4196 | Rev 4199 | Go to most recent revision | Show entire file | Ignore whitespace | Details | Blame | Last modification | View Log | RSS feed
| Rev 4196 | Rev 4198 | ||
|---|---|---|---|
| Line 42... | Line 42... | ||
| 42 | #include <arch.h> |
42 | #include <arch.h> |
| 43 | #include <console/kconsole.h> |
43 | #include <console/kconsole.h> |
| 44 | 44 | ||
| 45 | char invalch = '?'; |
45 | char invalch = '?'; |
| 46 | 46 | ||
| 47 | /** Byte mask consisting of bits 0 - (@n - 1) */ |
47 | /** Byte mask consisting of lowest @n bits (out of eight). */ |
| 48 | #define LO_MASK_8(n) ((uint8_t)((1 << (n)) - 1)) |
48 | #define LO_MASK_8(n) ((uint8_t)((1 << (n)) - 1)) |
| 49 | 49 | ||
| - | 50 | /** Byte mask consisting of lowest @n bits (out of 32). */ |
|
| - | 51 | #define LO_MASK_32(n) ((uint32_t)((1 << (n)) - 1)) |
|
| - | 52 | ||
| - | 53 | /** Byte mask consisting of highest @n bits (out of eight). */ |
|
| - | 54 | #define HI_MASK_8(n) (~LO_MASK_8(8 - (n))) |
|
| - | 55 | ||
| 50 | /** Number of data bits in a UTF-8 continuation byte. */ |
56 | /** Number of data bits in a UTF-8 continuation byte. */ |
| 51 | #define CONT_BITS 6 |
57 | #define CONT_BITS 6 |
| 52 | 58 | ||
| 53 | /** Decode a single UTF-8 character from a NULL-terminated string. |
59 | /** Decode a single UTF-8 character from a NULL-terminated string. |
| 54 | * |
60 | * |
| Line 142... | Line 148... | ||
| 142 | * Unicode code point. |
148 | * Unicode code point. |
| 143 | * |
149 | * |
| 144 | */ |
150 | */ |
| 145 | bool utf8_encode(const wchar_t ch, char *str, index_t *index, index_t limit) |
151 | bool utf8_encode(const wchar_t ch, char *str, index_t *index, index_t limit) |
| 146 | { |
152 | { |
| - | 153 | uint32_t cc; /* Unsigned version of ch. */ |
|
| - | 154 | ||
| - | 155 | int cbytes; /* Number of continuation bytes. */ |
|
| - | 156 | int b0_bits; /* Number of data bits in first byte. */ |
|
| - | 157 | int i; |
|
| - | 158 | ||
| 147 | if (*index > limit) |
159 | if (*index > limit) |
| 148 | return false; |
160 | return false; |
| 149 | 161 | ||
| 150 | if ((ch >= 0) && (ch <= 127)) { |
- | |
| 151 | /* Plain ASCII (code points 0 .. 127) */ |
- | |
| 152 | str[*index] = ch & 0x7f; |
162 | if (ch < 0) |
| 153 | return true; |
163 | return false; |
| 154 | } |
164 | |
| - | 165 | /* Bit operations should only be done on unsigned numbers. */ |
|
| - | 166 | cc = (uint32_t) ch; |
|
| 155 | 167 | ||
| 156 | if ((ch >= 128) && (ch <= 2047)) { |
168 | /* Determine how many continuation bytes are needed. */ |
| 157 | /* Code points 128 .. 2047 */ |
169 | if ((cc & ~LO_MASK_32(7)) == 0) { |
| 158 | if (*index + 1 > limit) |
170 | b0_bits = 7; |
| 159 | return false; |
171 | cbytes = 0; |
| 160 | - | ||
| 161 | str[*index] = 0xc0 | ((ch >> 6) & 0x1f); |
172 | } else if ((cc & ~LO_MASK_32(11)) == 0) { |
| 162 | (*index)++; |
173 | b0_bits = 5; |
| 163 | str[*index] = 0x80 | (ch & 0x3f); |
- | |
| 164 | return true; |
174 | cbytes = 1; |
| 165 | } |
- | |
| 166 | - | ||
| 167 | if ((ch >= 2048) && (ch <= 65535)) { |
175 | } else if ((cc & ~LO_MASK_32(16)) == 0) { |
| 168 | /* Code points 2048 .. 65535 */ |
- | |
| 169 | if (*index + 2 > limit) |
176 | b0_bits = 4; |
| 170 | return false; |
177 | cbytes = 2; |
| 171 | - | ||
| 172 | str[*index] = 0xe0 | ((ch >> 12) & 0x0f); |
178 | } else if ((cc & ~LO_MASK_32(21)) == 0) { |
| 173 | (*index)++; |
179 | b0_bits = 3; |
| 174 | str[*index] = 0x80 | ((ch >> 6) & 0x3f); |
180 | cbytes = 3; |
| 175 | (*index)++; |
181 | } else { |
| 176 | str[*index] = 0x80 | (ch & 0x3f); |
182 | /* Codes longer than 21 bits are not supported. */ |
| 177 | return true; |
183 | return false; |
| 178 | } |
184 | } |
| 179 | 185 | ||
| 180 | if ((ch >= 65536) && (ch <= 1114111)) { |
- | |
| 181 | /* Code points 65536 .. 1114111 */ |
186 | /* Check for available space in buffer. */ |
| 182 | if (*index + 3 > limit) |
187 | if (*index + cbytes > limit) |
| 183 | return false; |
188 | return false; |
| 184 | 189 | ||
| 185 | str[*index] = 0xf0 | ((ch >> 18) & 0x07); |
- | |
| 186 | (*index)++; |
- | |
| 187 | str[*index] = 0x80 | ((ch >> 12) & 0x3f); |
190 | /* Encode continuation bytes. */ |
| 188 | (*index)++; |
- | |
| 189 | str[*index] = 0x80 | ((ch >> 6) & 0x3f); |
191 | for (i = cbytes; i > 0; --i) { |
| 190 | (*index)++; |
- | |
| 191 | str[*index] = 0x80 | (ch & 0x3f); |
192 | str[*index + i] = 0x80 | (cc & LO_MASK_32(CONT_BITS)); |
| 192 | return true; |
193 | cc = cc >> CONT_BITS; |
| 193 | } |
194 | } |
| - | 195 | ||
| - | 196 | /* Encode first byte. */ |
|
| - | 197 | str[*index] = (cc & LO_MASK_32(b0_bits)) | HI_MASK_8(8 - b0_bits - 1); |
|
| - | 198 | ||
| - | 199 | /* Advance index. */ |
|
| - | 200 | *index += cbytes; |
|
| 194 | 201 | ||
| 195 | return false; |
202 | return true; |
| 196 | } |
203 | } |
| 197 | 204 | ||
| 198 | /** Get bytes used by UTF-8 characters. |
205 | /** Get bytes used by UTF-8 characters. |
| 199 | * |
206 | * |
| 200 | * Get the number of bytes (count of plain characters) which |
207 | * Get the number of bytes (count of plain characters) which |