diff --git a/src/parser3.h b/src/parser3.h index 659b5c4..bbbcde6 100644 --- a/src/parser3.h +++ b/src/parser3.h @@ -56,11 +56,7 @@ struct Parser3 { reset(); } - [[nodiscard]] WeaselJsonStatus parse(char *buf, int len) { - complete = len == 0; - this->dataBegin = this->writeBuf = buf; - return keepGoing(this, buf, buf + len); - } + [[nodiscard]] WeaselJsonStatus parse(char *buf, int len); void flushNumber(bool done, char *buf) { int len = buf - dataBegin; @@ -104,7 +100,6 @@ struct Parser3 { void reset() { stackPtr = stack(); - complete = false; std::ignore = push({N_VALUE, N_WHITESPACE, T_EOF}); } @@ -119,7 +114,6 @@ struct Parser3 { uint32_t utf16Surrogate; uint32_t minCodepoint; int const stackSize; - bool complete; NumDfa numDfa; Utf8Dfa strDfa; }; @@ -158,8 +152,9 @@ inline PRESERVE_NONE WeaselJsonStatus n_whitespace(Parser3 *self, char *buf, inline PRESERVE_NONE WeaselJsonStatus n_number(Parser3 *self, char *buf, char *bufEnd) { + bool complete = buf == bufEnd; buf = (char *)self->numDfa.scan(buf, bufEnd); - if (buf == bufEnd && !self->complete) { + if (buf == bufEnd && !complete) { self->flushNumber(false, buf); return WeaselJson_AGAIN; } @@ -346,6 +341,9 @@ inline PRESERVE_NONE WeaselJsonStatus n_value(Parser3 *self, char *buf, default: [[unlikely]] return WeaselJson_REJECT; } + if (buf == bufEnd) { + return WeaselJson_AGAIN; + } MUSTTAIL return Parser3::keepGoing(self, buf, bufEnd); } @@ -362,6 +360,9 @@ inline PRESERVE_NONE WeaselJsonStatus n_object2(Parser3 *self, char *buf, ++buf; self->pop(); self->callbacks->on_end_object(self->userdata); + if (buf == bufEnd) { + return WeaselJson_AGAIN; + } MUSTTAIL return Parser3::keepGoing(self, buf, bufEnd); case '"': ++buf; @@ -371,6 +372,9 @@ inline PRESERVE_NONE WeaselJsonStatus n_object2(Parser3 *self, char *buf, if (auto s = self->push({N_STRING2, T_COLON, N_VALUE, N_OBJECT3})) { return s; } + if (buf == bufEnd) { + return WeaselJson_AGAIN; + } MUSTTAIL return Parser3::keepGoing(self, buf, bufEnd); default: [[unlikely]] return WeaselJson_REJECT; @@ -390,6 +394,9 @@ inline PRESERVE_NONE WeaselJsonStatus n_object3(Parser3 *self, char *buf, ++buf; self->pop(); self->callbacks->on_end_object(self->userdata); + if (buf == bufEnd) { + return WeaselJson_AGAIN; + } MUSTTAIL return Parser3::keepGoing(self, buf, bufEnd); case ',': ++buf; @@ -397,6 +404,9 @@ inline PRESERVE_NONE WeaselJsonStatus n_object3(Parser3 *self, char *buf, if (auto s = self->push({N_STRING, T_COLON, N_VALUE, N_OBJECT3})) { return s; } + if (buf == bufEnd) { + return WeaselJson_AGAIN; + } MUSTTAIL return Parser3::keepGoing(self, buf, bufEnd); default: [[unlikely]] return WeaselJson_REJECT; @@ -416,6 +426,9 @@ inline PRESERVE_NONE WeaselJsonStatus n_array2(Parser3 *self, char *buf, ++buf; self->pop(); self->callbacks->on_end_array(self->userdata); + if (buf == bufEnd) { + return WeaselJson_AGAIN; + } MUSTTAIL return Parser3::keepGoing(self, buf, bufEnd); default: self->pop(); @@ -439,6 +452,9 @@ inline PRESERVE_NONE WeaselJsonStatus n_array3(Parser3 *self, char *buf, ++buf; self->pop(); self->callbacks->on_end_array(self->userdata); + if (buf == bufEnd) { + return WeaselJson_AGAIN; + } MUSTTAIL return Parser3::keepGoing(self, buf, bufEnd); case ',': ++buf; @@ -446,6 +462,9 @@ inline PRESERVE_NONE WeaselJsonStatus n_array3(Parser3 *self, char *buf, if (auto s = self->push({N_VALUE, N_ARRAY3})) { return s; } + if (buf == bufEnd) { + return WeaselJson_AGAIN; + } MUSTTAIL return Parser3::keepGoing(self, buf, bufEnd); default: [[unlikely]] return WeaselJson_REJECT; @@ -470,6 +489,9 @@ inline PRESERVE_NONE WeaselJsonStatus n_string(Parser3 *self, char *buf, if (auto s = self->push({N_STRING2})) { return s; } + if (buf == bufEnd) { + return WeaselJson_AGAIN; + } MUSTTAIL return Parser3::keepGoing(self, buf, bufEnd); } @@ -789,6 +811,9 @@ inline PRESERVE_NONE WeaselJsonStatus n_true(Parser3 *self, char *buf, ++buf; self->pop(); self->callbacks->on_true_literal(self->userdata); + if (buf == bufEnd) { + return WeaselJson_AGAIN; + } MUSTTAIL return Parser3::keepGoing(self, buf, bufEnd); } else [[unlikely]] { return WeaselJson_REJECT; @@ -804,6 +829,9 @@ inline PRESERVE_NONE WeaselJsonStatus n_false(Parser3 *self, char *buf, ++buf; self->pop(); self->callbacks->on_false_literal(self->userdata); + if (buf == bufEnd) { + return WeaselJson_AGAIN; + } MUSTTAIL return Parser3::keepGoing(self, buf, bufEnd); } else [[unlikely]] { return WeaselJson_REJECT; @@ -819,6 +847,9 @@ inline PRESERVE_NONE WeaselJsonStatus n_null(Parser3 *self, char *buf, ++buf; self->pop(); self->callbacks->on_null_literal(self->userdata); + if (buf == bufEnd) { + return WeaselJson_AGAIN; + } MUSTTAIL return Parser3::keepGoing(self, buf, bufEnd); } else [[unlikely]] { return WeaselJson_REJECT; @@ -839,18 +870,21 @@ inline PRESERVE_NONE WeaselJsonStatus singleChar(Parser3 *self, char *buf, if (*buf == kChar) { ++buf; self->pop(); + if (buf == bufEnd) { + return WeaselJson_AGAIN; + } MUSTTAIL return Parser3::keepGoing(self, buf, bufEnd); } else [[unlikely]] { return WeaselJson_REJECT; } } -inline PRESERVE_NONE WeaselJsonStatus t_eof(Parser3 *self, char *buf, +inline PRESERVE_NONE WeaselJsonStatus t_eof(Parser3 *, char *buf, char *bufEnd) { if (buf != bufEnd) [[unlikely]] { return WeaselJson_REJECT; } - return self->complete ? WeaselJson_OK : WeaselJson_AGAIN; + return WeaselJson_OK; } constexpr inline struct ContinuationTable { @@ -918,14 +952,14 @@ constexpr inline struct ContinuationTable { const char *symbolNames[N_SYMBOL_COUNT]{}; } symbolTables; +inline WeaselJsonStatus Parser3::parse(char *buf, int len) { + this->dataBegin = this->writeBuf = buf; + return symbolTables.continuations[top()](this, buf, buf + len); +} + inline PRESERVE_NONE WeaselJsonStatus Parser3::keepGoing(Parser3 *self, char *buf, char *bufEnd) { - if (bufEnd - buf == 0) { - if (!self->complete) { - return WeaselJson_AGAIN; - } - } // printf("%s\n", symbolTables.symbolNames[self->top()]); MUSTTAIL return symbolTables.continuations[self->top()](self, buf, bufEnd); }