/*
- * 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)
}
auto const wasE = *in == 'e' || *in == 'E';
+
+ constexpr const char* maxInt = "9223372036854775807";
+ constexpr const char* minInt = "9223372036854775808";
+ constexpr auto maxIntLen = __builtin_strlen(maxInt);
+
if (*in != '.' && !wasE) {
- auto val = to<int64_t>(integral);
- in.skipWhitespace();
- return val;
+ if (LIKELY(!in.getOpts().double_fallback || integral.size() < maxIntLen) ||
+ (integral.size() == maxIntLen &&
+ (integral <= maxInt || (integral == minInt && negative)))) {
+ auto val = to<int64_t>(integral);
+ in.skipWhitespace();
+ return val;
+ } else {
+ auto val = to<double>(integral);
+ in.skipWhitespace();
+ return val;
+ }
}
auto end = !wasE ? (++in, in.skipDigits().end()) : in.begin();