fix "limit" and "skip" logic in io (still not very good, though)
authoradam <adam@megacz.com>
Sun, 22 Jul 2007 02:24:42 +0000 (02:24 +0000)
committeradam <adam@megacz.com>
Sun, 22 Jul 2007 02:24:42 +0000 (02:24 +0000)
darcs-hash:20070722022442-5007d-00465e7c315db8a9bbde3dce5dd75a5a0a77f258.gz

src/org/ibex/io/ByteBufInputStream.java
src/org/ibex/io/Fountain.java
src/org/ibex/io/Stream.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;
+    public int limit = -1;
     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);
     }
+    public void setLimit(int limit) { this.limit = limit; }
     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 {
-                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;
@@ -44,6 +48,7 @@ abstract class ByteBufInputStream extends InputStream {
                         continue;
                     }
                 } else {
+                    if (limit >= 0) limit = Math.max(0, limit-end);
                     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; }
+    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;
@@ -71,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;
     }
index 849544f..d4c1a0d 100644 (file)
@@ -53,6 +53,36 @@ public interface Fountain {
         public StringFountain(String s)                  { super(s); }
     }
 
+    public static class SubFountain implements Fountain {
+        private final Fountain f;
+        private final int start;
+        private final int len;
+        public SubFountain(Fountain f, int start) { this(f, start, -1); }
+        public SubFountain(Fountain f, int start, int len) {
+            this.f = f;
+            this.start = start;
+            this.len = len;
+        }
+        public Stream getStream() {
+            Stream s = f.getStream();
+            // FIXME: this is really fragile and IMAP needs it
+            int remain = start;
+            while(remain > 0) {
+                long result = s.skip(start);
+                Log.error("skip", result + " / " + start);
+                if (result == -1) return s;
+                remain -= result;
+            }
+            if (len != -1) s.setLimit(len);
+            return s;
+        }
+        public long   getLength() {
+            if (len == -1) return f.getLength()-start;
+            return Math.min(f.getLength()-start, len);
+        }
+        public int    getNumLines() { return Stream.countLines(getStream()); }
+    }
+
     public static class Concatenate implements Fountain {
         private Fountain[] founts;
         public Concatenate(Fountain f1, Fountain f2)     { this(new Fountain[] { f1, f2 }); }
@@ -146,6 +176,8 @@ public interface Fountain {
     */
 
     public static class Util {
+        public static Fountain subFountain(Fountain f, int start) { return new SubFountain(f, start); }
+        public static Fountain subFountain(Fountain f, int start, int len) { return new SubFountain(f, start, len); }
         public static Fountain create(String s) { return new StringFountain(s); }
         public static Fountain concat(Fountain[] f) { return new Concatenate(f); }
         public static Fountain concat(Fountain f1, Fountain f2) {
index 2cc2e14..70c90f8 100644 (file)
@@ -43,6 +43,7 @@ public class Stream {
 
     // Main API //////////////////////////////////////////////////////////////////////////////
 
+    public void   setLimit(int limit)              { in.setLimit(limit); }
     public char   peekc()                          { flush(); return in.getc(true); }
     public char   getc()                           { flush(); return in.getc(false); }
     public String readln()                         { flush(); return in.readln(); }
@@ -52,6 +53,7 @@ public class Stream {
     public void writeBytes(byte[] b, int off, int len) { try { out.write(b, off, len); } catch (IOException e) { ioe(e); } }
     public int    read(byte[] b, int off, int len) { flush(); return in.readBytes(b, off, len); }
     public int    read(char[] c, int off, int len) { flush(); return in.readChars(c, off, len); }
+    public int    skip(int len) { return in.skip(len); }
     public void   close()                          { try { if (in!=null) in.close(); } finally { if (out!=null) out.close(); } }
     public void   setNewline(String s)             { newLine = s; }
     public InputStream getInputStream() { return in; }
@@ -85,12 +87,14 @@ public class Stream {
 
         public char getc(boolean peek) { return cbr.getc(peek); }
         public String readln() { return cbr.readln(); }
+        public int skip(int len) { return bbis.skip(len); }
         public int read() { return bbis.read(); }
         public int read(byte[] b) { try { return bbis.read(b); } catch (IOException e) { ioe(e); return 0; } }
         public int read(byte[] b, int off, int len) { return bbis.read(b, off, len); }
         public void close() { try { cbr.close(); } catch (Exception e) { Log.error(this, e); } }
         public int readBytes(byte[] b, int off, int len) { return bbis.read(b, off, len); }
         public int readChars(char[] c, int off, int len) { return cbr.read(c, off, len); }
+        public void setLimit(int len) { bbis.setLimit(len); }
 
         public In(InputStream in) {
             bbis = new ByteBufInputStream(in) {