fix "limit" and "skip" logic in io (still not very good, though)
[org.ibex.io.git] / src / org / ibex / io / ByteBufInputStream.java
index 7581c88..6f76f06 100644 (file)
@@ -4,31 +4,52 @@
 
 package org.ibex.io;
 import java.io.*;
+import org.ibex.crypto.*;
 
 /** package-private class */
 abstract class ByteBufInputStream extends InputStream {
 
     private InputStream is;
-    public  InputStream next;
+    public  Stream next = null;
     private byte[] buf = new byte[8192];
     private int start = 0;
     private int end = 0;
+    public int limit = -1;
+    public  Digest digest = null;
     
     public ByteBufInputStream(InputStream is) {
         this.is = is;
     }
 
+    public void appendStream(Stream next) {
+        if (this.next == null) this.next = next;
+        else this.next.appendStream(next);
+    }
+    public void setLimit(int limit) { this.limit = limit; }
     private int bufSize() { if (end==start) { end = start = 0; } return end-start; }
     private int fillBufIfEmpty() {
         try {
             if (bufSize() > 0) return bufSize();
+            if (is == null) return -1;
+            if (prereading) return -1;
             start = 0;
             do {
-                end = is.read(buf, 0, buf.length);
-                if (end == -1 && next != null) {
+                if      (limit == 0)  end = -1;
+                else if (limit == -1) end = is.read(buf, 0, buf.length);
+                else                  end = is.read(buf, 0, Math.min(buf.length, limit));
+                if (end == -1) {
                     is.close();
-                    is = next;
-                    continue;
+                    is = null;
+                    if (next != null) {
+                        // FIXME: append to a stream that has already run out?
+                        is = next.getInputStream();
+                        next = null;
+                        start = end = 0;
+                        continue;
+                    }
+                } else {
+                    if (limit >= 0) limit = Math.max(0, limit-end);
+                    if (digest != null) digest.update(buf, 0, end);
                 }
             } while(end==0);
             if (end == -1) { end = 0; return -1; }
@@ -47,6 +68,10 @@ abstract class ByteBufInputStream extends InputStream {
     private boolean prereading = false;
     public abstract void preread();
     public int read() { byte[] b = new byte[0]; if (read(b, 0, 1)<=0) return -1; return b[0] & 0xff; }
+    public int skip(int len) {
+        // FIXME ugly
+        return read(null, 0, len);
+    }
     public int read(byte[] c, int pos, int len) {
         if (prereading) return -1;
         prereading = true;
@@ -55,7 +80,7 @@ abstract class ByteBufInputStream extends InputStream {
         } finally { prereading = false; }
         if (fillBufIfEmpty() == -1) return -1;
         if (len > end - start) len = end - start;
-        System.arraycopy(buf, start, c, pos, len);
+        if (c!=null) System.arraycopy(buf, start, c, pos, len);
         start += len;
         return len;
     }