]> CyberLeo.Net >> Repos - FreeBSD/FreeBSD.git/blob - contrib/llvm/tools/lldb/include/lldb/Core/StructuredData.h
Merge OpenBSM 1.2 alpha 4.
[FreeBSD/FreeBSD.git] / contrib / llvm / tools / lldb / include / lldb / Core / StructuredData.h
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) :
88             m_type (t)
89         {
90         }
91
92         virtual ~Object ()
93         {
94         }
95
96         virtual bool
97         IsValid() const
98         {
99             return true;
100         }
101
102         virtual void
103         Clear ()
104         {
105             m_type = Type::eTypeInvalid;
106         }
107
108         Type
109         GetType () const
110         {
111             return m_type;
112         }
113
114         void
115         SetType (Type t)
116         {
117             m_type = t;
118         }
119
120         Array *
121         GetAsArray ()
122         {
123             if (m_type == Type::eTypeArray)
124                 return (Array *)this;
125             return NULL;
126         }
127
128         Dictionary *
129         GetAsDictionary ()
130         {
131             if (m_type == Type::eTypeDictionary)
132                 return (Dictionary *)this;
133             return NULL;
134         }
135
136         Integer *
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 *
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 *
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 *
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 *
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:
231         Array () :
232             Object (Type::eTypeArray)
233         {
234         }
235
236         virtual
237         ~Array()
238         {
239         }
240
241         bool
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
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
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
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
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
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
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
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
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
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
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
360         Push(ObjectSP item)
361         {
362             m_items.push_back(item);
363         }
364
365         void
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) :
383             Object (Type::eTypeInteger),
384             m_value (i)
385         {
386         }
387
388         virtual ~Integer()
389         {
390         }
391
392         void
393         SetValue (uint64_t value)
394         {
395             m_value = value;
396         }
397
398         uint64_t
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) :
414             Object (Type::eTypeFloat),
415             m_value (d)
416         {
417         }
418
419         virtual ~Float()
420         {
421         }
422
423         void
424         SetValue (double value)
425         {
426             m_value = value;
427         }
428
429         double
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) :
445             Object (Type::eTypeBoolean),
446             m_value (b)
447         {
448         }
449
450         virtual ~Boolean()
451         {
452         }
453
454         void
455         SetValue (bool value)
456         {
457             m_value = value;
458         }
459
460         bool
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) :
478             Object (Type::eTypeString),
479             m_value ()
480         {
481             if (cstr)
482                 m_value = cstr;
483         }
484
485         String (const std::string &s) :
486             Object (Type::eTypeString),
487             m_value (s)
488         {
489         }
490
491         String (const std::string &&s) :
492             Object (Type::eTypeString),
493             m_value (s)
494         {
495         }
496
497         void
498         SetValue (const std::string &string)
499         {
500             m_value = string;
501         }
502
503         const std::string &
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
519         Dictionary () :
520             Object (Type::eTypeDictionary),
521             m_dict ()
522         {
523         }
524
525         virtual ~Dictionary()
526         {
527         }
528
529         size_t
530         GetSize() const
531         {
532             return m_dict.size();
533         }
534
535         void
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
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
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
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
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
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
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
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
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
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
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
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
686         AddItem (llvm::StringRef key, ObjectSP value)
687         {
688             ConstString key_cs(key);
689             m_dict[key_cs] = value;
690         }
691
692         void
693         AddIntegerItem (llvm::StringRef key, uint64_t value)
694         {
695             AddItem (key, ObjectSP (new Integer(value)));
696         }
697
698         void
699         AddFloatItem (llvm::StringRef key, double value)
700         {
701             AddItem (key, ObjectSP (new Float(value)));
702         }
703
704         void
705         AddStringItem (llvm::StringRef key, std::string value)
706         {
707             AddItem (key, ObjectSP (new String(std::move(value))));
708         }
709
710         void
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:
726         Null () :
727             Object (Type::eTypeNull)
728         {
729         }
730
731         virtual ~Null()
732         {
733         }
734
735         bool
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) :
750             Object (Type::eTypeGeneric),
751             m_object (object)
752         {
753         }
754
755         void
756         SetValue(void *value)
757         {
758             m_object = value;
759         }
760
761         void *
762         GetValue() const
763         {
764             return m_object;
765         }
766
767         bool
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_