| 392 | } |
| 393 | |
| 394 | size_t DecodeUTF8(const void* bytes, size_t length, char32_t* ch) |
| 395 | { |
| 396 | const u8* s = reinterpret_cast<const u8*>(bytes); |
| 397 | if (s[0] < 0x80) |
| 398 | { |
| 399 | *ch = s[0]; |
| 400 | return 1; |
| 401 | } |
| 402 | else if ((s[0] & 0xe0) == 0xc0) |
| 403 | { |
| 404 | if (length < 2) |
| 405 | goto invalid; |
| 406 | |
| 407 | *ch = static_cast<char32_t>((static_cast<u32>(s[0] & 0x1f) << 6) | (static_cast<u32>(s[1] & 0x3f) << 0)); |
| 408 | return 2; |
| 409 | } |
| 410 | else if ((s[0] & 0xf0) == 0xe0) |
| 411 | { |
| 412 | if (length < 3) |
| 413 | goto invalid; |
| 414 | |
| 415 | *ch = static_cast<char32_t>((static_cast<u32>(s[0] & 0x0f) << 12) | (static_cast<u32>(s[1] & 0x3f) << 6) | |
| 416 | (static_cast<u32>(s[2] & 0x3f) << 0)); |
| 417 | return 3; |
| 418 | } |
| 419 | else if ((s[0] & 0xf8) == 0xf0 && (s[0] <= 0xf4)) |
| 420 | { |
| 421 | if (length < 4) |
| 422 | goto invalid; |
| 423 | |
| 424 | *ch = static_cast<char32_t>((static_cast<u32>(s[0] & 0x07) << 18) | (static_cast<u32>(s[1] & 0x3f) << 12) | |
| 425 | (static_cast<u32>(s[2] & 0x3f) << 6) | (static_cast<u32>(s[3] & 0x3f) << 0)); |
| 426 | return 4; |
| 427 | } |
| 428 | |
| 429 | invalid: |
| 430 | *ch = 0xFFFFFFFFu; |
| 431 | return 1; |
| 432 | } |
| 433 | |
| 434 | size_t DecodeUTF8(const std::string_view str, size_t offset, char32_t* ch) |
| 435 | { |
no test coverage detected