public class InputStreamBuffer extends 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(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.
|
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.
|
String |
toDebugString() |
String |
toString()
Returns a string representation of the object.
|
public InputStreamBuffer(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 IllegalStateException, 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.IllegalStateException
IndexOutOfBoundsException
public boolean has(int index) throws IllegalStateException, 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.IllegalStateException
IndexOutOfBoundsException
public void advanceTo(int index) throws IllegalStateException, IndexOutOfBoundsException
public String toString()
Object
toString
method returns a string that
"textually represents" this object. The result should
be a concise but informative representation that is easy for a
person to read.
It is recommended that all subclasses override this method.
The toString
method for class Object
returns a string consisting of the name of the class of which the
object is an instance, the at-sign character `@
', and
the unsigned hexadecimal representation of the hash code of the
object. In other words, this method returns a string equal to the
value of:
getClass().getName() + '@' + Integer.toHexString(hashCode())
public String toDebugString()