GCC Code Coverage Report


Directory: libs/http_proto/
File: include/boost/http_proto/file.hpp
Date: 2025-09-21 18:08:15
Exec Total Coverage
Lines: 61 67 91.0%
Functions: 20 20 100.0%
Branches: 13 26 50.0%

Line Branch Exec Source
1 //
2 // Copyright (c) 2022 Vinnie Falco (vinnie.falco@gmail.com)
3 // Copyright (c) 2025 Mohammad Nejati
4 //
5 // Distributed under the Boost Software License, Version 1.0. (See accompanying
6 // file LICENSE_1_0.txt or copy at http://www.boost.org/LICENSE_1_0.txt)
7 //
8 // Official repository: https://github.com/cppalliance/http_proto
9 //
10
11 #ifndef BOOST_HTTP_PROTO_FILE_HPP
12 #define BOOST_HTTP_PROTO_FILE_HPP
13
14 #include <boost/http_proto/detail/config.hpp>
15 #include <boost/http_proto/detail/except.hpp>
16 #include <boost/http_proto/detail/file_posix.hpp>
17 #include <boost/http_proto/detail/file_stdio.hpp>
18 #include <boost/http_proto/detail/file_win32.hpp>
19 #include <boost/http_proto/file_mode.hpp>
20 namespace boost {
21 namespace http_proto {
22
23 /** A platform-independent file stream.
24
25 This class provides a portable interface for
26 reading from and writing to files. It is
27 intended for use with @ref file_sink and @ref
28 file_source to enable streaming HTTP message
29 bodies to and from files.
30
31 @par Example 1
32 @code
33 file f("example.zip", file_mode::scan);
34 response.set_payload_size(f.size());
35 serializer.start<file_source>(response, std::move(f));
36 @endcode
37
38 @par Example 2
39 @code
40 parser.set_body<file_sink>("example.zip", file_mode::write_new);
41 @endcode
42
43 @see
44 @ref file_mode,
45 @ref file_sink,
46 @ref file_source.
47 */
48 class file
49 {
50 #if BOOST_HTTP_PROTO_USE_WIN32_FILE
51 using impl_type = detail::file_win32;
52 #elif BOOST_HTTP_PROTO_USE_POSIX_FILE
53 using impl_type = detail::file_posix;
54 #else
55 using impl_type = detail::file_stdio;
56 #endif
57
58 impl_type impl_;
59
60 public:
61 /** The type of the underlying native file handle.
62
63 This type is platform-specific.
64 */
65 using native_handle_type = impl_type::native_handle_type;
66
67 /** Constructor.
68
69 There is no open file initially.
70 */
71 file() = default;
72
73 /** Constructor.
74
75 Open a file at the given path with the specified mode.
76
77 @par Exception Safety
78 Exception thrown if operation fails.
79
80 @throw system_error
81 Operation fails.
82
83 @param path The UTF-8 encoded path to the file.
84
85 @param mode The file mode to use.
86
87 @see
88 @ref file_mode,
89 @ref open.
90 */
91 1 file(char const* path, file_mode mode)
92 1 {
93
1/2
✗ Branch 1 not taken.
✓ Branch 2 taken 1 times.
1 open(path, mode);
94 1 }
95
96 /** Constructor.
97
98 The moved-from object behaves as if default-constructed.
99 */
100 6 file(file&& other) noexcept = default;
101
102 /** Assignment
103
104 The moved-from object behaves as if default-constructed.
105 */
106 file&
107 3 operator=(
108 file&& other) noexcept = default;
109
110 /** Destructor
111
112 If the file is open it is first closed.
113 */
114 34 ~file() = default;
115
116 /** Returns the native handle associated with the file.
117 */
118 native_handle_type
119 2 native_handle()
120 {
121 2 return impl_.native_handle();
122 }
123
124 /** Set the native file handle.
125
126 If the file is open it is first closed.
127
128 @param h The native handle to assign.
129 */
130 void
131 1 native_handle(native_handle_type h)
132 {
133 1 impl_.native_handle(h);
134 1 }
135
136 /** Return true if the file is open.
137 */
138 bool
139 12 is_open() const
140 {
141 12 return impl_.is_open();
142 }
143
144 /** Close the file if open.
145
146 Note that, The descriptor is closed even if the function
147 reports an error.
148
149 @param ec Set to the error, if any occurred.
150 */
151 void
152 5 close(system::error_code& ec)
153 {
154 5 impl_.close(ec);
155 5 }
156
157 /** Close the file if open.
158
159 Note that, The descriptor is closed even if the function
160 reports an error.
161
162 @par Exception Safety
163 Exception thrown if operation fails.
164
165 @throw system_error
166 Operation fails.
167 */
168 void
169 close()
170 {
171 system::error_code ec;
172 impl_.close(ec);
173 if(ec.failed())
174 detail::throw_system_error(ec);
175 }
176
177 /** Open a file at the given path with the specified mode.
178
179 @param path The UTF-8 encoded path to the file.
180
181 @param mode The file mode to use.
182
183 @param ec Set to the error, if any occurred.
184
185 @see
186 @ref file_mode.
187 */
188 void
189 24 open(char const* path, file_mode mode, system::error_code& ec)
190 {
191 24 impl_.open(path, mode, ec);
192 24 }
193
194 /** Open a file at the given path with the specified mode.
195
196 @param path The UTF-8 encoded path to the file.
197
198 @param mode The file mode to use.
199
200 @par Exception Safety
201 Exception thrown if operation fails.
202
203 @throw system_error
204 Operation fails.
205
206 @see
207 @ref file_mode.
208 */
209 void
210 2 open(char const* path, file_mode mode)
211 {
212 2 system::error_code ec;
213
1/2
✓ Branch 1 taken 2 times.
✗ Branch 2 not taken.
2 impl_.open(path, mode, ec);
214
1/2
✓ Branch 1 taken 2 times.
✗ Branch 2 not taken.
2 if(ec.failed())
215 2 detail::throw_system_error(ec);
216 }
217
218 /** Return the size of the open file in bytes.
219
220 @param ec Set to the error, if any occurred.
221 */
222 std::uint64_t
223 2 size(system::error_code& ec) const
224 {
225 2 return impl_.size(ec);
226 }
227
228 /** Return the size of the open file in bytes.
229
230 @par Exception Safety
231 Exception thrown if operation fails.
232
233 @throw system_error
234 Operation fails.
235 */
236 std::uint64_t
237 1 size() const
238 {
239 1 system::error_code ec;
240
1/2
✓ Branch 1 taken 1 times.
✗ Branch 2 not taken.
1 auto r = impl_.size(ec);
241
1/2
✓ Branch 1 taken 1 times.
✗ Branch 2 not taken.
1 if(ec.failed())
242 1 detail::throw_system_error(ec);
243 return r;
244 }
245
246 /** Return the current position in the file, in bytes from the beginning.
247
248 @param ec Set to the error, if any occurred.
249 */
250 std::uint64_t
251 3 pos(system::error_code& ec) const
252 {
253 3 return impl_.pos(ec);
254 }
255
256 /** Return the current position in the file, in bytes from the beginning.
257
258 @par Exception Safety
259 Exception thrown if operation fails.
260
261 @throw system_error
262 Operation fails.
263 */
264 std::uint64_t
265 1 pos() const
266 {
267 1 system::error_code ec;
268
1/2
✓ Branch 1 taken 1 times.
✗ Branch 2 not taken.
1 auto r = impl_.pos(ec);
269
1/2
✓ Branch 1 taken 1 times.
✗ Branch 2 not taken.
1 if(ec.failed())
270 1 detail::throw_system_error(ec);
271 return r;
272 }
273
274 /** Set the current position in the file.
275
276 @param offset The byte offset from the beginning of the file.
277
278 @param ec Set to the error, if any occurred.
279 */
280 void
281 2 seek(std::uint64_t offset, system::error_code& ec)
282 {
283 2 impl_.seek(offset, ec);
284 2 }
285
286 /** Set the current position in the file.
287
288 @par Exception Safety
289 Exception thrown if operation fails.
290
291 @throw system_error
292 Operation fails.
293
294 @param offset The byte offset from the beginning of the file.
295 */
296 void
297 1 seek(std::uint64_t offset)
298 {
299 1 system::error_code ec;
300
1/2
✓ Branch 1 taken 1 times.
✗ Branch 2 not taken.
1 impl_.seek(offset, ec);
301
1/2
✓ Branch 1 taken 1 times.
✗ Branch 2 not taken.
1 if(ec.failed())
302 1 detail::throw_system_error(ec);
303 }
304
305 /** Read data from the file.
306
307 @return The number of bytes read. Returns
308 0 on end-of-file or if an error occurs (in
309 which case @p ec is set).
310
311 @param buffer The buffer to store the read data.
312
313 @param n The number of bytes to read.
314
315 @param ec Set to the error, if any occurred.
316 */
317 std::size_t
318 10 read(void* buffer, std::size_t n, system::error_code& ec)
319 {
320 10 return impl_.read(buffer, n, ec);
321 }
322
323 /** Read data from the file.
324
325 @par Exception Safety
326 Exception thrown if operation fails.
327
328 @throw system_error
329 Operation fails.
330
331 @return The number of bytes read. Returns
332 0 on end-of-file.
333
334 @param buffer The buffer to store the read data.
335
336 @param n The number of bytes to read.
337 */
338 std::size_t
339 1 read(void* buffer, std::size_t n)
340 {
341 1 system::error_code ec;
342
1/2
✓ Branch 1 taken 1 times.
✗ Branch 2 not taken.
1 auto r = impl_.read(buffer, n, ec);
343
1/2
✓ Branch 1 taken 1 times.
✗ Branch 2 not taken.
1 if(ec.failed())
344 1 detail::throw_system_error(ec);
345 return r;
346 }
347
348 /** Write data to the file.
349
350 @return The number of bytes written.
351 Returns 0 on error (in which case @p ec is
352 set).
353
354 @param buffer The buffer containing the data to write.
355
356 @param n The number of bytes to write.
357
358 @param ec Set to the error, if any occurred.
359 */
360 std::size_t
361 10 write(void const* buffer, std::size_t n, system::error_code& ec)
362 {
363 10 return impl_.write(buffer, n, ec);
364 }
365
366 /** Write data to the file.
367
368 @par Exception Safety
369 Exception thrown if operation fails.
370
371 @throw system_error
372 Operation fails.
373
374 @return The number of bytes written.
375
376 @param buffer The buffer containing the data to write.
377
378 @param n The number of bytes to write.
379 */
380 std::size_t
381 1 write(void const* buffer, std::size_t n)
382 {
383 1 system::error_code ec;
384
1/2
✓ Branch 1 taken 1 times.
✗ Branch 2 not taken.
1 auto r = impl_.write(buffer, n, ec);
385
1/2
✓ Branch 1 taken 1 times.
✗ Branch 2 not taken.
1 if(ec.failed())
386 1 detail::throw_system_error(ec);
387 return r;
388 }
389 };
390
391 } // http_proto
392 } // boost
393
394 #endif
395