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" 51 #include "zlib/zlib.h" 52 #include "zlib/adler32.c" 53 #include "zlib/compress.c" 56 #include "zlib/crc32.c" 57 #include "zlib/deflate.c" 58 #include "zlib/inffast.c" 66 #include "zlib/inflate.c" 67 #include "zlib/inftrees.c" 68 #include "zlib/trees.c" 69 #include "zlib/zutil.c" 79 #pragma clang diagnostic pop 82 #include JUCE_ZLIB_INCLUDE_PATH 88 #define z_uInt unsigned int 107 using namespace zlibNamespace;
109 streamIsValid = (inflateInit2 (&stream, getBitsForFormat (f)) == Z_OK);
110 finished = error = ! streamIsValid;
116 zlibNamespace::inflateEnd (&stream);
119 bool needsInput()
const noexcept {
return dataSize <= 0; }
121 void setInput (uint8*
const data_,
const size_t size) noexcept
127 int doNextBlock (uint8*
const dest,
const unsigned int destSize)
129 using namespace zlibNamespace;
131 if (streamIsValid && data !=
nullptr && ! finished)
133 stream.next_in = data;
134 stream.next_out = dest;
135 stream.avail_in = (uInt) dataSize;
136 stream.avail_out = (uInt) destSize;
138 switch (inflate (&stream, Z_PARTIAL_FLUSH))
144 data += dataSize - stream.avail_in;
145 dataSize = (uInt) stream.avail_in;
146 return (
int) (destSize - stream.avail_out);
149 needsDictionary =
true;
150 data += dataSize - stream.avail_in;
151 dataSize = (size_t) stream.avail_in;
166 static int getBitsForFormat (Format f) noexcept
170 case zlibFormat:
return MAX_WBITS;
171 case deflateFormat:
return -MAX_WBITS;
172 case gzipFormat:
return MAX_WBITS | 16;
173 default: jassertfalse;
break;
179 bool finished =
true, needsDictionary =
false, error =
true, streamIsValid =
false;
181 enum { gzipDecompBufferSize = 32768 };
184 zlibNamespace::z_stream stream;
185 uint8* data =
nullptr;
193 Format f, int64 uncompressedLength)
194 : sourceStream (source, deleteSourceWhenDestroyed),
195 uncompressedStreamLength (uncompressedLength),
197 originalSourcePos (source->getPosition()),
204 : sourceStream (&source, false),
205 uncompressedStreamLength (-1),
219 return uncompressedStreamLength;
224 jassert (destBuffer !=
nullptr && howMany >= 0);
226 if (howMany > 0 && ! isEof)
229 auto d =
static_cast<uint8*
> (destBuffer);
231 while (! helper->error)
233 auto n = helper->doNextBlock (d, (
unsigned int) howMany);
238 if (helper->finished || helper->needsDictionary)
244 if (helper->needsInput())
246 activeBufferSize = sourceStream->read (buffer, (
int) GZIPDecompressHelper::gzipDecompBufferSize);
248 if (activeBufferSize > 0)
250 helper->setInput (buffer, (
size_t) activeBufferSize);
276 return helper->error || helper->finished || isEof;
286 if (newPos < currentPos)
290 activeBufferSize = 0;
294 sourceStream->setPosition (originalSourcePos);
304 struct GZIPDecompressorInputStreamTests :
public UnitTest 306 GZIPDecompressorInputStreamTests()
307 :
UnitTest (
"GZIPDecompressorInputStreamTests",
"Streams")
310 void runTest()
override 312 const MemoryBlock data (
"abcdefghijklmnopqrstuvwxyz", 26);
317 gzipOutputStream.
flush();
324 expectEquals (stream.getPosition(), (int64) 0);
325 expectEquals (stream.getTotalLength(), (int64) data.
getSize());
326 expectEquals (stream.getNumBytesRemaining(), stream.getTotalLength());
327 expect (! stream.isExhausted());
329 size_t numBytesRead = 0;
332 while (numBytesRead < data.
getSize())
334 numBytesRead += (size_t) stream.read (&readBuffer[numBytesRead], 3);
336 expectEquals (stream.getPosition(), (int64) numBytesRead);
337 expectEquals (stream.getNumBytesRemaining(), (int64) (data.
getSize() - numBytesRead));
338 expect (stream.isExhausted() == (numBytesRead == data.
getSize()));
341 expectEquals (stream.getPosition(), (int64) data.
getSize());
342 expectEquals (stream.getNumBytesRemaining(), (int64) 0);
343 expect (stream.isExhausted());
345 expect (readBuffer == data);
349 stream.setPosition (0);
350 expectEquals (stream.getPosition(), (int64) 0);
351 expectEquals (stream.getTotalLength(), (int64) data.
getSize());
352 expectEquals (stream.getNumBytesRemaining(), stream.getTotalLength());
353 expect (! stream.isExhausted());
356 const int numBytesToSkip = 5;
358 while (numBytesRead < data.
getSize())
360 stream.skipNextBytes (numBytesToSkip);
361 numBytesRead += numBytesToSkip;
362 numBytesRead = std::min (numBytesRead, data.
getSize());
364 expectEquals (stream.getPosition(), (int64) numBytesRead);
365 expectEquals (stream.getNumBytesRemaining(), (int64) (data.
getSize() - numBytesRead));
366 expect (stream.isExhausted() == (numBytesRead == data.
getSize()));
369 expectEquals (stream.getPosition(), (int64) data.
getSize());
370 expectEquals (stream.getNumBytesRemaining(), (int64) 0);
371 expect (stream.isExhausted());
375 static GZIPDecompressorInputStreamTests gzipDecompressorInputStreamTests;
size_t getSize() const noexcept
Returns the block's current allocated size, in bytes.
void flush() override
Flushes and closes the stream.
A stream which uses zlib to compress the data written into it.
This is a base class for classes that perform a unit test.
bool write(const void *, size_t) override
Writes a block of data to the stream.
void * getData() const noexcept
Returns a void pointer to the data.
const void * getData() const noexcept
Returns a pointer to the data that has been written to the stream.
size_t getDataSize() const noexcept
Returns the number of bytes of data that have been written to the stream.
Writes data to an internal memory buffer, which grows as required.
A class to hold a resizable block of raw data.