151b1b6997fd3f980076b8081f7f1165ccc2a4008Piotr Jastrzebski/*
22c87ad3a45cecf9e344487cad1abfdebe79f2c7cNarayan Kamath * Copyright (C) 2014 The Android Open Source Project
369dae7ca4d593ff2ada99cf69696e782bcd46757Przemyslaw Szczepaniak * Copyright (c) 2005, 2013, Oracle and/or its affiliates. All rights reserved.
451b1b6997fd3f980076b8081f7f1165ccc2a4008Piotr Jastrzebski * DO NOT ALTER OR REMOVE COPYRIGHT NOTICES OR THIS FILE HEADER.
551b1b6997fd3f980076b8081f7f1165ccc2a4008Piotr Jastrzebski *
651b1b6997fd3f980076b8081f7f1165ccc2a4008Piotr Jastrzebski * This code is free software; you can redistribute it and/or modify it
751b1b6997fd3f980076b8081f7f1165ccc2a4008Piotr Jastrzebski * under the terms of the GNU General Public License version 2 only, as
851b1b6997fd3f980076b8081f7f1165ccc2a4008Piotr Jastrzebski * published by the Free Software Foundation.  Oracle designates this
951b1b6997fd3f980076b8081f7f1165ccc2a4008Piotr Jastrzebski * particular file as subject to the "Classpath" exception as provided
1051b1b6997fd3f980076b8081f7f1165ccc2a4008Piotr Jastrzebski * by Oracle in the LICENSE file that accompanied this code.
1151b1b6997fd3f980076b8081f7f1165ccc2a4008Piotr Jastrzebski *
1251b1b6997fd3f980076b8081f7f1165ccc2a4008Piotr Jastrzebski * This code is distributed in the hope that it will be useful, but WITHOUT
1351b1b6997fd3f980076b8081f7f1165ccc2a4008Piotr Jastrzebski * ANY WARRANTY; without even the implied warranty of MERCHANTABILITY or
1451b1b6997fd3f980076b8081f7f1165ccc2a4008Piotr Jastrzebski * FITNESS FOR A PARTICULAR PURPOSE.  See the GNU General Public License
1551b1b6997fd3f980076b8081f7f1165ccc2a4008Piotr Jastrzebski * version 2 for more details (a copy is included in the LICENSE file that
1651b1b6997fd3f980076b8081f7f1165ccc2a4008Piotr Jastrzebski * accompanied this code).
1751b1b6997fd3f980076b8081f7f1165ccc2a4008Piotr Jastrzebski *
1851b1b6997fd3f980076b8081f7f1165ccc2a4008Piotr Jastrzebski * You should have received a copy of the GNU General Public License version
1951b1b6997fd3f980076b8081f7f1165ccc2a4008Piotr Jastrzebski * 2 along with this work; if not, write to the Free Software Foundation,
2051b1b6997fd3f980076b8081f7f1165ccc2a4008Piotr Jastrzebski * Inc., 51 Franklin St, Fifth Floor, Boston, MA 02110-1301 USA.
2151b1b6997fd3f980076b8081f7f1165ccc2a4008Piotr Jastrzebski *
2251b1b6997fd3f980076b8081f7f1165ccc2a4008Piotr Jastrzebski * Please contact Oracle, 500 Oracle Parkway, Redwood Shores, CA 94065 USA
2351b1b6997fd3f980076b8081f7f1165ccc2a4008Piotr Jastrzebski * or visit www.oracle.com if you need additional information or have any
2451b1b6997fd3f980076b8081f7f1165ccc2a4008Piotr Jastrzebski * questions.
2551b1b6997fd3f980076b8081f7f1165ccc2a4008Piotr Jastrzebski */
2651b1b6997fd3f980076b8081f7f1165ccc2a4008Piotr Jastrzebski
2751b1b6997fd3f980076b8081f7f1165ccc2a4008Piotr Jastrzebskipackage java.io;
2851b1b6997fd3f980076b8081f7f1165ccc2a4008Piotr Jastrzebski
2951b1b6997fd3f980076b8081f7f1165ccc2a4008Piotr Jastrzebskiimport java.util.*;
3051b1b6997fd3f980076b8081f7f1165ccc2a4008Piotr Jastrzebskiimport java.nio.charset.Charset;
3151b1b6997fd3f980076b8081f7f1165ccc2a4008Piotr Jastrzebskiimport sun.nio.cs.StreamDecoder;
3251b1b6997fd3f980076b8081f7f1165ccc2a4008Piotr Jastrzebskiimport sun.nio.cs.StreamEncoder;
3351b1b6997fd3f980076b8081f7f1165ccc2a4008Piotr Jastrzebski
3451b1b6997fd3f980076b8081f7f1165ccc2a4008Piotr Jastrzebski/**
3551b1b6997fd3f980076b8081f7f1165ccc2a4008Piotr Jastrzebski * Methods to access the character-based console device, if any, associated
3651b1b6997fd3f980076b8081f7f1165ccc2a4008Piotr Jastrzebski * with the current Java virtual machine.
3751b1b6997fd3f980076b8081f7f1165ccc2a4008Piotr Jastrzebski *
3851b1b6997fd3f980076b8081f7f1165ccc2a4008Piotr Jastrzebski * <p> Whether a virtual machine has a console is dependent upon the
3951b1b6997fd3f980076b8081f7f1165ccc2a4008Piotr Jastrzebski * underlying platform and also upon the manner in which the virtual
4051b1b6997fd3f980076b8081f7f1165ccc2a4008Piotr Jastrzebski * machine is invoked.  If the virtual machine is started from an
4151b1b6997fd3f980076b8081f7f1165ccc2a4008Piotr Jastrzebski * interactive command line without redirecting the standard input and
4251b1b6997fd3f980076b8081f7f1165ccc2a4008Piotr Jastrzebski * output streams then its console will exist and will typically be
4351b1b6997fd3f980076b8081f7f1165ccc2a4008Piotr Jastrzebski * connected to the keyboard and display from which the virtual machine
4451b1b6997fd3f980076b8081f7f1165ccc2a4008Piotr Jastrzebski * was launched.  If the virtual machine is started automatically, for
4551b1b6997fd3f980076b8081f7f1165ccc2a4008Piotr Jastrzebski * example by a background job scheduler, then it will typically not
4651b1b6997fd3f980076b8081f7f1165ccc2a4008Piotr Jastrzebski * have a console.
4751b1b6997fd3f980076b8081f7f1165ccc2a4008Piotr Jastrzebski * <p>
4851b1b6997fd3f980076b8081f7f1165ccc2a4008Piotr Jastrzebski * If this virtual machine has a console then it is represented by a
4951b1b6997fd3f980076b8081f7f1165ccc2a4008Piotr Jastrzebski * unique instance of this class which can be obtained by invoking the
5051b1b6997fd3f980076b8081f7f1165ccc2a4008Piotr Jastrzebski * {@link java.lang.System#console()} method.  If no console device is
5151b1b6997fd3f980076b8081f7f1165ccc2a4008Piotr Jastrzebski * available then an invocation of that method will return <tt>null</tt>.
5251b1b6997fd3f980076b8081f7f1165ccc2a4008Piotr Jastrzebski * <p>
5351b1b6997fd3f980076b8081f7f1165ccc2a4008Piotr Jastrzebski * Read and write operations are synchronized to guarantee the atomic
5451b1b6997fd3f980076b8081f7f1165ccc2a4008Piotr Jastrzebski * completion of critical operations; therefore invoking methods
5551b1b6997fd3f980076b8081f7f1165ccc2a4008Piotr Jastrzebski * {@link #readLine()}, {@link #readPassword()}, {@link #format format()},
5651b1b6997fd3f980076b8081f7f1165ccc2a4008Piotr Jastrzebski * {@link #printf printf()} as well as the read, format and write operations
5751b1b6997fd3f980076b8081f7f1165ccc2a4008Piotr Jastrzebski * on the objects returned by {@link #reader()} and {@link #writer()} may
5851b1b6997fd3f980076b8081f7f1165ccc2a4008Piotr Jastrzebski * block in multithreaded scenarios.
5951b1b6997fd3f980076b8081f7f1165ccc2a4008Piotr Jastrzebski * <p>
6051b1b6997fd3f980076b8081f7f1165ccc2a4008Piotr Jastrzebski * Invoking <tt>close()</tt> on the objects returned by the {@link #reader()}
6151b1b6997fd3f980076b8081f7f1165ccc2a4008Piotr Jastrzebski * and the {@link #writer()} will not close the underlying stream of those
6251b1b6997fd3f980076b8081f7f1165ccc2a4008Piotr Jastrzebski * objects.
6351b1b6997fd3f980076b8081f7f1165ccc2a4008Piotr Jastrzebski * <p>
6451b1b6997fd3f980076b8081f7f1165ccc2a4008Piotr Jastrzebski * The console-read methods return <tt>null</tt> when the end of the
6551b1b6997fd3f980076b8081f7f1165ccc2a4008Piotr Jastrzebski * console input stream is reached, for example by typing control-D on
6651b1b6997fd3f980076b8081f7f1165ccc2a4008Piotr Jastrzebski * Unix or control-Z on Windows.  Subsequent read operations will succeed
6751b1b6997fd3f980076b8081f7f1165ccc2a4008Piotr Jastrzebski * if additional characters are later entered on the console's input
6851b1b6997fd3f980076b8081f7f1165ccc2a4008Piotr Jastrzebski * device.
6951b1b6997fd3f980076b8081f7f1165ccc2a4008Piotr Jastrzebski * <p>
7051b1b6997fd3f980076b8081f7f1165ccc2a4008Piotr Jastrzebski * Unless otherwise specified, passing a <tt>null</tt> argument to any method
7151b1b6997fd3f980076b8081f7f1165ccc2a4008Piotr Jastrzebski * in this class will cause a {@link NullPointerException} to be thrown.
7251b1b6997fd3f980076b8081f7f1165ccc2a4008Piotr Jastrzebski * <p>
7351b1b6997fd3f980076b8081f7f1165ccc2a4008Piotr Jastrzebski * <b>Security note:</b>
7451b1b6997fd3f980076b8081f7f1165ccc2a4008Piotr Jastrzebski * If an application needs to read a password or other secure data, it should
7551b1b6997fd3f980076b8081f7f1165ccc2a4008Piotr Jastrzebski * use {@link #readPassword()} or {@link #readPassword(String, Object...)} and
7651b1b6997fd3f980076b8081f7f1165ccc2a4008Piotr Jastrzebski * manually zero the returned character array after processing to minimize the
7751b1b6997fd3f980076b8081f7f1165ccc2a4008Piotr Jastrzebski * lifetime of sensitive data in memory.
7851b1b6997fd3f980076b8081f7f1165ccc2a4008Piotr Jastrzebski *
7969dae7ca4d593ff2ada99cf69696e782bcd46757Przemyslaw Szczepaniak * <blockquote><pre>{@code
8051b1b6997fd3f980076b8081f7f1165ccc2a4008Piotr Jastrzebski * Console cons;
8151b1b6997fd3f980076b8081f7f1165ccc2a4008Piotr Jastrzebski * char[] passwd;
8251b1b6997fd3f980076b8081f7f1165ccc2a4008Piotr Jastrzebski * if ((cons = System.console()) != null &&
8351b1b6997fd3f980076b8081f7f1165ccc2a4008Piotr Jastrzebski *     (passwd = cons.readPassword("[%s]", "Password:")) != null) {
8451b1b6997fd3f980076b8081f7f1165ccc2a4008Piotr Jastrzebski *     ...
8551b1b6997fd3f980076b8081f7f1165ccc2a4008Piotr Jastrzebski *     java.util.Arrays.fill(passwd, ' ');
8651b1b6997fd3f980076b8081f7f1165ccc2a4008Piotr Jastrzebski * }
8769dae7ca4d593ff2ada99cf69696e782bcd46757Przemyslaw Szczepaniak * }</pre></blockquote>
8851b1b6997fd3f980076b8081f7f1165ccc2a4008Piotr Jastrzebski *
8951b1b6997fd3f980076b8081f7f1165ccc2a4008Piotr Jastrzebski * @author  Xueming Shen
9051b1b6997fd3f980076b8081f7f1165ccc2a4008Piotr Jastrzebski * @since   1.6
9151b1b6997fd3f980076b8081f7f1165ccc2a4008Piotr Jastrzebski */
9251b1b6997fd3f980076b8081f7f1165ccc2a4008Piotr Jastrzebski
9351b1b6997fd3f980076b8081f7f1165ccc2a4008Piotr Jastrzebskipublic final class Console implements Flushable
9451b1b6997fd3f980076b8081f7f1165ccc2a4008Piotr Jastrzebski{
9551b1b6997fd3f980076b8081f7f1165ccc2a4008Piotr Jastrzebski   /**
9651b1b6997fd3f980076b8081f7f1165ccc2a4008Piotr Jastrzebski    * Retrieves the unique {@link java.io.PrintWriter PrintWriter} object
9751b1b6997fd3f980076b8081f7f1165ccc2a4008Piotr Jastrzebski    * associated with this console.
9851b1b6997fd3f980076b8081f7f1165ccc2a4008Piotr Jastrzebski    *
9951b1b6997fd3f980076b8081f7f1165ccc2a4008Piotr Jastrzebski    * @return  The printwriter associated with this console
10051b1b6997fd3f980076b8081f7f1165ccc2a4008Piotr Jastrzebski    */
10151b1b6997fd3f980076b8081f7f1165ccc2a4008Piotr Jastrzebski    public PrintWriter writer() {
10251b1b6997fd3f980076b8081f7f1165ccc2a4008Piotr Jastrzebski        return pw;
10351b1b6997fd3f980076b8081f7f1165ccc2a4008Piotr Jastrzebski    }
10451b1b6997fd3f980076b8081f7f1165ccc2a4008Piotr Jastrzebski
10551b1b6997fd3f980076b8081f7f1165ccc2a4008Piotr Jastrzebski   /**
10651b1b6997fd3f980076b8081f7f1165ccc2a4008Piotr Jastrzebski    * Retrieves the unique {@link java.io.Reader Reader} object associated
10751b1b6997fd3f980076b8081f7f1165ccc2a4008Piotr Jastrzebski    * with this console.
10851b1b6997fd3f980076b8081f7f1165ccc2a4008Piotr Jastrzebski    * <p>
10951b1b6997fd3f980076b8081f7f1165ccc2a4008Piotr Jastrzebski    * This method is intended to be used by sophisticated applications, for
11051b1b6997fd3f980076b8081f7f1165ccc2a4008Piotr Jastrzebski    * example, a {@link java.util.Scanner} object which utilizes the rich
11151b1b6997fd3f980076b8081f7f1165ccc2a4008Piotr Jastrzebski    * parsing/scanning functionality provided by the <tt>Scanner</tt>:
11251b1b6997fd3f980076b8081f7f1165ccc2a4008Piotr Jastrzebski    * <blockquote><pre>
11351b1b6997fd3f980076b8081f7f1165ccc2a4008Piotr Jastrzebski    * Console con = System.console();
11451b1b6997fd3f980076b8081f7f1165ccc2a4008Piotr Jastrzebski    * if (con != null) {
11551b1b6997fd3f980076b8081f7f1165ccc2a4008Piotr Jastrzebski    *     Scanner sc = new Scanner(con.reader());
11651b1b6997fd3f980076b8081f7f1165ccc2a4008Piotr Jastrzebski    *     ...
11751b1b6997fd3f980076b8081f7f1165ccc2a4008Piotr Jastrzebski    * }
11851b1b6997fd3f980076b8081f7f1165ccc2a4008Piotr Jastrzebski    * </pre></blockquote>
11951b1b6997fd3f980076b8081f7f1165ccc2a4008Piotr Jastrzebski    * <p>
12051b1b6997fd3f980076b8081f7f1165ccc2a4008Piotr Jastrzebski    * For simple applications requiring only line-oriented reading, use
12151b1b6997fd3f980076b8081f7f1165ccc2a4008Piotr Jastrzebski    * <tt>{@link #readLine}</tt>.
12251b1b6997fd3f980076b8081f7f1165ccc2a4008Piotr Jastrzebski    * <p>
12351b1b6997fd3f980076b8081f7f1165ccc2a4008Piotr Jastrzebski    * The bulk read operations {@link java.io.Reader#read(char[]) read(char[]) },
12451b1b6997fd3f980076b8081f7f1165ccc2a4008Piotr Jastrzebski    * {@link java.io.Reader#read(char[], int, int) read(char[], int, int) } and
12551b1b6997fd3f980076b8081f7f1165ccc2a4008Piotr Jastrzebski    * {@link java.io.Reader#read(java.nio.CharBuffer) read(java.nio.CharBuffer)}
12651b1b6997fd3f980076b8081f7f1165ccc2a4008Piotr Jastrzebski    * on the returned object will not read in characters beyond the line
12751b1b6997fd3f980076b8081f7f1165ccc2a4008Piotr Jastrzebski    * bound for each invocation, even if the destination buffer has space for
12869dae7ca4d593ff2ada99cf69696e782bcd46757Przemyslaw Szczepaniak    * more characters. The {@code Reader}'s {@code read} methods may block if a
12969dae7ca4d593ff2ada99cf69696e782bcd46757Przemyslaw Szczepaniak    * line bound has not been entered or reached on the console's input device.
13069dae7ca4d593ff2ada99cf69696e782bcd46757Przemyslaw Szczepaniak    * A line bound is considered to be any one of a line feed (<tt>'\n'</tt>),
13169dae7ca4d593ff2ada99cf69696e782bcd46757Przemyslaw Szczepaniak    * a carriage return (<tt>'\r'</tt>), a carriage return followed immediately
13269dae7ca4d593ff2ada99cf69696e782bcd46757Przemyslaw Szczepaniak    * by a linefeed, or an end of stream.
13351b1b6997fd3f980076b8081f7f1165ccc2a4008Piotr Jastrzebski    *
13451b1b6997fd3f980076b8081f7f1165ccc2a4008Piotr Jastrzebski    * @return  The reader associated with this console
13551b1b6997fd3f980076b8081f7f1165ccc2a4008Piotr Jastrzebski    */
13651b1b6997fd3f980076b8081f7f1165ccc2a4008Piotr Jastrzebski    public Reader reader() {
13751b1b6997fd3f980076b8081f7f1165ccc2a4008Piotr Jastrzebski        return reader;
13851b1b6997fd3f980076b8081f7f1165ccc2a4008Piotr Jastrzebski    }
13951b1b6997fd3f980076b8081f7f1165ccc2a4008Piotr Jastrzebski
14051b1b6997fd3f980076b8081f7f1165ccc2a4008Piotr Jastrzebski   /**
14151b1b6997fd3f980076b8081f7f1165ccc2a4008Piotr Jastrzebski    * Writes a formatted string to this console's output stream using
14251b1b6997fd3f980076b8081f7f1165ccc2a4008Piotr Jastrzebski    * the specified format string and arguments.
14351b1b6997fd3f980076b8081f7f1165ccc2a4008Piotr Jastrzebski    *
14451b1b6997fd3f980076b8081f7f1165ccc2a4008Piotr Jastrzebski    * @param  fmt
14551b1b6997fd3f980076b8081f7f1165ccc2a4008Piotr Jastrzebski    *         A format string as described in <a
14651b1b6997fd3f980076b8081f7f1165ccc2a4008Piotr Jastrzebski    *         href="../util/Formatter.html#syntax">Format string syntax</a>
14751b1b6997fd3f980076b8081f7f1165ccc2a4008Piotr Jastrzebski    *
14851b1b6997fd3f980076b8081f7f1165ccc2a4008Piotr Jastrzebski    * @param  args
14951b1b6997fd3f980076b8081f7f1165ccc2a4008Piotr Jastrzebski    *         Arguments referenced by the format specifiers in the format
15051b1b6997fd3f980076b8081f7f1165ccc2a4008Piotr Jastrzebski    *         string.  If there are more arguments than format specifiers, the
15151b1b6997fd3f980076b8081f7f1165ccc2a4008Piotr Jastrzebski    *         extra arguments are ignored.  The number of arguments is
15251b1b6997fd3f980076b8081f7f1165ccc2a4008Piotr Jastrzebski    *         variable and may be zero.  The maximum number of arguments is
15351b1b6997fd3f980076b8081f7f1165ccc2a4008Piotr Jastrzebski    *         limited by the maximum dimension of a Java array as defined by
15451b1b6997fd3f980076b8081f7f1165ccc2a4008Piotr Jastrzebski    *         <cite>The Java&trade; Virtual Machine Specification</cite>.
15551b1b6997fd3f980076b8081f7f1165ccc2a4008Piotr Jastrzebski    *         The behaviour on a
15651b1b6997fd3f980076b8081f7f1165ccc2a4008Piotr Jastrzebski    *         <tt>null</tt> argument depends on the <a
15751b1b6997fd3f980076b8081f7f1165ccc2a4008Piotr Jastrzebski    *         href="../util/Formatter.html#syntax">conversion</a>.
15851b1b6997fd3f980076b8081f7f1165ccc2a4008Piotr Jastrzebski    *
15951b1b6997fd3f980076b8081f7f1165ccc2a4008Piotr Jastrzebski    * @throws  IllegalFormatException
16051b1b6997fd3f980076b8081f7f1165ccc2a4008Piotr Jastrzebski    *          If a format string contains an illegal syntax, a format
16151b1b6997fd3f980076b8081f7f1165ccc2a4008Piotr Jastrzebski    *          specifier that is incompatible with the given arguments,
16251b1b6997fd3f980076b8081f7f1165ccc2a4008Piotr Jastrzebski    *          insufficient arguments given the format string, or other
16351b1b6997fd3f980076b8081f7f1165ccc2a4008Piotr Jastrzebski    *          illegal conditions.  For specification of all possible
16451b1b6997fd3f980076b8081f7f1165ccc2a4008Piotr Jastrzebski    *          formatting errors, see the <a
16551b1b6997fd3f980076b8081f7f1165ccc2a4008Piotr Jastrzebski    *          href="../util/Formatter.html#detail">Details</a> section
16651b1b6997fd3f980076b8081f7f1165ccc2a4008Piotr Jastrzebski    *          of the formatter class specification.
16751b1b6997fd3f980076b8081f7f1165ccc2a4008Piotr Jastrzebski    *
16851b1b6997fd3f980076b8081f7f1165ccc2a4008Piotr Jastrzebski    * @return  This console
16951b1b6997fd3f980076b8081f7f1165ccc2a4008Piotr Jastrzebski    */
17051b1b6997fd3f980076b8081f7f1165ccc2a4008Piotr Jastrzebski    public Console format(String fmt, Object ...args) {
17151b1b6997fd3f980076b8081f7f1165ccc2a4008Piotr Jastrzebski        formatter.format(fmt, args).flush();
17251b1b6997fd3f980076b8081f7f1165ccc2a4008Piotr Jastrzebski        return this;
17351b1b6997fd3f980076b8081f7f1165ccc2a4008Piotr Jastrzebski    }
17451b1b6997fd3f980076b8081f7f1165ccc2a4008Piotr Jastrzebski
17551b1b6997fd3f980076b8081f7f1165ccc2a4008Piotr Jastrzebski   /**
17651b1b6997fd3f980076b8081f7f1165ccc2a4008Piotr Jastrzebski    * A convenience method to write a formatted string to this console's
17751b1b6997fd3f980076b8081f7f1165ccc2a4008Piotr Jastrzebski    * output stream using the specified format string and arguments.
17851b1b6997fd3f980076b8081f7f1165ccc2a4008Piotr Jastrzebski    *
17951b1b6997fd3f980076b8081f7f1165ccc2a4008Piotr Jastrzebski    * <p> An invocation of this method of the form <tt>con.printf(format,
18051b1b6997fd3f980076b8081f7f1165ccc2a4008Piotr Jastrzebski    * args)</tt> behaves in exactly the same way as the invocation of
18151b1b6997fd3f980076b8081f7f1165ccc2a4008Piotr Jastrzebski    * <pre>con.format(format, args)</pre>.
18251b1b6997fd3f980076b8081f7f1165ccc2a4008Piotr Jastrzebski    *
18351b1b6997fd3f980076b8081f7f1165ccc2a4008Piotr Jastrzebski    * @param  format
18451b1b6997fd3f980076b8081f7f1165ccc2a4008Piotr Jastrzebski    *         A format string as described in <a
18551b1b6997fd3f980076b8081f7f1165ccc2a4008Piotr Jastrzebski    *         href="../util/Formatter.html#syntax">Format string syntax</a>.
18651b1b6997fd3f980076b8081f7f1165ccc2a4008Piotr Jastrzebski    *
18751b1b6997fd3f980076b8081f7f1165ccc2a4008Piotr Jastrzebski    * @param  args
18851b1b6997fd3f980076b8081f7f1165ccc2a4008Piotr Jastrzebski    *         Arguments referenced by the format specifiers in the format
18951b1b6997fd3f980076b8081f7f1165ccc2a4008Piotr Jastrzebski    *         string.  If there are more arguments than format specifiers, the
19051b1b6997fd3f980076b8081f7f1165ccc2a4008Piotr Jastrzebski    *         extra arguments are ignored.  The number of arguments is
19151b1b6997fd3f980076b8081f7f1165ccc2a4008Piotr Jastrzebski    *         variable and may be zero.  The maximum number of arguments is
19251b1b6997fd3f980076b8081f7f1165ccc2a4008Piotr Jastrzebski    *         limited by the maximum dimension of a Java array as defined by
19351b1b6997fd3f980076b8081f7f1165ccc2a4008Piotr Jastrzebski    *         <cite>The Java&trade; Virtual Machine Specification</cite>.
19451b1b6997fd3f980076b8081f7f1165ccc2a4008Piotr Jastrzebski    *         The behaviour on a
19551b1b6997fd3f980076b8081f7f1165ccc2a4008Piotr Jastrzebski    *         <tt>null</tt> argument depends on the <a
19651b1b6997fd3f980076b8081f7f1165ccc2a4008Piotr Jastrzebski    *         href="../util/Formatter.html#syntax">conversion</a>.
19751b1b6997fd3f980076b8081f7f1165ccc2a4008Piotr Jastrzebski    *
19851b1b6997fd3f980076b8081f7f1165ccc2a4008Piotr Jastrzebski    * @throws  IllegalFormatException
19951b1b6997fd3f980076b8081f7f1165ccc2a4008Piotr Jastrzebski    *          If a format string contains an illegal syntax, a format
20051b1b6997fd3f980076b8081f7f1165ccc2a4008Piotr Jastrzebski    *          specifier that is incompatible with the given arguments,
20151b1b6997fd3f980076b8081f7f1165ccc2a4008Piotr Jastrzebski    *          insufficient arguments given the format string, or other
20251b1b6997fd3f980076b8081f7f1165ccc2a4008Piotr Jastrzebski    *          illegal conditions.  For specification of all possible
20351b1b6997fd3f980076b8081f7f1165ccc2a4008Piotr Jastrzebski    *          formatting errors, see the <a
20451b1b6997fd3f980076b8081f7f1165ccc2a4008Piotr Jastrzebski    *          href="../util/Formatter.html#detail">Details</a> section of the
20551b1b6997fd3f980076b8081f7f1165ccc2a4008Piotr Jastrzebski    *          formatter class specification.
20651b1b6997fd3f980076b8081f7f1165ccc2a4008Piotr Jastrzebski    *
20751b1b6997fd3f980076b8081f7f1165ccc2a4008Piotr Jastrzebski    * @return  This console
20851b1b6997fd3f980076b8081f7f1165ccc2a4008Piotr Jastrzebski    */
20951b1b6997fd3f980076b8081f7f1165ccc2a4008Piotr Jastrzebski    public Console printf(String format, Object ... args) {
21051b1b6997fd3f980076b8081f7f1165ccc2a4008Piotr Jastrzebski        return format(format, args);
21151b1b6997fd3f980076b8081f7f1165ccc2a4008Piotr Jastrzebski    }
21251b1b6997fd3f980076b8081f7f1165ccc2a4008Piotr Jastrzebski
21351b1b6997fd3f980076b8081f7f1165ccc2a4008Piotr Jastrzebski   /**
21451b1b6997fd3f980076b8081f7f1165ccc2a4008Piotr Jastrzebski    * Provides a formatted prompt, then reads a single line of text from the
21551b1b6997fd3f980076b8081f7f1165ccc2a4008Piotr Jastrzebski    * console.
21651b1b6997fd3f980076b8081f7f1165ccc2a4008Piotr Jastrzebski    *
21751b1b6997fd3f980076b8081f7f1165ccc2a4008Piotr Jastrzebski    * @param  fmt
21851b1b6997fd3f980076b8081f7f1165ccc2a4008Piotr Jastrzebski    *         A format string as described in <a
21951b1b6997fd3f980076b8081f7f1165ccc2a4008Piotr Jastrzebski    *         href="../util/Formatter.html#syntax">Format string syntax</a>.
22051b1b6997fd3f980076b8081f7f1165ccc2a4008Piotr Jastrzebski    *
22151b1b6997fd3f980076b8081f7f1165ccc2a4008Piotr Jastrzebski    * @param  args
22251b1b6997fd3f980076b8081f7f1165ccc2a4008Piotr Jastrzebski    *         Arguments referenced by the format specifiers in the format
22351b1b6997fd3f980076b8081f7f1165ccc2a4008Piotr Jastrzebski    *         string.  If there are more arguments than format specifiers, the
22451b1b6997fd3f980076b8081f7f1165ccc2a4008Piotr Jastrzebski    *         extra arguments are ignored.  The maximum number of arguments is
22551b1b6997fd3f980076b8081f7f1165ccc2a4008Piotr Jastrzebski    *         limited by the maximum dimension of a Java array as defined by
22651b1b6997fd3f980076b8081f7f1165ccc2a4008Piotr Jastrzebski    *         <cite>The Java&trade; Virtual Machine Specification</cite>.
22751b1b6997fd3f980076b8081f7f1165ccc2a4008Piotr Jastrzebski    *
22851b1b6997fd3f980076b8081f7f1165ccc2a4008Piotr Jastrzebski    * @throws  IllegalFormatException
22951b1b6997fd3f980076b8081f7f1165ccc2a4008Piotr Jastrzebski    *          If a format string contains an illegal syntax, a format
23051b1b6997fd3f980076b8081f7f1165ccc2a4008Piotr Jastrzebski    *          specifier that is incompatible with the given arguments,
23151b1b6997fd3f980076b8081f7f1165ccc2a4008Piotr Jastrzebski    *          insufficient arguments given the format string, or other
23251b1b6997fd3f980076b8081f7f1165ccc2a4008Piotr Jastrzebski    *          illegal conditions.  For specification of all possible
23351b1b6997fd3f980076b8081f7f1165ccc2a4008Piotr Jastrzebski    *          formatting errors, see the <a
23451b1b6997fd3f980076b8081f7f1165ccc2a4008Piotr Jastrzebski    *          href="../util/Formatter.html#detail">Details</a> section
23551b1b6997fd3f980076b8081f7f1165ccc2a4008Piotr Jastrzebski    *          of the formatter class specification.
23651b1b6997fd3f980076b8081f7f1165ccc2a4008Piotr Jastrzebski    *
23751b1b6997fd3f980076b8081f7f1165ccc2a4008Piotr Jastrzebski    * @throws IOError
23851b1b6997fd3f980076b8081f7f1165ccc2a4008Piotr Jastrzebski    *         If an I/O error occurs.
23951b1b6997fd3f980076b8081f7f1165ccc2a4008Piotr Jastrzebski    *
24051b1b6997fd3f980076b8081f7f1165ccc2a4008Piotr Jastrzebski    * @return  A string containing the line read from the console, not
24151b1b6997fd3f980076b8081f7f1165ccc2a4008Piotr Jastrzebski    *          including any line-termination characters, or <tt>null</tt>
24251b1b6997fd3f980076b8081f7f1165ccc2a4008Piotr Jastrzebski    *          if an end of stream has been reached.
24351b1b6997fd3f980076b8081f7f1165ccc2a4008Piotr Jastrzebski    */
24451b1b6997fd3f980076b8081f7f1165ccc2a4008Piotr Jastrzebski    public String readLine(String fmt, Object ... args) {
24551b1b6997fd3f980076b8081f7f1165ccc2a4008Piotr Jastrzebski        String line = null;
24651b1b6997fd3f980076b8081f7f1165ccc2a4008Piotr Jastrzebski        synchronized (writeLock) {
24751b1b6997fd3f980076b8081f7f1165ccc2a4008Piotr Jastrzebski            synchronized(readLock) {
24851b1b6997fd3f980076b8081f7f1165ccc2a4008Piotr Jastrzebski                if (fmt.length() != 0)
24951b1b6997fd3f980076b8081f7f1165ccc2a4008Piotr Jastrzebski                    pw.format(fmt, args);
25051b1b6997fd3f980076b8081f7f1165ccc2a4008Piotr Jastrzebski                try {
25151b1b6997fd3f980076b8081f7f1165ccc2a4008Piotr Jastrzebski                    char[] ca = readline(false);
25251b1b6997fd3f980076b8081f7f1165ccc2a4008Piotr Jastrzebski                    if (ca != null)
25351b1b6997fd3f980076b8081f7f1165ccc2a4008Piotr Jastrzebski                        line = new String(ca);
25451b1b6997fd3f980076b8081f7f1165ccc2a4008Piotr Jastrzebski                } catch (IOException x) {
25551b1b6997fd3f980076b8081f7f1165ccc2a4008Piotr Jastrzebski                    throw new IOError(x);
25651b1b6997fd3f980076b8081f7f1165ccc2a4008Piotr Jastrzebski                }
25751b1b6997fd3f980076b8081f7f1165ccc2a4008Piotr Jastrzebski            }
25851b1b6997fd3f980076b8081f7f1165ccc2a4008Piotr Jastrzebski        }
25951b1b6997fd3f980076b8081f7f1165ccc2a4008Piotr Jastrzebski        return line;
26051b1b6997fd3f980076b8081f7f1165ccc2a4008Piotr Jastrzebski    }
26151b1b6997fd3f980076b8081f7f1165ccc2a4008Piotr Jastrzebski
26251b1b6997fd3f980076b8081f7f1165ccc2a4008Piotr Jastrzebski   /**
26351b1b6997fd3f980076b8081f7f1165ccc2a4008Piotr Jastrzebski    * Reads a single line of text from the console.
26451b1b6997fd3f980076b8081f7f1165ccc2a4008Piotr Jastrzebski    *
26551b1b6997fd3f980076b8081f7f1165ccc2a4008Piotr Jastrzebski    * @throws IOError
26651b1b6997fd3f980076b8081f7f1165ccc2a4008Piotr Jastrzebski    *         If an I/O error occurs.
26751b1b6997fd3f980076b8081f7f1165ccc2a4008Piotr Jastrzebski    *
26851b1b6997fd3f980076b8081f7f1165ccc2a4008Piotr Jastrzebski    * @return  A string containing the line read from the console, not
26951b1b6997fd3f980076b8081f7f1165ccc2a4008Piotr Jastrzebski    *          including any line-termination characters, or <tt>null</tt>
27051b1b6997fd3f980076b8081f7f1165ccc2a4008Piotr Jastrzebski    *          if an end of stream has been reached.
27151b1b6997fd3f980076b8081f7f1165ccc2a4008Piotr Jastrzebski    */
27251b1b6997fd3f980076b8081f7f1165ccc2a4008Piotr Jastrzebski    public String readLine() {
27351b1b6997fd3f980076b8081f7f1165ccc2a4008Piotr Jastrzebski        return readLine("");
27451b1b6997fd3f980076b8081f7f1165ccc2a4008Piotr Jastrzebski    }
27551b1b6997fd3f980076b8081f7f1165ccc2a4008Piotr Jastrzebski
27651b1b6997fd3f980076b8081f7f1165ccc2a4008Piotr Jastrzebski   /**
27751b1b6997fd3f980076b8081f7f1165ccc2a4008Piotr Jastrzebski    * Provides a formatted prompt, then reads a password or passphrase from
27851b1b6997fd3f980076b8081f7f1165ccc2a4008Piotr Jastrzebski    * the console with echoing disabled.
27951b1b6997fd3f980076b8081f7f1165ccc2a4008Piotr Jastrzebski    *
28051b1b6997fd3f980076b8081f7f1165ccc2a4008Piotr Jastrzebski    * @param  fmt
28151b1b6997fd3f980076b8081f7f1165ccc2a4008Piotr Jastrzebski    *         A format string as described in <a
28251b1b6997fd3f980076b8081f7f1165ccc2a4008Piotr Jastrzebski    *         href="../util/Formatter.html#syntax">Format string syntax</a>
28351b1b6997fd3f980076b8081f7f1165ccc2a4008Piotr Jastrzebski    *         for the prompt text.
28451b1b6997fd3f980076b8081f7f1165ccc2a4008Piotr Jastrzebski    *
28551b1b6997fd3f980076b8081f7f1165ccc2a4008Piotr Jastrzebski    * @param  args
28651b1b6997fd3f980076b8081f7f1165ccc2a4008Piotr Jastrzebski    *         Arguments referenced by the format specifiers in the format
28751b1b6997fd3f980076b8081f7f1165ccc2a4008Piotr Jastrzebski    *         string.  If there are more arguments than format specifiers, the
28851b1b6997fd3f980076b8081f7f1165ccc2a4008Piotr Jastrzebski    *         extra arguments are ignored.  The maximum number of arguments is
28951b1b6997fd3f980076b8081f7f1165ccc2a4008Piotr Jastrzebski    *         limited by the maximum dimension of a Java array as defined by
29051b1b6997fd3f980076b8081f7f1165ccc2a4008Piotr Jastrzebski    *         <cite>The Java&trade; Virtual Machine Specification</cite>.
29151b1b6997fd3f980076b8081f7f1165ccc2a4008Piotr Jastrzebski    *
29251b1b6997fd3f980076b8081f7f1165ccc2a4008Piotr Jastrzebski    * @throws  IllegalFormatException
29351b1b6997fd3f980076b8081f7f1165ccc2a4008Piotr Jastrzebski    *          If a format string contains an illegal syntax, a format
29451b1b6997fd3f980076b8081f7f1165ccc2a4008Piotr Jastrzebski    *          specifier that is incompatible with the given arguments,
29551b1b6997fd3f980076b8081f7f1165ccc2a4008Piotr Jastrzebski    *          insufficient arguments given the format string, or other
29651b1b6997fd3f980076b8081f7f1165ccc2a4008Piotr Jastrzebski    *          illegal conditions.  For specification of all possible
29751b1b6997fd3f980076b8081f7f1165ccc2a4008Piotr Jastrzebski    *          formatting errors, see the <a
29851b1b6997fd3f980076b8081f7f1165ccc2a4008Piotr Jastrzebski    *          href="../util/Formatter.html#detail">Details</a>
29951b1b6997fd3f980076b8081f7f1165ccc2a4008Piotr Jastrzebski    *          section of the formatter class specification.
30051b1b6997fd3f980076b8081f7f1165ccc2a4008Piotr Jastrzebski    *
30151b1b6997fd3f980076b8081f7f1165ccc2a4008Piotr Jastrzebski    * @throws IOError
30251b1b6997fd3f980076b8081f7f1165ccc2a4008Piotr Jastrzebski    *         If an I/O error occurs.
30351b1b6997fd3f980076b8081f7f1165ccc2a4008Piotr Jastrzebski    *
30451b1b6997fd3f980076b8081f7f1165ccc2a4008Piotr Jastrzebski    * @return  A character array containing the password or passphrase read
30551b1b6997fd3f980076b8081f7f1165ccc2a4008Piotr Jastrzebski    *          from the console, not including any line-termination characters,
30651b1b6997fd3f980076b8081f7f1165ccc2a4008Piotr Jastrzebski    *          or <tt>null</tt> if an end of stream has been reached.
30751b1b6997fd3f980076b8081f7f1165ccc2a4008Piotr Jastrzebski    */
30851b1b6997fd3f980076b8081f7f1165ccc2a4008Piotr Jastrzebski    public char[] readPassword(String fmt, Object ... args) {
30951b1b6997fd3f980076b8081f7f1165ccc2a4008Piotr Jastrzebski        char[] passwd = null;
31051b1b6997fd3f980076b8081f7f1165ccc2a4008Piotr Jastrzebski        synchronized (writeLock) {
31151b1b6997fd3f980076b8081f7f1165ccc2a4008Piotr Jastrzebski            synchronized(readLock) {
31251b1b6997fd3f980076b8081f7f1165ccc2a4008Piotr Jastrzebski                try {
31351b1b6997fd3f980076b8081f7f1165ccc2a4008Piotr Jastrzebski                    echoOff = echo(false);
31451b1b6997fd3f980076b8081f7f1165ccc2a4008Piotr Jastrzebski                } catch (IOException x) {
31551b1b6997fd3f980076b8081f7f1165ccc2a4008Piotr Jastrzebski                    throw new IOError(x);
31651b1b6997fd3f980076b8081f7f1165ccc2a4008Piotr Jastrzebski                }
31751b1b6997fd3f980076b8081f7f1165ccc2a4008Piotr Jastrzebski                IOError ioe = null;
31851b1b6997fd3f980076b8081f7f1165ccc2a4008Piotr Jastrzebski                try {
31951b1b6997fd3f980076b8081f7f1165ccc2a4008Piotr Jastrzebski                    if (fmt.length() != 0)
32051b1b6997fd3f980076b8081f7f1165ccc2a4008Piotr Jastrzebski                        pw.format(fmt, args);
32151b1b6997fd3f980076b8081f7f1165ccc2a4008Piotr Jastrzebski                    passwd = readline(true);
32251b1b6997fd3f980076b8081f7f1165ccc2a4008Piotr Jastrzebski                } catch (IOException x) {
32351b1b6997fd3f980076b8081f7f1165ccc2a4008Piotr Jastrzebski                    ioe = new IOError(x);
32451b1b6997fd3f980076b8081f7f1165ccc2a4008Piotr Jastrzebski                } finally {
32551b1b6997fd3f980076b8081f7f1165ccc2a4008Piotr Jastrzebski                    try {
32651b1b6997fd3f980076b8081f7f1165ccc2a4008Piotr Jastrzebski                        echoOff = echo(true);
32751b1b6997fd3f980076b8081f7f1165ccc2a4008Piotr Jastrzebski                    } catch (IOException x) {
32851b1b6997fd3f980076b8081f7f1165ccc2a4008Piotr Jastrzebski                        if (ioe == null)
32951b1b6997fd3f980076b8081f7f1165ccc2a4008Piotr Jastrzebski                            ioe = new IOError(x);
33051b1b6997fd3f980076b8081f7f1165ccc2a4008Piotr Jastrzebski                        else
33151b1b6997fd3f980076b8081f7f1165ccc2a4008Piotr Jastrzebski                            ioe.addSuppressed(x);
33251b1b6997fd3f980076b8081f7f1165ccc2a4008Piotr Jastrzebski                    }
33351b1b6997fd3f980076b8081f7f1165ccc2a4008Piotr Jastrzebski                    if (ioe != null)
33451b1b6997fd3f980076b8081f7f1165ccc2a4008Piotr Jastrzebski                        throw ioe;
33551b1b6997fd3f980076b8081f7f1165ccc2a4008Piotr Jastrzebski                }
33651b1b6997fd3f980076b8081f7f1165ccc2a4008Piotr Jastrzebski                pw.println();
33751b1b6997fd3f980076b8081f7f1165ccc2a4008Piotr Jastrzebski            }
33851b1b6997fd3f980076b8081f7f1165ccc2a4008Piotr Jastrzebski        }
33951b1b6997fd3f980076b8081f7f1165ccc2a4008Piotr Jastrzebski        return passwd;
34051b1b6997fd3f980076b8081f7f1165ccc2a4008Piotr Jastrzebski    }
34151b1b6997fd3f980076b8081f7f1165ccc2a4008Piotr Jastrzebski
34251b1b6997fd3f980076b8081f7f1165ccc2a4008Piotr Jastrzebski   /**
34351b1b6997fd3f980076b8081f7f1165ccc2a4008Piotr Jastrzebski    * Reads a password or passphrase from the console with echoing disabled
34451b1b6997fd3f980076b8081f7f1165ccc2a4008Piotr Jastrzebski    *
34551b1b6997fd3f980076b8081f7f1165ccc2a4008Piotr Jastrzebski    * @throws IOError
34651b1b6997fd3f980076b8081f7f1165ccc2a4008Piotr Jastrzebski    *         If an I/O error occurs.
34751b1b6997fd3f980076b8081f7f1165ccc2a4008Piotr Jastrzebski    *
34851b1b6997fd3f980076b8081f7f1165ccc2a4008Piotr Jastrzebski    * @return  A character array containing the password or passphrase read
34951b1b6997fd3f980076b8081f7f1165ccc2a4008Piotr Jastrzebski    *          from the console, not including any line-termination characters,
35051b1b6997fd3f980076b8081f7f1165ccc2a4008Piotr Jastrzebski    *          or <tt>null</tt> if an end of stream has been reached.
35151b1b6997fd3f980076b8081f7f1165ccc2a4008Piotr Jastrzebski    */
35251b1b6997fd3f980076b8081f7f1165ccc2a4008Piotr Jastrzebski    public char[] readPassword() {
35351b1b6997fd3f980076b8081f7f1165ccc2a4008Piotr Jastrzebski        return readPassword("");
35451b1b6997fd3f980076b8081f7f1165ccc2a4008Piotr Jastrzebski    }
35551b1b6997fd3f980076b8081f7f1165ccc2a4008Piotr Jastrzebski
35651b1b6997fd3f980076b8081f7f1165ccc2a4008Piotr Jastrzebski    /**
35751b1b6997fd3f980076b8081f7f1165ccc2a4008Piotr Jastrzebski     * Flushes the console and forces any buffered output to be written
35851b1b6997fd3f980076b8081f7f1165ccc2a4008Piotr Jastrzebski     * immediately .
35951b1b6997fd3f980076b8081f7f1165ccc2a4008Piotr Jastrzebski     */
36051b1b6997fd3f980076b8081f7f1165ccc2a4008Piotr Jastrzebski    public void flush() {
36151b1b6997fd3f980076b8081f7f1165ccc2a4008Piotr Jastrzebski        pw.flush();
36251b1b6997fd3f980076b8081f7f1165ccc2a4008Piotr Jastrzebski    }
36351b1b6997fd3f980076b8081f7f1165ccc2a4008Piotr Jastrzebski
36451b1b6997fd3f980076b8081f7f1165ccc2a4008Piotr Jastrzebski    private Object readLock;
36551b1b6997fd3f980076b8081f7f1165ccc2a4008Piotr Jastrzebski    private Object writeLock;
36651b1b6997fd3f980076b8081f7f1165ccc2a4008Piotr Jastrzebski    private Reader reader;
36751b1b6997fd3f980076b8081f7f1165ccc2a4008Piotr Jastrzebski    private Writer out;
36851b1b6997fd3f980076b8081f7f1165ccc2a4008Piotr Jastrzebski    private PrintWriter pw;
36951b1b6997fd3f980076b8081f7f1165ccc2a4008Piotr Jastrzebski    private Formatter formatter;
37051b1b6997fd3f980076b8081f7f1165ccc2a4008Piotr Jastrzebski    private Charset cs;
37151b1b6997fd3f980076b8081f7f1165ccc2a4008Piotr Jastrzebski    private char[] rcb;
37251b1b6997fd3f980076b8081f7f1165ccc2a4008Piotr Jastrzebski    private static native String encoding();
37351b1b6997fd3f980076b8081f7f1165ccc2a4008Piotr Jastrzebski    private static native boolean echo(boolean on) throws IOException;
37451b1b6997fd3f980076b8081f7f1165ccc2a4008Piotr Jastrzebski    private static boolean echoOff;
37551b1b6997fd3f980076b8081f7f1165ccc2a4008Piotr Jastrzebski
37651b1b6997fd3f980076b8081f7f1165ccc2a4008Piotr Jastrzebski    private char[] readline(boolean zeroOut) throws IOException {
37751b1b6997fd3f980076b8081f7f1165ccc2a4008Piotr Jastrzebski        int len = reader.read(rcb, 0, rcb.length);
37851b1b6997fd3f980076b8081f7f1165ccc2a4008Piotr Jastrzebski        if (len < 0)
37951b1b6997fd3f980076b8081f7f1165ccc2a4008Piotr Jastrzebski            return null;  //EOL
38051b1b6997fd3f980076b8081f7f1165ccc2a4008Piotr Jastrzebski        if (rcb[len-1] == '\r')
38151b1b6997fd3f980076b8081f7f1165ccc2a4008Piotr Jastrzebski            len--;        //remove CR at end;
38251b1b6997fd3f980076b8081f7f1165ccc2a4008Piotr Jastrzebski        else if (rcb[len-1] == '\n') {
38351b1b6997fd3f980076b8081f7f1165ccc2a4008Piotr Jastrzebski            len--;        //remove LF at end;
38451b1b6997fd3f980076b8081f7f1165ccc2a4008Piotr Jastrzebski            if (len > 0 && rcb[len-1] == '\r')
38551b1b6997fd3f980076b8081f7f1165ccc2a4008Piotr Jastrzebski                len--;    //remove the CR, if there is one
38651b1b6997fd3f980076b8081f7f1165ccc2a4008Piotr Jastrzebski        }
38751b1b6997fd3f980076b8081f7f1165ccc2a4008Piotr Jastrzebski        char[] b = new char[len];
38851b1b6997fd3f980076b8081f7f1165ccc2a4008Piotr Jastrzebski        if (len > 0) {
38951b1b6997fd3f980076b8081f7f1165ccc2a4008Piotr Jastrzebski            System.arraycopy(rcb, 0, b, 0, len);
39051b1b6997fd3f980076b8081f7f1165ccc2a4008Piotr Jastrzebski            if (zeroOut) {
39151b1b6997fd3f980076b8081f7f1165ccc2a4008Piotr Jastrzebski                Arrays.fill(rcb, 0, len, ' ');
39251b1b6997fd3f980076b8081f7f1165ccc2a4008Piotr Jastrzebski            }
39351b1b6997fd3f980076b8081f7f1165ccc2a4008Piotr Jastrzebski        }
39451b1b6997fd3f980076b8081f7f1165ccc2a4008Piotr Jastrzebski        return b;
39551b1b6997fd3f980076b8081f7f1165ccc2a4008Piotr Jastrzebski    }
39651b1b6997fd3f980076b8081f7f1165ccc2a4008Piotr Jastrzebski
39751b1b6997fd3f980076b8081f7f1165ccc2a4008Piotr Jastrzebski    private char[] grow() {
39851b1b6997fd3f980076b8081f7f1165ccc2a4008Piotr Jastrzebski        assert Thread.holdsLock(readLock);
39951b1b6997fd3f980076b8081f7f1165ccc2a4008Piotr Jastrzebski        char[] t = new char[rcb.length * 2];
40051b1b6997fd3f980076b8081f7f1165ccc2a4008Piotr Jastrzebski        System.arraycopy(rcb, 0, t, 0, rcb.length);
40151b1b6997fd3f980076b8081f7f1165ccc2a4008Piotr Jastrzebski        rcb = t;
40251b1b6997fd3f980076b8081f7f1165ccc2a4008Piotr Jastrzebski        return rcb;
40351b1b6997fd3f980076b8081f7f1165ccc2a4008Piotr Jastrzebski    }
40451b1b6997fd3f980076b8081f7f1165ccc2a4008Piotr Jastrzebski
40551b1b6997fd3f980076b8081f7f1165ccc2a4008Piotr Jastrzebski    class LineReader extends Reader {
40651b1b6997fd3f980076b8081f7f1165ccc2a4008Piotr Jastrzebski        private Reader in;
40751b1b6997fd3f980076b8081f7f1165ccc2a4008Piotr Jastrzebski        private char[] cb;
40851b1b6997fd3f980076b8081f7f1165ccc2a4008Piotr Jastrzebski        private int nChars, nextChar;
40951b1b6997fd3f980076b8081f7f1165ccc2a4008Piotr Jastrzebski        boolean leftoverLF;
41051b1b6997fd3f980076b8081f7f1165ccc2a4008Piotr Jastrzebski        LineReader(Reader in) {
41151b1b6997fd3f980076b8081f7f1165ccc2a4008Piotr Jastrzebski            this.in = in;
41251b1b6997fd3f980076b8081f7f1165ccc2a4008Piotr Jastrzebski            cb = new char[1024];
41351b1b6997fd3f980076b8081f7f1165ccc2a4008Piotr Jastrzebski            nextChar = nChars = 0;
41451b1b6997fd3f980076b8081f7f1165ccc2a4008Piotr Jastrzebski            leftoverLF = false;
41551b1b6997fd3f980076b8081f7f1165ccc2a4008Piotr Jastrzebski        }
41651b1b6997fd3f980076b8081f7f1165ccc2a4008Piotr Jastrzebski        public void close () {}
41751b1b6997fd3f980076b8081f7f1165ccc2a4008Piotr Jastrzebski        public boolean ready() throws IOException {
41851b1b6997fd3f980076b8081f7f1165ccc2a4008Piotr Jastrzebski            //in.ready synchronizes on readLock already
41951b1b6997fd3f980076b8081f7f1165ccc2a4008Piotr Jastrzebski            return in.ready();
42051b1b6997fd3f980076b8081f7f1165ccc2a4008Piotr Jastrzebski        }
42151b1b6997fd3f980076b8081f7f1165ccc2a4008Piotr Jastrzebski
42251b1b6997fd3f980076b8081f7f1165ccc2a4008Piotr Jastrzebski        public int read(char cbuf[], int offset, int length)
42351b1b6997fd3f980076b8081f7f1165ccc2a4008Piotr Jastrzebski            throws IOException
42451b1b6997fd3f980076b8081f7f1165ccc2a4008Piotr Jastrzebski        {
42551b1b6997fd3f980076b8081f7f1165ccc2a4008Piotr Jastrzebski            int off = offset;
42651b1b6997fd3f980076b8081f7f1165ccc2a4008Piotr Jastrzebski            int end = offset + length;
42751b1b6997fd3f980076b8081f7f1165ccc2a4008Piotr Jastrzebski            if (offset < 0 || offset > cbuf.length || length < 0 ||
42851b1b6997fd3f980076b8081f7f1165ccc2a4008Piotr Jastrzebski                end < 0 || end > cbuf.length) {
42951b1b6997fd3f980076b8081f7f1165ccc2a4008Piotr Jastrzebski                throw new IndexOutOfBoundsException();
43051b1b6997fd3f980076b8081f7f1165ccc2a4008Piotr Jastrzebski            }
43151b1b6997fd3f980076b8081f7f1165ccc2a4008Piotr Jastrzebski            synchronized(readLock) {
43251b1b6997fd3f980076b8081f7f1165ccc2a4008Piotr Jastrzebski                boolean eof = false;
43351b1b6997fd3f980076b8081f7f1165ccc2a4008Piotr Jastrzebski                char c = 0;
43451b1b6997fd3f980076b8081f7f1165ccc2a4008Piotr Jastrzebski                for (;;) {
43551b1b6997fd3f980076b8081f7f1165ccc2a4008Piotr Jastrzebski                    if (nextChar >= nChars) {   //fill
43651b1b6997fd3f980076b8081f7f1165ccc2a4008Piotr Jastrzebski                        int n = 0;
43751b1b6997fd3f980076b8081f7f1165ccc2a4008Piotr Jastrzebski                        do {
43851b1b6997fd3f980076b8081f7f1165ccc2a4008Piotr Jastrzebski                            n = in.read(cb, 0, cb.length);
43951b1b6997fd3f980076b8081f7f1165ccc2a4008Piotr Jastrzebski                        } while (n == 0);
44051b1b6997fd3f980076b8081f7f1165ccc2a4008Piotr Jastrzebski                        if (n > 0) {
44151b1b6997fd3f980076b8081f7f1165ccc2a4008Piotr Jastrzebski                            nChars = n;
44251b1b6997fd3f980076b8081f7f1165ccc2a4008Piotr Jastrzebski                            nextChar = 0;
44351b1b6997fd3f980076b8081f7f1165ccc2a4008Piotr Jastrzebski                            if (n < cb.length &&
44451b1b6997fd3f980076b8081f7f1165ccc2a4008Piotr Jastrzebski                                cb[n-1] != '\n' && cb[n-1] != '\r') {
44551b1b6997fd3f980076b8081f7f1165ccc2a4008Piotr Jastrzebski                                /*
44651b1b6997fd3f980076b8081f7f1165ccc2a4008Piotr Jastrzebski                                 * we're in canonical mode so each "fill" should
44751b1b6997fd3f980076b8081f7f1165ccc2a4008Piotr Jastrzebski                                 * come back with an eol. if there no lf or nl at
44851b1b6997fd3f980076b8081f7f1165ccc2a4008Piotr Jastrzebski                                 * the end of returned bytes we reached an eof.
44951b1b6997fd3f980076b8081f7f1165ccc2a4008Piotr Jastrzebski                                 */
45051b1b6997fd3f980076b8081f7f1165ccc2a4008Piotr Jastrzebski                                eof = true;
45151b1b6997fd3f980076b8081f7f1165ccc2a4008Piotr Jastrzebski                            }
45251b1b6997fd3f980076b8081f7f1165ccc2a4008Piotr Jastrzebski                        } else { /*EOF*/
45351b1b6997fd3f980076b8081f7f1165ccc2a4008Piotr Jastrzebski                            if (off - offset == 0)
45451b1b6997fd3f980076b8081f7f1165ccc2a4008Piotr Jastrzebski                                return -1;
45551b1b6997fd3f980076b8081f7f1165ccc2a4008Piotr Jastrzebski                            return off - offset;
45651b1b6997fd3f980076b8081f7f1165ccc2a4008Piotr Jastrzebski                        }
45751b1b6997fd3f980076b8081f7f1165ccc2a4008Piotr Jastrzebski                    }
45851b1b6997fd3f980076b8081f7f1165ccc2a4008Piotr Jastrzebski                    if (leftoverLF && cbuf == rcb && cb[nextChar] == '\n') {
45951b1b6997fd3f980076b8081f7f1165ccc2a4008Piotr Jastrzebski                        /*
46051b1b6997fd3f980076b8081f7f1165ccc2a4008Piotr Jastrzebski                         * if invoked by our readline, skip the leftover, otherwise
46151b1b6997fd3f980076b8081f7f1165ccc2a4008Piotr Jastrzebski                         * return the LF.
46251b1b6997fd3f980076b8081f7f1165ccc2a4008Piotr Jastrzebski                         */
46351b1b6997fd3f980076b8081f7f1165ccc2a4008Piotr Jastrzebski                        nextChar++;
46451b1b6997fd3f980076b8081f7f1165ccc2a4008Piotr Jastrzebski                    }
46551b1b6997fd3f980076b8081f7f1165ccc2a4008Piotr Jastrzebski                    leftoverLF = false;
46651b1b6997fd3f980076b8081f7f1165ccc2a4008Piotr Jastrzebski                    while (nextChar < nChars) {
46751b1b6997fd3f980076b8081f7f1165ccc2a4008Piotr Jastrzebski                        c = cbuf[off++] = cb[nextChar];
46851b1b6997fd3f980076b8081f7f1165ccc2a4008Piotr Jastrzebski                        cb[nextChar++] = 0;
46951b1b6997fd3f980076b8081f7f1165ccc2a4008Piotr Jastrzebski                        if (c == '\n') {
47051b1b6997fd3f980076b8081f7f1165ccc2a4008Piotr Jastrzebski                            return off - offset;
47151b1b6997fd3f980076b8081f7f1165ccc2a4008Piotr Jastrzebski                        } else if (c == '\r') {
47251b1b6997fd3f980076b8081f7f1165ccc2a4008Piotr Jastrzebski                            if (off == end) {
47351b1b6997fd3f980076b8081f7f1165ccc2a4008Piotr Jastrzebski                                /* no space left even the next is LF, so return
47451b1b6997fd3f980076b8081f7f1165ccc2a4008Piotr Jastrzebski                                 * whatever we have if the invoker is not our
47551b1b6997fd3f980076b8081f7f1165ccc2a4008Piotr Jastrzebski                                 * readLine()
47651b1b6997fd3f980076b8081f7f1165ccc2a4008Piotr Jastrzebski                                 */
47751b1b6997fd3f980076b8081f7f1165ccc2a4008Piotr Jastrzebski                                if (cbuf == rcb) {
47851b1b6997fd3f980076b8081f7f1165ccc2a4008Piotr Jastrzebski                                    cbuf = grow();
47951b1b6997fd3f980076b8081f7f1165ccc2a4008Piotr Jastrzebski                                    end = cbuf.length;
48051b1b6997fd3f980076b8081f7f1165ccc2a4008Piotr Jastrzebski                                } else {
48151b1b6997fd3f980076b8081f7f1165ccc2a4008Piotr Jastrzebski                                    leftoverLF = true;
48251b1b6997fd3f980076b8081f7f1165ccc2a4008Piotr Jastrzebski                                    return off - offset;
48351b1b6997fd3f980076b8081f7f1165ccc2a4008Piotr Jastrzebski                                }
48451b1b6997fd3f980076b8081f7f1165ccc2a4008Piotr Jastrzebski                            }
48551b1b6997fd3f980076b8081f7f1165ccc2a4008Piotr Jastrzebski                            if (nextChar == nChars && in.ready()) {
48651b1b6997fd3f980076b8081f7f1165ccc2a4008Piotr Jastrzebski                                /*
48751b1b6997fd3f980076b8081f7f1165ccc2a4008Piotr Jastrzebski                                 * we have a CR and we reached the end of
48851b1b6997fd3f980076b8081f7f1165ccc2a4008Piotr Jastrzebski                                 * the read in buffer, fill to make sure we
48951b1b6997fd3f980076b8081f7f1165ccc2a4008Piotr Jastrzebski                                 * don't miss a LF, if there is one, it's possible
49051b1b6997fd3f980076b8081f7f1165ccc2a4008Piotr Jastrzebski                                 * that it got cut off during last round reading
49151b1b6997fd3f980076b8081f7f1165ccc2a4008Piotr Jastrzebski                                 * simply because the read in buffer was full.
49251b1b6997fd3f980076b8081f7f1165ccc2a4008Piotr Jastrzebski                                 */
49351b1b6997fd3f980076b8081f7f1165ccc2a4008Piotr Jastrzebski                                nChars = in.read(cb, 0, cb.length);
49451b1b6997fd3f980076b8081f7f1165ccc2a4008Piotr Jastrzebski                                nextChar = 0;
49551b1b6997fd3f980076b8081f7f1165ccc2a4008Piotr Jastrzebski                            }
49651b1b6997fd3f980076b8081f7f1165ccc2a4008Piotr Jastrzebski                            if (nextChar < nChars && cb[nextChar] == '\n') {
49751b1b6997fd3f980076b8081f7f1165ccc2a4008Piotr Jastrzebski                                cbuf[off++] = '\n';
49851b1b6997fd3f980076b8081f7f1165ccc2a4008Piotr Jastrzebski                                nextChar++;
49951b1b6997fd3f980076b8081f7f1165ccc2a4008Piotr Jastrzebski                            }
50051b1b6997fd3f980076b8081f7f1165ccc2a4008Piotr Jastrzebski                            return off - offset;
50151b1b6997fd3f980076b8081f7f1165ccc2a4008Piotr Jastrzebski                        } else if (off == end) {
50251b1b6997fd3f980076b8081f7f1165ccc2a4008Piotr Jastrzebski                           if (cbuf == rcb) {
50351b1b6997fd3f980076b8081f7f1165ccc2a4008Piotr Jastrzebski                                cbuf = grow();
50451b1b6997fd3f980076b8081f7f1165ccc2a4008Piotr Jastrzebski                                end = cbuf.length;
50551b1b6997fd3f980076b8081f7f1165ccc2a4008Piotr Jastrzebski                           } else {
50651b1b6997fd3f980076b8081f7f1165ccc2a4008Piotr Jastrzebski                               return off - offset;
50751b1b6997fd3f980076b8081f7f1165ccc2a4008Piotr Jastrzebski                           }
50851b1b6997fd3f980076b8081f7f1165ccc2a4008Piotr Jastrzebski                        }
50951b1b6997fd3f980076b8081f7f1165ccc2a4008Piotr Jastrzebski                    }
51051b1b6997fd3f980076b8081f7f1165ccc2a4008Piotr Jastrzebski                    if (eof)
51151b1b6997fd3f980076b8081f7f1165ccc2a4008Piotr Jastrzebski                        return off - offset;
51251b1b6997fd3f980076b8081f7f1165ccc2a4008Piotr Jastrzebski                }
51351b1b6997fd3f980076b8081f7f1165ccc2a4008Piotr Jastrzebski            }
51451b1b6997fd3f980076b8081f7f1165ccc2a4008Piotr Jastrzebski        }
51551b1b6997fd3f980076b8081f7f1165ccc2a4008Piotr Jastrzebski    }
51651b1b6997fd3f980076b8081f7f1165ccc2a4008Piotr Jastrzebski
517c3155270c33344c61e2e8dc055410fc9fc215a24Tobias Thierer    // Android-removed: SharedSecrets setup and also the shutdown hook.
518c3155270c33344c61e2e8dc055410fc9fc215a24Tobias Thierer    // The hook is a no-op (but causes trouble when it's turned on).
519a80f9aeb7b637fc241c75448eed08275245ec652Piotr Jastrzebski
520c3155270c33344c61e2e8dc055410fc9fc215a24Tobias Thierer    // Android-changed: Use @hide rather than sun.misc.SharedSecrets to expose console().
5211550ed9ba326ce08cef8ebf01699a49fabdc64f3Przemyslaw Szczepaniak    /** @hide */
522a80f9aeb7b637fc241c75448eed08275245ec652Piotr Jastrzebski    public static Console console() {
523a80f9aeb7b637fc241c75448eed08275245ec652Piotr Jastrzebski        if (istty()) {
524a80f9aeb7b637fc241c75448eed08275245ec652Piotr Jastrzebski            if (cons == null)
525a80f9aeb7b637fc241c75448eed08275245ec652Piotr Jastrzebski                cons = new Console();
526a80f9aeb7b637fc241c75448eed08275245ec652Piotr Jastrzebski            return cons;
527a80f9aeb7b637fc241c75448eed08275245ec652Piotr Jastrzebski        }
528a80f9aeb7b637fc241c75448eed08275245ec652Piotr Jastrzebski        return null;
529a80f9aeb7b637fc241c75448eed08275245ec652Piotr Jastrzebski    }
530c3155270c33344c61e2e8dc055410fc9fc215a24Tobias Thierer    private static Console cons;
53151b1b6997fd3f980076b8081f7f1165ccc2a4008Piotr Jastrzebski    private native static boolean istty();
53251b1b6997fd3f980076b8081f7f1165ccc2a4008Piotr Jastrzebski    private Console() {
533c3155270c33344c61e2e8dc055410fc9fc215a24Tobias Thierer    // BEGIN Android-changed: Support custom in/out streams for testing.
53478dd410c20e2e9ef239d1b1cb821b189030e216dPrzemyslaw Szczepaniak      this(new FileInputStream(FileDescriptor.in), new FileOutputStream(FileDescriptor.out));
53578dd410c20e2e9ef239d1b1cb821b189030e216dPrzemyslaw Szczepaniak    }
53678dd410c20e2e9ef239d1b1cb821b189030e216dPrzemyslaw Szczepaniak
53778dd410c20e2e9ef239d1b1cb821b189030e216dPrzemyslaw Szczepaniak    // Constructor for tests
53878dd410c20e2e9ef239d1b1cb821b189030e216dPrzemyslaw Szczepaniak    private Console(InputStream inStream, OutputStream outStream) {
539c3155270c33344c61e2e8dc055410fc9fc215a24Tobias Thierer    // END Android-changed: Support custom in/out streams for testing.
54051b1b6997fd3f980076b8081f7f1165ccc2a4008Piotr Jastrzebski        readLock = new Object();
54151b1b6997fd3f980076b8081f7f1165ccc2a4008Piotr Jastrzebski        writeLock = new Object();
54251b1b6997fd3f980076b8081f7f1165ccc2a4008Piotr Jastrzebski        String csname = encoding();
54351b1b6997fd3f980076b8081f7f1165ccc2a4008Piotr Jastrzebski        if (csname != null) {
54451b1b6997fd3f980076b8081f7f1165ccc2a4008Piotr Jastrzebski            try {
54551b1b6997fd3f980076b8081f7f1165ccc2a4008Piotr Jastrzebski                cs = Charset.forName(csname);
54651b1b6997fd3f980076b8081f7f1165ccc2a4008Piotr Jastrzebski            } catch (Exception x) {}
54751b1b6997fd3f980076b8081f7f1165ccc2a4008Piotr Jastrzebski        }
54851b1b6997fd3f980076b8081f7f1165ccc2a4008Piotr Jastrzebski        if (cs == null)
54951b1b6997fd3f980076b8081f7f1165ccc2a4008Piotr Jastrzebski            cs = Charset.defaultCharset();
55051b1b6997fd3f980076b8081f7f1165ccc2a4008Piotr Jastrzebski        out = StreamEncoder.forOutputStreamWriter(
55178dd410c20e2e9ef239d1b1cb821b189030e216dPrzemyslaw Szczepaniak                  outStream,
55251b1b6997fd3f980076b8081f7f1165ccc2a4008Piotr Jastrzebski                  writeLock,
55351b1b6997fd3f980076b8081f7f1165ccc2a4008Piotr Jastrzebski                  cs);
55451b1b6997fd3f980076b8081f7f1165ccc2a4008Piotr Jastrzebski        pw = new PrintWriter(out, true) { public void close() {} };
55551b1b6997fd3f980076b8081f7f1165ccc2a4008Piotr Jastrzebski        formatter = new Formatter(out);
55651b1b6997fd3f980076b8081f7f1165ccc2a4008Piotr Jastrzebski        reader = new LineReader(StreamDecoder.forInputStreamReader(
55778dd410c20e2e9ef239d1b1cb821b189030e216dPrzemyslaw Szczepaniak                     inStream,
55851b1b6997fd3f980076b8081f7f1165ccc2a4008Piotr Jastrzebski                     readLock,
55951b1b6997fd3f980076b8081f7f1165ccc2a4008Piotr Jastrzebski                     cs));
56051b1b6997fd3f980076b8081f7f1165ccc2a4008Piotr Jastrzebski        rcb = new char[1024];
56151b1b6997fd3f980076b8081f7f1165ccc2a4008Piotr Jastrzebski    }
56251b1b6997fd3f980076b8081f7f1165ccc2a4008Piotr Jastrzebski}
563