feat(file): implement native sfile backend

This commit is contained in:
aomizu 2025-12-31 09:56:49 +09:00 committed by fallenoak
parent ac556fbda9
commit 65a6fc72b4

View file

@ -1,12 +1,32 @@
#include "storm/File.hpp"
#include <fstream>
#include <limits>
#include <string>
// TODO: implement native filesystem-backed SFile functions. same functionality as whoa's SFile?
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;
(void)handle;
if (handle) {
*handle = nullptr;
}
return 0;
}
@ -17,42 +37,116 @@ int32_t STORMAPI SFileCloseArchive(HSARCHIVE handle) {
int32_t STORMAPI SFileOpenFileEx(HSARCHIVE archivehandle, const char* filename, uint32_t flags, HSFILE* handle) {
(void)archivehandle;
(void)filename;
(void)flags;
(void)handle;
return 0;
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<std::streamsize>::max());
file->size = file->stream.gcount();
file->stream.clear();
file->stream.seekg(0, std::ios::beg);
*handle = reinterpret_cast<HSFILE>(file);
return 1;
}
int32_t STORMAPI SFileReadFile(HSFILE handle, void* buffer, uint32_t bytestoread, uint32_t* bytesread, LPOVERLAPPED overlapped) {
(void)handle;
(void)buffer;
(void)bytestoread;
(void)overlapped;
if (bytesread) {
*bytesread = 0;
if (!handle || !buffer) {
if (bytesread) {
*bytesread = 0;
}
return 0;
}
return 0;
auto file = reinterpret_cast<NativeFileHandle*>(handle);
file->stream.read(static_cast<char*>(buffer), bytestoread);
if (bytesread) {
*bytesread = static_cast<uint32_t>(file->stream.gcount());
}
return 1;
}
uint32_t STORMAPI SFileGetFileSize(HSFILE handle, uint32_t* filesizehigh) {
(void)handle;
if (filesizehigh) {
*filesizehigh = 0;
if (!handle) {
if (filesizehigh) {
*filesizehigh = 0;
}
return 0;
}
return 0;
auto file = reinterpret_cast<NativeFileHandle*>(handle);
uint64_t size = static_cast<uint64_t>(file->size);
if (filesizehigh) {
*filesizehigh = static_cast<uint32_t>(size >> 32);
}
return static_cast<uint32_t>(size & 0xFFFFFFFFu);
}
uint32_t STORMAPI SFileSetFilePointer(HSFILE handle, int32_t distancetomove, int32_t* distancetomovehigh, uint32_t movemethod) {
(void)handle;
(void)distancetomove;
(void)movemethod;
if (distancetomovehigh) {
*distancetomovehigh = 0;
if (!handle) {
if (distancetomovehigh) {
*distancetomovehigh = 0;
}
return 0;
}
return 0;
int64_t offset = static_cast<int64_t>(distancetomove);
if (distancetomovehigh) {
offset |= (static_cast<int64_t>(*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<NativeFileHandle*>(handle);
file->stream.clear();
file->stream.seekg(static_cast<std::streamoff>(offset), dir);
std::streamoff pos = file->stream.tellg();
uint64_t upos = pos < 0 ? 0 : static_cast<uint64_t>(pos);
if (distancetomovehigh) {
*distancetomovehigh = static_cast<int32_t>(upos >> 32);
}
return static_cast<uint32_t>(upos & 0xFFFFFFFFu);
}
int32_t STORMAPI SFileCloseFile(HSFILE handle) {
(void)handle;
return 0;
if (!handle) {
return 0;
}
auto file = reinterpret_cast<NativeFileHandle*>(handle);
file->stream.close();
delete file;
return 1;
}