diff options
Diffstat (limited to 'src/com/google/common/io/protocol/BoundInputStream.java')
-rw-r--r-- | src/com/google/common/io/protocol/BoundInputStream.java | 91 |
1 files changed, 91 insertions, 0 deletions
diff --git a/src/com/google/common/io/protocol/BoundInputStream.java b/src/com/google/common/io/protocol/BoundInputStream.java new file mode 100644 index 00000000..dbccca75 --- /dev/null +++ b/src/com/google/common/io/protocol/BoundInputStream.java @@ -0,0 +1,91 @@ +// Copyright 2008 Google Inc. All Rights Reserved. + +package com.google.common.io.protocol; + +import java.io.*; + +/** + * An input stream backed by another input stream, where reading from the + * underlying input stream is limited to a fixed number of bytes. Also does + * some buffering. + * + */ +public class BoundInputStream extends InputStream { + + /** Buffer size */ + static final int BUF_SIZE = 4096; + + /** Number of bytes that may still be read from the underlying stream */ + private int remaining; + + /** Small buffer to avoid making OS calls for each byte read. */ + private byte[] buf; + + /** Current position in the buffer */ + private int bufPos; + + /** Filled size of the buffer */ + private int bufSize; + + /** Underlying stream to read from */ + private InputStream base; + + public BoundInputStream(InputStream base, int len) { + this.base = base; + this.remaining = len; + + buf = new byte[Math.min(len, BUF_SIZE)]; + } + + /** + * Make sure there is at least one byte in the buffer. If not possible, + * return false. + */ + private boolean checkBuf() throws IOException { + if (remaining <= 0) { + return false; + } + + if (bufPos >= bufSize) { + bufSize = base.read(buf, 0, Math.min(remaining, buf.length)); + if (bufSize <= 0) { + remaining = 0; + return false; + } + bufPos = 0; + } + return true; + } + + public int available() { + return bufSize - bufPos; + } + + public int read() throws IOException { + if (!checkBuf()) { + return -1; + } + remaining--; + return buf[bufPos++] & 255; + } + + public int read(byte[] data, int start, int count) throws IOException { + if (!checkBuf()) { + return -1; + } + count = Math.min(count, bufSize - bufPos); + System.arraycopy(buf, bufPos, data, start, count); + bufPos += count; + remaining -= count; + return count; + } + + /** + * How many bytes are remaining, based on the length provided to the + * constructor. The underlying stream may terminate earlier. Provided mainly + * for testing purposes. + */ + public int getRemaining() { + return remaining; + } +} |