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

Generated by: LCOV version 2.1