From e5413c066489a5ed388a78c789de9c347a4616bc Mon Sep 17 00:00:00 2001 From: elsid Date: Mon, 18 Oct 2021 01:43:33 +0200 Subject: [PATCH] Add functions to compress/decompress vector of bytes --- apps/openmw_test_suite/CMakeLists.txt | 1 + apps/openmw_test_suite/misc/compression.cpp | 31 +++++++++++++ components/CMakeLists.txt | 1 + components/misc/compression.cpp | 48 +++++++++++++++++++++ components/misc/compression.hpp | 14 ++++++ 5 files changed, 95 insertions(+) create mode 100644 apps/openmw_test_suite/misc/compression.cpp create mode 100644 components/misc/compression.cpp create mode 100644 components/misc/compression.hpp diff --git a/apps/openmw_test_suite/CMakeLists.txt b/apps/openmw_test_suite/CMakeLists.txt index e8a296b563..3d19834066 100644 --- a/apps/openmw_test_suite/CMakeLists.txt +++ b/apps/openmw_test_suite/CMakeLists.txt @@ -25,6 +25,7 @@ if (GTEST_FOUND AND GMOCK_FOUND) misc/test_stringops.cpp misc/test_endianness.cpp misc/progressreporter.cpp + misc/compression.cpp nifloader/testbulletnifloader.cpp diff --git a/apps/openmw_test_suite/misc/compression.cpp b/apps/openmw_test_suite/misc/compression.cpp new file mode 100644 index 0000000000..e062599f4a --- /dev/null +++ b/apps/openmw_test_suite/misc/compression.cpp @@ -0,0 +1,31 @@ +#include + +#include + +#include +#include +#include + +namespace +{ + using namespace testing; + using namespace Misc; + + TEST(MiscCompressionTest, compressShouldAddPrefixWithDataSize) + { + const std::vector data(1234); + const std::vector compressed = compress(data); + int size = 0; + std::memcpy(&size, compressed.data(), sizeof(size)); + EXPECT_EQ(size, data.size()); + } + + TEST(MiscCompressionTest, decompressIsInverseToCompress) + { + const std::vector data(1024); + const std::vector compressed = compress(data); + EXPECT_LT(compressed.size(), data.size()); + const std::vector decompressed = decompress(compressed); + EXPECT_EQ(decompressed, data); + } +} diff --git a/components/CMakeLists.txt b/components/CMakeLists.txt index e71aa88f3c..7b06b6702d 100644 --- a/components/CMakeLists.txt +++ b/components/CMakeLists.txt @@ -93,6 +93,7 @@ add_component_dir (esmterrain add_component_dir (misc constants utf8stream stringops resourcehelpers rng messageformatparser weakcache thread + compression ) add_component_dir (debug diff --git a/components/misc/compression.cpp b/components/misc/compression.cpp new file mode 100644 index 0000000000..7f76d0900c --- /dev/null +++ b/components/misc/compression.cpp @@ -0,0 +1,48 @@ +#include "compression.hpp" + +#include + +#include +#include +#include +#include +#include + +namespace Misc +{ + std::vector compress(const std::vector& data) + { + const std::size_t originalSize = data.size(); + std::vector result(static_cast(LZ4_compressBound(static_cast(originalSize)) + sizeof(originalSize))); + const int size = LZ4_compress_default( + reinterpret_cast(data.data()), + reinterpret_cast(result.data()) + sizeof(originalSize), + static_cast(data.size()), + static_cast(result.size() - sizeof(originalSize)) + ); + if (size == 0) + throw std::runtime_error("Failed to compress"); + std::memcpy(result.data(), &originalSize, sizeof(originalSize)); + result.resize(static_cast(size) + sizeof(originalSize)); + return result; + } + + std::vector decompress(const std::vector& data) + { + std::size_t originalSize; + std::memcpy(&originalSize, data.data(), sizeof(originalSize)); + std::vector result(originalSize); + const int size = LZ4_decompress_safe( + reinterpret_cast(data.data()) + sizeof(originalSize), + reinterpret_cast(result.data()), + static_cast(data.size() - sizeof(originalSize)), + static_cast(result.size()) + ); + if (size < 0) + throw std::runtime_error("Failed to decompress"); + if (originalSize != static_cast(size)) + throw std::runtime_error("Size of decompressed data (" + std::to_string(size) + + ") doesn't match stored (" + std::to_string(originalSize) + ")"); + return result; + } +} diff --git a/components/misc/compression.hpp b/components/misc/compression.hpp new file mode 100644 index 0000000000..2b951ebed6 --- /dev/null +++ b/components/misc/compression.hpp @@ -0,0 +1,14 @@ +#ifndef OPENMW_COMPONENTS_MISC_COMPRESSION_H +#define OPENMW_COMPONENTS_MISC_COMPRESSION_H + +#include +#include + +namespace Misc +{ + std::vector compress(const std::vector& data); + + std::vector decompress(const std::vector& data); +} + +#endif