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_ptr: event_sp.get())), |
38 | m_data_sp(EventDataStructuredData::GetObjectFromEvent(event_ptr: 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(s&: stream); |
84 | return error; |
85 | } |
86 | // Get the data's description. |
87 | return plugin_sp->GetDescription(object_sp: 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(key: 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->GetUnsignedIntegerValue(fail_value) |
133 | : fail_value); |
134 | } |
135 | |
136 | int64_t GetIntegerValue(int64_t fail_value = 0) const { |
137 | return (m_data_sp ? m_data_sp->GetSignedIntegerValue(fail_value) |
138 | : fail_value); |
139 | } |
140 | |
141 | double GetFloatValue(double fail_value = 0.0) const { |
142 | return (m_data_sp ? m_data_sp->GetFloatValue(fail_value) : fail_value); |
143 | } |
144 | |
145 | bool GetBooleanValue(bool fail_value = false) const { |
146 | return (m_data_sp ? m_data_sp->GetBooleanValue(fail_value) : fail_value); |
147 | } |
148 | |
149 | size_t GetStringValue(char *dst, size_t dst_len) const { |
150 | if (!m_data_sp) |
151 | return 0; |
152 | |
153 | llvm::StringRef result = m_data_sp->GetStringValue(); |
154 | if (result.empty()) |
155 | return 0; |
156 | |
157 | if (!dst || !dst_len) { |
158 | char s[1]; |
159 | return (::snprintf(s: s, maxlen: 1, format: "%s" , result.data())); |
160 | } |
161 | return (::snprintf(s: dst, maxlen: dst_len, format: "%s" , result.data())); |
162 | } |
163 | |
164 | void *GetGenericValue() const { |
165 | if (!m_data_sp) |
166 | return nullptr; |
167 | |
168 | StructuredData::Generic *generic_data = m_data_sp->GetAsGeneric(); |
169 | if (!generic_data) |
170 | return nullptr; |
171 | |
172 | return generic_data->GetValue(); |
173 | } |
174 | |
175 | StructuredData::ObjectSP GetObjectSP() const { return m_data_sp; } |
176 | |
177 | private: |
178 | lldb::StructuredDataPluginWP m_plugin_wp; |
179 | StructuredData::ObjectSP m_data_sp; |
180 | }; |
181 | } // namespace lldb_private |
182 | #endif |
183 | |