From c6ec40ce9317938aa1ef90fa47d01ea52d7a5805 Mon Sep 17 00:00:00 2001 From: mykola2312 <49044616+mykola2312@users.noreply.github.com> Date: Wed, 24 Nov 2021 23:35:12 +0200 Subject: [PATCH] 24.11.2021: Backup commit. --- CMakeLists.txt | 7 +- win32ctrl.cpp | 4 + win32ctrl.h | 2 + win32util.cpp | 277 ++++++++++++++++++++++++++++++++++++++++++++----- win32util.h | 51 ++++++++- 5 files changed, 311 insertions(+), 30 deletions(-) diff --git a/CMakeLists.txt b/CMakeLists.txt index acd792a..686ba60 100644 --- a/CMakeLists.txt +++ b/CMakeLists.txt @@ -18,6 +18,7 @@ add_library(win32ctrl SHARED ${SOURCES} ${HEADERS}) target_include_directories(win32ctrl PUBLIC ${CMAKE_CURRENT_SOURCE_DIR} ) -target_link_libraries(win32ctrl PRIVATE - comctl32 -) + +if(MSVC) + target_link_libraries(win32ctrl PRIVATE comctl32) +endif() diff --git a/win32ctrl.cpp b/win32ctrl.cpp index 7bb7a21..c583f01 100644 --- a/win32ctrl.cpp +++ b/win32ctrl.cpp @@ -1,4 +1,6 @@ #include "win32ctrl.h" + +#ifdef WIN32 #include "win32util.h" #include #include @@ -509,3 +511,5 @@ AppMonitor::TV_GetItem(HWND hTree, DWORD_PTR dwItem) if (IsWow64()) return TV_GetItem32(hTree, dwItem); else return TV_GetItem64(hTree, dwItem); } + +#endif \ No newline at end of file diff --git a/win32ctrl.h b/win32ctrl.h index 635d720..fe67596 100644 --- a/win32ctrl.h +++ b/win32ctrl.h @@ -1,6 +1,7 @@ #ifndef __WIN32CTRL_H #define __WIN32CTRL_H +#ifdef WIN32 #include #include #include @@ -166,5 +167,6 @@ private: HWND m_hWnd = NULL; } m_Tmp; }; +#endif #endif diff --git a/win32util.cpp b/win32util.cpp index 87fa7b9..776f249 100644 --- a/win32util.cpp +++ b/win32util.cpp @@ -1,10 +1,41 @@ #include "win32util.h" + +#ifdef WIN32 #include +#endif + #include #include #include +#include #include #include +#include + +byteorder ArchByteOrder() +{ + uint16_t word = 0x0001; + auto* src = (char*)&word; + + return src[0] ? LittleEndian : BigEndian; +} + +const char* ArchInternalUCS() +{ + return ArchByteOrder() == BigEndian ? "UCS-4BE" : "UCS-4LE"; +} + +#ifdef WIN32 + +bool IsWindowsSystem() +{ + return true; +} + +bool IsLinuxSystem() +{ + return false; +} std::wstring TextToWchar(const std::string& text) { @@ -51,6 +82,178 @@ std::string WcharToAnsi(const std::wstring& text, int cp) return std::string(pszChar.get()); } +std::wstring TermToWchar(const std::string& text) +{ + return AnsiToWchar(text, GetConsoleCP()); +} + +std::string WcharToTerm(const std::wstring& text) +{ + return WcharToAnsi(text, GetConsoleOutputCP()); +} + +std::wstring JoinFilePath(const std::wstring& path, + const std::wstring& name) +{ + return path + L"\\" + name; +} + +listdir ListDirectory(const std::wstring& path) +{ + auto pFind = std::make_unique(); + std::wstring findPath = path + L"\\*"; + + std::vector files, dirs; + HANDLE hFind = FindFirstFileW(findPath.c_str(), pFind.get()); + if (hFind) + { + do { + if (!wcscmp(pFind->cFileName, L".")) + continue; + if (!wcscmp(pFind->cFileName, L"..")) + continue; + + if (pFind->dwFileAttributes & FILE_ATTRIBUTE_DIRECTORY) + dirs.emplace_back(pFind->cFileName); + else files.emplace_back(pFind->cFileName); + } while (FindNextFileW(hFind, pFind.get())); + FindClose(hFind); + } + + return std::make_tuple(files, dirs); +} + +uint64_t GetDirectorySize(const std::wstring& path) +{ + uint64_t uDirSize = 0; + auto [files, dirs] = ListDirectory(path); + + for (auto& file : files) + { + LARGE_INTEGER fileSize = {0}; + HANDLE hFile = CreateFileW(JoinFilePath(path, file).c_str(), + GENERIC_READ, FILE_SHARE_READ, NULL, OPEN_EXISTING, + FILE_ATTRIBUTE_NORMAL, NULL); + if (hFile == INVALID_HANDLE_VALUE) + continue; + if (GetFileSizeEx(hFile, &fileSize)) + uDirSize += fileSize.QuadPart; + CloseHandle(hFile); + } + + for (auto& dir : dirs) + uDirSize += GetDirectorySize(JoinFilePath(path, dir)); + + return uDirSize; +} +#else + +#include +#include + +bool IsWindowsSystem() +{ + return false; +} + +bool IsLinuxSystem() +{ + return true; +} + +std::wstring TextToWchar(const std::string& text) +{ + size_t bufLen = text.size() + 1; + size_t bufSize = bufLen * sizeof(wchar_t); + auto szOut = std::make_unique(bufLen); + + char* in = (char*)text.c_str(), *out = (char*)szOut.get(); + size_t inLen = bufLen, outLen = bufSize; + memset(out, '\0', outLen); + + iconv_t _cv = iconv_open(ArchInternalUCS(), "UTF-8"); + iconv(_cv, &in, &inLen, &out, &outLen); + iconv_close(_cv); + + size_t strLen = (bufSize - outLen) / sizeof(wchar_t); + szOut[strLen - 1] = 0; + return std::wstring(szOut.get(), strLen - 1); +} + +std::string WcharToText(const std::wstring& text) +{ + size_t bufSize = (text.size()+1)*sizeof(wchar_t); + auto szOut = std::make_unique(bufSize); + + char* in = (char*)text.c_str(), *out = szOut.get(); + size_t inLen = (text.size()+1)*sizeof(wchar_t), outLen = bufSize; + memset(szOut.get(), '\0', bufSize); + + iconv_t cv = iconv_open("UTF-8", ArchInternalUCS()); + iconv(cv, &in, &inLen, &out, &outLen); + iconv_close(cv); + + size_t strLen = bufSize - outLen; + szOut[strLen - 1] = 0; + return std::string(szOut.get(), strLen - 1); +} + +std::wstring AnsiToWchar(const std::string& text, int cp) +{ + if (cp == 3) cp = 1251; + + size_t bufLen = text.size() + 1; + size_t bufSize = bufLen * sizeof(wchar_t); + auto szOut = std::make_unique(bufLen); + + char* in = (char*)text.c_str(), *out = (char*)szOut.get(); + size_t inLen = bufLen, outLen = bufSize; + memset(out, '\0', outLen); + + iconv_t _cv = iconv_open(ArchInternalUCS(), + ("CP" + std::to_string(cp)).c_str()); + iconv(_cv, &in, &inLen, &out, &outLen); + iconv_close(_cv); + + size_t strLen = (bufSize - outLen) / sizeof(wchar_t); + szOut[strLen - 1] = 0; + return std::wstring(szOut.get(), strLen - 1); +} + +std::string WcharToAnsi(const std::wstring& text, int cp) +{ + if (cp == 3) cp = 1251; + + size_t bufSize = (text.size()+1)*sizeof(wchar_t); + auto szOut = std::make_unique(bufSize); + + char* in = (char*)text.c_str(), *out = szOut.get(); + size_t inLen = (text.size()+1)*sizeof(wchar_t), outLen = bufSize; + memset(szOut.get(), '\0', bufSize); + + iconv_t _cv = iconv_open(("CP" + + std::to_string(cp)).c_str(), ArchInternalUCS()); + iconv(_cv, &in, &inLen, &out, &outLen); + iconv_close(_cv); + + size_t strLen = bufSize - outLen; + szOut[strLen - 1] = 0; + return std::string(szOut.get(), strLen - 1); +} + +std::wstring TermToWchar(const std::string& text) +{ + return TextToWchar(text); +} + +std::string WcharToTerm(const std::wstring& text) +{ + return WcharToText(text); +} + +#endif + +#ifdef WIN32 struct _findwnd_s { DWORD m_dwPid; const char* m_pClass; @@ -139,27 +342,50 @@ bool ReconnectIO(bool OpenNewConsole) return MadeConsole; } +#else + +FILE* _wfopen(const wchar_t* path, const wchar_t* mode) +{ + return fopen(WcharToText(path).c_str(), WcharToText(mode).c_str()); +} + +int _wfopen_s(FILE** fpFile, const wchar_t* path, const wchar_t* mode) +{ + *fpFile = fopen(WcharToText(path).c_str(), WcharToText(mode).c_str()); + return !!(*fpFile); +} + +std::wstring JoinFilePath(const std::wstring& path, + const std::wstring& name) +{ + return path + L"/" + name; +} + +#include listdir ListDirectory(const std::wstring& path) { - auto pFind = std::make_unique(); - std::wstring findPath = path + L"\\*"; - std::vector files, dirs; - HANDLE hFind = FindFirstFileW(findPath.c_str(), pFind.get()); - if (hFind) + std::string utfPath = WcharToText(path); + + DIR* dir; + struct dirent* ent; + if (dir = opendir(utfPath.c_str())) { - do { - if (!wcscmp(pFind->cFileName, L".")) + while (ent = readdir(dir)) + { + if (!strcmp(ent->d_name, ".")) continue; - if (!wcscmp(pFind->cFileName, L"..")) + if (!strcmp(ent->d_name, "..")) continue; - - if (pFind->dwFileAttributes & FILE_ATTRIBUTE_DIRECTORY) - dirs.emplace_back(pFind->cFileName); - else files.emplace_back(pFind->cFileName); - } while (FindNextFileW(hFind, pFind.get())); - FindClose(hFind); + + std::wstring ucsName = TextToWchar(ent->d_name); + if (ent->d_type == DT_DIR) + dirs.push_back(ucsName); + else if (ent->d_type == DT_REG) + files.push_back(ucsName); + } + closedir(dir); } return std::make_tuple(files, dirs); @@ -172,19 +398,22 @@ uint64_t GetDirectorySize(const std::wstring& path) for (auto& file : files) { - LARGE_INTEGER fileSize = {0}; - HANDLE hFile = CreateFileW((path + L"\\" + file).c_str(), - GENERIC_READ, FILE_SHARE_READ, NULL, OPEN_EXISTING, - FILE_ATTRIBUTE_NORMAL, NULL); - if (hFile == INVALID_HANDLE_VALUE) - continue; - if (GetFileSizeEx(hFile, &fileSize)) - uDirSize += fileSize.QuadPart; - CloseHandle(hFile); + int64_t fileSize = {0}; + std::string utfPath = WcharToText(JoinFilePath(path, file)); + FILE* pFile = fopen(utfPath.c_str(), "rb"); + if (!pFile) continue; + + fseek(pFile, 0L, SEEK_END); + fileSize = (int64_t)ftell(pFile); + fclose(pFile); + + if (fileSize > 0) uDirSize += fileSize; } for (auto& dir : dirs) - uDirSize += GetDirectorySize(path + L"\\" + dir); + uDirSize += GetDirectorySize(JoinFilePath(path, dir)); return uDirSize; } + +#endif diff --git a/win32util.h b/win32util.h index 6ce61a2..fd270ca 100644 --- a/win32util.h +++ b/win32util.h @@ -1,21 +1,66 @@ #ifndef __WIN32UTIL_H #define __WIN32UTIL_H -#include #include + +#ifdef WIN32 +#include +#endif + +#ifdef min +#undef min +#endif + +#include #include #include #include +enum byteorder { + BigEndian = 0, + LittleEndian = 1 +}; + +byteorder ArchByteOrder(); +const char* ArchInternalUCS(); +bool IsWindowsSystem(); +bool IsLinuxSystem(); + std::wstring TextToWchar(const std::string& text); std::string WcharToText(const std::wstring& text); -std::wstring AnsiToWchar(const std::string& text, int cp = CP_THREAD_ACP); -std::string WcharToAnsi(const std::wstring& text, int cp = CP_THREAD_ACP); +std::wstring AnsiToWchar(const std::string& text, int cp = 3); +std::string WcharToAnsi(const std::wstring& text, int cp = 3); +std::wstring TermToWchar(const std::string& text); +std::string WcharToTerm(const std::wstring& text); + +#ifdef WIN32 bool FindProcessWindow(DWORD dwPid, const char* pClass, HWND& hWnd, DWORD& uiThread); bool ReconnectIO(bool OpenNewConsole); +#else +#define CP_UTF7 65000 +#define CP_UTF8 65001 + +#define _fseeki64 fseeko64 +#define _ftelli64 ftello64 + +FILE* _wfopen(const wchar_t* path, const wchar_t* mode); +int _wfopen_s(FILE** fpFile, const wchar_t* path, const wchar_t* mode); + +#include +#include + +#define scanf_s scanf +#define sscanf_s sscanf +#define sprintf_s sprintf +#define ssprintf_s ssprintf + +#endif + +std::wstring JoinFilePath(const std::wstring& path, + const std::wstring& name); using listdir = std::tuple< std::vector,