mirror of
https://github.com/simdjson/simdjson
synced 2026-06-08 17:27:07 +00:00
Tweaking.
This commit is contained in:
@@ -243,6 +243,93 @@ WARN_UNUSED error_code implementation::minify(const uint8_t *buf, size_t len, ui
|
||||
// for fear of aliasing
|
||||
return SUCCESS;
|
||||
}
|
||||
WARN_UNUSED bool implementation::validate_utf8(const char *buf, size_t len) const noexcept {
|
||||
const uint8_t *data = (const uint8_t *)buf;
|
||||
uint64_t pos = 0;
|
||||
uint64_t next_pos = 0;
|
||||
uint32_t code_point = 0;
|
||||
while (pos < len) {
|
||||
|
||||
// check of the next 8 bytes are ascii.
|
||||
next_pos = pos + 16;
|
||||
if (next_pos <=
|
||||
len) { // if it is safe to read 8 more bytes, check that they are ascii
|
||||
uint64_t v1;
|
||||
memcpy(&v1, data + pos, sizeof(uint64_t));
|
||||
uint64_t v2;
|
||||
memcpy(&v2, data + pos + sizeof(uint64_t), sizeof(uint64_t));
|
||||
uint64_t v{v1 | v2};
|
||||
if ((v & 0x8080808080808080) == 0) {
|
||||
pos = next_pos;
|
||||
continue;
|
||||
}
|
||||
}
|
||||
unsigned char byte = data[pos];
|
||||
|
||||
if (byte < 0b10000000) {
|
||||
pos++;
|
||||
continue;
|
||||
} else if ((byte & 0b11100000) == 0b11000000) {
|
||||
next_pos = pos + 2;
|
||||
if (next_pos > len) {
|
||||
return false;
|
||||
}
|
||||
if ((data[pos + 1] & 0b11000000) != 0b10000000) {
|
||||
return false;
|
||||
}
|
||||
// range check
|
||||
code_point = (byte & 0b00011111) << 6 | (data[pos + 1] & 0b00111111);
|
||||
if (code_point < 0x80 || 0x7ff < code_point) {
|
||||
return false;
|
||||
}
|
||||
} else if ((byte & 0b11110000) == 0b11100000) {
|
||||
next_pos = pos + 3;
|
||||
if (next_pos > len) {
|
||||
return false;
|
||||
}
|
||||
if ((data[pos + 1] & 0b11000000) != 0b10000000) {
|
||||
return false;
|
||||
}
|
||||
if ((data[pos + 2] & 0b11000000) != 0b10000000) {
|
||||
return false;
|
||||
}
|
||||
// range check
|
||||
code_point = (byte & 0b00001111) << 12 |
|
||||
(data[pos + 1] & 0b00111111) << 6 |
|
||||
(data[pos + 2] & 0b00111111);
|
||||
if (code_point < 0x800 || 0xffff < code_point ||
|
||||
(0xd7ff < code_point && code_point < 0xe000)) {
|
||||
return false;
|
||||
}
|
||||
} else if ((byte & 0b11111000) == 0b11110000) { // 0b11110000
|
||||
next_pos = pos + 4;
|
||||
if (next_pos > len) {
|
||||
return false;
|
||||
}
|
||||
if ((data[pos + 1] & 0b11000000) != 0b10000000) {
|
||||
return false;
|
||||
}
|
||||
if ((data[pos + 2] & 0b11000000) != 0b10000000) {
|
||||
return false;
|
||||
}
|
||||
if ((data[pos + 3] & 0b11000000) != 0b10000000) {
|
||||
return false;
|
||||
}
|
||||
// range check
|
||||
code_point =
|
||||
(byte & 0b00000111) << 18 | (data[pos + 1] & 0b00111111) << 12 |
|
||||
(data[pos + 2] & 0b00111111) << 6 | (data[pos + 3] & 0b00111111);
|
||||
if (code_point < 0xffff || 0x10ffff < code_point) {
|
||||
return false;
|
||||
}
|
||||
} else {
|
||||
// we may have a continuation
|
||||
return false;
|
||||
}
|
||||
pos = next_pos;
|
||||
}
|
||||
return true;
|
||||
}
|
||||
|
||||
} // namespace fallback
|
||||
} // namespace simdjson
|
||||
|
||||
Reference in New Issue
Block a user