/*
 
* Copyright (c) 1996, 2013, Oracle and/or its affiliates. All rights reserved.
 
* DO NOT ALTER OR REMOVE COPYRIGHT NOTICES OR THIS FILE HEADER.
 
*
 
* This code is free software; you can redistribute it and/or modify it
 
* under the terms of the GNU General Public License version 2 only, as
 
* published by the Free Software Foundation.
  
Oracle designates this
 
* particular file as subject to the "Classpath" exception as provided
 
* by Oracle in the LICENSE file that accompanied this code.
 
*
 
* This code is distributed in the hope that it will be useful, but WITHOUT
 
* ANY WARRANTY; without even the implied warranty of MERCHANTABILITY or
 
* FITNESS FOR A PARTICULAR PURPOSE.
  
See the GNU General Public License
 
* version 2 for more details (a copy is included in the LICENSE file that
 
* accompanied this code).
 
*
 
* You should have received a copy of the GNU General Public License version
 
* 2 along with this work; if not, write to the Free Software Foundation,
 
* Inc., 51 Franklin St, Fifth Floor, Boston, MA 02110-1301 USA.
 
*
 
* Please contact Oracle, 500 Oracle Parkway, Redwood Shores, CA 94065 USA
 
* or visit www.oracle.com if you need additional information or have any
 
* questions.
 
*/

package java.io;

import java.util.Formatter;
import java.util.Locale;
import java.nio.charset.Charset;
import java.nio.charset.IllegalCharsetNameException;
import java.nio.charset.UnsupportedCharsetException;

/**
 
* A <code>PrintStream</code> adds functionality to another output stream,
 
* namely the ability to print representations of various data values
 
* conveniently.
  
Two other features are provided as well.Unlike other output
 
* streams, a <code>PrintStream</code> never throws an
 
* <code>IOException</code>; instead, exceptional situations merely set an
 
* internal flag that can be tested via the <code>checkError</code> method.
 
* Optionally, a <code>PrintStream</code> can be created so as to flush
 
* automatically; this means that the <code>flush</code> method is
 
* automatically invoked after a byte array is written, one of the
 
* <code>println</code> methods is invoked, or a newline character or byte
 
* (<code>'\n'</code>) is written.
 
*
 
* <p> All characters printed by a <code>PrintStream</code> are converted into
 
* bytes using the platform's default character encoding.
  
The <code>{@link
 
* PrintWriter}</code> class should be used in situations that require writing
 
* characters rather than bytes.
 
*
 
* @author
     
Frank Yellin
 
* @author
     
Mark Reinhold
 
* @since
      
JDK1.0
 
*/


public class PrintStream extends FilterOutputStream
    
