/*
- * Copyright 2014 Facebook, Inc.
+ * Copyright 2015 Facebook, Inc.
*
* Licensed under the Apache License, Version 2.0 (the "License");
* you may not use this file except in compliance with the License.
* limitations under the License.
*/
-#include "folly/json.h"
+#include <folly/json.h>
#include <cassert>
#include <boost/next_prior.hpp>
#include <boost/algorithm/string.hpp>
-#include "folly/Range.h"
-#include "folly/Unicode.h"
-#include "folly/Conv.h"
+#include <folly/Conv.h>
+#include <folly/Range.h>
+#include <folly/String.h>
+#include <folly/Unicode.h>
namespace folly {
serialization_opts const& opts_;
};
-//////////////////////////////////////////////////////////////////////
+ //////////////////////////////////////////////////////////////////////
-struct ParseError : std::runtime_error {
- explicit ParseError(int line)
- : std::runtime_error(to<std::string>("json parse error on line ", line))
- {}
+ struct ParseError : std::runtime_error {
+ explicit ParseError(int line)
+ : std::runtime_error(to<std::string>("json parse error on line ", line))
+ {}
- explicit ParseError(int line, std::string const& context,
- std::string const& expected)
- : std::runtime_error(to<std::string>("json parse error on line ", line,
- !context.empty() ? to<std::string>(" near `", context, '\'')
- : "",
- ": ", expected))
- {}
+ explicit ParseError(int line, std::string const& context,
+ std::string const& expected)
+ : std::runtime_error(to<std::string>("json parse error on line ", line,
+ !context.empty() ? to<std::string>(" near `", context, '\'')
+ : "",
+ ": ", expected))
+ {}
- explicit ParseError(std::string const& what)
- : std::runtime_error("json parse error: " + what)
- {}
-};
+ explicit ParseError(std::string const& msg)
+ : std::runtime_error("json parse error: " + msg)
+ {}
+ };
// Wraps our input buffer with some helper functions.
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();
}
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;
+}
+
}
//////////////////////////////////////////////////////////////////////