001package org.unix4j.unix.cat;
002
003import org.unix4j.command.Command;
004import org.unix4j.context.ExecutionContext;
005import org.unix4j.line.Line;
006import org.unix4j.line.SimpleLine;
007import org.unix4j.processor.AbstractLineProcessor;
008import org.unix4j.processor.LineProcessor;
009
010class NumberLinesProcessor extends AbstractLineProcessor<CatArguments> {
011        
012        private final StringBuilder spaces = new StringBuilder("     ");//5 digits for numbers by default 
013        private final boolean numberBlankLines;
014        private long count = 0;
015
016        public NumberLinesProcessor(Command<CatArguments> command, ExecutionContext context, LineProcessor output) {
017                super(command, context, output);
018                this.numberBlankLines = getArguments().isNumberLines();
019        }
020
021        @Override
022        public boolean processLine(Line line) {
023                if (numberBlankLines || line.getContentLength() > 0) {
024                        count++;
025                        int digitsForCount = spaces.length();
026                        final StringBuilder countLine = new StringBuilder(line.getContentLength() + digitsForCount + 2);
027                        countLine.append(count);
028                        if (countLine.length() > digitsForCount) {
029                                //append more spaces for next numbers
030                                while (countLine.length() > spaces.length()) {
031                                        spaces.append(' ');
032                                }
033                        } else {
034                                countLine.insert(0, spaces, 0, digitsForCount - countLine.length());
035                        }
036                        //now the line itself
037                        countLine.append("  ").append(line, 0, line.getContentLength());
038                        final Line numberedLine = new SimpleLine(countLine, line.getLineEnding());
039                        return getOutput().processLine(numberedLine);
040                }
041                //unnumbered blank line
042                return getOutput().processLine(line);
043        }
044
045        @Override
046        public void finish() {
047                getOutput().finish();
048        }
049}