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_
13 #include "llvm/ADT/StringRef.h"
15 #include "lldb/Utility/ConstString.h"
16 #include "lldb/Utility/FileSpec.h" // for FileSpec
17 #include "lldb/lldb-enumerations.h" // for StructuredDataType
19 #include <cassert> // for assert
20 #include <cstddef> // for size_t
21 #include <cstdint> // for uint64_t
26 #include <type_traits> // for move
30 namespace lldb_private {
33 namespace lldb_private {
37 namespace lldb_private {
39 //----------------------------------------------------------------------
40 /// @class StructuredData StructuredData.h "lldb/Utility/StructuredData.h"
41 /// A class which can hold structured data
43 /// The StructuredData class is designed to hold the data from a JSON or plist
44 /// style file -- a serialized data structure with dictionaries (maps,
45 /// hashes), arrays, and concrete values like integers, floating point
46 /// numbers, strings, booleans.
48 /// StructuredData does not presuppose any knowledge of the schema for the
49 /// data it is holding; it can parse JSON data, for instance, and other parts
50 /// of lldb can iterate through the parsed data set to find keys and values
51 /// that may be present.
52 //----------------------------------------------------------------------
54 class StructuredData {
65 typedef std::shared_ptr<Object> ObjectSP;
66 typedef std::shared_ptr<Array> ArraySP;
67 typedef std::shared_ptr<Integer> IntegerSP;
68 typedef std::shared_ptr<Float> FloatSP;
69 typedef std::shared_ptr<Boolean> BooleanSP;
70 typedef std::shared_ptr<String> StringSP;
71 typedef std::shared_ptr<Dictionary> DictionarySP;
72 typedef std::shared_ptr<Generic> GenericSP;
74 class Object : public std::enable_shared_from_this<Object> {
76 Object(lldb::StructuredDataType t = lldb::eStructuredDataTypeInvalid)
79 virtual ~Object() = default;
81 virtual bool IsValid() const { return true; }
83 virtual void Clear() { m_type = lldb::eStructuredDataTypeInvalid; }
85 lldb::StructuredDataType GetType() const { return m_type; }
87 void SetType(lldb::StructuredDataType t) { m_type = t; }
90 return ((m_type == lldb::eStructuredDataTypeArray)
91 ? static_cast<Array *>(this)
95 Dictionary *GetAsDictionary() {
96 return ((m_type == lldb::eStructuredDataTypeDictionary)
97 ? static_cast<Dictionary *>(this)
101 Integer *GetAsInteger() {
102 return ((m_type == lldb::eStructuredDataTypeInteger)
103 ? static_cast<Integer *>(this)
107 uint64_t GetIntegerValue(uint64_t fail_value = 0) {
108 Integer *integer = GetAsInteger();
109 return ((integer != nullptr) ? integer->GetValue() : fail_value);
112 Float *GetAsFloat() {
113 return ((m_type == lldb::eStructuredDataTypeFloat)
114 ? static_cast<Float *>(this)
118 double GetFloatValue(double fail_value = 0.0) {
119 Float *f = GetAsFloat();
120 return ((f != nullptr) ? f->GetValue() : fail_value);
123 Boolean *GetAsBoolean() {
124 return ((m_type == lldb::eStructuredDataTypeBoolean)
125 ? 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 == lldb::eStructuredDataTypeString)
136 ? static_cast<String *>(this)
140 llvm::StringRef GetStringValue(const char *fail_value = nullptr) {
141 String *s = GetAsString();
143 return s->GetValue();
148 Generic *GetAsGeneric() {
149 return ((m_type == lldb::eStructuredDataTypeGeneric)
150 ? static_cast<Generic *>(this)
154 ObjectSP GetObjectForDotSeparatedPath(llvm::StringRef path);
156 void DumpToStdout(bool pretty_print = true) const;
158 virtual void Dump(Stream &s, bool pretty_print = true) const = 0;
161 lldb::StructuredDataType m_type;
164 class Array : public Object {
166 Array() : Object(lldb::eStructuredDataTypeArray) {}
168 ~Array() override = default;
171 ForEach(std::function<bool(Object *object)> const &foreach_callback) const {
172 for (const auto &object_sp : m_items) {
173 if (foreach_callback(object_sp.get()) == false)
179 size_t GetSize() const { return m_items.size(); }
181 ObjectSP operator[](size_t idx) {
182 if (idx < m_items.size())
187 ObjectSP GetItemAtIndex(size_t idx) const {
188 assert(idx < GetSize());
189 if (idx < m_items.size())
194 template <class IntType>
195 bool GetItemAtIndexAsInteger(size_t idx, IntType &result) const {
196 ObjectSP value_sp = GetItemAtIndex(idx);
197 if (value_sp.get()) {
198 if (auto int_value = value_sp->GetAsInteger()) {
199 result = static_cast<IntType>(int_value->GetValue());
206 template <class IntType>
207 bool GetItemAtIndexAsInteger(size_t idx, IntType &result,
208 IntType default_val) const {
209 bool success = GetItemAtIndexAsInteger(idx, result);
211 result = default_val;
215 bool GetItemAtIndexAsString(size_t idx, llvm::StringRef &result) const {
216 ObjectSP value_sp = GetItemAtIndex(idx);
217 if (value_sp.get()) {
218 if (auto string_value = value_sp->GetAsString()) {
219 result = string_value->GetValue();
226 bool GetItemAtIndexAsString(size_t idx, llvm::StringRef &result,
227 llvm::StringRef default_val) const {
228 bool success = GetItemAtIndexAsString(idx, result);
230 result = default_val;
234 bool GetItemAtIndexAsString(size_t idx, ConstString &result) const {
235 ObjectSP value_sp = GetItemAtIndex(idx);
236 if (value_sp.get()) {
237 if (auto string_value = value_sp->GetAsString()) {
238 result = ConstString(string_value->GetValue());
245 bool GetItemAtIndexAsString(size_t idx, ConstString &result,
246 const char *default_val) const {
247 bool success = GetItemAtIndexAsString(idx, result);
249 result.SetCString(default_val);
253 bool GetItemAtIndexAsDictionary(size_t idx, Dictionary *&result) const {
255 ObjectSP value_sp = GetItemAtIndex(idx);
256 if (value_sp.get()) {
257 result = value_sp->GetAsDictionary();
258 return (result != nullptr);
263 bool GetItemAtIndexAsArray(size_t idx, Array *&result) const {
265 ObjectSP value_sp = GetItemAtIndex(idx);
266 if (value_sp.get()) {
267 result = value_sp->GetAsArray();
268 return (result != nullptr);
273 void Push(ObjectSP item) { m_items.push_back(item); }
275 void AddItem(ObjectSP item) { m_items.push_back(item); }
277 void Dump(Stream &s, bool pretty_print = true) const override;
280 typedef std::vector<ObjectSP> collection;
284 class Integer : public Object {
286 Integer(uint64_t i = 0)
287 : Object(lldb::eStructuredDataTypeInteger), 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)
304 : Object(lldb::eStructuredDataTypeFloat), m_value(d) {}
306 ~Float() override = default;
308 void SetValue(double value) { m_value = value; }
310 double GetValue() { return m_value; }
312 void Dump(Stream &s, bool pretty_print = true) const override;
318 class Boolean : public Object {
320 Boolean(bool b = false)
321 : Object(lldb::eStructuredDataTypeBoolean), m_value(b) {}
323 ~Boolean() override = default;
325 void SetValue(bool value) { m_value = value; }
327 bool GetValue() { return m_value; }
329 void Dump(Stream &s, bool pretty_print = true) const override;
335 class String : public Object {
337 String() : Object(lldb::eStructuredDataTypeString) {}
338 explicit String(llvm::StringRef S)
339 : Object(lldb::eStructuredDataTypeString), m_value(S) {}
341 void SetValue(llvm::StringRef S) { m_value = S; }
343 llvm::StringRef GetValue() { return m_value; }
345 void Dump(Stream &s, bool pretty_print = true) const override;
351 class Dictionary : public Object {
353 Dictionary() : Object(lldb::eStructuredDataTypeDictionary), m_dict() {}
355 ~Dictionary() override = default;
357 size_t GetSize() const { return m_dict.size(); }
359 void ForEach(std::function<bool(ConstString key, Object *object)> const
361 for (const auto &pair : m_dict) {
362 if (callback(pair.first, pair.second.get()) == false)
367 ObjectSP GetKeys() const {
368 auto object_sp = std::make_shared<Array>();
369 collection::const_iterator iter;
370 for (iter = m_dict.begin(); iter != m_dict.end(); ++iter) {
371 auto key_object_sp = std::make_shared<String>();
372 key_object_sp->SetValue(iter->first.AsCString());
373 object_sp->Push(key_object_sp);
378 ObjectSP GetValueForKey(llvm::StringRef key) const {
381 ConstString key_cs(key);
382 collection::const_iterator iter = m_dict.find(key_cs);
383 if (iter != m_dict.end())
384 value_sp = iter->second;
389 bool GetValueForKeyAsBoolean(llvm::StringRef key, bool &result) const {
390 bool success = false;
391 ObjectSP value_sp = GetValueForKey(key);
392 if (value_sp.get()) {
393 Boolean *result_ptr = value_sp->GetAsBoolean();
395 result = result_ptr->GetValue();
401 template <class IntType>
402 bool GetValueForKeyAsInteger(llvm::StringRef key, IntType &result) const {
403 ObjectSP value_sp = GetValueForKey(key);
405 if (auto int_value = value_sp->GetAsInteger()) {
406 result = static_cast<IntType>(int_value->GetValue());
413 template <class IntType>
414 bool GetValueForKeyAsInteger(llvm::StringRef key, IntType &result,
415 IntType default_val) const {
416 bool success = GetValueForKeyAsInteger<IntType>(key, result);
418 result = default_val;
422 bool GetValueForKeyAsString(llvm::StringRef key,
423 llvm::StringRef &result) const {
424 ObjectSP value_sp = GetValueForKey(key);
425 if (value_sp.get()) {
426 if (auto string_value = value_sp->GetAsString()) {
427 result = string_value->GetValue();
434 bool GetValueForKeyAsString(llvm::StringRef key, llvm::StringRef &result,
435 const char *default_val) const {
436 bool success = GetValueForKeyAsString(key, result);
439 result = default_val;
441 result = llvm::StringRef();
446 bool GetValueForKeyAsString(llvm::StringRef key,
447 ConstString &result) const {
448 ObjectSP value_sp = GetValueForKey(key);
449 if (value_sp.get()) {
450 if (auto string_value = value_sp->GetAsString()) {
451 result = ConstString(string_value->GetValue());
458 bool GetValueForKeyAsString(llvm::StringRef key, ConstString &result,
459 const char *default_val) const {
460 bool success = GetValueForKeyAsString(key, result);
462 result.SetCString(default_val);
466 bool GetValueForKeyAsDictionary(llvm::StringRef key,
467 Dictionary *&result) const {
469 ObjectSP value_sp = GetValueForKey(key);
470 if (value_sp.get()) {
471 result = value_sp->GetAsDictionary();
472 return (result != nullptr);
477 bool GetValueForKeyAsArray(llvm::StringRef key, Array *&result) const {
479 ObjectSP value_sp = GetValueForKey(key);
480 if (value_sp.get()) {
481 result = value_sp->GetAsArray();
482 return (result != nullptr);
487 bool HasKey(llvm::StringRef key) const {
488 ConstString key_cs(key);
489 collection::const_iterator search = m_dict.find(key_cs);
490 return search != m_dict.end();
493 void AddItem(llvm::StringRef key, ObjectSP value_sp) {
494 ConstString key_cs(key);
495 m_dict[key_cs] = value_sp;
498 void AddIntegerItem(llvm::StringRef key, uint64_t value) {
499 AddItem(key, std::make_shared<Integer>(value));
502 void AddFloatItem(llvm::StringRef key, double value) {
503 AddItem(key, std::make_shared<Float>(value));
506 void AddStringItem(llvm::StringRef key, llvm::StringRef value) {
507 AddItem(key, std::make_shared<String>(std::move(value)));
510 void AddBooleanItem(llvm::StringRef key, bool value) {
511 AddItem(key, std::make_shared<Boolean>(value));
514 void Dump(Stream &s, bool pretty_print = true) const override;
517 typedef std::map<ConstString, ObjectSP> collection;
521 class Null : public Object {
523 Null() : Object(lldb::eStructuredDataTypeNull) {}
525 ~Null() override = default;
527 bool IsValid() const override { return false; }
529 void Dump(Stream &s, bool pretty_print = true) const override;
532 class Generic : public Object {
534 explicit Generic(void *object = nullptr)
535 : Object(lldb::eStructuredDataTypeGeneric), m_object(object) {}
537 void SetValue(void *value) { m_object = value; }
539 void *GetValue() const { return m_object; }
541 bool IsValid() const override { return m_object != nullptr; }
543 void Dump(Stream &s, bool pretty_print = true) const override;
549 static ObjectSP ParseJSON(std::string json_text);
551 static ObjectSP ParseJSONFromFile(const FileSpec &file, Status &error);
554 } // namespace lldb_private
556 #endif // liblldb_StructuredData_h_