Back to home page

EIC code displayed by LXR

 
 

    


File indexing completed on 2025-01-18 09:29:26

0001 //
0002 // Copyright (c) 2022 Seth Heeren (sgheeren at gmail dot com)
0003 //
0004 // Distributed under the Boost Software License, Version 1.0. (See accompanying
0005 // file LICENSE_1_0.txt or copy at http://www.boost.org/LICENSE_1_0.txt)
0006 //
0007 // Official repository: https://github.com/boostorg/beast
0008 //
0009 
0010 #ifndef BOOST_BEAST_CORE_IMPL_BUFFERS_GENERATOR_HPP
0011 #define BOOST_BEAST_CORE_IMPL_BUFFERS_GENERATOR_HPP
0012 
0013 #include <boost/beast/core/buffers_generator.hpp>
0014 
0015 #include <boost/asio/write.hpp>
0016 #include <boost/asio/async_result.hpp>
0017 #include <boost/asio/compose.hpp>
0018 #include <boost/asio/coroutine.hpp>
0019 
0020 #include <boost/beast/core/buffer_traits.hpp>
0021 #include <boost/beast/core/stream_traits.hpp>
0022 
0023 #include <boost/throw_exception.hpp>
0024 #include <type_traits>
0025 
0026 namespace boost {
0027 namespace beast {
0028 
0029 namespace detail {
0030 
0031 template <
0032     class AsyncWriteStream,
0033     class BuffersGenerator>
0034 struct write_buffers_generator_op
0035     : boost::asio::coroutine
0036 {
0037     write_buffers_generator_op(
0038         AsyncWriteStream& s, BuffersGenerator g)
0039         : s_(s)
0040         , g_(std::move(g))
0041     {
0042     }
0043 
0044     template<class Self>
0045     void operator()(
0046         Self& self, error_code ec = {}, std::size_t n = 0)
0047     {
0048         BOOST_ASIO_CORO_REENTER(*this)
0049         {
0050             while(! g_.is_done())
0051             {
0052                 BOOST_ASIO_CORO_YIELD
0053                 {
0054                     auto cb = g_.prepare(ec);
0055                     if(ec)
0056                         goto complete;
0057                     s_.async_write_some(
0058                         cb, std::move(self));
0059                 }
0060                 if(ec)
0061                     goto complete;
0062 
0063                 g_.consume(n);
0064 
0065                 total_ += n;
0066             }
0067 
0068         complete:
0069             self.complete(ec, total_);
0070         }
0071     }
0072 
0073 private:
0074     AsyncWriteStream& s_;
0075     BuffersGenerator g_;
0076     std::size_t total_ = 0;
0077 };
0078 
0079 } // detail
0080 
0081 template<
0082     class SyncWriteStream,
0083     class BuffersGenerator,
0084     typename std::enable_if< //
0085         is_buffers_generator<typename std::decay<
0086             BuffersGenerator>::type>::value>::type* /*= nullptr*/
0087     >
0088 size_t
0089 write(
0090     SyncWriteStream& stream,
0091     BuffersGenerator&& generator,
0092     beast::error_code& ec)
0093 {
0094     static_assert(
0095         is_sync_write_stream<SyncWriteStream>::value,
0096         "SyncWriteStream type requirements not met");
0097 
0098     ec.clear();
0099     size_t total = 0;
0100     while(! generator.is_done())
0101     {
0102         auto cb = generator.prepare(ec);
0103         if(ec)
0104             break;
0105 
0106         size_t n = net::write(stream, cb, ec);
0107 
0108         if(ec)
0109             break;
0110 
0111         generator.consume(n);
0112         total += n;
0113     }
0114 
0115     return total;
0116 }
0117 
0118 //----------------------------------------------------------
0119 
0120 template<
0121     class SyncWriteStream,
0122     class BuffersGenerator,
0123     typename std::enable_if<is_buffers_generator<
0124         typename std::decay<BuffersGenerator>::type>::value>::
0125         type* /*= nullptr*/
0126     >
0127 std::size_t
0128 write(SyncWriteStream& stream, BuffersGenerator&& generator)
0129 {
0130     static_assert(
0131         is_sync_write_stream<SyncWriteStream>::value,
0132         "SyncWriteStream type requirements not met");
0133     beast::error_code ec;
0134     std::size_t n = write(
0135         stream, std::forward<BuffersGenerator>(generator), ec);
0136     if(ec)
0137         BOOST_THROW_EXCEPTION(system_error{ ec });
0138     return n;
0139 }
0140 
0141 //----------------------------------------------------------
0142 
0143 template<
0144     class AsyncWriteStream,
0145     class BuffersGenerator,
0146     BOOST_BEAST_ASYNC_TPARAM2 CompletionToken,
0147     typename std::enable_if<is_buffers_generator<
0148         BuffersGenerator>::value>::type* /*= nullptr*/
0149     >
0150 BOOST_BEAST_ASYNC_RESULT2(CompletionToken)
0151 async_write(
0152     AsyncWriteStream& stream,
0153     BuffersGenerator generator,
0154     CompletionToken&& token)
0155 {
0156     static_assert(
0157         beast::is_async_write_stream<AsyncWriteStream>::value,
0158         "AsyncWriteStream type requirements not met");
0159 
0160     return net::async_compose< //
0161         CompletionToken,
0162         void(error_code, std::size_t)>(
0163         detail::write_buffers_generator_op<
0164             AsyncWriteStream,
0165             BuffersGenerator>{ stream, std::move(generator) },
0166         token,
0167         stream);
0168 }
0169 
0170 } // namespace beast
0171 } // namespace boost
0172 
0173 #endif