GCC Code Coverage Report


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