diff --git a/src/openrct2/util/sawyercoding.c b/src/openrct2/util/sawyercoding.c index 70cfb4fe34..0f72209a09 100644 --- a/src/openrct2/util/sawyercoding.c +++ b/src/openrct2/util/sawyercoding.c @@ -21,8 +21,6 @@ static size_t decode_chunk_rle(const uint8* src_buffer, uint8* dst_buffer, size_t length); static size_t decode_chunk_rle_with_size(const uint8* src_buffer, uint8* dst_buffer, size_t length, size_t dstSize); -static size_t decode_chunk_repeat(uint8 *buffer, size_t length, size_t dstLength); -static void decode_chunk_rotate(uint8 *buffer, size_t length); static size_t encode_chunk_rle(const uint8 *src_buffer, uint8 *dst_buffer, size_t length); static size_t encode_chunk_repeat(const uint8 *src_buffer, uint8 *dst_buffer, size_t length); @@ -40,27 +38,6 @@ uint32 sawyercoding_calculate_checksum(const uint8* buffer, size_t length) return checksum; } -size_t sawyercoding_read_chunk_buffer(uint8 *dst_buffer, const uint8 *src_buffer, sawyercoding_chunk_header chunkHeader, size_t dst_buffer_size) { - switch (chunkHeader.encoding) { - case CHUNK_ENCODING_NONE: - assert(chunkHeader.length <= dst_buffer_size); - memcpy(dst_buffer, src_buffer, chunkHeader.length); - break; - case CHUNK_ENCODING_RLE: - chunkHeader.length = (uint32)decode_chunk_rle_with_size(src_buffer, dst_buffer, chunkHeader.length, dst_buffer_size); - break; - case CHUNK_ENCODING_RLECOMPRESSED: - chunkHeader.length = (uint32)decode_chunk_rle_with_size(src_buffer, dst_buffer, chunkHeader.length, dst_buffer_size); - chunkHeader.length = (uint32)decode_chunk_repeat(dst_buffer, chunkHeader.length, dst_buffer_size); - break; - case CHUNK_ENCODING_ROTATE: - memcpy(dst_buffer, src_buffer, chunkHeader.length); - decode_chunk_rotate(dst_buffer, chunkHeader.length); - break; - } - return chunkHeader.length; -} - /** * * rct2: 0x006762E1 @@ -267,54 +244,6 @@ static size_t decode_chunk_rle_with_size(const uint8* src_buffer, uint8* dst_buf return dst - dst_buffer; } -/** - * - * rct2: 0x006769F1 - */ -static size_t decode_chunk_repeat(uint8 *buffer, size_t length, size_t dstLength) -{ - size_t i, count; - uint8 *src, *dst, *copyOffset; - - // Backup buffer - src = malloc(length); - memcpy(src, buffer, length); - dst = buffer; - - for (i = 0; i < length; i++) { - if (src[i] == 0xFF) { - *dst++ = src[++i]; - } else { - count = (src[i] & 7) + 1; - copyOffset = dst + (sint32)(src[i] >> 3) - 32; - assert(dst + count < buffer + dstLength); - assert(copyOffset + count < buffer + dstLength); - memcpy(dst, copyOffset, count); - dst = (uint8*)((uintptr_t)dst + count); - } - } - - // Free backup buffer - free(src); - - // Return final size - return dst - buffer; -} - -/** - * - * rct2: 0x006768F4 - */ -static void decode_chunk_rotate(uint8 *buffer, size_t length) -{ - size_t i; - uint8 code = 1; - for (i = 0; i < length; i++) { - buffer[i] = ror8(buffer[i], code); - code = (code + 2) % 8; - } -} - #pragma endregion #pragma region Encoding diff --git a/src/openrct2/util/sawyercoding.h b/src/openrct2/util/sawyercoding.h index def71f70d3..7a64baa9d4 100644 --- a/src/openrct2/util/sawyercoding.h +++ b/src/openrct2/util/sawyercoding.h @@ -54,7 +54,6 @@ extern "C" { extern bool gUseRLE; uint32 sawyercoding_calculate_checksum(const uint8* buffer, size_t length); -size_t sawyercoding_read_chunk_buffer(uint8 *dst_buffer, const uint8 *src_buffer, sawyercoding_chunk_header chunkHeader, size_t dst_buffer_size); size_t sawyercoding_write_chunk_buffer(uint8 *dst_file, const uint8 *src_buffer, sawyercoding_chunk_header chunkHeader); size_t sawyercoding_decode_sv4(const uint8 *src, uint8 *dst, size_t length, size_t bufferLength); size_t sawyercoding_decode_sc4(const uint8 *src, uint8 *dst, size_t length, size_t bufferLength); diff --git a/test/tests/CMakeLists.txt b/test/tests/CMakeLists.txt index 268c3827b2..2a52ef91e5 100644 --- a/test/tests/CMakeLists.txt +++ b/test/tests/CMakeLists.txt @@ -102,12 +102,14 @@ endif () set(SAWYERCODING_TEST_SOURCES "${CMAKE_CURRENT_LIST_DIR}/sawyercoding_test.cpp" - "${ROOT_DIR}/src/openrct2/diagnostic.c" + "${ROOT_DIR}/src/openrct2/core/IStream.cpp" + "${ROOT_DIR}/src/openrct2/core/MemoryStream.cpp" + "${ROOT_DIR}/src/openrct2/rct12/SawyerChunk.cpp" + "${ROOT_DIR}/src/openrct2/rct12/SawyerChunkReader.cpp" "${ROOT_DIR}/src/openrct2/util/sawyercoding.c" - "${ROOT_DIR}/src/openrct2/localisation/utf8.c" ) add_executable(test_sawyercoding ${SAWYERCODING_TEST_SOURCES}) -target_link_libraries(test_sawyercoding ${GTEST_LIBRARIES}) +target_link_libraries(test_sawyercoding ${GTEST_LIBRARIES} test-common ${LDL} z) add_test(NAME sawyercoding COMMAND test_sawyercoding) # LanguagePack test @@ -120,7 +122,7 @@ if (UNIX AND NOT ${CMAKE_SYSTEM_NAME} MATCHES "BSD") # Include libdl for dlopen set(LDL dl) endif () -target_link_libraries(test_languagepack ${GTEST_LIBRARIES} test-common ${LDL} z SDL2) +target_link_libraries(test_languagepack ${GTEST_LIBRARIES} test-common ${LDL} z) add_test(NAME languagepack COMMAND test_languagepack) # INI test diff --git a/test/tests/sawyercoding_test.cpp b/test/tests/sawyercoding_test.cpp index d728e781c3..3530035c77 100644 --- a/test/tests/sawyercoding_test.cpp +++ b/test/tests/sawyercoding_test.cpp @@ -1,11 +1,9 @@ -// Make MSVC shut up about M_PI -#include - -#include "openrct2/util/sawyercoding.h" - #include +#include +#include +#include -#define BUFFER_SIZE 0x600000 +constexpr size_t BUFFER_SIZE = 0x600000; class SawyerCodingTest : public testing::Test { @@ -18,36 +16,39 @@ protected: void test_encode_decode(uint8 encoding_type) { - sawyercoding_chunk_header chdr_in, chdr_out; + // Encode + sawyercoding_chunk_header chdr_in; chdr_in.encoding = encoding_type; chdr_in.length = sizeof(randomdata); uint8 * encodedDataBuffer = new uint8[BUFFER_SIZE]; size_t encodedDataSize = sawyercoding_write_chunk_buffer(encodedDataBuffer, (const uint8 *)randomdata, chdr_in); ASSERT_GT(encodedDataSize, sizeof(sawyercoding_chunk_header)); - memcpy(&chdr_out, encodedDataBuffer, sizeof(sawyercoding_chunk_header)); - ASSERT_EQ(chdr_out.encoding, encoding_type); - uint8 * decodeBuffer = new uint8[BUFFER_SIZE]; - size_t decodedDataSize = sawyercoding_read_chunk_buffer( - decodeBuffer, encodedDataBuffer + sizeof(sawyercoding_chunk_header), chdr_out, BUFFER_SIZE); - ASSERT_EQ(decodedDataSize, sizeof(randomdata)); - int result = memcmp(decodeBuffer, randomdata, sizeof(randomdata)); + + // Decode + MemoryStream ms(encodedDataBuffer, encodedDataSize); + SawyerChunkReader reader(&ms); + auto chunk = reader.ReadChunk(); + ASSERT_EQ((uint8)chunk->GetEncoding(), chdr_in.encoding); + ASSERT_EQ(chunk->GetLength(), chdr_in.length); + auto result = memcmp(chunk->GetData(), randomdata, sizeof(randomdata)); ASSERT_EQ(result, 0); - delete[] decodeBuffer; + delete[] encodedDataBuffer; } void test_decode(const uint8 * data, size_t size) { - sawyercoding_chunk_header chdr_in; - memcpy(&chdr_in, data, sizeof(sawyercoding_chunk_header)); - ASSERT_EQ(chdr_in.length, size - sizeof(sawyercoding_chunk_header)); - uint8 * decodeBuffer = new uint8[BUFFER_SIZE]; - size_t decodedDataSize = - sawyercoding_read_chunk_buffer(decodeBuffer, data + sizeof(sawyercoding_chunk_header), chdr_in, BUFFER_SIZE); - ASSERT_EQ(decodedDataSize, sizeof(randomdata)); - int result = memcmp(decodeBuffer, randomdata, sizeof(randomdata)); + auto expectedLength = size - sizeof(sawyercoding_chunk_header); + auto chdr_in = reinterpret_cast(data); + ASSERT_EQ(chdr_in->length, expectedLength); + + MemoryStream ms(data, size); + SawyerChunkReader reader(&ms); + auto chunk = reader.ReadChunk(); + ASSERT_EQ((uint8)chunk->GetEncoding(), chdr_in->encoding); + ASSERT_EQ(chunk->GetLength(), sizeof(randomdata)); + auto result = memcmp(chunk->GetData(), randomdata, sizeof(randomdata)); ASSERT_EQ(result, 0); - delete[] decodeBuffer; } };