GCC Code Coverage Report


Directory: libs/http_proto/include/boost/http_proto/
File: boost/http_proto/impl/file_stdio.ipp
Date: 2023-03-01 04:48:12
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.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 #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(
63 system::error_code& ec)
64 {
65
1/2
✓ Branch 0 taken 4 times.
✗ Branch 1 not taken.
4 if(f_)
66 {
67 4 int failed = fclose(f_);
68 4 f_ = nullptr;
69
1/2
✗ Branch 0 not taken.
✓ Branch 1 taken 4 times.
4 if(failed)
70 {
71 ec.assign(errno,
72 system::generic_category());
73 return;
74 }
75 }
76 4 ec = {};
77 }
78
79 void
80 21 file_stdio::
81 open(char const* path, file_mode mode,
82 system::error_code& ec)
83 {
84
2/2
✓ Branch 0 taken 1 times.
✓ Branch 1 taken 20 times.
21 if(f_)
85 {
86 1 fclose(f_);
87 1 f_ = nullptr;
88 }
89 21 ec = {};
90 #if defined(BOOST_MSVC) || defined(_MSVC_STL_VERSION)
91 boost::winapi::WCHAR_ const* s;
92 detail::win32_unicode_path unicode_path(path, ec);
93 if (ec)
94 return;
95 #else
96 char const* s;
97 #endif
98
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)
99 {
100 2 default:
101 case file_mode::read:
102 #if defined(BOOST_MSVC) || defined(_MSVC_STL_VERSION)
103 s = L"rb";
104 #else
105 2 s = "rb";
106 #endif
107 2 break;
108
109 1 case file_mode::scan:
110 #if defined(BOOST_MSVC) || defined(_MSVC_STL_VERSION)
111 s = L"rbS";
112 #else
113 1 s = "rb";
114 #endif
115 1 break;
116
117 10 case file_mode::write:
118 #if defined(BOOST_MSVC) || defined(_MSVC_STL_VERSION)
119 s = L"wb+";
120 #else
121 10 s = "wb+";
122 #endif
123 10 break;
124
125 2 case file_mode::write_new:
126 {
127 #if defined(BOOST_MSVC) || defined(_MSVC_STL_VERSION)
128 # if (defined(BOOST_MSVC) && BOOST_MSVC >= 1910) || (defined(_MSVC_STL_VERSION) && _MSVC_STL_VERSION >= 141)
129 s = L"wbx";
130 # else
131 std::FILE* f0;
132 auto const ev = ::_wfopen_s(&f0, unicode_path.c_str(), L"rb");
133 if(! ev)
134 {
135 std::fclose(f0);
136 ec = make_error_code(
137 system::errc::file_exists);
138 return;
139 }
140 else if(ev !=
141 system::errc::no_such_file_or_directory)
142 {
143 ec.assign(ev,
144 system::generic_category());
145 return;
146 }
147 s = L"wb";
148 # endif
149 #else
150 2 s = "wbx";
151 #endif
152 2 break;
153 }
154
155 2 case file_mode::write_existing:
156 #if defined(BOOST_MSVC) || defined(_MSVC_STL_VERSION)
157 s = L"rb+";
158 #else
159 2 s = "rb+";
160 #endif
161 2 break;
162
163 2 case file_mode::append:
164 #if defined(BOOST_MSVC) || defined(_MSVC_STL_VERSION)
165 s = L"ab";
166 #else
167 2 s = "ab";
168 #endif
169 2 break;
170
171 2 case file_mode::append_existing:
172 {
173 #if defined(BOOST_MSVC) || defined(_MSVC_STL_VERSION)
174 std::FILE* f0;
175 auto const ev =
176 ::_wfopen_s(&f0, unicode_path.c_str(), L"rb+");
177 if(ev)
178 {
179 ec.assign(ev,
180 system::generic_category());
181 return;
182 }
183 #else
184 auto const f0 =
185 2 std::fopen(path, "rb+");
186
2/2
✓ Branch 0 taken 1 times.
✓ Branch 1 taken 1 times.
2 if(! f0)
187 {
188 1 ec.assign(errno,
189 system::generic_category());
190 1 return;
191 }
192 #endif
193 1 std::fclose(f0);
194 #if defined(BOOST_MSVC) || defined(_MSVC_STL_VERSION)
195 s = L"ab";
196 #else
197 1 s = "ab";
198 #endif
199 1 break;
200 }
201 }
202
203 #if defined(BOOST_MSVC) || defined(_MSVC_STL_VERSION)
204 auto const ev = ::_wfopen_s(
205 &f_, unicode_path.c_str(), s);
206 if(ev)
207 {
208 f_ = nullptr;
209 ec.assign(ev,
210 system::generic_category());
211 return;
212 }
213 #else
214 20 f_ = std::fopen(path, s);
215
2/2
✓ Branch 0 taken 2 times.
✓ Branch 1 taken 18 times.
20 if(! f_)
216 {
217 2 ec.assign(errno,
218 system::generic_category());
219 2 return;
220 }
221 #endif
222 }
223
224 std::uint64_t
225 2 file_stdio::
226 size(
227 system::error_code& ec) const
228 {
229
2/2
✓ Branch 0 taken 1 times.
✓ Branch 1 taken 1 times.
2 if(! f_)
230 {
231 ec = make_error_code(
232 1 system::errc::bad_file_descriptor);
233 1 return 0;
234 }
235 1 long pos = std::ftell(f_);
236
1/2
✗ Branch 0 not taken.
✓ Branch 1 taken 1 times.
1 if(pos == -1L)
237 {
238 ec.assign(errno,
239 system::generic_category());
240 return 0;
241 }
242 1 int result = std::fseek(f_, 0, SEEK_END);
243
1/2
✗ Branch 0 not taken.
✓ Branch 1 taken 1 times.
1 if(result != 0)
244 {
245 ec.assign(errno,
246 system::generic_category());
247 return 0;
248 }
249 1 long size = std::ftell(f_);
250
1/2
✗ Branch 0 not taken.
✓ Branch 1 taken 1 times.
1 if(size == -1L)
251 {
252 ec.assign(errno,
253 system::generic_category());
254 std::fseek(f_, pos, SEEK_SET);
255 return 0;
256 }
257 1 result = std::fseek(f_, pos, SEEK_SET);
258
1/2
✗ Branch 0 not taken.
✓ Branch 1 taken 1 times.
1 if(result != 0)
259 ec.assign(errno,
260 system::generic_category());
261 else
262 1 ec = {};
263 1 return size;
264 }
265
266 std::uint64_t
267 3 file_stdio::
268 pos(
269 system::error_code& ec) const
270 {
271
2/2
✓ Branch 0 taken 1 times.
✓ Branch 1 taken 2 times.
3 if(! f_)
272 {
273 ec = make_error_code(
274 1 system::errc::bad_file_descriptor);
275 1 return 0;
276 }
277 2 long pos = std::ftell(f_);
278
1/2
✗ Branch 0 not taken.
✓ Branch 1 taken 2 times.
2 if(pos == -1L)
279 {
280 ec.assign(errno,
281 system::generic_category());
282 return 0;
283 }
284 2 ec = {};
285 2 return pos;
286 }
287
288 void
289 2 file_stdio::
290 seek(std::uint64_t offset,
291 system::error_code& ec)
292 {
293
2/2
✓ Branch 0 taken 1 times.
✓ Branch 1 taken 1 times.
2 if(! f_)
294 {
295 ec = make_error_code(
296 1 system::errc::bad_file_descriptor);
297 1 return;
298 }
299
1/2
✗ Branch 1 not taken.
✓ Branch 2 taken 1 times.
1 if(offset > static_cast<std::uint64_t>((std::numeric_limits<long>::max)()))
300 {
301 ec = make_error_code(
302 system::errc::invalid_seek);
303 return;
304 }
305 1 int result = std::fseek(f_,
306 static_cast<long>(offset), SEEK_SET);
307
1/2
✗ Branch 0 not taken.
✓ Branch 1 taken 1 times.
1 if(result != 0)
308 ec.assign(errno,
309 system::generic_category());
310 else
311 1 ec = {};
312 }
313
314 std::size_t
315 3 file_stdio::
316 read(void* buffer, std::size_t n,
317 system::error_code& ec) const
318 {
319
2/2
✓ Branch 0 taken 1 times.
✓ Branch 1 taken 2 times.
3 if(! f_)
320 {
321 ec = make_error_code(
322 1 system::errc::bad_file_descriptor);
323 1 return 0;
324 }
325 2 auto nread = std::fread(buffer, 1, n, f_);
326
1/2
✗ Branch 1 not taken.
✓ Branch 2 taken 2 times.
2 if(std::ferror(f_))
327 {
328 ec.assign(errno,
329 system::generic_category());
330 return 0;
331 }
332 2 return nread;
333 }
334
335 std::size_t
336 5 file_stdio::
337 write(void const* buffer, std::size_t n,
338 system::error_code& ec)
339 {
340
2/2
✓ Branch 0 taken 1 times.
✓ Branch 1 taken 4 times.
5 if(! f_)
341 {
342 ec = make_error_code(
343 1 system::errc::bad_file_descriptor);
344 1 return 0;
345 }
346 4 auto nwritten = std::fwrite(buffer, 1, n, f_);
347
1/2
✗ Branch 1 not taken.
✓ Branch 2 taken 4 times.
4 if(std::ferror(f_))
348 {
349 ec.assign(errno,
350 system::generic_category());
351 return 0;
352 }
353 4 return nwritten;
354 }
355
356 } // http_proto
357 } // boost
358
359 #endif
360