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 | } |