Frames | No Frames |
1: /* PrintStream.java -- OutputStream for printing output 2: Copyright (C) 1998, 1999, 2001, 2003, 2004, 2005 Free Software Foundation, Inc. 3: 4: This file is part of GNU Classpath. 5: 6: GNU Classpath is free software; you can redistribute it and/or modify 7: it under the terms of the GNU General Public License as published by 8: the Free Software Foundation; either version 2, or (at your option) 9: any later version. 10: 11: GNU Classpath is distributed in the hope that it will be useful, but 12: WITHOUT ANY WARRANTY; without even the implied warranty of 13: MERCHANTABILITY or FITNESS FOR A PARTICULAR PURPOSE. See the GNU 14: General Public License for more details. 15: 16: You should have received a copy of the GNU General Public License 17: along with GNU Classpath; see the file COPYING. If not, write to the 18: Free Software Foundation, Inc., 51 Franklin Street, Fifth Floor, Boston, MA 19: 02110-1301 USA. 20: 21: Linking this library statically or dynamically with other modules is 22: making a combined work based on this library. Thus, the terms and 23: conditions of the GNU General Public License cover the whole 24: combination. 25: 26: As a special exception, the copyright holders of this library give you 27: permission to link this library with independent modules to produce an 28: executable, regardless of the license terms of these independent 29: modules, and to copy and distribute the resulting executable under 30: terms of your choice, provided that you also meet, for each linked 31: independent module, the terms and conditions of the license of that 32: module. An independent module is a module which is not derived from 33: or based on this library. If you modify this library, you may extend 34: this exception to your version of the library, but you are not 35: obligated to do so. If you do not wish to do so, delete this 36: exception statement from your version. */ 37: 38: 39: package java.io; 40: 41: import gnu.gcj.convert.UnicodeToBytes; 42: 43: /* Written using "Java Class Libraries", 2nd edition, ISBN 0-201-31002-3 44: * "The Java Language Specification", ISBN 0-201-63451-1 45: * Status: Believed complete and correct to 1.3 46: */ 47: 48: /** 49: * This class prints Java primitive values and object to a stream as 50: * text. None of the methods in this class throw an exception. However, 51: * errors can be detected by calling the <code>checkError()</code> method. 52: * Additionally, this stream can be designated as "autoflush" when 53: * created so that any writes are automatically flushed to the underlying 54: * output sink when the current line is terminated. 55: * <p> 56: * This class converts char's into byte's using the system default encoding. 57: * 58: * @author Aaron M. Renn (arenn@urbanophile.com) 59: * @author Tom Tromey (tromey@cygnus.com) 60: */ 61: public class PrintStream extends FilterOutputStream 62: { 63: /* Notice the implementation is quite similar to OutputStreamWriter. 64: * This leads to some minor duplication, because neither inherits 65: * from the other, and we want to maximize performance. */ 66: 67: // Line separator string. 68: private static final char[] line_separator 69: = System.getProperty("line.separator").toCharArray(); 70: 71: UnicodeToBytes converter; 72: 73: // Work buffer of characters for converter. 74: char[] work = new char[100]; 75: // Work buffer of bytes where we temporarily keep converter output. 76: byte[] work_bytes = new byte[100]; 77: 78: /** 79: * This boolean indicates whether or not an error has ever occurred 80: * on this stream. 81: */ 82: private boolean error_occurred = false; 83: 84: /** 85: * This is <code>true</code> if auto-flush is enabled, 86: * <code>false</code> otherwise 87: */ 88: private boolean auto_flush; 89: 90: /** 91: * This method intializes a new <code>PrintStream</code> object to write 92: * to the specified output sink. 93: * 94: * @param out The <code>OutputStream</code> to write to. 95: */ 96: public PrintStream (OutputStream out) 97: { 98: this (out, false); 99: } 100: 101: /** 102: * This method intializes a new <code>PrintStream</code> object to write 103: * to the specified output sink. This constructor also allows "auto-flush" 104: * functionality to be specified where the stream will be flushed after 105: * every <code>print</code> or <code>println</code> call, when the 106: * <code>write</code> methods with array arguments are called, or when a 107: * single new-line character is written. 108: * <p> 109: * 110: * @param out The <code>OutputStream</code> to write to. 111: * @param auto_flush <code>true</code> to flush the stream after every 112: * line, <code>false</code> otherwise 113: */ 114: public PrintStream (OutputStream out, boolean auto_flush) 115: { 116: super (out); 117: 118: converter = UnicodeToBytes.getDefaultEncoder(); 119: this.auto_flush = auto_flush; 120: } 121: 122: /** 123: * This method intializes a new <code>PrintStream</code> object to write 124: * to the specified output sink. This constructor also allows "auto-flush" 125: * functionality to be specified where the stream will be flushed after 126: * every <code>print</code> or <code>println</code> call, when the 127: * <code>write</code> methods with array arguments are called, or when a 128: * single new-line character is written. 129: * <p> 130: * 131: * @param out The <code>OutputStream</code> to write to. 132: * @param auto_flush <code>true</code> to flush the stream after every 133: * line, <code>false</code> otherwise 134: * @param encoding The name of the character encoding to use for this 135: * object. 136: */ 137: public PrintStream (OutputStream out, boolean auto_flush, String encoding) 138: throws UnsupportedEncodingException 139: { 140: super (out); 141: 142: converter = UnicodeToBytes.getEncoder (encoding); 143: this.auto_flush = auto_flush; 144: } 145: 146: /** 147: * This method checks to see if an error has occurred on this stream. Note 148: * that once an error has occurred, this method will continue to report 149: * <code>true</code> forever for this stream. Before checking for an 150: * error condition, this method flushes the stream. 151: * 152: * @return <code>true</code> if an error has occurred, 153: * <code>false</code> otherwise 154: */ 155: public boolean checkError () 156: { 157: flush (); 158: return error_occurred; 159: } 160: 161: /** 162: * This method can be called by subclasses to indicate that an error 163: * has occurred and should be reported by <code>checkError</code>. 164: */ 165: protected void setError () 166: { 167: error_occurred = true; 168: } 169: 170: /** 171: * This method closes this stream and all underlying streams. 172: */ 173: public void close () 174: { 175: try 176: { 177: flush(); 178: out.close(); 179: } 180: catch (InterruptedIOException iioe) 181: { 182: Thread.currentThread().interrupt(); 183: } 184: catch (IOException e) 185: { 186: setError (); 187: } 188: } 189: 190: /** 191: * This method flushes any buffered bytes to the underlying stream and 192: * then flushes that stream as well. 193: */ 194: public void flush () 195: { 196: try 197: { 198: out.flush(); 199: } 200: catch (InterruptedIOException iioe) 201: { 202: Thread.currentThread().interrupt(); 203: } 204: catch (IOException e) 205: { 206: setError (); 207: } 208: } 209: 210: private synchronized void print (String str, boolean println) 211: { 212: try 213: { 214: writeChars(str, 0, str.length()); 215: if (println) 216: writeChars(line_separator, 0, line_separator.length); 217: if (auto_flush) 218: flush(); 219: } 220: catch (InterruptedIOException iioe) 221: { 222: Thread.currentThread().interrupt(); 223: } 224: catch (IOException e) 225: { 226: setError (); 227: } 228: } 229: 230: private synchronized void print (char[] chars, int pos, int len, 231: boolean println) 232: { 233: try 234: { 235: writeChars(chars, pos, len); 236: if (println) 237: writeChars(line_separator, 0, line_separator.length); 238: if (auto_flush) 239: flush(); 240: } 241: catch (InterruptedIOException iioe) 242: { 243: Thread.currentThread().interrupt(); 244: } 245: catch (IOException e) 246: { 247: setError (); 248: } 249: } 250: 251: private void writeChars(char[] buf, int offset, int count) 252: throws IOException 253: { 254: while (count > 0 || converter.havePendingBytes()) 255: { 256: converter.setOutput(work_bytes, 0); 257: int converted = converter.write(buf, offset, count); 258: offset += converted; 259: count -= converted; 260: out.write(work_bytes, 0, converter.count); 261: } 262: } 263: 264: private void writeChars(String str, int offset, int count) 265: throws IOException 266: { 267: while (count > 0 || converter.havePendingBytes()) 268: { 269: converter.setOutput(work_bytes, 0); 270: int converted = converter.write(str, offset, count, work); 271: offset += converted; 272: count -= converted; 273: out.write(work_bytes, 0, converter.count); 274: } 275: } 276: 277: /** 278: * This methods prints a boolean value to the stream. <code>true</code> 279: * values are printed as "true" and <code>false</code> values are printed 280: * as "false". 281: * 282: * @param bool The <code>boolean</code> value to print 283: */ 284: public void print (boolean bool) 285: { 286: print(String.valueOf(bool), false); 287: } 288: 289: /** 290: * This method prints an integer to the stream. The value printed is 291: * determined using the <code>String.valueOf()</code> method. 292: * 293: * @param inum The <code>int</code> value to be printed 294: */ 295: public void print (int inum) 296: { 297: print(String.valueOf(inum), false); 298: } 299: 300: /** 301: * This method prints a long to the stream. The value printed is 302: * determined using the <code>String.valueOf()</code> method. 303: * 304: * @param lnum The <code>long</code> value to be printed 305: */ 306: public void print (long lnum) 307: { 308: print(String.valueOf(lnum), false); 309: } 310: 311: /** 312: * This method prints a float to the stream. The value printed is 313: * determined using the <code>String.valueOf()</code> method. 314: * 315: * @param fnum The <code>float</code> value to be printed 316: */ 317: public void print (float fnum) 318: { 319: print(String.valueOf(fnum), false); 320: } 321: 322: /** 323: * This method prints a double to the stream. The value printed is 324: * determined using the <code>String.valueOf()</code> method. 325: * 326: * @param dnum The <code>double</code> value to be printed 327: */ 328: public void print (double dnum) 329: { 330: print(String.valueOf(dnum), false); 331: } 332: 333: /** 334: * This method prints an <code>Object</code> to the stream. The actual 335: * value printed is determined by calling the <code>String.valueOf()</code> 336: * method. 337: * 338: * @param obj The <code>Object</code> to print. 339: */ 340: public void print (Object obj) 341: { 342: print(obj == null ? "null" : obj.toString(), false); 343: } 344: 345: /** 346: * This method prints a <code>String</code> to the stream. The actual 347: * value printed depends on the system default encoding. 348: * 349: * @param str The <code>String</code> to print. 350: */ 351: public void print (String str) 352: { 353: print(str == null ? "null" : str, false); 354: } 355: 356: /** 357: * This method prints a char to the stream. The actual value printed is 358: * determined by the character encoding in use. 359: * 360: * @param ch The <code>char</code> value to be printed 361: */ 362: public synchronized void print (char ch) 363: { 364: work[0] = ch; 365: print(work, 0, 1, false); 366: } 367: 368: /** 369: * This method prints an array of characters to the stream. The actual 370: * value printed depends on the system default encoding. 371: * 372: * @param charArray The array of characters to print. 373: */ 374: public void print (char[] charArray) 375: { 376: print(charArray, 0, charArray.length, false); 377: } 378: 379: /** 380: * This method prints a line separator sequence to the stream. The value 381: * printed is determined by the system property <xmp>line.separator</xmp> 382: * and is not necessarily the Unix '\n' newline character. 383: */ 384: public void println () 385: { 386: print(line_separator, 0, line_separator.length, false); 387: } 388: 389: /** 390: * This methods prints a boolean value to the stream. <code>true</code> 391: * values are printed as "true" and <code>false</code> values are printed 392: * as "false". 393: * <p> 394: * This method prints a line termination sequence after printing the value. 395: * 396: * @param bool The <code>boolean</code> value to print 397: */ 398: public void println (boolean bool) 399: { 400: print(String.valueOf(bool), true); 401: } 402: 403: /** 404: * This method prints an integer to the stream. The value printed is 405: * determined using the <code>String.valueOf()</code> method. 406: * <p> 407: * This method prints a line termination sequence after printing the value. 408: * 409: * @param inum The <code>int</code> value to be printed 410: */ 411: public void println (int inum) 412: { 413: print(String.valueOf(inum), true); 414: } 415: 416: /** 417: * This method prints a long to the stream. The value printed is 418: * determined using the <code>String.valueOf()</code> method. 419: * <p> 420: * This method prints a line termination sequence after printing the value. 421: * 422: * @param lnum The <code>long</code> value to be printed 423: */ 424: public void println (long lnum) 425: { 426: print(String.valueOf(lnum), true); 427: } 428: 429: /** 430: * This method prints a float to the stream. The value printed is 431: * determined using the <code>String.valueOf()</code> method. 432: * <p> 433: * This method prints a line termination sequence after printing the value. 434: * 435: * @param fnum The <code>float</code> value to be printed 436: */ 437: public void println (float fnum) 438: { 439: print(String.valueOf(fnum), true); 440: } 441: 442: /** 443: * This method prints a double to the stream. The value printed is 444: * determined using the <code>String.valueOf()</code> method. 445: * <p> 446: * This method prints a line termination sequence after printing the value. 447: * 448: * @param dnum The <code>double</code> value to be printed 449: */ 450: public void println (double dnum) 451: { 452: print(String.valueOf(dnum), true); 453: } 454: 455: /** 456: * This method prints an <code>Object</code> to the stream. The actual 457: * value printed is determined by calling the <code>String.valueOf()</code> 458: * method. 459: * <p> 460: * This method prints a line termination sequence after printing the value. 461: * 462: * @param obj The <code>Object</code> to print. 463: */ 464: public void println (Object obj) 465: { 466: print(obj == null ? "null" : obj.toString(), true); 467: } 468: 469: /** 470: * This method prints a <code>String</code> to the stream. The actual 471: * value printed depends on the system default encoding. 472: * <p> 473: * This method prints a line termination sequence after printing the value. 474: * 475: * @param str The <code>String</code> to print. 476: */ 477: public void println (String str) 478: { 479: print (str == null ? "null" : str, true); 480: } 481: 482: /** 483: * This method prints a char to the stream. The actual value printed is 484: * determined by the character encoding in use. 485: * <p> 486: * This method prints a line termination sequence after printing the value. 487: * 488: * @param ch The <code>char</code> value to be printed 489: */ 490: public synchronized void println (char ch) 491: { 492: work[0] = ch; 493: print(work, 0, 1, true); 494: } 495: 496: /** 497: * This method prints an array of characters to the stream. The actual 498: * value printed depends on the system default encoding. 499: * <p> 500: * This method prints a line termination sequence after printing the value. 501: * 502: * @param charArray The array of characters to print. 503: */ 504: public void println (char[] charArray) 505: { 506: print(charArray, 0, charArray.length, true); 507: } 508: 509: /** 510: * This method writes a byte of data to the stream. If auto-flush is 511: * enabled, printing a newline character will cause the stream to be 512: * flushed after the character is written. 513: * 514: * @param oneByte The byte to be written 515: */ 516: public void write (int oneByte) 517: { 518: try 519: { 520: out.write (oneByte & 0xff); 521: 522: if (auto_flush && (oneByte == '\n')) 523: flush (); 524: } 525: catch (InterruptedIOException iioe) 526: { 527: Thread.currentThread ().interrupt (); 528: } 529: catch (IOException e) 530: { 531: setError (); 532: } 533: } 534: 535: /** 536: * This method writes <code>len</code> bytes from the specified array 537: * starting at index <code>offset</code> into the array. 538: * 539: * @param buffer The array of bytes to write 540: * @param offset The index into the array to start writing from 541: * @param len The number of bytes to write 542: */ 543: public void write (byte[] buffer, int offset, int len) 544: { 545: try 546: { 547: out.write (buffer, offset, len); 548: 549: if (auto_flush) 550: flush (); 551: } 552: catch (InterruptedIOException iioe) 553: { 554: Thread.currentThread ().interrupt (); 555: } 556: catch (IOException e) 557: { 558: setError (); 559: } 560: } 561: } // class PrintStream