mirror of
https://github.com/thunderbrewhq/squall.git
synced 2026-04-30 13:13:50 +00:00
feat(file): implement native sfile backend
This commit is contained in:
parent
ac556fbda9
commit
65a6fc72b4
1 changed files with 117 additions and 23 deletions
|
|
@ -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;
|
||||
}
|
||||
|
|
|
|||
Loading…
Add table
Add a link
Reference in a new issue