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.Reader;
22bc47398187c6ffd132435e51d8d61e6ec79a79dbPaul Westbrook
23bc47398187c6ffd132435e51d8d61e6ec79a79dbPaul Westbrook/**
24bc47398187c6ffd132435e51d8d61e6ec79a79dbPaul Westbrook * A functional, light weight {@link Reader} that emulates
25bc47398187c6ffd132435e51d8d61e6ec79a79dbPaul Westbrook * a reader of a specified size.
26bc47398187c6ffd132435e51d8d61e6ec79a79dbPaul Westbrook * <p>
27bc47398187c6ffd132435e51d8d61e6ec79a79dbPaul Westbrook * This implementation provides a light weight
28bc47398187c6ffd132435e51d8d61e6ec79a79dbPaul Westbrook * object for testing with an {@link Reader}
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 Reader} as it can emulate that
33bc47398187c6ffd132435e51d8d61e6ec79a79dbPaul Westbrook * scenario without the overhead of actually processing
34bc47398187c6ffd132435e51d8d61e6ec79a79dbPaul Westbrook * large numbers of characters - significantly speeding up
35bc47398187c6ffd132435e51d8d61e6ec79a79dbPaul Westbrook * test execution times.
36bc47398187c6ffd132435e51d8d61e6ec79a79dbPaul Westbrook * <p>
37bc47398187c6ffd132435e51d8d61e6ec79a79dbPaul Westbrook * This implementation returns a space from the method that
38bc47398187c6ffd132435e51d8d61e6ec79a79dbPaul Westbrook * reads a character and leaves the array unchanged in the read
39bc47398187c6ffd132435e51d8d61e6ec79a79dbPaul Westbrook * methods that are passed a character array.
40bc47398187c6ffd132435e51d8d61e6ec79a79dbPaul Westbrook * If alternative data is required the <code>processChar()</code> and
41bc47398187c6ffd132435e51d8d61e6ec79a79dbPaul Westbrook * <code>processChars()</code> methods can be implemented to generate
42bc47398187c6ffd132435e51d8d61e6ec79a79dbPaul Westbrook * data, for example:
43bc47398187c6ffd132435e51d8d61e6ec79a79dbPaul Westbrook *
44bc47398187c6ffd132435e51d8d61e6ec79a79dbPaul Westbrook * <pre>
45bc47398187c6ffd132435e51d8d61e6ec79a79dbPaul Westbrook *  public class TestReader extends NullReader {
46bc47398187c6ffd132435e51d8d61e6ec79a79dbPaul Westbrook *      public TestReader(int size) {
47bc47398187c6ffd132435e51d8d61e6ec79a79dbPaul Westbrook *          super(size);
48bc47398187c6ffd132435e51d8d61e6ec79a79dbPaul Westbrook *      }
49bc47398187c6ffd132435e51d8d61e6ec79a79dbPaul Westbrook *      protected char processChar() {
50bc47398187c6ffd132435e51d8d61e6ec79a79dbPaul Westbrook *          return ... // return required value here
51bc47398187c6ffd132435e51d8d61e6ec79a79dbPaul Westbrook *      }
52bc47398187c6ffd132435e51d8d61e6ec79a79dbPaul Westbrook *      protected void processChars(char[] chars, int offset, int length) {
53bc47398187c6ffd132435e51d8d61e6ec79a79dbPaul Westbrook *          for (int i = offset; i < length; i++) {
54bc47398187c6ffd132435e51d8d61e6ec79a79dbPaul Westbrook *              chars[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 NullReader extends Reader {
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 a {@link Reader} 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 reader to emulate.
78bc47398187c6ffd132435e51d8d61e6ec79a79dbPaul Westbrook     */
79bc47398187c6ffd132435e51d8d61e6ec79a79dbPaul Westbrook    public NullReader(long size) {
80bc47398187c6ffd132435e51d8d61e6ec79a79dbPaul Westbrook       this(size, true, false);
81bc47398187c6ffd132435e51d8d61e6ec79a79dbPaul Westbrook    }
82bc47398187c6ffd132435e51d8d61e6ec79a79dbPaul Westbrook
83bc47398187c6ffd132435e51d8d61e6ec79a79dbPaul Westbrook    /**
84bc47398187c6ffd132435e51d8d61e6ec79a79dbPaul Westbrook     * Create a {@link Reader} that emulates a specified
85bc47398187c6ffd132435e51d8d61e6ec79a79dbPaul Westbrook     * size with option settings.
86bc47398187c6ffd132435e51d8d61e6ec79a79dbPaul Westbrook     *
87bc47398187c6ffd132435e51d8d61e6ec79a79dbPaul Westbrook     * @param size The size of the reader 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 NullReader(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 Reader} emulates.
111bc47398187c6ffd132435e51d8d61e6ec79a79dbPaul Westbrook     *
112bc47398187c6ffd132435e51d8d61e6ec79a79dbPaul Westbrook     * @return The size of the reader to emulate.
113bc47398187c6ffd132435e51d8d61e6ec79a79dbPaul Westbrook     */
114bc47398187c6ffd132435e51d8d61e6ec79a79dbPaul Westbrook    public long getSize() {
115bc47398187c6ffd132435e51d8d61e6ec79a79dbPaul Westbrook        return size;
116bc47398187c6ffd132435e51d8d61e6ec79a79dbPaul Westbrook    }
117bc47398187c6ffd132435e51d8d61e6ec79a79dbPaul Westbrook
118bc47398187c6ffd132435e51d8d61e6ec79a79dbPaul Westbrook    /**
119bc47398187c6ffd132435e51d8d61e6ec79a79dbPaul Westbrook     * Close this Reader - resets the internal state to
120bc47398187c6ffd132435e51d8d61e6ec79a79dbPaul Westbrook     * the initial values.
121bc47398187c6ffd132435e51d8d61e6ec79a79dbPaul Westbrook     *
122bc47398187c6ffd132435e51d8d61e6ec79a79dbPaul Westbrook     * @throws IOException If an error occurs.
123bc47398187c6ffd132435e51d8d61e6ec79a79dbPaul Westbrook     */
124bc47398187c6ffd132435e51d8d61e6ec79a79dbPaul Westbrook    public void close() throws IOException {
125bc47398187c6ffd132435e51d8d61e6ec79a79dbPaul Westbrook        eof = false;
126bc47398187c6ffd132435e51d8d61e6ec79a79dbPaul Westbrook        position = 0;
127bc47398187c6ffd132435e51d8d61e6ec79a79dbPaul Westbrook        mark = -1;
128bc47398187c6ffd132435e51d8d61e6ec79a79dbPaul Westbrook    }
129bc47398187c6ffd132435e51d8d61e6ec79a79dbPaul Westbrook
130bc47398187c6ffd132435e51d8d61e6ec79a79dbPaul Westbrook    /**
131bc47398187c6ffd132435e51d8d61e6ec79a79dbPaul Westbrook     * Mark the current position.
132bc47398187c6ffd132435e51d8d61e6ec79a79dbPaul Westbrook     *
133bc47398187c6ffd132435e51d8d61e6ec79a79dbPaul Westbrook     * @param readlimit The number of characters before this marked position
134bc47398187c6ffd132435e51d8d61e6ec79a79dbPaul Westbrook     * is invalid.
135bc47398187c6ffd132435e51d8d61e6ec79a79dbPaul Westbrook     * @throws UnsupportedOperationException if mark is not supported.
136bc47398187c6ffd132435e51d8d61e6ec79a79dbPaul Westbrook     */
137bc47398187c6ffd132435e51d8d61e6ec79a79dbPaul Westbrook    public synchronized void mark(int readlimit) {
138bc47398187c6ffd132435e51d8d61e6ec79a79dbPaul Westbrook        if (!markSupported) {
139bc47398187c6ffd132435e51d8d61e6ec79a79dbPaul Westbrook            throw new UnsupportedOperationException("Mark not supported");
140bc47398187c6ffd132435e51d8d61e6ec79a79dbPaul Westbrook        }
141bc47398187c6ffd132435e51d8d61e6ec79a79dbPaul Westbrook        mark = position;
142bc47398187c6ffd132435e51d8d61e6ec79a79dbPaul Westbrook        this.readlimit = readlimit;
143bc47398187c6ffd132435e51d8d61e6ec79a79dbPaul Westbrook    }
144bc47398187c6ffd132435e51d8d61e6ec79a79dbPaul Westbrook
145bc47398187c6ffd132435e51d8d61e6ec79a79dbPaul Westbrook    /**
146bc47398187c6ffd132435e51d8d61e6ec79a79dbPaul Westbrook     * Indicates whether <i>mark</i> is supported.
147bc47398187c6ffd132435e51d8d61e6ec79a79dbPaul Westbrook     *
148bc47398187c6ffd132435e51d8d61e6ec79a79dbPaul Westbrook     * @return Whether <i>mark</i> is supported or not.
149bc47398187c6ffd132435e51d8d61e6ec79a79dbPaul Westbrook     */
150bc47398187c6ffd132435e51d8d61e6ec79a79dbPaul Westbrook    public boolean markSupported() {
151bc47398187c6ffd132435e51d8d61e6ec79a79dbPaul Westbrook        return markSupported;
152bc47398187c6ffd132435e51d8d61e6ec79a79dbPaul Westbrook    }
153bc47398187c6ffd132435e51d8d61e6ec79a79dbPaul Westbrook
154bc47398187c6ffd132435e51d8d61e6ec79a79dbPaul Westbrook    /**
155bc47398187c6ffd132435e51d8d61e6ec79a79dbPaul Westbrook     * Read a character.
156bc47398187c6ffd132435e51d8d61e6ec79a79dbPaul Westbrook     *
157bc47398187c6ffd132435e51d8d61e6ec79a79dbPaul Westbrook     * @return Either The character value returned by <code>processChar()</code>
158bc47398187c6ffd132435e51d8d61e6ec79a79dbPaul Westbrook     * or <code>-1</code> if the end of file has been reached and
159bc47398187c6ffd132435e51d8d61e6ec79a79dbPaul Westbrook     * <code>throwEofException</code> is set to <code>false</code>.
160bc47398187c6ffd132435e51d8d61e6ec79a79dbPaul Westbrook     * @throws EOFException if the end of file is reached and
161bc47398187c6ffd132435e51d8d61e6ec79a79dbPaul Westbrook     * <code>throwEofException</code> is set to <code>true</code>.
162bc47398187c6ffd132435e51d8d61e6ec79a79dbPaul Westbrook     * @throws IOException if trying to read past the end of file.
163bc47398187c6ffd132435e51d8d61e6ec79a79dbPaul Westbrook     */
164bc47398187c6ffd132435e51d8d61e6ec79a79dbPaul Westbrook    public int read() throws IOException {
165bc47398187c6ffd132435e51d8d61e6ec79a79dbPaul Westbrook        if (eof) {
166bc47398187c6ffd132435e51d8d61e6ec79a79dbPaul Westbrook            throw new IOException("Read after end of file");
167bc47398187c6ffd132435e51d8d61e6ec79a79dbPaul Westbrook        }
168bc47398187c6ffd132435e51d8d61e6ec79a79dbPaul Westbrook        if (position == size) {
169bc47398187c6ffd132435e51d8d61e6ec79a79dbPaul Westbrook            return doEndOfFile();
170bc47398187c6ffd132435e51d8d61e6ec79a79dbPaul Westbrook        }
171bc47398187c6ffd132435e51d8d61e6ec79a79dbPaul Westbrook        position++;
172bc47398187c6ffd132435e51d8d61e6ec79a79dbPaul Westbrook        return processChar();
173bc47398187c6ffd132435e51d8d61e6ec79a79dbPaul Westbrook    }
174bc47398187c6ffd132435e51d8d61e6ec79a79dbPaul Westbrook
175bc47398187c6ffd132435e51d8d61e6ec79a79dbPaul Westbrook    /**
176bc47398187c6ffd132435e51d8d61e6ec79a79dbPaul Westbrook     * Read some characters into the specified array.
177bc47398187c6ffd132435e51d8d61e6ec79a79dbPaul Westbrook     *
178bc47398187c6ffd132435e51d8d61e6ec79a79dbPaul Westbrook     * @param chars The character array to read into
179bc47398187c6ffd132435e51d8d61e6ec79a79dbPaul Westbrook     * @return The number of characters read or <code>-1</code>
180bc47398187c6ffd132435e51d8d61e6ec79a79dbPaul Westbrook     * if the end of file has been reached and
181bc47398187c6ffd132435e51d8d61e6ec79a79dbPaul Westbrook     * <code>throwEofException</code> is set to <code>false</code>.
182bc47398187c6ffd132435e51d8d61e6ec79a79dbPaul Westbrook     * @throws EOFException if the end of file is reached and
183bc47398187c6ffd132435e51d8d61e6ec79a79dbPaul Westbrook     * <code>throwEofException</code> is set to <code>true</code>.
184bc47398187c6ffd132435e51d8d61e6ec79a79dbPaul Westbrook     * @throws IOException if trying to read past the end of file.
185bc47398187c6ffd132435e51d8d61e6ec79a79dbPaul Westbrook     */
186bc47398187c6ffd132435e51d8d61e6ec79a79dbPaul Westbrook    public int read(char[] chars) throws IOException {
187bc47398187c6ffd132435e51d8d61e6ec79a79dbPaul Westbrook        return read(chars, 0, chars.length);
188bc47398187c6ffd132435e51d8d61e6ec79a79dbPaul Westbrook    }
189bc47398187c6ffd132435e51d8d61e6ec79a79dbPaul Westbrook
190bc47398187c6ffd132435e51d8d61e6ec79a79dbPaul Westbrook    /**
191bc47398187c6ffd132435e51d8d61e6ec79a79dbPaul Westbrook     * Read the specified number characters into an array.
192bc47398187c6ffd132435e51d8d61e6ec79a79dbPaul Westbrook     *
193bc47398187c6ffd132435e51d8d61e6ec79a79dbPaul Westbrook     * @param chars The character array to read into.
194bc47398187c6ffd132435e51d8d61e6ec79a79dbPaul Westbrook     * @param offset The offset to start reading characters into.
195bc47398187c6ffd132435e51d8d61e6ec79a79dbPaul Westbrook     * @param length The number of characters to read.
196bc47398187c6ffd132435e51d8d61e6ec79a79dbPaul Westbrook     * @return The number of characters read or <code>-1</code>
197bc47398187c6ffd132435e51d8d61e6ec79a79dbPaul Westbrook     * if the end of file has been reached and
198bc47398187c6ffd132435e51d8d61e6ec79a79dbPaul Westbrook     * <code>throwEofException</code> is set to <code>false</code>.
199bc47398187c6ffd132435e51d8d61e6ec79a79dbPaul Westbrook     * @throws EOFException if the end of file is reached and
200bc47398187c6ffd132435e51d8d61e6ec79a79dbPaul Westbrook     * <code>throwEofException</code> is set to <code>true</code>.
201bc47398187c6ffd132435e51d8d61e6ec79a79dbPaul Westbrook     * @throws IOException if trying to read past the end of file.
202bc47398187c6ffd132435e51d8d61e6ec79a79dbPaul Westbrook     */
203bc47398187c6ffd132435e51d8d61e6ec79a79dbPaul Westbrook    public int read(char[] chars, int offset, int length) throws IOException {
204bc47398187c6ffd132435e51d8d61e6ec79a79dbPaul Westbrook        if (eof) {
205bc47398187c6ffd132435e51d8d61e6ec79a79dbPaul Westbrook            throw new IOException("Read after end of file");
206bc47398187c6ffd132435e51d8d61e6ec79a79dbPaul Westbrook        }
207bc47398187c6ffd132435e51d8d61e6ec79a79dbPaul Westbrook        if (position == size) {
208bc47398187c6ffd132435e51d8d61e6ec79a79dbPaul Westbrook            return doEndOfFile();
209bc47398187c6ffd132435e51d8d61e6ec79a79dbPaul Westbrook        }
210bc47398187c6ffd132435e51d8d61e6ec79a79dbPaul Westbrook        position += length;
211bc47398187c6ffd132435e51d8d61e6ec79a79dbPaul Westbrook        int returnLength = length;
212bc47398187c6ffd132435e51d8d61e6ec79a79dbPaul Westbrook        if (position > size) {
213bc47398187c6ffd132435e51d8d61e6ec79a79dbPaul Westbrook            returnLength = length - (int)(position - size);
214bc47398187c6ffd132435e51d8d61e6ec79a79dbPaul Westbrook            position = size;
215bc47398187c6ffd132435e51d8d61e6ec79a79dbPaul Westbrook        }
216bc47398187c6ffd132435e51d8d61e6ec79a79dbPaul Westbrook        processChars(chars, offset, returnLength);
217bc47398187c6ffd132435e51d8d61e6ec79a79dbPaul Westbrook        return returnLength;
218bc47398187c6ffd132435e51d8d61e6ec79a79dbPaul Westbrook    }
219bc47398187c6ffd132435e51d8d61e6ec79a79dbPaul Westbrook
220bc47398187c6ffd132435e51d8d61e6ec79a79dbPaul Westbrook    /**
221bc47398187c6ffd132435e51d8d61e6ec79a79dbPaul Westbrook     * Reset the stream to the point when mark was last called.
222bc47398187c6ffd132435e51d8d61e6ec79a79dbPaul Westbrook     *
223bc47398187c6ffd132435e51d8d61e6ec79a79dbPaul Westbrook     * @throws UnsupportedOperationException if mark is not supported.
224bc47398187c6ffd132435e51d8d61e6ec79a79dbPaul Westbrook     * @throws IOException If no position has been marked
225bc47398187c6ffd132435e51d8d61e6ec79a79dbPaul Westbrook     * or the read limit has been exceed since the last position was
226bc47398187c6ffd132435e51d8d61e6ec79a79dbPaul Westbrook     * marked.
227bc47398187c6ffd132435e51d8d61e6ec79a79dbPaul Westbrook     */
228bc47398187c6ffd132435e51d8d61e6ec79a79dbPaul Westbrook    public synchronized void reset() throws IOException {
229bc47398187c6ffd132435e51d8d61e6ec79a79dbPaul Westbrook        if (!markSupported) {
230bc47398187c6ffd132435e51d8d61e6ec79a79dbPaul Westbrook            throw new UnsupportedOperationException("Mark not supported");
231bc47398187c6ffd132435e51d8d61e6ec79a79dbPaul Westbrook        }
232bc47398187c6ffd132435e51d8d61e6ec79a79dbPaul Westbrook        if (mark < 0) {
233bc47398187c6ffd132435e51d8d61e6ec79a79dbPaul Westbrook            throw new IOException("No position has been marked");
234bc47398187c6ffd132435e51d8d61e6ec79a79dbPaul Westbrook        }
235bc47398187c6ffd132435e51d8d61e6ec79a79dbPaul Westbrook        if (position > (mark + readlimit)) {
236bc47398187c6ffd132435e51d8d61e6ec79a79dbPaul Westbrook            throw new IOException("Marked position [" + mark +
237bc47398187c6ffd132435e51d8d61e6ec79a79dbPaul Westbrook                    "] is no longer valid - passed the read limit [" +
238bc47398187c6ffd132435e51d8d61e6ec79a79dbPaul Westbrook                    readlimit + "]");
239bc47398187c6ffd132435e51d8d61e6ec79a79dbPaul Westbrook        }
240bc47398187c6ffd132435e51d8d61e6ec79a79dbPaul Westbrook        position = mark;
241bc47398187c6ffd132435e51d8d61e6ec79a79dbPaul Westbrook        eof = false;
242bc47398187c6ffd132435e51d8d61e6ec79a79dbPaul Westbrook    }
243bc47398187c6ffd132435e51d8d61e6ec79a79dbPaul Westbrook
244bc47398187c6ffd132435e51d8d61e6ec79a79dbPaul Westbrook    /**
245bc47398187c6ffd132435e51d8d61e6ec79a79dbPaul Westbrook     * Skip a specified number of characters.
246bc47398187c6ffd132435e51d8d61e6ec79a79dbPaul Westbrook     *
247bc47398187c6ffd132435e51d8d61e6ec79a79dbPaul Westbrook     * @param numberOfChars The number of characters to skip.
248bc47398187c6ffd132435e51d8d61e6ec79a79dbPaul Westbrook     * @return The number of characters skipped or <code>-1</code>
249bc47398187c6ffd132435e51d8d61e6ec79a79dbPaul Westbrook     * if the end of file has been reached and
250bc47398187c6ffd132435e51d8d61e6ec79a79dbPaul Westbrook     * <code>throwEofException</code> is set to <code>false</code>.
251bc47398187c6ffd132435e51d8d61e6ec79a79dbPaul Westbrook     * @throws EOFException if the end of file is reached and
252bc47398187c6ffd132435e51d8d61e6ec79a79dbPaul Westbrook     * <code>throwEofException</code> is set to <code>true</code>.
253bc47398187c6ffd132435e51d8d61e6ec79a79dbPaul Westbrook     * @throws IOException if trying to read past the end of file.
254bc47398187c6ffd132435e51d8d61e6ec79a79dbPaul Westbrook     */
255bc47398187c6ffd132435e51d8d61e6ec79a79dbPaul Westbrook    public long skip(long numberOfChars) throws IOException {
256bc47398187c6ffd132435e51d8d61e6ec79a79dbPaul Westbrook        if (eof) {
257bc47398187c6ffd132435e51d8d61e6ec79a79dbPaul Westbrook            throw new IOException("Skip after end of file");
258bc47398187c6ffd132435e51d8d61e6ec79a79dbPaul Westbrook        }
259bc47398187c6ffd132435e51d8d61e6ec79a79dbPaul Westbrook        if (position == size) {
260bc47398187c6ffd132435e51d8d61e6ec79a79dbPaul Westbrook            return doEndOfFile();
261bc47398187c6ffd132435e51d8d61e6ec79a79dbPaul Westbrook        }
262bc47398187c6ffd132435e51d8d61e6ec79a79dbPaul Westbrook        position += numberOfChars;
263bc47398187c6ffd132435e51d8d61e6ec79a79dbPaul Westbrook        long returnLength = numberOfChars;
264bc47398187c6ffd132435e51d8d61e6ec79a79dbPaul Westbrook        if (position > size) {
265bc47398187c6ffd132435e51d8d61e6ec79a79dbPaul Westbrook            returnLength = numberOfChars - (position - size);
266bc47398187c6ffd132435e51d8d61e6ec79a79dbPaul Westbrook            position = size;
267bc47398187c6ffd132435e51d8d61e6ec79a79dbPaul Westbrook        }
268bc47398187c6ffd132435e51d8d61e6ec79a79dbPaul Westbrook        return returnLength;
269bc47398187c6ffd132435e51d8d61e6ec79a79dbPaul Westbrook    }
270bc47398187c6ffd132435e51d8d61e6ec79a79dbPaul Westbrook
271bc47398187c6ffd132435e51d8d61e6ec79a79dbPaul Westbrook    /**
272bc47398187c6ffd132435e51d8d61e6ec79a79dbPaul Westbrook     * Return a character value for the  <code>read()</code> method.
273bc47398187c6ffd132435e51d8d61e6ec79a79dbPaul Westbrook     * <p>
274bc47398187c6ffd132435e51d8d61e6ec79a79dbPaul Westbrook     * This implementation returns zero.
275bc47398187c6ffd132435e51d8d61e6ec79a79dbPaul Westbrook     *
276bc47398187c6ffd132435e51d8d61e6ec79a79dbPaul Westbrook     * @return This implementation always returns zero.
277bc47398187c6ffd132435e51d8d61e6ec79a79dbPaul Westbrook     */
278bc47398187c6ffd132435e51d8d61e6ec79a79dbPaul Westbrook    protected int processChar() {
279bc47398187c6ffd132435e51d8d61e6ec79a79dbPaul Westbrook        // do nothing - overridable by subclass
280bc47398187c6ffd132435e51d8d61e6ec79a79dbPaul Westbrook        return 0;
281bc47398187c6ffd132435e51d8d61e6ec79a79dbPaul Westbrook    }
282bc47398187c6ffd132435e51d8d61e6ec79a79dbPaul Westbrook
283bc47398187c6ffd132435e51d8d61e6ec79a79dbPaul Westbrook    /**
284bc47398187c6ffd132435e51d8d61e6ec79a79dbPaul Westbrook     * Process the characters for the <code>read(char[], offset, length)</code>
285bc47398187c6ffd132435e51d8d61e6ec79a79dbPaul Westbrook     * method.
286bc47398187c6ffd132435e51d8d61e6ec79a79dbPaul Westbrook     * <p>
287bc47398187c6ffd132435e51d8d61e6ec79a79dbPaul Westbrook     * This implementation leaves the character array unchanged.
288bc47398187c6ffd132435e51d8d61e6ec79a79dbPaul Westbrook     *
289bc47398187c6ffd132435e51d8d61e6ec79a79dbPaul Westbrook     * @param chars The character array
290bc47398187c6ffd132435e51d8d61e6ec79a79dbPaul Westbrook     * @param offset The offset to start at.
291bc47398187c6ffd132435e51d8d61e6ec79a79dbPaul Westbrook     * @param length The number of characters.
292bc47398187c6ffd132435e51d8d61e6ec79a79dbPaul Westbrook     */
293bc47398187c6ffd132435e51d8d61e6ec79a79dbPaul Westbrook    protected void processChars(char[] chars, int offset, int length) {
294bc47398187c6ffd132435e51d8d61e6ec79a79dbPaul Westbrook        // do nothing - overridable by subclass
295bc47398187c6ffd132435e51d8d61e6ec79a79dbPaul Westbrook    }
296bc47398187c6ffd132435e51d8d61e6ec79a79dbPaul Westbrook
297bc47398187c6ffd132435e51d8d61e6ec79a79dbPaul Westbrook    /**
298bc47398187c6ffd132435e51d8d61e6ec79a79dbPaul Westbrook     * Handle End of File.
299bc47398187c6ffd132435e51d8d61e6ec79a79dbPaul Westbrook     *
300bc47398187c6ffd132435e51d8d61e6ec79a79dbPaul Westbrook     * @return <code>-1</code> if <code>throwEofException</code> is
301bc47398187c6ffd132435e51d8d61e6ec79a79dbPaul Westbrook     * set to <code>false</code>
302bc47398187c6ffd132435e51d8d61e6ec79a79dbPaul Westbrook     * @throws EOFException if <code>throwEofException</code> is set
303bc47398187c6ffd132435e51d8d61e6ec79a79dbPaul Westbrook     * to <code>true</code>.
304bc47398187c6ffd132435e51d8d61e6ec79a79dbPaul Westbrook     */
305bc47398187c6ffd132435e51d8d61e6ec79a79dbPaul Westbrook    private int doEndOfFile() throws EOFException {
306bc47398187c6ffd132435e51d8d61e6ec79a79dbPaul Westbrook        eof = true;
307bc47398187c6ffd132435e51d8d61e6ec79a79dbPaul Westbrook        if (throwEofException) {
308bc47398187c6ffd132435e51d8d61e6ec79a79dbPaul Westbrook            throw new EOFException();
309bc47398187c6ffd132435e51d8d61e6ec79a79dbPaul Westbrook        }
310bc47398187c6ffd132435e51d8d61e6ec79a79dbPaul Westbrook        return -1;
311bc47398187c6ffd132435e51d8d61e6ec79a79dbPaul Westbrook    }
312bc47398187c6ffd132435e51d8d61e6ec79a79dbPaul Westbrook
313bc47398187c6ffd132435e51d8d61e6ec79a79dbPaul Westbrook}
314