| 103 | } |
| 104 | |
| 105 | bool IsStructurallyValid(absl::string_view str) { |
| 106 | const char *begin = str.data(); |
| 107 | const char *end = str.data() + str.size(); |
| 108 | size_t mblen = 0; |
| 109 | while (begin < end) { |
| 110 | const char32 c = DecodeUTF8(begin, end, &mblen); |
| 111 | if (c == kUnicodeError && mblen != 3) return false; |
| 112 | if (!IsValidCodepoint(c)) return false; |
| 113 | begin += mblen; |
| 114 | } |
| 115 | return true; |
| 116 | } |
| 117 | |
| 118 | size_t EncodeUTF8(char32 c, char *output) { |
| 119 | if (c <= 0x7F) { |