#include "storm/File.hpp" #include #include #include namespace { struct NativeFileHandle { std::ifstream stream; std::streamsize size = 0; }; std::string NormalizePath(const char* filename) { std::string path = filename ? filename : ""; for (char& ch : path) { if (ch == '\\') { ch = '/'; } } return path; } } int32_t STORMAPI SFileOpenArchive(const char* archivename, int32_t priority, uint32_t flags, HSARCHIVE* handle) { (void)archivename; (void)priority; (void)flags; if (handle) { *handle = nullptr; } return 0; } int32_t STORMAPI SFileCloseArchive(HSARCHIVE handle) { (void)handle; return 0; } int32_t STORMAPI SFileOpenFileEx(HSARCHIVE archivehandle, const char* filename, uint32_t flags, HSFILE* handle) { (void)archivehandle; (void)flags; if (!filename || !handle) { return 0; } auto file = new NativeFileHandle(); file->stream.open(NormalizePath(filename), std::ios::in | std::ios::binary | std::ios::ate); if (!file->stream.is_open()) { delete file; *handle = nullptr; return 0; } file->stream.seekg(0, std::ios::beg); file->stream.ignore(std::numeric_limits::max()); file->size = file->stream.gcount(); file->stream.clear(); file->stream.seekg(0, std::ios::beg); *handle = reinterpret_cast(file); return 1; } int32_t STORMAPI SFileReadFile(HSFILE handle, void* buffer, uint32_t bytestoread, uint32_t* bytesread, LPOVERLAPPED overlapped) { (void)overlapped; if (!handle || !buffer) { if (bytesread) { *bytesread = 0; } return 0; } auto file = reinterpret_cast(handle); file->stream.read(static_cast(buffer), bytestoread); if (bytesread) { *bytesread = static_cast(file->stream.gcount()); } return 1; } uint32_t STORMAPI SFileGetFileSize(HSFILE handle, uint32_t* filesizehigh) { if (!handle) { if (filesizehigh) { *filesizehigh = 0; } return 0; } auto file = reinterpret_cast(handle); uint64_t size = static_cast(file->size); if (filesizehigh) { *filesizehigh = static_cast(size >> 32); } return static_cast(size & 0xFFFFFFFFu); } uint32_t STORMAPI SFileSetFilePointer(HSFILE handle, int32_t distancetomove, int32_t* distancetomovehigh, uint32_t movemethod) { if (!handle) { if (distancetomovehigh) { *distancetomovehigh = 0; } return 0; } int64_t offset = static_cast(distancetomove); if (distancetomovehigh) { offset |= (static_cast(*distancetomovehigh) << 32); } std::ios_base::seekdir dir = std::ios::beg; switch (movemethod) { case 1: dir = std::ios::cur; break; case 2: dir = std::ios::end; break; default: dir = std::ios::beg; break; } auto file = reinterpret_cast(handle); file->stream.clear(); file->stream.seekg(static_cast(offset), dir); std::streamoff pos = file->stream.tellg(); uint64_t upos = pos < 0 ? 0 : static_cast(pos); if (distancetomovehigh) { *distancetomovehigh = static_cast(upos >> 32); } return static_cast(upos & 0xFFFFFFFFu); } int32_t STORMAPI SFileCloseFile(HSFILE handle) { if (!handle) { return 0; } auto file = reinterpret_cast(handle); file->stream.close(); delete file; return 1; }