1 //===-- SBEvent.cpp ---------------------------------------------*- 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 #include "lldb/API/SBEvent.h"
10 #include "lldb/API/SBBroadcaster.h"
11 #include "lldb/API/SBStream.h"
12 
13 #include "lldb/Breakpoint/Breakpoint.h"
14 #include "lldb/Core/StreamFile.h"
15 #include "lldb/Interpreter/CommandInterpreter.h"
16 #include "lldb/Target/Process.h"
17 #include "lldb/Utility/ConstString.h"
18 #include "lldb/Utility/Event.h"
19 #include "lldb/Utility/Stream.h"
20 
21 using namespace lldb;
22 using namespace lldb_private;
23 
24 SBEvent::SBEvent() : m_event_sp(), m_opaque_ptr(NULL) {}
25 
26 SBEvent::SBEvent(uint32_t event_type, const char *cstr, uint32_t cstr_len)
27     : m_event_sp(new Event(event_type, new EventDataBytes(cstr, cstr_len))),
28       m_opaque_ptr(m_event_sp.get()) {}
29 
30 SBEvent::SBEvent(EventSP &event_sp)
31     : m_event_sp(event_sp), m_opaque_ptr(event_sp.get()) {}
32 
33 SBEvent::SBEvent(Event *event_ptr) : m_event_sp(), m_opaque_ptr(event_ptr) {}
34 
35 SBEvent::SBEvent(const SBEvent &rhs)
36     : m_event_sp(rhs.m_event_sp), m_opaque_ptr(rhs.m_opaque_ptr) {}
37 
38 const SBEvent &SBEvent::operator=(const SBEvent &rhs) {
39   if (this != &rhs) {
40     m_event_sp = rhs.m_event_sp;
41     m_opaque_ptr = rhs.m_opaque_ptr;
42   }
43   return *this;
44 }
45 
46 SBEvent::~SBEvent() {}
47 
48 const char *SBEvent::GetDataFlavor() {
49   Event *lldb_event = get();
50   if (lldb_event) {
51     EventData *event_data = lldb_event->GetData();
52     if (event_data)
53       return lldb_event->GetData()->GetFlavor().AsCString();
54   }
55   return NULL;
56 }
57 
58 uint32_t SBEvent::GetType() const {
59   Log *log(lldb_private::GetLogIfAllCategoriesSet(LIBLLDB_LOG_API));
60 
61   const Event *lldb_event = get();
62   uint32_t event_type = 0;
63   if (lldb_event)
64     event_type = lldb_event->GetType();
65 
66   if (log) {
67     StreamString sstr;
68     if (lldb_event && lldb_event->GetBroadcaster() &&
69         lldb_event->GetBroadcaster()->GetEventNames(sstr, event_type, true))
70       log->Printf("SBEvent(%p)::GetType () => 0x%8.8x (%s)",
71                   static_cast<void *>(get()), event_type, sstr.GetData());
72     else
73       log->Printf("SBEvent(%p)::GetType () => 0x%8.8x",
74                   static_cast<void *>(get()), event_type);
75   }
76 
77   return event_type;
78 }
79 
80 SBBroadcaster SBEvent::GetBroadcaster() const {
81   SBBroadcaster broadcaster;
82   const Event *lldb_event = get();
83   if (lldb_event)
84     broadcaster.reset(lldb_event->GetBroadcaster(), false);
85   return broadcaster;
86 }
87 
88 const char *SBEvent::GetBroadcasterClass() const {
89   const Event *lldb_event = get();
90   if (lldb_event)
91     return lldb_event->GetBroadcaster()->GetBroadcasterClass().AsCString();
92   else
93     return "unknown class";
94 }
95 
96 bool SBEvent::BroadcasterMatchesPtr(const SBBroadcaster *broadcaster) {
97   if (broadcaster)
98     return BroadcasterMatchesRef(*broadcaster);
99   return false;
100 }
101 
102 bool SBEvent::BroadcasterMatchesRef(const SBBroadcaster &broadcaster) {
103 
104   Event *lldb_event = get();
105   bool success = false;
106   if (lldb_event)
107     success = lldb_event->BroadcasterIs(broadcaster.get());
108 
109   // For logging, this gets a little chatty so only enable this when verbose
110   // logging is on
111   Log *log(lldb_private::GetLogIfAllCategoriesSet(LIBLLDB_LOG_API));
112   LLDB_LOGV(log, "({0}) (SBBroadcaster({1}): {2}) => {3}", get(),
113             broadcaster.get(), broadcaster.GetName(), success);
114 
115   return success;
116 }
117 
118 void SBEvent::Clear() {
119   Event *lldb_event = get();
120   if (lldb_event)
121     lldb_event->Clear();
122 }
123 
124 EventSP &SBEvent::GetSP() const { return m_event_sp; }
125 
126 Event *SBEvent::get() const {
127   // There is a dangerous accessor call GetSharedPtr which can be used, so if
128   // we have anything valid in m_event_sp, we must use that since if it gets
129   // used by a function that puts something in there, then it won't update
130   // m_opaque_ptr...
131   if (m_event_sp)
132     m_opaque_ptr = m_event_sp.get();
133 
134   return m_opaque_ptr;
135 }
136 
137 void SBEvent::reset(EventSP &event_sp) {
138   m_event_sp = event_sp;
139   m_opaque_ptr = m_event_sp.get();
140 }
141 
142 void SBEvent::reset(Event *event_ptr) {
143   m_opaque_ptr = event_ptr;
144   m_event_sp.reset();
145 }
146 
147 bool SBEvent::IsValid() const {
148   // Do NOT use m_opaque_ptr directly!!! Must use the SBEvent::get() accessor.
149   // See comments in SBEvent::get()....
150   return SBEvent::get() != NULL;
151 }
152 
153 const char *SBEvent::GetCStringFromEvent(const SBEvent &event) {
154   Log *log(lldb_private::GetLogIfAllCategoriesSet(LIBLLDB_LOG_API));
155 
156   if (log)
157     log->Printf("SBEvent(%p)::GetCStringFromEvent () => \"%s\"",
158                 static_cast<void *>(event.get()),
159                 reinterpret_cast<const char *>(
160                     EventDataBytes::GetBytesFromEvent(event.get())));
161 
162   return reinterpret_cast<const char *>(
163       EventDataBytes::GetBytesFromEvent(event.get()));
164 }
165 
166 bool SBEvent::GetDescription(SBStream &description) {
167   Stream &strm = description.ref();
168 
169   if (get()) {
170     m_opaque_ptr->Dump(&strm);
171   } else
172     strm.PutCString("No value");
173 
174   return true;
175 }
176 
177 bool SBEvent::GetDescription(SBStream &description) const {
178   Stream &strm = description.ref();
179 
180   if (get()) {
181     m_opaque_ptr->Dump(&strm);
182   } else
183     strm.PutCString("No value");
184 
185   return true;
186 }
187