+ // Utilities: append() and transcribe() //////////////////////////////////////////////////////////////////////////////
+
+ public Stream append(String in_next) { return appendStream(new Stream(in_next)); }
+ public Stream appendStream(Stream in_next) {
+ if (this.in_next != null)
+ this.in_next.appendStream(in_next);
+ else
+ this.in_next = in_next;
+ return this;
+ }
+
+ public void transcribe(Stream out) { transcribe(out, false); }
+ public void transcribe(Stream out, boolean close) {
+ try {
+ byte[] buf = new byte[1024];
+ while(true) {
+ int numread = in.read(buf, 0, buf.length);
+ if (numread==-1) { in.close(); break; }
+ out.out.write(buf, 0, numread);
+ }
+ if (close) out.close();
+ } catch (IOException ioe) { ioe(ioe); }
+ }
+
+ public void transcribe(StringBuffer out) {
+ char[] buf = new char[1024];
+ while(true) {
+ int numread = in.read(buf, 0, buf.length);
+ if (numread==-1) { in.close(); return; }
+ out.append(buf, 0, numread);
+ }
+ }
+
+ public static int countLines(Stream s) {
+ int ret = 0;
+ while(s.readln() != null) ret++;
+ s.close();
+ return ret;
+ }
+
+ // Exceptions //////////////////////////////////////////////////////////////////////////////
+
+ static int ioe(IOException e) {
+ if (e instanceof SocketException && e.toString().indexOf("Connection reset")!=-1)
+ throw new Closed(e.getMessage());
+ throw new StreamException(e);
+ }
+ public static class StreamException extends RuntimeException {
+ public StreamException(Exception e) { super(e); }
+ public StreamException(String s) { super(s); }
+ }
+ public static class EOF extends StreamException { public EOF() { super("End of stream"); } }
+ public static class Closed extends StreamException { public Closed(String s) { super(s); } }