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 54 : `storage_size` bytes for storing the header. 55 : Attempting to grow the container beyond 56 : this amount will result in an exception. 57 : The storage is also used internally to store 58 : instances of an implementation-defined type. 59 : The requested number of bytes will be aligned 60 : accordingly (currently the alignment requirement is 4). 61 : 62 : <br/> 63 : 64 : This constructor is useful when an upper-bound size 65 : of the fields is known ahead of time and we want 66 : to prevent reallocations. 67 : 68 : <br/> 69 : 70 : Passing an initial storage size of `0` does not 71 : throw and the maximum capacity is set to an 72 : implementation-defined limit observable via 73 : @ref max_capacity_in_bytes(). 74 : 75 : @param storage_size The initial and final size of 76 : the storage. 77 : 78 : @code 79 : boost::http_proto::fields 80 : make_fields(std::string_view server) 81 : { 82 : std::size_t size = 4096; 83 : // flds.buffer() is now stable 84 : boost::http_proto::fields flds(size); 85 : BOOST_ASSERT( 86 : flds.max_capacity_in_bytes(), 4096); 87 : 88 : // uses spare capacity so that reallocations 89 : // are avoided 90 : flds.append( 91 : boost::http_proto::field::server, server); 92 : flds.append( 93 : boost::http_proto::field::connection, "close"); 94 : return flds; 95 : } 96 : @endcode 97 : */ 98 : BOOST_HTTP_PROTO_DECL 99 : explicit 100 : fields( 101 : std::size_t storage_size); 102 : 103 : /** Constructor 104 : 105 : Construct a fields container which allocates 106 : `storage_size` bytes for storing the header, with an 107 : upper limit of `max_storage_size`. Attempting to 108 : grow the container beyond its maximum will result in 109 : an exception. The storage is also used internally to 110 : store instances of an implementation-defined type. 111 : Both values will be aligned accordingly (currently 112 : the alignment requirement is 4). 113 : 114 : <br/> 115 : 116 : This constructor is useful when there's a best-fit 117 : guess for an initial header size but we still wish 118 : to permit reallocating and growing the container to 119 : some upper limit. 120 : 121 : <br/> 122 : 123 : Passing an initial size of `0` does not throw. 124 : 125 : @param storage_size The initial size of the storage. 126 : 127 : @param max_storage_size The maximum size of the 128 : allocated storage. Any operation that attempts to 129 : grow the container beyond this value throws 130 : `std::length_error`. 131 : 132 : @throws std::length_error Thrown if `size > max_size` 133 : 134 : @code 135 : boost::http_proto::fields 136 : make_fields(std::string_view host) 137 : { 138 : std::size_t size = 4096; 139 : boost::http_proto::fields flds(size, 2 * size); 140 : BOOST_ASSERT( 141 : flds.max_capacity_in_bytes(), 2 * 4096); 142 : 143 : // uses spare capacity so that reallocations 144 : // are avoided 145 : flds.append( 146 : boost::http_proto::field::host, host); 147 : flds.append( 148 : boost::http_proto::field::connection, "close"); 149 : return flds; 150 : } 151 : @endcode 152 : */ 153 : BOOST_HTTP_PROTO_DECL 154 : explicit 155 : fields( 156 : std::size_t storage_size, 157 : std::size_t max_storage_size); 158 : 159 : /** Constructor 160 : */ 161 : BOOST_HTTP_PROTO_DECL 162 : fields(fields&& other) noexcept; 163 : 164 : /** Constructor 165 : */ 166 : BOOST_HTTP_PROTO_DECL 167 : fields(fields const& other); 168 : 169 : /** Constructor 170 : */ 171 : BOOST_HTTP_PROTO_DECL 172 : fields(fields_view const& other); 173 : 174 : /** Assignment 175 : */ 176 : BOOST_HTTP_PROTO_DECL 177 : fields& 178 : operator=(fields&& f) noexcept; 179 : 180 : /** Assignment 181 : */ 182 : fields& 183 5 : operator=(fields const& f) noexcept 184 : { 185 5 : copy_impl(*f.ph_); 186 5 : return *this; 187 : } 188 : 189 : /** Assignment 190 : */ 191 : fields& 192 4 : operator=(fields_view const& f) 193 : { 194 4 : copy_impl(*f.ph_); 195 4 : return *this; 196 : } 197 : 198 : /** Conversion 199 : */ 200 4 : operator fields_view() const noexcept 201 : { 202 4 : return fields_view(ph_); 203 : } 204 : 205 : //-------------------------------------------- 206 : // 207 : // Modifiers 208 : // 209 : //-------------------------------------------- 210 : 211 : /** Swap this with another instance 212 : */ 213 : void 214 10 : swap(fields& other) noexcept 215 : { 216 10 : h_.swap(other.h_); 217 10 : } 218 : 219 : /** Swap two instances 220 : */ 221 : // hidden friend 222 : friend 223 : void 224 : swap( 225 : fields& t0, 226 : fields& t1) noexcept 227 : { 228 : t0.swap(t1); 229 : } 230 : }; 231 : 232 : } // http_proto 233 : } // boost 234 : 235 : #endif