LCOV - code coverage report
Current view: top level - boost/http_proto/fields_base.hpp (source / functions) Coverage Total Hit
Test: coverage_filtered.info Lines: 100.0 % 25 25
Test Date: 2024-07-18 19:38:54 Functions: 100.0 % 7 7

            Line data    Source code
       1              : //
       2              : // Copyright (c) 2021 Vinnie Falco (vinnie.falco@gmail.com)
       3              : // Copyright (c) 2024 Christian Mazakas
       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_FIELDS_BASE_HPP
      12              : #define BOOST_HTTP_PROTO_FIELDS_BASE_HPP
      13              : 
      14              : #include <boost/http_proto/detail/config.hpp>
      15              : #include <boost/http_proto/fields_view_base.hpp>
      16              : #include <boost/core/detail/string_view.hpp>
      17              : #include <boost/system/result.hpp>
      18              : 
      19              : namespace boost {
      20              : namespace http_proto {
      21              : 
      22              : namespace detail {
      23              : struct prefix_op;
      24              : } // detail
      25              : 
      26              : /** Mixin for modifiable HTTP fields
      27              : 
      28              :     @par Iterators
      29              : 
      30              :     Iterators obtained from @ref fields
      31              :     containers are not invalidated when
      32              :     the underlying container is modified.
      33              : 
      34              :     @note HTTP field names are case-insensitive.
      35              : */
      36              : class fields_base
      37              :     : public virtual fields_view_base
      38              : {
      39              :     detail::header h_;
      40              : 
      41              :     class op_t;
      42              :     using entry =
      43              :         detail::header::entry;
      44              :     using table =
      45              :         detail::header::table;
      46              : 
      47              :     friend class fields;
      48              :     friend class request;
      49              :     friend class response;
      50              :     friend class serializer;
      51              :     friend class message_base;
      52              :     friend struct detail::header;
      53              :     friend struct detail::prefix_op;
      54              : 
      55              :     BOOST_HTTP_PROTO_DECL
      56              :     fields_base(
      57              :         detail::kind,
      58              :         std::size_t size);
      59              : 
      60              :     BOOST_HTTP_PROTO_DECL
      61              :     fields_base(
      62              :         detail::kind,
      63              :         std::size_t size,
      64              :         std::size_t max_size);
      65              : 
      66              :     BOOST_HTTP_PROTO_DECL
      67              :     explicit
      68              :     fields_base(
      69              :         detail::kind) noexcept;
      70              : 
      71              :     BOOST_HTTP_PROTO_DECL
      72              :     fields_base(
      73              :         detail::kind,
      74              :         core::string_view);
      75              : 
      76              :     fields_base(detail::header const&);
      77              : 
      78              : public:
      79              :     /** Destructor
      80              :     */
      81              :     BOOST_HTTP_PROTO_DECL
      82              :     ~fields_base();
      83              : 
      84              :     //--------------------------------------------
      85              :     //
      86              :     // Capacity
      87              :     //
      88              :     //--------------------------------------------
      89              : 
      90              :     /** Returns the largest permissible capacity in bytes
      91              :     */
      92              :     std::size_t
      93         1002 :     max_capacity_in_bytes() noexcept
      94              :     {
      95         1002 :         return h_.max_cap;
      96              :     }
      97              : 
      98              :     /** Returns the total number of bytes allocated by the container
      99              :     */
     100              :     std::size_t
     101          114 :     capacity_in_bytes() const noexcept
     102              :     {
     103          114 :         return h_.cap;
     104              :     }
     105              : 
     106              :     /** Clear the contents, but not the capacity
     107              :     */
     108              :     BOOST_HTTP_PROTO_DECL
     109              :     void
     110              :     clear() noexcept;
     111              : 
     112              :     /** Reserve a minimum capacity
     113              :     */
     114              :     BOOST_HTTP_PROTO_DECL
     115              :     void
     116              :     reserve_bytes(std::size_t n);
     117              : 
     118              :     /** Remove excess capacity
     119              :     */
     120              :     BOOST_HTTP_PROTO_DECL
     121              :     void
     122              :     shrink_to_fit() noexcept;
     123              : 
     124              :     //--------------------------------------------
     125              :     //
     126              :     // Modifiers
     127              :     //
     128              :     //--------------------------------------------
     129              : 
     130              :     /** Append a header
     131              : 
     132              :         This function appends a new header with the
     133              :         specified id and value. The value must be
     134              :         syntactically valid or else an error is returned.
     135              :         Any leading or trailing whitespace in the new value
     136              :         is ignored.
     137              :         <br/>
     138              :         No iterators are invalidated.
     139              : 
     140              :         @par Example
     141              :         @code
     142              :         request req;
     143              : 
     144              :         req.append( field::user_agent, "Boost" );
     145              :         @endcode
     146              : 
     147              :         @par Complexity
     148              :         Linear in `to_string( id ).size() + value.size()`.
     149              : 
     150              :         @par Exception Safety
     151              :         Strong guarantee.
     152              :         Calls to allocate may throw.
     153              : 
     154              :         @param id The field name constant,
     155              :         which may not be @ref field::unknown.
     156              : 
     157              :         @param value A value, which must be semantically
     158              :         valid for the message.
     159              : 
     160              :         @return The error, if any occurred.
     161              :     */
     162              :     system::result<void>
     163          120 :     append(
     164              :         field id,
     165              :         core::string_view value)
     166              :     {
     167          120 :         BOOST_ASSERT(
     168              :             id != field::unknown);
     169          120 :         return insert_impl(
     170          237 :             id, to_string(id), value, h_.count);
     171              :     }
     172              : 
     173              :     /** Append a header
     174              : 
     175              :         This function appends a new header with the
     176              :         specified name and value. Both values must be
     177              :         syntactically valid or else an error is returned.
     178              :         Any leading or trailing whitespace in the new
     179              :         value is ignored.
     180              :         <br/>
     181              :         No iterators are invalidated.
     182              : 
     183              :         @par Example
     184              :         @code
     185              :         request req;
     186              : 
     187              :         req.append( "User-Agent", "Boost" );
     188              :         @endcode
     189              : 
     190              :         @par Complexity
     191              :         Linear in `name.size() + value.size()`.
     192              : 
     193              :         @par Exception Safety
     194              :         Strong guarantee.
     195              :         Calls to allocate may throw.
     196              : 
     197              :         @param name The header name.
     198              : 
     199              :         @param value A value, which must be semantically
     200              :         valid for the message.
     201              : 
     202              :         @return The error, if any occurred.
     203              :     */
     204              :     system::result<void>
     205           55 :     append(
     206              :         core::string_view name,
     207              :         core::string_view value)
     208              :     {
     209           55 :         return insert_impl(
     210              :             string_to_field(
     211              :                 name),
     212              :             name,
     213              :             value,
     214          109 :             h_.count);
     215              :     }
     216              : 
     217              :     /** Insert a header
     218              : 
     219              :         If a matching header with the same name
     220              :         exists, it is not replaced. Instead, an
     221              :         additional header with the same name is
     222              :         inserted. Names are not case-sensitive.
     223              :         Any leading or trailing whitespace in
     224              :         the new value is ignored.
     225              :         <br>
     226              :         All iterators that are equal to `before`
     227              :         or come after are invalidated.
     228              : 
     229              :         @par Example
     230              :         @code
     231              :         request req;
     232              : 
     233              :         req.insert( req.begin(), field::user_agent, "Boost" );
     234              :         @endcode
     235              : 
     236              :         @par Complexity
     237              :         Linear in `to_string( id ).size() + value.size()`.
     238              : 
     239              :         @par Exception Safety
     240              :         Strong guarantee.
     241              :         Calls to allocate may throw.
     242              : 
     243              :         @return An iterator the newly inserted header, or
     244              :         an error if any occurred.
     245              : 
     246              :         @param before Position to insert before.
     247              : 
     248              :         @param id The field name constant,
     249              :         which may not be @ref field::unknown.
     250              : 
     251              :         @param value A value, which must be semantically
     252              :         valid for the message.
     253              :     */
     254              :     system::result<iterator>
     255           43 :     insert(
     256              :         iterator before,
     257              :         field id,
     258              :         core::string_view value)
     259              :     {
     260              :         // TODO: this should probably return an error
     261           43 :         BOOST_ASSERT(
     262              :             id != field::unknown);
     263              : 
     264           43 :         auto rv = insert_impl(
     265              :             id, to_string(id), value, before.i_);
     266              : 
     267           43 :         if( rv.has_error() )
     268            1 :             return rv.error();
     269           42 :         return before;
     270              :     }
     271              : 
     272              :     /** Insert a header
     273              : 
     274              :         If a matching header with the same name
     275              :         exists, it is not replaced. Instead, an
     276              :         additional header with the same name is
     277              :         inserted. Names are not case-sensitive.
     278              :         Any leading or trailing whitespace in
     279              :         the new value is ignored.
     280              :         <br>
     281              :         All iterators that are equal to `before`
     282              :         or come after are invalidated.
     283              : 
     284              :         @par Example
     285              :         @code
     286              :         request req;
     287              : 
     288              :         req.insert( req.begin(), "User-Agent", "Boost" );
     289              :         @endcode
     290              : 
     291              :         @par Complexity
     292              :         Linear in `name.size() + value.size()`.
     293              : 
     294              :         @par Exception Safety
     295              :         Strong guarantee.
     296              :         Calls to allocate may throw.
     297              : 
     298              :         @return An iterator the newly inserted header, or
     299              :         an error if any occurred.
     300              : 
     301              :         @param before Position to insert before.
     302              : 
     303              :         @param name The header name.
     304              : 
     305              :         @param value A value, which must be semantically
     306              :         valid for the message.
     307              :     */
     308              :     system::result<iterator>
     309           15 :     insert(
     310              :         iterator before,
     311              :         core::string_view name,
     312              :         core::string_view value)
     313              :     {
     314           15 :         auto rv = insert_impl(
     315              :             string_to_field(
     316              :                 name),
     317              :             name,
     318              :             value,
     319              :             before.i_);
     320              : 
     321           15 :         if( rv.has_error() )
     322            3 :             return rv.error();
     323           12 :         return before;
     324              :     }
     325              : 
     326              :     //--------------------------------------------
     327              : 
     328              :     /** Erase headers
     329              : 
     330              :         This function removes the header pointed
     331              :         to by `it`.
     332              :         <br>
     333              :         All iterators that are equal to `it`
     334              :         or come after are invalidated.
     335              : 
     336              :         @par Complexity
     337              :         Linear in `name.size() + value.size()`.
     338              : 
     339              :         @par Exception Safety
     340              :         Throws nothing.
     341              : 
     342              :         @return An iterator to the inserted
     343              :         element.
     344              : 
     345              :         @param it An iterator to the element
     346              :         to erase.
     347              :     */
     348              :     iterator
     349           31 :     erase(iterator it) noexcept
     350              :     {
     351           31 :         erase_impl(it.i_, it->id);
     352           31 :         return it;
     353              :     }
     354              : 
     355              :     /** Erase headers
     356              : 
     357              :         This removes all headers whose name
     358              :         constant is equal to `id`.
     359              :         <br>
     360              :         If any headers are erased, then all
     361              :         iterators equal to or that come after
     362              :         the first erased element are invalidated.
     363              :         Otherwise, no iterators are invalidated.
     364              : 
     365              :         @par Complexity
     366              :         Linear in `this->string().size()`.
     367              : 
     368              :         @par Exception Safety
     369              :         Throws nothing.
     370              : 
     371              :         @return The number of headers erased.
     372              : 
     373              :         @param id The field name constant,
     374              :         which may not be @ref field::unknown.
     375              :     */
     376              :     BOOST_HTTP_PROTO_DECL
     377              :     std::size_t
     378              :     erase(field id) noexcept;
     379              : 
     380              :     /** Erase all matching fields
     381              : 
     382              :         This removes all headers with a matching
     383              :         name, using a case-insensitive comparison.
     384              :         <br>
     385              :         If any headers are erased, then all
     386              :         iterators equal to or that come after
     387              :         the first erased element are invalidated.
     388              :         Otherwise, no iterators are invalidated.
     389              : 
     390              :         @par Complexity
     391              :         Linear in `this->string().size()`.
     392              : 
     393              :         @par Exception Safety
     394              :         Throws nothing.
     395              : 
     396              :         @return The number of fields erased
     397              : 
     398              :         @param name The header name.
     399              :     */
     400              :     BOOST_HTTP_PROTO_DECL
     401              :     std::size_t
     402              :     erase(
     403              :         core::string_view name) noexcept;
     404              : 
     405              :     //--------------------------------------------
     406              : 
     407              :     /** Set a header value
     408              : 
     409              :         Uses the given value to overwrite the
     410              :         current one in the header field pointed to by the
     411              :         iterator. The value must be syntactically
     412              :         valid or else an error is returned.
     413              :         Any leading or trailing whitespace in the new value
     414              :         is ignored.
     415              : 
     416              :         @par Complexity
     417              : 
     418              :         @par Exception Safety
     419              :         Strong guarantee.
     420              :         Calls to allocate may throw.
     421              : 
     422              :         @return The error, if any occurred.
     423              : 
     424              :         @param it An iterator to the header.
     425              : 
     426              :         @param value A value, which must be semantically
     427              :         valid for the message.
     428              :     */
     429              :     BOOST_HTTP_PROTO_DECL
     430              :     system::result<void>
     431              :     set(
     432              :         iterator it,
     433              :         core::string_view value);
     434              : 
     435              :     /** Set a header value
     436              : 
     437              :         The container is modified to contain exactly
     438              :         one field with the specified id set to the given value,
     439              :         which must be syntactically valid or else an error is
     440              :         returned.
     441              :         Any leading or trailing whitespace in the new value
     442              :         is ignored.
     443              : 
     444              :         @par Postconditions
     445              :         @code
     446              :         this->count( id ) == 1 && this->at( id ) == value
     447              :         @endcode
     448              : 
     449              :         @par Complexity
     450              : 
     451              :         @return The error, if any occurred.
     452              : 
     453              :         @param id The field constant of the
     454              :         header to set.
     455              : 
     456              :         @param value A value, which must be semantically
     457              :         valid for the message.
     458              :     */
     459              :     BOOST_HTTP_PROTO_DECL
     460              :     system::result<void>
     461              :     set(
     462              :         field id,
     463              :         core::string_view value);
     464              : 
     465              :     /** Set a header value
     466              : 
     467              :         The container is modified to contain exactly
     468              :         one field with the specified name set to the given value,
     469              :         which must be syntactically valid or else an error is
     470              :         returned.
     471              :         Any leading or trailing whitespace in the new value
     472              :         is ignored.
     473              : 
     474              :         @par Postconditions
     475              :         @code
     476              :         this->count( name ) == 1 && this->at( name ) == value
     477              :         @endcode
     478              : 
     479              :         @return The error, if any occurred.
     480              : 
     481              :         @param name The field name.
     482              : 
     483              :         @param value A value, which must be semantically
     484              :         valid for the message.
     485              :     */
     486              :     BOOST_HTTP_PROTO_DECL
     487              :     system::result<void>
     488              :     set(
     489              :         core::string_view name,
     490              :         core::string_view value);
     491              : 
     492              :     //--------------------------------------------
     493              : 
     494              : private:
     495              :     BOOST_HTTP_PROTO_DECL
     496              :     void
     497              :     copy_impl(
     498              :         detail::header const&);
     499              : 
     500              :     void
     501              :     insert_impl_unchecked(
     502              :         field id,
     503              :         core::string_view name,
     504              :         core::string_view value,
     505              :         std::size_t before,
     506              :         bool has_obs_fold);
     507              : 
     508              :     BOOST_HTTP_PROTO_DECL
     509              :     system::result<void>
     510              :     insert_impl(
     511              :         field id,
     512              :         core::string_view name,
     513              :         core::string_view value,
     514              :         std::size_t before);
     515              : 
     516              :     BOOST_HTTP_PROTO_DECL
     517              :     void
     518              :     erase_impl(
     519              :         std::size_t i,
     520              :         field id) noexcept;
     521              : 
     522              :     void raw_erase(
     523              :         std::size_t) noexcept;
     524              : 
     525              :     std::size_t
     526              :     erase_all_impl(
     527              :         std::size_t i0,
     528              :         field id) noexcept;
     529              : 
     530              :     std::size_t
     531              :     offset(
     532              :         std::size_t i) const noexcept;
     533              : 
     534              :     std::size_t
     535              :     length(
     536              :         std::size_t i) const noexcept;
     537              : 
     538              :     void raw_erase_n(field, std::size_t) noexcept;
     539              : };
     540              : 
     541              : //------------------------------------------------
     542              : 
     543              : #ifndef BOOST_HTTP_PROTO_DOCS
     544              : namespace detail {
     545              : inline
     546              : header&
     547              : header::
     548              : get(fields_base& f) noexcept
     549              : {
     550              :     return f.h_;
     551              : }
     552              : } // detail
     553              : #endif
     554              : 
     555              : } // http_proto
     556              : } // boost
     557              : 
     558              : #endif
        

Generated by: LCOV version 2.1