typename std::enable_if< is_const_buffer_sequence<ConstBufferSequence>::value, std::size_t>::type buffer_count(ConstBufferSequence const& buffers) { return std::distance(buffers.begin(), buffers.end()); }
std::size_t write_some(ConstBufferSequence const& buf , boost::system::error_code& ec) { ec = boost::system::error_code(); std::size_t bytes_transferred(0); for(typename ConstBufferSequence::const_iterator i = buf.begin(), end (buf.end()) ; !ec && i != end; ++i) { std::size_t buf_len = boost::asio::buffer_size(*i); bytes_transferred += buf_len; //int ret(fputs(boost::asio::buffer_cast<const char*>(*i), stdout)); //if (ret == EOF) //{ // return ::BOOST_CGI_NAMESPACE::error::broken_pipe; //} //std::cerr<< "[buf] " // << std::string(boost::asio::buffer_cast<const char*>(*i), buf_len) // << std::endl; if (!std::fwrite(boost::asio::buffer_cast<const void *>(*i) , buf_len, 1, stdout)) { if (std::feof(stdout)) ec = ::BOOST_CGI_NAMESPACE::error::eof; else if (std::ferror(stdout)) ec = ::BOOST_CGI_NAMESPACE::error::bad_write; else ec = ::BOOST_CGI_NAMESPACE::error::broken_pipe; } } return bytes_transferred; }
buffered_handshake_op(stream_base::handshake_type type, const ConstBufferSequence& buffers) : type_(type), buffers_head_(buffers.begin()), buffers_end_(buffers.end()) { }
typename std::enable_if< is_const_buffer_sequence<ConstBufferSequence>::value, std::size_t>::type size_rev_pre(ConstBufferSequence const& buffers) { std::size_t n = 0; for(auto it = buffers.end(); it != buffers.begin();) n += boost::asio::buffer_size(*--it); return n; }
typename std::enable_if< is_ConstBufferSequence<ConstBufferSequence>::value, std::size_t>::type size_rev_post(ConstBufferSequence const& buffers) { std::size_t n = 0; for(auto it = buffers.end(); it != buffers.begin();) { it--; n += boost::asio::buffer_size(*it); } return n; }
void send(const ConstBufferSequence& buffers) { for (auto i = buffers.begin(); i != buffers.end(); ++i) { size_t buf_size = asio::buffer_size(*i); size_t new_size = buf_size + data_size; unsigned char* buf = const_cast<unsigned char*>(asio::buffer_cast<const unsigned char*>(*i)); unsigned char* new_data = new unsigned char[new_size]; memcpy(new_data, data, data_size); memcpy(new_data+data_size, buf, buf_size); delete[] data; data = new_data; data_size = new_size; } }
std::size_t write_some(ConstBufferSequence& buf , boost::system::error_code& ec) { ec = boost::system::error_code(); std::size_t bytes_transferred(0); for(typename ConstBufferSequence::const_iterator i = buf.begin(), end (buf.end()) ; !ec && i != end; ++i) { std::size_t buf_len = boost::asio::buffer_size(*i); bytes_transferred += write_some(boost::asio::buffer_cast<const char *>(*i), buf_len, ec); } return bytes_transferred; }
typename std::enable_if< is_const_buffer_sequence<ConstBufferSequence>::value, std::size_t>::type size_pre(ConstBufferSequence const& buffers) { std::size_t n = 0; for(auto it = buffers.begin(); it != buffers.end(); ++it) { typename ConstBufferSequence::const_iterator it0(std::move(it)); typename ConstBufferSequence::const_iterator it1(it0); typename ConstBufferSequence::const_iterator it2; it2 = it1; n += boost::asio::buffer_size(*it2); it = std::move(it2); } return n; }
void operator()(error_code& ec, ConstBufferSequence const& buffers) const { // These asio functions are needed to access a buffer's contents using boost::asio::buffer_cast; using boost::asio::buffer_size; // Error codes must be cleared on success ec = {}; // Keep a running total of how much we wrote std::size_t bytes_transferred = 0; // Loop over the buffer sequence for(auto it = buffers.begin(); it != buffers.end(); ++ it) { // This is the next buffer in the sequence boost::asio::const_buffer const buffer = *it; // Write it to the std::ostream os_.write( buffer_cast<char const*>(buffer), buffer_size(buffer)); // If the std::ostream fails, convert it to an error code if(os_.fail()) { ec = make_error_code(errc::io_error); return; } // Adjust our running total bytes_transferred += buffer_size(buffer); } // Inform the serializer of the amount we consumed sr_.consume(bytes_transferred); }
// Create an iterator for the specified position. const_buffers_iterator(const ConstBufferSequence& buffers, std::size_t position) : begin_(buffers.begin()), current_(buffers.begin()), end_(buffers.end()), position_(0) { while (current_ != end_) { current_buffer_ = *current_; std::size_t buffer_size = boost::asio::buffer_size(current_buffer_); if (position - position_ < buffer_size) { current_buffer_position_ = position - position_; position_ = position; return; } position_ += buffer_size; ++current_; } current_buffer_ = boost::asio::const_buffer(); current_buffer_position_ = 0; }
void async_write_some_at(implementation_type& impl, boost::uint64_t offset, const ConstBufferSequence& 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 write_operation<ConstBufferSequence, 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::const_buffer buffer; typename ConstBufferSequence::const_iterator iter = buffers.begin(); typename ConstBufferSequence::const_iterator end = buffers.end(); for (DWORD i = 0; iter != end; ++iter, ++i) { buffer = boost::asio::const_buffer(*iter); if (boost::asio::buffer_size(buffer) != 0) break; } // A request to write 0 bytes on a 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; } // Write the data. DWORD bytes_transferred = 0; ptr.get()->Offset = offset & 0xFFFFFFFF; ptr.get()->OffsetHigh = (offset >> 32) & 0xFFFFFFFF; BOOL ok = ::WriteFile(impl.handle_, boost::asio::buffer_cast<LPCVOID>(buffer), static_cast<DWORD>(boost::asio::buffer_size(buffer)), &bytes_transferred, ptr.get()); DWORD last_error = ::GetLastError(); // Check if the operation completed immediately. if (!ok && last_error != ERROR_IO_PENDING) { 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 write_some_at(implementation_type& impl, boost::uint64_t offset, const ConstBufferSequence& 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::const_buffer buffer; typename ConstBufferSequence::const_iterator iter = buffers.begin(); typename ConstBufferSequence::const_iterator end = buffers.end(); for (DWORD i = 0; iter != end; ++iter, ++i) { buffer = boost::asio::const_buffer(*iter); if (boost::asio::buffer_size(buffer) != 0) break; } // A request to write 0 bytes on a 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; } // Write the data. overlapped.Offset = offset & 0xFFFFFFFF; overlapped.OffsetHigh = (offset >> 32) & 0xFFFFFFFF; BOOL ok = ::WriteFile(impl.handle_, boost::asio::buffer_cast<LPCVOID>(buffer), static_cast<DWORD>(boost::asio::buffer_size(buffer)), 0, &overlapped); if (!ok) { DWORD last_error = ::GetLastError(); if (last_error != ERROR_IO_PENDING) { 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(); ec = boost::system::error_code(last_error, boost::asio::error::get_system_category()); } ec = boost::system::error_code(); return bytes_transferred; }