GCC Code Coverage Report


Directory: ./
File: libs/http/include/boost/http/impl/parser.hpp
Date: 2026-01-15 20:43:58
Exec Total Coverage
Lines: 36 45 80.0%
Functions: 19 21 90.5%
Branches: 6 12 50.0%

Line Branch Exec Source
1 //
2 // Copyright (c) 2019 Vinnie Falco (vinnie.falco@gmail.com)
3 //
4 // Distributed under the Boost Software License, Version 1.0. (See accompanying
5 // file LICENSE_1_0.txt or copy at http://www.boost.org/LICENSE_1_0.txt)
6 //
7 // Official repository: https://github.com/cppalliance/http
8 //
9
10 // we need a pragma once for the circular includes required
11 // clangd's intellisense
12 #pragma once
13
14 #ifndef BOOST_HTTP_IMPL_PARSER_HPP
15 #define BOOST_HTTP_IMPL_PARSER_HPP
16
17 #include <boost/http/parser.hpp>
18 #include <boost/http/sink.hpp>
19 #include <boost/http/detail/type_traits.hpp>
20
21 namespace boost {
22 namespace http {
23 namespace detail {
24
25 // A wrapper that provides reference semantics for dynamic buffers
26 // while satisfying the dynamic_buffer concept
27 template<class DynamicBuffer>
28 class dynamic_buffer_ref
29 {
30 DynamicBuffer* p_;
31
32 public:
33 using const_buffers_type = typename DynamicBuffer::const_buffers_type;
34 using mutable_buffers_type = typename DynamicBuffer::mutable_buffers_type;
35
36 explicit
37 372 dynamic_buffer_ref(DynamicBuffer& b) noexcept
38 372 : p_(&b)
39 {
40 372 }
41
42 std::size_t
43 54726 size() const noexcept
44 {
45 54726 return p_->size();
46 }
47
48 std::size_t
49 36569 max_size() const noexcept
50 {
51 36569 return p_->max_size();
52 }
53
54 std::size_t
55 18157 capacity() const noexcept
56 {
57 18157 return p_->capacity();
58 }
59
60 const_buffers_type
61 18411 data() const noexcept
62 {
63 18411 return p_->data();
64 }
65
66 mutable_buffers_type
67 18411 prepare(std::size_t n)
68 {
69 18411 return p_->prepare(n);
70 }
71
72 void
73 18411 commit(std::size_t n)
74 {
75 18411 p_->commit(n);
76 18411 }
77
78 void
79 consume(std::size_t n)
80 {
81 p_->consume(n);
82 }
83 };
84
85 } // detail
86
87 template<class ElasticBuffer>
88 typename std::enable_if<
89 ! detail::is_reference_wrapper<
90 ElasticBuffer>::value &&
91 ! is_sink<ElasticBuffer>::value>::type
92 11 parser::
93 set_body(
94 ElasticBuffer&& eb)
95 {
96 // If this goes off it means you are trying
97 // to pass by lvalue reference. Use std::ref
98 // instead.
99 static_assert(
100 ! std::is_reference<ElasticBuffer>::value,
101 "Use std::ref instead of pass-by-reference");
102
103 // Check ElasticBuffer type requirements
104 static_assert(
105 capy::is_dynamic_buffer<ElasticBuffer>::value,
106 "Type requirements not met.");
107
108 // body must not already be set
109
1/2
✗ Branch 1 not taken.
✓ Branch 2 taken 11 times.
11 if(is_body_set())
110 detail::throw_logic_error();
111
112 // headers must be complete
113
1/2
✗ Branch 1 not taken.
✓ Branch 2 taken 11 times.
11 if(! got_header())
114 detail::throw_logic_error();
115
116 11 auto& dyn = ws().emplace<
117 capy::any_dynamic_buffer_impl<typename
118 std::decay<ElasticBuffer>::type,
119 11 buffers_N>>(std::forward<ElasticBuffer>(eb));
120
121 11 set_body_impl(dyn);
122 11 }
123
124 template<class ElasticBuffer>
125 void
126 372 parser::
127 set_body(
128 std::reference_wrapper<ElasticBuffer> eb)
129 {
130 // Check ElasticBuffer type requirements
131 static_assert(
132 capy::is_dynamic_buffer<ElasticBuffer>::value,
133 "Type requirements not met.");
134
135 // body must not already be set
136
1/2
✗ Branch 1 not taken.
✓ Branch 2 taken 372 times.
372 if(is_body_set())
137 detail::throw_logic_error();
138
139 // headers must be complete
140
1/2
✗ Branch 1 not taken.
✓ Branch 2 taken 372 times.
372 if(! got_header())
141 detail::throw_logic_error();
142
143 // Use dynamic_buffer_ref to provide reference semantics
144 372 auto& dyn = ws().emplace<
145 capy::any_dynamic_buffer_impl<
146 detail::dynamic_buffer_ref<ElasticBuffer>,
147 372 buffers_N>>(eb.get());
148
149 372 set_body_impl(dyn);
150 372 }
151
152 template<
153 class Sink,
154 class... Args,
155 class>
156 Sink&
157 372 parser::
158 set_body(Args&&... args)
159 {
160 // body must not already be set
161
1/2
✗ Branch 1 not taken.
✓ Branch 2 taken 372 times.
372 if(is_body_set())
162 detail::throw_logic_error();
163
164 // headers must be complete
165
1/2
✗ Branch 1 not taken.
✓ Branch 2 taken 372 times.
372 if(! got_header())
166 detail::throw_logic_error();
167
168 372 auto& s = ws().emplace<Sink>(
169 std::forward<Args>(args)...);
170
171 372 set_body_impl(s);
172 372 return s;
173 }
174
175 } // http
176 } // boost
177
178 #endif
179