implements Appendable, Closeable
{

    
private final boolean autoFlush;
    
private boolean trouble = false;
    
private Formatter formatter;

    
/**
     
* Track both the text- and character-output streams, so that their buffers
     
* can be flushed without flushing the entire stream.
     
*/

    
private BufferedWriter textOut;
    
private OutputStreamWriter charOut;

    
/**
     
* requireNonNull is explicitly declared here so as not to create an extra
     
* dependency on java.util.Objects.requireNonNull. PrintStream is loaded
     
* early during system initialization.
     
*/

    
private static <T> T requireNonNull(T obj, String message) {
        
if (obj == null)
            
throw new NullPointerException(message);
        
return obj;
    
}

    
/**
     
* Returns a charset object for the given charset name.
     
* @throws NullPointerException
          
is csn is null
     
* @throws UnsupportedEncodingException
  
if the charset is not supported
     
*/

    
private static Charset toCharset(String csn)
        
throws UnsupportedEncodingException
    
{
        
requireNonNull(csn, "charsetName");
        
try {
            
return Charset.forName(csn);
        
} catch (IllegalCharsetNameException|UnsupportedCharsetException unused) {
            
// UnsupportedEncodingException should be thrown
            
throw new UnsupportedEncodingException(csn);
        
}
    
}

    
/* Private constructors */
    
private PrintStream(boolean autoFlush, OutputStream out) {
        
super(out);
        
this.autoFlush = autoFlush;
        
this.charOut = new OutputStreamWriter(this);
        
this.textOut = new BufferedWriter(charOut);
    
}

    
private PrintStream(boolean autoFlush, OutputStream out, Charset charset) {
        
super(out);
        
this.autoFlush = autoFlush;
        
this.charOut = new OutputStreamWriter(this, charset);
        
this.textOut = new BufferedWriter(charOut);
    
}

    
/* Variant of the private constructor so that the given charset name
     
* can be verified before evaluating the OutputStream argument. Used
     
* by constructors creating a FileOutputStream that also take a
     
* charset name.
     
*/

    
private PrintStream(boolean autoFlush, Charset charset, OutputStream out)
        
throws UnsupportedEncodingException
    
{
        
this(autoFlush, out, charset);
    
}

    
/**
     
* Creates a new print stream.
  
This stream will not flush automatically.
     
*
     
* @param
  
out
        
The output stream to which values and objects will be
     
*
                    
printed
     
*
     
* @see java.io.PrintWriter#PrintWriter(java.io.OutputStream)
     
*/

    
public PrintStream(OutputStream out) {
        
this(out, false);
    
}

    
/**
     
* Creates a new print stream.
     
*
     
* @param
  
out
        
The output stream to which values and objects will be
     
*
                    
printed
     
* @param
  
autoFlushA boolean; if true, the output buffer will be flushed
     
*
                    
whenever a byte array is written, one of the
     
*
                    
<code>println</code> methods is invoked, or a newline
     
*
                    
character or byte (<code>'\n'</code>) is written
     
*
     
* @see java.io.PrintWriter#PrintWriter(java.io.OutputStream, boolean)
     
*/

    
public PrintStream(OutputStream out, boolean autoFlush) {
        
this(autoFlush, requireNonNull(out, "Null output stream"));
    
}

    
/**
     
* Creates a new print stream.
     
*
     
* @param
  
out
        
The output stream to which values and objects will be
     
*
                    
printed
     
* @param
  
autoFlushA boolean; if true, the output buffer will be flushed
     
*
                    
whenever a byte array is written, one of the
     
*
                    
<code>println</code> methods is invoked, or a newline
     
*
                    
character or byte (<code>'\n'</code>) is written
     
* @param
  
encoding
   
The name of a supported
     
*
                    
<a href="../lang/package-summary.html#charenc">
     
*
                    
character encoding</a>
     
*
     
* @throws
  
UnsupportedEncodingException
     
*
          
If the named encoding is not supported
     
*
     
* @since
  
1.4
     
*/

    
public PrintStream(OutputStream out, boolean autoFlush, String encoding)
        
throws UnsupportedEncodingException
    
{
        
this(autoFlush,
             
requireNonNull(out, "Null output stream"),
             
toCharset(encoding));
    
}

    
/**
     
* Creates a new print stream, without automatic line flushing, with the
     
* specified file name.
  
This convenience constructor creates
     
* the necessary intermediate {@link java.io.OutputStreamWriter
     
* OutputStreamWriter}, which will encode characters using the
     
* {@linkplain java.nio.charset.Charset#defaultCharset() default charset}
     
* for this instance of the Java virtual machine.
     
*
     
* @param
  
fileName
     
*
         
The name of the file to use as the destination of this print
     
*
         
stream.
  
If the file exists, then it will be truncated to
     
*
         
zero size; otherwise, a new file will be created.
  
The output
     
*
         
will be written to the file and is buffered.
     
*
     
* @throws
  
FileNotFoundException
     
*
          
If the given file object does not denote an existing, writable
     
*
          
regular file and a new regular file of that name cannot be
     
*
          
created, or if some other error occurs while opening or
     
*
          
creating the file
     
*
     
* @throws
  
SecurityException
     
*
          
If a security manager is present and {@link
     
*
          
SecurityManager#checkWrite checkWrite(fileName)} denies write
     
*
          
access to the file
     
*
     
* @since
  
1.5
     
*/

    
public PrintStream(String fileName) throws FileNotFoundException {
        
this(false, new FileOutputStream(fileName));
    
}

    
/**
     
* Creates a new print stream, without automatic line flushing, with the
     
* specified file name and charset.
  
This convenience constructor creates
     
* the necessary intermediate {@link java.io.OutputStreamWriter
     
* OutputStreamWriter}, which will encode characters using the provided
     
* charset.
     
*
     
* @param
  
fileName
     
*
         
The name of the file to use as the destination of this print
     
*
         
stream.
  
If the file exists, then it will be truncated to
     
*
         
zero size; otherwise, a new file will be created.
  
The output
     
*
         
will be written to the file and is buffered.
     
*
     
* @param
  
csn
     
*
         
The name of a supported {@linkplain java.nio.charset.Charset
     
*
         
charset}
     
*
     
* @throws
  
FileNotFoundException
     
*
          
If the given file object does not denote an existing, writable
     
*
          
regular file and a new regular file of that name cannot be
     
*
          
created, or if some other error occurs while opening or
     
*
          
creating the file
     
*
     
* @throws
  
SecurityException
     
*
          
If a security manager is present and {@link
     
*
          
SecurityManager#checkWrite checkWrite(fileName)} denies write
     
*
          
access to the file
     
*
     
* @throws
  
UnsupportedEncodingException
     
*
          
If the named charset is not supported
     
*
     
* @since
  
1.5
     
*/

    
public PrintStream(String fileName, String csn)
        
throws FileNotFoundException, UnsupportedEncodingException
    
{
        
// ensure charset is checked before the file is opened
        
this(false, toCharset(csn), new FileOutputStream(fileName));
    
}

    
/**
     
* Creates a new print stream, without automatic line flushing, with the
     
* specified file.
  
This convenience constructor creates the necessary
     
* intermediate {@link java.io.OutputStreamWriter OutputStreamWriter},
     
* which will encode characters using the {@linkplain
     
* java.nio.charset.Charset#defaultCharset() default charset} for this
     
* instance of the Java virtual machine.
     
*
     
* @param
  
file
     
*
         
The file to use as the destination of this print stream.
  
If the
     
*
         
file exists, then it will be truncated to zero size; otherwise,
     
*
         
a new file will be created.
  
The output will be written to the
     
*
         
file and is buffered.
     
*
     
* @throws
  
FileNotFoundException
     
*
          
If the given file object does not denote an existing, writable
     
*
          
regular file and a new regular file of that name cannot be
     
*
          
created, or if some other error occurs while opening or
     
*
          
creating the file
     
*
     
* @throws
  
SecurityException
     
*
          
If a security manager is present and {@link
     
*
          
SecurityManager#checkWrite checkWrite(file.getPath())}
     
*
          
denies write access to the file
     
*
     
* @since
  
1.5
     
*/

    
public PrintStream(File file) throws FileNotFoundException {
        
this(false, new FileOutputStream(file));
    
}

    
/**
     
* Creates a new print stream, without automatic line flushing, with the
     
* specified file and charset.
  
This convenience constructor creates
     
* the necessary intermediate {@link java.io.OutputStreamWriter
     
* OutputStreamWriter}, which will encode characters using the provided
     
* charset.
     
*
     
* @param
  
file
     
*
         
The file to use as the destination of this print stream.
  
If the
     
*
         
file exists, then it will be truncated to zero size; otherwise,
     
*
         
a new file will be created.
  
The output will be written to the
     
*
         
file and is buffered.
     
*
     
* @param
  
csn
     
*
         
The name of a supported {@linkplain java.nio.charset.Charset
     
*
         
charset}
     
*
     
* @throws
  
FileNotFoundException
     
*
          
If the given file object does not denote an existing, writable
     
*
          
regular file and a new regular file of that name cannot be
     
*
          
created, or if some other error occurs while opening or
     
*
          
creating the file
     
*
     
* @throws
  
SecurityException
     
*
          
If a security manager is present and {@link
     
*
          
SecurityManager#checkWrite checkWrite(file.getPath())}
     
*
          
denies write access to the file
     
*
     
* @throws
  
UnsupportedEncodingException
     
*
          
If the named charset is not supported
     
*
     
* @since
  
1.5
     
*/

    
public PrintStream(File file, String csn)
        
throws FileNotFoundException, UnsupportedEncodingException
    
{
        
// ensure charset is checked before the file is opened
        
this(false, toCharset(csn), new FileOutputStream(file));
    
}

    
/** Check to make sure that the stream has not been closed */
    
private void ensureOpen() throws IOException {
        
if (out == null)
            
throw new IOException("Stream closed");
    
}

    
/**
     
* Flushes the stream.
  
This is done by writing any buffered output bytes to
     
* the underlying output stream and then flushing that stream.
     
*
     
* @see
        
java.io.OutputStream#flush()
     
*/

    
public void flush() {
        
synchronized (this) {
            
try {
                
ensureOpen();
                
out.flush();
            
}
            
catch (IOException x) {
                
trouble = true;
            
}
        
}
    
}

    
private boolean closing = false; /* To avoid recursive closing */

    
/**
     
* Closes the stream.
  
This is done by flushing the stream and then closing
     
* the underlying output stream.
     
*
     
* @see
        
java.io.OutputStream#close()
     
*/

    
public void close() {
        
synchronized (this) {
            
if (! closing) {
                
closing = true;
                
try {
                    
textOut.close();
                    
out.close();
                
}
                
catch (IOException x) {
                    
trouble = true;
                
}
                
textOut = null;
                
charOut = null;
                
out = null;
            
}
        
}
    
}

    
/**
     
* Flushes the stream and checks its error state. The internal error state
     
* is set to <code>true</code> when the underlying output stream throws an
     
* <code>IOException</code> other than <code>InterruptedIOException</code>,
     
* and when the <code>setError</code> method is invoked.
  
If an operation
     
* on the underlying output stream throws an
     
* <code>InterruptedIOException</code>, then the <code>PrintStream</code>
     
* converts the exception back into an interrupt by doing:
     
* <pre>
     
*Thread.currentThread().interrupt();
     
* </pre>
     
* or the equivalent.
     
*
     
* @return <code>true</code> if and only if this stream has encountered an
     
*
         
<code>IOException</code> other than
     
*
         
<code>InterruptedIOException</code>, or the
     
*
         
<code>setError</code> method has been invoked
     
*/

    
public boolean checkError() {
        
if (out != null)
            
flush();
        
if (out instanceof java.io.PrintStream) {
            
PrintStream ps = (PrintStream) out;
            
return ps.checkError();
        
}
        
return trouble;
    
}

    
/**
     
* Sets the error state of the stream to <code>true</code>.
     
*
     
* <p> This method will cause subsequent invocations of {@link
     
* #checkError()} to return <tt>true</tt> until {@link
     
* #clearError()} is invoked.
     
*
     
* @since JDK1.1
     
*/

    
protected void setError() {
        
trouble = true;
    
}

    
/**
     
* Clears the internal error state of this stream.
     
*
     
* <p> This method will cause subsequent invocations of {@link
     
* #checkError()} to return <tt>false</tt> until another write
     
* operation fails and invokes
 
.
     
*
     
* @since 1.6
     
*/

    
protected void clearError() {
        
trouble = false;
    
}

    
/*
     
* Exception-catching, synchronized output operations,
     
* which also implement the write() methods of OutputStream
     
*/


    
/**
     
* Writes the specified byte to this stream.
  
If the byte is a newline and
     
* automatic flushing is enabled then the <code>flush</code> method will be
     
* invoked.
     
*
     
* <p> Note that the byte is written as given; to write a character that
     
* will be translated according to the platform's default character
     
* encoding, use the <code>print(char)</code> or <code>println(char)</code>
     
* methods.
     
*
     
* @param
  
bThe byte to be written
     
* @see #print(char)
     
* @see #println(char)
     
*/

    
public void write(int b) {
        
try {
            
synchronized (this) {
                
ensureOpen();
                
out.write(b);
                
if ((b == '\n') && autoFlush)
                    
out.flush();
            
}
        
}
        
catch (InterruptedIOException x) {
            
Thread.currentThread().interrupt();
        
}
        
catch (IOException x) {
            
trouble = true;
        
}
    
}

    
/**
     
* Writes <code>len</code> bytes from the specified byte array starting at
     
* offset <code>off</code> to this stream.
  
If automatic flushing is
     
* enabled then the <code>flush</code> method will be invoked.
     
*
     
* <p> Note that the bytes will be written as given; to write characters
     
* that will be translated according to the platform's default character
     
* encoding, use the <code>print(char)</code> or <code>println(char)</code>
     
* methods.
     
*
     
* @param
  
buf
   
A byte array
     
* @param
  
off
   
Offset from which to start taking bytes
     
* @param
  
len
   
Number of bytes to write
     
*/

    
public void write(byte buf[], int off, int len) {
        
try {
            
synchronized (this) {
                
ensureOpen();
                
out.write(buf, off, len);
                
if (autoFlush)
                    
out.flush();
            
}
        
}
        
catch (InterruptedIOException x) {
            
Thread.currentThread().interrupt();
        
}
        
catch (IOException x) {
            
trouble = true;
        
}
    
}

    
/*
     
* The following private methods on the text- and character-output streams
     
* always flush the stream buffers, so that writes to the underlying byte
     
* stream occur as promptly as with the original PrintStream.
     
*/


    
private void write(char buf[]) {
        
try {
            
synchronized (this) {
                
ensureOpen();
                
textOut.write(buf);
                
textOut.flushBuffer();
                
charOut.flushBuffer();
                
if (autoFlush) {
                    
for (int i = 0; i < buf.length; i++)
                        
if (buf[i] == '\n')
                            
out.flush();
                
}
            
}
        
}
        
catch (InterruptedIOException x) {
            
Thread.currentThread().interrupt();
        
}
        
catch (IOException x) {
            
trouble = true;
        
}
    
}

    
private void write(String s) {
        
try {
            
synchronized (this) {
                
ensureOpen();
                
textOut.write(s);
                
textOut.flushBuffer();
                
charOut.flushBuffer();
                
if (autoFlush && (s.indexOf('\n') >= 0))
                    
out.flush();
            
}
        
}
        
catch (InterruptedIOException x) {
            
Thread.currentThread().interrupt();
        
}
        
catch (IOException x) {
            
trouble = true;
        
}
    
}

    
private void newLine() {
        
try {
            
synchronized (this) {
                
ensureOpen();
                
textOut.newLine();
                
textOut.flushBuffer();
                
charOut.flushBuffer();
                
if (autoFlush)
                    
out.flush();
            
}
        
}
        
catch (InterruptedIOException x) {
            
Thread.currentThread().interrupt();
        
}
        
catch (IOException x) {
            
trouble = true;
        
}
    
}

    
/* Methods that do not terminate lines */

    
/**
     
* Prints a boolean value.
  
The string produced by <code>{@link
     
* java.lang.String#valueOf(boolean)}</code> is translated into bytes
     
* according to the platform's default character encoding, and these bytes
     
* are written in exactly the manner of the
     
* <code>{@link #write(int)}</code> method.
     
*
     
* @param
      
b
   
The <code>boolean</code> to be printed
     
*/

    
public void print(boolean b) {
        
write(b ? "true" : "false");
    
}

    
/**
     
* Prints a character.
  
The character is translated into one or more bytes
     
* according to the platform's default character encoding, and these bytes
     
* are written in exactly the manner of the
     
* <code>{@link #write(int)}</code> method.
     
*
     
* @param
      
c
   
The <code>char</code> to be printed
     
*/

    
public void print(char c) {
        
write(String.valueOf(c));
    
}

    
/**
     
* Prints an integer.
  
The string produced by <code>{@link
     
* java.lang.String#valueOf(int)}</code> is translated into bytes
     
* according to the platform's default character encoding, and these bytes
     
* are written in exactly the manner of the
     
* <code>{@link #write(int)}</code> method.
     
*
     
* @param
      
i
   
The <code>int</code> to be printed
     
* @see
        
java.lang.Integer#toString(int)
     
*/

    
public void print(int i) {
        
write(String.valueOf(i));
    
}

    
/**
     
* Prints a long integer.
  
The string produced by <code>{@link
     
* java.lang.String#valueOf(long)}</code> is translated into bytes
     
* according to the platform's default character encoding, and these bytes
     
* are written in exactly the manner of the
     
* <code>{@link #write(int)}</code> method.
     
*
     
* @param
      
l
   
The <code>long</code> to be printed
     
* @see
        
java.lang.Long#toString(long)
     
*/

    
public void print(long l) {
        
write(String.valueOf(l));
    
}

    
/**
     
* Prints a floating-point number.
  
The string produced by <code>{@link
     
* java.lang.String#valueOf(float)}</code> is translated into bytes
     
* according to the platform's default character encoding, and these bytes
     
* are written in exactly the manner of the
     
* <code>{@link #write(int)}</code> method.
     
*
     
* @param
      
f
   
The <code>float</code> to be printed
     
* @see
        
java.lang.Float#toString(float)
     
*/

    
public void print(float f) {
        
write(String.valueOf(f));
    
}

    
/**
     
* Prints a double-precision floating-point number.
  
The string produced by
     
* <code>{@link java.lang.String#valueOf(double)}</code> is translated into
     
* bytes according to the platform's default character encoding, and these
     
* bytes are written in exactly the manner of the <code>{@link
     
* #write(int)}</code> method.
     
*
     
* @param
      
d
   
The <code>double</code> to be printed
     
* @see
        
java.lang.Double#toString(double)
     
*/

    
public void print(double d) {
        
write(String.valueOf(d));
    
}

    
/**
     
* Prints an array of characters.
  
The characters are converted into bytes
     
* according to the platform's default character encoding, and these bytes
     
* are written in exactly the manner of the
     
* <code>{@link #write(int)}</code> method.
     
*
     
* @param
      
s
   
The array of chars to be printed
     
*
     
* @throws
  
NullPointerExceptionIf <code>s</code> is <code>null</code>
     
*/

    
public void print(char s[]) {
        
write(s);
    
}

    
/**
     
* Prints a string.
  
If the argument is <code>null</code> then the string
     
* <code>"null"</code> is printed.
  
Otherwise, the string's characters are
     
* converted into bytes according to the platform's default character
     
* encoding, and these bytes are written in exactly the manner of the
     
* <code>{@link #write(int)}</code> method.
     
*
     
* @param
      
s
   
The <code>String</code> to be printed
     
*/

    
public void print(String s) {
        
if (s == null) {
            
s = "null";
        
}
        
write(s);
    
}

    
/**
     
* Prints an object.
  
The string produced by the <code>{@link
     
* java.lang.String#valueOf(Object)}</code> method is translated into bytes
     
* according to the platform's default character encoding, and these bytes
     
* are written in exactly the manner of the
     
* <code>{@link #write(int)}</code> method.
     
*
     
* @param
      
obj
   
The <code>Object</code> to be printed
     
* @see
        
java.lang.Object#toString()
     
*/

    
public void print(Object obj) {
        
write(String.valueOf(obj));
    
}


    
/* Methods that do terminate lines */

    
/**
     
* Terminates the current line by writing the line separator string.
  
The
     
* line separator string is defined by the system property
     
* <code>line.separator</code>, and is not necessarily a single newline
     
* character (<code>'\n'</code>).
     
*/

    
public void println() {
        
newLine();
    
}

    
/**
     
* Prints a boolean and then terminate the line.
  
This method behaves as
     
* though it invokes <code>{@link #print(boolean)}</code> and then
     
* <code> </code>.
     
*
     
* @param x
  
The <code>boolean</code> to be printed
     
*/

    
public void println(boolean x) {
        
synchronized (this) {
            
print(x);
            
newLine();
        
}
    
}

    
/**
     
* Prints a character and then terminate the line.
  
This method behaves as
     
* though it invokes <code>{@link #print(char)}</code> and then
     
* <code> </code>.
     
*
     
* @param x
  
The <code>char</code> to be printed.
     
*/

    
public void println(char x) {
        
synchronized (this) {
            
print(x);
            
newLine();
        
}
    
}

    
/**
     
* Prints an integer and then terminate the line.
  
This method behaves as
     
* though it invokes <code>{@link #print(int)}</code> and then
     
* <code> </code>.
     
*
     
* @param x
  
The <code>int</code> to be printed.
     
*/

    
public void println(int x) {
        
synchronized (this) {
            
print(x);
            
newLine();
        
}
    
}

    
/**
     
* Prints a long and then terminate the line.
  
This method behaves as
     
* though it invokes <code>{@link #print(long)}</code> and then
     
* <code> </code>.
     
*
     
* @param x
  
a The <code>long</code> to be printed.
     
*/

    
public void println(long x) {
        
synchronized (this) {
            
print(x);
            
newLine();
        
}
    
}

    
/**
     
* Prints a float and then terminate the line.
  
This method behaves as
     
* though it invokes <code>{@link #print(float)}</code> and then
     
* <code> </code>.
     
*
     
* @param x
  
The <code>float</code> to be printed.
     
*/

    
public void println(float x) {
        
synchronized (this) {
            
print(x);
            
newLine();
        
}
    
}

    
/**
     
* Prints a double and then terminate the line.
  
This method behaves as
     
* though it invokes <code>{@link #print(double)}</code> and then
     
* <code> </code>.
     
*
     
* @param x
  
The <code>double</code> to be printed.
     
*/

    
public void println(double x) {
        
synchronized (this) {
            
print(x);
            
newLine();
        
}
    
}

    
/**
     
* Prints an array of characters and then terminate the line.
  
This method
     
* behaves as though it invokes <code>{@link #print(char[])}</code> and
     
* then <code> </code>.
     
*
     
* @param x
  
an array of chars to print.
     
*/

    
public void println(char x[]) {
        
synchronized (this) {
            
print(x);
            
newLine();
        
}
    
}

    
/**
     
* Prints a String and then terminate the line.
  
This method behaves as
     
* though it invokes <code>{@link #print(String)}</code> and then
     
* <code> </code>.
     
*
     
* @param x
  
The <code>String</code> to be printed.
     
*/

    
public void println(String x) {
        
synchronized (this) {
            
print(x);
            
newLine();
        
}
    
}

    
/**
     
* Prints an Object and then terminate the line.
  
This method calls
     
* at first String.valueOf(x) to get the printed object's string value,
     
* then behaves as
     
* though it invokes <code>{@link #print(String)}</code> and then
     
* <code> </code>.
     
*
     
* @param x
  
The <code>Object</code> to be printed.
     
*/

    
public void println(Object x) {
        
String s = String.valueOf(x);
        
synchronized (this) {
            
print(s);
            
newLine();
        
}
    
}


    
/**
     
* A convenience method to write a formatted string to this output stream
     
* using the specified format string and arguments.
     
*
     
* <p> An invocation of this method of the form <tt>out.printf(format,
     
* args)</tt> behaves in exactly the same way as the invocation
     
*
     
* <pre>
     
*out.format(format, args) </pre>
     
*
     
* @param
  
format
     
*
         
A format string as described in <a
     
*
         
href="../util/Formatter.html#syntax">Format string syntax</a>
     
*
     
* @param
  
args
     
*
         
Arguments referenced by the format specifiers in the format
     
*
         
string.
  
If there are more arguments than format specifiers, the
     
*
         
extra arguments are ignored.
  
The number of arguments is
     
*
         
variable and may be zero.
  
The maximum number of arguments is
     
*
         
limited by the maximum dimension of a Java array as defined by
     
*
         
<cite>The Java&trade; Virtual Machine Specification</cite>.
     
*
         
The behaviour on a
     
*
         
<tt>null</tt> argument depends on the <a
     
*
         
href="../util/Formatter.html#syntax">conversion</a>.
     
*
     
* @throws
  
java.util.IllegalFormatException
     
*
          
If a format string contains an illegal syntax, a format
     
*
          
specifier that is incompatible with the given arguments,
     
*
          
insufficient arguments given the format string, or other
     
*
          
illegal conditions.
  
For specification of all possible
     
*
          
formatting errors, see the <a
     
*
          
href="../util/Formatter.html#detail">Details</a> section of the
     
*
          
formatter class specification.
     
*
     
* @throws
  
NullPointerException
     
*
          
If the <tt>format</tt> is <tt>null</tt>
     
*
     
* @return
  
This output stream
     
*
     
* @since
  
1.5
     
*/

    
public PrintStream printf(String format, Object ... args) {
        
return format(format, args);
    
}

    
/**
     
* A convenience method to write a formatted string to this output stream
     
* using the specified format string and arguments.
     
*
     
* <p> An invocation of this method of the form <tt>out.printf(l, format,
     
* args)</tt> behaves in exactly the same way as the invocation
     
*
     
* <pre>
     
*out.format(l, format, args) </pre>
     
*
     
* @param
  
l
     
*
         
The {@linkplain java.util.Locale locale} to apply during
     
*
         
formatting.
  
If <tt>l</tt> is <tt>null</tt> then no localization
     
*
         
is applied.
     
*
     
* @param
  
format
     
*
         
A format string as described in <a
     
*
         
href="../util/Formatter.html#syntax">Format string syntax</a>
     
*
     
* @param
  
args
     
*
         
Arguments referenced by the format specifiers in the format
     
*
         
string.
  
If there are more arguments than format specifiers, the
     
*
         
extra arguments are ignored.
  
The number of arguments is
     
*
         
variable and may be zero.
  
The maximum number of arguments is
     
*
         
limited by the maximum dimension of a Java array as defined by
     
*
         
<cite>The Java&trade; Virtual Machine Specification</cite>.
     
*
         
The behaviour on a
     
*
         
<tt>null</tt> argument depends on the <a
     
*
         
href="../util/Formatter.html#syntax">conversion</a>.
     
*
     
* @throws
  
java.util.IllegalFormatException
     
*
          
If a format string contains an illegal syntax, a format
     
*
          
specifier that is incompatible with the given arguments,
     
*
          
insufficient arguments given the format string, or other
     
*
          
illegal conditions.
  
For specification of all possible
     
*
          
formatting errors, see the <a
     
*
          
href="../util/Formatter.html#detail">Details</a> section of the
     
*
          
formatter class specification.
     
*
     
* @throws
  
NullPointerException
     
*
          
If the <tt>format</tt> is <tt>null</tt>
     
*
     
* @return
  
This output stream
     
*
     
* @since
  
1.5
     
*/

    
public PrintStream printf(Locale l, String format, Object ... args) {
        
return format(l, format, args);
    
}

    
/**
     
* Writes a formatted string to this output stream using the specified
     
* format string and arguments.
     
*
     
* <p> The locale always used is the one returned by {@link
     
* java.util.Locale#getDefault() Locale.getDefault()}, regardless of any
     
* previous invocations of other formatting methods on this object.
     
*
     
* @param
  
format
     
*
         
A format string as described in <a
     
*
         
href="../util/Formatter.html#syntax">Format string syntax</a>
     
*
     
* @param
  
args
     
*
         
Arguments referenced by the format specifiers in the format
     
*
         
string.
  
If there are more arguments than format specifiers, the
     
*
         
extra arguments are ignored.
  
The number of arguments is
     
*
         
variable and may be zero.
  
The maximum number of arguments is
     
*
         
limited by the maximum dimension of a Java array as defined by
     
*
         
<cite>The Java&trade; Virtual Machine Specification</cite>.
     
*
         
The behaviour on a
     
*
         
<tt>null</tt> argument depends on the <a
     
*
         
href="../util/Formatter.html#syntax">conversion</a>.
     
*
     
* @throws
  
java.util.IllegalFormatException
     
*
          
If a format string contains an illegal syntax, a format
     
*
          
specifier that is incompatible with the given arguments,
     
*
          
insufficient arguments given the format string, or other
     
*
          
illegal conditions.
  
For specification of all possible
     
*
          
formatting errors, see the <a
     
*
          
href="../util/Formatter.html#detail">Details</a> section of the
     
*
          
formatter class specification.
     
*
     
* @throws
  
NullPointerException
     
*
          
If the <tt>format</tt> is <tt>null</tt>
     
*
     
* @return
  
This output stream
     
*
     
* @since
  
1.5
     
*/

    
public PrintStream format(String format, Object ... args) {
        
try {
            
synchronized (this) {
                
ensureOpen();
                
if ((formatter == null)
                    
|| (formatter.locale() != Locale.getDefault()))
                    
formatter = new Formatter((Appendable) this);
                
formatter.format(Locale.getDefault(), format, args);
            
}
        
} catch (InterruptedIOException x) {
            
Thread.currentThread().interrupt();
        
} catch (IOException x) {
            
trouble = true;
        
}
        
return this;
    
}

    
/**
     
* Writes a formatted string to this output stream using the specified
     
* format string and arguments.
     
*
     
* @param
  
l
     
*
         
The {@linkplain java.util.Locale locale} to apply during
     
*
         
formatting.
  
If <tt>l</tt> is <tt>null</tt> then no localization
     
*
         
is applied.
     
*
     
* @param
  
format
     
*
         
A format string as described in <a
     
*
         
href="../util/Formatter.html#syntax">Format string syntax</a>
     
*
     
* @param
  
args
     
*
         
Arguments referenced by the format specifiers in the format
     
*
         
string.
  
If there are more arguments than format specifiers, the
     
*
         
extra arguments are ignored.
  
The number of arguments is
     
*
         
variable and may be zero.
  
The maximum number of arguments is
     
*
         
limited by the maximum dimension of a Java array as defined by
     
*
         
<cite>The Java&trade; Virtual Machine Specification</cite>.
     
*
         
The behaviour on a
     
*
         
<tt>null</tt> argument depends on the <a
     
*
         
href="../util/Formatter.html#syntax">conversion</a>.
     
*
     
* @throws
  
java.util.IllegalFormatException
     
*
          
If a format string contains an illegal syntax, a format
     
*
          
specifier that is incompatible with the given arguments,
     
*
          
insufficient arguments given the format string, or other
     
*
          
illegal conditions.
  
For specification of all possible
     
*
          
formatting errors, see the <a
     
*
          
href="../util/Formatter.html#detail">Details</a> section of the
     
*
          
formatter class specification.
     
*
     
* @throws
  
NullPointerException
     
*
          
If the <tt>format</tt> is <tt>null</tt>
     
*
     
* @return
  
This output stream
     
*
     
* @since
  
1.5
     
*/

    
public PrintStream format(Locale l, String format, Object ... args) {
        
try {
            
synchronized (this) {
                
ensureOpen();
                
if ((formatter == null)
                    
|| (formatter.locale() != l))
                    
formatter = new Formatter(this, l);
                
formatter.format(l, format, args);
            
}
        
} catch (InterruptedIOException x) {
            
Thread.currentThread().interrupt();
        
} catch (IOException x) {
            
trouble = true;
        
}
        
return this;
    
}

    
/**
     
* Appends the specified character sequence to this output stream.
     
*
     
* <p> An invocation of this method of the form <tt>out.append(csq)</tt>
     
* behaves in exactly the same way as the invocation
     
*
     
* <pre>
     
*out.print(csq.toString()) </pre>
     
*
     
* <p> Depending on the specification of <tt>toString</tt> for the
     
* character sequence <tt>csq</tt>, the entire sequence may not be
     
* appended.
  
For instance, invoking then <tt>toString</tt> method of a
     
* character buffer will return a subsequence whose content depends upon
     
* the buffer's position and limit.
     
*
     
* @param
  
csq
     
*
         
The character sequence to append.
  
If <tt>csq</tt> is
     
*
         
<tt>null</tt>, then the four characters <tt>"null"</tt> are
     
*
         
appended to this output stream.
     
*
     
* @return
  
This output stream
     
*
     
* @since
  
1.5
     
*/

    
public PrintStream append(CharSequence csq) {
        
if (csq == null)
            
print("null");
        
else
            
print(csq.toString());
        
return this;
    
}

    
/**
     
* Appends a subsequence of the specified character sequence to this output
     
* stream.
     
*
     
* <p> An invocation of this method of the form <tt>out.append(csq, start,
     
* end)</tt> when <tt>csq</tt> is not <tt>null</tt>, behaves in
     
* exactly the same way as the invocation
     
*
     
* <pre>
     
*out.print(csq.subSequence(start, end).toString()) </pre>
     
*
     
* @param
  
csq
     
*
         
The character sequence from which a subsequence will be
     
*
         
appended.
  
If <tt>csq</tt> is <tt>null</tt>, then characters
     
*
         
will be appended as if <tt>csq</tt> contained the four
     
*
         
characters <tt>"null"</tt>.
     
*
     
* @param
  
start
     
*
         
The index of the first character in the subsequence
     
*
     
* @param
  
end
     
*
         
The index of the character following the last character in the
     
*
         
subsequence
     
*
     
* @return
  
This output stream
     
*
     
* @throws
  
IndexOutOfBoundsException
     
*
          
If <tt>start</tt> or <tt>end</tt> are negative, <tt>start</tt>
     
*
          
is greater than <tt>end</tt>, or <tt>end</tt> is greater than
     
*
          
<tt>csq.length()</tt>
     
*
     
* @since
  
1.5
     
*/

    
public PrintStream append(CharSequence csq, int start, int end) {
        
CharSequence cs = (csq == null ? "null" : csq);
        
write(cs.subSequence(start, end).toString());
        
return this;
    
}

    
/**
     
* Appends the specified character to this output stream.
     
*
     
* <p> An invocation of this method of the form <tt>out.append(c)</tt>
     
* behaves in exactly the same way as the invocation
     
*
     
* <pre>
     
*out.print(c) </pre>
     
*
     
* @param
  
c
     
*
         
The 16-bit character to append
     
*
     
* @return
  
This output stream
     
*
     
* @since
  
1.5
     
*/

    
public PrintStream append(char c) {
        
print(c);
        
return this;
    
}

}