27 #pragma warning (push)
28 #pragma warning (disable: 4309 4305 4365)
31 namespace zlibNamespace
33 #if JUCE_INCLUDE_ZLIB_CODE
35 #pragma clang diagnostic push
36 #pragma clang diagnostic ignored "-Wconversion"
37 #pragma clang diagnostic ignored "-Wshadow"
38 #pragma clang diagnostic ignored "-Wdeprecated-register"
39 #if __has_warning("-Wzero-as-null-pointer-constant")
40 #pragma clang diagnostic ignored "-Wzero-as-null-pointer-constant"
42 #if __has_warning("-Wcomma")
43 #pragma clang diagnostic ignored "-Wcomma"
48 #pragma GCC diagnostic push
49 #pragma GCC diagnostic ignored "-Wconversion"
50 #pragma GCC diagnostic ignored "-Wsign-conversion"
51 #pragma GCC diagnostic ignored "-Wshadow"
52 #pragma GCC diagnostic ignored "-Wzero-as-null-pointer-constant"
59 #include "zlib/zlib.h"
60 #include "zlib/adler32.c"
61 #include "zlib/compress.c"
64 #include "zlib/crc32.c"
65 #include "zlib/deflate.c"
66 #include "zlib/inffast.c"
74 #include "zlib/inflate.c"
75 #include "zlib/inftrees.c"
76 #include "zlib/trees.c"
77 #include "zlib/zutil.c"
87 #pragma clang diagnostic pop
91 #pragma GCC diagnostic pop
94 #include JUCE_ZLIB_INCLUDE_PATH
100 #define z_uInt unsigned int
108 #pragma warning (pop)
119 using namespace zlibNamespace;
121 streamIsValid = (inflateInit2 (&stream, getBitsForFormat (f)) == Z_OK);
122 finished = error = ! streamIsValid;
128 zlibNamespace::inflateEnd (&stream);
131 bool needsInput()
const noexcept {
return dataSize <= 0; }
133 void setInput (uint8*
const data_,
const size_t size) noexcept
139 int doNextBlock (uint8*
const dest,
const unsigned int destSize)
141 using namespace zlibNamespace;
143 if (streamIsValid && data !=
nullptr && ! finished)
145 stream.next_in = data;
146 stream.next_out = dest;
147 stream.avail_in = (z_uInt) dataSize;
148 stream.avail_out = (z_uInt) destSize;
150 switch (inflate (&stream, Z_PARTIAL_FLUSH))
156 data += dataSize - stream.avail_in;
157 dataSize = (z_uInt) stream.avail_in;
158 return (
int) (destSize - stream.avail_out);
161 needsDictionary =
true;
162 data += dataSize - stream.avail_in;
163 dataSize = (size_t) stream.avail_in;
178 static int getBitsForFormat (Format f) noexcept
182 case zlibFormat:
return MAX_WBITS;
183 case deflateFormat:
return -MAX_WBITS;
184 case gzipFormat:
return MAX_WBITS | 16;
185 default: jassertfalse;
break;
191 bool finished =
true, needsDictionary =
false, error =
true, streamIsValid =
false;
193 enum { gzipDecompBufferSize = 32768 };
196 zlibNamespace::z_stream stream;
197 uint8* data =
nullptr;
205 Format f, int64 uncompressedLength)
206 : sourceStream (source, deleteSourceWhenDestroyed),
207 uncompressedStreamLength (uncompressedLength),
216 : sourceStream (&source, false),
217 uncompressedStreamLength (-1),
219 originalSourcePos (source.getPosition()),
231 return uncompressedStreamLength;
236 jassert (destBuffer !=
nullptr && howMany >= 0);
238 if (howMany > 0 && ! isEof)
241 auto d =
static_cast<uint8*
> (destBuffer);
243 while (! helper->error)
245 auto n = helper->doNextBlock (d, (
unsigned int) howMany);
250 if (helper->finished || helper->needsDictionary)
256 if (helper->needsInput())
258 activeBufferSize = sourceStream->read (buffer, (
int) GZIPDecompressHelper::gzipDecompBufferSize);
260 if (activeBufferSize > 0)
262 helper->setInput (buffer, (
size_t) activeBufferSize);
288 return helper->error || helper->finished || isEof;
298 if (newPos < currentPos)
302 activeBufferSize = 0;
306 sourceStream->setPosition (originalSourcePos);
318 struct GZIPDecompressorInputStreamTests :
public UnitTest
320 GZIPDecompressorInputStreamTests()
321 :
UnitTest (
"GZIPDecompressorInputStreamTests", UnitTestCategories::streams)
324 void runTest()
override
326 const MemoryBlock data (
"abcdefghijklmnopqrstuvwxyz", 26);
328 MemoryOutputStream mo;
329 GZIPCompressorOutputStream gzipOutputStream (mo);
330 gzipOutputStream.write (data.getData(), data.getSize());
331 gzipOutputStream.flush();
333 MemoryInputStream mi (mo.getData(), mo.getDataSize(),
false);
334 GZIPDecompressorInputStream stream (&mi,
false, GZIPDecompressorInputStream::zlibFormat, (int64) data.getSize());
338 expectEquals (stream.getPosition(), (int64) 0);
339 expectEquals (stream.getTotalLength(), (int64) data.getSize());
340 expectEquals (stream.getNumBytesRemaining(), stream.getTotalLength());
341 expect (! stream.isExhausted());
343 size_t numBytesRead = 0;
344 MemoryBlock readBuffer (data.getSize());
346 while (numBytesRead < data.getSize())
348 numBytesRead += (size_t) stream.read (&readBuffer[numBytesRead], 3);
350 expectEquals (stream.getPosition(), (int64) numBytesRead);
351 expectEquals (stream.getNumBytesRemaining(), (int64) (data.getSize() - numBytesRead));
352 expect (stream.isExhausted() == (numBytesRead == data.getSize()));
355 expectEquals (stream.getPosition(), (int64) data.getSize());
356 expectEquals (stream.getNumBytesRemaining(), (int64) 0);
357 expect (stream.isExhausted());
359 expect (readBuffer == data);
363 stream.setPosition (0);
364 expectEquals (stream.getPosition(), (int64) 0);
365 expectEquals (stream.getTotalLength(), (int64) data.getSize());
366 expectEquals (stream.getNumBytesRemaining(), stream.getTotalLength());
367 expect (! stream.isExhausted());
370 const int numBytesToSkip = 5;
372 while (numBytesRead < data.getSize())
374 stream.skipNextBytes (numBytesToSkip);
375 numBytesRead += numBytesToSkip;
376 numBytesRead = std::min (numBytesRead, data.getSize());
378 expectEquals (stream.getPosition(), (int64) numBytesRead);
379 expectEquals (stream.getNumBytesRemaining(), (int64) (data.getSize() - numBytesRead));
380 expect (stream.isExhausted() == (numBytesRead == data.getSize()));
383 expectEquals (stream.getPosition(), (int64) data.getSize());
384 expectEquals (stream.getNumBytesRemaining(), (int64) 0);
385 expect (stream.isExhausted());
389 static GZIPDecompressorInputStreamTests gzipDecompressorInputStreamTests;
This is a base class for classes that perform a unit test.