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-05 19:49:25 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 BOOST_HTTP_PROTO_DECL 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              :         ~serializer();
      72              : 
      73              :     /** Constructor
      74              :         Default-constructed serializers do not reference any implementation;
      75              :         the only valid operations are destruction and assignment.
      76              :     */
      77            3 :     serializer() = default;
      78              : 
      79              :     /** Constructor.
      80              : 
      81              :         The states of `other` are transferred
      82              :         to the newly constructed object,
      83              :         which includes the allocated buffer.
      84              :         After construction, the only valid
      85              :         operations on the moved-from object
      86              :         are destruction and assignment.
      87              : 
      88              :         Buffer sequences previously obtained
      89              :         using @ref prepare or @ref stream::prepare
      90              :         remain valid.
      91              : 
      92              :         @par Postconditions
      93              :         @code
      94              :         other.is_done() == true
      95              :         @endcode
      96              : 
      97              :         @par Complexity
      98              :         Constant.
      99              : 
     100              :         @param other The serializer to move from.
     101              :     */
     102              :         serializer(
     103              :         serializer&& other) noexcept;
     104              : 
     105              :     /** Assignment.
     106              :         The states of `other` are transferred
     107              :         to this object, which includes the
     108              :         allocated buffer. After assignment,
     109              :         the only valid operations on the
     110              :         moved-from object are destruction and
     111              :         assignment.
     112              :         Buffer sequences previously obtained
     113              :         using @ref prepare or @ref stream::prepare
     114              :         remain valid.
     115              :         @par Complexity
     116              :         Constant.
     117              :         @param other The serializer to move from.
     118              :         @return A reference to this object.
     119              :     */
     120              :     
     121              :     serializer&
     122              :     operator=(serializer&& other) noexcept;
     123              : 
     124              :     /** Constructor.
     125              : 
     126              :         Constructs a serializer that uses the @ref
     127              :         config parameters installed on the
     128              :         provided `ctx`.
     129              : 
     130              :         The serializer will attempt to allocate
     131              :         the required space on startup, with the
     132              :         amount depending on the @ref config
     133              :         parameters, and will not perform any
     134              :         further allocations, except for Brotli
     135              :         encoder instances, if enabled.
     136              : 
     137              :         Depending on which compression algorithms
     138              :         are enabled in the @ref config, the
     139              :         serializer will attempt to access the
     140              :         corresponding encoder services on the same
     141              :         `ctx`.
     142              : 
     143              :         @par Example
     144              :         @code
     145              :         serializer sr(ctx);
     146              :         @endcode
     147              : 
     148              :         @par Postconditions
     149              :         @code
     150              :         this->is_done() == true
     151              :         @endcode
     152              : 
     153              :         @par Complexity
     154              :         Constant.
     155              : 
     156              :         @par Exception Safety
     157              :         Calls to allocate may throw.
     158              : 
     159              :         @param ctx Context from which the
     160              :         serializer will access registered
     161              :         services. The caller is responsible for
     162              :         ensuring that the provided ctx remains
     163              :         valid for the lifetime of the serializer.
     164              : 
     165              :         @see
     166              :             @ref install_serializer_service,
     167              :             @ref config.
     168              :     */
     169              :     
     170              :     explicit
     171              :     serializer(
     172              :         capy::polystore& ctx);
     173              : 
     174              :     /** Reset the serializer for a new message.
     175              : 
     176              :         Aborts any ongoing serialization and
     177              :         prepares the serializer to start
     178              :         serialization of a new message.
     179              :     */
     180              :     
     181              :     void
     182              :     reset() noexcept;
     183              : 
     184              :     /** Start serializing a message with an empty body
     185              : 
     186              :         This function prepares the serializer to create a message which
     187              :         has an empty body.
     188              :         Ownership of the specified message is not transferred; the caller is
     189              :         responsible for ensuring the lifetime of the object extends until the
     190              :         serializer is done.
     191              : 
     192              :         @par Preconditions
     193              :         @code
     194              :         this->is_done() == true
     195              :         @endcode
     196              : 
     197              :         @par Postconditions
     198              :         @code
     199              :         this->is_done() == false
     200              :         @endcode
     201              : 
     202              :         @par Exception Safety
     203              :         Strong guarantee.
     204              :         Exceptions thrown if there is insufficient internal buffer space
     205              :         to start the operation.
     206              : 
     207              :         @throw std::logic_error `this->is_done() == true`.
     208              : 
     209              :         @throw std::length_error if there is insufficient internal buffer
     210              :         space to start the operation.
     211              : 
     212              :         @param m The request or response headers to serialize.
     213              : 
     214              :         @see
     215              :             @ref message_base.
     216              :     */
     217              :     void
     218              :     
     219              :     start(message_base const& m);
     220              : 
     221              :     /** Start serializing a message with a buffer sequence body
     222              : 
     223              :         Initializes the serializer with the HTTP start-line and headers from `m`,
     224              :         and the provided `buffers` for reading the message body from.
     225              : 
     226              :         Changing the contents of the message after calling this function and
     227              :         before @ref is_done returns `true` results in undefined behavior.
     228              : 
     229              :         At least one copy of the specified buffer sequence is maintained until
     230              :         the serializer is done, gets reset, or ios destroyed, after which all
     231              :         of its copies are destroyed. Ownership of the underlying memory is not
     232              :         transferred; the caller must ensure the memory remains valid until the
     233              :         serializer’s copies are destroyed.
     234              : 
     235              :         @par Preconditions
     236              :         @code
     237              :         this->is_done() == true
     238              :         @endcode
     239              : 
     240              :         @par Postconditions
     241              :         @code
     242              :         this->is_done() == false
     243              :         @endcode
     244              : 
     245              :         @par Constraints
     246              :         @code
     247              :         buffers::is_const_buffer_sequence_v<ConstBufferSequence> == true
     248              :         @endcode
     249              : 
     250              :         @par Exception Safety
     251              :         Strong guarantee.
     252              :         Exceptions thrown if there is insufficient internal buffer space
     253              :         to start the operation.
     254              : 
     255              :         @throw std::logic_error `this->is_done() == true`.
     256              : 
     257              :         @throw std::length_error If there is insufficient internal buffer
     258              :         space to start the operation.
     259              : 
     260              :         @param m The message to read the HTTP start-line and headers from.
     261              : 
     262              :         @param buffers A buffer sequence containing the message body.
     263              : 
     264              :         containing the message body data. While
     265              :         the buffers object is copied, ownership of
     266              :         the underlying memory remains with the
     267              :         caller, who must ensure it stays valid
     268              :         until @ref is_done returns `true`.
     269              : 
     270              :         @see
     271              :             @ref message_base.
     272              :     */
     273              :     template<
     274              :         class ConstBufferSequence,
     275              :         class = typename std::enable_if<
     276              :             buffers::is_const_buffer_sequence<
     277              :                 ConstBufferSequence>::value>::type
     278              :     >
     279              :     void
     280              :     start(
     281              :         message_base const& m,
     282              :         ConstBufferSequence&& buffers);
     283              : 
     284              :     /** Start serializing a message with a @em Source body
     285              : 
     286              :         Initializes the serializer with the HTTP start-line and headers from
     287              :         `m`, and constructs a `Source` object to provide the message body.
     288              : 
     289              :         Changing the contents of the message
     290              :         after calling this function and before
     291              :         @ref is_done returns `true` results in
     292              :         undefined behavior.
     293              : 
     294              :         The serializer destroys Source object when:
     295              :         @li `this->is_done() == true`
     296              :         @li An unrecoverable serialization error occurs
     297              :         @li The serializer is destroyed
     298              : 
     299              :         @par Example
     300              :         @code
     301              :         file f("example.zip", file_mode::scan);
     302              :         response.set_payload_size(f.size());
     303              :         serializer.start<file_source>(response, std::move(f));
     304              :         @endcode
     305              : 
     306              :         @par Preconditions
     307              :         @code
     308              :         this->is_done() == true
     309              :         @endcode
     310              : 
     311              :         @par Postconditions
     312              :         @code
     313              :         this->is_done() == false
     314              :         @endcode
     315              : 
     316              :         @par Constraints
     317              :         @code
     318              :         is_source<Source>::value == true
     319              :         @endcode
     320              : 
     321              :         @par Exception Safety
     322              :         Strong guarantee.
     323              :         Exceptions thrown if there is insufficient
     324              :         internal buffer space to start the
     325              :         operation.
     326              : 
     327              :         @throw std::length_error if there is
     328              :         insufficient internal buffer space to
     329              :         start the operation.
     330              : 
     331              :         @param m The message to read the HTTP
     332              :         start-line and headers from.
     333              : 
     334              :         @param args Arguments to be passed to the
     335              :         `Source` constructor.
     336              : 
     337              :         @return A reference to the constructed Source object.
     338              : 
     339              :         @see
     340              :             @ref source,
     341              :             @ref file_source,
     342              :             @ref message_base.
     343              :     */
     344              :     template<
     345              :         class Source,
     346              :         class... Args,
     347              :         class = typename std::enable_if<
     348              :             is_source<Source>::value>::type>
     349              :     Source&
     350              :     start(
     351              :         message_base const& m,
     352              :         Args&&... args);
     353              : 
     354              :     /** Prepare the serializer for a new message using a stream interface.
     355              : 
     356              :         Initializes the serializer with the HTTP
     357              :         start-line and headers from `m`, and returns
     358              :         a @ref stream object for writing the body
     359              :         data into the serializer's internal buffer.
     360              : 
     361              :         Once the serializer is destroyed, @ref reset
     362              :         is called, or @ref is_done returns true, the
     363              :         only valid operation on the stream is destruction.
     364              : 
     365              :         The stream allows inverted control flow: the
     366              :         caller supplies body data to the serializer’s
     367              :         internal buffer while reading from an external
     368              :         source.
     369              : 
     370              :         Changing the contents of the message
     371              :         after calling this function and before
     372              :         @ref is_done returns `true` results in
     373              :         undefined behavior.
     374              : 
     375              :         @par Example
     376              :         @code
     377              :         serializer::stream st = serializer.start_stream(response);
     378              :         do
     379              :         {
     380              :             if(st.is_open())
     381              :             {
     382              :                 std::size_t n = source.read_some(st.prepare());
     383              : 
     384              :                 if(ec == error::eof)
     385              :                     st.close();
     386              :                 else
     387              :                     st.commit(n);
     388              :             }
     389              : 
     390              :             write_some(client, serializer);
     391              : 
     392              :         } while(!serializer.is_done());
     393              :         @endcode
     394              : 
     395              :         @par Preconditions
     396              :         @code
     397              :         this->is_done() == true
     398              :         @endcode
     399              : 
     400              :         @par Postconditions
     401              :         @code
     402              :         this->is_done() == false
     403              :         @endcode
     404              : 
     405              :         @par Exception Safety
     406              :         Strong guarantee.
     407              :         Exceptions thrown if there is insufficient
     408              :         internal buffer space to start the
     409              :         operation.
     410              : 
     411              :         @throw std::length_error if there is
     412              :         insufficient internal buffer space to
     413              :         start the operation.
     414              : 
     415              :         @param m The message to read the HTTP
     416              :         start-line and headers from.
     417              : 
     418              :         @return A @ref stream object for writing the body
     419              :         data into the serializer's internal buffer.
     420              : 
     421              :         @see
     422              :             @ref stream,
     423              :             @ref message_base.
     424              :      */
     425              :     
     426              :     stream
     427              :     start_stream(
     428              :         message_base const& m);
     429              : 
     430              :     /** Return the output area.
     431              : 
     432              :         This function serializes some or all of
     433              :         the message and returns the corresponding
     434              :         output buffers. Afterward, a call to @ref
     435              :         consume is required to report the number
     436              :         of bytes used, if any.
     437              : 
     438              :         If the message includes an
     439              :         `Expect: 100-continue` header and the
     440              :         header section of the message has been
     441              :         consumed, the returned result will contain
     442              :         @ref error::expect_100_continue to
     443              :         indicate that the header part of the
     444              :         message is complete. The next call to @ref
     445              :         prepare will produce output.
     446              : 
     447              :         When the serializer is used through the
     448              :         @ref stream interface, the result may
     449              :         contain @ref error::need_data to indicate
     450              :         that additional input is required to
     451              :         produce output.
     452              : 
     453              :         If a @ref source object is in use and a
     454              :         call to @ref source::read returns an
     455              :         error, the serializer enters a faulted
     456              :         state and propagates the error to the
     457              :         caller. This faulted state can only be
     458              :         cleared by calling @ref reset. This
     459              :         ensures the caller is explicitly aware
     460              :         that the previous message was truncated
     461              :         and that the stream must be terminated.
     462              : 
     463              :         @par Preconditions
     464              :         @code
     465              :         this->is_done() == false
     466              :         @endcode
     467              :         No unrecoverable error reported from previous calls.
     468              : 
     469              :         @par Exception Safety
     470              :         Strong guarantee.
     471              :         Calls to @ref source::read may throw if in use.
     472              : 
     473              :         @throw std::logic_error
     474              :         `this->is_done() == true`.
     475              : 
     476              :         @return A result containing @ref
     477              :         const_buffers_type that represents the
     478              :         output area or an error if any occurred.
     479              : 
     480              :         @see
     481              :             @ref consume,
     482              :             @ref is_done,
     483              :             @ref const_buffers_type.
     484              :     */
     485              :     
     486              :     auto
     487              :     prepare() ->
     488              :         system::result<
     489              :             const_buffers_type>;
     490              : 
     491              :     /** Consume bytes from the output area.
     492              : 
     493              :         This function should be called after one
     494              :         or more bytes contained in the buffers
     495              :         provided in the prior call to @ref prepare
     496              :         have been used.
     497              : 
     498              :         After a call to @ref consume, callers
     499              :         should check the return value of @ref
     500              :         is_done to determine if the entire message
     501              :         has been serialized.
     502              : 
     503              :         @par Preconditions
     504              :         @code
     505              :         this->is_done() == false
     506              :         @endcode
     507              : 
     508              :         @par Exception Safety
     509              :         Strong guarantee.
     510              : 
     511              :         @throw std::logic_error
     512              :         `this->is_done() == true`.
     513              : 
     514              :         @param n The number of bytes to consume.
     515              :         If `n` is greater than the size of the
     516              :         buffer returned from @ref prepared the
     517              :         entire output sequence is consumed and no
     518              :         error is issued.
     519              : 
     520              :         @see
     521              :             @ref prepare,
     522              :             @ref is_done,
     523              :             @ref const_buffers_type.
     524              :     */
     525              :     
     526              :     void
     527              :     consume(std::size_t n);
     528              : 
     529              :     /** Return true if serialization is complete.
     530              :     */
     531              :     bool
     532              :     is_done() const noexcept;
     533              : 
     534              : private:
     535              :     class impl;
     536              :     class cbs_gen;
     537              :     template<class>
     538              :     class cbs_gen_impl;
     539              : 
     540              :     
     541              :     detail::workspace&
     542              :     ws();
     543              : 
     544              :     
     545              :     void
     546              :     start_init(
     547              :         message_base const&);
     548              : 
     549              :     
     550              :     void
     551              :     start_buffers(
     552              :         message_base const&,
     553              :         cbs_gen&);
     554              : 
     555              :     
     556              :     void
     557              :     start_source(
     558              :         message_base const&,
     559              :         source&);
     560              : 
     561              :     impl* impl_ = nullptr;
     562              : };
     563              : 
     564              : /** Serializer configuration settings.
     565              : 
     566              :     @see
     567              :         @ref install_serializer_service,
     568              :         @ref serializer.
     569              : */
     570              : struct serializer::config
     571              : {
     572              :     /** Enable Brotli Content-Encoding.
     573              : 
     574              :         Requires `boost::capy::brotli::encode_service` to be
     575              :         installed, otherwise an exception is thrown.
     576              :     */
     577              :     bool apply_brotli_encoder = false;
     578              : 
     579              :     /** Enable Deflate Content-Encoding.
     580              : 
     581              :         Requires `boost::zlib::deflate_service` to be
     582              :         installed, otherwise an exception is thrown.
     583              :     */
     584              :     bool apply_deflate_encoder = false;
     585              : 
     586              :     /** Enable Gzip Content-Encoding.
     587              : 
     588              :         Requires `boost::zlib::deflate_service` to be
     589              :         installed, otherwise an exception is thrown.
     590              :     */
     591              :     bool apply_gzip_encoder = false;
     592              : 
     593              :     /** Brotli compression quality (0–11).
     594              : 
     595              :         Higher values yield better but slower compression.
     596              :     */
     597              :     std::uint32_t brotli_comp_quality = 5;
     598              : 
     599              :     /** Brotli compression window size (10–24).
     600              : 
     601              :         Larger windows improve compression but increase
     602              :         memory usage.
     603              :     */
     604              :     std::uint32_t brotli_comp_window = 18;
     605              : 
     606              :     /** Zlib compression level (0–9).
     607              : 
     608              :         0 = no compression, 1 = fastest, 9 = best
     609              :         compression.
     610              :     */
     611              :     int zlib_comp_level = 6;
     612              : 
     613              :     /** Zlib window bits (9–15).
     614              : 
     615              :         Controls the history buffer size. Larger values
     616              :         improve compression but use more memory.
     617              :     */
     618              :     int zlib_window_bits = 15;
     619              : 
     620              :     /** Zlib memory level (1–9).
     621              : 
     622              :         Higher values use more memory, but offer faster
     623              :         and more efficient compression.
     624              :     */
     625              :     int zlib_mem_level = 8;
     626              : 
     627              :     /** Minimum buffer size for payloads (must be > 0). */
     628              :     std::size_t payload_buffer = 8192;
     629              : 
     630              :     /** Reserved space for type-erasure storage.
     631              : 
     632              :         Used for:
     633              :         @li User-defined @ref source objects.
     634              :         @li User-defined ConstBufferSequence instances.
     635              :     */
     636              :     std::size_t max_type_erase = 1024;
     637              : };
     638              : 
     639              : /** Install the serializer service.
     640              : 
     641              :     @par Example
     642              :     @code
     643              :     // default configuration settings
     644              :     install_serializer_service(ctx, {});
     645              : 
     646              :     serializer sr(ctx);
     647              :     @endcode
     648              : 
     649              :     @par Exception Safety
     650              :     Strong guarantee.
     651              : 
     652              :     @throw std::invalid_argument If the service is
     653              :     already installed on the context.
     654              : 
     655              :     @param ctx Reference to the context on which
     656              :     the service should be installed.
     657              : 
     658              :     @param cfg Configuration settings for the
     659              :     serializer.
     660              : 
     661              :     @see
     662              :         @ref serializer::config,
     663              :         @ref serializer.
     664              : */
     665              : 
     666              : BOOST_HTTP_PROTO_DECL
     667              : void
     668              : install_serializer_service(
     669              :     capy::polystore& ctx,
     670              :     serializer::config const& cfg);
     671              : 
     672              : //------------------------------------------------
     673              : 
     674              : /** Used for streaming body data during serialization.
     675              : 
     676              :     Provides an interface for supplying serialized
     677              :     body content from an external source. This
     678              :     object is returned by @ref
     679              :     serializer::start_stream and enables
     680              :     incremental writing of the message body into
     681              :     the serializer's internal buffer.
     682              : 
     683              :     The stream supports an inverted control flow
     684              :     model, where the caller pushes body data as
     685              :     needed.
     686              : 
     687              :     Valid operations depend on the state of the
     688              :     serializer. Once the serializer is destroyed,
     689              :     reset, or completes, the stream becomes
     690              :     invalid and must only be destroyed.
     691              : 
     692              :     @see
     693              :         @ref serializer::start_stream
     694              : */
     695              : class BOOST_HTTP_PROTO_DECL serializer::stream
     696              : {
     697              : public:
     698              :     /** The type used to represent a sequence
     699              :         of mutable buffers.
     700              :     */
     701              :     using mutable_buffers_type =
     702              :         buffers::mutable_buffer_pair;
     703              : 
     704              :     /** Constructor.
     705              : 
     706              :         A default-constructed stream is
     707              :         considered closed.
     708              : 
     709              :         @par Postconditions
     710              :         @code
     711              :         this->is_open() == false
     712              :         @endcode
     713              :     */
     714              :     stream() noexcept = default;
     715              : 
     716              :     /** Constructor.
     717              : 
     718              :         After construction, the moved-from
     719              :         object is as if default-constructed.
     720              : 
     721              :         @par Postconditions
     722              :         @code
     723              :         other->is_open() == false
     724              :         @endcode
     725              : 
     726              :         @param other The object to move from.
     727              :     */
     728              :     stream(stream&& other) noexcept
     729              :         : impl_(other.impl_)
     730              :     {
     731              :         other.impl_ = nullptr;
     732              :     }
     733              : 
     734              :     /** Move assignment.
     735              : 
     736              :         After assignment, the moved-from
     737              :         object is as if default-constructed.
     738              : 
     739              :         @par Postconditions
     740              :         @code
     741              :         other->is_open() == false
     742              :         @endcode
     743              : 
     744              :         @param other The object to assign from.
     745              :         @return A reference to this object.
     746              :     */
     747              :     stream&
     748              :     operator=(stream&& other) noexcept
     749              :     {
     750              :         std::swap(impl_, other.impl_);
     751              :         return *this;
     752              :     }
     753              : 
     754              :     /** Return true if the stream is open.
     755              :     */
     756              :     bool
     757         5046 :     is_open() const noexcept
     758              :     {
     759         5046 :         return impl_ != nullptr;
     760              :     }
     761              : 
     762              :     /** Return the available capacity.
     763              : 
     764              :         @par Preconditions
     765              :         @code
     766              :         this->is_open() == true
     767              :         @endcode
     768              : 
     769              :         @par Exception Safety
     770              :         Strong guarantee.
     771              : 
     772              :         @throw std::logic_error
     773              :         `this->is_open() == false`.
     774              :     */
     775              :     
     776              :     std::size_t
     777              :     capacity() const;
     778              : 
     779              :     /** Prepare a buffer for writing.
     780              : 
     781              :         Retuns a mutable buffer sequence representing
     782              :         the writable bytes. Use @ref commit to make the
     783              :         written data available to the serializer.
     784              : 
     785              :         All buffer sequences previously obtained
     786              :         using @ref prepare are invalidated.
     787              : 
     788              :         @par Preconditions
     789              :         @code
     790              :         this->is_open() == true && n <= this->capacity()
     791              :         @endcode
     792              : 
     793              :         @par Exception Safety
     794              :         Strong guarantee.
     795              : 
     796              :         @return An instance of @ref mutable_buffers_type
     797              :         the underlying memory is owned by the serializer.
     798              : 
     799              :         @throw std::logic_error
     800              :         `this->is_open() == false`
     801              : 
     802              :         @see
     803              :             @ref commit,
     804              :             @ref capacity.
     805              :     */
     806              :         mutable_buffers_type
     807              :     prepare();
     808              : 
     809              :     /** Commit data to the serializer.
     810              : 
     811              :         Makes `n` bytes available to the serializer.
     812              : 
     813              :         All buffer sequences previously obtained
     814              :         using @ref prepare are invalidated.
     815              : 
     816              :         @par Preconditions
     817              :         @code
     818              :         this->is_open() == true && n <= this->capacity()
     819              :         @endcode
     820              : 
     821              :         @par Exception Safety
     822              :         Strong guarantee.
     823              :         Exceptions thrown on invalid input.
     824              : 
     825              :         @param n The number of bytes to append.
     826              : 
     827              :         @throw std::invalid_argument
     828              :         `n > this->capacity()`
     829              : 
     830              :         @throw std::logic_error
     831              :         `this->is_open() == false`
     832              : 
     833              :         @see
     834              :             @ref prepare,
     835              :             @ref capacity.
     836              :     */
     837              :     
     838              :     void
     839              :     commit(std::size_t n);
     840              : 
     841              :     /** Close the stream if open.
     842              : 
     843              :         Closes the stream and
     844              :         notifies the serializer that the
     845              :         message body has ended.
     846              : 
     847              :         If the stream is already closed this
     848              :         call has no effect.
     849              : 
     850              :         @par Postconditions
     851              :         @code
     852              :         this->is_open() == false
     853              :         @endcode
     854              :     */
     855              :     
     856              :     void
     857              :     close() noexcept;
     858              : 
     859              :     /** Destructor.
     860              : 
     861              :         Closes the stream if open.
     862              :     */
     863           24 :     ~stream()
     864              :     {
     865           24 :         close();
     866           24 :     }
     867              : 
     868              : private:
     869              :     friend class serializer;
     870              : 
     871              :     explicit
     872           23 :     stream(serializer::impl* impl) noexcept
     873           23 :         : impl_(impl)
     874              :     {
     875           23 :     }
     876              : 
     877              :     serializer::impl* impl_ = nullptr;
     878              : };
     879              : 
     880              : } // http_proto
     881              : } // boost
     882              : 
     883              : #include <boost/http_proto/impl/serializer.hpp>
     884              : 
     885              : #endif
        

Generated by: LCOV version 2.1