public class InputStreamBuffer
extends java.lang.Object
InputStream that allows you to read bytes from it like a byte[]. An
internal buffer is kept as small as possible to avoid large unnecessary allocations.
Care must be taken so that the internal buffer is kept small. The best practice is to
precalculate the maximum buffer size that you will need. For example,
say you have a loop that reads bytes from index 0 to 10,
skips to index N, reads from index N to N+10, etc. Then
you know that the internal buffer can have a maximum size of 10,
and you should set the bufferSize parameter to 10 in the constructor.
Use advanceTo(int) to declare that you will not need to access lesser indexes. This
helps to keep the internal buffer small. In the above example, after reading bytes from index
0 to 10, you should call advanceTo(N) so that internal
buffer becomes filled with bytes from index N to N+10.
If you know that you are reading bytes from a strictly increasing or equal
index, then you should set the autoAdvance parameter to true in the
constructor. For complicated access patterns, or when you prefer to control the internal
buffer yourself, set autoAdvance to false. When
autoAdvance is enabled, every time an index is beyond the buffer length,
the buffer will be shifted forward such that the index requested becomes the first element in
the buffer.
All public methods with parameter index are absolute indexed. The index is from
the beginning of the wrapped input stream.| Constructor and Description |
|---|
InputStreamBuffer(java.io.InputStream inputStream,
int bufferSize,
boolean autoAdvance)
Construct a new wrapper for an InputStream.
|
| Modifier and Type | Method and Description |
|---|---|
void |
advanceTo(int index)
Attempts to advance the head of the buffer to the requested index.
|
static byte[] |
copyOf(byte[] original,
int newLength)
Arrays.copyOf(byte[] original, int newLength) not found in API <= 8.
|
byte |
get(int index)
Attempt to get byte at the requested index from the wrapped input stream.
|
boolean |
has(int index)
Attempt to return whether the requested index is within the size of the wrapped input
stream.
|
java.lang.String |
toDebugString() |
java.lang.String |
toString() |
public InputStreamBuffer(java.io.InputStream inputStream,
int bufferSize,
boolean autoAdvance)
autoAdvance is true, behavior is undefined if you call get(int)
or has(int) with an index N, then some arbitrary time later call get(int)
or has(int) with an index M < N. The wrapper may return the right value,
if the buffer happens to still contain index M, but more likely it will throw an
IllegalStateException.
If autoAdvance is false, you must be diligent and call advanceTo(int)
at the appropriate times to ensure that the internal buffer is not unnecessarily resized
and reallocated.inputStream - The input stream to wrap. The input stream will not be closed by the
wrapper.bufferSize - The initial size for the internal buffer. The buffer size should be
carefully chosen to avoid resizing and reallocating the internal buffer.
The internal buffer size used will be the least power of two greater
than this parameter.autoAdvance - Determines the behavior when you need to read an index that is beyond
the internal buffer size. If true, the internal buffer will shift so
that the requested index becomes the first element. If false,
the internal buffer size will grow to the smallest power of 2 which is
greater than the requested index.public byte get(int index)
throws java.lang.IllegalStateException,
java.lang.IndexOutOfBoundsException
fill(int) will be called first, and the byte at the index returned.
You should always call has(int) with the same index, unless you are sure that no
exceptions will be thrown as described above.
Consider calling advanceTo(int) if you know that you will never request a lesser
index in the future.index - The requested index.java.lang.IllegalStateExceptionjava.lang.IndexOutOfBoundsExceptionpublic boolean has(int index)
throws java.lang.IllegalStateException,
java.lang.IndexOutOfBoundsException
fill(int) will be called.
If this method returns true, it is guaranteed that get(int) with the same index
will not fail. That means that if the requested index is within the size of the wrapped
input stream, but the index is less than the head of the internal buffer,
a runtime exception is thrown.
See get(int) for caveats. A lot of the same warnings about exceptions and
advanceTo() apply.index - The requested index.java.lang.IllegalStateExceptionjava.lang.IndexOutOfBoundsExceptionpublic void advanceTo(int index)
throws java.lang.IllegalStateException,
java.lang.IndexOutOfBoundsException
get(int) or
has(int) call will fill the buffer.java.lang.IllegalStateExceptionjava.lang.IndexOutOfBoundsExceptionpublic static byte[] copyOf(byte[] original,
int newLength)
original - the array to be copiednewLength - the length of the copy to be returnepublic java.lang.String toString()
toString in class java.lang.Objectpublic java.lang.String toDebugString()