2010-05-19 14:17:06 -04:00
|
|
|
package com.fsck.k9.mail.filter;
|
2010-02-13 18:45:45 -05:00
|
|
|
|
|
|
|
import java.io.FilterOutputStream;
|
|
|
|
import java.io.IOException;
|
|
|
|
import java.io.OutputStream;
|
|
|
|
|
|
|
|
public class LineWrapOutputStream extends FilterOutputStream
|
|
|
|
{
|
|
|
|
private static final byte[] CRLF = new byte[] {'\r', '\n'};
|
|
|
|
|
|
|
|
private byte[] buffer;
|
|
|
|
private int bufferStart = 0;
|
|
|
|
private int lineLength = 0;
|
|
|
|
private int endOfLastWord = 0;
|
|
|
|
|
|
|
|
|
|
|
|
public LineWrapOutputStream(OutputStream out, int maxLineLength)
|
|
|
|
{
|
|
|
|
super(out);
|
|
|
|
buffer = new byte[maxLineLength - 2];
|
|
|
|
}
|
|
|
|
|
|
|
|
@Override
|
|
|
|
public void write(int oneByte) throws IOException
|
|
|
|
{
|
|
|
|
// Buffer full?
|
|
|
|
if (lineLength == buffer.length)
|
|
|
|
{
|
2010-04-29 00:59:14 -04:00
|
|
|
// Usable word-boundary found earlier?
|
2010-02-13 18:45:45 -05:00
|
|
|
if (endOfLastWord > 0)
|
|
|
|
{
|
2010-04-29 00:59:14 -04:00
|
|
|
// Yes, so output everything up to that word-boundary
|
2010-02-13 18:45:45 -05:00
|
|
|
out.write(buffer, bufferStart, endOfLastWord - bufferStart);
|
|
|
|
out.write(CRLF);
|
|
|
|
|
|
|
|
bufferStart = 0;
|
|
|
|
|
|
|
|
// Skip the <SPACE> in the buffer
|
|
|
|
endOfLastWord++;
|
|
|
|
lineLength = buffer.length - endOfLastWord;
|
|
|
|
if (lineLength > 0)
|
|
|
|
{
|
|
|
|
// Copy rest of the buffer to the front
|
|
|
|
for (int i = 0; i < lineLength; i++)
|
|
|
|
{
|
|
|
|
buffer[i] = buffer[endOfLastWord + i];
|
|
|
|
}
|
|
|
|
}
|
|
|
|
endOfLastWord = 0;
|
|
|
|
}
|
|
|
|
else
|
|
|
|
{
|
|
|
|
// No word-boundary found, so output whole buffer
|
|
|
|
out.write(buffer, bufferStart, buffer.length - bufferStart);
|
|
|
|
out.write(CRLF);
|
|
|
|
lineLength = 0;
|
|
|
|
bufferStart = 0;
|
|
|
|
}
|
|
|
|
}
|
|
|
|
|
|
|
|
if ((oneByte == '\n') || (oneByte == '\r'))
|
|
|
|
{
|
|
|
|
// <CR> or <LF> character found, so output buffer ...
|
|
|
|
if (lineLength - bufferStart > 0)
|
|
|
|
{
|
|
|
|
out.write(buffer, bufferStart, lineLength - bufferStart);
|
|
|
|
}
|
|
|
|
// ... and that character
|
|
|
|
out.write(oneByte);
|
|
|
|
lineLength = 0;
|
|
|
|
bufferStart = 0;
|
|
|
|
endOfLastWord = 0;
|
|
|
|
}
|
|
|
|
else
|
|
|
|
{
|
|
|
|
// Remember this position as last word-boundary if <SPACE> found
|
|
|
|
if (oneByte == ' ')
|
|
|
|
{
|
|
|
|
endOfLastWord = lineLength;
|
|
|
|
}
|
|
|
|
|
|
|
|
// Write character to the buffer
|
|
|
|
buffer[lineLength] = (byte)oneByte;
|
|
|
|
lineLength++;
|
|
|
|
}
|
|
|
|
}
|
|
|
|
|
|
|
|
@Override
|
|
|
|
public void flush() throws IOException
|
|
|
|
{
|
|
|
|
// Buffer empty?
|
|
|
|
if (lineLength > bufferStart)
|
|
|
|
{
|
|
|
|
// Output everything we have up till now
|
|
|
|
out.write(buffer, bufferStart, lineLength - bufferStart);
|
|
|
|
|
|
|
|
// Mark current position as new start of the buffer
|
|
|
|
bufferStart = (lineLength == buffer.length) ? 0 : lineLength;
|
|
|
|
endOfLastWord = 0;
|
|
|
|
}
|
|
|
|
out.flush();
|
|
|
|
}
|
|
|
|
}
|