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