Rev 4212 | Rev 4224 | Go to most recent revision | Show entire file | Ignore whitespace | Details | Blame | Last modification | View Log | RSS feed
| Rev 4212 | Rev 4223 | ||
|---|---|---|---|
| Line 107... | Line 107... | ||
| 107 | #include <arch/asm.h> |
107 | #include <arch/asm.h> |
| 108 | #include <arch.h> |
108 | #include <arch.h> |
| 109 | #include <errno.h> |
109 | #include <errno.h> |
| 110 | #include <align.h> |
110 | #include <align.h> |
| 111 | 111 | ||
| 112 | char invalch = '?'; |
- | |
| 113 | - | ||
| 114 | /** Byte mask consisting of lowest @n bits (out of 8) */ |
112 | /** Byte mask consisting of lowest @n bits (out of 8) */ |
| 115 | #define LO_MASK_8(n) ((uint8_t) ((1 << (n)) - 1)) |
113 | #define LO_MASK_8(n) ((uint8_t) ((1 << (n)) - 1)) |
| 116 | 114 | ||
| 117 | /** Byte mask consisting of lowest @n bits (out of 32) */ |
115 | /** Byte mask consisting of lowest @n bits (out of 32) */ |
| 118 | #define LO_MASK_32(n) ((uint32_t) ((1 << (n)) - 1)) |
116 | #define LO_MASK_32(n) ((uint32_t) ((1 << (n)) - 1)) |
| Line 132... | Line 130... | ||
| 132 | * |
130 | * |
| 133 | * @param str String (not necessarily NULL-terminated). |
131 | * @param str String (not necessarily NULL-terminated). |
| 134 | * @param offset Byte offset in string where to start decoding. |
132 | * @param offset Byte offset in string where to start decoding. |
| 135 | * @param size Size of the string (in bytes). |
133 | * @param size Size of the string (in bytes). |
| 136 | * |
134 | * |
| 137 | * @return Value of decoded character, invalch on decoding error or |
135 | * @return Value of decoded character, U_SPECIAL on decoding error or |
| 138 | * NULL if attempt to decode beyond @a size. |
136 | * NULL if attempt to decode beyond @a size. |
| 139 | * |
137 | * |
| 140 | */ |
138 | */ |
| 141 | wchar_t str_decode(const char *str, size_t *offset, size_t size) |
139 | wchar_t str_decode(const char *str, size_t *offset, size_t size) |
| 142 | { |
140 | { |
| Line 167... | Line 165... | ||
| 167 | /* 11110xxx 10xxxxxx 10xxxxxx 10xxxxxx */ |
165 | /* 11110xxx 10xxxxxx 10xxxxxx 10xxxxxx */ |
| 168 | b0_bits = 3; |
166 | b0_bits = 3; |
| 169 | cbytes = 3; |
167 | cbytes = 3; |
| 170 | } else { |
168 | } else { |
| 171 | /* 10xxxxxx -- unexpected continuation byte */ |
169 | /* 10xxxxxx -- unexpected continuation byte */ |
| 172 | return invalch; |
170 | return U_SPECIAL; |
| 173 | } |
171 | } |
| 174 | 172 | ||
| 175 | if (*offset + cbytes > size) |
173 | if (*offset + cbytes > size) |
| 176 | return invalch; |
174 | return U_SPECIAL; |
| 177 | 175 | ||
| 178 | wchar_t ch = b0 & LO_MASK_8(b0_bits); |
176 | wchar_t ch = b0 & LO_MASK_8(b0_bits); |
| 179 | 177 | ||
| 180 | /* Decode continuation bytes */ |
178 | /* Decode continuation bytes */ |
| 181 | while (cbytes > 0) { |
179 | while (cbytes > 0) { |
| 182 | uint8_t b = (uint8_t) str[(*offset)++]; |
180 | uint8_t b = (uint8_t) str[(*offset)++]; |
| 183 | 181 | ||
| 184 | /* Must be 10xxxxxx */ |
182 | /* Must be 10xxxxxx */ |
| 185 | if ((b & 0xc0) != 0x80) |
183 | if ((b & 0xc0) != 0x80) |
| 186 | return invalch; |
184 | return U_SPECIAL; |
| 187 | 185 | ||
| 188 | /* Shift data bits to ch */ |
186 | /* Shift data bits to ch */ |
| 189 | ch = (ch << CONT_BITS) | (wchar_t) (b & LO_MASK_8(CONT_BITS)); |
187 | ch = (ch << CONT_BITS) | (wchar_t) (b & LO_MASK_8(CONT_BITS)); |
| 190 | cbytes--; |
188 | cbytes--; |
| 191 | } |
189 | } |