LCOV - code coverage report
Current view: top level - boost/beast2/impl/read.hpp (source / functions) Coverage Total Hit
Test: coverage_filtered.info Lines: 94.5 % 55 52
Test Date: 2025-11-13 15:50:43 Functions: 92.5 % 40 37

            Line data    Source code
       1              : //
       2              : // Copyright (c) 2016-2019 Vinnie Falco (vinnie dot falco at gmail dot com)
       3              : // Copyright (c) 2025 Mohammad Nejati
       4              : //
       5              : // Distributed under the Boost Software License, Version 1.0. (See accompanying
       6              : // file LICENSE_1_0.txt or copy at http://www.boost.org/LICENSE_1_0.txt)
       7              : //
       8              : // Official repository: https://github.com/cppalliance/beast2
       9              : //
      10              : 
      11              : #ifndef BOOST_BEAST2_IMPL_READ_HPP
      12              : #define BOOST_BEAST2_IMPL_READ_HPP
      13              : 
      14              : #include <boost/beast2/detail/except.hpp>
      15              : #include <boost/http_proto/error.hpp>
      16              : #include <boost/http_proto/parser.hpp>
      17              : #include <boost/asio/append.hpp>
      18              : #include <boost/asio/compose.hpp>
      19              : #include <boost/asio/coroutine.hpp>
      20              : #include <boost/asio/immediate.hpp>
      21              : #include <boost/assert.hpp>
      22              : 
      23              : namespace boost {
      24              : namespace beast2 {
      25              : 
      26              : namespace detail {
      27              : 
      28              : template<class AsyncStream>
      29              : class read_until_op
      30              :     : public asio::coroutine
      31              : {
      32              :     AsyncStream& stream_;
      33              :     http_proto::parser& pr_;
      34              :     std::size_t total_bytes_ = 0;
      35              :     bool (&condition_)(http_proto::parser&);
      36              : 
      37              : public:
      38          834 :     read_until_op(
      39              :         AsyncStream& s,
      40              :         http_proto::parser& pr,
      41              :         bool (&condition)(http_proto::parser&)) noexcept
      42          834 :         : stream_(s)
      43          834 :         , pr_(pr)
      44          834 :         , condition_(condition)
      45              :     {
      46          834 :     }
      47              : 
      48              :     template<class Self>
      49              :     void
      50         1918 :     operator()(
      51              :         Self& self,
      52              :         system::error_code ec = {},
      53              :         std::size_t bytes_transferred = 0)
      54              :     {
      55         3836 :         BOOST_ASIO_CORO_REENTER(*this)
      56              :         {
      57          834 :             self.reset_cancellation_state(
      58          834 :                 asio::enable_total_cancellation());
      59              : 
      60          476 :             for(;;)
      61              :             {
      62            2 :                 for(;;)
      63              :                 {
      64         1312 :                     pr_.parse(ec);
      65         1312 :                     if(ec == http_proto::condition::need_more_input)
      66              :                     {
      67          549 :                         if(!!self.cancelled())
      68              :                         {
      69           39 :                             ec = asio::error::operation_aborted;
      70           39 :                             goto upcall;
      71              :                         }
      72              :                         // specific to http_io::async_read_some
      73          510 :                         if(total_bytes_ != 0 && condition_(pr_))
      74              :                         {
      75           31 :                             ec = {};
      76           31 :                             goto upcall;
      77              :                         }
      78          479 :                         break;
      79              :                     }
      80          763 :                     if(ec.failed() || condition_(pr_))
      81              :                     {
      82          761 :                         if(total_bytes_ == 0)
      83              :                         {
      84         1815 :                             BOOST_ASIO_CORO_YIELD
      85              :                             {
      86              :                                 BOOST_ASIO_HANDLER_LOCATION((
      87              :                                     __FILE__, __LINE__,
      88              :                                     "immediate"));
      89          605 :                                 auto io_ex = self.get_io_executor();
      90          605 :                                 asio::async_immediate(
      91              :                                     io_ex,
      92          605 :                                     asio::append(std::move(self), ec));
      93          605 :                             }
      94              :                         }
      95          761 :                         goto upcall;
      96              :                     }
      97              :                 }
      98         1437 :                 BOOST_ASIO_CORO_YIELD
      99              :                 {
     100              :                     BOOST_ASIO_HANDLER_LOCATION((
     101              :                         __FILE__, __LINE__,
     102              :                         "async_read_some"));
     103          479 :                     stream_.async_read_some(
     104          958 :                         pr_.prepare(),
     105          479 :                         std::move(self));
     106              :                 }
     107          479 :                 pr_.commit(bytes_transferred);
     108          479 :                 total_bytes_ += bytes_transferred;
     109          479 :                 if(ec == asio::error::eof)
     110              :                 {
     111            0 :                     BOOST_ASSERT(
     112              :                         bytes_transferred == 0);
     113            0 :                     pr_.commit_eof();
     114            0 :                     ec = {};
     115              :                 }
     116          479 :                 else if(ec.failed())
     117              :                 {
     118            3 :                     goto upcall;
     119              :                 }
     120              :             }
     121              : 
     122          834 :         upcall:
     123          834 :             self.complete(ec, total_bytes_);
     124              :         }
     125         1918 :     }
     126              : };
     127              : 
     128              : inline
     129              : bool
     130          998 : got_header_condition(http_proto::parser& pr)
     131              : {
     132          998 :     return pr.got_header();
     133              : }
     134              : 
     135              : inline
     136              : bool
     137           44 : is_complete_condition(http_proto::parser& pr)
     138              : {
     139           44 :     return pr.is_complete();
     140              : }
     141              : 
     142              : } // detail
     143              : 
     144              : //------------------------------------------------
     145              : 
     146              : template<
     147              :     class AsyncReadStream,
     148              :     BOOST_ASIO_COMPLETION_TOKEN_FOR(
     149              :         void(system::error_code, std::size_t)) CompletionToken>
     150              : BOOST_ASIO_INITFN_AUTO_RESULT_TYPE(CompletionToken,
     151              :     void (system::error_code, std::size_t))
     152          832 : async_read_some(
     153              :     AsyncReadStream& s,
     154              :     http_proto::parser& pr,
     155              :     CompletionToken&& token)
     156              : {
     157              :     return asio::async_compose<
     158              :         CompletionToken,
     159          832 :         void(system::error_code, std::size_t)>(
     160              :             detail::read_until_op<AsyncReadStream>
     161              :                 {s, pr, detail::got_header_condition},
     162              :             token,
     163          832 :             s);
     164              : }
     165              : 
     166              : template<
     167              :     class AsyncReadStream,
     168              :     BOOST_ASIO_COMPLETION_TOKEN_FOR(
     169              :         void(system::error_code, std::size_t)) CompletionToken>
     170              : BOOST_ASIO_INITFN_AUTO_RESULT_TYPE(CompletionToken,
     171              :     void (system::error_code, std::size_t))
     172          143 : async_read_header(
     173              :     AsyncReadStream& s,
     174              :     http_proto::parser& pr,
     175              :     CompletionToken&& token)
     176              : {
     177              :     // TODO: async_read_header should not perform a read
     178              :     // operation if `parser::got_header() == true`.
     179          143 :     return async_read_some(s, pr, std::move(token));
     180              : }
     181              : 
     182              : template<
     183              :     class AsyncReadStream,
     184              :     BOOST_ASIO_COMPLETION_TOKEN_FOR(
     185              :         void(system::error_code, std::size_t)) CompletionToken>
     186              : BOOST_ASIO_INITFN_AUTO_RESULT_TYPE(CompletionToken,
     187              :     void (system::error_code, std::size_t))
     188            2 : async_read(
     189              :     AsyncReadStream& s,
     190              :     http_proto::parser& pr,
     191              :     CompletionToken&& token)
     192              : {
     193              :     return asio::async_compose<
     194              :         CompletionToken,
     195            2 :         void(system::error_code, std::size_t)>(
     196              :             detail::read_until_op<AsyncReadStream>
     197              :                 {s, pr, detail::is_complete_condition},
     198              :             token,
     199            2 :             s);
     200              : }
     201              : 
     202              : } // beast2
     203              : } // boost
     204              : 
     205              : #endif
        

Generated by: LCOV version 2.1