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 #include "llvm/ADT/StringRef.h"
24 // Other libraries and framework includes
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 //----------------------------------------------------------------------
60 typedef std::shared_ptr<Object> ObjectSP;
61 typedef std::shared_ptr<Array> ArraySP;
62 typedef std::shared_ptr<Integer> IntegerSP;
63 typedef std::shared_ptr<Float> FloatSP;
64 typedef std::shared_ptr<Boolean> BooleanSP;
65 typedef std::shared_ptr<String> StringSP;
66 typedef std::shared_ptr<Dictionary> DictionarySP;
67 typedef std::shared_ptr<Generic> GenericSP;
83 public std::enable_shared_from_this<Object>
87 Object (Type t = Type::eTypeInvalid) :
105 m_type = Type::eTypeInvalid;
123 if (m_type == Type::eTypeArray)
124 return (Array *)this;
131 if (m_type == Type::eTypeDictionary)
132 return (Dictionary *)this;
139 if (m_type == Type::eTypeInteger)
140 return (Integer *)this;
145 GetIntegerValue (uint64_t fail_value = 0)
147 Integer *integer = GetAsInteger ();
149 return integer->GetValue();
156 if (m_type == Type::eTypeFloat)
157 return (Float *)this;
162 GetFloatValue (double fail_value = 0.0)
164 Float *f = GetAsFloat ();
166 return f->GetValue();
173 if (m_type == Type::eTypeBoolean)
174 return (Boolean *)this;
179 GetBooleanValue (bool fail_value = false)
181 Boolean *b = GetAsBoolean ();
183 return b->GetValue();
190 if (m_type == Type::eTypeString)
191 return (String *)this;
196 GetStringValue(const char *fail_value = NULL)
198 String *s = GetAsString ();
200 return s->GetValue();
202 if (fail_value && fail_value[0])
203 return std::string(fail_value);
205 return std::string();
211 if (m_type == Type::eTypeGeneric)
212 return (Generic *)this;
217 GetObjectForDotSeparatedPath (llvm::StringRef path);
219 void DumpToStdout() const;
222 Dump (Stream &s) const = 0;
228 class Array : public Object
232 Object (Type::eTypeArray)
242 ForEach (std::function <bool(Object* object)> const &foreach_callback) const
244 for (const auto &object_sp : m_items)
246 if (foreach_callback(object_sp.get()) == false)
256 return m_items.size();
260 operator[](size_t idx)
262 if (idx < m_items.size())
268 GetItemAtIndex(size_t idx) const
270 assert(idx < GetSize());
271 if (idx < m_items.size())
276 template <class IntType>
278 GetItemAtIndexAsInteger(size_t idx, IntType &result) const
280 ObjectSP value = GetItemAtIndex(idx);
281 if (auto int_value = value->GetAsInteger())
283 result = static_cast<IntType>(int_value->GetValue());
289 template <class IntType>
291 GetItemAtIndexAsInteger(size_t idx, IntType &result, IntType default_val) const
293 bool success = GetItemAtIndexAsInteger(idx, result);
295 result = default_val;
300 GetItemAtIndexAsString(size_t idx, std::string &result) const
302 ObjectSP value = GetItemAtIndex(idx);
303 if (auto string_value = value->GetAsString())
305 result = string_value->GetValue();
312 GetItemAtIndexAsString(size_t idx, std::string &result, const std::string &default_val) const
314 bool success = GetItemAtIndexAsString(idx, result);
316 result = default_val;
321 GetItemAtIndexAsString(size_t idx, ConstString &result) const
323 ObjectSP value = GetItemAtIndex(idx);
326 if (auto string_value = value->GetAsString())
328 result = ConstString(string_value->GetValue());
335 GetItemAtIndexAsString(size_t idx, ConstString &result, const char *default_val) const
337 bool success = GetItemAtIndexAsString(idx, result);
339 result.SetCString(default_val);
344 GetItemAtIndexAsDictionary(size_t idx, Dictionary *&result) const
346 ObjectSP value = GetItemAtIndex(idx);
347 result = value->GetAsDictionary();
348 return (result != nullptr);
352 GetItemAtIndexAsArray(size_t idx, Array *&result) const
354 ObjectSP value = GetItemAtIndex(idx);
355 result = value->GetAsArray();
356 return (result != nullptr);
362 m_items.push_back(item);
366 AddItem(ObjectSP item)
368 m_items.push_back(item);
371 void Dump(Stream &s) const override;
374 typedef std::vector<ObjectSP> collection;
379 class Integer : public Object
382 Integer (uint64_t i = 0) :
383 Object (Type::eTypeInteger),
393 SetValue (uint64_t value)
404 void Dump(Stream &s) const override;
410 class Float : public Object
413 Float (double d = 0.0) :
414 Object (Type::eTypeFloat),
424 SetValue (double value)
435 void Dump(Stream &s) const override;
441 class Boolean : public Object
444 Boolean (bool b = false) :
445 Object (Type::eTypeBoolean),
455 SetValue (bool value)
466 void Dump(Stream &s) const override;
474 class String : public Object
477 String (const char *cstr = NULL) :
478 Object (Type::eTypeString),
485 String (const std::string &s) :
486 Object (Type::eTypeString),
491 String (const std::string &&s) :
492 Object (Type::eTypeString),
498 SetValue (const std::string &string)
509 void Dump(Stream &s) const override;
515 class Dictionary : public Object
520 Object (Type::eTypeDictionary),
525 virtual ~Dictionary()
532 return m_dict.size();
536 ForEach (std::function <bool(ConstString key, Object* object)> const &callback) const
538 for (const auto &pair : m_dict)
540 if (callback (pair.first, pair.second.get()) == false)
548 ObjectSP object_sp(new Array ());
549 Array *array = object_sp->GetAsArray();
550 collection::const_iterator iter;
551 for (iter = m_dict.begin(); iter != m_dict.end(); ++iter)
553 ObjectSP key_object_sp(new String());
554 key_object_sp->GetAsString()->SetValue(iter->first.AsCString());
555 array->Push(key_object_sp);
561 GetValueForKey(llvm::StringRef key) const
566 ConstString key_cs(key);
567 for (collection::const_iterator iter = m_dict.begin(); iter != m_dict.end(); ++iter)
569 if (key_cs == iter->first)
571 value_sp = iter->second;
579 template <class IntType>
581 GetValueForKeyAsInteger(llvm::StringRef key, IntType &result) const
583 ObjectSP value = GetValueForKey(key);
586 if (auto int_value = value->GetAsInteger())
588 result = static_cast<IntType>(int_value->GetValue());
594 template <class IntType>
596 GetValueForKeyAsInteger(llvm::StringRef key, IntType &result, IntType default_val) const
598 bool success = GetValueForKeyAsInteger<IntType>(key, result);
600 result = default_val;
605 GetValueForKeyAsString(llvm::StringRef key, std::string &result) const
607 ObjectSP value = GetValueForKey(key);
610 if (auto string_value = value->GetAsString())
612 result = string_value->GetValue();
619 GetValueForKeyAsString(llvm::StringRef key, std::string &result, const char *default_val) const
621 bool success = GetValueForKeyAsString(key, result);
625 result = default_val;
633 GetValueForKeyAsString(llvm::StringRef key, ConstString &result) const
635 ObjectSP value = GetValueForKey(key);
638 if (auto string_value = value->GetAsString())
640 result = ConstString(string_value->GetValue());
647 GetValueForKeyAsString(llvm::StringRef key, ConstString &result, const char *default_val) const
649 bool success = GetValueForKeyAsString(key, result);
651 result.SetCString(default_val);
656 GetValueForKeyAsDictionary(llvm::StringRef key, Dictionary *&result) const
659 ObjectSP value = GetValueForKey(key);
662 result = value->GetAsDictionary();
667 GetValueForKeyAsArray(llvm::StringRef key, Array *&result) const
670 ObjectSP value = GetValueForKey(key);
673 result = value->GetAsArray();
678 HasKey(llvm::StringRef key) const
680 ConstString key_cs(key);
681 collection::const_iterator search = m_dict.find(key_cs);
682 return search != m_dict.end();
686 AddItem (llvm::StringRef key, ObjectSP value)
688 ConstString key_cs(key);
689 m_dict[key_cs] = value;
693 AddIntegerItem (llvm::StringRef key, uint64_t value)
695 AddItem (key, ObjectSP (new Integer(value)));
699 AddFloatItem (llvm::StringRef key, double value)
701 AddItem (key, ObjectSP (new Float(value)));
705 AddStringItem (llvm::StringRef key, std::string value)
707 AddItem (key, ObjectSP (new String(std::move(value))));
711 AddBooleanItem (llvm::StringRef key, bool value)
713 AddItem (key, ObjectSP (new Boolean(value)));
716 void Dump(Stream &s) const override;
719 typedef std::map<ConstString, ObjectSP> collection;
723 class Null : public Object
727 Object (Type::eTypeNull)
736 IsValid() const override
741 void Dump(Stream &s) const override;
746 class Generic : public Object
749 explicit Generic(void *object = nullptr) :
750 Object (Type::eTypeGeneric),
756 SetValue(void *value)
768 IsValid() const override
770 return m_object != nullptr;
773 void Dump(Stream &s) const override;
780 ParseJSON (std::string json_text);
782 }; // class StructuredData
785 } // namespace lldb_private
787 #endif // liblldb_StructuredData_h_