/* * 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 org.apache.tools.ant.filters; import java.io.FilterReader; import java.io.IOException; import java.io.Reader; import java.io.StringReader; import org.apache.tools.ant.Project; import org.apache.tools.ant.util.FileUtils; /** * Base class for core filter readers. * */ public abstract class BaseFilterReader extends FilterReader { /** Buffer size used when reading */ private static final int BUFFER_SIZE = 8192; /** Have the parameters passed been interpreted? */ private boolean initialized = false; /** The Ant project this filter is part of. */ private Project project = null; /** * Constructor used by Ant's introspection mechanism. * The original filter reader is only used for chaining * purposes, never for filtering purposes (and indeed * it would be useless for filtering purposes, as it has * no real data to filter). ChainedReaderHelper uses * this placeholder instance to create a chain of real filters. */ public BaseFilterReader() { super(new StringReader("")); FileUtils.close(this); } /** * Creates a new filtered reader. * * @param in A Reader object providing the underlying stream. * Must not be <code>null</code>. * */ public BaseFilterReader(final Reader in) { super(in); } /** * Reads characters into a portion of an array. This method will block * until some input is available, an I/O error occurs, or the end of the * stream is reached. * * @param cbuf Destination buffer to write characters to. * Must not be <code>null</code>. * @param off Offset at which to start storing characters. * @param len Maximum number of characters to read. * * @return the number of characters read, or -1 if the end of the * stream has been reached * * @exception IOException If an I/O error occurs */ public final int read(final char[] cbuf, final int off, final int len) throws IOException { for (int i = 0; i < len; i++) { final int ch = read(); if (ch == -1) { if (i == 0) { return -1; } else { return i; } } cbuf[off + i] = (char) ch; } return len; } /** * Skips characters. This method will block until some characters are * available, an I/O error occurs, or the end of the stream is reached. * * @param n The number of characters to skip * * @return the number of characters actually skipped * * @exception IllegalArgumentException If <code>n</code> is negative. * @exception IOException If an I/O error occurs */ public final long skip(final long n) throws IOException, IllegalArgumentException { if (n < 0L) { throw new IllegalArgumentException("skip value is negative"); } for (long i = 0; i < n; i++) { if (read() == -1) { return i; } } return n; } /** * Sets the initialized status. * * @param initialized Whether or not the filter is initialized. */ protected final void setInitialized(final boolean initialized) { this.initialized = initialized; } /** * Returns the initialized status. * * @return whether or not the filter is initialized */ protected final boolean getInitialized() { return initialized; } /** * Sets the project to work with. * * @param project The project this filter is part of. * Should not be <code>null</code>. */ public final void setProject(final Project project) { this.project = project; } /** * Returns the project this filter is part of. * * @return the project this filter is part of */ protected final Project getProject() { return project; } /** * Reads a line of text ending with '\n' (or until the end of the stream). * The returned String retains the '\n'. * * @return the line read, or <code>null</code> if the end of the stream * has already been reached * * @exception IOException if the underlying reader throws one during * reading */ protected final String readLine() throws IOException { int ch = in.read(); if (ch == -1) { return null; } StringBuffer line = new StringBuffer(); while (ch != -1) { line.append ((char) ch); if (ch == '\n') { break; } ch = in.read(); } return line.toString(); } /** * Reads to the end of the stream, returning the contents as a String. * * @return the remaining contents of the reader, as a String * * @exception IOException if the underlying reader throws one during * reading */ protected final String readFully() throws IOException { return FileUtils.readFully(in, BUFFER_SIZE); } }