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-01-15 07:18:31 Functions: 7 7 100.0 %

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

Generated by: LCOV version 1.15