mirror of
https://github.com/thunderbrewhq/thunderbrew
synced 2026-01-30 19:42:51 +03:00
feat(util): update SFile with logging (Windows only)
This commit is contained in:
parent
94bb7736aa
commit
d5a3874c2f
@ -41,6 +41,40 @@ char* OsPathFindExtensionWithDot(char* pathName) {
|
|||||||
return result;
|
return result;
|
||||||
}
|
}
|
||||||
|
|
||||||
|
void OsFileToNativeSlashes(char* path, size_t size) {
|
||||||
|
#ifdef WHOA_SYSTEM_WIN
|
||||||
|
OsFileToBackSlashes(path, size);
|
||||||
|
#else
|
||||||
|
OsFileToForwardSlashes(path, size);
|
||||||
|
#endif
|
||||||
|
}
|
||||||
|
|
||||||
|
void OsFileToForwardSlashes(char* path, size_t size) {
|
||||||
|
if (!path)
|
||||||
|
return;
|
||||||
|
|
||||||
|
for (size_t i = 0; i < size; ++i) {
|
||||||
|
if (!path[i])
|
||||||
|
return;
|
||||||
|
|
||||||
|
if (path[i] == '\\')
|
||||||
|
path[i] = '/';
|
||||||
|
}
|
||||||
|
}
|
||||||
|
|
||||||
|
void OsFileToBackSlashes(char* path, size_t size) {
|
||||||
|
if (!path)
|
||||||
|
return;
|
||||||
|
|
||||||
|
for (size_t i = 0; i < size; ++i) {
|
||||||
|
if (!path[i])
|
||||||
|
return;
|
||||||
|
|
||||||
|
if (path[i] == '/')
|
||||||
|
path[i] = '\\';
|
||||||
|
}
|
||||||
|
}
|
||||||
|
|
||||||
void OpenPatches(const std::string& language, const std::string& fileName) {
|
void OpenPatches(const std::string& language, const std::string& fileName) {
|
||||||
std::string path("Data/" + language + "/");
|
std::string path("Data/" + language + "/");
|
||||||
std::string fullPath;
|
std::string fullPath;
|
||||||
|
|||||||
@ -10,6 +10,10 @@ void OsBuildFontFilePath(const char*, char*, size_t);
|
|||||||
|
|
||||||
char* OsPathFindExtensionWithDot(char*);
|
char* OsPathFindExtensionWithDot(char*);
|
||||||
|
|
||||||
|
void OsFileToNativeSlashes(char* path, size_t size = (size_t) -1);
|
||||||
|
void OsFileToForwardSlashes(char* path, size_t size = (size_t) -1);
|
||||||
|
void OsFileToBackSlashes(char* path, size_t size = (size_t) -1);
|
||||||
|
|
||||||
void OpenArchives();
|
void OpenArchives();
|
||||||
|
|
||||||
extern void* g_mpqHandle;
|
extern void* g_mpqHandle;
|
||||||
|
|||||||
@ -8,19 +8,20 @@
|
|||||||
|
|
||||||
// TODO Proper implementation
|
// TODO Proper implementation
|
||||||
int32_t SFile::Close(SFile* file) {
|
int32_t SFile::Close(SFile* file) {
|
||||||
SFileCloseFile(file->m_file);
|
SFileCloseFile(file->m_handle);
|
||||||
delete file;
|
delete file;
|
||||||
return 1;
|
return 1;
|
||||||
}
|
}
|
||||||
|
|
||||||
// TODO Proper implementation
|
// TODO Proper implementation
|
||||||
size_t SFile::GetFileSize(SFile* file, size_t* filesizeHigh) {
|
uint32_t SFile::GetFileSize(SFile* file, uint32_t* filesizeHigh) {
|
||||||
DWORD highPart = 0;
|
DWORD high = 0;
|
||||||
DWORD lowPart = SFileGetFileSize(file->m_file, &highPart);
|
DWORD low = SFileGetFileSize(file->m_handle, &high);
|
||||||
|
|
||||||
if (filesizeHigh)
|
if (filesizeHigh)
|
||||||
*filesizeHigh = highPart;
|
*filesizeHigh = high;
|
||||||
return lowPart;
|
|
||||||
|
return low;
|
||||||
}
|
}
|
||||||
|
|
||||||
int32_t SFile::IsStreamingMode() {
|
int32_t SFile::IsStreamingMode() {
|
||||||
@ -30,73 +31,39 @@ int32_t SFile::IsStreamingMode() {
|
|||||||
|
|
||||||
// TODO Proper implementation
|
// TODO Proper implementation
|
||||||
int32_t SFile::Load(SArchive* archive, const char* filename, void** buffer, size_t* bytes, size_t extraBytes, uint32_t flags, SOVERLAPPED* overlapped) {
|
int32_t SFile::Load(SArchive* archive, const char* filename, void** buffer, size_t* bytes, size_t extraBytes, uint32_t flags, SOVERLAPPED* overlapped) {
|
||||||
auto pathLen = SStrLen(filename);
|
if (!buffer || !filename)
|
||||||
|
|
||||||
char archivePath[STORM_MAX_PATH] = { 0 };
|
|
||||||
char localPath[STORM_MAX_PATH] = { 0 };
|
|
||||||
char subPath[STORM_MAX_PATH] = { 0 };
|
|
||||||
|
|
||||||
bool containsPath = false;
|
|
||||||
|
|
||||||
for (int32_t i = 0; i < pathLen; ++i) {
|
|
||||||
if (filename[i] == '/') {
|
|
||||||
containsPath = true;
|
|
||||||
#ifdef WHOA_SYSTEM_WIN
|
|
||||||
localPath[i] = '\\';
|
|
||||||
#else
|
|
||||||
localPath[i] = '/';
|
|
||||||
#endif
|
|
||||||
archivePath[i] = '\\';
|
|
||||||
} else if (filename[i] == '\\') {
|
|
||||||
containsPath = true;
|
|
||||||
#ifdef WHOA_SYSTEM_WIN
|
|
||||||
localPath[i] = '\\';
|
|
||||||
#else
|
|
||||||
localPath[i] = '/';
|
|
||||||
#endif
|
|
||||||
archivePath[i] = '\\';
|
|
||||||
} else {
|
|
||||||
localPath[i] = filename[i];
|
|
||||||
archivePath[i] = filename[i];
|
|
||||||
}
|
|
||||||
}
|
|
||||||
|
|
||||||
if (!containsPath) {
|
|
||||||
#ifdef WHOA_SYSTEM_WIN
|
|
||||||
SStrCopy(subPath, "Data\\enGB\\", sizeof(subPath));
|
|
||||||
#else
|
|
||||||
SStrCopy(subPath, "Data/enGB/", sizeof(subPath));
|
|
||||||
#endif
|
|
||||||
strcat(subPath, filename);
|
|
||||||
}
|
|
||||||
|
|
||||||
|
|
||||||
HANDLE file;
|
|
||||||
if (!SFileOpenFileEx(nullptr, localPath, SFILE_OPEN_LOCAL_FILE, &file)) {
|
|
||||||
if (containsPath || !SFileOpenFileEx(nullptr, subPath, SFILE_OPEN_LOCAL_FILE, &file)) {
|
|
||||||
if (!SFileOpenFileEx(g_mpqHandle, archivePath, SFILE_OPEN_FROM_MPQ, &file))
|
|
||||||
return 0;
|
return 0;
|
||||||
}
|
|
||||||
}
|
|
||||||
|
|
||||||
DWORD highPart = 0;
|
|
||||||
size_t size = SFileGetFileSize(file, &highPart);
|
|
||||||
size |= (highPart << 32);
|
|
||||||
|
|
||||||
|
*buffer = nullptr;
|
||||||
if (bytes)
|
if (bytes)
|
||||||
*bytes = size;
|
*bytes = 0;
|
||||||
|
|
||||||
|
SFile* file = nullptr;
|
||||||
|
if (!SFile::OpenEx(nullptr, filename, 0, &file))
|
||||||
|
return 0;
|
||||||
|
|
||||||
|
uint32_t high = 0;
|
||||||
|
uint64_t size = SFile::GetFileSize(file, &high);
|
||||||
|
size |= ((uint64_t) high << 32);
|
||||||
|
|
||||||
char* data = (char*) SMemAlloc(size + extraBytes, __FILE__, __LINE__, 0);
|
char* data = (char*) SMemAlloc(size + extraBytes, __FILE__, __LINE__, 0);
|
||||||
|
|
||||||
SFileReadFile(file, data, size, &highPart, nullptr);
|
if (!SFile::Read(file, data, size, nullptr, nullptr, nullptr)) {
|
||||||
|
SMemFree(data, __FILE__, __LINE__, 0);
|
||||||
|
SFile::Close(file);
|
||||||
|
return 0;
|
||||||
|
}
|
||||||
|
|
||||||
if (extraBytes)
|
if (extraBytes)
|
||||||
memset(data + size, 0, extraBytes);
|
memset(data + size, 0, extraBytes);
|
||||||
|
|
||||||
|
if (bytes)
|
||||||
|
*bytes = size;
|
||||||
|
|
||||||
if (buffer)
|
if (buffer)
|
||||||
*buffer = data;
|
*buffer = data;
|
||||||
|
|
||||||
SFileCloseFile(file);
|
SFile::Close(file);
|
||||||
|
|
||||||
return 1;
|
return 1;
|
||||||
}
|
}
|
||||||
@ -107,46 +74,51 @@ int32_t SFile::Open(const char* filename, SFile** file) {
|
|||||||
|
|
||||||
// TODO Proper implementation
|
// TODO Proper implementation
|
||||||
int32_t SFile::OpenEx(SArchive* archive, const char* filename, uint32_t flags, SFile** file) {
|
int32_t SFile::OpenEx(SArchive* archive, const char* filename, uint32_t flags, SFile** file) {
|
||||||
auto pathLen = SStrLen(filename);
|
if (!file || !filename)
|
||||||
|
return 0;
|
||||||
|
|
||||||
char archivePath[STORM_MAX_PATH] = { 0 };
|
*file = nullptr;
|
||||||
char localPath[STORM_MAX_PATH] = { 0 };
|
|
||||||
|
|
||||||
for (int32_t i = 0; i < pathLen; ++i) {
|
size_t length = SStrLen(filename);
|
||||||
if (filename[i] == '/') {
|
// Overflow protection
|
||||||
#ifdef WHOA_SYSTEM_WIN
|
if (length + 1 > STORM_MAX_PATH)
|
||||||
localPath[i] = '\\';
|
return 0;
|
||||||
#else
|
|
||||||
localPath[i] = '/';
|
char nativePath[STORM_MAX_PATH] = { 0 };
|
||||||
#endif
|
char backslashPath[STORM_MAX_PATH] = { 0 };
|
||||||
archivePath[i] = '\\';
|
|
||||||
} else if (filename[i] == '\\') {
|
SStrCopy(nativePath, filename, STORM_MAX_PATH);
|
||||||
#ifdef WHOA_SYSTEM_WIN
|
SStrCopy(backslashPath, filename, STORM_MAX_PATH);
|
||||||
localPath[i] = '\\';
|
|
||||||
#else
|
OsFileToNativeSlashes(nativePath);
|
||||||
localPath[i] = '/';
|
OsFileToBackSlashes(backslashPath);
|
||||||
#endif
|
|
||||||
archivePath[i] = '\\';
|
char message[512] = { 0 };
|
||||||
} else {
|
|
||||||
localPath[i] = filename[i];
|
|
||||||
archivePath[i] = filename[i];
|
|
||||||
}
|
|
||||||
}
|
|
||||||
|
|
||||||
HANDLE handle;
|
HANDLE handle;
|
||||||
bool local = true;
|
bool local = true;
|
||||||
if (!SFileOpenFileEx(nullptr, localPath, SFILE_OPEN_LOCAL_FILE, &handle)) {
|
if (!SFileOpenFileEx(nullptr, nativePath, SFILE_OPEN_LOCAL_FILE, &handle)) {
|
||||||
local = false;
|
local = false;
|
||||||
if (!SFileOpenFileEx(g_mpqHandle, archivePath, SFILE_OPEN_FROM_MPQ, &handle)) {
|
if (!SFileOpenFileEx(g_mpqHandle, backslashPath, SFILE_OPEN_FROM_MPQ, &handle)) {
|
||||||
*file = nullptr;
|
SStrCopy(message, "[SFile] Unable to open: ", sizeof(message));
|
||||||
|
strcat(message, filename);
|
||||||
|
strcat(message, "\n");
|
||||||
|
OutputDebugStringA(message);
|
||||||
return 0;
|
return 0;
|
||||||
}
|
}
|
||||||
}
|
}
|
||||||
|
|
||||||
SFile* fileptr = new SFile;
|
if (local) {
|
||||||
fileptr->m_mpq = local ? nullptr : g_mpqHandle;
|
SStrCopy(message, "[SFile] Open (file system): ", sizeof(message));
|
||||||
fileptr->m_file = handle;
|
} else {
|
||||||
*file = fileptr;
|
SStrCopy(message, "[SFile] Open (archive): ", sizeof(message));
|
||||||
|
}
|
||||||
|
strcat(message, filename);
|
||||||
|
strcat(message, "\n");
|
||||||
|
OutputDebugStringA(message);
|
||||||
|
|
||||||
|
*file = new SFile;
|
||||||
|
(*file)->m_handle = handle;
|
||||||
|
|
||||||
return 1;
|
return 1;
|
||||||
}
|
}
|
||||||
@ -154,7 +126,7 @@ int32_t SFile::OpenEx(SArchive* archive, const char* filename, uint32_t flags, S
|
|||||||
// TODO Proper implementation
|
// TODO Proper implementation
|
||||||
int32_t SFile::Read(SFile* file, void* buffer, size_t bytestoread, size_t* bytesread, SOVERLAPPED* overlapped, TASYNCPARAMBLOCK* asyncparam) {
|
int32_t SFile::Read(SFile* file, void* buffer, size_t bytestoread, size_t* bytesread, SOVERLAPPED* overlapped, TASYNCPARAMBLOCK* asyncparam) {
|
||||||
DWORD read = 0;
|
DWORD read = 0;
|
||||||
if (SFileReadFile(file->m_file, buffer, bytestoread, &read, nullptr)) {
|
if (SFileReadFile(file->m_handle, buffer, bytestoread, &read, nullptr)) {
|
||||||
if (bytesread)
|
if (bytesread)
|
||||||
*bytesread = read;
|
*bytesread = read;
|
||||||
return 1;
|
return 1;
|
||||||
|
|||||||
@ -12,7 +12,7 @@ class SFile {
|
|||||||
public:
|
public:
|
||||||
// Static functions
|
// Static functions
|
||||||
static int32_t Close(SFile*);
|
static int32_t Close(SFile*);
|
||||||
static size_t GetFileSize(SFile*, size_t*);
|
static uint32_t GetFileSize(SFile*, uint32_t*);
|
||||||
static int32_t IsStreamingMode(void);
|
static int32_t IsStreamingMode(void);
|
||||||
static int32_t Load(SArchive*, const char*, void**, size_t*, size_t, uint32_t, SOVERLAPPED*);
|
static int32_t Load(SArchive*, const char*, void**, size_t*, size_t, uint32_t, SOVERLAPPED*);
|
||||||
static int32_t Open(const char*, SFile**);
|
static int32_t Open(const char*, SFile**);
|
||||||
@ -21,8 +21,7 @@ class SFile {
|
|||||||
static int32_t Unload(void*);
|
static int32_t Unload(void*);
|
||||||
|
|
||||||
// Member variables
|
// Member variables
|
||||||
void* m_mpq;
|
void* m_handle;
|
||||||
void* m_file;
|
|
||||||
};
|
};
|
||||||
|
|
||||||
#endif
|
#endif
|
||||||
|
|||||||
Loading…
Reference in New Issue
Block a user