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