X-Git-Url: http://git.nikiroo.be/?a=blobdiff_plain;f=src%2Fbe%2Fnikiroo%2Futils%2Fstreams%2FBufferedInputStream.java;h=683fa55865aff5ee4b6d442638721372c99e0e02;hb=5584adbbbf5444c0039fed2b35dc7d5bb57b71b1;hp=7c20f634824841c8c7dd5d60fe94456dce1c78da;hpb=8e76f6ab13a8a4a651f2518b6c91d5e6424c7922;p=nikiroo-utils.git diff --git a/src/be/nikiroo/utils/streams/BufferedInputStream.java b/src/be/nikiroo/utils/streams/BufferedInputStream.java index 7c20f63..683fa55 100644 --- a/src/be/nikiroo/utils/streams/BufferedInputStream.java +++ b/src/be/nikiroo/utils/streams/BufferedInputStream.java @@ -4,6 +4,8 @@ import java.io.IOException; import java.io.InputStream; import java.util.Arrays; +import be.nikiroo.utils.StringUtils; + /** * A simple {@link InputStream} that is buffered with a bytes array. *

@@ -14,13 +16,22 @@ import java.util.Arrays; * @author niki */ public class BufferedInputStream extends InputStream { + /** + * The size of the internal buffer (can be different if you pass your own + * buffer, of course). + *

+ * A second buffer of twice the size can sometimes be created as needed for + * the {@link BufferedInputStream#startsWith(byte[])} search operation. + */ + static private final int BUFFER_SIZE = 4096; + /** The current position in the buffer. */ protected int start; /** The index of the last usable position of the buffer. */ protected int stop; /** The buffer itself. */ protected byte[] buffer; - /** An End-Of-File (or buffer, here) marker. */ + /** An End-Of-File (or {@link InputStream}, here) marker. */ protected boolean eof; private boolean closed; @@ -45,7 +56,7 @@ public class BufferedInputStream extends InputStream { public BufferedInputStream(InputStream in) { this.in = in; - this.buffer = new byte[4096]; + this.buffer = new byte[BUFFER_SIZE]; this.originalBuffer = this.buffer; this.start = 0; this.stop = 0; @@ -94,6 +105,15 @@ public class BufferedInputStream extends InputStream { this.stop = length; } + /** + * The internal buffer size (can be useful to know for search methods). + * + * @return the size of the internal buffer, in bytes. + */ + public int getInternalBufferSize() { + return originalBuffer.length; + } + /** * Return this very same {@link BufferedInputStream}, but keep a counter of * how many streams were open this way. When calling @@ -116,6 +136,50 @@ public class BufferedInputStream extends InputStream { return this; } + /** + * Check if the current content (until eof) is equal to the given search + * term. + *

+ * Note: the search term size must be smaller or equal the internal + * buffer size. + * + * @param search + * the term to search for + * + * @return TRUE if the content that will be read starts with it + * + * @throws IOException + * in case of I/O error or if the size of the search term is + * greater than the internal buffer + */ + public boolean is(String search) throws IOException { + return is(StringUtils.getBytes(search)); + } + + /** + * Check if the current content (until eof) is equal to the given search + * term. + *

+ * Note: the search term size must be smaller or equal the internal + * buffer size. + * + * @param search + * the term to search for + * + * @return TRUE if the content that will be read starts with it + * + * @throws IOException + * in case of I/O error or if the size of the search term is + * greater than the internal buffer + */ + public boolean is(byte[] search) throws IOException { + if (startsWith(search)) { + return (stop - start) == search.length; + } + + return false; + } + /** * Check if the current content (what will be read next) starts with the * given search term. @@ -132,14 +196,17 @@ public class BufferedInputStream extends InputStream { * in case of I/O error or if the size of the search term is * greater than the internal buffer */ - public boolean startsWiths(String search) throws IOException { - return startsWith(search.getBytes("UTF-8")); + public boolean startsWith(String search) throws IOException { + return startsWith(StringUtils.getBytes(search)); } /** * Check if the current content (what will be read next) starts with the * given search term. *

+ * An empty string will always return true (unless the stream is closed, + * which would throw an {@link IOException}). + *

* Note: the search term size must be smaller or equal the internal * buffer size. * @@ -167,14 +234,14 @@ public class BufferedInputStream extends InputStream { if (available() >= search.length) { // Easy path - return startsWith(search, buffer, start, stop); - } else if (!eof) { + return StreamUtils.startsWith(search, buffer, start, stop); + } else if (in != null && !eof) { // Harder path if (buffer2 == null && buffer.length == originalBuffer.length) { buffer2 = Arrays.copyOf(buffer, buffer.length * 2); pos2 = buffer.length; - len2 = in.read(buffer2, pos2, buffer.length); + len2 = read(in, buffer2, pos2, buffer.length); if (len2 > 0) { bytesRead += len2; } @@ -183,7 +250,7 @@ public class BufferedInputStream extends InputStream { len2 += pos2; } - return startsWith(search, buffer2, pos2, len2); + return StreamUtils.startsWith(search, buffer2, pos2, len2); } return false; @@ -199,13 +266,39 @@ public class BufferedInputStream extends InputStream { } /** - * Check if this stream is totally spent (no more data to read or to + * Check if this stream is spent (no more data to read or to * process). * * @return TRUE if it is + * + * @throws IOException + * in case of I/O error + */ + public boolean eof() throws IOException { + if (closed) { + return true; + } + + preRead(); + return !hasMoreData(); + } + + /** + * Read the whole {@link InputStream} until the end and return the number of + * bytes read. + * + * @return the number of bytes read + * + * @throws IOException + * in case of I/O error */ - public boolean eof() { - return closed || (stop < 0 && !hasMoreData()); + public long end() throws IOException { + long skipped = 0; + while (hasMoreData()) { + skipped += skip(buffer.length); + } + + return skipped; } @Override @@ -241,7 +334,7 @@ public class BufferedInputStream extends InputStream { while (hasMoreData() && done < blen) { preRead(); if (hasMoreData()) { - int now = Math.min(blen, stop) - start; + int now = Math.min(blen - done, stop - start); if (now > 0) { System.arraycopy(buffer, start, b, boff + done, now); start += now; @@ -348,7 +441,7 @@ public class BufferedInputStream extends InputStream { */ protected boolean preRead() throws IOException { boolean hasRead = false; - if (!eof && in != null && start >= stop) { + if (in != null && !eof && start >= stop) { start = 0; if (buffer2 != null) { buffer = buffer2; @@ -361,7 +454,7 @@ public class BufferedInputStream extends InputStream { } else { buffer = originalBuffer; - stop = read(in, buffer); + stop = read(in, buffer, 0, buffer.length); if (stop > 0) { bytesRead += stop; } @@ -384,23 +477,33 @@ public class BufferedInputStream extends InputStream { * the under-laying {@link InputStream} * @param buffer * the buffer we use in this {@link BufferedInputStream} + * @param off + * the offset + * @param len + * the length in bytes * * @return the number of bytes read * * @throws IOException * in case of I/O error */ - protected int read(InputStream in, byte[] buffer) throws IOException { - return in.read(buffer); + protected int read(InputStream in, byte[] buffer, int off, int len) + throws IOException { + return in.read(buffer, off, len); } /** - * We have more data available in the buffer or we can fetch more. + * We have more data available in the buffer or we can, maybe, fetch + * more. * * @return TRUE if it is the case, FALSE if not */ protected boolean hasMoreData() { - return !closed && !(eof && start >= stop); + if (closed) { + return false; + } + + return (start < stop) || !eof; } /** @@ -416,46 +519,4 @@ public class BufferedInputStream extends InputStream { "This BufferedInputStream was closed, you cannot use it anymore."); } } - - /** - * Check if the buffer starts with the given search term (given as an array, - * a start position and a end position). - *

- * Note: the parameter len is the index of the last - * position, not the length. - *

- * Note: the search term size must be smaller or equal the internal - * buffer size. - * - * @param search - * the term to search for - * @param buffer - * the buffer to look into - * @param offset - * the offset at which to start the search - * @param len - * the maximum index of the data to check (this is not a - * length, but an index) - * - * @return TRUE if the search content is present at the given location and - * does not exceed the len index - */ - static protected boolean startsWith(byte[] search, byte[] buffer, - int offset, int len) { - - // Check if there even is enough space for it - if (search.length > (len - offset)) { - return false; - } - - boolean same = true; - for (int i = 0; i < search.length; i++) { - if (search[i] != buffer[offset + i]) { - same = false; - break; - } - } - - return same; - } }