1//
2// basic_socket_iostream.hpp
3// ~~~~~~~~~~~~~~~~~~~~~~~~~
4//
5// Copyright (c) 2003-2024 Christopher M. Kohlhoff (chris at kohlhoff dot com)
6//
7// Distributed under the Boost Software License, Version 1.0. (See accompanying
8// file LICENSE_1_0.txt or copy at http://www.boost.org/LICENSE_1_0.txt)
9//
10
11#ifndef BOOST_ASIO_BASIC_SOCKET_IOSTREAM_HPP
12#define BOOST_ASIO_BASIC_SOCKET_IOSTREAM_HPP
13
14#if defined(_MSC_VER) && (_MSC_VER >= 1200)
15# pragma once
16#endif // defined(_MSC_VER) && (_MSC_VER >= 1200)
17
18#include <boost/asio/detail/config.hpp>
19
20#if !defined(BOOST_ASIO_NO_IOSTREAM)
21
22#include <istream>
23#include <ostream>
24#include <boost/asio/basic_socket_streambuf.hpp>
25
26#include <boost/asio/detail/push_options.hpp>
27
28namespace boost {
29namespace asio {
30namespace detail {
31
32// A separate base class is used to ensure that the streambuf is initialised
33// prior to the basic_socket_iostream's basic_iostream base class.
34template <typename Protocol, typename Clock, typename WaitTraits>
35class socket_iostream_base
36{
37protected:
38 socket_iostream_base()
39 {
40 }
41
42 socket_iostream_base(socket_iostream_base&& other)
43 : streambuf_(std::move(other.streambuf_))
44 {
45 }
46
47 socket_iostream_base(basic_stream_socket<Protocol> s)
48 : streambuf_(std::move(s))
49 {
50 }
51
52 socket_iostream_base& operator=(socket_iostream_base&& other)
53 {
54 streambuf_ = std::move(other.streambuf_);
55 return *this;
56 }
57
58 basic_socket_streambuf<Protocol, Clock, WaitTraits> streambuf_;
59};
60
61} // namespace detail
62
63#if !defined(BOOST_ASIO_BASIC_SOCKET_IOSTREAM_FWD_DECL)
64#define BOOST_ASIO_BASIC_SOCKET_IOSTREAM_FWD_DECL
65
66// Forward declaration with defaulted arguments.
67template <typename Protocol,
68#if defined(BOOST_ASIO_HAS_BOOST_DATE_TIME) \
69 && defined(BOOST_ASIO_USE_BOOST_DATE_TIME_FOR_SOCKET_IOSTREAM)
70 typename Clock = boost::posix_time::ptime,
71 typename WaitTraits = time_traits<Clock>>
72#else // defined(BOOST_ASIO_HAS_BOOST_DATE_TIME)
73 // && defined(BOOST_ASIO_USE_BOOST_DATE_TIME_FOR_SOCKET_IOSTREAM)
74 typename Clock = chrono::steady_clock,
75 typename WaitTraits = wait_traits<Clock>>
76#endif // defined(BOOST_ASIO_HAS_BOOST_DATE_TIME)
77 // && defined(BOOST_ASIO_USE_BOOST_DATE_TIME_FOR_SOCKET_IOSTREAM)
78class basic_socket_iostream;
79
80#endif // !defined(BOOST_ASIO_BASIC_SOCKET_IOSTREAM_FWD_DECL)
81
82/// Iostream interface for a socket.
83#if defined(GENERATING_DOCUMENTATION)
84template <typename Protocol,
85 typename Clock = chrono::steady_clock,
86 typename WaitTraits = wait_traits<Clock>>
87#else // defined(GENERATING_DOCUMENTATION)
88template <typename Protocol, typename Clock, typename WaitTraits>
89#endif // defined(GENERATING_DOCUMENTATION)
90class basic_socket_iostream
91 : private detail::socket_iostream_base<Protocol, Clock, WaitTraits>,
92 public std::basic_iostream<char>
93{
94private:
95 // These typedefs are intended keep this class's implementation independent
96 // of whether it's using Boost.DateClock, Boost.Chrono or std::chrono.
97#if defined(BOOST_ASIO_HAS_BOOST_DATE_TIME) \
98 && defined(BOOST_ASIO_USE_BOOST_DATE_TIME_FOR_SOCKET_IOSTREAM)
99 typedef WaitTraits traits_helper;
100#else // defined(BOOST_ASIO_HAS_BOOST_DATE_TIME)
101 // && defined(BOOST_ASIO_USE_BOOST_DATE_TIME_FOR_SOCKET_IOSTREAM)
102 typedef detail::chrono_time_traits<Clock, WaitTraits> traits_helper;
103#endif // defined(BOOST_ASIO_HAS_BOOST_DATE_TIME)
104 // && defined(BOOST_ASIO_USE_BOOST_DATE_TIME_FOR_SOCKET_IOSTREAM)
105
106public:
107 /// The protocol type.
108 typedef Protocol protocol_type;
109
110 /// The endpoint type.
111 typedef typename Protocol::endpoint endpoint_type;
112
113 /// The clock type.
114 typedef Clock clock_type;
115
116#if defined(GENERATING_DOCUMENTATION)
117 /// (Deprecated: Use time_point.) The time type.
118 typedef typename WaitTraits::time_type time_type;
119
120 /// The time type.
121 typedef typename WaitTraits::time_point time_point;
122
123 /// (Deprecated: Use duration.) The duration type.
124 typedef typename WaitTraits::duration_type duration_type;
125
126 /// The duration type.
127 typedef typename WaitTraits::duration duration;
128#else
129# if !defined(BOOST_ASIO_NO_DEPRECATED)
130 typedef typename traits_helper::time_type time_type;
131 typedef typename traits_helper::duration_type duration_type;
132# endif // !defined(BOOST_ASIO_NO_DEPRECATED)
133 typedef typename traits_helper::time_type time_point;
134 typedef typename traits_helper::duration_type duration;
135#endif
136
137 /// Construct a basic_socket_iostream without establishing a connection.
138 basic_socket_iostream()
139 : std::basic_iostream<char>(
140 &this->detail::socket_iostream_base<
141 Protocol, Clock, WaitTraits>::streambuf_)
142 {
143 this->setf(std::ios_base::unitbuf);
144 }
145
146 /// Construct a basic_socket_iostream from the supplied socket.
147 explicit basic_socket_iostream(basic_stream_socket<protocol_type> s)
148 : detail::socket_iostream_base<
149 Protocol, Clock, WaitTraits>(std::move(s)),
150 std::basic_iostream<char>(
151 &this->detail::socket_iostream_base<
152 Protocol, Clock, WaitTraits>::streambuf_)
153 {
154 this->setf(std::ios_base::unitbuf);
155 }
156
157 /// Move-construct a basic_socket_iostream from another.
158 basic_socket_iostream(basic_socket_iostream&& other)
159 : detail::socket_iostream_base<
160 Protocol, Clock, WaitTraits>(std::move(other)),
161 std::basic_iostream<char>(std::move(other))
162 {
163 this->set_rdbuf(&this->detail::socket_iostream_base<
164 Protocol, Clock, WaitTraits>::streambuf_);
165 }
166
167 /// Move-assign a basic_socket_iostream from another.
168 basic_socket_iostream& operator=(basic_socket_iostream&& other)
169 {
170 std::basic_iostream<char>::operator=(std::move(other));
171 detail::socket_iostream_base<
172 Protocol, Clock, WaitTraits>::operator=(std::move(other));
173 return *this;
174 }
175
176 /// Establish a connection to an endpoint corresponding to a resolver query.
177 /**
178 * This constructor automatically establishes a connection based on the
179 * supplied resolver query parameters. The arguments are used to construct
180 * a resolver query object.
181 */
182 template <typename... T>
183 explicit basic_socket_iostream(T... x)
184 : std::basic_iostream<char>(
185 &this->detail::socket_iostream_base<
186 Protocol, Clock, WaitTraits>::streambuf_)
187 {
188 this->setf(std::ios_base::unitbuf);
189 if (rdbuf()->connect(x...) == 0)
190 this->setstate(std::ios_base::failbit);
191 }
192
193 /// Establish a connection to an endpoint corresponding to a resolver query.
194 /**
195 * This function automatically establishes a connection based on the supplied
196 * resolver query parameters. The arguments are used to construct a resolver
197 * query object.
198 */
199 template <typename... T>
200 void connect(T... x)
201 {
202 if (rdbuf()->connect(x...) == 0)
203 this->setstate(std::ios_base::failbit);
204 }
205
206 /// Close the connection.
207 void close()
208 {
209 if (rdbuf()->close() == 0)
210 this->setstate(std::ios_base::failbit);
211 }
212
213 /// Return a pointer to the underlying streambuf.
214 basic_socket_streambuf<Protocol, Clock, WaitTraits>* rdbuf() const
215 {
216 return const_cast<basic_socket_streambuf<Protocol, Clock, WaitTraits>*>(
217 &this->detail::socket_iostream_base<
218 Protocol, Clock, WaitTraits>::streambuf_);
219 }
220
221 /// Get a reference to the underlying socket.
222 basic_socket<Protocol>& socket()
223 {
224 return rdbuf()->socket();
225 }
226
227 /// Get the last error associated with the stream.
228 /**
229 * @return An \c error_code corresponding to the last error from the stream.
230 *
231 * @par Example
232 * To print the error associated with a failure to establish a connection:
233 * @code tcp::iostream s("www.boost.org", "http");
234 * if (!s)
235 * {
236 * std::cout << "Error: " << s.error().message() << std::endl;
237 * } @endcode
238 */
239 const boost::system::error_code& error() const
240 {
241 return rdbuf()->error();
242 }
243
244#if !defined(BOOST_ASIO_NO_DEPRECATED)
245 /// (Deprecated: Use expiry().) Get the stream's expiry time as an absolute
246 /// time.
247 /**
248 * @return An absolute time value representing the stream's expiry time.
249 */
250 time_point expires_at() const
251 {
252 return rdbuf()->expires_at();
253 }
254#endif // !defined(BOOST_ASIO_NO_DEPRECATED)
255
256 /// Get the stream's expiry time as an absolute time.
257 /**
258 * @return An absolute time value representing the stream's expiry time.
259 */
260 time_point expiry() const
261 {
262 return rdbuf()->expiry();
263 }
264
265 /// Set the stream's expiry time as an absolute time.
266 /**
267 * This function sets the expiry time associated with the stream. Stream
268 * operations performed after this time (where the operations cannot be
269 * completed using the internal buffers) will fail with the error
270 * boost::asio::error::operation_aborted.
271 *
272 * @param expiry_time The expiry time to be used for the stream.
273 */
274 void expires_at(const time_point& expiry_time)
275 {
276 rdbuf()->expires_at(expiry_time);
277 }
278
279 /// Set the stream's expiry time relative to now.
280 /**
281 * This function sets the expiry time associated with the stream. Stream
282 * operations performed after this time (where the operations cannot be
283 * completed using the internal buffers) will fail with the error
284 * boost::asio::error::operation_aborted.
285 *
286 * @param expiry_time The expiry time to be used for the timer.
287 */
288 void expires_after(const duration& expiry_time)
289 {
290 rdbuf()->expires_after(expiry_time);
291 }
292
293#if !defined(BOOST_ASIO_NO_DEPRECATED)
294 /// (Deprecated: Use expiry().) Get the stream's expiry time relative to now.
295 /**
296 * @return A relative time value representing the stream's expiry time.
297 */
298 duration expires_from_now() const
299 {
300 return rdbuf()->expires_from_now();
301 }
302
303 /// (Deprecated: Use expires_after().) Set the stream's expiry time relative
304 /// to now.
305 /**
306 * This function sets the expiry time associated with the stream. Stream
307 * operations performed after this time (where the operations cannot be
308 * completed using the internal buffers) will fail with the error
309 * boost::asio::error::operation_aborted.
310 *
311 * @param expiry_time The expiry time to be used for the timer.
312 */
313 void expires_from_now(const duration& expiry_time)
314 {
315 rdbuf()->expires_from_now(expiry_time);
316 }
317#endif // !defined(BOOST_ASIO_NO_DEPRECATED)
318
319private:
320 // Disallow copying and assignment.
321 basic_socket_iostream(const basic_socket_iostream&) = delete;
322 basic_socket_iostream& operator=(
323 const basic_socket_iostream&) = delete;
324};
325
326} // namespace asio
327} // namespace boost
328
329#include <boost/asio/detail/pop_options.hpp>
330
331#endif // !defined(BOOST_ASIO_NO_IOSTREAM)
332
333#endif // BOOST_ASIO_BASIC_SOCKET_IOSTREAM_HPP
334

source code of boost/libs/asio/include/boost/asio/basic_socket_iostream.hpp