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