fix "limit" and "skip" logic in io (still not very good, though)
[org.ibex.io.git] / src / org / ibex / io / ByteBufInputStream.java
index 064b7bd..6f76f06 100644 (file)
@@ -14,6 +14,7 @@ abstract class ByteBufInputStream extends InputStream {
     private byte[] buf = new byte[8192];
     private int start = 0;
     private int end = 0;
     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) {
     public  Digest digest = null;
     
     public ByteBufInputStream(InputStream is) {
@@ -24,6 +25,7 @@ abstract class ByteBufInputStream extends InputStream {
         if (this.next == null) this.next = next;
         else this.next.appendStream(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 {
     private int bufSize() { if (end==start) { end = start = 0; } return end-start; }
     private int fillBufIfEmpty() {
         try {
@@ -32,7 +34,9 @@ abstract class ByteBufInputStream extends InputStream {
             if (prereading) return -1;
             start = 0;
             do {
             if (prereading) return -1;
             start = 0;
             do {
-                end = is.read(buf, 0, buf.length);
+                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 = null;
                 if (end == -1) {
                     is.close();
                     is = null;
@@ -44,6 +48,7 @@ abstract class ByteBufInputStream extends InputStream {
                         continue;
                     }
                 } else {
                         continue;
                     }
                 } else {
+                    if (limit >= 0) limit = Math.max(0, limit-end);
                     if (digest != null) digest.update(buf, 0, end);
                 }
             } while(end==0);
                     if (digest != null) digest.update(buf, 0, end);
                 }
             } while(end==0);
@@ -63,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; }
     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;
     public int read(byte[] c, int pos, int len) {
         if (prereading) return -1;
         prereading = true;
@@ -71,7 +80,7 @@ abstract class ByteBufInputStream extends InputStream {
         } finally { prereading = false; }
         if (fillBufIfEmpty() == -1) return -1;
         if (len > end - start) len = end - start;
         } 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;
     }
         start += len;
         return len;
     }