diff --git a/CMakeLists.txt b/CMakeLists.txt index a28abbc7b..ed8919ba4 100644 --- a/CMakeLists.txt +++ b/CMakeLists.txt @@ -211,7 +211,7 @@ add_library(PKWare STATIC 3rdParty/PKWare/explode.cpp 3rdParty/PKWare/implode.cpp) -set(devilutionx_SRCS +set(devilutionx_SRCS Source/appfat.cpp Source/automap.cpp Source/capture.cpp @@ -296,6 +296,7 @@ set(devilutionx_SRCS Source/controls/touch.cpp Source/utils/console.cpp Source/utils/display.cpp + Source/utils/file_util.cpp Source/utils/paths.cpp Source/utils/soundsample.cpp Source/utils/thread.cpp @@ -359,7 +360,7 @@ if(SWITCH) Source/platform/switch/docking.cpp) set(BIN_TARGET devilutionx.elf) endif() - + if(VITA) list(APPEND devilutionx_SRCS Source/platform/vita/keyboard.cpp) diff --git a/Source/utils/file_util.cpp b/Source/utils/file_util.cpp new file mode 100644 index 000000000..7245a9c01 --- /dev/null +++ b/Source/utils/file_util.cpp @@ -0,0 +1,113 @@ +#include "utils/file_util.h" + +#include +#include + +#include + +#ifdef USE_SDL1 +#include "utils/sdl2_to_1_2_backports.h" +#endif + +#if defined(_WIN64) || defined(_WIN32) +// Suppress definitions of `min` and `max` macros by : +#define NOMINMAX 1 +#define WIN32_LEAN_AND_MEAN +#include +#endif + +#if _POSIX_C_SOURCE >= 200112L || defined(_BSD_SOURCE) || defined(__APPLE__) +#include +#include +#else +#include +#endif + +namespace devilution { + +bool FileExists(const char *path) +{ +#if _POSIX_C_SOURCE >= 200112L || defined(_BSD_SOURCE) || defined(__APPLE__) + return ::access(path, F_OK) == 0; +#else + FILE *file = std::fopen(path, "rb"); + if (file == NULL) + return false; + std::fclose(file); + return true; +#endif +} + +bool GetFileSize(const char *path, std::uintmax_t *size) +{ +#if defined(_WIN64) || defined(_WIN32) + WIN32_FILE_ATTRIBUTE_DATA attr; + int path_utf16_size = MultiByteToWideChar(CP_UTF8, 0, path, -1, NULL, 0); + wchar_t *path_utf16 = new wchar_t[path_utf16_size]; + if (MultiByteToWideChar(CP_UTF8, 0, path, -1, path_utf16, path_utf16_size) != path_utf16_size) { + delete[] path_utf16; + return false; + } + if (!GetFileAttributesExW(path_utf16, GetFileExInfoStandard, &attr)) { + delete[] path_utf16; + return false; + } + delete[] path_utf16; + *size = (attr.nFileSizeHigh) << (sizeof(attr.nFileSizeHigh) * 8) | attr.nFileSizeLow; + return true; +#else + struct ::stat stat_result; + if (::stat(path, &stat_result) == -1) + return false; + *size = static_cast(stat_result.st_size); + return true; +#endif +} + +bool ResizeFile(const char *path, std::uintmax_t size) +{ +#if defined(_WIN64) || defined(_WIN32) + LARGE_INTEGER lisize; + lisize.QuadPart = static_cast(size); + if (lisize.QuadPart < 0) { + return false; + } + int path_utf16_size = MultiByteToWideChar(CP_UTF8, 0, path, -1, NULL, 0); + wchar_t *path_utf16 = new wchar_t[path_utf16_size]; + if (MultiByteToWideChar(CP_UTF8, 0, path, -1, path_utf16, path_utf16_size) != path_utf16_size) { + delete[] path_utf16; + return false; + } + HANDLE file = ::CreateFileW(path_utf16, GENERIC_WRITE, 0, NULL, OPEN_EXISTING, 0, NULL); + delete[] path_utf16; + if (file == INVALID_HANDLE_VALUE) { + return false; + } else if (::SetFilePointerEx(file, lisize, NULL, FILE_BEGIN) == 0 || ::SetEndOfFile(file) == 0) { + ::CloseHandle(file); + return false; + } + ::CloseHandle(file); + return true; +#elif _POSIX_C_SOURCE >= 200112L || defined(_BSD_SOURCE) || defined(__APPLE__) + return ::truncate(path, static_cast(size)) == 0; +#else + static_assert(false, "truncate not implemented for the current platform"); +#endif +} + +void RemoveFile(const char *lpFileName) +{ + std::string name = lpFileName; + std::replace(name.begin(), name.end(), '\\', '/'); + FILE *f = fopen(name.c_str(), "r+"); + if (f) { + fclose(f); + remove(name.c_str()); + f = NULL; + SDL_Log("Removed file: %s", name.c_str()); + } else { + SDL_Log("Failed to remove file: %s", name.c_str()); + } +} + +} // namespace devilution diff --git a/Source/utils/file_util.h b/Source/utils/file_util.h index 879db38a9..61b3a9320 100644 --- a/Source/utils/file_util.h +++ b/Source/utils/file_util.h @@ -1,114 +1,11 @@ #pragma once -#include -#include #include - -#include - -#ifdef USE_SDL1 -#include "utils/sdl2_to_1_2_backports.h" -#endif - -#if defined(_WIN64) || defined(_WIN32) -// Suppress definitions of `min` and `max` macros by : -#define NOMINMAX 1 -#define WIN32_LEAN_AND_MEAN -#include -#endif - -#if _POSIX_C_SOURCE >= 200112L || defined(_BSD_SOURCE) || defined(__APPLE__) -#include -#include -#else -#include -#endif - namespace devilution { -inline bool FileExists(const char *path) -{ -#if _POSIX_C_SOURCE >= 200112L || defined(_BSD_SOURCE) || defined(__APPLE__) - return ::access(path, F_OK) == 0; -#else - FILE *file = std::fopen(path, "rb"); - if (file == NULL) - return false; - std::fclose(file); - return true; -#endif -} - -inline bool GetFileSize(const char *path, std::uintmax_t *size) -{ -#if defined(_WIN64) || defined(_WIN32) - WIN32_FILE_ATTRIBUTE_DATA attr; - int path_utf16_size = MultiByteToWideChar(CP_UTF8, 0, path, -1, NULL, 0); - wchar_t *path_utf16 = new wchar_t[path_utf16_size]; - if (MultiByteToWideChar(CP_UTF8, 0, path, -1, path_utf16, path_utf16_size) != path_utf16_size) { - delete[] path_utf16; - return false; - } - if (!GetFileAttributesExW(path_utf16, GetFileExInfoStandard, &attr)) { - delete[] path_utf16; - return false; - } - delete[] path_utf16; - *size = (attr.nFileSizeHigh) << (sizeof(attr.nFileSizeHigh) * 8) | attr.nFileSizeLow; - return true; -#else - struct ::stat stat_result; - if (::stat(path, &stat_result) == -1) - return false; - *size = static_cast(stat_result.st_size); - return true; -#endif -} - -inline bool ResizeFile(const char *path, std::uintmax_t size) -{ -#if defined(_WIN64) || defined(_WIN32) - LARGE_INTEGER lisize; - lisize.QuadPart = static_cast(size); - if (lisize.QuadPart < 0) { - return false; - } - int path_utf16_size = MultiByteToWideChar(CP_UTF8, 0, path, -1, NULL, 0); - wchar_t *path_utf16 = new wchar_t[path_utf16_size]; - if (MultiByteToWideChar(CP_UTF8, 0, path, -1, path_utf16, path_utf16_size) != path_utf16_size) { - delete[] path_utf16; - return false; - } - HANDLE file = ::CreateFileW(path_utf16, GENERIC_WRITE, 0, NULL, OPEN_EXISTING, 0, NULL); - delete[] path_utf16; - if (file == INVALID_HANDLE_VALUE) { - return false; - } else if (::SetFilePointerEx(file, lisize, NULL, FILE_BEGIN) == 0 || ::SetEndOfFile(file) == 0) { - ::CloseHandle(file); - return false; - } - ::CloseHandle(file); - return true; -#elif _POSIX_C_SOURCE >= 200112L || defined(_BSD_SOURCE) || defined(__APPLE__) - return ::truncate(path, static_cast(size)) == 0; -#else - static_assert(false, "truncate not implemented for the current platform"); -#endif -} - -inline void RemoveFile(const char *lpFileName) -{ - std::string name = lpFileName; - std::replace(name.begin(), name.end(), '\\', '/'); - FILE *f = fopen(name.c_str(), "r+"); - if (f) { - fclose(f); - remove(name.c_str()); - f = NULL; - SDL_Log("Removed file: %s", name.c_str()); - } else { - SDL_Log("Failed to remove file: %s", name.c_str()); - } -} +bool FileExists(const char *path); +bool GetFileSize(const char *path, std::uintmax_t *size); +bool ResizeFile(const char *path, std::uintmax_t size); +void RemoveFile(const char *lpFileName); } // namespace devilution