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.tomcat4;
018:
019: import java.io.IOException;
020:
021: import javax.servlet.ServletInputStream;
022:
023: import org.apache.coyote.Request;
024: import org.apache.tomcat.util.buf.ByteChunk;
025:
026: /**
027: * This class handles the readin input bytes, as well as the input buffering.
028: *
029: * @author Remy Maucherat
030: */
031: public class CoyoteInputStream extends ServletInputStream {
032:
033: // ----------------------------------------------------- Instance Variables
034:
035: private boolean closed = false;
036:
037: private Request coyoteRequest;
038:
039: private ByteChunk readChunk = new ByteChunk();
040:
041: /**
042: * Current read position in the byte buffer.
043: */
044: private int pos = -1;
045: private int end = -1;
046: private byte[] readBuffer = null;
047:
048: // --------------------------------------------------------- Public Methods
049:
050: void setRequest(Request coyoteRequest) {
051: this .coyoteRequest = coyoteRequest;
052: }
053:
054: /**
055: * Recycle the input stream.
056: */
057: void recycle() {
058: closed = false;
059: pos = -1;
060: end = -1;
061: readBuffer = null;
062: }
063:
064: // --------------------------------------------- ServletInputStream Methods
065:
066: public int read() throws IOException {
067:
068: if (closed)
069: throw new IOException("Stream closed");
070:
071: // Read additional bytes if none are available
072: while (pos >= end) {
073: if (readBytes() < 0)
074: return -1;
075: }
076:
077: return (readBuffer[pos++] & 0xFF);
078:
079: }
080:
081: public int available() throws IOException {
082: if (pos < end)
083: return end - pos;
084: return 0;
085: }
086:
087: public int read(byte[] b) throws IOException {
088:
089: return read(b, 0, b.length);
090:
091: }
092:
093: public int read(byte[] b, int off, int len) throws IOException {
094:
095: if (closed)
096: throw new IOException("Stream closed");
097:
098: // Read additional bytes if none are available
099: while (pos >= end) {
100: if (readBytes() < 0)
101: return -1;
102: }
103:
104: int n = -1;
105: if ((end - pos) > len) {
106: n = len;
107: } else {
108: n = end - pos;
109: }
110:
111: System.arraycopy(readBuffer, pos, b, off, n);
112:
113: pos += n;
114: return n;
115:
116: }
117:
118: public int readLine(byte[] b, int off, int len) throws IOException {
119: return super .readLine(b, off, len);
120: }
121:
122: /**
123: * Close the stream
124: * Since we re-cycle, we can't allow the call to super.close()
125: * which would permantely disable us.
126: */
127: public void close() {
128: closed = true;
129: }
130:
131: // ------------------------------------------------------ Protected Methods
132:
133: /**
134: * Read bytes to the read chunk buffer.
135: */
136: protected int readBytes() throws IOException {
137:
138: int result = coyoteRequest.doRead(readChunk);
139: if (result > 0) {
140: readBuffer = readChunk.getBytes();
141: end = readChunk.getEnd();
142: pos = readChunk.getStart();
143: }
144: return result;
145:
146: }
147:
148: }
|