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