If the source stream for some reason fails, ensureBuffered will never exit.
BufferedInputStream.h
private:
InputStream* const source;
const bool deleteSourceWhenDestroyed;
int bufferSize;
int64 position, lastReadPos, bufferStart, bufferOverlap;
char* buffer;
bool ensureBuffered(); // Returns bool now
BufferedInputStream (const BufferedInputStream&);
const BufferedInputStream& operator= (const BufferedInputStream&);
};
BufferedInputStream::ensureBuffered() :
else
{
bufferStart = position;
source->setPosition (bufferStart);
bytesRead = source->read (buffer, bufferSize);
if (bytesRead < jmin((int64)bufferSize, source->getTotalLength() - bufferStart))
{
// We've read too little
return false;
}
lastReadPos = bufferStart + bytesRead;
}
and BufferedInputStream::read(…) :
int BufferedInputStream::read (void* destBuffer, int maxBytesToRead)
{
if (position >= bufferStart
&& position + maxBytesToRead <= lastReadPos)
{
memcpy (destBuffer, buffer + (position - bufferStart), maxBytesToRead);
position += maxBytesToRead;
return maxBytesToRead;
}
else
{
if (position < bufferStart || position >= lastReadPos)
{
if (!ensureBuffered())
{
return 0;
}
}
int bytesRead = 0;
while (maxBytesToRead > 0)
{
const int bytesAvailable = jmin (maxBytesToRead, (int) (lastReadPos - position));
if (bytesAvailable > 0)
{
memcpy (destBuffer, buffer + (position - bufferStart), bytesAvailable);
maxBytesToRead -= bytesAvailable;
bytesRead += bytesAvailable;
position += bytesAvailable;
destBuffer = (void*) (((char*) destBuffer) + bytesAvailable);
}
if (!ensureBuffered())
break;
if (isExhausted())
break;
}
return bytesRead;
}
}
which will let the application fail gracefully.