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

Generated by: LCOV version 1.15