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:
StructuredDataImpl()28   StructuredDataImpl() : m_plugin_wp(), m_data_sp() {}
29 
30   StructuredDataImpl(const StructuredDataImpl &rhs) = default;
31 
StructuredDataImpl(const lldb::EventSP & event_sp)32   StructuredDataImpl(const lldb::EventSP &event_sp)
33       : m_plugin_wp(
34             EventDataStructuredData::GetPluginFromEvent(event_sp.get())),
35         m_data_sp(EventDataStructuredData::GetObjectFromEvent(event_sp.get())) {
36   }
37 
38   ~StructuredDataImpl() = default;
39 
40   StructuredDataImpl &operator=(const StructuredDataImpl &rhs) = default;
41 
IsValid()42   bool IsValid() const { return m_data_sp.get() != nullptr; }
43 
Clear()44   void Clear() {
45     m_plugin_wp.reset();
46     m_data_sp.reset();
47   }
48 
GetAsJSON(Stream & stream)49   Status GetAsJSON(Stream &stream) const {
50     Status error;
51 
52     if (!m_data_sp) {
53       error.SetErrorString("No structured data.");
54       return error;
55     }
56 
57     llvm::json::OStream s(stream.AsRawOstream());
58     m_data_sp->Serialize(s);
59     return error;
60   }
61 
GetDescription(Stream & stream)62   Status GetDescription(Stream &stream) const {
63     Status error;
64 
65     if (!m_data_sp) {
66       error.SetErrorString("Cannot pretty print structured data: "
67                            "no data to print.");
68       return error;
69     }
70 
71     // Grab the plugin
72     lldb::StructuredDataPluginSP plugin_sp = m_plugin_wp.lock();
73 
74     // If there's no plugin, call underlying data's dump method:
75     if (!plugin_sp) {
76       if (!m_data_sp) {
77         error.SetErrorString("No data to describe.");
78         return error;
79       }
80       m_data_sp->Dump(stream, true);
81       return error;
82     }
83     // Get the data's description.
84     return plugin_sp->GetDescription(m_data_sp, stream);
85   }
86 
GetObjectSP()87   StructuredData::ObjectSP GetObjectSP() { return m_data_sp; }
88 
SetObjectSP(const StructuredData::ObjectSP & obj)89   void SetObjectSP(const StructuredData::ObjectSP &obj) { m_data_sp = obj; }
90 
GetType()91   lldb::StructuredDataType GetType() const {
92     return (m_data_sp ? m_data_sp->GetType() :
93         lldb::eStructuredDataTypeInvalid);
94   }
95 
GetSize()96   size_t GetSize() const {
97     if (!m_data_sp)
98       return 0;
99 
100     if (m_data_sp->GetType() == lldb::eStructuredDataTypeDictionary) {
101       auto dict = m_data_sp->GetAsDictionary();
102       return (dict->GetSize());
103     } else if (m_data_sp->GetType() == lldb::eStructuredDataTypeArray) {
104       auto array = m_data_sp->GetAsArray();
105       return (array->GetSize());
106     } else
107       return 0;
108   }
109 
GetValueForKey(const char * key)110   StructuredData::ObjectSP GetValueForKey(const char *key) const {
111     if (m_data_sp) {
112       auto dict = m_data_sp->GetAsDictionary();
113       if (dict)
114         return dict->GetValueForKey(llvm::StringRef(key));
115     }
116     return StructuredData::ObjectSP();
117   }
118 
GetItemAtIndex(size_t idx)119   StructuredData::ObjectSP GetItemAtIndex(size_t idx) const {
120     if (m_data_sp) {
121       auto array = m_data_sp->GetAsArray();
122       if (array)
123         return array->GetItemAtIndex(idx);
124     }
125     return StructuredData::ObjectSP();
126   }
127 
128   uint64_t GetIntegerValue(uint64_t fail_value = 0) const {
129     return (m_data_sp ? m_data_sp->GetIntegerValue(fail_value) : fail_value);
130   }
131 
132   double GetFloatValue(double fail_value = 0.0) const {
133     return (m_data_sp ? m_data_sp->GetFloatValue(fail_value) : fail_value);
134   }
135 
136   bool GetBooleanValue(bool fail_value = false) const {
137     return (m_data_sp ? m_data_sp->GetBooleanValue(fail_value) : fail_value);
138   }
139 
GetStringValue(char * dst,size_t dst_len)140   size_t GetStringValue(char *dst, size_t dst_len) const {
141     if (!m_data_sp)
142       return 0;
143 
144     llvm::StringRef result = m_data_sp->GetStringValue();
145     if (result.empty())
146       return 0;
147 
148     if (!dst || !dst_len) {
149       char s[1];
150       return (::snprintf(s, 1, "%s", result.data()));
151     }
152     return (::snprintf(dst, dst_len, "%s", result.data()));
153   }
154 
155 private:
156   lldb::StructuredDataPluginWP m_plugin_wp;
157   StructuredData::ObjectSP m_data_sp;
158 };
159 } // namespace lldb_private
160 #endif
161