1 //===-- StructuredData.h ----------------------------------------*- 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 #ifndef liblldb_StructuredData_h_
11 #define liblldb_StructuredData_h_
22 // Other libraries and framework includes
23 #include "llvm/ADT/StringRef.h"
26 #include "lldb/Core/ConstString.h"
27 #include "lldb/Core/Stream.h"
28 #include "lldb/lldb-defines.h"
30 namespace lldb_private {
32 //----------------------------------------------------------------------
33 /// @class StructuredData StructuredData.h "lldb/Core/StructuredData.h"
34 /// @brief A class which can hold structured data
36 /// The StructuredData class is designed to hold the data from a JSON
37 /// or plist style file -- a serialized data structure with dictionaries
38 /// (maps, hashes), arrays, and concrete values like integers, floating
39 /// point numbers, strings, booleans.
41 /// StructuredData does not presuppose any knowledge of the schema for
42 /// the data it is holding; it can parse JSON data, for instance, and
43 /// other parts of lldb can iterate through the parsed data set to find
44 /// keys and values that may be present.
45 //----------------------------------------------------------------------
47 class StructuredData {
58 typedef std::shared_ptr<Object> ObjectSP;
59 typedef std::shared_ptr<Array> ArraySP;
60 typedef std::shared_ptr<Integer> IntegerSP;
61 typedef std::shared_ptr<Float> FloatSP;
62 typedef std::shared_ptr<Boolean> BooleanSP;
63 typedef std::shared_ptr<String> StringSP;
64 typedef std::shared_ptr<Dictionary> DictionarySP;
65 typedef std::shared_ptr<Generic> GenericSP;
79 class Object : public std::enable_shared_from_this<Object> {
81 Object(Type t = Type::eTypeInvalid) : m_type(t) {}
83 virtual ~Object() = default;
85 virtual bool IsValid() const { return true; }
87 virtual void Clear() { m_type = Type::eTypeInvalid; }
89 Type GetType() const { return m_type; }
91 void SetType(Type t) { m_type = t; }
94 return ((m_type == Type::eTypeArray) ? static_cast<Array *>(this)
98 Dictionary *GetAsDictionary() {
99 return ((m_type == Type::eTypeDictionary)
100 ? static_cast<Dictionary *>(this)
104 Integer *GetAsInteger() {
105 return ((m_type == Type::eTypeInteger) ? static_cast<Integer *>(this)
109 uint64_t GetIntegerValue(uint64_t fail_value = 0) {
110 Integer *integer = GetAsInteger();
111 return ((integer != nullptr) ? integer->GetValue() : fail_value);
114 Float *GetAsFloat() {
115 return ((m_type == Type::eTypeFloat) ? static_cast<Float *>(this)
119 double GetFloatValue(double fail_value = 0.0) {
120 Float *f = GetAsFloat();
121 return ((f != nullptr) ? f->GetValue() : fail_value);
124 Boolean *GetAsBoolean() {
125 return ((m_type == Type::eTypeBoolean) ? static_cast<Boolean *>(this)
129 bool GetBooleanValue(bool fail_value = false) {
130 Boolean *b = GetAsBoolean();
131 return ((b != nullptr) ? b->GetValue() : fail_value);
134 String *GetAsString() {
135 return ((m_type == Type::eTypeString) ? static_cast<String *>(this)
139 std::string GetStringValue(const char *fail_value = nullptr) {
140 String *s = GetAsString();
142 return s->GetValue();
144 if (fail_value && fail_value[0])
145 return std::string(fail_value);
147 return std::string();
150 Generic *GetAsGeneric() {
151 return ((m_type == Type::eTypeGeneric) ? static_cast<Generic *>(this)
155 ObjectSP GetObjectForDotSeparatedPath(llvm::StringRef path);
157 void DumpToStdout(bool pretty_print = true) const;
159 virtual void Dump(Stream &s, bool pretty_print = true) const = 0;
165 class Array : public Object {
167 Array() : Object(Type::eTypeArray) {}
169 ~Array() override = default;
172 ForEach(std::function<bool(Object *object)> const &foreach_callback) const {
173 for (const auto &object_sp : m_items) {
174 if (foreach_callback(object_sp.get()) == false)
180 size_t GetSize() const { return m_items.size(); }
182 ObjectSP operator[](size_t idx) {
183 if (idx < m_items.size())
188 ObjectSP GetItemAtIndex(size_t idx) const {
189 assert(idx < GetSize());
190 if (idx < m_items.size())
195 template <class IntType>
196 bool GetItemAtIndexAsInteger(size_t idx, IntType &result) const {
197 ObjectSP value_sp = GetItemAtIndex(idx);
198 if (value_sp.get()) {
199 if (auto int_value = value_sp->GetAsInteger()) {
200 result = static_cast<IntType>(int_value->GetValue());
207 template <class IntType>
208 bool GetItemAtIndexAsInteger(size_t idx, IntType &result,
209 IntType default_val) const {
210 bool success = GetItemAtIndexAsInteger(idx, result);
212 result = default_val;
216 bool GetItemAtIndexAsString(size_t idx, std::string &result) const {
217 ObjectSP value_sp = GetItemAtIndex(idx);
218 if (value_sp.get()) {
219 if (auto string_value = value_sp->GetAsString()) {
220 result = string_value->GetValue();
227 bool GetItemAtIndexAsString(size_t idx, std::string &result,
228 const std::string &default_val) const {
229 bool success = GetItemAtIndexAsString(idx, result);
231 result = default_val;
235 bool GetItemAtIndexAsString(size_t idx, ConstString &result) const {
236 ObjectSP value_sp = GetItemAtIndex(idx);
237 if (value_sp.get()) {
238 if (auto string_value = value_sp->GetAsString()) {
239 result = ConstString(string_value->GetValue());
246 bool GetItemAtIndexAsString(size_t idx, ConstString &result,
247 const char *default_val) const {
248 bool success = GetItemAtIndexAsString(idx, result);
250 result.SetCString(default_val);
254 bool GetItemAtIndexAsDictionary(size_t idx, Dictionary *&result) const {
256 ObjectSP value_sp = GetItemAtIndex(idx);
257 if (value_sp.get()) {
258 result = value_sp->GetAsDictionary();
259 return (result != nullptr);
264 bool GetItemAtIndexAsArray(size_t idx, Array *&result) const {
266 ObjectSP value_sp = GetItemAtIndex(idx);
267 if (value_sp.get()) {
268 result = value_sp->GetAsArray();
269 return (result != nullptr);
274 void Push(ObjectSP item) { m_items.push_back(item); }
276 void AddItem(ObjectSP item) { m_items.push_back(item); }
278 void Dump(Stream &s, bool pretty_print = true) const override;
281 typedef std::vector<ObjectSP> collection;
285 class Integer : public Object {
287 Integer(uint64_t i = 0) : Object(Type::eTypeInteger), m_value(i) {}
289 ~Integer() override = default;
291 void SetValue(uint64_t value) { m_value = value; }
293 uint64_t GetValue() { return m_value; }
295 void Dump(Stream &s, bool pretty_print = true) const override;
301 class Float : public Object {
303 Float(double d = 0.0) : Object(Type::eTypeFloat), m_value(d) {}
305 ~Float() override = default;
307 void SetValue(double value) { m_value = value; }
309 double GetValue() { return m_value; }
311 void Dump(Stream &s, bool pretty_print = true) const override;
317 class Boolean : public Object {
319 Boolean(bool b = false) : Object(Type::eTypeBoolean), m_value(b) {}
321 ~Boolean() override = default;
323 void SetValue(bool value) { m_value = value; }
325 bool GetValue() { return m_value; }
327 void Dump(Stream &s, bool pretty_print = true) const override;
333 class String : public Object {
335 String(const char *cstr = nullptr) : Object(Type::eTypeString), m_value() {
340 String(const std::string &s) : Object(Type::eTypeString), m_value(s) {}
342 String(const std::string &&s) : Object(Type::eTypeString), m_value(s) {}
344 void SetValue(const std::string &string) { m_value = string; }
346 const std::string &GetValue() { return m_value; }
348 void Dump(Stream &s, bool pretty_print = true) const override;
354 class Dictionary : public Object {
356 Dictionary() : Object(Type::eTypeDictionary), m_dict() {}
358 ~Dictionary() override = default;
360 size_t GetSize() const { return m_dict.size(); }
362 void ForEach(std::function<bool(ConstString key, Object *object)> const
364 for (const auto &pair : m_dict) {
365 if (callback(pair.first, pair.second.get()) == false)
370 ObjectSP GetKeys() const {
371 ObjectSP object_sp(new Array());
372 Array *array = object_sp->GetAsArray();
373 collection::const_iterator iter;
374 for (iter = m_dict.begin(); iter != m_dict.end(); ++iter) {
375 ObjectSP key_object_sp(new String());
376 key_object_sp->GetAsString()->SetValue(iter->first.AsCString());
377 array->Push(key_object_sp);
382 ObjectSP GetValueForKey(llvm::StringRef key) const {
385 ConstString key_cs(key);
386 collection::const_iterator iter = m_dict.find(key_cs);
387 if (iter != m_dict.end())
388 value_sp = iter->second;
393 bool GetValueForKeyAsBoolean(llvm::StringRef key, bool &result) const {
394 bool success = false;
395 ObjectSP value_sp = GetValueForKey(key);
396 if (value_sp.get()) {
397 Boolean *result_ptr = value_sp->GetAsBoolean();
399 result = result_ptr->GetValue();
405 template <class IntType>
406 bool GetValueForKeyAsInteger(llvm::StringRef key, IntType &result) const {
407 ObjectSP value_sp = GetValueForKey(key);
409 if (auto int_value = value_sp->GetAsInteger()) {
410 result = static_cast<IntType>(int_value->GetValue());
417 template <class IntType>
418 bool GetValueForKeyAsInteger(llvm::StringRef key, IntType &result,
419 IntType default_val) const {
420 bool success = GetValueForKeyAsInteger<IntType>(key, result);
422 result = default_val;
426 bool GetValueForKeyAsString(llvm::StringRef key,
427 std::string &result) const {
428 ObjectSP value_sp = GetValueForKey(key);
429 if (value_sp.get()) {
430 if (auto string_value = value_sp->GetAsString()) {
431 result = string_value->GetValue();
438 bool GetValueForKeyAsString(llvm::StringRef key, std::string &result,
439 const char *default_val) const {
440 bool success = GetValueForKeyAsString(key, result);
443 result = default_val;
450 bool GetValueForKeyAsString(llvm::StringRef key,
451 ConstString &result) const {
452 ObjectSP value_sp = GetValueForKey(key);
453 if (value_sp.get()) {
454 if (auto string_value = value_sp->GetAsString()) {
455 result = ConstString(string_value->GetValue());
462 bool GetValueForKeyAsString(llvm::StringRef key, ConstString &result,
463 const char *default_val) const {
464 bool success = GetValueForKeyAsString(key, result);
466 result.SetCString(default_val);
470 bool GetValueForKeyAsDictionary(llvm::StringRef key,
471 Dictionary *&result) const {
473 ObjectSP value_sp = GetValueForKey(key);
474 if (value_sp.get()) {
475 result = value_sp->GetAsDictionary();
476 return (result != nullptr);
481 bool GetValueForKeyAsArray(llvm::StringRef key, Array *&result) const {
483 ObjectSP value_sp = GetValueForKey(key);
484 if (value_sp.get()) {
485 result = value_sp->GetAsArray();
486 return (result != nullptr);
491 bool HasKey(llvm::StringRef key) const {
492 ConstString key_cs(key);
493 collection::const_iterator search = m_dict.find(key_cs);
494 return search != m_dict.end();
497 void AddItem(llvm::StringRef key, ObjectSP value_sp) {
498 ConstString key_cs(key);
499 m_dict[key_cs] = value_sp;
502 void AddIntegerItem(llvm::StringRef key, uint64_t value) {
503 AddItem(key, ObjectSP(new Integer(value)));
506 void AddFloatItem(llvm::StringRef key, double value) {
507 AddItem(key, ObjectSP(new Float(value)));
510 void AddStringItem(llvm::StringRef key, std::string value) {
511 AddItem(key, ObjectSP(new String(std::move(value))));
514 void AddBooleanItem(llvm::StringRef key, bool value) {
515 AddItem(key, ObjectSP(new Boolean(value)));
518 void Dump(Stream &s, bool pretty_print = true) const override;
521 typedef std::map<ConstString, ObjectSP> collection;
525 class Null : public Object {
527 Null() : Object(Type::eTypeNull) {}
529 ~Null() override = default;
531 bool IsValid() const override { return false; }
533 void Dump(Stream &s, bool pretty_print = true) const override;
536 class Generic : public Object {
538 explicit Generic(void *object = nullptr)
539 : Object(Type::eTypeGeneric), m_object(object) {}
541 void SetValue(void *value) { m_object = value; }
543 void *GetValue() const { return m_object; }
545 bool IsValid() const override { return m_object != nullptr; }
547 void Dump(Stream &s, bool pretty_print = true) const override;
553 static ObjectSP ParseJSON(std::string json_text);
555 static ObjectSP ParseJSONFromFile(const FileSpec &file, Error &error);
558 } // namespace lldb_private
560 #endif // liblldb_StructuredData_h_