1bc47398187c6ffd132435e51d8d61e6ec79a79dbPaul Westbrook/* 2bc47398187c6ffd132435e51d8d61e6ec79a79dbPaul Westbrook * Licensed to the Apache Software Foundation (ASF) under one or more 3bc47398187c6ffd132435e51d8d61e6ec79a79dbPaul Westbrook * contributor license agreements. See the NOTICE file distributed with 4bc47398187c6ffd132435e51d8d61e6ec79a79dbPaul Westbrook * this work for additional information regarding copyright ownership. 5bc47398187c6ffd132435e51d8d61e6ec79a79dbPaul Westbrook * The ASF licenses this file to You under the Apache License, Version 2.0 6bc47398187c6ffd132435e51d8d61e6ec79a79dbPaul Westbrook * (the "License"); you may not use this file except in compliance with 7bc47398187c6ffd132435e51d8d61e6ec79a79dbPaul Westbrook * the License. You may obtain a copy of the License at 8bc47398187c6ffd132435e51d8d61e6ec79a79dbPaul Westbrook * 9bc47398187c6ffd132435e51d8d61e6ec79a79dbPaul Westbrook * http://www.apache.org/licenses/LICENSE-2.0 10bc47398187c6ffd132435e51d8d61e6ec79a79dbPaul Westbrook * 11bc47398187c6ffd132435e51d8d61e6ec79a79dbPaul Westbrook * Unless required by applicable law or agreed to in writing, software 12bc47398187c6ffd132435e51d8d61e6ec79a79dbPaul Westbrook * distributed under the License is distributed on an "AS IS" BASIS, 13bc47398187c6ffd132435e51d8d61e6ec79a79dbPaul Westbrook * WITHOUT WARRANTIES OR CONDITIONS OF ANY KIND, either express or implied. 14bc47398187c6ffd132435e51d8d61e6ec79a79dbPaul Westbrook * See the License for the specific language governing permissions and 15bc47398187c6ffd132435e51d8d61e6ec79a79dbPaul Westbrook * limitations under the License. 16bc47398187c6ffd132435e51d8d61e6ec79a79dbPaul Westbrook */ 17bc47398187c6ffd132435e51d8d61e6ec79a79dbPaul Westbrookpackage org.apache.commons.io.input; 18bc47398187c6ffd132435e51d8d61e6ec79a79dbPaul Westbrook 19bc47398187c6ffd132435e51d8d61e6ec79a79dbPaul Westbrookimport java.io.EOFException; 20bc47398187c6ffd132435e51d8d61e6ec79a79dbPaul Westbrookimport java.io.IOException; 21bc47398187c6ffd132435e51d8d61e6ec79a79dbPaul Westbrookimport java.io.InputStream; 22bc47398187c6ffd132435e51d8d61e6ec79a79dbPaul Westbrook 23bc47398187c6ffd132435e51d8d61e6ec79a79dbPaul Westbrook/** 24bc47398187c6ffd132435e51d8d61e6ec79a79dbPaul Westbrook * A functional, light weight {@link InputStream} that emulates 25bc47398187c6ffd132435e51d8d61e6ec79a79dbPaul Westbrook * a stream of a specified size. 26bc47398187c6ffd132435e51d8d61e6ec79a79dbPaul Westbrook * <p> 27bc47398187c6ffd132435e51d8d61e6ec79a79dbPaul Westbrook * This implementation provides a light weight 28bc47398187c6ffd132435e51d8d61e6ec79a79dbPaul Westbrook * object for testing with an {@link InputStream} 29bc47398187c6ffd132435e51d8d61e6ec79a79dbPaul Westbrook * where the contents don't matter. 30bc47398187c6ffd132435e51d8d61e6ec79a79dbPaul Westbrook * <p> 31bc47398187c6ffd132435e51d8d61e6ec79a79dbPaul Westbrook * One use case would be for testing the handling of 32bc47398187c6ffd132435e51d8d61e6ec79a79dbPaul Westbrook * large {@link InputStream} as it can emulate that 33bc47398187c6ffd132435e51d8d61e6ec79a79dbPaul Westbrook * scenario without the overhead of actually processing 34bc47398187c6ffd132435e51d8d61e6ec79a79dbPaul Westbrook * large numbers of bytes - significantly speeding up 35bc47398187c6ffd132435e51d8d61e6ec79a79dbPaul Westbrook * test execution times. 36bc47398187c6ffd132435e51d8d61e6ec79a79dbPaul Westbrook * <p> 37bc47398187c6ffd132435e51d8d61e6ec79a79dbPaul Westbrook * This implementation returns zero from the method that 38bc47398187c6ffd132435e51d8d61e6ec79a79dbPaul Westbrook * reads a byte and leaves the array unchanged in the read 39bc47398187c6ffd132435e51d8d61e6ec79a79dbPaul Westbrook * methods that are passed a byte array. 40bc47398187c6ffd132435e51d8d61e6ec79a79dbPaul Westbrook * If alternative data is required the <code>processByte()</code> and 41bc47398187c6ffd132435e51d8d61e6ec79a79dbPaul Westbrook * <code>processBytes()</code> methods can be implemented to generate 42bc47398187c6ffd132435e51d8d61e6ec79a79dbPaul Westbrook * data, for example: 43bc47398187c6ffd132435e51d8d61e6ec79a79dbPaul Westbrook * 44bc47398187c6ffd132435e51d8d61e6ec79a79dbPaul Westbrook * <pre> 45bc47398187c6ffd132435e51d8d61e6ec79a79dbPaul Westbrook * public class TestInputStream extends NullInputStream { 46bc47398187c6ffd132435e51d8d61e6ec79a79dbPaul Westbrook * public TestInputStream(int size) { 47bc47398187c6ffd132435e51d8d61e6ec79a79dbPaul Westbrook * super(size); 48bc47398187c6ffd132435e51d8d61e6ec79a79dbPaul Westbrook * } 49bc47398187c6ffd132435e51d8d61e6ec79a79dbPaul Westbrook * protected int processByte() { 50bc47398187c6ffd132435e51d8d61e6ec79a79dbPaul Westbrook * return ... // return required value here 51bc47398187c6ffd132435e51d8d61e6ec79a79dbPaul Westbrook * } 52bc47398187c6ffd132435e51d8d61e6ec79a79dbPaul Westbrook * protected void processBytes(byte[] bytes, int offset, int length) { 53bc47398187c6ffd132435e51d8d61e6ec79a79dbPaul Westbrook * for (int i = offset; i < length; i++) { 54bc47398187c6ffd132435e51d8d61e6ec79a79dbPaul Westbrook * bytes[i] = ... // set array value here 55bc47398187c6ffd132435e51d8d61e6ec79a79dbPaul Westbrook * } 56bc47398187c6ffd132435e51d8d61e6ec79a79dbPaul Westbrook * } 57bc47398187c6ffd132435e51d8d61e6ec79a79dbPaul Westbrook * } 58bc47398187c6ffd132435e51d8d61e6ec79a79dbPaul Westbrook * </pre> 59bc47398187c6ffd132435e51d8d61e6ec79a79dbPaul Westbrook * 60bc47398187c6ffd132435e51d8d61e6ec79a79dbPaul Westbrook * @since Commons IO 1.3 61bc47398187c6ffd132435e51d8d61e6ec79a79dbPaul Westbrook * @version $Revision: 463529 $ 62bc47398187c6ffd132435e51d8d61e6ec79a79dbPaul Westbrook */ 63bc47398187c6ffd132435e51d8d61e6ec79a79dbPaul Westbrookpublic class NullInputStream extends InputStream { 64bc47398187c6ffd132435e51d8d61e6ec79a79dbPaul Westbrook 65bc47398187c6ffd132435e51d8d61e6ec79a79dbPaul Westbrook private long size; 66bc47398187c6ffd132435e51d8d61e6ec79a79dbPaul Westbrook private long position; 67bc47398187c6ffd132435e51d8d61e6ec79a79dbPaul Westbrook private long mark = -1; 68bc47398187c6ffd132435e51d8d61e6ec79a79dbPaul Westbrook private long readlimit; 69bc47398187c6ffd132435e51d8d61e6ec79a79dbPaul Westbrook private boolean eof; 70bc47398187c6ffd132435e51d8d61e6ec79a79dbPaul Westbrook private boolean throwEofException; 71bc47398187c6ffd132435e51d8d61e6ec79a79dbPaul Westbrook private boolean markSupported; 72bc47398187c6ffd132435e51d8d61e6ec79a79dbPaul Westbrook 73bc47398187c6ffd132435e51d8d61e6ec79a79dbPaul Westbrook /** 74bc47398187c6ffd132435e51d8d61e6ec79a79dbPaul Westbrook * Create an {@link InputStream} that emulates a specified size 75bc47398187c6ffd132435e51d8d61e6ec79a79dbPaul Westbrook * which supports marking and does not throw EOFException. 76bc47398187c6ffd132435e51d8d61e6ec79a79dbPaul Westbrook * 77bc47398187c6ffd132435e51d8d61e6ec79a79dbPaul Westbrook * @param size The size of the input stream to emulate. 78bc47398187c6ffd132435e51d8d61e6ec79a79dbPaul Westbrook */ 79bc47398187c6ffd132435e51d8d61e6ec79a79dbPaul Westbrook public NullInputStream(long size) { 80bc47398187c6ffd132435e51d8d61e6ec79a79dbPaul Westbrook this(size, true, false); 81bc47398187c6ffd132435e51d8d61e6ec79a79dbPaul Westbrook } 82bc47398187c6ffd132435e51d8d61e6ec79a79dbPaul Westbrook 83bc47398187c6ffd132435e51d8d61e6ec79a79dbPaul Westbrook /** 84bc47398187c6ffd132435e51d8d61e6ec79a79dbPaul Westbrook * Create an {@link InputStream} that emulates a specified 85bc47398187c6ffd132435e51d8d61e6ec79a79dbPaul Westbrook * size with option settings. 86bc47398187c6ffd132435e51d8d61e6ec79a79dbPaul Westbrook * 87bc47398187c6ffd132435e51d8d61e6ec79a79dbPaul Westbrook * @param size The size of the input stream to emulate. 88bc47398187c6ffd132435e51d8d61e6ec79a79dbPaul Westbrook * @param markSupported Whether this instance will support 89bc47398187c6ffd132435e51d8d61e6ec79a79dbPaul Westbrook * the <code>mark()</code> functionality. 90bc47398187c6ffd132435e51d8d61e6ec79a79dbPaul Westbrook * @param throwEofException Whether this implementation 91bc47398187c6ffd132435e51d8d61e6ec79a79dbPaul Westbrook * will throw an {@link EOFException} or return -1 when the 92bc47398187c6ffd132435e51d8d61e6ec79a79dbPaul Westbrook * end of file is reached. 93bc47398187c6ffd132435e51d8d61e6ec79a79dbPaul Westbrook */ 94bc47398187c6ffd132435e51d8d61e6ec79a79dbPaul Westbrook public NullInputStream(long size, boolean markSupported, boolean throwEofException) { 95bc47398187c6ffd132435e51d8d61e6ec79a79dbPaul Westbrook this.size = size; 96bc47398187c6ffd132435e51d8d61e6ec79a79dbPaul Westbrook this.markSupported = markSupported; 97bc47398187c6ffd132435e51d8d61e6ec79a79dbPaul Westbrook this.throwEofException = throwEofException; 98bc47398187c6ffd132435e51d8d61e6ec79a79dbPaul Westbrook } 99bc47398187c6ffd132435e51d8d61e6ec79a79dbPaul Westbrook 100bc47398187c6ffd132435e51d8d61e6ec79a79dbPaul Westbrook /** 101bc47398187c6ffd132435e51d8d61e6ec79a79dbPaul Westbrook * Return the current position. 102bc47398187c6ffd132435e51d8d61e6ec79a79dbPaul Westbrook * 103bc47398187c6ffd132435e51d8d61e6ec79a79dbPaul Westbrook * @return the current position. 104bc47398187c6ffd132435e51d8d61e6ec79a79dbPaul Westbrook */ 105bc47398187c6ffd132435e51d8d61e6ec79a79dbPaul Westbrook public long getPosition() { 106bc47398187c6ffd132435e51d8d61e6ec79a79dbPaul Westbrook return position; 107bc47398187c6ffd132435e51d8d61e6ec79a79dbPaul Westbrook } 108bc47398187c6ffd132435e51d8d61e6ec79a79dbPaul Westbrook 109bc47398187c6ffd132435e51d8d61e6ec79a79dbPaul Westbrook /** 110bc47398187c6ffd132435e51d8d61e6ec79a79dbPaul Westbrook * Return the size this {@link InputStream} emulates. 111bc47398187c6ffd132435e51d8d61e6ec79a79dbPaul Westbrook * 112bc47398187c6ffd132435e51d8d61e6ec79a79dbPaul Westbrook * @return The size of the input stream to emulate. 113bc47398187c6ffd132435e51d8d61e6ec79a79dbPaul Westbrook */ 114bc47398187c6ffd132435e51d8d61e6ec79a79dbPaul Westbrook public long getSize() { 115bc47398187c6ffd132435e51d8d61e6ec79a79dbPaul Westbrook return size; 116bc47398187c6ffd132435e51d8d61e6ec79a79dbPaul Westbrook } 117bc47398187c6ffd132435e51d8d61e6ec79a79dbPaul Westbrook 118bc47398187c6ffd132435e51d8d61e6ec79a79dbPaul Westbrook /** 119bc47398187c6ffd132435e51d8d61e6ec79a79dbPaul Westbrook * Return the number of bytes that can be read. 120bc47398187c6ffd132435e51d8d61e6ec79a79dbPaul Westbrook * 121bc47398187c6ffd132435e51d8d61e6ec79a79dbPaul Westbrook * @return The number of bytes that can be read. 122bc47398187c6ffd132435e51d8d61e6ec79a79dbPaul Westbrook */ 123bc47398187c6ffd132435e51d8d61e6ec79a79dbPaul Westbrook public int available() { 124bc47398187c6ffd132435e51d8d61e6ec79a79dbPaul Westbrook long avail = size - position; 125bc47398187c6ffd132435e51d8d61e6ec79a79dbPaul Westbrook if (avail <= 0) { 126bc47398187c6ffd132435e51d8d61e6ec79a79dbPaul Westbrook return 0; 127bc47398187c6ffd132435e51d8d61e6ec79a79dbPaul Westbrook } else if (avail > Integer.MAX_VALUE) { 128bc47398187c6ffd132435e51d8d61e6ec79a79dbPaul Westbrook return Integer.MAX_VALUE; 129bc47398187c6ffd132435e51d8d61e6ec79a79dbPaul Westbrook } else { 130bc47398187c6ffd132435e51d8d61e6ec79a79dbPaul Westbrook return (int)avail; 131bc47398187c6ffd132435e51d8d61e6ec79a79dbPaul Westbrook } 132bc47398187c6ffd132435e51d8d61e6ec79a79dbPaul Westbrook } 133bc47398187c6ffd132435e51d8d61e6ec79a79dbPaul Westbrook 134bc47398187c6ffd132435e51d8d61e6ec79a79dbPaul Westbrook /** 135bc47398187c6ffd132435e51d8d61e6ec79a79dbPaul Westbrook * Close this input stream - resets the internal state to 136bc47398187c6ffd132435e51d8d61e6ec79a79dbPaul Westbrook * the initial values. 137bc47398187c6ffd132435e51d8d61e6ec79a79dbPaul Westbrook * 138bc47398187c6ffd132435e51d8d61e6ec79a79dbPaul Westbrook * @throws IOException If an error occurs. 139bc47398187c6ffd132435e51d8d61e6ec79a79dbPaul Westbrook */ 140bc47398187c6ffd132435e51d8d61e6ec79a79dbPaul Westbrook public void close() throws IOException { 141bc47398187c6ffd132435e51d8d61e6ec79a79dbPaul Westbrook eof = false; 142bc47398187c6ffd132435e51d8d61e6ec79a79dbPaul Westbrook position = 0; 143bc47398187c6ffd132435e51d8d61e6ec79a79dbPaul Westbrook mark = -1; 144bc47398187c6ffd132435e51d8d61e6ec79a79dbPaul Westbrook } 145bc47398187c6ffd132435e51d8d61e6ec79a79dbPaul Westbrook 146bc47398187c6ffd132435e51d8d61e6ec79a79dbPaul Westbrook /** 147bc47398187c6ffd132435e51d8d61e6ec79a79dbPaul Westbrook * Mark the current position. 148bc47398187c6ffd132435e51d8d61e6ec79a79dbPaul Westbrook * 149bc47398187c6ffd132435e51d8d61e6ec79a79dbPaul Westbrook * @param readlimit The number of bytes before this marked position 150bc47398187c6ffd132435e51d8d61e6ec79a79dbPaul Westbrook * is invalid. 151bc47398187c6ffd132435e51d8d61e6ec79a79dbPaul Westbrook * @throws UnsupportedOperationException if mark is not supported. 152bc47398187c6ffd132435e51d8d61e6ec79a79dbPaul Westbrook */ 153bc47398187c6ffd132435e51d8d61e6ec79a79dbPaul Westbrook public synchronized void mark(int readlimit) { 154bc47398187c6ffd132435e51d8d61e6ec79a79dbPaul Westbrook if (!markSupported) { 155bc47398187c6ffd132435e51d8d61e6ec79a79dbPaul Westbrook throw new UnsupportedOperationException("Mark not supported"); 156bc47398187c6ffd132435e51d8d61e6ec79a79dbPaul Westbrook } 157bc47398187c6ffd132435e51d8d61e6ec79a79dbPaul Westbrook mark = position; 158bc47398187c6ffd132435e51d8d61e6ec79a79dbPaul Westbrook this.readlimit = readlimit; 159bc47398187c6ffd132435e51d8d61e6ec79a79dbPaul Westbrook } 160bc47398187c6ffd132435e51d8d61e6ec79a79dbPaul Westbrook 161bc47398187c6ffd132435e51d8d61e6ec79a79dbPaul Westbrook /** 162bc47398187c6ffd132435e51d8d61e6ec79a79dbPaul Westbrook * Indicates whether <i>mark</i> is supported. 163bc47398187c6ffd132435e51d8d61e6ec79a79dbPaul Westbrook * 164bc47398187c6ffd132435e51d8d61e6ec79a79dbPaul Westbrook * @return Whether <i>mark</i> is supported or not. 165bc47398187c6ffd132435e51d8d61e6ec79a79dbPaul Westbrook */ 166bc47398187c6ffd132435e51d8d61e6ec79a79dbPaul Westbrook public boolean markSupported() { 167bc47398187c6ffd132435e51d8d61e6ec79a79dbPaul Westbrook return markSupported; 168bc47398187c6ffd132435e51d8d61e6ec79a79dbPaul Westbrook } 169bc47398187c6ffd132435e51d8d61e6ec79a79dbPaul Westbrook 170bc47398187c6ffd132435e51d8d61e6ec79a79dbPaul Westbrook /** 171bc47398187c6ffd132435e51d8d61e6ec79a79dbPaul Westbrook * Read a byte. 172bc47398187c6ffd132435e51d8d61e6ec79a79dbPaul Westbrook * 173bc47398187c6ffd132435e51d8d61e6ec79a79dbPaul Westbrook * @return Either The byte value returned by <code>processByte()</code> 174bc47398187c6ffd132435e51d8d61e6ec79a79dbPaul Westbrook * or <code>-1</code> if the end of file has been reached and 175bc47398187c6ffd132435e51d8d61e6ec79a79dbPaul Westbrook * <code>throwEofException</code> is set to <code>false</code>. 176bc47398187c6ffd132435e51d8d61e6ec79a79dbPaul Westbrook * @throws EOFException if the end of file is reached and 177bc47398187c6ffd132435e51d8d61e6ec79a79dbPaul Westbrook * <code>throwEofException</code> is set to <code>true</code>. 178bc47398187c6ffd132435e51d8d61e6ec79a79dbPaul Westbrook * @throws IOException if trying to read past the end of file. 179bc47398187c6ffd132435e51d8d61e6ec79a79dbPaul Westbrook */ 180bc47398187c6ffd132435e51d8d61e6ec79a79dbPaul Westbrook public int read() throws IOException { 181bc47398187c6ffd132435e51d8d61e6ec79a79dbPaul Westbrook if (eof) { 182bc47398187c6ffd132435e51d8d61e6ec79a79dbPaul Westbrook throw new IOException("Read after end of file"); 183bc47398187c6ffd132435e51d8d61e6ec79a79dbPaul Westbrook } 184bc47398187c6ffd132435e51d8d61e6ec79a79dbPaul Westbrook if (position == size) { 185bc47398187c6ffd132435e51d8d61e6ec79a79dbPaul Westbrook return doEndOfFile(); 186bc47398187c6ffd132435e51d8d61e6ec79a79dbPaul Westbrook } 187bc47398187c6ffd132435e51d8d61e6ec79a79dbPaul Westbrook position++; 188bc47398187c6ffd132435e51d8d61e6ec79a79dbPaul Westbrook return processByte(); 189bc47398187c6ffd132435e51d8d61e6ec79a79dbPaul Westbrook } 190bc47398187c6ffd132435e51d8d61e6ec79a79dbPaul Westbrook 191bc47398187c6ffd132435e51d8d61e6ec79a79dbPaul Westbrook /** 192bc47398187c6ffd132435e51d8d61e6ec79a79dbPaul Westbrook * Read some bytes into the specified array. 193bc47398187c6ffd132435e51d8d61e6ec79a79dbPaul Westbrook * 194bc47398187c6ffd132435e51d8d61e6ec79a79dbPaul Westbrook * @param bytes The byte array to read into 195bc47398187c6ffd132435e51d8d61e6ec79a79dbPaul Westbrook * @return The number of bytes read or <code>-1</code> 196bc47398187c6ffd132435e51d8d61e6ec79a79dbPaul Westbrook * if the end of file has been reached and 197bc47398187c6ffd132435e51d8d61e6ec79a79dbPaul Westbrook * <code>throwEofException</code> is set to <code>false</code>. 198bc47398187c6ffd132435e51d8d61e6ec79a79dbPaul Westbrook * @throws EOFException if the end of file is reached and 199bc47398187c6ffd132435e51d8d61e6ec79a79dbPaul Westbrook * <code>throwEofException</code> is set to <code>true</code>. 200bc47398187c6ffd132435e51d8d61e6ec79a79dbPaul Westbrook * @throws IOException if trying to read past the end of file. 201bc47398187c6ffd132435e51d8d61e6ec79a79dbPaul Westbrook */ 202bc47398187c6ffd132435e51d8d61e6ec79a79dbPaul Westbrook public int read(byte[] bytes) throws IOException { 203bc47398187c6ffd132435e51d8d61e6ec79a79dbPaul Westbrook return read(bytes, 0, bytes.length); 204bc47398187c6ffd132435e51d8d61e6ec79a79dbPaul Westbrook } 205bc47398187c6ffd132435e51d8d61e6ec79a79dbPaul Westbrook 206bc47398187c6ffd132435e51d8d61e6ec79a79dbPaul Westbrook /** 207bc47398187c6ffd132435e51d8d61e6ec79a79dbPaul Westbrook * Read the specified number bytes into an array. 208bc47398187c6ffd132435e51d8d61e6ec79a79dbPaul Westbrook * 209bc47398187c6ffd132435e51d8d61e6ec79a79dbPaul Westbrook * @param bytes The byte array to read into. 210bc47398187c6ffd132435e51d8d61e6ec79a79dbPaul Westbrook * @param offset The offset to start reading bytes into. 211bc47398187c6ffd132435e51d8d61e6ec79a79dbPaul Westbrook * @param length The number of bytes to read. 212bc47398187c6ffd132435e51d8d61e6ec79a79dbPaul Westbrook * @return The number of bytes read or <code>-1</code> 213bc47398187c6ffd132435e51d8d61e6ec79a79dbPaul Westbrook * if the end of file has been reached and 214bc47398187c6ffd132435e51d8d61e6ec79a79dbPaul Westbrook * <code>throwEofException</code> is set to <code>false</code>. 215bc47398187c6ffd132435e51d8d61e6ec79a79dbPaul Westbrook * @throws EOFException if the end of file is reached and 216bc47398187c6ffd132435e51d8d61e6ec79a79dbPaul Westbrook * <code>throwEofException</code> is set to <code>true</code>. 217bc47398187c6ffd132435e51d8d61e6ec79a79dbPaul Westbrook * @throws IOException if trying to read past the end of file. 218bc47398187c6ffd132435e51d8d61e6ec79a79dbPaul Westbrook */ 219bc47398187c6ffd132435e51d8d61e6ec79a79dbPaul Westbrook public int read(byte[] bytes, int offset, int length) throws IOException { 220bc47398187c6ffd132435e51d8d61e6ec79a79dbPaul Westbrook if (eof) { 221bc47398187c6ffd132435e51d8d61e6ec79a79dbPaul Westbrook throw new IOException("Read after end of file"); 222bc47398187c6ffd132435e51d8d61e6ec79a79dbPaul Westbrook } 223bc47398187c6ffd132435e51d8d61e6ec79a79dbPaul Westbrook if (position == size) { 224bc47398187c6ffd132435e51d8d61e6ec79a79dbPaul Westbrook return doEndOfFile(); 225bc47398187c6ffd132435e51d8d61e6ec79a79dbPaul Westbrook } 226bc47398187c6ffd132435e51d8d61e6ec79a79dbPaul Westbrook position += length; 227bc47398187c6ffd132435e51d8d61e6ec79a79dbPaul Westbrook int returnLength = length; 228bc47398187c6ffd132435e51d8d61e6ec79a79dbPaul Westbrook if (position > size) { 229bc47398187c6ffd132435e51d8d61e6ec79a79dbPaul Westbrook returnLength = length - (int)(position - size); 230bc47398187c6ffd132435e51d8d61e6ec79a79dbPaul Westbrook position = size; 231bc47398187c6ffd132435e51d8d61e6ec79a79dbPaul Westbrook } 232bc47398187c6ffd132435e51d8d61e6ec79a79dbPaul Westbrook processBytes(bytes, offset, returnLength); 233bc47398187c6ffd132435e51d8d61e6ec79a79dbPaul Westbrook return returnLength; 234bc47398187c6ffd132435e51d8d61e6ec79a79dbPaul Westbrook } 235bc47398187c6ffd132435e51d8d61e6ec79a79dbPaul Westbrook 236bc47398187c6ffd132435e51d8d61e6ec79a79dbPaul Westbrook /** 237bc47398187c6ffd132435e51d8d61e6ec79a79dbPaul Westbrook * Reset the stream to the point when mark was last called. 238bc47398187c6ffd132435e51d8d61e6ec79a79dbPaul Westbrook * 239bc47398187c6ffd132435e51d8d61e6ec79a79dbPaul Westbrook * @throws UnsupportedOperationException if mark is not supported. 240bc47398187c6ffd132435e51d8d61e6ec79a79dbPaul Westbrook * @throws IOException If no position has been marked 241bc47398187c6ffd132435e51d8d61e6ec79a79dbPaul Westbrook * or the read limit has been exceed since the last position was 242bc47398187c6ffd132435e51d8d61e6ec79a79dbPaul Westbrook * marked. 243bc47398187c6ffd132435e51d8d61e6ec79a79dbPaul Westbrook */ 244bc47398187c6ffd132435e51d8d61e6ec79a79dbPaul Westbrook public synchronized void reset() throws IOException { 245bc47398187c6ffd132435e51d8d61e6ec79a79dbPaul Westbrook if (!markSupported) { 246bc47398187c6ffd132435e51d8d61e6ec79a79dbPaul Westbrook throw new UnsupportedOperationException("Mark not supported"); 247bc47398187c6ffd132435e51d8d61e6ec79a79dbPaul Westbrook } 248bc47398187c6ffd132435e51d8d61e6ec79a79dbPaul Westbrook if (mark < 0) { 249bc47398187c6ffd132435e51d8d61e6ec79a79dbPaul Westbrook throw new IOException("No position has been marked"); 250bc47398187c6ffd132435e51d8d61e6ec79a79dbPaul Westbrook } 251bc47398187c6ffd132435e51d8d61e6ec79a79dbPaul Westbrook if (position > (mark + readlimit)) { 252bc47398187c6ffd132435e51d8d61e6ec79a79dbPaul Westbrook throw new IOException("Marked position [" + mark + 253bc47398187c6ffd132435e51d8d61e6ec79a79dbPaul Westbrook "] is no longer valid - passed the read limit [" + 254bc47398187c6ffd132435e51d8d61e6ec79a79dbPaul Westbrook readlimit + "]"); 255bc47398187c6ffd132435e51d8d61e6ec79a79dbPaul Westbrook } 256bc47398187c6ffd132435e51d8d61e6ec79a79dbPaul Westbrook position = mark; 257bc47398187c6ffd132435e51d8d61e6ec79a79dbPaul Westbrook eof = false; 258bc47398187c6ffd132435e51d8d61e6ec79a79dbPaul Westbrook } 259bc47398187c6ffd132435e51d8d61e6ec79a79dbPaul Westbrook 260bc47398187c6ffd132435e51d8d61e6ec79a79dbPaul Westbrook /** 261bc47398187c6ffd132435e51d8d61e6ec79a79dbPaul Westbrook * Skip a specified number of bytes. 262bc47398187c6ffd132435e51d8d61e6ec79a79dbPaul Westbrook * 263bc47398187c6ffd132435e51d8d61e6ec79a79dbPaul Westbrook * @param numberOfBytes The number of bytes to skip. 264bc47398187c6ffd132435e51d8d61e6ec79a79dbPaul Westbrook * @return The number of bytes skipped or <code>-1</code> 265bc47398187c6ffd132435e51d8d61e6ec79a79dbPaul Westbrook * if the end of file has been reached and 266bc47398187c6ffd132435e51d8d61e6ec79a79dbPaul Westbrook * <code>throwEofException</code> is set to <code>false</code>. 267bc47398187c6ffd132435e51d8d61e6ec79a79dbPaul Westbrook * @throws EOFException if the end of file is reached and 268bc47398187c6ffd132435e51d8d61e6ec79a79dbPaul Westbrook * <code>throwEofException</code> is set to <code>true</code>. 269bc47398187c6ffd132435e51d8d61e6ec79a79dbPaul Westbrook * @throws IOException if trying to read past the end of file. 270bc47398187c6ffd132435e51d8d61e6ec79a79dbPaul Westbrook */ 271bc47398187c6ffd132435e51d8d61e6ec79a79dbPaul Westbrook public long skip(long numberOfBytes) throws IOException { 272bc47398187c6ffd132435e51d8d61e6ec79a79dbPaul Westbrook if (eof) { 273bc47398187c6ffd132435e51d8d61e6ec79a79dbPaul Westbrook throw new IOException("Skip after end of file"); 274bc47398187c6ffd132435e51d8d61e6ec79a79dbPaul Westbrook } 275bc47398187c6ffd132435e51d8d61e6ec79a79dbPaul Westbrook if (position == size) { 276bc47398187c6ffd132435e51d8d61e6ec79a79dbPaul Westbrook return doEndOfFile(); 277bc47398187c6ffd132435e51d8d61e6ec79a79dbPaul Westbrook } 278bc47398187c6ffd132435e51d8d61e6ec79a79dbPaul Westbrook position += numberOfBytes; 279bc47398187c6ffd132435e51d8d61e6ec79a79dbPaul Westbrook long returnLength = numberOfBytes; 280bc47398187c6ffd132435e51d8d61e6ec79a79dbPaul Westbrook if (position > size) { 281bc47398187c6ffd132435e51d8d61e6ec79a79dbPaul Westbrook returnLength = numberOfBytes - (position - size); 282bc47398187c6ffd132435e51d8d61e6ec79a79dbPaul Westbrook position = size; 283bc47398187c6ffd132435e51d8d61e6ec79a79dbPaul Westbrook } 284bc47398187c6ffd132435e51d8d61e6ec79a79dbPaul Westbrook return returnLength; 285bc47398187c6ffd132435e51d8d61e6ec79a79dbPaul Westbrook } 286bc47398187c6ffd132435e51d8d61e6ec79a79dbPaul Westbrook 287bc47398187c6ffd132435e51d8d61e6ec79a79dbPaul Westbrook /** 288bc47398187c6ffd132435e51d8d61e6ec79a79dbPaul Westbrook * Return a byte value for the <code>read()</code> method. 289bc47398187c6ffd132435e51d8d61e6ec79a79dbPaul Westbrook * <p> 290bc47398187c6ffd132435e51d8d61e6ec79a79dbPaul Westbrook * This implementation returns zero. 291bc47398187c6ffd132435e51d8d61e6ec79a79dbPaul Westbrook * 292bc47398187c6ffd132435e51d8d61e6ec79a79dbPaul Westbrook * @return This implementation always returns zero. 293bc47398187c6ffd132435e51d8d61e6ec79a79dbPaul Westbrook */ 294bc47398187c6ffd132435e51d8d61e6ec79a79dbPaul Westbrook protected int processByte() { 295bc47398187c6ffd132435e51d8d61e6ec79a79dbPaul Westbrook // do nothing - overridable by subclass 296bc47398187c6ffd132435e51d8d61e6ec79a79dbPaul Westbrook return 0; 297bc47398187c6ffd132435e51d8d61e6ec79a79dbPaul Westbrook } 298bc47398187c6ffd132435e51d8d61e6ec79a79dbPaul Westbrook 299bc47398187c6ffd132435e51d8d61e6ec79a79dbPaul Westbrook /** 300bc47398187c6ffd132435e51d8d61e6ec79a79dbPaul Westbrook * Process the bytes for the <code>read(byte[], offset, length)</code> 301bc47398187c6ffd132435e51d8d61e6ec79a79dbPaul Westbrook * method. 302bc47398187c6ffd132435e51d8d61e6ec79a79dbPaul Westbrook * <p> 303bc47398187c6ffd132435e51d8d61e6ec79a79dbPaul Westbrook * This implementation leaves the byte array unchanged. 304bc47398187c6ffd132435e51d8d61e6ec79a79dbPaul Westbrook * 305bc47398187c6ffd132435e51d8d61e6ec79a79dbPaul Westbrook * @param bytes The byte array 306bc47398187c6ffd132435e51d8d61e6ec79a79dbPaul Westbrook * @param offset The offset to start at. 307bc47398187c6ffd132435e51d8d61e6ec79a79dbPaul Westbrook * @param length The number of bytes. 308bc47398187c6ffd132435e51d8d61e6ec79a79dbPaul Westbrook */ 309bc47398187c6ffd132435e51d8d61e6ec79a79dbPaul Westbrook protected void processBytes(byte[] bytes, int offset, int length) { 310bc47398187c6ffd132435e51d8d61e6ec79a79dbPaul Westbrook // do nothing - overridable by subclass 311bc47398187c6ffd132435e51d8d61e6ec79a79dbPaul Westbrook } 312bc47398187c6ffd132435e51d8d61e6ec79a79dbPaul Westbrook 313bc47398187c6ffd132435e51d8d61e6ec79a79dbPaul Westbrook /** 314bc47398187c6ffd132435e51d8d61e6ec79a79dbPaul Westbrook * Handle End of File. 315bc47398187c6ffd132435e51d8d61e6ec79a79dbPaul Westbrook * 316bc47398187c6ffd132435e51d8d61e6ec79a79dbPaul Westbrook * @return <code>-1</code> if <code>throwEofException</code> is 317bc47398187c6ffd132435e51d8d61e6ec79a79dbPaul Westbrook * set to <code>false</code> 318bc47398187c6ffd132435e51d8d61e6ec79a79dbPaul Westbrook * @throws EOFException if <code>throwEofException</code> is set 319bc47398187c6ffd132435e51d8d61e6ec79a79dbPaul Westbrook * to <code>true</code>. 320bc47398187c6ffd132435e51d8d61e6ec79a79dbPaul Westbrook */ 321bc47398187c6ffd132435e51d8d61e6ec79a79dbPaul Westbrook private int doEndOfFile() throws EOFException { 322bc47398187c6ffd132435e51d8d61e6ec79a79dbPaul Westbrook eof = true; 323bc47398187c6ffd132435e51d8d61e6ec79a79dbPaul Westbrook if (throwEofException) { 324bc47398187c6ffd132435e51d8d61e6ec79a79dbPaul Westbrook throw new EOFException(); 325bc47398187c6ffd132435e51d8d61e6ec79a79dbPaul Westbrook } 326bc47398187c6ffd132435e51d8d61e6ec79a79dbPaul Westbrook return -1; 327bc47398187c6ffd132435e51d8d61e6ec79a79dbPaul Westbrook } 328bc47398187c6ffd132435e51d8d61e6ec79a79dbPaul Westbrook 329bc47398187c6ffd132435e51d8d61e6ec79a79dbPaul Westbrook} 330