Start line:  
End line:  

Snippet Preview

Snippet HTML Code

Stack Overflow Questions
  /*
   * Licensed to the Apache Software Foundation (ASF) under one or more
   * contributor license agreements.  See the NOTICE file distributed with
   * this work for additional information regarding copyright ownership.
   * The ASF licenses this file to You under the Apache License, Version 2.0
   * (the "License"); you may not use this file except in compliance with
   * the License.  You may obtain a copy of the License at
   * 
   *      http://www.apache.org/licenses/LICENSE-2.0
  * 
  * Unless required by applicable law or agreed to in writing, software
  * distributed under the License is distributed on an "AS IS" BASIS,
  * WITHOUT WARRANTIES OR CONDITIONS OF ANY KIND, either express or implied.
  * See the License for the specific language governing permissions and
  * limitations under the License.
  */ 
 
 package org.apache.catalina.connector;
 
 
 import static org.jboss.web.CatalinaMessages.MESSAGES;
 
 import java.io.Writer;
 
The buffer used by Tomcat response. This is a derivative of the Tomcat 3.3 OutputBuffer, with the removal of some of the state handling (which in Coyote is mostly the Processor's responsability).

Author(s):
Costin Manolache
Remy Maucherat
 
 public class OutputBuffer extends Writer
 
 
     // -------------------------------------------------------------- Constants
 
 
     public static final String DEFAULT_ENCODING = 
     public static final int DEFAULT_BUFFER_SIZE = 8*1024;
 
 
     // ----------------------------------------------------- Instance Variables
 

    
The byte buffer.
 
     private ByteChunk bb;


    
The chunk buffer.
 
     private CharChunk cb;


    
State of the output buffer.
 
     private boolean initial = true;


    
Number of bytes written.
 
     private long bytesWritten = 0;


    
Number of chars written.
 
     private long charsWritten = 0;


    
Flag which indicates if the output buffer is closed.
 
     private boolean closed = false;


    
Do a flush on the next operation.
    private boolean doFlush = false;


    
Byte chunk used to output bytes.
    private ByteChunk outputChunk = new ByteChunk();


    
Char chunk used to output chars.
    private CharChunk outputCharChunk = new CharChunk();


    
Encoding to use.
    private String enc;


    
Encoder is set.
    private boolean gotEnc = false;


    
List of encoders.
    protected HashMap<StringC2BConverterencoders = 
        new HashMap<StringC2BConverter>();


    
Current char to byte converter.
    protected C2BConverter conv;


    
Associated Coyote response.
    private Response coyoteResponse;


    
Associated request.
    private org.apache.catalina.connector.Response response;


    
Suspended flag. All output bytes will be swallowed if this is true.
    private boolean suspended = false;


    
Write listener.
    private WriteListener writeListener = null;
    // ----------------------------------------------------------- Constructors


    
Default constructor. Allocate the buffer with the default buffer size.
    public OutputBuffer(org.apache.catalina.connector.Response response) {
        this(response);
    }


    
Alternate constructor which allows specifying the initial buffer size.

Parameters:
size Buffer size to use
    public OutputBuffer(org.apache.catalina.connector.Response responseint size) {
        this. = response;
         = new ByteChunk(size);
        .setLimit(size);
        .setByteOutputChannel(this);
         = new CharChunk(size);
        .setLimit(size);
        .setOptimizedWrite(false);
        .setCharOutputChannel(this);
    }
    // ------------------------------------------------------------- Properties


    
Associated Coyote response.

Parameters:
coyoteResponse Associated Coyote response
    public void setResponse(Response coyoteResponse) {
        this. = coyoteResponse;
    }


    
Get associated Coyote response.

Returns:
the associated Coyote response
    public Response getResponse() {
        return this.;
    }


    
Is the response output suspended ?

Returns:
suspended flag value
    public boolean isSuspended() {
        return this.;
    }


    
Set the suspended flag.

Parameters:
suspended New suspended flag value
    public void setSuspended(boolean suspended) {
        this. = suspended;
    }


    
Is the response output closed ?

Returns:
closed flag value
    public boolean isClosed() {
        return this.;
    }
    // --------------------------------------------------------- Public Methods


    
Recycle the output buffer.
    public void recycle() {
        
         = true;
         = 0;
         = 0;
        
        .recycle();
        .recycle();
        .setChars(null, 0, 0);
         = false;
         = false;
         = false;
        
        if (!= null) {
            .recycle();
        }
        
         = false;
         = null;
         = null;
        
    }


    
Clear cached encoders (to save memory for event requests).
    public void clearEncoders() {
        .clear();
    }
    
    
    
Close the output buffer. This tries to calculate the response size if the response has not been committed yet.

Throws:
java.io.IOException An underlying IOException occurred
    public void close()
        throws IOException {
        if ()
            return;
        if ()
            return;
        Request request = .getRequest();
        if (request.getUpgradeHandler() != null && request.isEventMode()) {
            request.getEvent().close();
            return;
        }
        // If there are chars, flush all of them to the byte buffer now as bytes are used to
        // calculate the content-length (if everything fits into the byte buffer, of course).
        if (.getLength() > 0) {
            .flushBuffer();
        }
        if ((!.isCommitted()) 
            && (.getContentLengthLong() == -1)) {
            // If this didn't cause a commit of the response, the final content
            // length can be calculated
            if (!.isCommitted()) {
                .setContentLength(.getLength());
            }
        }
        doFlush(false);
         = true;
        .finish();
    }


    
Flush bytes or chars contained in the buffer.

Throws:
java.io.IOException An underlying IOException occurred
    public void flush()
        throws IOException {
        if (.getRequest().getUpgradeHandler() != null) {
            return;
        }
        doFlush(true);
    }


    
Flush bytes or chars contained in the buffer.

Throws:
java.io.IOException An underlying IOException occurred
    protected void doFlush(boolean realFlush)
        throws IOException {
        if ()
            return;
        if ()
            return;
         = true;
        if () {
            .sendHeaders();
             = false;
        }
        if (.getLength() > 0) {
            .flushBuffer();
        }
        if (.getLength() > 0) {
            .flushBuffer();
        }
         = false;
        if (realFlush) {
                                  );
            // If some exception occurred earlier, or if some IOE occurred
            // here, notify the servlet with an IOE
            if (.isExceptionPresent()) {
                throw new ClientAbortException
                    (.getErrorException());
            }
        }
    }

    
    
