mirror of
https://github.com/juce-framework/JUCE.git
synced 2026-01-10 23:44:24 +00:00
Improved error handling in BufferedInputStream and tidied up a few classes in the streams folder
This commit is contained in:
parent
f4de59972a
commit
08a1b7bb6d
16 changed files with 95 additions and 112 deletions
|
|
@ -24,16 +24,13 @@ namespace juce
|
|||
{
|
||||
|
||||
DirectoryIterator::DirectoryIterator (const File& directory, bool recursive,
|
||||
const String& pattern, const int type)
|
||||
const String& pattern, int type)
|
||||
: wildCards (parseWildcards (pattern)),
|
||||
fileFinder (directory, (recursive || wildCards.size() > 1) ? "*" : pattern),
|
||||
wildCard (pattern),
|
||||
path (File::addTrailingSeparator (directory.getFullPathName())),
|
||||
index (-1),
|
||||
totalNumFiles (-1),
|
||||
whatToLookFor (type),
|
||||
isRecursive (recursive),
|
||||
hasBeenAdvanced (false)
|
||||
isRecursive (recursive)
|
||||
{
|
||||
// you have to specify the type of files you're looking for!
|
||||
jassert ((type & (File::findFiles | File::findDirectories)) != 0);
|
||||
|
|
@ -53,10 +50,10 @@ StringArray DirectoryIterator::parseWildcards (const String& pattern)
|
|||
return s;
|
||||
}
|
||||
|
||||
bool DirectoryIterator::fileMatches (const StringArray& wildCards, const String& filename)
|
||||
bool DirectoryIterator::fileMatches (const StringArray& wildcards, const String& filename)
|
||||
{
|
||||
for (int i = 0; i < wildCards.size(); ++i)
|
||||
if (filename.matchesWildcard (wildCards[i], ! File::areFileNamesCaseSensitive()))
|
||||
for (auto& w : wildcards)
|
||||
if (filename.matchesWildcard (w, ! File::areFileNamesCaseSensitive()))
|
||||
return true;
|
||||
|
||||
return false;
|
||||
|
|
@ -67,8 +64,8 @@ bool DirectoryIterator::next()
|
|||
return next (nullptr, nullptr, nullptr, nullptr, nullptr, nullptr);
|
||||
}
|
||||
|
||||
bool DirectoryIterator::next (bool* const isDirResult, bool* const isHiddenResult, int64* const fileSize,
|
||||
Time* const modTime, Time* const creationTime, bool* const isReadOnly)
|
||||
bool DirectoryIterator::next (bool* isDirResult, bool* isHiddenResult, int64* fileSize,
|
||||
Time* modTime, Time* creationTime, bool* isReadOnly)
|
||||
{
|
||||
for (;;)
|
||||
{
|
||||
|
|
@ -156,8 +153,8 @@ float DirectoryIterator::getEstimatedProgress() const
|
|||
if (totalNumFiles <= 0)
|
||||
return 0.0f;
|
||||
|
||||
const float detailedIndex = (subIterator != nullptr) ? index + subIterator->getEstimatedProgress()
|
||||
: (float) index;
|
||||
auto detailedIndex = (subIterator != nullptr) ? index + subIterator->getEstimatedProgress()
|
||||
: (float) index;
|
||||
|
||||
return jlimit (0.0f, 1.0f, detailedIndex / totalNumFiles);
|
||||
}
|
||||
|
|
|
|||
|
|
@ -140,11 +140,11 @@ private:
|
|||
StringArray wildCards;
|
||||
NativeIterator fileFinder;
|
||||
String wildCard, path;
|
||||
int index;
|
||||
mutable int totalNumFiles;
|
||||
int index = -1;
|
||||
mutable int totalNumFiles = -1;
|
||||
const int whatToLookFor;
|
||||
const bool isRecursive;
|
||||
bool hasBeenAdvanced;
|
||||
bool hasBeenAdvanced = false;
|
||||
ScopedPointer<DirectoryIterator> subIterator;
|
||||
File currentFile;
|
||||
|
||||
|
|
|
|||
|
|
@ -27,11 +27,7 @@ int64 juce_fileSetPosition (void* handle, int64 pos);
|
|||
|
||||
|
||||
//==============================================================================
|
||||
FileInputStream::FileInputStream (const File& f)
|
||||
: file (f),
|
||||
fileHandle (nullptr),
|
||||
currentPosition (0),
|
||||
status (Result::ok())
|
||||
FileInputStream::FileInputStream (const File& f) : file (f)
|
||||
{
|
||||
openHandle();
|
||||
}
|
||||
|
|
@ -53,7 +49,7 @@ int FileInputStream::read (void* buffer, int bytesToRead)
|
|||
// sign that something is broken!
|
||||
jassert (buffer != nullptr && bytesToRead >= 0);
|
||||
|
||||
const size_t num = readInternal (buffer, (size_t) bytesToRead);
|
||||
auto num = readInternal (buffer, (size_t) bytesToRead);
|
||||
currentPosition += (int64) num;
|
||||
|
||||
return (int) num;
|
||||
|
|
|
|||
|
|
@ -75,9 +75,9 @@ public:
|
|||
private:
|
||||
//==============================================================================
|
||||
const File file;
|
||||
void* fileHandle;
|
||||
int64 currentPosition;
|
||||
Result status;
|
||||
void* fileHandle = nullptr;
|
||||
int64 currentPosition = 0;
|
||||
Result status { Result::ok() };
|
||||
|
||||
void openHandle();
|
||||
size_t readInternal (void*, size_t);
|
||||
|
|
|
|||
|
|
@ -28,11 +28,7 @@ int64 juce_fileSetPosition (void* handle, int64 pos);
|
|||
//==============================================================================
|
||||
FileOutputStream::FileOutputStream (const File& f, const size_t bufferSizeToUse)
|
||||
: file (f),
|
||||
fileHandle (nullptr),
|
||||
status (Result::ok()),
|
||||
currentPosition (0),
|
||||
bufferSize (bufferSizeToUse),
|
||||
bytesInBuffer (0),
|
||||
buffer (jmax (bufferSizeToUse, (size_t) 16))
|
||||
{
|
||||
openHandle();
|
||||
|
|
@ -102,7 +98,7 @@ bool FileOutputStream::write (const void* const src, const size_t numBytes)
|
|||
}
|
||||
else
|
||||
{
|
||||
const ssize_t bytesWritten = writeInternal (src, numBytes);
|
||||
auto bytesWritten = writeInternal (src, numBytes);
|
||||
|
||||
if (bytesWritten < 0)
|
||||
return false;
|
||||
|
|
|
|||
|
|
@ -94,10 +94,10 @@ public:
|
|||
private:
|
||||
//==============================================================================
|
||||
File file;
|
||||
void* fileHandle;
|
||||
Result status;
|
||||
int64 currentPosition;
|
||||
size_t bufferSize, bytesInBuffer;
|
||||
void* fileHandle = nullptr;
|
||||
Result status { Result::ok() };
|
||||
int64 currentPosition = 0;
|
||||
size_t bufferSize, bytesInBuffer = 0;
|
||||
HeapBlock<char> buffer;
|
||||
|
||||
void openHandle();
|
||||
|
|
|
|||
|
|
@ -55,8 +55,8 @@ void FileSearchPath::init (const String& path)
|
|||
directories.trim();
|
||||
directories.removeEmptyStrings();
|
||||
|
||||
for (int i = directories.size(); --i >= 0;)
|
||||
directories.set (i, directories[i].unquoted());
|
||||
for (auto& d : directories)
|
||||
d = d.unquoted();
|
||||
}
|
||||
|
||||
int FileSearchPath::getNumPaths() const
|
||||
|
|
@ -64,37 +64,38 @@ int FileSearchPath::getNumPaths() const
|
|||
return directories.size();
|
||||
}
|
||||
|
||||
File FileSearchPath::operator[] (const int index) const
|
||||
File FileSearchPath::operator[] (int index) const
|
||||
{
|
||||
return File (directories [index]);
|
||||
return File (directories[index]);
|
||||
}
|
||||
|
||||
String FileSearchPath::toString() const
|
||||
{
|
||||
StringArray directories2 (directories);
|
||||
for (int i = directories2.size(); --i >= 0;)
|
||||
if (directories2[i].containsChar (';'))
|
||||
directories2.set (i, directories2[i].quoted());
|
||||
auto dirs = directories;
|
||||
|
||||
return directories2.joinIntoString (";");
|
||||
for (auto& d : dirs)
|
||||
if (d.containsChar (';'))
|
||||
d = d.quoted();
|
||||
|
||||
return dirs.joinIntoString (";");
|
||||
}
|
||||
|
||||
void FileSearchPath::add (const File& dir, const int insertIndex)
|
||||
void FileSearchPath::add (const File& dir, int insertIndex)
|
||||
{
|
||||
directories.insert (insertIndex, dir.getFullPathName());
|
||||
}
|
||||
|
||||
bool FileSearchPath::addIfNotAlreadyThere (const File& dir)
|
||||
{
|
||||
for (int i = 0; i < directories.size(); ++i)
|
||||
if (File (directories[i]) == dir)
|
||||
for (auto& d : directories)
|
||||
if (File (d) == dir)
|
||||
return false;
|
||||
|
||||
add (dir);
|
||||
return true;
|
||||
}
|
||||
|
||||
void FileSearchPath::remove (const int index)
|
||||
void FileSearchPath::remove (int index)
|
||||
{
|
||||
directories.remove (index);
|
||||
}
|
||||
|
|
@ -115,7 +116,7 @@ void FileSearchPath::removeRedundantPaths()
|
|||
{
|
||||
const File d2 (directories[j]);
|
||||
|
||||
if ((i != j) && (d1.isAChildOf (d2) || d1 == d2))
|
||||
if (i != j && (d1.isAChildOf (d2) || d1 == d2))
|
||||
{
|
||||
directories.remove (i);
|
||||
break;
|
||||
|
|
@ -131,18 +132,13 @@ void FileSearchPath::removeNonExistentPaths()
|
|||
directories.remove (i);
|
||||
}
|
||||
|
||||
int FileSearchPath::findChildFiles (Array<File>& results,
|
||||
const int whatToLookFor,
|
||||
const bool searchRecursively,
|
||||
const String& wildCardPattern) const
|
||||
int FileSearchPath::findChildFiles (Array<File>& results, int whatToLookFor,
|
||||
bool recurse, const String& wildcard) const
|
||||
{
|
||||
int total = 0;
|
||||
|
||||
for (int i = 0; i < directories.size(); ++i)
|
||||
total += operator[] (i).findChildFiles (results,
|
||||
whatToLookFor,
|
||||
searchRecursively,
|
||||
wildCardPattern);
|
||||
for (auto& d : directories)
|
||||
total += File (d).findChildFiles (results, whatToLookFor, recurse, wildcard);
|
||||
|
||||
return total;
|
||||
}
|
||||
|
|
@ -150,18 +146,16 @@ int FileSearchPath::findChildFiles (Array<File>& results,
|
|||
bool FileSearchPath::isFileInPath (const File& fileToCheck,
|
||||
const bool checkRecursively) const
|
||||
{
|
||||
for (int i = directories.size(); --i >= 0;)
|
||||
for (auto& d : directories)
|
||||
{
|
||||
const File d (directories[i]);
|
||||
|
||||
if (checkRecursively)
|
||||
{
|
||||
if (fileToCheck.isAChildOf (d))
|
||||
if (fileToCheck.isAChildOf (File (d)))
|
||||
return true;
|
||||
}
|
||||
else
|
||||
{
|
||||
if (fileToCheck.getParentDirectory() == d)
|
||||
if (fileToCheck.getParentDirectory() == File (d))
|
||||
return true;
|
||||
}
|
||||
}
|
||||
|
|
|
|||
|
|
@ -24,7 +24,7 @@ namespace juce
|
|||
{
|
||||
|
||||
static File createTempFile (const File& parentDirectory, String name,
|
||||
const String& suffix, const int optionFlags)
|
||||
const String& suffix, int optionFlags)
|
||||
{
|
||||
if ((optionFlags & TemporaryFile::useHiddenFile) != 0)
|
||||
name = "." + name;
|
||||
|
|
|
|||
|
|
@ -26,23 +26,22 @@ namespace juce
|
|||
static void parseWildcard (const String& pattern, StringArray& result)
|
||||
{
|
||||
result.addTokens (pattern.toLowerCase(), ";,", "\"'");
|
||||
|
||||
result.trim();
|
||||
result.removeEmptyStrings();
|
||||
|
||||
// special case for *.*, because people use it to mean "any file", but it
|
||||
// would actually ignore files with no extension.
|
||||
for (int i = result.size(); --i >= 0;)
|
||||
if (result[i] == "*.*")
|
||||
result.set (i, "*");
|
||||
for (auto& r : result)
|
||||
if (r == "*.*")
|
||||
r = "*";
|
||||
}
|
||||
|
||||
static bool matchWildcard (const File& file, const StringArray& wildcards)
|
||||
{
|
||||
const String filename (file.getFileName());
|
||||
auto filename = file.getFileName();
|
||||
|
||||
for (int i = wildcards.size(); --i >= 0;)
|
||||
if (filename.matchesWildcard (wildcards[i], true))
|
||||
for (auto& w : wildcards)
|
||||
if (filename.matchesWildcard (w, true))
|
||||
return true;
|
||||
|
||||
return false;
|
||||
|
|
|
|||
|
|
@ -59,8 +59,10 @@ BufferedInputStream::~BufferedInputStream()
|
|||
//==============================================================================
|
||||
char BufferedInputStream::peekByte()
|
||||
{
|
||||
ensureBuffered();
|
||||
return position < lastReadPos ? *(buffer + (int) (position - bufferStart)) : 0;
|
||||
if (! ensureBuffered())
|
||||
return 0;
|
||||
|
||||
return position < lastReadPos ? buffer[(int) (position - bufferStart)] : 0;
|
||||
}
|
||||
|
||||
int64 BufferedInputStream::getTotalLength()
|
||||
|
|
@ -84,7 +86,7 @@ bool BufferedInputStream::isExhausted()
|
|||
return position >= lastReadPos && source->isExhausted();
|
||||
}
|
||||
|
||||
void BufferedInputStream::ensureBuffered()
|
||||
bool BufferedInputStream::ensureBuffered()
|
||||
{
|
||||
auto bufferEndOverlap = lastReadPos - bufferOverlap;
|
||||
|
||||
|
|
@ -100,24 +102,35 @@ void BufferedInputStream::ensureBuffered()
|
|||
memmove (buffer, buffer + (int) (position - bufferStart), (size_t) bytesToKeep);
|
||||
|
||||
bufferStart = position;
|
||||
|
||||
bytesRead = source->read (buffer + bytesToKeep,
|
||||
(int) (bufferSize - bytesToKeep));
|
||||
|
||||
if (bytesRead < 0)
|
||||
return false;
|
||||
|
||||
lastReadPos += bytesRead;
|
||||
bytesRead += bytesToKeep;
|
||||
}
|
||||
else
|
||||
{
|
||||
bufferStart = position;
|
||||
source->setPosition (bufferStart);
|
||||
|
||||
if (! source->setPosition (bufferStart))
|
||||
return false;
|
||||
|
||||
bytesRead = source->read (buffer, bufferSize);
|
||||
|
||||
if (bytesRead < 0)
|
||||
return false;
|
||||
|
||||
lastReadPos = bufferStart + bytesRead;
|
||||
}
|
||||
|
||||
while (bytesRead < bufferSize)
|
||||
buffer [bytesRead++] = 0;
|
||||
buffer[bytesRead++] = 0;
|
||||
}
|
||||
|
||||
return true;
|
||||
}
|
||||
|
||||
int BufferedInputStream::read (void* destBuffer, int maxBytesToRead)
|
||||
|
|
@ -133,7 +146,8 @@ int BufferedInputStream::read (void* destBuffer, int maxBytesToRead)
|
|||
}
|
||||
|
||||
if (position < bufferStart || position >= lastReadPos)
|
||||
ensureBuffered();
|
||||
if (! ensureBuffered())
|
||||
return 0;
|
||||
|
||||
int bytesRead = 0;
|
||||
|
||||
|
|
@ -151,12 +165,10 @@ int BufferedInputStream::read (void* destBuffer, int maxBytesToRead)
|
|||
}
|
||||
|
||||
auto oldLastReadPos = lastReadPos;
|
||||
ensureBuffered();
|
||||
|
||||
if (oldLastReadPos == lastReadPos)
|
||||
break; // if ensureBuffered() failed to read any more data, bail out
|
||||
|
||||
if (isExhausted())
|
||||
if (! ensureBuffered()
|
||||
|| oldLastReadPos == lastReadPos
|
||||
|| isExhausted())
|
||||
break;
|
||||
}
|
||||
|
||||
|
|
|
|||
|
|
@ -80,7 +80,7 @@ private:
|
|||
int bufferSize;
|
||||
int64 position, lastReadPos = 0, bufferStart, bufferOverlap = 128;
|
||||
HeapBlock<char> buffer;
|
||||
void ensureBuffered();
|
||||
bool ensureBuffered();
|
||||
|
||||
JUCE_DECLARE_NON_COPYABLE_WITH_LEAK_DETECTOR (BufferedInputStream)
|
||||
};
|
||||
|
|
|
|||
|
|
@ -23,24 +23,19 @@
|
|||
namespace juce
|
||||
{
|
||||
|
||||
MemoryInputStream::MemoryInputStream (const void* const sourceData,
|
||||
const size_t sourceDataSize,
|
||||
const bool keepInternalCopy)
|
||||
MemoryInputStream::MemoryInputStream (const void* sourceData, size_t sourceDataSize, bool keepCopy)
|
||||
: data (sourceData),
|
||||
dataSize (sourceDataSize),
|
||||
position (0)
|
||||
dataSize (sourceDataSize)
|
||||
{
|
||||
if (keepInternalCopy)
|
||||
if (keepCopy)
|
||||
createInternalCopy();
|
||||
}
|
||||
|
||||
MemoryInputStream::MemoryInputStream (const MemoryBlock& sourceData,
|
||||
const bool keepInternalCopy)
|
||||
MemoryInputStream::MemoryInputStream (const MemoryBlock& sourceData, bool keepCopy)
|
||||
: data (sourceData.getData()),
|
||||
dataSize (sourceData.getSize()),
|
||||
position (0)
|
||||
dataSize (sourceData.getSize())
|
||||
{
|
||||
if (keepInternalCopy)
|
||||
if (keepCopy)
|
||||
createInternalCopy();
|
||||
}
|
||||
|
||||
|
|
@ -60,14 +55,14 @@ int64 MemoryInputStream::getTotalLength()
|
|||
return (int64) dataSize;
|
||||
}
|
||||
|
||||
int MemoryInputStream::read (void* const buffer, const int howMany)
|
||||
int MemoryInputStream::read (void* buffer, int howMany)
|
||||
{
|
||||
jassert (buffer != nullptr && howMany >= 0);
|
||||
|
||||
if (howMany <= 0 || position >= dataSize)
|
||||
return 0;
|
||||
|
||||
const size_t num = jmin ((size_t) howMany, dataSize - position);
|
||||
auto num = jmin ((size_t) howMany, dataSize - position);
|
||||
|
||||
if (num > 0)
|
||||
{
|
||||
|
|
|
|||
|
|
@ -71,7 +71,7 @@ public:
|
|||
|
||||
//==============================================================================
|
||||
int64 getPosition() override;
|
||||
bool setPosition (int64 pos) override;
|
||||
bool setPosition (int64) override;
|
||||
int64 getTotalLength() override;
|
||||
bool isExhausted() override;
|
||||
int read (void* destBuffer, int maxBytesToRead) override;
|
||||
|
|
@ -79,7 +79,7 @@ public:
|
|||
private:
|
||||
//==============================================================================
|
||||
const void* data;
|
||||
size_t dataSize, position;
|
||||
size_t dataSize, position = 0;
|
||||
HeapBlock<char> internalCopy;
|
||||
|
||||
void createInternalCopy();
|
||||
|
|
|
|||
|
|
@ -23,9 +23,9 @@
|
|||
namespace juce
|
||||
{
|
||||
|
||||
SubregionStream::SubregionStream (InputStream* const sourceStream,
|
||||
const int64 start, const int64 length,
|
||||
const bool deleteSourceWhenDestroyed)
|
||||
SubregionStream::SubregionStream (InputStream* sourceStream,
|
||||
int64 start, int64 length,
|
||||
bool deleteSourceWhenDestroyed)
|
||||
: source (sourceStream, deleteSourceWhenDestroyed),
|
||||
startPositionInSourceStream (start),
|
||||
lengthOfSourceStream (length)
|
||||
|
|
@ -39,7 +39,7 @@ SubregionStream::~SubregionStream()
|
|||
|
||||
int64 SubregionStream::getTotalLength()
|
||||
{
|
||||
const int64 srcLen = source->getTotalLength() - startPositionInSourceStream;
|
||||
auto srcLen = source->getTotalLength() - startPositionInSourceStream;
|
||||
|
||||
return lengthOfSourceStream >= 0 ? jmin (lengthOfSourceStream, srcLen)
|
||||
: srcLen;
|
||||
|
|
|
|||
|
|
@ -191,10 +191,7 @@ GZIPDecompressorInputStream::GZIPDecompressorInputStream (InputStream* source, b
|
|||
: sourceStream (source, deleteSourceWhenDestroyed),
|
||||
uncompressedStreamLength (uncompressedLength),
|
||||
format (f),
|
||||
isEof (false),
|
||||
activeBufferSize (0),
|
||||
originalSourcePos (source->getPosition()),
|
||||
currentPos (0),
|
||||
buffer ((size_t) GZIPDecompressHelper::gzipDecompBufferSize),
|
||||
helper (new GZIPDecompressHelper (f))
|
||||
{
|
||||
|
|
@ -204,10 +201,7 @@ GZIPDecompressorInputStream::GZIPDecompressorInputStream (InputStream& source)
|
|||
: sourceStream (&source, false),
|
||||
uncompressedStreamLength (-1),
|
||||
format (zlibFormat),
|
||||
isEof (false),
|
||||
activeBufferSize (0),
|
||||
originalSourcePos (source.getPosition()),
|
||||
currentPos (0),
|
||||
buffer ((size_t) GZIPDecompressHelper::gzipDecompBufferSize),
|
||||
helper (new GZIPDecompressHelper (zlibFormat))
|
||||
{
|
||||
|
|
@ -229,11 +223,11 @@ int GZIPDecompressorInputStream::read (void* destBuffer, int howMany)
|
|||
if (howMany > 0 && ! isEof)
|
||||
{
|
||||
int numRead = 0;
|
||||
uint8* d = static_cast<uint8*> (destBuffer);
|
||||
auto d = static_cast<uint8*> (destBuffer);
|
||||
|
||||
while (! helper->error)
|
||||
{
|
||||
const int n = helper->doNextBlock (d, (unsigned int) howMany);
|
||||
auto n = helper->doNextBlock (d, (unsigned int) howMany);
|
||||
currentPos += n;
|
||||
|
||||
if (n == 0)
|
||||
|
|
|
|||
|
|
@ -82,9 +82,9 @@ private:
|
|||
OptionalScopedPointer<InputStream> sourceStream;
|
||||
const int64 uncompressedStreamLength;
|
||||
const Format format;
|
||||
bool isEof;
|
||||
int activeBufferSize;
|
||||
int64 originalSourcePos, currentPos;
|
||||
bool isEof = false;
|
||||
int activeBufferSize = 0;
|
||||
int64 originalSourcePos, currentPos = 0;
|
||||
HeapBlock<uint8> buffer;
|
||||
|
||||
class GZIPDecompressHelper;
|
||||
|
|
|
|||
Loading…
Add table
Add a link
Reference in a new issue