xref: /NextBSD/contrib/llvm/tools/lldb/include/lldb/Core/StructuredData.h (revision 84d351007654069f9643c8e4b4802a7f5f08ee42)
1 //===-- StructuredData.h ----------------------------------------*- C++ -*-===//
2 //
3 //                     The LLVM Compiler Infrastructure
4 //
5 // This file is distributed under the University of Illinois Open Source
6 // License. See LICENSE.TXT for details.
7 //
8 //===----------------------------------------------------------------------===//
9 
10 #ifndef liblldb_StructuredData_h_
11 #define liblldb_StructuredData_h_
12 
13 // C Includes
14 // C++ Includes
15 
16 #include <functional>
17 #include <map>
18 #include <string>
19 #include <utility>
20 #include <vector>
21 
22 #include "llvm/ADT/StringRef.h"
23 
24 // Other libraries and framework includes
25 // Project includes
26 #include "lldb/lldb-defines.h"
27 #include "lldb/Core/ConstString.h"
28 #include "lldb/Core/Stream.h"
29 
30 namespace lldb_private {
31 
32 //----------------------------------------------------------------------
33 /// @class StructuredData StructuredData.h "lldb/Core/StructuredData.h"
34 /// @brief A class which can hold structured data
35 ///
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.
40 ///
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 //----------------------------------------------------------------------
46 
47 class StructuredData
48 {
49 public:
50 
51     class Object;
52     class Array;
53     class Integer;
54     class Float;
55     class Boolean;
56     class String;
57     class Dictionary;
58     class Generic;
59 
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;
68 
69     enum class Type
70     {
71         eTypeInvalid = -1,
72         eTypeNull = 0,
73         eTypeGeneric,
74         eTypeArray,
75         eTypeInteger,
76         eTypeFloat,
77         eTypeBoolean,
78         eTypeString,
79         eTypeDictionary
80     };
81 
82     class Object :
83         public std::enable_shared_from_this<Object>
84     {
85     public:
86 
87         Object (Type t = Type::eTypeInvalid) :
m_type(t)88             m_type (t)
89         {
90         }
91 
~Object()92         virtual ~Object ()
93         {
94         }
95 
96         virtual bool
IsValid()97         IsValid() const
98         {
99             return true;
100         }
101 
102         virtual void
Clear()103         Clear ()
104         {
105             m_type = Type::eTypeInvalid;
106         }
107 
108         Type
GetType()109         GetType () const
110         {
111             return m_type;
112         }
113 
114         void
SetType(Type t)115         SetType (Type t)
116         {
117             m_type = t;
118         }
119 
120         Array *
GetAsArray()121         GetAsArray ()
122         {
123             if (m_type == Type::eTypeArray)
124                 return (Array *)this;
125             return NULL;
126         }
127 
128         Dictionary *
GetAsDictionary()129         GetAsDictionary ()
130         {
131             if (m_type == Type::eTypeDictionary)
132                 return (Dictionary *)this;
133             return NULL;
134         }
135 
136         Integer *
GetAsInteger()137         GetAsInteger ()
138         {
139             if (m_type == Type::eTypeInteger)
140                 return (Integer *)this;
141             return NULL;
142         }
143 
144         uint64_t
145         GetIntegerValue (uint64_t fail_value = 0)
146         {
147             Integer *integer = GetAsInteger ();
148             if (integer)
149                 return integer->GetValue();
150             return fail_value;
151         }
152 
153         Float *
GetAsFloat()154         GetAsFloat ()
155         {
156             if (m_type == Type::eTypeFloat)
157                 return (Float *)this;
158             return NULL;
159         }
160 
161         double
162         GetFloatValue (double fail_value = 0.0)
163         {
164             Float *f = GetAsFloat ();
165             if (f)
166                 return f->GetValue();
167             return fail_value;
168         }
169 
170         Boolean *
GetAsBoolean()171         GetAsBoolean ()
172         {
173             if (m_type == Type::eTypeBoolean)
174                 return (Boolean *)this;
175             return NULL;
176         }
177 
178         bool
179         GetBooleanValue (bool fail_value = false)
180         {
181             Boolean *b = GetAsBoolean ();
182             if (b)
183                 return b->GetValue();
184             return fail_value;
185         }
186 
187         String *
GetAsString()188         GetAsString ()
189         {
190             if (m_type == Type::eTypeString)
191                 return (String *)this;
192             return NULL;
193         }
194 
195         std::string
196         GetStringValue(const char *fail_value = NULL)
197         {
198             String *s = GetAsString ();
199             if (s)
200                 return s->GetValue();
201 
202             if (fail_value && fail_value[0])
203                 return std::string(fail_value);
204 
205             return std::string();
206         }
207 
208         Generic *
GetAsGeneric()209         GetAsGeneric()
210         {
211             if (m_type == Type::eTypeGeneric)
212                 return (Generic *)this;
213             return NULL;
214         }
215 
216         ObjectSP
217         GetObjectForDotSeparatedPath (llvm::StringRef path);
218 
219         void DumpToStdout() const;
220 
221         virtual void
222         Dump (Stream &s) const = 0;
223 
224     private:
225         Type m_type;
226     };
227 
228     class Array : public Object
229     {
230     public:
Array()231         Array () :
232             Object (Type::eTypeArray)
233         {
234         }
235 
236         virtual
~Array()237         ~Array()
238         {
239         }
240 
241         bool
ForEach(std::function<bool (Object * object)> const & foreach_callback)242         ForEach (std::function <bool(Object* object)> const &foreach_callback) const
243         {
244             for (const auto &object_sp : m_items)
245             {
246                 if (foreach_callback(object_sp.get()) == false)
247                     return false;
248             }
249             return true;
250         }
251 
252 
253         size_t
GetSize()254         GetSize() const
255         {
256             return m_items.size();
257         }
258 
259         ObjectSP
260         operator[](size_t idx)
261         {
262             if (idx < m_items.size())
263                 return m_items[idx];
264             return ObjectSP();
265         }
266 
267         ObjectSP
GetItemAtIndex(size_t idx)268         GetItemAtIndex(size_t idx) const
269         {
270             assert(idx < GetSize());
271             if (idx < m_items.size())
272                 return m_items[idx];
273             return ObjectSP();
274         }
275 
276         template <class IntType>
277         bool
GetItemAtIndexAsInteger(size_t idx,IntType & result)278         GetItemAtIndexAsInteger(size_t idx, IntType &result) const
279         {
280             ObjectSP value = GetItemAtIndex(idx);
281             if (auto int_value = value->GetAsInteger())
282             {
283                 result = static_cast<IntType>(int_value->GetValue());
284                 return true;
285             }
286             return false;
287         }
288 
289         template <class IntType>
290         bool
GetItemAtIndexAsInteger(size_t idx,IntType & result,IntType default_val)291         GetItemAtIndexAsInteger(size_t idx, IntType &result, IntType default_val) const
292         {
293             bool success = GetItemAtIndexAsInteger(idx, result);
294             if (!success)
295                 result = default_val;
296             return success;
297         }
298 
299         bool
GetItemAtIndexAsString(size_t idx,std::string & result)300         GetItemAtIndexAsString(size_t idx, std::string &result) const
301         {
302             ObjectSP value = GetItemAtIndex(idx);
303             if (auto string_value = value->GetAsString())
304             {
305                 result = string_value->GetValue();
306                 return true;
307             }
308             return false;
309         }
310 
311         bool
GetItemAtIndexAsString(size_t idx,std::string & result,const std::string & default_val)312         GetItemAtIndexAsString(size_t idx, std::string &result, const std::string &default_val) const
313         {
314             bool success = GetItemAtIndexAsString(idx, result);
315             if (!success)
316                 result = default_val;
317             return success;
318         }
319 
320         bool
GetItemAtIndexAsString(size_t idx,ConstString & result)321         GetItemAtIndexAsString(size_t idx, ConstString &result) const
322         {
323             ObjectSP value = GetItemAtIndex(idx);
324             if (!value)
325                 return false;
326             if (auto string_value = value->GetAsString())
327             {
328                 result = ConstString(string_value->GetValue());
329                 return true;
330             }
331             return false;
332         }
333 
334         bool
GetItemAtIndexAsString(size_t idx,ConstString & result,const char * default_val)335         GetItemAtIndexAsString(size_t idx, ConstString &result, const char *default_val) const
336         {
337             bool success = GetItemAtIndexAsString(idx, result);
338             if (!success)
339                 result.SetCString(default_val);
340             return success;
341         }
342 
343         bool
GetItemAtIndexAsDictionary(size_t idx,Dictionary * & result)344         GetItemAtIndexAsDictionary(size_t idx, Dictionary *&result) const
345         {
346             ObjectSP value = GetItemAtIndex(idx);
347             result = value->GetAsDictionary();
348             return (result != nullptr);
349         }
350 
351         bool
GetItemAtIndexAsArray(size_t idx,Array * & result)352         GetItemAtIndexAsArray(size_t idx, Array *&result) const
353         {
354             ObjectSP value = GetItemAtIndex(idx);
355             result = value->GetAsArray();
356             return (result != nullptr);
357         }
358 
359         void
Push(ObjectSP item)360         Push(ObjectSP item)
361         {
362             m_items.push_back(item);
363         }
364 
365         void
AddItem(ObjectSP item)366         AddItem(ObjectSP item)
367         {
368             m_items.push_back(item);
369         }
370 
371         void Dump(Stream &s) const override;
372 
373     protected:
374         typedef std::vector<ObjectSP> collection;
375         collection m_items;
376     };
377 
378 
379     class Integer  : public Object
380     {
381     public:
382         Integer (uint64_t i = 0) :
Object(Type::eTypeInteger)383             Object (Type::eTypeInteger),
384             m_value (i)
385         {
386         }
387 
~Integer()388         virtual ~Integer()
389         {
390         }
391 
392         void
SetValue(uint64_t value)393         SetValue (uint64_t value)
394         {
395             m_value = value;
396         }
397 
398         uint64_t
GetValue()399         GetValue ()
400         {
401             return m_value;
402         }
403 
404         void Dump(Stream &s) const override;
405 
406     protected:
407         uint64_t m_value;
408     };
409 
410     class Float  : public Object
411     {
412     public:
413         Float (double d = 0.0) :
Object(Type::eTypeFloat)414             Object (Type::eTypeFloat),
415             m_value (d)
416         {
417         }
418 
~Float()419         virtual ~Float()
420         {
421         }
422 
423         void
SetValue(double value)424         SetValue (double value)
425         {
426             m_value = value;
427         }
428 
429         double
GetValue()430         GetValue ()
431         {
432             return m_value;
433         }
434 
435         void Dump(Stream &s) const override;
436 
437     protected:
438         double m_value;
439     };
440 
441     class Boolean  : public Object
442     {
443     public:
444         Boolean (bool b = false) :
Object(Type::eTypeBoolean)445             Object (Type::eTypeBoolean),
446             m_value (b)
447         {
448         }
449 
~Boolean()450         virtual ~Boolean()
451         {
452         }
453 
454         void
SetValue(bool value)455         SetValue (bool value)
456         {
457             m_value = value;
458         }
459 
460         bool
GetValue()461         GetValue ()
462         {
463             return m_value;
464         }
465 
466         void Dump(Stream &s) const override;
467 
468     protected:
469         bool m_value;
470     };
471 
472 
473 
474     class String  : public Object
475     {
476     public:
477         String (const char *cstr = NULL) :
Object(Type::eTypeString)478             Object (Type::eTypeString),
479             m_value ()
480         {
481             if (cstr)
482                 m_value = cstr;
483         }
484 
String(const std::string & s)485         String (const std::string &s) :
486             Object (Type::eTypeString),
487             m_value (s)
488         {
489         }
490 
String(const std::string && s)491         String (const std::string &&s) :
492             Object (Type::eTypeString),
493             m_value (s)
494         {
495         }
496 
497         void
SetValue(const std::string & string)498         SetValue (const std::string &string)
499         {
500             m_value = string;
501         }
502 
503         const std::string &
GetValue()504         GetValue ()
505         {
506             return m_value;
507         }
508 
509         void Dump(Stream &s) const override;
510 
511     protected:
512         std::string m_value;
513     };
514 
515     class Dictionary : public Object
516     {
517     public:
518 
Dictionary()519         Dictionary () :
520             Object (Type::eTypeDictionary),
521             m_dict ()
522         {
523         }
524 
~Dictionary()525         virtual ~Dictionary()
526         {
527         }
528 
529         size_t
GetSize()530         GetSize() const
531         {
532             return m_dict.size();
533         }
534 
535         void
ForEach(std::function<bool (ConstString key,Object * object)> const & callback)536         ForEach (std::function <bool(ConstString key, Object* object)> const &callback) const
537         {
538             for (const auto &pair : m_dict)
539             {
540                 if (callback (pair.first, pair.second.get()) == false)
541                     break;
542             }
543         }
544 
545         ObjectSP
GetKeys()546         GetKeys() const
547         {
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)
552             {
553                 ObjectSP key_object_sp(new String());
554                 key_object_sp->GetAsString()->SetValue(iter->first.AsCString());
555                 array->Push(key_object_sp);
556             }
557             return object_sp;
558         }
559 
560         ObjectSP
GetValueForKey(llvm::StringRef key)561         GetValueForKey(llvm::StringRef key) const
562         {
563             ObjectSP value_sp;
564             if (!key.empty())
565             {
566                 ConstString key_cs(key);
567                 for (collection::const_iterator iter = m_dict.begin(); iter != m_dict.end(); ++iter)
568                 {
569                     if (key_cs == iter->first)
570                     {
571                         value_sp = iter->second;
572                         break;
573                     }
574                 }
575             }
576             return value_sp;
577         }
578 
579         template <class IntType>
580         bool
GetValueForKeyAsInteger(llvm::StringRef key,IntType & result)581         GetValueForKeyAsInteger(llvm::StringRef key, IntType &result) const
582         {
583             ObjectSP value = GetValueForKey(key);
584             if (!value)
585                 return false;
586             if (auto int_value = value->GetAsInteger())
587             {
588                 result = static_cast<IntType>(int_value->GetValue());
589                 return true;
590             }
591             return false;
592         }
593 
594         template <class IntType>
595         bool
GetValueForKeyAsInteger(llvm::StringRef key,IntType & result,IntType default_val)596         GetValueForKeyAsInteger(llvm::StringRef key, IntType &result, IntType default_val) const
597         {
598             bool success = GetValueForKeyAsInteger<IntType>(key, result);
599             if (!success)
600                 result = default_val;
601             return success;
602         }
603 
604         bool
GetValueForKeyAsString(llvm::StringRef key,std::string & result)605         GetValueForKeyAsString(llvm::StringRef key, std::string &result) const
606         {
607             ObjectSP value = GetValueForKey(key);
608             if (!value)
609                 return false;
610             if (auto string_value = value->GetAsString())
611             {
612                 result = string_value->GetValue();
613                 return true;
614             }
615             return false;
616         }
617 
618         bool
GetValueForKeyAsString(llvm::StringRef key,std::string & result,const char * default_val)619         GetValueForKeyAsString(llvm::StringRef key, std::string &result, const char *default_val) const
620         {
621             bool success = GetValueForKeyAsString(key, result);
622             if (!success)
623             {
624                 if (default_val)
625                     result = default_val;
626                 else
627                     result.clear();
628             }
629             return success;
630         }
631 
632         bool
GetValueForKeyAsString(llvm::StringRef key,ConstString & result)633         GetValueForKeyAsString(llvm::StringRef key, ConstString &result) const
634         {
635             ObjectSP value = GetValueForKey(key);
636             if (!value)
637                 return false;
638             if (auto string_value = value->GetAsString())
639             {
640                 result = ConstString(string_value->GetValue());
641                 return true;
642             }
643             return false;
644         }
645 
646         bool
GetValueForKeyAsString(llvm::StringRef key,ConstString & result,const char * default_val)647         GetValueForKeyAsString(llvm::StringRef key, ConstString &result, const char *default_val) const
648         {
649             bool success = GetValueForKeyAsString(key, result);
650             if (!success)
651                 result.SetCString(default_val);
652             return success;
653         }
654 
655         bool
GetValueForKeyAsDictionary(llvm::StringRef key,Dictionary * & result)656         GetValueForKeyAsDictionary(llvm::StringRef key, Dictionary *&result) const
657         {
658             result = nullptr;
659             ObjectSP value = GetValueForKey(key);
660             if (!value)
661                 return false;
662             result = value->GetAsDictionary();
663             return true;
664         }
665 
666         bool
GetValueForKeyAsArray(llvm::StringRef key,Array * & result)667         GetValueForKeyAsArray(llvm::StringRef key, Array *&result) const
668         {
669             result = nullptr;
670             ObjectSP value = GetValueForKey(key);
671             if (!value)
672                 return false;
673             result = value->GetAsArray();
674             return true;
675         }
676 
677         bool
HasKey(llvm::StringRef key)678         HasKey(llvm::StringRef key) const
679         {
680             ConstString key_cs(key);
681             collection::const_iterator search = m_dict.find(key_cs);
682             return search != m_dict.end();
683         }
684 
685         void
AddItem(llvm::StringRef key,ObjectSP value)686         AddItem (llvm::StringRef key, ObjectSP value)
687         {
688             ConstString key_cs(key);
689             m_dict[key_cs] = value;
690         }
691 
692         void
AddIntegerItem(llvm::StringRef key,uint64_t value)693         AddIntegerItem (llvm::StringRef key, uint64_t value)
694         {
695             AddItem (key, ObjectSP (new Integer(value)));
696         }
697 
698         void
AddFloatItem(llvm::StringRef key,double value)699         AddFloatItem (llvm::StringRef key, double value)
700         {
701             AddItem (key, ObjectSP (new Float(value)));
702         }
703 
704         void
AddStringItem(llvm::StringRef key,std::string value)705         AddStringItem (llvm::StringRef key, std::string value)
706         {
707             AddItem (key, ObjectSP (new String(std::move(value))));
708         }
709 
710         void
AddBooleanItem(llvm::StringRef key,bool value)711         AddBooleanItem (llvm::StringRef key, bool value)
712         {
713             AddItem (key, ObjectSP (new Boolean(value)));
714         }
715 
716         void Dump(Stream &s) const override;
717 
718     protected:
719         typedef std::map<ConstString, ObjectSP> collection;
720         collection m_dict;
721     };
722 
723     class Null : public Object
724     {
725     public:
Null()726         Null () :
727             Object (Type::eTypeNull)
728         {
729         }
730 
~Null()731         virtual ~Null()
732         {
733         }
734 
735         bool
IsValid()736         IsValid() const override
737         {
738             return false;
739         }
740 
741         void Dump(Stream &s) const override;
742 
743     protected:
744     };
745 
746     class Generic : public Object
747     {
748       public:
749         explicit Generic(void *object = nullptr) :
Object(Type::eTypeGeneric)750             Object (Type::eTypeGeneric),
751             m_object (object)
752         {
753         }
754 
755         void
SetValue(void * value)756         SetValue(void *value)
757         {
758             m_object = value;
759         }
760 
761         void *
GetValue()762         GetValue() const
763         {
764             return m_object;
765         }
766 
767         bool
IsValid()768         IsValid() const override
769         {
770             return m_object != nullptr;
771         }
772 
773         void Dump(Stream &s) const override;
774 
775       private:
776         void *m_object;
777     };
778 
779     static ObjectSP
780     ParseJSON (std::string json_text);
781 
782 };  // class StructuredData
783 
784 
785 } // namespace lldb_private
786 
787 #endif  // liblldb_StructuredData_h_
788