| 74 | } |
| 75 | |
| 76 | int32_t UTF::NextUTF8(const char** ptr, const char* end) { |
| 77 | if (!ptr || !end) { |
| 78 | return -1; |
| 79 | } |
| 80 | const uint8_t* p = (const uint8_t*)*ptr; |
| 81 | if (!p || p >= (const uint8_t*)end) { |
| 82 | return next_fail(ptr, end); |
| 83 | } |
| 84 | int c = *p; |
| 85 | int hic = c << 24; |
| 86 | |
| 87 | if (!utf8_type_is_valid_leading_byte(utf8_byte_type((uint8_t)c))) { |
| 88 | return next_fail(ptr, end); |
| 89 | } |
| 90 | if (hic < 0) { |
| 91 | uint32_t mask = (uint32_t)~0x3F; |
| 92 | hic = left_shift(hic, 1); |
| 93 | do { |
| 94 | ++p; |
| 95 | if (p >= (const uint8_t*)end) { |
| 96 | return next_fail(ptr, end); |
| 97 | } |
| 98 | uint8_t nextByte = *p; |
| 99 | if (!utf8_byte_is_continuation(nextByte)) { |
| 100 | return next_fail(ptr, end); |
| 101 | } |
| 102 | c = (c << 6) | (nextByte & 0x3F); |
| 103 | mask <<= 5; |
| 104 | } while ((hic = left_shift(hic, 1)) < 0); |
| 105 | c &= ~mask; |
| 106 | } |
| 107 | *ptr = (char*)p + 1; |
| 108 | return c; |
| 109 | } |
| 110 | |
| 111 | std::string UTF::ToUTF8(int32_t unichar) { |
| 112 | if ((uint32_t)unichar > 0x10FFFF) { |
nothing calls this directly
no test coverage detected