in src/main/java/org/apache/commons/io/input/UnsynchronizedBufferedInputStream.java [287:356]
public int read(final byte[] buffer, int offset, final int length) throws IOException {
// Use local ref since buf may be invalidated by an unsynchronized
// close()
byte[] localBuf = buffer;
if (localBuf == null) {
throw new IOException("Stream is closed");
}
// avoid int overflow
if (offset > buffer.length - length || offset < 0 || length < 0) {
throw new IndexOutOfBoundsException();
}
if (length == 0) {
return 0;
}
final InputStream localIn = inputStream;
if (localIn == null) {
throw new IOException("Stream is closed");
}
int required;
if (pos < count) {
/* There are bytes available in the buffer. */
final int copylength = count - pos >= length ? length : count - pos;
System.arraycopy(localBuf, pos, buffer, offset, copylength);
pos += copylength;
if (copylength == length || localIn.available() == 0) {
return copylength;
}
offset += copylength;
required = length - copylength;
} else {
required = length;
}
while (true) {
final int read;
/*
* If we're not marked and the required size is greater than the buffer, simply read the bytes directly bypassing the buffer.
*/
if (markPos == IOUtils.EOF && required >= localBuf.length) {
read = localIn.read(buffer, offset, required);
if (read == IOUtils.EOF) {
return required == length ? IOUtils.EOF : length - required;
}
} else {
if (fillBuffer(localIn, localBuf) == IOUtils.EOF) {
return required == length ? IOUtils.EOF : length - required;
}
// localBuf may have been invalidated by fillBuffer()
if (localBuf != buffer) {
localBuf = buffer;
if (localBuf == null) {
throw new IOException("Stream is closed");
}
}
read = count - pos >= required ? required : count - pos;
System.arraycopy(localBuf, pos, buffer, offset, read);
pos += read;
}
required -= read;
if (required == 0) {
return length;
}
if (localIn.available() == 0) {
return length - required;
}
offset += read;
}
}