2022-07-18 14:25:00 -04:00
|
|
|
#include "file.h"
|
|
|
|
|
2022-07-31 18:20:32 -04:00
|
|
|
#ifdef _WIN32
|
|
|
|
#define NOMINMAX
|
|
|
|
#include <Windows.h>
|
|
|
|
#else
|
|
|
|
#include <fstream>
|
|
|
|
#define FSTR(x) static_cast<std::fstream*>(x)
|
|
|
|
#endif
|
|
|
|
|
2022-07-18 14:25:00 -04:00
|
|
|
namespace si {
|
|
|
|
|
2022-07-31 18:20:32 -04:00
|
|
|
File::File()
|
|
|
|
{
|
|
|
|
m_Handle = NULL;
|
|
|
|
}
|
|
|
|
|
2022-07-18 14:25:00 -04:00
|
|
|
bool File::Open(const char *c, Mode mode)
|
|
|
|
{
|
2022-07-31 16:28:43 -04:00
|
|
|
#ifdef _WIN32
|
|
|
|
m_Handle = CreateFileA(c,
|
|
|
|
mode == Read ? GENERIC_READ : GENERIC_WRITE,
|
|
|
|
FILE_SHARE_READ,
|
|
|
|
NULL,
|
|
|
|
mode == Read ? OPEN_EXISTING : CREATE_NEW,
|
|
|
|
FILE_ATTRIBUTE_NORMAL,
|
|
|
|
NULL);
|
2022-07-31 17:28:50 -04:00
|
|
|
m_Mode = mode;
|
2022-07-31 16:28:43 -04:00
|
|
|
return m_Handle != INVALID_HANDLE_VALUE;
|
|
|
|
#else
|
2022-07-18 14:55:00 -04:00
|
|
|
std::ios::openmode m = std::ios::binary;
|
2022-07-18 14:25:00 -04:00
|
|
|
|
|
|
|
if (mode == Read) {
|
|
|
|
m |= std::ios::in;
|
|
|
|
} else {
|
|
|
|
m |= std::ios::out;
|
|
|
|
}
|
|
|
|
|
2022-07-31 18:20:32 -04:00
|
|
|
m_Handle = new std::fstream();
|
|
|
|
FSTR(m_Handle)->open(c, m);
|
|
|
|
if (FSTR(m_Handle)->good() && FSTR(m_Handle)->is_open()) {
|
2022-07-18 14:25:00 -04:00
|
|
|
m_Mode = mode;
|
|
|
|
return true;
|
|
|
|
}
|
|
|
|
|
|
|
|
return false;
|
2022-07-31 16:28:43 -04:00
|
|
|
#endif
|
2022-07-18 14:25:00 -04:00
|
|
|
}
|
|
|
|
|
|
|
|
#ifdef _WIN32
|
|
|
|
bool File::Open(const wchar_t *c, Mode mode)
|
|
|
|
{
|
2022-07-31 16:28:43 -04:00
|
|
|
m_Handle = CreateFileW(c,
|
|
|
|
mode == Read ? GENERIC_READ : GENERIC_WRITE,
|
|
|
|
FILE_SHARE_READ,
|
|
|
|
NULL,
|
|
|
|
mode == Read ? OPEN_EXISTING : CREATE_NEW,
|
|
|
|
FILE_ATTRIBUTE_NORMAL,
|
|
|
|
NULL);
|
|
|
|
return m_Handle != INVALID_HANDLE_VALUE;
|
2022-07-18 14:25:00 -04:00
|
|
|
}
|
|
|
|
#endif
|
|
|
|
|
2022-07-31 18:20:32 -04:00
|
|
|
File::pos_t File::pos()
|
2022-07-18 14:25:00 -04:00
|
|
|
{
|
2022-07-31 16:28:43 -04:00
|
|
|
#ifdef _WIN32
|
2022-07-31 17:05:57 -04:00
|
|
|
LONG high = 0;
|
2022-07-31 16:28:43 -04:00
|
|
|
DWORD low = SetFilePointer(m_Handle, 0, &high, FILE_CURRENT);
|
2022-07-31 18:20:32 -04:00
|
|
|
return pos_t(high) << 32 | low;
|
2022-07-31 16:28:43 -04:00
|
|
|
#else
|
2022-07-18 14:25:00 -04:00
|
|
|
if (m_Mode == Read) {
|
2022-07-31 18:20:32 -04:00
|
|
|
return FSTR(m_Handle)->tellg();
|
2022-07-18 14:25:00 -04:00
|
|
|
} else {
|
2022-07-31 18:20:32 -04:00
|
|
|
return FSTR(m_Handle)->tellp();
|
2022-07-18 14:25:00 -04:00
|
|
|
}
|
2022-07-31 16:28:43 -04:00
|
|
|
#endif
|
2022-07-18 14:25:00 -04:00
|
|
|
}
|
|
|
|
|
2022-07-31 18:20:32 -04:00
|
|
|
File::pos_t File::size()
|
2022-07-18 18:29:05 -04:00
|
|
|
{
|
2022-07-31 16:28:43 -04:00
|
|
|
#ifdef _WIN32
|
|
|
|
DWORD high;
|
|
|
|
DWORD low = GetFileSize(m_Handle, &high);
|
2022-07-31 18:20:32 -04:00
|
|
|
return pos_t(high) << 32 | low;
|
2022-07-31 16:28:43 -04:00
|
|
|
#else
|
2022-07-31 18:20:32 -04:00
|
|
|
pos_t before = pos();
|
2022-07-18 18:29:05 -04:00
|
|
|
seek(0, SeekEnd);
|
2022-07-31 18:20:32 -04:00
|
|
|
pos_t sz = pos();
|
2022-07-18 18:29:05 -04:00
|
|
|
seek(before, SeekStart);
|
|
|
|
return sz;
|
2022-07-31 16:28:43 -04:00
|
|
|
#endif
|
2022-07-18 18:29:05 -04:00
|
|
|
}
|
|
|
|
|
2022-07-31 18:20:32 -04:00
|
|
|
void File::seek(File::pos_t p, SeekMode s)
|
2022-07-18 14:25:00 -04:00
|
|
|
{
|
2022-07-31 16:28:43 -04:00
|
|
|
#ifdef _WIN32
|
2022-07-31 17:05:57 -04:00
|
|
|
LONG high = p >> 32;
|
2022-07-31 18:20:32 -04:00
|
|
|
DWORD low = (DWORD) p;
|
2022-07-31 16:28:43 -04:00
|
|
|
|
|
|
|
DWORD m;
|
|
|
|
switch (s) {
|
|
|
|
case SeekStart:
|
|
|
|
m = FILE_BEGIN;
|
|
|
|
break;
|
|
|
|
case SeekCurrent:
|
|
|
|
m = FILE_CURRENT;
|
|
|
|
break;
|
|
|
|
case SeekEnd:
|
|
|
|
m = FILE_END;
|
|
|
|
break;
|
|
|
|
}
|
|
|
|
|
|
|
|
SetFilePointer(m_Handle, low, &high, m);
|
|
|
|
#else
|
2023-09-26 23:27:03 -04:00
|
|
|
std::ios::seekdir d = std::ios::beg;
|
2022-07-18 14:25:00 -04:00
|
|
|
|
|
|
|
switch (s) {
|
|
|
|
case SeekStart:
|
|
|
|
d = std::ios::beg;
|
|
|
|
break;
|
|
|
|
case SeekCurrent:
|
|
|
|
d = std::ios::cur;
|
|
|
|
break;
|
|
|
|
case SeekEnd:
|
|
|
|
d = std::ios::end;
|
|
|
|
break;
|
|
|
|
}
|
|
|
|
|
|
|
|
if (m_Mode == Read) {
|
2022-07-31 18:20:32 -04:00
|
|
|
FSTR(m_Handle)->seekg(p, d);
|
2022-07-18 14:25:00 -04:00
|
|
|
} else {
|
2022-07-31 18:20:32 -04:00
|
|
|
FSTR(m_Handle)->seekp(p, d);
|
2022-07-18 14:25:00 -04:00
|
|
|
}
|
2022-07-31 16:28:43 -04:00
|
|
|
#endif
|
2022-07-18 14:25:00 -04:00
|
|
|
}
|
|
|
|
|
2022-07-18 18:29:05 -04:00
|
|
|
void File::Close()
|
2022-07-18 14:25:00 -04:00
|
|
|
{
|
2022-07-31 16:28:43 -04:00
|
|
|
#ifdef _WIN32
|
|
|
|
CloseHandle(m_Handle);
|
|
|
|
#else
|
2022-07-31 18:20:32 -04:00
|
|
|
FSTR(m_Handle)->close();
|
|
|
|
delete FSTR(m_Handle);
|
|
|
|
m_Handle = NULL;
|
2022-07-31 16:28:43 -04:00
|
|
|
#endif
|
2022-07-18 14:25:00 -04:00
|
|
|
}
|
|
|
|
|
2022-07-31 18:20:32 -04:00
|
|
|
File::pos_t File::ReadData(void *data, File::pos_t size)
|
2022-07-18 14:25:00 -04:00
|
|
|
{
|
2022-07-31 16:28:43 -04:00
|
|
|
#ifdef _WIN32
|
|
|
|
DWORD r;
|
2022-07-31 18:20:32 -04:00
|
|
|
ReadFile(m_Handle, data, (DWORD) size, &r, NULL);
|
2022-07-31 16:28:43 -04:00
|
|
|
return r;
|
|
|
|
#else
|
2022-07-31 18:20:32 -04:00
|
|
|
pos_t before = this->pos();
|
|
|
|
FSTR(m_Handle)->read((char *) data, size);
|
2022-07-18 18:29:05 -04:00
|
|
|
return this->pos() - before;
|
2022-07-31 16:28:43 -04:00
|
|
|
#endif
|
2022-07-18 14:25:00 -04:00
|
|
|
}
|
|
|
|
|
2022-07-31 18:20:32 -04:00
|
|
|
File::pos_t File::WriteData(const void *data, File::pos_t size)
|
2022-07-18 14:25:00 -04:00
|
|
|
{
|
2022-07-31 16:28:43 -04:00
|
|
|
#ifdef _WIN32
|
|
|
|
DWORD w;
|
2022-07-31 18:20:32 -04:00
|
|
|
WriteFile(m_Handle, data, (DWORD) size, &w, NULL);
|
2022-07-31 16:28:43 -04:00
|
|
|
return w;
|
|
|
|
#else
|
2022-07-31 18:20:32 -04:00
|
|
|
pos_t before = this->pos();
|
|
|
|
FSTR(m_Handle)->write((const char *) data, size);
|
2022-07-18 18:29:05 -04:00
|
|
|
return this->pos() - before;
|
2022-07-31 16:28:43 -04:00
|
|
|
#endif
|
2022-07-18 14:25:00 -04:00
|
|
|
}
|
|
|
|
|
|
|
|
uint8_t FileBase::ReadU8()
|
|
|
|
{
|
|
|
|
uint8_t u;
|
2022-07-21 20:05:50 -04:00
|
|
|
ReadData(&u, sizeof(u));
|
2022-07-18 14:25:00 -04:00
|
|
|
return u;
|
|
|
|
}
|
|
|
|
|
|
|
|
void FileBase::WriteU8(uint8_t u)
|
|
|
|
{
|
2022-07-21 20:05:50 -04:00
|
|
|
WriteData(&u, sizeof(u));
|
2022-07-18 14:25:00 -04:00
|
|
|
}
|
|
|
|
|
|
|
|
uint16_t FileBase::ReadU16()
|
|
|
|
{
|
|
|
|
uint16_t u;
|
2022-07-21 20:05:50 -04:00
|
|
|
ReadData(&u, sizeof(u));
|
2022-07-18 14:25:00 -04:00
|
|
|
return u;
|
|
|
|
}
|
|
|
|
|
|
|
|
void FileBase::WriteU16(uint16_t u)
|
|
|
|
{
|
2022-07-21 20:05:50 -04:00
|
|
|
WriteData(&u, sizeof(u));
|
2022-07-18 14:25:00 -04:00
|
|
|
}
|
|
|
|
|
|
|
|
uint32_t FileBase::ReadU32()
|
|
|
|
{
|
|
|
|
uint32_t u;
|
2022-07-21 20:05:50 -04:00
|
|
|
ReadData(&u, sizeof(u));
|
2022-07-18 14:25:00 -04:00
|
|
|
return u;
|
|
|
|
}
|
|
|
|
|
|
|
|
void FileBase::WriteU32(uint32_t u)
|
|
|
|
{
|
2022-07-21 20:05:50 -04:00
|
|
|
WriteData(&u, sizeof(u));
|
2022-07-18 14:25:00 -04:00
|
|
|
}
|
|
|
|
|
|
|
|
Vector3 FileBase::ReadVector3()
|
|
|
|
{
|
|
|
|
Vector3 u;
|
2022-07-21 20:05:50 -04:00
|
|
|
ReadData(&u, sizeof(u));
|
2022-07-18 14:25:00 -04:00
|
|
|
return u;
|
|
|
|
}
|
|
|
|
|
|
|
|
void FileBase::WriteVector3(const Vector3 &v)
|
|
|
|
{
|
2022-07-21 20:05:50 -04:00
|
|
|
WriteData(&v, sizeof(v));
|
2022-07-18 14:25:00 -04:00
|
|
|
}
|
|
|
|
|
|
|
|
std::string FileBase::ReadString()
|
|
|
|
{
|
|
|
|
std::string d;
|
|
|
|
|
|
|
|
while (true) {
|
|
|
|
char c;
|
|
|
|
ReadData(&c, 1);
|
|
|
|
if (c == 0) {
|
|
|
|
break;
|
|
|
|
}
|
|
|
|
d.push_back(c);
|
|
|
|
}
|
|
|
|
|
|
|
|
return d;
|
|
|
|
}
|
|
|
|
|
|
|
|
void FileBase::WriteString(const std::string &d)
|
|
|
|
{
|
|
|
|
WriteData(d.c_str(), d.size());
|
|
|
|
|
|
|
|
// Ensure null terminator
|
|
|
|
WriteU8(0);
|
|
|
|
}
|
|
|
|
|
2022-07-31 18:20:32 -04:00
|
|
|
bytearray FileBase::ReadBytes(File::pos_t size)
|
2022-07-18 14:25:00 -04:00
|
|
|
{
|
|
|
|
bytearray d;
|
|
|
|
|
|
|
|
d.resize(size);
|
|
|
|
ReadData(d.data(), size);
|
|
|
|
|
|
|
|
return d;
|
|
|
|
}
|
|
|
|
|
|
|
|
void FileBase::WriteBytes(const bytearray &ba)
|
|
|
|
{
|
|
|
|
WriteData(ba.data(), ba.size());
|
|
|
|
}
|
|
|
|
|
|
|
|
MemoryBuffer::MemoryBuffer()
|
|
|
|
{
|
|
|
|
m_Position = 0;
|
|
|
|
}
|
|
|
|
|
2022-07-18 18:29:05 -04:00
|
|
|
MemoryBuffer::MemoryBuffer(const bytearray &data)
|
|
|
|
{
|
|
|
|
m_Internal = data;
|
|
|
|
m_Position = 0;
|
|
|
|
}
|
|
|
|
|
2022-07-31 18:20:32 -04:00
|
|
|
File::pos_t MemoryBuffer::pos()
|
2022-07-18 14:25:00 -04:00
|
|
|
{
|
|
|
|
return m_Position;
|
|
|
|
}
|
|
|
|
|
2022-07-31 18:20:32 -04:00
|
|
|
File::pos_t MemoryBuffer::size()
|
2022-07-18 18:29:05 -04:00
|
|
|
{
|
|
|
|
return m_Internal.size();
|
|
|
|
}
|
|
|
|
|
2022-07-31 18:20:32 -04:00
|
|
|
void MemoryBuffer::seek(File::pos_t p, SeekMode s)
|
2022-07-18 14:25:00 -04:00
|
|
|
{
|
|
|
|
switch (s) {
|
|
|
|
case SeekStart:
|
2022-08-06 23:22:59 -04:00
|
|
|
m_Position = std::min(p, size());
|
2022-07-18 14:25:00 -04:00
|
|
|
break;
|
|
|
|
case SeekCurrent:
|
2022-08-06 23:22:59 -04:00
|
|
|
m_Position = std::min(m_Position + p, size());
|
2022-07-18 14:25:00 -04:00
|
|
|
break;
|
|
|
|
case SeekEnd:
|
2022-08-06 23:22:59 -04:00
|
|
|
if (p > size()) {
|
|
|
|
m_Position = 0;
|
|
|
|
} else {
|
|
|
|
m_Position = size() - p;
|
|
|
|
}
|
2022-07-18 14:25:00 -04:00
|
|
|
break;
|
|
|
|
}
|
|
|
|
}
|
|
|
|
|
2022-07-31 18:20:32 -04:00
|
|
|
File::pos_t MemoryBuffer::ReadData(void *data, File::pos_t size)
|
2022-07-18 14:25:00 -04:00
|
|
|
{
|
2022-08-06 23:22:59 -04:00
|
|
|
pos_t remaining = m_Internal.size() - m_Position;
|
|
|
|
size = std::min(size, remaining);
|
2022-07-18 14:25:00 -04:00
|
|
|
memcpy(data, m_Internal.data() + m_Position, size);
|
|
|
|
m_Position += size;
|
2022-07-18 18:29:05 -04:00
|
|
|
return size;
|
2022-07-18 14:25:00 -04:00
|
|
|
}
|
|
|
|
|
2022-07-31 18:20:32 -04:00
|
|
|
File::pos_t MemoryBuffer::WriteData(const void *data, File::pos_t size)
|
2022-07-18 14:25:00 -04:00
|
|
|
{
|
2022-07-31 18:20:32 -04:00
|
|
|
pos_t end = m_Position + size;
|
2022-07-18 14:25:00 -04:00
|
|
|
if (end > m_Internal.size()) {
|
|
|
|
m_Internal.resize(end);
|
|
|
|
}
|
|
|
|
memcpy(m_Internal.data() + m_Position, data, size);
|
|
|
|
m_Position += size;
|
2022-07-18 18:29:05 -04:00
|
|
|
return size;
|
2022-07-18 14:25:00 -04:00
|
|
|
}
|
|
|
|
|
|
|
|
}
|