1 //===---------------------StructuredData.cpp ---------------------*- C++ -*-===//
3 // The LLVM Compiler Infrastructure
5 // This file is distributed under the University of Illinois Open Source
6 // License. See LICENSE.TXT for details.
8 //===----------------------------------------------------------------------===//
10 #include "lldb/Core/StructuredData.h"
16 #include "lldb/Core/StreamString.h"
17 #include "lldb/Host/StringConvert.h"
18 #include "lldb/Utility/JSON.h"
20 using namespace lldb_private;
23 //----------------------------------------------------------------------
24 // Functions that use a JSONParser to parse JSON into StructuredData
25 //----------------------------------------------------------------------
26 static StructuredData::ObjectSP ParseJSONValue (JSONParser &json_parser);
27 static StructuredData::ObjectSP ParseJSONObject (JSONParser &json_parser);
28 static StructuredData::ObjectSP ParseJSONArray (JSONParser &json_parser);
30 static StructuredData::ObjectSP
31 ParseJSONObject (JSONParser &json_parser)
33 // The "JSONParser::Token::ObjectStart" token should have already been consumed
34 // by the time this function is called
35 std::unique_ptr<StructuredData::Dictionary> dict_up(new StructuredData::Dictionary());
41 JSONParser::Token token = json_parser.GetToken(value);
43 if (token == JSONParser::Token::String)
46 token = json_parser.GetToken(value);
47 if (token == JSONParser::Token::Colon)
49 StructuredData::ObjectSP value_sp = ParseJSONValue(json_parser);
51 dict_up->AddItem(key, value_sp);
56 else if (token == JSONParser::Token::ObjectEnd)
58 return StructuredData::ObjectSP(dict_up.release());
60 else if (token == JSONParser::Token::Comma)
69 return StructuredData::ObjectSP();
72 static StructuredData::ObjectSP
73 ParseJSONArray (JSONParser &json_parser)
75 // The "JSONParser::Token::ObjectStart" token should have already been consumed
76 // by the time this function is called
77 std::unique_ptr<StructuredData::Array> array_up(new StructuredData::Array());
83 StructuredData::ObjectSP value_sp = ParseJSONValue(json_parser);
85 array_up->AddItem(value_sp);
89 JSONParser::Token token = json_parser.GetToken(value);
90 if (token == JSONParser::Token::Comma)
94 else if (token == JSONParser::Token::ArrayEnd)
96 return StructuredData::ObjectSP(array_up.release());
103 return StructuredData::ObjectSP();
106 static StructuredData::ObjectSP
107 ParseJSONValue (JSONParser &json_parser)
110 const JSONParser::Token token = json_parser.GetToken(value);
113 case JSONParser::Token::ObjectStart:
114 return ParseJSONObject(json_parser);
116 case JSONParser::Token::ArrayStart:
117 return ParseJSONArray(json_parser);
119 case JSONParser::Token::Integer:
121 bool success = false;
122 uint64_t uval = StringConvert::ToUInt64(value.c_str(), 0, 0, &success);
124 return StructuredData::ObjectSP(new StructuredData::Integer(uval));
128 case JSONParser::Token::Float:
130 bool success = false;
131 double val = StringConvert::ToDouble(value.c_str(), 0.0, &success);
133 return StructuredData::ObjectSP(new StructuredData::Float(val));
137 case JSONParser::Token::String:
138 return StructuredData::ObjectSP(new StructuredData::String(value));
140 case JSONParser::Token::True:
141 case JSONParser::Token::False:
142 return StructuredData::ObjectSP(new StructuredData::Boolean(token == JSONParser::Token::True));
144 case JSONParser::Token::Null:
145 return StructuredData::ObjectSP(new StructuredData::Null());
150 return StructuredData::ObjectSP();
154 StructuredData::ObjectSP
155 StructuredData::ParseJSON (std::string json_text)
157 JSONParser json_parser(json_text.c_str());
158 StructuredData::ObjectSP object_sp = ParseJSONValue(json_parser);
162 StructuredData::ObjectSP
163 StructuredData::Object::GetObjectForDotSeparatedPath (llvm::StringRef path)
165 if (this->GetType() == Type::eTypeDictionary)
167 std::pair<llvm::StringRef, llvm::StringRef> match = path.split('.');
168 std::string key = match.first.str();
169 ObjectSP value = this->GetAsDictionary()->GetValueForKey (key.c_str());
172 // Do we have additional words to descend? If not, return the
173 // value we're at right now.
174 if (match.second.empty())
180 return value->GetObjectForDotSeparatedPath (match.second);
186 if (this->GetType() == Type::eTypeArray)
188 std::pair<llvm::StringRef, llvm::StringRef> match = path.split('[');
189 if (match.second.size() == 0)
191 return this->shared_from_this();
194 uint64_t val = strtoul (match.second.str().c_str(), NULL, 10);
197 return this->GetAsArray()->GetItemAtIndex(val);
202 return this->shared_from_this();
206 StructuredData::Object::DumpToStdout() const
210 printf("%s\n", stream.GetString().c_str());
214 StructuredData::Array::Dump(Stream &s) const
219 for (const auto &item_sp : m_items)
236 StructuredData::Integer::Dump (Stream &s) const
238 s.Printf ("%" PRIu64, m_value);
243 StructuredData::Float::Dump (Stream &s) const
245 s.Printf ("%lg", m_value);
249 StructuredData::Boolean::Dump (Stream &s) const
252 s.PutCString ("true");
254 s.PutCString ("false");
259 StructuredData::String::Dump (Stream &s) const
262 const size_t strsize = m_value.size();
263 for (size_t i = 0; i < strsize ; ++i)
265 char ch = m_value[i];
267 quoted.push_back ('\\');
268 quoted.push_back (ch);
270 s.Printf ("\"%s\"", quoted.c_str());
274 StructuredData::Dictionary::Dump (Stream &s) const
279 for (const auto &pair : m_dict)
286 s << "\"" << pair.first.AsCString() << "\" : ";
287 pair.second->Dump(s);
296 StructuredData::Null::Dump (Stream &s) const
302 StructuredData::Generic::Dump(Stream &s) const
304 s << "0x" << m_object;