diff options
Diffstat (limited to 'contrib/llvm/tools/lldb/source/Utility/JSON.cpp')
-rw-r--r-- | contrib/llvm/tools/lldb/source/Utility/JSON.cpp | 1083 |
1 files changed, 470 insertions, 613 deletions
diff --git a/contrib/llvm/tools/lldb/source/Utility/JSON.cpp b/contrib/llvm/tools/lldb/source/Utility/JSON.cpp index 7ad3232..5b809c5 100644 --- a/contrib/llvm/tools/lldb/source/Utility/JSON.cpp +++ b/contrib/llvm/tools/lldb/source/Utility/JSON.cpp @@ -9,685 +9,542 @@ #include "lldb/Utility/JSON.h" -#include <limits.h> #include "lldb/Core/StreamString.h" #include "lldb/Host/StringConvert.h" #include "llvm/Support/ErrorHandling.h" +#include <limits.h> using namespace lldb_private; -std::string -JSONString::json_string_quote_metachars (const std::string &s) -{ - if (s.find('"') == std::string::npos) - return s; - - std::string output; - const size_t s_size = s.size(); - const char *s_chars = s.c_str(); - for (size_t i = 0; i < s_size; i++) - { - unsigned char ch = *(s_chars + i); - if (ch == '"') - { - output.push_back ('\\'); - } - output.push_back (ch); +std::string JSONString::json_string_quote_metachars(const std::string &s) { + if (s.find('"') == std::string::npos) + return s; + + std::string output; + const size_t s_size = s.size(); + const char *s_chars = s.c_str(); + for (size_t i = 0; i < s_size; i++) { + unsigned char ch = *(s_chars + i); + if (ch == '"') { + output.push_back('\\'); } - return output; + output.push_back(ch); + } + return output; } -JSONString::JSONString () : - JSONValue(JSONValue::Kind::String), - m_data() -{ -} +JSONString::JSONString() : JSONValue(JSONValue::Kind::String), m_data() {} -JSONString::JSONString (const char* s) : - JSONValue(JSONValue::Kind::String), - m_data(s ? s : "") -{ -} +JSONString::JSONString(const char *s) + : JSONValue(JSONValue::Kind::String), m_data(s ? s : "") {} -JSONString::JSONString (const std::string& s) : - JSONValue(JSONValue::Kind::String), - m_data(s) -{ -} +JSONString::JSONString(const std::string &s) + : JSONValue(JSONValue::Kind::String), m_data(s) {} -void -JSONString::Write (Stream& s) -{ - s.Printf("\"%s\"", json_string_quote_metachars(m_data).c_str()); +void JSONString::Write(Stream &s) { + s.Printf("\"%s\"", json_string_quote_metachars(m_data).c_str()); } -uint64_t -JSONNumber::GetAsUnsigned() const -{ - switch (m_data_type) - { - case DataType::Unsigned: - return m_data.m_unsigned; - case DataType::Signed: - return (uint64_t)m_data.m_signed; - case DataType::Double: - return (uint64_t)m_data.m_double; - } - llvm_unreachable("Unhandled data type"); +uint64_t JSONNumber::GetAsUnsigned() const { + switch (m_data_type) { + case DataType::Unsigned: + return m_data.m_unsigned; + case DataType::Signed: + return (uint64_t)m_data.m_signed; + case DataType::Double: + return (uint64_t)m_data.m_double; + } + llvm_unreachable("Unhandled data type"); } -int64_t -JSONNumber::GetAsSigned() const -{ - switch (m_data_type) - { - case DataType::Unsigned: - return (int64_t)m_data.m_unsigned; - case DataType::Signed: - return m_data.m_signed; - case DataType::Double: - return (int64_t)m_data.m_double; - } - llvm_unreachable("Unhandled data type"); +int64_t JSONNumber::GetAsSigned() const { + switch (m_data_type) { + case DataType::Unsigned: + return (int64_t)m_data.m_unsigned; + case DataType::Signed: + return m_data.m_signed; + case DataType::Double: + return (int64_t)m_data.m_double; + } + llvm_unreachable("Unhandled data type"); } -double -JSONNumber::GetAsDouble() const -{ - switch (m_data_type) - { - case DataType::Unsigned: - return (double)m_data.m_unsigned; - case DataType::Signed: - return (double)m_data.m_signed; - case DataType::Double: - return m_data.m_double; - } - llvm_unreachable("Unhandled data type"); +double JSONNumber::GetAsDouble() const { + switch (m_data_type) { + case DataType::Unsigned: + return (double)m_data.m_unsigned; + case DataType::Signed: + return (double)m_data.m_signed; + case DataType::Double: + return m_data.m_double; + } + llvm_unreachable("Unhandled data type"); } -void -JSONNumber::Write (Stream& s) -{ - switch (m_data_type) - { - case DataType::Unsigned: - s.Printf("%" PRIu64, m_data.m_unsigned); - break; - case DataType::Signed: - s.Printf("%" PRId64, m_data.m_signed); - break; - case DataType::Double: - s.Printf("%g", m_data.m_double); - break; - } +void JSONNumber::Write(Stream &s) { + switch (m_data_type) { + case DataType::Unsigned: + s.Printf("%" PRIu64, m_data.m_unsigned); + break; + case DataType::Signed: + s.Printf("%" PRId64, m_data.m_signed); + break; + case DataType::Double: + s.Printf("%g", m_data.m_double); + break; + } } -JSONTrue::JSONTrue () : - JSONValue(JSONValue::Kind::True) -{ -} +JSONTrue::JSONTrue() : JSONValue(JSONValue::Kind::True) {} -void -JSONTrue::Write(Stream& s) -{ - s.Printf("true"); -} +void JSONTrue::Write(Stream &s) { s.Printf("true"); } -JSONFalse::JSONFalse () : - JSONValue(JSONValue::Kind::False) -{ -} +JSONFalse::JSONFalse() : JSONValue(JSONValue::Kind::False) {} -void -JSONFalse::Write(Stream& s) -{ - s.Printf("false"); -} +void JSONFalse::Write(Stream &s) { s.Printf("false"); } -JSONNull::JSONNull () : - JSONValue(JSONValue::Kind::Null) -{ -} +JSONNull::JSONNull() : JSONValue(JSONValue::Kind::Null) {} -void -JSONNull::Write(Stream& s) -{ - s.Printf("null"); -} +void JSONNull::Write(Stream &s) { s.Printf("null"); } -JSONObject::JSONObject () : - JSONValue(JSONValue::Kind::Object) -{ -} +JSONObject::JSONObject() : JSONValue(JSONValue::Kind::Object) {} -void -JSONObject::Write (Stream& s) -{ - bool first = true; - s.PutChar('{'); - auto iter = m_elements.begin(), end = m_elements.end(); - for (;iter != end; iter++) - { - if (first) - first = false; - else - s.PutChar(','); - JSONString key(iter->first); - JSONValue::SP value(iter->second); - key.Write(s); - s.PutChar(':'); - value->Write(s); - } - s.PutChar('}'); +void JSONObject::Write(Stream &s) { + bool first = true; + s.PutChar('{'); + auto iter = m_elements.begin(), end = m_elements.end(); + for (; iter != end; iter++) { + if (first) + first = false; + else + s.PutChar(','); + JSONString key(iter->first); + JSONValue::SP value(iter->second); + key.Write(s); + s.PutChar(':'); + value->Write(s); + } + s.PutChar('}'); } -bool -JSONObject::SetObject (const std::string& key, - JSONValue::SP value) -{ - if (key.empty() || nullptr == value.get()) - return false; - m_elements[key] = value; - return true; +bool JSONObject::SetObject(const std::string &key, JSONValue::SP value) { + if (key.empty() || nullptr == value.get()) + return false; + m_elements[key] = value; + return true; } -JSONValue::SP -JSONObject::GetObject (const std::string& key) -{ - auto iter = m_elements.find(key), end = m_elements.end(); - if (iter == end) - return JSONValue::SP(); - return iter->second; +JSONValue::SP JSONObject::GetObject(const std::string &key) { + auto iter = m_elements.find(key), end = m_elements.end(); + if (iter == end) + return JSONValue::SP(); + return iter->second; } -JSONArray::JSONArray () : - JSONValue(JSONValue::Kind::Array) -{ +JSONArray::JSONArray() : JSONValue(JSONValue::Kind::Array) {} + +void JSONArray::Write(Stream &s) { + bool first = true; + s.PutChar('['); + auto iter = m_elements.begin(), end = m_elements.end(); + for (; iter != end; iter++) { + if (first) + first = false; + else + s.PutChar(','); + (*iter)->Write(s); + } + s.PutChar(']'); } -void -JSONArray::Write (Stream& s) -{ - bool first = true; - s.PutChar('['); - auto iter = m_elements.begin(), end = m_elements.end(); - for (;iter != end; iter++) - { - if (first) - first = false; - else - s.PutChar(','); - (*iter)->Write(s); - } - s.PutChar(']'); -} - -bool -JSONArray::SetObject (Index i, - JSONValue::SP value) -{ - if (value.get() == nullptr) - return false; - if (i < m_elements.size()) - { - m_elements[i] = value; - return true; - } - if (i == m_elements.size()) - { - m_elements.push_back(value); - return true; - } +bool JSONArray::SetObject(Index i, JSONValue::SP value) { + if (value.get() == nullptr) return false; -} - -bool -JSONArray::AppendObject (JSONValue::SP value) -{ - if (value.get() == nullptr) - return false; + if (i < m_elements.size()) { + m_elements[i] = value; + return true; + } + if (i == m_elements.size()) { m_elements.push_back(value); return true; + } + return false; } -JSONValue::SP -JSONArray::GetObject (Index i) -{ - if (i < m_elements.size()) - return m_elements[i]; - return JSONValue::SP(); +bool JSONArray::AppendObject(JSONValue::SP value) { + if (value.get() == nullptr) + return false; + m_elements.push_back(value); + return true; } -JSONArray::Size -JSONArray::GetNumElements () -{ - return m_elements.size(); +JSONValue::SP JSONArray::GetObject(Index i) { + if (i < m_elements.size()) + return m_elements[i]; + return JSONValue::SP(); } +JSONArray::Size JSONArray::GetNumElements() { return m_elements.size(); } + +JSONParser::JSONParser(const char *cstr) : StringExtractor(cstr) {} + +JSONParser::Token JSONParser::GetToken(std::string &value) { + StreamString error; + + value.clear(); + SkipSpaces(); + const uint64_t start_index = m_index; + const char ch = GetChar(); + switch (ch) { + case '{': + return Token::ObjectStart; + case '}': + return Token::ObjectEnd; + case '[': + return Token::ArrayStart; + case ']': + return Token::ArrayEnd; + case ',': + return Token::Comma; + case ':': + return Token::Colon; + case '\0': + return Token::EndOfFile; + case 't': + if (GetChar() == 'r') + if (GetChar() == 'u') + if (GetChar() == 'e') + return Token::True; + break; + + case 'f': + if (GetChar() == 'a') + if (GetChar() == 'l') + if (GetChar() == 's') + if (GetChar() == 'e') + return Token::False; + break; + + case 'n': + if (GetChar() == 'u') + if (GetChar() == 'l') + if (GetChar() == 'l') + return Token::Null; + break; + + case '"': { + while (1) { + bool was_escaped = false; + int escaped_ch = GetEscapedChar(was_escaped); + if (escaped_ch == -1) { + error.Printf( + "error: an error occurred getting a character from offset %" PRIu64, + start_index); + value = std::move(error.GetString()); + return Token::Error; + + } else { + const bool is_end_quote = escaped_ch == '"'; + const bool is_null = escaped_ch == 0; + if (was_escaped || (!is_end_quote && !is_null)) { + if (CHAR_MIN <= escaped_ch && escaped_ch <= CHAR_MAX) { + value.append(1, (char)escaped_ch); + } else { + error.Printf("error: wide character support is needed for unicode " + "character 0x%4.4x at offset %" PRIu64, + escaped_ch, start_index); + value = std::move(error.GetString()); + return Token::Error; + } + } else if (is_end_quote) { + return Token::String; + } else if (is_null) { + value = "error: missing end quote for string"; + return Token::Error; + } + } + } + } break; + + case '-': + case '0': + case '1': + case '2': + case '3': + case '4': + case '5': + case '6': + case '7': + case '8': + case '9': { + bool done = false; + bool got_decimal_point = false; + uint64_t exp_index = 0; + bool got_int_digits = (ch >= '0') && (ch <= '9'); + bool got_frac_digits = false; + bool got_exp_digits = false; + while (!done) { + const char next_ch = PeekChar(); + switch (next_ch) { + case '0': + case '1': + case '2': + case '3': + case '4': + case '5': + case '6': + case '7': + case '8': + case '9': + if (exp_index != 0) { + got_exp_digits = true; + } else if (got_decimal_point) { + got_frac_digits = true; + } else { + got_int_digits = true; + } + ++m_index; // Skip this character + break; + + case '.': + if (got_decimal_point) { + error.Printf("error: extra decimal point found at offset %" PRIu64, + start_index); + value = std::move(error.GetString()); + return Token::Error; + } else { + got_decimal_point = true; + ++m_index; // Skip this character + } + break; + + case 'e': + case 'E': + if (exp_index != 0) { + error.Printf( + "error: extra exponent character found at offset %" PRIu64, + start_index); + value = std::move(error.GetString()); + return Token::Error; + } else { + exp_index = m_index; + ++m_index; // Skip this character + } + break; + + case '+': + case '-': + // The '+' and '-' can only come after an exponent character... + if (exp_index == m_index - 1) { + ++m_index; // Skip the exponent sign character + } else { + error.Printf("error: unexpected %c character at offset %" PRIu64, + next_ch, start_index); + value = std::move(error.GetString()); + return Token::Error; + } + break; -JSONParser::JSONParser (const char *cstr) : - StringExtractor(cstr) -{ -} - -JSONParser::Token -JSONParser::GetToken (std::string &value) -{ - StreamString error; - - value.clear(); - SkipSpaces (); - const uint64_t start_index = m_index; - const char ch = GetChar(); - switch (ch) - { - case '{': return Token::ObjectStart; - case '}': return Token::ObjectEnd; - case '[': return Token::ArrayStart; - case ']': return Token::ArrayEnd; - case ',': return Token::Comma; - case ':': return Token::Colon; - case '\0': return Token::EndOfFile; - case 't': - if (GetChar() == 'r') - if (GetChar() == 'u') - if (GetChar() == 'e') - return Token::True; - break; - - case 'f': - if (GetChar() == 'a') - if (GetChar() == 'l') - if (GetChar() == 's') - if (GetChar() == 'e') - return Token::False; - break; - - case 'n': - if (GetChar() == 'u') - if (GetChar() == 'l') - if (GetChar() == 'l') - return Token::Null; - break; - - case '"': - { - while (1) - { - bool was_escaped = false; - int escaped_ch = GetEscapedChar(was_escaped); - if (escaped_ch == -1) - { - error.Printf("error: an error occurred getting a character from offset %" PRIu64, start_index); - value = std::move(error.GetString()); - return Token::Error; - - } - else - { - const bool is_end_quote = escaped_ch == '"'; - const bool is_null = escaped_ch == 0; - if (was_escaped || (!is_end_quote && !is_null)) - { - if (CHAR_MIN <= escaped_ch && escaped_ch <= CHAR_MAX) - { - value.append(1, (char)escaped_ch); - } - else - { - error.Printf("error: wide character support is needed for unicode character 0x%4.4x at offset %" PRIu64, escaped_ch, start_index); - value = std::move(error.GetString()); - return Token::Error; - } - } - else if (is_end_quote) - { - return Token::String; - } - else if (is_null) - { - value = "error: missing end quote for string"; - return Token::Error; - } - } - } - } - break; - - case '-': - case '0': - case '1': - case '2': - case '3': - case '4': - case '5': - case '6': - case '7': - case '8': - case '9': - { - bool done = false; - bool got_decimal_point = false; - uint64_t exp_index = 0; - bool got_int_digits = (ch >= '0') && (ch <= '9'); - bool got_frac_digits = false; - bool got_exp_digits = false; - while (!done) - { - const char next_ch = PeekChar(); - switch (next_ch) - { - case '0': - case '1': - case '2': - case '3': - case '4': - case '5': - case '6': - case '7': - case '8': - case '9': - if (exp_index != 0) - { - got_exp_digits = true; - } - else if (got_decimal_point) - { - got_frac_digits = true; - } - else - { - got_int_digits = true; - } - ++m_index; // Skip this character - break; - - case '.': - if (got_decimal_point) - { - error.Printf("error: extra decimal point found at offset %" PRIu64, start_index); - value = std::move(error.GetString()); - return Token::Error; - } - else - { - got_decimal_point = true; - ++m_index; // Skip this character - } - break; - - case 'e': - case 'E': - if (exp_index != 0) - { - error.Printf("error: extra exponent character found at offset %" PRIu64, start_index); - value = std::move(error.GetString()); - return Token::Error; - } - else - { - exp_index = m_index; - ++m_index; // Skip this character - } - break; - - case '+': - case '-': - // The '+' and '-' can only come after an exponent character... - if (exp_index == m_index - 1) - { - ++m_index; // Skip the exponent sign character - } - else - { - error.Printf("error: unexpected %c character at offset %" PRIu64, next_ch, start_index); - value = std::move(error.GetString()); - return Token::Error; - } - break; - - default: - done = true; - break; - } - } - - if (m_index > start_index) - { - value = m_packet.substr(start_index, m_index - start_index); - if (got_decimal_point) - { - if (exp_index != 0) - { - // We have an exponent, make sure we got exponent digits - if (got_exp_digits) - { - return Token::Float; - } - else - { - error.Printf("error: got exponent character but no exponent digits at offset in float value \"%s\"", value.c_str()); - value = std::move(error.GetString()); - return Token::Error; - } - } - else - { - // No exponent, but we need at least one decimal after the decimal point - if (got_frac_digits) - { - return Token::Float; - } - else - { - error.Printf("error: no digits after decimal point \"%s\"", value.c_str()); - value = std::move(error.GetString()); - return Token::Error; - } - } - } - else - { - // No decimal point - if (got_int_digits) - { - // We need at least some integer digits to make an integer - return Token::Integer; - } - else - { - error.Printf("error: no digits negate sign \"%s\"", value.c_str()); - value = std::move(error.GetString()); - return Token::Error; - } - } - } - else - { - error.Printf("error: invalid number found at offset %" PRIu64, start_index); - value = std::move(error.GetString()); - return Token::Error; - } - } - break; - default: - break; + default: + done = true; + break; + } } - error.Printf("error: failed to parse token at offset %" PRIu64 " (around character '%c')", start_index, ch); - value = std::move(error.GetString()); - return Token::Error; -} -int -JSONParser::GetEscapedChar(bool &was_escaped) -{ - was_escaped = false; - const char ch = GetChar(); - if (ch == '\\') - { - was_escaped = true; - const char ch2 = GetChar(); - switch (ch2) - { - case '"': - case '\\': - case '/': - default: - break; - - case 'b': return '\b'; - case 'f': return '\f'; - case 'n': return '\n'; - case 'r': return '\r'; - case 't': return '\t'; - case 'u': - { - const int hi_byte = DecodeHexU8(); - const int lo_byte = DecodeHexU8(); - if (hi_byte >=0 && lo_byte >= 0) - return hi_byte << 8 | lo_byte; - return -1; - } - break; + if (m_index > start_index) { + value = m_packet.substr(start_index, m_index - start_index); + if (got_decimal_point) { + if (exp_index != 0) { + // We have an exponent, make sure we got exponent digits + if (got_exp_digits) { + return Token::Float; + } else { + error.Printf("error: got exponent character but no exponent digits " + "at offset in float value \"%s\"", + value.c_str()); + value = std::move(error.GetString()); + return Token::Error; + } + } else { + // No exponent, but we need at least one decimal after the decimal + // point + if (got_frac_digits) { + return Token::Float; + } else { + error.Printf("error: no digits after decimal point \"%s\"", + value.c_str()); + value = std::move(error.GetString()); + return Token::Error; + } + } + } else { + // No decimal point + if (got_int_digits) { + // We need at least some integer digits to make an integer + return Token::Integer; + } else { + error.Printf("error: no digits negate sign \"%s\"", value.c_str()); + value = std::move(error.GetString()); + return Token::Error; } - return ch2; + } + } else { + error.Printf("error: invalid number found at offset %" PRIu64, + start_index); + value = std::move(error.GetString()); + return Token::Error; } - return ch; + } break; + default: + break; + } + error.Printf("error: failed to parse token at offset %" PRIu64 + " (around character '%c')", + start_index, ch); + value = std::move(error.GetString()); + return Token::Error; } -JSONValue::SP -JSONParser::ParseJSONObject () -{ - // The "JSONParser::Token::ObjectStart" token should have already been consumed - // by the time this function is called - std::unique_ptr<JSONObject> dict_up(new JSONObject()); - - std::string value; - std::string key; - while (1) - { - JSONParser::Token token = GetToken(value); - - if (token == JSONParser::Token::String) - { - key.swap(value); - token = GetToken(value); - if (token == JSONParser::Token::Colon) - { - JSONValue::SP value_sp = ParseJSONValue(); - if (value_sp) - dict_up->SetObject(key, value_sp); - else - break; - } - } - else if (token == JSONParser::Token::ObjectEnd) - { - return JSONValue::SP(dict_up.release()); - } - else if (token == JSONParser::Token::Comma) - { - continue; - } - else - { - break; - } +int JSONParser::GetEscapedChar(bool &was_escaped) { + was_escaped = false; + const char ch = GetChar(); + if (ch == '\\') { + was_escaped = true; + const char ch2 = GetChar(); + switch (ch2) { + case '"': + case '\\': + case '/': + default: + break; + + case 'b': + return '\b'; + case 'f': + return '\f'; + case 'n': + return '\n'; + case 'r': + return '\r'; + case 't': + return '\t'; + case 'u': { + const int hi_byte = DecodeHexU8(); + const int lo_byte = DecodeHexU8(); + if (hi_byte >= 0 && lo_byte >= 0) + return hi_byte << 8 | lo_byte; + return -1; + } break; } - return JSONValue::SP(); + return ch2; + } + return ch; } -JSONValue::SP -JSONParser::ParseJSONArray () -{ - // The "JSONParser::Token::ObjectStart" token should have already been consumed - // by the time this function is called - std::unique_ptr<JSONArray> array_up(new JSONArray()); - - std::string value; - std::string key; - while (1) - { +JSONValue::SP JSONParser::ParseJSONObject() { + // The "JSONParser::Token::ObjectStart" token should have already been + // consumed + // by the time this function is called + std::unique_ptr<JSONObject> dict_up(new JSONObject()); + + std::string value; + std::string key; + while (1) { + JSONParser::Token token = GetToken(value); + + if (token == JSONParser::Token::String) { + key.swap(value); + token = GetToken(value); + if (token == JSONParser::Token::Colon) { JSONValue::SP value_sp = ParseJSONValue(); if (value_sp) - array_up->AppendObject(value_sp); + dict_up->SetObject(key, value_sp); else - break; + break; + } + } else if (token == JSONParser::Token::ObjectEnd) { + return JSONValue::SP(dict_up.release()); + } else if (token == JSONParser::Token::Comma) { + continue; + } else { + break; + } + } + return JSONValue::SP(); +} - JSONParser::Token token = GetToken(value); - if (token == JSONParser::Token::Comma) - { - continue; - } - else if (token == JSONParser::Token::ArrayEnd) - { - return JSONValue::SP(array_up.release()); - } - else - { - break; - } +JSONValue::SP JSONParser::ParseJSONArray() { + // The "JSONParser::Token::ObjectStart" token should have already been + // consumed + // by the time this function is called + std::unique_ptr<JSONArray> array_up(new JSONArray()); + + std::string value; + std::string key; + while (1) { + JSONValue::SP value_sp = ParseJSONValue(); + if (value_sp) + array_up->AppendObject(value_sp); + else + break; + + JSONParser::Token token = GetToken(value); + if (token == JSONParser::Token::Comma) { + continue; + } else if (token == JSONParser::Token::ArrayEnd) { + return JSONValue::SP(array_up.release()); + } else { + break; } - return JSONValue::SP(); + } + return JSONValue::SP(); } -JSONValue::SP -JSONParser::ParseJSONValue () -{ - std::string value; - const JSONParser::Token token = GetToken(value); - switch (token) - { - case JSONParser::Token::ObjectStart: - return ParseJSONObject(); - - case JSONParser::Token::ArrayStart: - return ParseJSONArray(); - - case JSONParser::Token::Integer: - { - if (value.front() == '-') - { - bool success = false; - int64_t sval = StringConvert::ToSInt64(value.c_str(), 0, 0, &success); - if (success) - return JSONValue::SP(new JSONNumber(sval)); - } - else - { - bool success = false; - uint64_t uval = StringConvert::ToUInt64(value.c_str(), 0, 0, &success); - if (success) - return JSONValue::SP(new JSONNumber(uval)); - } - } - break; - - case JSONParser::Token::Float: - { - bool success = false; - double val = StringConvert::ToDouble(value.c_str(), 0.0, &success); - if (success) - return JSONValue::SP(new JSONNumber(val)); - } - break; +JSONValue::SP JSONParser::ParseJSONValue() { + std::string value; + const JSONParser::Token token = GetToken(value); + switch (token) { + case JSONParser::Token::ObjectStart: + return ParseJSONObject(); + + case JSONParser::Token::ArrayStart: + return ParseJSONArray(); + + case JSONParser::Token::Integer: { + if (value.front() == '-') { + bool success = false; + int64_t sval = StringConvert::ToSInt64(value.c_str(), 0, 0, &success); + if (success) + return JSONValue::SP(new JSONNumber(sval)); + } else { + bool success = false; + uint64_t uval = StringConvert::ToUInt64(value.c_str(), 0, 0, &success); + if (success) + return JSONValue::SP(new JSONNumber(uval)); + } + } break; - case JSONParser::Token::String: - return JSONValue::SP(new JSONString(value)); + case JSONParser::Token::Float: { + bool success = false; + double val = StringConvert::ToDouble(value.c_str(), 0.0, &success); + if (success) + return JSONValue::SP(new JSONNumber(val)); + } break; - case JSONParser::Token::True: - return JSONValue::SP(new JSONTrue()); + case JSONParser::Token::String: + return JSONValue::SP(new JSONString(value)); - case JSONParser::Token::False: - return JSONValue::SP(new JSONFalse()); + case JSONParser::Token::True: + return JSONValue::SP(new JSONTrue()); - case JSONParser::Token::Null: - return JSONValue::SP(new JSONNull()); + case JSONParser::Token::False: + return JSONValue::SP(new JSONFalse()); - default: - break; - } - return JSONValue::SP(); - + case JSONParser::Token::Null: + return JSONValue::SP(new JSONNull()); + + default: + break; + } + return JSONValue::SP(); } |