buffers_adapter(Deduced&& other, std::size_t nbegin, std::size_t nout, std::size_t nend) : bs_(std::forward<Deduced>(other).bs_) , begin_(std::next(bs_.begin(), nbegin)) , out_(std::next(bs_.begin(), nout)) , end_(std::next(bs_.begin(), nend)) , max_size_(other.max_size_) , in_pos_(other.in_pos_) , in_size_(other.in_size_) , out_pos_(other.out_pos_) , out_end_(other.out_end_) { }
std::size_t read_some(const MutableBufferSequence& buffers, boost::system::error_code& ec) { if (!file_) { ec = boost::asio::error::eof; return 0; } typename MutableBufferSequence::const_iterator iter = buffers.begin(); typename MutableBufferSequence::const_iterator end = buffers.end(); for (; iter != end; ++iter) { boost::asio::mutable_buffer buffer(*iter); size_t length = boost::asio::buffer_size(buffer); if (length > 0) { file_.read(boost::asio::buffer_cast<char*>(buffer), length); length = file_.gcount(); if (length == 0 && !file_) ec = boost::asio::error::eof; return length; } } ec = boost::system::error_code(); return 0; }
std::size_t read_some(const MutableBufferSequence& buffers , boost::system::error_code& ec) { ec = boost::system::error_code(); typename MutableBufferSequence::const_iterator iter = buffers.begin(); typename MutableBufferSequence::const_iterator end = buffers.end(); DWORD i = 0; size_t buffer_size = 0; size_t bytes_transferred = 0; size_t total_bytes_transferred = 0; for (; !ec && iter != end && i < max_buffers; ++iter, ++i) { boost::asio::mutable_buffer buffer(*iter); buffer_size = boost::asio::buffer_size(buffer); bytes_transferred = read_some( boost::asio::buffer_cast<char*>(buffer), buffer_size , ec); if (bytes_transferred < buffer_size) return bytes_transferred; total_bytes_transferred += buffer_size; } return total_bytes_transferred; }
void async_read_some_at(implementation_type& impl, boost::uint64_t offset, const MutableBufferSequence& buffers, Handler handler) { if (!is_open(impl)) { this->get_io_service().post(bind_handler(handler, boost::asio::error::bad_descriptor, 0)); return; } // Update the ID of the thread from which cancellation is safe. if (impl.safe_cancellation_thread_id_ == 0) impl.safe_cancellation_thread_id_ = ::GetCurrentThreadId(); else if (impl.safe_cancellation_thread_id_ != ::GetCurrentThreadId()) impl.safe_cancellation_thread_id_ = ~DWORD(0); // Allocate and construct an operation to wrap the handler. typedef read_operation<MutableBufferSequence, Handler> value_type; typedef handler_alloc_traits<Handler, value_type> alloc_traits; raw_handler_ptr<alloc_traits> raw_ptr(handler); handler_ptr<alloc_traits> ptr(raw_ptr, iocp_service_, buffers, handler); // Find first buffer of non-zero length. boost::asio::mutable_buffer buffer; typename MutableBufferSequence::const_iterator iter = buffers.begin(); typename MutableBufferSequence::const_iterator end = buffers.end(); for (DWORD i = 0; iter != end; ++iter, ++i) { buffer = boost::asio::mutable_buffer(*iter); if (boost::asio::buffer_size(buffer) != 0) break; } // A request to receive 0 bytes on a stream handle is a no-op. if (boost::asio::buffer_size(buffer) == 0) { boost::asio::io_service::work work(this->get_io_service()); ptr.reset(); boost::system::error_code error; iocp_service_.post(bind_handler(handler, error, 0)); return; } // Read some data. DWORD bytes_transferred = 0; ptr.get()->Offset = offset & 0xFFFFFFFF; ptr.get()->OffsetHigh = (offset >> 32) & 0xFFFFFFFF; BOOL ok = ::ReadFile(impl.handle_, boost::asio::buffer_cast<LPVOID>(buffer), static_cast<DWORD>(boost::asio::buffer_size(buffer)), &bytes_transferred, ptr.get()); DWORD last_error = ::GetLastError(); if (!ok && last_error != ERROR_IO_PENDING && last_error != ERROR_MORE_DATA) { boost::asio::io_service::work work(this->get_io_service()); ptr.reset(); boost::system::error_code ec(last_error, boost::asio::error::get_system_category()); iocp_service_.post(bind_handler(handler, ec, bytes_transferred)); } else { ptr.release(); } }
size_t read_some_at(implementation_type& impl, boost::uint64_t offset, const MutableBufferSequence& buffers, boost::system::error_code& ec) { if (!is_open(impl)) { ec = boost::asio::error::bad_descriptor; return 0; } // Find first buffer of non-zero length. boost::asio::mutable_buffer buffer; typename MutableBufferSequence::const_iterator iter = buffers.begin(); typename MutableBufferSequence::const_iterator end = buffers.end(); for (DWORD i = 0; iter != end; ++iter, ++i) { buffer = boost::asio::mutable_buffer(*iter); if (boost::asio::buffer_size(buffer) != 0) break; } // A request to read 0 bytes on a stream handle is a no-op. if (boost::asio::buffer_size(buffer) == 0) { ec = boost::system::error_code(); return 0; } overlapped_wrapper overlapped(ec); if (ec) { return 0; } // Read some data. overlapped.Offset = offset & 0xFFFFFFFF; overlapped.OffsetHigh = (offset >> 32) & 0xFFFFFFFF; BOOL ok = ::ReadFile(impl.handle_, boost::asio::buffer_cast<LPVOID>(buffer), static_cast<DWORD>(boost::asio::buffer_size(buffer)), 0, &overlapped); if (!ok) { DWORD last_error = ::GetLastError(); if (last_error != ERROR_IO_PENDING && last_error != ERROR_MORE_DATA) { if (last_error == ERROR_HANDLE_EOF) { ec = boost::asio::error::eof; } else { ec = boost::system::error_code(last_error, boost::asio::error::get_system_category()); } return 0; } } // Wait for the operation to complete. DWORD bytes_transferred = 0; ok = ::GetOverlappedResult(impl.handle_, &overlapped, &bytes_transferred, TRUE); if (!ok) { DWORD last_error = ::GetLastError(); if (last_error == ERROR_HANDLE_EOF) { ec = boost::asio::error::eof; } else { ec = boost::system::error_code(last_error, boost::asio::error::get_system_category()); } } ec = boost::system::error_code(); return bytes_transferred; }