GNU Classpath (0.95) | |
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 java.util.Locale; 43: import java.util.Formatter; 44: 45: import gnu.classpath.SystemProperties; 46: 47: /* Written using "Java Class Libraries", 2nd edition, ISBN 0-201-31002-3 48: * "The Java Language Specification", ISBN 0-201-63451-1 49: * Status: Believed complete and correct to 1.3 50: */ 51: 52: /** 53: * This class prints Java primitive values and object to a stream as 54: * text. None of the methods in this class throw an exception. However, 55: * errors can be detected by calling the <code>checkError()</code> method. 56: * Additionally, this stream can be designated as "autoflush" when 57: * created so that any writes are automatically flushed to the underlying 58: * output sink when the current line is terminated. 59: * <p> 60: * This class converts char's into byte's using the system default encoding. 61: * 62: * @author Aaron M. Renn (arenn@urbanophile.com) 63: * @author Tom Tromey (tromey@cygnus.com) 64: * @author Andrew John Hughes (gnu_andrew@member.fsf.org) 65: */ 66: public class PrintStream extends FilterOutputStream implements Appendable 67: { 68: /* Notice the implementation is quite similar to OutputStreamWriter. 69: * This leads to some minor duplication, because neither inherits 70: * from the other, and we want to maximize performance. */ 71: 72: // Line separator string. 73: private static final char[] line_separator 74: = SystemProperties.getProperty("line.separator", "\n").toCharArray(); 75: 76: /** 77: * Encoding name 78: */ 79: private String encoding; 80: 81: /** 82: * This boolean indicates whether or not an error has ever occurred 83: * on this stream. 84: */ 85: private boolean error_occurred = false; 86: 87: /** 88: * This is <code>true</code> if auto-flush is enabled, 89: * <code>false</code> otherwise 90: */ 91: private boolean auto_flush; 92: 93: /** 94: * This method initializes a new <code>PrintStream</code> object to write 95: * to the specified output File. Doesn't autoflush. 96: * 97: * @param file The <code>File</code> to write to. 98: * @throws FileNotFoundException if an error occurs while opening the file. 99: * 100: * @since 1.5 101: */ 102: public PrintStream (File file) 103: throws FileNotFoundException 104: { 105: this (new FileOutputStream(file), false); 106: } 107: 108: /** 109: * This method initializes a new <code>PrintStream</code> object to write 110: * to the specified output File. Doesn't autoflush. 111: * 112: * @param file The <code>File</code> to write to. 113: * @param encoding The name of the character encoding to use for this 114: * object. 115: * @throws FileNotFoundException If an error occurs while opening the file. 116: * @throws UnsupportedEncodingException If the charset specified by 117: * <code>encoding</code> is invalid. 118: * 119: * @since 1.5 120: */ 121: public PrintStream (File file, String encoding) 122: throws FileNotFoundException,UnsupportedEncodingException 123: { 124: this (new FileOutputStream(file), false, encoding); 125: } 126: 127: /** 128: * This method initializes a new <code>PrintStream</code> object to write 129: * to the specified output File. Doesn't autoflush. 130: * 131: * @param fileName The name of the <code>File</code> to write to. 132: * @throws FileNotFoundException if an error occurs while opening the file, 133: * 134: * @since 1.5 135: */ 136: public PrintStream (String fileName) 137: throws FileNotFoundException 138: { 139: this (new FileOutputStream(new File(fileName)), false); 140: } 141: 142: /** 143: * This method initializes a new <code>PrintStream</code> object to write 144: * to the specified output File. Doesn't autoflush. 145: * 146: * @param fileName The name of the <code>File</code> to write to. 147: * @param encoding The name of the character encoding to use for this 148: * object. 149: * @throws FileNotFoundException if an error occurs while opening the file. 150: * @throws UnsupportedEncodingException If the charset specified by 151: * <code>encoding</code> is invalid. 152: * 153: * @since 1.5 154: */ 155: public PrintStream (String fileName, String encoding) 156: throws FileNotFoundException,UnsupportedEncodingException 157: { 158: this (new FileOutputStream(new File(fileName)), false, encoding); 159: } 160: 161: /** 162: * This method initializes a new <code>PrintStream</code> object to write 163: * to the specified output sink. Doesn't autoflush. 164: * 165: * @param out The <code>OutputStream</code> to write to. 166: */ 167: public PrintStream (OutputStream out) 168: { 169: this (out, false); 170: } 171: 172: /** 173: * This method initializes a new <code>PrintStream</code> object to write 174: * to the specified output sink. This constructor also allows "auto-flush" 175: * functionality to be specified where the stream will be flushed after 176: * every <code>print</code> or <code>println</code> call, when the 177: * <code>write</code> methods with array arguments are called, or when a 178: * single new-line character is written. 179: * <p> 180: * 181: * @param out The <code>OutputStream</code> to write to. 182: * @param auto_flush <code>true</code> to flush the stream after every 183: * line, <code>false</code> otherwise 184: */ 185: public PrintStream (OutputStream out, boolean auto_flush) 186: { 187: super (out); 188: 189: try { 190: this.encoding = SystemProperties.getProperty("file.encoding"); 191: } catch (SecurityException e){ 192: this.encoding = "ISO8859_1"; 193: } catch (IllegalArgumentException e){ 194: this.encoding = "ISO8859_1"; 195: } catch (NullPointerException e){ 196: this.encoding = "ISO8859_1"; 197: } 198: this.auto_flush = auto_flush; 199: } 200: 201: /** 202: * This method initializes a new <code>PrintStream</code> object to write 203: * to the specified output sink. This constructor also allows "auto-flush" 204: * functionality to be specified where the stream will be flushed after 205: * every <code>print</code> or <code>println</code> call, when the 206: * <code>write</code> methods with array arguments are called, or when a 207: * single new-line character is written. 208: * <p> 209: * 210: * @param out The <code>OutputStream</code> to write to. 211: * @param auto_flush <code>true</code> to flush the stream after every 212: * line, <code>false</code> otherwise 213: * @param encoding The name of the character encoding to use for this 214: * object. 215: */ 216: public PrintStream (OutputStream out, boolean auto_flush, String encoding) 217: throws UnsupportedEncodingException 218: { 219: super (out); 220: 221: new String(new byte[]{0}, encoding); // check if encoding is supported 222: this.encoding = encoding; 223: this.auto_flush = auto_flush; 224: } 225: 226: /** 227: * This method checks to see if an error has occurred on this stream. Note 228: * that once an error has occurred, this method will continue to report 229: * <code>true</code> forever for this stream. Before checking for an 230: * error condition, this method flushes the stream. 231: * 232: * @return <code>true</code> if an error has occurred, 233: * <code>false</code> otherwise 234: */ 235: public boolean checkError () 236: { 237: flush (); 238: return error_occurred; 239: } 240: 241: /** 242: * This method can be called by subclasses to indicate that an error 243: * has occurred and should be reported by <code>checkError</code>. 244: */ 245: protected void setError () 246: { 247: error_occurred = true; 248: } 249: 250: /** 251: * This method closes this stream and all underlying streams. 252: */ 253: public void close () 254: { 255: try 256: { 257: flush(); 258: out.close(); 259: } 260: catch (InterruptedIOException iioe) 261: { 262: Thread.currentThread().interrupt(); 263: } 264: catch (IOException e) 265: { 266: setError (); 267: } 268: } 269: 270: /** 271: * This method flushes any buffered bytes to the underlying stream and 272: * then flushes that stream as well. 273: */ 274: public void flush () 275: { 276: try 277: { 278: out.flush(); 279: } 280: catch (InterruptedIOException iioe) 281: { 282: Thread.currentThread().interrupt(); 283: } 284: catch (IOException e) 285: { 286: setError (); 287: } 288: } 289: 290: private synchronized void print (String str, boolean println) 291: { 292: try 293: { 294: writeChars(str, 0, str.length()); 295: if (println) 296: writeChars(line_separator, 0, line_separator.length); 297: if (auto_flush) 298: flush(); 299: } 300: catch (InterruptedIOException iioe) 301: { 302: Thread.currentThread().interrupt(); 303: } 304: catch (IOException e) 305: { 306: setError (); 307: } 308: } 309: 310: private synchronized void print (char[] chars, int pos, int len, 311: boolean println) 312: { 313: try 314: { 315: writeChars(chars, pos, len); 316: if (println) 317: writeChars(line_separator, 0, line_separator.length); 318: if (auto_flush) 319: flush(); 320: } 321: catch (InterruptedIOException iioe) 322: { 323: Thread.currentThread().interrupt(); 324: } 325: catch (IOException e) 326: { 327: setError (); 328: } 329: } 330: 331: private void writeChars(char[] buf, int offset, int count) 332: throws IOException 333: { 334: byte[] bytes = (new String(buf, offset, count)).getBytes(encoding); 335: out.write(bytes, 0, bytes.length); 336: } 337: 338: private void writeChars(String str, int offset, int count) 339: throws IOException 340: { 341: byte[] bytes = str.substring(offset, offset+count).getBytes(encoding); 342: out.write(bytes, 0, bytes.length); 343: } 344: 345: /** 346: * This methods prints a boolean value to the stream. <code>true</code> 347: * values are printed as "true" and <code>false</code> values are printed 348: * as "false". 349: * 350: * @param bool The <code>boolean</code> value to print 351: */ 352: public void print (boolean bool) 353: { 354: print(String.valueOf(bool), false); 355: } 356: 357: /** 358: * This method prints an integer to the stream. The value printed is 359: * determined using the <code>String.valueOf()</code> method. 360: * 361: * @param inum The <code>int</code> value to be printed 362: */ 363: public void print (int inum) 364: { 365: print(String.valueOf(inum), false); 366: } 367: 368: /** 369: * This method prints a long to the stream. The value printed is 370: * determined using the <code>String.valueOf()</code> method. 371: * 372: * @param lnum The <code>long</code> value to be printed 373: */ 374: public void print (long lnum) 375: { 376: print(String.valueOf(lnum), false); 377: } 378: 379: /** 380: * This method prints a float to the stream. The value printed is 381: * determined using the <code>String.valueOf()</code> method. 382: * 383: * @param fnum The <code>float</code> value to be printed 384: */ 385: public void print (float fnum) 386: { 387: print(String.valueOf(fnum), false); 388: } 389: 390: /** 391: * This method prints a double to the stream. The value printed is 392: * determined using the <code>String.valueOf()</code> method. 393: * 394: * @param dnum The <code>double</code> value to be printed 395: */ 396: public void print (double dnum) 397: { 398: print(String.valueOf(dnum), false); 399: } 400: 401: /** 402: * This method prints an <code>Object</code> to the stream. The actual 403: * value printed is determined by calling the <code>String.valueOf()</code> 404: * method. 405: * 406: * @param obj The <code>Object</code> to print. 407: */ 408: public void print (Object obj) 409: { 410: print(obj == null ? "null" : obj.toString(), false); 411: } 412: 413: /** 414: * This method prints a <code>String</code> to the stream. The actual 415: * value printed depends on the system default encoding. 416: * 417: * @param str The <code>String</code> to print. 418: */ 419: public void print (String str) 420: { 421: print(str == null ? "null" : str, false); 422: } 423: 424: /** 425: * This method prints a char to the stream. The actual value printed is 426: * determined by the character encoding in use. 427: * 428: * @param ch The <code>char</code> value to be printed 429: */ 430: public synchronized void print (char ch) 431: { 432: print(new char[]{ch}, 0, 1, false); 433: } 434: 435: /** 436: * This method prints an array of characters to the stream. The actual 437: * value printed depends on the system default encoding. 438: * 439: * @param charArray The array of characters to print. 440: */ 441: public void print (char[] charArray) 442: { 443: print(charArray, 0, charArray.length, false); 444: } 445: 446: /** 447: * This method prints a line separator sequence to the stream. The value 448: * printed is determined by the system property <xmp>line.separator</xmp> 449: * and is not necessarily the Unix '\n' newline character. 450: */ 451: public void println () 452: { 453: print(line_separator, 0, line_separator.length, false); 454: } 455: 456: /** 457: * This methods prints a boolean value to the stream. <code>true</code> 458: * values are printed as "true" and <code>false</code> values are printed 459: * as "false". 460: * <p> 461: * This method prints a line termination sequence after printing the value. 462: * 463: * @param bool The <code>boolean</code> value to print 464: */ 465: public void println (boolean bool) 466: { 467: print(String.valueOf(bool), true); 468: } 469: 470: /** 471: * This method prints an integer to the stream. The value printed is 472: * determined using the <code>String.valueOf()</code> method. 473: * <p> 474: * This method prints a line termination sequence after printing the value. 475: * 476: * @param inum The <code>int</code> value to be printed 477: */ 478: public void println (int inum) 479: { 480: print(String.valueOf(inum), true); 481: } 482: 483: /** 484: * This method prints a long to the stream. The value printed is 485: * determined using the <code>String.valueOf()</code> method. 486: * <p> 487: * This method prints a line termination sequence after printing the value. 488: * 489: * @param lnum The <code>long</code> value to be printed 490: */ 491: public void println (long lnum) 492: { 493: print(String.valueOf(lnum), true); 494: } 495: 496: /** 497: * This method prints a float to the stream. The value printed is 498: * determined using the <code>String.valueOf()</code> method. 499: * <p> 500: * This method prints a line termination sequence after printing the value. 501: * 502: * @param fnum The <code>float</code> value to be printed 503: */ 504: public void println (float fnum) 505: { 506: print(String.valueOf(fnum), true); 507: } 508: 509: /** 510: * This method prints a double to the stream. The value printed is 511: * determined using the <code>String.valueOf()</code> method. 512: * <p> 513: * This method prints a line termination sequence after printing the value. 514: * 515: * @param dnum The <code>double</code> value to be printed 516: */ 517: public void println (double dnum) 518: { 519: print(String.valueOf(dnum), true); 520: } 521: 522: /** 523: * This method prints an <code>Object</code> to the stream. The actual 524: * value printed is determined by calling the <code>String.valueOf()</code> 525: * method. 526: * <p> 527: * This method prints a line termination sequence after printing the value. 528: * 529: * @param obj The <code>Object</code> to print. 530: */ 531: public void println (Object obj) 532: { 533: print(obj == null ? "null" : obj.toString(), true); 534: } 535: 536: /** 537: * This method prints a <code>String</code> to the stream. The actual 538: * value printed depends on the system default encoding. 539: * <p> 540: * This method prints a line termination sequence after printing the value. 541: * 542: * @param str The <code>String</code> to print. 543: */ 544: public void println (String str) 545: { 546: print (str == null ? "null" : str, true); 547: } 548: 549: /** 550: * This method prints a char to the stream. The actual value printed is 551: * determined by the character encoding in use. 552: * <p> 553: * This method prints a line termination sequence after printing the value. 554: * 555: * @param ch The <code>char</code> value to be printed 556: */ 557: public synchronized void println (char ch) 558: { 559: print(new char[]{ch}, 0, 1, true); 560: } 561: 562: /** 563: * This method prints an array of characters to the stream. The actual 564: * value printed depends on the system default encoding. 565: * <p> 566: * This method prints a line termination sequence after printing the value. 567: * 568: * @param charArray The array of characters to print. 569: */ 570: public void println (char[] charArray) 571: { 572: print(charArray, 0, charArray.length, true); 573: } 574: 575: /** 576: * This method writes a byte of data to the stream. If auto-flush is 577: * enabled, printing a newline character will cause the stream to be 578: * flushed after the character is written. 579: * 580: * @param oneByte The byte to be written 581: */ 582: public void write (int oneByte) 583: { 584: try 585: { 586: out.write (oneByte & 0xff); 587: 588: if (auto_flush && (oneByte == '\n')) 589: flush (); 590: } 591: catch (InterruptedIOException iioe) 592: { 593: Thread.currentThread ().interrupt (); 594: } 595: catch (IOException e) 596: { 597: setError (); 598: } 599: } 600: 601: /** 602: * This method writes <code>len</code> bytes from the specified array 603: * starting at index <code>offset</code> into the array. 604: * 605: * @param buffer The array of bytes to write 606: * @param offset The index into the array to start writing from 607: * @param len The number of bytes to write 608: */ 609: public void write (byte[] buffer, int offset, int len) 610: { 611: try 612: { 613: out.write (buffer, offset, len); 614: 615: if (auto_flush) 616: flush (); 617: } 618: catch (InterruptedIOException iioe) 619: { 620: Thread.currentThread ().interrupt (); 621: } 622: catch (IOException e) 623: { 624: setError (); 625: } 626: } 627: 628: /** @since 1.5 */ 629: public PrintStream append(char c) 630: { 631: print(c); 632: return this; 633: } 634: 635: /** @since 1.5 */ 636: public PrintStream append(CharSequence cs) 637: { 638: print(cs == null ? "null" : cs.toString()); 639: return this; 640: } 641: 642: /** @since 1.5 */ 643: public PrintStream append(CharSequence cs, int start, int end) 644: { 645: print(cs == null ? "null" : cs.subSequence(start, end).toString()); 646: return this; 647: } 648: 649: /** @since 1.5 */ 650: public PrintStream printf(String format, Object... args) 651: { 652: return format(format, args); 653: } 654: 655: /** @since 1.5 */ 656: public PrintStream printf(Locale locale, String format, Object... args) 657: { 658: return format(locale, format, args); 659: } 660: 661: /** @since 1.5 */ 662: public PrintStream format(String format, Object... args) 663: { 664: return format(Locale.getDefault(), format, args); 665: } 666: 667: /** @since 1.5 */ 668: public PrintStream format(Locale locale, String format, Object... args) 669: { 670: Formatter f = new Formatter(this, locale); 671: f.format(format, args); 672: return this; 673: } 674: } // class PrintStream
GNU Classpath (0.95) |