SIEdit/lib/file.cpp
itsmattkc 85e786924d lib: use void * in utility read/write functions
Easier to write since you don't have to cast to char * all the time
2022-07-21 17:05:50 -07:00

259 lines
3.8 KiB
C++

#include "file.h"
#include "util.h"
namespace si {
bool File::Open(const char *c, Mode mode)
{
std::ios::openmode m = std::ios::binary;
if (mode == Read) {
m |= std::ios::in;
} else {
m |= std::ios::out;
}
m_Stream.open(c, m);
if (m_Stream.good() && m_Stream.is_open()) {
m_Mode = mode;
return true;
}
return false;
}
#ifdef _WIN32
bool File::Open(const wchar_t *c, Mode mode)
{
std::ios::open_mode m = std::ios::binary;
if (mode == Read) {
m |= std::ios::in;
} else {
m |= std::ios::out;
}
m_Stream.open(c, m);
if (m_Stream.good() && m_Stream.is_open()) {
m_Mode = mode;
return true;
}
return false;
}
#endif
size_t File::pos()
{
if (m_Mode == Read) {
return m_Stream.tellg();
} else {
return m_Stream.tellp();
}
}
size_t File::size()
{
size_t before = pos();
seek(0, SeekEnd);
size_t sz = pos();
seek(before, SeekStart);
return sz;
}
void File::seek(size_t p, SeekMode s)
{
std::ios::seekdir d;
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) {
m_Stream.seekg(p, d);
} else {
m_Stream.seekp(p, d);
}
}
bool File::atEnd()
{
return !m_Stream.good();
}
void File::Close()
{
m_Stream.close();
}
size_t File::ReadData(void *data, size_t size)
{
size_t before = this->pos();
m_Stream.read((char *) data, size);
return this->pos() - before;
}
size_t File::WriteData(const void *data, size_t size)
{
size_t before = this->pos();
m_Stream.write((const char *) data, size);
return this->pos() - before;
}
uint8_t FileBase::ReadU8()
{
uint8_t u;
ReadData(&u, sizeof(u));
return u;
}
void FileBase::WriteU8(uint8_t u)
{
WriteData(&u, sizeof(u));
}
uint16_t FileBase::ReadU16()
{
uint16_t u;
ReadData(&u, sizeof(u));
return u;
}
void FileBase::WriteU16(uint16_t u)
{
WriteData(&u, sizeof(u));
}
uint32_t FileBase::ReadU32()
{
uint32_t u;
ReadData(&u, sizeof(u));
return u;
}
void FileBase::WriteU32(uint32_t u)
{
WriteData(&u, sizeof(u));
}
Vector3 FileBase::ReadVector3()
{
Vector3 u;
ReadData(&u, sizeof(u));
return u;
}
void FileBase::WriteVector3(const Vector3 &v)
{
WriteData(&v, sizeof(v));
}
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);
}
bytearray FileBase::ReadBytes(size_t size)
{
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;
}
MemoryBuffer::MemoryBuffer(const bytearray &data)
{
m_Internal = data;
m_Position = 0;
}
size_t MemoryBuffer::pos()
{
return m_Position;
}
size_t MemoryBuffer::size()
{
return m_Internal.size();
}
void MemoryBuffer::seek(size_t p, SeekMode s)
{
switch (s) {
case SeekStart:
m_Position = p;
break;
case SeekCurrent:
m_Position += p;
break;
case SeekEnd:
m_Position = std::max(size_t(0), m_Internal.size() - p);
break;
}
}
bool MemoryBuffer::atEnd()
{
return m_Position == m_Internal.size();
}
size_t MemoryBuffer::ReadData(void *data, size_t size)
{
size = std::min(size, m_Internal.size() - m_Position);
memcpy(data, m_Internal.data() + m_Position, size);
m_Position += size;
return size;
}
size_t MemoryBuffer::WriteData(const void *data, size_t size)
{
size_t end = m_Position + size;
if (end > m_Internal.size()) {
m_Internal.resize(end);
}
memcpy(m_Internal.data() + m_Position, data, size);
m_Position += size;
return size;
}
}