tesseract  4.1.3
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 103 of file svutil.h.

Constructor & Destructor Documentation

◆ SVNetwork()

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

Set up a connection to hostname on port.

Definition at line 338 of file svutil.cpp.

338  {
339  msg_buffer_in_ = new char[kMaxMsgSize + 1];
340  msg_buffer_in_[0] = '\0';
341 
342  has_content = false;
343  buffer_ptr_ = nullptr;
344 
345  struct addrinfo *addr_info = nullptr;
346  char port_str[40];
347  snprintf(port_str, 40, "%d", port);
348 #ifdef _WIN32
349  // Initialize Winsock
350  WSADATA wsaData;
351  int iResult = WSAStartup(MAKEWORD(2, 2), &wsaData);
352  if (iResult != 0) {
353  std::cerr << "WSAStartup failed: " << iResult << std::endl;
354  }
355 #endif // _WIN32
356 
357  if (getaddrinfo(hostname, port_str, nullptr, &addr_info) != 0) {
358  std::cerr << "Error resolving name for ScrollView host "
359  << std::string(hostname) << ":" << port << std::endl;
360 #ifdef _WIN32
361  WSACleanup();
362 #endif // _WIN32
363  }
364 
365  stream_ = socket(addr_info->ai_family, addr_info->ai_socktype,
366  addr_info->ai_protocol);
367 
368  if (stream_ < 0) {
369  std::cerr << "Failed to open socket" << std::endl;
370  } else if (connect(stream_, addr_info->ai_addr, addr_info->ai_addrlen) < 0) {
371  // If server is not there, we will start a new server as local child process.
372  const char* scrollview_path = getenv("SCROLLVIEW_PATH");
373  if (scrollview_path == nullptr) {
374 #ifdef SCROLLVIEW_PATH
375 #define _STR(a) #a
376 #define _XSTR(a) _STR(a)
377  scrollview_path = _XSTR(SCROLLVIEW_PATH);
378 #undef _XSTR
379 #undef _STR
380 #else
381  scrollview_path = ".";
382 #endif
383  }
384  const char *prog = ScrollViewProg();
385  std::string command = ScrollViewCommand(scrollview_path);
386  SVSync::StartProcess(prog, command.c_str());
387 
388  // Wait for server to show up.
389  // Note: There is no exception handling in case the server never turns up.
390 
391  Close();
392  for (;;) {
393  stream_ = socket(addr_info->ai_family, addr_info->ai_socktype,
394  addr_info->ai_protocol);
395  if (stream_ >= 0) {
396  if (connect(stream_, addr_info->ai_addr, addr_info->ai_addrlen) == 0) {
397  break;
398  }
399 
400  Close();
401 
402  std::cout << "ScrollView: Waiting for server...\n";
403  std::this_thread::sleep_for(std::chrono::seconds(1));
404  }
405  }
406  }
407 #ifdef _WIN32
408  // WSACleanup(); // This cause ScrollView windows is not displayed
409 #endif // _WIN32
410  freeaddrinfo(addr_info);
411 }
const int kMaxMsgSize
Definition: svutil.cpp:110
static void StartProcess(const char *executable, const char *args)
Starts a new process.
Definition: svutil.cpp:122
void Close()
Close the connection to the server.
Definition: svutil.cpp:287

◆ ~SVNetwork()

SVNetwork::~SVNetwork ( )

Destructor.

Definition at line 413 of file svutil.cpp.

413  {
414  Close();
415  delete[] msg_buffer_in_;
416 }
void Close()
Close the connection to the server.
Definition: svutil.cpp:287

Member Function Documentation

◆ Close()

void SVNetwork::Close ( )

Close the connection to the server.

Definition at line 287 of file svutil.cpp.

287  {
288 #ifdef _WIN32
289  closesocket(stream_);
290 #else
291  close(stream_);
292 #endif
293  // Mark stream_ as invalid.
294  stream_ = -1;
295 }

◆ Flush()

void SVNetwork::Flush ( )

Flush the buffer.

Definition at line 228 of file svutil.cpp.

228  {
229  mutex_send_.Lock();
230  while (!msg_buffer_out_.empty()) {
231  int i = send(stream_, msg_buffer_out_.c_str(), msg_buffer_out_.length(), 0);
232  msg_buffer_out_.erase(0, i);
233  }
234  mutex_send_.Unlock();
235 }
void Lock()
Locks on a mutex.
Definition: svutil.cpp:72
void Unlock()
Unlocks on a mutex.
Definition: svutil.cpp:80

◆ Receive()

char * SVNetwork::Receive ( )

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

Definition at line 239 of file svutil.cpp.

239  {
240  char* result = nullptr;
241 #if defined(_WIN32) || defined(__CYGWIN__)
242  if (has_content) { result = strtok (nullptr, "\n"); }
243 #else
244  if (buffer_ptr_ != nullptr) { result = strtok_r(nullptr, "\n", &buffer_ptr_); }
245 #endif
246 
247  // This means there is something left in the buffer and we return it.
248  if (result != nullptr) { return result;
249  // Otherwise, we read from the stream_.
250  } else {
251  buffer_ptr_ = nullptr;
252  has_content = false;
253 
254  // The timeout length is not really important since we are looping anyway
255  // until a new message is delivered.
256  struct timeval tv;
257  tv.tv_sec = 10;
258  tv.tv_usec = 0;
259 
260  // Set the flags to return when the stream_ is ready to be read.
261  fd_set readfds;
262  FD_ZERO(&readfds);
263  FD_SET(stream_, &readfds);
264 
265  int i = select(stream_+1, &readfds, nullptr, nullptr, &tv);
266 
267  // The stream_ died.
268  if (i == 0) { return nullptr; }
269 
270  // Read the message buffer.
271  i = recv(stream_, msg_buffer_in_, kMaxMsgSize, 0);
272 
273  // Server quit (0) or error (-1).
274  if (i <= 0) { return nullptr; }
275  msg_buffer_in_[i] = '\0';
276  has_content = true;
277 #ifdef _WIN32
278  return strtok(msg_buffer_in_, "\n");
279 #else
280  // Setup a new string tokenizer.
281  return strtok_r(msg_buffer_in_, "\n", &buffer_ptr_);
282 #endif
283  }
284 }
const int kMaxMsgSize
Definition: svutil.cpp:110

◆ Send()

void SVNetwork::Send ( const char *  msg)

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

Definition at line 221 of file svutil.cpp.

221  {
222  mutex_send_.Lock();
223  msg_buffer_out_.append(msg);
224  mutex_send_.Unlock();
225 }
void Lock()
Locks on a mutex.
Definition: svutil.cpp:72
void Unlock()
Unlocks on a mutex.
Definition: svutil.cpp:80

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