1//===-- SBCommunication.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/API/SBCommunication.h"
11#include "lldb/API/SBBroadcaster.h"
12#include "lldb/Core/Communication.h"
13#include "lldb/Core/ConnectionFileDescriptor.h"
14#include "lldb/Core/Log.h"
15
16using namespace lldb;
17using namespace lldb_private;
18
19
20
21SBCommunication::SBCommunication() :
22    m_opaque (NULL),
23    m_opaque_owned (false)
24{
25}
26
27SBCommunication::SBCommunication(const char * broadcaster_name) :
28    m_opaque (new Communication (broadcaster_name)),
29    m_opaque_owned (true)
30{
31    Log *log(lldb_private::GetLogIfAllCategoriesSet (LIBLLDB_LOG_API));
32
33    if (log)
34        log->Printf ("SBCommunication::SBCommunication (broadcaster_name=\"%s\") => "
35                     "SBCommunication(%p)", broadcaster_name, m_opaque);
36}
37
38SBCommunication::~SBCommunication()
39{
40    if (m_opaque && m_opaque_owned)
41        delete m_opaque;
42    m_opaque = NULL;
43    m_opaque_owned = false;
44}
45
46bool
47SBCommunication::IsValid () const
48{
49    return m_opaque != NULL;
50}
51
52bool
53SBCommunication::GetCloseOnEOF ()
54{
55    if (m_opaque)
56        return m_opaque->GetCloseOnEOF ();
57    return false;
58}
59
60void
61SBCommunication::SetCloseOnEOF (bool b)
62{
63    if (m_opaque)
64        m_opaque->SetCloseOnEOF (b);
65}
66
67ConnectionStatus
68SBCommunication::Connect (const char *url)
69{
70    if (m_opaque)
71    {
72        if (!m_opaque->HasConnection ())
73            m_opaque->SetConnection (new ConnectionFileDescriptor());
74        return m_opaque->Connect (url, NULL);
75    }
76    return eConnectionStatusNoConnection;
77}
78
79ConnectionStatus
80SBCommunication::AdoptFileDesriptor (int fd, bool owns_fd)
81{
82    Log *log(lldb_private::GetLogIfAllCategoriesSet (LIBLLDB_LOG_API));
83
84    ConnectionStatus status = eConnectionStatusNoConnection;
85    if (m_opaque)
86    {
87        if (m_opaque->HasConnection ())
88        {
89            if (m_opaque->IsConnected())
90                m_opaque->Disconnect();
91        }
92        m_opaque->SetConnection (new ConnectionFileDescriptor (fd, owns_fd));
93        if (m_opaque->IsConnected())
94            status = eConnectionStatusSuccess;
95        else
96            status = eConnectionStatusLostConnection;
97    }
98
99    if (log)
100        log->Printf ("SBCommunication(%p)::AdoptFileDescriptor (fd=%d, ownd_fd=%i) => %s",
101                     m_opaque, fd, owns_fd, Communication::ConnectionStatusAsCString (status));
102
103    return status;
104}
105
106
107ConnectionStatus
108SBCommunication::Disconnect ()
109{
110    Log *log(lldb_private::GetLogIfAllCategoriesSet (LIBLLDB_LOG_API));
111
112    ConnectionStatus status= eConnectionStatusNoConnection;
113    if (m_opaque)
114        status = m_opaque->Disconnect ();
115
116    if (log)
117        log->Printf ("SBCommunication(%p)::Disconnect () => %s", m_opaque,
118                     Communication::ConnectionStatusAsCString (status));
119
120    return status;
121}
122
123bool
124SBCommunication::IsConnected () const
125{
126    Log *log(lldb_private::GetLogIfAllCategoriesSet (LIBLLDB_LOG_API));
127    bool result = false;
128    if (m_opaque)
129        result = m_opaque->IsConnected ();
130
131    if (log)
132        log->Printf ("SBCommunication(%p)::IsConnected () => %i", m_opaque, result);
133
134    return false;
135}
136
137size_t
138SBCommunication::Read (void *dst, size_t dst_len, uint32_t timeout_usec, ConnectionStatus &status)
139{
140    Log *log(lldb_private::GetLogIfAllCategoriesSet (LIBLLDB_LOG_API));
141    if (log)
142        log->Printf ("SBCommunication(%p)::Read (dst=%p, dst_len=%" PRIu64 ", timeout_usec=%u, &status)...",
143                     m_opaque,
144                     dst,
145                     (uint64_t)dst_len,
146                     timeout_usec);
147    size_t bytes_read = 0;
148    if (m_opaque)
149        bytes_read = m_opaque->Read (dst, dst_len, timeout_usec, status, NULL);
150    else
151        status = eConnectionStatusNoConnection;
152
153    if (log)
154        log->Printf ("SBCommunication(%p)::Read (dst=%p, dst_len=%" PRIu64 ", timeout_usec=%u, &status=%s) => %" PRIu64,
155                     m_opaque,
156                     dst,
157                     (uint64_t)dst_len,
158                     timeout_usec,
159                     Communication::ConnectionStatusAsCString (status),
160                     (uint64_t)bytes_read);
161    return bytes_read;
162}
163
164
165size_t
166SBCommunication::Write (const void *src, size_t src_len, ConnectionStatus &status)
167{
168    size_t bytes_written = 0;
169    if (m_opaque)
170        bytes_written = m_opaque->Write (src, src_len, status, NULL);
171    else
172        status = eConnectionStatusNoConnection;
173
174    Log *log(lldb_private::GetLogIfAllCategoriesSet (LIBLLDB_LOG_API));
175    if (log)
176        log->Printf ("SBCommunication(%p)::Write (src=%p, src_len=%" PRIu64 ", &status=%s) => %" PRIu64,
177                     m_opaque, src, (uint64_t)src_len, Communication::ConnectionStatusAsCString (status), (uint64_t)bytes_written);
178
179    return 0;
180}
181
182bool
183SBCommunication::ReadThreadStart ()
184{
185    Log *log(lldb_private::GetLogIfAllCategoriesSet (LIBLLDB_LOG_API));
186
187    bool success = false;
188    if (m_opaque)
189        success = m_opaque->StartReadThread ();
190
191    if (log)
192        log->Printf ("SBCommunication(%p)::ReadThreadStart () => %i", m_opaque, success);
193
194    return success;
195}
196
197
198bool
199SBCommunication::ReadThreadStop ()
200{
201    Log *log(lldb_private::GetLogIfAllCategoriesSet (LIBLLDB_LOG_API));
202    if (log)
203        log->Printf ("SBCommunication(%p)::ReadThreadStop ()...", m_opaque);
204
205    bool success = false;
206    if (m_opaque)
207        success = m_opaque->StopReadThread ();
208
209    if (log)
210        log->Printf ("SBCommunication(%p)::ReadThreadStop () => %i", m_opaque, success);
211
212    return success;
213}
214
215bool
216SBCommunication::ReadThreadIsRunning ()
217{
218    bool result = false;
219    if (m_opaque)
220        result = m_opaque->ReadThreadIsRunning ();
221    Log *log(lldb_private::GetLogIfAllCategoriesSet (LIBLLDB_LOG_API));
222    if (log)
223        log->Printf ("SBCommunication(%p)::ReadThreadIsRunning () => %i", m_opaque, result);
224    return result;
225}
226
227bool
228SBCommunication::SetReadThreadBytesReceivedCallback
229(
230    ReadThreadBytesReceived callback,
231    void *callback_baton
232)
233{
234    Log *log(lldb_private::GetLogIfAllCategoriesSet (LIBLLDB_LOG_API));
235
236    bool result = false;
237    if (m_opaque)
238    {
239        m_opaque->SetReadThreadBytesReceivedCallback (callback, callback_baton);
240        result = true;
241    }
242
243    if (log)
244        log->Printf ("SBCommunication(%p)::SetReadThreadBytesReceivedCallback (callback=%p, baton=%p) => %i",
245                     m_opaque, callback, callback_baton, result);
246
247    return result;
248}
249
250SBBroadcaster
251SBCommunication::GetBroadcaster ()
252{
253    SBBroadcaster broadcaster (m_opaque, false);
254
255    Log *log(lldb_private::GetLogIfAllCategoriesSet (LIBLLDB_LOG_API));
256
257    if (log)
258        log->Printf ("SBCommunication(%p)::GetBroadcaster () => SBBroadcaster (%p)",
259                     m_opaque, broadcaster.get());
260
261    return broadcaster;
262}
263
264const char *
265SBCommunication::GetBroadcasterClass ()
266{
267    return Communication::GetStaticBroadcasterClass().AsCString();
268}
269
270//
271//void
272//SBCommunication::CreateIfNeeded ()
273//{
274//    if (m_opaque == NULL)
275//    {
276//        static uint32_t g_broadcaster_num;
277//        char broadcaster_name[256];
278//        ::snprintf (name, broadcaster_name, "%p SBCommunication", this);
279//        m_opaque = new Communication (broadcaster_name);
280//        m_opaque_owned = true;
281//    }
282//    assert (m_opaque);
283//}
284//
285//
286