package org.rascalmpl.repl; import java.io.IOException; import java.io.Writer; import org.rascalmpl.interpreter.utils.LimitedResultWriter.IOLimitReachedException; public class LimitedLineWriter extends NonClosingFilterWriter { private final long limit; private int written; public LimitedLineWriter(Writer out, long limit) { super(out); this.limit = limit; written = 0; } @Override public void write(int c) throws IOException { if (written == limit) { throw new IOLimitReachedException(); } out.write(c); if (c == '\n' || c == '\r') { written++; if (written == limit) { out.write("..."); } } } @Override public void write(char[] cbuf, int off, int len) throws IOException { if (written == limit) { throw new IOLimitReachedException(); } len = calculateNewLength(cbuf, off, len); out.write(cbuf, off, len); if (written == limit) { out.write("..."); } } private int calculateNewLength(char[] cbuf, int off, int len) { for (int i = off; i < off + len; i++) { if (cbuf[i] == '\n' || cbuf[i] == '\r') { written++; if (written == limit) { // we have to change the length to just after the last newline return Math.min((i + 1) - off, len); } } } return len; } private int calculateNewLength(String str, int off, int len) { for (int i = off; i < off + len; i++) { if (str.charAt(i) == '\n' || str.charAt(i) == '\r') { written++; if (written == limit) { // we have to change the length to just after the last newline return Math.min((i + 1) - off, len); } } } return len; } @Override public void write(String str, int off, int len) throws IOException { if (written == limit) { throw new IOLimitReachedException(); } len = calculateNewLength(str, off, len); out.write(str, off, len); if (written == limit) { out.write("..."); } } }