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