| Line | Branch | Exec | Source |
|---|---|---|---|
| 1 | // | ||
| 2 | // Copyright (c) 2021 Vinnie Falco (vinnie.falco@gmail.com) | ||
| 3 | // Copyright (c) 2024 Christian Mazakas | ||
| 4 | // Copyright (c) 2025 Mohammad Nejati | ||
| 5 | // | ||
| 6 | // Distributed under the Boost Software License, Version 1.0. (See accompanying | ||
| 7 | // file LICENSE_1_0.txt or copy at http://www.boost.org/LICENSE_1_0.txt) | ||
| 8 | // | ||
| 9 | // Official repository: https://github.com/cppalliance/http_proto | ||
| 10 | // | ||
| 11 | |||
| 12 | #ifndef BOOST_HTTP_PROTO_FIELDS_BASE_HPP | ||
| 13 | #define BOOST_HTTP_PROTO_FIELDS_BASE_HPP | ||
| 14 | |||
| 15 | #include <boost/http_proto/detail/config.hpp> | ||
| 16 | #include <boost/http_proto/detail/except.hpp> | ||
| 17 | #include <boost/http_proto/fields_view_base.hpp> | ||
| 18 | #include <boost/core/detail/string_view.hpp> | ||
| 19 | |||
| 20 | namespace boost { | ||
| 21 | namespace http_proto { | ||
| 22 | |||
| 23 | /** Mixin for modifiable HTTP fields. | ||
| 24 | |||
| 25 | @par Iterators | ||
| 26 | |||
| 27 | Iterators obtained from @ref fields | ||
| 28 | containers are not invalidated when | ||
| 29 | the underlying container is modified. | ||
| 30 | |||
| 31 | @note HTTP field names are case-insensitive. | ||
| 32 | */ | ||
| 33 | class fields_base | ||
| 34 | : public virtual fields_view_base | ||
| 35 | { | ||
| 36 | detail::header h_; | ||
| 37 | std::size_t max_cap_ = | ||
| 38 | std::numeric_limits<std::size_t>::max(); | ||
| 39 | bool external_storage_ = false; | ||
| 40 | |||
| 41 | using entry = | ||
| 42 | detail::header::entry; | ||
| 43 | using offset_type = | ||
| 44 | detail::header::offset_type; | ||
| 45 | using table = | ||
| 46 | detail::header::table; | ||
| 47 | |||
| 48 | class op_t; | ||
| 49 | class prefix_op_t | ||
| 50 | { | ||
| 51 | fields_base& self_; | ||
| 52 | offset_type new_prefix_; | ||
| 53 | char* buf_ = nullptr; | ||
| 54 | |||
| 55 | public: | ||
| 56 | prefix_op_t( | ||
| 57 | fields_base& self, | ||
| 58 | std::size_t new_prefix, | ||
| 59 | core::string_view* s0 = nullptr, | ||
| 60 | core::string_view* s1 = nullptr); | ||
| 61 | |||
| 62 | ~prefix_op_t(); | ||
| 63 | }; | ||
| 64 | |||
| 65 | friend class fields; | ||
| 66 | template<std::size_t> | ||
| 67 | friend class static_fields; | ||
| 68 | friend class request_base; | ||
| 69 | friend class request; | ||
| 70 | template<std::size_t> | ||
| 71 | friend class static_request; | ||
| 72 | friend class response_base; | ||
| 73 | friend class response; | ||
| 74 | template<std::size_t> | ||
| 75 | friend class static_response; | ||
| 76 | friend class message_base; | ||
| 77 | |||
| 78 | BOOST_HTTP_PROTO_DECL | ||
| 79 | explicit | ||
| 80 | fields_base( | ||
| 81 | detail::kind k) noexcept; | ||
| 82 | |||
| 83 | BOOST_HTTP_PROTO_DECL | ||
| 84 | fields_base( | ||
| 85 | detail::kind k, | ||
| 86 | char* storage, | ||
| 87 | std::size_t cap) noexcept; | ||
| 88 | |||
| 89 | BOOST_HTTP_PROTO_DECL | ||
| 90 | fields_base( | ||
| 91 | detail::kind k, | ||
| 92 | core::string_view s); | ||
| 93 | |||
| 94 | BOOST_HTTP_PROTO_DECL | ||
| 95 | fields_base( | ||
| 96 | detail::kind k, | ||
| 97 | char* storage, | ||
| 98 | std::size_t cap, | ||
| 99 | core::string_view s); | ||
| 100 | |||
| 101 | BOOST_HTTP_PROTO_DECL | ||
| 102 | explicit | ||
| 103 | fields_base( | ||
| 104 | detail::header const& h); | ||
| 105 | |||
| 106 | BOOST_HTTP_PROTO_DECL | ||
| 107 | fields_base( | ||
| 108 | detail::header const& h, | ||
| 109 | char* storage, | ||
| 110 | std::size_t cap); | ||
| 111 | |||
| 112 | public: | ||
| 113 | /** Destructor. | ||
| 114 | */ | ||
| 115 | BOOST_HTTP_PROTO_DECL | ||
| 116 | ~fields_base(); | ||
| 117 | |||
| 118 | //-------------------------------------------- | ||
| 119 | // | ||
| 120 | // Capacity | ||
| 121 | // | ||
| 122 | //-------------------------------------------- | ||
| 123 | |||
| 124 | /** Return the maximum allowed capacity in bytes. | ||
| 125 | */ | ||
| 126 | std::size_t | ||
| 127 | 24 | max_capacity_in_bytes() noexcept | |
| 128 | { | ||
| 129 | 24 | return max_cap_; | |
| 130 | } | ||
| 131 | |||
| 132 | /** Return the total number of bytes allocated by the container. | ||
| 133 | */ | ||
| 134 | std::size_t | ||
| 135 | 119 | capacity_in_bytes() const noexcept | |
| 136 | { | ||
| 137 | 119 | return h_.cap; | |
| 138 | } | ||
| 139 | |||
| 140 | /** Clear contents while preserving the capacity. | ||
| 141 | |||
| 142 | In the case of response and request | ||
| 143 | containers the start-line also resets to | ||
| 144 | default. | ||
| 145 | |||
| 146 | @par Postconditions | ||
| 147 | @code | ||
| 148 | this->size() == 0 | ||
| 149 | @endcode | ||
| 150 | |||
| 151 | @par Complexity | ||
| 152 | Constant. | ||
| 153 | */ | ||
| 154 | BOOST_HTTP_PROTO_DECL | ||
| 155 | void | ||
| 156 | clear() noexcept; | ||
| 157 | |||
| 158 | /** Adjust the capacity without changing the size. | ||
| 159 | |||
| 160 | This function adjusts the capacity | ||
| 161 | of the container in bytes, without | ||
| 162 | affecting the current contents. Has | ||
| 163 | no effect if `n <= this->capacity_in_bytes()`. | ||
| 164 | |||
| 165 | @par Postconditions | ||
| 166 | @code | ||
| 167 | this->capacity_in_bytes() >= n | ||
| 168 | @endcode | ||
| 169 | |||
| 170 | @par Exception Safety | ||
| 171 | Strong guarantee. | ||
| 172 | Calls to allocate may throw. | ||
| 173 | Exception thrown if max capacity exceeded. | ||
| 174 | |||
| 175 | @throw std::length_error | ||
| 176 | Max capacity would be exceeded. | ||
| 177 | |||
| 178 | @param n The capacity in bytes. | ||
| 179 | */ | ||
| 180 | BOOST_HTTP_PROTO_DECL | ||
| 181 | void | ||
| 182 | reserve_bytes(std::size_t n); | ||
| 183 | |||
| 184 | /** Set the maximum allowed capacity in bytes. | ||
| 185 | |||
| 186 | Prevents the container from growing beyond | ||
| 187 | `n` bytes. Exceeding this limit will throw | ||
| 188 | an exception. | ||
| 189 | |||
| 190 | @par Preconditions | ||
| 191 | @code | ||
| 192 | this->capacity_in_bytes() <= n | ||
| 193 | @endcode | ||
| 194 | |||
| 195 | @par Postconditions | ||
| 196 | @code | ||
| 197 | this->max_capacity_in_bytes() == n | ||
| 198 | @endcode | ||
| 199 | |||
| 200 | @par Exception Safety | ||
| 201 | Strong guarantee. | ||
| 202 | Exception thrown on invalid input. | ||
| 203 | |||
| 204 | @throw std::invalid_argument | ||
| 205 | `n < this->capacity_in_bytes()` | ||
| 206 | |||
| 207 | @param n The maximum allowed capacity in bytes. | ||
| 208 | */ | ||
| 209 | BOOST_HTTP_PROTO_DECL | ||
| 210 | void | ||
| 211 | set_max_capacity_in_bytes(std::size_t n); | ||
| 212 | |||
| 213 | /** Remove excess capacity. | ||
| 214 | |||
| 215 | @par Exception Safety | ||
| 216 | Strong guarantee. | ||
| 217 | Calls to allocate may throw. | ||
| 218 | */ | ||
| 219 | BOOST_HTTP_PROTO_DECL | ||
| 220 | void | ||
| 221 | shrink_to_fit(); | ||
| 222 | |||
| 223 | //-------------------------------------------- | ||
| 224 | // | ||
| 225 | // Modifiers | ||
| 226 | // | ||
| 227 | //-------------------------------------------- | ||
| 228 | |||
| 229 | /** Append a header. | ||
| 230 | |||
| 231 | This function appends a new header. | ||
| 232 | Existing headers with the same name are | ||
| 233 | not changed. | ||
| 234 | |||
| 235 | Any leading or trailing whitespace in the | ||
| 236 | value is ignored. | ||
| 237 | |||
| 238 | No iterators are invalidated. | ||
| 239 | |||
| 240 | @par Example | ||
| 241 | @code | ||
| 242 | request req; | ||
| 243 | |||
| 244 | req.append( field::user_agent, "Boost" ); | ||
| 245 | @endcode | ||
| 246 | |||
| 247 | @par Complexity | ||
| 248 | Linear in `to_string( id ).size() + value.size()`. | ||
| 249 | |||
| 250 | @par Exception Safety | ||
| 251 | Strong guarantee. | ||
| 252 | Calls to allocate may throw. | ||
| 253 | Exception thrown on invalid input. | ||
| 254 | Exception thrown if max capacity exceeded. | ||
| 255 | |||
| 256 | @throw system_error | ||
| 257 | Input is invalid. | ||
| 258 | |||
| 259 | @throw std::length_error | ||
| 260 | Max capacity would be exceeded. | ||
| 261 | |||
| 262 | @param id The field name constant. | ||
| 263 | |||
| 264 | @param value The value which must be semantically | ||
| 265 | valid for the message. | ||
| 266 | */ | ||
| 267 | void | ||
| 268 | 96 | append( | |
| 269 | field id, | ||
| 270 | core::string_view value) | ||
| 271 | { | ||
| 272 | 96 | system::error_code ec; | |
| 273 |
2/2✓ Branch 1 taken 91 times.
✓ Branch 2 taken 5 times.
|
96 | append(id, value, ec); |
| 274 |
2/2✓ Branch 1 taken 3 times.
✓ Branch 2 taken 88 times.
|
91 | if(ec.failed()) |
| 275 | 3 | detail::throw_system_error(ec); | |
| 276 | 88 | } | |
| 277 | |||
| 278 | /** Append a header. | ||
| 279 | |||
| 280 | This function appends a new header. | ||
| 281 | Existing headers with the same name are | ||
| 282 | not changed. | ||
| 283 | |||
| 284 | Any leading or trailing whitespace in the | ||
| 285 | value is ignored. | ||
| 286 | |||
| 287 | No iterators are invalidated. | ||
| 288 | |||
| 289 | @par Example | ||
| 290 | @code | ||
| 291 | request req; | ||
| 292 | |||
| 293 | req.append( field::user_agent, "Boost" ); | ||
| 294 | @endcode | ||
| 295 | |||
| 296 | @par Complexity | ||
| 297 | Linear in `to_string( id ).size() + value.size()`. | ||
| 298 | |||
| 299 | @par Exception Safety | ||
| 300 | Strong guarantee. | ||
| 301 | Calls to allocate may throw. | ||
| 302 | Exception thrown if max capacity exceeded. | ||
| 303 | |||
| 304 | @throw std::length_error | ||
| 305 | Max capacity would be exceeded. | ||
| 306 | |||
| 307 | @param id The field name constant. | ||
| 308 | |||
| 309 | @param value The value which must be semantically | ||
| 310 | valid for the message. | ||
| 311 | |||
| 312 | @param ec Set to the error if input is invalid. | ||
| 313 | */ | ||
| 314 | void | ||
| 315 | 96 | append( | |
| 316 | field id, | ||
| 317 | core::string_view value, | ||
| 318 | system::error_code& ec) | ||
| 319 | { | ||
| 320 |
3/4✓ Branch 1 taken 96 times.
✗ Branch 2 not taken.
✓ Branch 4 taken 91 times.
✓ Branch 5 taken 5 times.
|
96 | insert_impl( |
| 321 | id, | ||
| 322 | to_string(id), | ||
| 323 | value, | ||
| 324 | 96 | h_.count, | |
| 325 | ec); | ||
| 326 | 91 | } | |
| 327 | |||
| 328 | /** Append a header. | ||
| 329 | |||
| 330 | This function appends a new header. | ||
| 331 | Existing headers with the same name are | ||
| 332 | not changed. | ||
| 333 | |||
| 334 | Any leading or trailing whitespace in the | ||
| 335 | value is ignored. | ||
| 336 | |||
| 337 | No iterators are invalidated. | ||
| 338 | |||
| 339 | @par Example | ||
| 340 | @code | ||
| 341 | request req; | ||
| 342 | |||
| 343 | req.append( "User-Agent", "Boost" ); | ||
| 344 | @endcode | ||
| 345 | |||
| 346 | @par Complexity | ||
| 347 | Linear in `name.size() + value.size()`. | ||
| 348 | |||
| 349 | @par Exception Safety | ||
| 350 | Strong guarantee. | ||
| 351 | Calls to allocate may throw. | ||
| 352 | Exception thrown on invalid input. | ||
| 353 | Exception thrown if max capacity exceeded. | ||
| 354 | |||
| 355 | @throw system_error | ||
| 356 | Input is invalid. | ||
| 357 | |||
| 358 | @throw std::length_error | ||
| 359 | Max capacity would be exceeded. | ||
| 360 | |||
| 361 | @param name The header name. | ||
| 362 | |||
| 363 | @param value The header value, which must | ||
| 364 | be semantically valid for the message. | ||
| 365 | */ | ||
| 366 | void | ||
| 367 | 59 | append( | |
| 368 | core::string_view name, | ||
| 369 | core::string_view value) | ||
| 370 | { | ||
| 371 | 59 | system::error_code ec; | |
| 372 |
2/2✓ Branch 1 taken 57 times.
✓ Branch 2 taken 2 times.
|
59 | append(name, value, ec); |
| 373 |
2/2✓ Branch 1 taken 1 times.
✓ Branch 2 taken 56 times.
|
57 | if(ec.failed()) |
| 374 | 1 | detail::throw_system_error(ec); | |
| 375 | 56 | } | |
| 376 | |||
| 377 | /** Append a header. | ||
| 378 | |||
| 379 | This function appends a new header. | ||
| 380 | Existing headers with the same name are | ||
| 381 | not changed. | ||
| 382 | |||
| 383 | Any leading or trailing whitespace in the | ||
| 384 | value is ignored. | ||
| 385 | |||
| 386 | No iterators are invalidated. | ||
| 387 | |||
| 388 | @par Example | ||
| 389 | @code | ||
| 390 | request req; | ||
| 391 | |||
| 392 | req.append( "User-Agent", "Boost" ); | ||
| 393 | @endcode | ||
| 394 | |||
| 395 | @par Complexity | ||
| 396 | Linear in `name.size() + value.size()`. | ||
| 397 | |||
| 398 | @par Exception Safety | ||
| 399 | Strong guarantee. | ||
| 400 | Calls to allocate may throw. | ||
| 401 | Exception thrown if max capacity exceeded. | ||
| 402 | |||
| 403 | @throw std::length_error | ||
| 404 | Max capacity would be exceeded. | ||
| 405 | |||
| 406 | @param name The header name. | ||
| 407 | |||
| 408 | @param value The value which must be semantically | ||
| 409 | valid for the message. | ||
| 410 | |||
| 411 | @param ec Set to the error if input is invalid. | ||
| 412 | */ | ||
| 413 | void | ||
| 414 | 72 | append( | |
| 415 | core::string_view name, | ||
| 416 | core::string_view value, | ||
| 417 | system::error_code& ec) | ||
| 418 | { | ||
| 419 | 72 | insert_impl( | |
| 420 | string_to_field(name), | ||
| 421 | name, | ||
| 422 | value, | ||
| 423 | 72 | h_.count, | |
| 424 | ec); | ||
| 425 | 70 | } | |
| 426 | |||
| 427 | /** Insert a header. | ||
| 428 | |||
| 429 | If a matching header with the same name | ||
| 430 | exists, it is not replaced. Instead, an | ||
| 431 | additional header with the same name is | ||
| 432 | inserted. Names are not case-sensitive. | ||
| 433 | Any leading or trailing whitespace in | ||
| 434 | the new value is ignored. | ||
| 435 | |||
| 436 | All iterators that are equal to `before` | ||
| 437 | or come after are invalidated. | ||
| 438 | |||
| 439 | @par Example | ||
| 440 | @code | ||
| 441 | request req; | ||
| 442 | |||
| 443 | req.insert( req.begin(), field::user_agent, "Boost" ); | ||
| 444 | @endcode | ||
| 445 | |||
| 446 | @par Complexity | ||
| 447 | Linear in `to_string( id ).size() + value.size()`. | ||
| 448 | |||
| 449 | @par Exception Safety | ||
| 450 | Strong guarantee. | ||
| 451 | Calls to allocate may throw. | ||
| 452 | Exception thrown on invalid input. | ||
| 453 | Exception thrown if max capacity exceeded. | ||
| 454 | |||
| 455 | @throw system_error | ||
| 456 | Input is invalid. | ||
| 457 | |||
| 458 | @throw std::length_error | ||
| 459 | Max capacity would be exceeded. | ||
| 460 | |||
| 461 | @return An iterator to the newly inserted header. | ||
| 462 | |||
| 463 | @param before Position to insert before. | ||
| 464 | |||
| 465 | @param id The field name constant. | ||
| 466 | |||
| 467 | @param value The value which must be semantically | ||
| 468 | valid for the message. | ||
| 469 | */ | ||
| 470 | iterator | ||
| 471 | 26 | insert( | |
| 472 | iterator before, | ||
| 473 | field id, | ||
| 474 | core::string_view value) | ||
| 475 | { | ||
| 476 | 26 | system::error_code ec; | |
| 477 |
1/2✓ Branch 1 taken 26 times.
✗ Branch 2 not taken.
|
26 | auto const it = insert( |
| 478 | before, id, value, ec); | ||
| 479 |
2/2✓ Branch 1 taken 1 times.
✓ Branch 2 taken 25 times.
|
26 | if(ec.failed()) |
| 480 | 1 | detail::throw_system_error(ec); | |
| 481 | 25 | return it; | |
| 482 | } | ||
| 483 | |||
| 484 | /** Insert a header. | ||
| 485 | |||
| 486 | If a matching header with the same name | ||
| 487 | exists, it is not replaced. Instead, an | ||
| 488 | additional header with the same name is | ||
| 489 | inserted. Names are not case-sensitive. | ||
| 490 | |||
| 491 | Any leading or trailing whitespace in | ||
| 492 | the new value is ignored. | ||
| 493 | |||
| 494 | All iterators that are equal to `before` | ||
| 495 | or come after are invalidated. | ||
| 496 | |||
| 497 | @par Example | ||
| 498 | @code | ||
| 499 | request req; | ||
| 500 | |||
| 501 | req.insert( req.begin(), field::user_agent, "Boost" ); | ||
| 502 | @endcode | ||
| 503 | |||
| 504 | @par Complexity | ||
| 505 | Linear in `to_string( id ).size() + value.size()`. | ||
| 506 | |||
| 507 | @par Exception Safety | ||
| 508 | Strong guarantee. | ||
| 509 | Calls to allocate may throw. | ||
| 510 | Exception thrown if max capacity exceeded. | ||
| 511 | |||
| 512 | @throw std::length_error | ||
| 513 | Max capacity would be exceeded. | ||
| 514 | |||
| 515 | @return An iterator to the newly inserted header. | ||
| 516 | |||
| 517 | @param before Position to insert before. | ||
| 518 | |||
| 519 | @param id The field name constant. | ||
| 520 | |||
| 521 | @param value The value which must be semantically | ||
| 522 | valid for the message. | ||
| 523 | |||
| 524 | @param ec Set to the error if input is invalid. | ||
| 525 | */ | ||
| 526 | iterator | ||
| 527 | 33 | insert( | |
| 528 | iterator before, | ||
| 529 | field id, | ||
| 530 | core::string_view value, | ||
| 531 | system::error_code& ec) | ||
| 532 | { | ||
| 533 |
2/4✓ Branch 2 taken 33 times.
✗ Branch 3 not taken.
✓ Branch 5 taken 33 times.
✗ Branch 6 not taken.
|
33 | insert_impl( |
| 534 | id, | ||
| 535 | to_string(id), | ||
| 536 | value, | ||
| 537 | before.i_, | ||
| 538 | ec); | ||
| 539 | 33 | return before; | |
| 540 | } | ||
| 541 | |||
| 542 | /** Insert a header. | ||
| 543 | |||
| 544 | If a matching header with the same name | ||
| 545 | exists, it is not replaced. Instead, an | ||
| 546 | additional header with the same name is | ||
| 547 | inserted. Names are not case-sensitive. | ||
| 548 | |||
| 549 | Any leading or trailing whitespace in | ||
| 550 | the new value is ignored. | ||
| 551 | |||
| 552 | All iterators that are equal to `before` | ||
| 553 | or come after are invalidated. | ||
| 554 | |||
| 555 | @par Example | ||
| 556 | @code | ||
| 557 | request req; | ||
| 558 | |||
| 559 | req.insert( req.begin(), "User-Agent", "Boost" ); | ||
| 560 | @endcode | ||
| 561 | |||
| 562 | @par Complexity | ||
| 563 | Linear in `name.size() + value.size()`. | ||
| 564 | |||
| 565 | @par Exception Safety | ||
| 566 | Strong guarantee. | ||
| 567 | Calls to allocate may throw. | ||
| 568 | Exception thrown on invalid input. | ||
| 569 | Exception thrown if max capacity exceeded. | ||
| 570 | |||
| 571 | @throw system_error | ||
| 572 | Input is invalid. | ||
| 573 | |||
| 574 | @throw std::length_error | ||
| 575 | Max capacity would be exceeded. | ||
| 576 | |||
| 577 | @return An iterator to the newly inserted header. | ||
| 578 | |||
| 579 | @param before Position to insert before. | ||
| 580 | |||
| 581 | @param name The header name. | ||
| 582 | |||
| 583 | @param value The value which must be semantically | ||
| 584 | valid for the message. | ||
| 585 | */ | ||
| 586 | iterator | ||
| 587 | 13 | insert( | |
| 588 | iterator before, | ||
| 589 | core::string_view name, | ||
| 590 | core::string_view value) | ||
| 591 | { | ||
| 592 | 13 | system::error_code ec; | |
| 593 |
1/2✓ Branch 1 taken 13 times.
✗ Branch 2 not taken.
|
13 | insert(before, name, value, ec); |
| 594 |
2/2✓ Branch 1 taken 1 times.
✓ Branch 2 taken 12 times.
|
13 | if(ec.failed()) |
| 595 | 1 | detail::throw_system_error(ec); | |
| 596 | 12 | return before; | |
| 597 | } | ||
| 598 | |||
| 599 | /** Insert a header. | ||
| 600 | |||
| 601 | If a matching header with the same name | ||
| 602 | exists, it is not replaced. Instead, an | ||
| 603 | additional header with the same name is | ||
| 604 | inserted. Names are not case-sensitive. | ||
| 605 | |||
| 606 | Any leading or trailing whitespace in | ||
| 607 | the new value is ignored. | ||
| 608 | |||
| 609 | All iterators that are equal to `before` | ||
| 610 | or come after are invalidated. | ||
| 611 | |||
| 612 | @par Example | ||
| 613 | @code | ||
| 614 | request req; | ||
| 615 | |||
| 616 | req.insert( req.begin(), "User-Agent", "Boost" ); | ||
| 617 | @endcode | ||
| 618 | |||
| 619 | @par Complexity | ||
| 620 | Linear in `name.size() + value.size()`. | ||
| 621 | |||
| 622 | @par Exception Safety | ||
| 623 | Strong guarantee. | ||
| 624 | Calls to allocate may throw. | ||
| 625 | Exception thrown if max capacity exceeded. | ||
| 626 | |||
| 627 | @throw std::length_error | ||
| 628 | Max capacity would be exceeded. | ||
| 629 | |||
| 630 | @return An iterator to the newly inserted header. | ||
| 631 | |||
| 632 | @param before Position to insert before. | ||
| 633 | |||
| 634 | @param name The header name. | ||
| 635 | |||
| 636 | @param value The value which must be semantically | ||
| 637 | valid for the message. | ||
| 638 | |||
| 639 | @param ec Set to the error if input is invalid. | ||
| 640 | */ | ||
| 641 | iterator | ||
| 642 | 16 | insert( | |
| 643 | iterator before, | ||
| 644 | core::string_view name, | ||
| 645 | core::string_view value, | ||
| 646 | system::error_code& ec) | ||
| 647 | { | ||
| 648 | 16 | insert_impl( | |
| 649 | string_to_field(name), | ||
| 650 | name, | ||
| 651 | value, | ||
| 652 | before.i_, | ||
| 653 | ec); | ||
| 654 | 16 | return before; | |
| 655 | } | ||
| 656 | |||
| 657 | //-------------------------------------------- | ||
| 658 | |||
| 659 | /** Erase headers. | ||
| 660 | |||
| 661 | This function removes the header pointed | ||
| 662 | to by `it`. | ||
| 663 | |||
| 664 | All iterators that are equal to `it` | ||
| 665 | or come after are invalidated. | ||
| 666 | |||
| 667 | @par Complexity | ||
| 668 | Linear in `name.size() + value.size()`. | ||
| 669 | |||
| 670 | @return An iterator to one past the | ||
| 671 | removed element. | ||
| 672 | |||
| 673 | @param it The iterator to the element | ||
| 674 | to erase. | ||
| 675 | */ | ||
| 676 | BOOST_HTTP_PROTO_DECL | ||
| 677 | iterator | ||
| 678 | erase(iterator it) noexcept; | ||
| 679 | |||
| 680 | /** Erase headers. | ||
| 681 | |||
| 682 | This removes all headers whose name | ||
| 683 | constant is equal to `id`. | ||
| 684 | |||
| 685 | If any headers are erased, then all | ||
| 686 | iterators equal to or that come after | ||
| 687 | the first erased element are invalidated. | ||
| 688 | Otherwise, no iterators are invalidated. | ||
| 689 | |||
| 690 | @par Complexity | ||
| 691 | Linear in `this->string().size()`. | ||
| 692 | |||
| 693 | @return The number of headers erased. | ||
| 694 | |||
| 695 | @param id The field name constant. | ||
| 696 | */ | ||
| 697 | BOOST_HTTP_PROTO_DECL | ||
| 698 | std::size_t | ||
| 699 | erase(field id) noexcept; | ||
| 700 | |||
| 701 | /** Erase all matching fields. | ||
| 702 | |||
| 703 | This removes all headers with a matching | ||
| 704 | name, using a case-insensitive comparison. | ||
| 705 | |||
| 706 | If any headers are erased, then all | ||
| 707 | iterators equal to or that come after | ||
| 708 | the first erased element are invalidated. | ||
| 709 | Otherwise, no iterators are invalidated. | ||
| 710 | |||
| 711 | @par Complexity | ||
| 712 | Linear in `this->string().size()`. | ||
| 713 | |||
| 714 | @return The number of fields erased | ||
| 715 | |||
| 716 | @param name The header name. | ||
| 717 | */ | ||
| 718 | BOOST_HTTP_PROTO_DECL | ||
| 719 | std::size_t | ||
| 720 | erase( | ||
| 721 | core::string_view name) noexcept; | ||
| 722 | |||
| 723 | //-------------------------------------------- | ||
| 724 | |||
| 725 | /** Set a header value. | ||
| 726 | |||
| 727 | Uses the given value to overwrite the | ||
| 728 | current one in the header field pointed to | ||
| 729 | by the iterator. The value must be | ||
| 730 | syntactically valid or else an error is | ||
| 731 | returned. | ||
| 732 | |||
| 733 | Any leading or trailing whitespace in the | ||
| 734 | new value is ignored. | ||
| 735 | |||
| 736 | @par Complexity | ||
| 737 | |||
| 738 | @par Exception Safety | ||
| 739 | Strong guarantee. | ||
| 740 | Calls to allocate may throw. | ||
| 741 | Exception thrown on invalid input. | ||
| 742 | Exception thrown if max capacity exceeded. | ||
| 743 | |||
| 744 | @throw system_error | ||
| 745 | Input is invalid. | ||
| 746 | |||
| 747 | @throw std::length_error | ||
| 748 | Max capacity would be exceeded. | ||
| 749 | |||
| 750 | @param it The iterator to the header. | ||
| 751 | |||
| 752 | @param value The value which must be semantically | ||
| 753 | valid for the message. | ||
| 754 | */ | ||
| 755 | void | ||
| 756 | 27 | set( | |
| 757 | iterator it, | ||
| 758 | core::string_view value) | ||
| 759 | { | ||
| 760 | 27 | system::error_code ec; | |
| 761 |
1/2✓ Branch 1 taken 27 times.
✗ Branch 2 not taken.
|
27 | set(it, value, ec); |
| 762 |
2/2✓ Branch 1 taken 2 times.
✓ Branch 2 taken 25 times.
|
27 | if(ec.failed()) |
| 763 | 2 | detail::throw_system_error(ec); | |
| 764 | 25 | } | |
| 765 | |||
| 766 | /** Set a header value. | ||
| 767 | |||
| 768 | Uses the given value to overwrite the | ||
| 769 | current one in the header field pointed to | ||
| 770 | by the iterator. The value must be | ||
| 771 | syntactically valid or else an error is | ||
| 772 | returned. | ||
| 773 | |||
| 774 | Any leading or trailing whitespace in the | ||
| 775 | new value is ignored. | ||
| 776 | |||
| 777 | @par Complexity | ||
| 778 | |||
| 779 | @par Exception Safety | ||
| 780 | Strong guarantee. | ||
| 781 | Calls to allocate may throw. | ||
| 782 | Exception thrown if max capacity exceeded. | ||
| 783 | |||
| 784 | @throw std::length_error | ||
| 785 | Max capacity would be exceeded. | ||
| 786 | |||
| 787 | @param it The iterator to the header. | ||
| 788 | |||
| 789 | @param value The value which must be semantically | ||
| 790 | valid for the message. | ||
| 791 | |||
| 792 | @param ec Set to the error if input is invalid. | ||
| 793 | */ | ||
| 794 | BOOST_HTTP_PROTO_DECL | ||
| 795 | void | ||
| 796 | set( | ||
| 797 | iterator it, | ||
| 798 | core::string_view value, | ||
| 799 | system::error_code& ec); | ||
| 800 | |||
| 801 | /** Set a header value. | ||
| 802 | |||
| 803 | The container is modified to contain | ||
| 804 | exactly one field with the specified id | ||
| 805 | set to the given value, which must be | ||
| 806 | syntactically valid or else an error is | ||
| 807 | returned. | ||
| 808 | |||
| 809 | Any leading or trailing whitespace in the | ||
| 810 | new value is ignored. | ||
| 811 | |||
| 812 | @par Postconditions | ||
| 813 | @code | ||
| 814 | this->count( id ) == 1 && this->at( id ) == value | ||
| 815 | @endcode | ||
| 816 | |||
| 817 | @par Complexity | ||
| 818 | |||
| 819 | @par Exception Safety | ||
| 820 | Strong guarantee. | ||
| 821 | Calls to allocate may throw. | ||
| 822 | Exception thrown on invalid input. | ||
| 823 | Exception thrown if max capacity exceeded. | ||
| 824 | |||
| 825 | @throw system_error | ||
| 826 | Input is invalid. | ||
| 827 | |||
| 828 | @throw std::length_error | ||
| 829 | Max capacity would be exceeded. | ||
| 830 | |||
| 831 | @param id The field constant of the header | ||
| 832 | to set. | ||
| 833 | |||
| 834 | @param value The value which must be semantically | ||
| 835 | valid for the message. | ||
| 836 | */ | ||
| 837 | void | ||
| 838 | 104 | set( | |
| 839 | field id, | ||
| 840 | core::string_view value) | ||
| 841 | { | ||
| 842 | 104 | system::error_code ec; | |
| 843 |
1/2✓ Branch 1 taken 104 times.
✗ Branch 2 not taken.
|
104 | set(id, value, ec); |
| 844 |
2/2✓ Branch 1 taken 2 times.
✓ Branch 2 taken 102 times.
|
104 | if(ec.failed()) |
| 845 | 2 | detail::throw_system_error(ec); | |
| 846 | 102 | } | |
| 847 | |||
| 848 | /** Set a header value. | ||
| 849 | |||
| 850 | The container is modified to contain | ||
| 851 | exactly one field with the specified id | ||
| 852 | set to the given value, which must be | ||
| 853 | syntactically valid or else an error is | ||
| 854 | returned. | ||
| 855 | |||
| 856 | Any leading or trailing whitespace in the | ||
| 857 | new value is ignored. | ||
| 858 | |||
| 859 | @par Postconditions | ||
| 860 | @code | ||
| 861 | this->count( id ) == 1 && this->at( id ) == value | ||
| 862 | @endcode | ||
| 863 | |||
| 864 | @par Complexity | ||
| 865 | |||
| 866 | @par Exception Safety | ||
| 867 | Strong guarantee. | ||
| 868 | Calls to allocate may throw. | ||
| 869 | Exception thrown if max capacity exceeded. | ||
| 870 | |||
| 871 | @throw std::length_error | ||
| 872 | Max capacity would be exceeded. | ||
| 873 | |||
| 874 | @param id The field name constant. | ||
| 875 | |||
| 876 | @param value The value which must be semantically | ||
| 877 | valid for the message. | ||
| 878 | |||
| 879 | @param ec Set to the error if input is invalid. | ||
| 880 | */ | ||
| 881 | BOOST_HTTP_PROTO_DECL | ||
| 882 | void | ||
| 883 | set( | ||
| 884 | field id, | ||
| 885 | core::string_view value, | ||
| 886 | system::error_code& ec); | ||
| 887 | |||
| 888 | /** Set a header value. | ||
| 889 | |||
| 890 | The container is modified to contain | ||
| 891 | exactly one field with the specified name | ||
| 892 | set to the given value, which must be | ||
| 893 | syntactically valid or else an error is | ||
| 894 | returned. | ||
| 895 | |||
| 896 | Any leading or trailing whitespace in the | ||
| 897 | new value is ignored. | ||
| 898 | |||
| 899 | @par Postconditions | ||
| 900 | @code | ||
| 901 | this->count( name ) == 1 && this->at( name ) == value | ||
| 902 | @endcode | ||
| 903 | |||
| 904 | @par Complexity | ||
| 905 | |||
| 906 | @par Exception Safety | ||
| 907 | Strong guarantee. | ||
| 908 | Calls to allocate may throw. | ||
| 909 | Exception thrown on invalid input. | ||
| 910 | Exception thrown if max capacity exceeded. | ||
| 911 | |||
| 912 | @throw system_error | ||
| 913 | Input is invalid. | ||
| 914 | |||
| 915 | @throw std::length_error | ||
| 916 | Max capacity would be exceeded. | ||
| 917 | |||
| 918 | @param name The field name. | ||
| 919 | |||
| 920 | @param value The value which must be semantically | ||
| 921 | valid for the message. | ||
| 922 | */ | ||
| 923 | void | ||
| 924 | 29 | set( | |
| 925 | core::string_view name, | ||
| 926 | core::string_view value) | ||
| 927 | { | ||
| 928 | 29 | system::error_code ec; | |
| 929 |
2/2✓ Branch 1 taken 28 times.
✓ Branch 2 taken 1 times.
|
29 | set(name, value, ec); |
| 930 |
2/2✓ Branch 1 taken 4 times.
✓ Branch 2 taken 24 times.
|
28 | if(ec.failed()) |
| 931 | 4 | detail::throw_system_error(ec); | |
| 932 | 24 | } | |
| 933 | |||
| 934 | /** Set a header value. | ||
| 935 | |||
| 936 | The container is modified to contain | ||
| 937 | exactly one field with the specified name | ||
| 938 | set to the given value, which must be | ||
| 939 | syntactically valid or else an error is | ||
| 940 | returned. | ||
| 941 | |||
| 942 | Any leading or trailing whitespace in the | ||
| 943 | new value is ignored. | ||
| 944 | |||
| 945 | @par Postconditions | ||
| 946 | @code | ||
| 947 | this->count( name ) == 1 && this->at( name ) == value | ||
| 948 | @endcode | ||
| 949 | |||
| 950 | @par Complexity | ||
| 951 | |||
| 952 | @par Exception Safety | ||
| 953 | Strong guarantee. | ||
| 954 | Calls to allocate may throw. | ||
| 955 | Exception thrown if max capacity exceeded. | ||
| 956 | |||
| 957 | @throw std::length_error | ||
| 958 | Max capacity would be exceeded. | ||
| 959 | |||
| 960 | @param name The field name. | ||
| 961 | |||
| 962 | @param value The value which must be semantically | ||
| 963 | valid for the message. | ||
| 964 | |||
| 965 | @param ec Set to the error if input is invalid. | ||
| 966 | */ | ||
| 967 | BOOST_HTTP_PROTO_DECL | ||
| 968 | void | ||
| 969 | set( | ||
| 970 | core::string_view name, | ||
| 971 | core::string_view value, | ||
| 972 | system::error_code& ec); | ||
| 973 | |||
| 974 | private: | ||
| 975 | BOOST_HTTP_PROTO_DECL | ||
| 976 | void | ||
| 977 | copy_impl( | ||
| 978 | detail::header const&); | ||
| 979 | |||
| 980 | BOOST_HTTP_PROTO_DECL | ||
| 981 | void | ||
| 982 | insert_impl( | ||
| 983 | optional<field> id, | ||
| 984 | core::string_view name, | ||
| 985 | core::string_view value, | ||
| 986 | std::size_t before, | ||
| 987 | system::error_code& ec); | ||
| 988 | |||
| 989 | void | ||
| 990 | insert_unchecked( | ||
| 991 | optional<field> id, | ||
| 992 | core::string_view name, | ||
| 993 | core::string_view value, | ||
| 994 | std::size_t before, | ||
| 995 | bool has_obs_fold); | ||
| 996 | |||
| 997 | void | ||
| 998 | raw_erase( | ||
| 999 | std::size_t) noexcept; | ||
| 1000 | |||
| 1001 | void | ||
| 1002 | raw_erase_n(field, std::size_t) noexcept; | ||
| 1003 | |||
| 1004 | std::size_t | ||
| 1005 | erase_all( | ||
| 1006 | std::size_t i0, | ||
| 1007 | field id) noexcept; | ||
| 1008 | |||
| 1009 | std::size_t | ||
| 1010 | erase_all( | ||
| 1011 | std::size_t i0, | ||
| 1012 | core::string_view name) noexcept; | ||
| 1013 | |||
| 1014 | std::size_t | ||
| 1015 | offset( | ||
| 1016 | std::size_t i) const noexcept; | ||
| 1017 | |||
| 1018 | std::size_t | ||
| 1019 | length( | ||
| 1020 | std::size_t i) const noexcept; | ||
| 1021 | }; | ||
| 1022 | |||
| 1023 | } // http_proto | ||
| 1024 | } // boost | ||
| 1025 | |||
| 1026 | #endif | ||
| 1027 |