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 |