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 liblldb_StructuredDataImpl_h_
10#define liblldb_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
24namespace lldb_private {
25
26class StructuredDataImpl {
27public:
28  StructuredDataImpl() : m_plugin_wp(), m_data_sp() {}
29
30  StructuredDataImpl(const StructuredDataImpl &rhs) = default;
31
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
42  bool IsValid() const { return m_data_sp.get() != nullptr; }
43
44  void Clear() {
45    m_plugin_wp.reset();
46    m_data_sp.reset();
47  }
48
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
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    auto plugin_sp = lldb::StructuredDataPluginSP(m_plugin_wp);
73    if (!plugin_sp) {
74      error.SetErrorString("Cannot pretty print structured data: "
75                           "plugin doesn't exist.");
76      return error;
77    }
78
79    // Get the data's description.
80    return plugin_sp->GetDescription(m_data_sp, stream);
81  }
82
83  StructuredData::ObjectSP GetObjectSP() { return m_data_sp; }
84
85  void SetObjectSP(const StructuredData::ObjectSP &obj) { m_data_sp = obj; }
86
87  lldb::StructuredDataType GetType() const {
88    return (m_data_sp ? m_data_sp->GetType() :
89        lldb::eStructuredDataTypeInvalid);
90  }
91
92  size_t GetSize() const {
93    if (!m_data_sp)
94      return 0;
95
96    if (m_data_sp->GetType() == lldb::eStructuredDataTypeDictionary) {
97      auto dict = m_data_sp->GetAsDictionary();
98      return (dict->GetSize());
99    } else if (m_data_sp->GetType() == lldb::eStructuredDataTypeArray) {
100      auto array = m_data_sp->GetAsArray();
101      return (array->GetSize());
102    } else
103      return 0;
104  }
105
106  StructuredData::ObjectSP GetValueForKey(const char *key) const {
107    if (m_data_sp) {
108      auto dict = m_data_sp->GetAsDictionary();
109      if (dict)
110        return dict->GetValueForKey(llvm::StringRef(key));
111    }
112    return StructuredData::ObjectSP();
113  }
114
115  StructuredData::ObjectSP GetItemAtIndex(size_t idx) const {
116    if (m_data_sp) {
117      auto array = m_data_sp->GetAsArray();
118      if (array)
119        return array->GetItemAtIndex(idx);
120    }
121    return StructuredData::ObjectSP();
122  }
123
124  uint64_t GetIntegerValue(uint64_t fail_value = 0) const {
125    return (m_data_sp ? m_data_sp->GetIntegerValue(fail_value) : fail_value);
126  }
127
128  double GetFloatValue(double fail_value = 0.0) const {
129    return (m_data_sp ? m_data_sp->GetFloatValue(fail_value) : fail_value);
130  }
131
132  bool GetBooleanValue(bool fail_value = false) const {
133    return (m_data_sp ? m_data_sp->GetBooleanValue(fail_value) : fail_value);
134  }
135
136  size_t GetStringValue(char *dst, size_t dst_len) const {
137    if (!m_data_sp)
138      return 0;
139
140    llvm::StringRef result = m_data_sp->GetStringValue();
141    if (result.empty())
142      return 0;
143
144    if (!dst || !dst_len) {
145      char s[1];
146      return (::snprintf(s, 1, "%s", result.data()));
147    }
148    return (::snprintf(dst, dst_len, "%s", result.data()));
149  }
150
151private:
152  lldb::StructuredDataPluginWP m_plugin_wp;
153  StructuredData::ObjectSP m_data_sp;
154};
155} // namespace lldb_private
156#endif
157