From ce18bd8cb89a6aef0398a1447c2dffca74a08f4c Mon Sep 17 00:00:00 2001 From: kichik Date: Tue, 23 Jan 2007 16:05:03 +0000 Subject: [PATCH] compression tests git-svn-id: https://svn.code.sf.net/p/nsis/code/NSIS/trunk@4862 212acab6-be3b-0410-9dea-997c60f758d6 --- Source/Tests/SConscript | 69 +++++++++++++++- Source/Tests/compression.cpp | 154 +++++++++++++++++++++++++++++++++++ Source/Tests/decompress.cpp | 59 ++++++++++++++ Source/Tests/decompress.h | 66 +++++++++++++++ Source/Tests/memcpy.c | 11 +++ 5 files changed, 358 insertions(+), 1 deletion(-) create mode 100644 Source/Tests/compression.cpp create mode 100644 Source/Tests/decompress.cpp create mode 100644 Source/Tests/decompress.h create mode 100644 Source/Tests/memcpy.c diff --git a/Source/Tests/SConscript b/Source/Tests/SConscript index 78ab3c1b..b0896b91 100644 --- a/Source/Tests/SConscript +++ b/Source/Tests/SConscript @@ -1,6 +1,8 @@ target = 'test' tests = Split(""" + compression.cpp + decompress.cpp DialogTemplate.cpp endian.cpp mmap.cpp @@ -18,6 +20,52 @@ required = Split(""" util.cpp """) +required_exehead = Split(""" + Tests/memcpy.c +""") + +lzma_files = Split(""" + clzma.cpp + 7zip/7zGuids.cpp + 7zip/7zip/Common/OutBuffer.cpp + 7zip/7zip/Common/StreamUtils.cpp + 7zip/7zip/Compress/LZ/LZInWindow.cpp + 7zip/7zip/Compress/LZMA/LZMAEncoder.cpp + 7zip/7zip/Compress/RangeCoder/RangeCoderBit.cpp + 7zip/Common/Alloc.cpp + 7zip/Common/CRC.cpp + 7zip/LZMADecode.c +""") + +required += lzma_files + +bzip2_files = Split(""" + bzip2/blocksort.c + bzip2/bzlib.c + bzip2/compress.c + bzip2/huffman.c +""") + +bzip2_exehead_files = Split(""" + bzip2/bzlib.c + bzip2/decompress.c +""") + +required += bzip2_files +required_exehead += bzip2_exehead_files + +zlib_files = Split(""" + zlib/deflate.c + zlib/trees.c +""") + +zlib_exehead_files = Split(""" + zlib/INFBLOCK.C +""") + +required += zlib_files +required_exehead += zlib_exehead_files + cppunitlibs = Split(""" cppunit """) @@ -48,6 +96,9 @@ if 'msvc' in env['TOOLS'] or 'mstoolkit' in env['TOOLS']: # uses exceptions env.Append(CCFLAGS = ['$EXCEPTION_FLAG']) +# for lzma +env.Append(CPPDEFINES = ['COMPRESS_MF_BT']) + # test for CppUnit conf = env.Configure() cppunit = conf.CheckLibWithHeader(cppunitlibs, 'cppunit/extensions/HelperMacros.h', 'C++') @@ -59,12 +110,28 @@ if cppunit: required_obj = [] for i in required: - b = 'required/%s' % i[:-4] + b = 'required/%s' % i.split('.')[0] s = '#Source/%s' % i o = env.Object(b, s) required_obj.append(o) + # exehead files special treatment + exehead_env = env.Clone() + exehead_env.Append( + CPPDEFINES = [ + 'EXEHEAD', + 'NSIS_COMPRESS_USE_ZLIB' # just so config.h won't complain + ] + ) + + for i in required_exehead: + b = 'required/exehead/%s' % i.split('.')[0] + s = '#Source/%s' % i + o = exehead_env.Object(b, s) + + required_obj.append(o) + # build test program tests = env.Program(target, tests + required_obj) diff --git a/Source/Tests/compression.cpp b/Source/Tests/compression.cpp new file mode 100644 index 00000000..f04d8198 --- /dev/null +++ b/Source/Tests/compression.cpp @@ -0,0 +1,154 @@ +#include +#include "../Platform.h" +#include "../growbuf.h" + +#include +#include + +#include "decompress.h" + +#include "../cbzip2.h" +#include "../clzma.h" +#include "../czlib.h" + +class CompressionTest : public CppUnit::TestFixture { + +public: + void randData(IGrowBuf &buf, int kb) { + srand(time(0)); + + for (int i = 0; i < kb; i++) { + int r = rand(); + for (int j = 0; j < 1024/sizeof(int); j++) { + buf.add(&r, sizeof(int)); + } + } + } + + // compressor must be initialized! + void compress(ICompressor &compressor, IGrowBuf& in, IGrowBuf& out) { + compressor.SetNextIn((char *) in.get(), in.getlen()); + + int ret; + + do { + char outbuf[1024]; + compressor.SetNextOut(outbuf, sizeof(outbuf)); + + ret = compressor.Compress(C_FINISH); + + CPPUNIT_ASSERT_MESSAGE( compressor.GetErrStr(ret) , ret >= 0 ); + + out.add(outbuf, sizeof(outbuf) - compressor.GetAvailOut()); + } while (ret == 0); + } + + typedef void (*decompressInitPtr)(void *); + typedef int (*decompressWorkPtr)(void *); + + void decompress(IDecompressor& decompressor, IGrowBuf& in, IGrowBuf& out) { + decompressor.init(); + decompressor.setNextIn(in.get(), in.getlen()); + + int ret; + + do { + char outbuf[1024]; + decompressor.setNextOut(outbuf, sizeof(outbuf)); + + ret = decompressor.decompress(); + + CPPUNIT_ASSERT( ret >= 0 ); + + out.add(outbuf, sizeof(outbuf) - decompressor.getAvailOut()); + + } while (ret == 0); + + } + + // compressor must be initialized! + void testCompressDecompress(int size_kb, ICompressor &compressor, IDecompressor& decompressor) { + GrowBuf data; + GrowBuf compressed; + GrowBuf decompressed; + + randData(data, size_kb); + + compress(compressor, data, compressed); + decompress(decompressor, compressed, decompressed); + + CPPUNIT_ASSERT_MESSAGE( "decompressed data is smaller", data.getlen() <= decompressed.getlen() ); + CPPUNIT_ASSERT_MESSAGE( "decompressed data is larger", data.getlen() >= decompressed.getlen() ); + CPPUNIT_ASSERT_MESSAGE( "decompressed data is different", !memcmp(data.get(), decompressed.get(), data.getlen()) ); + } + + void testCompressDecompress(ICompressor &compressor, IDecompressor& decompressor) { + CPPUNIT_ASSERT( compressor.Init(9, 1 << 23) == C_OK ); + testCompressDecompress(1, compressor, decompressor); + + CPPUNIT_ASSERT( compressor.Init(9, 1 << 23) == C_OK ); + testCompressDecompress(1024, compressor, decompressor); + + CPPUNIT_ASSERT( compressor.Init(9, 1 << 23) == C_OK ); + testCompressDecompress(8*1024, compressor, decompressor); + + CPPUNIT_ASSERT( compressor.Init(9, 1 << 23) == C_OK ); + testCompressDecompress(32*1024, compressor, decompressor); + } + +}; + +class bzip2CompressionTest : public CompressionTest { + + CPPUNIT_TEST_SUITE( bzip2CompressionTest ); + CPPUNIT_TEST( test ); + CPPUNIT_TEST_SUITE_END(); + +public: + + void test() { + CBzip2 compressor; + bzip2Decompressor decompressor; + + testCompressDecompress(compressor, decompressor); + } + +}; + +class lzmaCompressionTest : public CompressionTest { + + CPPUNIT_TEST_SUITE( lzmaCompressionTest ); + CPPUNIT_TEST( test ); + CPPUNIT_TEST_SUITE_END(); + +public: + + void test() { + CLZMA compressor; + lzmaDecompressor decompressor; + + testCompressDecompress(compressor, decompressor); + } + +}; + +class zlibCompressionTest : public CompressionTest { + + CPPUNIT_TEST_SUITE( zlibCompressionTest ); + CPPUNIT_TEST( test ); + CPPUNIT_TEST_SUITE_END(); + +public: + + void test() { + CZlib compressor; + zlibDecompressor decompressor; + + testCompressDecompress(compressor, decompressor); + } + +}; + +CPPUNIT_TEST_SUITE_REGISTRATION( bzip2CompressionTest ); +CPPUNIT_TEST_SUITE_REGISTRATION( lzmaCompressionTest ); +CPPUNIT_TEST_SUITE_REGISTRATION( zlibCompressionTest ); diff --git a/Source/Tests/decompress.cpp b/Source/Tests/decompress.cpp new file mode 100644 index 00000000..f01d8335 --- /dev/null +++ b/Source/Tests/decompress.cpp @@ -0,0 +1,59 @@ +#include "decompress.h" + +#define EXEHEAD +#define NSIS_CONFIG_COMPRESSION_SUPPORT + +extern "C" { +#define NSIS_COMPRESS_USE_BZIP2 +#include "../bzip2/bzlib.h" +#undef NSIS_COMPRESS_USE_BZIP2 + +#define NSIS_COMPRESS_USE_LZMA +#include "../7zip/LZMADecode.h" +#undef NSIS_COMPRESS_USE_LZMA + +#define NSIS_COMPRESS_USE_ZLIB +#include "../zlib/ZLIB.H" +#undef NSIS_COMPRESS_USE_ZLIB +} + +#define DECOMPRESSOR(name, type, initf, dec, u) \ + name::name() { \ + vs = new type; \ + } \ + \ + name::~name() { \ + delete vs; \ + vs = NULL; \ + } \ + \ + void name::setNextIn(void *buffer, int size) { \ + type *s = (type *) vs; \ + s->next_in = (u *) buffer; \ + s->avail_in = size; \ + } \ + \ + void name::setNextOut(void *buffer, int size) { \ + type *s = (type *) vs; \ + s->next_out = (u *) buffer; \ + s->avail_out = size; \ + } \ + \ + int name::getAvailOut() { \ + type *s = (type *) vs; \ + return s->avail_out; \ + } \ + \ + void name::init() { \ + type *s = (type *) vs; \ + initf(s); \ + } \ + \ + int name::decompress() { \ + type *s = (type *) vs; \ + return dec(s); \ + } + +DECOMPRESSOR(lzmaDecompressor, lzma_stream, lzmaInit, lzmaDecode, unsigned char); +DECOMPRESSOR(bzip2Decompressor, DState, BZ2_bzDecompressInit, BZ2_bzDecompress, char); +DECOMPRESSOR(zlibDecompressor, z_stream, inflateReset, inflate, unsigned char); diff --git a/Source/Tests/decompress.h b/Source/Tests/decompress.h new file mode 100644 index 00000000..6fb2a766 --- /dev/null +++ b/Source/Tests/decompress.h @@ -0,0 +1,66 @@ +class IDecompressor { +public: + + virtual ~IDecompressor() {}; + + virtual void init() = 0; + virtual void setNextIn(void *buffer, int size) = 0; + virtual void setNextOut(void *buffer, int size) = 0; + virtual int getAvailOut() = 0; + virtual int decompress() = 0; + +}; + +class lzmaDecompressor : public IDecompressor { +public: + + lzmaDecompressor(); + virtual ~lzmaDecompressor(); + + virtual void init(); + virtual void setNextIn(void *buffer, int size); + virtual void setNextOut(void *buffer, int size); + virtual int getAvailOut(); + virtual int decompress(); + +private: + + void *vs; + +}; + +class bzip2Decompressor : public IDecompressor { +public: + + bzip2Decompressor(); + virtual ~bzip2Decompressor(); + + virtual void init(); + virtual void setNextIn(void *buffer, int size); + virtual void setNextOut(void *buffer, int size); + virtual int getAvailOut(); + virtual int decompress(); + +private: + + void *vs; + +}; + +class zlibDecompressor : public IDecompressor { +public: + + zlibDecompressor(); + virtual ~zlibDecompressor(); + + virtual void init(); + virtual void setNextIn(void *buffer, int size); + virtual void setNextOut(void *buffer, int size); + virtual int getAvailOut(); + virtual int decompress(); + +private: + + void *vs; + +}; diff --git a/Source/Tests/memcpy.c b/Source/Tests/memcpy.c new file mode 100644 index 00000000..d14c5b5b --- /dev/null +++ b/Source/Tests/memcpy.c @@ -0,0 +1,11 @@ +#include "../exehead/util.h" + +void NSISCALL mini_memcpy(void *out, const void *in, int len) +{ + char *c_out=(char*)out; + char *c_in=(char *)in; + while (len-- > 0) + { + *c_out++=*c_in++; + } +}