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.
 583      * The automatic flushing setting is ignored. The internal flag
 584      * tested by {@link #checkError()} will <i>not</i> be set if an
 585      * {@code IOException} is thrown.
 586      *
 587      * <p> Note that the bytes will be written as given; to write characters
 588      * that will be translated according to the platform's default character
 589      * encoding, use the {@code print(char[])} or {@code println(char[])}
 590      * methods.
 591      *
 592      * @apiNote
 593      * Unlike other overridden methods in this class, this method may throw
 594      * an {@code IOException}. To write an array of bytes without being
 595      * required to handle an {@code IOException}, use either
 596      * {@link #writeBytes(byte[] buf) writeBytes(buf)} or
 597      * {@link #write(byte[],int,int) write(buf,0,buf.length)}.
 598      *
 599      * @implSpec
 600      * The default implementation is equivalent to
 601      * {@link java.io.FilterOutputStream#write(byte[],int,int)
 602      * super.write(buf,0,buf.length)}.
 603      *
 604      * @param  buf   A byte array
 605      *
 606      * @see #writeBytes(byte[])
 607      * @see #write(byte[],int,int)
 608      */
 609     @Override
 610     public void write(byte buf[]) throws IOException {
 611         super.write(buf, 0, buf.length);
 612     }
 613 
 614     /**
 615      * Writes all bytes from the specified byte array to this stream.
 616      * If automatic flushing is enabled then the {@code flush} method
 617      * will be invoked.
 618      *
 619      * <p> Note that the bytes will be written as given; to write characters
 620      * that will be translated according to the platform's default character
 621      * encoding, use the {@code print(char[])} or {@code println(char[])}
 622      * methods.
 623      *
 624      * @implSpec
 625      * The default implementation is equivalent to
 626      * {@link #write(byte[],int,int) this.write(buf, 0, buf.length)}.
 627      *
 628      * @param  buf   A byte array
 629      *
 630      * @since 14
 631      */
 632     public void writeBytes(byte buf[]) {
 633         this.write(buf, 0, buf.length);
 634     }
 635 
 636     /*
 637      * The following private methods on the text- and character-output streams
 638      * always flush the stream buffers, so that writes to the underlying byte
 639      * stream occur as promptly as with the original PrintStream.
 640      */
 641 
 642     private void write(char[] buf) {
 643         try {
 644             synchronized (this) {
 645                 ensureOpen();
 646                 textOut.write(buf);
 647                 textOut.flushBuffer();
 648                 charOut.flushBuffer();
 649                 if (autoFlush) {
 650                     for (int i = 0; i < buf.length; i++)
 651                         if (buf[i] == '\n') {
 652                             out.flush();
 653                             break;
 654                         }
 655                 }
 656             }
 657         } catch (InterruptedIOException x) {
 658             Thread.currentThread().interrupt();
 659         } catch (IOException x) {
 660             trouble = true;
 661         }
 662     }
 663 
 664     // Used to optimize away back-to-back flushing and synchronization when
 665     // using println, but since subclasses could exist which depend on
 666     // observing a call to print followed by newLine() we only use this if
 667     // getClass() == PrintStream.class to avoid compatibility issues.
 668     private void writeln(char[] buf) {
 669         try {
 670             synchronized (this) {
 671                 ensureOpen();
 672                 textOut.write(buf);
 673                 textOut.newLine();
 674                 textOut.flushBuffer();
 675                 charOut.flushBuffer();
 676                 if (autoFlush)
 677                     out.flush();
 678             }
 679         }
 680         catch (InterruptedIOException x) {
 681             Thread.currentThread().interrupt();
 682         }
 683         catch (IOException x) {
 684             trouble = true;
 685         }
 686     }
 687 
 688     private void write(String s) {
 689         try {
 690             synchronized (this) {
 691                 ensureOpen();
 692                 textOut.write(s);
 693                 textOut.flushBuffer();
 694                 charOut.flushBuffer();
 695                 if (autoFlush && (s.indexOf('\n') >= 0))
 696                     out.flush();
 697             }
 698         }
 699         catch (InterruptedIOException x) {
 700             Thread.currentThread().interrupt();
 701         }
 702         catch (IOException x) {
 703             trouble = true;
 704         }
 705     }
 706 
 707     // Used to optimize away back-to-back flushing and synchronization when
 708     // using println, but since subclasses could exist which depend on
 709     // observing a call to print followed by newLine we only use this if
 710     // getClass() == PrintStream.class to avoid compatibility issues.
 711     private void writeln(String s) {
 712         try {
 713             synchronized (this) {
 714                 ensureOpen();
 715                 textOut.write(s);
 716                 textOut.newLine();
 717                 textOut.flushBuffer();
 718                 charOut.flushBuffer();
 719                 if (autoFlush)
 720                     out.flush();
 721             }
 722         }
 723         catch (InterruptedIOException x) {
 724             Thread.currentThread().interrupt();
 725         }
 726         catch (IOException x) {
 727             trouble = true;
 728         }
 729     }
 730 
 731     private void newLine() {
 732         try {
 733             synchronized (this) {
 734                 ensureOpen();
 735                 textOut.newLine();
 736                 textOut.flushBuffer();
 737                 charOut.flushBuffer();
 738                 if (autoFlush)
 739                     out.flush();
 740             }
 741         }
 742         catch (InterruptedIOException x) {
 743             Thread.currentThread().interrupt();
 744         }
 745         catch (IOException x) {
 746             trouble = true;
 747         }
 748     }
 749 
 750     /* Methods that do not terminate lines */
 751 
 752     /**
 753      * Prints a boolean value.  The string produced by {@link
 754      * java.lang.String#valueOf(boolean)} is translated into bytes
 755      * according to the platform's default character encoding, and these bytes
 756      * are written in exactly the manner of the
 757      * {@link #write(int)} method.
 758      *
 759      * @param      b   The {@code boolean} to be printed
 760      */
 761     public void print(boolean b) {
 762         write(String.valueOf(b));
 763     }
 764 
 765     /**
 766      * Prints a character.  The character is translated into one or more bytes
 767      * according to the character encoding given to the constructor, or the
 768      * platform's default character encoding if none specified. These bytes
 769      * are written in exactly the manner of the {@link #write(int)} method.
 770      *
 771      * @param      c   The {@code char} to be printed
 772      */
 773     public void print(char c) {
 774         write(String.valueOf(c));
 775     }
 776 
 777     /**
 778      * Prints an integer.  The string produced by {@link
 779      * java.lang.String#valueOf(int)} is translated into bytes
 780      * according to the platform's default character encoding, and these bytes
 781      * are written in exactly the manner of the
 782      * {@link #write(int)} method.
 783      *
 784      * @param      i   The {@code int} to be printed
 785      * @see        java.lang.Integer#toString(int)
 786      */
 787     public void print(int i) {
 788         write(String.valueOf(i));
 789     }
 790 
 791     /**
 792      * Prints a long integer.  The string produced by {@link
 793      * java.lang.String#valueOf(long)} is translated into bytes
 794      * according to the platform's default character encoding, and these bytes
 795      * are written in exactly the manner of the
 796      * {@link #write(int)} method.
 797      *
 798      * @param      l   The {@code long} to be printed
 799      * @see        java.lang.Long#toString(long)
 800      */
 801     public void print(long l) {
 802         write(String.valueOf(l));
 803     }
 804 
 805     /**
 806      * Prints a floating-point number.  The string produced by {@link
 807      * java.lang.String#valueOf(float)} is translated into bytes
 808      * according to the platform's default character encoding, and these bytes
 809      * are written in exactly the manner of the
 810      * {@link #write(int)} method.
 811      *
 812      * @param      f   The {@code float} to be printed
 813      * @see        java.lang.Float#toString(float)
 814      */
 815     public void print(float f) {
 816         write(String.valueOf(f));
 817     }
 818 
 819     /**
 820      * Prints a double-precision floating-point number.  The string produced by
 821      * {@link java.lang.String#valueOf(double)} is translated into
 822      * bytes according to the platform's default character encoding, and these
 823      * bytes are written in exactly the manner of the {@link
 824      * #write(int)} method.
 825      *
 826      * @param      d   The {@code double} to be printed
 827      * @see        java.lang.Double#toString(double)
 828      */
 829     public void print(double d) {
 830         write(String.valueOf(d));
 831     }
 832 
 833     /**
 834      * Prints an array of characters.  The characters are converted into bytes
 835      * according to the character encoding given to the constructor, or the
 836      * platform's default character encoding if none specified. These bytes
 837      * are written in exactly the manner of the {@link #write(int)} method.
 838      *
 839      * @param      s   The array of chars to be printed
 840      *
 841      * @throws  NullPointerException  If {@code s} is {@code null}
 842      */
 843     public void print(char s[]) {
 844         write(s);
 845     }
 846 
 847     /**
 848      * Prints a string.  If the argument is {@code null} then the string
 849      * {@code "null"} is printed.  Otherwise, the string's characters are
 850      * converted into bytes according to the character encoding given to the
 851      * constructor, or the platform's default character encoding if none
 852      * specified. These bytes are written in exactly the manner of the
 853      * {@link #write(int)} method.
 854      *
 855      * @param      s   The {@code String} to be printed
 856      */
 857     public void print(String s) {
 858         write(String.valueOf(s));
 859     }
 860 
 861     /**
 862      * Prints an object.  The string produced by the {@link
 863      * java.lang.String#valueOf(Object)} method is translated into bytes
 864      * according to the platform's default character encoding, and these bytes
 865      * are written in exactly the manner of the
 866      * {@link #write(int)} method.
 867      *
 868      * @param      obj   The {@code Object} to be printed
 869      * @see        java.lang.Object#toString()
 870      */
 871     public void print(Object obj) {
 872         write(String.valueOf(obj));
 873     }
 874 
 875 
 876     /* Methods that do terminate lines */
 877 
 878     /**
 879      * Terminates the current line by writing the line separator string.  The
 880      * line separator string is defined by the system property
 881      * {@code line.separator}, and is not necessarily a single newline
 882      * character ({@code '\n'}).
 883      */
 884     public void println() {
 885         newLine();
 886     }
 887 
 888     /**
 889      * Prints a boolean and then terminate the line.  This method behaves as
 890      * though it invokes {@link #print(boolean)} and then
 891      * {@link #println()}.
 892      *
 893      * @param x  The {@code boolean} to be printed
 894      */
 895     public void println(boolean x) {
 896         if (getClass() == PrintStream.class) {
 897             writeln(String.valueOf(x));
 898         } else {
 899             synchronized (this) {
 900                 print(x);
 901                 newLine();
 902             }
 903         }
 904     }
 905 
 906     /**
 907      * Prints a character and then terminate the line.  This method behaves as
 908      * though it invokes {@link #print(char)} and then
 909      * {@link #println()}.
 910      *
 911      * @param x  The {@code char} to be printed.
 912      */
 913     public void println(char x) {
 914         if (getClass() == PrintStream.class) {
 915             writeln(String.valueOf(x));
 916         } else {
 917             synchronized (this) {
 918                 print(x);
 919                 newLine();
 920             }
 921         }
 922     }
 923 
 924     /**
 925      * Prints an integer and then terminate the line.  This method behaves as
 926      * though it invokes {@link #print(int)} and then
 927      * {@link #println()}.
 928      *
 929      * @param x  The {@code int} to be printed.
 930      */
 931     public void println(int x) {
 932         if (getClass() == PrintStream.class) {
 933             writeln(String.valueOf(x));
 934         } else {
 935             synchronized (this) {
 936                 print(x);
 937                 newLine();
 938             }
 939         }
 940     }
 941 
 942     /**
 943      * Prints a long and then terminate the line.  This method behaves as
 944      * though it invokes {@link #print(long)} and then
 945      * {@link #println()}.
 946      *
 947      * @param x  a The {@code long} to be printed.
 948      */
 949     public void println(long x) {
 950         if (getClass() == PrintStream.class) {
 951             writeln(String.valueOf(x));
 952         } else {
 953             synchronized (this) {
 954                 print(x);
 955                 newLine();
 956             }
 957         }
 958     }
 959 
 960     /**
 961      * Prints a float and then terminate the line.  This method behaves as
 962      * though it invokes {@link #print(float)} and then
 963      * {@link #println()}.
 964      *
 965      * @param x  The {@code float} to be printed.
 966      */
 967     public void println(float x) {
 968         if (getClass() == PrintStream.class) {
 969             writeln(String.valueOf(x));
 970         } else {
 971             synchronized (this) {
 972                 print(x);
 973                 newLine();
 974             }
 975         }
 976     }
 977 
 978     /**
 979      * Prints a double and then terminate the line.  This method behaves as
 980      * though it invokes {@link #print(double)} and then
 981      * {@link #println()}.
 982      *
 983      * @param x  The {@code double} to be printed.
 984      */
 985     public void println(double x) {
 986         if (getClass() == PrintStream.class) {
 987             writeln(String.valueOf(x));
 988         } else {
 989             synchronized (this) {
 990                 print(x);
 991                 newLine();
 992             }
 993         }
 994     }
 995 
 996     /**
 997      * Prints an array of characters and then terminate the line.  This method
 998      * behaves as though it invokes {@link #print(char[])} and
 999      * then {@link #println()}.
1000      *
1001      * @param x  an array of chars to print.
1002      */
1003     public void println(char[] x) {
1004         if (getClass() == PrintStream.class) {
1005             writeln(x);
1006         } else {
1007             synchronized (this) {
1008                 print(x);
1009                 newLine();
1010             }
1011         }
1012     }
1013 
1014     /**
1015      * Prints a String and then terminate the line.  This method behaves as
1016      * though it invokes {@link #print(String)} and then
1017      * {@link #println()}.
1018      *
1019      * @param x  The {@code String} to be printed.
1020      */
1021     public void println(String x) {
1022         if (getClass() == PrintStream.class) {
1023             writeln(String.valueOf(x));
1024         } else {
1025             synchronized (this) {
1026                 print(x);
1027                 newLine();
1028             }
1029         }
1030     }
1031 
1032     /**
1033      * Prints an Object and then terminate the line.  This method calls
1034      * at first String.valueOf(x) to get the printed object's string value,
1035      * then behaves as
1036      * though it invokes {@link #print(String)} and then
1037      * {@link #println()}.
1038      *
1039      * @param x  The {@code Object} to be printed.
1040      */
1041     public void println(Object x) {
1042         String s = String.valueOf(x);
1043         if (getClass() == PrintStream.class) {
1044             // need to apply String.valueOf again since first invocation
1045             // might return null
1046             writeln(String.valueOf(s));
1047         } else {
1048             synchronized (this) {
1049                 print(s);
1050                 newLine();
1051             }
1052         }
1053     }
1054 
1055 
1056     /**
1057      * A convenience method to write a formatted string to this output stream
1058      * using the specified format string and arguments.
1059      *
1060      * <p> An invocation of this method of the form
1061      * {@code out.printf(format, args)} behaves
1062      * in exactly the same way as the invocation
1063      *
1064      * <pre>{@code
1065      *     out.format(format, args)
1066      * }</pre>
1067      *
1068      * @param  format
1069      *         A format string as described in <a
1070      *         href="../util/Formatter.html#syntax">Format string syntax</a>
1071      *
1072      * @param  args
1073      *         Arguments referenced by the format specifiers in the format
1074      *         string.  If there are more arguments than format specifiers, the
1075      *         extra arguments are ignored.  The number of arguments is
1076      *         variable and may be zero.  The maximum number of arguments is
1077      *         limited by the maximum dimension of a Java array as defined by
1078      *         <cite>The Java&trade; Virtual Machine Specification</cite>.
1079      *         The behaviour on a
1080      *         {@code null} argument depends on the <a
1081      *         href="../util/Formatter.html#syntax">conversion</a>.
1082      *
1083      * @throws  java.util.IllegalFormatException
1084      *          If a format string contains an illegal syntax, a format
1085      *          specifier that is incompatible with the given arguments,
1086      *          insufficient arguments given the format string, or other
1087      *          illegal conditions.  For specification of all possible
1088      *          formatting errors, see the <a
1089      *          href="../util/Formatter.html#detail">Details</a> section of the
1090      *          formatter class specification.
1091      *
1092      * @throws  NullPointerException
1093      *          If the {@code format} is {@code null}
1094      *
1095      * @return  This output stream
1096      *
1097      * @since  1.5
1098      */
1099     public PrintStream printf(String format, Object ... args) {
1100         return format(format, args);
1101     }
1102 
1103     /**
1104      * A convenience method to write a formatted string to this output stream
1105      * using the specified format string and arguments.
1106      *
1107      * <p> An invocation of this method of the form
1108      * {@code out.printf(l, format, args)} behaves
1109      * in exactly the same way as the invocation
1110      *
1111      * <pre>{@code
1112      *     out.format(l, format, args)
1113      * }</pre>
1114      *
1115      * @param  l
1116      *         The {@linkplain java.util.Locale locale} to apply during
1117      *         formatting.  If {@code l} is {@code null} then no localization
1118      *         is applied.
1119      *
1120      * @param  format
1121      *         A format string as described in <a
1122      *         href="../util/Formatter.html#syntax">Format string syntax</a>
1123      *
1124      * @param  args
1125      *         Arguments referenced by the format specifiers in the format
1126      *         string.  If there are more arguments than format specifiers, the
1127      *         extra arguments are ignored.  The number of arguments is
1128      *         variable and may be zero.  The maximum number of arguments is
1129      *         limited by the maximum dimension of a Java array as defined by
1130      *         <cite>The Java&trade; Virtual Machine Specification</cite>.
1131      *         The behaviour on a
1132      *         {@code null} argument depends on the <a
1133      *         href="../util/Formatter.html#syntax">conversion</a>.
1134      *
1135      * @throws  java.util.IllegalFormatException
1136      *          If a format string contains an illegal syntax, a format
1137      *          specifier that is incompatible with the given arguments,
1138      *          insufficient arguments given the format string, or other
1139      *          illegal conditions.  For specification of all possible
1140      *          formatting errors, see the <a
1141      *          href="../util/Formatter.html#detail">Details</a> section of the
1142      *          formatter class specification.
1143      *
1144      * @throws  NullPointerException
1145      *          If the {@code format} is {@code null}
1146      *
1147      * @return  This output stream
1148      *
1149      * @since  1.5
1150      */
1151     public PrintStream printf(Locale l, String format, Object ... args) {
1152         return format(l, format, args);
1153     }
1154 
1155     /**
1156      * Writes a formatted string to this output stream using the specified
1157      * format string and arguments.
1158      *
1159      * <p> The locale always used is the one returned by {@link
1160      * java.util.Locale#getDefault(Locale.Category)} with
1161      * {@link java.util.Locale.Category#FORMAT FORMAT} category specified,
1162      * regardless of any previous invocations of other formatting methods on
1163      * this object.
1164      *
1165      * @param  format
1166      *         A format string as described in <a
1167      *         href="../util/Formatter.html#syntax">Format string syntax</a>
1168      *
1169      * @param  args
1170      *         Arguments referenced by the format specifiers in the format
1171      *         string.  If there are more arguments than format specifiers, the
1172      *         extra arguments are ignored.  The number of arguments is
1173      *         variable and may be zero.  The maximum number of arguments is
1174      *         limited by the maximum dimension of a Java array as defined by
1175      *         <cite>The Java&trade; Virtual Machine Specification</cite>.
1176      *         The behaviour on a
1177      *         {@code null} argument depends on the <a
1178      *         href="../util/Formatter.html#syntax">conversion</a>.
1179      *
1180      * @throws  java.util.IllegalFormatException
1181      *          If a format string contains an illegal syntax, a format
1182      *          specifier that is incompatible with the given arguments,
1183      *          insufficient arguments given the format string, or other
1184      *          illegal conditions.  For specification of all possible
1185      *          formatting errors, see the <a
1186      *          href="../util/Formatter.html#detail">Details</a> section of the
1187      *          formatter class specification.
1188      *
1189      * @throws  NullPointerException
1190      *          If the {@code format} is {@code null}
1191      *
1192      * @return  This output stream
1193      *
1194      * @since  1.5
1195      */
1196     public PrintStream format(String format, Object ... args) {
1197         try {
1198             synchronized (this) {
1199                 ensureOpen();
1200                 if ((formatter == null)
1201                     || (formatter.locale() !=
1202                         Locale.getDefault(Locale.Category.FORMAT)))
1203                     formatter = new Formatter((Appendable) this);
1204                 formatter.format(Locale.getDefault(Locale.Category.FORMAT),
1205                                  format, args);
1206             }
1207         } catch (InterruptedIOException x) {
1208             Thread.currentThread().interrupt();
1209         } catch (IOException x) {
1210             trouble = true;
1211         }
1212         return this;
1213     }
1214 
1215     /**
1216      * Writes a formatted string to this output stream using the specified
1217      * format string and arguments.
1218      *
1219      * @param  l
1220      *         The {@linkplain java.util.Locale locale} to apply during
1221      *         formatting.  If {@code l} is {@code null} then no localization
1222      *         is applied.
1223      *
1224      * @param  format
1225      *         A format string as described in <a
1226      *         href="../util/Formatter.html#syntax">Format string syntax</a>
1227      *
1228      * @param  args
1229      *         Arguments referenced by the format specifiers in the format
1230      *         string.  If there are more arguments than format specifiers, the
1231      *         extra arguments are ignored.  The number of arguments is
1232      *         variable and may be zero.  The maximum number of arguments is
1233      *         limited by the maximum dimension of a Java array as defined by
1234      *         <cite>The Java&trade; Virtual Machine Specification</cite>.
1235      *         The behaviour on a
1236      *         {@code null} argument depends on the <a
1237      *         href="../util/Formatter.html#syntax">conversion</a>.
1238      *
1239      * @throws  java.util.IllegalFormatException
1240      *          If a format string contains an illegal syntax, a format
1241      *          specifier that is incompatible with the given arguments,
1242      *          insufficient arguments given the format string, or other
1243      *          illegal conditions.  For specification of all possible
1244      *          formatting errors, see the <a
1245      *          href="../util/Formatter.html#detail">Details</a> section of the
1246      *          formatter class specification.
1247      *
1248      * @throws  NullPointerException
1249      *          If the {@code format} is {@code null}
1250      *
1251      * @return  This output stream
1252      *
1253      * @since  1.5
1254      */
1255     public PrintStream format(Locale l, String format, Object ... args) {
1256         try {
1257             synchronized (this) {
1258                 ensureOpen();
1259                 if ((formatter == null)
1260                     || (formatter.locale() != l))
1261                     formatter = new Formatter(this, l);
1262                 formatter.format(l, format, args);
1263             }
1264         } catch (InterruptedIOException x) {
1265             Thread.currentThread().interrupt();
1266         } catch (IOException x) {
1267             trouble = true;
1268         }
1269         return this;
1270     }
1271 
1272     /**
1273      * Appends the specified character sequence to this output stream.
1274      *
1275      * <p> An invocation of this method of the form {@code out.append(csq)}
1276      * behaves in exactly the same way as the invocation
1277      *
1278      * <pre>{@code
1279      *     out.print(csq.toString())
1280      * }</pre>
1281      *
1282      * <p> Depending on the specification of {@code toString} for the
1283      * character sequence {@code csq}, the entire sequence may not be
1284      * appended.  For instance, invoking then {@code toString} method of a
1285      * character buffer will return a subsequence whose content depends upon
1286      * the buffer's position and limit.
1287      *
1288      * @param  csq
1289      *         The character sequence to append.  If {@code csq} is
1290      *         {@code null}, then the four characters {@code "null"} are
1291      *         appended to this output stream.
1292      *
1293      * @return  This output stream
1294      *
1295      * @since  1.5
1296      */
1297     public PrintStream append(CharSequence csq) {
1298         print(String.valueOf(csq));
1299         return this;
1300     }
1301 
1302     /**
1303      * Appends a subsequence of the specified character sequence to this output
1304      * stream.
1305      *
1306      * <p> An invocation of this method of the form
1307      * {@code out.append(csq, start, end)} when
1308      * {@code csq} is not {@code null}, behaves in
1309      * exactly the same way as the invocation
1310      *
1311      * <pre>{@code
1312      *     out.print(csq.subSequence(start, end).toString())
1313      * }</pre>
1314      *
1315      * @param  csq
1316      *         The character sequence from which a subsequence will be
1317      *         appended.  If {@code csq} is {@code null}, then characters
1318      *         will be appended as if {@code csq} contained the four
1319      *         characters {@code "null"}.
1320      *
1321      * @param  start
1322      *         The index of the first character in the subsequence
1323      *
1324      * @param  end
1325      *         The index of the character following the last character in the
1326      *         subsequence
1327      *
1328      * @return  This output stream
1329      *
1330      * @throws  IndexOutOfBoundsException
1331      *          If {@code start} or {@code end} are negative, {@code start}
1332      *          is greater than {@code end}, or {@code end} is greater than
1333      *          {@code csq.length()}
1334      *
1335      * @since  1.5
1336      */
1337     public PrintStream append(CharSequence csq, int start, int end) {
1338         if (csq == null) csq = "null";
1339         return append(csq.subSequence(start, end));
1340     }
1341 
1342     /**
1343      * Appends the specified character to this output stream.
1344      *
1345      * <p> An invocation of this method of the form {@code out.append(c)}
1346      * behaves in exactly the same way as the invocation
1347      *
1348      * <pre>{@code
1349      *     out.print(c)
1350      * }</pre>
1351      *
1352      * @param  c
1353      *         The 16-bit character to append
1354      *
1355      * @return  This output stream
1356      *
1357      * @since  1.5
1358      */
1359     public PrintStream append(char c) {
1360         print(c);
1361         return this;
1362     }
1363 
1364 }