/*
- * 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.
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))
+ {}
+
+ 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& msg)
+ : std::runtime_error("json parse error: " + msg)
+ {}
+ };
+
// Wraps our input buffer with some helper functions.
struct Input {
explicit Input(StringPiece range, json::serialization_opts const* opts)
state = State::LineComment;
++i;
continue;
- } else if (s.startsWith("\"")) {
+ } else if (s[0] == '\"') {
state = State::InString;
}
result.push_back(s[0]);
break;
case State::InString:
- if (s.startsWith("\\\"")) {
+ 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.startsWith("\"")) {
+ } else if (s[0] == '\"') {
state = State::None;
}
result.push_back(s[0]);
}
break;
case State::LineComment:
- if (s.startsWith("\n")) {
+ if (s[0] == '\n') {
// skip the line break. It doesn't matter.
state = State::None;
}