private boolean closed;
private InputStream in;
private int openCounter;
+ private byte[] singleByteReader = new byte[1];
/** array + offset of pushed-back buffers */
private List<Entry<byte[], Integer>> backBuffers;
private long bytesRead;
/**
- * Create a new {@link BufferedInputStream2} that wraps the given
+ * Create a new {@link BufferedInputStream} that wraps the given
* {@link InputStream}.
*
* @param in
}
/**
- * Create a new {@link BufferedInputStream2} that wraps the given bytes
- * array as a data source.
+ * Create a new {@link BufferedInputStream} that wraps the given bytes array
+ * as a data source.
*
* @param in
* the array to wrap, cannot be NULL
}
/**
- * Create a new {@link BufferedInputStream2} that wraps the given bytes
- * array as a data source.
+ * Create a new {@link BufferedInputStream} that wraps the given bytes array
+ * as a data source.
*
* @param in
* the array to wrap, cannot be NULL
}
/**
- * Return this very same {@link BufferedInputStream2}, but keep a counter of
+ * Return this very same {@link BufferedInputStream}, but keep a counter of
* how many streams were open this way. When calling
- * {@link BufferedInputStream2#close()}, decrease this counter if it is not
+ * {@link BufferedInputStream#close()}, decrease this counter if it is not
* already zero instead of actually closing the stream.
* <p>
* You are now responsible for it — you <b>must</b> close it.
@Override
public int read() throws IOException {
- checkClose();
-
- preRead();
- if (eof) {
+ if (read(singleByteReader) < 0) {
return -1;
}
- return buffer[start++];
+ return singleByteReader[0];
}
@Override
}
// Read from the pushed-back buffers if any
+ if (backBuffers.isEmpty()) {
+ preRead(); // an implementation could pushback in preRead()
+ }
+
if (!backBuffers.isEmpty()) {
int read = 0;
byte[] bbBuffer = bb.getKey();
int bbOffset = bb.getValue();
int bbSize = bbBuffer.length - bbOffset;
-
+
if (bbSize > blen) {
read = blen;
System.arraycopy(bbBuffer, bbOffset, b, boff, read);
* <p>
* Including the under-laying {@link InputStream}.
* <p>
- * <b>Note:</b> if you called the {@link BufferedInputStream2#open()} method
+ * <b>Note:</b> if you called the {@link BufferedInputStream#open()} method
* prior to this one, it will just decrease the internal count of how many
* open streams it held and do nothing else. The stream will actually be
- * closed when you have called {@link BufferedInputStream2#close()} once
- * more than {@link BufferedInputStream2#open()}.
+ * closed when you have called {@link BufferedInputStream#close()} once more
+ * than {@link BufferedInputStream#open()}.
*
* @exception IOException
* in case of I/O error
* You can call this method multiple times, it will not cause an
* {@link IOException} for subsequent calls.
* <p>
- * <b>Note:</b> if you called the {@link BufferedInputStream2#open()} method
+ * <b>Note:</b> if you called the {@link BufferedInputStream#open()} method
* prior to this one, it will just decrease the internal count of how many
* open streams it held and do nothing else. The stream will actually be
- * closed when you have called {@link BufferedInputStream2#close()} once
- * more than {@link BufferedInputStream2#open()}.
+ * closed when you have called {@link BufferedInputStream#close()} once more
+ * than {@link BufferedInputStream#open()}.
*
* @param includingSubStream
* also close the under-laying stream
boolean hasRead = false;
if (in != null && !eof && start >= stop) {
start = 0;
- stop = read(in, buffer, 0, buffer.length);
+ stop = read(in, buffer);
if (stop > 0) {
bytesRead += stop;
}
new AbstractMap.SimpleEntry<byte[], Integer>(buffer, offset));
}
+ /**
+ * Push back some data that will be read again at the next read call.
+ *
+ * @param buffer
+ * the buffer to push back
+ * @param offset
+ * the offset at which to start reading in the buffer
+ * @param len
+ * the length to copy
+ */
+ protected void pushback(byte[] buffer, int offset, int len) {
+ // TODO: not efficient!
+ if (buffer.length != len) {
+ byte[] lenNotSupportedYet = new byte[len];
+ System.arraycopy(buffer, offset, lenNotSupportedYet, 0, len);
+ buffer = lenNotSupportedYet;
+ offset = 0;
+ }
+
+ pushback(buffer, offset);
+ }
+
/**
* Read the under-laying stream into the given local buffer.
*
* @param in
* the under-laying {@link InputStream}
* @param buffer
- * the buffer we use in this {@link BufferedInputStream2}
- * @param off
- * the offset
- * @param len
- * the length in bytes
+ * the buffer we use in this {@link BufferedInputStream}
*
* @return the number of bytes read
*
* @throws IOException
* in case of I/O error
*/
- protected int read(InputStream in, byte[] buffer, int off, int len)
- throws IOException {
- return in.read(buffer, off, len);
+ protected int read(InputStream in, byte[] buffer) throws IOException {
+ return in.read(buffer, 0, buffer.length);
}
/**