Add remaining files
[juce-lv2.git] / juce / source / src / io / streams / juce_GZIPDecompressorInputStream.cpp
blobca44933b7d5abeae2d7a1b21aef359c174e32a14
1 /*
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"
28 #if JUCE_MSVC
29 #pragma warning (push)
30 #pragma warning (disable: 4309 4305)
31 #endif
33 namespace zlibNamespace
35 #if JUCE_INCLUDE_ZLIB_CODE
36 #undef OS_CODE
37 #undef fdopen
38 #define ZLIB_INTERNAL
39 #define NO_DUMMY_DECL
40 #include "zlib/zlib.h"
41 #include "zlib/adler32.c"
42 #include "zlib/compress.c"
43 #undef DO1
44 #undef DO8
45 #include "zlib/crc32.c"
46 #include "zlib/deflate.c"
47 #include "zlib/inffast.c"
48 #undef PULLBYTE
49 #undef LOAD
50 #undef RESTORE
51 #undef INITBITS
52 #undef NEEDBITS
53 #undef DROPBITS
54 #undef BYTEBITS
55 #include "zlib/inflate.c"
56 #include "zlib/inftrees.c"
57 #include "zlib/trees.c"
58 #include "zlib/zutil.c"
59 #undef Byte
60 #else
61 #include <zlib.h>
62 #endif
65 #if JUCE_MSVC
66 #pragma warning (pop)
67 #endif
69 BEGIN_JUCE_NAMESPACE
71 #include "juce_GZIPDecompressorInputStream.h"
74 //==============================================================================
75 // internal helper object that holds the zlib structures so they don't have to be
76 // included publicly.
77 class GZIPDecompressorInputStream::GZIPDecompressHelper
79 public:
80 GZIPDecompressHelper (const bool noWrap)
81 : finished (true),
82 needsDictionary (false),
83 error (true),
84 streamIsValid (false),
85 data (nullptr),
86 dataSize (0)
88 using namespace zlibNamespace;
89 zerostruct (stream);
90 streamIsValid = (inflateInit2 (&stream, noWrap ? -MAX_WBITS : MAX_WBITS) == Z_OK);
91 finished = error = ! streamIsValid;
94 ~GZIPDecompressHelper()
96 using namespace zlibNamespace;
97 if (streamIsValid)
98 inflateEnd (&stream);
101 bool needsInput() const noexcept { return dataSize <= 0; }
103 void setInput (uint8* const data_, const int size) noexcept
105 data = data_;
106 dataSize = size;
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))
121 case Z_STREAM_END:
122 finished = true;
123 // deliberate fall-through
124 case Z_OK:
125 data += dataSize - stream.avail_in;
126 dataSize = stream.avail_in;
127 return destSize - stream.avail_out;
129 case Z_NEED_DICT:
130 needsDictionary = true;
131 data += dataSize - stream.avail_in;
132 dataSize = stream.avail_in;
133 break;
135 case Z_DATA_ERROR:
136 case Z_MEM_ERROR:
137 error = true;
139 default:
140 break;
144 return 0;
147 bool finished, needsDictionary, error, streamIsValid;
149 enum { gzipDecompBufferSize = 32768 };
151 private:
152 zlibNamespace::z_stream stream;
153 uint8* data;
154 int dataSize;
156 JUCE_DECLARE_NON_COPYABLE (GZIPDecompressHelper);
159 //==============================================================================
160 GZIPDecompressorInputStream::GZIPDecompressorInputStream (InputStream* const sourceStream_,
161 const bool deleteSourceWhenDestroyed,
162 const bool noWrap_,
163 const int64 uncompressedStreamLength_)
164 : sourceStream (sourceStream_, deleteSourceWhenDestroyed),
165 uncompressedStreamLength (uncompressedStreamLength_),
166 noWrap (noWrap_),
167 isEof (false),
168 activeBufferSize (0),
169 originalSourcePos (sourceStream_->getPosition()),
170 currentPos (0),
171 buffer ((size_t) GZIPDecompressHelper::gzipDecompBufferSize),
172 helper (new GZIPDecompressHelper (noWrap_))
176 GZIPDecompressorInputStream::GZIPDecompressorInputStream (InputStream& sourceStream_)
177 : sourceStream (&sourceStream_, false),
178 uncompressedStreamLength (-1),
179 noWrap (false),
180 isEof (false),
181 activeBufferSize (0),
182 originalSourcePos (sourceStream_.getPosition()),
183 currentPos (0),
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)
206 int numRead = 0;
207 uint8* d = static_cast <uint8*> (destBuffer);
209 while (! helper->error)
211 const int n = helper->doNextBlock (d, howMany);
212 currentPos += n;
214 if (n == 0)
216 if (helper->finished || helper->needsDictionary)
218 isEof = true;
219 return numRead;
222 if (helper->needsInput())
224 activeBufferSize = sourceStream->read (buffer, (int) GZIPDecompressHelper::gzipDecompBufferSize);
226 if (activeBufferSize > 0)
228 helper->setInput (buffer, activeBufferSize);
230 else
232 isEof = true;
233 return numRead;
237 else
239 numRead += n;
240 howMany -= n;
241 d += n;
243 if (howMany <= 0)
244 return numRead;
250 return 0;
253 bool GZIPDecompressorInputStream::isExhausted()
255 return helper->error || isEof;
258 int64 GZIPDecompressorInputStream::getPosition()
260 return currentPos;
263 bool GZIPDecompressorInputStream::setPosition (int64 newPos)
265 if (newPos < currentPos)
267 // to go backwards, reset the stream and start again..
268 isEof = false;
269 activeBufferSize = 0;
270 currentPos = 0;
271 helper = new GZIPDecompressHelper (noWrap);
273 sourceStream->setPosition (originalSourcePos);
276 skipNextBytes (newPos - currentPos);
277 return true;
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);
286 END_JUCE_NAMESPACE