1//===-- SBListener.cpp ------------------------------------------*- C++ -*-===//
2//
3//                     The LLVM Compiler Infrastructure
4//
5// This file is distributed under the University of Illinois Open Source
6// License. See LICENSE.TXT for details.
7//
8//===----------------------------------------------------------------------===//
9
10#include "lldb/lldb-python.h"
11
12#include "lldb/API/SBListener.h"
13#include "lldb/API/SBBroadcaster.h"
14#include "lldb/API/SBDebugger.h"
15#include "lldb/API/SBEvent.h"
16#include "lldb/API/SBStream.h"
17#include "lldb/Core/Broadcaster.h"
18#include "lldb/Core/Debugger.h"
19#include "lldb/Core/Listener.h"
20#include "lldb/Core/Log.h"
21#include "lldb/Core/StreamString.h"
22#include "lldb/Host/TimeValue.h"
23
24
25using namespace lldb;
26using namespace lldb_private;
27
28
29SBListener::SBListener () :
30    m_opaque_sp (),
31    m_opaque_ptr (NULL)
32{
33}
34
35SBListener::SBListener (const char *name) :
36    m_opaque_sp (new Listener (name)),
37    m_opaque_ptr (NULL)
38{
39    m_opaque_ptr = m_opaque_sp.get();
40
41    Log *log(lldb_private::GetLogIfAllCategoriesSet (LIBLLDB_LOG_API));
42
43    if (log)
44        log->Printf ("SBListener::SBListener (name=\"%s\") => SBListener(%p)",
45                     name, m_opaque_ptr);
46}
47
48
49SBListener::SBListener (const SBListener &rhs) :
50    m_opaque_sp (rhs.m_opaque_sp),
51    m_opaque_ptr (rhs.m_opaque_ptr)
52{
53}
54
55const lldb::SBListener &
56SBListener::operator = (const lldb::SBListener &rhs)
57{
58    if (this != &rhs)
59    {
60        m_opaque_sp = rhs.m_opaque_sp;
61        m_opaque_ptr = rhs.m_opaque_ptr;
62    }
63    return *this;
64}
65
66SBListener::SBListener (Listener &listener) :
67    m_opaque_sp (),
68    m_opaque_ptr (&listener)
69{
70}
71
72SBListener::~SBListener ()
73{
74}
75
76bool
77SBListener::IsValid() const
78{
79    return m_opaque_ptr != NULL;
80}
81
82void
83SBListener::AddEvent (const SBEvent &event)
84{
85    EventSP &event_sp = event.GetSP ();
86    if (event_sp)
87        m_opaque_ptr->AddEvent (event_sp);
88}
89
90void
91SBListener::Clear ()
92{
93    if (m_opaque_ptr)
94        m_opaque_ptr->Clear ();
95}
96
97uint32_t
98SBListener::StartListeningForEventClass (SBDebugger &debugger,
99                             const char *broadcaster_class,
100                             uint32_t event_mask)
101{
102    if (m_opaque_ptr)
103    {
104        Debugger *lldb_debugger = debugger.get();
105        if (!lldb_debugger)
106            return 0;
107        BroadcastEventSpec event_spec (ConstString (broadcaster_class), event_mask);
108        return m_opaque_ptr->StartListeningForEventSpec (*lldb_debugger, event_spec);
109    }
110    else
111        return 0;
112}
113
114bool
115SBListener::StopListeningForEventClass (SBDebugger &debugger,
116                            const char *broadcaster_class,
117                            uint32_t event_mask)
118{
119    if (m_opaque_ptr)
120    {
121        Debugger *lldb_debugger = debugger.get();
122        if (!lldb_debugger)
123            return false;
124        BroadcastEventSpec event_spec (ConstString (broadcaster_class), event_mask);
125        return m_opaque_ptr->StopListeningForEventSpec (*lldb_debugger, event_spec);
126    }
127    else
128        return false;
129}
130
131uint32_t
132SBListener::StartListeningForEvents (const SBBroadcaster& broadcaster, uint32_t event_mask)
133{
134    uint32_t acquired_event_mask = 0;
135    if (m_opaque_ptr && broadcaster.IsValid())
136    {
137        acquired_event_mask = m_opaque_ptr->StartListeningForEvents (broadcaster.get(), event_mask);
138    }
139
140    Log *log = lldb_private::GetLogIfAllCategoriesSet (LIBLLDB_LOG_API);
141    if (log)
142    {
143        StreamString sstr_requested;
144        StreamString sstr_acquired;
145
146        Broadcaster *lldb_broadcaster = broadcaster.get();
147        if (lldb_broadcaster)
148        {
149            const bool got_requested_names = lldb_broadcaster->GetEventNames (sstr_requested, event_mask, false);
150            const bool got_acquired_names = lldb_broadcaster->GetEventNames (sstr_acquired, acquired_event_mask, false);
151            log->Printf ("SBListener(%p)::StartListeneingForEvents (SBBroadcaster(%p): %s, event_mask=0x%8.8x%s%s%s) => 0x%8.8x%s%s%s",
152                         m_opaque_ptr,
153                         lldb_broadcaster,
154                         lldb_broadcaster->GetBroadcasterName().GetCString(),
155                         event_mask,
156                         got_requested_names ? " (" : "",
157                         sstr_requested.GetData(),
158                         got_requested_names ? ")" : "",
159                         acquired_event_mask,
160                         got_acquired_names ? " (" : "",
161                         sstr_acquired.GetData(),
162                         got_acquired_names ? ")" : "");
163        }
164        else
165        {
166            log->Printf ("SBListener(%p)::StartListeneingForEvents (SBBroadcaster(%p), event_mask=0x%8.8x) => 0x%8.8x",
167                         m_opaque_ptr,
168                         lldb_broadcaster,
169                         event_mask,
170                         acquired_event_mask);
171
172        }
173    }
174
175    return acquired_event_mask;
176}
177
178bool
179SBListener::StopListeningForEvents (const SBBroadcaster& broadcaster, uint32_t event_mask)
180{
181    if (m_opaque_ptr && broadcaster.IsValid())
182    {
183        return m_opaque_ptr->StopListeningForEvents (broadcaster.get(), event_mask);
184    }
185    return false;
186}
187
188bool
189SBListener::WaitForEvent (uint32_t timeout_secs, SBEvent &event)
190{
191    Log *log(lldb_private::GetLogIfAllCategoriesSet (LIBLLDB_LOG_API));
192    if (log)
193    {
194        if (timeout_secs == UINT32_MAX)
195        {
196            log->Printf ("SBListener(%p)::WaitForEvent (timeout_secs=INFINITE, SBEvent(%p))...",
197                         m_opaque_ptr, event.get());
198        }
199        else
200        {
201            log->Printf ("SBListener(%p)::WaitForEvent (timeout_secs=%d, SBEvent(%p))...",
202                         m_opaque_ptr, timeout_secs, event.get());
203        }
204    }
205    bool success = false;
206
207    if (m_opaque_ptr)
208    {
209        TimeValue time_value;
210        if (timeout_secs != UINT32_MAX)
211        {
212            assert (timeout_secs != 0); // Take this out after all calls with timeout set to zero have been removed....
213            time_value = TimeValue::Now();
214            time_value.OffsetWithSeconds (timeout_secs);
215        }
216        EventSP event_sp;
217        if (m_opaque_ptr->WaitForEvent (time_value.IsValid() ? &time_value : NULL, event_sp))
218        {
219            event.reset (event_sp);
220            success = true;
221        }
222    }
223
224    if (log)
225    {
226        if (timeout_secs == UINT32_MAX)
227        {
228            log->Printf ("SBListener(%p)::WaitForEvent (timeout_secs=INFINITE, SBEvent(%p)) => %i",
229                         m_opaque_ptr, event.get(), success);
230        }
231        else
232        {
233            log->Printf ("SBListener(%p)::WaitForEvent (timeout_secs=%d, SBEvent(%p)) => %i",
234                         m_opaque_ptr, timeout_secs, event.get(), success);
235        }
236    }
237    if (!success)
238        event.reset (NULL);
239    return success;
240}
241
242bool
243SBListener::WaitForEventForBroadcaster
244(
245    uint32_t num_seconds,
246    const SBBroadcaster &broadcaster,
247    SBEvent &event
248)
249{
250    if (m_opaque_ptr && broadcaster.IsValid())
251    {
252        TimeValue time_value;
253        if (num_seconds != UINT32_MAX)
254        {
255            time_value = TimeValue::Now();
256            time_value.OffsetWithSeconds (num_seconds);
257        }
258        EventSP event_sp;
259        if (m_opaque_ptr->WaitForEventForBroadcaster (time_value.IsValid() ? &time_value : NULL,
260                                                         broadcaster.get(),
261                                                         event_sp))
262        {
263            event.reset (event_sp);
264            return true;
265        }
266
267    }
268    event.reset (NULL);
269    return false;
270}
271
272bool
273SBListener::WaitForEventForBroadcasterWithType
274(
275    uint32_t num_seconds,
276    const SBBroadcaster &broadcaster,
277    uint32_t event_type_mask,
278    SBEvent &event
279)
280{
281    if (m_opaque_ptr && broadcaster.IsValid())
282    {
283        TimeValue time_value;
284        if (num_seconds != UINT32_MAX)
285        {
286            time_value = TimeValue::Now();
287            time_value.OffsetWithSeconds (num_seconds);
288        }
289        EventSP event_sp;
290        if (m_opaque_ptr->WaitForEventForBroadcasterWithType (time_value.IsValid() ? &time_value : NULL,
291                                                              broadcaster.get(),
292                                                              event_type_mask,
293                                                              event_sp))
294        {
295            event.reset (event_sp);
296            return true;
297        }
298    }
299    event.reset (NULL);
300    return false;
301}
302
303bool
304SBListener::PeekAtNextEvent (SBEvent &event)
305{
306    if (m_opaque_ptr)
307    {
308        event.reset (m_opaque_ptr->PeekAtNextEvent ());
309        return event.IsValid();
310    }
311    event.reset (NULL);
312    return false;
313}
314
315bool
316SBListener::PeekAtNextEventForBroadcaster (const SBBroadcaster &broadcaster, SBEvent &event)
317{
318    if (m_opaque_ptr && broadcaster.IsValid())
319    {
320        event.reset (m_opaque_ptr->PeekAtNextEventForBroadcaster (broadcaster.get()));
321        return event.IsValid();
322    }
323    event.reset (NULL);
324    return false;
325}
326
327bool
328SBListener::PeekAtNextEventForBroadcasterWithType (const SBBroadcaster &broadcaster, uint32_t event_type_mask,
329                                                   SBEvent &event)
330{
331    if (m_opaque_ptr && broadcaster.IsValid())
332    {
333        event.reset(m_opaque_ptr->PeekAtNextEventForBroadcasterWithType (broadcaster.get(), event_type_mask));
334        return event.IsValid();
335    }
336    event.reset (NULL);
337    return false;
338}
339
340bool
341SBListener::GetNextEvent (SBEvent &event)
342{
343    if (m_opaque_ptr)
344    {
345        EventSP event_sp;
346        if (m_opaque_ptr->GetNextEvent (event_sp))
347        {
348            event.reset (event_sp);
349            return true;
350        }
351    }
352    event.reset (NULL);
353    return false;
354}
355
356bool
357SBListener::GetNextEventForBroadcaster (const SBBroadcaster &broadcaster, SBEvent &event)
358{
359    if (m_opaque_ptr && broadcaster.IsValid())
360    {
361        EventSP event_sp;
362        if (m_opaque_ptr->GetNextEventForBroadcaster (broadcaster.get(), event_sp))
363        {
364            event.reset (event_sp);
365            return true;
366        }
367    }
368    event.reset (NULL);
369    return false;
370}
371
372bool
373SBListener::GetNextEventForBroadcasterWithType
374(
375    const SBBroadcaster &broadcaster,
376    uint32_t event_type_mask,
377    SBEvent &event
378)
379{
380    if (m_opaque_ptr && broadcaster.IsValid())
381    {
382        EventSP event_sp;
383        if (m_opaque_ptr->GetNextEventForBroadcasterWithType (broadcaster.get(),
384                                                              event_type_mask,
385                                                              event_sp))
386        {
387            event.reset (event_sp);
388            return true;
389        }
390    }
391    event.reset (NULL);
392    return false;
393}
394
395bool
396SBListener::HandleBroadcastEvent (const SBEvent &event)
397{
398    if (m_opaque_ptr)
399        return m_opaque_ptr->HandleBroadcastEvent (event.GetSP());
400    return false;
401}
402
403Listener *
404SBListener::operator->() const
405{
406    return m_opaque_ptr;
407}
408
409Listener *
410SBListener::get() const
411{
412    return m_opaque_ptr;
413}
414
415void
416SBListener::reset(Listener *listener, bool owns)
417{
418    if (owns)
419        m_opaque_sp.reset (listener);
420    else
421        m_opaque_sp.reset ();
422    m_opaque_ptr = listener;
423}
424
425Listener &
426SBListener::ref() const
427{
428    return *m_opaque_ptr;
429}
430
431Listener &
432SBListener::operator *()
433{
434    return *m_opaque_ptr;
435}
436
437const Listener &
438SBListener::operator *() const
439{
440    return *m_opaque_ptr;
441}
442
443
444