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