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  public LoggingFilterReader(Reader in, Logger logger) {
021    super(in);
022    this.logger = logger;
023  }
024
025  protected void log() {
026    if (buffer.length() > 0) {
027      // TODO Change from debug, to a user defined level
028      logger.debug(buffer.toString());
029      buffer.setLength(0);
030    }
031  }
032
033  private static int indexOf(char[] array, char c, int off, int len) {
034    for (int i = off; i < off + len; i++) {
035      if (array[i] == c) {
036        return i;
037      }
038    }
039    return -1;
040  }
041
042  @Override
043  public int read(char[] cbuf, int off, int len) throws IOException {
044    int ret = super.read(cbuf, off, len);
045    if (ret != -1) {
046      buffer.append(cbuf, off, ret);
047    }
048
049    // If end of stream, or contains new line
050    if (ret == -1 || indexOf(cbuf, LOG_CHAR, off, ret) != -1) {
051      // BUG this will log a unfinished line, if a string such as
052      // "line \n unfinished" is read.
053      log();
054    }
055
056    return ret;
057  }
058
059  @Override
060  public int read() throws IOException {
061    int ret = super.read();
062    if (ret != -1) {
063      buffer.append((char) ret);
064    }
065
066    // If end of stream, or contains new line
067    if (ret == -1 || ret == LOG_CHAR) {
068      log();
069    }
070    return ret;
071  }
072}