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