]>
Commit | Line | Data |
---|---|---|
11fdf7f2 | 1 | /* |
7c673cae FG |
2 | * Copyright (c) 2016-present, Facebook, Inc. |
3 | * All rights reserved. | |
4 | * | |
11fdf7f2 TL |
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). | |
7c673cae FG |
8 | */ |
9 | #pragma once | |
10 | ||
11 | #include "utils/Range.h" | |
12 | ||
13 | #include <sys/stat.h> | |
14 | #include <cerrno> | |
15 | #include <cstdint> | |
16 | #include <system_error> | |
17 | ||
18 | // A small subset of `std::filesystem`. | |
19 | // `std::filesystem` should be a drop in replacement. | |
20 | // See http://en.cppreference.com/w/cpp/filesystem for documentation. | |
21 | ||
22 | namespace pzstd { | |
23 | ||
24 | // using file_status = ... causes gcc to emit a false positive warning | |
25 | #if defined(_MSC_VER) | |
26 | typedef struct ::_stat64 file_status; | |
27 | #else | |
28 | typedef struct ::stat file_status; | |
29 | #endif | |
30 | ||
31 | /// http://en.cppreference.com/w/cpp/filesystem/status | |
32 | inline file_status status(StringPiece path, std::error_code& ec) noexcept { | |
33 | file_status status; | |
34 | #if defined(_MSC_VER) | |
35 | const auto error = ::_stat64(path.data(), &status); | |
36 | #else | |
37 | const auto error = ::stat(path.data(), &status); | |
38 | #endif | |
39 | if (error) { | |
40 | ec.assign(errno, std::generic_category()); | |
41 | } else { | |
42 | ec.clear(); | |
43 | } | |
44 | return status; | |
45 | } | |
46 | ||
47 | /// http://en.cppreference.com/w/cpp/filesystem/is_regular_file | |
48 | inline bool is_regular_file(file_status status) noexcept { | |
49 | #if defined(S_ISREG) | |
50 | return S_ISREG(status.st_mode); | |
51 | #elif !defined(S_ISREG) && defined(S_IFMT) && defined(S_IFREG) | |
52 | return (status.st_mode & S_IFMT) == S_IFREG; | |
53 | #else | |
54 | static_assert(false, "No POSIX stat() support."); | |
55 | #endif | |
56 | } | |
57 | ||
58 | /// http://en.cppreference.com/w/cpp/filesystem/is_regular_file | |
59 | inline bool is_regular_file(StringPiece path, std::error_code& ec) noexcept { | |
60 | return is_regular_file(status(path, ec)); | |
61 | } | |
62 | ||
63 | /// http://en.cppreference.com/w/cpp/filesystem/is_directory | |
64 | inline bool is_directory(file_status status) noexcept { | |
65 | #if defined(S_ISDIR) | |
66 | return S_ISDIR(status.st_mode); | |
67 | #elif !defined(S_ISDIR) && defined(S_IFMT) && defined(S_IFDIR) | |
68 | return (status.st_mode & S_IFMT) == S_IFDIR; | |
69 | #else | |
70 | static_assert(false, "NO POSIX stat() support."); | |
71 | #endif | |
72 | } | |
73 | ||
74 | /// http://en.cppreference.com/w/cpp/filesystem/is_directory | |
75 | inline bool is_directory(StringPiece path, std::error_code& ec) noexcept { | |
76 | return is_directory(status(path, ec)); | |
77 | } | |
78 | ||
79 | /// http://en.cppreference.com/w/cpp/filesystem/file_size | |
80 | inline std::uintmax_t file_size( | |
81 | StringPiece path, | |
82 | std::error_code& ec) noexcept { | |
83 | auto stat = status(path, ec); | |
84 | if (ec) { | |
85 | return -1; | |
86 | } | |
87 | if (!is_regular_file(stat)) { | |
88 | ec.assign(ENOTSUP, std::generic_category()); | |
89 | return -1; | |
90 | } | |
91 | ec.clear(); | |
92 | return stat.st_size; | |
93 | } | |
94 | } |