LCOV - code coverage report
Current view: top level - boost/http_proto - serializer.hpp (source / functions) Hit Total Coverage
Test: coverage_filtered.info Lines: 11 15 73.3 %
Date: 2024-03-19 15:22:00 Functions: 7 9 77.8 %

          Line data    Source code
       1             : //
       2             : // Copyright (c) 2019 Vinnie Falco (vinnie.falco@gmail.com)
       3             : //
       4             : // Distributed under the Boost Software License, Version 1.0. (See accompanying
       5             : // file LICENSE_1_0.txt or copy at http://www.boost.org/LICENSE_1_0.txt)
       6             : //
       7             : // Official repository: https://github.com/cppalliance/http_proto
       8             : //
       9             : 
      10             : #ifndef BOOST_HTTP_PROTO_SERIALIZER_HPP
      11             : #define BOOST_HTTP_PROTO_SERIALIZER_HPP
      12             : 
      13             : #include <boost/http_proto/buffered_base.hpp>
      14             : #include <boost/http_proto/detail/config.hpp>
      15             : #include <boost/http_proto/detail/array_of_buffers.hpp>
      16             : #include <boost/http_proto/detail/header.hpp>
      17             : #include <boost/http_proto/detail/workspace.hpp>
      18             : #include <boost/buffers/circular_buffer.hpp>
      19             : #include <boost/buffers/mutable_buffer_span.hpp>
      20             : #include <boost/buffers/range.hpp>
      21             : #include <boost/buffers/type_traits.hpp>
      22             : #include <boost/buffers/type_traits.hpp>
      23             : #include <boost/system/result.hpp>
      24             : #include <type_traits>
      25             : 
      26             : namespace boost {
      27             : namespace http_proto {
      28             : 
      29             : #ifndef BOOST_HTTP_PROTO_DOCS
      30             : class request;
      31             : class response;
      32             : class request_view;
      33             : class response_view;
      34             : class message_view_base;
      35             : #endif
      36             : 
      37             : /** A serializer for HTTP/1 messages
      38             : 
      39             :     This is used to serialize one or more complete
      40             :     HTTP/1 messages. Each message consists of a
      41             :     required header followed by an optional body.
      42             : */
      43             : class BOOST_SYMBOL_VISIBLE
      44           0 :     serializer
      45             : {
      46             : public:
      47             :     /** A ConstBuffers representing the output
      48             :     */
      49             :     class const_buffers_type;
      50             : 
      51             :     struct source;
      52             :     struct stream;
      53             : 
      54             :     /** Destructor
      55             :     */
      56             :     BOOST_HTTP_PROTO_DECL
      57             :     ~serializer();
      58             : 
      59             :     /** Constructor
      60             :     */
      61             :     BOOST_HTTP_PROTO_DECL
      62             :     serializer();
      63             : 
      64             :     /** Constructor
      65             :     */
      66             :     BOOST_HTTP_PROTO_DECL
      67             :     serializer(
      68             :         serializer&&) noexcept;
      69             : 
      70             :     /** Constructor
      71             :     */
      72             :     BOOST_HTTP_PROTO_DECL
      73             :     explicit
      74             :     serializer(
      75             :         std::size_t buffer_size);
      76             : 
      77             :     //--------------------------------------------
      78             : 
      79             :     /** Prepare the serializer for a new stream
      80             :     */
      81             :     BOOST_HTTP_PROTO_DECL
      82             :     void
      83             :     reset() noexcept;
      84             : 
      85             :     /** Prepare the serializer for a new message
      86             : 
      87             :         The message will not contain a body.
      88             :         Changing the contents of the message
      89             :         after calling this function and before
      90             :         @ref is_done returns `true` results in
      91             :         undefined behavior.
      92             :     */
      93             :     void
      94           4 :     start(
      95             :         message_view_base const& m)
      96             :     {
      97           4 :         start_empty(m);
      98           4 :     }
      99             : 
     100             :     /** Prepare the serializer for a new message
     101             : 
     102             :         Changing the contents of the message
     103             :         after calling this function and before
     104             :         @ref is_done returns `true` results in
     105             :         undefined behavior.
     106             : 
     107             :         @par Constraints
     108             :         @code
     109             :         is_const_buffers< ConstBuffers >::value == true
     110             :         @endcode
     111             :     */
     112             :     template<
     113             :         class ConstBufferSequence
     114             : #ifndef BOOST_HTTP_PROTO_DOCS
     115             :         ,class = typename
     116             :             std::enable_if<
     117             :                 buffers::is_const_buffer_sequence<
     118             :                     ConstBufferSequence>::value
     119             :                         >::type
     120             : #endif
     121             :     >
     122             :     void
     123             :     start(
     124             :         message_view_base const& m,
     125             :         ConstBufferSequence&& body);    
     126             : 
     127             :     /** Prepare the serializer for a new message
     128             : 
     129             :         Changing the contents of the message
     130             :         after calling this function and before
     131             :         @ref is_done returns `true` results in
     132             :         undefined behavior.
     133             :     */
     134             :     template<
     135             :         class Source
     136             : #ifndef BOOST_HTTP_PROTO_DOCS
     137             :         ,class = typename std::enable_if<
     138             :             std::is_convertible<
     139             :                 typename std::decay<Source>::type*,
     140             :                 source*>::value>::type
     141             : #endif
     142             :     >
     143             :     auto
     144             :     start(
     145             :         message_view_base const& m,
     146             :         Source&& body) ->
     147             :             typename std::decay<
     148             :                 Source>::type&;
     149             : 
     150             :     //--------------------------------------------
     151             : 
     152             :     BOOST_HTTP_PROTO_DECL
     153             :     stream
     154             :     start_stream(
     155             :         message_view_base const& m);
     156             : 
     157             :     //--------------------------------------------
     158             : 
     159             :     /** Return true if serialization is complete.
     160             :     */
     161             :     bool
     162          41 :     is_done() const noexcept
     163             :     {
     164          41 :         return is_done_;
     165             :     }
     166             : 
     167             :     /** Return the output area.
     168             : 
     169             :         This function will serialize some or
     170             :         all of the content and return the
     171             :         corresponding output buffers.
     172             : 
     173             :         @par Preconditions
     174             :         @code
     175             :         this->is_done() == false
     176             :         @endcode
     177             :     */
     178             :     BOOST_HTTP_PROTO_DECL
     179             :     auto
     180             :     prepare() ->
     181             :         system::result<
     182             :             const_buffers_type>;
     183             : 
     184             :     /** Consume bytes from the output area.
     185             :     */
     186             :     BOOST_HTTP_PROTO_DECL
     187             :     void
     188             :     consume(std::size_t n);
     189             : 
     190             : private:
     191             :     static void copy(
     192             :         buffers::const_buffer*,
     193             :         buffers::const_buffer const*,
     194             :         std::size_t n) noexcept;
     195             :     auto
     196             :     make_array(std::size_t n) ->
     197             :         detail::array_of_const_buffers;
     198             : 
     199             :     BOOST_HTTP_PROTO_DECL void start_init(message_view_base const&);
     200             :     BOOST_HTTP_PROTO_DECL void start_empty(message_view_base const&);
     201             :     BOOST_HTTP_PROTO_DECL void start_buffers(message_view_base const&);
     202             :     BOOST_HTTP_PROTO_DECL void start_source(message_view_base const&, source*);
     203             : 
     204             :     enum class style
     205             :     {
     206             :         empty,
     207             :         buffers,
     208             :         source,
     209             :         stream
     210             :     };
     211             : 
     212             :     static
     213             :     constexpr
     214             :     std::size_t
     215             :     chunked_overhead_ =
     216             :         16 +        // size
     217             :         2 +         // CRLF
     218             :         2 +         // CRLF
     219             :         1 +         // "0"
     220             :         2 +         // CRLF
     221             :         2;          // CRLF
     222             : 
     223             :     detail::workspace ws_;
     224             :     detail::array_of_const_buffers buf_;
     225             :     source* src_;
     226             : 
     227             :     buffers::circular_buffer tmp0_;
     228             :     buffers::circular_buffer tmp1_;
     229             :     detail::array_of_const_buffers out_;
     230             : 
     231             :     buffers::const_buffer* hp_;  // header
     232             : 
     233             :     style st_;
     234             :     bool more_;
     235             :     bool is_done_;
     236             :     bool is_chunked_;
     237             :     bool is_expect_continue_;
     238             : };
     239             : 
     240             : //------------------------------------------------
     241             : 
     242             : /** An algorithm for producing buffers of data.
     243             : 
     244             :     This interface abstracts the production of
     245             :     a finite stream of data, returned by writing
     246             :     into caller-provided buffers until there
     247             :     is no more output data.
     248             : 
     249             :     @par Thread Safety
     250             :     Non-const member functions may not be
     251             :     called concurrently on the same instance.
     252             : */
     253             : struct BOOST_HTTP_PROTO_DECL
     254             :     serializer::source
     255             :     : buffered_base
     256             : {
     257             :     /** The results of producing data.
     258             :     */
     259             :     struct results
     260             :     {
     261             :         /** The error, if any occurred.
     262             :         */
     263             :         system::error_code ec;
     264             : 
     265             :         /** The number of bytes produced in the output.
     266             :         */
     267             :         std::size_t bytes = 0;
     268             : 
     269             :         /** True if there will be no more output.
     270             :         */
     271             :         bool finished = false;
     272             : 
     273             :         /** Accumulate results.
     274             :         */
     275             :         results&
     276             :         operator+=(
     277             :             results const& rv) noexcept;
     278             :     };
     279             : 
     280             :     /** Produce data.
     281             : 
     282             :         This function attempts to read from the
     283             :         source, placing the data into the given
     284             :         mutable buffer sequence.
     285             :         The return value indicates the number of
     286             :         bytes placed into the buffers, the error
     287             :         if any occurred, and a `bool` indicating
     288             :         whether or not there is more data
     289             :         remaining in the source.
     290             : 
     291             :         @par Preconditions
     292             :         @li @ref init was called, and
     293             :         @li There is more data remaining.
     294             : 
     295             :         @return The result of the operation.
     296             : 
     297             :         @param bs The buffers to use.
     298             :             Each buffer in the sequence will
     299             :             be filled completely before data
     300             :             is placed in the next buffer.
     301             :     */
     302             :     template<class MutableBufferSequence>
     303             :     results
     304          24 :     read(MutableBufferSequence const& bs)
     305             :     {
     306             :         static_assert(
     307             :             buffers::is_mutable_buffer_sequence<
     308             :                 MutableBufferSequence>::value,
     309             :             "Type requirements not met");
     310             : 
     311          24 :         return read_impl(bs);
     312             :     }
     313             : 
     314             : #ifdef BOOST_HTTP_PROTO_DOCS
     315             : protected:
     316             : #else
     317             : private:
     318             : #endif
     319             :     /** Derived class override.
     320             : 
     321             :         This pure virtual function is called by
     322             :         the implementation and must be overriden.
     323             :         The callee should attempt to place data
     324             :         into the given mutable buffer.
     325             :         The return value must be set to indicate
     326             :         the number of bytes placed into the
     327             :         buffers, the error if any occurred,
     328             :         and a `bool` indicating whether or
     329             :         not there is more data remaining
     330             :         in the source.
     331             : 
     332             :         @par Preconditions
     333             :         @li @ref init was called, and
     334             :         @li There is more data remaining.
     335             : 
     336             :         @return The result of the operation.
     337             : 
     338             :         @param b The buffer to use.
     339             :             If this is not filled completely,
     340             :             then the result must indicate failure
     341             :             or that no more data remains (or both).
     342             :     */
     343             :     virtual
     344             :     results
     345             :     on_read(
     346             :         buffers::mutable_buffer b) = 0;
     347             : 
     348             :     /** Derived class override.
     349             : 
     350             :         This pure virtual function is called by
     351             :         the implementation and must be overriden.
     352             :         The callee should attempt to place data
     353             :         into the given mutable buffer sequence.
     354             :         The return value must be set to indicate
     355             :         the number of bytes placed into the
     356             :         buffers, the error if any occurred,
     357             :         and a `bool` indicating whether or
     358             :         not there is more data remaining
     359             :         in the source.
     360             : 
     361             :         @par Preconditions
     362             :         @li @ref init was called, and
     363             :         @li There is more data remaining.
     364             : 
     365             :         @return The result of the operation.
     366             : 
     367             :         @param bs The buffer sequence to use.
     368             :             Each buffer in the sequence must
     369             :             be filled completely before data
     370             :             is placed in the next buffer.
     371             :             If the buffers are not filled
     372             :             completely, then the result must
     373             :             indicate failure or that no more
     374             :             data remains (or both).
     375             :     */
     376             :     virtual
     377             :     results
     378             :     on_read(
     379             :         buffers::mutable_buffer_span bs);
     380             : 
     381             : private:
     382             :     results
     383           2 :     read_impl(
     384             :         buffers::mutable_buffer const& b)
     385             :     {
     386           2 :         return on_read(b);
     387             :     }
     388             : 
     389             :     results
     390           5 :     read_impl(
     391             :         buffers::mutable_buffer_span const& bs)
     392             :     {
     393           5 :         return on_read(bs);
     394             :     }
     395             : 
     396             :     template<class T>
     397             :     results
     398             :     read_impl(T const&);
     399             : };
     400             : 
     401             : //------------------------------------------------
     402             : 
     403             : struct serializer::stream
     404             : {
     405             :     /** Constructor.
     406             :     */
     407             :     stream() = default;
     408             : 
     409             :     /** Constructor.
     410             :     */
     411             :     stream(stream const&) = default;
     412             : 
     413             :     /** Constructor.
     414             :     */
     415             :     stream& operator=
     416             :         (stream const&) = default;
     417             : 
     418             :     using buffers_type =
     419             :         buffers::mutable_buffer_pair;
     420             : 
     421             :     BOOST_HTTP_PROTO_DECL
     422             :     std::size_t
     423             :     capacity() const;
     424             : 
     425             :     BOOST_HTTP_PROTO_DECL
     426             :     std::size_t
     427             :     size() const;
     428             : 
     429             :     BOOST_HTTP_PROTO_DECL
     430             :     buffers_type
     431             :     prepare(std::size_t n) const;
     432             : 
     433             :     BOOST_HTTP_PROTO_DECL
     434             :     void
     435             :     commit(std::size_t n) const;
     436             : 
     437             :     BOOST_HTTP_PROTO_DECL
     438             :     void
     439             :     close() const;
     440             : 
     441             : private:
     442             :     friend class serializer;
     443             : 
     444             :     explicit
     445           0 :     stream(
     446             :         serializer& sr) noexcept
     447           0 :         : sr_(&sr)
     448             :     {
     449           0 :     }
     450             : 
     451             :     serializer* sr_ = nullptr;
     452             : };
     453             : 
     454             : } // http_proto
     455             : } // boost
     456             : 
     457             : #include <boost/http_proto/impl/serializer.hpp>
     458             : 
     459             : #endif

Generated by: LCOV version 1.15