|
- /*
- ==============================================================================
-
- This file is part of the JUCE library - "Jules' Utility Class Extensions"
- Copyright 2004-9 by Raw Material Software Ltd.
-
- ------------------------------------------------------------------------------
-
- JUCE can be redistributed and/or modified under the terms of the GNU General
- Public License (Version 2), as published by the Free Software Foundation.
- A copy of the license is included in the JUCE distribution, or can be found
- online at www.gnu.org/licenses.
-
- JUCE is distributed in the hope that it will be useful, but WITHOUT ANY
- WARRANTY; without even the implied warranty of MERCHANTABILITY or FITNESS FOR
- A PARTICULAR PURPOSE. See the GNU General Public License for more details.
-
- ------------------------------------------------------------------------------
-
- To release a closed-source product which uses JUCE, commercial licenses are
- available: visit www.rawmaterialsoftware.com/juce for more information.
-
- ==============================================================================
- */
-
- #include "../../core/juce_StandardHeader.h"
-
- #if JUCE_MSVC
- #pragma warning (push)
- #pragma warning (disable: 4309 4305)
- #endif
-
- namespace zlibNamespace
- {
- #if JUCE_INCLUDE_ZLIB_CODE
- extern "C"
- {
- #undef OS_CODE
- #undef fdopen
- #define ZLIB_INTERNAL
- #define NO_DUMMY_DECL
- #include "zlib/zlib.h"
- #include "zlib/adler32.c"
- #include "zlib/compress.c"
- #undef DO1
- #undef DO8
- #include "zlib/crc32.c"
- #include "zlib/deflate.c"
- #include "zlib/inffast.c"
- #undef PULLBYTE
- #undef LOAD
- #undef RESTORE
- #undef INITBITS
- #undef NEEDBITS
- #undef DROPBITS
- #undef BYTEBITS
- #include "zlib/inflate.c"
- #include "zlib/inftrees.c"
- #include "zlib/trees.c"
- #include "zlib/zutil.c"
- #undef Byte
- }
- #else
- #include <zlib.h>
- #endif
- }
-
- #if JUCE_MSVC
- #pragma warning (pop)
- #endif
-
- BEGIN_JUCE_NAMESPACE
-
- #include "juce_GZIPDecompressorInputStream.h"
-
- using namespace zlibNamespace;
-
- //==============================================================================
- // internal helper object that holds the zlib structures so they don't have to be
- // included publicly.
- class GZIPDecompressHelper
- {
- public:
- GZIPDecompressHelper (const bool noWrap) throw()
- : data (0),
- dataSize (0),
- finished (true),
- needsDictionary (false),
- error (true),
- streamIsValid (false)
- {
- zerostruct (stream);
- streamIsValid = (inflateInit2 (&stream, noWrap ? -MAX_WBITS : MAX_WBITS) == Z_OK);
- finished = error = ! streamIsValid;
- }
-
- ~GZIPDecompressHelper() throw()
- {
- if (streamIsValid)
- inflateEnd (&stream);
- }
-
- bool needsInput() const throw() { return dataSize <= 0; }
-
- void setInput (uint8* const data_, const int size) throw()
- {
- data = data_;
- dataSize = size;
- }
-
- int doNextBlock (uint8* const dest, const int destSize) throw()
- {
- if (streamIsValid && data != 0 && ! finished)
- {
- stream.next_in = data;
- stream.next_out = dest;
- stream.avail_in = dataSize;
- stream.avail_out = destSize;
-
- switch (inflate (&stream, Z_PARTIAL_FLUSH))
- {
- case Z_STREAM_END:
- finished = true;
- // deliberate fall-through
- case Z_OK:
- data += dataSize - stream.avail_in;
- dataSize = stream.avail_in;
- return destSize - stream.avail_out;
-
- case Z_NEED_DICT:
- needsDictionary = true;
- data += dataSize - stream.avail_in;
- dataSize = stream.avail_in;
- break;
-
- case Z_DATA_ERROR:
- case Z_MEM_ERROR:
- error = true;
-
- default:
- break;
- }
- }
-
- return 0;
- }
-
- private:
- z_stream stream;
- uint8* data;
- int dataSize;
-
- public:
- bool finished, needsDictionary, error, streamIsValid;
- };
-
- //==============================================================================
- const int gzipDecompBufferSize = 32768;
-
- GZIPDecompressorInputStream::GZIPDecompressorInputStream (InputStream* const sourceStream_,
- const bool deleteSourceWhenDestroyed,
- const bool noWrap_,
- const int64 uncompressedStreamLength_)
- : sourceStream (sourceStream_),
- streamToDelete (deleteSourceWhenDestroyed ? sourceStream_ : 0),
- uncompressedStreamLength (uncompressedStreamLength_),
- noWrap (noWrap_),
- isEof (false),
- activeBufferSize (0),
- originalSourcePos (sourceStream_->getPosition()),
- currentPos (0),
- buffer (gzipDecompBufferSize),
- helper (new GZIPDecompressHelper (noWrap_))
- {
- }
-
- GZIPDecompressorInputStream::~GZIPDecompressorInputStream()
- {
- }
-
- int64 GZIPDecompressorInputStream::getTotalLength()
- {
- return uncompressedStreamLength;
- }
-
- int GZIPDecompressorInputStream::read (void* destBuffer, int howMany)
- {
- if ((howMany > 0) && ! isEof)
- {
- jassert (destBuffer != 0);
-
- if (destBuffer != 0)
- {
- int numRead = 0;
- uint8* d = (uint8*) destBuffer;
-
- while (! helper->error)
- {
- const int n = helper->doNextBlock (d, howMany);
- currentPos += n;
-
- if (n == 0)
- {
- if (helper->finished || helper->needsDictionary)
- {
- isEof = true;
- return numRead;
- }
-
- if (helper->needsInput())
- {
- activeBufferSize = sourceStream->read (buffer, gzipDecompBufferSize);
-
- if (activeBufferSize > 0)
- {
- helper->setInput ((uint8*) buffer, activeBufferSize);
- }
- else
- {
- isEof = true;
- return numRead;
- }
- }
- }
- else
- {
- numRead += n;
- howMany -= n;
- d += n;
-
- if (howMany <= 0)
- return numRead;
- }
- }
- }
- }
-
- return 0;
- }
-
- bool GZIPDecompressorInputStream::isExhausted()
- {
- return helper->error || isEof;
- }
-
- int64 GZIPDecompressorInputStream::getPosition()
- {
- return currentPos;
- }
-
- bool GZIPDecompressorInputStream::setPosition (int64 newPos)
- {
- if (newPos < currentPos)
- {
- // to go backwards, reset the stream and start again..
- isEof = false;
- activeBufferSize = 0;
- currentPos = 0;
- helper = new GZIPDecompressHelper (noWrap);
-
- sourceStream->setPosition (originalSourcePos);
- }
-
- skipNextBytes (newPos - currentPos);
- return true;
- }
-
- END_JUCE_NAMESPACE
|