-
Notifications
You must be signed in to change notification settings - Fork 0
Expand file tree
/
Copy pathfattr.hpp
More file actions
102 lines (94 loc) · 3.39 KB
/
Copy pathfattr.hpp
File metadata and controls
102 lines (94 loc) · 3.39 KB
1
2
3
4
5
6
7
8
9
10
11
12
13
14
15
16
17
18
19
20
21
22
23
24
25
26
27
28
29
30
31
32
33
34
35
36
37
38
39
40
41
42
43
44
45
46
47
48
49
50
51
52
53
54
55
56
57
58
59
60
61
62
63
64
65
66
67
68
69
70
71
72
73
74
75
76
77
78
79
80
81
82
83
84
85
86
87
88
89
90
91
92
93
94
95
96
97
98
99
100
101
102
/* File attributes functions. */
#pragma once
#include <filesystem>
#include <chrono>
#include <string>
#include "fexcept.hpp"
#ifdef _WIN32
#include <windows.h>
#else
#include <sys/stat.h>
#endif
namespace file {
bool exists(FNAME name) {
return std::filesystem::exists(name);
}
bool isRegular(FNAME name) {
if (!exists(name)) F_THROW_NOTFOUND(name);
return std::filesystem::is_regular_file(name);
}
std::string relativePathOf(FNAME name) {
// The relative path of a file.
// e.g. /usr/xxx/abc.txt -> abc.txt
if (!exists(name)) F_THROW_NOTFOUND(name);
return std::filesystem::relative(name).string();
}
std::string absPathOf(FNAME name) {
// Returns the absolute path.
// e.g. abc.txt -> /usr/xxx/abc.txt
if (!exists(name)) F_THROW_NOTFOUND(name);
return std::filesystem::absolute(name).string();
}
std::string extensionOf(FNAME name) {
// Returns the extension of the file.
// abc.txt -> .txt
if (!exists(name)) F_THROW_NOTFOUND(name);
return std::filesystem::path(name).extension().string();
}
int64_t modifyTime(const std::filesystem::path& p) {
/* Get the lastest modify timestamp of a file. */
auto tp = std::filesystem::last_write_time(p);
auto sctp = std::chrono::time_point_cast<std::chrono::system_clock::duration>(
tp - std::filesystem::file_time_type::clock::now() + std::chrono::system_clock::now()
);
return std::chrono::duration_cast<std::chrono::seconds>(sctp.time_since_epoch()).count();
}
std::string stemOf(FNAME name) {
// Returns the stem of the file.
// abc.txt -> abc
if (!exists(name)) F_THROW_NOTFOUND(name);
return std::filesystem::path(name).stem().string();
}
bool isReadOnly(FNAME name) {
if (!exists(name)) F_THROW_NOTFOUND(name);
#ifdef _WIN32
DWORD attr = GetFileAttributesA(name.c_str());
// Invalid file attributes
if (attr == INVALID_FILE_ATTRIBUTES) {
F_THROW_INVALIDATTR(name);
}
/* Read-only mark: FILE_ATTRIBUTE_READONLY */
return (attr & FILE_ATTRIBUTE_READONLY) != 0;
#else
struct stat fileStat{};
if (stat(name.c_str(), &fileStat) != 0) {
F_THROW_NOTFOUND(name); // File not fonud
}
// 0222 = All users not writable -> readonly.
return (fileStat.st_mode & S_IWUSR) == 0; // Owner unwritable
#endif
}
size_t size(FNAME name) {
/* Size of the file.(bytes) */
size_t res=0;
try {
res = static_cast<uint64_t>(std::filesystem::file_size(name));
} catch(...) {
F_THROW_NOTFOUND(name);
}
return res;
}
bool isHidden(FNAME name) {
if (!exists(name)) F_THROW_NOTFOUND(name);
#ifdef _WIN32
DWORD attr = GetFileAttributesA(name.c_str());
if (attr == INVALID_FILE_ATTRIBUTES) F_THROW_INVALIDATTR(name);
return (attr & FILE_ATTRIBUTE_HIDDEN) != 0;
#else
const std::filesystem::path path(name);
auto namestring = path.filename().string();
// The hidden file starts with '.'.
return !namestring.empty() && name.front() == '.';
#endif
}
}