/
file.h
116 lines (98 loc) · 2.7 KB
/
file.h
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
103
104
105
106
107
108
109
110
111
112
113
114
115
116
#pragma once
#include "itextstream.h"
#include "fs.h"
#include "debugging/debugging.h"
/// \file
/// \brief OS file-system querying and manipulation.
#ifdef WIN32
#include <io.h> // _access()
#ifdef _MSC_VER
// greebo: The Windows API doesn't define R_OK et al, but luckily
// the _access method takes the same integer/bit values as the POSIX access()
#define F_OK 0x00
#define W_OK 0x02
#define R_OK 0x04
#endif
#else
#include <unistd.h> // access()
#endif
namespace os
{
namespace detail
{
enum class FileAccess
{
Read = R_OK,
Write = W_OK,
ReadWrite = Read | Write,
Exists = F_OK
};
/// \brief Returns true if the file or directory identified by \p path exists and/or may be
/// accessed for reading, writing or both, depending on the value of \p mode.
inline bool checkFileAccess(const std::string& path, FileAccess mode)
{
#ifdef WIN32
return ::_access(path.c_str(), static_cast<int>(mode)) == 0;
#else
return ::access(path.c_str(), static_cast<int>(mode)) == 0;
#endif
}
}
/// \brief Returns true if the file or directory identified by \p path exists and may be opened for reading.
inline bool fileIsReadable(const std::string& path)
{
return detail::checkFileAccess(path, detail::FileAccess::Read);
}
/// \brief Returns true if the file or directory identified by \p path exists and may be opened for reading.
inline bool fileIsReadable(const fs::path& path)
{
return detail::checkFileAccess(path.string(), detail::FileAccess::Read);
}
/// \brief Returns true if the file or directory identified by \p path exists and may be opened for writing.
inline bool fileIsWritable(const std::string& path)
{
return detail::checkFileAccess(path, detail::FileAccess::Write);
}
/// \brief Returns true if the file or directory identified by \p path exists and may be opened for writing.
inline bool fileIsWritable(const fs::path& path)
{
return detail::checkFileAccess(path.string(), detail::FileAccess::Write);
}
/// \brief Returns true if the file or directory identified by \p path exists.
inline bool fileOrDirExists(const std::string& path)
{
try
{
return fs::exists(path);
}
catch (fs::filesystem_error&)
{
return false;
}
}
/// \brief Returns true if the file or directory identified by \p path exists.
inline bool fileOrDirExists(const fs::path& path)
{
try
{
return fs::exists(path);
}
catch (fs::filesystem_error&)
{
return false;
}
}
// Returns the file size in bytes, or static_cast<std::size_t>(-1)
inline std::size_t getFileSize(const std::string& path)
{
try
{
return static_cast<std::size_t>(fs::file_size(path));
}
catch (fs::filesystem_error& err)
{
rError() << "Error checking filesize: " << err.what() << std::endl;
return static_cast<std::size_t>(-1);
}
}
} // namespace