/*
* Copyright 2003-2006 Rick Knowles <winstone-devel at lists sourceforge net>
* Distributed under the terms of either:
* - the common development and distribution license (CDDL), v1.0; or
* - the GNU Lesser General Public License, v2.1 or later
*/
package winstone;
import java.io.IOException;
import java.io.OutputStreamWriter;
import java.io.PrintWriter;
import java.io.UnsupportedEncodingException;
/**
* A hacked print writer that allows us to trigger an automatic flush on
* println operations that go over the content length or buffer size.
*
* This is only necessary because the spec authors seem intent of having
* the print writer's flushing behaviour be half auto-flush and half not.
* Damned if I know why - seems unnecessary and confusing to me.
*
* @author <a href="mailto:rick_knowles@hotmail.com">Rick Knowles</a>
* @version $Id: WinstoneResponseWriter.java,v 1.3 2006/02/28 07:32:47 rickknowles Exp $
*/
public class WinstoneResponseWriter extends PrintWriter {
private WinstoneOutputStream outputStream;
private WinstoneResponse response;
private int bytesBuffered;
public WinstoneResponseWriter(WinstoneOutputStream out,
WinstoneResponse response) throws UnsupportedEncodingException {
super(new OutputStreamWriter(out, response.getCharacterEncoding()), false);
this.outputStream = out;
this.response = response;
this.bytesBuffered = 0;
}
public void write(int c) {
super.write(c);
appendByteCount("" + ((char) c));
}
public void write(char[] buf, int off, int len) {
super.write(buf, off, len);
if (buf != null) {
appendByteCount(new String(buf, off, len));
}
}
public void write(String s, int off, int len) {
super.write(s, off, len);
if (s != null) {
appendByteCount(s.substring(off, len));
}
}
protected void appendByteCount(String input) {
try {
this.bytesBuffered += input.getBytes(response.getCharacterEncoding()).length;
} catch (IOException err) {/* impossible */}
}
public void println() {
super.println();
simulateAutoFlush();
}
public void flush() {
super.flush();
this.bytesBuffered = 0;
}
protected void simulateAutoFlush() {
String contentLengthHeader = response.getHeader(WinstoneResponse.CONTENT_LENGTH_HEADER);
if ((contentLengthHeader != null) &&
((this.outputStream.getOutputStreamLength() + this.bytesBuffered) >=
Integer.parseInt(contentLengthHeader))) {
Logger.log(Logger.FULL_DEBUG, Launcher.RESOURCES, "WinstoneResponseWriter.AutoFlush",
new String[] {contentLengthHeader,
(this.outputStream.getOutputStreamLength() + this.bytesBuffered) + ""});
flush();
}
}
}