00001
00002
00003
00004
00005
00006
00007
00008
00009
00010
00011 #ifndef ASIO_READ_IPP
00012 #define ASIO_READ_IPP
00013
00014 #if defined(_MSC_VER) && (_MSC_VER >= 1200)
00015 # pragma once
00016 #endif // defined(_MSC_VER) && (_MSC_VER >= 1200)
00017
00018 #include "asio/detail/push_options.hpp"
00019
00020 #include "asio/detail/push_options.hpp"
00021 #include <algorithm>
00022 #include "asio/detail/pop_options.hpp"
00023
00024 #include "asio/buffer.hpp"
00025 #include "asio/completion_condition.hpp"
00026 #include "asio/error.hpp"
00027 #include "asio/detail/bind_handler.hpp"
00028 #include "asio/detail/consuming_buffers.hpp"
00029 #include "asio/detail/handler_alloc_helpers.hpp"
00030 #include "asio/detail/handler_invoke_helpers.hpp"
00031 #include "asio/detail/throw_error.hpp"
00032
00033 namespace asio {
00034
00035 template <typename SyncReadStream, typename MutableBufferSequence,
00036 typename CompletionCondition>
00037 std::size_t read(SyncReadStream& s, const MutableBufferSequence& buffers,
00038 CompletionCondition completion_condition, asio::error_code& ec)
00039 {
00040 asio::detail::consuming_buffers<
00041 mutable_buffer, MutableBufferSequence> tmp(buffers);
00042 std::size_t total_transferred = 0;
00043 while (tmp.begin() != tmp.end())
00044 {
00045 std::size_t bytes_transferred = s.read_some(tmp, ec);
00046 tmp.consume(bytes_transferred);
00047 total_transferred += bytes_transferred;
00048 if (completion_condition(ec, total_transferred))
00049 return total_transferred;
00050 }
00051 ec = asio::error_code();
00052 return total_transferred;
00053 }
00054
00055 template <typename SyncReadStream, typename MutableBufferSequence>
00056 inline std::size_t read(SyncReadStream& s, const MutableBufferSequence& buffers)
00057 {
00058 asio::error_code ec;
00059 std::size_t bytes_transferred = read(s, buffers, transfer_all(), ec);
00060 asio::detail::throw_error(ec);
00061 return bytes_transferred;
00062 }
00063
00064 template <typename SyncReadStream, typename MutableBufferSequence,
00065 typename CompletionCondition>
00066 inline std::size_t read(SyncReadStream& s, const MutableBufferSequence& buffers,
00067 CompletionCondition completion_condition)
00068 {
00069 asio::error_code ec;
00070 std::size_t bytes_transferred = read(s, buffers, completion_condition, ec);
00071 asio::detail::throw_error(ec);
00072 return bytes_transferred;
00073 }
00074
00075 template <typename SyncReadStream, typename Allocator,
00076 typename CompletionCondition>
00077 std::size_t read(SyncReadStream& s,
00078 asio::basic_streambuf<Allocator>& b,
00079 CompletionCondition completion_condition, asio::error_code& ec)
00080 {
00081 std::size_t total_transferred = 0;
00082 for (;;)
00083 {
00084 std::size_t bytes_available =
00085 std::min<std::size_t>(512, b.max_size() - b.size());
00086 std::size_t bytes_transferred = s.read_some(b.prepare(bytes_available), ec);
00087 b.commit(bytes_transferred);
00088 total_transferred += bytes_transferred;
00089 if (b.size() == b.max_size()
00090 || completion_condition(ec, total_transferred))
00091 return total_transferred;
00092 }
00093 }
00094
00095 template <typename SyncReadStream, typename Allocator>
00096 inline std::size_t read(SyncReadStream& s,
00097 asio::basic_streambuf<Allocator>& b)
00098 {
00099 asio::error_code ec;
00100 std::size_t bytes_transferred = read(s, b, transfer_all(), ec);
00101 asio::detail::throw_error(ec);
00102 return bytes_transferred;
00103 }
00104
00105 template <typename SyncReadStream, typename Allocator,
00106 typename CompletionCondition>
00107 inline std::size_t read(SyncReadStream& s,
00108 asio::basic_streambuf<Allocator>& b,
00109 CompletionCondition completion_condition)
00110 {
00111 asio::error_code ec;
00112 std::size_t bytes_transferred = read(s, b, completion_condition, ec);
00113 asio::detail::throw_error(ec);
00114 return bytes_transferred;
00115 }
00116
00117 namespace detail
00118 {
00119 template <typename AsyncReadStream, typename MutableBufferSequence,
00120 typename CompletionCondition, typename ReadHandler>
00121 class read_handler
00122 {
00123 public:
00124 typedef asio::detail::consuming_buffers<
00125 mutable_buffer, MutableBufferSequence> buffers_type;
00126
00127 read_handler(AsyncReadStream& stream, const buffers_type& buffers,
00128 CompletionCondition completion_condition, ReadHandler handler)
00129 : stream_(stream),
00130 buffers_(buffers),
00131 total_transferred_(0),
00132 completion_condition_(completion_condition),
00133 handler_(handler)
00134 {
00135 }
00136
00137 void operator()(const asio::error_code& ec,
00138 std::size_t bytes_transferred)
00139 {
00140 total_transferred_ += bytes_transferred;
00141 buffers_.consume(bytes_transferred);
00142 if (completion_condition_(ec, total_transferred_)
00143 || buffers_.begin() == buffers_.end())
00144 {
00145 handler_(ec, total_transferred_);
00146 }
00147 else
00148 {
00149 stream_.async_read_some(buffers_, *this);
00150 }
00151 }
00152
00153
00154 AsyncReadStream& stream_;
00155 buffers_type buffers_;
00156 std::size_t total_transferred_;
00157 CompletionCondition completion_condition_;
00158 ReadHandler handler_;
00159 };
00160
00161 template <typename AsyncReadStream, typename MutableBufferSequence,
00162 typename CompletionCondition, typename ReadHandler>
00163 inline void* asio_handler_allocate(std::size_t size,
00164 read_handler<AsyncReadStream, MutableBufferSequence,
00165 CompletionCondition, ReadHandler>* this_handler)
00166 {
00167 return asio_handler_alloc_helpers::allocate(
00168 size, &this_handler->handler_);
00169 }
00170
00171 template <typename AsyncReadStream, typename MutableBufferSequence,
00172 typename CompletionCondition, typename ReadHandler>
00173 inline void asio_handler_deallocate(void* pointer, std::size_t size,
00174 read_handler<AsyncReadStream, MutableBufferSequence,
00175 CompletionCondition, ReadHandler>* this_handler)
00176 {
00177 asio_handler_alloc_helpers::deallocate(
00178 pointer, size, &this_handler->handler_);
00179 }
00180
00181 template <typename Function, typename AsyncReadStream,
00182 typename MutableBufferSequence, typename CompletionCondition,
00183 typename ReadHandler>
00184 inline void asio_handler_invoke(const Function& function,
00185 read_handler<AsyncReadStream, MutableBufferSequence,
00186 CompletionCondition, ReadHandler>* this_handler)
00187 {
00188 asio_handler_invoke_helpers::invoke(
00189 function, &this_handler->handler_);
00190 }
00191 }
00192
00193 template <typename AsyncReadStream, typename MutableBufferSequence,
00194 typename CompletionCondition, typename ReadHandler>
00195 inline void async_read(AsyncReadStream& s, const MutableBufferSequence& buffers,
00196 CompletionCondition completion_condition, ReadHandler handler)
00197 {
00198 asio::detail::consuming_buffers<
00199 mutable_buffer, MutableBufferSequence> tmp(buffers);
00200 s.async_read_some(tmp,
00201 detail::read_handler<AsyncReadStream, MutableBufferSequence,
00202 CompletionCondition, ReadHandler>(
00203 s, tmp, completion_condition, handler));
00204 }
00205
00206 template <typename AsyncReadStream, typename MutableBufferSequence,
00207 typename ReadHandler>
00208 inline void async_read(AsyncReadStream& s, const MutableBufferSequence& buffers,
00209 ReadHandler handler)
00210 {
00211 async_read(s, buffers, transfer_all(), handler);
00212 }
00213
00214 namespace detail
00215 {
00216 template <typename AsyncReadStream, typename Allocator,
00217 typename CompletionCondition, typename ReadHandler>
00218 class read_streambuf_handler
00219 {
00220 public:
00221 read_streambuf_handler(AsyncReadStream& stream,
00222 basic_streambuf<Allocator>& streambuf,
00223 CompletionCondition completion_condition, ReadHandler handler)
00224 : stream_(stream),
00225 streambuf_(streambuf),
00226 total_transferred_(0),
00227 completion_condition_(completion_condition),
00228 handler_(handler)
00229 {
00230 }
00231
00232 void operator()(const asio::error_code& ec,
00233 std::size_t bytes_transferred)
00234 {
00235 total_transferred_ += bytes_transferred;
00236 streambuf_.commit(bytes_transferred);
00237 if (streambuf_.size() == streambuf_.max_size()
00238 || completion_condition_(ec, total_transferred_))
00239 {
00240 handler_(ec, total_transferred_);
00241 }
00242 else
00243 {
00244 std::size_t bytes_available =
00245 std::min<std::size_t>(512, streambuf_.max_size() - streambuf_.size());
00246 stream_.async_read_some(streambuf_.prepare(bytes_available), *this);
00247 }
00248 }
00249
00250
00251 AsyncReadStream& stream_;
00252 asio::basic_streambuf<Allocator>& streambuf_;
00253 std::size_t total_transferred_;
00254 CompletionCondition completion_condition_;
00255 ReadHandler handler_;
00256 };
00257
00258 template <typename AsyncReadStream, typename Allocator,
00259 typename CompletionCondition, typename ReadHandler>
00260 inline void* asio_handler_allocate(std::size_t size,
00261 read_streambuf_handler<AsyncReadStream, Allocator,
00262 CompletionCondition, ReadHandler>* this_handler)
00263 {
00264 return asio_handler_alloc_helpers::allocate(
00265 size, &this_handler->handler_);
00266 }
00267
00268 template <typename AsyncReadStream, typename Allocator,
00269 typename CompletionCondition, typename ReadHandler>
00270 inline void asio_handler_deallocate(void* pointer, std::size_t size,
00271 read_streambuf_handler<AsyncReadStream, Allocator,
00272 CompletionCondition, ReadHandler>* this_handler)
00273 {
00274 asio_handler_alloc_helpers::deallocate(
00275 pointer, size, &this_handler->handler_);
00276 }
00277
00278 template <typename Function, typename AsyncReadStream,
00279 typename Allocator, typename CompletionCondition, typename ReadHandler>
00280 inline void asio_handler_invoke(const Function& function,
00281 read_streambuf_handler<AsyncReadStream, Allocator,
00282 CompletionCondition, ReadHandler>* this_handler)
00283 {
00284 asio_handler_invoke_helpers::invoke(
00285 function, &this_handler->handler_);
00286 }
00287 }
00288
00289 template <typename AsyncReadStream, typename Allocator,
00290 typename CompletionCondition, typename ReadHandler>
00291 inline void async_read(AsyncReadStream& s,
00292 asio::basic_streambuf<Allocator>& b,
00293 CompletionCondition completion_condition, ReadHandler handler)
00294 {
00295 std::size_t bytes_available =
00296 std::min<std::size_t>(512, b.max_size() - b.size());
00297 s.async_read_some(b.prepare(bytes_available),
00298 detail::read_streambuf_handler<AsyncReadStream, Allocator,
00299 CompletionCondition, ReadHandler>(
00300 s, b, completion_condition, handler));
00301 }
00302
00303 template <typename AsyncReadStream, typename Allocator, typename ReadHandler>
00304 inline void async_read(AsyncReadStream& s,
00305 asio::basic_streambuf<Allocator>& b, ReadHandler handler)
00306 {
00307 async_read(s, b, transfer_all(), handler);
00308 }
00309
00310 }
00311
00312 #include "asio/detail/pop_options.hpp"
00313
00314 #endif // ASIO_READ_IPP