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