tesseract  5.0.0
tesseract::SVNetwork Class Reference

#include <svutil.h>

Public Member Functions

 SVNetwork (const char *hostname, int port)
 Set up a connection to hostname on port. More...
 
 ~SVNetwork ()
 Destructor. More...
 
void Send (const char *msg)
 Put a message in the messagebuffer to the server and try to send it. More...
 
char * Receive ()
 
void Close ()
 Close the connection to the server. More...
 
void Flush ()
 Flush the buffer. More...
 

Detailed Description

The SVNetwork class takes care of the remote connection for ScrollView This means setting up and maintaining a remote connection, sending and receiving messages and closing the connection. It is designed to work on both Linux and Windows.

Definition at line 71 of file svutil.h.

Constructor & Destructor Documentation

◆ SVNetwork()

tesseract::SVNetwork::SVNetwork ( const char *  hostname,
int  port 
)

Set up a connection to hostname on port.

Definition at line 275 of file svutil.cpp.

275  {
276  msg_buffer_in_ = new char[kMaxMsgSize + 1];
277  msg_buffer_in_[0] = '\0';
278 
279  buffer_ptr_ = nullptr;
280 
281  struct addrinfo *addr_info = nullptr;
282  auto port_string = std::to_string(port);
283 # ifdef _WIN32
284  // Initialize Winsock
285  WSADATA wsaData;
286  int iResult = WSAStartup(MAKEWORD(2, 2), &wsaData);
287  if (iResult != 0) {
288  std::cerr << "WSAStartup failed: " << iResult << std::endl;
289  }
290 # endif // _WIN32
291 
292  if (getaddrinfo(hostname, port_string.c_str(), nullptr, &addr_info) != 0) {
293  std::cerr << "Error resolving name for ScrollView host "
294  << std::string(hostname) << ":" << port << std::endl;
295 # ifdef _WIN32
296  WSACleanup();
297 # endif // _WIN32
298  }
299 
300  stream_ = socket(addr_info->ai_family, addr_info->ai_socktype,
301  addr_info->ai_protocol);
302 
303  if (stream_ < 0) {
304  std::cerr << "Failed to open socket" << std::endl;
305  } else if (connect(stream_, addr_info->ai_addr, addr_info->ai_addrlen) < 0) {
306  // If server is not there, we will start a new server as local child
307  // process.
308  const char *scrollview_path = getenv("SCROLLVIEW_PATH");
309  if (scrollview_path == nullptr) {
310 # ifdef SCROLLVIEW_PATH
311 # define _STR(a) # a
312 # define _XSTR(a) _STR(a)
313  scrollview_path = _XSTR(SCROLLVIEW_PATH);
314 # undef _XSTR
315 # undef _STR
316 # else
317  scrollview_path = ".";
318 # endif
319  }
320  const char *prog = ScrollViewProg();
321  std::string command = ScrollViewCommand(scrollview_path);
322  SVSync::StartProcess(prog, command.c_str());
323 
324  // Wait for server to show up.
325  // Note: There is no exception handling in case the server never turns up.
326 
327  Close();
328  for (;;) {
329  stream_ = socket(addr_info->ai_family, addr_info->ai_socktype,
330  addr_info->ai_protocol);
331  if (stream_ >= 0) {
332  if (connect(stream_, addr_info->ai_addr, addr_info->ai_addrlen) == 0) {
333  break;
334  }
335 
336  Close();
337 
338  std::cout << "ScrollView: Waiting for server...\n";
339  std::this_thread::sleep_for(std::chrono::seconds(1));
340  }
341  }
342  }
343 # ifdef _WIN32
344  // WSACleanup(); // This cause ScrollView windows is not displayed
345 # endif // _WIN32
346  freeaddrinfo(addr_info);
347 }
const int kMaxMsgSize
Definition: scrollview.cpp:46
static void StartProcess(const char *executable, const char *args)
Starts a new process.
Definition: svutil.cpp:67
void Close()
Close the connection to the server.
Definition: svutil.cpp:225

◆ ~SVNetwork()

tesseract::SVNetwork::~SVNetwork ( )

Destructor.

Definition at line 349 of file svutil.cpp.

349  {
350  Close();
351  delete[] msg_buffer_in_;
352 }

Member Function Documentation

◆ Close()

void tesseract::SVNetwork::Close ( )

Close the connection to the server.

Definition at line 225 of file svutil.cpp.

225  {
226 # ifdef _WIN32
227  closesocket(stream_);
228 # else
229  close(stream_);
230 # endif
231  // Mark stream_ as invalid.
232  stream_ = -1;
233 }

◆ Flush()

void tesseract::SVNetwork::Flush ( )

Flush the buffer.

Definition at line 170 of file svutil.cpp.

170  {
171  std::lock_guard<std::mutex> guard(mutex_send_);
172  while (!msg_buffer_out_.empty()) {
173  int i = send(stream_, msg_buffer_out_.c_str(), msg_buffer_out_.length(), 0);
174  msg_buffer_out_.erase(0, i);
175  }
176 }

◆ Receive()

char * tesseract::SVNetwork::Receive ( )

Receive a message from the server. This will always return one line of char* (denoted by \n).

Definition at line 180 of file svutil.cpp.

180  {
181  char *result = nullptr;
182  if (buffer_ptr_ != nullptr) {
183  result = strtok_r(nullptr, "\n", &buffer_ptr_);
184  }
185 
186  // This means there is something left in the buffer and we return it.
187  if (result != nullptr) {
188  return result;
189  // Otherwise, we read from the stream_.
190  } else {
191  buffer_ptr_ = nullptr;
192 
193  // The timeout length is not really important since we are looping anyway
194  // until a new message is delivered.
195  struct timeval tv;
196  tv.tv_sec = 10;
197  tv.tv_usec = 0;
198 
199  // Set the flags to return when the stream_ is ready to be read.
200  fd_set readfds;
201  FD_ZERO(&readfds);
202  FD_SET(stream_, &readfds);
203 
204  int i = select(stream_ + 1, &readfds, nullptr, nullptr, &tv);
205 
206  // The stream_ died.
207  if (i == 0) {
208  return nullptr;
209  }
210 
211  // Read the message buffer.
212  i = recv(stream_, msg_buffer_in_, kMaxMsgSize, 0);
213 
214  // Server quit (0) or error (-1).
215  if (i <= 0) {
216  return nullptr;
217  }
218  msg_buffer_in_[i] = '\0';
219  // Setup a new string tokenizer.
220  return strtok_r(msg_buffer_in_, "\n", &buffer_ptr_);
221  }
222 }

◆ Send()

void tesseract::SVNetwork::Send ( const char *  msg)

Put a message in the messagebuffer to the server and try to send it.

Definition at line 164 of file svutil.cpp.

164  {
165  std::lock_guard<std::mutex> guard(mutex_send_);
166  msg_buffer_out_.append(msg);
167 }

The documentation for this class was generated from the following files: