xref: /aosp_15_r20/external/fmtlib/include/fmt/os.h (revision 5c90c05cd622c0a81b57953a4d343e0e489f2e08)
1*5c90c05cSAndroid Build Coastguard Worker // Formatting library for C++ - optional OS-specific functionality
2*5c90c05cSAndroid Build Coastguard Worker //
3*5c90c05cSAndroid Build Coastguard Worker // Copyright (c) 2012 - present, Victor Zverovich
4*5c90c05cSAndroid Build Coastguard Worker // All rights reserved.
5*5c90c05cSAndroid Build Coastguard Worker //
6*5c90c05cSAndroid Build Coastguard Worker // For the license information refer to format.h.
7*5c90c05cSAndroid Build Coastguard Worker 
8*5c90c05cSAndroid Build Coastguard Worker #ifndef FMT_OS_H_
9*5c90c05cSAndroid Build Coastguard Worker #define FMT_OS_H_
10*5c90c05cSAndroid Build Coastguard Worker 
11*5c90c05cSAndroid Build Coastguard Worker #include "format.h"
12*5c90c05cSAndroid Build Coastguard Worker 
13*5c90c05cSAndroid Build Coastguard Worker #ifndef FMT_MODULE
14*5c90c05cSAndroid Build Coastguard Worker #  include <cerrno>
15*5c90c05cSAndroid Build Coastguard Worker #  include <cstddef>
16*5c90c05cSAndroid Build Coastguard Worker #  include <cstdio>
17*5c90c05cSAndroid Build Coastguard Worker #  include <system_error>  // std::system_error
18*5c90c05cSAndroid Build Coastguard Worker 
19*5c90c05cSAndroid Build Coastguard Worker #  if FMT_HAS_INCLUDE(<xlocale.h>)
20*5c90c05cSAndroid Build Coastguard Worker #    include <xlocale.h>  // LC_NUMERIC_MASK on macOS
21*5c90c05cSAndroid Build Coastguard Worker #  endif
22*5c90c05cSAndroid Build Coastguard Worker #endif  // FMT_MODULE
23*5c90c05cSAndroid Build Coastguard Worker 
24*5c90c05cSAndroid Build Coastguard Worker #ifndef FMT_USE_FCNTL
25*5c90c05cSAndroid Build Coastguard Worker // UWP doesn't provide _pipe.
26*5c90c05cSAndroid Build Coastguard Worker #  if FMT_HAS_INCLUDE("winapifamily.h")
27*5c90c05cSAndroid Build Coastguard Worker #    include <winapifamily.h>
28*5c90c05cSAndroid Build Coastguard Worker #  endif
29*5c90c05cSAndroid Build Coastguard Worker #  if (FMT_HAS_INCLUDE(<fcntl.h>) || defined(__APPLE__) || \
30*5c90c05cSAndroid Build Coastguard Worker        defined(__linux__)) &&                              \
31*5c90c05cSAndroid Build Coastguard Worker       (!defined(WINAPI_FAMILY) ||                          \
32*5c90c05cSAndroid Build Coastguard Worker        (WINAPI_FAMILY == WINAPI_FAMILY_DESKTOP_APP))
33*5c90c05cSAndroid Build Coastguard Worker #    include <fcntl.h>  // for O_RDONLY
34*5c90c05cSAndroid Build Coastguard Worker #    define FMT_USE_FCNTL 1
35*5c90c05cSAndroid Build Coastguard Worker #  else
36*5c90c05cSAndroid Build Coastguard Worker #    define FMT_USE_FCNTL 0
37*5c90c05cSAndroid Build Coastguard Worker #  endif
38*5c90c05cSAndroid Build Coastguard Worker #endif
39*5c90c05cSAndroid Build Coastguard Worker 
40*5c90c05cSAndroid Build Coastguard Worker #ifndef FMT_POSIX
41*5c90c05cSAndroid Build Coastguard Worker #  if defined(_WIN32) && !defined(__MINGW32__)
42*5c90c05cSAndroid Build Coastguard Worker // Fix warnings about deprecated symbols.
43*5c90c05cSAndroid Build Coastguard Worker #    define FMT_POSIX(call) _##call
44*5c90c05cSAndroid Build Coastguard Worker #  else
45*5c90c05cSAndroid Build Coastguard Worker #    define FMT_POSIX(call) call
46*5c90c05cSAndroid Build Coastguard Worker #  endif
47*5c90c05cSAndroid Build Coastguard Worker #endif
48*5c90c05cSAndroid Build Coastguard Worker 
49*5c90c05cSAndroid Build Coastguard Worker // Calls to system functions are wrapped in FMT_SYSTEM for testability.
50*5c90c05cSAndroid Build Coastguard Worker #ifdef FMT_SYSTEM
51*5c90c05cSAndroid Build Coastguard Worker #  define FMT_HAS_SYSTEM
52*5c90c05cSAndroid Build Coastguard Worker #  define FMT_POSIX_CALL(call) FMT_SYSTEM(call)
53*5c90c05cSAndroid Build Coastguard Worker #else
54*5c90c05cSAndroid Build Coastguard Worker #  define FMT_SYSTEM(call) ::call
55*5c90c05cSAndroid Build Coastguard Worker #  ifdef _WIN32
56*5c90c05cSAndroid Build Coastguard Worker // Fix warnings about deprecated symbols.
57*5c90c05cSAndroid Build Coastguard Worker #    define FMT_POSIX_CALL(call) ::_##call
58*5c90c05cSAndroid Build Coastguard Worker #  else
59*5c90c05cSAndroid Build Coastguard Worker #    define FMT_POSIX_CALL(call) ::call
60*5c90c05cSAndroid Build Coastguard Worker #  endif
61*5c90c05cSAndroid Build Coastguard Worker #endif
62*5c90c05cSAndroid Build Coastguard Worker 
63*5c90c05cSAndroid Build Coastguard Worker // Retries the expression while it evaluates to error_result and errno
64*5c90c05cSAndroid Build Coastguard Worker // equals to EINTR.
65*5c90c05cSAndroid Build Coastguard Worker #ifndef _WIN32
66*5c90c05cSAndroid Build Coastguard Worker #  define FMT_RETRY_VAL(result, expression, error_result) \
67*5c90c05cSAndroid Build Coastguard Worker     do {                                                  \
68*5c90c05cSAndroid Build Coastguard Worker       (result) = (expression);                            \
69*5c90c05cSAndroid Build Coastguard Worker     } while ((result) == (error_result) && errno == EINTR)
70*5c90c05cSAndroid Build Coastguard Worker #else
71*5c90c05cSAndroid Build Coastguard Worker #  define FMT_RETRY_VAL(result, expression, error_result) result = (expression)
72*5c90c05cSAndroid Build Coastguard Worker #endif
73*5c90c05cSAndroid Build Coastguard Worker 
74*5c90c05cSAndroid Build Coastguard Worker #define FMT_RETRY(result, expression) FMT_RETRY_VAL(result, expression, -1)
75*5c90c05cSAndroid Build Coastguard Worker 
76*5c90c05cSAndroid Build Coastguard Worker FMT_BEGIN_NAMESPACE
77*5c90c05cSAndroid Build Coastguard Worker FMT_BEGIN_EXPORT
78*5c90c05cSAndroid Build Coastguard Worker 
79*5c90c05cSAndroid Build Coastguard Worker /**
80*5c90c05cSAndroid Build Coastguard Worker  * A reference to a null-terminated string. It can be constructed from a C
81*5c90c05cSAndroid Build Coastguard Worker  * string or `std::string`.
82*5c90c05cSAndroid Build Coastguard Worker  *
83*5c90c05cSAndroid Build Coastguard Worker  * You can use one of the following type aliases for common character types:
84*5c90c05cSAndroid Build Coastguard Worker  *
85*5c90c05cSAndroid Build Coastguard Worker  * +---------------+-----------------------------+
86*5c90c05cSAndroid Build Coastguard Worker  * | Type          | Definition                  |
87*5c90c05cSAndroid Build Coastguard Worker  * +===============+=============================+
88*5c90c05cSAndroid Build Coastguard Worker  * | cstring_view  | basic_cstring_view<char>    |
89*5c90c05cSAndroid Build Coastguard Worker  * +---------------+-----------------------------+
90*5c90c05cSAndroid Build Coastguard Worker  * | wcstring_view | basic_cstring_view<wchar_t> |
91*5c90c05cSAndroid Build Coastguard Worker  * +---------------+-----------------------------+
92*5c90c05cSAndroid Build Coastguard Worker  *
93*5c90c05cSAndroid Build Coastguard Worker  * This class is most useful as a parameter type for functions that wrap C APIs.
94*5c90c05cSAndroid Build Coastguard Worker  */
95*5c90c05cSAndroid Build Coastguard Worker template <typename Char> class basic_cstring_view {
96*5c90c05cSAndroid Build Coastguard Worker  private:
97*5c90c05cSAndroid Build Coastguard Worker   const Char* data_;
98*5c90c05cSAndroid Build Coastguard Worker 
99*5c90c05cSAndroid Build Coastguard Worker  public:
100*5c90c05cSAndroid Build Coastguard Worker   /// Constructs a string reference object from a C string.
basic_cstring_view(const Char * s)101*5c90c05cSAndroid Build Coastguard Worker   basic_cstring_view(const Char* s) : data_(s) {}
102*5c90c05cSAndroid Build Coastguard Worker 
103*5c90c05cSAndroid Build Coastguard Worker   /// Constructs a string reference from an `std::string` object.
basic_cstring_view(const std::basic_string<Char> & s)104*5c90c05cSAndroid Build Coastguard Worker   basic_cstring_view(const std::basic_string<Char>& s) : data_(s.c_str()) {}
105*5c90c05cSAndroid Build Coastguard Worker 
106*5c90c05cSAndroid Build Coastguard Worker   /// Returns the pointer to a C string.
107*5c90c05cSAndroid Build Coastguard Worker   auto c_str() const -> const Char* { return data_; }
108*5c90c05cSAndroid Build Coastguard Worker };
109*5c90c05cSAndroid Build Coastguard Worker 
110*5c90c05cSAndroid Build Coastguard Worker using cstring_view = basic_cstring_view<char>;
111*5c90c05cSAndroid Build Coastguard Worker using wcstring_view = basic_cstring_view<wchar_t>;
112*5c90c05cSAndroid Build Coastguard Worker 
113*5c90c05cSAndroid Build Coastguard Worker #ifdef _WIN32
114*5c90c05cSAndroid Build Coastguard Worker FMT_API const std::error_category& system_category() noexcept;
115*5c90c05cSAndroid Build Coastguard Worker 
116*5c90c05cSAndroid Build Coastguard Worker namespace detail {
117*5c90c05cSAndroid Build Coastguard Worker FMT_API void format_windows_error(buffer<char>& out, int error_code,
118*5c90c05cSAndroid Build Coastguard Worker                                   const char* message) noexcept;
119*5c90c05cSAndroid Build Coastguard Worker }
120*5c90c05cSAndroid Build Coastguard Worker 
121*5c90c05cSAndroid Build Coastguard Worker FMT_API std::system_error vwindows_error(int error_code, string_view fmt,
122*5c90c05cSAndroid Build Coastguard Worker                                          format_args args);
123*5c90c05cSAndroid Build Coastguard Worker 
124*5c90c05cSAndroid Build Coastguard Worker /**
125*5c90c05cSAndroid Build Coastguard Worker  * Constructs a `std::system_error` object with the description of the form
126*5c90c05cSAndroid Build Coastguard Worker  *
127*5c90c05cSAndroid Build Coastguard Worker  *     <message>: <system-message>
128*5c90c05cSAndroid Build Coastguard Worker  *
129*5c90c05cSAndroid Build Coastguard Worker  * where `<message>` is the formatted message and `<system-message>` is the
130*5c90c05cSAndroid Build Coastguard Worker  * system message corresponding to the error code.
131*5c90c05cSAndroid Build Coastguard Worker  * `error_code` is a Windows error code as given by `GetLastError`.
132*5c90c05cSAndroid Build Coastguard Worker  * If `error_code` is not a valid error code such as -1, the system message
133*5c90c05cSAndroid Build Coastguard Worker  * will look like "error -1".
134*5c90c05cSAndroid Build Coastguard Worker  *
135*5c90c05cSAndroid Build Coastguard Worker  * **Example**:
136*5c90c05cSAndroid Build Coastguard Worker  *
137*5c90c05cSAndroid Build Coastguard Worker  *     // This throws a system_error with the description
138*5c90c05cSAndroid Build Coastguard Worker  *     //   cannot open file 'madeup': The system cannot find the file
139*5c90c05cSAndroid Build Coastguard Worker  * specified.
140*5c90c05cSAndroid Build Coastguard Worker  *     // or similar (system message may vary).
141*5c90c05cSAndroid Build Coastguard Worker  *     const char *filename = "madeup";
142*5c90c05cSAndroid Build Coastguard Worker  *     LPOFSTRUCT of = LPOFSTRUCT();
143*5c90c05cSAndroid Build Coastguard Worker  *     HFILE file = OpenFile(filename, &of, OF_READ);
144*5c90c05cSAndroid Build Coastguard Worker  *     if (file == HFILE_ERROR) {
145*5c90c05cSAndroid Build Coastguard Worker  *       throw fmt::windows_error(GetLastError(),
146*5c90c05cSAndroid Build Coastguard Worker  *                                "cannot open file '{}'", filename);
147*5c90c05cSAndroid Build Coastguard Worker  *     }
148*5c90c05cSAndroid Build Coastguard Worker  */
149*5c90c05cSAndroid Build Coastguard Worker template <typename... T>
150*5c90c05cSAndroid Build Coastguard Worker auto windows_error(int error_code, string_view message, const T&... args)
151*5c90c05cSAndroid Build Coastguard Worker     -> std::system_error {
152*5c90c05cSAndroid Build Coastguard Worker   return vwindows_error(error_code, message, vargs<T...>{{args...}});
153*5c90c05cSAndroid Build Coastguard Worker }
154*5c90c05cSAndroid Build Coastguard Worker 
155*5c90c05cSAndroid Build Coastguard Worker // Reports a Windows error without throwing an exception.
156*5c90c05cSAndroid Build Coastguard Worker // Can be used to report errors from destructors.
157*5c90c05cSAndroid Build Coastguard Worker FMT_API void report_windows_error(int error_code, const char* message) noexcept;
158*5c90c05cSAndroid Build Coastguard Worker #else
159*5c90c05cSAndroid Build Coastguard Worker inline auto system_category() noexcept -> const std::error_category& {
160*5c90c05cSAndroid Build Coastguard Worker   return std::system_category();
161*5c90c05cSAndroid Build Coastguard Worker }
162*5c90c05cSAndroid Build Coastguard Worker #endif  // _WIN32
163*5c90c05cSAndroid Build Coastguard Worker 
164*5c90c05cSAndroid Build Coastguard Worker // std::system is not available on some platforms such as iOS (#2248).
165*5c90c05cSAndroid Build Coastguard Worker #ifdef __OSX__
166*5c90c05cSAndroid Build Coastguard Worker template <typename S, typename... Args, typename Char = char_t<S>>
say(const S & fmt,Args &&...args)167*5c90c05cSAndroid Build Coastguard Worker void say(const S& fmt, Args&&... args) {
168*5c90c05cSAndroid Build Coastguard Worker   std::system(format("say \"{}\"", format(fmt, args...)).c_str());
169*5c90c05cSAndroid Build Coastguard Worker }
170*5c90c05cSAndroid Build Coastguard Worker #endif
171*5c90c05cSAndroid Build Coastguard Worker 
172*5c90c05cSAndroid Build Coastguard Worker // A buffered file.
173*5c90c05cSAndroid Build Coastguard Worker class buffered_file {
174*5c90c05cSAndroid Build Coastguard Worker  private:
175*5c90c05cSAndroid Build Coastguard Worker   FILE* file_;
176*5c90c05cSAndroid Build Coastguard Worker 
177*5c90c05cSAndroid Build Coastguard Worker   friend class file;
178*5c90c05cSAndroid Build Coastguard Worker 
buffered_file(FILE * f)179*5c90c05cSAndroid Build Coastguard Worker   inline explicit buffered_file(FILE* f) : file_(f) {}
180*5c90c05cSAndroid Build Coastguard Worker 
181*5c90c05cSAndroid Build Coastguard Worker  public:
182*5c90c05cSAndroid Build Coastguard Worker   buffered_file(const buffered_file&) = delete;
183*5c90c05cSAndroid Build Coastguard Worker   void operator=(const buffered_file&) = delete;
184*5c90c05cSAndroid Build Coastguard Worker 
185*5c90c05cSAndroid Build Coastguard Worker   // Constructs a buffered_file object which doesn't represent any file.
buffered_file()186*5c90c05cSAndroid Build Coastguard Worker   inline buffered_file() noexcept : file_(nullptr) {}
187*5c90c05cSAndroid Build Coastguard Worker 
188*5c90c05cSAndroid Build Coastguard Worker   // Destroys the object closing the file it represents if any.
189*5c90c05cSAndroid Build Coastguard Worker   FMT_API ~buffered_file() noexcept;
190*5c90c05cSAndroid Build Coastguard Worker 
191*5c90c05cSAndroid Build Coastguard Worker  public:
buffered_file(buffered_file && other)192*5c90c05cSAndroid Build Coastguard Worker   inline buffered_file(buffered_file&& other) noexcept : file_(other.file_) {
193*5c90c05cSAndroid Build Coastguard Worker     other.file_ = nullptr;
194*5c90c05cSAndroid Build Coastguard Worker   }
195*5c90c05cSAndroid Build Coastguard Worker 
196*5c90c05cSAndroid Build Coastguard Worker   inline auto operator=(buffered_file&& other) -> buffered_file& {
197*5c90c05cSAndroid Build Coastguard Worker     close();
198*5c90c05cSAndroid Build Coastguard Worker     file_ = other.file_;
199*5c90c05cSAndroid Build Coastguard Worker     other.file_ = nullptr;
200*5c90c05cSAndroid Build Coastguard Worker     return *this;
201*5c90c05cSAndroid Build Coastguard Worker   }
202*5c90c05cSAndroid Build Coastguard Worker 
203*5c90c05cSAndroid Build Coastguard Worker   // Opens a file.
204*5c90c05cSAndroid Build Coastguard Worker   FMT_API buffered_file(cstring_view filename, cstring_view mode);
205*5c90c05cSAndroid Build Coastguard Worker 
206*5c90c05cSAndroid Build Coastguard Worker   // Closes the file.
207*5c90c05cSAndroid Build Coastguard Worker   FMT_API void close();
208*5c90c05cSAndroid Build Coastguard Worker 
209*5c90c05cSAndroid Build Coastguard Worker   // Returns the pointer to a FILE object representing this file.
210*5c90c05cSAndroid Build Coastguard Worker   inline auto get() const noexcept -> FILE* { return file_; }
211*5c90c05cSAndroid Build Coastguard Worker 
212*5c90c05cSAndroid Build Coastguard Worker   FMT_API auto descriptor() const -> int;
213*5c90c05cSAndroid Build Coastguard Worker 
214*5c90c05cSAndroid Build Coastguard Worker   template <typename... T>
print(string_view fmt,const T &...args)215*5c90c05cSAndroid Build Coastguard Worker   inline void print(string_view fmt, const T&... args) {
216*5c90c05cSAndroid Build Coastguard Worker     fmt::vargs<T...> vargs = {{args...}};
217*5c90c05cSAndroid Build Coastguard Worker     detail::is_locking<T...>() ? fmt::vprint_buffered(file_, fmt, vargs)
218*5c90c05cSAndroid Build Coastguard Worker                                : fmt::vprint(file_, fmt, vargs);
219*5c90c05cSAndroid Build Coastguard Worker   }
220*5c90c05cSAndroid Build Coastguard Worker };
221*5c90c05cSAndroid Build Coastguard Worker 
222*5c90c05cSAndroid Build Coastguard Worker #if FMT_USE_FCNTL
223*5c90c05cSAndroid Build Coastguard Worker 
224*5c90c05cSAndroid Build Coastguard Worker // A file. Closed file is represented by a file object with descriptor -1.
225*5c90c05cSAndroid Build Coastguard Worker // Methods that are not declared with noexcept may throw
226*5c90c05cSAndroid Build Coastguard Worker // fmt::system_error in case of failure. Note that some errors such as
227*5c90c05cSAndroid Build Coastguard Worker // closing the file multiple times will cause a crash on Windows rather
228*5c90c05cSAndroid Build Coastguard Worker // than an exception. You can get standard behavior by overriding the
229*5c90c05cSAndroid Build Coastguard Worker // invalid parameter handler with _set_invalid_parameter_handler.
230*5c90c05cSAndroid Build Coastguard Worker class FMT_API file {
231*5c90c05cSAndroid Build Coastguard Worker  private:
232*5c90c05cSAndroid Build Coastguard Worker   int fd_;  // File descriptor.
233*5c90c05cSAndroid Build Coastguard Worker 
234*5c90c05cSAndroid Build Coastguard Worker   // Constructs a file object with a given descriptor.
file(int fd)235*5c90c05cSAndroid Build Coastguard Worker   explicit file(int fd) : fd_(fd) {}
236*5c90c05cSAndroid Build Coastguard Worker 
237*5c90c05cSAndroid Build Coastguard Worker   friend struct pipe;
238*5c90c05cSAndroid Build Coastguard Worker 
239*5c90c05cSAndroid Build Coastguard Worker  public:
240*5c90c05cSAndroid Build Coastguard Worker   // Possible values for the oflag argument to the constructor.
241*5c90c05cSAndroid Build Coastguard Worker   enum {
242*5c90c05cSAndroid Build Coastguard Worker     RDONLY = FMT_POSIX(O_RDONLY),  // Open for reading only.
243*5c90c05cSAndroid Build Coastguard Worker     WRONLY = FMT_POSIX(O_WRONLY),  // Open for writing only.
244*5c90c05cSAndroid Build Coastguard Worker     RDWR = FMT_POSIX(O_RDWR),      // Open for reading and writing.
245*5c90c05cSAndroid Build Coastguard Worker     CREATE = FMT_POSIX(O_CREAT),   // Create if the file doesn't exist.
246*5c90c05cSAndroid Build Coastguard Worker     APPEND = FMT_POSIX(O_APPEND),  // Open in append mode.
247*5c90c05cSAndroid Build Coastguard Worker     TRUNC = FMT_POSIX(O_TRUNC)     // Truncate the content of the file.
248*5c90c05cSAndroid Build Coastguard Worker   };
249*5c90c05cSAndroid Build Coastguard Worker 
250*5c90c05cSAndroid Build Coastguard Worker   // Constructs a file object which doesn't represent any file.
file()251*5c90c05cSAndroid Build Coastguard Worker   inline file() noexcept : fd_(-1) {}
252*5c90c05cSAndroid Build Coastguard Worker 
253*5c90c05cSAndroid Build Coastguard Worker   // Opens a file and constructs a file object representing this file.
254*5c90c05cSAndroid Build Coastguard Worker   file(cstring_view path, int oflag);
255*5c90c05cSAndroid Build Coastguard Worker 
256*5c90c05cSAndroid Build Coastguard Worker  public:
257*5c90c05cSAndroid Build Coastguard Worker   file(const file&) = delete;
258*5c90c05cSAndroid Build Coastguard Worker   void operator=(const file&) = delete;
259*5c90c05cSAndroid Build Coastguard Worker 
file(file && other)260*5c90c05cSAndroid Build Coastguard Worker   inline file(file&& other) noexcept : fd_(other.fd_) { other.fd_ = -1; }
261*5c90c05cSAndroid Build Coastguard Worker 
262*5c90c05cSAndroid Build Coastguard Worker   // Move assignment is not noexcept because close may throw.
263*5c90c05cSAndroid Build Coastguard Worker   inline auto operator=(file&& other) -> file& {
264*5c90c05cSAndroid Build Coastguard Worker     close();
265*5c90c05cSAndroid Build Coastguard Worker     fd_ = other.fd_;
266*5c90c05cSAndroid Build Coastguard Worker     other.fd_ = -1;
267*5c90c05cSAndroid Build Coastguard Worker     return *this;
268*5c90c05cSAndroid Build Coastguard Worker   }
269*5c90c05cSAndroid Build Coastguard Worker 
270*5c90c05cSAndroid Build Coastguard Worker   // Destroys the object closing the file it represents if any.
271*5c90c05cSAndroid Build Coastguard Worker   ~file() noexcept;
272*5c90c05cSAndroid Build Coastguard Worker 
273*5c90c05cSAndroid Build Coastguard Worker   // Returns the file descriptor.
274*5c90c05cSAndroid Build Coastguard Worker   inline auto descriptor() const noexcept -> int { return fd_; }
275*5c90c05cSAndroid Build Coastguard Worker 
276*5c90c05cSAndroid Build Coastguard Worker   // Closes the file.
277*5c90c05cSAndroid Build Coastguard Worker   void close();
278*5c90c05cSAndroid Build Coastguard Worker 
279*5c90c05cSAndroid Build Coastguard Worker   // Returns the file size. The size has signed type for consistency with
280*5c90c05cSAndroid Build Coastguard Worker   // stat::st_size.
281*5c90c05cSAndroid Build Coastguard Worker   auto size() const -> long long;
282*5c90c05cSAndroid Build Coastguard Worker 
283*5c90c05cSAndroid Build Coastguard Worker   // Attempts to read count bytes from the file into the specified buffer.
284*5c90c05cSAndroid Build Coastguard Worker   auto read(void* buffer, size_t count) -> size_t;
285*5c90c05cSAndroid Build Coastguard Worker 
286*5c90c05cSAndroid Build Coastguard Worker   // Attempts to write count bytes from the specified buffer to the file.
287*5c90c05cSAndroid Build Coastguard Worker   auto write(const void* buffer, size_t count) -> size_t;
288*5c90c05cSAndroid Build Coastguard Worker 
289*5c90c05cSAndroid Build Coastguard Worker   // Duplicates a file descriptor with the dup function and returns
290*5c90c05cSAndroid Build Coastguard Worker   // the duplicate as a file object.
291*5c90c05cSAndroid Build Coastguard Worker   static auto dup(int fd) -> file;
292*5c90c05cSAndroid Build Coastguard Worker 
293*5c90c05cSAndroid Build Coastguard Worker   // Makes fd be the copy of this file descriptor, closing fd first if
294*5c90c05cSAndroid Build Coastguard Worker   // necessary.
295*5c90c05cSAndroid Build Coastguard Worker   void dup2(int fd);
296*5c90c05cSAndroid Build Coastguard Worker 
297*5c90c05cSAndroid Build Coastguard Worker   // Makes fd be the copy of this file descriptor, closing fd first if
298*5c90c05cSAndroid Build Coastguard Worker   // necessary.
299*5c90c05cSAndroid Build Coastguard Worker   void dup2(int fd, std::error_code& ec) noexcept;
300*5c90c05cSAndroid Build Coastguard Worker 
301*5c90c05cSAndroid Build Coastguard Worker   // Creates a buffered_file object associated with this file and detaches
302*5c90c05cSAndroid Build Coastguard Worker   // this file object from the file.
303*5c90c05cSAndroid Build Coastguard Worker   auto fdopen(const char* mode) -> buffered_file;
304*5c90c05cSAndroid Build Coastguard Worker 
305*5c90c05cSAndroid Build Coastguard Worker #  if defined(_WIN32) && !defined(__MINGW32__)
306*5c90c05cSAndroid Build Coastguard Worker   // Opens a file and constructs a file object representing this file by
307*5c90c05cSAndroid Build Coastguard Worker   // wcstring_view filename. Windows only.
308*5c90c05cSAndroid Build Coastguard Worker   static file open_windows_file(wcstring_view path, int oflag);
309*5c90c05cSAndroid Build Coastguard Worker #  endif
310*5c90c05cSAndroid Build Coastguard Worker };
311*5c90c05cSAndroid Build Coastguard Worker 
312*5c90c05cSAndroid Build Coastguard Worker struct FMT_API pipe {
313*5c90c05cSAndroid Build Coastguard Worker   file read_end;
314*5c90c05cSAndroid Build Coastguard Worker   file write_end;
315*5c90c05cSAndroid Build Coastguard Worker 
316*5c90c05cSAndroid Build Coastguard Worker   // Creates a pipe setting up read_end and write_end file objects for reading
317*5c90c05cSAndroid Build Coastguard Worker   // and writing respectively.
318*5c90c05cSAndroid Build Coastguard Worker   pipe();
319*5c90c05cSAndroid Build Coastguard Worker };
320*5c90c05cSAndroid Build Coastguard Worker 
321*5c90c05cSAndroid Build Coastguard Worker // Returns the memory page size.
322*5c90c05cSAndroid Build Coastguard Worker auto getpagesize() -> long;
323*5c90c05cSAndroid Build Coastguard Worker 
324*5c90c05cSAndroid Build Coastguard Worker namespace detail {
325*5c90c05cSAndroid Build Coastguard Worker 
326*5c90c05cSAndroid Build Coastguard Worker struct buffer_size {
327*5c90c05cSAndroid Build Coastguard Worker   constexpr buffer_size() = default;
328*5c90c05cSAndroid Build Coastguard Worker   size_t value = 0;
329*5c90c05cSAndroid Build Coastguard Worker   FMT_CONSTEXPR auto operator=(size_t val) const -> buffer_size {
330*5c90c05cSAndroid Build Coastguard Worker     auto bs = buffer_size();
331*5c90c05cSAndroid Build Coastguard Worker     bs.value = val;
332*5c90c05cSAndroid Build Coastguard Worker     return bs;
333*5c90c05cSAndroid Build Coastguard Worker   }
334*5c90c05cSAndroid Build Coastguard Worker };
335*5c90c05cSAndroid Build Coastguard Worker 
336*5c90c05cSAndroid Build Coastguard Worker struct ostream_params {
337*5c90c05cSAndroid Build Coastguard Worker   int oflag = file::WRONLY | file::CREATE | file::TRUNC;
338*5c90c05cSAndroid Build Coastguard Worker   size_t buffer_size = BUFSIZ > 32768 ? BUFSIZ : 32768;
339*5c90c05cSAndroid Build Coastguard Worker 
ostream_paramsostream_params340*5c90c05cSAndroid Build Coastguard Worker   constexpr ostream_params() {}
341*5c90c05cSAndroid Build Coastguard Worker 
342*5c90c05cSAndroid Build Coastguard Worker   template <typename... T>
ostream_paramsostream_params343*5c90c05cSAndroid Build Coastguard Worker   ostream_params(T... params, int new_oflag) : ostream_params(params...) {
344*5c90c05cSAndroid Build Coastguard Worker     oflag = new_oflag;
345*5c90c05cSAndroid Build Coastguard Worker   }
346*5c90c05cSAndroid Build Coastguard Worker 
347*5c90c05cSAndroid Build Coastguard Worker   template <typename... T>
ostream_paramsostream_params348*5c90c05cSAndroid Build Coastguard Worker   ostream_params(T... params, detail::buffer_size bs)
349*5c90c05cSAndroid Build Coastguard Worker       : ostream_params(params...) {
350*5c90c05cSAndroid Build Coastguard Worker     this->buffer_size = bs.value;
351*5c90c05cSAndroid Build Coastguard Worker   }
352*5c90c05cSAndroid Build Coastguard Worker 
353*5c90c05cSAndroid Build Coastguard Worker // Intel has a bug that results in failure to deduce a constructor
354*5c90c05cSAndroid Build Coastguard Worker // for empty parameter packs.
355*5c90c05cSAndroid Build Coastguard Worker #  if defined(__INTEL_COMPILER) && __INTEL_COMPILER < 2000
ostream_paramsostream_params356*5c90c05cSAndroid Build Coastguard Worker   ostream_params(int new_oflag) : oflag(new_oflag) {}
ostream_paramsostream_params357*5c90c05cSAndroid Build Coastguard Worker   ostream_params(detail::buffer_size bs) : buffer_size(bs.value) {}
358*5c90c05cSAndroid Build Coastguard Worker #  endif
359*5c90c05cSAndroid Build Coastguard Worker };
360*5c90c05cSAndroid Build Coastguard Worker 
361*5c90c05cSAndroid Build Coastguard Worker }  // namespace detail
362*5c90c05cSAndroid Build Coastguard Worker 
363*5c90c05cSAndroid Build Coastguard Worker FMT_INLINE_VARIABLE constexpr auto buffer_size = detail::buffer_size();
364*5c90c05cSAndroid Build Coastguard Worker 
365*5c90c05cSAndroid Build Coastguard Worker /// A fast buffered output stream for writing from a single thread. Writing from
366*5c90c05cSAndroid Build Coastguard Worker /// multiple threads without external synchronization may result in a data race.
367*5c90c05cSAndroid Build Coastguard Worker class FMT_API ostream : private detail::buffer<char> {
368*5c90c05cSAndroid Build Coastguard Worker  private:
369*5c90c05cSAndroid Build Coastguard Worker   file file_;
370*5c90c05cSAndroid Build Coastguard Worker 
371*5c90c05cSAndroid Build Coastguard Worker   ostream(cstring_view path, const detail::ostream_params& params);
372*5c90c05cSAndroid Build Coastguard Worker 
373*5c90c05cSAndroid Build Coastguard Worker   static void grow(buffer<char>& buf, size_t);
374*5c90c05cSAndroid Build Coastguard Worker 
375*5c90c05cSAndroid Build Coastguard Worker  public:
376*5c90c05cSAndroid Build Coastguard Worker   ostream(ostream&& other) noexcept;
377*5c90c05cSAndroid Build Coastguard Worker   ~ostream();
378*5c90c05cSAndroid Build Coastguard Worker 
writer()379*5c90c05cSAndroid Build Coastguard Worker   operator writer() {
380*5c90c05cSAndroid Build Coastguard Worker     detail::buffer<char>& buf = *this;
381*5c90c05cSAndroid Build Coastguard Worker     return buf;
382*5c90c05cSAndroid Build Coastguard Worker   }
383*5c90c05cSAndroid Build Coastguard Worker 
flush()384*5c90c05cSAndroid Build Coastguard Worker   inline void flush() {
385*5c90c05cSAndroid Build Coastguard Worker     if (size() == 0) return;
386*5c90c05cSAndroid Build Coastguard Worker     file_.write(data(), size() * sizeof(data()[0]));
387*5c90c05cSAndroid Build Coastguard Worker     clear();
388*5c90c05cSAndroid Build Coastguard Worker   }
389*5c90c05cSAndroid Build Coastguard Worker 
390*5c90c05cSAndroid Build Coastguard Worker   template <typename... T>
391*5c90c05cSAndroid Build Coastguard Worker   friend auto output_file(cstring_view path, T... params) -> ostream;
392*5c90c05cSAndroid Build Coastguard Worker 
close()393*5c90c05cSAndroid Build Coastguard Worker   inline void close() {
394*5c90c05cSAndroid Build Coastguard Worker     flush();
395*5c90c05cSAndroid Build Coastguard Worker     file_.close();
396*5c90c05cSAndroid Build Coastguard Worker   }
397*5c90c05cSAndroid Build Coastguard Worker 
398*5c90c05cSAndroid Build Coastguard Worker   /// Formats `args` according to specifications in `fmt` and writes the
399*5c90c05cSAndroid Build Coastguard Worker   /// output to the file.
print(format_string<T...> fmt,T &&...args)400*5c90c05cSAndroid Build Coastguard Worker   template <typename... T> void print(format_string<T...> fmt, T&&... args) {
401*5c90c05cSAndroid Build Coastguard Worker     vformat_to(appender(*this), fmt.str, vargs<T...>{{args...}});
402*5c90c05cSAndroid Build Coastguard Worker   }
403*5c90c05cSAndroid Build Coastguard Worker };
404*5c90c05cSAndroid Build Coastguard Worker 
405*5c90c05cSAndroid Build Coastguard Worker /**
406*5c90c05cSAndroid Build Coastguard Worker  * Opens a file for writing. Supported parameters passed in `params`:
407*5c90c05cSAndroid Build Coastguard Worker  *
408*5c90c05cSAndroid Build Coastguard Worker  * - `<integer>`: Flags passed to [open](
409*5c90c05cSAndroid Build Coastguard Worker  *   https://pubs.opengroup.org/onlinepubs/007904875/functions/open.html)
410*5c90c05cSAndroid Build Coastguard Worker  *   (`file::WRONLY | file::CREATE | file::TRUNC` by default)
411*5c90c05cSAndroid Build Coastguard Worker  * - `buffer_size=<integer>`: Output buffer size
412*5c90c05cSAndroid Build Coastguard Worker  *
413*5c90c05cSAndroid Build Coastguard Worker  * **Example**:
414*5c90c05cSAndroid Build Coastguard Worker  *
415*5c90c05cSAndroid Build Coastguard Worker  *     auto out = fmt::output_file("guide.txt");
416*5c90c05cSAndroid Build Coastguard Worker  *     out.print("Don't {}", "Panic");
417*5c90c05cSAndroid Build Coastguard Worker  */
418*5c90c05cSAndroid Build Coastguard Worker template <typename... T>
419*5c90c05cSAndroid Build Coastguard Worker inline auto output_file(cstring_view path, T... params) -> ostream {
420*5c90c05cSAndroid Build Coastguard Worker   return {path, detail::ostream_params(params...)};
421*5c90c05cSAndroid Build Coastguard Worker }
422*5c90c05cSAndroid Build Coastguard Worker #endif  // FMT_USE_FCNTL
423*5c90c05cSAndroid Build Coastguard Worker 
424*5c90c05cSAndroid Build Coastguard Worker FMT_END_EXPORT
425*5c90c05cSAndroid Build Coastguard Worker FMT_END_NAMESPACE
426*5c90c05cSAndroid Build Coastguard Worker 
427*5c90c05cSAndroid Build Coastguard Worker #endif  // FMT_OS_H_
428