001package net.bramp.ffmpeg.io; 002 003import java.io.FilterReader; 004import java.io.IOException; 005import java.io.Reader; 006import org.slf4j.Logger; 007 008/** 009 * Wraps a Reader, and logs full lines of input as it is read. 010 * 011 * @author bramp 012 */ 013public class LoggingFilterReader extends FilterReader { 014 015 static final char LOG_CHAR = '\n'; 016 017 final Logger logger; 018 final StringBuilder buffer = new StringBuilder(); 019 020 /** Constructs a new LoggingFilterReader that logs lines read from the given reader. */ 021 public LoggingFilterReader(Reader in, Logger logger) { 022 super(in); 023 this.logger = logger; 024 } 025 026 /** Logs the contents of the buffer and resets it. */ 027 protected void log() { 028 if (buffer.length() > 0) { 029 // TODO Change from debug, to a user defined level 030 logger.debug(buffer.toString()); 031 buffer.setLength(0); 032 } 033 } 034 035 private static int indexOf(char[] array, char c, int off, int len) { 036 for (int i = off; i < off + len; i++) { 037 if (array[i] == c) { 038 return i; 039 } 040 } 041 return -1; 042 } 043 044 @Override 045 public int read(char[] cbuf, int off, int len) throws IOException { 046 int ret = super.read(cbuf, off, len); 047 if (ret != -1) { 048 buffer.append(cbuf, off, ret); 049 } 050 051 // If end of stream, or contains new line 052 if (ret == -1 || indexOf(cbuf, LOG_CHAR, off, ret) != -1) { 053 // BUG this will log a unfinished line, if a string such as 054 // "line \n unfinished" is read. 055 log(); 056 } 057 058 return ret; 059 } 060 061 @Override 062 public int read() throws IOException { 063 int ret = super.read(); 064 if (ret != -1) { 065 buffer.append((char) ret); 066 } 067 068 // If end of stream, or contains new line 069 if (ret == -1 || ret == LOG_CHAR) { 070 log(); 071 } 072 return ret; 073 } 074}