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 20b9cc455ed89df1a0cf4186c92b352c9649995d96Elliott Hughesimport java.util.Arrays; 21b9cc455ed89df1a0cf4186c92b352c9649995d96Elliott Hughes 22adc854b798c1cfe3bfd4c27d68d5cee38ca617daThe Android Open Source Project/** 23adc854b798c1cfe3bfd4c27d68d5cee38ca617daThe Android Open Source Project * Wraps an existing {@link Reader} and adds functionality to "push back" 24adc854b798c1cfe3bfd4c27d68d5cee38ca617daThe Android Open Source Project * characters that have been read, so that they can be read again. Parsers may 25adc854b798c1cfe3bfd4c27d68d5cee38ca617daThe Android Open Source Project * find this useful. The number of characters which may be pushed back can be 26adc854b798c1cfe3bfd4c27d68d5cee38ca617daThe Android Open Source Project * specified during construction. If the buffer of pushed back bytes is empty, 27adc854b798c1cfe3bfd4c27d68d5cee38ca617daThe Android Open Source Project * characters are read from the underlying reader. 28adc854b798c1cfe3bfd4c27d68d5cee38ca617daThe Android Open Source Project */ 29adc854b798c1cfe3bfd4c27d68d5cee38ca617daThe Android Open Source Projectpublic class PushbackReader extends FilterReader { 30adc854b798c1cfe3bfd4c27d68d5cee38ca617daThe Android Open Source Project /** 31adc854b798c1cfe3bfd4c27d68d5cee38ca617daThe Android Open Source Project * The {@code char} array containing the chars to read. 32adc854b798c1cfe3bfd4c27d68d5cee38ca617daThe Android Open Source Project */ 33adc854b798c1cfe3bfd4c27d68d5cee38ca617daThe Android Open Source Project char[] buf; 34adc854b798c1cfe3bfd4c27d68d5cee38ca617daThe Android Open Source Project 35adc854b798c1cfe3bfd4c27d68d5cee38ca617daThe Android Open Source Project /** 36adc854b798c1cfe3bfd4c27d68d5cee38ca617daThe Android Open Source Project * The current position within the char array {@code buf}. A value 37adc854b798c1cfe3bfd4c27d68d5cee38ca617daThe Android Open Source Project * equal to buf.length indicates no chars available. A value of 0 indicates 38adc854b798c1cfe3bfd4c27d68d5cee38ca617daThe Android Open Source Project * the buffer is full. 39adc854b798c1cfe3bfd4c27d68d5cee38ca617daThe Android Open Source Project */ 40adc854b798c1cfe3bfd4c27d68d5cee38ca617daThe Android Open Source Project int pos; 41adc854b798c1cfe3bfd4c27d68d5cee38ca617daThe Android Open Source Project 42adc854b798c1cfe3bfd4c27d68d5cee38ca617daThe Android Open Source Project /** 43adc854b798c1cfe3bfd4c27d68d5cee38ca617daThe Android Open Source Project * Constructs a new {@code PushbackReader} with the specified reader as 44adc854b798c1cfe3bfd4c27d68d5cee38ca617daThe Android Open Source Project * source. The size of the pushback buffer is set to the default value of 1 45adc854b798c1cfe3bfd4c27d68d5cee38ca617daThe Android Open Source Project * character. 46f5597e626ecf7949d249dea08c1a2964d890ec11Jesse Wilson * 47adc854b798c1cfe3bfd4c27d68d5cee38ca617daThe Android Open Source Project * @param in 48adc854b798c1cfe3bfd4c27d68d5cee38ca617daThe Android Open Source Project * the source reader. 49adc854b798c1cfe3bfd4c27d68d5cee38ca617daThe Android Open Source Project */ 50adc854b798c1cfe3bfd4c27d68d5cee38ca617daThe Android Open Source Project public PushbackReader(Reader in) { 51adc854b798c1cfe3bfd4c27d68d5cee38ca617daThe Android Open Source Project super(in); 52adc854b798c1cfe3bfd4c27d68d5cee38ca617daThe Android Open Source Project buf = new char[1]; 53adc854b798c1cfe3bfd4c27d68d5cee38ca617daThe Android Open Source Project pos = 1; 54adc854b798c1cfe3bfd4c27d68d5cee38ca617daThe Android Open Source Project } 55adc854b798c1cfe3bfd4c27d68d5cee38ca617daThe Android Open Source Project 56adc854b798c1cfe3bfd4c27d68d5cee38ca617daThe Android Open Source Project /** 57adc854b798c1cfe3bfd4c27d68d5cee38ca617daThe Android Open Source Project * Constructs a new {@code PushbackReader} with {@code in} as source reader. 58adc854b798c1cfe3bfd4c27d68d5cee38ca617daThe Android Open Source Project * The size of the pushback buffer is set to {@code size}. 59f5597e626ecf7949d249dea08c1a2964d890ec11Jesse Wilson * 60adc854b798c1cfe3bfd4c27d68d5cee38ca617daThe Android Open Source Project * @param in 61adc854b798c1cfe3bfd4c27d68d5cee38ca617daThe Android Open Source Project * the source reader. 62adc854b798c1cfe3bfd4c27d68d5cee38ca617daThe Android Open Source Project * @param size 63adc854b798c1cfe3bfd4c27d68d5cee38ca617daThe Android Open Source Project * the size of the pushback buffer. 64adc854b798c1cfe3bfd4c27d68d5cee38ca617daThe Android Open Source Project * @throws IllegalArgumentException 65adc854b798c1cfe3bfd4c27d68d5cee38ca617daThe Android Open Source Project * if {@code size} is negative. 66adc854b798c1cfe3bfd4c27d68d5cee38ca617daThe Android Open Source Project */ 67adc854b798c1cfe3bfd4c27d68d5cee38ca617daThe Android Open Source Project public PushbackReader(Reader in, int size) { 68adc854b798c1cfe3bfd4c27d68d5cee38ca617daThe Android Open Source Project super(in); 69adc854b798c1cfe3bfd4c27d68d5cee38ca617daThe Android Open Source Project if (size <= 0) { 70b1396870f92135aa140bd2b86221768dea5bc11dElliott Hughes throw new IllegalArgumentException("size <= 0"); 71adc854b798c1cfe3bfd4c27d68d5cee38ca617daThe Android Open Source Project } 72adc854b798c1cfe3bfd4c27d68d5cee38ca617daThe Android Open Source Project buf = new char[size]; 73adc854b798c1cfe3bfd4c27d68d5cee38ca617daThe Android Open Source Project pos = size; 74adc854b798c1cfe3bfd4c27d68d5cee38ca617daThe Android Open Source Project } 75adc854b798c1cfe3bfd4c27d68d5cee38ca617daThe Android Open Source Project 76adc854b798c1cfe3bfd4c27d68d5cee38ca617daThe Android Open Source Project /** 77adc854b798c1cfe3bfd4c27d68d5cee38ca617daThe Android Open Source Project * Closes this reader. This implementation closes the source reader 78adc854b798c1cfe3bfd4c27d68d5cee38ca617daThe Android Open Source Project * and releases the pushback buffer. 79f5597e626ecf7949d249dea08c1a2964d890ec11Jesse Wilson * 80adc854b798c1cfe3bfd4c27d68d5cee38ca617daThe Android Open Source Project * @throws IOException 81adc854b798c1cfe3bfd4c27d68d5cee38ca617daThe Android Open Source Project * if an error occurs while closing this reader. 82adc854b798c1cfe3bfd4c27d68d5cee38ca617daThe Android Open Source Project */ 83adc854b798c1cfe3bfd4c27d68d5cee38ca617daThe Android Open Source Project @Override 84adc854b798c1cfe3bfd4c27d68d5cee38ca617daThe Android Open Source Project public void close() throws IOException { 85adc854b798c1cfe3bfd4c27d68d5cee38ca617daThe Android Open Source Project synchronized (lock) { 86adc854b798c1cfe3bfd4c27d68d5cee38ca617daThe Android Open Source Project buf = null; 87adc854b798c1cfe3bfd4c27d68d5cee38ca617daThe Android Open Source Project in.close(); 88adc854b798c1cfe3bfd4c27d68d5cee38ca617daThe Android Open Source Project } 89adc854b798c1cfe3bfd4c27d68d5cee38ca617daThe Android Open Source Project } 90adc854b798c1cfe3bfd4c27d68d5cee38ca617daThe Android Open Source Project 91adc854b798c1cfe3bfd4c27d68d5cee38ca617daThe Android Open Source Project /** 92adc854b798c1cfe3bfd4c27d68d5cee38ca617daThe Android Open Source Project * Marks the current position in this stream. Setting a mark is not 93adc854b798c1cfe3bfd4c27d68d5cee38ca617daThe Android Open Source Project * supported in this class; this implementation always throws an 94adc854b798c1cfe3bfd4c27d68d5cee38ca617daThe Android Open Source Project * {@code IOException}. 95f5597e626ecf7949d249dea08c1a2964d890ec11Jesse Wilson * 96adc854b798c1cfe3bfd4c27d68d5cee38ca617daThe Android Open Source Project * @param readAheadLimit 97adc854b798c1cfe3bfd4c27d68d5cee38ca617daThe Android Open Source Project * the number of character that can be read from this reader 98adc854b798c1cfe3bfd4c27d68d5cee38ca617daThe Android Open Source Project * before the mark is invalidated; this parameter is ignored. 99adc854b798c1cfe3bfd4c27d68d5cee38ca617daThe Android Open Source Project * @throws IOException 100adc854b798c1cfe3bfd4c27d68d5cee38ca617daThe Android Open Source Project * if this method is called. 101adc854b798c1cfe3bfd4c27d68d5cee38ca617daThe Android Open Source Project */ 102adc854b798c1cfe3bfd4c27d68d5cee38ca617daThe Android Open Source Project @Override 103adc854b798c1cfe3bfd4c27d68d5cee38ca617daThe Android Open Source Project public void mark(int readAheadLimit) throws IOException { 104b1396870f92135aa140bd2b86221768dea5bc11dElliott Hughes throw new IOException("mark/reset not supported"); 105adc854b798c1cfe3bfd4c27d68d5cee38ca617daThe Android Open Source Project } 106adc854b798c1cfe3bfd4c27d68d5cee38ca617daThe Android Open Source Project 107adc854b798c1cfe3bfd4c27d68d5cee38ca617daThe Android Open Source Project /** 108adc854b798c1cfe3bfd4c27d68d5cee38ca617daThe Android Open Source Project * Indicates whether this reader supports the {@code mark(int)} and 109adc854b798c1cfe3bfd4c27d68d5cee38ca617daThe Android Open Source Project * {@code reset()} methods. {@code PushbackReader} does not support them, so 110adc854b798c1cfe3bfd4c27d68d5cee38ca617daThe Android Open Source Project * it returns {@code false}. 111f5597e626ecf7949d249dea08c1a2964d890ec11Jesse Wilson * 112adc854b798c1cfe3bfd4c27d68d5cee38ca617daThe Android Open Source Project * @return always {@code false}. 113adc854b798c1cfe3bfd4c27d68d5cee38ca617daThe Android Open Source Project * @see #mark(int) 114adc854b798c1cfe3bfd4c27d68d5cee38ca617daThe Android Open Source Project * @see #reset() 115adc854b798c1cfe3bfd4c27d68d5cee38ca617daThe Android Open Source Project */ 116adc854b798c1cfe3bfd4c27d68d5cee38ca617daThe Android Open Source Project @Override 117adc854b798c1cfe3bfd4c27d68d5cee38ca617daThe Android Open Source Project public boolean markSupported() { 118adc854b798c1cfe3bfd4c27d68d5cee38ca617daThe Android Open Source Project return false; 119adc854b798c1cfe3bfd4c27d68d5cee38ca617daThe Android Open Source Project } 120adc854b798c1cfe3bfd4c27d68d5cee38ca617daThe Android Open Source Project 121adc854b798c1cfe3bfd4c27d68d5cee38ca617daThe Android Open Source Project /** 122adc854b798c1cfe3bfd4c27d68d5cee38ca617daThe Android Open Source Project * Reads a single character from this reader and returns it as an integer 123adc854b798c1cfe3bfd4c27d68d5cee38ca617daThe Android Open Source Project * with the two higher-order bytes set to 0. Returns -1 if the end of the 124adc854b798c1cfe3bfd4c27d68d5cee38ca617daThe Android Open Source Project * reader has been reached. If the pushback buffer does not contain any 125adc854b798c1cfe3bfd4c27d68d5cee38ca617daThe Android Open Source Project * available characters then a character from the source reader is returned. 126adc854b798c1cfe3bfd4c27d68d5cee38ca617daThe Android Open Source Project * Blocks until one character has been read, the end of the source reader is 127adc854b798c1cfe3bfd4c27d68d5cee38ca617daThe Android Open Source Project * detected or an exception is thrown. 128f5597e626ecf7949d249dea08c1a2964d890ec11Jesse Wilson * 129adc854b798c1cfe3bfd4c27d68d5cee38ca617daThe Android Open Source Project * @return the character read or -1 if the end of the source reader has been 130adc854b798c1cfe3bfd4c27d68d5cee38ca617daThe Android Open Source Project * reached. 131adc854b798c1cfe3bfd4c27d68d5cee38ca617daThe Android Open Source Project * @throws IOException 132adc854b798c1cfe3bfd4c27d68d5cee38ca617daThe Android Open Source Project * if this reader is closed or an I/O error occurs while reading 133adc854b798c1cfe3bfd4c27d68d5cee38ca617daThe Android Open Source Project * from this reader. 134adc854b798c1cfe3bfd4c27d68d5cee38ca617daThe Android Open Source Project */ 135adc854b798c1cfe3bfd4c27d68d5cee38ca617daThe Android Open Source Project @Override 136adc854b798c1cfe3bfd4c27d68d5cee38ca617daThe Android Open Source Project public int read() throws IOException { 137adc854b798c1cfe3bfd4c27d68d5cee38ca617daThe Android Open Source Project synchronized (lock) { 138b1396870f92135aa140bd2b86221768dea5bc11dElliott Hughes checkNotClosed(); 139adc854b798c1cfe3bfd4c27d68d5cee38ca617daThe Android Open Source Project /* Is there a pushback character available? */ 140adc854b798c1cfe3bfd4c27d68d5cee38ca617daThe Android Open Source Project if (pos < buf.length) { 141adc854b798c1cfe3bfd4c27d68d5cee38ca617daThe Android Open Source Project return buf[pos++]; 142adc854b798c1cfe3bfd4c27d68d5cee38ca617daThe Android Open Source Project } 143adc854b798c1cfe3bfd4c27d68d5cee38ca617daThe Android Open Source Project /** 144adc854b798c1cfe3bfd4c27d68d5cee38ca617daThe Android Open Source Project * Assume read() in the InputStream will return 2 lowest-order bytes 145adc854b798c1cfe3bfd4c27d68d5cee38ca617daThe Android Open Source Project * or -1 if end of stream. 146adc854b798c1cfe3bfd4c27d68d5cee38ca617daThe Android Open Source Project */ 147adc854b798c1cfe3bfd4c27d68d5cee38ca617daThe Android Open Source Project return in.read(); 148adc854b798c1cfe3bfd4c27d68d5cee38ca617daThe Android Open Source Project } 149adc854b798c1cfe3bfd4c27d68d5cee38ca617daThe Android Open Source Project } 150adc854b798c1cfe3bfd4c27d68d5cee38ca617daThe Android Open Source Project 151b1396870f92135aa140bd2b86221768dea5bc11dElliott Hughes private void checkNotClosed() throws IOException { 152b1396870f92135aa140bd2b86221768dea5bc11dElliott Hughes if (buf == null) { 153b1396870f92135aa140bd2b86221768dea5bc11dElliott Hughes throw new IOException("PushbackReader is closed"); 154b1396870f92135aa140bd2b86221768dea5bc11dElliott Hughes } 155b1396870f92135aa140bd2b86221768dea5bc11dElliott Hughes } 156b1396870f92135aa140bd2b86221768dea5bc11dElliott Hughes 157adc854b798c1cfe3bfd4c27d68d5cee38ca617daThe Android Open Source Project /** 158adc854b798c1cfe3bfd4c27d68d5cee38ca617daThe Android Open Source Project * Reads at most {@code length} bytes from this reader and stores them in 159adc854b798c1cfe3bfd4c27d68d5cee38ca617daThe Android Open Source Project * byte array {@code buffer} starting at {@code offset}. Characters are 160adc854b798c1cfe3bfd4c27d68d5cee38ca617daThe Android Open Source Project * read from the pushback buffer first, then from the source reader if more 161adc854b798c1cfe3bfd4c27d68d5cee38ca617daThe Android Open Source Project * bytes are required. Blocks until {@code count} characters have been read, 162adc854b798c1cfe3bfd4c27d68d5cee38ca617daThe Android Open Source Project * the end of the source reader is detected or an exception is thrown. 163f5597e626ecf7949d249dea08c1a2964d890ec11Jesse Wilson * 164adc854b798c1cfe3bfd4c27d68d5cee38ca617daThe Android Open Source Project * @param buffer 165adc854b798c1cfe3bfd4c27d68d5cee38ca617daThe Android Open Source Project * the array in which to store the characters read from this 166adc854b798c1cfe3bfd4c27d68d5cee38ca617daThe Android Open Source Project * reader. 167adc854b798c1cfe3bfd4c27d68d5cee38ca617daThe Android Open Source Project * @param offset 168adc854b798c1cfe3bfd4c27d68d5cee38ca617daThe Android Open Source Project * the initial position in {@code buffer} to store the characters 169adc854b798c1cfe3bfd4c27d68d5cee38ca617daThe Android Open Source Project * read from this reader. 170adc854b798c1cfe3bfd4c27d68d5cee38ca617daThe Android Open Source Project * @param count 171adc854b798c1cfe3bfd4c27d68d5cee38ca617daThe Android Open Source Project * the maximum number of bytes to store in {@code buffer}. 172adc854b798c1cfe3bfd4c27d68d5cee38ca617daThe Android Open Source Project * @return the number of bytes read or -1 if the end of the source reader 173adc854b798c1cfe3bfd4c27d68d5cee38ca617daThe Android Open Source Project * has been reached. 174adc854b798c1cfe3bfd4c27d68d5cee38ca617daThe Android Open Source Project * @throws IndexOutOfBoundsException 175adc854b798c1cfe3bfd4c27d68d5cee38ca617daThe Android Open Source Project * if {@code offset < 0} or {@code count < 0}, or if 176adc854b798c1cfe3bfd4c27d68d5cee38ca617daThe Android Open Source Project * {@code offset + count} is greater than the length of 177adc854b798c1cfe3bfd4c27d68d5cee38ca617daThe Android Open Source Project * {@code buffer}. 178adc854b798c1cfe3bfd4c27d68d5cee38ca617daThe Android Open Source Project * @throws IOException 179adc854b798c1cfe3bfd4c27d68d5cee38ca617daThe Android Open Source Project * if this reader is closed or another I/O error occurs while 180adc854b798c1cfe3bfd4c27d68d5cee38ca617daThe Android Open Source Project * reading from this reader. 181adc854b798c1cfe3bfd4c27d68d5cee38ca617daThe Android Open Source Project */ 182adc854b798c1cfe3bfd4c27d68d5cee38ca617daThe Android Open Source Project @Override 183adc854b798c1cfe3bfd4c27d68d5cee38ca617daThe Android Open Source Project public int read(char[] buffer, int offset, int count) throws IOException { 184adc854b798c1cfe3bfd4c27d68d5cee38ca617daThe Android Open Source Project synchronized (lock) { 185b1396870f92135aa140bd2b86221768dea5bc11dElliott Hughes checkNotClosed(); 186a1603838fe9e865575c87982e32c6343740e464cElliott Hughes Arrays.checkOffsetAndCount(buffer.length, offset, count); 187adc854b798c1cfe3bfd4c27d68d5cee38ca617daThe Android Open Source Project 188adc854b798c1cfe3bfd4c27d68d5cee38ca617daThe Android Open Source Project int copiedChars = 0; 189adc854b798c1cfe3bfd4c27d68d5cee38ca617daThe Android Open Source Project int copyLength = 0; 190adc854b798c1cfe3bfd4c27d68d5cee38ca617daThe Android Open Source Project int newOffset = offset; 191adc854b798c1cfe3bfd4c27d68d5cee38ca617daThe Android Open Source Project /* Are there pushback chars available? */ 192adc854b798c1cfe3bfd4c27d68d5cee38ca617daThe Android Open Source Project if (pos < buf.length) { 193adc854b798c1cfe3bfd4c27d68d5cee38ca617daThe Android Open Source Project copyLength = (buf.length - pos >= count) ? count : buf.length 194adc854b798c1cfe3bfd4c27d68d5cee38ca617daThe Android Open Source Project - pos; 195adc854b798c1cfe3bfd4c27d68d5cee38ca617daThe Android Open Source Project System.arraycopy(buf, pos, buffer, newOffset, copyLength); 196adc854b798c1cfe3bfd4c27d68d5cee38ca617daThe Android Open Source Project newOffset += copyLength; 197adc854b798c1cfe3bfd4c27d68d5cee38ca617daThe Android Open Source Project copiedChars += copyLength; 198adc854b798c1cfe3bfd4c27d68d5cee38ca617daThe Android Open Source Project /* Use up the chars in the local buffer */ 199adc854b798c1cfe3bfd4c27d68d5cee38ca617daThe Android Open Source Project pos += copyLength; 200adc854b798c1cfe3bfd4c27d68d5cee38ca617daThe Android Open Source Project } 201adc854b798c1cfe3bfd4c27d68d5cee38ca617daThe Android Open Source Project /* Have we copied enough? */ 202adc854b798c1cfe3bfd4c27d68d5cee38ca617daThe Android Open Source Project if (copyLength == count) { 203adc854b798c1cfe3bfd4c27d68d5cee38ca617daThe Android Open Source Project return count; 204adc854b798c1cfe3bfd4c27d68d5cee38ca617daThe Android Open Source Project } 205adc854b798c1cfe3bfd4c27d68d5cee38ca617daThe Android Open Source Project int inCopied = in.read(buffer, newOffset, count - copiedChars); 206adc854b798c1cfe3bfd4c27d68d5cee38ca617daThe Android Open Source Project if (inCopied > 0) { 207adc854b798c1cfe3bfd4c27d68d5cee38ca617daThe Android Open Source Project return inCopied + copiedChars; 208adc854b798c1cfe3bfd4c27d68d5cee38ca617daThe Android Open Source Project } 209adc854b798c1cfe3bfd4c27d68d5cee38ca617daThe Android Open Source Project if (copiedChars == 0) { 210adc854b798c1cfe3bfd4c27d68d5cee38ca617daThe Android Open Source Project return inCopied; 211adc854b798c1cfe3bfd4c27d68d5cee38ca617daThe Android Open Source Project } 212adc854b798c1cfe3bfd4c27d68d5cee38ca617daThe Android Open Source Project return copiedChars; 213adc854b798c1cfe3bfd4c27d68d5cee38ca617daThe Android Open Source Project } 214adc854b798c1cfe3bfd4c27d68d5cee38ca617daThe Android Open Source Project } 215adc854b798c1cfe3bfd4c27d68d5cee38ca617daThe Android Open Source Project 216adc854b798c1cfe3bfd4c27d68d5cee38ca617daThe Android Open Source Project /** 217adc854b798c1cfe3bfd4c27d68d5cee38ca617daThe Android Open Source Project * Indicates whether this reader is ready to be read without blocking. 218adc854b798c1cfe3bfd4c27d68d5cee38ca617daThe Android Open Source Project * Returns {@code true} if this reader will not block when {@code read} is 219adc854b798c1cfe3bfd4c27d68d5cee38ca617daThe Android Open Source Project * called, {@code false} if unknown or blocking will occur. 220f5597e626ecf7949d249dea08c1a2964d890ec11Jesse Wilson * 221adc854b798c1cfe3bfd4c27d68d5cee38ca617daThe Android Open Source Project * @return {@code true} if the receiver will not block when 222adc854b798c1cfe3bfd4c27d68d5cee38ca617daThe Android Open Source Project * {@code read()} is called, {@code false} if unknown 223adc854b798c1cfe3bfd4c27d68d5cee38ca617daThe Android Open Source Project * or blocking will occur. 224adc854b798c1cfe3bfd4c27d68d5cee38ca617daThe Android Open Source Project * @throws IOException 225adc854b798c1cfe3bfd4c27d68d5cee38ca617daThe Android Open Source Project * if this reader is closed or some other I/O error occurs. 226adc854b798c1cfe3bfd4c27d68d5cee38ca617daThe Android Open Source Project * @see #read() 227adc854b798c1cfe3bfd4c27d68d5cee38ca617daThe Android Open Source Project * @see #read(char[], int, int) 228adc854b798c1cfe3bfd4c27d68d5cee38ca617daThe Android Open Source Project */ 229adc854b798c1cfe3bfd4c27d68d5cee38ca617daThe Android Open Source Project @Override 230adc854b798c1cfe3bfd4c27d68d5cee38ca617daThe Android Open Source Project public boolean ready() throws IOException { 231adc854b798c1cfe3bfd4c27d68d5cee38ca617daThe Android Open Source Project synchronized (lock) { 232adc854b798c1cfe3bfd4c27d68d5cee38ca617daThe Android Open Source Project if (buf == null) { 233b1396870f92135aa140bd2b86221768dea5bc11dElliott Hughes throw new IOException("Reader is closed"); 234adc854b798c1cfe3bfd4c27d68d5cee38ca617daThe Android Open Source Project } 235adc854b798c1cfe3bfd4c27d68d5cee38ca617daThe Android Open Source Project return (buf.length - pos > 0 || in.ready()); 236adc854b798c1cfe3bfd4c27d68d5cee38ca617daThe Android Open Source Project } 237adc854b798c1cfe3bfd4c27d68d5cee38ca617daThe Android Open Source Project } 238adc854b798c1cfe3bfd4c27d68d5cee38ca617daThe Android Open Source Project 239adc854b798c1cfe3bfd4c27d68d5cee38ca617daThe Android Open Source Project /** 240adc854b798c1cfe3bfd4c27d68d5cee38ca617daThe Android Open Source Project * Resets this reader to the last marked position. Resetting the reader is 241adc854b798c1cfe3bfd4c27d68d5cee38ca617daThe Android Open Source Project * not supported in this class; this implementation always throws an 242adc854b798c1cfe3bfd4c27d68d5cee38ca617daThe Android Open Source Project * {@code IOException}. 243f5597e626ecf7949d249dea08c1a2964d890ec11Jesse Wilson * 244adc854b798c1cfe3bfd4c27d68d5cee38ca617daThe Android Open Source Project * @throws IOException 245adc854b798c1cfe3bfd4c27d68d5cee38ca617daThe Android Open Source Project * if this method is called. 246adc854b798c1cfe3bfd4c27d68d5cee38ca617daThe Android Open Source Project */ 247adc854b798c1cfe3bfd4c27d68d5cee38ca617daThe Android Open Source Project @Override 248adc854b798c1cfe3bfd4c27d68d5cee38ca617daThe Android Open Source Project public void reset() throws IOException { 249b1396870f92135aa140bd2b86221768dea5bc11dElliott Hughes throw new IOException("mark/reset not supported"); 250adc854b798c1cfe3bfd4c27d68d5cee38ca617daThe Android Open Source Project } 251adc854b798c1cfe3bfd4c27d68d5cee38ca617daThe Android Open Source Project 252adc854b798c1cfe3bfd4c27d68d5cee38ca617daThe Android Open Source Project /** 253adc854b798c1cfe3bfd4c27d68d5cee38ca617daThe Android Open Source Project * Pushes all the characters in {@code buffer} back to this reader. The 254adc854b798c1cfe3bfd4c27d68d5cee38ca617daThe Android Open Source Project * characters are pushed back in such a way that the next character read 255adc854b798c1cfe3bfd4c27d68d5cee38ca617daThe Android Open Source Project * from this reader is buffer[0], then buffer[1] and so on. 256adc854b798c1cfe3bfd4c27d68d5cee38ca617daThe Android Open Source Project * <p> 257adc854b798c1cfe3bfd4c27d68d5cee38ca617daThe Android Open Source Project * If this reader's internal pushback buffer cannot store the entire 258adc854b798c1cfe3bfd4c27d68d5cee38ca617daThe Android Open Source Project * contents of {@code buffer}, an {@code IOException} is thrown. Parts of 259adc854b798c1cfe3bfd4c27d68d5cee38ca617daThe Android Open Source Project * {@code buffer} may have already been copied to the pushback buffer when 260adc854b798c1cfe3bfd4c27d68d5cee38ca617daThe Android Open Source Project * the exception is thrown. 261f5597e626ecf7949d249dea08c1a2964d890ec11Jesse Wilson * 262adc854b798c1cfe3bfd4c27d68d5cee38ca617daThe Android Open Source Project * @param buffer 263adc854b798c1cfe3bfd4c27d68d5cee38ca617daThe Android Open Source Project * the buffer containing the characters to push back to this 264adc854b798c1cfe3bfd4c27d68d5cee38ca617daThe Android Open Source Project * reader. 265adc854b798c1cfe3bfd4c27d68d5cee38ca617daThe Android Open Source Project * @throws IOException 266adc854b798c1cfe3bfd4c27d68d5cee38ca617daThe Android Open Source Project * if this reader is closed or the free space in the internal 267adc854b798c1cfe3bfd4c27d68d5cee38ca617daThe Android Open Source Project * pushback buffer is not sufficient to store the contents of 268adc854b798c1cfe3bfd4c27d68d5cee38ca617daThe Android Open Source Project * {@code buffer}. 269adc854b798c1cfe3bfd4c27d68d5cee38ca617daThe Android Open Source Project */ 270adc854b798c1cfe3bfd4c27d68d5cee38ca617daThe Android Open Source Project public void unread(char[] buffer) throws IOException { 271adc854b798c1cfe3bfd4c27d68d5cee38ca617daThe Android Open Source Project unread(buffer, 0, buffer.length); 272adc854b798c1cfe3bfd4c27d68d5cee38ca617daThe Android Open Source Project } 273adc854b798c1cfe3bfd4c27d68d5cee38ca617daThe Android Open Source Project 274adc854b798c1cfe3bfd4c27d68d5cee38ca617daThe Android Open Source Project /** 275adc854b798c1cfe3bfd4c27d68d5cee38ca617daThe Android Open Source Project * Pushes a subset of the characters in {@code buffer} back to this reader. 276adc854b798c1cfe3bfd4c27d68d5cee38ca617daThe Android Open Source Project * The subset is defined by the start position {@code offset} within 277adc854b798c1cfe3bfd4c27d68d5cee38ca617daThe Android Open Source Project * {@code buffer} and the number of characters specified by {@code length}. 278adc854b798c1cfe3bfd4c27d68d5cee38ca617daThe Android Open Source Project * The bytes are pushed back in such a way that the next byte read from this 279adc854b798c1cfe3bfd4c27d68d5cee38ca617daThe Android Open Source Project * stream is {@code buffer[offset]}, then {@code buffer[1]} and so on. 280adc854b798c1cfe3bfd4c27d68d5cee38ca617daThe Android Open Source Project * <p> 281adc854b798c1cfe3bfd4c27d68d5cee38ca617daThe Android Open Source Project * If this stream's internal pushback buffer cannot store the selected 282adc854b798c1cfe3bfd4c27d68d5cee38ca617daThe Android Open Source Project * subset of {@code buffer}, an {@code IOException} is thrown. Parts of 283adc854b798c1cfe3bfd4c27d68d5cee38ca617daThe Android Open Source Project * {@code buffer} may have already been copied to the pushback buffer when 284adc854b798c1cfe3bfd4c27d68d5cee38ca617daThe Android Open Source Project * the exception is thrown. 285f5597e626ecf7949d249dea08c1a2964d890ec11Jesse Wilson * 286adc854b798c1cfe3bfd4c27d68d5cee38ca617daThe Android Open Source Project * @param buffer 287adc854b798c1cfe3bfd4c27d68d5cee38ca617daThe Android Open Source Project * the buffer containing the characters to push back to this 288adc854b798c1cfe3bfd4c27d68d5cee38ca617daThe Android Open Source Project * reader. 289adc854b798c1cfe3bfd4c27d68d5cee38ca617daThe Android Open Source Project * @param offset 290adc854b798c1cfe3bfd4c27d68d5cee38ca617daThe Android Open Source Project * the index of the first byte in {@code buffer} to push back. 2915839b909d9528b7726e678a4b696ed37df15d897Jesse Wilson * @param length 292adc854b798c1cfe3bfd4c27d68d5cee38ca617daThe Android Open Source Project * the number of bytes to push back. 293adc854b798c1cfe3bfd4c27d68d5cee38ca617daThe Android Open Source Project * @throws IndexOutOfBoundsException 294adc854b798c1cfe3bfd4c27d68d5cee38ca617daThe Android Open Source Project * if {@code offset < 0} or {@code count < 0}, or if 295adc854b798c1cfe3bfd4c27d68d5cee38ca617daThe Android Open Source Project * {@code offset + count} is greater than the length of 296adc854b798c1cfe3bfd4c27d68d5cee38ca617daThe Android Open Source Project * {@code buffer}. 297adc854b798c1cfe3bfd4c27d68d5cee38ca617daThe Android Open Source Project * @throws IOException 298adc854b798c1cfe3bfd4c27d68d5cee38ca617daThe Android Open Source Project * if this reader is closed or the free space in the internal 299adc854b798c1cfe3bfd4c27d68d5cee38ca617daThe Android Open Source Project * pushback buffer is not sufficient to store the selected 300adc854b798c1cfe3bfd4c27d68d5cee38ca617daThe Android Open Source Project * contents of {@code buffer}. 301adc854b798c1cfe3bfd4c27d68d5cee38ca617daThe Android Open Source Project * @throws NullPointerException 302adc854b798c1cfe3bfd4c27d68d5cee38ca617daThe Android Open Source Project * if {@code buffer} is {@code null}. 303adc854b798c1cfe3bfd4c27d68d5cee38ca617daThe Android Open Source Project */ 3045839b909d9528b7726e678a4b696ed37df15d897Jesse Wilson public void unread(char[] buffer, int offset, int length) throws IOException { 305adc854b798c1cfe3bfd4c27d68d5cee38ca617daThe Android Open Source Project synchronized (lock) { 306b1396870f92135aa140bd2b86221768dea5bc11dElliott Hughes checkNotClosed(); 3075839b909d9528b7726e678a4b696ed37df15d897Jesse Wilson if (length > pos) { 308b1396870f92135aa140bd2b86221768dea5bc11dElliott Hughes throw new IOException("Pushback buffer full"); 309adc854b798c1cfe3bfd4c27d68d5cee38ca617daThe Android Open Source Project } 310b9cc455ed89df1a0cf4186c92b352c9649995d96Elliott Hughes Arrays.checkOffsetAndCount(buffer.length, offset, length); 3115839b909d9528b7726e678a4b696ed37df15d897Jesse Wilson for (int i = offset + length - 1; i >= offset; i--) { 312adc854b798c1cfe3bfd4c27d68d5cee38ca617daThe Android Open Source Project unread(buffer[i]); 313adc854b798c1cfe3bfd4c27d68d5cee38ca617daThe Android Open Source Project } 314adc854b798c1cfe3bfd4c27d68d5cee38ca617daThe Android Open Source Project } 315adc854b798c1cfe3bfd4c27d68d5cee38ca617daThe Android Open Source Project } 316adc854b798c1cfe3bfd4c27d68d5cee38ca617daThe Android Open Source Project 317adc854b798c1cfe3bfd4c27d68d5cee38ca617daThe Android Open Source Project /** 318adc854b798c1cfe3bfd4c27d68d5cee38ca617daThe Android Open Source Project * Pushes the specified character {@code oneChar} back to this reader. This 319adc854b798c1cfe3bfd4c27d68d5cee38ca617daThe Android Open Source Project * is done in such a way that the next character read from this reader is 320adc854b798c1cfe3bfd4c27d68d5cee38ca617daThe Android Open Source Project * {@code (char) oneChar}. 321adc854b798c1cfe3bfd4c27d68d5cee38ca617daThe Android Open Source Project * <p> 322adc854b798c1cfe3bfd4c27d68d5cee38ca617daThe Android Open Source Project * If this reader's internal pushback buffer cannot store the character, an 323adc854b798c1cfe3bfd4c27d68d5cee38ca617daThe Android Open Source Project * {@code IOException} is thrown. 324f5597e626ecf7949d249dea08c1a2964d890ec11Jesse Wilson * 325adc854b798c1cfe3bfd4c27d68d5cee38ca617daThe Android Open Source Project * @param oneChar 326adc854b798c1cfe3bfd4c27d68d5cee38ca617daThe Android Open Source Project * the character to push back to this stream. 327adc854b798c1cfe3bfd4c27d68d5cee38ca617daThe Android Open Source Project * @throws IOException 328adc854b798c1cfe3bfd4c27d68d5cee38ca617daThe Android Open Source Project * if this reader is closed or the internal pushback buffer is 329adc854b798c1cfe3bfd4c27d68d5cee38ca617daThe Android Open Source Project * full. 330adc854b798c1cfe3bfd4c27d68d5cee38ca617daThe Android Open Source Project */ 331adc854b798c1cfe3bfd4c27d68d5cee38ca617daThe Android Open Source Project public void unread(int oneChar) throws IOException { 332adc854b798c1cfe3bfd4c27d68d5cee38ca617daThe Android Open Source Project synchronized (lock) { 333b1396870f92135aa140bd2b86221768dea5bc11dElliott Hughes checkNotClosed(); 334adc854b798c1cfe3bfd4c27d68d5cee38ca617daThe Android Open Source Project if (pos == 0) { 335b1396870f92135aa140bd2b86221768dea5bc11dElliott Hughes throw new IOException("Pushback buffer full"); 336adc854b798c1cfe3bfd4c27d68d5cee38ca617daThe Android Open Source Project } 337adc854b798c1cfe3bfd4c27d68d5cee38ca617daThe Android Open Source Project buf[--pos] = (char) oneChar; 338adc854b798c1cfe3bfd4c27d68d5cee38ca617daThe Android Open Source Project } 339adc854b798c1cfe3bfd4c27d68d5cee38ca617daThe Android Open Source Project } 340adc854b798c1cfe3bfd4c27d68d5cee38ca617daThe Android Open Source Project 341adc854b798c1cfe3bfd4c27d68d5cee38ca617daThe Android Open Source Project /** 342f9480f317cddcec859025833b748f096247a40aaElliott Hughes * Skips {@code charCount} characters in this reader. This implementation skips 343adc854b798c1cfe3bfd4c27d68d5cee38ca617daThe Android Open Source Project * characters in the pushback buffer first and then in the source reader if 344adc854b798c1cfe3bfd4c27d68d5cee38ca617daThe Android Open Source Project * necessary. 345f5597e626ecf7949d249dea08c1a2964d890ec11Jesse Wilson * 346adc854b798c1cfe3bfd4c27d68d5cee38ca617daThe Android Open Source Project * @return the number of characters actually skipped. 347f9480f317cddcec859025833b748f096247a40aaElliott Hughes * @throws IllegalArgumentException if {@code charCount < 0}. 348adc854b798c1cfe3bfd4c27d68d5cee38ca617daThe Android Open Source Project * @throws IOException 349adc854b798c1cfe3bfd4c27d68d5cee38ca617daThe Android Open Source Project * if this reader is closed or another I/O error occurs. 350adc854b798c1cfe3bfd4c27d68d5cee38ca617daThe Android Open Source Project */ 351adc854b798c1cfe3bfd4c27d68d5cee38ca617daThe Android Open Source Project @Override 352f9480f317cddcec859025833b748f096247a40aaElliott Hughes public long skip(long charCount) throws IOException { 353f9480f317cddcec859025833b748f096247a40aaElliott Hughes if (charCount < 0) { 354a1603838fe9e865575c87982e32c6343740e464cElliott Hughes throw new IllegalArgumentException("charCount < 0: " + charCount); 355adc854b798c1cfe3bfd4c27d68d5cee38ca617daThe Android Open Source Project } 356adc854b798c1cfe3bfd4c27d68d5cee38ca617daThe Android Open Source Project synchronized (lock) { 357b1396870f92135aa140bd2b86221768dea5bc11dElliott Hughes checkNotClosed(); 358f9480f317cddcec859025833b748f096247a40aaElliott Hughes if (charCount == 0) { 359adc854b798c1cfe3bfd4c27d68d5cee38ca617daThe Android Open Source Project return 0; 360adc854b798c1cfe3bfd4c27d68d5cee38ca617daThe Android Open Source Project } 361adc854b798c1cfe3bfd4c27d68d5cee38ca617daThe Android Open Source Project long inSkipped; 362adc854b798c1cfe3bfd4c27d68d5cee38ca617daThe Android Open Source Project int availableFromBuffer = buf.length - pos; 363adc854b798c1cfe3bfd4c27d68d5cee38ca617daThe Android Open Source Project if (availableFromBuffer > 0) { 364f9480f317cddcec859025833b748f096247a40aaElliott Hughes long requiredFromIn = charCount - availableFromBuffer; 365adc854b798c1cfe3bfd4c27d68d5cee38ca617daThe Android Open Source Project if (requiredFromIn <= 0) { 366f9480f317cddcec859025833b748f096247a40aaElliott Hughes pos += charCount; 367f9480f317cddcec859025833b748f096247a40aaElliott Hughes return charCount; 368adc854b798c1cfe3bfd4c27d68d5cee38ca617daThe Android Open Source Project } 369adc854b798c1cfe3bfd4c27d68d5cee38ca617daThe Android Open Source Project pos += availableFromBuffer; 370adc854b798c1cfe3bfd4c27d68d5cee38ca617daThe Android Open Source Project inSkipped = in.skip(requiredFromIn); 371adc854b798c1cfe3bfd4c27d68d5cee38ca617daThe Android Open Source Project } else { 372f9480f317cddcec859025833b748f096247a40aaElliott Hughes inSkipped = in.skip(charCount); 373adc854b798c1cfe3bfd4c27d68d5cee38ca617daThe Android Open Source Project } 374adc854b798c1cfe3bfd4c27d68d5cee38ca617daThe Android Open Source Project return inSkipped + availableFromBuffer; 375adc854b798c1cfe3bfd4c27d68d5cee38ca617daThe Android Open Source Project } 376adc854b798c1cfe3bfd4c27d68d5cee38ca617daThe Android Open Source Project } 377adc854b798c1cfe3bfd4c27d68d5cee38ca617daThe Android Open Source Project} 378