8d57d05f0fad918e4df4342146ff085f334b8927
[pcsx_rearmed.git] / deps / libchdr / deps / zstd-1.5.5 / contrib / pzstd / utils / FileSystem.h
1 /*
2  * Copyright (c) Meta Platforms, Inc. and affiliates.
3  * All rights reserved.
4  *
5  * This source code is licensed under both the BSD-style license (found in the
6  * LICENSE file in the root directory of this source tree) and the GPLv2 (found
7  * in the COPYING file in the root directory of this source tree).
8  */
9 #pragma once
10
11 #include "utils/Portability.h"
12 #include "utils/Range.h"
13
14 #include <sys/stat.h>
15 #include <cerrno>
16 #include <cstdint>
17 #include <limits>
18 #include <system_error>
19
20 // A small subset of `std::filesystem`.
21 // `std::filesystem` should be a drop in replacement.
22 // See https://en.cppreference.com/w/cpp/filesystem for documentation.
23
24 namespace pzstd {
25
26 // using file_status = ... causes gcc to emit a false positive warning
27 #if defined(_MSC_VER)
28 typedef struct ::_stat64 file_status;
29 #else
30 typedef struct ::stat file_status;
31 #endif
32
33 /// https://en.cppreference.com/w/cpp/filesystem/status
34 inline file_status status(StringPiece path, std::error_code& ec) noexcept {
35   file_status status;
36 #if defined(_MSC_VER)
37   const auto error = ::_stat64(path.data(), &status);
38 #else
39   const auto error = ::stat(path.data(), &status);
40 #endif
41   if (error) {
42     ec.assign(errno, std::generic_category());
43   } else {
44     ec.clear();
45   }
46   return status;
47 }
48
49 /// https://en.cppreference.com/w/cpp/filesystem/is_regular_file
50 inline bool is_regular_file(file_status status) noexcept {
51 #if defined(S_ISREG)
52   return S_ISREG(status.st_mode);
53 #elif !defined(S_ISREG) && defined(S_IFMT) && defined(S_IFREG)
54   return (status.st_mode & S_IFMT) == S_IFREG;
55 #else
56   static_assert(false, "No POSIX stat() support.");
57 #endif
58 }
59
60 /// https://en.cppreference.com/w/cpp/filesystem/is_regular_file
61 inline bool is_regular_file(StringPiece path, std::error_code& ec) noexcept {
62   return is_regular_file(status(path, ec));
63 }
64
65 /// https://en.cppreference.com/w/cpp/filesystem/is_directory
66 inline bool is_directory(file_status status) noexcept {
67 #if defined(S_ISDIR)
68   return S_ISDIR(status.st_mode);
69 #elif !defined(S_ISDIR) && defined(S_IFMT) && defined(S_IFDIR)
70   return (status.st_mode & S_IFMT) == S_IFDIR;
71 #else
72   static_assert(false, "NO POSIX stat() support.");
73 #endif
74 }
75
76 /// https://en.cppreference.com/w/cpp/filesystem/is_directory
77 inline bool is_directory(StringPiece path, std::error_code& ec) noexcept {
78   return is_directory(status(path, ec));
79 }
80
81 /// https://en.cppreference.com/w/cpp/filesystem/file_size
82 inline std::uintmax_t file_size(
83     StringPiece path,
84     std::error_code& ec) noexcept {
85   auto stat = status(path, ec);
86   if (ec) {
87     return std::numeric_limits<uintmax_t>::max();
88   }
89   if (!is_regular_file(stat)) {
90     ec.assign(ENOTSUP, std::generic_category());
91     return std::numeric_limits<uintmax_t>::max();
92   }
93   ec.clear();
94   return stat.st_size;
95 }
96 }