Return the amount of bytes written by the lower layer.
    protected int lastWrite() {
        int res = .getLastWrite();
        if (res == 0) {
            .action(.null);
        }
        return res;
    }
    
    // ------------------------------------------------- Bytes Handling Methods


    
Sends the buffer data to the client output, checking the state of Response and calling the right interceptors.

Parameters:
buf Byte buffer to be written to the response
off Offset
cnt Length
Throws:
java.io.IOException An underlying IOException occurred
    public void realWriteBytes(byte buf[], int offint cnt)
        throws IOException {
        if ()
            return;
        if ( == null)
            return;
        // If we really have something to write
        if (cnt > 0) {
            // real write to the adapter
            .setBytes(bufoffcnt);
            try {
                .doWrite();
            } catch (IOException e) {
                // An IOException on a write is almost always due to
                // the remote client aborting the request.  Wrap this
                // so that it can be handled better by the error dispatcher.
                throw new ClientAbortException(e);
            }
        }
    }
    public void write(byte b[], int offint lenthrows IOException {
        if ()
            return;
        writeBytes(bofflen);
    }
    private void writeBytes(byte b[], int offint len
        throws IOException {
        if ()
            return;
        if (.getRequest().getUpgradeHandler() != null) {
            // If we really have something to write
            if (len > 0) {
                // real write to the adapter
                ByteChunk output = new ByteChunk();
                output.setBytes(bofflen);
                try {
                    .doWrite(output);
                } catch (IOException e) {
                    // An IOException on a write is almost always due to
                    // the remote client aborting the request.  Wrap this
                    // so that it can be handled better by the error dispatcher.
                    throw new ClientAbortException(e);
                }
            }
        } else {
            .append(bofflen);
             += len;
            // if called from within flush(), then immediately flush
            // remaining bytes
            if () {
                .flushBuffer();
            }
        }
    }
    public void writeByte(int b)
        throws IOException {
        if ()
            return;
        .append((byteb);
        ++;
    }
    // ------------------------------------------------- Chars Handling Methods


    
Convert the chars to bytes, then send the data to the client.

Parameters:
buf Char buffer to be written to the response
off Offset
len Length
Throws:
java.io.IOException An underlying IOException occurred
    public void realWriteChars(char buf[], int offint len)
        throws IOException {
        .setChars(bufofflen);
        while (.getLength() > 0) { 
            .convert();
            if (.getLength() == 0) {
                // Break out of the loop if more chars are needed to produce any output
                break;
            }
            if (.getLength() > 0) {
                .flushBuffer();
            }
        }
        
    }
    public void write(int c)
        throws IOException {
        if ()
            return;
        .append((charc);
         ++;
    }
    public void write(char c[])
        throws IOException {
        write(c, 0, c.length);
    }
    public void write(char c[], int offint len)
        throws IOException {
        if ()
            return;
        .append(cofflen);
         += len;
    }


    
Append a string to the buffer
    public void write(String sint offint len)
        throws IOException {
        if ()
            return;
        if (s == null)
            s = "null";
        .append(sofflen);
         += len;
    }
    public void write(String s)
        throws IOException {
        if ()
            return;
        if (s == null)
            s = "null";
        .append(s);
         += s.length();
    } 
    public void setEncoding(String s) {
         = s;
    }
    public void checkConverter() 
        throws IOException {
        if (!)
            setConverter();
    }
    protected void setConverter() 
        throws IOException {
        if ( != null)
             = .getCharacterEncoding();
         = true;
         = ( == null) ?  : .toUpperCase(.);
         = .get();
        if ( == null) {
            if (.){
                try {
                     = AccessController
                            .doPrivileged(new PrivilegedExceptionAction<C2BConverter>() {
                                public C2BConverter run() throws IOException {
                                    return new C2BConverter();
                                }
                            });
                } catch (PrivilegedActionException ex) {
                    Exception e = ex.getException();
                    if (e instanceof IOException)
                        throw (IOExceptione;
                }
            } else {
                 = new C2BConverter();
            }
            
            .put();
        }
    }
    
    // --------------------  BufferedOutputStream compatibility


    
Real write - this buffer will be sent to the client
    public void flushBytes()
        throws IOException {
        .flushBuffer();
    }
    public int getBytesWritten() {
        if ( < .) {
            return (int;
        }
        return -1;
    }
    public void setBytesWritten(long bytesWritten) {
        this. = bytesWritten;
    }
    public int getCharsWritten() {
        if ( < .) {
            return (int;
        }
        return -1;
    }
    public int getContentWritten() {
        long size =  + ;
        if (size < .) {
            return (intsize;
        }
        return -1;
    }
    public long getContentWrittenLong() {
        return  + ;
    }
    
    
True if this buffer hasn't been used ( since recycle() ) - i.e. no chars or bytes have been added to the buffer.
    public boolean isNew() {
        return ( == 0) && ( == 0);
    }
    public void setBufferSize(int size) {
        if (size > .getLimit()) {// ??????
            .setLimit(size);
        }
    }
    public void reset() {
        .recycle();
        .recycle();
         = 0;
         = 0;
         = false;
         = null;
         = true;
        
    }
    public int getBufferSize() {
        return .getLimit();
    }
    public WriteListener getWriteListener() {
        return ;
    }
    public void setWriteListener(WriteListener writeListener) {
        if (this. != null) {
            throw .writeListenerAlreadySet();
        }
        if (writeListener == null) {
            throw .nullListener();
        }
        if (!.getRequest().isEventMode()) {
            throw .cannotSetListenerWithoutUpgradeOrAsync();
        }
        this. = writeListener;
                (.getRequest().getUpgradeHandler() != null) ? writeListener : null);
    }
New to GrepCode? Check out our FAQ X