GCC Code Coverage Report


Directory: ./
File: libs/http_proto/include/boost/http_proto/fields_base.hpp
Date: 2025-12-09 20:49:49
Exec Total Coverage
Lines: 43 43 100.0%
Functions: 11 11 100.0%
Branches: 14 14 100.0%

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/detail/header.hpp>
18 #include <boost/core/detail/string_view.hpp>
19
20 #include <iosfwd>
21
22 #if defined(BOOST_MSVC)
23 # pragma warning(push)
24 # pragma warning(disable:4251)
25 #endif
26
27 namespace boost {
28 namespace http_proto {
29
30 /** Mixin for modifiable HTTP fields.
31
32 @par Iterators
33
34 Iterators obtained from @ref fields
35 containers are not invalidated when
36 the underlying container is modified.
37
38 @note HTTP field names are case-insensitive.
39 */
40 class BOOST_HTTP_PROTO_DECL fields_base
41 {
42 detail::header h_;
43 std::size_t max_cap_ =
44 std::numeric_limits<std::size_t>::max();
45 bool external_storage_ = false;
46
47 using entry =
48 detail::header::entry;
49 using offset_type =
50 detail::header::offset_type;
51 using table =
52 detail::header::table;
53
54 class op_t;
55 class prefix_op_t
56 {
57 fields_base& self_;
58 offset_type new_prefix_;
59 char* buf_ = nullptr;
60
61 public:
62 prefix_op_t(
63 fields_base& self,
64 std::size_t new_prefix,
65 core::string_view* s0 = nullptr,
66 core::string_view* s1 = nullptr);
67
68 ~prefix_op_t();
69 };
70
71 friend class fields;
72 friend class message_base;
73 friend class request_base;
74 friend class request;
75 friend class static_request;
76 friend class response_base;
77 friend class response;
78 friend class static_response;
79 friend class parser;
80 friend class serializer;
81
82
83 explicit
84 fields_base(
85 detail::kind k) noexcept;
86
87
88 fields_base(
89 detail::kind k,
90 void* storage,
91 std::size_t cap) noexcept;
92
93
94 fields_base(
95 detail::kind k,
96 core::string_view s);
97
98
99 explicit
100 fields_base(
101 detail::header const& h);
102
103
104 fields_base(
105 fields_base const&);
106
107
108 fields_base(
109 detail::header const& h,
110 void* storage,
111 std::size_t cap);
112
113 public:
114 //--------------------------------------------
115 //
116 // Types
117 //
118 //--------------------------------------------
119
120 /** A view to an HTTP field.
121
122 The view will be invalidated when the
123 underlying container is modified.
124
125 The caller is responsible for ensuring
126 that the lifetime of the container extends
127 until it is no longer referenced.
128 */
129 struct reference
130 {
131 /** Field name constant.
132
133 Set to `boost::none` if the constant
134 does not exist in @ref field.
135 */
136 boost::optional<field> const id;
137
138 /// A view to the field name.
139 core::string_view const name;
140
141 /// A view to the field value.
142 core::string_view const value;
143
144 reference const*
145 1731 operator->() const noexcept
146 {
147 1731 return this;
148 }
149 };
150
151 /// @copydoc reference
152 typedef reference const_reference;
153
154 /** A value type which represent an HTTP field.
155
156 This type allows for making a copy of
157 a field where ownership is retained
158 in the copy.
159 */
160 struct value_type
161 {
162 /** Field name constant.
163
164 Set to `boost::none` if the
165 constant does not exist in @ref field.
166 */
167 boost::optional<field> id;
168
169 /// Field name.
170 std::string name;
171
172 /// Field value.
173 std::string value;
174
175 /// Constructor.
176
177 value_type(
178 reference const& other);
179
180 /** Conversion.
181
182 @see
183 @ref reference.
184
185 @return A view to the fields.
186 */
187 operator reference() const noexcept;
188 };
189
190 /** A bidirectional iterator to HTTP fields.
191 */
192 class iterator;
193
194 /// @copydoc iterator
195 using const_iterator = iterator;
196
197 /** A bidirectional reverse iterator to HTTP fields.
198 */
199 class reverse_iterator;
200
201 /// @copydoc iterator
202 using const_reverse_iterator = reverse_iterator;
203
204 /** A forward range of matching fields.
205
206 Objects of this type are returned by
207 the function @ref find_all.
208 */
209 class subrange;
210
211 //--------------------------------------------
212 //
213 // Special Members
214 //
215 //--------------------------------------------
216
217 /** Destructor.
218 */
219
220 ~fields_base();
221
222 //--------------------------------------------
223 //
224 // Observers
225 //
226 //--------------------------------------------
227
228 /** Return the largest possible serialized message.
229 */
230 static
231 constexpr
232 std::size_t
233 max_size() noexcept
234 {
235 // TODO: this doesn't take into account
236 // the start-line
237 return detail::header::max_offset;
238 }
239
240 /** Return an iterator to the beginning.
241 */
242 iterator
243 begin() const noexcept;
244
245 /** Return an iterator to the end.
246 */
247 iterator
248 end() const noexcept;
249
250 /** Return a reverse iterator to the beginning.
251 */
252 reverse_iterator
253 rbegin() const noexcept;
254
255 /** Return a reverse iterator to the end.
256 */
257 reverse_iterator
258 rend() const noexcept;
259
260 /** Return a string view representing the serialized data.
261 */
262 core::string_view
263 690 buffer() const noexcept
264 {
265 1380 return core::string_view(
266 690 h_.cbuf, h_.size);
267 }
268
269 /** Return the number of fields in the container.
270 */
271 std::size_t
272 185 size() const noexcept
273 {
274 185 return h_.count;
275 }
276
277 /** Return the value of a field, or throws an exception.
278
279 If more than one field with the specified
280 name exists, the first field defined by
281 insertion order is returned.
282
283 @par Exception Safety
284 Strong guarantee.
285
286 @throw std::out_of_range
287 Field is not found.
288
289 @param id The field name constant.
290 */
291
292 core::string_view
293 at(field id) const;
294
295 /** Return the value of a field, or throws an exception.
296
297 If more than one field with the specified
298 name exists, the first field defined by
299 insertion order is returned.
300
301 If `name` refers to a known field, it is
302 faster to call @ref at with a field id
303 instead of a string.
304
305 @par Exception Safety
306 Strong guarantee.
307
308 @throw std::out_of_range
309 Field is not found.
310
311 @param name The field name.
312 */
313
314 core::string_view
315 at(core::string_view name) const;
316
317 /** Return true if a field exists.
318 */
319
320 bool
321 exists(field id) const noexcept;
322
323 /** Return true if a field exists.
324
325 If `name` refers to a known field,
326 it is faster to call @ref exists
327 with a field id instead of a string.
328
329 @param name The field name.
330 */
331
332 bool
333 exists(
334 core::string_view name) const noexcept;
335
336 /** Return the number of matching fields.
337
338 @param id The field name constant.
339 */
340
341 std::size_t
342 count(field id) const noexcept;
343
344 /** Return the number of matching fields.
345
346 If `name` refers to a known field,
347 it is faster to call @ref count
348 with a field id instead of a string.
349
350 @param name The field name.
351 */
352
353 std::size_t
354 count(
355 core::string_view name) const noexcept;
356
357 /** Return an iterator to the matching element if it exists.
358
359 @param id The field name constant.
360 */
361
362 iterator
363 find(field id) const noexcept;
364
365 /** Return an iterator to the matching element if it exists.
366
367 If `name` refers to a known field,
368 it is faster to call @ref find
369 with a field id instead of a string.
370
371 @param name The field name.
372 */
373
374 iterator
375 find(
376 core::string_view name) const noexcept;
377
378 /** Return an iterator to the matching element if it exists.
379
380 @param from The position to begin the
381 search from. This can be `end()`.
382
383 @param id The field name constant.
384 */
385
386 iterator
387 find(
388 iterator from,
389 field id) const noexcept;
390
391 /** Return an iterator to the matching element if it exists.
392
393 If `name` refers to a known field,
394 it is faster to call @ref find
395 with a field id instead of a string.
396
397 @param from The position to begin the
398 search from. This can be `end()`.
399
400 @param name The field name.
401 */
402
403 iterator
404 find(
405 iterator from,
406 core::string_view name) const noexcept;
407
408 /** Return an iterator to the matching element if it exists.
409
410 @param before One past the position
411 to begin the search from. This can
412 be `end()`.
413
414 @param id The field name constant.
415 */
416
417 iterator
418 find_last(
419 iterator before,
420 field id) const noexcept;
421
422 /** Return an iterator to the matching element if it exists.
423
424 If `name` refers to a known field,
425 it is faster to call @ref find_last
426 with a field id instead of a string.
427
428 @param before One past the position
429 to begin the search from. This can
430 be `end()`.
431
432 @param name The field name.
433 */
434
435 iterator
436 find_last(
437 iterator before,
438 core::string_view name) const noexcept;
439
440 /** Return the value of a field or a default if missing.
441
442 @param id The field name constant.
443
444 @param s The value to be returned if
445 field does not exist.
446 */
447
448 core::string_view
449 value_or(
450 field id,
451 core::string_view s) const noexcept;
452
453 /** Return the value of a field or a default if missing.
454
455 If `name` refers to a known field,
456 it is faster to call @ref value_or
457 with a field id instead of a string.
458
459 @param name The field name.
460
461 @param s The value to be returned if
462 field does not exist.
463 */
464
465 core::string_view
466 value_or(
467 core::string_view name,
468 core::string_view s) const noexcept;
469
470 /** Return a forward range containing values for all matching fields.
471
472 @param id The field name constant.
473 */
474
475 subrange
476 find_all(field id) const noexcept;
477
478 /** Return a forward range containing values for all matching fields.
479
480 If `name` refers to a known field,
481 it is faster to call @ref find_all
482 with a field id instead of a string.
483
484 @param name The field name.
485 */
486
487 subrange
488 find_all(
489 core::string_view name) const noexcept;
490
491 //--------------------------------------------
492 //
493 // Capacity
494 //
495 //--------------------------------------------
496
497 /** Return the maximum allowed capacity in bytes.
498 */
499 std::size_t
500 24 max_capacity_in_bytes() noexcept
501 {
502 24 return max_cap_;
503 }
504
505 /** Return the total number of bytes allocated by the container.
506 */
507 std::size_t
508 105 capacity_in_bytes() const noexcept
509 {
510 105 return h_.cap;
511 }
512
513 /** Clear contents while preserving the capacity.
514
515 In the case of response and request
516 containers the start-line also resets to
517 default.
518
519 @par Postconditions
520 @code
521 this->size() == 0
522 @endcode
523
524 @par Complexity
525 Constant.
526 */
527
528 void
529 clear() noexcept;
530
531 /** Adjust the capacity without changing the size.
532
533 This function adjusts the capacity
534 of the container in bytes, without
535 affecting the current contents. Has
536 no effect if `n <= this->capacity_in_bytes()`.
537
538 @par Postconditions
539 @code
540 this->capacity_in_bytes() >= n
541 @endcode
542
543 @par Exception Safety
544 Strong guarantee.
545 Calls to allocate may throw.
546 Exception thrown if max capacity exceeded.
547
548 @throw std::length_error
549 Max capacity would be exceeded.
550
551 @param n The capacity in bytes.
552 */
553
554 void
555 reserve_bytes(std::size_t n);
556
557 /** Set the maximum allowed capacity in bytes.
558
559 Prevents the container from growing beyond
560 `n` bytes. Exceeding this limit will throw
561 an exception.
562
563 @par Preconditions
564 @code
565 this->capacity_in_bytes() <= n
566 @endcode
567
568 @par Postconditions
569 @code
570 this->max_capacity_in_bytes() == n
571 @endcode
572
573 @par Exception Safety
574 Strong guarantee.
575 Exception thrown on invalid input.
576
577 @throw std::invalid_argument
578 `n < this->capacity_in_bytes()`
579
580 @param n The maximum allowed capacity in bytes.
581 */
582
583 void
584 set_max_capacity_in_bytes(std::size_t n);
585
586 /** Remove excess capacity.
587
588 @par Exception Safety
589 Strong guarantee.
590 Calls to allocate may throw.
591 */
592
593 void
594 shrink_to_fit();
595
596 //--------------------------------------------
597 //
598 // Modifiers
599 //
600 //--------------------------------------------
601
602 /** Append a header.
603
604 This function appends a new header.
605 Existing headers with the same name are
606 not changed.
607
608 Any leading or trailing whitespace in the
609 value is ignored.
610
611 No iterators are invalidated.
612
613 @par Example
614 @code
615 request req;
616
617 req.append( field::user_agent, "Boost" );
618 @endcode
619
620 @par Complexity
621 Linear in `to_string( id ).size() + value.size()`.
622
623 @par Exception Safety
624 Strong guarantee.
625 Calls to allocate may throw.
626 Exception thrown on invalid input.
627 Exception thrown if max capacity exceeded.
628
629 @throw system_error
630 Input is invalid.
631
632 @throw std::length_error
633 Max capacity would be exceeded.
634
635 @param id The field name constant.
636
637 @param value The value which must be semantically
638 valid for the message.
639 */
640 void
641 93 append(
642 field id,
643 core::string_view value)
644 {
645 93 system::error_code ec;
646
1/1
✓ Branch 1 taken 89 times.
93 append(id, value, ec);
647
2/2
✓ Branch 1 taken 3 times.
✓ Branch 2 taken 86 times.
89 if(ec.failed())
648 3 detail::throw_system_error(ec);
649 86 }
650
651 /** Append a header.
652
653 This function appends a new header.
654 Existing headers with the same name are
655 not changed.
656
657 Any leading or trailing whitespace in the
658 value is ignored.
659
660 No iterators are invalidated.
661
662 @par Example
663 @code
664 request req;
665
666 req.append( field::user_agent, "Boost" );
667 @endcode
668
669 @par Complexity
670 Linear in `to_string( id ).size() + value.size()`.
671
672 @par Exception Safety
673 Strong guarantee.
674 Calls to allocate may throw.
675 Exception thrown if max capacity exceeded.
676
677 @throw std::length_error
678 Max capacity would be exceeded.
679
680 @param id The field name constant.
681
682 @param value The value which must be semantically
683 valid for the message.
684
685 @param ec Set to the error if input is invalid.
686 */
687 void
688 93 append(
689 field id,
690 core::string_view value,
691 system::error_code& ec)
692 {
693
2/2
✓ Branch 1 taken 93 times.
✓ Branch 4 taken 89 times.
93 insert_impl(
694 id,
695 to_string(id),
696 value,
697 93 h_.count,
698 ec);
699 89 }
700
701 /** Append a header.
702
703 This function appends a new header.
704 Existing headers with the same name are
705 not changed.
706
707 Any leading or trailing whitespace in the
708 value is ignored.
709
710 No iterators are invalidated.
711
712 @par Example
713 @code
714 request req;
715
716 req.append( "User-Agent", "Boost" );
717 @endcode
718
719 @par Complexity
720 Linear in `name.size() + value.size()`.
721
722 @par Exception Safety
723 Strong guarantee.
724 Calls to allocate may throw.
725 Exception thrown on invalid input.
726 Exception thrown if max capacity exceeded.
727
728 @throw system_error
729 Input is invalid.
730
731 @throw std::length_error
732 Max capacity would be exceeded.
733
734 @param name The header name.
735
736 @param value The header value, which must
737 be semantically valid for the message.
738 */
739 void
740 48 append(
741 core::string_view name,
742 core::string_view value)
743 {
744 48 system::error_code ec;
745
1/1
✓ Branch 1 taken 46 times.
48 append(name, value, ec);
746
2/2
✓ Branch 1 taken 1 times.
✓ Branch 2 taken 45 times.
46 if(ec.failed())
747 1 detail::throw_system_error(ec);
748 45 }
749
750 /** Append a header.
751
752 This function appends a new header.
753 Existing headers with the same name are
754 not changed.
755
756 Any leading or trailing whitespace in the
757 value is ignored.
758
759 No iterators are invalidated.
760
761 @par Example
762 @code
763 request req;
764
765 req.append( "User-Agent", "Boost" );
766 @endcode
767
768 @par Complexity
769 Linear in `name.size() + value.size()`.
770
771 @par Exception Safety
772 Strong guarantee.
773 Calls to allocate may throw.
774 Exception thrown if max capacity exceeded.
775
776 @throw std::length_error
777 Max capacity would be exceeded.
778
779 @param name The header name.
780
781 @param value The value which must be semantically
782 valid for the message.
783
784 @param ec Set to the error if input is invalid.
785 */
786 void
787 61 append(
788 core::string_view name,
789 core::string_view value,
790 system::error_code& ec)
791 {
792 61 insert_impl(
793 string_to_field(name),
794 name,
795 value,
796 61 h_.count,
797 ec);
798 59 }
799
800 /** Insert a header.
801
802 If a matching header with the same name
803 exists, it is not replaced. Instead, an
804 additional header with the same name is
805 inserted. Names are not case-sensitive.
806 Any leading or trailing whitespace in
807 the new value is ignored.
808
809 All iterators that are equal to `before`
810 or come after are invalidated.
811
812 @par Example
813 @code
814 request req;
815
816 req.insert( req.begin(), field::user_agent, "Boost" );
817 @endcode
818
819 @par Complexity
820 Linear in `to_string( id ).size() + value.size()`.
821
822 @par Exception Safety
823 Strong guarantee.
824 Calls to allocate may throw.
825 Exception thrown on invalid input.
826 Exception thrown if max capacity exceeded.
827
828 @throw system_error
829 Input is invalid.
830
831 @throw std::length_error
832 Max capacity would be exceeded.
833
834 @return An iterator to the newly inserted header.
835
836 @param before Position to insert before.
837
838 @param id The field name constant.
839
840 @param value The value which must be semantically
841 valid for the message.
842 */
843
844 iterator
845 insert(
846 iterator before,
847 field id,
848 core::string_view value);
849
850 /** Insert a header.
851
852 If a matching header with the same name
853 exists, it is not replaced. Instead, an
854 additional header with the same name is
855 inserted. Names are not case-sensitive.
856
857 Any leading or trailing whitespace in
858 the new value is ignored.
859
860 All iterators that are equal to `before`
861 or come after are invalidated.
862
863 @par Example
864 @code
865 request req;
866
867 req.insert( req.begin(), field::user_agent, "Boost" );
868 @endcode
869
870 @par Complexity
871 Linear in `to_string( id ).size() + value.size()`.
872
873 @par Exception Safety
874 Strong guarantee.
875 Calls to allocate may throw.
876 Exception thrown if max capacity exceeded.
877
878 @throw std::length_error
879 Max capacity would be exceeded.
880
881 @return An iterator to the newly inserted header.
882
883 @param before Position to insert before.
884
885 @param id The field name constant.
886
887 @param value The value which must be semantically
888 valid for the message.
889
890 @param ec Set to the error if input is invalid.
891 */
892
893 iterator
894 insert(
895 iterator before,
896 field id,
897 core::string_view value,
898 system::error_code& ec);
899
900 /** Insert a header.
901
902 If a matching header with the same name
903 exists, it is not replaced. Instead, an
904 additional header with the same name is
905 inserted. Names are not case-sensitive.
906
907 Any leading or trailing whitespace in
908 the new value is ignored.
909
910 All iterators that are equal to `before`
911 or come after are invalidated.
912
913 @par Example
914 @code
915 request req;
916
917 req.insert( req.begin(), "User-Agent", "Boost" );
918 @endcode
919
920 @par Complexity
921 Linear in `name.size() + value.size()`.
922
923 @par Exception Safety
924 Strong guarantee.
925 Calls to allocate may throw.
926 Exception thrown on invalid input.
927 Exception thrown if max capacity exceeded.
928
929 @throw system_error
930 Input is invalid.
931
932 @throw std::length_error
933 Max capacity would be exceeded.
934
935 @return An iterator to the newly inserted header.
936
937 @param before Position to insert before.
938
939 @param name The header name.
940
941 @param value The value which must be semantically
942 valid for the message.
943 */
944
945 iterator
946 insert(
947 iterator before,
948 core::string_view name,
949 core::string_view value);
950
951 /** Insert a header.
952
953 If a matching header with the same name
954 exists, it is not replaced. Instead, an
955 additional header with the same name is
956 inserted. Names are not case-sensitive.
957
958 Any leading or trailing whitespace in
959 the new value is ignored.
960
961 All iterators that are equal to `before`
962 or come after are invalidated.
963
964 @par Example
965 @code
966 request req;
967
968 req.insert( req.begin(), "User-Agent", "Boost" );
969 @endcode
970
971 @par Complexity
972 Linear in `name.size() + value.size()`.
973
974 @par Exception Safety
975 Strong guarantee.
976 Calls to allocate may throw.
977 Exception thrown if max capacity exceeded.
978
979 @throw std::length_error
980 Max capacity would be exceeded.
981
982 @return An iterator to the newly inserted header.
983
984 @param before Position to insert before.
985
986 @param name The header name.
987
988 @param value The value which must be semantically
989 valid for the message.
990
991 @param ec Set to the error if input is invalid.
992 */
993
994 iterator
995 insert(
996 iterator before,
997 core::string_view name,
998 core::string_view value,
999 system::error_code& ec);
1000
1001 //--------------------------------------------
1002
1003 /** Erase headers.
1004
1005 This function removes the header pointed
1006 to by `it`.
1007
1008 All iterators that are equal to `it`
1009 or come after are invalidated.
1010
1011 @par Complexity
1012 Linear in `name.size() + value.size()`.
1013
1014 @return An iterator to one past the
1015 removed element.
1016
1017 @param it The iterator to the element
1018 to erase.
1019 */
1020
1021 iterator
1022 erase(iterator it) noexcept;
1023
1024 /** Erase headers.
1025
1026 This removes all headers whose name
1027 constant is equal to `id`.
1028
1029 If any headers are erased, then all
1030 iterators equal to or that come after
1031 the first erased element are invalidated.
1032 Otherwise, no iterators are invalidated.
1033
1034 @par Complexity
1035 Linear in `this->string().size()`.
1036
1037 @return The number of headers erased.
1038
1039 @param id The field name constant.
1040 */
1041
1042 std::size_t
1043 erase(field id) noexcept;
1044
1045 /** Erase all matching fields.
1046
1047 This removes all headers with a matching
1048 name, using a case-insensitive comparison.
1049
1050 If any headers are erased, then all
1051 iterators equal to or that come after
1052 the first erased element are invalidated.
1053 Otherwise, no iterators are invalidated.
1054
1055 @par Complexity
1056 Linear in `this->string().size()`.
1057
1058 @return The number of fields erased
1059
1060 @param name The header name.
1061 */
1062
1063 std::size_t
1064 erase(
1065 core::string_view name) noexcept;
1066
1067 //--------------------------------------------
1068
1069 /** Set a header value.
1070
1071 Uses the given value to overwrite the
1072 current one in the header field pointed to
1073 by the iterator. The value must be
1074 syntactically valid or else an error is
1075 returned.
1076
1077 Any leading or trailing whitespace in the
1078 new value is ignored.
1079
1080 @par Complexity
1081
1082 @par Exception Safety
1083 Strong guarantee.
1084 Calls to allocate may throw.
1085 Exception thrown on invalid input.
1086 Exception thrown if max capacity exceeded.
1087
1088 @throw system_error
1089 Input is invalid.
1090
1091 @throw std::length_error
1092 Max capacity would be exceeded.
1093
1094 @param it The iterator to the header.
1095
1096 @param value The value which must be semantically
1097 valid for the message.
1098 */
1099
1100 void
1101 set(iterator it, core::string_view value);
1102
1103 /** Set a header value.
1104
1105 Uses the given value to overwrite the
1106 current one in the header field pointed to
1107 by the iterator. The value must be
1108 syntactically valid or else an error is
1109 returned.
1110
1111 Any leading or trailing whitespace in the
1112 new value is ignored.
1113
1114 @par Complexity
1115
1116 @par Exception Safety
1117 Strong guarantee.
1118 Calls to allocate may throw.
1119 Exception thrown if max capacity exceeded.
1120
1121 @throw std::length_error
1122 Max capacity would be exceeded.
1123
1124 @param it The iterator to the header.
1125
1126 @param value The value which must be semantically
1127 valid for the message.
1128
1129 @param ec Set to the error if input is invalid.
1130 */
1131
1132 void
1133 set(
1134 iterator it,
1135 core::string_view value,
1136 system::error_code& ec);
1137
1138 /** Set a header value.
1139
1140 The container is modified to contain
1141 exactly one field with the specified id
1142 set to the given value, which must be
1143 syntactically valid or else an error is
1144 returned.
1145
1146 Any leading or trailing whitespace in the
1147 new value is ignored.
1148
1149 @par Postconditions
1150 @code
1151 this->count( id ) == 1 && this->at( id ) == value
1152 @endcode
1153
1154 @par Complexity
1155
1156 @par Exception Safety
1157 Strong guarantee.
1158 Calls to allocate may throw.
1159 Exception thrown on invalid input.
1160 Exception thrown if max capacity exceeded.
1161
1162 @throw system_error
1163 Input is invalid.
1164
1165 @throw std::length_error
1166 Max capacity would be exceeded.
1167
1168 @param id The field constant of the header
1169 to set.
1170
1171 @param value The value which must be semantically
1172 valid for the message.
1173 */
1174 void
1175 106 set(
1176 field id,
1177 core::string_view value)
1178 {
1179 106 system::error_code ec;
1180
1/1
✓ Branch 1 taken 106 times.
106 set(id, value, ec);
1181
2/2
✓ Branch 1 taken 2 times.
✓ Branch 2 taken 104 times.
106 if(ec.failed())
1182 2 detail::throw_system_error(ec);
1183 104 }
1184
1185 /** Set a header value.
1186
1187 The container is modified to contain
1188 exactly one field with the specified id
1189 set to the given value, which must be
1190 syntactically valid or else an error is
1191 returned.
1192
1193 Any leading or trailing whitespace in the
1194 new value is ignored.
1195
1196 @par Postconditions
1197 @code
1198 this->count( id ) == 1 && this->at( id ) == value
1199 @endcode
1200
1201 @par Complexity
1202
1203 @par Exception Safety
1204 Strong guarantee.
1205 Calls to allocate may throw.
1206 Exception thrown if max capacity exceeded.
1207
1208 @throw std::length_error
1209 Max capacity would be exceeded.
1210
1211 @param id The field name constant.
1212
1213 @param value The value which must be semantically
1214 valid for the message.
1215
1216 @param ec Set to the error if input is invalid.
1217 */
1218
1219 void
1220 set(
1221 field id,
1222 core::string_view value,
1223 system::error_code& ec);
1224
1225 /** Set a header value.
1226
1227 The container is modified to contain
1228 exactly one field with the specified name
1229 set to the given value, which must be
1230 syntactically valid or else an error is
1231 returned.
1232
1233 Any leading or trailing whitespace in the
1234 new value is ignored.
1235
1236 @par Postconditions
1237 @code
1238 this->count( name ) == 1 && this->at( name ) == value
1239 @endcode
1240
1241 @par Complexity
1242
1243 @par Exception Safety
1244 Strong guarantee.
1245 Calls to allocate may throw.
1246 Exception thrown on invalid input.
1247 Exception thrown if max capacity exceeded.
1248
1249 @throw system_error
1250 Input is invalid.
1251
1252 @throw std::length_error
1253 Max capacity would be exceeded.
1254
1255 @param name The field name.
1256
1257 @param value The value which must be semantically
1258 valid for the message.
1259 */
1260 void
1261 28 set(
1262 core::string_view name,
1263 core::string_view value)
1264 {
1265 28 system::error_code ec;
1266
1/1
✓ Branch 1 taken 27 times.
28 set(name, value, ec);
1267
2/2
✓ Branch 1 taken 4 times.
✓ Branch 2 taken 23 times.
27 if(ec.failed())
1268 4 detail::throw_system_error(ec);
1269 23 }
1270
1271 /** Set a header value.
1272
1273 The container is modified to contain
1274 exactly one field with the specified name
1275 set to the given value, which must be
1276 syntactically valid or else an error is
1277 returned.
1278
1279 Any leading or trailing whitespace in the
1280 new value is ignored.
1281
1282 @par Postconditions
1283 @code
1284 this->count( name ) == 1 && this->at( name ) == value
1285 @endcode
1286
1287 @par Complexity
1288
1289 @par Exception Safety
1290 Strong guarantee.
1291 Calls to allocate may throw.
1292 Exception thrown if max capacity exceeded.
1293
1294 @throw std::length_error
1295 Max capacity would be exceeded.
1296
1297 @param name The field name.
1298
1299 @param value The value which must be semantically
1300 valid for the message.
1301
1302 @param ec Set to the error if input is invalid.
1303 */
1304
1305 void
1306 set(
1307 core::string_view name,
1308 core::string_view value,
1309 system::error_code& ec);
1310
1311 //--------------------------------------------
1312
1313 /** Format the container to the output stream
1314
1315 This function serializes the container to
1316 the specified output stream.
1317
1318 @par Example
1319 @code
1320 request req;
1321 req.set(field::content_length, "42");
1322 std::stringstream ss;
1323 ss << req;
1324 assert( ss.str() == "GET / HTTP/1.1\nContent-Length: 42\n" );
1325 @endcode
1326
1327 @par Effects
1328 @code
1329 return os << f.buffer();
1330 @endcode
1331
1332 @par Complexity
1333 Linear in `f.buffer().size()`
1334
1335 @par Exception Safety
1336 Basic guarantee.
1337
1338 @return A reference to the output stream, for chaining
1339
1340 @param os The output stream to write to.
1341
1342 @param f The container to write.
1343 */
1344 friend
1345
1346 BOOST_HTTP_PROTO_DECL
1347 std::ostream&
1348 operator<<(
1349 std::ostream& os,
1350 const fields_base& f);
1351
1352 private:
1353
1354 void
1355 copy_impl(
1356 detail::header const&);
1357
1358
1359 void
1360 insert_impl(
1361 optional<field> id,
1362 core::string_view name,
1363 core::string_view value,
1364 std::size_t before,
1365 system::error_code& ec);
1366
1367 void
1368 insert_unchecked(
1369 optional<field> id,
1370 core::string_view name,
1371 core::string_view value,
1372 std::size_t before,
1373 bool has_obs_fold);
1374
1375 void
1376 raw_erase(
1377 std::size_t) noexcept;
1378
1379 void
1380 raw_erase_n(field, std::size_t) noexcept;
1381
1382 std::size_t
1383 erase_all(
1384 std::size_t i0,
1385 field id) noexcept;
1386
1387 std::size_t
1388 erase_all(
1389 std::size_t i0,
1390 core::string_view name) noexcept;
1391
1392 std::size_t
1393 offset(
1394 std::size_t i) const noexcept;
1395
1396 std::size_t
1397 length(
1398 std::size_t i) const noexcept;
1399 };
1400
1401 } // http_proto
1402 } // boost
1403
1404 #include <boost/http_proto/impl/fields_base.hpp>
1405
1406 #if defined(BOOST_MSVC)
1407 # pragma warning(pop)
1408 #endif
1409
1410 #endif
1411