All Downloads are FREE. Search and download functionalities are using the official Maven repository.

net.lightbody.bmp.proxy.jetty.http.ChunkingOutputStream Maven / Gradle / Ivy

// ========================================================================
// $Id: ChunkingOutputStream.java,v 1.6 2004/10/19 00:27:23 gregwilkins Exp $
// Copyright 1996-2004 Mort Bay Consulting Pty. Ltd.
// ------------------------------------------------------------------------
// Licensed 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 net.lightbody.bmp.proxy.jetty.http;

import java.io.IOException;
import java.io.OutputStream;

/**
 * HTTP Chunking OutputStream.
 *
 * @author Greg Wilkins
 * @version $Id: ChunkingOutputStream.java,v 1.6 2004/10/19 00:27:23 gregwilkins Exp $
 */
public class ChunkingOutputStream extends BufferedOutputStream implements HttpMessage.HeaderWriter {
    final static byte[] __CRLF = {(byte) '\015', (byte) '\012'};
    final static byte[] __CHUNK_EOF = {(byte) '0', (byte) '\015', (byte) '\012', (byte) '\015', (byte) '\012'};

    final static int __CHUNK_RESERVE = 8;
    final static int __EOF_RESERVE = 8;

    private boolean _chunking;
    private boolean _complete;
    private boolean _completed;

    /**
     * Constructor.
     *
     * @param outputStream The outputStream to buffer or chunk to.
     */
    public ChunkingOutputStream(OutputStream outputStream, int bufferSize, int headerReserve) {
        this(outputStream, bufferSize, headerReserve, true);
    }

    /**
     * Constructor.
     *
     * @param outputStream The outputStream to buffer or chunk to.
     */
    public ChunkingOutputStream(OutputStream outputStream, int bufferSize, int headerReserve, boolean chunking) {
        super(outputStream, bufferSize, headerReserve, __CHUNK_RESERVE, __EOF_RESERVE);
        _chunking = chunking;
        setBypassBuffer(true);
        setFixed(true);
    }

    public boolean isChunking() {
        return _chunking;
    }

    public void setChunking(boolean chunking) {
        _chunking = chunking;
    }

    public void close() throws IOException {
        _complete = true;
        flush();
    }

    public void resetStream() {
        _complete = false;
        _completed = false;
        _chunking = true;
        super.resetStream();
    }

    protected void wrapBuffer() throws IOException {
        // Handle chunking
        int size = size();
        if (_chunking && size() > 0) {
            prewrite(__CRLF, 0, __CRLF.length);
            while (size > 0) {
                int d = size % 16;
                if (d <= 9) {
                    prewrite('0' + d);
                } else {
                    prewrite('a' - 10 + d);
                }
                size = size / 16;
            }
            postwrite(__CRLF, 0, __CRLF.length);
        }

        // Complete it if we must.
        if (_complete && !_completed) {
            _completed = true;
            if (_chunking) {
                postwrite(__CHUNK_EOF, 0, __CHUNK_EOF.length);
            }
        }
    }

    protected void bypassWrite(byte[] b, int offset, int length) throws IOException {
        int i = 9;
        int chunk = length;
        _buf[10] = (byte) '\012';
        _buf[9] = (byte) '\015';
        while (chunk > 0) {
            int d = chunk % 16;
            if (d <= 9) {
                _buf[--i] = (byte) ('0' + d);
            } else {
                _buf[--i] = (byte) ('a' - 10 + d);
            }
            chunk = chunk / 16;
        }
        if (_chunking) {
            _out.write(_buf, i, 10 - i + 1);
        }
        _out.write(b, offset, length);
        if (_chunking) {
            _out.write(__CRLF, 0, __CRLF.length);
        }
        _out.flush();
    }

}

    




© 2015 - 2025 Weber Informatics LLC | Privacy Policy