return true if s[0..n-1] contains a \0 (NUL) or a non-displayable invalid UTF-8 sequence
| 780 | |
| 781 | // return true if s[0..n-1] contains a \0 (NUL) or a non-displayable invalid UTF-8 sequence |
| 782 | bool is_binary(const char *s, size_t n) |
| 783 | { |
| 784 | const char *e = s + n; |
| 785 | while (s < e) |
| 786 | { |
| 787 | int8_t c; |
| 788 | while (s < e && (c = static_cast<int8_t>(*s)) > 0) |
| 789 | ++s; |
| 790 | if (s++ >= e) |
| 791 | break; |
| 792 | // U+0080 ~ U+07ff <-> c2 80 ~ df bf (disallow 2 byte overlongs) |
| 793 | if (c < -62 || c > -12 || s >= e || (*s++ & 0xc0) != 0x80) |
| 794 | return true; |
| 795 | // U+0800 ~ U+ffff <-> e0 a0 80 ~ ef bf bf (quick but allows surrogates and 3 byte overlongs) |
| 796 | if (c >= -32 && (s >= e || (*s++ & 0xc0) != 0x80)) |
| 797 | return true; |
| 798 | // U+010000 ~ U+10ffff <-> f0 90 80 80 ~ f4 8f bf bf (quick but allows 4 byte overlongs) |
| 799 | if (c >= -16 && (s >= e || (*s++ & 0xc0) != 0x80)) |
| 800 | return true; |
| 801 | } |
| 802 | return false; |
| 803 | } |
| 804 | |
| 805 | // prime 61 mod 2^16 file indexing hash function |
| 806 | inline uint32_t indexhash(uint32_t h, uint8_t b) |