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/lldb-defines.h"
27 #include "lldb/Core/ConstString.h"
28 #include "lldb/Core/Stream.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 //----------------------------------------------------------------------
59 typedef std::shared_ptr<Object> ObjectSP;
60 typedef std::shared_ptr<Array> ArraySP;
61 typedef std::shared_ptr<Integer> IntegerSP;
62 typedef std::shared_ptr<Float> FloatSP;
63 typedef std::shared_ptr<Boolean> BooleanSP;
64 typedef std::shared_ptr<String> StringSP;
65 typedef std::shared_ptr<Dictionary> DictionarySP;
66 typedef std::shared_ptr<Generic> GenericSP;
82 public std::enable_shared_from_this<Object>
86 Object (Type t = Type::eTypeInvalid) :
91 virtual ~Object() = default;
102 m_type = Type::eTypeInvalid;
120 return ((m_type == Type::eTypeArray) ? static_cast<Array *>(this) : nullptr);
126 return ((m_type == Type::eTypeDictionary) ? static_cast<Dictionary *>(this) : nullptr);
132 return ((m_type == Type::eTypeInteger) ? static_cast<Integer *>(this) : nullptr);
136 GetIntegerValue (uint64_t fail_value = 0)
138 Integer *integer = GetAsInteger ();
139 return ((integer != nullptr) ? integer->GetValue() : fail_value);
145 return ((m_type == Type::eTypeFloat) ? static_cast<Float *>(this) : nullptr);
149 GetFloatValue (double fail_value = 0.0)
151 Float *f = GetAsFloat ();
152 return ((f != nullptr) ? f->GetValue() : fail_value);
158 return ((m_type == Type::eTypeBoolean) ? static_cast<Boolean *>(this) : nullptr);
162 GetBooleanValue (bool fail_value = false)
164 Boolean *b = GetAsBoolean ();
165 return ((b != nullptr) ? b->GetValue() : fail_value);
171 return ((m_type == Type::eTypeString) ? static_cast<String *>(this) : nullptr);
175 GetStringValue(const char *fail_value = nullptr)
177 String *s = GetAsString ();
179 return s->GetValue();
181 if (fail_value && fail_value[0])
182 return std::string(fail_value);
184 return std::string();
190 return ((m_type == Type::eTypeGeneric) ? static_cast<Generic *>(this) : nullptr);
194 GetObjectForDotSeparatedPath (llvm::StringRef path);
196 void DumpToStdout() const;
199 Dump (Stream &s) const = 0;
205 class Array : public Object
209 Object (Type::eTypeArray)
213 ~Array() override = default;
216 ForEach (std::function <bool(Object* object)> const &foreach_callback) const
218 for (const auto &object_sp : m_items)
220 if (foreach_callback(object_sp.get()) == false)
229 return m_items.size();
233 operator[](size_t idx)
235 if (idx < m_items.size())
241 GetItemAtIndex(size_t idx) const
243 assert(idx < GetSize());
244 if (idx < m_items.size())
249 template <class IntType>
251 GetItemAtIndexAsInteger(size_t idx, IntType &result) const
253 ObjectSP value_sp = GetItemAtIndex(idx);
256 if (auto int_value = value_sp->GetAsInteger())
258 result = static_cast<IntType>(int_value->GetValue());
265 template <class IntType>
267 GetItemAtIndexAsInteger(size_t idx, IntType &result, IntType default_val) const
269 bool success = GetItemAtIndexAsInteger(idx, result);
271 result = default_val;
276 GetItemAtIndexAsString(size_t idx, std::string &result) const
278 ObjectSP value_sp = GetItemAtIndex(idx);
281 if (auto string_value = value_sp->GetAsString())
283 result = string_value->GetValue();
291 GetItemAtIndexAsString(size_t idx, std::string &result, const std::string &default_val) const
293 bool success = GetItemAtIndexAsString(idx, result);
295 result = default_val;
300 GetItemAtIndexAsString(size_t idx, ConstString &result) const
302 ObjectSP value_sp = GetItemAtIndex(idx);
303 if (value_sp.get()) {
304 if (auto string_value = value_sp->GetAsString())
306 result = ConstString(string_value->GetValue());
314 GetItemAtIndexAsString(size_t idx, ConstString &result, const char *default_val) const
316 bool success = GetItemAtIndexAsString(idx, result);
318 result.SetCString(default_val);
323 GetItemAtIndexAsDictionary(size_t idx, Dictionary *&result) const
326 ObjectSP value_sp = GetItemAtIndex(idx);
329 result = value_sp->GetAsDictionary();
330 return (result != nullptr);
336 GetItemAtIndexAsArray(size_t idx, Array *&result) const
339 ObjectSP value_sp = GetItemAtIndex(idx);
342 result = value_sp->GetAsArray();
343 return (result != nullptr);
351 m_items.push_back(item);
355 AddItem(ObjectSP item)
357 m_items.push_back(item);
360 void Dump(Stream &s) const override;
363 typedef std::vector<ObjectSP> collection;
367 class Integer : public Object
370 Integer (uint64_t i = 0) :
371 Object (Type::eTypeInteger),
376 ~Integer() override = default;
379 SetValue (uint64_t value)
390 void Dump(Stream &s) const override;
396 class Float : public Object
399 Float (double d = 0.0) :
400 Object (Type::eTypeFloat),
405 ~Float() override = default;
408 SetValue (double value)
419 void Dump(Stream &s) const override;
425 class Boolean : public Object
428 Boolean (bool b = false) :
429 Object (Type::eTypeBoolean),
434 ~Boolean() override = default;
437 SetValue (bool value)
448 void Dump(Stream &s) const override;
454 class String : public Object
457 String(const char *cstr = nullptr) :
458 Object (Type::eTypeString),
465 String (const std::string &s) :
466 Object (Type::eTypeString),
471 String (const std::string &&s) :
472 Object (Type::eTypeString),
478 SetValue (const std::string &string)
489 void Dump(Stream &s) const override;
495 class Dictionary : public Object
500 Object (Type::eTypeDictionary),
505 ~Dictionary() override = default;
510 return m_dict.size();
514 ForEach (std::function <bool(ConstString key, Object* object)> const &callback) const
516 for (const auto &pair : m_dict)
518 if (callback (pair.first, pair.second.get()) == false)
526 ObjectSP object_sp(new Array ());
527 Array *array = object_sp->GetAsArray();
528 collection::const_iterator iter;
529 for (iter = m_dict.begin(); iter != m_dict.end(); ++iter)
531 ObjectSP key_object_sp(new String());
532 key_object_sp->GetAsString()->SetValue(iter->first.AsCString());
533 array->Push(key_object_sp);
539 GetValueForKey(llvm::StringRef key) const
544 ConstString key_cs(key);
545 for (collection::const_iterator iter = m_dict.begin(); iter != m_dict.end(); ++iter)
547 if (key_cs == iter->first)
549 value_sp = iter->second;
557 template <class IntType>
559 GetValueForKeyAsInteger(llvm::StringRef key, IntType &result) const
561 ObjectSP value_sp = GetValueForKey(key);
563 if (auto int_value = value_sp->GetAsInteger())
565 result = static_cast<IntType>(int_value->GetValue());
572 template <class IntType>
574 GetValueForKeyAsInteger(llvm::StringRef key, IntType &result, IntType default_val) const
576 bool success = GetValueForKeyAsInteger<IntType>(key, result);
578 result = default_val;
583 GetValueForKeyAsString(llvm::StringRef key, std::string &result) const
585 ObjectSP value_sp = GetValueForKey(key);
588 if (auto string_value = value_sp->GetAsString())
590 result = string_value->GetValue();
598 GetValueForKeyAsString(llvm::StringRef key, std::string &result, const char *default_val) const
600 bool success = GetValueForKeyAsString(key, result);
604 result = default_val;
612 GetValueForKeyAsString(llvm::StringRef key, ConstString &result) const
614 ObjectSP value_sp = GetValueForKey(key);
617 if (auto string_value = value_sp->GetAsString())
619 result = ConstString(string_value->GetValue());
627 GetValueForKeyAsString(llvm::StringRef key, ConstString &result, const char *default_val) const
629 bool success = GetValueForKeyAsString(key, result);
631 result.SetCString(default_val);
636 GetValueForKeyAsDictionary(llvm::StringRef key, Dictionary *&result) const
639 ObjectSP value_sp = GetValueForKey(key);
642 result = value_sp->GetAsDictionary();
643 return (result != nullptr);
649 GetValueForKeyAsArray(llvm::StringRef key, Array *&result) const
652 ObjectSP value_sp = GetValueForKey(key);
655 result = value_sp->GetAsArray();
656 return (result != nullptr);
662 HasKey(llvm::StringRef key) const
664 ConstString key_cs(key);
665 collection::const_iterator search = m_dict.find(key_cs);
666 return search != m_dict.end();
670 AddItem (llvm::StringRef key, ObjectSP value_sp)
672 ConstString key_cs(key);
673 m_dict[key_cs] = value_sp;
677 AddIntegerItem (llvm::StringRef key, uint64_t value)
679 AddItem (key, ObjectSP (new Integer(value)));
683 AddFloatItem (llvm::StringRef key, double value)
685 AddItem (key, ObjectSP (new Float(value)));
689 AddStringItem (llvm::StringRef key, std::string value)
691 AddItem (key, ObjectSP (new String(std::move(value))));
695 AddBooleanItem (llvm::StringRef key, bool value)
697 AddItem (key, ObjectSP (new Boolean(value)));
700 void Dump(Stream &s) const override;
703 typedef std::map<ConstString, ObjectSP> collection;
707 class Null : public Object
711 Object (Type::eTypeNull)
715 ~Null() override = default;
718 IsValid() const override
723 void Dump(Stream &s) const override;
726 class Generic : public Object
729 explicit Generic(void *object = nullptr) :
730 Object (Type::eTypeGeneric),
736 SetValue(void *value)
748 IsValid() const override
750 return m_object != nullptr;
753 void Dump(Stream &s) const override;
760 ParseJSON (std::string json_text);
763 } // namespace lldb_private
765 #endif // liblldb_StructuredData_h_