import java.security.PrivilegedExceptionAction;\r
import java.util.HashMap;\r
\r
-import org.apache.catalina.security.SecurityUtil;\r
import org.apache.coyote.ActionCode;\r
import org.apache.coyote.Response;\r
import org.apache.tomcat.util.buf.ByteChunk;\r
import org.apache.tomcat.util.buf.C2BConverter;\r
-import org.apache.tomcat.util.buf.CharChunk;\r
\r
\r
/**\r
* @author Remy Maucherat\r
*/\r
public class OutputBuffer extends Writer\r
- implements ByteChunk.ByteOutputChannel, CharChunk.CharOutputChannel {\r
+ implements ByteChunk.ByteOutputChannel {\r
\r
\r
// -------------------------------------------------------------- Constants\r
public static final int DEFAULT_BUFFER_SIZE = 8*1024;\r
\r
\r
- // The buffer can be used for byte[] and char[] writing\r
- // ( this is needed to support ServletOutputStream and for\r
- // efficient implementations of templating systems )\r
- public final int INITIAL_STATE = 0;\r
- public final int CHAR_STATE = 1;\r
- public final int BYTE_STATE = 2;\r
-\r
-\r
// ----------------------------------------------------- Instance Variables\r
\r
\r
\r
\r
/**\r
- * The chunk buffer.\r
- */\r
- private CharChunk cb;\r
-\r
-\r
- /**\r
* State of the output buffer.\r
*/\r
- private int state = 0;\r
+ private boolean initial = true;\r
\r
\r
/**\r
bb = new ByteChunk(size);\r
bb.setLimit(size);\r
bb.setByteOutputChannel(this);\r
- cb = new CharChunk(size);\r
- cb.setCharOutputChannel(this);\r
- cb.setLimit(size);\r
\r
}\r
\r
*/\r
public void recycle() {\r
\r
- state = INITIAL_STATE;\r
+ initial = true;\r
bytesWritten = 0;\r
charsWritten = 0;\r
\r
- cb.recycle();\r
bb.recycle(); \r
closed = false;\r
suspended = false;\r
\r
if ((!coyoteResponse.isCommitted()) \r
&& (coyoteResponse.getContentLengthLong() == -1)) {\r
- // Flushing the char buffer\r
- if (state == CHAR_STATE) {\r
- cb.flushBuffer();\r
- state = BYTE_STATE;\r
- }\r
// If this didn't cause a commit of the response, the final content\r
// length can be calculated\r
if (!coyoteResponse.isCommitted()) {\r
return;\r
\r
doFlush = true;\r
- if (state == CHAR_STATE) {\r
- cb.flushBuffer();\r
- bb.flushBuffer();\r
- state = BYTE_STATE;\r
- } else if (state == BYTE_STATE) {\r
- bb.flushBuffer();\r
- } else if (state == INITIAL_STATE) {\r
- // If the buffers are empty, commit the response header\r
+ if (initial) {\r
coyoteResponse.sendHeaders();\r
+ initial = false;\r
+ }\r
+ if (bb.getLength() > 0) {\r
+ bb.flushBuffer();\r
}\r
doFlush = false;\r
\r
if (suspended)\r
return;\r
\r
- if (state == CHAR_STATE)\r
- cb.flushBuffer();\r
- state = BYTE_STATE;\r
writeBytes(b, off, len);\r
\r
}\r
if (suspended)\r
return;\r
\r
- if (state == CHAR_STATE)\r
- cb.flushBuffer();\r
- state = BYTE_STATE;\r
-\r
- bb.append( (byte)b );\r
+ bb.append((byte) b);\r
bytesWritten++;\r
\r
}\r
if (suspended)\r
return;\r
\r
- state = CHAR_STATE;\r
-\r
- cb.append((char) c);\r
+ conv.convert((char) c);\r
+ conv.flushBuffer();\r
charsWritten++;\r
-\r
+ \r
}\r
\r
\r
if (suspended)\r
return;\r
\r
- state = CHAR_STATE;\r
-\r
- cb.append(c, off, len);\r
- charsWritten += len;\r
-\r
- }\r
-\r
-\r
- public void write(StringBuffer sb)\r
- throws IOException {\r
-\r
- if (suspended)\r
- return;\r
-\r
- state = CHAR_STATE;\r
-\r
- int len = sb.length();\r
+ conv.convert(c, off, len);\r
+ conv.flushBuffer();\r
charsWritten += len;\r
- cb.append(sb);\r
\r
}\r
\r
if (suspended)\r
return;\r
\r
- state=CHAR_STATE;\r
-\r
charsWritten += len;\r
- if (s==null)\r
- s="null";\r
- cb.append( s, off, len );\r
+ if (s == null)\r
+ s = "null";\r
+ conv.convert(s, off, len);\r
+ conv.flushBuffer();\r
\r
}\r
\r
if (suspended)\r
return;\r
\r
- state = CHAR_STATE;\r
- if (s==null)\r
- s="null";\r
- write(s, 0, s.length());\r
+ if (s == null)\r
+ s = "null";\r
+ conv.convert(s);\r
+ conv.flushBuffer();\r
\r
} \r
\r
\r
- public void flushChars()\r
- throws IOException {\r
-\r
- cb.flushBuffer();\r
- state = BYTE_STATE;\r
-\r
- }\r
-\r
-\r
- public boolean flushCharsNeeded() {\r
- return state == CHAR_STATE;\r
- }\r
-\r
-\r
public void setEncoding(String s) {\r
enc = s;\r
}\r
\r
\r
- public void realWriteChars(char c[], int off, int len) \r
- throws IOException {\r
-\r
- if (!gotEnc)\r
- setConverter();\r
-\r
- conv.convert(c, off, len);\r
- conv.flushBuffer(); // ???\r
-\r
- }\r
-\r
-\r
public void checkConverter() \r
throws IOException {\r
\r
\r
public void setBufferSize(int size) {\r
if (size > bb.getLimit()) {// ??????\r
- bb.setLimit(size);\r
- }\r
+ bb.setLimit(size);\r
+ }\r
}\r
\r
\r
public void reset() {\r
\r
- //count=0;\r
bb.recycle();\r
bytesWritten = 0;\r
- cb.recycle();\r
charsWritten = 0;\r
gotEnc = false;\r
enc = null;\r
- state = INITIAL_STATE;\r
+ initial = true;\r
+ \r
}\r
\r
\r
public int getBufferSize() {\r
- return bb.getLimit();\r
+ return bb.getLimit();\r
}\r
\r
\r