FCGIOutputStream.java [plain text]
package com.fastcgi;
import java.io.*;
public class FCGIOutputStream
extends OutputStream
{
private static final String RCSID = "$Id: FCGIOutputStream.java,v 1.3 2000/03/21 12:12:26 robs Exp $";
public int wrNext;
public int stop;
public boolean isClosed;
private int errno;
private Exception errex;
public byte buff[];
public int buffLen;
public int buffStop;
public int type;
public boolean isAnythingWritten;
public boolean rawWrite;
public FCGIRequest request;
public FileOutputStream out;
public FCGIOutputStream(FileOutputStream outStream,
int bufLen, int streamType,
FCGIRequest inreq) {
out = outStream;
buffLen = Math.min(bufLen, FCGIGlobalDefs.def_FCGIMaxLen);
buff = new byte[buffLen];
type = streamType;
stop = buffStop = buffLen;
isAnythingWritten = false;
rawWrite = false;
wrNext = FCGIGlobalDefs.def_FCGIHeaderLen;
isClosed = false;
request = inreq;
}
public void write(int c) throws IOException {
if(wrNext != stop) {
buff[wrNext++] = (byte)c;
return;
}
if(isClosed) {
throw new EOFException();
}
empty(false);
if(wrNext != stop) {
buff[wrNext++] = (byte)c;
return;
}
throw new EOFException();
}
public void write(byte b[]) throws IOException{
write(b, 0, b.length);
}
public void write(byte b[], int off, int len) throws IOException {
int m, bytesMoved;
if(len <= (stop - wrNext)) {
System.arraycopy(b, off, buff, wrNext, len);
wrNext += len;
return;
}
bytesMoved = 0;
for (;;) {
if(wrNext != stop) {
m = Math.min(len - bytesMoved, stop - wrNext);
System.arraycopy(b, off, buff, wrNext, m);
bytesMoved += m;
wrNext += m;
if(bytesMoved == len) {
return;
}
off += m;
}
if(isClosed) {
throw new EOFException();
}
empty(false);
}
}
public void empty(boolean doClose) throws IOException {
int cLen;
if (!rawWrite) {
cLen = wrNext - FCGIGlobalDefs.def_FCGIHeaderLen;
if(cLen > 0) {
System.arraycopy(new FCGIMessage().makeHeader(type,
request.requestID, cLen, 0),
0, buff, 0,
FCGIGlobalDefs.def_FCGIHeaderLen);
}
else {
wrNext = 0;
}
}
if (doClose) {
writeCloseRecords();
}
if (wrNext != 0) {
isAnythingWritten = true;
try {
out.write(buff, 0, wrNext);
} catch (IOException e) {
setException(e);
return;
}
wrNext = 0;
}
if(!rawWrite) {
wrNext += FCGIGlobalDefs.def_FCGIHeaderLen;
}
}
public void close() throws IOException {
if (isClosed) {
return;
}
empty(true);
isClosed = true;
stop = wrNext;
return;
}
public void flush() throws IOException {
if (isClosed) {
return;
}
empty(false);
return;
}
public void setFCGIError(int errnum) {
if (errno == 0) {
errno = errnum;
}
isClosed = true;
}
public void setException(Exception errexpt) {
if (errex == null) {
errex = errexpt;
}
isClosed = true;
}
public void clearFCGIError() {
errno = 0;
}
public void clearException() {
errex = null;
}
public int etFCGIError() {
return errno;
}
public Exception getException() {
return errex;
}
public void writeCloseRecords() throws IOException {
FCGIMessage msg = new FCGIMessage();
rawWrite = true;
if(!(type == FCGIGlobalDefs.def_FCGIStderr
&& wrNext == 0
&& !isAnythingWritten)) {
byte hdr[] =
new byte[FCGIGlobalDefs.def_FCGIHeaderLen];
System.arraycopy(msg.makeHeader(type,
request.requestID,
0, 0),
0, hdr,0,
FCGIGlobalDefs.def_FCGIHeaderLen);
write(hdr, 0, hdr.length);
}
if(request.numWriters == 1) {
byte endReq[] =
new byte[FCGIGlobalDefs.def_FCGIHeaderLen
+ FCGIGlobalDefs.def_FCGIEndReqBodyLen];
System.arraycopy(msg.makeHeader(
FCGIGlobalDefs.def_FCGIEndRequest,
request.requestID,
FCGIGlobalDefs.def_FCGIEndReqBodyLen,0),
0, endReq, 0,
FCGIGlobalDefs.def_FCGIHeaderLen);
System.arraycopy(msg.makeEndrequestBody(
request.appStatus,
FCGIGlobalDefs.def_FCGIRequestComplete),
0,endReq,
FCGIGlobalDefs.def_FCGIHeaderLen,
FCGIGlobalDefs.def_FCGIEndReqBodyLen);
write(endReq,0, FCGIGlobalDefs.def_FCGIHeaderLen
+ FCGIGlobalDefs.def_FCGIEndReqBodyLen);
}
request.numWriters--;
}
}