|
|
@@ -39,7 +39,24 @@ namespace json {
|
|
|
namespace json {
|
|
|
namespace helper {
|
|
|
const char get_next_element(char const*& data);
|
|
|
- char const * get_numeric_token_end(char const * start);
|
|
|
+
|
|
|
+ enum numeric_state {
|
|
|
+ DOUBLE, INTEGER
|
|
|
+ };
|
|
|
+
|
|
|
+ struct numeric_token_info {
|
|
|
+ numeric_token_info(char const * start);
|
|
|
+ numeric_state parse_numeric();
|
|
|
+
|
|
|
+ uint_jt val;
|
|
|
+
|
|
|
+ char const * it;
|
|
|
+ char const * end;
|
|
|
+ bool is_double;
|
|
|
+ bool is_negative;
|
|
|
+ };
|
|
|
+
|
|
|
+ numeric_token_info get_numeric_token_info(char const * it);
|
|
|
|
|
|
/**
|
|
|
* @throws json::malformed_json_exception
|
|
|
@@ -72,42 +89,27 @@ namespace json {
|
|
|
|
|
|
template <typename J>
|
|
|
void parse_numeric(J & json, char const * & data) {
|
|
|
- char const * start = data;
|
|
|
- char const * const end = get_numeric_token_end(start);
|
|
|
-
|
|
|
- if (end == start) {
|
|
|
- throw malformed_json_exception("Expected any token, got nothing");
|
|
|
- }
|
|
|
+ numeric_token_info info = data;
|
|
|
|
|
|
- bool const negative = *start == '-';
|
|
|
- if (negative) ++start;
|
|
|
-
|
|
|
- uint_jt const threshold = (UINT_JT_MAX / 10);
|
|
|
- uint_jt val = 0;
|
|
|
- for (; start != end; ++start) {
|
|
|
- if (!isdigit(*start)) {
|
|
|
- helper::parse_double(json, data);
|
|
|
- return;
|
|
|
- }
|
|
|
- int_jt digit = static_cast<int_jt>(*start - '0');
|
|
|
- if (val >= threshold) {
|
|
|
- if (val > threshold || (start + 1) < end || digit > INT_JT_MAX_LAST_DIGIT) {
|
|
|
- helper::parse_double(json, data);
|
|
|
- return;
|
|
|
+ if ( info.is_double ) {
|
|
|
+ helper::parse_double(json, data);
|
|
|
+ } else if ( info.parse_numeric() == DOUBLE ) {
|
|
|
+ helper::parse_double(json, data);
|
|
|
+ } else {
|
|
|
+ uint_jt const val = info.val;
|
|
|
+ if (info.is_negative) {
|
|
|
+ if (val == INT_JT_OVER) {
|
|
|
+ json = INT_JT_MIN;
|
|
|
+ } else {
|
|
|
+ json = -int_jt(val);
|
|
|
}
|
|
|
+ } else if (val <= uint_jt(INT_JT_MAX)) {
|
|
|
+ json = int_jt(val);
|
|
|
+ } else {
|
|
|
+ json = val;
|
|
|
}
|
|
|
- val = (10 * val) + digit;
|
|
|
+ data = info.it;
|
|
|
}
|
|
|
- if (negative && val == INT_JT_OVER) {
|
|
|
- json = INT_JT_MIN;
|
|
|
- } else if (negative) {
|
|
|
- json = -int_jt(val);
|
|
|
- } else if (val <= uint_jt(INT_JT_MAX)) {
|
|
|
- json = int_jt(val);
|
|
|
- } else {
|
|
|
- json = val;
|
|
|
- }
|
|
|
- data = start;
|
|
|
}
|
|
|
- }
|
|
|
+ }
|
|
|
}
|