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