xref: /llvm-project/lldb/source/API/SBStructuredData.cpp (revision b798f4bd50bbf0f5eb46804afad10629797c73aa)
1 //===-- SBStructuredData.cpp ----------------------------------------------===//
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 #include "lldb/API/SBStructuredData.h"
10 
11 #include "lldb/API/SBDebugger.h"
12 #include "lldb/API/SBScriptObject.h"
13 #include "lldb/API/SBStream.h"
14 #include "lldb/API/SBStringList.h"
15 #include "lldb/Core/Debugger.h"
16 #include "lldb/Core/StructuredDataImpl.h"
17 #include "lldb/Interpreter/ScriptInterpreter.h"
18 #include "lldb/Target/StructuredDataPlugin.h"
19 #include "lldb/Utility/Event.h"
20 #include "lldb/Utility/Instrumentation.h"
21 #include "lldb/Utility/Status.h"
22 #include "lldb/Utility/Stream.h"
23 #include "lldb/Utility/StringList.h"
24 #include "lldb/Utility/StructuredData.h"
25 
26 using namespace lldb;
27 using namespace lldb_private;
28 
29 #pragma mark--
30 #pragma mark SBStructuredData
31 
32 SBStructuredData::SBStructuredData() : m_impl_up(new StructuredDataImpl()) {
33   LLDB_INSTRUMENT_VA(this);
34 }
35 
36 SBStructuredData::SBStructuredData(const lldb::SBStructuredData &rhs)
37     : m_impl_up(new StructuredDataImpl(*rhs.m_impl_up)) {
38   LLDB_INSTRUMENT_VA(this, rhs);
39 }
40 
41 SBStructuredData::SBStructuredData(const lldb::SBScriptObject obj,
42                                    const lldb::SBDebugger &debugger) {
43   LLDB_INSTRUMENT_VA(this, obj, debugger);
44 
45   if (!obj.IsValid())
46     return;
47 
48   ScriptInterpreter *interpreter =
49       debugger.m_opaque_sp->GetScriptInterpreter(true, obj.GetLanguage());
50 
51   if (!interpreter)
52     return;
53 
54   StructuredDataImplUP impl_up = std::make_unique<StructuredDataImpl>(
55       interpreter->CreateStructuredDataFromScriptObject(obj.ref()));
56   if (impl_up && impl_up->IsValid())
57     m_impl_up.reset(impl_up.release());
58 }
59 
60 SBStructuredData::SBStructuredData(const lldb::EventSP &event_sp)
61     : m_impl_up(new StructuredDataImpl(event_sp)) {
62   LLDB_INSTRUMENT_VA(this, event_sp);
63 }
64 
65 SBStructuredData::SBStructuredData(const lldb_private::StructuredDataImpl &impl)
66     : m_impl_up(new StructuredDataImpl(impl)) {
67   LLDB_INSTRUMENT_VA(this, impl);
68 }
69 
70 SBStructuredData::~SBStructuredData() = default;
71 
72 SBStructuredData &SBStructuredData::
73 operator=(const lldb::SBStructuredData &rhs) {
74   LLDB_INSTRUMENT_VA(this, rhs);
75 
76   *m_impl_up = *rhs.m_impl_up;
77   return *this;
78 }
79 
80 lldb::SBError SBStructuredData::SetFromJSON(lldb::SBStream &stream) {
81   LLDB_INSTRUMENT_VA(this, stream);
82 
83   lldb::SBError error;
84 
85   StructuredData::ObjectSP json_obj =
86       StructuredData::ParseJSON(stream.GetData());
87   m_impl_up->SetObjectSP(json_obj);
88 
89   static constexpr StructuredDataType unsupported_type[] = {
90       eStructuredDataTypeInvalid,
91       eStructuredDataTypeGeneric,
92   };
93 
94   if (!json_obj || llvm::is_contained(unsupported_type, json_obj->GetType()))
95     error = Status::FromErrorString("Invalid Syntax");
96   return error;
97 }
98 
99 lldb::SBError SBStructuredData::SetFromJSON(const char *json) {
100   LLDB_INSTRUMENT_VA(this, json);
101   lldb::SBStream s;
102   s.Print(json);
103   return SetFromJSON(s);
104 }
105 
106 bool SBStructuredData::IsValid() const {
107   LLDB_INSTRUMENT_VA(this);
108   return this->operator bool();
109 }
110 
111 SBStructuredData::operator bool() const {
112   LLDB_INSTRUMENT_VA(this);
113 
114   return m_impl_up->IsValid();
115 }
116 
117 void SBStructuredData::Clear() {
118   LLDB_INSTRUMENT_VA(this);
119 
120   m_impl_up->Clear();
121 }
122 
123 SBError SBStructuredData::GetAsJSON(lldb::SBStream &stream) const {
124   LLDB_INSTRUMENT_VA(this, stream);
125 
126   SBError error;
127   error.SetError(m_impl_up->GetAsJSON(stream.ref()));
128   return error;
129 }
130 
131 lldb::SBError SBStructuredData::GetDescription(lldb::SBStream &stream) const {
132   LLDB_INSTRUMENT_VA(this, stream);
133 
134   Status error = m_impl_up->GetDescription(stream.ref());
135   SBError sb_error;
136   sb_error.SetError(std::move(error));
137   return sb_error;
138 }
139 
140 StructuredDataType SBStructuredData::GetType() const {
141   LLDB_INSTRUMENT_VA(this);
142 
143   return m_impl_up->GetType();
144 }
145 
146 size_t SBStructuredData::GetSize() const {
147   LLDB_INSTRUMENT_VA(this);
148 
149   return m_impl_up->GetSize();
150 }
151 
152 bool SBStructuredData::GetKeys(lldb::SBStringList &keys) const {
153   LLDB_INSTRUMENT_VA(this, keys);
154 
155   if (GetType() != eStructuredDataTypeDictionary)
156     return false;
157 
158   StructuredData::ObjectSP obj_sp = m_impl_up->GetObjectSP();
159   if (!obj_sp)
160     return false;
161 
162   StructuredData::Dictionary *dict = obj_sp->GetAsDictionary();
163   // We claimed we were a dictionary, so this can't be null.
164   assert(dict);
165   // The return kind of GetKeys is an Array:
166   StructuredData::ObjectSP array_sp = dict->GetKeys();
167   StructuredData::Array *key_arr = array_sp->GetAsArray();
168   assert(key_arr);
169 
170   key_arr->ForEach([&keys](StructuredData::Object *object) -> bool {
171     llvm::StringRef key = object->GetStringValue("");
172     keys->AppendString(key);
173     return true;
174   });
175   return true;
176 }
177 
178 lldb::SBStructuredData SBStructuredData::GetValueForKey(const char *key) const {
179   LLDB_INSTRUMENT_VA(this, key);
180 
181   SBStructuredData result;
182   result.m_impl_up->SetObjectSP(m_impl_up->GetValueForKey(key));
183   return result;
184 }
185 
186 lldb::SBStructuredData SBStructuredData::GetItemAtIndex(size_t idx) const {
187   LLDB_INSTRUMENT_VA(this, idx);
188 
189   SBStructuredData result;
190   result.m_impl_up->SetObjectSP(m_impl_up->GetItemAtIndex(idx));
191   return result;
192 }
193 
194 uint64_t SBStructuredData::GetIntegerValue(uint64_t fail_value) const {
195   LLDB_INSTRUMENT_VA(this, fail_value);
196 
197   return GetUnsignedIntegerValue(fail_value);
198 }
199 
200 uint64_t SBStructuredData::GetUnsignedIntegerValue(uint64_t fail_value) const {
201   LLDB_INSTRUMENT_VA(this, fail_value);
202 
203   return m_impl_up->GetIntegerValue(fail_value);
204 }
205 
206 int64_t SBStructuredData::GetSignedIntegerValue(int64_t fail_value) const {
207   LLDB_INSTRUMENT_VA(this, fail_value);
208 
209   return m_impl_up->GetIntegerValue(fail_value);
210 }
211 
212 double SBStructuredData::GetFloatValue(double fail_value) const {
213   LLDB_INSTRUMENT_VA(this, fail_value);
214 
215   return m_impl_up->GetFloatValue(fail_value);
216 }
217 
218 bool SBStructuredData::GetBooleanValue(bool fail_value) const {
219   LLDB_INSTRUMENT_VA(this, fail_value);
220 
221   return m_impl_up->GetBooleanValue(fail_value);
222 }
223 
224 size_t SBStructuredData::GetStringValue(char *dst, size_t dst_len) const {
225   LLDB_INSTRUMENT_VA(this, dst, dst_len);
226 
227   return m_impl_up->GetStringValue(dst, dst_len);
228 }
229 
230 lldb::SBScriptObject SBStructuredData::GetGenericValue() const {
231   LLDB_INSTRUMENT_VA(this);
232 
233   return {m_impl_up->GetGenericValue(), eScriptLanguageDefault};
234 }
235