fix "limit" and "skip" logic in io (still not very good, though)
[org.ibex.io.git] / src / org / ibex / io / Fountain.java
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) {