2 ==============================================================================
4 This file is part of the JUCE library - "Jules' Utility Class Extensions"
5 Copyright 2004-11 by Raw Material Software Ltd.
7 ------------------------------------------------------------------------------
9 JUCE can be redistributed and/or modified under the terms of the GNU General
10 Public License (Version 2), as published by the Free Software Foundation.
11 A copy of the license is included in the JUCE distribution, or can be found
12 online at www.gnu.org/licenses.
14 JUCE is distributed in the hope that it will be useful, but WITHOUT ANY
15 WARRANTY; without even the implied warranty of MERCHANTABILITY or FITNESS FOR
16 A PARTICULAR PURPOSE. See the GNU General Public License for more details.
18 ------------------------------------------------------------------------------
20 To release a closed-source product which uses JUCE, commercial licenses are
21 available: visit www.rawmaterialsoftware.com/juce for more information.
23 ==============================================================================
26 #include "../../core/juce_StandardHeader.h"
29 #pragma warning (push)
30 #pragma warning (disable: 4309 4305)
33 namespace zlibNamespace
35 #if JUCE_INCLUDE_ZLIB_CODE
40 #include "zlib/zlib.h"
41 #include "zlib/adler32.c"
42 #include "zlib/compress.c"
45 #include "zlib/crc32.c"
46 #include "zlib/deflate.c"
47 #include "zlib/inffast.c"
55 #include "zlib/inflate.c"
56 #include "zlib/inftrees.c"
57 #include "zlib/trees.c"
58 #include "zlib/zutil.c"
71 #include "juce_GZIPDecompressorInputStream.h"
74 //==============================================================================
75 // internal helper object that holds the zlib structures so they don't have to be
77 class GZIPDecompressorInputStream::GZIPDecompressHelper
80 GZIPDecompressHelper (const bool noWrap
)
82 needsDictionary (false),
84 streamIsValid (false),
88 using namespace zlibNamespace
;
90 streamIsValid
= (inflateInit2 (&stream
, noWrap
? -MAX_WBITS
: MAX_WBITS
) == Z_OK
);
91 finished
= error
= ! streamIsValid
;
94 ~GZIPDecompressHelper()
96 using namespace zlibNamespace
;
101 bool needsInput() const noexcept
{ return dataSize
<= 0; }
103 void setInput (uint8
* const data_
, const int size
) noexcept
109 int doNextBlock (uint8
* const dest
, const int destSize
)
111 using namespace zlibNamespace
;
112 if (streamIsValid
&& data
!= nullptr && ! finished
)
114 stream
.next_in
= data
;
115 stream
.next_out
= dest
;
116 stream
.avail_in
= dataSize
;
117 stream
.avail_out
= destSize
;
119 switch (inflate (&stream
, Z_PARTIAL_FLUSH
))
123 // deliberate fall-through
125 data
+= dataSize
- stream
.avail_in
;
126 dataSize
= stream
.avail_in
;
127 return destSize
- stream
.avail_out
;
130 needsDictionary
= true;
131 data
+= dataSize
- stream
.avail_in
;
132 dataSize
= stream
.avail_in
;
147 bool finished
, needsDictionary
, error
, streamIsValid
;
149 enum { gzipDecompBufferSize
= 32768 };
152 zlibNamespace::z_stream stream
;
156 JUCE_DECLARE_NON_COPYABLE (GZIPDecompressHelper
);
159 //==============================================================================
160 GZIPDecompressorInputStream::GZIPDecompressorInputStream (InputStream
* const sourceStream_
,
161 const bool deleteSourceWhenDestroyed
,
163 const int64 uncompressedStreamLength_
)
164 : sourceStream (sourceStream_
, deleteSourceWhenDestroyed
),
165 uncompressedStreamLength (uncompressedStreamLength_
),
168 activeBufferSize (0),
169 originalSourcePos (sourceStream_
->getPosition()),
171 buffer ((size_t) GZIPDecompressHelper::gzipDecompBufferSize
),
172 helper (new GZIPDecompressHelper (noWrap_
))
176 GZIPDecompressorInputStream::GZIPDecompressorInputStream (InputStream
& sourceStream_
)
177 : sourceStream (&sourceStream_
, false),
178 uncompressedStreamLength (-1),
181 activeBufferSize (0),
182 originalSourcePos (sourceStream_
.getPosition()),
184 buffer ((size_t) GZIPDecompressHelper::gzipDecompBufferSize
),
185 helper (new GZIPDecompressHelper (false))
189 GZIPDecompressorInputStream::~GZIPDecompressorInputStream()
193 int64
GZIPDecompressorInputStream::getTotalLength()
195 return uncompressedStreamLength
;
198 int GZIPDecompressorInputStream::read (void* destBuffer
, int howMany
)
200 if ((howMany
> 0) && ! isEof
)
202 jassert (destBuffer
!= nullptr);
204 if (destBuffer
!= nullptr)
207 uint8
* d
= static_cast <uint8
*> (destBuffer
);
209 while (! helper
->error
)
211 const int n
= helper
->doNextBlock (d
, howMany
);
216 if (helper
->finished
|| helper
->needsDictionary
)
222 if (helper
->needsInput())
224 activeBufferSize
= sourceStream
->read (buffer
, (int) GZIPDecompressHelper::gzipDecompBufferSize
);
226 if (activeBufferSize
> 0)
228 helper
->setInput (buffer
, activeBufferSize
);
253 bool GZIPDecompressorInputStream::isExhausted()
255 return helper
->error
|| isEof
;
258 int64
GZIPDecompressorInputStream::getPosition()
263 bool GZIPDecompressorInputStream::setPosition (int64 newPos
)
265 if (newPos
< currentPos
)
267 // to go backwards, reset the stream and start again..
269 activeBufferSize
= 0;
271 helper
= new GZIPDecompressHelper (noWrap
);
273 sourceStream
->setPosition (originalSourcePos
);
276 skipNextBytes (newPos
- currentPos
);
280 // (This is used as a way for the zip file code to use the crc32 function without including zlib)
281 unsigned long juce_crc32 (unsigned long crc
, const unsigned char* buf
, unsigned len
)
283 return zlibNamespace::crc32 (crc
, buf
, len
);