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