2020-06-20 23:39:08 +02:00
|
|
|
#include "framework.h"
|
|
|
|
#include "ChunkReader.h"
|
|
|
|
|
2020-06-20 21:02:45 -03:00
|
|
|
int ChunkReader::readInt32() {
|
2020-06-20 23:39:08 +02:00
|
|
|
int value = 0;
|
|
|
|
m_stream->Read(reinterpret_cast<char*>(&value), 4);
|
|
|
|
return value;
|
|
|
|
}
|
|
|
|
|
2020-06-20 21:02:45 -03:00
|
|
|
short ChunkReader::readInt16() {
|
2020-06-20 23:39:08 +02:00
|
|
|
short value = 0;
|
|
|
|
m_stream->Read(reinterpret_cast<char*>(&value), 2);
|
|
|
|
return value;
|
|
|
|
}
|
|
|
|
|
2020-06-20 21:02:45 -03:00
|
|
|
ChunkReader::ChunkReader(int expectedMagicNumber, BaseStream* stream) {
|
2020-06-20 23:39:08 +02:00
|
|
|
m_isValid = false;
|
|
|
|
|
|
|
|
if (stream == NULL)
|
|
|
|
return;
|
|
|
|
|
|
|
|
m_stream = stream;
|
|
|
|
|
|
|
|
// Check the magic number
|
|
|
|
int magicNumber = readInt32();
|
|
|
|
if (magicNumber != expectedMagicNumber)
|
|
|
|
return;
|
|
|
|
|
|
|
|
// TODO: future use for compression
|
|
|
|
m_stream->Seek(4, SeekOrigin::CURRENT);
|
|
|
|
m_emptyChunk = new ChunkId(NULL, 0);
|
|
|
|
m_isValid = true;
|
|
|
|
}
|
|
|
|
|
2020-06-20 21:02:45 -03:00
|
|
|
ChunkReader::~ChunkReader() {
|
2020-06-20 23:39:08 +02:00
|
|
|
delete m_emptyChunk;
|
|
|
|
}
|
|
|
|
|
2020-06-20 21:02:45 -03:00
|
|
|
bool ChunkReader::IsValid() {
|
2020-06-20 23:39:08 +02:00
|
|
|
return m_isValid;
|
|
|
|
}
|
|
|
|
|
2020-06-20 21:02:45 -03:00
|
|
|
bool ChunkReader::ReadChunks(bool(*func)(ChunkId* parentChunkId, int maxSize, int arg), int arg) {
|
2020-06-20 23:39:08 +02:00
|
|
|
do {
|
2020-08-11 19:18:36 +02:00
|
|
|
std::unique_ptr<ChunkId> chunkId = ChunkId::FromStream(m_stream);
|
2020-06-20 23:39:08 +02:00
|
|
|
if (chunkId->EqualsTo(m_emptyChunk)) // End reached
|
|
|
|
break;
|
|
|
|
|
|
|
|
// Read up to a 64 bit number for the chunk size
|
|
|
|
__int64 chunkSize = LEB128::ReadLong(m_stream);
|
|
|
|
|
|
|
|
// Try loading chunk content
|
|
|
|
bool chunkRecognized = false;
|
|
|
|
int startPos = m_stream->GetCurrentPosition();
|
|
|
|
|
2020-08-11 19:18:36 +02:00
|
|
|
chunkRecognized = func(chunkId.get(), chunkSize, arg);
|
2020-06-20 23:39:08 +02:00
|
|
|
int readDataCount = m_stream->GetCurrentPosition() - startPos;
|
|
|
|
|
|
|
|
// Adjust _stream position if necessary
|
|
|
|
if (readDataCount != chunkSize)
|
|
|
|
m_stream->Seek(chunkSize - readDataCount, SeekOrigin::CURRENT);
|
|
|
|
} while (true);
|
|
|
|
|
|
|
|
return true;
|
|
|
|
}
|
|
|
|
|
2020-06-20 21:02:45 -03:00
|
|
|
bool ChunkReader::ReadChunks(std::function<bool(ChunkId*, long, int)> func, int arg) {
|
2020-06-20 23:39:08 +02:00
|
|
|
do {
|
2020-08-11 19:18:36 +02:00
|
|
|
std::unique_ptr<ChunkId> chunkId = ChunkId::FromStream(m_stream);
|
2020-06-20 23:39:08 +02:00
|
|
|
if (chunkId->EqualsTo(m_emptyChunk)) // End reached
|
|
|
|
break;
|
|
|
|
|
|
|
|
// Read up to a 64 bit number for the chunk size
|
|
|
|
__int64 chunkSize = LEB128::ReadLong(m_stream);
|
|
|
|
|
|
|
|
// Try loading chunk content
|
|
|
|
bool chunkRecognized = false;
|
|
|
|
int startPos = m_stream->GetCurrentPosition();
|
|
|
|
|
2020-08-11 19:18:36 +02:00
|
|
|
chunkRecognized = func(chunkId.get(), chunkSize, arg);
|
2020-06-20 23:39:08 +02:00
|
|
|
int readDataCount = m_stream->GetCurrentPosition() - startPos;
|
|
|
|
|
|
|
|
// Adjust _stream position if necessary
|
|
|
|
if (readDataCount != chunkSize)
|
|
|
|
m_stream->Seek(chunkSize - readDataCount, SeekOrigin::CURRENT);
|
|
|
|
} while (true);
|
|
|
|
|
|
|
|
return true;
|
|
|
|
}
|
|
|
|
|
2020-06-20 21:02:45 -03:00
|
|
|
char* ChunkReader::ReadChunkArrayOfBytes(__int64 length) {
|
2020-06-20 23:39:08 +02:00
|
|
|
char* value = (char*)malloc(length);
|
|
|
|
m_stream->Read(value, length);
|
|
|
|
return value;
|
|
|
|
}
|
|
|
|
|
2020-06-20 21:02:45 -03:00
|
|
|
bool ChunkReader::ReadChunkBool(__int64 length) {
|
2020-06-20 23:39:08 +02:00
|
|
|
return (LEB128::ReadByte(m_stream) != 0);
|
|
|
|
}
|
|
|
|
|
2020-06-20 21:02:45 -03:00
|
|
|
__int64 ChunkReader::ReadChunkLong(__int64 length) {
|
2020-06-20 23:39:08 +02:00
|
|
|
return LEB128::ReadLong(m_stream);
|
|
|
|
}
|
|
|
|
|
2020-06-20 21:02:45 -03:00
|
|
|
int ChunkReader::ReadChunkInt32(__int64 length) {
|
2020-06-20 23:39:08 +02:00
|
|
|
return LEB128::ReadInt32(m_stream);
|
|
|
|
}
|
|
|
|
|
2020-06-20 21:02:45 -03:00
|
|
|
unsigned int ChunkReader::ReadChunkUInt32(__int64 length) {
|
2020-06-20 23:39:08 +02:00
|
|
|
return LEB128::ReadUInt32(m_stream);
|
|
|
|
}
|
|
|
|
|
2020-06-20 21:02:45 -03:00
|
|
|
short ChunkReader::ReadChunkInt16(__int64 length) {
|
2020-06-20 23:39:08 +02:00
|
|
|
return LEB128::ReadInt16(m_stream);
|
|
|
|
}
|
|
|
|
|
2020-06-20 21:02:45 -03:00
|
|
|
unsigned short ChunkReader::ReadChunkUInt16(__int64 length) {
|
2020-06-20 23:39:08 +02:00
|
|
|
return LEB128::ReadUInt16(m_stream);
|
|
|
|
}
|
|
|
|
|
2020-06-20 21:02:45 -03:00
|
|
|
byte ChunkReader::ReadChunkByte(__int64 length) {
|
2020-06-20 23:39:08 +02:00
|
|
|
return LEB128::ReadByte(m_stream);
|
|
|
|
}
|
|
|
|
|
2020-06-20 21:02:45 -03:00
|
|
|
char* ChunkReader::ReadChunkString(long length) {
|
2020-06-20 23:39:08 +02:00
|
|
|
char* value = (char*)malloc(length);
|
|
|
|
memcpy(value, LevelDataPtr, length);
|
|
|
|
return value;
|
|
|
|
}
|
|
|
|
|
2020-06-20 21:02:45 -03:00
|
|
|
BaseStream* ChunkReader::GetRawStream() {
|
2020-06-20 23:39:08 +02:00
|
|
|
return m_stream;
|
|
|
|
}
|