1 | // |
2 | // windows/basic_random_access_handle.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_WINDOWS_BASIC_RANDOM_ACCESS_HANDLE_HPP |
12 | #define BOOST_ASIO_WINDOWS_BASIC_RANDOM_ACCESS_HANDLE_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 | |
20 | #if defined(BOOST_ASIO_HAS_WINDOWS_RANDOM_ACCESS_HANDLE) \ |
21 | || defined(GENERATING_DOCUMENTATION) |
22 | |
23 | #include <cstddef> |
24 | #include <boost/asio/detail/handler_type_requirements.hpp> |
25 | #include <boost/asio/detail/throw_error.hpp> |
26 | #include <boost/asio/error.hpp> |
27 | #include <boost/asio/windows/basic_handle.hpp> |
28 | #include <boost/asio/windows/random_access_handle_service.hpp> |
29 | |
30 | #include <boost/asio/detail/push_options.hpp> |
31 | |
32 | namespace boost { |
33 | namespace asio { |
34 | namespace windows { |
35 | |
36 | /// Provides random-access handle functionality. |
37 | /** |
38 | * The windows::basic_random_access_handle class template provides asynchronous |
39 | * and blocking random-access handle functionality. |
40 | * |
41 | * @par Thread Safety |
42 | * @e Distinct @e objects: Safe.@n |
43 | * @e Shared @e objects: Unsafe. |
44 | */ |
45 | template <typename RandomAccessHandleService = random_access_handle_service> |
46 | class basic_random_access_handle |
47 | : public basic_handle<RandomAccessHandleService> |
48 | { |
49 | public: |
50 | /// (Deprecated: Use native_handle_type.) The native representation of a |
51 | /// handle. |
52 | typedef typename RandomAccessHandleService::native_handle_type native_type; |
53 | |
54 | /// The native representation of a handle. |
55 | typedef typename RandomAccessHandleService::native_handle_type |
56 | native_handle_type; |
57 | |
58 | /// Construct a basic_random_access_handle without opening it. |
59 | /** |
60 | * This constructor creates a random-access handle without opening it. The |
61 | * handle needs to be opened before data can be written to or read from it. |
62 | * |
63 | * @param io_service The io_service object that the random-access handle will |
64 | * use to dispatch handlers for any asynchronous operations performed on the |
65 | * handle. |
66 | */ |
67 | explicit basic_random_access_handle(boost::asio::io_service& io_service) |
68 | : basic_handle<RandomAccessHandleService>(io_service) |
69 | { |
70 | } |
71 | |
72 | /// Construct a basic_random_access_handle on an existing native handle. |
73 | /** |
74 | * This constructor creates a random-access handle object to hold an existing |
75 | * native handle. |
76 | * |
77 | * @param io_service The io_service object that the random-access handle will |
78 | * use to dispatch handlers for any asynchronous operations performed on the |
79 | * handle. |
80 | * |
81 | * @param handle The new underlying handle implementation. |
82 | * |
83 | * @throws boost::system::system_error Thrown on failure. |
84 | */ |
85 | basic_random_access_handle(boost::asio::io_service& io_service, |
86 | const native_handle_type& handle) |
87 | : basic_handle<RandomAccessHandleService>(io_service, handle) |
88 | { |
89 | } |
90 | |
91 | #if defined(BOOST_ASIO_HAS_MOVE) || defined(GENERATING_DOCUMENTATION) |
92 | /// Move-construct a basic_random_access_handle from another. |
93 | /** |
94 | * This constructor moves a random-access handle from one object to another. |
95 | * |
96 | * @param other The other basic_random_access_handle object from which the |
97 | * move will occur. |
98 | * |
99 | * @note Following the move, the moved-from object is in the same state as if |
100 | * constructed using the @c basic_random_access_handle(io_service&) |
101 | * constructor. |
102 | */ |
103 | basic_random_access_handle(basic_random_access_handle&& other) |
104 | : basic_handle<RandomAccessHandleService>( |
105 | BOOST_ASIO_MOVE_CAST(basic_random_access_handle)(other)) |
106 | { |
107 | } |
108 | |
109 | /// Move-assign a basic_random_access_handle from another. |
110 | /** |
111 | * This assignment operator moves a random-access handle from one object to |
112 | * another. |
113 | * |
114 | * @param other The other basic_random_access_handle object from which the |
115 | * move will occur. |
116 | * |
117 | * @note Following the move, the moved-from object is in the same state as if |
118 | * constructed using the @c basic_random_access_handle(io_service&) |
119 | * constructor. |
120 | */ |
121 | basic_random_access_handle& operator=(basic_random_access_handle&& other) |
122 | { |
123 | basic_handle<RandomAccessHandleService>::operator=( |
124 | BOOST_ASIO_MOVE_CAST(basic_random_access_handle)(other)); |
125 | return *this; |
126 | } |
127 | #endif // defined(BOOST_ASIO_HAS_MOVE) || defined(GENERATING_DOCUMENTATION) |
128 | |
129 | /// Write some data to the handle at the specified offset. |
130 | /** |
131 | * This function is used to write data to the random-access handle. The |
132 | * function call will block until one or more bytes of the data has been |
133 | * written successfully, or until an error occurs. |
134 | * |
135 | * @param offset The offset at which the data will be written. |
136 | * |
137 | * @param buffers One or more data buffers to be written to the handle. |
138 | * |
139 | * @returns The number of bytes written. |
140 | * |
141 | * @throws boost::system::system_error Thrown on failure. An error code of |
142 | * boost::asio::error::eof indicates that the connection was closed by the |
143 | * peer. |
144 | * |
145 | * @note The write_some_at operation may not write all of the data. Consider |
146 | * using the @ref write_at function if you need to ensure that all data is |
147 | * written before the blocking operation completes. |
148 | * |
149 | * @par Example |
150 | * To write a single data buffer use the @ref buffer function as follows: |
151 | * @code |
152 | * handle.write_some_at(42, boost::asio::buffer(data, size)); |
153 | * @endcode |
154 | * See the @ref buffer documentation for information on writing multiple |
155 | * buffers in one go, and how to use it with arrays, boost::array or |
156 | * std::vector. |
157 | */ |
158 | template <typename ConstBufferSequence> |
159 | std::size_t write_some_at(uint64_t offset, |
160 | const ConstBufferSequence& buffers) |
161 | { |
162 | boost::system::error_code ec; |
163 | std::size_t s = this->get_service().write_some_at( |
164 | this->get_implementation(), offset, buffers, ec); |
165 | boost::asio::detail::throw_error(ec, "write_some_at" ); |
166 | return s; |
167 | } |
168 | |
169 | /// Write some data to the handle at the specified offset. |
170 | /** |
171 | * This function is used to write data to the random-access handle. The |
172 | * function call will block until one or more bytes of the data has been |
173 | * written successfully, or until an error occurs. |
174 | * |
175 | * @param offset The offset at which the data will be written. |
176 | * |
177 | * @param buffers One or more data buffers to be written to the handle. |
178 | * |
179 | * @param ec Set to indicate what error occurred, if any. |
180 | * |
181 | * @returns The number of bytes written. Returns 0 if an error occurred. |
182 | * |
183 | * @note The write_some operation may not transmit all of the data to the |
184 | * peer. Consider using the @ref write_at function if you need to ensure that |
185 | * all data is written before the blocking operation completes. |
186 | */ |
187 | template <typename ConstBufferSequence> |
188 | std::size_t write_some_at(uint64_t offset, |
189 | const ConstBufferSequence& buffers, boost::system::error_code& ec) |
190 | { |
191 | return this->get_service().write_some_at( |
192 | this->get_implementation(), offset, buffers, ec); |
193 | } |
194 | |
195 | /// Start an asynchronous write at the specified offset. |
196 | /** |
197 | * This function is used to asynchronously write data to the random-access |
198 | * handle. The function call always returns immediately. |
199 | * |
200 | * @param offset The offset at which the data will be written. |
201 | * |
202 | * @param buffers One or more data buffers to be written to the handle. |
203 | * Although the buffers object may be copied as necessary, ownership of the |
204 | * underlying memory blocks is retained by the caller, which must guarantee |
205 | * that they remain valid until the handler is called. |
206 | * |
207 | * @param handler The handler to be called when the write operation completes. |
208 | * Copies will be made of the handler as required. The function signature of |
209 | * the handler must be: |
210 | * @code void handler( |
211 | * const boost::system::error_code& error, // Result of operation. |
212 | * std::size_t bytes_transferred // Number of bytes written. |
213 | * ); @endcode |
214 | * Regardless of whether the asynchronous operation completes immediately or |
215 | * not, the handler will not be invoked from within this function. Invocation |
216 | * of the handler will be performed in a manner equivalent to using |
217 | * boost::asio::io_service::post(). |
218 | * |
219 | * @note The write operation may not transmit all of the data to the peer. |
220 | * Consider using the @ref async_write_at function if you need to ensure that |
221 | * all data is written before the asynchronous operation completes. |
222 | * |
223 | * @par Example |
224 | * To write a single data buffer use the @ref buffer function as follows: |
225 | * @code |
226 | * handle.async_write_some_at(42, boost::asio::buffer(data, size), handler); |
227 | * @endcode |
228 | * See the @ref buffer documentation for information on writing multiple |
229 | * buffers in one go, and how to use it with arrays, boost::array or |
230 | * std::vector. |
231 | */ |
232 | template <typename ConstBufferSequence, typename WriteHandler> |
233 | BOOST_ASIO_INITFN_RESULT_TYPE(WriteHandler, |
234 | void (boost::system::error_code, std::size_t)) |
235 | async_write_some_at(uint64_t offset, |
236 | const ConstBufferSequence& buffers, |
237 | BOOST_ASIO_MOVE_ARG(WriteHandler) handler) |
238 | { |
239 | // If you get an error on the following line it means that your handler does |
240 | // not meet the documented type requirements for a WriteHandler. |
241 | BOOST_ASIO_WRITE_HANDLER_CHECK(WriteHandler, handler) type_check; |
242 | |
243 | return this->get_service().async_write_some_at(this->get_implementation(), |
244 | offset, buffers, BOOST_ASIO_MOVE_CAST(WriteHandler)(handler)); |
245 | } |
246 | |
247 | /// Read some data from the handle at the specified offset. |
248 | /** |
249 | * This function is used to read data from the random-access handle. The |
250 | * function call will block until one or more bytes of data has been read |
251 | * successfully, or until an error occurs. |
252 | * |
253 | * @param offset The offset at which the data will be read. |
254 | * |
255 | * @param buffers One or more buffers into which the data will be read. |
256 | * |
257 | * @returns The number of bytes read. |
258 | * |
259 | * @throws boost::system::system_error Thrown on failure. An error code of |
260 | * boost::asio::error::eof indicates that the connection was closed by the |
261 | * peer. |
262 | * |
263 | * @note The read_some operation may not read all of the requested number of |
264 | * bytes. Consider using the @ref read_at function if you need to ensure that |
265 | * the requested amount of data is read before the blocking operation |
266 | * completes. |
267 | * |
268 | * @par Example |
269 | * To read into a single data buffer use the @ref buffer function as follows: |
270 | * @code |
271 | * handle.read_some_at(42, boost::asio::buffer(data, size)); |
272 | * @endcode |
273 | * See the @ref buffer documentation for information on reading into multiple |
274 | * buffers in one go, and how to use it with arrays, boost::array or |
275 | * std::vector. |
276 | */ |
277 | template <typename MutableBufferSequence> |
278 | std::size_t read_some_at(uint64_t offset, |
279 | const MutableBufferSequence& buffers) |
280 | { |
281 | boost::system::error_code ec; |
282 | std::size_t s = this->get_service().read_some_at( |
283 | this->get_implementation(), offset, buffers, ec); |
284 | boost::asio::detail::throw_error(ec, "read_some_at" ); |
285 | return s; |
286 | } |
287 | |
288 | /// Read some data from the handle at the specified offset. |
289 | /** |
290 | * This function is used to read data from the random-access handle. The |
291 | * function call will block until one or more bytes of data has been read |
292 | * successfully, or until an error occurs. |
293 | * |
294 | * @param offset The offset at which the data will be read. |
295 | * |
296 | * @param buffers One or more buffers into which the data will be read. |
297 | * |
298 | * @param ec Set to indicate what error occurred, if any. |
299 | * |
300 | * @returns The number of bytes read. Returns 0 if an error occurred. |
301 | * |
302 | * @note The read_some operation may not read all of the requested number of |
303 | * bytes. Consider using the @ref read_at function if you need to ensure that |
304 | * the requested amount of data is read before the blocking operation |
305 | * completes. |
306 | */ |
307 | template <typename MutableBufferSequence> |
308 | std::size_t read_some_at(uint64_t offset, |
309 | const MutableBufferSequence& buffers, boost::system::error_code& ec) |
310 | { |
311 | return this->get_service().read_some_at( |
312 | this->get_implementation(), offset, buffers, ec); |
313 | } |
314 | |
315 | /// Start an asynchronous read at the specified offset. |
316 | /** |
317 | * This function is used to asynchronously read data from the random-access |
318 | * handle. The function call always returns immediately. |
319 | * |
320 | * @param offset The offset at which the data will be read. |
321 | * |
322 | * @param buffers One or more buffers into which the data will be read. |
323 | * Although the buffers object may be copied as necessary, ownership of the |
324 | * underlying memory blocks is retained by the caller, which must guarantee |
325 | * that they remain valid until the handler is called. |
326 | * |
327 | * @param handler The handler to be called when the read operation completes. |
328 | * Copies will be made of the handler as required. The function signature of |
329 | * the handler must be: |
330 | * @code void handler( |
331 | * const boost::system::error_code& error, // Result of operation. |
332 | * std::size_t bytes_transferred // Number of bytes read. |
333 | * ); @endcode |
334 | * Regardless of whether the asynchronous operation completes immediately or |
335 | * not, the handler will not be invoked from within this function. Invocation |
336 | * of the handler will be performed in a manner equivalent to using |
337 | * boost::asio::io_service::post(). |
338 | * |
339 | * @note The read operation may not read all of the requested number of bytes. |
340 | * Consider using the @ref async_read_at function if you need to ensure that |
341 | * the requested amount of data is read before the asynchronous operation |
342 | * completes. |
343 | * |
344 | * @par Example |
345 | * To read into a single data buffer use the @ref buffer function as follows: |
346 | * @code |
347 | * handle.async_read_some_at(42, boost::asio::buffer(data, size), handler); |
348 | * @endcode |
349 | * See the @ref buffer documentation for information on reading into multiple |
350 | * buffers in one go, and how to use it with arrays, boost::array or |
351 | * std::vector. |
352 | */ |
353 | template <typename MutableBufferSequence, typename ReadHandler> |
354 | BOOST_ASIO_INITFN_RESULT_TYPE(ReadHandler, |
355 | void (boost::system::error_code, std::size_t)) |
356 | async_read_some_at(uint64_t offset, |
357 | const MutableBufferSequence& buffers, |
358 | BOOST_ASIO_MOVE_ARG(ReadHandler) handler) |
359 | { |
360 | // If you get an error on the following line it means that your handler does |
361 | // not meet the documented type requirements for a ReadHandler. |
362 | BOOST_ASIO_READ_HANDLER_CHECK(ReadHandler, handler) type_check; |
363 | |
364 | return this->get_service().async_read_some_at(this->get_implementation(), |
365 | offset, buffers, BOOST_ASIO_MOVE_CAST(ReadHandler)(handler)); |
366 | } |
367 | }; |
368 | |
369 | } // namespace windows |
370 | } // namespace asio |
371 | } // namespace boost |
372 | |
373 | #include <boost/asio/detail/pop_options.hpp> |
374 | |
375 | #endif // defined(BOOST_ASIO_HAS_WINDOWS_RANDOM_ACCESS_HANDLE) |
376 | // || defined(GENERATING_DOCUMENTATION) |
377 | |
378 | #endif // BOOST_ASIO_WINDOWS_BASIC_RANDOM_ACCESS_HANDLE_HPP |
379 | |