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) {
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 (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;
continue;
}
} else {
+ if (limit >= 0) limit = Math.max(0, limit-end);
if (digest != null) digest.update(buf, 0, end);
}
} while(end==0);
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;
} 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;
}
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 }); }
*/
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) {
// 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(); }
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; }
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) {