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