forked from Hal47/dsfix
-
Notifications
You must be signed in to change notification settings - Fork 0
/
Copy pathutil.cpp
131 lines (118 loc) · 4.76 KB
/
util.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
#include "util.h"
#include <spdlog/fmt/ostr.h>
#include <system_error>
std::wstring FormatMessageString(DWORD dwMessageId);
std::string toUtf8(const std::wstring& wideCharStr);
std::wstring toUnicode(const std::string& multiByteStr);
std::istream& operator>>(std::istream& is, std::wstring& s) {
std::string utf8;
is >> utf8;
s = toUnicode(utf8);
return is;
}
std::ostream& operator<<(std::ostream& os, const std::wstring& s) {
os << toUtf8(s);
return os;
}
std::ostream& operator<<(std::ostream& os, const wchar_t* s) {
os << toUtf8(s);
return os;
}
std::wstring FormatMessageString(DWORD dwMessageId) {
LPWSTR pBuffer = nullptr;
DWORD length = ::FormatMessageW(FORMAT_MESSAGE_ALLOCATE_BUFFER | FORMAT_MESSAGE_FROM_SYSTEM |
FORMAT_MESSAGE_IGNORE_INSERTS,
nullptr, dwMessageId, MAKELANGID(LANG_NEUTRAL, SUBLANG_DEFAULT),
(LPWSTR)&pBuffer, 0, nullptr);
if (length == 0)
return L"";
std::wstring result(pBuffer, length);
LocalFree(pBuffer);
return result;
}
std::wstring GetLastErrorString() { return FormatMessageString(GetLastError()); }
fs::path GetModuleDirectoryPath(HMODULE hModule) {
fs::path dllPath = GetModuleFileNamePath(hModule);
return dllPath.parent_path();
}
fs::path GetModuleFileNamePath(HMODULE hModule) {
std::wstring filename;
filename.resize(MAX_PATH);
bool truncated;
do {
DWORD nRet = ::GetModuleFileNameW(hModule, &filename[0], filename.size());
if (nRet == 0)
throw std::system_error(::GetLastError(), std::system_category());
truncated = nRet == filename.size();
filename.resize(truncated ? filename.size() * 2 : nRet);
} while (truncated);
return filename;
}
fs::path GetSystemDirectoryPath() {
std::wstring buffer;
buffer.resize(MAX_PATH);
bool notEnoughSpace;
do {
UINT uRet = ::GetSystemDirectoryW(&buffer[0], buffer.size());
if (uRet == 0) {
throw std::system_error(::GetLastError(), std::system_category());
}
notEnoughSpace = uRet > buffer.size();
buffer.resize(uRet);
} while (notEnoughSpace);
return buffer;
}
std::string toUtf8(const std::wstring& wideCharStr) {
if (wideCharStr.empty())
return "";
int cbMultiByte = ::WideCharToMultiByte(CP_UTF8, 0, wideCharStr.data(), wideCharStr.size(),
nullptr, 0, nullptr, nullptr);
if (cbMultiByte == 0)
throw std::system_error(::GetLastError(), std::system_category());
std::string multiByteStr;
multiByteStr.resize(cbMultiByte);
cbMultiByte = ::WideCharToMultiByte(CP_UTF8, 0, wideCharStr.data(), wideCharStr.size(),
&multiByteStr[0], cbMultiByte, nullptr, nullptr);
if (cbMultiByte == 0)
throw std::system_error(::GetLastError(), std::system_category());
return multiByteStr;
}
std::wstring toUnicode(const std::string& multiByteStr) {
if (multiByteStr.empty())
return L"";
int cchWideChar =
::MultiByteToWideChar(CP_UTF8, 0, multiByteStr.data(), multiByteStr.size(), nullptr, 0);
if (cchWideChar == 0)
throw std::system_error(::GetLastError(), std::system_category());
std::wstring wideCharStr;
wideCharStr.resize(cchWideChar);
cchWideChar = ::MultiByteToWideChar(CP_UTF8, 0, multiByteStr.data(), multiByteStr.size(),
&wideCharStr[0], cchWideChar);
if (cchWideChar == 0)
throw std::system_error(::GetLastError(), std::system_category());
return wideCharStr;
}
std::string toUtf8(const wchar_t* wideCharStr) {
int cbMultiByte =
::WideCharToMultiByte(CP_UTF8, 0, wideCharStr, -1, nullptr, 0, nullptr, nullptr);
if (cbMultiByte == 0)
throw std::system_error(::GetLastError(), std::system_category());
std::string multiByteStr;
multiByteStr.resize(cbMultiByte - 1); // cbMultiByte includes the null character
cbMultiByte = ::WideCharToMultiByte(CP_UTF8, 0, wideCharStr, -1, &multiByteStr[0], cbMultiByte,
nullptr, nullptr);
if (cbMultiByte == 0)
throw std::system_error(::GetLastError(), std::system_category());
return multiByteStr;
}
std::wstring toUnicode(const char* multiByteStr) {
int cchWideChar = ::MultiByteToWideChar(CP_UTF8, 0, multiByteStr, -1, nullptr, 0);
if (cchWideChar == 0)
throw std::system_error(::GetLastError(), std::system_category());
std::wstring wideCharStr;
wideCharStr.resize(cchWideChar - 1); // cchWideChar includes the null character
cchWideChar = ::MultiByteToWideChar(CP_UTF8, 0, multiByteStr, -1, &wideCharStr[0], cchWideChar);
if (cchWideChar == 0)
throw std::system_error(::GetLastError(), std::system_category());
return wideCharStr;
}