From f658e02ec5209c9669351800503f448d38c16bbb Mon Sep 17 00:00:00 2001 From: adam Date: Sun, 22 Jul 2007 02:24:42 +0000 Subject: [PATCH] fix "limit" and "skip" logic in io (still not very good, though) darcs-hash:20070722022442-5007d-00465e7c315db8a9bbde3dce5dd75a5a0a77f258.gz --- src/org/ibex/io/ByteBufInputStream.java | 13 +++++++++++-- src/org/ibex/io/Fountain.java | 32 +++++++++++++++++++++++++++++++ src/org/ibex/io/Stream.java | 4 ++++ 3 files changed, 47 insertions(+), 2 deletions(-) diff --git a/src/org/ibex/io/ByteBufInputStream.java b/src/org/ibex/io/ByteBufInputStream.java index 064b7bd..6f76f06 100644 --- a/src/org/ibex/io/ByteBufInputStream.java +++ b/src/org/ibex/io/ByteBufInputStream.java @@ -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; } diff --git a/src/org/ibex/io/Fountain.java b/src/org/ibex/io/Fountain.java index 849544f..d4c1a0d 100644 --- a/src/org/ibex/io/Fountain.java +++ b/src/org/ibex/io/Fountain.java @@ -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) { diff --git a/src/org/ibex/io/Stream.java b/src/org/ibex/io/Stream.java index 2cc2e14..70c90f8 100644 --- a/src/org/ibex/io/Stream.java +++ b/src/org/ibex/io/Stream.java @@ -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) { -- 1.7.10.4