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