132 lines
4.3 KiB
C++
132 lines
4.3 KiB
C++
/*
|
|
* MIT License
|
|
*
|
|
* Copyright (c) 2025 Vanessa T. <nessa@neko-tools.de>
|
|
*
|
|
* Permission is hereby granted, free of charge, to any person obtaining a copy
|
|
* of this software and associated documentation files (the "Software"), to deal
|
|
* in the Software without restriction, including without limitation the rights
|
|
* to use, copy, modify, merge, publish, distribute, sublicense, and/or sell
|
|
* copies of the Software, and to permit persons to whom the Software is
|
|
* furnished to do so, subject to the following conditions:
|
|
*
|
|
* The above copyright notice and this permission notice shall be included in all
|
|
* copies or substantial portions of the Software.
|
|
*
|
|
* THE SOFTWARE IS PROVIDED "AS IS", WITHOUT WARRANTY OF ANY KIND, EXPRESS OR
|
|
* IMPLIED, INCLUDING BUT NOT LIMITED TO THE WARRANTIES OF MERCHANTABILITY,
|
|
* FITNESS FOR A PARTICULAR PURPOSE AND NONINFRINGEMENT. IN NO EVENT SHALL THE
|
|
* AUTHORS OR COPYRIGHT HOLDERS BE LIABLE FOR ANY CLAIM, DAMAGES OR OTHER
|
|
* LIABILITY, WHETHER IN AN ACTION OF CONTRACT, TORT OR OTHERWISE, ARISING FROM,
|
|
* OUT OF OR IN CONNECTION WITH THE SOFTWARE OR THE USE OR OTHER DEALINGS IN THE
|
|
* SOFTWARE.
|
|
*/
|
|
|
|
#include "Utility.h"
|
|
|
|
#include <windows.h>
|
|
#include <string>
|
|
#include <stdexcept>
|
|
|
|
std::wstring stringToWString(const std::string& str) {
|
|
if (str.empty()) return {};
|
|
|
|
// Calculate the required buffer size
|
|
int size = MultiByteToWideChar(CP_UTF8, 0, str.c_str(), -1, nullptr, 0);
|
|
std::wstring result(size - 1, 0); // size-1 because MultiByteToWideChar counts null terminator
|
|
MultiByteToWideChar(CP_UTF8, 0, str.c_str(), -1, &result[0], size);
|
|
|
|
return result;
|
|
}
|
|
|
|
std::string wstringToString(const std::wstring& wstr) {
|
|
// Convert to UTF-8
|
|
int size_needed = WideCharToMultiByte(CP_UTF8, 0, wstr.c_str(), -1, nullptr, 0, nullptr, nullptr);
|
|
std::string message(size_needed - 1, 0); // -1 because WideCharToMultiByte counts null terminator
|
|
WideCharToMultiByte(CP_UTF8, 0, wstr.c_str(), -1, &message[0], size_needed, nullptr, nullptr);
|
|
|
|
return message;
|
|
}
|
|
|
|
std::string formatBytesString(size_t bytes) {
|
|
const char* units[] = {"B", "KB", "MB", "GB", "TB"};
|
|
int unitIndex = 0;
|
|
auto displayBytes = static_cast<double>(bytes);
|
|
|
|
while (displayBytes >= 1024 && unitIndex < 4) {
|
|
displayBytes /= 1024;
|
|
unitIndex++;
|
|
}
|
|
|
|
char buffer[64];
|
|
std::snprintf(buffer, sizeof(buffer), "%.2f %s", displayBytes, units[unitIndex]);
|
|
return {buffer};
|
|
}
|
|
|
|
std::wstring formatBytesWideString(size_t bytes) {
|
|
return stringToWString(formatBytesString(bytes));
|
|
}
|
|
|
|
std::vector<std::string> convertCommandLine(int argc, char **argv) {
|
|
std::vector<std::string> args;
|
|
|
|
for (auto i = 1; i < argc; i++) {
|
|
args.emplace_back(argv[i]);
|
|
}
|
|
|
|
return args;
|
|
}
|
|
|
|
std::string getErrorMessage(DWORD errorCode) {
|
|
if (errorCode == 0) return {};
|
|
|
|
LPWSTR messageBuffer = nullptr;
|
|
DWORD size = FormatMessageW(
|
|
FORMAT_MESSAGE_ALLOCATE_BUFFER |
|
|
FORMAT_MESSAGE_FROM_SYSTEM |
|
|
FORMAT_MESSAGE_IGNORE_INSERTS,
|
|
nullptr,
|
|
errorCode,
|
|
MAKELANGID(LANG_NEUTRAL, SUBLANG_DEFAULT),
|
|
reinterpret_cast<LPWSTR>(&messageBuffer),
|
|
0,
|
|
nullptr
|
|
);
|
|
|
|
if (size == 0) {
|
|
return "Unknown error code: " + std::to_string(errorCode);
|
|
}
|
|
|
|
// Convert to wstring first to handle Unicode properly
|
|
std::wstring wmessage(messageBuffer);
|
|
// Free the Windows-allocated buffer
|
|
LocalFree(messageBuffer);
|
|
|
|
// Remove potential trailing newline and carriage return
|
|
while (!wmessage.empty() && (wmessage.back() == L'\n' || wmessage.back() == L'\r')) {
|
|
wmessage.pop_back();
|
|
}
|
|
|
|
return std::to_string(errorCode) + " - " + wstringToString(wmessage);
|
|
}
|
|
|
|
void checkAndThrowLastWindowsError(const std::string& message) {
|
|
auto lastError = GetLastError();
|
|
if (lastError != ERROR_SUCCESS) {
|
|
SetLastError(0);
|
|
|
|
throw std::runtime_error(message + ": " + getErrorMessage(lastError));
|
|
}
|
|
}
|
|
|
|
ConsoleDimensions getConsoleDimensions() {
|
|
CONSOLE_SCREEN_BUFFER_INFO csbi;
|
|
int columns, rows;
|
|
|
|
GetConsoleScreenBufferInfo(GetStdHandle(STD_OUTPUT_HANDLE), &csbi);
|
|
columns = csbi.srWindow.Right - csbi.srWindow.Left + 1;
|
|
rows = csbi.srWindow.Bottom - csbi.srWindow.Top + 1;
|
|
|
|
return { columns, rows};
|
|
}
|