Don't track len separately
This commit is contained in:
47
src/test.cpp
47
src/test.cpp
@@ -223,7 +223,7 @@ namespace {
|
||||
// treats numbers as [0-9.]+. May stack overflow on deeply nested json documents
|
||||
struct Parser1 {
|
||||
Parser1(char *buf, int len, const Callbacks *callbacks, void *data)
|
||||
: buf(buf), len(len), callbacks(callbacks), data(data) {}
|
||||
: buf(buf), bufEnd(buf + len), callbacks(callbacks), data(data) {}
|
||||
|
||||
// Returns false to reject
|
||||
[[nodiscard]] bool parse() { return parse_element(); }
|
||||
@@ -235,29 +235,29 @@ struct Parser1 {
|
||||
|
||||
private:
|
||||
char *buf;
|
||||
int len;
|
||||
char *bufEnd;
|
||||
const Callbacks *const callbacks;
|
||||
void *const data;
|
||||
|
||||
int len() const { return bufEnd - buf; }
|
||||
|
||||
// Helpers
|
||||
void maybeSkipWs() {
|
||||
int leadingWs = leadingWhitespaceCount(buf, len);
|
||||
int leadingWs = leadingWhitespaceCount(buf, len());
|
||||
buf += leadingWs;
|
||||
len -= leadingWs;
|
||||
}
|
||||
bool parseLiteral(const char *literal) {
|
||||
const int litLen = strlen(literal);
|
||||
if (len < litLen) {
|
||||
if (len() < litLen) {
|
||||
return false;
|
||||
}
|
||||
len -= litLen;
|
||||
return memcmp(std::exchange(buf, buf + litLen), literal, litLen) == 0;
|
||||
}
|
||||
|
||||
// functions corresponding to productions
|
||||
bool parse_element() {
|
||||
maybeSkipWs();
|
||||
if (len == 0) {
|
||||
if (len() == 0) {
|
||||
return false;
|
||||
}
|
||||
if (*buf == '{') {
|
||||
@@ -299,7 +299,7 @@ private:
|
||||
}
|
||||
callbacks->on_begin_object(data);
|
||||
maybeSkipWs();
|
||||
if (len == 0) {
|
||||
if (len() == 0) {
|
||||
return false;
|
||||
}
|
||||
if (*buf != '}') {
|
||||
@@ -318,7 +318,7 @@ private:
|
||||
if (!parse_member()) {
|
||||
return false;
|
||||
}
|
||||
if (len == 0) {
|
||||
if (len() == 0) {
|
||||
return false;
|
||||
}
|
||||
if (*buf == ',') {
|
||||
@@ -351,7 +351,7 @@ private:
|
||||
}
|
||||
callbacks->on_begin_array(data);
|
||||
maybeSkipWs();
|
||||
if (len == 0) {
|
||||
if (len() == 0) {
|
||||
return false;
|
||||
}
|
||||
if (*buf != ']') {
|
||||
@@ -371,7 +371,7 @@ private:
|
||||
if (!parse_element()) {
|
||||
return false;
|
||||
}
|
||||
if (len == 0) {
|
||||
if (len() == 0) {
|
||||
return false;
|
||||
}
|
||||
if (*buf == ',') {
|
||||
@@ -388,14 +388,13 @@ private:
|
||||
if (!parseLiteral("\"")) {
|
||||
return false;
|
||||
}
|
||||
auto *result = (char *)memchr(buf, '"', len);
|
||||
auto *result = (char *)memchr(buf, '"', len());
|
||||
if (result == nullptr) {
|
||||
return false;
|
||||
}
|
||||
int stringLen = result - buf;
|
||||
callbacks->on_string_data(data, buf, stringLen);
|
||||
buf += stringLen;
|
||||
len -= stringLen;
|
||||
if (!parseLiteral("\"")) {
|
||||
return false;
|
||||
}
|
||||
@@ -407,12 +406,11 @@ private:
|
||||
callbacks->on_begin_number(data);
|
||||
char *const bufBefore = buf;
|
||||
for (;;) {
|
||||
if (len == 0) {
|
||||
if (len() == 0) {
|
||||
return false;
|
||||
}
|
||||
if ('0' <= *buf && *buf <= '9' || (*buf == '.')) {
|
||||
++buf;
|
||||
--len;
|
||||
} else {
|
||||
break;
|
||||
}
|
||||
@@ -464,7 +462,7 @@ private:
|
||||
// [0-9.]+. Could be adapted to have a streaming interface. Uses O(1) memory.
|
||||
struct Parser2 {
|
||||
Parser2(char *buf, int len, const Callbacks *callbacks, void *data)
|
||||
: buf(buf), len(len), callbacks(callbacks), data(data) {}
|
||||
: buf(buf), bufEnd(buf + len), callbacks(callbacks), data(data) {}
|
||||
|
||||
// Returns false to reject
|
||||
[[nodiscard]] bool parse() {
|
||||
@@ -484,17 +482,16 @@ struct Parser2 {
|
||||
private:
|
||||
// Helpers
|
||||
void maybeSkipWs() {
|
||||
int leadingWs = leadingWhitespaceCount(buf, len);
|
||||
int leadingWs = leadingWhitespaceCount(buf, len());
|
||||
// printf("ws: %d\n", leadingWs);
|
||||
buf += leadingWs;
|
||||
len -= leadingWs;
|
||||
}
|
||||
bool parseLiteral(const char *literal) {
|
||||
const int litLen = strlen(literal);
|
||||
if (len < litLen) {
|
||||
if (len() < litLen) {
|
||||
return false;
|
||||
}
|
||||
if (memcmp(buf, literal, litLen) == 0) {
|
||||
len -= litLen;
|
||||
buf += litLen;
|
||||
return true;
|
||||
}
|
||||
@@ -502,16 +499,14 @@ private:
|
||||
}
|
||||
bool parse_number() {
|
||||
char *const bufBefore = buf;
|
||||
if (len == 0 || !('0' <= *buf && *buf <= '9' || (*buf == '.'))) {
|
||||
if (len() == 0 || !('0' <= *buf && *buf <= '9' || (*buf == '.'))) {
|
||||
return false;
|
||||
}
|
||||
callbacks->on_begin_number(data);
|
||||
++buf;
|
||||
--len;
|
||||
for (;;) {
|
||||
if ('0' <= *buf && *buf <= '9' || (*buf == '.')) {
|
||||
++buf;
|
||||
--len;
|
||||
} else {
|
||||
break;
|
||||
}
|
||||
@@ -528,14 +523,13 @@ private:
|
||||
return false;
|
||||
}
|
||||
callbacks->on_begin_string(data);
|
||||
auto *result = (char *)memchr(buf, '"', len);
|
||||
auto *result = (char *)memchr(buf, '"', len());
|
||||
if (result == nullptr) {
|
||||
return false;
|
||||
}
|
||||
int stringLen = result - buf;
|
||||
callbacks->on_string_data(data, buf, stringLen);
|
||||
buf += stringLen;
|
||||
len -= stringLen;
|
||||
if (!parseLiteral("\"")) {
|
||||
return false;
|
||||
}
|
||||
@@ -650,7 +644,8 @@ private:
|
||||
};
|
||||
|
||||
char *buf;
|
||||
int len;
|
||||
char *bufEnd;
|
||||
int len() { return bufEnd - buf; }
|
||||
const Callbacks *const callbacks;
|
||||
void *const data;
|
||||
Symbol stack[kMaxStackSize];
|
||||
|
||||
Reference in New Issue
Block a user