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

Generated by: LCOV version 2.1