X-Git-Url: http://demsky.eecs.uci.edu/git/?a=blobdiff_plain;f=folly%2Fjson.cpp;h=f51b038b4f186891b6be8614bbc467eeded69a68;hb=46e3ed2921bd4e5de81fbc36fcb6a82d30d1499f;hp=28fe5f11e992806f3949d6b42a32d26c66894b74;hpb=de873ac77d23d95a72a498a90ef82cade243f752;p=folly.git diff --git a/folly/json.cpp b/folly/json.cpp index 28fe5f11..f51b038b 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 { @@ -127,11 +128,11 @@ struct Printer { switch (v.type()) { case dynamic::DOUBLE: if (!opts_.allow_nan_inf && - (isnan(v.asDouble()) || isinf(v.asDouble()))) { + (std::isnan(v.asDouble()) || std::isinf(v.asDouble()))) { throw std::runtime_error("folly::toJson: JSON object value was a " "NaN or INF"); } - toAppend(v.asDouble(), &out_); + toAppend(v.asDouble(), &out_, opts_.double_mode, opts_.double_num_digits); break; case dynamic::INT64: { auto intval = v.asInt(); @@ -216,7 +217,7 @@ private: indent(); newline(); (*this)(a[0]); - for (auto& val : makeRange(boost::next(a.begin()), a.end())) { + for (auto& val : range(boost::next(a.begin()), a.end())) { out_ += ','; newline(); (*this)(val); @@ -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(); } @@ -509,7 +477,7 @@ dynamic parseNumber(Input& in) { auto expPart = in.skipDigits(); end = expPart.end(); } - auto fullNum = makeRange(integral.begin(), end); + auto fullNum = range(integral.begin(), end); auto val = to(fullNum); return val; @@ -716,6 +684,62 @@ 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.startsWith("\"")) { + state = State::InString; + } + result.push_back(s[0]); + break; + case State::InString: + if (s.startsWith("\\\"")) { + result.push_back(s[0]); + result.push_back(s[1]); + ++i; + continue; + } else if (s.startsWith("\"")) { + 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.startsWith("\n")) { + // skip the line break. It doesn't matter. + state = State::None; + } + break; + default: + throw std::logic_error("Unknown comment state"); + } + } + return result; +} + } //////////////////////////////////////////////////////////////////////