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