151b1b6997fd3f980076b8081f7f1165ccc2a4008Piotr Jastrzebski/*
22c87ad3a45cecf9e344487cad1abfdebe79f2c7cNarayan Kamath * Copyright (C) 2014 The Android Open Source Project
32c4230d24a2349039b4d7d513d0fb61542bc4cb7Yi Kong * Copyright (c) 1996, 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 Jastrzebski
302c4230d24a2349039b4d7d513d0fb61542bc4cb7Yi Kongimport java.util.Iterator;
312c4230d24a2349039b4d7d513d0fb61542bc4cb7Yi Kongimport java.util.NoSuchElementException;
322c4230d24a2349039b4d7d513d0fb61542bc4cb7Yi Kongimport java.util.Spliterator;
332c4230d24a2349039b4d7d513d0fb61542bc4cb7Yi Kongimport java.util.Spliterators;
342c4230d24a2349039b4d7d513d0fb61542bc4cb7Yi Kongimport java.util.stream.Stream;
352c4230d24a2349039b4d7d513d0fb61542bc4cb7Yi Kongimport java.util.stream.StreamSupport;
362c4230d24a2349039b4d7d513d0fb61542bc4cb7Yi Kong
3751b1b6997fd3f980076b8081f7f1165ccc2a4008Piotr Jastrzebski/**
3851b1b6997fd3f980076b8081f7f1165ccc2a4008Piotr Jastrzebski * Reads text from a character-input stream, buffering characters so as to
3951b1b6997fd3f980076b8081f7f1165ccc2a4008Piotr Jastrzebski * provide for the efficient reading of characters, arrays, and lines.
4051b1b6997fd3f980076b8081f7f1165ccc2a4008Piotr Jastrzebski *
4151b1b6997fd3f980076b8081f7f1165ccc2a4008Piotr Jastrzebski * <p> The buffer size may be specified, or the default size may be used.  The
4251b1b6997fd3f980076b8081f7f1165ccc2a4008Piotr Jastrzebski * default is large enough for most purposes.
4351b1b6997fd3f980076b8081f7f1165ccc2a4008Piotr Jastrzebski *
4451b1b6997fd3f980076b8081f7f1165ccc2a4008Piotr Jastrzebski * <p> In general, each read request made of a Reader causes a corresponding
4551b1b6997fd3f980076b8081f7f1165ccc2a4008Piotr Jastrzebski * read request to be made of the underlying character or byte stream.  It is
4651b1b6997fd3f980076b8081f7f1165ccc2a4008Piotr Jastrzebski * therefore advisable to wrap a BufferedReader around any Reader whose read()
4751b1b6997fd3f980076b8081f7f1165ccc2a4008Piotr Jastrzebski * operations may be costly, such as FileReaders and InputStreamReaders.  For
4851b1b6997fd3f980076b8081f7f1165ccc2a4008Piotr Jastrzebski * example,
4951b1b6997fd3f980076b8081f7f1165ccc2a4008Piotr Jastrzebski *
5051b1b6997fd3f980076b8081f7f1165ccc2a4008Piotr Jastrzebski * <pre>
5151b1b6997fd3f980076b8081f7f1165ccc2a4008Piotr Jastrzebski * BufferedReader in
5251b1b6997fd3f980076b8081f7f1165ccc2a4008Piotr Jastrzebski *   = new BufferedReader(new FileReader("foo.in"));
5351b1b6997fd3f980076b8081f7f1165ccc2a4008Piotr Jastrzebski * </pre>
5451b1b6997fd3f980076b8081f7f1165ccc2a4008Piotr Jastrzebski *
5551b1b6997fd3f980076b8081f7f1165ccc2a4008Piotr Jastrzebski * will buffer the input from the specified file.  Without buffering, each
5651b1b6997fd3f980076b8081f7f1165ccc2a4008Piotr Jastrzebski * invocation of read() or readLine() could cause bytes to be read from the
5751b1b6997fd3f980076b8081f7f1165ccc2a4008Piotr Jastrzebski * file, converted into characters, and then returned, which can be very
5851b1b6997fd3f980076b8081f7f1165ccc2a4008Piotr Jastrzebski * inefficient.
5951b1b6997fd3f980076b8081f7f1165ccc2a4008Piotr Jastrzebski *
6051b1b6997fd3f980076b8081f7f1165ccc2a4008Piotr Jastrzebski * <p> Programs that use DataInputStreams for textual input can be localized by
6151b1b6997fd3f980076b8081f7f1165ccc2a4008Piotr Jastrzebski * replacing each DataInputStream with an appropriate BufferedReader.
6251b1b6997fd3f980076b8081f7f1165ccc2a4008Piotr Jastrzebski *
6351b1b6997fd3f980076b8081f7f1165ccc2a4008Piotr Jastrzebski * @see FileReader
6451b1b6997fd3f980076b8081f7f1165ccc2a4008Piotr Jastrzebski * @see InputStreamReader
6551b1b6997fd3f980076b8081f7f1165ccc2a4008Piotr Jastrzebski * @see java.nio.file.Files#newBufferedReader
6651b1b6997fd3f980076b8081f7f1165ccc2a4008Piotr Jastrzebski *
6751b1b6997fd3f980076b8081f7f1165ccc2a4008Piotr Jastrzebski * @author      Mark Reinhold
6851b1b6997fd3f980076b8081f7f1165ccc2a4008Piotr Jastrzebski * @since       JDK1.1
6951b1b6997fd3f980076b8081f7f1165ccc2a4008Piotr Jastrzebski */
7051b1b6997fd3f980076b8081f7f1165ccc2a4008Piotr Jastrzebski
7151b1b6997fd3f980076b8081f7f1165ccc2a4008Piotr Jastrzebskipublic class BufferedReader extends Reader {
7251b1b6997fd3f980076b8081f7f1165ccc2a4008Piotr Jastrzebski
7351b1b6997fd3f980076b8081f7f1165ccc2a4008Piotr Jastrzebski    private Reader in;
7451b1b6997fd3f980076b8081f7f1165ccc2a4008Piotr Jastrzebski
7551b1b6997fd3f980076b8081f7f1165ccc2a4008Piotr Jastrzebski    private char cb[];
7651b1b6997fd3f980076b8081f7f1165ccc2a4008Piotr Jastrzebski    private int nChars, nextChar;
7751b1b6997fd3f980076b8081f7f1165ccc2a4008Piotr Jastrzebski
7851b1b6997fd3f980076b8081f7f1165ccc2a4008Piotr Jastrzebski    private static final int INVALIDATED = -2;
7951b1b6997fd3f980076b8081f7f1165ccc2a4008Piotr Jastrzebski    private static final int UNMARKED = -1;
8051b1b6997fd3f980076b8081f7f1165ccc2a4008Piotr Jastrzebski    private int markedChar = UNMARKED;
8151b1b6997fd3f980076b8081f7f1165ccc2a4008Piotr Jastrzebski    private int readAheadLimit = 0; /* Valid only when markedChar > 0 */
8251b1b6997fd3f980076b8081f7f1165ccc2a4008Piotr Jastrzebski
8351b1b6997fd3f980076b8081f7f1165ccc2a4008Piotr Jastrzebski    /** If the next character is a line feed, skip it */
8451b1b6997fd3f980076b8081f7f1165ccc2a4008Piotr Jastrzebski    private boolean skipLF = false;
8551b1b6997fd3f980076b8081f7f1165ccc2a4008Piotr Jastrzebski
8651b1b6997fd3f980076b8081f7f1165ccc2a4008Piotr Jastrzebski    /** The skipLF flag when the mark was set */
8751b1b6997fd3f980076b8081f7f1165ccc2a4008Piotr Jastrzebski    private boolean markedSkipLF = false;
8851b1b6997fd3f980076b8081f7f1165ccc2a4008Piotr Jastrzebski
8951b1b6997fd3f980076b8081f7f1165ccc2a4008Piotr Jastrzebski    private static int defaultCharBufferSize = 8192;
9051b1b6997fd3f980076b8081f7f1165ccc2a4008Piotr Jastrzebski    private static int defaultExpectedLineLength = 80;
9151b1b6997fd3f980076b8081f7f1165ccc2a4008Piotr Jastrzebski
9251b1b6997fd3f980076b8081f7f1165ccc2a4008Piotr Jastrzebski    /**
9351b1b6997fd3f980076b8081f7f1165ccc2a4008Piotr Jastrzebski     * Creates a buffering character-input stream that uses an input buffer of
9451b1b6997fd3f980076b8081f7f1165ccc2a4008Piotr Jastrzebski     * the specified size.
9551b1b6997fd3f980076b8081f7f1165ccc2a4008Piotr Jastrzebski     *
9651b1b6997fd3f980076b8081f7f1165ccc2a4008Piotr Jastrzebski     * @param  in   A Reader
9751b1b6997fd3f980076b8081f7f1165ccc2a4008Piotr Jastrzebski     * @param  sz   Input-buffer size
9851b1b6997fd3f980076b8081f7f1165ccc2a4008Piotr Jastrzebski     *
992e3af1f347f088ed6cd432f88b8dcf63d7a628e5Przemyslaw Szczepaniak     * @exception  IllegalArgumentException  If {@code sz <= 0}
10051b1b6997fd3f980076b8081f7f1165ccc2a4008Piotr Jastrzebski     */
10151b1b6997fd3f980076b8081f7f1165ccc2a4008Piotr Jastrzebski    public BufferedReader(Reader in, int sz) {
10251b1b6997fd3f980076b8081f7f1165ccc2a4008Piotr Jastrzebski        super(in);
10351b1b6997fd3f980076b8081f7f1165ccc2a4008Piotr Jastrzebski        if (sz <= 0)
10451b1b6997fd3f980076b8081f7f1165ccc2a4008Piotr Jastrzebski            throw new IllegalArgumentException("Buffer size <= 0");
10551b1b6997fd3f980076b8081f7f1165ccc2a4008Piotr Jastrzebski        this.in = in;
10651b1b6997fd3f980076b8081f7f1165ccc2a4008Piotr Jastrzebski        cb = new char[sz];
10751b1b6997fd3f980076b8081f7f1165ccc2a4008Piotr Jastrzebski        nextChar = nChars = 0;
10851b1b6997fd3f980076b8081f7f1165ccc2a4008Piotr Jastrzebski    }
10951b1b6997fd3f980076b8081f7f1165ccc2a4008Piotr Jastrzebski
11051b1b6997fd3f980076b8081f7f1165ccc2a4008Piotr Jastrzebski    /**
11151b1b6997fd3f980076b8081f7f1165ccc2a4008Piotr Jastrzebski     * Creates a buffering character-input stream that uses a default-sized
11251b1b6997fd3f980076b8081f7f1165ccc2a4008Piotr Jastrzebski     * input buffer.
11351b1b6997fd3f980076b8081f7f1165ccc2a4008Piotr Jastrzebski     *
11451b1b6997fd3f980076b8081f7f1165ccc2a4008Piotr Jastrzebski     * @param  in   A Reader
11551b1b6997fd3f980076b8081f7f1165ccc2a4008Piotr Jastrzebski     */
11651b1b6997fd3f980076b8081f7f1165ccc2a4008Piotr Jastrzebski    public BufferedReader(Reader in) {
11751b1b6997fd3f980076b8081f7f1165ccc2a4008Piotr Jastrzebski        this(in, defaultCharBufferSize);
11851b1b6997fd3f980076b8081f7f1165ccc2a4008Piotr Jastrzebski    }
11951b1b6997fd3f980076b8081f7f1165ccc2a4008Piotr Jastrzebski
12051b1b6997fd3f980076b8081f7f1165ccc2a4008Piotr Jastrzebski    /** Checks to make sure that the stream has not been closed */
12151b1b6997fd3f980076b8081f7f1165ccc2a4008Piotr Jastrzebski    private void ensureOpen() throws IOException {
12251b1b6997fd3f980076b8081f7f1165ccc2a4008Piotr Jastrzebski        if (in == null)
12351b1b6997fd3f980076b8081f7f1165ccc2a4008Piotr Jastrzebski            throw new IOException("Stream closed");
12451b1b6997fd3f980076b8081f7f1165ccc2a4008Piotr Jastrzebski    }
12551b1b6997fd3f980076b8081f7f1165ccc2a4008Piotr Jastrzebski
12651b1b6997fd3f980076b8081f7f1165ccc2a4008Piotr Jastrzebski    /**
12751b1b6997fd3f980076b8081f7f1165ccc2a4008Piotr Jastrzebski     * Fills the input buffer, taking the mark into account if it is valid.
12851b1b6997fd3f980076b8081f7f1165ccc2a4008Piotr Jastrzebski     */
12951b1b6997fd3f980076b8081f7f1165ccc2a4008Piotr Jastrzebski    private void fill() throws IOException {
13051b1b6997fd3f980076b8081f7f1165ccc2a4008Piotr Jastrzebski        int dst;
13151b1b6997fd3f980076b8081f7f1165ccc2a4008Piotr Jastrzebski        if (markedChar <= UNMARKED) {
13251b1b6997fd3f980076b8081f7f1165ccc2a4008Piotr Jastrzebski            /* No mark */
13351b1b6997fd3f980076b8081f7f1165ccc2a4008Piotr Jastrzebski            dst = 0;
13451b1b6997fd3f980076b8081f7f1165ccc2a4008Piotr Jastrzebski        } else {
13551b1b6997fd3f980076b8081f7f1165ccc2a4008Piotr Jastrzebski            /* Marked */
13651b1b6997fd3f980076b8081f7f1165ccc2a4008Piotr Jastrzebski            int delta = nextChar - markedChar;
13751b1b6997fd3f980076b8081f7f1165ccc2a4008Piotr Jastrzebski            if (delta >= readAheadLimit) {
13851b1b6997fd3f980076b8081f7f1165ccc2a4008Piotr Jastrzebski                /* Gone past read-ahead limit: Invalidate mark */
13951b1b6997fd3f980076b8081f7f1165ccc2a4008Piotr Jastrzebski                markedChar = INVALIDATED;
14051b1b6997fd3f980076b8081f7f1165ccc2a4008Piotr Jastrzebski                readAheadLimit = 0;
14151b1b6997fd3f980076b8081f7f1165ccc2a4008Piotr Jastrzebski                dst = 0;
14251b1b6997fd3f980076b8081f7f1165ccc2a4008Piotr Jastrzebski            } else {
14351b1b6997fd3f980076b8081f7f1165ccc2a4008Piotr Jastrzebski                if (readAheadLimit <= cb.length) {
14451b1b6997fd3f980076b8081f7f1165ccc2a4008Piotr Jastrzebski                    /* Shuffle in the current buffer */
14551b1b6997fd3f980076b8081f7f1165ccc2a4008Piotr Jastrzebski                    System.arraycopy(cb, markedChar, cb, 0, delta);
14651b1b6997fd3f980076b8081f7f1165ccc2a4008Piotr Jastrzebski                    markedChar = 0;
14751b1b6997fd3f980076b8081f7f1165ccc2a4008Piotr Jastrzebski                    dst = delta;
14851b1b6997fd3f980076b8081f7f1165ccc2a4008Piotr Jastrzebski                } else {
14951b1b6997fd3f980076b8081f7f1165ccc2a4008Piotr Jastrzebski                    /* Reallocate buffer to accommodate read-ahead limit */
1502fd3e2e1740339c5d23bba55fdef64a87627f18cNarayan Kamath                    //
1516975f84c2ed72e1e26d20190b6f318718c849008Tobias Thierer                    // Android-changed: Use the same strategy as BufferedInputStream,
1522fd3e2e1740339c5d23bba55fdef64a87627f18cNarayan Kamath                    // i.e, double the size of the buffer on each fill. Do not directly
1532fd3e2e1740339c5d23bba55fdef64a87627f18cNarayan Kamath                    // size the buffer to the readAheadLimit.
1542fd3e2e1740339c5d23bba55fdef64a87627f18cNarayan Kamath                    //
1552fd3e2e1740339c5d23bba55fdef64a87627f18cNarayan Kamath                    // char ncb[] = new char[readAheadLimit];
1562fd3e2e1740339c5d23bba55fdef64a87627f18cNarayan Kamath                    int nlength = cb.length * 2;
1572fd3e2e1740339c5d23bba55fdef64a87627f18cNarayan Kamath                    if (nlength > readAheadLimit) {
1582fd3e2e1740339c5d23bba55fdef64a87627f18cNarayan Kamath                        nlength = readAheadLimit;
1592fd3e2e1740339c5d23bba55fdef64a87627f18cNarayan Kamath                    }
1602fd3e2e1740339c5d23bba55fdef64a87627f18cNarayan Kamath                    char ncb[] = new char[nlength];
16151b1b6997fd3f980076b8081f7f1165ccc2a4008Piotr Jastrzebski                    System.arraycopy(cb, markedChar, ncb, 0, delta);
16251b1b6997fd3f980076b8081f7f1165ccc2a4008Piotr Jastrzebski                    cb = ncb;
16351b1b6997fd3f980076b8081f7f1165ccc2a4008Piotr Jastrzebski                    markedChar = 0;
16451b1b6997fd3f980076b8081f7f1165ccc2a4008Piotr Jastrzebski                    dst = delta;
16551b1b6997fd3f980076b8081f7f1165ccc2a4008Piotr Jastrzebski                }
16651b1b6997fd3f980076b8081f7f1165ccc2a4008Piotr Jastrzebski                nextChar = nChars = delta;
16751b1b6997fd3f980076b8081f7f1165ccc2a4008Piotr Jastrzebski            }
16851b1b6997fd3f980076b8081f7f1165ccc2a4008Piotr Jastrzebski        }
16951b1b6997fd3f980076b8081f7f1165ccc2a4008Piotr Jastrzebski
17051b1b6997fd3f980076b8081f7f1165ccc2a4008Piotr Jastrzebski        int n;
17151b1b6997fd3f980076b8081f7f1165ccc2a4008Piotr Jastrzebski        do {
17251b1b6997fd3f980076b8081f7f1165ccc2a4008Piotr Jastrzebski            n = in.read(cb, dst, cb.length - dst);
17351b1b6997fd3f980076b8081f7f1165ccc2a4008Piotr Jastrzebski        } while (n == 0);
17451b1b6997fd3f980076b8081f7f1165ccc2a4008Piotr Jastrzebski        if (n > 0) {
17551b1b6997fd3f980076b8081f7f1165ccc2a4008Piotr Jastrzebski            nChars = dst + n;
17651b1b6997fd3f980076b8081f7f1165ccc2a4008Piotr Jastrzebski            nextChar = dst;
17751b1b6997fd3f980076b8081f7f1165ccc2a4008Piotr Jastrzebski        }
17851b1b6997fd3f980076b8081f7f1165ccc2a4008Piotr Jastrzebski    }
17951b1b6997fd3f980076b8081f7f1165ccc2a4008Piotr Jastrzebski
18051b1b6997fd3f980076b8081f7f1165ccc2a4008Piotr Jastrzebski    /**
18151b1b6997fd3f980076b8081f7f1165ccc2a4008Piotr Jastrzebski     * Reads a single character.
18251b1b6997fd3f980076b8081f7f1165ccc2a4008Piotr Jastrzebski     *
18351b1b6997fd3f980076b8081f7f1165ccc2a4008Piotr Jastrzebski     * @return The character read, as an integer in the range
18451b1b6997fd3f980076b8081f7f1165ccc2a4008Piotr Jastrzebski     *         0 to 65535 (<tt>0x00-0xffff</tt>), or -1 if the
18551b1b6997fd3f980076b8081f7f1165ccc2a4008Piotr Jastrzebski     *         end of the stream has been reached
18651b1b6997fd3f980076b8081f7f1165ccc2a4008Piotr Jastrzebski     * @exception  IOException  If an I/O error occurs
18751b1b6997fd3f980076b8081f7f1165ccc2a4008Piotr Jastrzebski     */
18851b1b6997fd3f980076b8081f7f1165ccc2a4008Piotr Jastrzebski    public int read() throws IOException {
18951b1b6997fd3f980076b8081f7f1165ccc2a4008Piotr Jastrzebski        synchronized (lock) {
19051b1b6997fd3f980076b8081f7f1165ccc2a4008Piotr Jastrzebski            ensureOpen();
19151b1b6997fd3f980076b8081f7f1165ccc2a4008Piotr Jastrzebski            for (;;) {
19251b1b6997fd3f980076b8081f7f1165ccc2a4008Piotr Jastrzebski                if (nextChar >= nChars) {
19351b1b6997fd3f980076b8081f7f1165ccc2a4008Piotr Jastrzebski                    fill();
19451b1b6997fd3f980076b8081f7f1165ccc2a4008Piotr Jastrzebski                    if (nextChar >= nChars)
19551b1b6997fd3f980076b8081f7f1165ccc2a4008Piotr Jastrzebski                        return -1;
19651b1b6997fd3f980076b8081f7f1165ccc2a4008Piotr Jastrzebski                }
19751b1b6997fd3f980076b8081f7f1165ccc2a4008Piotr Jastrzebski                if (skipLF) {
19851b1b6997fd3f980076b8081f7f1165ccc2a4008Piotr Jastrzebski                    skipLF = false;
19951b1b6997fd3f980076b8081f7f1165ccc2a4008Piotr Jastrzebski                    if (cb[nextChar] == '\n') {
20051b1b6997fd3f980076b8081f7f1165ccc2a4008Piotr Jastrzebski                        nextChar++;
20151b1b6997fd3f980076b8081f7f1165ccc2a4008Piotr Jastrzebski                        continue;
20251b1b6997fd3f980076b8081f7f1165ccc2a4008Piotr Jastrzebski                    }
20351b1b6997fd3f980076b8081f7f1165ccc2a4008Piotr Jastrzebski                }
20451b1b6997fd3f980076b8081f7f1165ccc2a4008Piotr Jastrzebski                return cb[nextChar++];
20551b1b6997fd3f980076b8081f7f1165ccc2a4008Piotr Jastrzebski            }
20651b1b6997fd3f980076b8081f7f1165ccc2a4008Piotr Jastrzebski        }
20751b1b6997fd3f980076b8081f7f1165ccc2a4008Piotr Jastrzebski    }
20851b1b6997fd3f980076b8081f7f1165ccc2a4008Piotr Jastrzebski
20951b1b6997fd3f980076b8081f7f1165ccc2a4008Piotr Jastrzebski    /**
21051b1b6997fd3f980076b8081f7f1165ccc2a4008Piotr Jastrzebski     * Reads characters into a portion of an array, reading from the underlying
21151b1b6997fd3f980076b8081f7f1165ccc2a4008Piotr Jastrzebski     * stream if necessary.
21251b1b6997fd3f980076b8081f7f1165ccc2a4008Piotr Jastrzebski     */
21351b1b6997fd3f980076b8081f7f1165ccc2a4008Piotr Jastrzebski    private int read1(char[] cbuf, int off, int len) throws IOException {
21451b1b6997fd3f980076b8081f7f1165ccc2a4008Piotr Jastrzebski        if (nextChar >= nChars) {
21551b1b6997fd3f980076b8081f7f1165ccc2a4008Piotr Jastrzebski            /* If the requested length is at least as large as the buffer, and
21651b1b6997fd3f980076b8081f7f1165ccc2a4008Piotr Jastrzebski               if there is no mark/reset activity, and if line feeds are not
21751b1b6997fd3f980076b8081f7f1165ccc2a4008Piotr Jastrzebski               being skipped, do not bother to copy the characters into the
21851b1b6997fd3f980076b8081f7f1165ccc2a4008Piotr Jastrzebski               local buffer.  In this way buffered streams will cascade
21951b1b6997fd3f980076b8081f7f1165ccc2a4008Piotr Jastrzebski               harmlessly. */
22051b1b6997fd3f980076b8081f7f1165ccc2a4008Piotr Jastrzebski            if (len >= cb.length && markedChar <= UNMARKED && !skipLF) {
22151b1b6997fd3f980076b8081f7f1165ccc2a4008Piotr Jastrzebski                return in.read(cbuf, off, len);
22251b1b6997fd3f980076b8081f7f1165ccc2a4008Piotr Jastrzebski            }
22351b1b6997fd3f980076b8081f7f1165ccc2a4008Piotr Jastrzebski            fill();
22451b1b6997fd3f980076b8081f7f1165ccc2a4008Piotr Jastrzebski        }
22551b1b6997fd3f980076b8081f7f1165ccc2a4008Piotr Jastrzebski        if (nextChar >= nChars) return -1;
22651b1b6997fd3f980076b8081f7f1165ccc2a4008Piotr Jastrzebski        if (skipLF) {
22751b1b6997fd3f980076b8081f7f1165ccc2a4008Piotr Jastrzebski            skipLF = false;
22851b1b6997fd3f980076b8081f7f1165ccc2a4008Piotr Jastrzebski            if (cb[nextChar] == '\n') {
22951b1b6997fd3f980076b8081f7f1165ccc2a4008Piotr Jastrzebski                nextChar++;
23051b1b6997fd3f980076b8081f7f1165ccc2a4008Piotr Jastrzebski                if (nextChar >= nChars)
23151b1b6997fd3f980076b8081f7f1165ccc2a4008Piotr Jastrzebski                    fill();
23251b1b6997fd3f980076b8081f7f1165ccc2a4008Piotr Jastrzebski                if (nextChar >= nChars)
23351b1b6997fd3f980076b8081f7f1165ccc2a4008Piotr Jastrzebski                    return -1;
23451b1b6997fd3f980076b8081f7f1165ccc2a4008Piotr Jastrzebski            }
23551b1b6997fd3f980076b8081f7f1165ccc2a4008Piotr Jastrzebski        }
23651b1b6997fd3f980076b8081f7f1165ccc2a4008Piotr Jastrzebski        int n = Math.min(len, nChars - nextChar);
23751b1b6997fd3f980076b8081f7f1165ccc2a4008Piotr Jastrzebski        System.arraycopy(cb, nextChar, cbuf, off, n);
23851b1b6997fd3f980076b8081f7f1165ccc2a4008Piotr Jastrzebski        nextChar += n;
23951b1b6997fd3f980076b8081f7f1165ccc2a4008Piotr Jastrzebski        return n;
24051b1b6997fd3f980076b8081f7f1165ccc2a4008Piotr Jastrzebski    }
24151b1b6997fd3f980076b8081f7f1165ccc2a4008Piotr Jastrzebski
24251b1b6997fd3f980076b8081f7f1165ccc2a4008Piotr Jastrzebski    /**
24351b1b6997fd3f980076b8081f7f1165ccc2a4008Piotr Jastrzebski     * Reads characters into a portion of an array.
24451b1b6997fd3f980076b8081f7f1165ccc2a4008Piotr Jastrzebski     *
24551b1b6997fd3f980076b8081f7f1165ccc2a4008Piotr Jastrzebski     * <p> This method implements the general contract of the corresponding
24651b1b6997fd3f980076b8081f7f1165ccc2a4008Piotr Jastrzebski     * <code>{@link Reader#read(char[], int, int) read}</code> method of the
24751b1b6997fd3f980076b8081f7f1165ccc2a4008Piotr Jastrzebski     * <code>{@link Reader}</code> class.  As an additional convenience, it
24851b1b6997fd3f980076b8081f7f1165ccc2a4008Piotr Jastrzebski     * attempts to read as many characters as possible by repeatedly invoking
24951b1b6997fd3f980076b8081f7f1165ccc2a4008Piotr Jastrzebski     * the <code>read</code> method of the underlying stream.  This iterated
25051b1b6997fd3f980076b8081f7f1165ccc2a4008Piotr Jastrzebski     * <code>read</code> continues until one of the following conditions becomes
25151b1b6997fd3f980076b8081f7f1165ccc2a4008Piotr Jastrzebski     * true: <ul>
25251b1b6997fd3f980076b8081f7f1165ccc2a4008Piotr Jastrzebski     *
25351b1b6997fd3f980076b8081f7f1165ccc2a4008Piotr Jastrzebski     *   <li> The specified number of characters have been read,
25451b1b6997fd3f980076b8081f7f1165ccc2a4008Piotr Jastrzebski     *
25551b1b6997fd3f980076b8081f7f1165ccc2a4008Piotr Jastrzebski     *   <li> The <code>read</code> method of the underlying stream returns
25651b1b6997fd3f980076b8081f7f1165ccc2a4008Piotr Jastrzebski     *   <code>-1</code>, indicating end-of-file, or
25751b1b6997fd3f980076b8081f7f1165ccc2a4008Piotr Jastrzebski     *
25851b1b6997fd3f980076b8081f7f1165ccc2a4008Piotr Jastrzebski     *   <li> The <code>ready</code> method of the underlying stream
25951b1b6997fd3f980076b8081f7f1165ccc2a4008Piotr Jastrzebski     *   returns <code>false</code>, indicating that further input requests
26051b1b6997fd3f980076b8081f7f1165ccc2a4008Piotr Jastrzebski     *   would block.
26151b1b6997fd3f980076b8081f7f1165ccc2a4008Piotr Jastrzebski     *
26251b1b6997fd3f980076b8081f7f1165ccc2a4008Piotr Jastrzebski     * </ul> If the first <code>read</code> on the underlying stream returns
26351b1b6997fd3f980076b8081f7f1165ccc2a4008Piotr Jastrzebski     * <code>-1</code> to indicate end-of-file then this method returns
26451b1b6997fd3f980076b8081f7f1165ccc2a4008Piotr Jastrzebski     * <code>-1</code>.  Otherwise this method returns the number of characters
26551b1b6997fd3f980076b8081f7f1165ccc2a4008Piotr Jastrzebski     * actually read.
26651b1b6997fd3f980076b8081f7f1165ccc2a4008Piotr Jastrzebski     *
26751b1b6997fd3f980076b8081f7f1165ccc2a4008Piotr Jastrzebski     * <p> Subclasses of this class are encouraged, but not required, to
26851b1b6997fd3f980076b8081f7f1165ccc2a4008Piotr Jastrzebski     * attempt to read as many characters as possible in the same fashion.
26951b1b6997fd3f980076b8081f7f1165ccc2a4008Piotr Jastrzebski     *
27051b1b6997fd3f980076b8081f7f1165ccc2a4008Piotr Jastrzebski     * <p> Ordinarily this method takes characters from this stream's character
27151b1b6997fd3f980076b8081f7f1165ccc2a4008Piotr Jastrzebski     * buffer, filling it from the underlying stream as necessary.  If,
27251b1b6997fd3f980076b8081f7f1165ccc2a4008Piotr Jastrzebski     * however, the buffer is empty, the mark is not valid, and the requested
27351b1b6997fd3f980076b8081f7f1165ccc2a4008Piotr Jastrzebski     * length is at least as large as the buffer, then this method will read
27451b1b6997fd3f980076b8081f7f1165ccc2a4008Piotr Jastrzebski     * characters directly from the underlying stream into the given array.
27551b1b6997fd3f980076b8081f7f1165ccc2a4008Piotr Jastrzebski     * Thus redundant <code>BufferedReader</code>s will not copy data
27651b1b6997fd3f980076b8081f7f1165ccc2a4008Piotr Jastrzebski     * unnecessarily.
27751b1b6997fd3f980076b8081f7f1165ccc2a4008Piotr Jastrzebski     *
27851b1b6997fd3f980076b8081f7f1165ccc2a4008Piotr Jastrzebski     * @param      cbuf  Destination buffer
27951b1b6997fd3f980076b8081f7f1165ccc2a4008Piotr Jastrzebski     * @param      off   Offset at which to start storing characters
28051b1b6997fd3f980076b8081f7f1165ccc2a4008Piotr Jastrzebski     * @param      len   Maximum number of characters to read
28151b1b6997fd3f980076b8081f7f1165ccc2a4008Piotr Jastrzebski     *
28251b1b6997fd3f980076b8081f7f1165ccc2a4008Piotr Jastrzebski     * @return     The number of characters read, or -1 if the end of the
28351b1b6997fd3f980076b8081f7f1165ccc2a4008Piotr Jastrzebski     *             stream has been reached
28451b1b6997fd3f980076b8081f7f1165ccc2a4008Piotr Jastrzebski     *
28551b1b6997fd3f980076b8081f7f1165ccc2a4008Piotr Jastrzebski     * @exception  IOException  If an I/O error occurs
28651b1b6997fd3f980076b8081f7f1165ccc2a4008Piotr Jastrzebski     */
28751b1b6997fd3f980076b8081f7f1165ccc2a4008Piotr Jastrzebski    public int read(char cbuf[], int off, int len) throws IOException {
28851b1b6997fd3f980076b8081f7f1165ccc2a4008Piotr Jastrzebski        synchronized (lock) {
28951b1b6997fd3f980076b8081f7f1165ccc2a4008Piotr Jastrzebski            ensureOpen();
29051b1b6997fd3f980076b8081f7f1165ccc2a4008Piotr Jastrzebski            if ((off < 0) || (off > cbuf.length) || (len < 0) ||
29151b1b6997fd3f980076b8081f7f1165ccc2a4008Piotr Jastrzebski                ((off + len) > cbuf.length) || ((off + len) < 0)) {
29251b1b6997fd3f980076b8081f7f1165ccc2a4008Piotr Jastrzebski                throw new IndexOutOfBoundsException();
29351b1b6997fd3f980076b8081f7f1165ccc2a4008Piotr Jastrzebski            } else if (len == 0) {
29451b1b6997fd3f980076b8081f7f1165ccc2a4008Piotr Jastrzebski                return 0;
29551b1b6997fd3f980076b8081f7f1165ccc2a4008Piotr Jastrzebski            }
29651b1b6997fd3f980076b8081f7f1165ccc2a4008Piotr Jastrzebski
29751b1b6997fd3f980076b8081f7f1165ccc2a4008Piotr Jastrzebski            int n = read1(cbuf, off, len);
29851b1b6997fd3f980076b8081f7f1165ccc2a4008Piotr Jastrzebski            if (n <= 0) return n;
29951b1b6997fd3f980076b8081f7f1165ccc2a4008Piotr Jastrzebski            while ((n < len) && in.ready()) {
30051b1b6997fd3f980076b8081f7f1165ccc2a4008Piotr Jastrzebski                int n1 = read1(cbuf, off + n, len - n);
30151b1b6997fd3f980076b8081f7f1165ccc2a4008Piotr Jastrzebski                if (n1 <= 0) break;
30251b1b6997fd3f980076b8081f7f1165ccc2a4008Piotr Jastrzebski                n += n1;
30351b1b6997fd3f980076b8081f7f1165ccc2a4008Piotr Jastrzebski            }
30451b1b6997fd3f980076b8081f7f1165ccc2a4008Piotr Jastrzebski            return n;
30551b1b6997fd3f980076b8081f7f1165ccc2a4008Piotr Jastrzebski        }
30651b1b6997fd3f980076b8081f7f1165ccc2a4008Piotr Jastrzebski    }
30751b1b6997fd3f980076b8081f7f1165ccc2a4008Piotr Jastrzebski
30851b1b6997fd3f980076b8081f7f1165ccc2a4008Piotr Jastrzebski    /**
30951b1b6997fd3f980076b8081f7f1165ccc2a4008Piotr Jastrzebski     * Reads a line of text.  A line is considered to be terminated by any one
31051b1b6997fd3f980076b8081f7f1165ccc2a4008Piotr Jastrzebski     * of a line feed ('\n'), a carriage return ('\r'), or a carriage return
31151b1b6997fd3f980076b8081f7f1165ccc2a4008Piotr Jastrzebski     * followed immediately by a linefeed.
31251b1b6997fd3f980076b8081f7f1165ccc2a4008Piotr Jastrzebski     *
31351b1b6997fd3f980076b8081f7f1165ccc2a4008Piotr Jastrzebski     * @param      ignoreLF  If true, the next '\n' will be skipped
31451b1b6997fd3f980076b8081f7f1165ccc2a4008Piotr Jastrzebski     *
31551b1b6997fd3f980076b8081f7f1165ccc2a4008Piotr Jastrzebski     * @return     A String containing the contents of the line, not including
31651b1b6997fd3f980076b8081f7f1165ccc2a4008Piotr Jastrzebski     *             any line-termination characters, or null if the end of the
31751b1b6997fd3f980076b8081f7f1165ccc2a4008Piotr Jastrzebski     *             stream has been reached
31851b1b6997fd3f980076b8081f7f1165ccc2a4008Piotr Jastrzebski     *
31951b1b6997fd3f980076b8081f7f1165ccc2a4008Piotr Jastrzebski     * @see        java.io.LineNumberReader#readLine()
32051b1b6997fd3f980076b8081f7f1165ccc2a4008Piotr Jastrzebski     *
32151b1b6997fd3f980076b8081f7f1165ccc2a4008Piotr Jastrzebski     * @exception  IOException  If an I/O error occurs
32251b1b6997fd3f980076b8081f7f1165ccc2a4008Piotr Jastrzebski     */
32351b1b6997fd3f980076b8081f7f1165ccc2a4008Piotr Jastrzebski    String readLine(boolean ignoreLF) throws IOException {
32451b1b6997fd3f980076b8081f7f1165ccc2a4008Piotr Jastrzebski        StringBuffer s = null;
32551b1b6997fd3f980076b8081f7f1165ccc2a4008Piotr Jastrzebski        int startChar;
32651b1b6997fd3f980076b8081f7f1165ccc2a4008Piotr Jastrzebski
32751b1b6997fd3f980076b8081f7f1165ccc2a4008Piotr Jastrzebski        synchronized (lock) {
32851b1b6997fd3f980076b8081f7f1165ccc2a4008Piotr Jastrzebski            ensureOpen();
32951b1b6997fd3f980076b8081f7f1165ccc2a4008Piotr Jastrzebski            boolean omitLF = ignoreLF || skipLF;
33051b1b6997fd3f980076b8081f7f1165ccc2a4008Piotr Jastrzebski
33151b1b6997fd3f980076b8081f7f1165ccc2a4008Piotr Jastrzebski        bufferLoop:
33251b1b6997fd3f980076b8081f7f1165ccc2a4008Piotr Jastrzebski            for (;;) {
33351b1b6997fd3f980076b8081f7f1165ccc2a4008Piotr Jastrzebski
33451b1b6997fd3f980076b8081f7f1165ccc2a4008Piotr Jastrzebski                if (nextChar >= nChars)
33551b1b6997fd3f980076b8081f7f1165ccc2a4008Piotr Jastrzebski                    fill();
33651b1b6997fd3f980076b8081f7f1165ccc2a4008Piotr Jastrzebski                if (nextChar >= nChars) { /* EOF */
33751b1b6997fd3f980076b8081f7f1165ccc2a4008Piotr Jastrzebski                    if (s != null && s.length() > 0)
33851b1b6997fd3f980076b8081f7f1165ccc2a4008Piotr Jastrzebski                        return s.toString();
33951b1b6997fd3f980076b8081f7f1165ccc2a4008Piotr Jastrzebski                    else
34051b1b6997fd3f980076b8081f7f1165ccc2a4008Piotr Jastrzebski                        return null;
34151b1b6997fd3f980076b8081f7f1165ccc2a4008Piotr Jastrzebski                }
34251b1b6997fd3f980076b8081f7f1165ccc2a4008Piotr Jastrzebski                boolean eol = false;
34351b1b6997fd3f980076b8081f7f1165ccc2a4008Piotr Jastrzebski                char c = 0;
34451b1b6997fd3f980076b8081f7f1165ccc2a4008Piotr Jastrzebski                int i;
34551b1b6997fd3f980076b8081f7f1165ccc2a4008Piotr Jastrzebski
34651b1b6997fd3f980076b8081f7f1165ccc2a4008Piotr Jastrzebski                /* Skip a leftover '\n', if necessary */
34751b1b6997fd3f980076b8081f7f1165ccc2a4008Piotr Jastrzebski                if (omitLF && (cb[nextChar] == '\n'))
34851b1b6997fd3f980076b8081f7f1165ccc2a4008Piotr Jastrzebski                    nextChar++;
34951b1b6997fd3f980076b8081f7f1165ccc2a4008Piotr Jastrzebski                skipLF = false;
35051b1b6997fd3f980076b8081f7f1165ccc2a4008Piotr Jastrzebski                omitLF = false;
35151b1b6997fd3f980076b8081f7f1165ccc2a4008Piotr Jastrzebski
35251b1b6997fd3f980076b8081f7f1165ccc2a4008Piotr Jastrzebski            charLoop:
35351b1b6997fd3f980076b8081f7f1165ccc2a4008Piotr Jastrzebski                for (i = nextChar; i < nChars; i++) {
35451b1b6997fd3f980076b8081f7f1165ccc2a4008Piotr Jastrzebski                    c = cb[i];
35551b1b6997fd3f980076b8081f7f1165ccc2a4008Piotr Jastrzebski                    if ((c == '\n') || (c == '\r')) {
35651b1b6997fd3f980076b8081f7f1165ccc2a4008Piotr Jastrzebski                        eol = true;
35751b1b6997fd3f980076b8081f7f1165ccc2a4008Piotr Jastrzebski                        break charLoop;
35851b1b6997fd3f980076b8081f7f1165ccc2a4008Piotr Jastrzebski                    }
35951b1b6997fd3f980076b8081f7f1165ccc2a4008Piotr Jastrzebski                }
36051b1b6997fd3f980076b8081f7f1165ccc2a4008Piotr Jastrzebski
36151b1b6997fd3f980076b8081f7f1165ccc2a4008Piotr Jastrzebski                startChar = nextChar;
36251b1b6997fd3f980076b8081f7f1165ccc2a4008Piotr Jastrzebski                nextChar = i;
36351b1b6997fd3f980076b8081f7f1165ccc2a4008Piotr Jastrzebski
36451b1b6997fd3f980076b8081f7f1165ccc2a4008Piotr Jastrzebski                if (eol) {
36551b1b6997fd3f980076b8081f7f1165ccc2a4008Piotr Jastrzebski                    String str;
36651b1b6997fd3f980076b8081f7f1165ccc2a4008Piotr Jastrzebski                    if (s == null) {
36751b1b6997fd3f980076b8081f7f1165ccc2a4008Piotr Jastrzebski                        str = new String(cb, startChar, i - startChar);
36851b1b6997fd3f980076b8081f7f1165ccc2a4008Piotr Jastrzebski                    } else {
36951b1b6997fd3f980076b8081f7f1165ccc2a4008Piotr Jastrzebski                        s.append(cb, startChar, i - startChar);
37051b1b6997fd3f980076b8081f7f1165ccc2a4008Piotr Jastrzebski                        str = s.toString();
37151b1b6997fd3f980076b8081f7f1165ccc2a4008Piotr Jastrzebski                    }
37251b1b6997fd3f980076b8081f7f1165ccc2a4008Piotr Jastrzebski                    nextChar++;
37351b1b6997fd3f980076b8081f7f1165ccc2a4008Piotr Jastrzebski                    if (c == '\r') {
37451b1b6997fd3f980076b8081f7f1165ccc2a4008Piotr Jastrzebski                        skipLF = true;
37551b1b6997fd3f980076b8081f7f1165ccc2a4008Piotr Jastrzebski                    }
37651b1b6997fd3f980076b8081f7f1165ccc2a4008Piotr Jastrzebski                    return str;
37751b1b6997fd3f980076b8081f7f1165ccc2a4008Piotr Jastrzebski                }
37851b1b6997fd3f980076b8081f7f1165ccc2a4008Piotr Jastrzebski
37951b1b6997fd3f980076b8081f7f1165ccc2a4008Piotr Jastrzebski                if (s == null)
38051b1b6997fd3f980076b8081f7f1165ccc2a4008Piotr Jastrzebski                    s = new StringBuffer(defaultExpectedLineLength);
38151b1b6997fd3f980076b8081f7f1165ccc2a4008Piotr Jastrzebski                s.append(cb, startChar, i - startChar);
38251b1b6997fd3f980076b8081f7f1165ccc2a4008Piotr Jastrzebski            }
38351b1b6997fd3f980076b8081f7f1165ccc2a4008Piotr Jastrzebski        }
38451b1b6997fd3f980076b8081f7f1165ccc2a4008Piotr Jastrzebski    }
38551b1b6997fd3f980076b8081f7f1165ccc2a4008Piotr Jastrzebski
38651b1b6997fd3f980076b8081f7f1165ccc2a4008Piotr Jastrzebski    /**
38751b1b6997fd3f980076b8081f7f1165ccc2a4008Piotr Jastrzebski     * Reads a line of text.  A line is considered to be terminated by any one
38851b1b6997fd3f980076b8081f7f1165ccc2a4008Piotr Jastrzebski     * of a line feed ('\n'), a carriage return ('\r'), or a carriage return
38951b1b6997fd3f980076b8081f7f1165ccc2a4008Piotr Jastrzebski     * followed immediately by a linefeed.
39051b1b6997fd3f980076b8081f7f1165ccc2a4008Piotr Jastrzebski     *
39151b1b6997fd3f980076b8081f7f1165ccc2a4008Piotr Jastrzebski     * @return     A String containing the contents of the line, not including
39251b1b6997fd3f980076b8081f7f1165ccc2a4008Piotr Jastrzebski     *             any line-termination characters, or null if the end of the
39351b1b6997fd3f980076b8081f7f1165ccc2a4008Piotr Jastrzebski     *             stream has been reached
39451b1b6997fd3f980076b8081f7f1165ccc2a4008Piotr Jastrzebski     *
39551b1b6997fd3f980076b8081f7f1165ccc2a4008Piotr Jastrzebski     * @exception  IOException  If an I/O error occurs
39651b1b6997fd3f980076b8081f7f1165ccc2a4008Piotr Jastrzebski     *
39751b1b6997fd3f980076b8081f7f1165ccc2a4008Piotr Jastrzebski     * @see java.nio.file.Files#readAllLines
39851b1b6997fd3f980076b8081f7f1165ccc2a4008Piotr Jastrzebski     */
39951b1b6997fd3f980076b8081f7f1165ccc2a4008Piotr Jastrzebski    public String readLine() throws IOException {
40051b1b6997fd3f980076b8081f7f1165ccc2a4008Piotr Jastrzebski        return readLine(false);
40151b1b6997fd3f980076b8081f7f1165ccc2a4008Piotr Jastrzebski    }
40251b1b6997fd3f980076b8081f7f1165ccc2a4008Piotr Jastrzebski
40351b1b6997fd3f980076b8081f7f1165ccc2a4008Piotr Jastrzebski    /**
40451b1b6997fd3f980076b8081f7f1165ccc2a4008Piotr Jastrzebski     * Skips characters.
40551b1b6997fd3f980076b8081f7f1165ccc2a4008Piotr Jastrzebski     *
40651b1b6997fd3f980076b8081f7f1165ccc2a4008Piotr Jastrzebski     * @param  n  The number of characters to skip
40751b1b6997fd3f980076b8081f7f1165ccc2a4008Piotr Jastrzebski     *
40851b1b6997fd3f980076b8081f7f1165ccc2a4008Piotr Jastrzebski     * @return    The number of characters actually skipped
40951b1b6997fd3f980076b8081f7f1165ccc2a4008Piotr Jastrzebski     *
41051b1b6997fd3f980076b8081f7f1165ccc2a4008Piotr Jastrzebski     * @exception  IllegalArgumentException  If <code>n</code> is negative.
41151b1b6997fd3f980076b8081f7f1165ccc2a4008Piotr Jastrzebski     * @exception  IOException  If an I/O error occurs
41251b1b6997fd3f980076b8081f7f1165ccc2a4008Piotr Jastrzebski     */
41351b1b6997fd3f980076b8081f7f1165ccc2a4008Piotr Jastrzebski    public long skip(long n) throws IOException {
41451b1b6997fd3f980076b8081f7f1165ccc2a4008Piotr Jastrzebski        if (n < 0L) {
41551b1b6997fd3f980076b8081f7f1165ccc2a4008Piotr Jastrzebski            throw new IllegalArgumentException("skip value is negative");
41651b1b6997fd3f980076b8081f7f1165ccc2a4008Piotr Jastrzebski        }
41751b1b6997fd3f980076b8081f7f1165ccc2a4008Piotr Jastrzebski        synchronized (lock) {
41851b1b6997fd3f980076b8081f7f1165ccc2a4008Piotr Jastrzebski            ensureOpen();
41951b1b6997fd3f980076b8081f7f1165ccc2a4008Piotr Jastrzebski            long r = n;
42051b1b6997fd3f980076b8081f7f1165ccc2a4008Piotr Jastrzebski            while (r > 0) {
42151b1b6997fd3f980076b8081f7f1165ccc2a4008Piotr Jastrzebski                if (nextChar >= nChars)
42251b1b6997fd3f980076b8081f7f1165ccc2a4008Piotr Jastrzebski                    fill();
42351b1b6997fd3f980076b8081f7f1165ccc2a4008Piotr Jastrzebski                if (nextChar >= nChars) /* EOF */
42451b1b6997fd3f980076b8081f7f1165ccc2a4008Piotr Jastrzebski                    break;
42551b1b6997fd3f980076b8081f7f1165ccc2a4008Piotr Jastrzebski                if (skipLF) {
42651b1b6997fd3f980076b8081f7f1165ccc2a4008Piotr Jastrzebski                    skipLF = false;
42751b1b6997fd3f980076b8081f7f1165ccc2a4008Piotr Jastrzebski                    if (cb[nextChar] == '\n') {
42851b1b6997fd3f980076b8081f7f1165ccc2a4008Piotr Jastrzebski                        nextChar++;
42951b1b6997fd3f980076b8081f7f1165ccc2a4008Piotr Jastrzebski                    }
43051b1b6997fd3f980076b8081f7f1165ccc2a4008Piotr Jastrzebski                }
43151b1b6997fd3f980076b8081f7f1165ccc2a4008Piotr Jastrzebski                long d = nChars - nextChar;
43251b1b6997fd3f980076b8081f7f1165ccc2a4008Piotr Jastrzebski                if (r <= d) {
43351b1b6997fd3f980076b8081f7f1165ccc2a4008Piotr Jastrzebski                    nextChar += r;
43451b1b6997fd3f980076b8081f7f1165ccc2a4008Piotr Jastrzebski                    r = 0;
43551b1b6997fd3f980076b8081f7f1165ccc2a4008Piotr Jastrzebski                    break;
43651b1b6997fd3f980076b8081f7f1165ccc2a4008Piotr Jastrzebski                }
43751b1b6997fd3f980076b8081f7f1165ccc2a4008Piotr Jastrzebski                else {
43851b1b6997fd3f980076b8081f7f1165ccc2a4008Piotr Jastrzebski                    r -= d;
43951b1b6997fd3f980076b8081f7f1165ccc2a4008Piotr Jastrzebski                    nextChar = nChars;
44051b1b6997fd3f980076b8081f7f1165ccc2a4008Piotr Jastrzebski                }
44151b1b6997fd3f980076b8081f7f1165ccc2a4008Piotr Jastrzebski            }
44251b1b6997fd3f980076b8081f7f1165ccc2a4008Piotr Jastrzebski            return n - r;
44351b1b6997fd3f980076b8081f7f1165ccc2a4008Piotr Jastrzebski        }
44451b1b6997fd3f980076b8081f7f1165ccc2a4008Piotr Jastrzebski    }
44551b1b6997fd3f980076b8081f7f1165ccc2a4008Piotr Jastrzebski
44651b1b6997fd3f980076b8081f7f1165ccc2a4008Piotr Jastrzebski    /**
44751b1b6997fd3f980076b8081f7f1165ccc2a4008Piotr Jastrzebski     * Tells whether this stream is ready to be read.  A buffered character
44851b1b6997fd3f980076b8081f7f1165ccc2a4008Piotr Jastrzebski     * stream is ready if the buffer is not empty, or if the underlying
44951b1b6997fd3f980076b8081f7f1165ccc2a4008Piotr Jastrzebski     * character stream is ready.
45051b1b6997fd3f980076b8081f7f1165ccc2a4008Piotr Jastrzebski     *
45151b1b6997fd3f980076b8081f7f1165ccc2a4008Piotr Jastrzebski     * @exception  IOException  If an I/O error occurs
45251b1b6997fd3f980076b8081f7f1165ccc2a4008Piotr Jastrzebski     */
45351b1b6997fd3f980076b8081f7f1165ccc2a4008Piotr Jastrzebski    public boolean ready() throws IOException {
45451b1b6997fd3f980076b8081f7f1165ccc2a4008Piotr Jastrzebski        synchronized (lock) {
45551b1b6997fd3f980076b8081f7f1165ccc2a4008Piotr Jastrzebski            ensureOpen();
45651b1b6997fd3f980076b8081f7f1165ccc2a4008Piotr Jastrzebski
45751b1b6997fd3f980076b8081f7f1165ccc2a4008Piotr Jastrzebski            /*
45851b1b6997fd3f980076b8081f7f1165ccc2a4008Piotr Jastrzebski             * If newline needs to be skipped and the next char to be read
45951b1b6997fd3f980076b8081f7f1165ccc2a4008Piotr Jastrzebski             * is a newline character, then just skip it right away.
46051b1b6997fd3f980076b8081f7f1165ccc2a4008Piotr Jastrzebski             */
46151b1b6997fd3f980076b8081f7f1165ccc2a4008Piotr Jastrzebski            if (skipLF) {
46251b1b6997fd3f980076b8081f7f1165ccc2a4008Piotr Jastrzebski                /* Note that in.ready() will return true if and only if the next
46351b1b6997fd3f980076b8081f7f1165ccc2a4008Piotr Jastrzebski                 * read on the stream will not block.
46451b1b6997fd3f980076b8081f7f1165ccc2a4008Piotr Jastrzebski                 */
46551b1b6997fd3f980076b8081f7f1165ccc2a4008Piotr Jastrzebski                if (nextChar >= nChars && in.ready()) {
46651b1b6997fd3f980076b8081f7f1165ccc2a4008Piotr Jastrzebski                    fill();
46751b1b6997fd3f980076b8081f7f1165ccc2a4008Piotr Jastrzebski                }
46851b1b6997fd3f980076b8081f7f1165ccc2a4008Piotr Jastrzebski                if (nextChar < nChars) {
46951b1b6997fd3f980076b8081f7f1165ccc2a4008Piotr Jastrzebski                    if (cb[nextChar] == '\n')
47051b1b6997fd3f980076b8081f7f1165ccc2a4008Piotr Jastrzebski                        nextChar++;
47151b1b6997fd3f980076b8081f7f1165ccc2a4008Piotr Jastrzebski                    skipLF = false;
47251b1b6997fd3f980076b8081f7f1165ccc2a4008Piotr Jastrzebski                }
47351b1b6997fd3f980076b8081f7f1165ccc2a4008Piotr Jastrzebski            }
47451b1b6997fd3f980076b8081f7f1165ccc2a4008Piotr Jastrzebski            return (nextChar < nChars) || in.ready();
47551b1b6997fd3f980076b8081f7f1165ccc2a4008Piotr Jastrzebski        }
47651b1b6997fd3f980076b8081f7f1165ccc2a4008Piotr Jastrzebski    }
47751b1b6997fd3f980076b8081f7f1165ccc2a4008Piotr Jastrzebski
47851b1b6997fd3f980076b8081f7f1165ccc2a4008Piotr Jastrzebski    /**
47951b1b6997fd3f980076b8081f7f1165ccc2a4008Piotr Jastrzebski     * Tells whether this stream supports the mark() operation, which it does.
48051b1b6997fd3f980076b8081f7f1165ccc2a4008Piotr Jastrzebski     */
48151b1b6997fd3f980076b8081f7f1165ccc2a4008Piotr Jastrzebski    public boolean markSupported() {
48251b1b6997fd3f980076b8081f7f1165ccc2a4008Piotr Jastrzebski        return true;
48351b1b6997fd3f980076b8081f7f1165ccc2a4008Piotr Jastrzebski    }
48451b1b6997fd3f980076b8081f7f1165ccc2a4008Piotr Jastrzebski
48551b1b6997fd3f980076b8081f7f1165ccc2a4008Piotr Jastrzebski    /**
48651b1b6997fd3f980076b8081f7f1165ccc2a4008Piotr Jastrzebski     * Marks the present position in the stream.  Subsequent calls to reset()
48751b1b6997fd3f980076b8081f7f1165ccc2a4008Piotr Jastrzebski     * will attempt to reposition the stream to this point.
48851b1b6997fd3f980076b8081f7f1165ccc2a4008Piotr Jastrzebski     *
48951b1b6997fd3f980076b8081f7f1165ccc2a4008Piotr Jastrzebski     * @param readAheadLimit   Limit on the number of characters that may be
49051b1b6997fd3f980076b8081f7f1165ccc2a4008Piotr Jastrzebski     *                         read while still preserving the mark. An attempt
49151b1b6997fd3f980076b8081f7f1165ccc2a4008Piotr Jastrzebski     *                         to reset the stream after reading characters
49251b1b6997fd3f980076b8081f7f1165ccc2a4008Piotr Jastrzebski     *                         up to this limit or beyond may fail.
49351b1b6997fd3f980076b8081f7f1165ccc2a4008Piotr Jastrzebski     *                         A limit value larger than the size of the input
49451b1b6997fd3f980076b8081f7f1165ccc2a4008Piotr Jastrzebski     *                         buffer will cause a new buffer to be allocated
49551b1b6997fd3f980076b8081f7f1165ccc2a4008Piotr Jastrzebski     *                         whose size is no smaller than limit.
49651b1b6997fd3f980076b8081f7f1165ccc2a4008Piotr Jastrzebski     *                         Therefore large values should be used with care.
49751b1b6997fd3f980076b8081f7f1165ccc2a4008Piotr Jastrzebski     *
4982e3af1f347f088ed6cd432f88b8dcf63d7a628e5Przemyslaw Szczepaniak     * @exception  IllegalArgumentException  If {@code readAheadLimit < 0}
49951b1b6997fd3f980076b8081f7f1165ccc2a4008Piotr Jastrzebski     * @exception  IOException  If an I/O error occurs
50051b1b6997fd3f980076b8081f7f1165ccc2a4008Piotr Jastrzebski     */
50151b1b6997fd3f980076b8081f7f1165ccc2a4008Piotr Jastrzebski    public void mark(int readAheadLimit) throws IOException {
50251b1b6997fd3f980076b8081f7f1165ccc2a4008Piotr Jastrzebski        if (readAheadLimit < 0) {
50351b1b6997fd3f980076b8081f7f1165ccc2a4008Piotr Jastrzebski            throw new IllegalArgumentException("Read-ahead limit < 0");
50451b1b6997fd3f980076b8081f7f1165ccc2a4008Piotr Jastrzebski        }
50551b1b6997fd3f980076b8081f7f1165ccc2a4008Piotr Jastrzebski        synchronized (lock) {
50651b1b6997fd3f980076b8081f7f1165ccc2a4008Piotr Jastrzebski            ensureOpen();
50751b1b6997fd3f980076b8081f7f1165ccc2a4008Piotr Jastrzebski            this.readAheadLimit = readAheadLimit;
50851b1b6997fd3f980076b8081f7f1165ccc2a4008Piotr Jastrzebski            markedChar = nextChar;
50951b1b6997fd3f980076b8081f7f1165ccc2a4008Piotr Jastrzebski            markedSkipLF = skipLF;
51051b1b6997fd3f980076b8081f7f1165ccc2a4008Piotr Jastrzebski        }
51151b1b6997fd3f980076b8081f7f1165ccc2a4008Piotr Jastrzebski    }
51251b1b6997fd3f980076b8081f7f1165ccc2a4008Piotr Jastrzebski
51351b1b6997fd3f980076b8081f7f1165ccc2a4008Piotr Jastrzebski    /**
51451b1b6997fd3f980076b8081f7f1165ccc2a4008Piotr Jastrzebski     * Resets the stream to the most recent mark.
51551b1b6997fd3f980076b8081f7f1165ccc2a4008Piotr Jastrzebski     *
51651b1b6997fd3f980076b8081f7f1165ccc2a4008Piotr Jastrzebski     * @exception  IOException  If the stream has never been marked,
51751b1b6997fd3f980076b8081f7f1165ccc2a4008Piotr Jastrzebski     *                          or if the mark has been invalidated
51851b1b6997fd3f980076b8081f7f1165ccc2a4008Piotr Jastrzebski     */
51951b1b6997fd3f980076b8081f7f1165ccc2a4008Piotr Jastrzebski    public void reset() throws IOException {
52051b1b6997fd3f980076b8081f7f1165ccc2a4008Piotr Jastrzebski        synchronized (lock) {
52151b1b6997fd3f980076b8081f7f1165ccc2a4008Piotr Jastrzebski            ensureOpen();
52251b1b6997fd3f980076b8081f7f1165ccc2a4008Piotr Jastrzebski            if (markedChar < 0)
52351b1b6997fd3f980076b8081f7f1165ccc2a4008Piotr Jastrzebski                throw new IOException((markedChar == INVALIDATED)
52451b1b6997fd3f980076b8081f7f1165ccc2a4008Piotr Jastrzebski                                      ? "Mark invalid"
52551b1b6997fd3f980076b8081f7f1165ccc2a4008Piotr Jastrzebski                                      : "Stream not marked");
52651b1b6997fd3f980076b8081f7f1165ccc2a4008Piotr Jastrzebski            nextChar = markedChar;
52751b1b6997fd3f980076b8081f7f1165ccc2a4008Piotr Jastrzebski            skipLF = markedSkipLF;
52851b1b6997fd3f980076b8081f7f1165ccc2a4008Piotr Jastrzebski        }
52951b1b6997fd3f980076b8081f7f1165ccc2a4008Piotr Jastrzebski    }
53051b1b6997fd3f980076b8081f7f1165ccc2a4008Piotr Jastrzebski
53151b1b6997fd3f980076b8081f7f1165ccc2a4008Piotr Jastrzebski    public void close() throws IOException {
53251b1b6997fd3f980076b8081f7f1165ccc2a4008Piotr Jastrzebski        synchronized (lock) {
53351b1b6997fd3f980076b8081f7f1165ccc2a4008Piotr Jastrzebski            if (in == null)
53451b1b6997fd3f980076b8081f7f1165ccc2a4008Piotr Jastrzebski                return;
5352e3af1f347f088ed6cd432f88b8dcf63d7a628e5Przemyslaw Szczepaniak            try {
5362e3af1f347f088ed6cd432f88b8dcf63d7a628e5Przemyslaw Szczepaniak                in.close();
5372e3af1f347f088ed6cd432f88b8dcf63d7a628e5Przemyslaw Szczepaniak            } finally {
5382e3af1f347f088ed6cd432f88b8dcf63d7a628e5Przemyslaw Szczepaniak                in = null;
5392e3af1f347f088ed6cd432f88b8dcf63d7a628e5Przemyslaw Szczepaniak                cb = null;
5402e3af1f347f088ed6cd432f88b8dcf63d7a628e5Przemyslaw Szczepaniak            }
54151b1b6997fd3f980076b8081f7f1165ccc2a4008Piotr Jastrzebski        }
54251b1b6997fd3f980076b8081f7f1165ccc2a4008Piotr Jastrzebski    }
5432c4230d24a2349039b4d7d513d0fb61542bc4cb7Yi Kong
5442c4230d24a2349039b4d7d513d0fb61542bc4cb7Yi Kong    /**
5452c4230d24a2349039b4d7d513d0fb61542bc4cb7Yi Kong     * Returns a {@code Stream}, the elements of which are lines read from
5462c4230d24a2349039b4d7d513d0fb61542bc4cb7Yi Kong     * this {@code BufferedReader}.  The {@link Stream} is lazily populated,
5472c4230d24a2349039b4d7d513d0fb61542bc4cb7Yi Kong     * i.e., read only occurs during the
5482c4230d24a2349039b4d7d513d0fb61542bc4cb7Yi Kong     * <a href="../util/stream/package-summary.html#StreamOps">terminal
5492c4230d24a2349039b4d7d513d0fb61542bc4cb7Yi Kong     * stream operation</a>.
5502c4230d24a2349039b4d7d513d0fb61542bc4cb7Yi Kong     *
5512c4230d24a2349039b4d7d513d0fb61542bc4cb7Yi Kong     * <p> The reader must not be operated on during the execution of the
5522c4230d24a2349039b4d7d513d0fb61542bc4cb7Yi Kong     * terminal stream operation. Otherwise, the result of the terminal stream
5532c4230d24a2349039b4d7d513d0fb61542bc4cb7Yi Kong     * operation is undefined.
5542c4230d24a2349039b4d7d513d0fb61542bc4cb7Yi Kong     *
5552c4230d24a2349039b4d7d513d0fb61542bc4cb7Yi Kong     * <p> After execution of the terminal stream operation there are no
5562c4230d24a2349039b4d7d513d0fb61542bc4cb7Yi Kong     * guarantees that the reader will be at a specific position from which to
5572c4230d24a2349039b4d7d513d0fb61542bc4cb7Yi Kong     * read the next character or line.
5582c4230d24a2349039b4d7d513d0fb61542bc4cb7Yi Kong     *
5592c4230d24a2349039b4d7d513d0fb61542bc4cb7Yi Kong     * <p> If an {@link IOException} is thrown when accessing the underlying
5602c4230d24a2349039b4d7d513d0fb61542bc4cb7Yi Kong     * {@code BufferedReader}, it is wrapped in an {@link
5612c4230d24a2349039b4d7d513d0fb61542bc4cb7Yi Kong     * UncheckedIOException} which will be thrown from the {@code Stream}
5622c4230d24a2349039b4d7d513d0fb61542bc4cb7Yi Kong     * method that caused the read to take place. This method will return a
5632c4230d24a2349039b4d7d513d0fb61542bc4cb7Yi Kong     * Stream if invoked on a BufferedReader that is closed. Any operation on
5642c4230d24a2349039b4d7d513d0fb61542bc4cb7Yi Kong     * that stream that requires reading from the BufferedReader after it is
5652c4230d24a2349039b4d7d513d0fb61542bc4cb7Yi Kong     * closed, will cause an UncheckedIOException to be thrown.
5662c4230d24a2349039b4d7d513d0fb61542bc4cb7Yi Kong     *
5672c4230d24a2349039b4d7d513d0fb61542bc4cb7Yi Kong     * @return a {@code Stream<String>} providing the lines of text
5682c4230d24a2349039b4d7d513d0fb61542bc4cb7Yi Kong     *         described by this {@code BufferedReader}
5692c4230d24a2349039b4d7d513d0fb61542bc4cb7Yi Kong     *
5702c4230d24a2349039b4d7d513d0fb61542bc4cb7Yi Kong     * @since 1.8
5712c4230d24a2349039b4d7d513d0fb61542bc4cb7Yi Kong     */
5722c4230d24a2349039b4d7d513d0fb61542bc4cb7Yi Kong    public Stream<String> lines() {
5732c4230d24a2349039b4d7d513d0fb61542bc4cb7Yi Kong        Iterator<String> iter = new Iterator<String>() {
5742c4230d24a2349039b4d7d513d0fb61542bc4cb7Yi Kong            String nextLine = null;
5752c4230d24a2349039b4d7d513d0fb61542bc4cb7Yi Kong
5762c4230d24a2349039b4d7d513d0fb61542bc4cb7Yi Kong            @Override
5772c4230d24a2349039b4d7d513d0fb61542bc4cb7Yi Kong            public boolean hasNext() {
5782c4230d24a2349039b4d7d513d0fb61542bc4cb7Yi Kong                if (nextLine != null) {
5792c4230d24a2349039b4d7d513d0fb61542bc4cb7Yi Kong                    return true;
5802c4230d24a2349039b4d7d513d0fb61542bc4cb7Yi Kong                } else {
5812c4230d24a2349039b4d7d513d0fb61542bc4cb7Yi Kong                    try {
5822c4230d24a2349039b4d7d513d0fb61542bc4cb7Yi Kong                        nextLine = readLine();
5832c4230d24a2349039b4d7d513d0fb61542bc4cb7Yi Kong                        return (nextLine != null);
5842c4230d24a2349039b4d7d513d0fb61542bc4cb7Yi Kong                    } catch (IOException e) {
5852c4230d24a2349039b4d7d513d0fb61542bc4cb7Yi Kong                        throw new UncheckedIOException(e);
5862c4230d24a2349039b4d7d513d0fb61542bc4cb7Yi Kong                    }
5872c4230d24a2349039b4d7d513d0fb61542bc4cb7Yi Kong                }
5882c4230d24a2349039b4d7d513d0fb61542bc4cb7Yi Kong            }
5892c4230d24a2349039b4d7d513d0fb61542bc4cb7Yi Kong
5902c4230d24a2349039b4d7d513d0fb61542bc4cb7Yi Kong            @Override
5912c4230d24a2349039b4d7d513d0fb61542bc4cb7Yi Kong            public String next() {
5922c4230d24a2349039b4d7d513d0fb61542bc4cb7Yi Kong                if (nextLine != null || hasNext()) {
5932c4230d24a2349039b4d7d513d0fb61542bc4cb7Yi Kong                    String line = nextLine;
5942c4230d24a2349039b4d7d513d0fb61542bc4cb7Yi Kong                    nextLine = null;
5952c4230d24a2349039b4d7d513d0fb61542bc4cb7Yi Kong                    return line;
5962c4230d24a2349039b4d7d513d0fb61542bc4cb7Yi Kong                } else {
5972c4230d24a2349039b4d7d513d0fb61542bc4cb7Yi Kong                    throw new NoSuchElementException();
5982c4230d24a2349039b4d7d513d0fb61542bc4cb7Yi Kong                }
5992c4230d24a2349039b4d7d513d0fb61542bc4cb7Yi Kong            }
6002c4230d24a2349039b4d7d513d0fb61542bc4cb7Yi Kong        };
6012c4230d24a2349039b4d7d513d0fb61542bc4cb7Yi Kong        return StreamSupport.stream(Spliterators.spliteratorUnknownSize(
6022c4230d24a2349039b4d7d513d0fb61542bc4cb7Yi Kong                iter, Spliterator.ORDERED | Spliterator.NONNULL), false);
6032c4230d24a2349039b4d7d513d0fb61542bc4cb7Yi Kong    }
60451b1b6997fd3f980076b8081f7f1165ccc2a4008Piotr Jastrzebski}
605