code cleanup, fix for ReplaceInputStream
[nikiroo-utils.git] / src / be / nikiroo / utils / streams / BufferedInputStream.java
index 7c20f634824841c8c7dd5d60fe94456dce1c78da..42f0d9d24c123be0fad89cce35f43bb9b5831855 100644 (file)
@@ -14,13 +14,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).
+        * <p>
+        * 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 +54,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;
@@ -167,14 +176,14 @@ public class BufferedInputStream extends InputStream {
 
                if (available() >= search.length) {
                        // Easy path
-                       return startsWith(search, buffer, start, stop);
+                       return StreamUtils.startsWith(search, buffer, start, stop);
                } else if (!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 +192,7 @@ public class BufferedInputStream extends InputStream {
                                len2 += pos2;
                        }
 
-                       return startsWith(search, buffer2, pos2, len2);
+                       return StreamUtils.startsWith(search, buffer2, pos2, len2);
                }
 
                return false;
@@ -203,9 +212,17 @@ public class BufferedInputStream extends InputStream {
         * process).
         * 
         * @return TRUE if it is
+        * 
+        * @throws IOException
+        *             in case of I/O error
         */
-       public boolean eof() {
-               return closed || (stop < 0 && !hasMoreData());
+       public boolean eof() throws IOException {
+               if (closed) {
+                       return true;
+               }
+
+               preRead();
+               return !hasMoreData();
        }
 
        @Override
@@ -241,7 +258,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 +365,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 +378,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 +401,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 <b>or</b> 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 +443,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).
-        * <p>
-        * Note: the parameter <tt>len</tt> is the <b>index</b> of the last
-        * position, <b>not</b> the length.
-        * <p>
-        * Note: the search term size <b>must</b> 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 <b>not</b> a
-        *            length, but an index)
-        * 
-        * @return TRUE if the search content is present at the given location and
-        *         does not exceed the <tt>len</tt> 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;
-       }
 }