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