X-Git-Url: http://demsky.eecs.uci.edu/git/?a=blobdiff_plain;f=folly%2Fjson.cpp;h=d4f0771d98a7d75c6138e0836462e3244ac100f4;hb=fd915b73606e09a5f46a1bca0a5d3643a1567014;hp=5ca57d475b31b5249370d033ff27e5a2c2ae8f1f;hpb=d9c79af86a4dc0576d8df453804d3354347c07dc;p=folly.git diff --git a/folly/json.cpp b/folly/json.cpp index 5ca57d47..d4f0771d 100644 --- a/folly/json.cpp +++ b/folly/json.cpp @@ -14,14 +14,15 @@ * limitations under the License. */ -#include "folly/json.h" +#include #include #include #include -#include "folly/Range.h" -#include "folly/Unicode.h" -#include "folly/Conv.h" +#include +#include +#include +#include namespace folly { @@ -255,26 +256,6 @@ private: serialization_opts const& opts_; }; -////////////////////////////////////////////////////////////////////// - -struct ParseError : std::runtime_error { - explicit ParseError(int line) - : std::runtime_error(to("json parse error on line ", line)) - {} - - explicit ParseError(int line, std::string const& context, - std::string const& expected) - : std::runtime_error(to("json parse error on line ", line, - !context.empty() ? to(" near `", context, '\'') - : "", - ": ", expected)) - {} - - explicit ParseError(std::string const& what) - : std::runtime_error("json parse error: " + what) - {} -}; - // Wraps our input buffer with some helper functions. struct Input { explicit Input(StringPiece range, json::serialization_opts const* opts) @@ -323,20 +304,7 @@ struct Input { } void skipWhitespace() { - // Spaces other than ' ' characters are less common but should be - // checked. This configuration where we loop on the ' ' - // separately from oddspaces was empirically fastest. - auto oddspace = [] (char c) { - return c == '\n' || c == '\t' || c == '\r'; - }; - - loop: - for (; !range_.empty() && range_.front() == ' '; range_.pop_front()) { - } - if (!range_.empty() && oddspace(range_.front())) { - range_.pop_front(); - goto loop; - } + range_ = folly::skipWhitespace(range_); storeCurrent(); } @@ -716,6 +684,65 @@ void escapeString(StringPiece input, out.push_back('\"'); } +fbstring stripComments(StringPiece jsonC) { + fbstring result; + enum class State { + None, + InString, + InlineComment, + LineComment + } state = State::None; + + for (size_t i = 0; i < jsonC.size(); ++i) { + auto s = jsonC.subpiece(i); + switch (state) { + case State::None: + if (s.startsWith("/*")) { + state = State::InlineComment; + ++i; + continue; + } else if (s.startsWith("//")) { + state = State::LineComment; + ++i; + continue; + } else if (s[0] == '\"') { + state = State::InString; + } + result.push_back(s[0]); + break; + case State::InString: + if (s[0] == '\\') { + if (UNLIKELY(s.size() == 1)) { + throw std::logic_error("Invalid JSONC: string is not terminated"); + } + result.push_back(s[0]); + result.push_back(s[1]); + ++i; + continue; + } else if (s[0] == '\"') { + state = State::None; + } + result.push_back(s[0]); + break; + case State::InlineComment: + if (s.startsWith("*/")) { + state = State::None; + ++i; + } + break; + case State::LineComment: + if (s[0] == '\n') { + // skip the line break. It doesn't matter. + state = State::None; + } + break; + default: + throw std::logic_error("Unknown comment state"); + } + } + return result; +} + } //////////////////////////////////////////////////////////////////////