GNU Classpath (0.97.2) | |
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 final 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 final 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: String encoding; 189: try { 190: encoding = SystemProperties.getProperty("file.encoding"); 191: } catch (SecurityException e){ 192: encoding = "ISO8859_1"; 193: } catch (IllegalArgumentException e){ 194: encoding = "ISO8859_1"; 195: } catch (NullPointerException e){ 196: encoding = "ISO8859_1"; 197: } 198: this.encoding = encoding; 199: this.auto_flush = auto_flush; 200: } 201: 202: /** 203: * This method initializes a new <code>PrintStream</code> object to write 204: * to the specified output sink. This constructor also allows "auto-flush" 205: * functionality to be specified where the stream will be flushed after 206: * every <code>print</code> or <code>println</code> call, when the 207: * <code>write</code> methods with array arguments are called, or when a 208: * single new-line character is written. 209: * <p> 210: * 211: * @param out The <code>OutputStream</code> to write to. 212: * @param auto_flush <code>true</code> to flush the stream after every 213: * line, <code>false</code> otherwise 214: * @param encoding The name of the character encoding to use for this 215: * object. 216: */ 217: public PrintStream (OutputStream out, boolean auto_flush, String encoding) 218: throws UnsupportedEncodingException 219: { 220: super (out); 221: 222: new String(new byte[]{0}, encoding); // check if encoding is supported 223: this.encoding = encoding; 224: this.auto_flush = auto_flush; 225: } 226: 227: /** 228: * This method checks to see if an error has occurred on this stream. Note 229: * that once an error has occurred, this method will continue to report 230: * <code>true</code> forever for this stream. Before checking for an 231: * error condition, this method flushes the stream. 232: * 233: * @return <code>true</code> if an error has occurred, 234: * <code>false</code> otherwise 235: */ 236: public boolean checkError () 237: { 238: flush (); 239: return error_occurred; 240: } 241: 242: /** 243: * This method can be called by subclasses to indicate that an error 244: * has occurred and should be reported by <code>checkError</code>. 245: */ 246: protected void setError () 247: { 248: error_occurred = true; 249: } 250: 251: /** 252: * This method closes this stream and all underlying streams. 253: */ 254: public void close () 255: { 256: try 257: { 258: flush(); 259: out.close(); 260: } 261: catch (InterruptedIOException iioe) 262: { 263: Thread.currentThread().interrupt(); 264: } 265: catch (IOException e) 266: { 267: setError (); 268: } 269: } 270: 271: /** 272: * This method flushes any buffered bytes to the underlying stream and 273: * then flushes that stream as well. 274: */ 275: public void flush () 276: { 277: try 278: { 279: out.flush(); 280: } 281: catch (InterruptedIOException iioe) 282: { 283: Thread.currentThread().interrupt(); 284: } 285: catch (IOException e) 286: { 287: setError (); 288: } 289: } 290: 291: private synchronized void print (String str, boolean println) 292: { 293: try 294: { 295: writeChars(str, 0, str.length()); 296: if (println) 297: writeChars(line_separator, 0, line_separator.length); 298: if (auto_flush) 299: flush(); 300: } 301: catch (InterruptedIOException iioe) 302: { 303: Thread.currentThread().interrupt(); 304: } 305: catch (IOException e) 306: { 307: setError (); 308: } 309: } 310: 311: private synchronized void print (char[] chars, int pos, int len, 312: boolean println) 313: { 314: try 315: { 316: writeChars(chars, pos, len); 317: if (println) 318: writeChars(line_separator, 0, line_separator.length); 319: if (auto_flush) 320: flush(); 321: } 322: catch (InterruptedIOException iioe) 323: { 324: Thread.currentThread().interrupt(); 325: } 326: catch (IOException e) 327: { 328: setError (); 329: } 330: } 331: 332: private void writeChars(char[] buf, int offset, int count) 333: throws IOException 334: { 335: byte[] bytes = (new String(buf, offset, count)).getBytes(encoding); 336: out.write(bytes, 0, bytes.length); 337: } 338: 339: private void writeChars(String str, int offset, int count) 340: throws IOException 341: { 342: byte[] bytes = str.substring(offset, offset+count).getBytes(encoding); 343: out.write(bytes, 0, bytes.length); 344: } 345: 346: /** 347: * This methods prints a boolean value to the stream. <code>true</code> 348: * values are printed as "true" and <code>false</code> values are printed 349: * as "false". 350: * 351: * @param bool The <code>boolean</code> value to print 352: */ 353: public void print (boolean bool) 354: { 355: print(String.valueOf(bool), false); 356: } 357: 358: /** 359: * This method prints an integer to the stream. The value printed is 360: * determined using the <code>String.valueOf()</code> method. 361: * 362: * @param inum The <code>int</code> value to be printed 363: */ 364: public void print (int inum) 365: { 366: print(String.valueOf(inum), false); 367: } 368: 369: /** 370: * This method prints a long to the stream. The value printed is 371: * determined using the <code>String.valueOf()</code> method. 372: * 373: * @param lnum The <code>long</code> value to be printed 374: */ 375: public void print (long lnum) 376: { 377: print(String.valueOf(lnum), false); 378: } 379: 380: /** 381: * This method prints a float to the stream. The value printed is 382: * determined using the <code>String.valueOf()</code> method. 383: * 384: * @param fnum The <code>float</code> value to be printed 385: */ 386: public void print (float fnum) 387: { 388: print(String.valueOf(fnum), false); 389: } 390: 391: /** 392: * This method prints a double to the stream. The value printed is 393: * determined using the <code>String.valueOf()</code> method. 394: * 395: * @param dnum The <code>double</code> value to be printed 396: */ 397: public void print (double dnum) 398: { 399: print(String.valueOf(dnum), false); 400: } 401: 402: /** 403: * This method prints an <code>Object</code> to the stream. The actual 404: * value printed is determined by calling the <code>String.valueOf()</code> 405: * method. 406: * 407: * @param obj The <code>Object</code> to print. 408: */ 409: public void print (Object obj) 410: { 411: print(obj == null ? "null" : obj.toString(), false); 412: } 413: 414: /** 415: * This method prints a <code>String</code> to the stream. The actual 416: * value printed depends on the system default encoding. 417: * 418: * @param str The <code>String</code> to print. 419: */ 420: public void print (String str) 421: { 422: print(str == null ? "null" : str, false); 423: } 424: 425: /** 426: * This method prints a char to the stream. The actual value printed is 427: * determined by the character encoding in use. 428: * 429: * @param ch The <code>char</code> value to be printed 430: */ 431: public synchronized void print (char ch) 432: { 433: print(new char[]{ch}, 0, 1, false); 434: } 435: 436: /** 437: * This method prints an array of characters to the stream. The actual 438: * value printed depends on the system default encoding. 439: * 440: * @param charArray The array of characters to print. 441: */ 442: public void print (char[] charArray) 443: { 444: print(charArray, 0, charArray.length, false); 445: } 446: 447: /** 448: * This method prints a line separator sequence to the stream. The value 449: * printed is determined by the system property <xmp>line.separator</xmp> 450: * and is not necessarily the Unix '\n' newline character. 451: */ 452: public void println () 453: { 454: print(line_separator, 0, line_separator.length, false); 455: } 456: 457: /** 458: * This methods prints a boolean value to the stream. <code>true</code> 459: * values are printed as "true" and <code>false</code> values are printed 460: * as "false". 461: * <p> 462: * This method prints a line termination sequence after printing the value. 463: * 464: * @param bool The <code>boolean</code> value to print 465: */ 466: public void println (boolean bool) 467: { 468: print(String.valueOf(bool), true); 469: } 470: 471: /** 472: * This method prints an integer to the stream. The value printed is 473: * determined using the <code>String.valueOf()</code> method. 474: * <p> 475: * This method prints a line termination sequence after printing the value. 476: * 477: * @param inum The <code>int</code> value to be printed 478: */ 479: public void println (int inum) 480: { 481: print(String.valueOf(inum), true); 482: } 483: 484: /** 485: * This method prints a long to the stream. The value printed is 486: * determined using the <code>String.valueOf()</code> method. 487: * <p> 488: * This method prints a line termination sequence after printing the value. 489: * 490: * @param lnum The <code>long</code> value to be printed 491: */ 492: public void println (long lnum) 493: { 494: print(String.valueOf(lnum), true); 495: } 496: 497: /** 498: * This method prints a float to the stream. The value printed is 499: * determined using the <code>String.valueOf()</code> method. 500: * <p> 501: * This method prints a line termination sequence after printing the value. 502: * 503: * @param fnum The <code>float</code> value to be printed 504: */ 505: public void println (float fnum) 506: { 507: print(String.valueOf(fnum), true); 508: } 509: 510: /** 511: * This method prints a double to the stream. The value printed is 512: * determined using the <code>String.valueOf()</code> method. 513: * <p> 514: * This method prints a line termination sequence after printing the value. 515: * 516: * @param dnum The <code>double</code> value to be printed 517: */ 518: public void println (double dnum) 519: { 520: print(String.valueOf(dnum), true); 521: } 522: 523: /** 524: * This method prints an <code>Object</code> to the stream. The actual 525: * value printed is determined by calling the <code>String.valueOf()</code> 526: * method. 527: * <p> 528: * This method prints a line termination sequence after printing the value. 529: * 530: * @param obj The <code>Object</code> to print. 531: */ 532: public void println (Object obj) 533: { 534: print(obj == null ? "null" : obj.toString(), true); 535: } 536: 537: /** 538: * This method prints a <code>String</code> to the stream. The actual 539: * value printed depends on the system default encoding. 540: * <p> 541: * This method prints a line termination sequence after printing the value. 542: * 543: * @param str The <code>String</code> to print. 544: */ 545: public void println (String str) 546: { 547: print (str == null ? "null" : str, true); 548: } 549: 550: /** 551: * This method prints a char to the stream. The actual value printed is 552: * determined by the character encoding in use. 553: * <p> 554: * This method prints a line termination sequence after printing the value. 555: * 556: * @param ch The <code>char</code> value to be printed 557: */ 558: public synchronized void println (char ch) 559: { 560: print(new char[]{ch}, 0, 1, true); 561: } 562: 563: /** 564: * This method prints an array of characters to the stream. The actual 565: * value printed depends on the system default encoding. 566: * <p> 567: * This method prints a line termination sequence after printing the value. 568: * 569: * @param charArray The array of characters to print. 570: */ 571: public void println (char[] charArray) 572: { 573: print(charArray, 0, charArray.length, true); 574: } 575: 576: /** 577: * This method writes a byte of data to the stream. If auto-flush is 578: * enabled, printing a newline character will cause the stream to be 579: * flushed after the character is written. 580: * 581: * @param oneByte The byte to be written 582: */ 583: public void write (int oneByte) 584: { 585: try 586: { 587: out.write (oneByte & 0xff); 588: 589: if (auto_flush && (oneByte == '\n')) 590: flush (); 591: } 592: catch (InterruptedIOException iioe) 593: { 594: Thread.currentThread ().interrupt (); 595: } 596: catch (IOException e) 597: { 598: setError (); 599: } 600: } 601: 602: /** 603: * This method writes <code>len</code> bytes from the specified array 604: * starting at index <code>offset</code> into the array. 605: * 606: * @param buffer The array of bytes to write 607: * @param offset The index into the array to start writing from 608: * @param len The number of bytes to write 609: */ 610: public void write (byte[] buffer, int offset, int len) 611: { 612: try 613: { 614: out.write (buffer, offset, len); 615: 616: if (auto_flush) 617: flush (); 618: } 619: catch (InterruptedIOException iioe) 620: { 621: Thread.currentThread ().interrupt (); 622: } 623: catch (IOException e) 624: { 625: setError (); 626: } 627: } 628: 629: /** @since 1.5 */ 630: public PrintStream append(char c) 631: { 632: print(c); 633: return this; 634: } 635: 636: /** @since 1.5 */ 637: public PrintStream append(CharSequence cs) 638: { 639: print(cs == null ? "null" : cs.toString()); 640: return this; 641: } 642: 643: /** @since 1.5 */ 644: public PrintStream append(CharSequence cs, int start, int end) 645: { 646: print(cs == null ? "null" : cs.subSequence(start, end).toString()); 647: return this; 648: } 649: 650: /** @since 1.5 */ 651: public PrintStream printf(String format, Object... args) 652: { 653: return format(format, args); 654: } 655: 656: /** @since 1.5 */ 657: public PrintStream printf(Locale locale, String format, Object... args) 658: { 659: return format(locale, format, args); 660: } 661: 662: /** @since 1.5 */ 663: public PrintStream format(String format, Object... args) 664: { 665: return format(Locale.getDefault(), format, args); 666: } 667: 668: /** @since 1.5 */ 669: public PrintStream format(Locale locale, String format, Object... args) 670: { 671: Formatter f = new Formatter(this, locale); 672: f.format(format, args); 673: return this; 674: } 675: } // class PrintStream
GNU Classpath (0.97.2) |