30 : compLevel ((compressionLevel < 0 || compressionLevel > 9) ? -1 : compressionLevel)
32 using namespace zlibNamespace;
35 streamIsValid = (deflateInit2 (&stream, compLevel, Z_DEFLATED,
36 windowBits != 0 ? windowBits : MAX_WBITS,
37 8, strategy) == Z_OK);
43 zlibNamespace::deflateEnd (&stream);
53 if (! doNextBlock (data, dataSize, out, Z_NO_FLUSH))
61 const uint8* data =
nullptr;
65 doNextBlock (data, dataSize, out, Z_FINISH);
69 enum { strategy = 0 };
71 zlibNamespace::z_stream stream;
73 bool isFirstDeflate =
true, streamIsValid =
false, finished =
false;
74 zlibNamespace::Bytef buffer[32768];
76 bool doNextBlock (
const uint8*& data,
size_t& dataSize,
OutputStream& out,
const int flushMode)
78 using namespace zlibNamespace;
82 stream.next_in =
const_cast<uint8*
> (data);
83 stream.next_out = buffer;
84 stream.avail_in = (z_uInt) dataSize;
85 stream.avail_out = (z_uInt)
sizeof (buffer);
87 auto result = isFirstDeflate ? deflateParams (&stream, compLevel, strategy)
88 : deflate (&stream, flushMode);
89 isFirstDeflate =
false;
98 data += dataSize - stream.avail_in;
99 dataSize = stream.avail_in;
100 auto bytesDone = (
ssize_t)
sizeof (buffer) - (
ssize_t) stream.avail_out;
101 return bytesDone <= 0 || out.
write (buffer, (
size_t) bytesDone);
122 : destStream (out, deleteDestStream),
135 helper->finish (*destStream);
143 return helper->write (
static_cast<const uint8*
> (destBuffer), howMany, *destStream);
148 return destStream->getPosition();
162struct GZIPTests final :
public UnitTest
165 :
UnitTest (
"GZIP", UnitTestCategories::compression)
168 void runTest()
override
171 Random rng = getRandom();
173 for (
int i = 100; --i >= 0;)
175 MemoryOutputStream original, compressed, uncompressed;
178 GZIPCompressorOutputStream zipper (compressed, rng.nextInt (10));
180 for (
int j = rng.nextInt (100); --j >= 0;)
182 MemoryBlock data ((
unsigned int) (rng.nextInt (2000) + 1));
184 for (
int k = (
int) data.getSize(); --k >= 0;)
185 data[k] = (
char) rng.nextInt (255);
193 MemoryInputStream compressedInput (compressed.getData(), compressed.getDataSize(),
false);
194 GZIPDecompressorInputStream unzipper (compressedInput);
196 uncompressed << unzipper;
199 expectEquals ((
int) uncompressed.getDataSize(),
200 (
int) original.getDataSize());
202 if (original.getDataSize() == uncompressed.getDataSize())
203 expect (memcmp (uncompressed.getData(),
205 original.getDataSize()) == 0);
210static GZIPTests gzipTests;
A stream which uses zlib to compress the data written into it.
GZIPCompressorOutputStream(OutputStream &destStream, int compressionLevel=-1, int windowBits=0)
Creates a compression stream.
bool setPosition(int64) override
Tries to move the stream's output position.
bool write(const void *, size_t) override
Writes a block of data to the stream.
~GZIPCompressorOutputStream() override
Destructor.
void flush() override
Flushes and closes the stream.
int64 getPosition() override
Returns the stream's current position.
The base class for streams that write data to some kind of destination.
virtual bool write(const void *dataToWrite, size_t numberOfBytes)=0
Writes a block of data to the stream.
This is a base class for classes that perform a unit test.
void zerostruct(Type &structure) noexcept
Overwrites a structure or object with zeros.
unsigned char uint8
A platform-independent 8-bit unsigned integer type.
long long int64
A platform-independent 64-bit integer type.