From 5e16edc84ee97b36569148374693461822b8c83b Mon Sep 17 00:00:00 2001 From: Magesh Umasankar Date: Mon, 18 Feb 2002 03:07:30 +0000 Subject: [PATCH] Filter to read the last 'n' lines. git-svn-id: https://svn.apache.org/repos/asf/ant/core/trunk@271394 13f79535-47bb-0310-9956-ffa450edef68 --- .../apache/tools/ant/filters/TailFilter.java | 168 ++++++++++++++++++ 1 file changed, 168 insertions(+) create mode 100644 proposal/sandbox/filterreaders/src/main/org/apache/tools/ant/filters/TailFilter.java diff --git a/proposal/sandbox/filterreaders/src/main/org/apache/tools/ant/filters/TailFilter.java b/proposal/sandbox/filterreaders/src/main/org/apache/tools/ant/filters/TailFilter.java new file mode 100644 index 000000000..f4989d56d --- /dev/null +++ b/proposal/sandbox/filterreaders/src/main/org/apache/tools/ant/filters/TailFilter.java @@ -0,0 +1,168 @@ +package org.apache.tools.ant.filters; + +import java.io.FilterReader; +import java.io.IOException; +import java.io.Reader; + +import org.apache.tools.ant.types.Parameter; +import org.apache.tools.ant.types.Parameterizable; + +/** + * Read the last n lines. Default is last 10 lines. + * + * Example: + * ======= + * + * + * + * + * + * @author Magesh Umasankar + */ +public final class TailFilter + extends FilterReader + implements Parameterizable +{ + private static final String LINES_KEY = "lines"; + + private Parameter[] parameters; + + private boolean initialized = false; + + private long linesRead = 0; + + private long lines = 10; + + private boolean ignoreLineFeed = false; + + private char[] buffer = new char[4096]; + + private int returnedCharPos = -1; + + private boolean completedReadAhead = false; + + private int bufferPos = 0; + + /** + * Create a new filtered reader. + * + * @param in a Reader object providing the underlying stream. + */ + public TailFilter(final Reader in) { + super(in); + } + + /** + * Read ahead and keep in buffer last n lines only at any given + * point. Grow buffer as needed. + */ + public final int read() throws IOException { + if (!initialized) { + initialize(); + initialized = true; + } + + if (!completedReadAhead) { + int ch = -1; + while ((ch = in.read()) != -1) { + if (buffer.length == bufferPos) { + if (returnedCharPos != -1) { + final char[] tmpBuffer = new char[buffer.length]; + System.arraycopy(buffer, returnedCharPos + 1, tmpBuffer, + 0, buffer.length - (returnedCharPos + 1)); + buffer = tmpBuffer; + bufferPos = bufferPos - (returnedCharPos + 1); + returnedCharPos = -1; + } else { + final char[] tmpBuffer = new char[buffer.length * 2]; + System.arraycopy(buffer, 0, tmpBuffer, 0, bufferPos); + buffer = tmpBuffer; + } + } + + if (ignoreLineFeed) { + if (ch == '\n') { + ch = in.read(); + } + ignoreLineFeed = false; + } + + switch (ch) { + case '\r': + ch = '\n'; + ignoreLineFeed = true; + //fall through + case '\n': + linesRead++; + + if (linesRead == lines + 1) { + int i = 0; + for (i = returnedCharPos + 1; buffer[i] != '\n'; i++) { + } + returnedCharPos = i; + linesRead--; + } + break; + } + if (ch == -1) { + break; + } + + buffer[bufferPos] = (char) ch; + bufferPos++; + } + completedReadAhead = true; + } + + ++returnedCharPos; + if (returnedCharPos >= bufferPos) { + return -1; + } else { + return buffer[returnedCharPos]; + } + } + + 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; + } + + public final long skip(long n) throws IOException { + for (long i = 0; i < n; i++) { + if (in.read() == -1) { + return i; + } + } + return n; + } + + /** + * Set Parameters + */ + public final void setParameters(final Parameter[] parameters) { + this.parameters = parameters; + initialized = false; + } + + private final void initialize() { + if (parameters != null) { + for (int i = 0; i < parameters.length; i++) { + if (LINES_KEY.equals(parameters[i].getName())) { + lines = new Long(parameters[i].getValue()).longValue(); + break; + } + } + } + } +}