This source file includes following definitions.
- set_options
- connect
- write
- write
- read
- read
- read
- to_string
1
2
3
4
5
6
7
8
9
10
11
12
13
14
15
16
17
18
19
20
21 namespace jmmcg { namespace socket { namespace asio {
22
23 inline void
24 socket_wrapper::set_options(std::size_t , std::size_t max_message_size) {
25 socket_.set_option(boost::asio::socket_base::send_buffer_size(max_message_size));
26
27 socket_.set_option(boost::asio::socket_base::receive_buffer_size(max_message_size));
28 socket_.set_option(boost::asio::ip::tcp::no_delay(true));
29 }
30
31 inline
32 socket_wrapper::socket_wrapper(boost::asio::io_service &io_service)
33 : socket_(io_service) {
34 }
35
36 inline void
37 socket_wrapper::connect(boost::asio::ip::tcp::endpoint const &endpoint) {
38 socket_.connect(endpoint);
39 }
40
41 template<class MsgT> inline void
42 socket_wrapper::write(MsgT const &message) {
43 if (MsgT::has_static_size) {
44 using raw_buff_t=char const [sizeof(MsgT)];
45 assert(message.length()==sizeof(MsgT));
46 [[maybe_unused]] const std::size_t bytes_written=boost::asio::write(socket_, boost::asio::buffer(reinterpret_cast<raw_buff_t &>(message)), io_error);
47 if (UNLIKELY(io_error==boost::asio::error::eof)) {
48 return;
49 } else if (UNLIKELY(io_error)) {
50 return;
51 }
52 assert(bytes_written>=sizeof(MsgT));
53 } else {
54 [[maybe_unused]] const std::size_t bytes_written=boost::asio::write(socket_, boost::asio::buffer(reinterpret_cast<std::uint8_t const *>(&message), message.length()), io_error);
55 if (UNLIKELY(io_error==boost::asio::error::eof)) {
56 return;
57 } else if (UNLIKELY(io_error)) {
58 return;
59 }
60 assert(bytes_written<=sizeof(MsgT));
61 assert(bytes_written>=message.length());
62 }
63 }
64
65 template<class V, std::size_t N> inline void
66 socket_wrapper::write(std::array<V, N> const &message) {
67 [[maybe_unused]] const std::size_t bytes_written=boost::asio::write(socket_, boost::asio::buffer(message), io_error);
68 if (UNLIKELY(io_error==boost::asio::error::eof)) {
69 return;
70 } else if (UNLIKELY(io_error)) {
71 return;
72 }
73 assert(bytes_written>=sizeof(V)*N);
74 }
75
76 template<class MsgT> inline void
77 socket_wrapper::read(MsgT &dest) {
78 if (MsgT::has_static_size) {
79 using raw_buff_t=char [sizeof(MsgT)];
80 assert(dest.length()==sizeof(MsgT));
81 [[maybe_unused]] const std::size_t bytes_read=boost::asio::read(socket_, boost::asio::buffer(reinterpret_cast<raw_buff_t &>(dest)), io_error);
82 if (UNLIKELY(io_error==boost::asio::error::eof)) {
83 return;
84 } else if (UNLIKELY(io_error)) {
85 throw boost::system::system_error(io_error);
86 }
87 assert(bytes_read>0);
88 assert(bytes_read==sizeof(MsgT));
89 } else {
90 [[maybe_unused]] const std::size_t bytes_read=boost::asio::read(socket_, boost::asio::buffer(reinterpret_cast<std::uint8_t *>(&dest), MsgT::header_t_size), io_error);
91 if (UNLIKELY(io_error==boost::asio::error::eof)) {
92 return;
93 } else if (UNLIKELY(io_error)) {
94 throw boost::system::system_error(io_error);
95 }
96 assert(bytes_read>0);
97 typename MsgT::Header_t const *hdr=reinterpret_cast<typename MsgT::Header_t const *>(&dest);
98 const std::size_t length=hdr->length();
99 const std::size_t header_t_sz=MsgT::header_t_size;
100 assert(length>=header_t_sz);
101 const std::size_t body_size=length-header_t_sz;
102 [[maybe_unused]] const std::size_t bytes_read1=boost::asio::read(socket_, boost::asio::buffer(reinterpret_cast<std::uint8_t *>(&dest)+MsgT::header_t_size, body_size), io_error);
103 if (UNLIKELY(io_error==boost::asio::error::eof)) {
104 return;
105 } else if (UNLIKELY(io_error)) {
106 throw boost::system::system_error(io_error);
107 }
108 assert(bytes_read1<=dest.length());
109 }
110 }
111
112 template<class V, std::size_t SrcSz> inline void
113 socket_wrapper::read(V (& dest)[SrcSz]) {
114 [[maybe_unused]] const std::size_t bytes_read=boost::asio::read(socket_, boost::asio::buffer(dest));
115 assert(bytes_read==sizeof(V)*SrcSz);
116 }
117
118 template<class MsgDetails, class V, std::size_t N> inline bool
119 socket_wrapper::read(std::array<V, N> &buff) noexcept(false) {
120 using msg_details_t=MsgDetails;
121
122 assert(socket_.is_open());
123 BOOST_MPL_ASSERT_RELATION(msg_details_t::max_msg_size, >=, msg_details_t::header_t_size);
124 [[maybe_unused]] std::size_t len_read=boost::asio::read(socket_, boost::asio::buffer(buff, msg_details_t::header_t_size), io_error);
125 if (UNLIKELY(io_error==boost::asio::error::eof)) {
126
127 return true;
128 } else if (UNLIKELY(io_error)) {
129 throw boost::system::system_error(io_error);
130 }
131 assert(len_read>=msg_details_t::header_t_size);
132 assert(len_read<=msg_details_t::max_msg_size);
133 typename msg_details_t::Header_t const *hdr=reinterpret_cast<typename msg_details_t::Header_t const *>(buff.data());
134 const std::size_t length=hdr->length();
135 assert(length>=msg_details_t::header_t_size);
136 const std::size_t body_size=length-msg_details_t::header_t_size;
137 if (body_size) {
138 len_read=boost::asio::read(socket_, boost::asio::buffer(&*std::next(buff.begin(), msg_details_t::header_t_size), body_size), io_error);
139 if (io_error==boost::asio::error::eof) {
140 return true;
141 } else if (io_error) {
142 throw boost::system::system_error(io_error);
143 }
144 assert(len_read>=body_size);
145 assert(len_read<=msg_details_t::max_msg_size);
146 }
147 return false;
148 }
149
150 inline std::string
151 socket_wrapper::to_string() const noexcept(false) {
152 std::ostringstream ss;
153 ss
154 <<"socket_="<<const_cast<boost::asio::ip::tcp::socket &>(socket_).native_handle();
155 return ss.str();
156 }
157
158 inline std::ostream &
159 operator<<(std::ostream &os, socket_wrapper const &ec) noexcept(false) {
160 os<<ec.to_string();
161 return os;
162 }
163
164 } } }