| 109 | extern const wchar32 BROKEN_RUNE = 0xFFFD; |
| 110 | |
| 111 | static const char* SkipUTF8Chars(const char* begin, const char* end, size_t numChars) { |
| 112 | const unsigned char* uEnd = reinterpret_cast<const unsigned char*>(end); |
| 113 | while (begin != end && numChars > 0) { |
| 114 | const unsigned char* uBegin = reinterpret_cast<const unsigned char*>(begin); |
| 115 | size_t runeLen; |
| 116 | if (GetUTF8CharLen(runeLen, uBegin, uEnd) != RECODE_OK) { |
| 117 | ythrow yexception() << "invalid UTF-8 char"; |
| 118 | } |
| 119 | begin += runeLen; |
| 120 | Y_ASSERT(begin <= end); |
| 121 | --numChars; |
| 122 | } |
| 123 | return begin; |
| 124 | } |
| 125 | |
| 126 | TStringBuf SubstrUTF8(const TStringBuf str Y_LIFETIME_BOUND, size_t pos, size_t len) { |
| 127 | const char* start = SkipUTF8Chars(str.begin(), str.end(), pos); |
no test coverage detected