GCC Code Coverage Report


Directory: libs/http_proto/include/boost/http_proto/
File: boost/http_proto/impl/file_stdio.ipp
Date: 2023-02-02 18:17:22
Exec Total Coverage
Lines: 108 127 85.0%
Functions: 11 11 100.0%
Branches: 41 53 77.4%

Line Branch Exec Source
1 //
2 // Copyright (c) 2022 Vinnie Falco (vinnie dot falco at gmail dot 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 #ifndef BOOST_HTTP_PROTO_IMPL_FILE_STDIO_IPP
11 #define BOOST_HTTP_PROTO_IMPL_FILE_STDIO_IPP
12
13 #include <boost/http_proto/file_stdio.hpp>
14 #include <boost/http_proto/error.hpp>
15 #include <boost/http_proto/detail/win32_unicode_path.hpp>
16 #include <boost/config/workaround.hpp>
17 #include <boost/core/exchange.hpp>
18 #include <limits>
19
20 namespace boost {
21 namespace http_proto {
22
23 23 file_stdio::
24 23 ~file_stdio()
25 {
26
2/2
✓ Branch 0 taken 11 times.
✓ Branch 1 taken 12 times.
23 if(f_)
27 11 fclose(f_);
28 23 }
29
30 1 file_stdio::
31 file_stdio(
32 1 file_stdio&& other) noexcept
33 1 : f_(boost::exchange(other.f_, nullptr))
34 {
35 1 }
36
37 file_stdio&
38 3 file_stdio::
39 operator=(
40 file_stdio&& other) noexcept
41 {
42
2/2
✓ Branch 0 taken 1 times.
✓ Branch 1 taken 2 times.
3 if(&other == this)
43 1 return *this;
44
2/2
✓ Branch 0 taken 1 times.
✓ Branch 1 taken 1 times.
2 if(f_)
45 1 fclose(f_);
46 2 f_ = other.f_;
47 2 other.f_ = nullptr;
48 2 return *this;
49 }
50
51 void
52 1 file_stdio::
53 native_handle(std::FILE* f)
54 {
55
1/2
✓ Branch 0 taken 1 times.
✗ Branch 1 not taken.
1 if(f_)
56 1 fclose(f_);
57 1 f_ = f;
58 1 }
59
60 void
61 4 file_stdio::
62 close(error_code& ec)
63 {
64
1/2
✓ Branch 0 taken 4 times.
✗ Branch 1 not taken.
4 if(f_)
65 {
66 4 int failed = fclose(f_);
67 4 f_ = nullptr;
68
1/2
✗ Branch 0 not taken.
✓ Branch 1 taken 4 times.
4 if(failed)
69 {
70 ec.assign(errno, generic_category());
71 return;
72 }
73 }
74 4 ec = {};
75 }
76
77 void
78 21 file_stdio::
79 open(char const* path, file_mode mode, error_code& ec)
80 {
81
2/2
✓ Branch 0 taken 1 times.
✓ Branch 1 taken 20 times.
21 if(f_)
82 {
83 1 fclose(f_);
84 1 f_ = nullptr;
85 }
86 21 ec = {};
87 #if defined(BOOST_MSVC) || defined(_MSVC_STL_VERSION)
88 boost::winapi::WCHAR_ const* s;
89 detail::win32_unicode_path unicode_path(path, ec);
90 if (ec)
91 return;
92 #else
93 char const* s;
94 #endif
95
7/7
✓ Branch 0 taken 2 times.
✓ Branch 1 taken 1 times.
✓ Branch 2 taken 10 times.
✓ Branch 3 taken 2 times.
✓ Branch 4 taken 2 times.
✓ Branch 5 taken 2 times.
✓ Branch 6 taken 2 times.
21 switch(mode)
96 {
97 2 default:
98 case file_mode::read:
99 #if defined(BOOST_MSVC) || defined(_MSVC_STL_VERSION)
100 s = L"rb";
101 #else
102 2 s = "rb";
103 #endif
104 2 break;
105
106 1 case file_mode::scan:
107 #if defined(BOOST_MSVC) || defined(_MSVC_STL_VERSION)
108 s = L"rbS";
109 #else
110 1 s = "rb";
111 #endif
112 1 break;
113
114 10 case file_mode::write:
115 #if defined(BOOST_MSVC) || defined(_MSVC_STL_VERSION)
116 s = L"wb+";
117 #else
118 10 s = "wb+";
119 #endif
120 10 break;
121
122 2 case file_mode::write_new:
123 {
124 #if defined(BOOST_MSVC) || defined(_MSVC_STL_VERSION)
125 # if (defined(BOOST_MSVC) && BOOST_MSVC >= 1910) || (defined(_MSVC_STL_VERSION) && _MSVC_STL_VERSION >= 141)
126 s = L"wbx";
127 # else
128 std::FILE* f0;
129 auto const ev = ::_wfopen_s(&f0, unicode_path.c_str(), L"rb");
130 if(! ev)
131 {
132 std::fclose(f0);
133 ec = make_error_code(errc::file_exists);
134 return;
135 }
136 else if(ev !=
137 errc::no_such_file_or_directory)
138 {
139 ec.assign(ev, generic_category());
140 return;
141 }
142 s = L"wb";
143 # endif
144 #else
145 2 s = "wbx";
146 #endif
147 2 break;
148 }
149
150 2 case file_mode::write_existing:
151 #if defined(BOOST_MSVC) || defined(_MSVC_STL_VERSION)
152 s = L"rb+";
153 #else
154 2 s = "rb+";
155 #endif
156 2 break;
157
158 2 case file_mode::append:
159 #if defined(BOOST_MSVC) || defined(_MSVC_STL_VERSION)
160 s = L"ab";
161 #else
162 2 s = "ab";
163 #endif
164 2 break;
165
166 2 case file_mode::append_existing:
167 {
168 #if defined(BOOST_MSVC) || defined(_MSVC_STL_VERSION)
169 std::FILE* f0;
170 auto const ev =
171 ::_wfopen_s(&f0, unicode_path.c_str(), L"rb+");
172 if(ev)
173 {
174 ec.assign(ev, generic_category());
175 return;
176 }
177 #else
178 auto const f0 =
179 2 std::fopen(path, "rb+");
180
2/2
✓ Branch 0 taken 1 times.
✓ Branch 1 taken 1 times.
2 if(! f0)
181 {
182 1 ec.assign(errno, generic_category());
183 1 return;
184 }
185 #endif
186 1 std::fclose(f0);
187 #if defined(BOOST_MSVC) || defined(_MSVC_STL_VERSION)
188 s = L"ab";
189 #else
190 1 s = "ab";
191 #endif
192 1 break;
193 }
194 }
195
196 #if defined(BOOST_MSVC) || defined(_MSVC_STL_VERSION)
197 auto const ev = ::_wfopen_s(&f_, unicode_path.c_str(), s);
198 if(ev)
199 {
200 f_ = nullptr;
201 ec.assign(ev, generic_category());
202 return;
203 }
204 #else
205 20 f_ = std::fopen(path, s);
206
2/2
✓ Branch 0 taken 2 times.
✓ Branch 1 taken 18 times.
20 if(! f_)
207 {
208 2 ec.assign(errno, generic_category());
209 2 return;
210 }
211 #endif
212 }
213
214 std::uint64_t
215 2 file_stdio::
216 size(error_code& ec) const
217 {
218
2/2
✓ Branch 0 taken 1 times.
✓ Branch 1 taken 1 times.
2 if(! f_)
219 {
220 1 ec = make_error_code(errc::bad_file_descriptor);
221 1 return 0;
222 }
223 1 long pos = std::ftell(f_);
224
1/2
✗ Branch 0 not taken.
✓ Branch 1 taken 1 times.
1 if(pos == -1L)
225 {
226 ec.assign(errno, generic_category());
227 return 0;
228 }
229 1 int result = std::fseek(f_, 0, SEEK_END);
230
1/2
✗ Branch 0 not taken.
✓ Branch 1 taken 1 times.
1 if(result != 0)
231 {
232 ec.assign(errno, generic_category());
233 return 0;
234 }
235 1 long size = std::ftell(f_);
236
1/2
✗ Branch 0 not taken.
✓ Branch 1 taken 1 times.
1 if(size == -1L)
237 {
238 ec.assign(errno, generic_category());
239 std::fseek(f_, pos, SEEK_SET);
240 return 0;
241 }
242 1 result = std::fseek(f_, pos, SEEK_SET);
243
1/2
✗ Branch 0 not taken.
✓ Branch 1 taken 1 times.
1 if(result != 0)
244 ec.assign(errno, generic_category());
245 else
246 1 ec = {};
247 1 return size;
248 }
249
250 std::uint64_t
251 3 file_stdio::
252 pos(error_code& ec) const
253 {
254
2/2
✓ Branch 0 taken 1 times.
✓ Branch 1 taken 2 times.
3 if(! f_)
255 {
256 1 ec = make_error_code(errc::bad_file_descriptor);
257 1 return 0;
258 }
259 2 long pos = std::ftell(f_);
260
1/2
✗ Branch 0 not taken.
✓ Branch 1 taken 2 times.
2 if(pos == -1L)
261 {
262 ec.assign(errno, generic_category());
263 return 0;
264 }
265 2 ec = {};
266 2 return pos;
267 }
268
269 void
270 2 file_stdio::
271 seek(std::uint64_t offset, error_code& ec)
272 {
273
2/2
✓ Branch 0 taken 1 times.
✓ Branch 1 taken 1 times.
2 if(! f_)
274 {
275 1 ec = make_error_code(errc::bad_file_descriptor);
276 1 return;
277 }
278
1/2
✗ Branch 1 not taken.
✓ Branch 2 taken 1 times.
1 if(offset > static_cast<std::uint64_t>((std::numeric_limits<long>::max)()))
279 {
280 ec = make_error_code(errc::invalid_seek);
281 return;
282 }
283 1 int result = std::fseek(f_,
284 static_cast<long>(offset), SEEK_SET);
285
1/2
✗ Branch 0 not taken.
✓ Branch 1 taken 1 times.
1 if(result != 0)
286 ec.assign(errno, generic_category());
287 else
288 1 ec = {};
289 }
290
291 std::size_t
292 3 file_stdio::
293 read(void* buffer, std::size_t n, error_code& ec) const
294 {
295
2/2
✓ Branch 0 taken 1 times.
✓ Branch 1 taken 2 times.
3 if(! f_)
296 {
297 1 ec = make_error_code(errc::bad_file_descriptor);
298 1 return 0;
299 }
300 2 auto nread = std::fread(buffer, 1, n, f_);
301
1/2
✗ Branch 1 not taken.
✓ Branch 2 taken 2 times.
2 if(std::ferror(f_))
302 {
303 ec.assign(errno, generic_category());
304 return 0;
305 }
306 2 return nread;
307 }
308
309 std::size_t
310 5 file_stdio::
311 write(void const* buffer, std::size_t n, error_code& ec)
312 {
313
2/2
✓ Branch 0 taken 1 times.
✓ Branch 1 taken 4 times.
5 if(! f_)
314 {
315 1 ec = make_error_code(errc::bad_file_descriptor);
316 1 return 0;
317 }
318 4 auto nwritten = std::fwrite(buffer, 1, n, f_);
319
1/2
✗ Branch 1 not taken.
✓ Branch 2 taken 4 times.
4 if(std::ferror(f_))
320 {
321 ec.assign(errno, generic_category());
322 return 0;
323 }
324 4 return nwritten;
325 }
326
327 } // http_proto
328 } // boost
329
330 #endif
331