|
||||
File indexing completed on 2025-01-18 09:29:05
0001 // 0002 // basic_random_access_file.hpp 0003 // ~~~~~~~~~~~~~~~~~~~~~~~~~~~~ 0004 // 0005 // Copyright (c) 2003-2023 Christopher M. Kohlhoff (chris at kohlhoff dot com) 0006 // 0007 // Distributed under the Boost Software License, Version 1.0. (See accompanying 0008 // file LICENSE_1_0.txt or copy at http://www.boost.org/LICENSE_1_0.txt) 0009 // 0010 0011 #ifndef BOOST_ASIO_BASIC_RANDOM_ACCESS_FILE_HPP 0012 #define BOOST_ASIO_BASIC_RANDOM_ACCESS_FILE_HPP 0013 0014 #if defined(_MSC_VER) && (_MSC_VER >= 1200) 0015 # pragma once 0016 #endif // defined(_MSC_VER) && (_MSC_VER >= 1200) 0017 0018 #include <boost/asio/detail/config.hpp> 0019 0020 #if defined(BOOST_ASIO_HAS_FILE) \ 0021 || defined(GENERATING_DOCUMENTATION) 0022 0023 #include <cstddef> 0024 #include <boost/asio/async_result.hpp> 0025 #include <boost/asio/basic_file.hpp> 0026 #include <boost/asio/detail/handler_type_requirements.hpp> 0027 #include <boost/asio/detail/non_const_lvalue.hpp> 0028 #include <boost/asio/detail/throw_error.hpp> 0029 #include <boost/asio/error.hpp> 0030 0031 #include <boost/asio/detail/push_options.hpp> 0032 0033 namespace boost { 0034 namespace asio { 0035 0036 #if !defined(BOOST_ASIO_BASIC_RANDOM_ACCESS_FILE_FWD_DECL) 0037 #define BOOST_ASIO_BASIC_RANDOM_ACCESS_FILE_FWD_DECL 0038 0039 // Forward declaration with defaulted arguments. 0040 template <typename Executor = any_io_executor> 0041 class basic_random_access_file; 0042 0043 #endif // !defined(BOOST_ASIO_BASIC_RANDOM_ACCESS_FILE_FWD_DECL) 0044 0045 /// Provides random-access file functionality. 0046 /** 0047 * The basic_random_access_file class template provides asynchronous and 0048 * blocking random-access file functionality. 0049 * 0050 * @par Thread Safety 0051 * @e Distinct @e objects: Safe.@n 0052 * @e Shared @e objects: Unsafe. 0053 * 0054 * Synchronous @c read_some_at and @c write_some_at operations are thread safe 0055 * with respect to each other, if the underlying operating system calls are 0056 * also thread safe. This means that it is permitted to perform concurrent 0057 * calls to these synchronous operations on a single file object. Other 0058 * synchronous operations, such as @c open or @c close, are not thread safe. 0059 */ 0060 template <typename Executor> 0061 class basic_random_access_file 0062 : public basic_file<Executor> 0063 { 0064 private: 0065 class initiate_async_write_some_at; 0066 class initiate_async_read_some_at; 0067 0068 public: 0069 /// The type of the executor associated with the object. 0070 typedef Executor executor_type; 0071 0072 /// Rebinds the file type to another executor. 0073 template <typename Executor1> 0074 struct rebind_executor 0075 { 0076 /// The file type when rebound to the specified executor. 0077 typedef basic_random_access_file<Executor1> other; 0078 }; 0079 0080 /// The native representation of a file. 0081 #if defined(GENERATING_DOCUMENTATION) 0082 typedef implementation_defined native_handle_type; 0083 #else 0084 typedef typename basic_file<Executor>::native_handle_type native_handle_type; 0085 #endif 0086 0087 /// Construct a basic_random_access_file without opening it. 0088 /** 0089 * This constructor initialises a file without opening it. The file needs to 0090 * be opened before data can be read from or or written to it. 0091 * 0092 * @param ex The I/O executor that the file will use, by default, to 0093 * dispatch handlers for any asynchronous operations performed on the file. 0094 */ 0095 explicit basic_random_access_file(const executor_type& ex) 0096 : basic_file<Executor>(ex) 0097 { 0098 } 0099 0100 /// Construct a basic_random_access_file without opening it. 0101 /** 0102 * This constructor initialises a file without opening it. The file needs to 0103 * be opened before data can be read from or or written to it. 0104 * 0105 * @param context An execution context which provides the I/O executor that 0106 * the file will use, by default, to dispatch handlers for any asynchronous 0107 * operations performed on the file. 0108 */ 0109 template <typename ExecutionContext> 0110 explicit basic_random_access_file(ExecutionContext& context, 0111 constraint_t< 0112 is_convertible<ExecutionContext&, execution_context&>::value, 0113 defaulted_constraint 0114 > = defaulted_constraint()) 0115 : basic_file<Executor>(context) 0116 { 0117 } 0118 0119 /// Construct and open a basic_random_access_file. 0120 /** 0121 * This constructor initialises and opens a file. 0122 * 0123 * @param ex The I/O executor that the file will use, by default, to 0124 * dispatch handlers for any asynchronous operations performed on the file. 0125 * 0126 * @param path The path name identifying the file to be opened. 0127 * 0128 * @param open_flags A set of flags that determine how the file should be 0129 * opened. 0130 * 0131 * @throws boost::system::system_error Thrown on failure. 0132 */ 0133 basic_random_access_file(const executor_type& ex, 0134 const char* path, file_base::flags open_flags) 0135 : basic_file<Executor>(ex, path, open_flags) 0136 { 0137 } 0138 0139 /// Construct and open a basic_random_access_file. 0140 /** 0141 * This constructor initialises and opens a file. 0142 * 0143 * @param context An execution context which provides the I/O executor that 0144 * the file will use, by default, to dispatch handlers for any asynchronous 0145 * operations performed on the file. 0146 * 0147 * @param path The path name identifying the file to be opened. 0148 * 0149 * @param open_flags A set of flags that determine how the file should be 0150 * opened. 0151 * 0152 * @throws boost::system::system_error Thrown on failure. 0153 */ 0154 template <typename ExecutionContext> 0155 basic_random_access_file(ExecutionContext& context, 0156 const char* path, file_base::flags open_flags, 0157 constraint_t< 0158 is_convertible<ExecutionContext&, execution_context&>::value, 0159 defaulted_constraint 0160 > = defaulted_constraint()) 0161 : basic_file<Executor>(context, path, open_flags) 0162 { 0163 } 0164 0165 /// Construct and open a basic_random_access_file. 0166 /** 0167 * This constructor initialises and opens a file. 0168 * 0169 * @param ex The I/O executor that the file will use, by default, to 0170 * dispatch handlers for any asynchronous operations performed on the file. 0171 * 0172 * @param path The path name identifying the file to be opened. 0173 * 0174 * @param open_flags A set of flags that determine how the file should be 0175 * opened. 0176 * 0177 * @throws boost::system::system_error Thrown on failure. 0178 */ 0179 basic_random_access_file(const executor_type& ex, 0180 const std::string& path, file_base::flags open_flags) 0181 : basic_file<Executor>(ex, path, open_flags) 0182 { 0183 } 0184 0185 /// Construct and open a basic_random_access_file. 0186 /** 0187 * This constructor initialises and opens a file. 0188 * 0189 * @param context An execution context which provides the I/O executor that 0190 * the file will use, by default, to dispatch handlers for any asynchronous 0191 * operations performed on the file. 0192 * 0193 * @param path The path name identifying the file to be opened. 0194 * 0195 * @param open_flags A set of flags that determine how the file should be 0196 * opened. 0197 * 0198 * @throws boost::system::system_error Thrown on failure. 0199 */ 0200 template <typename ExecutionContext> 0201 basic_random_access_file(ExecutionContext& context, 0202 const std::string& path, file_base::flags open_flags, 0203 constraint_t< 0204 is_convertible<ExecutionContext&, execution_context&>::value, 0205 defaulted_constraint 0206 > = defaulted_constraint()) 0207 : basic_file<Executor>(context, path, open_flags) 0208 { 0209 } 0210 0211 /// Construct a basic_random_access_file on an existing native file. 0212 /** 0213 * This constructor initialises a random-access file object to hold an 0214 * existing native file. 0215 * 0216 * @param ex The I/O executor that the file will use, by default, to 0217 * dispatch handlers for any asynchronous operations performed on the file. 0218 * 0219 * @param native_file The new underlying file implementation. 0220 * 0221 * @throws boost::system::system_error Thrown on failure. 0222 */ 0223 basic_random_access_file(const executor_type& ex, 0224 const native_handle_type& native_file) 0225 : basic_file<Executor>(ex, native_file) 0226 { 0227 } 0228 0229 /// Construct a basic_random_access_file on an existing native file. 0230 /** 0231 * This constructor initialises a random-access file object to hold an 0232 * existing native file. 0233 * 0234 * @param context An execution context which provides the I/O executor that 0235 * the file will use, by default, to dispatch handlers for any asynchronous 0236 * operations performed on the file. 0237 * 0238 * @param native_file The new underlying file implementation. 0239 * 0240 * @throws boost::system::system_error Thrown on failure. 0241 */ 0242 template <typename ExecutionContext> 0243 basic_random_access_file(ExecutionContext& context, 0244 const native_handle_type& native_file, 0245 constraint_t< 0246 is_convertible<ExecutionContext&, execution_context&>::value, 0247 defaulted_constraint 0248 > = defaulted_constraint()) 0249 : basic_file<Executor>(context, native_file) 0250 { 0251 } 0252 0253 /// Move-construct a basic_random_access_file from another. 0254 /** 0255 * This constructor moves a random-access file from one object to another. 0256 * 0257 * @param other The other basic_random_access_file object from which the move 0258 * will occur. 0259 * 0260 * @note Following the move, the moved-from object is in the same state as if 0261 * constructed using the @c basic_random_access_file(const executor_type&) 0262 * constructor. 0263 */ 0264 basic_random_access_file(basic_random_access_file&& other) noexcept 0265 : basic_file<Executor>(std::move(other)) 0266 { 0267 } 0268 0269 /// Move-assign a basic_random_access_file from another. 0270 /** 0271 * This assignment operator moves a random-access file from one object to 0272 * another. 0273 * 0274 * @param other The other basic_random_access_file object from which the move 0275 * will occur. 0276 * 0277 * @note Following the move, the moved-from object is in the same state as if 0278 * constructed using the @c basic_random_access_file(const executor_type&) 0279 * constructor. 0280 */ 0281 basic_random_access_file& operator=(basic_random_access_file&& other) 0282 { 0283 basic_file<Executor>::operator=(std::move(other)); 0284 return *this; 0285 } 0286 0287 /// Move-construct a basic_random_access_file from a file of another executor 0288 /// type. 0289 /** 0290 * This constructor moves a random-access file from one object to another. 0291 * 0292 * @param other The other basic_random_access_file object from which the move 0293 * will occur. 0294 * 0295 * @note Following the move, the moved-from object is in the same state as if 0296 * constructed using the @c basic_random_access_file(const executor_type&) 0297 * constructor. 0298 */ 0299 template <typename Executor1> 0300 basic_random_access_file(basic_random_access_file<Executor1>&& other, 0301 constraint_t< 0302 is_convertible<Executor1, Executor>::value, 0303 defaulted_constraint 0304 > = defaulted_constraint()) 0305 : basic_file<Executor>(std::move(other)) 0306 { 0307 } 0308 0309 /// Move-assign a basic_random_access_file from a file of another executor 0310 /// type. 0311 /** 0312 * This assignment operator moves a random-access file from one object to 0313 * another. 0314 * 0315 * @param other The other basic_random_access_file object from which the move 0316 * will occur. 0317 * 0318 * @note Following the move, the moved-from object is in the same state as if 0319 * constructed using the @c basic_random_access_file(const executor_type&) 0320 * constructor. 0321 */ 0322 template <typename Executor1> 0323 constraint_t< 0324 is_convertible<Executor1, Executor>::value, 0325 basic_random_access_file& 0326 > operator=(basic_random_access_file<Executor1>&& other) 0327 { 0328 basic_file<Executor>::operator=(std::move(other)); 0329 return *this; 0330 } 0331 0332 /// Destroys the file. 0333 /** 0334 * This function destroys the file, cancelling any outstanding asynchronous 0335 * operations associated with the file as if by calling @c cancel. 0336 */ 0337 ~basic_random_access_file() 0338 { 0339 } 0340 0341 /// Write some data to the handle at the specified offset. 0342 /** 0343 * This function is used to write data to the random-access handle. The 0344 * function call will block until one or more bytes of the data has been 0345 * written successfully, or until an error occurs. 0346 * 0347 * @param offset The offset at which the data will be written. 0348 * 0349 * @param buffers One or more data buffers to be written to the handle. 0350 * 0351 * @returns The number of bytes written. 0352 * 0353 * @throws boost::system::system_error Thrown on failure. An error code of 0354 * boost::asio::error::eof indicates that the end of the file was reached. 0355 * 0356 * @note The write_some_at operation may not write all of the data. Consider 0357 * using the @ref write_at function if you need to ensure that all data is 0358 * written before the blocking operation completes. 0359 * 0360 * @par Example 0361 * To write a single data buffer use the @ref buffer function as follows: 0362 * @code 0363 * handle.write_some_at(42, boost::asio::buffer(data, size)); 0364 * @endcode 0365 * See the @ref buffer documentation for information on writing multiple 0366 * buffers in one go, and how to use it with arrays, boost::array or 0367 * std::vector. 0368 */ 0369 template <typename ConstBufferSequence> 0370 std::size_t write_some_at(uint64_t offset, 0371 const ConstBufferSequence& buffers) 0372 { 0373 boost::system::error_code ec; 0374 std::size_t s = this->impl_.get_service().write_some_at( 0375 this->impl_.get_implementation(), offset, buffers, ec); 0376 boost::asio::detail::throw_error(ec, "write_some_at"); 0377 return s; 0378 } 0379 0380 /// Write some data to the handle at the specified offset. 0381 /** 0382 * This function is used to write data to the random-access handle. The 0383 * function call will block until one or more bytes of the data has been 0384 * written successfully, or until an error occurs. 0385 * 0386 * @param offset The offset at which the data will be written. 0387 * 0388 * @param buffers One or more data buffers to be written to the handle. 0389 * 0390 * @param ec Set to indicate what error occurred, if any. 0391 * 0392 * @returns The number of bytes written. Returns 0 if an error occurred. 0393 * 0394 * @note The write_some operation may not write all of the data to the 0395 * file. Consider using the @ref write_at function if you need to ensure that 0396 * all data is written before the blocking operation completes. 0397 */ 0398 template <typename ConstBufferSequence> 0399 std::size_t write_some_at(uint64_t offset, 0400 const ConstBufferSequence& buffers, boost::system::error_code& ec) 0401 { 0402 return this->impl_.get_service().write_some_at( 0403 this->impl_.get_implementation(), offset, buffers, ec); 0404 } 0405 0406 /// Start an asynchronous write at the specified offset. 0407 /** 0408 * This function is used to asynchronously write data to the random-access 0409 * handle. It is an initiating function for an @ref asynchronous_operation, 0410 * and always returns immediately. 0411 * 0412 * @param offset The offset at which the data will be written. 0413 * 0414 * @param buffers One or more data buffers to be written to the handle. 0415 * Although the buffers object may be copied as necessary, ownership of the 0416 * underlying memory blocks is retained by the caller, which must guarantee 0417 * that they remain valid until the completion handler is called. 0418 * 0419 * @param token The @ref completion_token that will be used to produce a 0420 * completion handler, which will be called when the write completes. 0421 * Potential completion tokens include @ref use_future, @ref use_awaitable, 0422 * @ref yield_context, or a function object with the correct completion 0423 * signature. The function signature of the completion handler must be: 0424 * @code void handler( 0425 * const boost::system::error_code& error, // Result of operation. 0426 * std::size_t bytes_transferred // Number of bytes written. 0427 * ); @endcode 0428 * Regardless of whether the asynchronous operation completes immediately or 0429 * not, the completion handler will not be invoked from within this function. 0430 * On immediate completion, invocation of the handler will be performed in a 0431 * manner equivalent to using boost::asio::post(). 0432 * 0433 * @par Completion Signature 0434 * @code void(boost::system::error_code, std::size_t) @endcode 0435 * 0436 * @note The write operation may not write all of the data to the file. 0437 * Consider using the @ref async_write_at function if you need to ensure that 0438 * all data is written before the asynchronous operation completes. 0439 * 0440 * @par Example 0441 * To write a single data buffer use the @ref buffer function as follows: 0442 * @code 0443 * handle.async_write_some_at(42, boost::asio::buffer(data, size), handler); 0444 * @endcode 0445 * See the @ref buffer documentation for information on writing multiple 0446 * buffers in one go, and how to use it with arrays, boost::array or 0447 * std::vector. 0448 * 0449 * @par Per-Operation Cancellation 0450 * This asynchronous operation supports cancellation for the following 0451 * boost::asio::cancellation_type values: 0452 * 0453 * @li @c cancellation_type::terminal 0454 * 0455 * @li @c cancellation_type::partial 0456 * 0457 * @li @c cancellation_type::total 0458 */ 0459 template <typename ConstBufferSequence, 0460 BOOST_ASIO_COMPLETION_TOKEN_FOR(void (boost::system::error_code, 0461 std::size_t)) WriteToken = default_completion_token_t<executor_type>> 0462 auto async_write_some_at(uint64_t offset, const ConstBufferSequence& buffers, 0463 WriteToken&& token = default_completion_token_t<executor_type>()) 0464 -> decltype( 0465 async_initiate<WriteToken, 0466 void (boost::system::error_code, std::size_t)>( 0467 declval<initiate_async_write_some_at>(), token, offset, buffers)) 0468 { 0469 return async_initiate<WriteToken, 0470 void (boost::system::error_code, std::size_t)>( 0471 initiate_async_write_some_at(this), token, offset, buffers); 0472 } 0473 0474 /// Read some data from the handle at the specified offset. 0475 /** 0476 * This function is used to read data from the random-access handle. The 0477 * function call will block until one or more bytes of data has been read 0478 * successfully, or until an error occurs. 0479 * 0480 * @param offset The offset at which the data will be read. 0481 * 0482 * @param buffers One or more buffers into which the data will be read. 0483 * 0484 * @returns The number of bytes read. 0485 * 0486 * @throws boost::system::system_error Thrown on failure. An error code of 0487 * boost::asio::error::eof indicates that the end of the file was reached. 0488 * 0489 * @note The read_some operation may not read all of the requested number of 0490 * bytes. Consider using the @ref read_at function if you need to ensure that 0491 * the requested amount of data is read before the blocking operation 0492 * completes. 0493 * 0494 * @par Example 0495 * To read into a single data buffer use the @ref buffer function as follows: 0496 * @code 0497 * handle.read_some_at(42, boost::asio::buffer(data, size)); 0498 * @endcode 0499 * See the @ref buffer documentation for information on reading into multiple 0500 * buffers in one go, and how to use it with arrays, boost::array or 0501 * std::vector. 0502 */ 0503 template <typename MutableBufferSequence> 0504 std::size_t read_some_at(uint64_t offset, 0505 const MutableBufferSequence& buffers) 0506 { 0507 boost::system::error_code ec; 0508 std::size_t s = this->impl_.get_service().read_some_at( 0509 this->impl_.get_implementation(), offset, buffers, ec); 0510 boost::asio::detail::throw_error(ec, "read_some_at"); 0511 return s; 0512 } 0513 0514 /// Read some data from the handle at the specified offset. 0515 /** 0516 * This function is used to read data from the random-access handle. The 0517 * function call will block until one or more bytes of data has been read 0518 * successfully, or until an error occurs. 0519 * 0520 * @param offset The offset at which the data will be read. 0521 * 0522 * @param buffers One or more buffers into which the data will be read. 0523 * 0524 * @param ec Set to indicate what error occurred, if any. 0525 * 0526 * @returns The number of bytes read. Returns 0 if an error occurred. 0527 * 0528 * @note The read_some operation may not read all of the requested number of 0529 * bytes. Consider using the @ref read_at function if you need to ensure that 0530 * the requested amount of data is read before the blocking operation 0531 * completes. 0532 */ 0533 template <typename MutableBufferSequence> 0534 std::size_t read_some_at(uint64_t offset, 0535 const MutableBufferSequence& buffers, boost::system::error_code& ec) 0536 { 0537 return this->impl_.get_service().read_some_at( 0538 this->impl_.get_implementation(), offset, buffers, ec); 0539 } 0540 0541 /// Start an asynchronous read at the specified offset. 0542 /** 0543 * This function is used to asynchronously read data from the random-access 0544 * handle. It is an initiating function for an @ref asynchronous_operation, 0545 * and always returns immediately. 0546 * 0547 * @param offset The offset at which the data will be read. 0548 * 0549 * @param buffers One or more buffers into which the data will be read. 0550 * Although the buffers object may be copied as necessary, ownership of the 0551 * underlying memory blocks is retained by the caller, which must guarantee 0552 * that they remain valid until the completion handler is called. 0553 * 0554 * @param token The @ref completion_token that will be used to produce a 0555 * completion handler, which will be called when the read completes. 0556 * Potential completion tokens include @ref use_future, @ref use_awaitable, 0557 * @ref yield_context, or a function object with the correct completion 0558 * signature. The function signature of the completion handler must be: 0559 * @code void handler( 0560 * const boost::system::error_code& error, // Result of operation. 0561 * std::size_t bytes_transferred // Number of bytes read. 0562 * ); @endcode 0563 * Regardless of whether the asynchronous operation completes immediately or 0564 * not, the completion handler will not be invoked from within this function. 0565 * On immediate completion, invocation of the handler will be performed in a 0566 * manner equivalent to using boost::asio::post(). 0567 * 0568 * @par Completion Signature 0569 * @code void(boost::system::error_code, std::size_t) @endcode 0570 * 0571 * @note The read operation may not read all of the requested number of bytes. 0572 * Consider using the @ref async_read_at function if you need to ensure that 0573 * the requested amount of data is read before the asynchronous operation 0574 * completes. 0575 * 0576 * @par Example 0577 * To read into a single data buffer use the @ref buffer function as follows: 0578 * @code 0579 * handle.async_read_some_at(42, boost::asio::buffer(data, size), handler); 0580 * @endcode 0581 * See the @ref buffer documentation for information on reading into multiple 0582 * buffers in one go, and how to use it with arrays, boost::array or 0583 * std::vector. 0584 * 0585 * @par Per-Operation Cancellation 0586 * This asynchronous operation supports cancellation for the following 0587 * boost::asio::cancellation_type values: 0588 * 0589 * @li @c cancellation_type::terminal 0590 * 0591 * @li @c cancellation_type::partial 0592 * 0593 * @li @c cancellation_type::total 0594 */ 0595 template <typename MutableBufferSequence, 0596 BOOST_ASIO_COMPLETION_TOKEN_FOR(void (boost::system::error_code, 0597 std::size_t)) ReadToken = default_completion_token_t<executor_type>> 0598 auto async_read_some_at(uint64_t offset, const MutableBufferSequence& buffers, 0599 ReadToken&& token = default_completion_token_t<executor_type>()) 0600 -> decltype( 0601 async_initiate<ReadToken, 0602 void (boost::system::error_code, std::size_t)>( 0603 declval<initiate_async_read_some_at>(), token, offset, buffers)) 0604 { 0605 return async_initiate<ReadToken, 0606 void (boost::system::error_code, std::size_t)>( 0607 initiate_async_read_some_at(this), token, offset, buffers); 0608 } 0609 0610 private: 0611 // Disallow copying and assignment. 0612 basic_random_access_file(const basic_random_access_file&) = delete; 0613 basic_random_access_file& operator=( 0614 const basic_random_access_file&) = delete; 0615 0616 class initiate_async_write_some_at 0617 { 0618 public: 0619 typedef Executor executor_type; 0620 0621 explicit initiate_async_write_some_at(basic_random_access_file* self) 0622 : self_(self) 0623 { 0624 } 0625 0626 const executor_type& get_executor() const noexcept 0627 { 0628 return self_->get_executor(); 0629 } 0630 0631 template <typename WriteHandler, typename ConstBufferSequence> 0632 void operator()(WriteHandler&& handler, 0633 uint64_t offset, const ConstBufferSequence& buffers) const 0634 { 0635 // If you get an error on the following line it means that your handler 0636 // does not meet the documented type requirements for a WriteHandler. 0637 BOOST_ASIO_WRITE_HANDLER_CHECK(WriteHandler, handler) type_check; 0638 0639 detail::non_const_lvalue<WriteHandler> handler2(handler); 0640 self_->impl_.get_service().async_write_some_at( 0641 self_->impl_.get_implementation(), offset, buffers, 0642 handler2.value, self_->impl_.get_executor()); 0643 } 0644 0645 private: 0646 basic_random_access_file* self_; 0647 }; 0648 0649 class initiate_async_read_some_at 0650 { 0651 public: 0652 typedef Executor executor_type; 0653 0654 explicit initiate_async_read_some_at(basic_random_access_file* self) 0655 : self_(self) 0656 { 0657 } 0658 0659 const executor_type& get_executor() const noexcept 0660 { 0661 return self_->get_executor(); 0662 } 0663 0664 template <typename ReadHandler, typename MutableBufferSequence> 0665 void operator()(ReadHandler&& handler, 0666 uint64_t offset, const MutableBufferSequence& buffers) const 0667 { 0668 // If you get an error on the following line it means that your handler 0669 // does not meet the documented type requirements for a ReadHandler. 0670 BOOST_ASIO_READ_HANDLER_CHECK(ReadHandler, handler) type_check; 0671 0672 detail::non_const_lvalue<ReadHandler> handler2(handler); 0673 self_->impl_.get_service().async_read_some_at( 0674 self_->impl_.get_implementation(), offset, buffers, 0675 handler2.value, self_->impl_.get_executor()); 0676 } 0677 0678 private: 0679 basic_random_access_file* self_; 0680 }; 0681 }; 0682 0683 } // namespace asio 0684 } // namespace boost 0685 0686 #include <boost/asio/detail/pop_options.hpp> 0687 0688 #endif // defined(BOOST_ASIO_HAS_FILE) 0689 // || defined(GENERATING_DOCUMENTATION) 0690 0691 #endif // BOOST_ASIO_BASIC_RANDOM_ACCESS_FILE_HPP
[ Source navigation ] | [ Diff markup ] | [ Identifier search ] | [ general search ] |
This page was automatically generated by the 2.3.7 LXR engine. The LXR team |