summaryrefslogtreecommitdiffstats
path: root/contrib/llvm/tools/lldb/source/Utility/JSON.cpp
diff options
context:
space:
mode:
Diffstat (limited to 'contrib/llvm/tools/lldb/source/Utility/JSON.cpp')
-rw-r--r--contrib/llvm/tools/lldb/source/Utility/JSON.cpp1083
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();
}
OpenPOWER on IntegriCloud