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 /** 74fb4616d0efbba1903b9237c0a428b59868365a69Elliott Hughes * Constructs a new {@code BufferedReader}, providing {@code in} with a buffer 75fb4616d0efbba1903b9237c0a428b59868365a69Elliott Hughes * of 8192 characters. 76fb4616d0efbba1903b9237c0a428b59868365a69Elliott Hughes * 77fb4616d0efbba1903b9237c0a428b59868365a69Elliott Hughes * @param in the {@code Reader} the buffer reads from. 78adc854b798c1cfe3bfd4c27d68d5cee38ca617daThe Android Open Source Project */ 79adc854b798c1cfe3bfd4c27d68d5cee38ca617daThe Android Open Source Project public BufferedReader(Reader in) { 80fb4616d0efbba1903b9237c0a428b59868365a69Elliott Hughes this(in, 8192); 81adc854b798c1cfe3bfd4c27d68d5cee38ca617daThe Android Open Source Project } 82adc854b798c1cfe3bfd4c27d68d5cee38ca617daThe Android Open Source Project 83adc854b798c1cfe3bfd4c27d68d5cee38ca617daThe Android Open Source Project /** 84fb4616d0efbba1903b9237c0a428b59868365a69Elliott Hughes * Constructs a new {@code BufferedReader}, providing {@code in} with {@code size} characters 85fb4616d0efbba1903b9237c0a428b59868365a69Elliott Hughes * of buffer. 86fb4616d0efbba1903b9237c0a428b59868365a69Elliott Hughes * 87fb4616d0efbba1903b9237c0a428b59868365a69Elliott Hughes * @param in the {@code InputStream} the buffer reads from. 88fb4616d0efbba1903b9237c0a428b59868365a69Elliott Hughes * @param size the size of buffer in characters. 89fb4616d0efbba1903b9237c0a428b59868365a69Elliott Hughes * @throws IllegalArgumentException if {@code size <= 0}. 90adc854b798c1cfe3bfd4c27d68d5cee38ca617daThe Android Open Source Project */ 91adc854b798c1cfe3bfd4c27d68d5cee38ca617daThe Android Open Source Project public BufferedReader(Reader in, int size) { 92adc854b798c1cfe3bfd4c27d68d5cee38ca617daThe Android Open Source Project super(in); 93adc854b798c1cfe3bfd4c27d68d5cee38ca617daThe Android Open Source Project if (size <= 0) { 94b1396870f92135aa140bd2b86221768dea5bc11dElliott Hughes throw new IllegalArgumentException("size <= 0"); 95adc854b798c1cfe3bfd4c27d68d5cee38ca617daThe Android Open Source Project } 96adc854b798c1cfe3bfd4c27d68d5cee38ca617daThe Android Open Source Project this.in = in; 97adc854b798c1cfe3bfd4c27d68d5cee38ca617daThe Android Open Source Project buf = new char[size]; 98adc854b798c1cfe3bfd4c27d68d5cee38ca617daThe Android Open Source Project } 99adc854b798c1cfe3bfd4c27d68d5cee38ca617daThe Android Open Source Project 100adc854b798c1cfe3bfd4c27d68d5cee38ca617daThe Android Open Source Project /** 101adc854b798c1cfe3bfd4c27d68d5cee38ca617daThe Android Open Source Project * Closes this reader. This implementation closes the buffered source reader 102adc854b798c1cfe3bfd4c27d68d5cee38ca617daThe Android Open Source Project * and releases the buffer. Nothing is done if this reader has already been 103adc854b798c1cfe3bfd4c27d68d5cee38ca617daThe Android Open Source Project * closed. 104f33eae7e84eb6d3b0f4e86b59605bb3de73009f3Elliott Hughes * 105adc854b798c1cfe3bfd4c27d68d5cee38ca617daThe Android Open Source Project * @throws IOException 106adc854b798c1cfe3bfd4c27d68d5cee38ca617daThe Android Open Source Project * if an error occurs while closing this reader. 107adc854b798c1cfe3bfd4c27d68d5cee38ca617daThe Android Open Source Project */ 108adc854b798c1cfe3bfd4c27d68d5cee38ca617daThe Android Open Source Project @Override 109adc854b798c1cfe3bfd4c27d68d5cee38ca617daThe Android Open Source Project public void close() throws IOException { 110adc854b798c1cfe3bfd4c27d68d5cee38ca617daThe Android Open Source Project synchronized (lock) { 111adc854b798c1cfe3bfd4c27d68d5cee38ca617daThe Android Open Source Project if (!isClosed()) { 112adc854b798c1cfe3bfd4c27d68d5cee38ca617daThe Android Open Source Project in.close(); 113adc854b798c1cfe3bfd4c27d68d5cee38ca617daThe Android Open Source Project buf = null; 114adc854b798c1cfe3bfd4c27d68d5cee38ca617daThe Android Open Source Project } 115adc854b798c1cfe3bfd4c27d68d5cee38ca617daThe Android Open Source Project } 116adc854b798c1cfe3bfd4c27d68d5cee38ca617daThe Android Open Source Project } 117adc854b798c1cfe3bfd4c27d68d5cee38ca617daThe Android Open Source Project 11882a2dfcd2281c2f8042fd5f09c98bea1e728530fJesse Wilson /** 11982a2dfcd2281c2f8042fd5f09c98bea1e728530fJesse Wilson * Populates the buffer with data. It is an error to call this method when 12082a2dfcd2281c2f8042fd5f09c98bea1e728530fJesse Wilson * the buffer still contains data; ie. if {@code pos < end}. 12182a2dfcd2281c2f8042fd5f09c98bea1e728530fJesse Wilson * 12282a2dfcd2281c2f8042fd5f09c98bea1e728530fJesse Wilson * @return the number of bytes read into the buffer, or -1 if the end of the 12382a2dfcd2281c2f8042fd5f09c98bea1e728530fJesse Wilson * source stream has been reached. 12482a2dfcd2281c2f8042fd5f09c98bea1e728530fJesse Wilson */ 12582a2dfcd2281c2f8042fd5f09c98bea1e728530fJesse Wilson private int fillBuf() throws IOException { 12682a2dfcd2281c2f8042fd5f09c98bea1e728530fJesse Wilson // assert(pos == end); 12782a2dfcd2281c2f8042fd5f09c98bea1e728530fJesse Wilson 12882a2dfcd2281c2f8042fd5f09c98bea1e728530fJesse Wilson if (mark == -1 || (pos - mark >= markLimit)) { 12982a2dfcd2281c2f8042fd5f09c98bea1e728530fJesse Wilson /* mark isn't set or has exceeded its limit. use the whole buffer */ 130adc854b798c1cfe3bfd4c27d68d5cee38ca617daThe Android Open Source Project int result = in.read(buf, 0, buf.length); 131adc854b798c1cfe3bfd4c27d68d5cee38ca617daThe Android Open Source Project if (result > 0) { 13282a2dfcd2281c2f8042fd5f09c98bea1e728530fJesse Wilson mark = -1; 133adc854b798c1cfe3bfd4c27d68d5cee38ca617daThe Android Open Source Project pos = 0; 13482a2dfcd2281c2f8042fd5f09c98bea1e728530fJesse Wilson end = result; 135adc854b798c1cfe3bfd4c27d68d5cee38ca617daThe Android Open Source Project } 136adc854b798c1cfe3bfd4c27d68d5cee38ca617daThe Android Open Source Project return result; 137adc854b798c1cfe3bfd4c27d68d5cee38ca617daThe Android Open Source Project } 13882a2dfcd2281c2f8042fd5f09c98bea1e728530fJesse Wilson 13982a2dfcd2281c2f8042fd5f09c98bea1e728530fJesse Wilson if (mark == 0 && markLimit > buf.length) { 14082a2dfcd2281c2f8042fd5f09c98bea1e728530fJesse Wilson /* the only way to make room when mark=0 is by growing the buffer */ 141adc854b798c1cfe3bfd4c27d68d5cee38ca617daThe Android Open Source Project int newLength = buf.length * 2; 14282a2dfcd2281c2f8042fd5f09c98bea1e728530fJesse Wilson if (newLength > markLimit) { 14382a2dfcd2281c2f8042fd5f09c98bea1e728530fJesse Wilson newLength = markLimit; 144adc854b798c1cfe3bfd4c27d68d5cee38ca617daThe Android Open Source Project } 145adc854b798c1cfe3bfd4c27d68d5cee38ca617daThe Android Open Source Project char[] newbuf = new char[newLength]; 146adc854b798c1cfe3bfd4c27d68d5cee38ca617daThe Android Open Source Project System.arraycopy(buf, 0, newbuf, 0, buf.length); 147adc854b798c1cfe3bfd4c27d68d5cee38ca617daThe Android Open Source Project buf = newbuf; 14882a2dfcd2281c2f8042fd5f09c98bea1e728530fJesse Wilson } else if (mark > 0) { 14982a2dfcd2281c2f8042fd5f09c98bea1e728530fJesse Wilson /* make room by shifting the buffered data to left mark positions */ 15082a2dfcd2281c2f8042fd5f09c98bea1e728530fJesse Wilson System.arraycopy(buf, mark, buf, 0, buf.length - mark); 15182a2dfcd2281c2f8042fd5f09c98bea1e728530fJesse Wilson pos -= mark; 15282a2dfcd2281c2f8042fd5f09c98bea1e728530fJesse Wilson end -= mark; 15382a2dfcd2281c2f8042fd5f09c98bea1e728530fJesse Wilson mark = 0; 154adc854b798c1cfe3bfd4c27d68d5cee38ca617daThe Android Open Source Project } 155adc854b798c1cfe3bfd4c27d68d5cee38ca617daThe Android Open Source Project 156adc854b798c1cfe3bfd4c27d68d5cee38ca617daThe Android Open Source Project /* Set the new position and mark position */ 15782a2dfcd2281c2f8042fd5f09c98bea1e728530fJesse Wilson int count = in.read(buf, pos, buf.length - pos); 15882a2dfcd2281c2f8042fd5f09c98bea1e728530fJesse Wilson if (count != -1) { 15982a2dfcd2281c2f8042fd5f09c98bea1e728530fJesse Wilson end += count; 16082a2dfcd2281c2f8042fd5f09c98bea1e728530fJesse Wilson } 16182a2dfcd2281c2f8042fd5f09c98bea1e728530fJesse Wilson return count; 162adc854b798c1cfe3bfd4c27d68d5cee38ca617daThe Android Open Source Project } 163adc854b798c1cfe3bfd4c27d68d5cee38ca617daThe Android Open Source Project 164adc854b798c1cfe3bfd4c27d68d5cee38ca617daThe Android Open Source Project /** 165adc854b798c1cfe3bfd4c27d68d5cee38ca617daThe Android Open Source Project * Indicates whether or not this reader is closed. 166f33eae7e84eb6d3b0f4e86b59605bb3de73009f3Elliott Hughes * 167adc854b798c1cfe3bfd4c27d68d5cee38ca617daThe Android Open Source Project * @return {@code true} if this reader is closed, {@code false} 168adc854b798c1cfe3bfd4c27d68d5cee38ca617daThe Android Open Source Project * otherwise. 169adc854b798c1cfe3bfd4c27d68d5cee38ca617daThe Android Open Source Project */ 170adc854b798c1cfe3bfd4c27d68d5cee38ca617daThe Android Open Source Project private boolean isClosed() { 171adc854b798c1cfe3bfd4c27d68d5cee38ca617daThe Android Open Source Project return buf == null; 172adc854b798c1cfe3bfd4c27d68d5cee38ca617daThe Android Open Source Project } 173adc854b798c1cfe3bfd4c27d68d5cee38ca617daThe Android Open Source Project 174adc854b798c1cfe3bfd4c27d68d5cee38ca617daThe Android Open Source Project /** 17582a2dfcd2281c2f8042fd5f09c98bea1e728530fJesse Wilson * Sets a mark position in this reader. The parameter {@code markLimit} 176adc854b798c1cfe3bfd4c27d68d5cee38ca617daThe Android Open Source Project * indicates how many characters can be read before the mark is invalidated. 177adc854b798c1cfe3bfd4c27d68d5cee38ca617daThe Android Open Source Project * Calling {@code reset()} will reposition the reader back to the marked 17882a2dfcd2281c2f8042fd5f09c98bea1e728530fJesse Wilson * position if {@code markLimit} has not been surpassed. 179f33eae7e84eb6d3b0f4e86b59605bb3de73009f3Elliott Hughes * 18082a2dfcd2281c2f8042fd5f09c98bea1e728530fJesse Wilson * @param markLimit 181adc854b798c1cfe3bfd4c27d68d5cee38ca617daThe Android Open Source Project * the number of characters that can be read before the mark is 182adc854b798c1cfe3bfd4c27d68d5cee38ca617daThe Android Open Source Project * invalidated. 183adc854b798c1cfe3bfd4c27d68d5cee38ca617daThe Android Open Source Project * @throws IllegalArgumentException 18482a2dfcd2281c2f8042fd5f09c98bea1e728530fJesse Wilson * if {@code markLimit < 0}. 185adc854b798c1cfe3bfd4c27d68d5cee38ca617daThe Android Open Source Project * @throws IOException 186adc854b798c1cfe3bfd4c27d68d5cee38ca617daThe Android Open Source Project * if an error occurs while setting a mark in this reader. 187adc854b798c1cfe3bfd4c27d68d5cee38ca617daThe Android Open Source Project * @see #markSupported() 188adc854b798c1cfe3bfd4c27d68d5cee38ca617daThe Android Open Source Project * @see #reset() 189adc854b798c1cfe3bfd4c27d68d5cee38ca617daThe Android Open Source Project */ 190adc854b798c1cfe3bfd4c27d68d5cee38ca617daThe Android Open Source Project @Override 19182a2dfcd2281c2f8042fd5f09c98bea1e728530fJesse Wilson public void mark(int markLimit) throws IOException { 19282a2dfcd2281c2f8042fd5f09c98bea1e728530fJesse Wilson if (markLimit < 0) { 193adc854b798c1cfe3bfd4c27d68d5cee38ca617daThe Android Open Source Project throw new IllegalArgumentException(); 194adc854b798c1cfe3bfd4c27d68d5cee38ca617daThe Android Open Source Project } 195adc854b798c1cfe3bfd4c27d68d5cee38ca617daThe Android Open Source Project synchronized (lock) { 196b1396870f92135aa140bd2b86221768dea5bc11dElliott Hughes checkNotClosed(); 19782a2dfcd2281c2f8042fd5f09c98bea1e728530fJesse Wilson this.markLimit = markLimit; 19882a2dfcd2281c2f8042fd5f09c98bea1e728530fJesse Wilson mark = pos; 199adc854b798c1cfe3bfd4c27d68d5cee38ca617daThe Android Open Source Project } 200adc854b798c1cfe3bfd4c27d68d5cee38ca617daThe Android Open Source Project } 201adc854b798c1cfe3bfd4c27d68d5cee38ca617daThe Android Open Source Project 202b1396870f92135aa140bd2b86221768dea5bc11dElliott Hughes private void checkNotClosed() throws IOException { 203b1396870f92135aa140bd2b86221768dea5bc11dElliott Hughes if (isClosed()) { 204b1396870f92135aa140bd2b86221768dea5bc11dElliott Hughes throw new IOException("BufferedReader is closed"); 205b1396870f92135aa140bd2b86221768dea5bc11dElliott Hughes } 206b1396870f92135aa140bd2b86221768dea5bc11dElliott Hughes } 207b1396870f92135aa140bd2b86221768dea5bc11dElliott Hughes 208adc854b798c1cfe3bfd4c27d68d5cee38ca617daThe Android Open Source Project /** 209adc854b798c1cfe3bfd4c27d68d5cee38ca617daThe Android Open Source Project * Indicates whether this reader supports the {@code mark()} and 210adc854b798c1cfe3bfd4c27d68d5cee38ca617daThe Android Open Source Project * {@code reset()} methods. This implementation returns {@code true}. 211f33eae7e84eb6d3b0f4e86b59605bb3de73009f3Elliott Hughes * 212adc854b798c1cfe3bfd4c27d68d5cee38ca617daThe Android Open Source Project * @return {@code true} for {@code BufferedReader}. 213adc854b798c1cfe3bfd4c27d68d5cee38ca617daThe Android Open Source Project * @see #mark(int) 214adc854b798c1cfe3bfd4c27d68d5cee38ca617daThe Android Open Source Project * @see #reset() 215adc854b798c1cfe3bfd4c27d68d5cee38ca617daThe Android Open Source Project */ 216adc854b798c1cfe3bfd4c27d68d5cee38ca617daThe Android Open Source Project @Override 217adc854b798c1cfe3bfd4c27d68d5cee38ca617daThe Android Open Source Project public boolean markSupported() { 218adc854b798c1cfe3bfd4c27d68d5cee38ca617daThe Android Open Source Project return true; 219adc854b798c1cfe3bfd4c27d68d5cee38ca617daThe Android Open Source Project } 220adc854b798c1cfe3bfd4c27d68d5cee38ca617daThe Android Open Source Project 221adc854b798c1cfe3bfd4c27d68d5cee38ca617daThe Android Open Source Project /** 222adc854b798c1cfe3bfd4c27d68d5cee38ca617daThe Android Open Source Project * Reads a single character from this reader and returns it with the two 223adc854b798c1cfe3bfd4c27d68d5cee38ca617daThe Android Open Source Project * higher-order bytes set to 0. If possible, BufferedReader returns a 224adc854b798c1cfe3bfd4c27d68d5cee38ca617daThe Android Open Source Project * character from the buffer. If there are no characters available in the 225adc854b798c1cfe3bfd4c27d68d5cee38ca617daThe Android Open Source Project * buffer, it fills the buffer and then returns a character. It returns -1 226adc854b798c1cfe3bfd4c27d68d5cee38ca617daThe Android Open Source Project * if there are no more characters in the source reader. 227f5597e626ecf7949d249dea08c1a2964d890ec11Jesse Wilson * 228adc854b798c1cfe3bfd4c27d68d5cee38ca617daThe Android Open Source Project * @return the character read or -1 if the end of the source reader has been 229adc854b798c1cfe3bfd4c27d68d5cee38ca617daThe Android Open Source Project * reached. 230adc854b798c1cfe3bfd4c27d68d5cee38ca617daThe Android Open Source Project * @throws IOException 231adc854b798c1cfe3bfd4c27d68d5cee38ca617daThe Android Open Source Project * if this reader is closed or some other I/O error occurs. 232adc854b798c1cfe3bfd4c27d68d5cee38ca617daThe Android Open Source Project */ 233adc854b798c1cfe3bfd4c27d68d5cee38ca617daThe Android Open Source Project @Override 234adc854b798c1cfe3bfd4c27d68d5cee38ca617daThe Android Open Source Project public int read() throws IOException { 235adc854b798c1cfe3bfd4c27d68d5cee38ca617daThe Android Open Source Project synchronized (lock) { 236b1396870f92135aa140bd2b86221768dea5bc11dElliott Hughes checkNotClosed(); 237adc854b798c1cfe3bfd4c27d68d5cee38ca617daThe Android Open Source Project /* Are there buffered characters available? */ 23882a2dfcd2281c2f8042fd5f09c98bea1e728530fJesse Wilson if (pos < end || fillBuf() != -1) { 239adc854b798c1cfe3bfd4c27d68d5cee38ca617daThe Android Open Source Project return buf[pos++]; 240adc854b798c1cfe3bfd4c27d68d5cee38ca617daThe Android Open Source Project } 241adc854b798c1cfe3bfd4c27d68d5cee38ca617daThe Android Open Source Project return -1; 242adc854b798c1cfe3bfd4c27d68d5cee38ca617daThe Android Open Source Project } 243adc854b798c1cfe3bfd4c27d68d5cee38ca617daThe Android Open Source Project } 244adc854b798c1cfe3bfd4c27d68d5cee38ca617daThe Android Open Source Project 245adc854b798c1cfe3bfd4c27d68d5cee38ca617daThe Android Open Source Project /** 246adc854b798c1cfe3bfd4c27d68d5cee38ca617daThe Android Open Source Project * Reads at most {@code length} characters from this reader and stores them 247adc854b798c1cfe3bfd4c27d68d5cee38ca617daThe Android Open Source Project * at {@code offset} in the character array {@code buffer}. Returns the 248adc854b798c1cfe3bfd4c27d68d5cee38ca617daThe Android Open Source Project * number of characters actually read or -1 if the end of the source reader 249adc854b798c1cfe3bfd4c27d68d5cee38ca617daThe Android Open Source Project * has been reached. If all the buffered characters have been used, a mark 250adc854b798c1cfe3bfd4c27d68d5cee38ca617daThe Android Open Source Project * has not been set and the requested number of characters is larger than 251adc854b798c1cfe3bfd4c27d68d5cee38ca617daThe Android Open Source Project * this readers buffer size, BufferedReader bypasses the buffer and simply 252adc854b798c1cfe3bfd4c27d68d5cee38ca617daThe Android Open Source Project * places the results directly into {@code buffer}. 253f33eae7e84eb6d3b0f4e86b59605bb3de73009f3Elliott Hughes * 254adc854b798c1cfe3bfd4c27d68d5cee38ca617daThe Android Open Source Project * @param buffer 255adc854b798c1cfe3bfd4c27d68d5cee38ca617daThe Android Open Source Project * the character array to store the characters read. 256adc854b798c1cfe3bfd4c27d68d5cee38ca617daThe Android Open Source Project * @param offset 257adc854b798c1cfe3bfd4c27d68d5cee38ca617daThe Android Open Source Project * the initial position in {@code buffer} to store the bytes read 258adc854b798c1cfe3bfd4c27d68d5cee38ca617daThe Android Open Source Project * from this reader. 259adc854b798c1cfe3bfd4c27d68d5cee38ca617daThe Android Open Source Project * @param length 260adc854b798c1cfe3bfd4c27d68d5cee38ca617daThe Android Open Source Project * the maximum number of characters to read, must be 261adc854b798c1cfe3bfd4c27d68d5cee38ca617daThe Android Open Source Project * non-negative. 262adc854b798c1cfe3bfd4c27d68d5cee38ca617daThe Android Open Source Project * @return number of characters read or -1 if the end of the source reader 263adc854b798c1cfe3bfd4c27d68d5cee38ca617daThe Android Open Source Project * has been reached. 264adc854b798c1cfe3bfd4c27d68d5cee38ca617daThe Android Open Source Project * @throws IndexOutOfBoundsException 265adc854b798c1cfe3bfd4c27d68d5cee38ca617daThe Android Open Source Project * if {@code offset < 0} or {@code length < 0}, or if 266adc854b798c1cfe3bfd4c27d68d5cee38ca617daThe Android Open Source Project * {@code offset + length} is greater than the size of 267adc854b798c1cfe3bfd4c27d68d5cee38ca617daThe Android Open Source Project * {@code buffer}. 268adc854b798c1cfe3bfd4c27d68d5cee38ca617daThe Android Open Source Project * @throws IOException 269adc854b798c1cfe3bfd4c27d68d5cee38ca617daThe Android Open Source Project * if this reader is closed or some other I/O error occurs. 270adc854b798c1cfe3bfd4c27d68d5cee38ca617daThe Android Open Source Project */ 271adc854b798c1cfe3bfd4c27d68d5cee38ca617daThe Android Open Source Project @Override 272adc854b798c1cfe3bfd4c27d68d5cee38ca617daThe Android Open Source Project public int read(char[] buffer, int offset, int length) throws IOException { 273adc854b798c1cfe3bfd4c27d68d5cee38ca617daThe Android Open Source Project synchronized (lock) { 274b1396870f92135aa140bd2b86221768dea5bc11dElliott Hughes checkNotClosed(); 275a1603838fe9e865575c87982e32c6343740e464cElliott Hughes Arrays.checkOffsetAndCount(buffer.length, offset, length); 27682a2dfcd2281c2f8042fd5f09c98bea1e728530fJesse Wilson int outstanding = length; 27782a2dfcd2281c2f8042fd5f09c98bea1e728530fJesse Wilson while (outstanding > 0) { 27882a2dfcd2281c2f8042fd5f09c98bea1e728530fJesse Wilson 27982a2dfcd2281c2f8042fd5f09c98bea1e728530fJesse Wilson /* 28082a2dfcd2281c2f8042fd5f09c98bea1e728530fJesse Wilson * If there are bytes in the buffer, grab those first. 28182a2dfcd2281c2f8042fd5f09c98bea1e728530fJesse Wilson */ 28282a2dfcd2281c2f8042fd5f09c98bea1e728530fJesse Wilson int available = end - pos; 28382a2dfcd2281c2f8042fd5f09c98bea1e728530fJesse Wilson if (available > 0) { 28482a2dfcd2281c2f8042fd5f09c98bea1e728530fJesse Wilson int count = available >= outstanding ? outstanding : available; 28582a2dfcd2281c2f8042fd5f09c98bea1e728530fJesse Wilson System.arraycopy(buf, pos, buffer, offset, count); 28682a2dfcd2281c2f8042fd5f09c98bea1e728530fJesse Wilson pos += count; 28782a2dfcd2281c2f8042fd5f09c98bea1e728530fJesse Wilson offset += count; 28882a2dfcd2281c2f8042fd5f09c98bea1e728530fJesse Wilson outstanding -= count; 289adc854b798c1cfe3bfd4c27d68d5cee38ca617daThe Android Open Source Project } 290adc854b798c1cfe3bfd4c27d68d5cee38ca617daThe Android Open Source Project 291adc854b798c1cfe3bfd4c27d68d5cee38ca617daThe Android Open Source Project /* 29282a2dfcd2281c2f8042fd5f09c98bea1e728530fJesse Wilson * Before attempting to read from the underlying stream, make 29382a2dfcd2281c2f8042fd5f09c98bea1e728530fJesse Wilson * sure we really, really want to. We won't bother if we're 29482a2dfcd2281c2f8042fd5f09c98bea1e728530fJesse Wilson * done, or if we've already got some bytes and reading from the 29582a2dfcd2281c2f8042fd5f09c98bea1e728530fJesse Wilson * underlying stream would block. 296adc854b798c1cfe3bfd4c27d68d5cee38ca617daThe Android Open Source Project */ 29782a2dfcd2281c2f8042fd5f09c98bea1e728530fJesse Wilson if (outstanding == 0 || (outstanding < length && !in.ready())) { 29882a2dfcd2281c2f8042fd5f09c98bea1e728530fJesse Wilson break; 299adc854b798c1cfe3bfd4c27d68d5cee38ca617daThe Android Open Source Project } 30082a2dfcd2281c2f8042fd5f09c98bea1e728530fJesse Wilson 30182a2dfcd2281c2f8042fd5f09c98bea1e728530fJesse Wilson // assert(pos == end); 30282a2dfcd2281c2f8042fd5f09c98bea1e728530fJesse Wilson 30382a2dfcd2281c2f8042fd5f09c98bea1e728530fJesse Wilson /* 30482a2dfcd2281c2f8042fd5f09c98bea1e728530fJesse Wilson * If we're unmarked and the requested size is greater than our 30582a2dfcd2281c2f8042fd5f09c98bea1e728530fJesse Wilson * buffer, read the bytes directly into the caller's buffer. We 30682a2dfcd2281c2f8042fd5f09c98bea1e728530fJesse Wilson * don't read into smaller buffers because that could result in 30782a2dfcd2281c2f8042fd5f09c98bea1e728530fJesse Wilson * a many reads. 30882a2dfcd2281c2f8042fd5f09c98bea1e728530fJesse Wilson */ 309344110141de805108972f0ad24f16de59ba2aa32Elliott Hughes if ((mark == -1 || (pos - mark >= markLimit)) && outstanding >= buf.length) { 31082a2dfcd2281c2f8042fd5f09c98bea1e728530fJesse Wilson int count = in.read(buffer, offset, outstanding); 31182a2dfcd2281c2f8042fd5f09c98bea1e728530fJesse Wilson if (count > 0) { 31282a2dfcd2281c2f8042fd5f09c98bea1e728530fJesse Wilson outstanding -= count; 31382a2dfcd2281c2f8042fd5f09c98bea1e728530fJesse Wilson mark = -1; 31482a2dfcd2281c2f8042fd5f09c98bea1e728530fJesse Wilson } 31582a2dfcd2281c2f8042fd5f09c98bea1e728530fJesse Wilson break; // assume the source stream gave us all that it could 316adc854b798c1cfe3bfd4c27d68d5cee38ca617daThe Android Open Source Project } 31782a2dfcd2281c2f8042fd5f09c98bea1e728530fJesse Wilson 31882a2dfcd2281c2f8042fd5f09c98bea1e728530fJesse Wilson if (fillBuf() == -1) { 31982a2dfcd2281c2f8042fd5f09c98bea1e728530fJesse Wilson break; // source is exhausted 320adc854b798c1cfe3bfd4c27d68d5cee38ca617daThe Android Open Source Project } 321adc854b798c1cfe3bfd4c27d68d5cee38ca617daThe Android Open Source Project } 32282a2dfcd2281c2f8042fd5f09c98bea1e728530fJesse Wilson 32382a2dfcd2281c2f8042fd5f09c98bea1e728530fJesse Wilson int count = length - outstanding; 32482a2dfcd2281c2f8042fd5f09c98bea1e728530fJesse Wilson return (count > 0 || count == length) ? count : -1; 325adc854b798c1cfe3bfd4c27d68d5cee38ca617daThe Android Open Source Project } 326adc854b798c1cfe3bfd4c27d68d5cee38ca617daThe Android Open Source Project } 327adc854b798c1cfe3bfd4c27d68d5cee38ca617daThe Android Open Source Project 328adc854b798c1cfe3bfd4c27d68d5cee38ca617daThe Android Open Source Project /** 32955392539fea537abfb6581b474918f9d611fba27Jesse Wilson * Peeks at the next input character, refilling the buffer if necessary. If 33055392539fea537abfb6581b474918f9d611fba27Jesse Wilson * this character is a newline character ("\n"), it is discarded. 33155392539fea537abfb6581b474918f9d611fba27Jesse Wilson */ 33255392539fea537abfb6581b474918f9d611fba27Jesse Wilson final void chompNewline() throws IOException { 33355392539fea537abfb6581b474918f9d611fba27Jesse Wilson if ((pos != end || fillBuf() != -1) 33455392539fea537abfb6581b474918f9d611fba27Jesse Wilson && buf[pos] == '\n') { 33555392539fea537abfb6581b474918f9d611fba27Jesse Wilson pos++; 33655392539fea537abfb6581b474918f9d611fba27Jesse Wilson } 33755392539fea537abfb6581b474918f9d611fba27Jesse Wilson } 33855392539fea537abfb6581b474918f9d611fba27Jesse Wilson 33955392539fea537abfb6581b474918f9d611fba27Jesse Wilson /** 340adc854b798c1cfe3bfd4c27d68d5cee38ca617daThe Android Open Source Project * Returns the next line of text available from this reader. A line is 341adc854b798c1cfe3bfd4c27d68d5cee38ca617daThe Android Open Source Project * represented by zero or more characters followed by {@code '\n'}, 342adc854b798c1cfe3bfd4c27d68d5cee38ca617daThe Android Open Source Project * {@code '\r'}, {@code "\r\n"} or the end of the reader. The string does 343a389b4a499f40379b0b204d7ba1c2057663d95c0Jesse Wilson * not include the newline sequence. 344f33eae7e84eb6d3b0f4e86b59605bb3de73009f3Elliott Hughes * 345adc854b798c1cfe3bfd4c27d68d5cee38ca617daThe Android Open Source Project * @return the contents of the line or {@code null} if no characters were 346adc854b798c1cfe3bfd4c27d68d5cee38ca617daThe Android Open Source Project * read before the end of the reader has been reached. 347adc854b798c1cfe3bfd4c27d68d5cee38ca617daThe Android Open Source Project * @throws IOException 348adc854b798c1cfe3bfd4c27d68d5cee38ca617daThe Android Open Source Project * if this reader is closed or some other I/O error occurs. 349adc854b798c1cfe3bfd4c27d68d5cee38ca617daThe Android Open Source Project */ 350adc854b798c1cfe3bfd4c27d68d5cee38ca617daThe Android Open Source Project public String readLine() throws IOException { 351adc854b798c1cfe3bfd4c27d68d5cee38ca617daThe Android Open Source Project synchronized (lock) { 352b1396870f92135aa140bd2b86221768dea5bc11dElliott Hughes checkNotClosed(); 35382a2dfcd2281c2f8042fd5f09c98bea1e728530fJesse Wilson /* has the underlying stream been exhausted? */ 35482a2dfcd2281c2f8042fd5f09c98bea1e728530fJesse Wilson if (pos == end && fillBuf() == -1) { 355adc854b798c1cfe3bfd4c27d68d5cee38ca617daThe Android Open Source Project return null; 356adc854b798c1cfe3bfd4c27d68d5cee38ca617daThe Android Open Source Project } 35782a2dfcd2281c2f8042fd5f09c98bea1e728530fJesse Wilson for (int charPos = pos; charPos < end; charPos++) { 358adc854b798c1cfe3bfd4c27d68d5cee38ca617daThe Android Open Source Project char ch = buf[charPos]; 359a389b4a499f40379b0b204d7ba1c2057663d95c0Jesse Wilson if (ch > '\r') { 360adc854b798c1cfe3bfd4c27d68d5cee38ca617daThe Android Open Source Project continue; 361adc854b798c1cfe3bfd4c27d68d5cee38ca617daThe Android Open Source Project } 362adc854b798c1cfe3bfd4c27d68d5cee38ca617daThe Android Open Source Project if (ch == '\n') { 363adc854b798c1cfe3bfd4c27d68d5cee38ca617daThe Android Open Source Project String res = new String(buf, pos, charPos - pos); 364adc854b798c1cfe3bfd4c27d68d5cee38ca617daThe Android Open Source Project pos = charPos + 1; 365adc854b798c1cfe3bfd4c27d68d5cee38ca617daThe Android Open Source Project return res; 366adc854b798c1cfe3bfd4c27d68d5cee38ca617daThe Android Open Source Project } else if (ch == '\r') { 367adc854b798c1cfe3bfd4c27d68d5cee38ca617daThe Android Open Source Project String res = new String(buf, pos, charPos - pos); 368adc854b798c1cfe3bfd4c27d68d5cee38ca617daThe Android Open Source Project pos = charPos + 1; 36982a2dfcd2281c2f8042fd5f09c98bea1e728530fJesse Wilson if (((pos < end) || (fillBuf() != -1)) 370adc854b798c1cfe3bfd4c27d68d5cee38ca617daThe Android Open Source Project && (buf[pos] == '\n')) { 371adc854b798c1cfe3bfd4c27d68d5cee38ca617daThe Android Open Source Project pos++; 372adc854b798c1cfe3bfd4c27d68d5cee38ca617daThe Android Open Source Project } 373adc854b798c1cfe3bfd4c27d68d5cee38ca617daThe Android Open Source Project return res; 374adc854b798c1cfe3bfd4c27d68d5cee38ca617daThe Android Open Source Project } 375adc854b798c1cfe3bfd4c27d68d5cee38ca617daThe Android Open Source Project } 376adc854b798c1cfe3bfd4c27d68d5cee38ca617daThe Android Open Source Project 377adc854b798c1cfe3bfd4c27d68d5cee38ca617daThe Android Open Source Project char eol = '\0'; 378adc854b798c1cfe3bfd4c27d68d5cee38ca617daThe Android Open Source Project StringBuilder result = new StringBuilder(80); 379adc854b798c1cfe3bfd4c27d68d5cee38ca617daThe Android Open Source Project /* Typical Line Length */ 380adc854b798c1cfe3bfd4c27d68d5cee38ca617daThe Android Open Source Project 38182a2dfcd2281c2f8042fd5f09c98bea1e728530fJesse Wilson result.append(buf, pos, end - pos); 382adc854b798c1cfe3bfd4c27d68d5cee38ca617daThe Android Open Source Project while (true) { 38382a2dfcd2281c2f8042fd5f09c98bea1e728530fJesse Wilson pos = end; 38482a2dfcd2281c2f8042fd5f09c98bea1e728530fJesse Wilson 385adc854b798c1cfe3bfd4c27d68d5cee38ca617daThe Android Open Source Project /* Are there buffered characters available? */ 38682a2dfcd2281c2f8042fd5f09c98bea1e728530fJesse Wilson if (eol == '\n') { 38782a2dfcd2281c2f8042fd5f09c98bea1e728530fJesse Wilson return result.toString(); 38882a2dfcd2281c2f8042fd5f09c98bea1e728530fJesse Wilson } 38982a2dfcd2281c2f8042fd5f09c98bea1e728530fJesse Wilson // attempt to fill buffer 39082a2dfcd2281c2f8042fd5f09c98bea1e728530fJesse Wilson if (fillBuf() == -1) { 39182a2dfcd2281c2f8042fd5f09c98bea1e728530fJesse Wilson // characters or null. 39282a2dfcd2281c2f8042fd5f09c98bea1e728530fJesse Wilson return result.length() > 0 || eol != '\0' 39382a2dfcd2281c2f8042fd5f09c98bea1e728530fJesse Wilson ? result.toString() 39482a2dfcd2281c2f8042fd5f09c98bea1e728530fJesse Wilson : null; 395adc854b798c1cfe3bfd4c27d68d5cee38ca617daThe Android Open Source Project } 39682a2dfcd2281c2f8042fd5f09c98bea1e728530fJesse Wilson for (int charPos = pos; charPos < end; charPos++) { 39782a2dfcd2281c2f8042fd5f09c98bea1e728530fJesse Wilson char c = buf[charPos]; 398adc854b798c1cfe3bfd4c27d68d5cee38ca617daThe Android Open Source Project if (eol == '\0') { 39982a2dfcd2281c2f8042fd5f09c98bea1e728530fJesse Wilson if ((c == '\n' || c == '\r')) { 40082a2dfcd2281c2f8042fd5f09c98bea1e728530fJesse Wilson eol = c; 401adc854b798c1cfe3bfd4c27d68d5cee38ca617daThe Android Open Source Project } 40282a2dfcd2281c2f8042fd5f09c98bea1e728530fJesse Wilson } else if (eol == '\r' && c == '\n') { 403adc854b798c1cfe3bfd4c27d68d5cee38ca617daThe Android Open Source Project if (charPos > pos) { 404adc854b798c1cfe3bfd4c27d68d5cee38ca617daThe Android Open Source Project result.append(buf, pos, charPos - pos - 1); 405adc854b798c1cfe3bfd4c27d68d5cee38ca617daThe Android Open Source Project } 406adc854b798c1cfe3bfd4c27d68d5cee38ca617daThe Android Open Source Project pos = charPos + 1; 407adc854b798c1cfe3bfd4c27d68d5cee38ca617daThe Android Open Source Project return result.toString(); 408a389b4a499f40379b0b204d7ba1c2057663d95c0Jesse Wilson } else { 409adc854b798c1cfe3bfd4c27d68d5cee38ca617daThe Android Open Source Project if (charPos > pos) { 410adc854b798c1cfe3bfd4c27d68d5cee38ca617daThe Android Open Source Project result.append(buf, pos, charPos - pos - 1); 411adc854b798c1cfe3bfd4c27d68d5cee38ca617daThe Android Open Source Project } 412adc854b798c1cfe3bfd4c27d68d5cee38ca617daThe Android Open Source Project pos = charPos; 413adc854b798c1cfe3bfd4c27d68d5cee38ca617daThe Android Open Source Project return result.toString(); 414adc854b798c1cfe3bfd4c27d68d5cee38ca617daThe Android Open Source Project } 415adc854b798c1cfe3bfd4c27d68d5cee38ca617daThe Android Open Source Project } 416adc854b798c1cfe3bfd4c27d68d5cee38ca617daThe Android Open Source Project if (eol == '\0') { 41782a2dfcd2281c2f8042fd5f09c98bea1e728530fJesse Wilson result.append(buf, pos, end - pos); 418adc854b798c1cfe3bfd4c27d68d5cee38ca617daThe Android Open Source Project } else { 41982a2dfcd2281c2f8042fd5f09c98bea1e728530fJesse Wilson result.append(buf, pos, end - pos - 1); 420adc854b798c1cfe3bfd4c27d68d5cee38ca617daThe Android Open Source Project } 421adc854b798c1cfe3bfd4c27d68d5cee38ca617daThe Android Open Source Project } 422adc854b798c1cfe3bfd4c27d68d5cee38ca617daThe Android Open Source Project } 423adc854b798c1cfe3bfd4c27d68d5cee38ca617daThe Android Open Source Project 424adc854b798c1cfe3bfd4c27d68d5cee38ca617daThe Android Open Source Project } 425adc854b798c1cfe3bfd4c27d68d5cee38ca617daThe Android Open Source Project 426adc854b798c1cfe3bfd4c27d68d5cee38ca617daThe Android Open Source Project /** 427adc854b798c1cfe3bfd4c27d68d5cee38ca617daThe Android Open Source Project * Indicates whether this reader is ready to be read without blocking. 428f5597e626ecf7949d249dea08c1a2964d890ec11Jesse Wilson * 429adc854b798c1cfe3bfd4c27d68d5cee38ca617daThe Android Open Source Project * @return {@code true} if this reader will not block when {@code read} is 430adc854b798c1cfe3bfd4c27d68d5cee38ca617daThe Android Open Source Project * called, {@code false} if unknown or blocking will occur. 431adc854b798c1cfe3bfd4c27d68d5cee38ca617daThe Android Open Source Project * @throws IOException 432adc854b798c1cfe3bfd4c27d68d5cee38ca617daThe Android Open Source Project * if this reader is closed or some other I/O error occurs. 433adc854b798c1cfe3bfd4c27d68d5cee38ca617daThe Android Open Source Project * @see #read() 434adc854b798c1cfe3bfd4c27d68d5cee38ca617daThe Android Open Source Project * @see #read(char[], int, int) 435adc854b798c1cfe3bfd4c27d68d5cee38ca617daThe Android Open Source Project * @see #readLine() 436adc854b798c1cfe3bfd4c27d68d5cee38ca617daThe Android Open Source Project */ 437adc854b798c1cfe3bfd4c27d68d5cee38ca617daThe Android Open Source Project @Override 438adc854b798c1cfe3bfd4c27d68d5cee38ca617daThe Android Open Source Project public boolean ready() throws IOException { 439adc854b798c1cfe3bfd4c27d68d5cee38ca617daThe Android Open Source Project synchronized (lock) { 440b1396870f92135aa140bd2b86221768dea5bc11dElliott Hughes checkNotClosed(); 44182a2dfcd2281c2f8042fd5f09c98bea1e728530fJesse Wilson return ((end - pos) > 0) || in.ready(); 442adc854b798c1cfe3bfd4c27d68d5cee38ca617daThe Android Open Source Project } 443adc854b798c1cfe3bfd4c27d68d5cee38ca617daThe Android Open Source Project } 444adc854b798c1cfe3bfd4c27d68d5cee38ca617daThe Android Open Source Project 445adc854b798c1cfe3bfd4c27d68d5cee38ca617daThe Android Open Source Project /** 446adc854b798c1cfe3bfd4c27d68d5cee38ca617daThe Android Open Source Project * Resets this reader's position to the last {@code mark()} location. 447adc854b798c1cfe3bfd4c27d68d5cee38ca617daThe Android Open Source Project * Invocations of {@code read()} and {@code skip()} will occur from this new 448adc854b798c1cfe3bfd4c27d68d5cee38ca617daThe Android Open Source Project * location. 449f33eae7e84eb6d3b0f4e86b59605bb3de73009f3Elliott Hughes * 450adc854b798c1cfe3bfd4c27d68d5cee38ca617daThe Android Open Source Project * @throws IOException 451adc854b798c1cfe3bfd4c27d68d5cee38ca617daThe Android Open Source Project * if this reader is closed or no mark has been set. 452adc854b798c1cfe3bfd4c27d68d5cee38ca617daThe Android Open Source Project * @see #mark(int) 453adc854b798c1cfe3bfd4c27d68d5cee38ca617daThe Android Open Source Project * @see #markSupported() 454adc854b798c1cfe3bfd4c27d68d5cee38ca617daThe Android Open Source Project */ 455adc854b798c1cfe3bfd4c27d68d5cee38ca617daThe Android Open Source Project @Override 456adc854b798c1cfe3bfd4c27d68d5cee38ca617daThe Android Open Source Project public void reset() throws IOException { 457adc854b798c1cfe3bfd4c27d68d5cee38ca617daThe Android Open Source Project synchronized (lock) { 458b1396870f92135aa140bd2b86221768dea5bc11dElliott Hughes checkNotClosed(); 45982a2dfcd2281c2f8042fd5f09c98bea1e728530fJesse Wilson if (mark == -1) { 460b1396870f92135aa140bd2b86221768dea5bc11dElliott Hughes throw new IOException("Invalid mark"); 461adc854b798c1cfe3bfd4c27d68d5cee38ca617daThe Android Open Source Project } 46282a2dfcd2281c2f8042fd5f09c98bea1e728530fJesse Wilson pos = mark; 463adc854b798c1cfe3bfd4c27d68d5cee38ca617daThe Android Open Source Project } 464adc854b798c1cfe3bfd4c27d68d5cee38ca617daThe Android Open Source Project } 465adc854b798c1cfe3bfd4c27d68d5cee38ca617daThe Android Open Source Project 466adc854b798c1cfe3bfd4c27d68d5cee38ca617daThe Android Open Source Project /** 467f9480f317cddcec859025833b748f096247a40aaElliott Hughes * Skips {@code byteCount} bytes in this stream. Subsequent calls to 468f9480f317cddcec859025833b748f096247a40aaElliott Hughes * {@code read} will not return these bytes unless {@code reset} is 469f9480f317cddcec859025833b748f096247a40aaElliott Hughes * used. 470f9480f317cddcec859025833b748f096247a40aaElliott Hughes * Skipping characters may invalidate a mark if {@code markLimit} 471adc854b798c1cfe3bfd4c27d68d5cee38ca617daThe Android Open Source Project * is surpassed. 472f33eae7e84eb6d3b0f4e86b59605bb3de73009f3Elliott Hughes * 473f9480f317cddcec859025833b748f096247a40aaElliott Hughes * @param byteCount 474adc854b798c1cfe3bfd4c27d68d5cee38ca617daThe Android Open Source Project * the maximum number of characters to skip. 475adc854b798c1cfe3bfd4c27d68d5cee38ca617daThe Android Open Source Project * @return the number of characters actually skipped. 476adc854b798c1cfe3bfd4c27d68d5cee38ca617daThe Android Open Source Project * @throws IllegalArgumentException 477f9480f317cddcec859025833b748f096247a40aaElliott Hughes * if {@code byteCount < 0}. 478adc854b798c1cfe3bfd4c27d68d5cee38ca617daThe Android Open Source Project * @throws IOException 479adc854b798c1cfe3bfd4c27d68d5cee38ca617daThe Android Open Source Project * if this reader is closed or some other I/O error occurs. 480adc854b798c1cfe3bfd4c27d68d5cee38ca617daThe Android Open Source Project * @see #mark(int) 481adc854b798c1cfe3bfd4c27d68d5cee38ca617daThe Android Open Source Project * @see #markSupported() 482adc854b798c1cfe3bfd4c27d68d5cee38ca617daThe Android Open Source Project * @see #reset() 483adc854b798c1cfe3bfd4c27d68d5cee38ca617daThe Android Open Source Project */ 484adc854b798c1cfe3bfd4c27d68d5cee38ca617daThe Android Open Source Project @Override 485f9480f317cddcec859025833b748f096247a40aaElliott Hughes public long skip(long byteCount) throws IOException { 486f9480f317cddcec859025833b748f096247a40aaElliott Hughes if (byteCount < 0) { 487a1603838fe9e865575c87982e32c6343740e464cElliott Hughes throw new IllegalArgumentException("byteCount < 0: " + byteCount); 488adc854b798c1cfe3bfd4c27d68d5cee38ca617daThe Android Open Source Project } 489adc854b798c1cfe3bfd4c27d68d5cee38ca617daThe Android Open Source Project synchronized (lock) { 490b1396870f92135aa140bd2b86221768dea5bc11dElliott Hughes checkNotClosed(); 491f9480f317cddcec859025833b748f096247a40aaElliott Hughes if (byteCount < 1) { 492adc854b798c1cfe3bfd4c27d68d5cee38ca617daThe Android Open Source Project return 0; 493adc854b798c1cfe3bfd4c27d68d5cee38ca617daThe Android Open Source Project } 494f9480f317cddcec859025833b748f096247a40aaElliott Hughes if (end - pos >= byteCount) { 495f9480f317cddcec859025833b748f096247a40aaElliott Hughes pos += byteCount; 496f9480f317cddcec859025833b748f096247a40aaElliott Hughes return byteCount; 497adc854b798c1cfe3bfd4c27d68d5cee38ca617daThe Android Open Source Project } 498adc854b798c1cfe3bfd4c27d68d5cee38ca617daThe Android Open Source Project 49982a2dfcd2281c2f8042fd5f09c98bea1e728530fJesse Wilson long read = end - pos; 50082a2dfcd2281c2f8042fd5f09c98bea1e728530fJesse Wilson pos = end; 501f9480f317cddcec859025833b748f096247a40aaElliott Hughes while (read < byteCount) { 50282a2dfcd2281c2f8042fd5f09c98bea1e728530fJesse Wilson if (fillBuf() == -1) { 503adc854b798c1cfe3bfd4c27d68d5cee38ca617daThe Android Open Source Project return read; 504adc854b798c1cfe3bfd4c27d68d5cee38ca617daThe Android Open Source Project } 505f9480f317cddcec859025833b748f096247a40aaElliott Hughes if (end - pos >= byteCount - read) { 506f9480f317cddcec859025833b748f096247a40aaElliott Hughes pos += byteCount - read; 507f9480f317cddcec859025833b748f096247a40aaElliott Hughes return byteCount; 508adc854b798c1cfe3bfd4c27d68d5cee38ca617daThe Android Open Source Project } 509adc854b798c1cfe3bfd4c27d68d5cee38ca617daThe Android Open Source Project // Couldn't get all the characters, skip what we read 51082a2dfcd2281c2f8042fd5f09c98bea1e728530fJesse Wilson read += (end - pos); 51182a2dfcd2281c2f8042fd5f09c98bea1e728530fJesse Wilson pos = end; 512adc854b798c1cfe3bfd4c27d68d5cee38ca617daThe Android Open Source Project } 513f9480f317cddcec859025833b748f096247a40aaElliott Hughes return byteCount; 514adc854b798c1cfe3bfd4c27d68d5cee38ca617daThe Android Open Source Project } 515adc854b798c1cfe3bfd4c27d68d5cee38ca617daThe Android Open Source Project } 516adc854b798c1cfe3bfd4c27d68d5cee38ca617daThe Android Open Source Project} 517