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 java.io;
028:
029: /**
030: * A <code>PrintStream</code> adds functionality to another output stream,
031: * namely the ability to print representations of various data values
032: * conveniently. Two other features are provided as well. Unlike other output
033: * streams, a <code>PrintStream</code> never throws an
034: * <code>IOException</code>; instead, exceptional situations merely set an
035: * internal flag that can be tested via the <code>checkError</code> method.
036: *
037: * <p> All characters printed by a <code>PrintStream</code> are converted into
038: * bytes using the platform's default character encoding.
039: *
040: * @version 12/17/01 (CLDC 1.1)
041: * @since JDK1.0, CLDC 1.0
042: */
043:
044: public class PrintStream extends OutputStream {
045:
046: private boolean trouble = false;
047:
048: /**
049: * Track both the text- and character-output streams, so that their buffers
050: * can be flushed without flushing the entire stream.
051: */
052: private OutputStreamWriter charOut;
053: private OutputStream byteOut;
054:
055: /**
056: * Create a new print stream. This stream will not flush automatically.
057: *
058: * @param out The output stream to which values and objects will be
059: * printed
060: */
061: public PrintStream(OutputStream out) {
062: if (out == null) {
063: throw new NullPointerException(
064: /* #ifdef VERBOSE_EXCEPTIONS */
065: /// skipped "Null output stream"
066: /* #endif */
067: );
068: }
069: byteOut = out;
070: this .charOut = new OutputStreamWriter(out);
071: }
072:
073: /**
074: * Check to make sure that the stream has not been closed
075: */
076: private void ensureOpen() throws IOException {
077: if (charOut == null) {
078: throw new IOException(
079: /* #ifdef VERBOSE_EXCEPTIONS */
080: /// skipped "Stream closed"
081: /* #endif */
082: );
083: }
084: }
085:
086: /**
087: * Flush the stream. This is done by writing any buffered output bytes to
088: * the underlying output stream and then flushing that stream.
089: *
090: * @see java.io.OutputStream#flush()
091: */
092: public void flush() {
093: synchronized (this ) {
094: try {
095: ensureOpen();
096: charOut.flush();
097: } catch (IOException x) {
098: trouble = true;
099: }
100: }
101: }
102:
103: private boolean closing = false; /* To avoid recursive closing */
104:
105: /**
106: * Close the stream. This is done by flushing the stream and then closing
107: * the underlying output stream.
108: *
109: * @see java.io.OutputStream#close()
110: */
111: public void close() {
112: synchronized (this ) {
113: if (!closing) {
114: closing = true;
115: try {
116: charOut.close();
117: } catch (IOException x) {
118: trouble = true;
119: }
120: charOut = null;
121: byteOut = null;
122: }
123: }
124: }
125:
126: /**
127: * Flush the stream and check its error state. The internal error state
128: * is set to <code>true</code> when the underlying output stream throws an
129: * <code>IOException</code>,
130: * and when the <code>setError</code> method is invoked.
131: *
132: * @return True if and only if this stream has encountered an
133: * <code>IOException</code>, or the
134: * <code>setError</code> method has been invoked
135: */
136: public boolean checkError() {
137: if (charOut != null)
138: flush();
139: return trouble;
140: }
141:
142: /**
143: * Set the error state of the stream to <code>true</code>.
144: *
145: * @since JDK1.1
146: */
147: protected void setError() {
148: trouble = true;
149: }
150:
151: /*
152: * Exception-catching, synchronized output operations,
153: * which also implement the write() methods of OutputStream
154: */
155:
156: /**
157: * Write the specified byte to this stream.
158: *
159: * <p> Note that the byte is written as given; to write a character that
160: * will be translated according to the platform's default character
161: * encoding, use the <code>print(char)</code> or <code>println(char)</code>
162: * methods.
163: *
164: * @param b The byte to be written
165: * @see #print(char)
166: * @see #println(char)
167: */
168: public void write(int b) {
169: try {
170: synchronized (this ) {
171: ensureOpen();
172: byteOut.write(b);
173: }
174: } catch (IOException x) {
175: trouble = true;
176: }
177: }
178:
179: /**
180: * Write <code>len</code> bytes from the specified byte array starting at
181: * offset <code>off</code> to this stream.
182: *
183: * <p> Note that the bytes will be written as given; to write characters
184: * that will be translated according to the platform's default character
185: * encoding, use the <code>print(char)</code> or <code>println(char)</code>
186: * methods.
187: *
188: * @param buf A byte array
189: * @param off Offset from which to start taking bytes
190: * @param len Number of bytes to write
191: */
192: public void write(byte buf[], int off, int len) {
193: try {
194: synchronized (this ) {
195: ensureOpen();
196: byteOut.write(buf, off, len);
197: }
198: } catch (IOException x) {
199: trouble = true;
200: }
201: }
202:
203: /*
204: * The following private methods on the text- and character-output streams
205: * always flush the stream buffers, so that writes to the underlying byte
206: * stream occur as promptly as with the original PrintStream.
207: */
208:
209: private void write(char buf[]) {
210: try {
211: synchronized (this ) {
212: ensureOpen();
213: charOut.write(buf);
214: }
215: } catch (IOException x) {
216: trouble = true;
217: }
218: }
219:
220: private void write(String s) {
221: try {
222: synchronized (this ) {
223: ensureOpen();
224: charOut.write(s);
225: }
226: } catch (IOException x) {
227: trouble = true;
228: }
229: }
230:
231: private void newLine() {
232: try {
233: synchronized (this ) {
234: ensureOpen();
235: charOut.write('\n');
236: }
237: } catch (IOException x) {
238: trouble = true;
239: }
240: }
241:
242: /* Methods that do not terminate lines */
243:
244: /**
245: * Print a boolean value. The string produced by <code>{@link
246: * java.lang.String#valueOf(boolean)}</code> is translated into bytes
247: * according to the platform's default character encoding, and these bytes
248: * are written in exactly the manner of the
249: * <code>{@link #write(int)}</code> method.
250: *
251: * @param b The <code>boolean</code> to be printed
252: */
253: public void print(boolean b) {
254: write(b ? "true" : "false");
255: }
256:
257: /**
258: * Print a character. The character is translated into one or more bytes
259: * according to the platform's default character encoding, and these bytes
260: * are written in exactly the manner of the
261: * <code>{@link #write(int)}</code> method.
262: *
263: * @param c The <code>char</code> to be printed
264: */
265: public void print(char c) {
266: write(String.valueOf(c));
267: }
268:
269: /**
270: * Print an integer. The string produced by <code>{@link
271: * java.lang.String#valueOf(int)}</code> is translated into bytes
272: * according to the platform's default character encoding, and these bytes
273: * are written in exactly the manner of the
274: * <code>{@link #write(int)}</code> method.
275: *
276: * @param i The <code>int</code> to be printed
277: * @see java.lang.Integer#toString(int)
278: */
279: public void print(int i) {
280: write(String.valueOf(i));
281: }
282:
283: /**
284: * Print a long integer. The string produced by <code>{@link
285: * java.lang.String#valueOf(long)}</code> is translated into bytes
286: * according to the platform's default character encoding, and these bytes
287: * are written in exactly the manner of the
288: * <code>{@link #write(int)}</code> method.
289: *
290: * @param l The <code>long</code> to be printed
291: * @see java.lang.Long#toString(long)
292: */
293: public void print(long l) {
294: write(String.valueOf(l));
295: }
296:
297: /**
298: * Print a floating point number. The string produced by
299: * <code>{@link java.lang.String#valueOf(float)}</code> is translated
300: * into bytes according to the platform's default character encoding,
301: * and these bytes are written in exactly the manner of the
302: * <code>{@link #write(int)}</code> method.
303: *
304: * @param f The <code>float</code> to be printed
305: * @see java.lang.Float#toString(float)
306: * @since CLDC 1.1
307: */
308: public void print(float f) {
309: write(String.valueOf(f));
310: }
311:
312: /**
313: * Print a double-precision floating point number. The string produced by
314: * <code>{@link java.lang.String#valueOf(double)}</code> is translated
315: * into bytes according to the platform's default character encoding,
316: * and these bytes are written in exactly the manner of the
317: * <code>{@link #write(int)}</code> method.
318: *
319: * @param d The <code>double</code> to be printed
320: * @see java.lang.Double#toString(double)
321: * @since CLDC 1.1
322: */
323: public void print(double d) {
324: write(String.valueOf(d));
325: }
326:
327: /**
328: * Print an array of characters. The characters are converted into bytes
329: * according to the platform's default character encoding, and these bytes
330: * are written in exactly the manner of the
331: * <code>{@link #write(int)}</code> method.
332: *
333: * @param s The array of chars to be printed
334: *
335: * @throws NullPointerException If <code>s</code> is <code>null</code>
336: */
337: public void print(char s[]) {
338: write(s);
339: }
340:
341: /**
342: * Print a string. If the argument is <code>null</code> then the string
343: * <code>"null"</code> is printed. Otherwise, the string's characters are
344: * converted into bytes according to the platform's default character
345: * encoding, and these bytes are written in exactly the manner of the
346: * <code>{@link #write(int)}</code> method.
347: *
348: * @param s The <code>String</code> to be printed
349: */
350: public void print(String s) {
351: if (s == null) {
352: s = "null";
353: }
354: write(s);
355: }
356:
357: /**
358: * Print an object. The string produced by the <code>{@link
359: * java.lang.String#valueOf(Object)}</code> method is translated into bytes
360: * according to the platform's default character encoding, and these bytes
361: * are written in exactly the manner of the
362: * <code>{@link #write(int)}</code> method.
363: *
364: * @param obj The <code>Object</code> to be printed
365: * @see java.lang.Object#toString()
366: */
367: public void print(Object obj) {
368: write(String.valueOf(obj));
369: }
370:
371: /* Methods that do terminate lines */
372:
373: /**
374: * Terminate the current line by writing the line separator string. The
375: * line separator string is defined by the system property
376: * <code>line.separator</code>, and is not necessarily a single newline
377: * character (<code>'\n'</code>).
378: */
379: public void println() {
380: newLine();
381: }
382:
383: /**
384: * Print a boolean and then terminate the line. This method behaves as
385: * though it invokes <code>{@link #print(boolean)}</code> and then
386: * <code>{@link #println()}</code>.
387: *
388: * @param x The <code>boolean</code> to be printed
389: */
390: public void println(boolean x) {
391: synchronized (this ) {
392: print(x);
393: newLine();
394: }
395: }
396:
397: /**
398: * Print a character and then terminate the line. This method behaves as
399: * though it invokes <code>{@link #print(char)}</code> and then
400: * <code>{@link #println()}</code>.
401: *
402: * @param x The <code>char</code> to be printed.
403: */
404: public void println(char x) {
405: synchronized (this ) {
406: print(x);
407: newLine();
408: }
409: }
410:
411: /**
412: * Print an integer and then terminate the line. This method behaves as
413: * though it invokes <code>{@link #print(int)}</code> and then
414: * <code>{@link #println()}</code>.
415: *
416: * @param x The <code>int</code> to be printed.
417: */
418: public void println(int x) {
419: synchronized (this ) {
420: print(x);
421: newLine();
422: }
423: }
424:
425: /**
426: * Print a long and then terminate the line. This method behaves as
427: * though it invokes <code>{@link #print(long)}</code> and then
428: * <code>{@link #println()}</code>.
429: *
430: * @param x The <code>long</code> to be printed.
431: */
432: public void println(long x) {
433: synchronized (this ) {
434: print(x);
435: newLine();
436: }
437: }
438:
439: /**
440: * Print a float and then terminate the line. This method behaves as
441: * though it invokes <code>{@link #print(float)}</code> and then
442: * <code>{@link #println()}</code>.
443: *
444: * @param x The <code>float</code> to be printed.
445: * @since CLDC 1.1
446: */
447: public void println(float x) {
448: synchronized (this ) {
449: print(x);
450: newLine();
451: }
452: }
453:
454: /**
455: * Print a double and then terminate the line. This method behaves as
456: * though it invokes <code>{@link #print(double)}</code> and then
457: * <code>{@link #println()}</code>.
458: *
459: * @param x The <code>double</code> to be printed.
460: * @since CLDC 1.1
461: */
462: public void println(double x) {
463: synchronized (this ) {
464: print(x);
465: newLine();
466: }
467: }
468:
469: /**
470: * Print an array of characters and then terminate the line. This method
471: * behaves as though it invokes <code>{@link #print(char[])}</code> and
472: * then <code>{@link #println()}</code>.
473: *
474: * @param x an array of chars to print.
475: */
476: public void println(char x[]) {
477: synchronized (this ) {
478: print(x);
479: newLine();
480: }
481: }
482:
483: /**
484: * Print a String and then terminate the line. This method behaves as
485: * though it invokes <code>{@link #print(String)}</code> and then
486: * <code>{@link #println()}</code>.
487: *
488: * @param x The <code>String</code> to be printed.
489: */
490: public void println(String x) {
491: synchronized (this ) {
492: print(x);
493: newLine();
494: }
495: }
496:
497: /**
498: * Print an Object and then terminate the line. This method behaves as
499: * though it invokes <code>{@link #print(Object)}</code> and then
500: * <code>{@link #println()}</code>.
501: *
502: * @param x The <code>Object</code> to be printed.
503: */
504: public void println(Object x) {
505: synchronized (this) {
506: print(x);
507: newLine();
508: }
509: }
510:
511: }
|