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