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