Decode a single UTF-8 encoded character starting at \e p. The resulting Unicode value (in the range 0-0x10ffff) is returned, and \e len is set the number of bytes in the UTF-8 encoding (adding \e len to \e p will point at the next character). If \a p points at an illegal UTF-8 encoding, including one that would go past \e end, or where a code is uses more bytes than necess
| 234 | are ASCII. |
| 235 | */ |
| 236 | static unsigned utf8decode(const char *p, const char *end, int *len) { |
| 237 | unsigned char c = *reinterpret_cast<const unsigned char *>(p); |
| 238 | if (c < 0x80) { |
| 239 | *len = 1; |
| 240 | return c; |
| 241 | #if ERRORS_TO_CP1252 |
| 242 | } else if (c < 0xa0) { |
| 243 | *len = 1; |
| 244 | return cp1252[c - 0x80]; |
| 245 | #endif |
| 246 | } else if (c < 0xc2) { |
| 247 | goto FAIL; |
| 248 | } |
| 249 | if (p + 1 >= end || (p[1] & 0xc0) != 0x80) |
| 250 | goto FAIL; |
| 251 | if (c < 0xe0) { |
| 252 | *len = 2; |
| 253 | return ((p[0] & 0x1f) << 6) + ((p[1] & 0x3f)); |
| 254 | } else if (c == 0xe0) { |
| 255 | if ((reinterpret_cast<const unsigned char *>(p))[1] < 0xa0) |
| 256 | goto FAIL; |
| 257 | goto UTF8_3; |
| 258 | #if STRICT_RFC3629 |
| 259 | } else if (c == 0xed) { |
| 260 | // RFC 3629 says surrogate chars are illegal. |
| 261 | if ((reinterpret_cast<const unsigned char *>(p))[1] >= 0xa0) |
| 262 | goto FAIL; |
| 263 | goto UTF8_3; |
| 264 | } else if (c == 0xef) { |
| 265 | // 0xfffe and 0xffff are also illegal characters. |
| 266 | if ((reinterpret_cast<const unsigned char *>(p))[1] == 0xbf && |
| 267 | (reinterpret_cast<const unsigned char *>(p))[2] >= 0xbe) |
| 268 | goto FAIL; |
| 269 | goto UTF8_3; |
| 270 | #endif |
| 271 | } else if (c < 0xf0) { |
| 272 | UTF8_3: |
| 273 | if (p + 2 >= end || (p[2] & 0xc0) != 0x80) |
| 274 | goto FAIL; |
| 275 | *len = 3; |
| 276 | return ((p[0] & 0x0f) << 12) + ((p[1] & 0x3f) << 6) + ((p[2] & 0x3f)); |
| 277 | } else if (c == 0xf0) { |
| 278 | if ((reinterpret_cast<const unsigned char *>(p))[1] < 0x90) |
| 279 | goto FAIL; |
| 280 | goto UTF8_4; |
| 281 | } else if (c < 0xf4) { |
| 282 | UTF8_4: |
| 283 | if (p + 3 >= end || (p[2] & 0xc0) != 0x80 || (p[3] & 0xc0) != 0x80) |
| 284 | goto FAIL; |
| 285 | *len = 4; |
| 286 | #if STRICT_RFC3629 |
| 287 | // RFC 3629 says all codes ending in fffe or ffff are illegal: |
| 288 | if ((p[1] & 0xf) == 0xf && |
| 289 | (reinterpret_cast<const unsigned char *>(p))[2] == 0xbf && |
| 290 | (reinterpret_cast<const unsigned char *>(p))[3] >= 0xbe) |
| 291 | goto FAIL; |
| 292 | #endif |
| 293 | return ((p[0] & 0x07) << 18) + ((p[1] & 0x3f) << 12) + |