LCOV - code coverage report
Current view: top level - boost/http_proto - serializer.hpp (source / functions) Coverage Total Hit
Test: coverage_filtered.info Lines: 100.0 % 9 9
Test Date: 2025-12-22 14:47:57 Functions: 100.0 % 4 4

            Line data    Source code
       1              : //
       2              : // Copyright (c) 2019 Vinnie Falco (vinnie.falco@gmail.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/http_proto
       9              : //
      10              : 
      11              : #ifndef BOOST_HTTP_PROTO_SERIALIZER_HPP
      12              : #define BOOST_HTTP_PROTO_SERIALIZER_HPP
      13              : 
      14              : #include <boost/http_proto/detail/config.hpp>
      15              : #include <boost/http_proto/detail/workspace.hpp>
      16              : #include <boost/http_proto/source.hpp>
      17              : 
      18              : #include <boost/buffers/buffer_pair.hpp>
      19              : #include <boost/core/span.hpp>
      20              : #include <boost/capy/polystore_fwd.hpp>
      21              : #include <boost/system/result.hpp>
      22              : 
      23              : #include <type_traits>
      24              : #include <utility>
      25              : 
      26              : namespace boost {
      27              : namespace http_proto {
      28              : 
      29              : // Forward declaration
      30              : class message_base;
      31              : 
      32              : /** A serializer for HTTP/1 messages
      33              : 
      34              :     This is used to serialize one or more complete
      35              :     HTTP/1 messages. Each message consists of a
      36              :     required header followed by an optional body.
      37              : 
      38              :     Objects of this type operate using an "input area" and an
      39              :     "output area". Callers provide data to the input area
      40              :     using one of the @ref start or @ref start_stream member
      41              :     functions. After input is provided, serialized data
      42              :     becomes available in the serializer's output area in the
      43              :     form of a constant buffer sequence.
      44              : 
      45              :     Callers alternate between filling the input area and
      46              :     consuming the output area until all the input has been
      47              :     provided and all the output data has been consumed, or
      48              :     an error occurs.
      49              : 
      50              :     After calling @ref start, the caller must ensure that the
      51              :     contents of the associated message are not changed or
      52              :     destroyed until @ref is_done returns true, @ref reset is
      53              :     called, or the serializer is destroyed, otherwise the
      54              :     behavior is undefined.
      55              : */
      56              : class serializer
      57              : {
      58              : public:
      59              :     class stream;
      60              :     struct config;
      61              : 
      62              :     /** The type used to represent a sequence of
      63              :         constant buffers that refers to the output
      64              :         area.
      65              :     */
      66              :     using const_buffers_type =
      67              :         boost::span<buffers::const_buffer const>;
      68              : 
      69              :     /** Destructor
      70              :     */
      71              :     BOOST_HTTP_PROTO_DECL
      72              :     ~serializer();
      73              : 
      74              :     /** Constructor
      75              :         Default-constructed serializers do not reference any implementation;
      76              :         the only valid operations are destruction and assignment.
      77              :     */
      78            3 :     serializer() = default;
      79              : 
      80              :     /** Constructor.
      81              : 
      82              :         The states of `other` are transferred
      83              :         to the newly constructed object,
      84              :         which includes the allocated buffer.
      85              :         After construction, the only valid
      86              :         operations on the moved-from object
      87              :         are destruction and assignment.
      88              : 
      89              :         Buffer sequences previously obtained
      90              :         using @ref prepare or @ref stream::prepare
      91              :         remain valid.
      92              : 
      93              :         @par Postconditions
      94              :         @code
      95              :         other.is_done() == true
      96              :         @endcode
      97              : 
      98              :         @par Complexity
      99              :         Constant.
     100              : 
     101              :         @param other The serializer to move from.
     102              :     */
     103              :     BOOST_HTTP_PROTO_DECL
     104              :     serializer(
     105              :         serializer&& other) noexcept;
     106              : 
     107              :     /** Assignment.
     108              :         The states of `other` are transferred
     109              :         to this object, which includes the
     110              :         allocated buffer. After assignment,
     111              :         the only valid operations on the
     112              :         moved-from object are destruction and
     113              :         assignment.
     114              :         Buffer sequences previously obtained
     115              :         using @ref prepare or @ref stream::prepare
     116              :         remain valid.
     117              :         @par Complexity
     118              :         Constant.
     119              :         @param other The serializer to move from.
     120              :         @return A reference to this object.
     121              :     */
     122              :     BOOST_HTTP_PROTO_DECL
     123              :     serializer&
     124              :     operator=(serializer&& other) noexcept;
     125              : 
     126              :     /** Constructor.
     127              : 
     128              :         Constructs a serializer that uses the @ref
     129              :         config parameters installed on the
     130              :         provided `ctx`.
     131              : 
     132              :         The serializer will attempt to allocate
     133              :         the required space on startup, with the
     134              :         amount depending on the @ref config
     135              :         parameters, and will not perform any
     136              :         further allocations, except for Brotli
     137              :         encoder instances, if enabled.
     138              : 
     139              :         Depending on which compression algorithms
     140              :         are enabled in the @ref config, the
     141              :         serializer will attempt to access the
     142              :         corresponding encoder services on the same
     143              :         `ctx`.
     144              : 
     145              :         @par Example
     146              :         @code
     147              :         serializer sr(ctx);
     148              :         @endcode
     149              : 
     150              :         @par Postconditions
     151              :         @code
     152              :         this->is_done() == true
     153              :         @endcode
     154              : 
     155              :         @par Complexity
     156              :         Constant.
     157              : 
     158              :         @par Exception Safety
     159              :         Calls to allocate may throw.
     160              : 
     161              :         @param ctx Context from which the
     162              :         serializer will access registered
     163              :         services. The caller is responsible for
     164              :         ensuring that the provided ctx remains
     165              :         valid for the lifetime of the serializer.
     166              : 
     167              :         @see
     168              :             @ref install_serializer_service,
     169              :             @ref config.
     170              :     */
     171              :     BOOST_HTTP_PROTO_DECL
     172              :     explicit
     173              :     serializer(
     174              :         capy::polystore& ctx);
     175              : 
     176              :     /** Reset the serializer for a new message.
     177              : 
     178              :         Aborts any ongoing serialization and
     179              :         prepares the serializer to start
     180              :         serialization of a new message.
     181              :     */
     182              :     BOOST_HTTP_PROTO_DECL
     183              :     void
     184              :     reset() noexcept;
     185              : 
     186              :     /** Start serializing a message with an empty body
     187              : 
     188              :         This function prepares the serializer to create a message which
     189              :         has an empty body.
     190              :         Ownership of the specified message is not transferred; the caller is
     191              :         responsible for ensuring the lifetime of the object extends until the
     192              :         serializer is done.
     193              : 
     194              :         @par Preconditions
     195              :         @code
     196              :         this->is_done() == true
     197              :         @endcode
     198              : 
     199              :         @par Postconditions
     200              :         @code
     201              :         this->is_done() == false
     202              :         @endcode
     203              : 
     204              :         @par Exception Safety
     205              :         Strong guarantee.
     206              :         Exceptions thrown if there is insufficient internal buffer space
     207              :         to start the operation.
     208              : 
     209              :         @throw std::logic_error `this->is_done() == true`.
     210              : 
     211              :         @throw std::length_error if there is insufficient internal buffer
     212              :         space to start the operation.
     213              : 
     214              :         @param m The request or response headers to serialize.
     215              : 
     216              :         @see
     217              :             @ref message_base.
     218              :     */
     219              :     void
     220              :     BOOST_HTTP_PROTO_DECL
     221              :     start(message_base const& m);
     222              : 
     223              :     /** Start serializing a message with a buffer sequence body
     224              : 
     225              :         Initializes the serializer with the HTTP start-line and headers from `m`,
     226              :         and the provided `buffers` for reading the message body from.
     227              : 
     228              :         Changing the contents of the message after calling this function and
     229              :         before @ref is_done returns `true` results in undefined behavior.
     230              : 
     231              :         At least one copy of the specified buffer sequence is maintained until
     232              :         the serializer is done, gets reset, or ios destroyed, after which all
     233              :         of its copies are destroyed. Ownership of the underlying memory is not
     234              :         transferred; the caller must ensure the memory remains valid until the
     235              :         serializer’s copies are destroyed.
     236              : 
     237              :         @par Preconditions
     238              :         @code
     239              :         this->is_done() == true
     240              :         @endcode
     241              : 
     242              :         @par Postconditions
     243              :         @code
     244              :         this->is_done() == false
     245              :         @endcode
     246              : 
     247              :         @par Constraints
     248              :         @code
     249              :         buffers::is_const_buffer_sequence_v<ConstBufferSequence> == true
     250              :         @endcode
     251              : 
     252              :         @par Exception Safety
     253              :         Strong guarantee.
     254              :         Exceptions thrown if there is insufficient internal buffer space
     255              :         to start the operation.
     256              : 
     257              :         @throw std::logic_error `this->is_done() == true`.
     258              : 
     259              :         @throw std::length_error If there is insufficient internal buffer
     260              :         space to start the operation.
     261              : 
     262              :         @param m The message to read the HTTP start-line and headers from.
     263              : 
     264              :         @param buffers A buffer sequence containing the message body.
     265              : 
     266              :         containing the message body data. While
     267              :         the buffers object is copied, ownership of
     268              :         the underlying memory remains with the
     269              :         caller, who must ensure it stays valid
     270              :         until @ref is_done returns `true`.
     271              : 
     272              :         @see
     273              :             @ref message_base.
     274              :     */
     275              :     template<
     276              :         class ConstBufferSequence,
     277              :         class = typename std::enable_if<
     278              :             buffers::is_const_buffer_sequence<
     279              :                 ConstBufferSequence>::value>::type
     280              :     >
     281              :     void
     282              :     start(
     283              :         message_base const& m,
     284              :         ConstBufferSequence&& buffers);
     285              : 
     286              :     /** Start serializing a message with a @em Source body
     287              : 
     288              :         Initializes the serializer with the HTTP start-line and headers from
     289              :         `m`, and constructs a `Source` object to provide the message body.
     290              : 
     291              :         Changing the contents of the message
     292              :         after calling this function and before
     293              :         @ref is_done returns `true` results in
     294              :         undefined behavior.
     295              : 
     296              :         The serializer destroys Source object when:
     297              :         @li `this->is_done() == true`
     298              :         @li An unrecoverable serialization error occurs
     299              :         @li The serializer is destroyed
     300              : 
     301              :         @par Example
     302              :         @code
     303              :         file f("example.zip", file_mode::scan);
     304              :         response.set_payload_size(f.size());
     305              :         serializer.start<file_source>(response, std::move(f));
     306              :         @endcode
     307              : 
     308              :         @par Preconditions
     309              :         @code
     310              :         this->is_done() == true
     311              :         @endcode
     312              : 
     313              :         @par Postconditions
     314              :         @code
     315              :         this->is_done() == false
     316              :         @endcode
     317              : 
     318              :         @par Constraints
     319              :         @code
     320              :         is_source<Source>::value == true
     321              :         @endcode
     322              : 
     323              :         @par Exception Safety
     324              :         Strong guarantee.
     325              :         Exceptions thrown if there is insufficient
     326              :         internal buffer space to start the
     327              :         operation.
     328              : 
     329              :         @throw std::length_error if there is
     330              :         insufficient internal buffer space to
     331              :         start the operation.
     332              : 
     333              :         @param m The message to read the HTTP
     334              :         start-line and headers from.
     335              : 
     336              :         @param args Arguments to be passed to the
     337              :         `Source` constructor.
     338              : 
     339              :         @return A reference to the constructed Source object.
     340              : 
     341              :         @see
     342              :             @ref source,
     343              :             @ref file_source,
     344              :             @ref message_base.
     345              :     */
     346              :     template<
     347              :         class Source,
     348              :         class... Args,
     349              :         class = typename std::enable_if<
     350              :             is_source<Source>::value>::type>
     351              :     Source&
     352              :     start(
     353              :         message_base const& m,
     354              :         Args&&... args);
     355              : 
     356              :     /** Prepare the serializer for a new message using a stream interface.
     357              : 
     358              :         Initializes the serializer with the HTTP
     359              :         start-line and headers from `m`, and returns
     360              :         a @ref stream object for writing the body
     361              :         data into the serializer's internal buffer.
     362              : 
     363              :         Once the serializer is destroyed, @ref reset
     364              :         is called, or @ref is_done returns true, the
     365              :         only valid operation on the stream is destruction.
     366              : 
     367              :         The stream allows inverted control flow: the
     368              :         caller supplies body data to the serializer’s
     369              :         internal buffer while reading from an external
     370              :         source.
     371              : 
     372              :         Changing the contents of the message
     373              :         after calling this function and before
     374              :         @ref is_done returns `true` results in
     375              :         undefined behavior.
     376              : 
     377              :         @par Example
     378              :         @code
     379              :         serializer::stream st = serializer.start_stream(response);
     380              :         do
     381              :         {
     382              :             if(st.is_open())
     383              :             {
     384              :                 std::size_t n = source.read_some(st.prepare());
     385              : 
     386              :                 if(ec == error::eof)
     387              :                     st.close();
     388              :                 else
     389              :                     st.commit(n);
     390              :             }
     391              : 
     392              :             write_some(client, serializer);
     393              : 
     394              :         } while(!serializer.is_done());
     395              :         @endcode
     396              : 
     397              :         @par Preconditions
     398              :         @code
     399              :         this->is_done() == true
     400              :         @endcode
     401              : 
     402              :         @par Postconditions
     403              :         @code
     404              :         this->is_done() == false
     405              :         @endcode
     406              : 
     407              :         @par Exception Safety
     408              :         Strong guarantee.
     409              :         Exceptions thrown if there is insufficient
     410              :         internal buffer space to start the
     411              :         operation.
     412              : 
     413              :         @throw std::length_error if there is
     414              :         insufficient internal buffer space to
     415              :         start the operation.
     416              : 
     417              :         @param m The message to read the HTTP
     418              :         start-line and headers from.
     419              : 
     420              :         @return A @ref stream object for writing the body
     421              :         data into the serializer's internal buffer.
     422              : 
     423              :         @see
     424              :             @ref stream,
     425              :             @ref message_base.
     426              :      */
     427              :     BOOST_HTTP_PROTO_DECL
     428              :     stream
     429              :     start_stream(
     430              :         message_base const& m);
     431              : 
     432              :     /** Return the output area.
     433              : 
     434              :         This function serializes some or all of
     435              :         the message and returns the corresponding
     436              :         output buffers. Afterward, a call to @ref
     437              :         consume is required to report the number
     438              :         of bytes used, if any.
     439              : 
     440              :         If the message includes an
     441              :         `Expect: 100-continue` header and the
     442              :         header section of the message has been
     443              :         consumed, the returned result will contain
     444              :         @ref error::expect_100_continue to
     445              :         indicate that the header part of the
     446              :         message is complete. The next call to @ref
     447              :         prepare will produce output.
     448              : 
     449              :         When the serializer is used through the
     450              :         @ref stream interface, the result may
     451              :         contain @ref error::need_data to indicate
     452              :         that additional input is required to
     453              :         produce output.
     454              : 
     455              :         If a @ref source object is in use and a
     456              :         call to @ref source::read returns an
     457              :         error, the serializer enters a faulted
     458              :         state and propagates the error to the
     459              :         caller. This faulted state can only be
     460              :         cleared by calling @ref reset. This
     461              :         ensures the caller is explicitly aware
     462              :         that the previous message was truncated
     463              :         and that the stream must be terminated.
     464              : 
     465              :         @par Preconditions
     466              :         @code
     467              :         this->is_done() == false
     468              :         @endcode
     469              :         No unrecoverable error reported from previous calls.
     470              : 
     471              :         @par Exception Safety
     472              :         Strong guarantee.
     473              :         Calls to @ref source::read may throw if in use.
     474              : 
     475              :         @throw std::logic_error
     476              :         `this->is_done() == true`.
     477              : 
     478              :         @return A result containing @ref
     479              :         const_buffers_type that represents the
     480              :         output area or an error if any occurred.
     481              : 
     482              :         @see
     483              :             @ref consume,
     484              :             @ref is_done,
     485              :             @ref const_buffers_type.
     486              :     */
     487              :     BOOST_HTTP_PROTO_DECL
     488              :     auto
     489              :     prepare() ->
     490              :         system::result<
     491              :             const_buffers_type>;
     492              : 
     493              :     /** Consume bytes from the output area.
     494              : 
     495              :         This function should be called after one
     496              :         or more bytes contained in the buffers
     497              :         provided in the prior call to @ref prepare
     498              :         have been used.
     499              : 
     500              :         After a call to @ref consume, callers
     501              :         should check the return value of @ref
     502              :         is_done to determine if the entire message
     503              :         has been serialized.
     504              : 
     505              :         @par Preconditions
     506              :         @code
     507              :         this->is_done() == false
     508              :         @endcode
     509              : 
     510              :         @par Exception Safety
     511              :         Strong guarantee.
     512              : 
     513              :         @throw std::logic_error
     514              :         `this->is_done() == true`.
     515              : 
     516              :         @param n The number of bytes to consume.
     517              :         If `n` is greater than the size of the
     518              :         buffer returned from @ref prepared the
     519              :         entire output sequence is consumed and no
     520              :         error is issued.
     521              : 
     522              :         @see
     523              :             @ref prepare,
     524              :             @ref is_done,
     525              :             @ref const_buffers_type.
     526              :     */
     527              :     BOOST_HTTP_PROTO_DECL
     528              :     void
     529              :     consume(std::size_t n);
     530              : 
     531              :     /** Return true if serialization is complete.
     532              :     */
     533              :     BOOST_HTTP_PROTO_DECL
     534              :     bool
     535              :     is_done() const noexcept;
     536              : 
     537              :     /** Return true if headers have been set.
     538              : 
     539              :         Returns `true` if @ref set_headers has been
     540              :         called and no @ref start or @ref start_stream
     541              :         function has been called since. This indicates
     542              :         that the serializer is ready to begin
     543              :         serialization with a body style.
     544              : 
     545              :         @see
     546              :             @ref set_headers,
     547              :             @ref is_done.
     548              :     */
     549              :     BOOST_HTTP_PROTO_DECL
     550              :     bool
     551              :     is_headers_set() const noexcept;
     552              : 
     553              :     /** Set the message headers for serialization.
     554              : 
     555              :         This function prepares the serializer with the
     556              :         HTTP start-line and headers from `m`. After
     557              :         calling this function, one of the @ref start
     558              :         or @ref start_stream overloads that do not
     559              :         take a message parameter must be called to
     560              :         begin serialization.
     561              : 
     562              :         Changing the contents of the message after
     563              :         calling this function and before @ref is_done
     564              :         returns `true` results in undefined behavior.
     565              : 
     566              :         @par Preconditions
     567              :         @code
     568              :         this->is_done() == true
     569              :         @endcode
     570              : 
     571              :         @par Exception Safety
     572              :         Strong guarantee.
     573              : 
     574              :         @throw std::logic_error `this->is_done() == false`.
     575              : 
     576              :         @param m The request or response headers to serialize.
     577              : 
     578              :         @see
     579              :             @ref message_base.
     580              :     */
     581              :     BOOST_HTTP_PROTO_DECL
     582              :     void
     583              :     set_headers(message_base const& m);
     584              : 
     585              :     /** Start serializing a message with an empty body.
     586              : 
     587              :         This overload requires @ref set_headers to have
     588              :         been called first.
     589              : 
     590              :         @par Preconditions
     591              :         @ref set_headers has been called and no @ref start
     592              :         or @ref start_stream function has been called since.
     593              : 
     594              :         @par Postconditions
     595              :         @code
     596              :         this->is_done() == false
     597              :         @endcode
     598              : 
     599              :         @par Exception Safety
     600              :         Strong guarantee.
     601              : 
     602              :         @throw std::logic_error if @ref set_headers was not called.
     603              : 
     604              :         @throw std::length_error if there is insufficient internal buffer
     605              :         space to start the operation.
     606              : 
     607              :         @see
     608              :             @ref set_headers.
     609              :     */
     610              :     BOOST_HTTP_PROTO_DECL
     611              :     void
     612              :     start();
     613              : 
     614              :     /** Start serializing a message with a buffer sequence body.
     615              : 
     616              :         This overload requires @ref set_headers to have
     617              :         been called first.
     618              : 
     619              :         At least one copy of the specified buffer sequence is maintained until
     620              :         the serializer is done, gets reset, or is destroyed, after which all
     621              :         of its copies are destroyed. Ownership of the underlying memory is not
     622              :         transferred; the caller must ensure the memory remains valid until the
     623              :         serializer's copies are destroyed.
     624              : 
     625              :         @par Preconditions
     626              :         @ref set_headers has been called and no @ref start
     627              :         or @ref start_stream function has been called since.
     628              : 
     629              :         @par Postconditions
     630              :         @code
     631              :         this->is_done() == false
     632              :         @endcode
     633              : 
     634              :         @par Constraints
     635              :         @code
     636              :         buffers::is_const_buffer_sequence_v<ConstBufferSequence> == true
     637              :         @endcode
     638              : 
     639              :         @par Exception Safety
     640              :         Strong guarantee.
     641              : 
     642              :         @throw std::logic_error if @ref set_headers was not called.
     643              : 
     644              :         @throw std::length_error If there is insufficient internal buffer
     645              :         space to start the operation.
     646              : 
     647              :         @param buffers A buffer sequence containing the message body.
     648              : 
     649              :         @see
     650              :             @ref set_headers.
     651              :     */
     652              :     template<
     653              :         class ConstBufferSequence,
     654              :         class = typename std::enable_if<
     655              :             buffers::is_const_buffer_sequence<
     656              :                 ConstBufferSequence>::value>::type
     657              :     >
     658              :     void
     659              :     start(
     660              :         ConstBufferSequence&& buffers);
     661              : 
     662              :     /** Start serializing a message with a @em Source body.
     663              : 
     664              :         This overload requires @ref set_headers to have
     665              :         been called first.
     666              : 
     667              :         The serializer destroys the Source object when:
     668              :         @li `this->is_done() == true`
     669              :         @li An unrecoverable serialization error occurs
     670              :         @li The serializer is destroyed
     671              : 
     672              :         @par Example
     673              :         @code
     674              :         file f("example.zip", file_mode::scan);
     675              :         response.set_payload_size(f.size());
     676              :         serializer.set_headers(response);
     677              :         serializer.start<file_source>(std::move(f));
     678              :         @endcode
     679              : 
     680              :         @par Preconditions
     681              :         @ref set_headers has been called and no @ref start
     682              :         or @ref start_stream function has been called since.
     683              : 
     684              :         @par Postconditions
     685              :         @code
     686              :         this->is_done() == false
     687              :         @endcode
     688              : 
     689              :         @par Constraints
     690              :         @code
     691              :         is_source<Source>::value == true
     692              :         @endcode
     693              : 
     694              :         @par Exception Safety
     695              :         Strong guarantee.
     696              : 
     697              :         @throw std::logic_error if @ref set_headers was not called.
     698              : 
     699              :         @throw std::length_error if there is insufficient
     700              :         internal buffer space to start the operation.
     701              : 
     702              :         @param args Arguments to be passed to the
     703              :         `Source` constructor.
     704              : 
     705              :         @return A reference to the constructed Source object.
     706              : 
     707              :         @see
     708              :             @ref set_headers,
     709              :             @ref source,
     710              :             @ref file_source.
     711              :     */
     712              :     template<
     713              :         class Source,
     714              :         class Arg0,
     715              :         class... Args,
     716              :         class = typename std::enable_if<
     717              :             is_source<Source>::value &&
     718              :             !std::is_convertible<
     719              :                 Arg0,
     720              :                 message_base const&>::value>::type>
     721              :     Source&
     722              :     start(Arg0&& arg0, Args&&... args);
     723              : 
     724              :     /** Start serializing a message with a @em Source body.
     725              : 
     726              :         This overload requires @ref set_headers to have
     727              :         been called first. This version takes no arguments
     728              :         and default-constructs the Source.
     729              : 
     730              :         @par Preconditions
     731              :         @ref set_headers has been called and no @ref start
     732              :         or @ref start_stream function has been called since.
     733              : 
     734              :         @par Postconditions
     735              :         @code
     736              :         this->is_done() == false
     737              :         @endcode
     738              : 
     739              :         @par Constraints
     740              :         @code
     741              :         is_source<Source>::value == true
     742              :         @endcode
     743              : 
     744              :         @par Exception Safety
     745              :         Strong guarantee.
     746              : 
     747              :         @throw std::logic_error if @ref set_headers was not called.
     748              : 
     749              :         @throw std::length_error if there is insufficient
     750              :         internal buffer space to start the operation.
     751              : 
     752              :         @return A reference to the constructed Source object.
     753              : 
     754              :         @see
     755              :             @ref set_headers,
     756              :             @ref source.
     757              :     */
     758              :     template<
     759              :         class Source,
     760              :         class = typename std::enable_if<
     761              :             is_source<Source>::value>::type>
     762              :     Source&
     763              :     start();
     764              : 
     765              :     /** Start serializing a message using a stream interface.
     766              : 
     767              :         This overload requires @ref set_headers to have
     768              :         been called first.
     769              : 
     770              :         Returns a @ref stream object for writing the body
     771              :         data into the serializer's internal buffer.
     772              : 
     773              :         Once the serializer is destroyed, @ref reset
     774              :         is called, or @ref is_done returns true, the
     775              :         only valid operation on the stream is destruction.
     776              : 
     777              :         @par Example
     778              :         @code
     779              :         serializer.set_headers(response);
     780              :         serializer::stream st = serializer.start_stream();
     781              :         do
     782              :         {
     783              :             if(st.is_open())
     784              :             {
     785              :                 std::size_t n = source.read_some(st.prepare());
     786              : 
     787              :                 if(ec == error::eof)
     788              :                     st.close();
     789              :                 else
     790              :                     st.commit(n);
     791              :             }
     792              : 
     793              :             write_some(client, serializer);
     794              : 
     795              :         } while(!serializer.is_done());
     796              :         @endcode
     797              : 
     798              :         @par Preconditions
     799              :         @ref set_headers has been called and no @ref start
     800              :         or @ref start_stream function has been called since.
     801              : 
     802              :         @par Postconditions
     803              :         @code
     804              :         this->is_done() == false
     805              :         @endcode
     806              : 
     807              :         @par Exception Safety
     808              :         Strong guarantee.
     809              : 
     810              :         @throw std::logic_error if @ref set_headers was not called.
     811              : 
     812              :         @throw std::length_error if there is insufficient
     813              :         internal buffer space to start the operation.
     814              : 
     815              :         @return A @ref stream object for writing the body
     816              :         data into the serializer's internal buffer.
     817              : 
     818              :         @see
     819              :             @ref set_headers,
     820              :             @ref stream.
     821              :      */
     822              :     BOOST_HTTP_PROTO_DECL
     823              :     stream
     824              :     start_stream();
     825              : 
     826              : private:
     827              :     class impl;
     828              :     class cbs_gen;
     829              :     template<class>
     830              :     class cbs_gen_impl;
     831              : 
     832              :     BOOST_HTTP_PROTO_DECL
     833              :     detail::workspace&
     834              :     ws();
     835              : 
     836              :     BOOST_HTTP_PROTO_DECL
     837              :     void
     838              :     start_buffers_impl(
     839              :         cbs_gen&);
     840              : 
     841              :     BOOST_HTTP_PROTO_DECL
     842              :     void
     843              :     start_source_impl(
     844              :         source&);
     845              : 
     846              :     impl* impl_ = nullptr;
     847              : };
     848              : 
     849              : /** Serializer configuration settings.
     850              : 
     851              :     @see
     852              :         @ref install_serializer_service,
     853              :         @ref serializer.
     854              : */
     855              : struct serializer::config
     856              : {
     857              :     /** Enable Brotli Content-Encoding.
     858              : 
     859              :         Requires `boost::capy::brotli::encode_service` to be
     860              :         installed, otherwise an exception is thrown.
     861              :     */
     862              :     bool apply_brotli_encoder = false;
     863              : 
     864              :     /** Enable Deflate Content-Encoding.
     865              : 
     866              :         Requires `boost::zlib::deflate_service` to be
     867              :         installed, otherwise an exception is thrown.
     868              :     */
     869              :     bool apply_deflate_encoder = false;
     870              : 
     871              :     /** Enable Gzip Content-Encoding.
     872              : 
     873              :         Requires `boost::zlib::deflate_service` to be
     874              :         installed, otherwise an exception is thrown.
     875              :     */
     876              :     bool apply_gzip_encoder = false;
     877              : 
     878              :     /** Brotli compression quality (0–11).
     879              : 
     880              :         Higher values yield better but slower compression.
     881              :     */
     882              :     std::uint32_t brotli_comp_quality = 5;
     883              : 
     884              :     /** Brotli compression window size (10–24).
     885              : 
     886              :         Larger windows improve compression but increase
     887              :         memory usage.
     888              :     */
     889              :     std::uint32_t brotli_comp_window = 18;
     890              : 
     891              :     /** Zlib compression level (0–9).
     892              : 
     893              :         0 = no compression, 1 = fastest, 9 = best
     894              :         compression.
     895              :     */
     896              :     int zlib_comp_level = 6;
     897              : 
     898              :     /** Zlib window bits (9–15).
     899              : 
     900              :         Controls the history buffer size. Larger values
     901              :         improve compression but use more memory.
     902              :     */
     903              :     int zlib_window_bits = 15;
     904              : 
     905              :     /** Zlib memory level (1–9).
     906              : 
     907              :         Higher values use more memory, but offer faster
     908              :         and more efficient compression.
     909              :     */
     910              :     int zlib_mem_level = 8;
     911              : 
     912              :     /** Minimum buffer size for payloads (must be > 0). */
     913              :     std::size_t payload_buffer = 8192;
     914              : 
     915              :     /** Reserved space for type-erasure storage.
     916              : 
     917              :         Used for:
     918              :         @li User-defined @ref source objects.
     919              :         @li User-defined ConstBufferSequence instances.
     920              :     */
     921              :     std::size_t max_type_erase = 1024;
     922              : };
     923              : 
     924              : /** Install the serializer service.
     925              : 
     926              :     @par Example
     927              :     @code
     928              :     // default configuration settings
     929              :     install_serializer_service(ctx, {});
     930              : 
     931              :     serializer sr(ctx);
     932              :     @endcode
     933              : 
     934              :     @par Exception Safety
     935              :     Strong guarantee.
     936              : 
     937              :     @throw std::invalid_argument If the service is
     938              :     already installed on the context.
     939              : 
     940              :     @param ctx Reference to the context on which
     941              :     the service should be installed.
     942              : 
     943              :     @param cfg Configuration settings for the
     944              :     serializer.
     945              : 
     946              :     @see
     947              :         @ref serializer::config,
     948              :         @ref serializer.
     949              : */
     950              : BOOST_HTTP_PROTO_DECL
     951              : void
     952              : install_serializer_service(
     953              :     capy::polystore& ctx,
     954              :     serializer::config const& cfg);
     955              : 
     956              : //------------------------------------------------
     957              : 
     958              : /** Used for streaming body data during serialization.
     959              : 
     960              :     Provides an interface for supplying serialized
     961              :     body content from an external source. This
     962              :     object is returned by @ref
     963              :     serializer::start_stream and enables
     964              :     incremental writing of the message body into
     965              :     the serializer's internal buffer.
     966              : 
     967              :     The stream supports an inverted control flow
     968              :     model, where the caller pushes body data as
     969              :     needed.
     970              : 
     971              :     Valid operations depend on the state of the
     972              :     serializer. Once the serializer is destroyed,
     973              :     reset, or completes, the stream becomes
     974              :     invalid and must only be destroyed.
     975              : 
     976              :     @see
     977              :         @ref serializer::start_stream
     978              : */
     979              : class serializer::stream
     980              : {
     981              : public:
     982              :     /** The type used to represent a sequence
     983              :         of mutable buffers.
     984              :     */
     985              :     using mutable_buffers_type =
     986              :         buffers::mutable_buffer_pair;
     987              : 
     988              :     /** Constructor.
     989              : 
     990              :         A default-constructed stream is
     991              :         considered closed.
     992              : 
     993              :         @par Postconditions
     994              :         @code
     995              :         this->is_open() == false
     996              :         @endcode
     997              :     */
     998              :     stream() noexcept = default;
     999              : 
    1000              :     /** Constructor.
    1001              : 
    1002              :         After construction, the moved-from
    1003              :         object is as if default-constructed.
    1004              : 
    1005              :         @par Postconditions
    1006              :         @code
    1007              :         other->is_open() == false
    1008              :         @endcode
    1009              : 
    1010              :         @param other The object to move from.
    1011              :     */
    1012              :     stream(stream&& other) noexcept
    1013              :         : impl_(other.impl_)
    1014              :     {
    1015              :         other.impl_ = nullptr;
    1016              :     }
    1017              : 
    1018              :     /** Move assignment.
    1019              : 
    1020              :         After assignment, the moved-from
    1021              :         object is as if default-constructed.
    1022              : 
    1023              :         @par Postconditions
    1024              :         @code
    1025              :         other->is_open() == false
    1026              :         @endcode
    1027              : 
    1028              :         @param other The object to assign from.
    1029              :         @return A reference to this object.
    1030              :     */
    1031              :     stream&
    1032              :     operator=(stream&& other) noexcept
    1033              :     {
    1034              :         std::swap(impl_, other.impl_);
    1035              :         return *this;
    1036              :     }
    1037              : 
    1038              :     /** Return true if the stream is open.
    1039              :     */
    1040              :     bool
    1041         5062 :     is_open() const noexcept
    1042              :     {
    1043         5062 :         return impl_ != nullptr;
    1044              :     }
    1045              : 
    1046              :     /** Return the available capacity.
    1047              : 
    1048              :         @par Preconditions
    1049              :         @code
    1050              :         this->is_open() == true
    1051              :         @endcode
    1052              : 
    1053              :         @par Exception Safety
    1054              :         Strong guarantee.
    1055              : 
    1056              :         @throw std::logic_error
    1057              :         `this->is_open() == false`.
    1058              :     */
    1059              :     BOOST_HTTP_PROTO_DECL
    1060              :     std::size_t
    1061              :     capacity() const;
    1062              : 
    1063              :     /** Prepare a buffer for writing.
    1064              : 
    1065              :         Retuns a mutable buffer sequence representing
    1066              :         the writable bytes. Use @ref commit to make the
    1067              :         written data available to the serializer.
    1068              : 
    1069              :         All buffer sequences previously obtained
    1070              :         using @ref prepare are invalidated.
    1071              : 
    1072              :         @par Preconditions
    1073              :         @code
    1074              :         this->is_open() == true && n <= this->capacity()
    1075              :         @endcode
    1076              : 
    1077              :         @par Exception Safety
    1078              :         Strong guarantee.
    1079              : 
    1080              :         @return An instance of @ref mutable_buffers_type
    1081              :         the underlying memory is owned by the serializer.
    1082              : 
    1083              :         @throw std::logic_error
    1084              :         `this->is_open() == false`
    1085              : 
    1086              :         @see
    1087              :             @ref commit,
    1088              :             @ref capacity.
    1089              :     */
    1090              :     BOOST_HTTP_PROTO_DECL
    1091              :     mutable_buffers_type
    1092              :     prepare();
    1093              : 
    1094              :     /** Commit data to the serializer.
    1095              : 
    1096              :         Makes `n` bytes available to the serializer.
    1097              : 
    1098              :         All buffer sequences previously obtained
    1099              :         using @ref prepare are invalidated.
    1100              : 
    1101              :         @par Preconditions
    1102              :         @code
    1103              :         this->is_open() == true && n <= this->capacity()
    1104              :         @endcode
    1105              : 
    1106              :         @par Exception Safety
    1107              :         Strong guarantee.
    1108              :         Exceptions thrown on invalid input.
    1109              : 
    1110              :         @param n The number of bytes to append.
    1111              : 
    1112              :         @throw std::invalid_argument
    1113              :         `n > this->capacity()`
    1114              : 
    1115              :         @throw std::logic_error
    1116              :         `this->is_open() == false`
    1117              : 
    1118              :         @see
    1119              :             @ref prepare,
    1120              :             @ref capacity.
    1121              :     */
    1122              :     BOOST_HTTP_PROTO_DECL
    1123              :     void
    1124              :     commit(std::size_t n);
    1125              : 
    1126              :     /** Close the stream if open.
    1127              : 
    1128              :         Closes the stream and
    1129              :         notifies the serializer that the
    1130              :         message body has ended.
    1131              : 
    1132              :         If the stream is already closed this
    1133              :         call has no effect.
    1134              : 
    1135              :         @par Postconditions
    1136              :         @code
    1137              :         this->is_open() == false
    1138              :         @endcode
    1139              :     */
    1140              :     BOOST_HTTP_PROTO_DECL
    1141              :     void
    1142              :     close() noexcept;
    1143              : 
    1144              :     /** Destructor.
    1145              : 
    1146              :         Closes the stream if open.
    1147              :     */
    1148           24 :     ~stream()
    1149              :     {
    1150           24 :         close();
    1151           24 :     }
    1152              : 
    1153              : private:
    1154              :     friend class serializer;
    1155              : 
    1156              :     explicit
    1157           23 :     stream(serializer::impl* impl) noexcept
    1158           23 :         : impl_(impl)
    1159              :     {
    1160           23 :     }
    1161              : 
    1162              :     serializer::impl* impl_ = nullptr;
    1163              : };
    1164              : 
    1165              : } // http_proto
    1166              : } // boost
    1167              : 
    1168              : #include <boost/http_proto/impl/serializer.hpp>
    1169              : 
    1170              : #endif
        

Generated by: LCOV version 2.1