blob: e8e06dd098d8b40f0a38f564b49ddd32b5077908 [file] [log] [blame]
/*
* Licensed to the Apache Software Foundation (ASF) under one or more
* contributor license agreements. See the NOTICE file distributed with
* this work for additional information regarding copyright ownership.
* The ASF licenses this file to You under the Apache License, Version 2.0
* (the "License"); you may not use this file except in compliance with
* the License. You may obtain a copy of the License at
*
* http://www.apache.org/licenses/LICENSE-2.0
*
* Unless required by applicable law or agreed to in writing, software
* distributed under the License is distributed on an "AS IS" BASIS,
* WITHOUT WARRANTIES OR CONDITIONS OF ANY KIND, either express or implied.
* See the License for the specific language governing permissions and
* limitations under the License.
*/
package java.io;
/**
* Wraps an existing {@link Reader} and performs some transformation on the
* input data while it is being read. Transformations can be anything from a
* simple byte-wise filtering input data to an on-the-fly compression or
* decompression of the underlying reader. Readers that wrap another reader and
* provide some additional functionality on top of it usually inherit from this
* class.
*
* @see FilterWriter
*/
public abstract class FilterReader extends Reader {
/**
* The target Reader which is being filtered.
*/
protected Reader in;
/**
* Constructs a new FilterReader on the Reader {@code in}.
*
* @param in
* The non-null Reader to filter reads on.
*/
protected FilterReader(Reader in) {
super(in);
this.in = in;
}
/**
* Closes this reader. This implementation closes the filtered reader.
*
* @throws IOException
* if an error occurs while closing this reader.
*/
@Override
public void close() throws IOException {
synchronized (lock) {
in.close();
}
}
/**
* Sets a mark position in this reader. The parameter {@code readlimit}
* indicates how many bytes can be read before the mark is invalidated.
* Sending {@code reset()} will reposition this reader back to the marked
* position, provided that {@code readlimit} has not been surpassed.
* <p>
* This implementation sets a mark in the filtered reader.
*
* @param readlimit
* the number of bytes that can be read from this reader before
* the mark is invalidated.
* @throws IOException
* if an error occurs while marking this reader.
* @see #markSupported()
* @see #reset()
*/
@Override
public synchronized void mark(int readlimit) throws IOException {
synchronized (lock) {
in.mark(readlimit);
}
}
/**
* Indicates whether this reader supports {@code mark()} and {@code reset()}.
* This implementation returns whether the filtered reader supports marking.
*
* @return {@code true} if {@code mark()} and {@code reset()} are supported
* by the filtered reader, {@code false} otherwise.
* @see #mark(int)
* @see #reset()
* @see #skip(long)
*/
@Override
public boolean markSupported() {
synchronized (lock) {
return in.markSupported();
}
}
/**
* Reads a single character from the filtered reader and returns it as an
* integer with the two higher-order bytes set to 0. Returns -1 if the end
* of the filtered reader has been reached.
*
* @return The character read or -1 if the end of the filtered reader has
* been reached.
* @throws IOException
* if an error occurs while reading from this reader.
*/
@Override
public int read() throws IOException {
synchronized (lock) {
return in.read();
}
}
/**
* Reads at most {@code count} characters from the filtered reader and stores them
* in the byte array {@code buffer} starting at {@code offset}. Returns the
* number of characters actually read or -1 if no characters were read and
* the end of the filtered reader was encountered.
*
* @param buffer
* the char array in which to store the characters read.
* @param offset
* the initial position in {@code buffer} to store the characters
* read from this reader.
* @param count
* the maximum number of characters to store in {@code buffer}.
* @return the number of characters actually read or -1 if the end of the
* filtered reader has been reached while reading.
* @throws IOException
* if an error occurs while reading from this reader.
*/
@Override
public int read(char[] buffer, int offset, int count) throws IOException {
synchronized (lock) {
return in.read(buffer, offset, count);
}
}
/**
* Indicates whether this reader is ready to be read without blocking. If
* the result is {@code true}, the next {@code read()} will not block. If
* the result is {@code false}, this reader may or may not block when
* {@code read()} is sent.
*
* @return {@code true} if this reader will not block when {@code read()}
* is called, {@code false} if unknown or blocking will occur.
* @throws IOException
* if the reader is closed or some other I/O error occurs.
*/
@Override
public boolean ready() throws IOException {
synchronized (lock) {
return in.ready();
}
}
/**
* Resets this reader's position to the last marked location. Invocations of
* {@code read()} and {@code skip()} will occur from this new location. If
* this reader was not marked, the behavior depends on the implementation of
* {@code reset()} in the Reader subclass that is filtered by this reader.
* The default behavior for Reader is to throw an {@code IOException}.
*
* @throws IOException
* if a problem occurred or the filtered reader does not support
* {@code mark()} and {@code reset()}.
* @see #mark(int)
* @see #markSupported()
*/
@Override
public void reset() throws IOException {
synchronized (lock) {
in.reset();
}
}
/**
* Skips {@code count} characters in this reader. Subsequent {@code read()}'s
* will not return these characters unless {@code reset()} is used. The
* default implementation is to skip characters in the filtered reader.
*
* @param count
* the maximum number of characters to skip.
* @return the number of characters actually skipped.
* @throws IOException
* if the filtered reader is closed or some other I/O error
* occurs.
* @see #mark(int)
* @see #markSupported()
* @see #reset()
*/
@Override
public long skip(long count) throws IOException {
synchronized (lock) {
return in.skip(count);
}
}
}