-
-
Notifications
You must be signed in to change notification settings - Fork 16
/
OSCommonLayer.cpp
172 lines (151 loc) · 4.56 KB
/
OSCommonLayer.cpp
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
117
118
119
120
121
122
123
124
125
126
127
128
129
130
131
132
133
134
135
136
137
138
139
140
141
142
143
144
145
146
147
148
149
150
151
152
153
154
155
156
157
158
159
160
161
162
163
164
165
166
167
168
169
170
171
172
#include "Log.h"
#include "OSCompatibilityLayer.h"
#include <algorithm>
#include <codecvt>
#include <filesystem>
namespace fs = std::filesystem;
namespace commonItems
{
bool TryCreateFolder(const std::string& path)
{
if (fs::exists(fs::u8path(path)))
return true;
if (fs::create_directory(fs::u8path(path)))
return true;
Log(LogLevel::Error) << "Could not create directory: " << path << " : " << GetLastErrorString();
return false;
}
std::wstring GetCurrentDirectoryWString()
{
// Tried straight returning wstring, but on Linux it will break if filesystem uses characters
// outside ascii, apparently inherent conversion is broken.
try
{
const auto path = fs::current_path().string();
return convertUTF8ToUTF16(path);
}
catch (std::exception& e)
{
Log(LogLevel::Error) << "Cannot determine current path; " << e.what();
return {};
}
}
std::set<std::string> GetAllFilesInFolder(const std::string& path)
{
std::set<std::string> fileNames;
if (!fs::exists(fs::u8path(path)))
return fileNames;
for (const auto& p: fs::directory_iterator(fs::u8path(path)))
{
if (!p.is_directory())
{
fileNames.insert(p.path().filename().string());
}
}
return fileNames;
}
std::set<std::string> GetAllSubfolders(const std::string& path)
{
std::set<std::string> subFolders;
if (!fs::exists(fs::u8path(path)))
return subFolders;
for (const auto& p: fs::directory_iterator(fs::u8path(path)))
{
if (p.is_directory())
{
subFolders.insert(p.path().filename().string());
}
}
return subFolders;
}
bool TryCopyFile(const std::string& sourcePath, const std::string& destPath)
{
if (fs::copy_file(fs::u8path(sourcePath), fs::u8path(destPath), std::filesystem::copy_options::overwrite_existing))
return true;
LOG(LogLevel::Warning) << "Could not copy file " << sourcePath << " to " << destPath << " - " << GetLastErrorString();
return false;
}
bool CopyFolder(const std::string& sourceFolder, const std::string& destFolder)
{
try
{
fs::copy(fs::u8path(sourceFolder), fs::u8path(destFolder), fs::copy_options::recursive);
return true;
}
catch (std::exception& e)
{
Log(LogLevel::Error) << "Could not copy folder: " << e.what() << " " << GetLastErrorString();
return false;
}
}
bool RenameFolder(const std::string& sourceFolder, const std::string& destFolder)
{
try
{
fs::rename(fs::u8path(sourceFolder), fs::u8path(destFolder));
return true;
}
catch (std::exception& e)
{
Log(LogLevel::Error) << "Could not rename folder: " << e.what() << " " << GetLastErrorString();
return false;
}
}
bool DoesFileExist(const std::string& path)
{
if (const auto tempPath = fs::u8path(path); fs::exists(tempPath) && !fs::is_directory(tempPath))
return true;
return false;
}
bool DoesFolderExist(const std::string& path)
{
if (const auto tempPath = fs::u8path(path); fs::exists(tempPath) && fs::is_directory(tempPath))
return true;
return false;
}
bool DeleteFolder(const std::string& folder)
{
if (!fs::exists(fs::u8path(folder)))
return true;
if (fs::remove_all(fs::u8path(folder)) != static_cast<std::uintmax_t>(-1))
return true;
Log(LogLevel::Error) << "Could not delete folder: " << folder << " " << GetLastErrorString();
return false;
}
std::string normalizeUTF8Path(const std::string& utf_8_path)
{
std::string asciiPath = convertUTF8ToASCII(utf_8_path);
std::ranges::replace(asciiPath, '/', '_');
std::ranges::replace(asciiPath, '\\', '_');
std::ranges::replace(asciiPath, ':', '_');
std::ranges::replace(asciiPath, '*', '_');
std::ranges::replace(asciiPath, '?', '_');
std::ranges::replace(asciiPath, '\"', '_');
std::ranges::replace(asciiPath, '<', '_');
std::ranges::replace(asciiPath, '>', '_');
std::ranges::replace(asciiPath, '|', '_');
asciiPath.erase(std::ranges::remove(asciiPath, '\t').begin(), asciiPath.end());
asciiPath.erase(std::ranges::remove(asciiPath, '\n').begin(), asciiPath.end());
asciiPath.erase(std::ranges::remove(asciiPath, '\r').begin(), asciiPath.end());
return asciiPath;
}
#if _MSC_VER >= 1900 && _MSC_VER < 1920
std::string utf16_to_utf8(std::u16string utf16_string)
{
std::wstring_convert<std::codecvt_utf8_utf16<int16_t>, int16_t> conversion;
auto p = reinterpret_cast<const int16_t*>(utf16_string.data());
return conversion.to_bytes(p, p + utf16_string.size());
}
#else
std::string utf16_to_utf8(const std::u16string& utf16_string)
{
std::wstring_convert<std::codecvt_utf8_utf16<char16_t>, char16_t> conversion;
return conversion.to_bytes(utf16_string);
}
#endif
std::string UTF16ToUTF8(const std::wstring& UTF16)
{
const std::u16string u16str(UTF16.begin(), UTF16.end());
return utf16_to_utf8(u16str);
}
} // namespace commonItems