/* * MIT License * * Copyright (c) 2025 Vanessa T. * * 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 #include #include 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(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 convertCommandLine(int argc, char **argv) { std::vector 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(&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}; }