| 177 | |
| 178 | template <typename InputStream, typename OutputStream> |
| 179 | static bool Validate(InputStream& is, OutputStream& os) { |
| 180 | #define COPY() os.Put(c = is.Take()) |
| 181 | #define TRANS(mask) result &= ((GetRange(static_cast<unsigned char>(c)) & mask) != 0) |
| 182 | #define TAIL() COPY(); TRANS(0x70) |
| 183 | Ch c; |
| 184 | COPY(); |
| 185 | if (!(c & 0x80)) |
| 186 | return true; |
| 187 | |
| 188 | bool result = true; |
| 189 | switch (GetRange(static_cast<unsigned char>(c))) { |
| 190 | case 2: TAIL(); return result; |
| 191 | case 3: TAIL(); TAIL(); return result; |
| 192 | case 4: COPY(); TRANS(0x50); TAIL(); return result; |
| 193 | case 5: COPY(); TRANS(0x10); TAIL(); TAIL(); return result; |
| 194 | case 6: TAIL(); TAIL(); TAIL(); return result; |
| 195 | case 10: COPY(); TRANS(0x20); TAIL(); return result; |
| 196 | case 11: COPY(); TRANS(0x60); TAIL(); TAIL(); return result; |
| 197 | default: return false; |
| 198 | } |
| 199 | #undef COPY |
| 200 | #undef TRANS |
| 201 | #undef TAIL |
| 202 | } |
| 203 | |
| 204 | static unsigned char GetRange(unsigned char c) { |
| 205 | // Referring to DFA of http://bjoern.hoehrmann.de/utf-8/decoder/dfa/ |
no test coverage detected