The Battle for Wesnoth  1.15.12+dev
network_asio.hpp
Go to the documentation of this file.
1 /*
2  Copyright (C) 2011 - 2018 by Sergey Popov <loonycyborg@gmail.com>
3  Part of the Battle for Wesnoth Project https://www.wesnoth.org/
4 
5  This program is free software; you can redistribute it and/or modify
6  it under the terms of the GNU General Public License as published by
7  the Free Software Foundation; either version 2 of the License, or
8  (at your option) any later version.
9  This program is distributed in the hope that it will be useful,
10  but WITHOUT ANY WARRANTY.
11 
12  See the COPYING file for more details.
13 */
14 
15 #pragma once
16 
17 #ifdef _WIN32
18 
19 #ifdef INADDR_ANY
20 #undef INADDR_ANY
21 #endif
22 
23 #ifdef INADDR_BROADCAST
24 #undef INADDR_BROADCAST
25 #endif
26 
27 #ifdef INADDR_NONE
28 #undef INADDR_NONE
29 #endif
30 
31 #endif
32 
33 #include "exceptions.hpp"
34 
35 #if BOOST_VERSION >= 106600
36 #include <boost/asio/io_context.hpp>
37 #else
38 #include <boost/asio/io_service.hpp>
39 #endif
40 #include <boost/asio/ip/tcp.hpp>
41 #include <boost/asio/streambuf.hpp>
42 
43 class config;
44 
45 namespace network_asio
46 {
47 struct error : public game::error
48 {
49  error(const boost::system::error_code& error)
50  : game::error(error.message())
51  {
52  }
53 };
54 
55 union data_union {
56  char binary[4];
57  uint32_t num;
58 };
59 
60 /** A class that represents a TCP/IP connection. */
62 {
63 public:
64  /**
65  * Constructor.
66  *
67  * @param host Name of the host to connect to
68  * @param service Service identifier such as "80" or "http"
69  */
70  connection(const std::string& host, const std::string& service);
71 
72  void transfer(const config& request, config& response);
73 
74  /** Handle all pending asynchronous events and return */
75  std::size_t poll()
76  {
77  try {
78  return io_context_.poll();
79  } catch(const boost::system::system_error& err) {
80  if(err.code() == boost::asio::error::operation_aborted) {
81  return 1;
82  }
83 
84  throw error(err.code());
85  }
86  }
87 
88  /**
89  * Run asio's event loop
90  *
91  * Handle asynchronous events blocking until all asynchronous operations have finished.
92  */
93  void run()
94  {
95  io_context_.run();
96  }
97 
98  void cancel();
99 
100  /** True if connected and no high-level operation is in progress */
101  bool done() const
102  {
103  return done_;
104  }
105 
106  std::size_t bytes_to_write() const
107  {
108  return bytes_to_write_;
109  }
110 
111  std::size_t bytes_written() const
112  {
113  return bytes_written_;
114  }
115 
116  std::size_t bytes_to_read() const
117  {
118  return bytes_to_read_;
119  }
120 
121  std::size_t bytes_read() const
122  {
123  return bytes_read_;
124  }
125 
126 private:
127 #if BOOST_VERSION >= 106600
128  boost::asio::io_context io_context_;
129 #else
130  boost::asio::io_service io_context_;
131 #endif
132 
133  typedef boost::asio::ip::tcp::resolver resolver;
134  resolver resolver_;
135 
136  typedef boost::asio::ip::tcp::socket socket;
137  socket socket_;
138 
139  bool done_;
140 
141  std::unique_ptr<boost::asio::streambuf> write_buf_;
142  std::unique_ptr<boost::asio::streambuf> read_buf_;
143 
144 #if BOOST_VERSION >= 106600
145  using results_type = resolver::results_type;
146  using endpoint = const boost::asio::ip::tcp::endpoint&;
147 #else
150 #endif
151 
152  void handle_resolve(const boost::system::error_code& ec, results_type results);
153  void handle_connect(const boost::system::error_code& ec, endpoint endpoint);
154 
155  void handshake();
156  void handle_handshake(const boost::system::error_code& ec);
157 
159 
160  std::size_t is_write_complete(const boost::system::error_code& error, std::size_t bytes_transferred);
161  void handle_write(const boost::system::error_code& ec, std::size_t bytes_transferred);
162 
163  std::size_t is_read_complete(const boost::system::error_code& error, std::size_t bytes_transferred);
164  void handle_read(const boost::system::error_code& ec, std::size_t bytes_transferred, config& response);
165 
166  uint32_t payload_size_;
167 
168  std::size_t bytes_to_write_;
169  std::size_t bytes_written_;
170  std::size_t bytes_to_read_;
171  std::size_t bytes_read_;
172 };
173 }
boost::asio::io_service io_context_
boost::asio::ip::tcp::socket socket
resolver::iterator results_type
std::size_t bytes_read() const
boost::asio::ip::tcp::resolver resolver
std::size_t bytes_to_read() const
A class that represents a TCP/IP connection.
error(const boost::system::error_code &error)
bool done() const
True if connected and no high-level operation is in progress.
logger & err()
Definition: log.cpp:76
void run()
Run asio&#39;s event loop.
std::unique_ptr< boost::asio::streambuf > read_buf_
resolver::iterator endpoint
Base class for all the errors encountered by the engine.
Definition: exceptions.hpp:27
std::unique_ptr< boost::asio::streambuf > write_buf_
std::string message
Definition: exceptions.hpp:29
std::size_t bytes_written() const
std::size_t poll()
Handle all pending asynchronous events and return.
A config object defines a single node in a WML file, with access to child nodes.
Definition: config.hpp:59
std::size_t bytes_to_write() const
std::string::const_iterator iterator
Definition: tokenizer.hpp:24