src/jdk.internal.le/share/classes/jdk/internal/jline/internal/InputStreamReader.java
branchJDK-8200758-branch
changeset 57072 29604aafa0fc
parent 57071 94e9270166f0
parent 52979 7384e00d5860
child 57076 687505381ca4
--- a/src/jdk.internal.le/share/classes/jdk/internal/jline/internal/InputStreamReader.java	Wed Dec 12 08:27:16 2018 -0500
+++ /dev/null	Thu Jan 01 00:00:00 1970 +0000
@@ -1,334 +0,0 @@
-/*
- * Copyright (c) 2002-2016, the original author or authors.
- *
- * This software is distributable under the BSD license. See the terms of the
- * BSD license in the documentation provided with this software.
- *
- * http://www.opensource.org/licenses/bsd-license.php
- */
-package jdk.internal.jline.internal;
-
-import java.io.IOException;
-import java.io.InputStream;
-import java.io.OutputStreamWriter;
-import java.io.Reader;
-import java.io.UnsupportedEncodingException;
-import java.nio.ByteBuffer;
-import java.nio.CharBuffer;
-import java.nio.charset.Charset;
-import java.nio.charset.CharsetDecoder;
-import java.nio.charset.CoderResult;
-import java.nio.charset.CodingErrorAction;
-import java.nio.charset.MalformedInputException;
-import java.nio.charset.UnmappableCharacterException;
-
-
-/**
- *
- * NOTE for JLine: the default InputStreamReader that comes from the JRE
- * usually read more bytes than needed from the input stream, which
- * is not usable in a character per character model used in the console.
- * We thus use the harmony code which only reads the minimal number of bytes,
- * with a modification to ensure we can read larger characters (UTF-16 has
- * up to 4 bytes, and UTF-32, rare as it is, may have up to 8).
- */
-/**
- * A class for turning a byte stream into a character stream. Data read from the
- * source input stream is converted into characters by either a default or a
- * provided character converter. The default encoding is taken from the
- * "file.encoding" system property. {@code InputStreamReader} contains a buffer
- * of bytes read from the source stream and converts these into characters as
- * needed. The buffer size is 8K.
- *
- * @see OutputStreamWriter
- */
-public class InputStreamReader extends Reader {
-    private InputStream in;
-
-    private static final int BUFFER_SIZE = 8192;
-
-    private boolean endOfInput = false;
-
-    CharsetDecoder decoder;
-
-    ByteBuffer bytes = ByteBuffer.allocate(BUFFER_SIZE);
-
-    /**
-     * Constructs a new {@code InputStreamReader} on the {@link InputStream}
-     * {@code in}. This constructor sets the character converter to the encoding
-     * specified in the "file.encoding" property and falls back to ISO 8859_1
-     * (ISO-Latin-1) if the property doesn't exist.
-     *
-     * @param in
-     *            the input stream from which to read characters.
-     */
-    public InputStreamReader(InputStream in) {
-        super(in);
-        this.in = in;
-        decoder = Charset.defaultCharset().newDecoder().onMalformedInput(
-                CodingErrorAction.REPLACE).onUnmappableCharacter(
-                CodingErrorAction.REPLACE);
-        bytes.limit(0);
-    }
-
-    /**
-     * Constructs a new InputStreamReader on the InputStream {@code in}. The
-     * character converter that is used to decode bytes into characters is
-     * identified by name by {@code enc}. If the encoding cannot be found, an
-     * UnsupportedEncodingException error is thrown.
-     *
-     * @param in
-     *            the InputStream from which to read characters.
-     * @param enc
-     *            identifies the character converter to use.
-     * @throws NullPointerException
-     *             if {@code enc} is {@code null}.
-     * @throws UnsupportedEncodingException
-     *             if the encoding specified by {@code enc} cannot be found.
-     */
-    public InputStreamReader(InputStream in, final String enc)
-            throws UnsupportedEncodingException {
-        super(in);
-        if (enc == null) {
-            throw new NullPointerException();
-        }
-        this.in = in;
-        try {
-            decoder = Charset.forName(enc).newDecoder().onMalformedInput(
-                    CodingErrorAction.REPLACE).onUnmappableCharacter(
-                    CodingErrorAction.REPLACE);
-        } catch (IllegalArgumentException e) {
-            throw (UnsupportedEncodingException)
-                    new UnsupportedEncodingException(enc).initCause(e);
-        }
-        bytes.limit(0);
-    }
-
-    /**
-     * Constructs a new InputStreamReader on the InputStream {@code in} and
-     * CharsetDecoder {@code dec}.
-     *
-     * @param in
-     *            the source InputStream from which to read characters.
-     * @param dec
-     *            the CharsetDecoder used by the character conversion.
-     */
-    public InputStreamReader(InputStream in, CharsetDecoder dec) {
-        super(in);
-        dec.averageCharsPerByte();
-        this.in = in;
-        decoder = dec;
-        bytes.limit(0);
-    }
-
-    /**
-     * Constructs a new InputStreamReader on the InputStream {@code in} and
-     * Charset {@code charset}.
-     *
-     * @param in
-     *            the source InputStream from which to read characters.
-     * @param charset
-     *            the Charset that defines the character converter
-     */
-    public InputStreamReader(InputStream in, Charset charset) {
-        super(in);
-        this.in = in;
-        decoder = charset.newDecoder().onMalformedInput(
-                CodingErrorAction.REPLACE).onUnmappableCharacter(
-                CodingErrorAction.REPLACE);
-        bytes.limit(0);
-    }
-
-    /**
-     * Closes this reader. This implementation closes the source InputStream and
-     * releases all local storage.
-     *
-     * @throws IOException
-     *             if an error occurs attempting to close this reader.
-     */
-    @Override
-    public void close() throws IOException {
-        synchronized (lock) {
-            decoder = null;
-            if (in != null) {
-                in.close();
-                in = null;
-            }
-        }
-    }
-
-    /**
-     * Returns the name of the encoding used to convert bytes into characters.
-     * The value {@code null} is returned if this reader has been closed.
-     *
-     * @return the name of the character converter or {@code null} if this
-     *         reader is closed.
-     */
-    public String getEncoding() {
-        if (!isOpen()) {
-            return null;
-        }
-        return decoder.charset().name();
-    }
-
-    /**
-     * Reads a single character from this reader and returns it as an integer
-     * with the two higher-order bytes set to 0. Returns -1 if the end of the
-     * reader has been reached. The byte value is either obtained from
-     * converting bytes in this reader's buffer or by first filling the buffer
-     * from the source InputStream and then reading from the buffer.
-     *
-     * @return the character read or -1 if the end of the reader has been
-     *         reached.
-     * @throws IOException
-     *             if this reader is closed or some other I/O error occurs.
-     */
-    @Override
-    public int read() throws IOException {
-        synchronized (lock) {
-            if (!isOpen()) {
-                throw new IOException("InputStreamReader is closed.");
-            }
-
-            char buf[] = new char[4];
-            return read(buf, 0, 4) != -1 ? Character.codePointAt(buf, 0) : -1;
-        }
-    }
-
-    /**
-     * Reads at most {@code length} characters from this reader and stores them
-     * at position {@code offset} in the character array {@code buf}. Returns
-     * the number of characters actually read or -1 if the end of the reader has
-     * been reached. The bytes are either obtained from converting bytes in this
-     * reader's buffer or by first filling the buffer from the source
-     * InputStream and then reading from the buffer.
-     *
-     * @param buf
-     *            the array to store the characters read.
-     * @param offset
-     *            the initial position in {@code buf} to store the characters
-     *            read from this reader.
-     * @param length
-     *            the maximum number of characters to read.
-     * @return the number of characters read or -1 if the end of the reader has
-     *         been reached.
-     * @throws IndexOutOfBoundsException
-     *             if {@code offset < 0} or {@code length < 0}, or if
-     *             {@code offset + length} is greater than the length of
-     *             {@code buf}.
-     * @throws IOException
-     *             if this reader is closed or some other I/O error occurs.
-     */
-    @Override
-    public int read(char[] buf, int offset, int length) throws IOException {
-        synchronized (lock) {
-            if (!isOpen()) {
-                throw new IOException("InputStreamReader is closed.");
-            }
-            if (offset < 0 || offset > buf.length - length || length < 0) {
-                throw new IndexOutOfBoundsException();
-            }
-            if (length == 0) {
-                return 0;
-            }
-
-            CharBuffer out = CharBuffer.wrap(buf, offset, length);
-            CoderResult result = CoderResult.UNDERFLOW;
-
-            // bytes.remaining() indicates number of bytes in buffer
-            // when 1-st time entered, it'll be equal to zero
-            boolean needInput = !bytes.hasRemaining();
-
-            while (out.hasRemaining()) {
-                // fill the buffer if needed
-                if (needInput) {
-                    try {
-                        if ((in.available() == 0)
-                            && (out.position() > offset)) {
-                            // we could return the result without blocking read
-                            break;
-                        }
-                    } catch (IOException e) {
-                        // available didn't work so just try the read
-                    }
-
-                    int to_read = bytes.capacity() - bytes.limit();
-                    int off = bytes.arrayOffset() + bytes.limit();
-                    int was_red = in.read(bytes.array(), off, to_read);
-
-                    if (was_red == -1) {
-                        endOfInput = true;
-                        break;
-                    } else if (was_red == 0) {
-                        break;
-                    }
-                    bytes.limit(bytes.limit() + was_red);
-                    needInput = false;
-                }
-
-                // decode bytes
-                result = decoder.decode(bytes, out, false);
-
-                if (result.isUnderflow()) {
-                    // compact the buffer if no space left
-                    if (bytes.limit() == bytes.capacity()) {
-                        bytes.compact();
-                        bytes.limit(bytes.position());
-                        bytes.position(0);
-                    }
-                    needInput = true;
-                } else {
-                    break;
-                }
-            }
-
-            if (result == CoderResult.UNDERFLOW && endOfInput) {
-                result = decoder.decode(bytes, out, true);
-                decoder.flush(out);
-                decoder.reset();
-            }
-            if (result.isMalformed()) {
-                throw new MalformedInputException(result.length());
-            } else if (result.isUnmappable()) {
-                throw new UnmappableCharacterException(result.length());
-            }
-
-            return out.position() - offset == 0 ? -1 : out.position() - offset;
-        }
-    }
-
-    /*
-     * Answer a boolean indicating whether or not this InputStreamReader is
-     * open.
-     */
-    private boolean isOpen() {
-        return in != null;
-    }
-
-    /**
-     * Indicates whether this reader is ready to be read without blocking. If
-     * the result is {@code true}, the next {@code read()} will not block. If
-     * the result is {@code false} then this reader may or may not block when
-     * {@code read()} is called. This implementation returns {@code true} if
-     * there are bytes available in the buffer or the source stream has bytes
-     * available.
-     *
-     * @return {@code true} if the receiver will not block when {@code read()}
-     *         is called, {@code false} if unknown or blocking will occur.
-     * @throws IOException
-     *             if this reader is closed or some other I/O error occurs.
-     */
-    @Override
-    public boolean ready() throws IOException {
-        synchronized (lock) {
-            if (in == null) {
-                throw new IOException("InputStreamReader is closed.");
-            }
-            try {
-                return bytes.hasRemaining() || in.available() > 0;
-            } catch (IOException e) {
-                return false;
-            }
-        }
-    }
-}