1 /*
   2  * Copyright (c) 1996, 2006, Oracle and/or its affiliates. All rights reserved.
   3  * DO NOT ALTER OR REMOVE COPYRIGHT NOTICES OR THIS FILE HEADER.
   4  *
   5  * This code is free software; you can redistribute it and/or modify it
   6  * under the terms of the GNU General Public License version 2 only, as
   7  * published by the Free Software Foundation.  Oracle designates this
   8  * particular file as subject to the "Classpath" exception as provided
   9  * by Oracle in the LICENSE file that accompanied this code.
  10  *
  11  * This code is distributed in the hope that it will be useful, but WITHOUT
  12  * ANY WARRANTY; without even the implied warranty of MERCHANTABILITY or
  13  * FITNESS FOR A PARTICULAR PURPOSE.  See the GNU General Public License
  14  * version 2 for more details (a copy is included in the LICENSE file that
  15  * accompanied this code).
  16  *
  17  * You should have received a copy of the GNU General Public License version
  18  * 2 along with this work; if not, write to the Free Software Foundation,
  19  * Inc., 51 Franklin St, Fifth Floor, Boston, MA 02110-1301 USA.
  20  *
  21  * Please contact Oracle, 500 Oracle Parkway, Redwood Shores, CA 94065 USA
  22  * or visit www.oracle.com if you need additional information or have any
  23  * questions.
  24  */
  25 
  26 package java.io;
  27 
  28 import java.util.Formatter;
  29 import java.util.Locale;
  30 import java.nio.charset.Charset;
  31 import java.nio.charset.IllegalCharsetNameException;
  32 
  33 /**
  34  * A <code>PrintStream</code> adds functionality to another output stream,
  35  * namely the ability to print representations of various data values
  36  * conveniently.  Two other features are provided as well.  Unlike other output
  37  * streams, a <code>PrintStream</code> never throws an
  38  * <code>IOException</code>; instead, exceptional situations merely set an
  39  * internal flag that can be tested via the <code>checkError</code> method.
  40  * Optionally, a <code>PrintStream</code> can be created so as to flush
  41  * automatically; this means that the <code>flush</code> method is
  42  * automatically invoked after a byte array is written, one of the
  43  * <code>println</code> methods is invoked, or a newline character or byte
  44  * (<code>'\n'</code>) is written.
  45  *
  46  * <p> All characters printed by a <code>PrintStream</code> are converted into
  47  * bytes using the platform's default character encoding.  The <code>{@link
  48  * PrintWriter}</code> class should be used in situations that require writing
  49  * characters rather than bytes.
  50  *
  51  * @author     Frank Yellin
  52  * @author     Mark Reinhold
  53  * @since      JDK1.0
  54  */
  55 
  56 public class PrintStream extends FilterOutputStream
  57     implements Appendable, Closeable
  58 {
  59 
  60     private final boolean autoFlush;
  61     private boolean trouble = false;
  62     private Formatter formatter;
  63 
  64     /**
  65      * Track both the text- and character-output streams, so that their buffers
  66      * can be flushed without flushing the entire stream.
  67      */
  68     private BufferedWriter textOut;
  69     private OutputStreamWriter charOut;
  70 
  71     /**
  72      * nonNull is explicitly delcared here so as not to create an extra
  73      * dependency on java.util.Objects.nonNull. PrintStream is loaded
  74      * early during system initialization.
  75      */
  76     private static <T> T nonNull(T obj, String message) {
  77         if (obj == null)
  78             throw new NullPointerException(message);
  79         return obj;
  80     }
  81 
  82     /**
  83      * Returns a charset object for the given charset name.
  84      * @throws NullPointerException          is csn is null
  85      * @throws UnsupportedEncodingException  if the charset is not supported
  86      */
  87     private static Charset toCharset(String csn)
  88             throws UnsupportedEncodingException {
  89         nonNull(csn, "charsetName");
  90         try {
  91             return Charset.forName(csn);
  92         } catch (IllegalCharsetNameException unused) {
  93             /* swallow this exception since UnsupportedEncodingException
  94              * will be thrown */
  95         }
  96         throw new UnsupportedEncodingException(csn);
  97     }
  98 
  99     /* Private constructors */
 100     private PrintStream(boolean autoFlush, OutputStream out) {
 101         super(out);
 102         this.autoFlush = autoFlush;
 103         this.charOut = new OutputStreamWriter(this);
 104         this.textOut = new BufferedWriter(charOut);
 105     }
 106     
 107     private PrintStream(boolean autoFlush, OutputStream out, Charset charset) {
 108         super(out);
 109         this.autoFlush = autoFlush;
 110         this.charOut = new OutputStreamWriter(this, charset);
 111         this.textOut = new BufferedWriter(charOut);
 112     }
 113     
 114     /* Variant of the private constructor so that the given charset name
 115      * can be verified before evaluating the OutputStream argument. Used
 116      * by constructors creating a FileOutputStream that also take a
 117      * charset name.
 118      */
 119     private PrintStream(boolean autoFlush, Charset charset, OutputStream out)
 120             throws UnsupportedEncodingException {
 121         this(autoFlush, out, charset);
 122     }
 123 
 124     /**
 125      * Creates a new print stream.  This stream will not flush automatically.
 126      *
 127      * @param  out        The output stream to which values and objects will be
 128      *                    printed
 129      *
 130      * @see java.io.PrintWriter#PrintWriter(java.io.OutputStream)
 131      */
 132     public PrintStream(OutputStream out) {
 133         this(out, false);
 134     }
 135 
 136     /**
 137      * Creates a new print stream.
 138      *
 139      * @param  out        The output stream to which values and objects will be
 140      *                    printed
 141      * @param  autoFlush  A boolean; if true, the output buffer will be flushed
 142      *                    whenever a byte array is written, one of the
 143      *                    <code>println</code> methods is invoked, or a newline
 144      *                    character or byte (<code>'\n'</code>) is written
 145      *
 146      * @see java.io.PrintWriter#PrintWriter(java.io.OutputStream, boolean)
 147      */
 148     public PrintStream(OutputStream out, boolean autoFlush) {
 149         this(autoFlush, nonNull(out, "Null output stream"));
 150     }
 151 
 152     /**
 153      * Creates a new print stream.
 154      *
 155      * @param  out        The output stream to which values and objects will be
 156      *                    printed
 157      * @param  autoFlush  A boolean; if true, the output buffer will be flushed
 158      *                    whenever a byte array is written, one of the
 159      *                    <code>println</code> methods is invoked, or a newline
 160      *                    character or byte (<code>'\n'</code>) is written
 161      * @param  encoding   The name of a supported
 162      *                    <a href="../lang/package-summary.html#charenc">
 163      *                    character encoding</a>
 164      *
 165      * @throws  UnsupportedEncodingException
 166      *          If the named encoding is not supported
 167      *
 168      * @since  1.4
 169      */
 170     public PrintStream(OutputStream out, boolean autoFlush, String encoding)
 171         throws UnsupportedEncodingException
 172     {
 173         this(autoFlush,
 174              nonNull(out, "Null output stream"),
 175              toCharset(encoding));
 176     }
 177 
 178     /**
 179      * Creates a new print stream, without automatic line flushing, with the
 180      * specified file name.  This convenience constructor creates
 181      * the necessary intermediate {@link java.io.OutputStreamWriter
 182      * OutputStreamWriter}, which will encode characters using the
 183      * {@linkplain java.nio.charset.Charset#defaultCharset() default charset}
 184      * for this instance of the Java virtual machine.
 185      *
 186      * @param  fileName
 187      *         The name of the file to use as the destination of this print
 188      *         stream.  If the file exists, then it will be truncated to
 189      *         zero size; otherwise, a new file will be created.  The output
 190      *         will be written to the file and is buffered.
 191      *
 192      * @throws  FileNotFoundException
 193      *          If the given file object does not denote an existing, writable
 194      *          regular file and a new regular file of that name cannot be
 195      *          created, or if some other error occurs while opening or
 196      *          creating the file
 197      *
 198      * @throws  SecurityException
 199      *          If a security manager is present and {@link
 200      *          SecurityManager#checkWrite checkWrite(fileName)} denies write
 201      *          access to the file
 202      *
 203      * @since  1.5
 204      */
 205     public PrintStream(String fileName) throws FileNotFoundException {
 206         this(false, new FileOutputStream(fileName));
 207     }
 208 
 209     /**
 210      * Creates a new print stream, without automatic line flushing, with the
 211      * specified file name and charset.  This convenience constructor creates
 212      * the necessary intermediate {@link java.io.OutputStreamWriter
 213      * OutputStreamWriter}, which will encode characters using the provided
 214      * charset.
 215      *
 216      * @param  fileName
 217      *         The name of the file to use as the destination of this print
 218      *         stream.  If the file exists, then it will be truncated to
 219      *         zero size; otherwise, a new file will be created.  The output
 220      *         will be written to the file and is buffered.
 221      *
 222      * @param  csn
 223      *         The name of a supported {@linkplain java.nio.charset.Charset
 224      *         charset}
 225      *
 226      * @throws  FileNotFoundException
 227      *          If the given file object does not denote an existing, writable
 228      *          regular file and a new regular file of that name cannot be
 229      *          created, or if some other error occurs while opening or
 230      *          creating the file
 231      *
 232      * @throws  SecurityException
 233      *          If a security manager is present and {@link
 234      *          SecurityManager#checkWrite checkWrite(fileName)} denies write
 235      *          access to the file
 236      *
 237      * @throws  UnsupportedEncodingException
 238      *          If the named charset is not supported
 239      *
 240      * @since  1.5
 241      */
 242     public PrintStream(String fileName, String csn)
 243         throws FileNotFoundException, UnsupportedEncodingException
 244     {
 245         /* this(boolean,Charset,OutputStream) is invoked so the
 246          * charset name can be verified before creating an output
 247          * stream to the file. */
 248         this(false, toCharset(csn), new FileOutputStream(fileName));
 249     }
 250 
 251     /**
 252      * Creates a new print stream, without automatic line flushing, with the
 253      * specified file.  This convenience constructor creates the necessary
 254      * intermediate {@link java.io.OutputStreamWriter OutputStreamWriter},
 255      * which will encode characters using the {@linkplain
 256      * java.nio.charset.Charset#defaultCharset() default charset} for this
 257      * instance of the Java virtual machine.
 258      *
 259      * @param  file
 260      *         The file to use as the destination of this print stream.  If the
 261      *         file exists, then it will be truncated to zero size; otherwise,
 262      *         a new file will be created.  The output will be written to the
 263      *         file and is buffered.
 264      *
 265      * @throws  FileNotFoundException
 266      *          If the given file object does not denote an existing, writable
 267      *          regular file and a new regular file of that name cannot be
 268      *          created, or if some other error occurs while opening or
 269      *          creating the file
 270      *
 271      * @throws  SecurityException
 272      *          If a security manager is present and {@link
 273      *          SecurityManager#checkWrite checkWrite(file.getPath())}
 274      *          denies write access to the file
 275      *
 276      * @since  1.5
 277      */
 278     public PrintStream(File file) throws FileNotFoundException {
 279         this(false, new FileOutputStream(file));
 280     }
 281 
 282     /**
 283      * Creates a new print stream, without automatic line flushing, with the
 284      * specified file and charset.  This convenience constructor creates
 285      * the necessary intermediate {@link java.io.OutputStreamWriter
 286      * OutputStreamWriter}, which will encode characters using the provided
 287      * charset.
 288      *
 289      * @param  file
 290      *         The file to use as the destination of this print stream.  If the
 291      *         file exists, then it will be truncated to zero size; otherwise,
 292      *         a new file will be created.  The output will be written to the
 293      *         file and is buffered.
 294      *
 295      * @param  csn
 296      *         The name of a supported {@linkplain java.nio.charset.Charset
 297      *         charset}
 298      *
 299      * @throws  FileNotFoundException
 300      *          If the given file object does not denote an existing, writable
 301      *          regular file and a new regular file of that name cannot be
 302      *          created, or if some other error occurs while opening or
 303      *          creating the file
 304      *
 305      * @throws  SecurityException
 306      *          If a security manager is presentand {@link
 307      *          SecurityManager#checkWrite checkWrite(file.getPath())}
 308      *          denies write access to the file
 309      *
 310      * @throws  UnsupportedEncodingException
 311      *          If the named charset is not supported
 312      *
 313      * @since  1.5
 314      */
 315     public PrintStream(File file, String csn)
 316         throws FileNotFoundException, UnsupportedEncodingException
 317     {
 318         /* this(boolean,Charset,OutputStream) is invoked so the
 319          * charset name can be verified before creating an output
 320          * stream to the file. */
 321         this(false, toCharset(csn), new FileOutputStream(file));
 322     }
 323 
 324     /** Check to make sure that the stream has not been closed */
 325     private void ensureOpen() throws IOException {
 326         if (out == null)
 327             throw new IOException("Stream closed");
 328     }
 329 
 330     /**
 331      * Flushes the stream.  This is done by writing any buffered output bytes to
 332      * the underlying output stream and then flushing that stream.
 333      *
 334      * @see        java.io.OutputStream#flush()
 335      */
 336     public void flush() {
 337         synchronized (this) {
 338             try {
 339                 ensureOpen();
 340                 out.flush();
 341             }
 342             catch (IOException x) {
 343                 trouble = true;
 344             }
 345         }
 346     }
 347 
 348     private boolean closing = false; /* To avoid recursive closing */
 349 
 350     /**
 351      * Closes the stream.  This is done by flushing the stream and then closing
 352      * the underlying output stream.
 353      *
 354      * @see        java.io.OutputStream#close()
 355      */
 356     public void close() {
 357         synchronized (this) {
 358             if (! closing) {
 359                 closing = true;
 360                 try {
 361                     textOut.close();
 362                     out.close();
 363                 }
 364                 catch (IOException x) {
 365                     trouble = true;
 366                 }
 367                 textOut = null;
 368                 charOut = null;
 369                 out = null;
 370             }
 371         }
 372     }
 373 
 374     /**
 375      * Flushes the stream and checks its error state. The internal error state
 376      * is set to <code>true</code> when the underlying output stream throws an
 377      * <code>IOException</code> other than <code>InterruptedIOException</code>,
 378      * and when the <code>setError</code> method is invoked.  If an operation
 379      * on the underlying output stream throws an
 380      * <code>InterruptedIOException</code>, then the <code>PrintStream</code>
 381      * converts the exception back into an interrupt by doing:
 382      * <pre>
 383      *     Thread.currentThread().interrupt();
 384      * </pre>
 385      * or the equivalent.
 386      *
 387      * @return <code>true</code> if and only if this stream has encountered an
 388      *         <code>IOException</code> other than
 389      *         <code>InterruptedIOException</code>, or the
 390      *         <code>setError</code> method has been invoked
 391      */
 392     public boolean checkError() {
 393         if (out != null)
 394             flush();
 395         if (out instanceof java.io.PrintStream) {
 396             PrintStream ps = (PrintStream) out;
 397             return ps.checkError();
 398         }
 399         return trouble;
 400     }
 401 
 402     /**
 403      * Sets the error state of the stream to <code>true</code>.
 404      *
 405      * <p> This method will cause subsequent invocations of {@link
 406      * #checkError()} to return <tt>true</tt> until {@link
 407      * #clearError()} is invoked.
 408      *
 409      * @since JDK1.1
 410      */
 411     protected void setError() {
 412         trouble = true;
 413     }
 414 
 415     /**
 416      * Clears the internal error state of this stream.
 417      *
 418      * <p> This method will cause subsequent invocations of {@link
 419      * #checkError()} to return <tt>false</tt> until another write
 420      * operation fails and invokes {@link #setError()}.
 421      *
 422      * @since 1.6
 423      */
 424     protected void clearError() {
 425         trouble = false;
 426     }
 427 
 428     /*
 429      * Exception-catching, synchronized output operations,
 430      * which also implement the write() methods of OutputStream
 431      */
 432 
 433     /**
 434      * Writes the specified byte to this stream.  If the byte is a newline and
 435      * automatic flushing is enabled then the <code>flush</code> method will be
 436      * invoked.
 437      *
 438      * <p> Note that the byte is written as given; to write a character that
 439      * will be translated according to the platform's default character
 440      * encoding, use the <code>print(char)</code> or <code>println(char)</code>
 441      * methods.
 442      *
 443      * @param  b  The byte to be written
 444      * @see #print(char)
 445      * @see #println(char)
 446      */
 447     public void write(int b) {
 448         try {
 449             synchronized (this) {
 450                 ensureOpen();
 451                 out.write(b);
 452                 if ((b == '\n') && autoFlush)
 453                     out.flush();
 454             }
 455         }
 456         catch (InterruptedIOException x) {
 457             Thread.currentThread().interrupt();
 458         }
 459         catch (IOException x) {
 460             trouble = true;
 461         }
 462     }
 463 
 464     /**
 465      * Writes <code>len</code> bytes from the specified byte array starting at
 466      * offset <code>off</code> to this stream.  If automatic flushing is
 467      * enabled then the <code>flush</code> method will be invoked.
 468      *
 469      * <p> Note that the bytes will be written as given; to write characters
 470      * that will be translated according to the platform's default character
 471      * encoding, use the <code>print(char)</code> or <code>println(char)</code>
 472      * methods.
 473      *
 474      * @param  buf   A byte array
 475      * @param  off   Offset from which to start taking bytes
 476      * @param  len   Number of bytes to write
 477      */
 478     public void write(byte buf[], int off, int len) {
 479         try {
 480             synchronized (this) {
 481                 ensureOpen();
 482                 out.write(buf, off, len);
 483                 if (autoFlush)
 484                     out.flush();
 485             }
 486         }
 487         catch (InterruptedIOException x) {
 488             Thread.currentThread().interrupt();
 489         }
 490         catch (IOException x) {
 491             trouble = true;
 492         }
 493     }
 494 
 495     /*
 496      * The following private methods on the text- and character-output streams
 497      * always flush the stream buffers, so that writes to the underlying byte
 498      * stream occur as promptly as with the original PrintStream.
 499      */
 500 
 501     private void write(char buf[]) {
 502         try {
 503             synchronized (this) {
 504                 ensureOpen();
 505                 textOut.write(buf);
 506                 textOut.flushBuffer();
 507                 charOut.flushBuffer();
 508                 if (autoFlush) {
 509                     for (int i = 0; i < buf.length; i++)
 510                         if (buf[i] == '\n')
 511                             out.flush();
 512                 }
 513             }
 514         }
 515         catch (InterruptedIOException x) {
 516             Thread.currentThread().interrupt();
 517         }
 518         catch (IOException x) {
 519             trouble = true;
 520         }
 521     }
 522 
 523     private void write(String s) {
 524         try {
 525             synchronized (this) {
 526                 ensureOpen();
 527                 textOut.write(s);
 528                 textOut.flushBuffer();
 529                 charOut.flushBuffer();
 530                 if (autoFlush && (s.indexOf('\n') >= 0))
 531                     out.flush();
 532             }
 533         }
 534         catch (InterruptedIOException x) {
 535             Thread.currentThread().interrupt();
 536         }
 537         catch (IOException x) {
 538             trouble = true;
 539         }
 540     }
 541 
 542     private void newLine() {
 543         try {
 544             synchronized (this) {
 545                 ensureOpen();
 546                 textOut.newLine();
 547                 textOut.flushBuffer();
 548                 charOut.flushBuffer();
 549                 if (autoFlush)
 550                     out.flush();
 551             }
 552         }
 553         catch (InterruptedIOException x) {
 554             Thread.currentThread().interrupt();
 555         }
 556         catch (IOException x) {
 557             trouble = true;
 558         }
 559     }
 560 
 561     /* Methods that do not terminate lines */
 562 
 563     /**
 564      * Prints a boolean value.  The string produced by <code>{@link
 565      * java.lang.String#valueOf(boolean)}</code> is translated into bytes
 566      * according to the platform's default character encoding, and these bytes
 567      * are written in exactly the manner of the
 568      * <code>{@link #write(int)}</code> method.
 569      *
 570      * @param      b   The <code>boolean</code> to be printed
 571      */
 572     public void print(boolean b) {
 573         write(b ? "true" : "false");
 574     }
 575 
 576     /**
 577      * Prints a character.  The character is translated into one or more bytes
 578      * according to the platform's default character encoding, and these bytes
 579      * are written in exactly the manner of the
 580      * <code>{@link #write(int)}</code> method.
 581      *
 582      * @param      c   The <code>char</code> to be printed
 583      */
 584     public void print(char c) {
 585         write(String.valueOf(c));
 586     }
 587 
 588     /**
 589      * Prints an integer.  The string produced by <code>{@link
 590      * java.lang.String#valueOf(int)}</code> is translated into bytes
 591      * according to the platform's default character encoding, and these bytes
 592      * are written in exactly the manner of the
 593      * <code>{@link #write(int)}</code> method.
 594      *
 595      * @param      i   The <code>int</code> to be printed
 596      * @see        java.lang.Integer#toString(int)
 597      */
 598     public void print(int i) {
 599         write(String.valueOf(i));
 600     }
 601 
 602     /**
 603      * Prints a long integer.  The string produced by <code>{@link
 604      * java.lang.String#valueOf(long)}</code> is translated into bytes
 605      * according to the platform's default character encoding, and these bytes
 606      * are written in exactly the manner of the
 607      * <code>{@link #write(int)}</code> method.
 608      *
 609      * @param      l   The <code>long</code> to be printed
 610      * @see        java.lang.Long#toString(long)
 611      */
 612     public void print(long l) {
 613         write(String.valueOf(l));
 614     }
 615 
 616     /**
 617      * Prints a floating-point number.  The string produced by <code>{@link
 618      * java.lang.String#valueOf(float)}</code> is translated into bytes
 619      * according to the platform's default character encoding, and these bytes
 620      * are written in exactly the manner of the
 621      * <code>{@link #write(int)}</code> method.
 622      *
 623      * @param      f   The <code>float</code> to be printed
 624      * @see        java.lang.Float#toString(float)
 625      */
 626     public void print(float f) {
 627         write(String.valueOf(f));
 628     }
 629 
 630     /**
 631      * Prints a double-precision floating-point number.  The string produced by
 632      * <code>{@link java.lang.String#valueOf(double)}</code> is translated into
 633      * bytes according to the platform's default character encoding, and these
 634      * bytes are written in exactly the manner of the <code>{@link
 635      * #write(int)}</code> method.
 636      *
 637      * @param      d   The <code>double</code> to be printed
 638      * @see        java.lang.Double#toString(double)
 639      */
 640     public void print(double d) {
 641         write(String.valueOf(d));
 642     }
 643 
 644     /**
 645      * Prints an array of characters.  The characters are converted into bytes
 646      * according to the platform's default character encoding, and these bytes
 647      * are written in exactly the manner of the
 648      * <code>{@link #write(int)}</code> method.
 649      *
 650      * @param      s   The array of chars to be printed
 651      *
 652      * @throws  NullPointerException  If <code>s</code> is <code>null</code>
 653      */
 654     public void print(char s[]) {
 655         write(s);
 656     }
 657 
 658     /**
 659      * Prints a string.  If the argument is <code>null</code> then the string
 660      * <code>"null"</code> is printed.  Otherwise, the string's characters are
 661      * converted into bytes according to the platform's default character
 662      * encoding, and these bytes are written in exactly the manner of the
 663      * <code>{@link #write(int)}</code> method.
 664      *
 665      * @param      s   The <code>String</code> to be printed
 666      */
 667     public void print(String s) {
 668         if (s == null) {
 669             s = "null";
 670         }
 671         write(s);
 672     }
 673 
 674     /**
 675      * Prints an object.  The string produced by the <code>{@link
 676      * java.lang.String#valueOf(Object)}</code> method is translated into bytes
 677      * according to the platform's default character encoding, and these bytes
 678      * are written in exactly the manner of the
 679      * <code>{@link #write(int)}</code> method.
 680      *
 681      * @param      obj   The <code>Object</code> to be printed
 682      * @see        java.lang.Object#toString()
 683      */
 684     public void print(Object obj) {
 685         write(String.valueOf(obj));
 686     }
 687 
 688 
 689     /* Methods that do terminate lines */
 690 
 691     /**
 692      * Terminates the current line by writing the line separator string.  The
 693      * line separator string is defined by the system property
 694      * <code>line.separator</code>, and is not necessarily a single newline
 695      * character (<code>'\n'</code>).
 696      */
 697     public void println() {
 698         newLine();
 699     }
 700 
 701     /**
 702      * Prints a boolean and then terminate the line.  This method behaves as
 703      * though it invokes <code>{@link #print(boolean)}</code> and then
 704      * <code>{@link #println()}</code>.
 705      *
 706      * @param x  The <code>boolean</code> to be printed
 707      */
 708     public void println(boolean x) {
 709         synchronized (this) {
 710             print(x);
 711             newLine();
 712         }
 713     }
 714 
 715     /**
 716      * Prints a character and then terminate the line.  This method behaves as
 717      * though it invokes <code>{@link #print(char)}</code> and then
 718      * <code>{@link #println()}</code>.
 719      *
 720      * @param x  The <code>char</code> to be printed.
 721      */
 722     public void println(char x) {
 723         synchronized (this) {
 724             print(x);
 725             newLine();
 726         }
 727     }
 728 
 729     /**
 730      * Prints an integer and then terminate the line.  This method behaves as
 731      * though it invokes <code>{@link #print(int)}</code> and then
 732      * <code>{@link #println()}</code>.
 733      *
 734      * @param x  The <code>int</code> to be printed.
 735      */
 736     public void println(int x) {
 737         synchronized (this) {
 738             print(x);
 739             newLine();
 740         }
 741     }
 742 
 743     /**
 744      * Prints a long and then terminate the line.  This method behaves as
 745      * though it invokes <code>{@link #print(long)}</code> and then
 746      * <code>{@link #println()}</code>.
 747      *
 748      * @param x  a The <code>long</code> to be printed.
 749      */
 750     public void println(long x) {
 751         synchronized (this) {
 752             print(x);
 753             newLine();
 754         }
 755     }
 756 
 757     /**
 758      * Prints a float and then terminate the line.  This method behaves as
 759      * though it invokes <code>{@link #print(float)}</code> and then
 760      * <code>{@link #println()}</code>.
 761      *
 762      * @param x  The <code>float</code> to be printed.
 763      */
 764     public void println(float x) {
 765         synchronized (this) {
 766             print(x);
 767             newLine();
 768         }
 769     }
 770 
 771     /**
 772      * Prints a double and then terminate the line.  This method behaves as
 773      * though it invokes <code>{@link #print(double)}</code> and then
 774      * <code>{@link #println()}</code>.
 775      *
 776      * @param x  The <code>double</code> to be printed.
 777      */
 778     public void println(double x) {
 779         synchronized (this) {
 780             print(x);
 781             newLine();
 782         }
 783     }
 784 
 785     /**
 786      * Prints an array of characters and then terminate the line.  This method
 787      * behaves as though it invokes <code>{@link #print(char[])}</code> and
 788      * then <code>{@link #println()}</code>.
 789      *
 790      * @param x  an array of chars to print.
 791      */
 792     public void println(char x[]) {
 793         synchronized (this) {
 794             print(x);
 795             newLine();
 796         }
 797     }
 798 
 799     /**
 800      * Prints a String and then terminate the line.  This method behaves as
 801      * though it invokes <code>{@link #print(String)}</code> and then
 802      * <code>{@link #println()}</code>.
 803      *
 804      * @param x  The <code>String</code> to be printed.
 805      */
 806     public void println(String x) {
 807         synchronized (this) {
 808             print(x);
 809             newLine();
 810         }
 811     }
 812 
 813     /**
 814      * Prints an Object and then terminate the line.  This method calls
 815      * at first String.valueOf(x) to get the printed object's string value,
 816      * then behaves as
 817      * though it invokes <code>{@link #print(String)}</code> and then
 818      * <code>{@link #println()}</code>.
 819      *
 820      * @param x  The <code>Object</code> to be printed.
 821      */
 822     public void println(Object x) {
 823         String s = String.valueOf(x);
 824         synchronized (this) {
 825             print(s);
 826             newLine();
 827         }
 828     }
 829 
 830 
 831     /**
 832      * A convenience method to write a formatted string to this output stream
 833      * using the specified format string and arguments.
 834      *
 835      * <p> An invocation of this method of the form <tt>out.printf(format,
 836      * args)</tt> behaves in exactly the same way as the invocation
 837      *
 838      * <pre>
 839      *     out.format(format, args) </pre>
 840      *
 841      * @param  format
 842      *         A format string as described in <a
 843      *         href="../util/Formatter.html#syntax">Format string syntax</a>
 844      *
 845      * @param  args
 846      *         Arguments referenced by the format specifiers in the format
 847      *         string.  If there are more arguments than format specifiers, the
 848      *         extra arguments are ignored.  The number of arguments is
 849      *         variable and may be zero.  The maximum number of arguments is
 850      *         limited by the maximum dimension of a Java array as defined by
 851      *         the <a href="http://java.sun.com/docs/books/vmspec/">Java
 852      *         Virtual Machine Specification</a>.  The behaviour on a
 853      *         <tt>null</tt> argument depends on the <a
 854      *         href="../util/Formatter.html#syntax">conversion</a>.
 855      *
 856      * @throws  IllegalFormatException
 857      *          If a format string contains an illegal syntax, a format
 858      *          specifier that is incompatible with the given arguments,
 859      *          insufficient arguments given the format string, or other
 860      *          illegal conditions.  For specification of all possible
 861      *          formatting errors, see the <a
 862      *          href="../util/Formatter.html#detail">Details</a> section of the
 863      *          formatter class specification.
 864      *
 865      * @throws  NullPointerException
 866      *          If the <tt>format</tt> is <tt>null</tt>
 867      *
 868      * @return  This output stream
 869      *
 870      * @since  1.5
 871      */
 872     public PrintStream printf(String format, Object ... args) {
 873         return format(format, args);
 874     }
 875 
 876     /**
 877      * A convenience method to write a formatted string to this output stream
 878      * using the specified format string and arguments.
 879      *
 880      * <p> An invocation of this method of the form <tt>out.printf(l, format,
 881      * args)</tt> behaves in exactly the same way as the invocation
 882      *
 883      * <pre>
 884      *     out.format(l, format, args) </pre>
 885      *
 886      * @param  l
 887      *         The {@linkplain java.util.Locale locale} to apply during
 888      *         formatting.  If <tt>l</tt> is <tt>null</tt> then no localization
 889      *         is applied.
 890      *
 891      * @param  format
 892      *         A format string as described in <a
 893      *         href="../util/Formatter.html#syntax">Format string syntax</a>
 894      *
 895      * @param  args
 896      *         Arguments referenced by the format specifiers in the format
 897      *         string.  If there are more arguments than format specifiers, the
 898      *         extra arguments are ignored.  The number of arguments is
 899      *         variable and may be zero.  The maximum number of arguments is
 900      *         limited by the maximum dimension of a Java array as defined by
 901      *         the <a href="http://java.sun.com/docs/books/vmspec/">Java
 902      *         Virtual Machine Specification</a>.  The behaviour on a
 903      *         <tt>null</tt> argument depends on the <a
 904      *         href="../util/Formatter.html#syntax">conversion</a>.
 905      *
 906      * @throws  IllegalFormatException
 907      *          If a format string contains an illegal syntax, a format
 908      *          specifier that is incompatible with the given arguments,
 909      *          insufficient arguments given the format string, or other
 910      *          illegal conditions.  For specification of all possible
 911      *          formatting errors, see the <a
 912      *          href="../util/Formatter.html#detail">Details</a> section of the
 913      *          formatter class specification.
 914      *
 915      * @throws  NullPointerException
 916      *          If the <tt>format</tt> is <tt>null</tt>
 917      *
 918      * @return  This output stream
 919      *
 920      * @since  1.5
 921      */
 922     public PrintStream printf(Locale l, String format, Object ... args) {
 923         return format(l, format, args);
 924     }
 925 
 926     /**
 927      * Writes a formatted string to this output stream using the specified
 928      * format string and arguments.
 929      *
 930      * <p> The locale always used is the one returned by {@link
 931      * java.util.Locale#getDefault() Locale.getDefault()}, regardless of any
 932      * previous invocations of other formatting methods on this object.
 933      *
 934      * @param  format
 935      *         A format string as described in <a
 936      *         href="../util/Formatter.html#syntax">Format string syntax</a>
 937      *
 938      * @param  args
 939      *         Arguments referenced by the format specifiers in the format
 940      *         string.  If there are more arguments than format specifiers, the
 941      *         extra arguments are ignored.  The number of arguments is
 942      *         variable and may be zero.  The maximum number of arguments is
 943      *         limited by the maximum dimension of a Java array as defined by
 944      *         the <a href="http://java.sun.com/docs/books/vmspec/">Java
 945      *         Virtual Machine Specification</a>.  The behaviour on a
 946      *         <tt>null</tt> argument depends on the <a
 947      *         href="../util/Formatter.html#syntax">conversion</a>.
 948      *
 949      * @throws  IllegalFormatException
 950      *          If a format string contains an illegal syntax, a format
 951      *          specifier that is incompatible with the given arguments,
 952      *          insufficient arguments given the format string, or other
 953      *          illegal conditions.  For specification of all possible
 954      *          formatting errors, see the <a
 955      *          href="../util/Formatter.html#detail">Details</a> section of the
 956      *          formatter class specification.
 957      *
 958      * @throws  NullPointerException
 959      *          If the <tt>format</tt> is <tt>null</tt>
 960      *
 961      * @return  This output stream
 962      *
 963      * @since  1.5
 964      */
 965     public PrintStream format(String format, Object ... args) {
 966         try {
 967             synchronized (this) {
 968                 ensureOpen();
 969                 if ((formatter == null)
 970                     || (formatter.locale() != Locale.getDefault()))
 971                     formatter = new Formatter((Appendable) this);
 972                 formatter.format(Locale.getDefault(), format, args);
 973             }
 974         } catch (InterruptedIOException x) {
 975             Thread.currentThread().interrupt();
 976         } catch (IOException x) {
 977             trouble = true;
 978         }
 979         return this;
 980     }
 981 
 982     /**
 983      * Writes a formatted string to this output stream using the specified
 984      * format string and arguments.
 985      *
 986      * @param  l
 987      *         The {@linkplain java.util.Locale locale} to apply during
 988      *         formatting.  If <tt>l</tt> is <tt>null</tt> then no localization
 989      *         is applied.
 990      *
 991      * @param  format
 992      *         A format string as described in <a
 993      *         href="../util/Formatter.html#syntax">Format string syntax</a>
 994      *
 995      * @param  args
 996      *         Arguments referenced by the format specifiers in the format
 997      *         string.  If there are more arguments than format specifiers, the
 998      *         extra arguments are ignored.  The number of arguments is
 999      *         variable and may be zero.  The maximum number of arguments is
1000      *         limited by the maximum dimension of a Java array as defined by
1001      *         the <a href="http://java.sun.com/docs/books/vmspec/">Java
1002      *         Virtual Machine Specification</a>.  The behaviour on a
1003      *         <tt>null</tt> argument depends on the <a
1004      *         href="../util/Formatter.html#syntax">conversion</a>.
1005      *
1006      * @throws  IllegalFormatException
1007      *          If a format string contains an illegal syntax, a format
1008      *          specifier that is incompatible with the given arguments,
1009      *          insufficient arguments given the format string, or other
1010      *          illegal conditions.  For specification of all possible
1011      *          formatting errors, see the <a
1012      *          href="../util/Formatter.html#detail">Details</a> section of the
1013      *          formatter class specification.
1014      *
1015      * @throws  NullPointerException
1016      *          If the <tt>format</tt> is <tt>null</tt>
1017      *
1018      * @return  This output stream
1019      *
1020      * @since  1.5
1021      */
1022     public PrintStream format(Locale l, String format, Object ... args) {
1023         try {
1024             synchronized (this) {
1025                 ensureOpen();
1026                 if ((formatter == null)
1027                     || (formatter.locale() != l))
1028                     formatter = new Formatter(this, l);
1029                 formatter.format(l, format, args);
1030             }
1031         } catch (InterruptedIOException x) {
1032             Thread.currentThread().interrupt();
1033         } catch (IOException x) {
1034             trouble = true;
1035         }
1036         return this;
1037     }
1038 
1039     /**
1040      * Appends the specified character sequence to this output stream.
1041      *
1042      * <p> An invocation of this method of the form <tt>out.append(csq)</tt>
1043      * behaves in exactly the same way as the invocation
1044      *
1045      * <pre>
1046      *     out.print(csq.toString()) </pre>
1047      *
1048      * <p> Depending on the specification of <tt>toString</tt> for the
1049      * character sequence <tt>csq</tt>, the entire sequence may not be
1050      * appended.  For instance, invoking then <tt>toString</tt> method of a
1051      * character buffer will return a subsequence whose content depends upon
1052      * the buffer's position and limit.
1053      *
1054      * @param  csq
1055      *         The character sequence to append.  If <tt>csq</tt> is
1056      *         <tt>null</tt>, then the four characters <tt>"null"</tt> are
1057      *         appended to this output stream.
1058      *
1059      * @return  This output stream
1060      *
1061      * @since  1.5
1062      */
1063     public PrintStream append(CharSequence csq) {
1064         if (csq == null)
1065             print("null");
1066         else
1067             print(csq.toString());
1068         return this;
1069     }
1070 
1071     /**
1072      * Appends a subsequence of the specified character sequence to this output
1073      * stream.
1074      *
1075      * <p> An invocation of this method of the form <tt>out.append(csq, start,
1076      * end)</tt> when <tt>csq</tt> is not <tt>null</tt>, behaves in
1077      * exactly the same way as the invocation
1078      *
1079      * <pre>
1080      *     out.print(csq.subSequence(start, end).toString()) </pre>
1081      *
1082      * @param  csq
1083      *         The character sequence from which a subsequence will be
1084      *         appended.  If <tt>csq</tt> is <tt>null</tt>, then characters
1085      *         will be appended as if <tt>csq</tt> contained the four
1086      *         characters <tt>"null"</tt>.
1087      *
1088      * @param  start
1089      *         The index of the first character in the subsequence
1090      *
1091      * @param  end
1092      *         The index of the character following the last character in the
1093      *         subsequence
1094      *
1095      * @return  This output stream
1096      *
1097      * @throws  IndexOutOfBoundsException
1098      *          If <tt>start</tt> or <tt>end</tt> are negative, <tt>start</tt>
1099      *          is greater than <tt>end</tt>, or <tt>end</tt> is greater than
1100      *          <tt>csq.length()</tt>
1101      *
1102      * @since  1.5
1103      */
1104     public PrintStream append(CharSequence csq, int start, int end) {
1105         CharSequence cs = (csq == null ? "null" : csq);
1106         write(cs.subSequence(start, end).toString());
1107         return this;
1108     }
1109 
1110     /**
1111      * Appends the specified character to this output stream.
1112      *
1113      * <p> An invocation of this method of the form <tt>out.append(c)</tt>
1114      * behaves in exactly the same way as the invocation
1115      *
1116      * <pre>
1117      *     out.print(c) </pre>
1118      *
1119      * @param  c
1120      *         The 16-bit character to append
1121      *
1122      * @return  This output stream
1123      *
1124      * @since  1.5
1125      */
1126     public PrintStream append(char c) {
1127         print(c);
1128         return this;
1129     }
1130 
1131 }