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