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