From 0dcab94411f101b02fc84409975a979603b28dbf Mon Sep 17 00:00:00 2001 From: Ted John Date: Sun, 5 Feb 2017 12:26:52 +0000 Subject: [PATCH] Remove chunk code from SawyerEncoding --- src/openrct2/rct12/SawyerEncoding.cpp | 173 ++++---------------------- src/openrct2/rct12/SawyerEncoding.h | 12 -- 2 files changed, 27 insertions(+), 158 deletions(-) diff --git a/src/openrct2/rct12/SawyerEncoding.cpp b/src/openrct2/rct12/SawyerEncoding.cpp index edc55ce3ab..a25227247e 100644 --- a/src/openrct2/rct12/SawyerEncoding.cpp +++ b/src/openrct2/rct12/SawyerEncoding.cpp @@ -14,171 +14,52 @@ *****************************************************************************/ #pragma endregion -#include #include "../core/IStream.hpp" #include "../core/Math.hpp" #include "SawyerEncoding.h" -extern "C" -{ - #include "../util/sawyercoding.h" -} - namespace SawyerEncoding { - void SkipChunk(IStream * stream) - { - auto header = stream->ReadValue(); - stream->Seek(header.length, STREAM_SEEK_CURRENT); - } - - void * ReadChunk(IStream * stream, size_t * outSize) - { - uint64 originalPosition = stream->GetPosition(); - - auto header = stream->ReadValue(); - switch (header.encoding) { - case CHUNK_ENCODING_NONE: - case CHUNK_ENCODING_RLE: - case CHUNK_ENCODING_RLECOMPRESSED: - case CHUNK_ENCODING_ROTATE: - { - std::unique_ptr compressedData = std::unique_ptr(Memory::Allocate(header.length)); - if (stream->TryRead(compressedData.get(), header.length) != header.length) - { - throw IOException("Corrupt chunk size."); - } - - // Allow 16MiB for chunk data - size_t bufferSize = 16 * 1024 * 1024; - uint8 * buffer = Memory::Allocate(bufferSize); - if (buffer == nullptr) - { - throw Exception("Unable to allocate buffer."); - } - - size_t uncompressedLength = sawyercoding_read_chunk_buffer(buffer, compressedData.get(), header, bufferSize); - buffer = Memory::Reallocate(buffer, uncompressedLength); - if (buffer == nullptr) - { - throw Exception("Unable to reallocate buffer."); - } - - if (outSize != nullptr) *outSize = uncompressedLength; - return buffer; - } - default: - stream->SetPosition(originalPosition); - throw IOException("Invalid chunk encoding."); - } - } - - void ReadChunk(void * dst, size_t expectedSize, IStream * stream) - { - if (!TryReadChunk(dst, expectedSize, stream)) - { - throw IOException("Invalid or incorrect chunk size."); - } - } - - void ReadChunkTolerant(void * dst, size_t expectedSize, IStream * stream) - { - uint64 originalPosition = stream->GetPosition(); - - auto header = stream->ReadValue(); - switch (header.encoding) { - case CHUNK_ENCODING_NONE: - case CHUNK_ENCODING_RLE: - case CHUNK_ENCODING_RLECOMPRESSED: - case CHUNK_ENCODING_ROTATE: - { - std::unique_ptr compressedData = std::unique_ptr(Memory::Allocate(header.length)); - if (stream->TryRead(compressedData.get(), header.length) != header.length) - { - throw IOException("Corrupt chunk size."); - } - - // Allow 16MiB for chunk data - size_t bufferSize = 16 * 1024 * 1024; - std::unique_ptr buffer = std::unique_ptr(Memory::Allocate(bufferSize)); - size_t uncompressedLength = sawyercoding_read_chunk_buffer(buffer.get(), compressedData.get(), header, bufferSize); - size_t copyLength = Math::Min(uncompressedLength, expectedSize); - - Memory::Set(dst, 0, expectedSize); - Memory::Copy(dst, buffer.get(), copyLength); - break; - } - default: - stream->SetPosition(originalPosition); - throw IOException("Invalid chunk encoding."); - } - } - - bool TryReadChunk(void * dst, size_t expectedSize, IStream * stream) - { - uint64 originalPosition = stream->GetPosition(); - - bool success = false; - auto header = stream->ReadValue(); - switch (header.encoding) { - case CHUNK_ENCODING_NONE: - case CHUNK_ENCODING_RLE: - case CHUNK_ENCODING_RLECOMPRESSED: - case CHUNK_ENCODING_ROTATE: - uint8 * compressedData = Memory::Allocate(header.length); - if (stream->TryRead(compressedData, header.length) == header.length) - { - size_t uncompressedLength = sawyercoding_read_chunk_buffer((uint8 *)dst, compressedData, header, expectedSize); - if (uncompressedLength == expectedSize) - { - success = true; - } - } - Memory::Free(compressedData); - break; - } - - if (!success) - { - stream->SetPosition(originalPosition); - } - return success; - } - bool ValidateChecksum(IStream * stream) { - // Get data size uint64 initialPosition = stream->GetPosition(); uint64 dataSize = stream->GetLength() - initialPosition; if (dataSize < 8) { return false; } - dataSize -= 4; - // Calculate checksum - uint32 checksum = 0; - do + try { - uint8 buffer[4096]; - uint64 bufferSize = Math::Min(dataSize, sizeof(buffer)); - stream->Read(buffer, bufferSize); - - for (uint64 i = 0; i < bufferSize; i++) + // Calculate checksum + uint32 checksum = 0; + do { - checksum += buffer[i]; + uint8 buffer[4096]; + uint64 bufferSize = Math::Min(dataSize, sizeof(buffer)); + stream->Read(buffer, bufferSize); + + for (uint64 i = 0; i < bufferSize; i++) + { + checksum += buffer[i]; + } + + dataSize -= bufferSize; } + while (dataSize != 0); - dataSize -= bufferSize; + // Read file checksum + uint32 fileChecksum = stream->ReadValue(); + + // Rewind back to original position + stream->SetPosition(initialPosition); + return checksum == fileChecksum; + } + catch (Exception) + { + // Rewind back to original position + stream->SetPosition(initialPosition); + return false; } - while (dataSize != 0); - - // Read file checksum - uint32 fileChecksum = stream->ReadValue(); - - // Rewind - stream->SetPosition(initialPosition); - - return checksum == fileChecksum; } } diff --git a/src/openrct2/rct12/SawyerEncoding.h b/src/openrct2/rct12/SawyerEncoding.h index 10ba234a28..104106b514 100644 --- a/src/openrct2/rct12/SawyerEncoding.h +++ b/src/openrct2/rct12/SawyerEncoding.h @@ -22,17 +22,5 @@ interface IStream; namespace SawyerEncoding { - void SkipChunk(IStream * stream); - void * ReadChunk(IStream * stream, size_t * outSize); - void ReadChunk(void * dst, size_t expectedSize, IStream * stream); - void ReadChunkTolerant(void * dst, size_t expectedSize, IStream * stream); - bool TryReadChunk(void * dst, size_t expectedSize, IStream * stream); - - template - bool TryReadChunk(T * dst, IStream * stream) - { - return TryReadChunk(dst, sizeof(T), stream); - } - bool ValidateChecksum(IStream * stream); }