| 205 | |
| 206 | template <typename BufferedByteReader> |
| 207 | bool Utf8IsValidImpl(BufferedByteReader* reader) { |
| 208 | while (reader->HasRemaining()) { |
| 209 | const auto b = static_cast<uint8_t>(reader->Read()); |
| 210 | if (b < kUtf8RuneSelf) { |
| 211 | continue; |
| 212 | } |
| 213 | const auto leading = kLeading[b]; |
| 214 | if (leading == kXX) { |
| 215 | return false; |
| 216 | } |
| 217 | const auto size = static_cast<size_t>(leading & 7) - 1; |
| 218 | if (size > reader->Remaining()) { |
| 219 | return false; |
| 220 | } |
| 221 | const absl::string_view segment = reader->Peek(size); |
| 222 | const auto& accept = kAccept[leading >> 4]; |
| 223 | if (static_cast<uint8_t>(segment[0]) < accept.first || |
| 224 | static_cast<uint8_t>(segment[0]) > accept.second) { |
| 225 | return false; |
| 226 | } else if (size == 1) { |
| 227 | } else if (static_cast<uint8_t>(segment[1]) < kLow || |
| 228 | static_cast<uint8_t>(segment[1]) > kHigh) { |
| 229 | return false; |
| 230 | } else if (size == 2) { |
| 231 | } else if (static_cast<uint8_t>(segment[2]) < kLow || |
| 232 | static_cast<uint8_t>(segment[2]) > kHigh) { |
| 233 | return false; |
| 234 | } |
| 235 | reader->Advance(size); |
| 236 | } |
| 237 | return true; |
| 238 | } |
| 239 | |
| 240 | template <typename BufferedByteReader> |
| 241 | size_t Utf8CodePointCountImpl(BufferedByteReader* reader) { |
no test coverage detected