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