Advertisement
Not a member of Pastebin yet?
Sign Up,
it unlocks many cool features!
- #pragma once
- #include <boost/asio/ip/tcp.hpp>
- #include <boost/asio/buffer.hpp>
- #include <boost/asio/spawn.hpp>
- using namespace boost::asio;
- using namespace boost::system;
- namespace msocks::utility
- {
- template<typename AsyncBufferedReadStream, typename AsyncWriteStream>
- async_result<yield_context, void(error_code, std::string)>::return_type
- socket_pair(
- AsyncBufferedReadStream& source,
- AsyncWriteStream& destination,
- io_context& ioc,
- mutable_buffer m_buf,
- std::function<void(std::size_t)> before_read,
- std::function<void(mutable_buffer)> before_write,
- yield_context token
- )
- {
- using result_type = async_result<yield_context, void(error_code, std::string)>;
- using handler_type = result_type::completion_handler_type;
- handler_type handler(token);
- result_type result(handler);
- spawn(
- ioc,
- [
- &source,
- &destination,
- &ioc,
- m_buf,
- before_read(std::move(before_read)),
- before_write(std::move(before_write)),
- handler
- ](yield_context yield) mutable
- {
- error_code ec;
- std::string err_source;
- while (true)
- {
- if (source.in_avail() <= 4096)
- {
- source.async_fill(yield);
- }
- auto ready_to_read = std::min(source.in_avail(), m_buf.size());
- before_read(ready_to_read);
- auto n_read = source.async_read_some(buffer(m_buf,ready_to_read), yield[ec]);
- if(ec)
- {
- source = "source";
- break;
- }
- before_write(buffer(m_buf, n_read));
- async_write(destination, buffer(m_buf, n_read), yield[ec]);
- if (ec)
- {
- source = "destination";
- break;
- }
- }
- post(ioc, std::bind(handler, ec, err_source));
- });
- return result.get();
- }
- }
Advertisement
Add Comment
Please, Sign In to add comment
Advertisement