001: /*
002: *
003: *
004: * Copyright 1990-2007 Sun Microsystems, Inc. All Rights Reserved.
005: * DO NOT ALTER OR REMOVE COPYRIGHT NOTICES OR THIS FILE HEADER
006: *
007: * This program is free software; you can redistribute it and/or
008: * modify it under the terms of the GNU General Public License version
009: * 2 only, as published by the Free Software Foundation.
010: *
011: * This program is distributed in the hope that it will be useful, but
012: * WITHOUT ANY WARRANTY; without even the implied warranty of
013: * MERCHANTABILITY or FITNESS FOR A PARTICULAR PURPOSE. See the GNU
014: * General Public License version 2 for more details (a copy is
015: * included at /legal/license.txt).
016: *
017: * You should have received a copy of the GNU General Public License
018: * version 2 along with this work; if not, write to the Free Software
019: * Foundation, Inc., 51 Franklin St, Fifth Floor, Boston, MA
020: * 02110-1301 USA
021: *
022: * Please contact Sun Microsystems, Inc., 4150 Network Circle, Santa
023: * Clara, CA 95054 or visit www.sun.com if you need additional
024: * information or have any questions.
025: */
026:
027: package util;
028:
029: import java.io.PrintStream;
030: import java.io.OutputStream;
031: import java.io.IOException;
032:
033: /**
034: * Like PrintStream, but does its own
035: * buffering. This mashing of abstraction layers
036: * saves many a methodcall.
037: *
038: * NOTE the lack of synchronization!
039: * Also note the lack of autoflush.
040: * Finally, note especially troublesome solution we use in determining
041: * when to flush buffers. This relies on relative speed of dealing
042: * with a Java exception and the size of the buffer, thus infrequency
043: * of its occurrence.
044: */
045: public class BufferedPrintStream extends PrintStream {
046: private final static int bufsize = 2 * 4096; // to choose a number at random.
047: private final static int buflastindex = bufsize - 1;
048: protected byte[] buf;
049: protected int curindex;
050: protected OutputStream f;
051: protected boolean errorOccured;
052: protected IOException recentException;
053:
054: private final static byte NL = (byte) '\n';
055:
056: protected void flushit() {
057: try {
058: f.write(buf, 0, curindex);
059: } catch (IOException e) {
060: errorOccured = true;
061: recentException = e;
062: }
063: curindex = 0;
064: }
065:
066: public BufferedPrintStream(OutputStream file) {
067: super (file);// whatever...
068: f = file;
069: errorOccured = false;
070: buf = new byte[bufsize];
071: curindex = 0;
072: }
073:
074: public boolean checkException() {
075: flush();
076: return errorOccured;
077: }
078:
079: public void flush() {
080: try {
081: if (curindex != 0) {
082: f.write(buf, 0, curindex);
083: }
084: f.flush();
085: } catch (IOException e) {
086: errorOccured = true;
087: recentException = e;
088: }
089: curindex = 0;
090: }
091:
092: public void close() {
093: flush();
094: buf = null;
095: numbuf = null;
096: try {
097: if (f != null)
098: f.close();
099: } catch (IOException e) {
100: errorOccured = true;
101: recentException = e;
102: }
103: super .close();
104: f = null;
105: }
106:
107: public void write(int b) {
108: try {
109: buf[curindex] = (byte) b;
110: curindex++;
111: return;
112: } catch (IndexOutOfBoundsException e) {
113: flushit();
114: buf[curindex++] = (byte) b;
115: }
116: }
117:
118: public void write(byte b[], int off, int len) {
119: try {
120: if (len == 1) {
121: buf[curindex] = b[off];
122: curindex++;
123: return;
124: } else {
125: System.arraycopy(b, off, buf, curindex, len);
126: curindex += len;
127: return;
128: }
129: } catch (IndexOutOfBoundsException e) {
130: flushit();
131: System.arraycopy(b, off, buf, curindex, len);
132: curindex += len;
133: }
134: }
135:
136: private static byte[] truth = { (byte) 't', (byte) 'r', (byte) 'u',
137: (byte) 'e', (byte) '\n' };
138: private static byte[] falsity = { (byte) 'f', (byte) 'a',
139: (byte) 'l', (byte) 's', (byte) 'e', (byte) '\n' };
140:
141: public void print(boolean b) {
142: if (b) {
143: write(truth, 0, 4);
144: } else {
145: write(falsity, 0, 5);
146: }
147: }
148:
149: public void println(boolean b) {
150: if (b) {
151: write(truth, 0, 5);
152: } else {
153: write(falsity, 0, 6);
154: }
155: }
156:
157: public void print(char c) {
158: try {
159: buf[curindex] = (byte) c;
160: curindex++;
161: return;
162: } catch (IndexOutOfBoundsException e) {
163: flushit();
164: buf[curindex++] = (byte) c;
165: }
166: }
167:
168: public void println(char c) {
169: try {
170: buf[curindex] = (byte) c;
171: curindex++;
172: } catch (IndexOutOfBoundsException e) {
173: flushit();
174: buf[curindex++] = (byte) c;
175: buf[curindex++] = NL;
176: return;
177: }
178: try {
179: buf[curindex] = NL;
180: curindex++;
181: return;
182: } catch (IndexOutOfBoundsException e) {
183: flushit();
184: buf[curindex++] = NL;
185: }
186: }
187:
188: public void print(char s[]) {
189: int slen = s.length;
190: for (int i = 0; i < slen; i++) {
191: try {
192: buf[curindex] = (byte) s[i];
193: curindex++;
194: continue;
195: } catch (IndexOutOfBoundsException e) {
196: flushit();
197: buf[curindex++] = (byte) s[i];
198: }
199: }
200: }
201:
202: public void println(char s[]) {
203: // enough pain to not be worth replicating the above
204: print(s);
205: //if ( curindex >= bufsize-1 ) flushit();
206: // count on print to have left one space at end of buf for us.
207: try {
208: buf[curindex] = NL;
209: curindex++;
210: } catch (IndexOutOfBoundsException e) {
211: flushit();
212: buf[curindex++] = NL;
213: }
214: }
215:
216: private static final int nnumbuf = 25;
217: private byte[] numbuf = new byte[nnumbuf]; // for integer conversions
218:
219: public void print(int i) {
220: if (i < 0) {
221: if (i == Integer.MIN_VALUE) {
222: // special case, not worth bothering with.
223: print(Integer.toString(Integer.MIN_VALUE));
224: return;
225: }
226: i = -i;
227: // since even negative numbers hardly happen,
228: // we don't mind this extra call...
229: write('-');
230: }
231: int n = nnumbuf;
232: do {
233: numbuf[--n] = (byte) ('0' + (i % 10));
234: i /= 10;
235: } while (i != 0);
236: int nsz = nnumbuf - n;
237: try {
238: System.arraycopy(numbuf, n, buf, curindex, nsz);
239: } catch (IndexOutOfBoundsException e) {
240: flushit();
241: System.arraycopy(numbuf, n, buf, curindex, nsz);
242: }
243: curindex += nsz;
244: }
245:
246: public void println(int i) {
247: // enough pain to not be worth replicating the above
248: print(i);
249: try {
250: buf[curindex] = NL;
251: curindex++;
252: } catch (IndexOutOfBoundsException e) {
253: flushit();
254: buf[curindex++] = NL;
255: }
256: }
257:
258: public void print(long l) {
259: if (l < 0) {
260: if (l == Long.MIN_VALUE) {
261: // special case, not worth bothering with.
262: print(Long.toString(Long.MIN_VALUE));
263: return;
264: }
265: l = -l;
266: // since even negative numbers hardly happen,
267: // we don't mind this extra call...
268: write('-');
269: }
270: int n = nnumbuf;
271: do {
272: numbuf[--n] = (byte) ('0' + (byte) (l % 10L));
273: l /= 10L;
274: } while (l != 0L);
275: int nsz = nnumbuf - n;
276: try {
277: System.arraycopy(numbuf, n, buf, curindex, nsz - n);
278: } catch (IndexOutOfBoundsException e) {
279: flushit();
280: System.arraycopy(numbuf, n, buf, curindex, nsz - n);
281: }
282: curindex += nsz;
283: }
284:
285: public void println(long l) {
286: // enough pain to not be worth replicating the above
287: print(l);
288: try {
289: buf[curindex] = NL;
290: curindex++;
291: } catch (IndexOutOfBoundsException e) {
292: flushit();
293: buf[curindex++] = NL;
294: }
295: }
296:
297: public void print(Object o) {
298: if (o == null)
299: print("(null)");
300: else
301: print(o.toString());
302: }
303:
304: public void println(Object o) {
305: if (o == null)
306: println("(null)");
307: else
308: println(o.toString());
309: }
310:
311: public void print(String s) {
312: int slen = s.length();
313: try {
314: s.getBytes(0, slen, buf, curindex);
315: } catch (IndexOutOfBoundsException e) {
316: flushit();
317: s.getBytes(0, slen, buf, curindex);
318: }
319: curindex += slen;
320: }
321:
322: public void println(String s) {
323: int slen = s.length();
324: try {
325: s.getBytes(0, slen, buf, curindex);
326: } catch (IndexOutOfBoundsException e) {
327: flushit();
328: s.getBytes(0, slen, buf, curindex);
329: }
330: curindex += slen;
331: try {
332: buf[curindex] = NL;
333: curindex++;
334: } catch (IndexOutOfBoundsException e) {
335: flushit();
336: buf[curindex++] = NL;
337: }
338: }
339:
340: public void println() {
341: try {
342: buf[curindex] = NL;
343: curindex++;
344: } catch (IndexOutOfBoundsException e) {
345: flushit();
346: buf[curindex++] = NL;
347: }
348: }
349:
350: }
|