GCC Code Coverage Report


Directory: libs/http_proto/
File: libs/http_proto/src/detail/workspace.cpp
Date: 2024-05-23 18:56:45
Exec Total Coverage
Lines: 61 83 73.5%
Functions: 8 9 88.9%
Branches: 17 30 56.7%

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_proto
8 //
9
10 #include <boost/http_proto/detail/workspace.hpp>
11 #include <boost/http_proto/detail/except.hpp>
12 #include <boost/assert.hpp>
13
14 namespace boost {
15 namespace http_proto {
16 namespace detail {
17
18 694 workspace::
19 any::
20 ~any() = default;
21
22 1084 workspace::
23 ~workspace()
24 {
25
2/2
✓ Branch 0 taken 1064 times.
✓ Branch 1 taken 20 times.
1084 if(begin_)
26 {
27 1064 clear();
28
1/2
✓ Branch 0 taken 1064 times.
✗ Branch 1 not taken.
1064 delete[] begin_;
29 }
30 1084 }
31
32 20 workspace::
33 workspace(
34 20 std::size_t n)
35 20 : begin_(new unsigned char[n])
36 20 , front_(begin_)
37 20 , head_(begin_ + n)
38 20 , back_(head_)
39 20 , end_(head_)
40 {
41 20 }
42
43 workspace::
44 workspace(
45 workspace&& other) noexcept
46 : begin_(other.begin_)
47 , front_(other.front_)
48 , head_(other.end_)
49 , back_(other.back_)
50 , end_(other.end_)
51 {
52 other.begin_ = nullptr;
53 other.front_ = nullptr;
54 other.head_ = nullptr;
55 other.back_ = nullptr;
56 other.end_ = nullptr;
57 }
58
59 void
60 1044 workspace::
61 allocate(
62 std::size_t n)
63 {
64 // Cannot be empty
65
1/2
✗ Branch 0 not taken.
✓ Branch 1 taken 1044 times.
1044 if(n == 0)
66 detail::throw_invalid_argument();
67
68 // Already allocated
69
1/2
✗ Branch 0 not taken.
✓ Branch 1 taken 1044 times.
1044 if(begin_ != nullptr)
70 detail::throw_logic_error();
71
72 1044 begin_ = new unsigned char[n];
73 1044 front_ = begin_;
74 1044 head_ = begin_ + n;
75 1044 back_ = head_;
76 1044 end_ = head_;
77 1044 }
78
79 void
80 4337 workspace::
81 clear() noexcept
82 {
83
1/2
✗ Branch 0 not taken.
✓ Branch 1 taken 4337 times.
4337 if(! begin_)
84 return;
85
86 4337 auto const end =
87 reinterpret_cast<
88 any const*>(back_);
89 4337 auto p =
90 reinterpret_cast<
91 any const*>(head_);
92
2/2
✓ Branch 0 taken 347 times.
✓ Branch 1 taken 4337 times.
4684 while(p != end)
93 {
94 347 auto next = p->next;
95 347 p->~any();
96 347 p = next;
97 }
98 4337 front_ = begin_;
99 4337 head_ = end_;
100 4337 back_ = end_;
101 }
102
103 unsigned char*
104 1329 workspace::
105 reserve_front(
106 std::size_t n)
107 {
108 //
109 // Requested size exceeds available space.
110 // Note you can never reserve the last byte.
111
1/2
✗ Branch 1 not taken.
✓ Branch 2 taken 1329 times.
1329 if(n >= size())
112 detail::throw_length_error();
113
114 1329 auto const p = front_;
115 1329 front_ += n ;
116 1329 return p;
117 }
118
119 unsigned char*
120 1329 workspace::
121 reserve_back(
122 std::size_t n)
123 {
124 // can't reserve after acquire
125
1/2
✗ Branch 0 not taken.
✓ Branch 1 taken 1329 times.
1329 if(head_ != end_)
126 detail::throw_logic_error();
127
128 // can't reserve twice
129
1/2
✗ Branch 0 not taken.
✓ Branch 1 taken 1329 times.
1329 if(back_ != end_)
130 detail::throw_logic_error();
131
132 // over capacity
133 1329 std::size_t const lim =
134 1329 head_ - front_;
135
1/2
✗ Branch 0 not taken.
✓ Branch 1 taken 1329 times.
1329 if(n >= lim)
136 detail::throw_length_error();
137
138 1329 head_ -= n;
139 1329 back_ = head_;
140 1329 return back_;
141 }
142
143 // https://fitzgeraldnick.com/2019/11/01/always-bump-downwards.html
144 unsigned char*
145 347 workspace::
146 bump_down(
147 std::size_t size,
148 std::size_t align)
149 {
150
1/2
✗ Branch 0 not taken.
✓ Branch 1 taken 347 times.
347 BOOST_ASSERT(align > 0);
151
1/2
✗ Branch 0 not taken.
✓ Branch 1 taken 347 times.
347 BOOST_ASSERT(
152 (align & (align - 1)) == 0);
153
1/2
✗ Branch 0 not taken.
✓ Branch 1 taken 347 times.
347 BOOST_ASSERT(front_);
154
155 347 auto ip0 = reinterpret_cast<
156 347 std::uintptr_t>(front_);
157 347 auto ip = reinterpret_cast<
158 347 std::uintptr_t>(head_);
159
160 // If you get an exception here, it
161 // means that a buffer was too small
162 // for your workload. Increase the
163 // buffer size.
164
1/2
✗ Branch 0 not taken.
✓ Branch 1 taken 347 times.
347 if(size > ip - ip0)
165 detail::throw_bad_alloc();
166
167 347 ip -= size;
168 347 ip &= ~(align - 1);
169
170 // If you get an exception here, it
171 // means that a buffer was too small
172 // for your workload. Increase the
173 // buffer size.
174
1/2
✗ Branch 0 not taken.
✓ Branch 1 taken 347 times.
347 if(ip < ip0)
175 detail::throw_bad_alloc();
176
177 return reinterpret_cast<
178 347 unsigned char*>(ip);
179 }
180
181 } // detail
182 } // http_proto
183 } // boost
184