1adc854b798c1cfe3bfd4c27d68d5cee38ca617daThe Android Open Source Project/* 2adc854b798c1cfe3bfd4c27d68d5cee38ca617daThe Android Open Source Project * Licensed to the Apache Software Foundation (ASF) under one or more 3adc854b798c1cfe3bfd4c27d68d5cee38ca617daThe Android Open Source Project * contributor license agreements. See the NOTICE file distributed with 4adc854b798c1cfe3bfd4c27d68d5cee38ca617daThe Android Open Source Project * this work for additional information regarding copyright ownership. 5adc854b798c1cfe3bfd4c27d68d5cee38ca617daThe Android Open Source Project * The ASF licenses this file to You under the Apache License, Version 2.0 6adc854b798c1cfe3bfd4c27d68d5cee38ca617daThe Android Open Source Project * (the "License"); you may not use this file except in compliance with 7adc854b798c1cfe3bfd4c27d68d5cee38ca617daThe Android Open Source Project * the License. You may obtain a copy of the License at 8adc854b798c1cfe3bfd4c27d68d5cee38ca617daThe Android Open Source Project * 9adc854b798c1cfe3bfd4c27d68d5cee38ca617daThe Android Open Source Project * http://www.apache.org/licenses/LICENSE-2.0 10adc854b798c1cfe3bfd4c27d68d5cee38ca617daThe Android Open Source Project * 11adc854b798c1cfe3bfd4c27d68d5cee38ca617daThe Android Open Source Project * Unless required by applicable law or agreed to in writing, software 12adc854b798c1cfe3bfd4c27d68d5cee38ca617daThe Android Open Source Project * distributed under the License is distributed on an "AS IS" BASIS, 13adc854b798c1cfe3bfd4c27d68d5cee38ca617daThe Android Open Source Project * WITHOUT WARRANTIES OR CONDITIONS OF ANY KIND, either express or implied. 14adc854b798c1cfe3bfd4c27d68d5cee38ca617daThe Android Open Source Project * See the License for the specific language governing permissions and 15adc854b798c1cfe3bfd4c27d68d5cee38ca617daThe Android Open Source Project * limitations under the License. 16adc854b798c1cfe3bfd4c27d68d5cee38ca617daThe Android Open Source Project */ 17adc854b798c1cfe3bfd4c27d68d5cee38ca617daThe Android Open Source Project 18adc854b798c1cfe3bfd4c27d68d5cee38ca617daThe Android Open Source Projectpackage java.io; 19adc854b798c1cfe3bfd4c27d68d5cee38ca617daThe Android Open Source Project 20a1603838fe9e865575c87982e32c6343740e464cElliott Hughesimport java.util.Arrays; 21a1603838fe9e865575c87982e32c6343740e464cElliott Hughes 22adc854b798c1cfe3bfd4c27d68d5cee38ca617daThe Android Open Source Project/** 23adc854b798c1cfe3bfd4c27d68d5cee38ca617daThe Android Open Source Project * Wraps an existing {@link Reader} and <em>buffers</em> the input. Expensive 24adc854b798c1cfe3bfd4c27d68d5cee38ca617daThe Android Open Source Project * interaction with the underlying reader is minimized, since most (smaller) 25adc854b798c1cfe3bfd4c27d68d5cee38ca617daThe Android Open Source Project * requests can be satisfied by accessing the buffer alone. The drawback is that 26adc854b798c1cfe3bfd4c27d68d5cee38ca617daThe Android Open Source Project * some extra space is required to hold the buffer and that copying takes place 27adc854b798c1cfe3bfd4c27d68d5cee38ca617daThe Android Open Source Project * when filling that buffer, but this is usually outweighed by the performance 28adc854b798c1cfe3bfd4c27d68d5cee38ca617daThe Android Open Source Project * benefits. 29f33eae7e84eb6d3b0f4e86b59605bb3de73009f3Elliott Hughes * 30adc854b798c1cfe3bfd4c27d68d5cee38ca617daThe Android Open Source Project * <p/>A typical application pattern for the class looks like this:<p/> 31f5597e626ecf7949d249dea08c1a2964d890ec11Jesse Wilson * 32adc854b798c1cfe3bfd4c27d68d5cee38ca617daThe Android Open Source Project * <pre> 33adc854b798c1cfe3bfd4c27d68d5cee38ca617daThe Android Open Source Project * BufferedReader buf = new BufferedReader(new FileReader("file.java")); 34adc854b798c1cfe3bfd4c27d68d5cee38ca617daThe Android Open Source Project * </pre> 35f33eae7e84eb6d3b0f4e86b59605bb3de73009f3Elliott Hughes * 36adc854b798c1cfe3bfd4c27d68d5cee38ca617daThe Android Open Source Project * @see BufferedWriter 37f5597e626ecf7949d249dea08c1a2964d890ec11Jesse Wilson * @since 1.1 38adc854b798c1cfe3bfd4c27d68d5cee38ca617daThe Android Open Source Project */ 39adc854b798c1cfe3bfd4c27d68d5cee38ca617daThe Android Open Source Projectpublic class BufferedReader extends Reader { 40adc854b798c1cfe3bfd4c27d68d5cee38ca617daThe Android Open Source Project 41adc854b798c1cfe3bfd4c27d68d5cee38ca617daThe Android Open Source Project private Reader in; 42adc854b798c1cfe3bfd4c27d68d5cee38ca617daThe Android Open Source Project 4382a2dfcd2281c2f8042fd5f09c98bea1e728530fJesse Wilson /** 4482a2dfcd2281c2f8042fd5f09c98bea1e728530fJesse Wilson * The characters that can be read and refilled in bulk. We maintain three 4582a2dfcd2281c2f8042fd5f09c98bea1e728530fJesse Wilson * indices into this buffer:<pre> 4682a2dfcd2281c2f8042fd5f09c98bea1e728530fJesse Wilson * { X X X X X X X X X X X X - - } 4782a2dfcd2281c2f8042fd5f09c98bea1e728530fJesse Wilson * ^ ^ ^ 4882a2dfcd2281c2f8042fd5f09c98bea1e728530fJesse Wilson * | | | 4982a2dfcd2281c2f8042fd5f09c98bea1e728530fJesse Wilson * mark pos end</pre> 5082a2dfcd2281c2f8042fd5f09c98bea1e728530fJesse Wilson * Pos points to the next readable character. End is one greater than the 5182a2dfcd2281c2f8042fd5f09c98bea1e728530fJesse Wilson * last readable character. When {@code pos == end}, the buffer is empty and 5282a2dfcd2281c2f8042fd5f09c98bea1e728530fJesse Wilson * must be {@link #fillBuf() filled} before characters can be read. 5382a2dfcd2281c2f8042fd5f09c98bea1e728530fJesse Wilson * 5482a2dfcd2281c2f8042fd5f09c98bea1e728530fJesse Wilson * <p>Mark is the value pos will be set to on calls to {@link #reset}. Its 5582a2dfcd2281c2f8042fd5f09c98bea1e728530fJesse Wilson * value is in the range {@code [0...pos]}. If the mark is {@code -1}, the 5682a2dfcd2281c2f8042fd5f09c98bea1e728530fJesse Wilson * buffer cannot be reset. 5782a2dfcd2281c2f8042fd5f09c98bea1e728530fJesse Wilson * 5882a2dfcd2281c2f8042fd5f09c98bea1e728530fJesse Wilson * <p>MarkLimit limits the distance between the mark and the pos. When this 5982a2dfcd2281c2f8042fd5f09c98bea1e728530fJesse Wilson * limit is exceeded, {@link #reset} is permitted (but not required) to 6082a2dfcd2281c2f8042fd5f09c98bea1e728530fJesse Wilson * throw an exception. For shorter distances, {@link #reset} shall not throw 6182a2dfcd2281c2f8042fd5f09c98bea1e728530fJesse Wilson * (unless the reader is closed). 6282a2dfcd2281c2f8042fd5f09c98bea1e728530fJesse Wilson */ 63adc854b798c1cfe3bfd4c27d68d5cee38ca617daThe Android Open Source Project private char[] buf; 64adc854b798c1cfe3bfd4c27d68d5cee38ca617daThe Android Open Source Project 6582a2dfcd2281c2f8042fd5f09c98bea1e728530fJesse Wilson private int pos; 66adc854b798c1cfe3bfd4c27d68d5cee38ca617daThe Android Open Source Project 6782a2dfcd2281c2f8042fd5f09c98bea1e728530fJesse Wilson private int end; 68adc854b798c1cfe3bfd4c27d68d5cee38ca617daThe Android Open Source Project 6982a2dfcd2281c2f8042fd5f09c98bea1e728530fJesse Wilson private int mark = -1; 70adc854b798c1cfe3bfd4c27d68d5cee38ca617daThe Android Open Source Project 7182a2dfcd2281c2f8042fd5f09c98bea1e728530fJesse Wilson private int markLimit = -1; 72adc854b798c1cfe3bfd4c27d68d5cee38ca617daThe Android Open Source Project 73adc854b798c1cfe3bfd4c27d68d5cee38ca617daThe Android Open Source Project /** 740409fa8fe9b1b3cd501931a8c25e109e6ff71be0Elliott Hughes * readLine returns a line as soon as it sees '\n' or '\r'. In the latter 750409fa8fe9b1b3cd501931a8c25e109e6ff71be0Elliott Hughes * case, there might be a following '\n' that should be treated as part of 760409fa8fe9b1b3cd501931a8c25e109e6ff71be0Elliott Hughes * the same line ending. Both readLine and all read methods are supposed 770409fa8fe9b1b3cd501931a8c25e109e6ff71be0Elliott Hughes * to skip the '\n' (and clear this field) but only readLine looks for '\r' 780409fa8fe9b1b3cd501931a8c25e109e6ff71be0Elliott Hughes * and sets it. 790409fa8fe9b1b3cd501931a8c25e109e6ff71be0Elliott Hughes */ 800409fa8fe9b1b3cd501931a8c25e109e6ff71be0Elliott Hughes private boolean lastWasCR; 810409fa8fe9b1b3cd501931a8c25e109e6ff71be0Elliott Hughes 820409fa8fe9b1b3cd501931a8c25e109e6ff71be0Elliott Hughes /** 830409fa8fe9b1b3cd501931a8c25e109e6ff71be0Elliott Hughes * We also need to keep the 'lastWasCR' state for the mark position, in case 840409fa8fe9b1b3cd501931a8c25e109e6ff71be0Elliott Hughes * we reset to there. 850409fa8fe9b1b3cd501931a8c25e109e6ff71be0Elliott Hughes */ 860409fa8fe9b1b3cd501931a8c25e109e6ff71be0Elliott Hughes private boolean markedLastWasCR; 870409fa8fe9b1b3cd501931a8c25e109e6ff71be0Elliott Hughes 880409fa8fe9b1b3cd501931a8c25e109e6ff71be0Elliott Hughes /** 89fb4616d0efbba1903b9237c0a428b59868365a69Elliott Hughes * Constructs a new {@code BufferedReader}, providing {@code in} with a buffer 90fb4616d0efbba1903b9237c0a428b59868365a69Elliott Hughes * of 8192 characters. 91fb4616d0efbba1903b9237c0a428b59868365a69Elliott Hughes * 92fb4616d0efbba1903b9237c0a428b59868365a69Elliott Hughes * @param in the {@code Reader} the buffer reads from. 93adc854b798c1cfe3bfd4c27d68d5cee38ca617daThe Android Open Source Project */ 94adc854b798c1cfe3bfd4c27d68d5cee38ca617daThe Android Open Source Project public BufferedReader(Reader in) { 95fb4616d0efbba1903b9237c0a428b59868365a69Elliott Hughes this(in, 8192); 96adc854b798c1cfe3bfd4c27d68d5cee38ca617daThe Android Open Source Project } 97adc854b798c1cfe3bfd4c27d68d5cee38ca617daThe Android Open Source Project 98adc854b798c1cfe3bfd4c27d68d5cee38ca617daThe Android Open Source Project /** 99fb4616d0efbba1903b9237c0a428b59868365a69Elliott Hughes * Constructs a new {@code BufferedReader}, providing {@code in} with {@code size} characters 100fb4616d0efbba1903b9237c0a428b59868365a69Elliott Hughes * of buffer. 101fb4616d0efbba1903b9237c0a428b59868365a69Elliott Hughes * 102fb4616d0efbba1903b9237c0a428b59868365a69Elliott Hughes * @param in the {@code InputStream} the buffer reads from. 103fb4616d0efbba1903b9237c0a428b59868365a69Elliott Hughes * @param size the size of buffer in characters. 104fb4616d0efbba1903b9237c0a428b59868365a69Elliott Hughes * @throws IllegalArgumentException if {@code size <= 0}. 105adc854b798c1cfe3bfd4c27d68d5cee38ca617daThe Android Open Source Project */ 106adc854b798c1cfe3bfd4c27d68d5cee38ca617daThe Android Open Source Project public BufferedReader(Reader in, int size) { 107adc854b798c1cfe3bfd4c27d68d5cee38ca617daThe Android Open Source Project super(in); 108adc854b798c1cfe3bfd4c27d68d5cee38ca617daThe Android Open Source Project if (size <= 0) { 109b1396870f92135aa140bd2b86221768dea5bc11dElliott Hughes throw new IllegalArgumentException("size <= 0"); 110adc854b798c1cfe3bfd4c27d68d5cee38ca617daThe Android Open Source Project } 111adc854b798c1cfe3bfd4c27d68d5cee38ca617daThe Android Open Source Project this.in = in; 112adc854b798c1cfe3bfd4c27d68d5cee38ca617daThe Android Open Source Project buf = new char[size]; 113adc854b798c1cfe3bfd4c27d68d5cee38ca617daThe Android Open Source Project } 114adc854b798c1cfe3bfd4c27d68d5cee38ca617daThe Android Open Source Project 115adc854b798c1cfe3bfd4c27d68d5cee38ca617daThe Android Open Source Project /** 116adc854b798c1cfe3bfd4c27d68d5cee38ca617daThe Android Open Source Project * Closes this reader. This implementation closes the buffered source reader 117adc854b798c1cfe3bfd4c27d68d5cee38ca617daThe Android Open Source Project * and releases the buffer. Nothing is done if this reader has already been 118adc854b798c1cfe3bfd4c27d68d5cee38ca617daThe Android Open Source Project * closed. 119f33eae7e84eb6d3b0f4e86b59605bb3de73009f3Elliott Hughes * 120adc854b798c1cfe3bfd4c27d68d5cee38ca617daThe Android Open Source Project * @throws IOException 121adc854b798c1cfe3bfd4c27d68d5cee38ca617daThe Android Open Source Project * if an error occurs while closing this reader. 122adc854b798c1cfe3bfd4c27d68d5cee38ca617daThe Android Open Source Project */ 123adc854b798c1cfe3bfd4c27d68d5cee38ca617daThe Android Open Source Project @Override 124adc854b798c1cfe3bfd4c27d68d5cee38ca617daThe Android Open Source Project public void close() throws IOException { 125adc854b798c1cfe3bfd4c27d68d5cee38ca617daThe Android Open Source Project synchronized (lock) { 126adc854b798c1cfe3bfd4c27d68d5cee38ca617daThe Android Open Source Project if (!isClosed()) { 127adc854b798c1cfe3bfd4c27d68d5cee38ca617daThe Android Open Source Project in.close(); 128adc854b798c1cfe3bfd4c27d68d5cee38ca617daThe Android Open Source Project buf = null; 129adc854b798c1cfe3bfd4c27d68d5cee38ca617daThe Android Open Source Project } 130adc854b798c1cfe3bfd4c27d68d5cee38ca617daThe Android Open Source Project } 131adc854b798c1cfe3bfd4c27d68d5cee38ca617daThe Android Open Source Project } 132adc854b798c1cfe3bfd4c27d68d5cee38ca617daThe Android Open Source Project 13382a2dfcd2281c2f8042fd5f09c98bea1e728530fJesse Wilson /** 13482a2dfcd2281c2f8042fd5f09c98bea1e728530fJesse Wilson * Populates the buffer with data. It is an error to call this method when 13582a2dfcd2281c2f8042fd5f09c98bea1e728530fJesse Wilson * the buffer still contains data; ie. if {@code pos < end}. 13682a2dfcd2281c2f8042fd5f09c98bea1e728530fJesse Wilson * 137fd1bbd5cb70830aaf6639dafc240c4d17181ef75Jesse Wilson * @return the number of chars read into the buffer, or -1 if the end of the 13882a2dfcd2281c2f8042fd5f09c98bea1e728530fJesse Wilson * source stream has been reached. 13982a2dfcd2281c2f8042fd5f09c98bea1e728530fJesse Wilson */ 14082a2dfcd2281c2f8042fd5f09c98bea1e728530fJesse Wilson private int fillBuf() throws IOException { 14182a2dfcd2281c2f8042fd5f09c98bea1e728530fJesse Wilson // assert(pos == end); 14282a2dfcd2281c2f8042fd5f09c98bea1e728530fJesse Wilson 14382a2dfcd2281c2f8042fd5f09c98bea1e728530fJesse Wilson if (mark == -1 || (pos - mark >= markLimit)) { 14482a2dfcd2281c2f8042fd5f09c98bea1e728530fJesse Wilson /* mark isn't set or has exceeded its limit. use the whole buffer */ 145adc854b798c1cfe3bfd4c27d68d5cee38ca617daThe Android Open Source Project int result = in.read(buf, 0, buf.length); 146adc854b798c1cfe3bfd4c27d68d5cee38ca617daThe Android Open Source Project if (result > 0) { 14782a2dfcd2281c2f8042fd5f09c98bea1e728530fJesse Wilson mark = -1; 148adc854b798c1cfe3bfd4c27d68d5cee38ca617daThe Android Open Source Project pos = 0; 14982a2dfcd2281c2f8042fd5f09c98bea1e728530fJesse Wilson end = result; 150adc854b798c1cfe3bfd4c27d68d5cee38ca617daThe Android Open Source Project } 151adc854b798c1cfe3bfd4c27d68d5cee38ca617daThe Android Open Source Project return result; 152adc854b798c1cfe3bfd4c27d68d5cee38ca617daThe Android Open Source Project } 15382a2dfcd2281c2f8042fd5f09c98bea1e728530fJesse Wilson 15482a2dfcd2281c2f8042fd5f09c98bea1e728530fJesse Wilson if (mark == 0 && markLimit > buf.length) { 15582a2dfcd2281c2f8042fd5f09c98bea1e728530fJesse Wilson /* the only way to make room when mark=0 is by growing the buffer */ 156adc854b798c1cfe3bfd4c27d68d5cee38ca617daThe Android Open Source Project int newLength = buf.length * 2; 15782a2dfcd2281c2f8042fd5f09c98bea1e728530fJesse Wilson if (newLength > markLimit) { 15882a2dfcd2281c2f8042fd5f09c98bea1e728530fJesse Wilson newLength = markLimit; 159adc854b798c1cfe3bfd4c27d68d5cee38ca617daThe Android Open Source Project } 160adc854b798c1cfe3bfd4c27d68d5cee38ca617daThe Android Open Source Project char[] newbuf = new char[newLength]; 161adc854b798c1cfe3bfd4c27d68d5cee38ca617daThe Android Open Source Project System.arraycopy(buf, 0, newbuf, 0, buf.length); 162adc854b798c1cfe3bfd4c27d68d5cee38ca617daThe Android Open Source Project buf = newbuf; 16382a2dfcd2281c2f8042fd5f09c98bea1e728530fJesse Wilson } else if (mark > 0) { 16482a2dfcd2281c2f8042fd5f09c98bea1e728530fJesse Wilson /* make room by shifting the buffered data to left mark positions */ 16582a2dfcd2281c2f8042fd5f09c98bea1e728530fJesse Wilson System.arraycopy(buf, mark, buf, 0, buf.length - mark); 16682a2dfcd2281c2f8042fd5f09c98bea1e728530fJesse Wilson pos -= mark; 16782a2dfcd2281c2f8042fd5f09c98bea1e728530fJesse Wilson end -= mark; 16882a2dfcd2281c2f8042fd5f09c98bea1e728530fJesse Wilson mark = 0; 169adc854b798c1cfe3bfd4c27d68d5cee38ca617daThe Android Open Source Project } 170adc854b798c1cfe3bfd4c27d68d5cee38ca617daThe Android Open Source Project 171adc854b798c1cfe3bfd4c27d68d5cee38ca617daThe Android Open Source Project /* Set the new position and mark position */ 17282a2dfcd2281c2f8042fd5f09c98bea1e728530fJesse Wilson int count = in.read(buf, pos, buf.length - pos); 17382a2dfcd2281c2f8042fd5f09c98bea1e728530fJesse Wilson if (count != -1) { 17482a2dfcd2281c2f8042fd5f09c98bea1e728530fJesse Wilson end += count; 17582a2dfcd2281c2f8042fd5f09c98bea1e728530fJesse Wilson } 17682a2dfcd2281c2f8042fd5f09c98bea1e728530fJesse Wilson return count; 177adc854b798c1cfe3bfd4c27d68d5cee38ca617daThe Android Open Source Project } 178adc854b798c1cfe3bfd4c27d68d5cee38ca617daThe Android Open Source Project 179adc854b798c1cfe3bfd4c27d68d5cee38ca617daThe Android Open Source Project /** 180adc854b798c1cfe3bfd4c27d68d5cee38ca617daThe Android Open Source Project * Indicates whether or not this reader is closed. 181f33eae7e84eb6d3b0f4e86b59605bb3de73009f3Elliott Hughes * 182adc854b798c1cfe3bfd4c27d68d5cee38ca617daThe Android Open Source Project * @return {@code true} if this reader is closed, {@code false} 183adc854b798c1cfe3bfd4c27d68d5cee38ca617daThe Android Open Source Project * otherwise. 184adc854b798c1cfe3bfd4c27d68d5cee38ca617daThe Android Open Source Project */ 185adc854b798c1cfe3bfd4c27d68d5cee38ca617daThe Android Open Source Project private boolean isClosed() { 186adc854b798c1cfe3bfd4c27d68d5cee38ca617daThe Android Open Source Project return buf == null; 187adc854b798c1cfe3bfd4c27d68d5cee38ca617daThe Android Open Source Project } 188adc854b798c1cfe3bfd4c27d68d5cee38ca617daThe Android Open Source Project 189adc854b798c1cfe3bfd4c27d68d5cee38ca617daThe Android Open Source Project /** 19082a2dfcd2281c2f8042fd5f09c98bea1e728530fJesse Wilson * Sets a mark position in this reader. The parameter {@code markLimit} 191adc854b798c1cfe3bfd4c27d68d5cee38ca617daThe Android Open Source Project * indicates how many characters can be read before the mark is invalidated. 192adc854b798c1cfe3bfd4c27d68d5cee38ca617daThe Android Open Source Project * Calling {@code reset()} will reposition the reader back to the marked 19382a2dfcd2281c2f8042fd5f09c98bea1e728530fJesse Wilson * position if {@code markLimit} has not been surpassed. 194f33eae7e84eb6d3b0f4e86b59605bb3de73009f3Elliott Hughes * 19582a2dfcd2281c2f8042fd5f09c98bea1e728530fJesse Wilson * @param markLimit 196adc854b798c1cfe3bfd4c27d68d5cee38ca617daThe Android Open Source Project * the number of characters that can be read before the mark is 197adc854b798c1cfe3bfd4c27d68d5cee38ca617daThe Android Open Source Project * invalidated. 198adc854b798c1cfe3bfd4c27d68d5cee38ca617daThe Android Open Source Project * @throws IllegalArgumentException 19982a2dfcd2281c2f8042fd5f09c98bea1e728530fJesse Wilson * if {@code markLimit < 0}. 200adc854b798c1cfe3bfd4c27d68d5cee38ca617daThe Android Open Source Project * @throws IOException 201adc854b798c1cfe3bfd4c27d68d5cee38ca617daThe Android Open Source Project * if an error occurs while setting a mark in this reader. 202adc854b798c1cfe3bfd4c27d68d5cee38ca617daThe Android Open Source Project * @see #markSupported() 203adc854b798c1cfe3bfd4c27d68d5cee38ca617daThe Android Open Source Project * @see #reset() 204adc854b798c1cfe3bfd4c27d68d5cee38ca617daThe Android Open Source Project */ 205adc854b798c1cfe3bfd4c27d68d5cee38ca617daThe Android Open Source Project @Override 20682a2dfcd2281c2f8042fd5f09c98bea1e728530fJesse Wilson public void mark(int markLimit) throws IOException { 20782a2dfcd2281c2f8042fd5f09c98bea1e728530fJesse Wilson if (markLimit < 0) { 208cff1616012dc0d56c2da9af2b9b1183e76c7e044Elliott Hughes throw new IllegalArgumentException("markLimit < 0:" + markLimit); 209adc854b798c1cfe3bfd4c27d68d5cee38ca617daThe Android Open Source Project } 210adc854b798c1cfe3bfd4c27d68d5cee38ca617daThe Android Open Source Project synchronized (lock) { 211b1396870f92135aa140bd2b86221768dea5bc11dElliott Hughes checkNotClosed(); 21282a2dfcd2281c2f8042fd5f09c98bea1e728530fJesse Wilson this.markLimit = markLimit; 2130409fa8fe9b1b3cd501931a8c25e109e6ff71be0Elliott Hughes this.mark = pos; 2140409fa8fe9b1b3cd501931a8c25e109e6ff71be0Elliott Hughes this.markedLastWasCR = lastWasCR; 215adc854b798c1cfe3bfd4c27d68d5cee38ca617daThe Android Open Source Project } 216adc854b798c1cfe3bfd4c27d68d5cee38ca617daThe Android Open Source Project } 217adc854b798c1cfe3bfd4c27d68d5cee38ca617daThe Android Open Source Project 218b1396870f92135aa140bd2b86221768dea5bc11dElliott Hughes private void checkNotClosed() throws IOException { 219b1396870f92135aa140bd2b86221768dea5bc11dElliott Hughes if (isClosed()) { 220b1396870f92135aa140bd2b86221768dea5bc11dElliott Hughes throw new IOException("BufferedReader is closed"); 221b1396870f92135aa140bd2b86221768dea5bc11dElliott Hughes } 222b1396870f92135aa140bd2b86221768dea5bc11dElliott Hughes } 223b1396870f92135aa140bd2b86221768dea5bc11dElliott Hughes 224adc854b798c1cfe3bfd4c27d68d5cee38ca617daThe Android Open Source Project /** 225adc854b798c1cfe3bfd4c27d68d5cee38ca617daThe Android Open Source Project * Indicates whether this reader supports the {@code mark()} and 226adc854b798c1cfe3bfd4c27d68d5cee38ca617daThe Android Open Source Project * {@code reset()} methods. This implementation returns {@code true}. 227f33eae7e84eb6d3b0f4e86b59605bb3de73009f3Elliott Hughes * 228adc854b798c1cfe3bfd4c27d68d5cee38ca617daThe Android Open Source Project * @return {@code true} for {@code BufferedReader}. 229adc854b798c1cfe3bfd4c27d68d5cee38ca617daThe Android Open Source Project * @see #mark(int) 230adc854b798c1cfe3bfd4c27d68d5cee38ca617daThe Android Open Source Project * @see #reset() 231adc854b798c1cfe3bfd4c27d68d5cee38ca617daThe Android Open Source Project */ 232adc854b798c1cfe3bfd4c27d68d5cee38ca617daThe Android Open Source Project @Override 233adc854b798c1cfe3bfd4c27d68d5cee38ca617daThe Android Open Source Project public boolean markSupported() { 234adc854b798c1cfe3bfd4c27d68d5cee38ca617daThe Android Open Source Project return true; 235adc854b798c1cfe3bfd4c27d68d5cee38ca617daThe Android Open Source Project } 236adc854b798c1cfe3bfd4c27d68d5cee38ca617daThe Android Open Source Project 237adc854b798c1cfe3bfd4c27d68d5cee38ca617daThe Android Open Source Project /** 238adc854b798c1cfe3bfd4c27d68d5cee38ca617daThe Android Open Source Project * Reads a single character from this reader and returns it with the two 239adc854b798c1cfe3bfd4c27d68d5cee38ca617daThe Android Open Source Project * higher-order bytes set to 0. If possible, BufferedReader returns a 240adc854b798c1cfe3bfd4c27d68d5cee38ca617daThe Android Open Source Project * character from the buffer. If there are no characters available in the 241adc854b798c1cfe3bfd4c27d68d5cee38ca617daThe Android Open Source Project * buffer, it fills the buffer and then returns a character. It returns -1 242adc854b798c1cfe3bfd4c27d68d5cee38ca617daThe Android Open Source Project * if there are no more characters in the source reader. 243f5597e626ecf7949d249dea08c1a2964d890ec11Jesse Wilson * 244adc854b798c1cfe3bfd4c27d68d5cee38ca617daThe Android Open Source Project * @return the character read or -1 if the end of the source reader has been 245adc854b798c1cfe3bfd4c27d68d5cee38ca617daThe Android Open Source Project * reached. 246adc854b798c1cfe3bfd4c27d68d5cee38ca617daThe Android Open Source Project * @throws IOException 247adc854b798c1cfe3bfd4c27d68d5cee38ca617daThe Android Open Source Project * if this reader is closed or some other I/O error occurs. 248adc854b798c1cfe3bfd4c27d68d5cee38ca617daThe Android Open Source Project */ 249adc854b798c1cfe3bfd4c27d68d5cee38ca617daThe Android Open Source Project @Override 250adc854b798c1cfe3bfd4c27d68d5cee38ca617daThe Android Open Source Project public int read() throws IOException { 251adc854b798c1cfe3bfd4c27d68d5cee38ca617daThe Android Open Source Project synchronized (lock) { 252b1396870f92135aa140bd2b86221768dea5bc11dElliott Hughes checkNotClosed(); 2530409fa8fe9b1b3cd501931a8c25e109e6ff71be0Elliott Hughes int ch = readChar(); 2540409fa8fe9b1b3cd501931a8c25e109e6ff71be0Elliott Hughes if (lastWasCR && ch == '\n') { 2550409fa8fe9b1b3cd501931a8c25e109e6ff71be0Elliott Hughes ch = readChar(); 256adc854b798c1cfe3bfd4c27d68d5cee38ca617daThe Android Open Source Project } 2570409fa8fe9b1b3cd501931a8c25e109e6ff71be0Elliott Hughes lastWasCR = false; 2580409fa8fe9b1b3cd501931a8c25e109e6ff71be0Elliott Hughes return ch; 2590409fa8fe9b1b3cd501931a8c25e109e6ff71be0Elliott Hughes } 2600409fa8fe9b1b3cd501931a8c25e109e6ff71be0Elliott Hughes } 2610409fa8fe9b1b3cd501931a8c25e109e6ff71be0Elliott Hughes 2620409fa8fe9b1b3cd501931a8c25e109e6ff71be0Elliott Hughes private int readChar() throws IOException { 2630409fa8fe9b1b3cd501931a8c25e109e6ff71be0Elliott Hughes if (pos < end || fillBuf() != -1) { 2640409fa8fe9b1b3cd501931a8c25e109e6ff71be0Elliott Hughes return buf[pos++]; 265adc854b798c1cfe3bfd4c27d68d5cee38ca617daThe Android Open Source Project } 2660409fa8fe9b1b3cd501931a8c25e109e6ff71be0Elliott Hughes return -1; 267adc854b798c1cfe3bfd4c27d68d5cee38ca617daThe Android Open Source Project } 268adc854b798c1cfe3bfd4c27d68d5cee38ca617daThe Android Open Source Project 269adc854b798c1cfe3bfd4c27d68d5cee38ca617daThe Android Open Source Project /** 270325ff8c68ed5e530e9e1d487b9e2e6d8f8e2bd37Elliott Hughes * Reads up to {@code length} characters from this reader and stores them 271adc854b798c1cfe3bfd4c27d68d5cee38ca617daThe Android Open Source Project * at {@code offset} in the character array {@code buffer}. Returns the 272adc854b798c1cfe3bfd4c27d68d5cee38ca617daThe Android Open Source Project * number of characters actually read or -1 if the end of the source reader 273adc854b798c1cfe3bfd4c27d68d5cee38ca617daThe Android Open Source Project * has been reached. If all the buffered characters have been used, a mark 274adc854b798c1cfe3bfd4c27d68d5cee38ca617daThe Android Open Source Project * has not been set and the requested number of characters is larger than 275adc854b798c1cfe3bfd4c27d68d5cee38ca617daThe Android Open Source Project * this readers buffer size, BufferedReader bypasses the buffer and simply 276adc854b798c1cfe3bfd4c27d68d5cee38ca617daThe Android Open Source Project * places the results directly into {@code buffer}. 277f33eae7e84eb6d3b0f4e86b59605bb3de73009f3Elliott Hughes * 278adc854b798c1cfe3bfd4c27d68d5cee38ca617daThe Android Open Source Project * @throws IndexOutOfBoundsException 279325ff8c68ed5e530e9e1d487b9e2e6d8f8e2bd37Elliott Hughes * if {@code offset < 0 || length < 0 || offset + length > buffer.length}. 280adc854b798c1cfe3bfd4c27d68d5cee38ca617daThe Android Open Source Project * @throws IOException 281adc854b798c1cfe3bfd4c27d68d5cee38ca617daThe Android Open Source Project * if this reader is closed or some other I/O error occurs. 282adc854b798c1cfe3bfd4c27d68d5cee38ca617daThe Android Open Source Project */ 283adc854b798c1cfe3bfd4c27d68d5cee38ca617daThe Android Open Source Project @Override 284adc854b798c1cfe3bfd4c27d68d5cee38ca617daThe Android Open Source Project public int read(char[] buffer, int offset, int length) throws IOException { 285adc854b798c1cfe3bfd4c27d68d5cee38ca617daThe Android Open Source Project synchronized (lock) { 286b1396870f92135aa140bd2b86221768dea5bc11dElliott Hughes checkNotClosed(); 287a1603838fe9e865575c87982e32c6343740e464cElliott Hughes Arrays.checkOffsetAndCount(buffer.length, offset, length); 2880409fa8fe9b1b3cd501931a8c25e109e6ff71be0Elliott Hughes if (length == 0) { 2890409fa8fe9b1b3cd501931a8c25e109e6ff71be0Elliott Hughes return 0; 2900409fa8fe9b1b3cd501931a8c25e109e6ff71be0Elliott Hughes } 2910409fa8fe9b1b3cd501931a8c25e109e6ff71be0Elliott Hughes 2920409fa8fe9b1b3cd501931a8c25e109e6ff71be0Elliott Hughes maybeSwallowLF(); 2930409fa8fe9b1b3cd501931a8c25e109e6ff71be0Elliott Hughes 29482a2dfcd2281c2f8042fd5f09c98bea1e728530fJesse Wilson int outstanding = length; 29582a2dfcd2281c2f8042fd5f09c98bea1e728530fJesse Wilson while (outstanding > 0) { 2960409fa8fe9b1b3cd501931a8c25e109e6ff71be0Elliott Hughes // If there are chars in the buffer, grab those first. 29782a2dfcd2281c2f8042fd5f09c98bea1e728530fJesse Wilson int available = end - pos; 29882a2dfcd2281c2f8042fd5f09c98bea1e728530fJesse Wilson if (available > 0) { 29982a2dfcd2281c2f8042fd5f09c98bea1e728530fJesse Wilson int count = available >= outstanding ? outstanding : available; 30082a2dfcd2281c2f8042fd5f09c98bea1e728530fJesse Wilson System.arraycopy(buf, pos, buffer, offset, count); 30182a2dfcd2281c2f8042fd5f09c98bea1e728530fJesse Wilson pos += count; 30282a2dfcd2281c2f8042fd5f09c98bea1e728530fJesse Wilson offset += count; 30382a2dfcd2281c2f8042fd5f09c98bea1e728530fJesse Wilson outstanding -= count; 304adc854b798c1cfe3bfd4c27d68d5cee38ca617daThe Android Open Source Project } 305adc854b798c1cfe3bfd4c27d68d5cee38ca617daThe Android Open Source Project 306adc854b798c1cfe3bfd4c27d68d5cee38ca617daThe Android Open Source Project /* 30782a2dfcd2281c2f8042fd5f09c98bea1e728530fJesse Wilson * Before attempting to read from the underlying stream, make 30882a2dfcd2281c2f8042fd5f09c98bea1e728530fJesse Wilson * sure we really, really want to. We won't bother if we're 309fd1bbd5cb70830aaf6639dafc240c4d17181ef75Jesse Wilson * done, or if we've already got some chars and reading from the 31082a2dfcd2281c2f8042fd5f09c98bea1e728530fJesse Wilson * underlying stream would block. 311adc854b798c1cfe3bfd4c27d68d5cee38ca617daThe Android Open Source Project */ 31282a2dfcd2281c2f8042fd5f09c98bea1e728530fJesse Wilson if (outstanding == 0 || (outstanding < length && !in.ready())) { 31382a2dfcd2281c2f8042fd5f09c98bea1e728530fJesse Wilson break; 314adc854b798c1cfe3bfd4c27d68d5cee38ca617daThe Android Open Source Project } 31582a2dfcd2281c2f8042fd5f09c98bea1e728530fJesse Wilson 31682a2dfcd2281c2f8042fd5f09c98bea1e728530fJesse Wilson // assert(pos == end); 31782a2dfcd2281c2f8042fd5f09c98bea1e728530fJesse Wilson 31882a2dfcd2281c2f8042fd5f09c98bea1e728530fJesse Wilson /* 31982a2dfcd2281c2f8042fd5f09c98bea1e728530fJesse Wilson * If we're unmarked and the requested size is greater than our 320fd1bbd5cb70830aaf6639dafc240c4d17181ef75Jesse Wilson * buffer, read the chars directly into the caller's buffer. We 32182a2dfcd2281c2f8042fd5f09c98bea1e728530fJesse Wilson * don't read into smaller buffers because that could result in 32282a2dfcd2281c2f8042fd5f09c98bea1e728530fJesse Wilson * a many reads. 32382a2dfcd2281c2f8042fd5f09c98bea1e728530fJesse Wilson */ 324344110141de805108972f0ad24f16de59ba2aa32Elliott Hughes if ((mark == -1 || (pos - mark >= markLimit)) && outstanding >= buf.length) { 32582a2dfcd2281c2f8042fd5f09c98bea1e728530fJesse Wilson int count = in.read(buffer, offset, outstanding); 32682a2dfcd2281c2f8042fd5f09c98bea1e728530fJesse Wilson if (count > 0) { 32782a2dfcd2281c2f8042fd5f09c98bea1e728530fJesse Wilson outstanding -= count; 32882a2dfcd2281c2f8042fd5f09c98bea1e728530fJesse Wilson mark = -1; 32982a2dfcd2281c2f8042fd5f09c98bea1e728530fJesse Wilson } 33082a2dfcd2281c2f8042fd5f09c98bea1e728530fJesse Wilson break; // assume the source stream gave us all that it could 331adc854b798c1cfe3bfd4c27d68d5cee38ca617daThe Android Open Source Project } 33282a2dfcd2281c2f8042fd5f09c98bea1e728530fJesse Wilson 33382a2dfcd2281c2f8042fd5f09c98bea1e728530fJesse Wilson if (fillBuf() == -1) { 33482a2dfcd2281c2f8042fd5f09c98bea1e728530fJesse Wilson break; // source is exhausted 335adc854b798c1cfe3bfd4c27d68d5cee38ca617daThe Android Open Source Project } 336adc854b798c1cfe3bfd4c27d68d5cee38ca617daThe Android Open Source Project } 33782a2dfcd2281c2f8042fd5f09c98bea1e728530fJesse Wilson 33882a2dfcd2281c2f8042fd5f09c98bea1e728530fJesse Wilson int count = length - outstanding; 3390409fa8fe9b1b3cd501931a8c25e109e6ff71be0Elliott Hughes if (count > 0) { 3400409fa8fe9b1b3cd501931a8c25e109e6ff71be0Elliott Hughes return count; 3410409fa8fe9b1b3cd501931a8c25e109e6ff71be0Elliott Hughes } 3420409fa8fe9b1b3cd501931a8c25e109e6ff71be0Elliott Hughes return -1; 343adc854b798c1cfe3bfd4c27d68d5cee38ca617daThe Android Open Source Project } 344adc854b798c1cfe3bfd4c27d68d5cee38ca617daThe Android Open Source Project } 345adc854b798c1cfe3bfd4c27d68d5cee38ca617daThe Android Open Source Project 346adc854b798c1cfe3bfd4c27d68d5cee38ca617daThe Android Open Source Project /** 34755392539fea537abfb6581b474918f9d611fba27Jesse Wilson * Peeks at the next input character, refilling the buffer if necessary. If 34855392539fea537abfb6581b474918f9d611fba27Jesse Wilson * this character is a newline character ("\n"), it is discarded. 34955392539fea537abfb6581b474918f9d611fba27Jesse Wilson */ 35055392539fea537abfb6581b474918f9d611fba27Jesse Wilson final void chompNewline() throws IOException { 3510409fa8fe9b1b3cd501931a8c25e109e6ff71be0Elliott Hughes if ((pos != end || fillBuf() != -1) && buf[pos] == '\n') { 3520409fa8fe9b1b3cd501931a8c25e109e6ff71be0Elliott Hughes ++pos; 3530409fa8fe9b1b3cd501931a8c25e109e6ff71be0Elliott Hughes } 3540409fa8fe9b1b3cd501931a8c25e109e6ff71be0Elliott Hughes } 3550409fa8fe9b1b3cd501931a8c25e109e6ff71be0Elliott Hughes 3560409fa8fe9b1b3cd501931a8c25e109e6ff71be0Elliott Hughes // If the last character was CR and the next character is LF, skip it. 3570409fa8fe9b1b3cd501931a8c25e109e6ff71be0Elliott Hughes private void maybeSwallowLF() throws IOException { 3580409fa8fe9b1b3cd501931a8c25e109e6ff71be0Elliott Hughes if (lastWasCR) { 3590409fa8fe9b1b3cd501931a8c25e109e6ff71be0Elliott Hughes chompNewline(); 3600409fa8fe9b1b3cd501931a8c25e109e6ff71be0Elliott Hughes lastWasCR = false; 36155392539fea537abfb6581b474918f9d611fba27Jesse Wilson } 36255392539fea537abfb6581b474918f9d611fba27Jesse Wilson } 36355392539fea537abfb6581b474918f9d611fba27Jesse Wilson 36455392539fea537abfb6581b474918f9d611fba27Jesse Wilson /** 365adc854b798c1cfe3bfd4c27d68d5cee38ca617daThe Android Open Source Project * Returns the next line of text available from this reader. A line is 366adc854b798c1cfe3bfd4c27d68d5cee38ca617daThe Android Open Source Project * represented by zero or more characters followed by {@code '\n'}, 367adc854b798c1cfe3bfd4c27d68d5cee38ca617daThe Android Open Source Project * {@code '\r'}, {@code "\r\n"} or the end of the reader. The string does 368a389b4a499f40379b0b204d7ba1c2057663d95c0Jesse Wilson * not include the newline sequence. 369f33eae7e84eb6d3b0f4e86b59605bb3de73009f3Elliott Hughes * 370adc854b798c1cfe3bfd4c27d68d5cee38ca617daThe Android Open Source Project * @return the contents of the line or {@code null} if no characters were 371adc854b798c1cfe3bfd4c27d68d5cee38ca617daThe Android Open Source Project * read before the end of the reader has been reached. 372adc854b798c1cfe3bfd4c27d68d5cee38ca617daThe Android Open Source Project * @throws IOException 373adc854b798c1cfe3bfd4c27d68d5cee38ca617daThe Android Open Source Project * if this reader is closed or some other I/O error occurs. 374adc854b798c1cfe3bfd4c27d68d5cee38ca617daThe Android Open Source Project */ 375adc854b798c1cfe3bfd4c27d68d5cee38ca617daThe Android Open Source Project public String readLine() throws IOException { 376adc854b798c1cfe3bfd4c27d68d5cee38ca617daThe Android Open Source Project synchronized (lock) { 377b1396870f92135aa140bd2b86221768dea5bc11dElliott Hughes checkNotClosed(); 3780409fa8fe9b1b3cd501931a8c25e109e6ff71be0Elliott Hughes 3790409fa8fe9b1b3cd501931a8c25e109e6ff71be0Elliott Hughes maybeSwallowLF(); 3800409fa8fe9b1b3cd501931a8c25e109e6ff71be0Elliott Hughes 3810409fa8fe9b1b3cd501931a8c25e109e6ff71be0Elliott Hughes // Do we have a whole line in the buffer? 3820409fa8fe9b1b3cd501931a8c25e109e6ff71be0Elliott Hughes for (int i = pos; i < end; ++i) { 3830409fa8fe9b1b3cd501931a8c25e109e6ff71be0Elliott Hughes char ch = buf[i]; 3840409fa8fe9b1b3cd501931a8c25e109e6ff71be0Elliott Hughes if (ch == '\n' || ch == '\r') { 3850409fa8fe9b1b3cd501931a8c25e109e6ff71be0Elliott Hughes String line = new String(buf, pos, i - pos); 3860409fa8fe9b1b3cd501931a8c25e109e6ff71be0Elliott Hughes pos = i + 1; 3870409fa8fe9b1b3cd501931a8c25e109e6ff71be0Elliott Hughes lastWasCR = (ch == '\r'); 3880409fa8fe9b1b3cd501931a8c25e109e6ff71be0Elliott Hughes return line; 389adc854b798c1cfe3bfd4c27d68d5cee38ca617daThe Android Open Source Project } 390adc854b798c1cfe3bfd4c27d68d5cee38ca617daThe Android Open Source Project } 391adc854b798c1cfe3bfd4c27d68d5cee38ca617daThe Android Open Source Project 3920409fa8fe9b1b3cd501931a8c25e109e6ff71be0Elliott Hughes // Accumulate buffers in a StringBuilder until we've read a whole line. 3930409fa8fe9b1b3cd501931a8c25e109e6ff71be0Elliott Hughes StringBuilder result = new StringBuilder(end - pos + 80); 39482a2dfcd2281c2f8042fd5f09c98bea1e728530fJesse Wilson result.append(buf, pos, end - pos); 395adc854b798c1cfe3bfd4c27d68d5cee38ca617daThe Android Open Source Project while (true) { 39682a2dfcd2281c2f8042fd5f09c98bea1e728530fJesse Wilson pos = end; 39782a2dfcd2281c2f8042fd5f09c98bea1e728530fJesse Wilson if (fillBuf() == -1) { 3980409fa8fe9b1b3cd501931a8c25e109e6ff71be0Elliott Hughes // If there's no more input, return what we've read so far, if anything. 3990409fa8fe9b1b3cd501931a8c25e109e6ff71be0Elliott Hughes return (result.length() > 0) ? result.toString() : null; 400adc854b798c1cfe3bfd4c27d68d5cee38ca617daThe Android Open Source Project } 4010409fa8fe9b1b3cd501931a8c25e109e6ff71be0Elliott Hughes 4020409fa8fe9b1b3cd501931a8c25e109e6ff71be0Elliott Hughes // Do we have a whole line in the buffer now? 4030409fa8fe9b1b3cd501931a8c25e109e6ff71be0Elliott Hughes for (int i = pos; i < end; ++i) { 4040409fa8fe9b1b3cd501931a8c25e109e6ff71be0Elliott Hughes char ch = buf[i]; 4050409fa8fe9b1b3cd501931a8c25e109e6ff71be0Elliott Hughes if (ch == '\n' || ch == '\r') { 4060409fa8fe9b1b3cd501931a8c25e109e6ff71be0Elliott Hughes result.append(buf, pos, i - pos); 4070409fa8fe9b1b3cd501931a8c25e109e6ff71be0Elliott Hughes pos = i + 1; 4080409fa8fe9b1b3cd501931a8c25e109e6ff71be0Elliott Hughes lastWasCR = (ch == '\r'); 409adc854b798c1cfe3bfd4c27d68d5cee38ca617daThe Android Open Source Project return result.toString(); 410adc854b798c1cfe3bfd4c27d68d5cee38ca617daThe Android Open Source Project } 411adc854b798c1cfe3bfd4c27d68d5cee38ca617daThe Android Open Source Project } 4120409fa8fe9b1b3cd501931a8c25e109e6ff71be0Elliott Hughes 4130409fa8fe9b1b3cd501931a8c25e109e6ff71be0Elliott Hughes // Add this whole buffer to the line-in-progress and try again... 4140409fa8fe9b1b3cd501931a8c25e109e6ff71be0Elliott Hughes result.append(buf, pos, end - pos); 415adc854b798c1cfe3bfd4c27d68d5cee38ca617daThe Android Open Source Project } 416adc854b798c1cfe3bfd4c27d68d5cee38ca617daThe Android Open Source Project } 417adc854b798c1cfe3bfd4c27d68d5cee38ca617daThe Android Open Source Project } 418adc854b798c1cfe3bfd4c27d68d5cee38ca617daThe Android Open Source Project 419adc854b798c1cfe3bfd4c27d68d5cee38ca617daThe Android Open Source Project /** 420adc854b798c1cfe3bfd4c27d68d5cee38ca617daThe Android Open Source Project * Indicates whether this reader is ready to be read without blocking. 421f5597e626ecf7949d249dea08c1a2964d890ec11Jesse Wilson * 422adc854b798c1cfe3bfd4c27d68d5cee38ca617daThe Android Open Source Project * @return {@code true} if this reader will not block when {@code read} is 423adc854b798c1cfe3bfd4c27d68d5cee38ca617daThe Android Open Source Project * called, {@code false} if unknown or blocking will occur. 424adc854b798c1cfe3bfd4c27d68d5cee38ca617daThe Android Open Source Project * @throws IOException 425adc854b798c1cfe3bfd4c27d68d5cee38ca617daThe Android Open Source Project * if this reader is closed or some other I/O error occurs. 426adc854b798c1cfe3bfd4c27d68d5cee38ca617daThe Android Open Source Project * @see #read() 427adc854b798c1cfe3bfd4c27d68d5cee38ca617daThe Android Open Source Project * @see #read(char[], int, int) 428adc854b798c1cfe3bfd4c27d68d5cee38ca617daThe Android Open Source Project * @see #readLine() 429adc854b798c1cfe3bfd4c27d68d5cee38ca617daThe Android Open Source Project */ 430adc854b798c1cfe3bfd4c27d68d5cee38ca617daThe Android Open Source Project @Override 431adc854b798c1cfe3bfd4c27d68d5cee38ca617daThe Android Open Source Project public boolean ready() throws IOException { 432adc854b798c1cfe3bfd4c27d68d5cee38ca617daThe Android Open Source Project synchronized (lock) { 433b1396870f92135aa140bd2b86221768dea5bc11dElliott Hughes checkNotClosed(); 43482a2dfcd2281c2f8042fd5f09c98bea1e728530fJesse Wilson return ((end - pos) > 0) || in.ready(); 435adc854b798c1cfe3bfd4c27d68d5cee38ca617daThe Android Open Source Project } 436adc854b798c1cfe3bfd4c27d68d5cee38ca617daThe Android Open Source Project } 437adc854b798c1cfe3bfd4c27d68d5cee38ca617daThe Android Open Source Project 438adc854b798c1cfe3bfd4c27d68d5cee38ca617daThe Android Open Source Project /** 439adc854b798c1cfe3bfd4c27d68d5cee38ca617daThe Android Open Source Project * Resets this reader's position to the last {@code mark()} location. 440adc854b798c1cfe3bfd4c27d68d5cee38ca617daThe Android Open Source Project * Invocations of {@code read()} and {@code skip()} will occur from this new 441adc854b798c1cfe3bfd4c27d68d5cee38ca617daThe Android Open Source Project * location. 442f33eae7e84eb6d3b0f4e86b59605bb3de73009f3Elliott Hughes * 443adc854b798c1cfe3bfd4c27d68d5cee38ca617daThe Android Open Source Project * @throws IOException 444adc854b798c1cfe3bfd4c27d68d5cee38ca617daThe Android Open Source Project * if this reader is closed or no mark has been set. 445adc854b798c1cfe3bfd4c27d68d5cee38ca617daThe Android Open Source Project * @see #mark(int) 446adc854b798c1cfe3bfd4c27d68d5cee38ca617daThe Android Open Source Project * @see #markSupported() 447adc854b798c1cfe3bfd4c27d68d5cee38ca617daThe Android Open Source Project */ 448adc854b798c1cfe3bfd4c27d68d5cee38ca617daThe Android Open Source Project @Override 449adc854b798c1cfe3bfd4c27d68d5cee38ca617daThe Android Open Source Project public void reset() throws IOException { 450adc854b798c1cfe3bfd4c27d68d5cee38ca617daThe Android Open Source Project synchronized (lock) { 451b1396870f92135aa140bd2b86221768dea5bc11dElliott Hughes checkNotClosed(); 45282a2dfcd2281c2f8042fd5f09c98bea1e728530fJesse Wilson if (mark == -1) { 453b1396870f92135aa140bd2b86221768dea5bc11dElliott Hughes throw new IOException("Invalid mark"); 454adc854b798c1cfe3bfd4c27d68d5cee38ca617daThe Android Open Source Project } 4550409fa8fe9b1b3cd501931a8c25e109e6ff71be0Elliott Hughes this.pos = mark; 4560409fa8fe9b1b3cd501931a8c25e109e6ff71be0Elliott Hughes this.lastWasCR = this.markedLastWasCR; 457adc854b798c1cfe3bfd4c27d68d5cee38ca617daThe Android Open Source Project } 458adc854b798c1cfe3bfd4c27d68d5cee38ca617daThe Android Open Source Project } 459adc854b798c1cfe3bfd4c27d68d5cee38ca617daThe Android Open Source Project 460adc854b798c1cfe3bfd4c27d68d5cee38ca617daThe Android Open Source Project /** 4610409fa8fe9b1b3cd501931a8c25e109e6ff71be0Elliott Hughes * Skips at most {@code charCount} chars in this stream. Subsequent calls to 462fd1bbd5cb70830aaf6639dafc240c4d17181ef75Jesse Wilson * {@code read} will not return these chars unless {@code reset} is 463f9480f317cddcec859025833b748f096247a40aaElliott Hughes * used. 464fd1bbd5cb70830aaf6639dafc240c4d17181ef75Jesse Wilson * 465fd1bbd5cb70830aaf6639dafc240c4d17181ef75Jesse Wilson * <p>Skipping characters may invalidate a mark if {@code markLimit} 466adc854b798c1cfe3bfd4c27d68d5cee38ca617daThe Android Open Source Project * is surpassed. 467f33eae7e84eb6d3b0f4e86b59605bb3de73009f3Elliott Hughes * 468adc854b798c1cfe3bfd4c27d68d5cee38ca617daThe Android Open Source Project * @return the number of characters actually skipped. 469fd1bbd5cb70830aaf6639dafc240c4d17181ef75Jesse Wilson * @throws IllegalArgumentException if {@code charCount < 0}. 470adc854b798c1cfe3bfd4c27d68d5cee38ca617daThe Android Open Source Project * @throws IOException 471adc854b798c1cfe3bfd4c27d68d5cee38ca617daThe Android Open Source Project * if this reader is closed or some other I/O error occurs. 472adc854b798c1cfe3bfd4c27d68d5cee38ca617daThe Android Open Source Project */ 473adc854b798c1cfe3bfd4c27d68d5cee38ca617daThe Android Open Source Project @Override 474fd1bbd5cb70830aaf6639dafc240c4d17181ef75Jesse Wilson public long skip(long charCount) throws IOException { 475fd1bbd5cb70830aaf6639dafc240c4d17181ef75Jesse Wilson if (charCount < 0) { 476fd1bbd5cb70830aaf6639dafc240c4d17181ef75Jesse Wilson throw new IllegalArgumentException("charCount < 0: " + charCount); 477adc854b798c1cfe3bfd4c27d68d5cee38ca617daThe Android Open Source Project } 478adc854b798c1cfe3bfd4c27d68d5cee38ca617daThe Android Open Source Project synchronized (lock) { 479b1396870f92135aa140bd2b86221768dea5bc11dElliott Hughes checkNotClosed(); 480fd1bbd5cb70830aaf6639dafc240c4d17181ef75Jesse Wilson if (end - pos >= charCount) { 481fd1bbd5cb70830aaf6639dafc240c4d17181ef75Jesse Wilson pos += charCount; 482fd1bbd5cb70830aaf6639dafc240c4d17181ef75Jesse Wilson return charCount; 483adc854b798c1cfe3bfd4c27d68d5cee38ca617daThe Android Open Source Project } 484adc854b798c1cfe3bfd4c27d68d5cee38ca617daThe Android Open Source Project 48582a2dfcd2281c2f8042fd5f09c98bea1e728530fJesse Wilson long read = end - pos; 48682a2dfcd2281c2f8042fd5f09c98bea1e728530fJesse Wilson pos = end; 487fd1bbd5cb70830aaf6639dafc240c4d17181ef75Jesse Wilson while (read < charCount) { 48882a2dfcd2281c2f8042fd5f09c98bea1e728530fJesse Wilson if (fillBuf() == -1) { 489adc854b798c1cfe3bfd4c27d68d5cee38ca617daThe Android Open Source Project return read; 490adc854b798c1cfe3bfd4c27d68d5cee38ca617daThe Android Open Source Project } 491fd1bbd5cb70830aaf6639dafc240c4d17181ef75Jesse Wilson if (end - pos >= charCount - read) { 492fd1bbd5cb70830aaf6639dafc240c4d17181ef75Jesse Wilson pos += charCount - read; 493fd1bbd5cb70830aaf6639dafc240c4d17181ef75Jesse Wilson return charCount; 494adc854b798c1cfe3bfd4c27d68d5cee38ca617daThe Android Open Source Project } 495adc854b798c1cfe3bfd4c27d68d5cee38ca617daThe Android Open Source Project // Couldn't get all the characters, skip what we read 49682a2dfcd2281c2f8042fd5f09c98bea1e728530fJesse Wilson read += (end - pos); 49782a2dfcd2281c2f8042fd5f09c98bea1e728530fJesse Wilson pos = end; 498adc854b798c1cfe3bfd4c27d68d5cee38ca617daThe Android Open Source Project } 499fd1bbd5cb70830aaf6639dafc240c4d17181ef75Jesse Wilson return charCount; 500adc854b798c1cfe3bfd4c27d68d5cee38ca617daThe Android Open Source Project } 501adc854b798c1cfe3bfd4c27d68d5cee38ca617daThe Android Open Source Project } 502adc854b798c1cfe3bfd4c27d68d5cee38ca617daThe Android Open Source Project} 503