Line data Source code
1 : // 2 : // Copyright (c) 2021 Vinnie Falco (vinnie.falco@gmail.com) 3 : // Copyright (c) 2024 Christian Mazakas 4 : // 5 : // Distributed under the Boost Software License, Version 1.0. (See accompanying 6 : // file LICENSE_1_0.txt or copy at http://www.boost.org/LICENSE_1_0.txt) 7 : // 8 : // Official repository: https://github.com/cppalliance/http_proto 9 : // 10 : 11 : #ifndef BOOST_HTTP_PROTO_FIELDS_HPP 12 : #define BOOST_HTTP_PROTO_FIELDS_HPP 13 : 14 : #include <boost/http_proto/detail/config.hpp> 15 : #include <boost/http_proto/fields_base.hpp> 16 : #include <boost/http_proto/fields_view.hpp> 17 : #include <boost/core/detail/string_view.hpp> 18 : #include <initializer_list> 19 : 20 : namespace boost { 21 : namespace http_proto { 22 : 23 : /** A modifiable container of HTTP fields 24 : */ 25 : class fields final 26 : : public fields_base 27 : { 28 : public: 29 : 30 : //-------------------------------------------- 31 : // 32 : // Special Members 33 : // 34 : //-------------------------------------------- 35 : 36 : /** Constructor 37 : 38 : Default-constructed fields have no 39 : name-value pairs. 40 : */ 41 : BOOST_HTTP_PROTO_DECL 42 : fields() noexcept; 43 : 44 : /** Constructor 45 : */ 46 : BOOST_HTTP_PROTO_DECL 47 : explicit 48 : fields( 49 : core::string_view s); 50 : 51 : /** Constructor 52 : 53 : Construct a fields container which allocates `size` bytes 54 : for storing the header. The provided `size` 55 : will be aligned up as required by the implementation. 56 : This size will also be used as the limit for 57 : growing the header. 58 : 59 : <br/> 60 : 61 : This constructor is useful when an upper-bound size 62 : of the fields is known ahead of time and we want 63 : to prevent reallocations. 64 : 65 : <br/> 66 : 67 : Passing an initial size of `0` does not throw and 68 : the maximum capacity is set to an 69 : implementation-defined limit. 70 : 71 : @param size Initial and final size, in bytes, of 72 : the backing allocation for the fields' header. 73 : Any operation that attempts to grow the container 74 : beyond this size will throw `std::length_error`. 75 : 76 : @code 77 : boost::http_proto::fields 78 : make_fields(std::string_view server) 79 : { 80 : std::size_t size = 4096; 81 : boost::http_proto::fields flds(size); 82 : BOOST_ASSERT( 83 : flds.max_capacity_in_bytes(), 4096); 84 : 85 : // uses spare capacity so that reallocations 86 : // are avoided 87 : flds.append( 88 : boost::http_proto::field::server, server); 89 : flds.append( 90 : boost::http_proto::field::connection, "close"); 91 : return flds; 92 : } 93 : @endcode 94 : */ 95 : BOOST_HTTP_PROTO_DECL 96 : explicit 97 : fields( 98 : std::size_t size); 99 : 100 : /** Constructor 101 : 102 : Constructs a fields container with an initial allocation of 103 : `size` bytes used for the fields header. The 104 : container can regrow up until the limit `max_size`. 105 : `size` and `max_size` are aligned up as required by the 106 : implementation. 107 : 108 : <br/> 109 : 110 : This constructor is useful when there's a best-fit 111 : guess for an initial header size but we still wish 112 : to permit reallocating and growing the container to 113 : some upper limit. 114 : 115 : <br/> 116 : 117 : Passing an initial size of `0` does not throw. 118 : 119 : @param size Initial size, in bytes, of 120 : the backing allocation for the fields' header. 121 : 122 : @param max_size Max size, in bytes, of the backing 123 : allocation for the fields' header. Any operation 124 : that attempts to grow the container beyond this 125 : size will throw `std::length_error`. 126 : 127 : @throws std::length_error Thrown if `size > max_size` 128 : 129 : @code 130 : boost::http_proto::fields 131 : make_fields(std::string_view host) 132 : { 133 : std::size_t size = 4096; 134 : boost::http_proto::fields flds(size, 2 * size); 135 : BOOST_ASSERT( 136 : flds.max_capacity_in_bytes(), 2 * 4096); 137 : 138 : // uses spare capacity so that reallocations 139 : // are avoided 140 : flds.append( 141 : boost::http_proto::field::host, host); 142 : flds.append( 143 : boost::http_proto::field::connection, "close"); 144 : return flds; 145 : } 146 : @endcode 147 : */ 148 : BOOST_HTTP_PROTO_DECL 149 : explicit 150 : fields( 151 : std::size_t size, 152 : std::size_t max_size); 153 : 154 : /** Constructor 155 : */ 156 : BOOST_HTTP_PROTO_DECL 157 : fields(fields&& other) noexcept; 158 : 159 : /** Constructor 160 : */ 161 : BOOST_HTTP_PROTO_DECL 162 : fields(fields const& other); 163 : 164 : /** Constructor 165 : */ 166 : BOOST_HTTP_PROTO_DECL 167 : fields(fields_view const& other); 168 : 169 : /** Assignment 170 : */ 171 : BOOST_HTTP_PROTO_DECL 172 : fields& 173 : operator=(fields&& f) noexcept; 174 : 175 : /** Assignment 176 : */ 177 : fields& 178 5 : operator=(fields const& f) noexcept 179 : { 180 5 : copy_impl(*f.ph_); 181 5 : return *this; 182 : } 183 : 184 : /** Assignment 185 : */ 186 : fields& 187 4 : operator=(fields_view const& f) 188 : { 189 4 : copy_impl(*f.ph_); 190 4 : return *this; 191 : } 192 : 193 : /** Conversion 194 : */ 195 4 : operator fields_view() const noexcept 196 : { 197 4 : return fields_view(ph_); 198 : } 199 : 200 : //-------------------------------------------- 201 : // 202 : // Modifiers 203 : // 204 : //-------------------------------------------- 205 : 206 : /** Swap this with another instance 207 : */ 208 : void 209 10 : swap(fields& other) noexcept 210 : { 211 10 : h_.swap(other.h_); 212 10 : } 213 : 214 : /** Swap two instances 215 : */ 216 : // hidden friend 217 : friend 218 : void 219 : swap( 220 : fields& t0, 221 : fields& t1) noexcept 222 : { 223 : t0.swap(t1); 224 : } 225 : }; 226 : 227 : } // http_proto 228 : } // boost 229 : 230 : #endif