Scan string directly in n_value

This commit is contained in:
2025-06-21 21:17:12 -04:00
parent 229a68bfdd
commit fa0cc1a970

View File

@@ -780,6 +780,31 @@ inline PRESERVE_NONE WeaselJsonStatus n_number(Parser3 *self, char *buf,
MUSTTAIL return Parser3::keepGoing(self, buf, bufEnd); MUSTTAIL return Parser3::keepGoing(self, buf, bufEnd);
} }
// Advance buf until double quote, backslash, invalid utf8, or codepoint <
// 0x20
inline PRESERVE_NONE WeaselJsonStatus n_scan_string(Parser3 *self, char *&buf,
char *bufEnd) {
const auto before = buf;
buf = (char *)self->strDfa.scan(buf, bufEnd);
int len = buf - before;
if (self->writeBuf != before) {
memmove(self->writeBuf, before, len);
}
self->writeBuf += len;
if (buf == bufEnd) {
self->flushString(false);
return WeaselJson_AGAIN;
}
if (!self->strDfa.accept()) [[unlikely]] {
return WeaselJson_REJECT;
}
return WeaselJson_OK;
}
inline PRESERVE_NONE WeaselJsonStatus n_value(Parser3 *self, char *buf, inline PRESERVE_NONE WeaselJsonStatus n_value(Parser3 *self, char *buf,
char *bufEnd) { char *bufEnd) {
assert(bufEnd - buf != 0); assert(bufEnd - buf != 0);
@@ -811,10 +836,30 @@ inline PRESERVE_NONE WeaselJsonStatus n_value(Parser3 *self, char *buf,
self->dataBegin = self->writeBuf = buf; self->dataBegin = self->writeBuf = buf;
self->pop(); self->pop();
self->strDfa.reset(); self->strDfa.reset();
if (auto s = self->push({N_STRING2})) { if (auto s = n_scan_string(self, buf, bufEnd)) {
if (s == WeaselJson_AGAIN) {
if (auto s2 = self->push({N_STRING2})) {
return s2;
}
}
return s; return s;
} }
break; {
switch (*buf) {
case '"':
self->flushString(true);
++buf;
MUSTTAIL return Parser3::keepGoing(self, buf, bufEnd);
case '\\':
++buf;
if (auto s = self->push({N_STRING_FOLLOWING_ESCAPE})) {
return s;
}
MUSTTAIL return Parser3::keepGoing(self, buf, bufEnd);
default:
return WeaselJson_REJECT;
}
}
case '0': case '0':
case '1': case '1':
case '2': case '2':
@@ -1027,25 +1072,9 @@ inline PRESERVE_NONE WeaselJsonStatus n_string(Parser3 *self, char *buf,
inline PRESERVE_NONE WeaselJsonStatus n_string2(Parser3 *self, char *buf, inline PRESERVE_NONE WeaselJsonStatus n_string2(Parser3 *self, char *buf,
char *bufEnd) { char *bufEnd) {
const auto before = buf; if (auto s = n_scan_string(self, buf, bufEnd)) {
return s;
// Advance buf until double quote, backslash, invalid utf8, or codepoint <
// 0x20
buf = (char *)self->strDfa.scan(buf, bufEnd);
int len = buf - before;
memmove(self->writeBuf, before, len);
self->writeBuf += len;
if (buf == bufEnd) {
self->flushString(false);
return WeaselJson_AGAIN;
} }
if (!self->strDfa.accept()) [[unlikely]] {
return WeaselJson_REJECT;
}
switch (*buf) { switch (*buf) {
case '"': case '"':
self->flushString(true); self->flushString(true);