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 |