11 #ifndef ASIO_BASIC_SOCKET_STREAMBUF_HPP 12 #define ASIO_BASIC_SOCKET_STREAMBUF_HPP 14 #if defined(_MSC_VER) && (_MSC_VER >= 1200) 16 #endif // defined(_MSC_VER) && (_MSC_VER >= 1200) 20 #if !defined(ASIO_NO_IOSTREAM) 30 #if defined(ASIO_HAS_BOOST_DATE_TIME) 36 #if !defined(ASIO_HAS_VARIADIC_TEMPLATES) 56 # define ASIO_PRIVATE_CONNECT_DEF(n) \ 57 template <ASIO_VARIADIC_TPARAMS(n)> \ 58 basic_socket_streambuf<Protocol, StreamSocketService, \ 59 Time, TimeTraits, TimerService>* connect(ASIO_VARIADIC_PARAMS(n)) \ 62 this->basic_socket<Protocol, StreamSocketService>::close(ec_); \ 63 typedef typename Protocol::resolver resolver_type; \ 64 typedef typename resolver_type::query resolver_query; \ 65 resolver_query query(ASIO_VARIADIC_ARGS(n)); \ 66 resolve_and_connect(query); \ 67 return !ec_ ? this : 0; \ 71 #endif // !defined(ASIO_HAS_VARIADIC_TEMPLATES) 89 template <
typename Protocol,
91 #if defined(ASIO_HAS_BOOST_DATE_TIME) \ 92 || defined(GENERATING_DOCUMENTATION) 93 typename Time = boost::posix_time::ptime,
94 typename TimeTraits = asio::time_traits<Time>,
97 typename Time = steady_timer::clock_type,
98 typename TimeTraits = steady_timer::traits_type,
99 typename TimerService = steady_timer::service_type>
109 #if defined(ASIO_HAS_BOOST_DATE_TIME) 119 #if defined(GENERATING_DOCUMENTATION) 120 typedef typename TimeTraits::time_type
time_type;
136 timer_state_(no_timer)
144 if (pptr() != pbase())
159 const endpoint_type& endpoint)
165 if (timer_state_ == timer_has_expired)
171 io_handler handler = {
this };
176 this->get_service().get_io_service().reset();
177 do this->get_service().get_io_service().run_one();
180 return !ec_ ?
this : 0;
183 #if defined(GENERATING_DOCUMENTATION) 193 template <
typename T1, ...,
typename TN>
196 #elif defined(ASIO_HAS_VARIADIC_TEMPLATES) 197 template <
typename... T>
199 Time, TimeTraits, TimerService>*
connect(T... x)
203 typedef typename Protocol::resolver resolver_type;
204 typedef typename resolver_type::query resolver_query;
205 resolver_query query(x...);
206 resolve_and_connect(query);
207 return !ec_ ?
this : 0;
219 Time, TimeTraits, TimerService>*
close()
225 return !ec_ ?
this : 0;
245 return timer_service_
246 ? timer_service_->expires_at(timer_implementation_)
264 timer_service_->expires_at(timer_implementation_, expiry_time, ec);
276 return traits_helper::subtract(expires_at(), traits_helper::now());
293 timer_service_->expires_from_now(timer_implementation_, expiry_time, ec);
302 if (gptr() == egptr())
304 if (timer_state_ == timer_has_expired)
310 io_handler handler = {
this };
311 this->get_service().async_receive(this->get_implementation(),
316 this->get_service().get_io_service().reset();
317 do this->get_service().get_io_service().run_one();
322 setg(&get_buffer_[0], &get_buffer_[0] + putback_max,
323 &get_buffer_[0] + putback_max + bytes_transferred_);
324 return traits_type::to_int_type(*gptr());
339 return traits_type::not_eof(c);
343 if (timer_state_ == timer_has_expired)
350 char_type ch = traits_type::to_char_type(c);
351 io_handler handler = {
this };
352 this->get_service().async_send(this->get_implementation(),
356 this->get_service().get_io_service().reset();
357 do this->get_service().get_io_service().run_one();
372 if (timer_state_ == timer_has_expired)
378 io_handler handler = {
this };
379 this->get_service().async_send(this->get_implementation(),
383 this->get_service().get_io_service().reset();
384 do this->get_service().get_io_service().run_one();
389 buffer = buffer + bytes_transferred_;
391 setp(&put_buffer_[0], &put_buffer_[0] + put_buffer_.size());
395 return traits_type::not_eof(c);
398 *pptr() = traits_type::to_char_type(c);
411 if (pptr() == pbase() && s == 0 && n == 0)
434 setg(&get_buffer_[0],
435 &get_buffer_[0] + putback_max,
436 &get_buffer_[0] + putback_max);
440 setp(&put_buffer_[0], &put_buffer_[0] + put_buffer_.size());
443 template <
typename ResolverQuery>
444 void resolve_and_connect(
const ResolverQuery& query)
446 typedef typename Protocol::resolver resolver_type;
447 typedef typename resolver_type::iterator iterator_type;
449 iterator_type i = resolver.resolve(query, ec_);
454 while (ec_ && i != end)
458 if (timer_state_ == timer_has_expired)
464 io_handler handler = {
this };
469 this->get_service().get_io_service().reset();
470 do this->get_service().get_io_service().run_one();
479 friend struct io_handler;
485 std::size_t bytes_transferred = 0)
488 this_->bytes_transferred_ = bytes_transferred;
492 struct timer_handler;
493 friend struct timer_handler;
500 time_type now = traits_helper::now();
502 time_type expiry_time = this_->timer_service_->expires_at(
503 this_->timer_implementation_);
505 if (traits_helper::less_than(now, expiry_time))
507 this_->timer_state_ = timer_is_pending;
508 this_->timer_service_->async_wait(this_->timer_implementation_, *
this);
512 this_->timer_state_ = timer_has_expired;
514 this_->basic_socket<Protocol, StreamSocketService>::close(ec);
519 void construct_timer()
521 if (timer_service_ == 0)
523 TimerService& timer_service = use_service<TimerService>(
525 timer_service.construct(timer_implementation_);
526 timer_service_ = &timer_service;
533 timer_service_->destroy(timer_implementation_);
538 if (timer_state_ != timer_is_pending)
540 timer_handler handler = {
this };
545 enum { putback_max = 8 };
551 std::size_t bytes_transferred_;
552 TimerService* timer_service_;
553 typename TimerService::implementation_type timer_implementation_;
554 enum state { no_timer, timer_is_pending, timer_has_expired } timer_state_;
561 #if !defined(ASIO_HAS_VARIADIC_TEMPLATES) 562 # undef ASIO_PRIVATE_CONNECT_DEF 563 #endif // !defined(ASIO_HAS_VARIADIC_TEMPLATES) 565 #endif // !defined(ASIO_NO_IOSTREAM) 567 #endif // ASIO_BASIC_SOCKET_STREAMBUF_HPP const asio::error_code & puberror() const
Get the last error associated with the stream buffer.
void expires_at(const time_type &expiry_time)
Set the stream buffer's expiry time as an absolute time.
void throw_error(const asio::error_code &err)
basic_streambuf streambuf
Typedef for the typical usage of basic_streambuf.
Provides core I/O functionality.
Holds a buffer that cannot be modified.
Protocol::endpoint endpoint_type
The endpoint type.
int_type overflow(int_type c)
traits_helper::duration_type duration_type
Default service implementation for a stream socket.
virtual ~basic_socket_streambuf()
Destructor flushes buffered data.
mutable_buffers_1 buffer(const mutable_buffer &b)
Create a new modifiable buffer from an existing buffer.
Iterator connect(basic_socket< Protocol, SocketService > &s, Iterator begin)
Establishes a socket connection by trying each endpoint in a sequence.
The socket is marked non-blocking and the requested operation would block.
traits_helper::time_type time_type
std::size_t buffer_size(const mutable_buffer &b)
Get the number of bytes in a modifiable buffer.
Host not found (authoritative).
void expires_from_now(const duration_type &expiry_time)
Set the stream buffer's expiry time relative to now.
clock_type::duration duration_type
basic_socket_streambuf< Protocol, StreamSocketService, Time, TimeTraits, TimerService > * connect(const endpoint_type &endpoint)
Establish a connection.
clock_type::time_point time_type
Class to represent an error code value.
#define ASIO_VARIADIC_GENERATE(m)
#define ASIO_PRIVATE_CONNECT_DEF(n)
basic_socket_streambuf()
Construct a basic_socket_streambuf without establishing a connection.
void close()
Close the socket.
time_type expires_at() const
Get the stream buffer's expiry time as an absolute time.
Provides socket functionality.
SocketService Iterator Iterator end
Iostream streambuf for a socket.
duration_type expires_from_now() const
Get the stream buffer's expiry time relative to now.
std::streambuf * setbuf(char_type *s, std::streamsize n)
virtual const asio::error_code & error() const
Get the last error associated with the stream buffer.
basic_socket_streambuf< Protocol, StreamSocketService, Time, TimeTraits, TimerService > * close()
Close the connection.