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

Generated by: LCOV version 1.15