1 //===-- StructuredDataImpl.h ------------------------------------*- C++ -*-===//
2 //
3 // Part of the LLVM Project, under the Apache License v2.0 with LLVM Exceptions.
4 // See https://llvm.org/LICENSE.txt for license information.
5 // SPDX-License-Identifier: Apache-2.0 WITH LLVM-exception
6 //
7 //===----------------------------------------------------------------------===//
8 
9 #ifndef LLDB_CORE_STRUCTUREDDATAIMPL_H
10 #define LLDB_CORE_STRUCTUREDDATAIMPL_H
11 
12 #include "lldb/Target/StructuredDataPlugin.h"
13 #include "lldb/Utility/Event.h"
14 #include "lldb/Utility/Status.h"
15 #include "lldb/Utility/Stream.h"
16 #include "lldb/Utility/StructuredData.h"
17 #include "lldb/lldb-enumerations.h"
18 #include "lldb/lldb-forward.h"
19 #include "llvm/ADT/StringRef.h"
20 
21 #pragma mark--
22 #pragma mark StructuredDataImpl
23 
24 namespace lldb_private {
25 
26 class StructuredDataImpl {
27 public:
28   StructuredDataImpl() = default;
29 
30   StructuredDataImpl(const StructuredDataImpl &rhs) = default;
31 
32   StructuredDataImpl(StructuredData::ObjectSP obj)
33       : m_data_sp(std::move(obj)) {}
34 
35   StructuredDataImpl(const lldb::EventSP &event_sp)
36       : m_plugin_wp(
37             EventDataStructuredData::GetPluginFromEvent(event_sp.get())),
38         m_data_sp(EventDataStructuredData::GetObjectFromEvent(event_sp.get())) {
39   }
40 
41   ~StructuredDataImpl() = default;
42 
43   StructuredDataImpl &operator=(const StructuredDataImpl &rhs) = default;
44 
45   bool IsValid() const { return m_data_sp.get() != nullptr; }
46 
47   void Clear() {
48     m_plugin_wp.reset();
49     m_data_sp.reset();
50   }
51 
52   Status GetAsJSON(Stream &stream) const {
53     Status error;
54 
55     if (!m_data_sp) {
56       error.SetErrorString("No structured data.");
57       return error;
58     }
59 
60     llvm::json::OStream s(stream.AsRawOstream());
61     m_data_sp->Serialize(s);
62     return error;
63   }
64 
65   Status GetDescription(Stream &stream) const {
66     Status error;
67 
68     if (!m_data_sp) {
69       error.SetErrorString("Cannot pretty print structured data: "
70                            "no data to print.");
71       return error;
72     }
73 
74     // Grab the plugin
75     lldb::StructuredDataPluginSP plugin_sp = m_plugin_wp.lock();
76 
77     // If there's no plugin, call underlying data's dump method:
78     if (!plugin_sp) {
79       if (!m_data_sp) {
80         error.SetErrorString("No data to describe.");
81         return error;
82       }
83       m_data_sp->GetDescription(stream);
84       return error;
85     }
86     // Get the data's description.
87     return plugin_sp->GetDescription(m_data_sp, stream);
88   }
89 
90   StructuredData::ObjectSP GetObjectSP() { return m_data_sp; }
91 
92   void SetObjectSP(const StructuredData::ObjectSP &obj) { m_data_sp = obj; }
93 
94   lldb::StructuredDataType GetType() const {
95     return (m_data_sp ? m_data_sp->GetType() :
96         lldb::eStructuredDataTypeInvalid);
97   }
98 
99   size_t GetSize() const {
100     if (!m_data_sp)
101       return 0;
102 
103     if (m_data_sp->GetType() == lldb::eStructuredDataTypeDictionary) {
104       auto dict = m_data_sp->GetAsDictionary();
105       return (dict->GetSize());
106     } else if (m_data_sp->GetType() == lldb::eStructuredDataTypeArray) {
107       auto array = m_data_sp->GetAsArray();
108       return (array->GetSize());
109     } else
110       return 0;
111   }
112 
113   StructuredData::ObjectSP GetValueForKey(const char *key) const {
114     if (m_data_sp) {
115       auto dict = m_data_sp->GetAsDictionary();
116       if (dict)
117         return dict->GetValueForKey(llvm::StringRef(key));
118     }
119     return StructuredData::ObjectSP();
120   }
121 
122   StructuredData::ObjectSP GetItemAtIndex(size_t idx) const {
123     if (m_data_sp) {
124       auto array = m_data_sp->GetAsArray();
125       if (array)
126         return array->GetItemAtIndex(idx);
127     }
128     return StructuredData::ObjectSP();
129   }
130 
131   uint64_t GetIntegerValue(uint64_t fail_value = 0) const {
132     return (m_data_sp ? m_data_sp->GetIntegerValue(fail_value) : fail_value);
133   }
134 
135   double GetFloatValue(double fail_value = 0.0) const {
136     return (m_data_sp ? m_data_sp->GetFloatValue(fail_value) : fail_value);
137   }
138 
139   bool GetBooleanValue(bool fail_value = false) const {
140     return (m_data_sp ? m_data_sp->GetBooleanValue(fail_value) : fail_value);
141   }
142 
143   size_t GetStringValue(char *dst, size_t dst_len) const {
144     if (!m_data_sp)
145       return 0;
146 
147     llvm::StringRef result = m_data_sp->GetStringValue();
148     if (result.empty())
149       return 0;
150 
151     if (!dst || !dst_len) {
152       char s[1];
153       return (::snprintf(s, 1, "%s", result.data()));
154     }
155     return (::snprintf(dst, dst_len, "%s", result.data()));
156   }
157 
158   StructuredData::ObjectSP GetObjectSP() const { return m_data_sp; }
159 
160 private:
161   lldb::StructuredDataPluginWP m_plugin_wp;
162   StructuredData::ObjectSP m_data_sp;
163 };
164 } // namespace lldb_private
165 #endif
166