GCC Code Coverage Report


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