001: /*
002: * Copyright 1999-2004 The Apache Software Foundation
003: *
004: * Licensed under the Apache License, Version 2.0 (the "License");
005: * you may not use this file except in compliance with the License.
006: * You may obtain a copy of the License at
007: *
008: * http://www.apache.org/licenses/LICENSE-2.0
009: *
010: * Unless required by applicable law or agreed to in writing, software
011: * distributed under the License is distributed on an "AS IS" BASIS,
012: * WITHOUT WARRANTIES OR CONDITIONS OF ANY KIND, either express or implied.
013: * See the License for the specific language governing permissions and
014: * limitations under the License.
015: */
016:
017: package org.apache.coyote.http11.filters;
018:
019: import java.io.IOException;
020:
021: import org.apache.tomcat.util.buf.ByteChunk;
022:
023: import org.apache.coyote.OutputBuffer;
024: import org.apache.coyote.Response;
025: import org.apache.coyote.http11.OutputFilter;
026:
027: /**
028: * Identity output filter.
029: *
030: * @author Remy Maucherat
031: */
032: public class IdentityOutputFilter implements OutputFilter {
033:
034: // -------------------------------------------------------------- Constants
035:
036: protected static final String ENCODING_NAME = "identity";
037: protected static final ByteChunk ENCODING = new ByteChunk();
038:
039: // ----------------------------------------------------- Static Initializer
040:
041: static {
042: ENCODING.setBytes(ENCODING_NAME.getBytes(), 0, ENCODING_NAME
043: .length());
044: }
045:
046: // ----------------------------------------------------- Instance Variables
047:
048: /**
049: * Content length.
050: */
051: protected long contentLength = -1;
052:
053: /**
054: * Remaining bytes.
055: */
056: protected long remaining = 0;
057:
058: /**
059: * Next buffer in the pipeline.
060: */
061: protected OutputBuffer buffer;
062:
063: // ------------------------------------------------------------- Properties
064:
065: /**
066: * Get content length.
067: */
068: public long getContentLength() {
069: return contentLength;
070: }
071:
072: /**
073: * Get remaining bytes.
074: */
075: public long getRemaining() {
076: return remaining;
077: }
078:
079: // --------------------------------------------------- OutputBuffer Methods
080:
081: /**
082: * Write some bytes.
083: *
084: * @return number of bytes written by the filter
085: */
086: public int doWrite(ByteChunk chunk, Response res)
087: throws IOException {
088:
089: int result = -1;
090:
091: if (contentLength >= 0) {
092: if (remaining > 0) {
093: result = chunk.getLength();
094: if (result > remaining) {
095: // The chunk is longer than the number of bytes remaining
096: // in the body; changing the chunk length to the number
097: // of bytes remaining
098: chunk.setBytes(chunk.getBytes(), chunk.getStart(),
099: (int) remaining);
100: result = (int) remaining;
101: remaining = 0;
102: } else {
103: remaining = remaining - result;
104: }
105: buffer.doWrite(chunk, res);
106: } else {
107: // No more bytes left to be written : return -1 and clear the
108: // buffer
109: chunk.recycle();
110: result = -1;
111: }
112: } else {
113: // If no content length was set, just write the bytes
114: buffer.doWrite(chunk, res);
115: result = chunk.getLength();
116: }
117:
118: return result;
119:
120: }
121:
122: // --------------------------------------------------- OutputFilter Methods
123:
124: /**
125: * Some filters need additional parameters from the response. All the
126: * necessary reading can occur in that method, as this method is called
127: * after the response header processing is complete.
128: */
129: public void setResponse(Response response) {
130: contentLength = response.getContentLength();
131: remaining = contentLength;
132: }
133:
134: /**
135: * Set the next buffer in the filter pipeline.
136: */
137: public void setBuffer(OutputBuffer buffer) {
138: this .buffer = buffer;
139: }
140:
141: /**
142: * End the current request. It is acceptable to write extra bytes using
143: * buffer.doWrite during the execution of this method.
144: */
145: public long end() throws IOException {
146:
147: if (remaining > 0)
148: return remaining;
149: return 0;
150:
151: }
152:
153: /**
154: * Make the filter ready to process the next request.
155: */
156: public void recycle() {
157: contentLength = -1;
158: remaining = 0;
159: }
160:
161: /**
162: * Return the name of the associated encoding; Here, the value is
163: * "identity".
164: */
165: public ByteChunk getEncodingName() {
166: return ENCODING;
167: }
168:
169: }
|