diff options
author | Ash Wolf <ninji@wuffs.org> | 2023-06-14 00:50:34 +0100 |
---|---|---|
committer | Ash Wolf <ninji@wuffs.org> | 2023-06-14 00:50:34 +0100 |
commit | 37e364b2c6cc7487a1c888d256a73e5337bb7189 (patch) | |
tree | eaf6e857382eef16c2dd940eb4125536fbe068bd /src/T2DLL/T2Archive.cpp | |
download | t2win-37e364b2c6cc7487a1c888d256a73e5337bb7189.tar.gz t2win-37e364b2c6cc7487a1c888d256a73e5337bb7189.zip |
initial commit
Diffstat (limited to '')
-rw-r--r-- | src/T2DLL/T2Archive.cpp | 394 |
1 files changed, 394 insertions, 0 deletions
diff --git a/src/T2DLL/T2Archive.cpp b/src/T2DLL/T2Archive.cpp new file mode 100644 index 0000000..8aac959 --- /dev/null +++ b/src/T2DLL/T2Archive.cpp @@ -0,0 +1,394 @@ +#include "T2Archive.h" + +T2Archive::T2Archive() { + mFile = NULL; + m8 = 0; + mIsReadable = false; + mIsWritable = false; + mBuffer = NULL; + mBufferLen = 0; + + mBuffer = (char *) malloc(0x10000); + mPtr = mBuffer; +} + +/*virtual*/ T2Archive::~T2Archive() { + if (mFile) + Close(); + if (mBuffer) + free(mBuffer); +} + +/*virtual*/ BOOL T2Archive::OpenAsReadMode(const char* path) { + if (mFile) + Close(); + + mFile = new CFile; + CFileException exc; + + BOOL success = mFile->Open(path, CFile::shareDenyWrite, &exc); + if (!success) { + delete mFile; + mFile = NULL; + } else { + mIsReadable = true; + mIsWritable = false; + mPtr = mBuffer; + } + + return success; +} + +/*virtual*/ BOOL T2Archive::OpenAsWriteMode(const char* path) { + if (mFile) + Close(); + + mFile = new CFile; + + BOOL success = mFile->Open(path, CFile::modeCreate | CFile::modeWrite | CFile::shareDenyRead); + if (!success) { + delete mFile; + mFile = NULL; + } else { + mIsReadable = false; + mIsWritable = true; + } + + return success; +} + +/*virtual*/ BOOL T2Archive::Close() { +#line 93 + _ASSERT(mFile); + + if (mBuffer && mBufferLen > 0 && mIsWritable) { + mFile->Write(mBuffer, mBufferLen); + mBufferLen = 0; + } + + mFile->Close(); + delete mFile; + + mFile = NULL; + mIsReadable = false; + mIsWritable = false; + + return true; +} + +/*virtual*/ int T2Archive::Read(void* buffer, int size) { +#line 111 + _ASSERT(mIsReadable); + _ASSERT(size <= 0x10000); + + int readAmount; + if (mBuffer) { + if (mBufferLen < size) { + memmove(mBuffer, mPtr, mBufferLen); + mPtr = mBuffer; + mBufferLen += mFile->Read(mBuffer + mBufferLen, 0x10000 - mBufferLen); +#line 122 + _ASSERT(mBufferLen >= size); + } + + memcpy(buffer, mPtr, size); + mPtr += size; + mBufferLen -= size; + readAmount = size; + } else { + readAmount = mFile->Read(buffer, size); +#line 132 + _ASSERT(readAmount == size); + } + + return readAmount; +} + +/*virtual*/ int T2Archive::Write(const void* buffer, int size) { +#line 139 + _ASSERT(mIsWritable); + _ASSERT(size <= 0x10000); + + if (mBuffer) { + if (mBufferLen + size > 0x10000) { + mFile->Write(mBuffer, mBufferLen); + mBufferLen = 0; + } + memcpy(mBuffer + mBufferLen, buffer, size); + mBufferLen += size; + } else { + mFile->Write(buffer, size); + } + + return size; +} + +/*virtual*/ void T2Archive::BeginCompressedStream() { +} + +/*virtual*/ void T2Archive::EndCompressedStream() { +} + +BOOL T2Archive::operator>>(unsigned char& v) { + if (Read(&v, 1) != 1) + return false; + return true; +} + +BOOL T2Archive::operator<<(unsigned char v) { + if (Write(&v, 1) != 1) + return false; + return true; +} + +BOOL T2Archive::operator>>(char& v) { + if (Read(&v, 1) != 1) + return false; + return true; +} + +BOOL T2Archive::operator<<(char v) { + if (Write(&v, 1) != 1) + return false; + return true; +} + +BOOL T2Archive::operator>>(int& v) { + if (Read(&v, 4) != 4) + return false; + return true; +} + +BOOL T2Archive::operator<<(int v) { + if (Write(&v, 4) != 4) + return false; + return true; +} + +BOOL T2Archive::operator>>(short& v) { + if (Read(&v, 2) != 2) + return false; + return true; +} + +BOOL T2Archive::operator<<(short v) { + if (Write(&v, 2) != 2) + return false; + return true; +} + +BOOL T2Archive::operator>>(unsigned int& v) { + if (Read(&v, 4) != 4) + return false; + return true; +} + +BOOL T2Archive::operator<<(unsigned int v) { + if (Write(&v, 4) != 4) + return false; + return true; +} + +BOOL T2Archive::operator>>(unsigned long& v) { + if (Read(&v, 4) != 4) + return false; + return true; +} + +BOOL T2Archive::operator<<(unsigned long v) { + if (Write(&v, 4) != 4) + return false; + return true; +} + +BOOL T2Archive::operator>>(unsigned short& v) { + if (Read(&v, 2) != 2) + return false; + return true; +} + +BOOL T2Archive::operator<<(unsigned short v) { + if (Write(&v, 2) != 2) + return false; + return true; +} + +BOOL T2Archive::operator>>(POINT& v) { + if (Read(&v, sizeof(v)) != sizeof(v)) + return false; + return true; +} + +BOOL T2Archive::operator<<(POINT v) { + if (Write(&v, sizeof(v)) != sizeof(v)) + return false; + return true; +} + +BOOL T2Archive::operator>>(RECT& v) { + if (Read(&v, sizeof(v)) != sizeof(v)) + return false; + return true; +} + +BOOL T2Archive::operator<<(RECT v) { + if (Write(&v, sizeof(v)) != sizeof(v)) + return false; + return true; +} + +BOOL T2Archive::operator>>(CString& v) { + int maxSize = 16; + char buf[17]; + + v = ""; + + int sz = Read(buf, maxSize); + while (strlen(buf) == sz) { + buf[sz] = 0; + v += buf; + if (sz < maxSize) + return false; + sz = Read(buf, maxSize); + } + + int len = strlen(buf); + mFile->Seek(len - sz + 1, CFile::current); + v += buf; + + return true; +} + +BOOL T2Archive::operator<<(CString& v) { + int len = v.GetLength() + 1; + if (Write(v, len) != len) + return false; + return true; +} + +BOOL T2Archive::operator>>(char* v) { + int maxSize = 16; + char buf[17]; + + v = ""; // BUG!! + + int sz = Read(buf, maxSize); + while (strlen(buf) == sz) { + buf[sz] = 0; + strcat(v, buf); + if (sz < maxSize) + return false; + sz = Read(buf, maxSize); + } + + int len = strlen(buf); + mFile->Seek(len - sz + 1, CFile::current); + strcat(v, buf); + + return true; +} + +BOOL T2Archive::operator<<(const char* v) { + int len = strlen(v) + 1; + if (Write(v, len) != len) + return false; + return true; +} + +BOOL T2Archive::ReadPStr(char* v) { + unsigned char len; + Read(&len, 1); + memset(v, 0, len + 1); + Read(v, len); + return true; +} + +BOOL T2Archive::ReadPStr(CString& v) { + unsigned char len; + Read(&len, 1); + + char *buf = (char *) malloc(len + 1); + memset(buf, 0, len + 1); + Read(buf, len); + v = buf; + free(buf); + + return true; +} + +BOOL T2Archive::WritePStr(const char* v) { + int len = strlen(v) + 1; + if (len > 255) + return false; + + unsigned char len8 = len; + Write(&len8, 1); + Write(v, strlen(v) + 1); + + return true; +} + +/*virtual*/ BOOL T2Archive::Skip(unsigned long v) { + int size; + BOOL result = true; + + if (v > 1000) + size = 1000; + else + size = v; + + void *buf = malloc(size); + + while (v > 0) { + int howMuch = Read(buf, size); + v -= howMuch; + if (howMuch < size && v > 0) { + result = false; + break; + } + } + + free(buf); + + return result; +} + +static short swap16(short v); + +BOOL T2Archive::ReadSRect(RECT& v) { + struct { + short top, left, bottom, right; + } r; + Read(&r, sizeof(r)); + v.top = swap16(r.top); + v.left = swap16(r.left); + v.bottom = swap16(r.bottom); + v.right = swap16(r.right); + return true; +} + +static short swap16(short v) { + union { + unsigned char b[2]; + short s; + } work; + unsigned char tmp; + + work.s = v; + tmp = work.b[0]; + work.b[0] = work.b[1]; + work.b[1] = tmp; + return work.s; +} + +BOOL T2Archive::WriteSRect(const RECT& v) { + struct { + short top, left, bottom, right; + } r; + r.top = swap16(v.top); + r.left = swap16(v.left); + r.bottom = swap16(v.bottom); + r.right = swap16(v.right); + Write(&r, sizeof(r)); + return true; +} |