1 // Copyright 2000-2007 the Contributors, as shown in the revision logs.
2 // Licensed under the Apache Public Source License 2.0 ("the License").
3 // You may not use this file except in compliance with the License.
10 import java.util.zip.*;
11 import org.ibex.util.*;
12 import org.ibex.crypto.*;
15 // - automatically flush writer before reading on linked read/write pairs
16 // - no checked exceptions thrown
17 // - unified write(char), print(char), and write(byte)
18 // - unreading/peeking
20 // - append (daisy-chaining)
21 // - automatically closes input streams when end reached
23 /** plays the role of InputStream, OutputStream, Reader and Writer, with logging and unchecked exceptions */
26 protected final In in;
27 protected final Out out;
28 private String newLine = "\r\n";
30 public Stream(byte[] b, int off, int len) { this.in = new Stream.In(new ByteArrayInputStream(b, off, len)); this.out=null; }
31 public Stream(InputStream in) { this.in = new Stream.In(in); this.out = null; }
32 public Stream( OutputStream out) { this.in = null; this.out = new Stream.Out(out); }
33 public Stream(InputStream in, OutputStream out) { this.in = new Stream.In(in); this.out = new Stream.Out(out); }
34 public Stream(String s) { this(new ByteArrayInputStream(s.getBytes())); }
35 public Stream(File f) {
36 try { this.in = new Stream.In(new FileInputStream(f)); } catch (IOException e) { ioe(e); throw new Error(); }
39 public Stream(Socket s) {
40 try { this.in = new Stream.In(s.getInputStream()); } catch (IOException e) { ioe(e); throw new Error(); }
41 try { this.out = new Stream.Out(s.getOutputStream()); } catch (IOException e) { ioe(e); throw new Error(); }
44 // Main API //////////////////////////////////////////////////////////////////////////////
46 public void setLimit(int limit) { in.setLimit(limit); }
47 public char peekc() { flush(); return in.getc(true); }
48 public char getc() { flush(); return in.getc(false); }
49 public String readln() { flush(); return in.readln(); }
50 public void print(String s) { out.write(s); flush(); }
51 public void println(String s) { print(s); print(newLine); }
52 public void flush() { if (out != null) out.flushWriter(); }
53 public void writeBytes(byte[] b, int off, int len) { try { out.write(b, off, len); } catch (IOException e) { ioe(e); } }
54 public int read(byte[] b, int off, int len) { flush(); return in.readBytes(b, off, len); }
55 public int read(char[] c, int off, int len) { flush(); return in.readChars(c, off, len); }
56 public int skip(int len) { return in.skip(len); }
57 public void close() { try { if (in!=null) in.close(); } finally { if (out!=null) out.close(); } }
58 public void setNewline(String s) { newLine = s; }
59 public InputStream getInputStream() { return in; }
61 public void setInputDigest(Digest d) { in.bbis.digest = d; }
63 private static class Out extends BufferedOutputStream {
64 private Writer writer = new OutputStreamWriter(this);
65 public Out(OutputStream out) { super(out); }
66 public void close() { try { super.close(); } catch (Exception e) { Log.error(this, e); } }
67 public void write(String s) { try { writer.write(s); } catch (IOException e) { ioe(e); } }
68 private void flushWriter() { try { writer.flush(); } catch (IOException e) { ioe(e); } }
69 private boolean flushing = false;
76 } finally { flushing = false; }
78 } catch (IOException e) { ioe(e); }
82 private class In extends InputStream {
83 private ByteBufInputStream bbis;
84 private CharBufReader cbr;
86 private Writer unreader;
88 public char getc(boolean peek) { return cbr.getc(peek); }
89 public String readln() { return cbr.readln(); }
90 public int skip(int len) { return bbis.skip(len); }
91 public int read() { return bbis.read(); }
92 public int read(byte[] b) { try { return bbis.read(b); } catch (IOException e) { ioe(e); return 0; } }
93 public int read(byte[] b, int off, int len) { return bbis.read(b, off, len); }
94 public void close() { try { cbr.close(); } catch (Exception e) { Log.error(this, e); } }
95 public int readBytes(byte[] b, int off, int len) { return bbis.read(b, off, len); }
96 public int readChars(char[] c, int off, int len) { return cbr.read(c, off, len); }
97 public void setLimit(int len) { bbis.setLimit(len); }
99 public In(InputStream in) {
100 bbis = new ByteBufInputStream(in) {
101 public void preread() {
102 cbr.unbuffer(unreader);
104 if (!cbr.ready()) return;
105 } catch (IOException e) { ioe(e); }
106 char[] c = new char[20];
109 if (!cbr.ready()) break;
110 int numread = cbr.read(c, 0, c.length);
111 if (numread == -1) break;
112 unreader.write(c, 0, numread);
113 } catch (IOException e) { ioe(e); }
117 unreader = new OutputStreamWriter(new UnReaderStream(bbis));
118 cbr = new CharBufReader(new InputStreamReader(bbis));
122 // Utilities: append() and transcribe() ///////////////////////////////////////////////////////
124 public Stream append(String in_next) { return appendStream(new Stream(in_next)); }
125 public Stream appendStream(Stream in_next) { in.bbis.appendStream(in_next); return this; }
127 public void transcribe(Stream out) { transcribe(out, false); }
128 public void transcribe(Stream out, boolean close) {
129 byte[] buf = new byte[1024];
131 int numread = in.read(buf, 0, buf.length);
132 if (numread==-1) { in.close(); break; }
133 out.writeBytes(buf, 0, numread);
135 if (close) out.close();
138 public void transcribe(StringBuffer out) {
139 char[] buf = new char[1024];
141 int numread = in.readChars(buf, 0, buf.length);
142 if (numread==-1) { in.close(); return; }
143 out.append(buf, 0, numread);
147 public static int countLines(Stream s) {
149 while(s.readln() != null) ret++;
155 public static int countBytes(Stream s) {
157 while(s.in.read() != -1) ret++;
162 // Exceptions //////////////////////////////////////////////////////////////////////////////
164 static int ioe(IOException e) {
165 if (e instanceof SocketException && e.toString().indexOf("Connection reset")!=-1)
166 throw new Closed(e.getMessage());
167 throw new StreamException(e);
169 public static class StreamException extends RuntimeException {
170 public StreamException(Exception e) { super(e); }
171 public StreamException(String s) { super(s); }
173 public static class EOF extends StreamException { public EOF() { super("End of stream"); } }
174 public static class Closed extends StreamException { public Closed(String s) { super(s); } }