From e9691fb437387b11ca7f864ba0ffa79943fa5d52 Mon Sep 17 00:00:00 2001 From: jules Date: Thu, 5 Jun 2008 14:37:23 +0000 Subject: [PATCH] --- .../audio/devices/juce_AudioDeviceManager.cpp | 24 +- .../audio/devices/juce_AudioDeviceManager.h | 1 + .../processors/juce_AudioProcessorGraph.cpp | 16 +- .../gui/components/controls/juce_ComboBox.cpp | 8 +- .../gui/components/controls/juce_Slider.cpp | 6 - .../filebrowser/juce_FileListComponent.cpp | 3 +- .../filebrowser/juce_FileTreeComponent.cpp | 3 +- .../gui/components/layout/juce_ScrollBar.cpp | 6 - .../lookandfeel/juce_LookAndFeel.cpp | 14 +- .../components/lookandfeel/juce_LookAndFeel.h | 5 +- .../components/windows/juce_SplashScreen.cpp | 3 +- .../gui/graphics/contexts/juce_EdgeTable.h | 3 +- .../juce_GZIPDecompressorInputStream.cpp | 576 +++++++++--------- 13 files changed, 338 insertions(+), 330 deletions(-) diff --git a/src/juce_appframework/audio/devices/juce_AudioDeviceManager.cpp b/src/juce_appframework/audio/devices/juce_AudioDeviceManager.cpp index 85379b2c9f..b608bebe0c 100644 --- a/src/juce_appframework/audio/devices/juce_AudioDeviceManager.cpp +++ b/src/juce_appframework/audio/devices/juce_AudioDeviceManager.cpp @@ -96,14 +96,14 @@ const String AudioDeviceManager::initialise (const int numInputChannelsNeeded, e->hasAttribute (T("audioDeviceOutChans")) ? &outs : 0, true)); - StringArray enabledMidiIns; + midiInsFromXml.clear(); forEachXmlChildElementWithTagName (*e, c, T("MIDIINPUT")) - enabledMidiIns.add (c->getStringAttribute (T("name"))); + midiInsFromXml.add (c->getStringAttribute (T("name"))); const StringArray allMidiIns (MidiInput::getDevices()); for (int i = allMidiIns.size(); --i >= 0;) - setMidiInputEnabled (allMidiIns[i], enabledMidiIns.contains (allMidiIns[i])); + setMidiInputEnabled (allMidiIns[i], midiInsFromXml.contains (allMidiIns[i])); if (error.isNotEmpty() && selectDefaultDeviceOnFailure) error = initialise (numInputChannelsNeeded, numOutputChannelsNeeded, 0, @@ -450,6 +450,24 @@ void AudioDeviceManager::updateXml() lastExplicitSettings->addChildElement (m); } + if (midiInsFromXml.size() > 0) + { + // Add any midi devices that have been enabled before, but which aren't currently + // open because the device has been disconnected. + const StringArray availableMidiDevices (MidiInput::getDevices()); + + for (int i = 0; i < midiInsFromXml.size(); ++i) + { + if (! availableMidiDevices.contains (midiInsFromXml[i], true)) + { + XmlElement* const m = new XmlElement (T("MIDIINPUT")); + m->setAttribute (T("name"), midiInsFromXml[i]); + + lastExplicitSettings->addChildElement (m); + } + } + } + if (defaultMidiOutputName.isNotEmpty()) lastExplicitSettings->setAttribute (T("defaultMidiOutput"), defaultMidiOutputName); } diff --git a/src/juce_appframework/audio/devices/juce_AudioDeviceManager.h b/src/juce_appframework/audio/devices/juce_AudioDeviceManager.h index 5b7ca03263..a5700f3458 100644 --- a/src/juce_appframework/audio/devices/juce_AudioDeviceManager.h +++ b/src/juce_appframework/audio/devices/juce_AudioDeviceManager.h @@ -371,6 +371,7 @@ private: mutable bool listNeedsScanning; bool useInputNames; + StringArray midiInsFromXml; OwnedArray enabledMidiInputs; Array midiCallbacks; Array midiCallbackDevices; diff --git a/src/juce_appframework/audio/processors/juce_AudioProcessorGraph.cpp b/src/juce_appframework/audio/processors/juce_AudioProcessorGraph.cpp index a0033a178c..e29b878939 100644 --- a/src/juce_appframework/audio/processors/juce_AudioProcessorGraph.cpp +++ b/src/juce_appframework/audio/processors/juce_AudioProcessorGraph.cpp @@ -419,16 +419,9 @@ public: ~AddChannelOp() throw() {} - void perform (AudioSampleBuffer& sharedBufferChans, - const OwnedArray & sharedMidiBuffers, - const int numSamples) throw() + void perform (AudioSampleBuffer& sharedBufferChans, const OwnedArray &, const int numSamples) throw() { - if (dstChannelNum != AudioProcessorGraph::midiChannelIndex) - sharedBufferChans.addFrom (dstChannelNum, 0, sharedBufferChans, srcChannelNum, 0, numSamples); - else - sharedMidiBuffers.getUnchecked (dstChannelNum) - ->addEvents (*sharedMidiBuffers.getUnchecked (srcChannelNum), - 0, numSamples, 0); + sharedBufferChans.addFrom (dstChannelNum, 0, sharedBufferChans, srcChannelNum, 0, numSamples); } private: @@ -719,9 +712,8 @@ private: { const int srcIndex = getBufferContaining (sourceNodes.getUnchecked(j), sourceOutputChans.getUnchecked(j)); - jassert (srcIndex >= 0); - - renderingOps.add (new AddChannelOp (srcIndex, bufIndex)); + if (srcIndex >= 0) + renderingOps.add (new AddChannelOp (srcIndex, bufIndex)); } } } diff --git a/src/juce_appframework/gui/components/controls/juce_ComboBox.cpp b/src/juce_appframework/gui/components/controls/juce_ComboBox.cpp index 4730864839..25f2658f17 100644 --- a/src/juce_appframework/gui/components/controls/juce_ComboBox.cpp +++ b/src/juce_appframework/gui/components/controls/juce_ComboBox.cpp @@ -429,13 +429,7 @@ void ComboBox::paint (Graphics& g) void ComboBox::resized() { if (getHeight() > 0 && getWidth() > 0) - { - label->setBounds (1, 1, - getWidth() + 3 - getHeight(), - getHeight() - 2); - - label->setFont (getLookAndFeel().getComboBoxFont (*this)); - } + getLookAndFeel().positionComboBoxText (*this, *label); } void ComboBox::enablementChanged() diff --git a/src/juce_appframework/gui/components/controls/juce_Slider.cpp b/src/juce_appframework/gui/components/controls/juce_Slider.cpp index 6e69718ddd..8378d620e3 100644 --- a/src/juce_appframework/gui/components/controls/juce_Slider.cpp +++ b/src/juce_appframework/gui/components/controls/juce_Slider.cpp @@ -1304,12 +1304,6 @@ void Slider::mouseDrag (const MouseEvent& e) mouseXWhenLastDragged = e.x; mouseYWhenLastDragged = e.y; - - // (repainting synchronously makes the sliders feel a bit snappier..) - ComponentPeer* const peer = getPeer(); - - if (peer != 0) - peer->performAnyPendingRepaintsNow(); } } diff --git a/src/juce_appframework/gui/components/filebrowser/juce_FileListComponent.cpp b/src/juce_appframework/gui/components/filebrowser/juce_FileListComponent.cpp index 830014c070..674b535034 100644 --- a/src/juce_appframework/gui/components/filebrowser/juce_FileListComponent.cpp +++ b/src/juce_appframework/gui/components/filebrowser/juce_FileListComponent.cpp @@ -101,7 +101,8 @@ public: file.getFileName(), icon, fileSize, modTime, - isDirectory, highlighted); + isDirectory, highlighted, + index); } void mouseDown (const MouseEvent& e) diff --git a/src/juce_appframework/gui/components/filebrowser/juce_FileTreeComponent.cpp b/src/juce_appframework/gui/components/filebrowser/juce_FileTreeComponent.cpp index 51cb72d860..774284d626 100644 --- a/src/juce_appframework/gui/components/filebrowser/juce_FileTreeComponent.cpp +++ b/src/juce_appframework/gui/components/filebrowser/juce_FileTreeComponent.cpp @@ -160,7 +160,8 @@ public: file.getFileName(), icon, fileSize, modTime, - isDirectory, isSelected()); + isDirectory, isSelected(), + indexInContentsList); } void itemClicked (const MouseEvent& e) diff --git a/src/juce_appframework/gui/components/layout/juce_ScrollBar.cpp b/src/juce_appframework/gui/components/layout/juce_ScrollBar.cpp index 2bbf7b2039..701c11ab25 100644 --- a/src/juce_appframework/gui/components/layout/juce_ScrollBar.cpp +++ b/src/juce_appframework/gui/components/layout/juce_ScrollBar.cpp @@ -394,12 +394,6 @@ void ScrollBar::mouseDrag (const MouseEvent& e) setCurrentRangeStart (dragStartRange + deltaPixels * ((maximum - minimum) - rangeSize) / (thumbAreaSize - thumbSize)); - - // (repainting synchronously makes it feel a bit snappier..) - ComponentPeer* const peer = getPeer(); - - if (peer != 0) - peer->performAnyPendingRepaintsNow(); } else { diff --git a/src/juce_appframework/gui/components/lookandfeel/juce_LookAndFeel.cpp b/src/juce_appframework/gui/components/lookandfeel/juce_LookAndFeel.cpp index 0741ed1c78..68e5e0ae31 100644 --- a/src/juce_appframework/gui/components/lookandfeel/juce_LookAndFeel.cpp +++ b/src/juce_appframework/gui/components/lookandfeel/juce_LookAndFeel.cpp @@ -537,7 +537,7 @@ void LookAndFeel::drawProgressBar (Graphics& g, ProgressBar& progressBar, Path p; - for (float x = (float) (stripeWidth - position); x < width + stripeWidth; x += stripeWidth) + for (float x = (float) (-stripeWidth - position); x < width + stripeWidth; x += stripeWidth) p.addQuadrilateral (x, 0.0f, x + stripeWidth * 0.5f, 0.0f, x, (float) height, @@ -1178,6 +1178,15 @@ Label* LookAndFeel::createComboBoxTextBox (ComboBox&) return new Label (String::empty, String::empty); } +void LookAndFeel::positionComboBoxText (ComboBox& box, Label& label) +{ + label.setBounds (1, 1, + box.getWidth() + 3 - box.getHeight(), + box.getHeight() - 2); + + label.setFont (getComboBoxFont (box)); +} + //============================================================================== void LookAndFeel::drawLinearSliderBackground (Graphics& g, int x, int y, @@ -2346,7 +2355,8 @@ void LookAndFeel::drawFileBrowserRow (Graphics& g, int width, int height, const String& fileSizeDescription, const String& fileTimeDescription, const bool isDirectory, - const bool isItemSelected) + const bool isItemSelected, + const int /*itemIndex*/) { if (isItemSelected) g.fillAll (findColour (DirectoryContentsDisplayComponent::highlightColourId)); diff --git a/src/juce_appframework/gui/components/lookandfeel/juce_LookAndFeel.h b/src/juce_appframework/gui/components/lookandfeel/juce_LookAndFeel.h index 003a4ff1eb..b2c5ad9fe1 100644 --- a/src/juce_appframework/gui/components/lookandfeel/juce_LookAndFeel.h +++ b/src/juce_appframework/gui/components/lookandfeel/juce_LookAndFeel.h @@ -266,7 +266,8 @@ public: const String& fileSizeDescription, const String& fileTimeDescription, const bool isDirectory, - const bool isItemSelected); + const bool isItemSelected, + const int itemIndex); virtual Button* createFileBrowserGoUpButton(); @@ -343,6 +344,8 @@ public: virtual Label* createComboBoxTextBox (ComboBox& box); + virtual void positionComboBoxText (ComboBox& box, Label& labelToPosition); + //============================================================================== virtual void drawLinearSlider (Graphics& g, int x, int y, diff --git a/src/juce_appframework/gui/components/windows/juce_SplashScreen.cpp b/src/juce_appframework/gui/components/windows/juce_SplashScreen.cpp index 750c001a42..dddee37a14 100644 --- a/src/juce_appframework/gui/components/windows/juce_SplashScreen.cpp +++ b/src/juce_appframework/gui/components/windows/juce_SplashScreen.cpp @@ -93,8 +93,7 @@ void SplashScreen::show (const String& title, setVisible (true); centreWithSize (width, height); - addToDesktop (useDropShadow ? (ComponentPeer::windowAppearsOnTaskbar | ComponentPeer::windowHasDropShadow) - : ComponentPeer::windowAppearsOnTaskbar); + addToDesktop (useDropShadow ? ComponentPeer::windowHasDropShadow : 0); toFront (false); MessageManager::getInstance()->dispatchPendingMessages(); diff --git a/src/juce_appframework/gui/graphics/contexts/juce_EdgeTable.h b/src/juce_appframework/gui/graphics/contexts/juce_EdgeTable.h index 75e4943a00..f6510cb185 100644 --- a/src/juce_appframework/gui/graphics/contexts/juce_EdgeTable.h +++ b/src/juce_appframework/gui/graphics/contexts/juce_EdgeTable.h @@ -58,7 +58,8 @@ public: { Oversampling_none = 0, /**< No vertical anti-aliasing at all. */ Oversampling_4times = 2, /**< Anti-aliased with 4 levels of grey - good enough for normal use. */ - Oversampling_16times = 4, /**< Anti-aliased with 16 levels of grey - very good quality but slower. */ + Oversampling_16times = 4, /**< Anti-aliased with 16 levels of grey - very good quality. */ + Oversampling_32times = 5, /**< Anti-aliased with 32 levels of grey - very good quality but slower. */ Oversampling_256times = 8 /**< Anti-aliased with 256 levels of grey - best quality, but too slow for normal user-interface use. */ }; diff --git a/src/juce_core/io/streams/juce_GZIPDecompressorInputStream.cpp b/src/juce_core/io/streams/juce_GZIPDecompressorInputStream.cpp index 58d6d3d39f..10261bcdae 100644 --- a/src/juce_core/io/streams/juce_GZIPDecompressorInputStream.cpp +++ b/src/juce_core/io/streams/juce_GZIPDecompressorInputStream.cpp @@ -1,297 +1,297 @@ -/* - ============================================================================== - - This file is part of the JUCE library - "Jules' Utility Class Extensions" - Copyright 2004-7 by Raw Material Software ltd. - - ------------------------------------------------------------------------------ - - JUCE can be redistributed and/or modified under the terms of the - GNU General Public License, as published by the Free Software Foundation; - either version 2 of the License, or (at your option) any later version. - - 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. - - You should have received a copy of the GNU General Public License - along with JUCE; if not, visit www.gnu.org/licenses or write to the - Free Software Foundation, Inc., 59 Temple Place, Suite 330, - Boston, MA 02111-1307 USA - - ------------------------------------------------------------------------------ - - If you'd like to release a closed-source product which uses JUCE, commercial - licenses are also available: visit www.rawmaterialsoftware.com/juce for - more information. - - ============================================================================== -*/ - -#include "../../basics/juce_StandardHeader.h" - +/* + ============================================================================== + + This file is part of the JUCE library - "Jules' Utility Class Extensions" + Copyright 2004-7 by Raw Material Software ltd. + + ------------------------------------------------------------------------------ + + JUCE can be redistributed and/or modified under the terms of the + GNU General Public License, as published by the Free Software Foundation; + either version 2 of the License, or (at your option) any later version. + + 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. + + You should have received a copy of the GNU General Public License + along with JUCE; if not, visit www.gnu.org/licenses or write to the + Free Software Foundation, Inc., 59 Temple Place, Suite 330, + Boston, MA 02111-1307 USA + + ------------------------------------------------------------------------------ + + If you'd like to release a closed-source product which uses JUCE, commercial + licenses are also available: visit www.rawmaterialsoftware.com/juce for + more information. + + ============================================================================== +*/ + +#include "../../basics/juce_StandardHeader.h" + #if JUCE_MSVC #pragma warning (push) #pragma warning (disable: 4309 4305) #endif -namespace zlibNamespace -{ - 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/infback.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/uncompr.c" - #include "zlib/zutil.c" - } -} +namespace zlibNamespace +{ + 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/infback.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/uncompr.c" + #include "zlib/zutil.c" + } +} #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 -{ -private: - z_stream* stream; - uint8* data; - int dataSize; - -public: - bool finished, needsDictionary, error; - - GZIPDecompressHelper (const bool noWrap) throw() - : data (0), - dataSize (0), - finished (false), - needsDictionary (false), - error (false) - { - stream = (z_stream*) juce_calloc (sizeof (z_stream)); - - if (inflateInit2 (stream, (noWrap) ? -MAX_WBITS - : MAX_WBITS) != Z_OK) - { - juce_free (stream); - stream = 0; - error = true; - finished = true; - } - } - - ~GZIPDecompressHelper() throw() - { - if (stream != 0) - { - inflateEnd (stream); - juce_free (stream); - } - } - - bool needsInput() const throw() { return dataSize <= 0; } - int getTotalOut() const throw() { return (stream != 0) ? stream->total_out : 0; } - - void setInput (uint8* const data_, const int size) throw() - { - data = data_; - dataSize = size; - } - - int doNextBlock (uint8* const dest, const int destSize) throw() - { - if (stream != 0 && 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; - } -}; - -//============================================================================== -const int gzipDecompBufferSize = 32768; - -GZIPDecompressorInputStream::GZIPDecompressorInputStream (InputStream* const sourceStream_, - const bool deleteSourceWhenDestroyed_, - const bool noWrap_, - const int64 uncompressedStreamLength_) - : sourceStream (sourceStream_), - uncompressedStreamLength (uncompressedStreamLength_), - deleteSourceWhenDestroyed (deleteSourceWhenDestroyed_), - noWrap (noWrap_), - isEof (false), - activeBufferSize (0), - originalSourcePos (sourceStream_->getPosition()) -{ - buffer = (uint8*) juce_malloc (gzipDecompBufferSize); - helper = new GZIPDecompressHelper (noWrap_); -} - -GZIPDecompressorInputStream::~GZIPDecompressorInputStream() -{ - juce_free (buffer); - - if (deleteSourceWhenDestroyed) - delete sourceStream; - - GZIPDecompressHelper* const h = (GZIPDecompressHelper*) helper; - delete h; -} - -int64 GZIPDecompressorInputStream::getTotalLength() -{ - return uncompressedStreamLength; -} - -int GZIPDecompressorInputStream::read (void* destBuffer, int howMany) -{ - GZIPDecompressHelper* const h = (GZIPDecompressHelper*) helper; - - if ((howMany > 0) && ! isEof) - { - jassert (destBuffer != 0); - - if (destBuffer != 0) - { - int numRead = 0; - uint8* d = (uint8*) destBuffer; - - while (! h->error) - { - const int n = h->doNextBlock (d, howMany); - - if (n == 0) - { - if (h->finished || h->needsDictionary) - { - isEof = true; - return numRead; - } - - if (h->needsInput()) - { - activeBufferSize = sourceStream->read (buffer, gzipDecompBufferSize); - - if (activeBufferSize > 0) - { - h->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() -{ - const GZIPDecompressHelper* const h = (GZIPDecompressHelper*) helper; - - return h->error || isEof; -} - -int64 GZIPDecompressorInputStream::getPosition() -{ - const GZIPDecompressHelper* const h = (GZIPDecompressHelper*) helper; - - return h->getTotalOut() + activeBufferSize; -} - -bool GZIPDecompressorInputStream::setPosition (int64 newPos) -{ - const int64 currentPos = getPosition(); - - if (newPos != currentPos) - { - // reset the stream and start again.. - GZIPDecompressHelper* const h = (GZIPDecompressHelper*) helper; - delete h; - - isEof = false; - activeBufferSize = 0; - helper = new GZIPDecompressHelper (noWrap); - - sourceStream->setPosition (originalSourcePos); - skipNextBytes (newPos); - } - - return true; -} - -END_JUCE_NAMESPACE + +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 +{ +private: + z_stream* stream; + uint8* data; + int dataSize; + +public: + bool finished, needsDictionary, error; + + GZIPDecompressHelper (const bool noWrap) throw() + : data (0), + dataSize (0), + finished (false), + needsDictionary (false), + error (false) + { + stream = (z_stream*) juce_calloc (sizeof (z_stream)); + + if (inflateInit2 (stream, (noWrap) ? -MAX_WBITS + : MAX_WBITS) != Z_OK) + { + juce_free (stream); + stream = 0; + error = true; + finished = true; + } + } + + ~GZIPDecompressHelper() throw() + { + if (stream != 0) + { + inflateEnd (stream); + juce_free (stream); + } + } + + bool needsInput() const throw() { return dataSize <= 0; } + int getTotalOut() const throw() { return (stream != 0) ? stream->total_out : 0; } + + void setInput (uint8* const data_, const int size) throw() + { + data = data_; + dataSize = size; + } + + int doNextBlock (uint8* const dest, const int destSize) throw() + { + if (stream != 0 && 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; + } +}; + +//============================================================================== +const int gzipDecompBufferSize = 32768; + +GZIPDecompressorInputStream::GZIPDecompressorInputStream (InputStream* const sourceStream_, + const bool deleteSourceWhenDestroyed_, + const bool noWrap_, + const int64 uncompressedStreamLength_) + : sourceStream (sourceStream_), + uncompressedStreamLength (uncompressedStreamLength_), + deleteSourceWhenDestroyed (deleteSourceWhenDestroyed_), + noWrap (noWrap_), + isEof (false), + activeBufferSize (0), + originalSourcePos (sourceStream_->getPosition()) +{ + buffer = (uint8*) juce_malloc (gzipDecompBufferSize); + helper = new GZIPDecompressHelper (noWrap_); +} + +GZIPDecompressorInputStream::~GZIPDecompressorInputStream() +{ + juce_free (buffer); + + if (deleteSourceWhenDestroyed) + delete sourceStream; + + GZIPDecompressHelper* const h = (GZIPDecompressHelper*) helper; + delete h; +} + +int64 GZIPDecompressorInputStream::getTotalLength() +{ + return uncompressedStreamLength; +} + +int GZIPDecompressorInputStream::read (void* destBuffer, int howMany) +{ + GZIPDecompressHelper* const h = (GZIPDecompressHelper*) helper; + + if ((howMany > 0) && ! isEof) + { + jassert (destBuffer != 0); + + if (destBuffer != 0) + { + int numRead = 0; + uint8* d = (uint8*) destBuffer; + + while (! h->error) + { + const int n = h->doNextBlock (d, howMany); + + if (n == 0) + { + if (h->finished || h->needsDictionary) + { + isEof = true; + return numRead; + } + + if (h->needsInput()) + { + activeBufferSize = sourceStream->read (buffer, gzipDecompBufferSize); + + if (activeBufferSize > 0) + { + h->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() +{ + const GZIPDecompressHelper* const h = (GZIPDecompressHelper*) helper; + + return h->error || isEof; +} + +int64 GZIPDecompressorInputStream::getPosition() +{ + const GZIPDecompressHelper* const h = (GZIPDecompressHelper*) helper; + + return h->getTotalOut() + activeBufferSize; +} + +bool GZIPDecompressorInputStream::setPosition (int64 newPos) +{ + const int64 currentPos = getPosition(); + + if (newPos != currentPos) + { + // reset the stream and start again.. + GZIPDecompressHelper* const h = (GZIPDecompressHelper*) helper; + delete h; + + isEof = false; + activeBufferSize = 0; + helper = new GZIPDecompressHelper (noWrap); + + sourceStream->setPosition (originalSourcePos); + skipNextBytes (newPos); + } + + return true; +} + +END_JUCE_NAMESPACE