1/* 2 * Licensed to the Apache Software Foundation (ASF) under one or more 3 * contributor license agreements. See the NOTICE file distributed with 4 * this work for additional information regarding copyright ownership. 5 * The ASF licenses this file to You under the Apache License, Version 2.0 6 * (the "License"); you may not use this file except in compliance with 7 * the License. You may obtain a copy of the License at 8 * 9 * http://www.apache.org/licenses/LICENSE-2.0 10 * 11 * Unless required by applicable law or agreed to in writing, software 12 * distributed under the License is distributed on an "AS IS" BASIS, 13 * WITHOUT WARRANTIES OR CONDITIONS OF ANY KIND, either express or implied. 14 * See the License for the specific language governing permissions and 15 * limitations under the License. 16 */ 17 18package java.io; 19 20/** 21 * Wraps an existing {@link Reader} and performs some transformation on the 22 * input data while it is being read. Transformations can be anything from a 23 * simple byte-wise filtering input data to an on-the-fly compression or 24 * decompression of the underlying reader. Readers that wrap another reader and 25 * provide some additional functionality on top of it usually inherit from this 26 * class. 27 * 28 * @see FilterWriter 29 */ 30public abstract class FilterReader extends Reader { 31 32 /** 33 * The target Reader which is being filtered. 34 */ 35 protected Reader in; 36 37 /** 38 * Constructs a new FilterReader on the Reader {@code in}. 39 * 40 * @param in 41 * The non-null Reader to filter reads on. 42 */ 43 protected FilterReader(Reader in) { 44 super(in); 45 this.in = in; 46 } 47 48 /** 49 * Closes this reader. This implementation closes the filtered reader. 50 * 51 * @throws IOException 52 * if an error occurs while closing this reader. 53 */ 54 @Override 55 public void close() throws IOException { 56 synchronized (lock) { 57 in.close(); 58 } 59 } 60 61 /** 62 * Sets a mark position in this reader. The parameter {@code readlimit} 63 * indicates how many bytes can be read before the mark is invalidated. 64 * Sending {@code reset()} will reposition this reader back to the marked 65 * position, provided that {@code readlimit} has not been surpassed. 66 * <p> 67 * This implementation sets a mark in the filtered reader. 68 * 69 * @param readlimit 70 * the number of bytes that can be read from this reader before 71 * the mark is invalidated. 72 * @throws IOException 73 * if an error occurs while marking this reader. 74 * @see #markSupported() 75 * @see #reset() 76 */ 77 @Override 78 public synchronized void mark(int readlimit) throws IOException { 79 synchronized (lock) { 80 in.mark(readlimit); 81 } 82 } 83 84 /** 85 * Indicates whether this reader supports {@code mark()} and {@code reset()}. 86 * This implementation returns whether the filtered reader supports marking. 87 * 88 * @return {@code true} if {@code mark()} and {@code reset()} are supported 89 * by the filtered reader, {@code false} otherwise. 90 * @see #mark(int) 91 * @see #reset() 92 * @see #skip(long) 93 */ 94 @Override 95 public boolean markSupported() { 96 synchronized (lock) { 97 return in.markSupported(); 98 } 99 } 100 101 /** 102 * Reads a single character from the filtered reader and returns it as an 103 * integer with the two higher-order bytes set to 0. Returns -1 if the end 104 * of the filtered reader has been reached. 105 * 106 * @return The character read or -1 if the end of the filtered reader has 107 * been reached. 108 * @throws IOException 109 * if an error occurs while reading from this reader. 110 */ 111 @Override 112 public int read() throws IOException { 113 synchronized (lock) { 114 return in.read(); 115 } 116 } 117 118 /** 119 * Reads at most {@code count} characters from the filtered reader and stores them 120 * in the byte array {@code buffer} starting at {@code offset}. Returns the 121 * number of characters actually read or -1 if no characters were read and 122 * the end of the filtered reader was encountered. 123 * 124 * @param buffer 125 * the char array in which to store the characters read. 126 * @param offset 127 * the initial position in {@code buffer} to store the characters 128 * read from this reader. 129 * @param count 130 * the maximum number of characters to store in {@code buffer}. 131 * @return the number of characters actually read or -1 if the end of the 132 * filtered reader has been reached while reading. 133 * @throws IOException 134 * if an error occurs while reading from this reader. 135 */ 136 @Override 137 public int read(char[] buffer, int offset, int count) throws IOException { 138 synchronized (lock) { 139 return in.read(buffer, offset, count); 140 } 141 } 142 143 /** 144 * Indicates whether this reader is ready to be read without blocking. If 145 * the result is {@code true}, the next {@code read()} will not block. If 146 * the result is {@code false}, this reader may or may not block when 147 * {@code read()} is sent. 148 * 149 * @return {@code true} if this reader will not block when {@code read()} 150 * is called, {@code false} if unknown or blocking will occur. 151 * @throws IOException 152 * if the reader is closed or some other I/O error occurs. 153 */ 154 @Override 155 public boolean ready() throws IOException { 156 synchronized (lock) { 157 return in.ready(); 158 } 159 } 160 161 /** 162 * Resets this reader's position to the last marked location. Invocations of 163 * {@code read()} and {@code skip()} will occur from this new location. If 164 * this reader was not marked, the behavior depends on the implementation of 165 * {@code reset()} in the Reader subclass that is filtered by this reader. 166 * The default behavior for Reader is to throw an {@code IOException}. 167 * 168 * @throws IOException 169 * if a problem occurred or the filtered reader does not support 170 * {@code mark()} and {@code reset()}. 171 * @see #mark(int) 172 * @see #markSupported() 173 */ 174 @Override 175 public void reset() throws IOException { 176 synchronized (lock) { 177 in.reset(); 178 } 179 } 180 181 /** 182 * Skips {@code charCount} characters in this reader. Subsequent calls to {@code read} 183 * will not return these characters unless {@code reset} is used. The 184 * default implementation is to skip characters in the filtered reader. 185 * 186 * @return the number of characters actually skipped. 187 * @throws IOException 188 * if the filtered reader is closed or some other I/O error 189 * occurs. 190 * @see #mark(int) 191 * @see #markSupported() 192 * @see #reset() 193 */ 194 @Override 195 public long skip(long charCount) throws IOException { 196 synchronized (lock) { 197 return in.skip(charCount); 198 } 199 } 200} 201