package net.vhati.modmanager.core;
import java.io.FilterWriter;
import java.io.IOException;
import java.io.Writer;
/**
* A filter that replaces \r, \n, or \r\n, with a standard EOL string.
*
* Essentially, s.replaceAll( "\r(?!\n)|(?<!\r)\n|\r\n", eol );
*
* Filters can be chained to share one destination buffer, while each regex
* call creates and returns a new string.
*/
public class EOLWriter extends FilterWriter {
private String eol;
private boolean sawCR = false;
/**
* Creates a new EOLWriter.
*
* @param out a Writer object to provide the underlying stream
* @param eol the string to substitute where line breaks occur
*/
public EOLWriter( Writer out, String eol ) {
super( out );
this.eol = eol;
}
@Override
public void write( int c ) throws IOException {
if ( c == '\r' ) {
this.out.write( eol );
sawCR = true;
}
else if ( c == '\n' ) {
// If in the middle of \r\n, don't bother adding another eol.
if ( !sawCR ) this.out.write( eol );
sawCR = false;
}
else {
this.out.write( c );
sawCR = false;
}
}
@Override
public void write( char cbuf[], int off, int len ) throws IOException {
int end = off + len;
for ( int i=off; i < end; i++ ) {
if ( cbuf[i] == '\r' ) {
this.out.write( cbuf, off, i-off ); // Write everything up to here.
off = i + 1; // Skip this char.
this.out.write( eol ); // Write EOL instead.
sawCR = true;
}
else if ( cbuf[i] == '\n' ) {
this.out.write( cbuf, off, i-off ); // Write everything up to here.
off = i + 1; // Skip this char.
if ( sawCR ) {
sawCR = false;
} else {
this.out.write( eol ); // Write EOL instead.
}
}
else {
sawCR = false; // Keep scanning for breaks.
}
}
if ( off < end ) { // Write all remaining chars.
this.out.write( cbuf, off, end-off );
}
}
@Override
public void write( String str, int off, int len ) throws IOException {
write( str.toCharArray(), off, len );
}
}