LCOV - code coverage report
Current view: top level - boost/http_proto - fields_base.hpp (source / functions) Hit Total Coverage
Test: coverage_filtered.info Lines: 23 23 100.0 %
Date: 2024-04-04 20:17:10 Functions: 7 7 100.0 %

          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         930 :     max_capacity_in_bytes() noexcept
      94             :     {
      95         930 :         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          96 :     append(
     164             :         field id,
     165             :         core::string_view value)
     166             :     {
     167          96 :         BOOST_ASSERT(
     168             :             id != field::unknown);
     169             :         return insert_impl(
     170          96 :             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             :         return insert_impl(
     210             :             string_to_field(
     211             :                 name),
     212             :             name,
     213             :             value,
     214          55 :             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             :         auto rv = insert_impl(
     265          43 :             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             :         auto rv = insert_impl(
     315             :             string_to_field(
     316             :                 name),
     317             :             name,
     318             :             value,
     319          15 :             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 1.15