Commit 9598430a authored by Kamal Marhubi's avatar Kamal Marhubi

Drop <regex> in number parsing

parent c662e628
...@@ -382,7 +382,7 @@ KJ_TEST("basic json decoding") { ...@@ -382,7 +382,7 @@ KJ_TEST("basic json decoding") {
MallocMessageBuilder message; MallocMessageBuilder message;
auto root = message.initRoot<JsonValue>(); auto root = message.initRoot<JsonValue>();
KJ_EXPECT_THROW_MESSAGE("Expected number", json.decodeRaw("-", root)); KJ_EXPECT_THROW_MESSAGE("ends prematurely", json.decodeRaw("-", root));
} }
{ {
...@@ -426,8 +426,8 @@ KJ_TEST("basic json decoding") { ...@@ -426,8 +426,8 @@ KJ_TEST("basic json decoding") {
KJ_EXPECT_THROW_MESSAGE("Invalid escape", json.decodeRaw(R"("\z")", root)); KJ_EXPECT_THROW_MESSAGE("Invalid escape", json.decodeRaw(R"("\z")", root));
KJ_EXPECT_THROW_MESSAGE("ends prematurely", json.decodeRaw(R"(["\n\", 3])", root)); KJ_EXPECT_THROW_MESSAGE("ends prematurely", json.decodeRaw(R"(["\n\", 3])", root));
KJ_EXPECT_THROW_MESSAGE("Invalid hex", json.decodeRaw(R"("\u12zz")", root)); KJ_EXPECT_THROW_MESSAGE("Invalid hex", json.decodeRaw(R"("\u12zz")", root));
KJ_EXPECT_THROW_MESSAGE("Expected number", json.decodeRaw("-", root)); KJ_EXPECT_THROW_MESSAGE("ends prematurely", json.decodeRaw("-", root));
KJ_EXPECT_THROW_MESSAGE("Expected number", json.decodeRaw("--", root)); KJ_EXPECT_THROW_MESSAGE("Unexpected input", json.decodeRaw("--", root));
} }
} }
......
...@@ -20,9 +20,9 @@ ...@@ -20,9 +20,9 @@
// THE SOFTWARE. // THE SOFTWARE.
#include "json.h" #include "json.h"
#include <cmath> // for HUGEVAL to check for overflow in std::strtod
#include <cstdlib> // std::strtod #include <cstdlib> // std::strtod
#include <errno.h> // for std::strtod errors #include <errno.h> // for std::strtod errors
#include <regex> // for numbers
#include <unordered_map> #include <unordered_map>
#include <capnp/orphan.h> #include <capnp/orphan.h>
#include <kj/debug.h> #include <kj/debug.h>
...@@ -543,6 +543,21 @@ public: ...@@ -543,6 +543,21 @@ public:
advance(expected.size()); advance(expected.size());
} }
bool tryConsume(char expected) {
bool found = !inputExhausted() && nextChar() == expected;
if (found) { advance(); }
return found;
}
template <typename Predicate>
void consumeOne(Predicate&& predicate) {
char current = nextChar();
KJ_REQUIRE(predicate(current), "Unexpected input in JSON message.");
advance();
}
template <typename Predicate> template <typename Predicate>
kj::ArrayPtr<const char> consumeWhile(Predicate&& predicate) { kj::ArrayPtr<const char> consumeWhile(Predicate&& predicate) {
auto originalPos = remaining_.begin(); auto originalPos = remaining_.begin();
...@@ -607,26 +622,29 @@ public: ...@@ -607,26 +622,29 @@ public:
} }
kj::String consumeNumber() { kj::String consumeNumber() {
// TODO(perf): <regex> could be eliminated. auto originalPos = remaining_.begin();
static std::regex jsonNumber(
R"(-?(0|[1-9][0-9]*)(\.[0-9]+)?((e|E)([+-])?[0-9]+)?)"); tryConsume('-');
// jsonNumber matches numbers as seen in railroad diagram at http://json.org/. if (!tryConsume('0')) {
consumeOne([](char c) { return '1' <= c && c <= '9'; });
consumeWhile([](char c) { return '0' <= c && c <= '9'; });
}
std::cmatch match; if (tryConsume('.')) {
bool foundNumber = std::regex_search( consumeWhile([](char c) { return '0' <= c && c <= '9'; });
remaining_.begin(), }
remaining_.end(),
match, jsonNumber, if (tryConsume('e') || tryConsume('E')) {
std::regex_constants::match_continuous); tryConsume('+') || tryConsume('-');
consumeWhile([](char c) { return '0' <= c && c <= '9'; });
}
KJ_REQUIRE(foundNumber, "Expected number in JSON input."); KJ_REQUIRE(remaining_.begin() != originalPos, "Expected number in JSON input.");
kj::Vector<char> number; kj::Vector<char> number;
number.addAll(match[0].first, match[0].second); number.addAll(originalPos, remaining_.begin());
number.add('\0'); number.add('\0');
advanceTo(match.suffix().first);
return kj::String(number.releaseAsArray()); return kj::String(number.releaseAsArray());
} }
......
Markdown is supported
0% or
You are about to add 0 people to the discussion. Proceed with caution.
Finish editing this message first!
Please register or to comment