1//
2// completion_condition.hpp
3// ~~~~~~~~~~~~~~~~~~~~~~~~
4//
5// Copyright (c) 2003-2015 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_COMPLETION_CONDITION_HPP
12#define BOOST_ASIO_COMPLETION_CONDITION_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#include <cstddef>
20
21#include <boost/asio/detail/push_options.hpp>
22
23namespace boost {
24namespace asio {
25
26namespace detail {
27
28// The default maximum number of bytes to transfer in a single operation.
29enum default_max_transfer_size_t { default_max_transfer_size = 65536 };
30
31// Adapt result of old-style completion conditions (which had a bool result
32// where true indicated that the operation was complete).
33inline std::size_t adapt_completion_condition_result(bool result)
34{
35 return result ? 0 : default_max_transfer_size;
36}
37
38// Adapt result of current completion conditions (which have a size_t result
39// where 0 means the operation is complete, and otherwise the result is the
40// maximum number of bytes to transfer on the next underlying operation).
41inline std::size_t adapt_completion_condition_result(std::size_t result)
42{
43 return result;
44}
45
46class transfer_all_t
47{
48public:
49 typedef std::size_t result_type;
50
51 template <typename Error>
52 std::size_t operator()(const Error& err, std::size_t)
53 {
54 return !!err ? 0 : default_max_transfer_size;
55 }
56};
57
58class transfer_at_least_t
59{
60public:
61 typedef std::size_t result_type;
62
63 explicit transfer_at_least_t(std::size_t minimum)
64 : minimum_(minimum)
65 {
66 }
67
68 template <typename Error>
69 std::size_t operator()(const Error& err, std::size_t bytes_transferred)
70 {
71 return (!!err || bytes_transferred >= minimum_)
72 ? 0 : default_max_transfer_size;
73 }
74
75private:
76 std::size_t minimum_;
77};
78
79class transfer_exactly_t
80{
81public:
82 typedef std::size_t result_type;
83
84 explicit transfer_exactly_t(std::size_t size)
85 : size_(size)
86 {
87 }
88
89 template <typename Error>
90 std::size_t operator()(const Error& err, std::size_t bytes_transferred)
91 {
92 return (!!err || bytes_transferred >= size_) ? 0 :
93 (size_ - bytes_transferred < default_max_transfer_size
94 ? size_ - bytes_transferred : std::size_t(default_max_transfer_size));
95 }
96
97private:
98 std::size_t size_;
99};
100
101} // namespace detail
102
103/**
104 * @defgroup completion_condition Completion Condition Function Objects
105 *
106 * Function objects used for determining when a read or write operation should
107 * complete.
108 */
109/*@{*/
110
111/// Return a completion condition function object that indicates that a read or
112/// write operation should continue until all of the data has been transferred,
113/// or until an error occurs.
114/**
115 * This function is used to create an object, of unspecified type, that meets
116 * CompletionCondition requirements.
117 *
118 * @par Example
119 * Reading until a buffer is full:
120 * @code
121 * boost::array<char, 128> buf;
122 * boost::system::error_code ec;
123 * std::size_t n = boost::asio::read(
124 * sock, boost::asio::buffer(buf),
125 * boost::asio::transfer_all(), ec);
126 * if (ec)
127 * {
128 * // An error occurred.
129 * }
130 * else
131 * {
132 * // n == 128
133 * }
134 * @endcode
135 */
136#if defined(GENERATING_DOCUMENTATION)
137unspecified transfer_all();
138#else
139inline detail::transfer_all_t transfer_all()
140{
141 return detail::transfer_all_t();
142}
143#endif
144
145/// Return a completion condition function object that indicates that a read or
146/// write operation should continue until a minimum number of bytes has been
147/// transferred, or until an error occurs.
148/**
149 * This function is used to create an object, of unspecified type, that meets
150 * CompletionCondition requirements.
151 *
152 * @par Example
153 * Reading until a buffer is full or contains at least 64 bytes:
154 * @code
155 * boost::array<char, 128> buf;
156 * boost::system::error_code ec;
157 * std::size_t n = boost::asio::read(
158 * sock, boost::asio::buffer(buf),
159 * boost::asio::transfer_at_least(64), ec);
160 * if (ec)
161 * {
162 * // An error occurred.
163 * }
164 * else
165 * {
166 * // n >= 64 && n <= 128
167 * }
168 * @endcode
169 */
170#if defined(GENERATING_DOCUMENTATION)
171unspecified transfer_at_least(std::size_t minimum);
172#else
173inline detail::transfer_at_least_t transfer_at_least(std::size_t minimum)
174{
175 return detail::transfer_at_least_t(minimum);
176}
177#endif
178
179/// Return a completion condition function object that indicates that a read or
180/// write operation should continue until an exact number of bytes has been
181/// transferred, or until an error occurs.
182/**
183 * This function is used to create an object, of unspecified type, that meets
184 * CompletionCondition requirements.
185 *
186 * @par Example
187 * Reading until a buffer is full or contains exactly 64 bytes:
188 * @code
189 * boost::array<char, 128> buf;
190 * boost::system::error_code ec;
191 * std::size_t n = boost::asio::read(
192 * sock, boost::asio::buffer(buf),
193 * boost::asio::transfer_exactly(64), ec);
194 * if (ec)
195 * {
196 * // An error occurred.
197 * }
198 * else
199 * {
200 * // n == 64
201 * }
202 * @endcode
203 */
204#if defined(GENERATING_DOCUMENTATION)
205unspecified transfer_exactly(std::size_t size);
206#else
207inline detail::transfer_exactly_t transfer_exactly(std::size_t size)
208{
209 return detail::transfer_exactly_t(size);
210}
211#endif
212
213/*@}*/
214
215} // namespace asio
216} // namespace boost
217
218#include <boost/asio/detail/pop_options.hpp>
219
220#endif // BOOST_ASIO_COMPLETION_CONDITION_HPP
221