001package org.unix4j.unix.tail; 002 003import java.util.LinkedList; 004 005import org.unix4j.context.ExecutionContext; 006import org.unix4j.line.Line; 007import org.unix4j.line.SimpleLine; 008import org.unix4j.processor.LineProcessor; 009import org.unix4j.util.Counter; 010 011public class TailCharsFromEndProcessor extends AbstractTailProcessor { 012 013 private final Counter counter = new Counter(); 014 private final LinkedList<Line> tailLines = new LinkedList<Line>(); 015 016 @Override 017 public void resetCountersAndFlush() { 018 final LineProcessor output = getOutput(); 019 boolean more = true; 020 if (counter.getCount() > count) { 021 final Line line = tailLines.removeFirst(); 022 final int offset = (int)(counter.getCount() - count); 023 final Line cutLine = SimpleLine.subLine(line, offset, line.length(), false); 024 more = output.processLine(cutLine); 025 } 026 while (!tailLines.isEmpty() && more) { 027 more = output.processLine(tailLines.removeFirst());//remove to free memory 028 } 029 counter.reset(); 030 tailLines.clear(); 031 } 032 033 public TailCharsFromEndProcessor(TailCommand command, ExecutionContext context, LineProcessor output) { 034 super(command, context, output); 035 } 036 037 @Override 038 public boolean processLine(Line line) { 039 tailLines.add(line); 040 if (counter.increment(line.length()) > count) { 041 long firstLen = tailLines.getFirst().length(); 042 while (counter.getCount() - firstLen >= count) { 043 tailLines.removeFirst(); 044 counter.decrement(firstLen); 045 firstLen = tailLines.isEmpty() ? counter.getCount() : tailLines.getFirst().length(); 046 } 047 } 048 return true;//we want all lines 049 } 050 051 @Override 052 public void finish() { 053 final LineProcessor output = getOutput(); 054 resetCountersAndFlush(); 055 output.finish(); 056 } 057 058}