Prepare for streaming interface
This commit is contained in:
61
src/test.cpp
61
src/test.cpp
@@ -415,15 +415,30 @@ private:
|
|||||||
// Table-based ll(1) parser that doesn't handle escaping and treats numbers as
|
// Table-based ll(1) parser that doesn't handle escaping and treats numbers as
|
||||||
// [0-9.]+. Could be adapted to have a streaming interface. Uses O(1) memory.
|
// [0-9.]+. Could be adapted to have a streaming interface. Uses O(1) memory.
|
||||||
struct Parser2 {
|
struct Parser2 {
|
||||||
Parser2(char *buf, int len, const Callbacks *callbacks, void *data)
|
Parser2(const Callbacks *callbacks, void *data)
|
||||||
: buf(buf), bufEnd(buf + len), callbacks(callbacks), data(data) {}
|
: callbacks(callbacks), data(data) {}
|
||||||
|
|
||||||
// Returns false to reject
|
void prime(char *buf, int len) {
|
||||||
[[nodiscard]] bool parse() {
|
this->buf = buf;
|
||||||
if (push({N_VALUE}) != S_OK) {
|
this->bufEnd = buf + len;
|
||||||
return false;
|
|
||||||
}
|
}
|
||||||
return keepGoing(this) == S_OK;
|
|
||||||
|
enum Status {
|
||||||
|
// Accept input
|
||||||
|
S_OK,
|
||||||
|
// Consumed available input. Prime more and parse again
|
||||||
|
S_AGAIN,
|
||||||
|
// Invalid json
|
||||||
|
S_REJECT,
|
||||||
|
// json is too deeply nested
|
||||||
|
S_OVERFLOW,
|
||||||
|
};
|
||||||
|
|
||||||
|
[[nodiscard]] Status parse() {
|
||||||
|
if (Status s = push({N_VALUE})) {
|
||||||
|
return s;
|
||||||
|
}
|
||||||
|
return keepGoing(this);
|
||||||
}
|
}
|
||||||
|
|
||||||
Parser2(Parser2 const &) = delete;
|
Parser2(Parser2 const &) = delete;
|
||||||
@@ -433,13 +448,6 @@ struct Parser2 {
|
|||||||
|
|
||||||
static constexpr int kMaxStackSize = 1 << 10;
|
static constexpr int kMaxStackSize = 1 << 10;
|
||||||
|
|
||||||
enum Status {
|
|
||||||
S_OK,
|
|
||||||
S_AGAIN,
|
|
||||||
S_REJECT,
|
|
||||||
S_OVERFLOW,
|
|
||||||
};
|
|
||||||
|
|
||||||
private:
|
private:
|
||||||
// Helpers
|
// Helpers
|
||||||
void maybeSkipWs() {
|
void maybeSkipWs() {
|
||||||
@@ -632,8 +640,8 @@ private:
|
|||||||
/*N_OBJECT_MAYBE_CONTINUE*/ objectContinue,
|
/*N_OBJECT_MAYBE_CONTINUE*/ objectContinue,
|
||||||
};
|
};
|
||||||
|
|
||||||
char *buf;
|
char *buf = nullptr;
|
||||||
char *bufEnd;
|
char *bufEnd = nullptr;
|
||||||
int len() const { return bufEnd - buf; }
|
int len() const { return bufEnd - buf; }
|
||||||
const Callbacks *const callbacks;
|
const Callbacks *const callbacks;
|
||||||
void *const data;
|
void *const data;
|
||||||
@@ -724,13 +732,23 @@ TEST_CASE("parser2") {
|
|||||||
Callbacks c = printCallbacks();
|
Callbacks c = printCallbacks();
|
||||||
{
|
{
|
||||||
auto copy = json;
|
auto copy = json;
|
||||||
Parser2 parser(copy.data(), copy.length(), &c, nullptr);
|
Parser2 parser(&c, nullptr);
|
||||||
CHECK(parser.parse());
|
parser.prime(copy.data(), copy.length());
|
||||||
|
CHECK(parser.parse() == Parser2::S_OK);
|
||||||
}
|
}
|
||||||
{
|
{
|
||||||
std::string copy = "{\"x\": [], \"y\": {}}";
|
std::string copy = "{\"x\": [], \"y\": {}}";
|
||||||
Parser2 parser(copy.data(), copy.length(), &c, nullptr);
|
Parser2 parser(&c, nullptr);
|
||||||
CHECK(parser.parse());
|
parser.prime(copy.data(), copy.length());
|
||||||
|
CHECK(parser.parse() == Parser2::S_OK);
|
||||||
|
}
|
||||||
|
{
|
||||||
|
std::string copy = "true";
|
||||||
|
Parser2 parser(&c, nullptr);
|
||||||
|
parser.prime(copy.data(), 2);
|
||||||
|
CHECK(parser.parse() == Parser2::S_AGAIN);
|
||||||
|
parser.prime(copy.data() + 2, 2);
|
||||||
|
CHECK(parser.parse() == Parser2::S_OK);
|
||||||
}
|
}
|
||||||
}
|
}
|
||||||
|
|
||||||
@@ -753,7 +771,8 @@ TEST_CASE("bench2") {
|
|||||||
bench.unit("byte");
|
bench.unit("byte");
|
||||||
bench.run("parser2", [&]() {
|
bench.run("parser2", [&]() {
|
||||||
auto copy = json;
|
auto copy = json;
|
||||||
Parser2 parser(copy.data(), copy.length(), &c, nullptr);
|
Parser2 parser(&c, nullptr);
|
||||||
|
parser.prime(copy.data(), copy.length());
|
||||||
bench.doNotOptimizeAway(parser.parse());
|
bench.doNotOptimizeAway(parser.parse());
|
||||||
});
|
});
|
||||||
}
|
}
|
||||||
|
|||||||
Reference in New Issue
Block a user