2 // basic_socket_iostream.hpp
3 // ~~~~~~~~~~~~~~~~~~~~~~~~~
5 // Copyright (c) 2003-2011 Christopher M. Kohlhoff (chris at kohlhoff dot com)
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)
11 #ifndef BOOST_ASIO_BASIC_SOCKET_IOSTREAM_HPP
12 #define BOOST_ASIO_BASIC_SOCKET_IOSTREAM_HPP
14 #if defined(_MSC_VER) && (_MSC_VER >= 1200)
16 #endif // defined(_MSC_VER) && (_MSC_VER >= 1200)
18 #include <boost/asio/detail/config.hpp>
20 #if !defined(BOOST_NO_IOSTREAM)
22 #include <boost/utility/base_from_member.hpp>
23 #include <boost/asio/basic_socket_streambuf.hpp>
24 #include <boost/asio/stream_socket_service.hpp>
26 #if !defined(BOOST_ASIO_HAS_VARIADIC_TEMPLATES)
28 # include <boost/preprocessor/arithmetic/inc.hpp>
29 # include <boost/preprocessor/repetition/enum_binary_params.hpp>
30 # include <boost/preprocessor/repetition/enum_params.hpp>
31 # include <boost/preprocessor/repetition/repeat_from_to.hpp>
33 # if !defined(BOOST_ASIO_SOCKET_IOSTREAM_MAX_ARITY)
34 # define BOOST_ASIO_SOCKET_IOSTREAM_MAX_ARITY 5
35 # endif // !defined(BOOST_ASIO_SOCKET_IOSTREAM_MAX_ARITY)
37 // A macro that should expand to:
38 // template <typename T1, ..., typename Tn>
39 // explicit basic_socket_iostream(T1 x1, ..., Tn xn)
40 // : basic_iostream<char>(&this->boost::base_from_member<
41 // basic_socket_streambuf<Protocol, StreamSocketService,
42 // Time, TimeTraits, TimerService> >::member)
44 // if (rdbuf()->connect(x1, ..., xn) == 0)
45 // this->setstate(std::ios_base::failbit);
47 // This macro should only persist within this file.
49 # define BOOST_ASIO_PRIVATE_CTR_DEF(z, n, data) \
50 template <BOOST_PP_ENUM_PARAMS(n, typename T)> \
51 explicit basic_socket_iostream(BOOST_PP_ENUM_BINARY_PARAMS(n, T, x)) \
52 : std::basic_iostream<char>(&this->boost::base_from_member< \
53 basic_socket_streambuf<Protocol, StreamSocketService, \
54 Time, TimeTraits, TimerService> >::member) \
57 if (rdbuf()->connect(BOOST_PP_ENUM_PARAMS(n, x)) == 0) \
58 this->setstate(std::ios_base::failbit); \
62 // A macro that should expand to:
63 // template <typename T1, ..., typename Tn>
64 // void connect(T1 x1, ..., Tn xn)
66 // if (rdbuf()->connect(x1, ..., xn) == 0)
67 // this->setstate(std::ios_base::failbit);
69 // This macro should only persist within this file.
71 # define BOOST_ASIO_PRIVATE_CONNECT_DEF(z, n, data) \
72 template <BOOST_PP_ENUM_PARAMS(n, typename T)> \
73 void connect(BOOST_PP_ENUM_BINARY_PARAMS(n, T, x)) \
75 if (rdbuf()->connect(BOOST_PP_ENUM_PARAMS(n, x)) == 0) \
76 this->setstate(std::ios_base::failbit); \
80 #endif // !defined(BOOST_ASIO_HAS_VARIADIC_TEMPLATES)
82 #include <boost/asio/detail/push_options.hpp>
87 /// Iostream interface for a socket.
88 template <typename Protocol,
89 typename StreamSocketService = stream_socket_service<Protocol>,
90 typename Time = boost::posix_time::ptime,
91 typename TimeTraits = boost::asio::time_traits<Time>,
92 typename TimerService = deadline_timer_service<Time, TimeTraits> >
93 class basic_socket_iostream
94 : public boost::base_from_member<
95 basic_socket_streambuf<Protocol, StreamSocketService,
96 Time, TimeTraits, TimerService> >,
97 public std::basic_iostream<char>
100 /// The endpoint type.
101 typedef typename Protocol::endpoint endpoint_type;
104 typedef typename TimeTraits::time_type time_type;
106 /// The duration type.
107 typedef typename TimeTraits::duration_type duration_type;
109 /// Construct a basic_socket_iostream without establishing a connection.
110 basic_socket_iostream()
111 : std::basic_iostream<char>(&this->boost::base_from_member<
112 basic_socket_streambuf<Protocol, StreamSocketService,
113 Time, TimeTraits, TimerService> >::member)
118 #if defined(GENERATING_DOCUMENTATION)
119 /// Establish a connection to an endpoint corresponding to a resolver query.
121 * This constructor automatically establishes a connection based on the
122 * supplied resolver query parameters. The arguments are used to construct
123 * a resolver query object.
125 template <typename T1, ..., typename TN>
126 explicit basic_socket_iostream(T1 t1, ..., TN tn);
127 #elif defined(BOOST_ASIO_HAS_VARIADIC_TEMPLATES)
128 template <typename... T>
129 explicit basic_socket_iostream(T... x)
130 : std::basic_iostream<char>(&this->boost::base_from_member<
131 basic_socket_streambuf<Protocol, StreamSocketService,
132 Time, TimeTraits, TimerService> >::member)
135 if (rdbuf()->connect(x...) == 0)
136 this->setstate(std::ios_base::failbit);
139 BOOST_PP_REPEAT_FROM_TO(
140 1, BOOST_PP_INC(BOOST_ASIO_SOCKET_IOSTREAM_MAX_ARITY),
141 BOOST_ASIO_PRIVATE_CTR_DEF, _ )
144 #if defined(GENERATING_DOCUMENTATION)
145 /// Establish a connection to an endpoint corresponding to a resolver query.
147 * This function automatically establishes a connection based on the supplied
148 * resolver query parameters. The arguments are used to construct a resolver
151 template <typename T1, ..., typename TN>
152 void connect(T1 t1, ..., TN tn);
153 #elif defined(BOOST_ASIO_HAS_VARIADIC_TEMPLATES)
154 template <typename... T>
157 if (rdbuf()->connect(x...) == 0)
158 this->setstate(std::ios_base::failbit);
161 BOOST_PP_REPEAT_FROM_TO(
162 1, BOOST_PP_INC(BOOST_ASIO_SOCKET_IOSTREAM_MAX_ARITY),
163 BOOST_ASIO_PRIVATE_CONNECT_DEF, _ )
166 /// Close the connection.
169 if (rdbuf()->close() == 0)
170 this->setstate(std::ios_base::failbit);
173 /// Return a pointer to the underlying streambuf.
174 basic_socket_streambuf<Protocol, StreamSocketService,
175 Time, TimeTraits, TimerService>* rdbuf() const
177 return const_cast<basic_socket_streambuf<Protocol, StreamSocketService,
178 Time, TimeTraits, TimerService>*>(
179 &this->boost::base_from_member<
180 basic_socket_streambuf<Protocol, StreamSocketService,
181 Time, TimeTraits, TimerService> >::member);
184 /// Get the last error associated with the stream.
186 * @return An \c error_code corresponding to the last error from the stream.
189 * To print the error associated with a failure to establish a connection:
190 * @code tcp::iostream s("www.boost.org", "http");
193 * std::cout << "Error: " << s.error().message() << std::endl;
196 const boost::system::error_code& error() const
198 return rdbuf()->puberror();
201 /// Get the stream's expiry time as an absolute time.
203 * @return An absolute time value representing the stream's expiry time.
205 time_type expires_at() const
207 return rdbuf()->expires_at();
210 /// Set the stream's expiry time as an absolute time.
212 * This function sets the expiry time associated with the stream. Stream
213 * operations performed after this time (where the operations cannot be
214 * completed using the internal buffers) will fail with the error
215 * boost::asio::error::operation_aborted.
217 * @param expiry_time The expiry time to be used for the stream.
219 void expires_at(const time_type& expiry_time)
221 rdbuf()->expires_at(expiry_time);
224 /// Get the timer's expiry time relative to now.
226 * @return A relative time value representing the stream's expiry time.
228 duration_type expires_from_now() const
230 return rdbuf()->expires_from_now();
233 /// Set the stream's expiry time relative to now.
235 * This function sets the expiry time associated with the stream. Stream
236 * operations performed after this time (where the operations cannot be
237 * completed using the internal buffers) will fail with the error
238 * boost::asio::error::operation_aborted.
240 * @param expiry_time The expiry time to be used for the timer.
242 void expires_from_now(const duration_type& expiry_time)
244 rdbuf()->expires_from_now(expiry_time);
251 #include <boost/asio/detail/pop_options.hpp>
253 #if !defined(BOOST_ASIO_HAS_VARIADIC_TEMPLATES)
254 # undef BOOST_ASIO_PRIVATE_CTR_DEF
255 # undef BOOST_ASIO_PRIVATE_CONNECT_DEF
256 #endif // !defined(BOOST_ASIO_HAS_VARIADIC_TEMPLATES)
258 #endif // defined(BOOST_NO_IOSTREAM)
260 #endif // BOOST_ASIO_BASIC_SOCKET_IOSTREAM_HPP