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-03-04 15:37:43 Functions: 7 7 100.0 %

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

Generated by: LCOV version 1.15