Source for java.io.PrintStream

   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:    */
  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:    */
 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:    */
 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:    */
 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:    */
 170:   protected void setError ()
 171:   {
 172:     error_occurred = true;
 173:   }
 174: 
 175:   /**
 176:    * This method closes this stream and all underlying streams.
 177:    */
 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:    */
 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: 
 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: 
 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: 
 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: 
 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:    */
 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:    */
 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:    */
 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:    */
 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:    */
 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:    */
 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:    */
 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:    */
 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:    */
 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:    */
 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:    */
 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:    */
 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:    */
 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:    */
 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:    */
 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:    */
 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:    */
 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:    */
 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:    */
 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:    */
 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:    */
 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