LMMS
Loading...
Searching...
No Matches
juce_GZIPDecompressorInputStream.cpp
Go to the documentation of this file.
1/*
2 ==============================================================================
3
4 This file is part of the JUCE library.
5 Copyright (c) 2022 - Raw Material Software Limited
6
7 JUCE is an open source library subject to commercial or open-source
8 licensing.
9
10 The code included in this file is provided under the terms of the ISC license
11 http://www.isc.org/downloads/software-support-policy/isc-license. Permission
12 To use, copy, modify, and/or distribute this software for any purpose with or
13 without fee is hereby granted provided that the above copyright notice and
14 this permission notice appear in all copies.
15
16 JUCE IS PROVIDED "AS IS" WITHOUT ANY WARRANTY, AND ALL WARRANTIES, WHETHER
17 EXPRESSED OR IMPLIED, INCLUDING MERCHANTABILITY AND FITNESS FOR PURPOSE, ARE
18 DISCLAIMED.
19
20 ==============================================================================
21*/
22
23namespace juce
24{
25
26JUCE_BEGIN_IGNORE_WARNINGS_MSVC (4309 4305 4365 6385 6326 6340)
27
29{
30 #if JUCE_INCLUDE_ZLIB_CODE
32 "-Wsign-conversion",
33 "-Wshadow",
34 "-Wdeprecated-register",
35 "-Wswitch-enum",
36 "-Wswitch-default",
37 "-Wredundant-decls",
38 "-Wimplicit-fallthrough",
39 "-Wzero-as-null-pointer-constant",
40 "-Wcomma")
41
42 #undef OS_CODE
43 #undef fdopen
44 #define ZLIB_INTERNAL
45 #define NO_DUMMY_DECL
46 #include "zlib/zlib.h"
47 #include "zlib/adler32.c"
48 #include "zlib/compress.c"
49 #undef DO1
50 #undef DO8
51 #include "zlib/crc32.c"
52 #include "zlib/deflate.c"
53 #include "zlib/inffast.c"
54 #undef PULLBYTE
55 #undef LOAD
56 #undef RESTORE
57 #undef INITBITS
58 #undef NEEDBITS
59 #undef DROPBITS
60 #undef BYTEBITS
61 #include "zlib/inflate.c"
62 #include "zlib/inftrees.c"
63 #include "zlib/trees.c"
64 #include "zlib/zutil.c"
65 #undef Byte
66 #undef fdopen
67 #undef local
68 #undef Freq
69 #undef Code
70 #undef Dad
71 #undef Len
72
74 #else
75 #include JUCE_ZLIB_INCLUDE_PATH
76
77 #ifndef z_uInt
78 #ifdef uInt
79 #define z_uInt uInt
80 #else
81 #define z_uInt unsigned int
82 #endif
83 #endif
84
85 #endif
86}
87
89
90//==============================================================================
91// internal helper object that holds the zlib structures so they don't have to be
92// included publicly.
94{
95public:
103
105 {
106 if (streamIsValid)
107 zlibNamespace::inflateEnd (&stream);
108 }
109
110 bool needsInput() const noexcept { return dataSize <= 0; }
111
112 void setInput (uint8* const data_, const size_t size) noexcept
113 {
114 data = data_;
115 dataSize = size;
116 }
117
118 int doNextBlock (uint8* const dest, const unsigned int destSize)
119 {
120 using namespace zlibNamespace;
121
122 if (streamIsValid && data != nullptr && ! finished)
123 {
124 stream.next_in = data;
125 stream.next_out = dest;
126 stream.avail_in = (z_uInt) dataSize;
127 stream.avail_out = (z_uInt) destSize;
128
129 switch (inflate (&stream, Z_PARTIAL_FLUSH))
130 {
131 case Z_STREAM_END:
132 finished = true;
134 case Z_OK:
135 data += dataSize - stream.avail_in;
136 dataSize = (z_uInt) stream.avail_in;
137 return (int) (destSize - stream.avail_out);
138
139 case Z_NEED_DICT:
140 needsDictionary = true;
141 data += dataSize - stream.avail_in;
142 dataSize = (size_t) stream.avail_in;
143 break;
144
145 case Z_DATA_ERROR:
146 case Z_MEM_ERROR:
147 error = true;
149 default:
150 break;
151 }
152 }
153
154 return 0;
155 }
156
157 static int getBitsForFormat (Format f) noexcept
158 {
159 switch (f)
160 {
161 case zlibFormat: return MAX_WBITS;
162 case deflateFormat: return -MAX_WBITS;
163 case gzipFormat: return MAX_WBITS | 16;
164 default: jassertfalse; break;
165 }
166
167 return MAX_WBITS;
168 }
169
170 bool finished = true, needsDictionary = false, error = true, streamIsValid = false;
171
172 enum { gzipDecompBufferSize = 32768 };
173
174private:
175 zlibNamespace::z_stream stream;
176 uint8* data = nullptr;
177 size_t dataSize = 0;
178
180};
181
182//==============================================================================
184 Format f, int64 uncompressedLength)
185 : sourceStream (source, deleteSourceWhenDestroyed),
186 uncompressedStreamLength (uncompressedLength),
187 format (f),
188 originalSourcePos (source->getPosition()),
189 buffer ((size_t) GZIPDecompressHelper::gzipDecompBufferSize),
191{
192}
193
203
207
212
213int GZIPDecompressorInputStream::read (void* destBuffer, int howMany)
214{
215 jassert (destBuffer != nullptr && howMany >= 0);
216
217 if (howMany > 0 && ! isEof)
218 {
219 int numRead = 0;
220 auto d = static_cast<uint8*> (destBuffer);
221
222 while (! helper->error)
223 {
224 auto n = helper->doNextBlock (d, (unsigned int) howMany);
225 currentPos += n;
226
227 if (n == 0)
228 {
229 if (helper->finished || helper->needsDictionary)
230 {
231 isEof = true;
232 return numRead;
233 }
234
235 if (helper->needsInput())
236 {
238
239 if (activeBufferSize > 0)
240 {
241 helper->setInput (buffer, (size_t) activeBufferSize);
242 }
243 else
244 {
245 isEof = true;
246 return numRead;
247 }
248 }
249 }
250 else
251 {
252 numRead += n;
253 howMany -= n;
254 d += n;
255
256 if (howMany <= 0)
257 return numRead;
258 }
259 }
260 }
261
262 return 0;
263}
264
266{
267 return helper->error || helper->finished || isEof;
268}
269
274
276{
277 if (newPos < currentPos)
278 {
279 // to go backwards, reset the stream and start again..
280 isEof = false;
282 currentPos = 0;
283 helper.reset (new GZIPDecompressHelper (format));
284
285 sourceStream->setPosition (originalSourcePos);
286 }
287
288 skipNextBytes (newPos - currentPos);
289 return true;
290}
291
292
293//==============================================================================
294//==============================================================================
295#if JUCE_UNIT_TESTS
296
297struct GZIPDecompressorInputStreamTests : public UnitTest
298{
299 GZIPDecompressorInputStreamTests()
300 : UnitTest ("GZIPDecompressorInputStreamTests", UnitTestCategories::streams)
301 {}
302
303 void runTest() override
304 {
305 const MemoryBlock data ("abcdefghijklmnopqrstuvwxyz", 26);
306
308 GZIPCompressorOutputStream gzipOutputStream (mo);
309 gzipOutputStream.write (data.getData(), data.getSize());
310 gzipOutputStream.flush();
311
312 MemoryInputStream mi (mo.getData(), mo.getDataSize(), false);
313 GZIPDecompressorInputStream stream (&mi, false, GZIPDecompressorInputStream::zlibFormat, (int64) data.getSize());
314
315 beginTest ("Read");
316
317 expectEquals (stream.getPosition(), (int64) 0);
318 expectEquals (stream.getTotalLength(), (int64) data.getSize());
319 expectEquals (stream.getNumBytesRemaining(), stream.getTotalLength());
320 expect (! stream.isExhausted());
321
322 size_t numBytesRead = 0;
323 MemoryBlock readBuffer (data.getSize());
324
325 while (numBytesRead < data.getSize())
326 {
327 numBytesRead += (size_t) stream.read (&readBuffer[numBytesRead], 3);
328
329 expectEquals (stream.getPosition(), (int64) numBytesRead);
330 expectEquals (stream.getNumBytesRemaining(), (int64) (data.getSize() - numBytesRead));
331 expect (stream.isExhausted() == (numBytesRead == data.getSize()));
332 }
333
334 expectEquals (stream.getPosition(), (int64) data.getSize());
335 expectEquals (stream.getNumBytesRemaining(), (int64) 0);
336 expect (stream.isExhausted());
337
338 expect (readBuffer == data);
339
340 beginTest ("Skip");
341
342 stream.setPosition (0);
343 expectEquals (stream.getPosition(), (int64) 0);
344 expectEquals (stream.getTotalLength(), (int64) data.getSize());
345 expectEquals (stream.getNumBytesRemaining(), stream.getTotalLength());
346 expect (! stream.isExhausted());
347
348 numBytesRead = 0;
349 const int numBytesToSkip = 5;
350
351 while (numBytesRead < data.getSize())
352 {
353 stream.skipNextBytes (numBytesToSkip);
354 numBytesRead += numBytesToSkip;
355 numBytesRead = std::min (numBytesRead, data.getSize());
356
357 expectEquals (stream.getPosition(), (int64) numBytesRead);
358 expectEquals (stream.getNumBytesRemaining(), (int64) (data.getSize() - numBytesRead));
359 expect (stream.isExhausted() == (numBytesRead == data.getSize()));
360 }
361
362 expectEquals (stream.getPosition(), (int64) data.getSize());
363 expectEquals (stream.getNumBytesRemaining(), (int64) 0);
364 expect (stream.isExhausted());
365 }
366};
367
368static GZIPDecompressorInputStreamTests gzipDecompressorInputStreamTests;
369
370#endif
371
372} // namespace juce
#define noexcept
Definition DistrhoDefines.h:72
int64_t int64
Definition basics.h:91
Definition MemoryBlock.h:39
Definition MemoryOutputStream.h:42
Definition juce_GZIPDecompressorInputStream.cpp:94
size_t dataSize
Definition juce_GZIPDecompressorInputStream.cpp:177
zlibNamespace::z_stream stream
Definition juce_GZIPDecompressorInputStream.cpp:175
bool error
Definition juce_GZIPDecompressorInputStream.cpp:170
@ gzipDecompBufferSize
Definition juce_GZIPDecompressorInputStream.cpp:172
uint8 * data
Definition juce_GZIPDecompressorInputStream.cpp:176
static int getBitsForFormat(Format f) noexcept
Definition juce_GZIPDecompressorInputStream.cpp:157
bool needsDictionary
Definition juce_GZIPDecompressorInputStream.cpp:170
GZIPDecompressHelper(Format f)
Definition juce_GZIPDecompressorInputStream.cpp:96
int doNextBlock(uint8 *const dest, const unsigned int destSize)
Definition juce_GZIPDecompressorInputStream.cpp:118
bool streamIsValid
Definition juce_GZIPDecompressorInputStream.cpp:170
~GZIPDecompressHelper()
Definition juce_GZIPDecompressorInputStream.cpp:104
bool finished
Definition juce_GZIPDecompressorInputStream.cpp:170
bool needsInput() const noexcept
Definition juce_GZIPDecompressorInputStream.cpp:110
void setInput(uint8 *const data_, const size_t size) noexcept
Definition juce_GZIPDecompressorInputStream.cpp:112
int64 originalSourcePos
Definition juce_GZIPDecompressorInputStream.h:89
bool setPosition(int64 pos) override
Definition juce_GZIPDecompressorInputStream.cpp:275
~GZIPDecompressorInputStream() override
Definition juce_GZIPDecompressorInputStream.cpp:204
const Format format
Definition juce_GZIPDecompressorInputStream.h:86
int64 getPosition() override
Definition juce_GZIPDecompressorInputStream.cpp:270
const int64 uncompressedStreamLength
Definition juce_GZIPDecompressorInputStream.h:85
int64 getTotalLength() override
Definition juce_GZIPDecompressorInputStream.cpp:208
Format
Definition juce_GZIPDecompressorInputStream.h:42
@ zlibFormat
Definition juce_GZIPDecompressorInputStream.h:43
@ gzipFormat
Definition juce_GZIPDecompressorInputStream.h:45
@ deflateFormat
Definition juce_GZIPDecompressorInputStream.h:44
bool isExhausted() override
Definition juce_GZIPDecompressorInputStream.cpp:265
OptionalScopedPointer< InputStream > sourceStream
Definition juce_GZIPDecompressorInputStream.h:84
int read(void *destBuffer, int maxBytesToRead) override
Definition juce_GZIPDecompressorInputStream.cpp:213
HeapBlock< uint8 > buffer
Definition juce_GZIPDecompressorInputStream.h:90
GZIPDecompressorInputStream(InputStream *sourceStream, bool deleteSourceWhenDestroyed, Format sourceFormat=zlibFormat, int64 uncompressedStreamLength=-1)
Definition juce_GZIPDecompressorInputStream.cpp:183
std::unique_ptr< GZIPDecompressHelper > helper
Definition juce_GZIPDecompressorInputStream.h:93
int64 currentPos
Definition juce_GZIPDecompressorInputStream.h:89
bool isEof
Definition juce_GZIPDecompressorInputStream.h:87
int activeBufferSize
Definition juce_GZIPDecompressorInputStream.h:88
InputStream()=default
virtual void skipNextBytes(int64 numBytesToSkip)
Definition juce_InputStream.cpp:237
Definition juce_UnitTest.h:70
unsigned d
Definition inflate.c:940
unsigned f
Definition inflate.c:1572
JSAMPIMAGE data
Definition jpeglib.h:945
#define JUCE_BEGIN_IGNORE_WARNINGS_GCC_LIKE(...)
Definition juce_CompilerWarnings.h:181
#define JUCE_END_IGNORE_WARNINGS_GCC_LIKE
Definition juce_CompilerWarnings.h:182
#define JUCE_BEGIN_IGNORE_WARNINGS_MSVC(warnings)
Definition juce_CompilerWarnings.h:198
#define JUCE_END_IGNORE_WARNINGS_MSVC
Definition juce_CompilerWarnings.h:199
#define z_uInt
Definition juce_GZIPDecompressorInputStream.cpp:81
#define jassert(expression)
#define JUCE_DECLARE_NON_COPYABLE(className)
#define jassertfalse
#define JUCE_FALLTHROUGH
Definition juce_UnitTestCategories.h:27
Definition juce_GZIPDecompressorInputStream.cpp:29
Definition carla_juce.cpp:31
void zerostruct(Type &structure) noexcept
Definition juce_Memory.h:32
long long int64
Definition juce_MathsFunctions.h:54
unsigned char uint8
Definition juce_MathsFunctions.h:37
#define false
Definition ordinals.h:83
int n
Definition crypt.c:458
ulg size
Definition extract.c:2350
mo
Definition zipinfo.c:2287
#define const
Definition zconf.h:137
#define inflate
Definition zconf.h:29
#define MAX_WBITS
Definition zconf.h:161
#define Z_NEED_DICT
Definition zlib.h:173
#define inflateInit2(strm, windowBits)
Definition zlib.h:1339
#define Z_STREAM_END
Definition zlib.h:172
#define Z_OK
Definition zlib.h:171
#define Z_DATA_ERROR
Definition zlib.h:176
#define Z_PARTIAL_FLUSH
Definition zlib.h:164
#define Z_MEM_ERROR
Definition zlib.h:177