blob: 5bd339957e5d8d9a943f3f983675bfdee465b041 [file] [log] [blame]
/*
* Copyright 1999-2004 The Apache Software Foundation.
*
* 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 org.apache.cocoon.util;
import java.io.FilterOutputStream;
import java.io.IOException;
import java.io.OutputStream;
/**
* This class is like the {@link java.io.BufferedOutputStream} but it
* extends it with a logic to count the number of bytes written to
* the output stream.
*
* @author <a href="mailto:cziegeler@apache.org">Carsten Ziegeler</a>
* @version CVS $Id: BufferedOutputStream.java,v 1.3 2004/03/05 13:03:00 bdelacretaz Exp $
* @since 2.1
*/
public final class BufferedOutputStream extends FilterOutputStream {
protected byte buf[];
protected int count;
/**
* Creates a new buffered output stream to write data to the
* specified underlying output stream with a default 8192-byte
* buffer size.
*
* @param out the underlying output stream.
*/
public BufferedOutputStream(OutputStream out) {
this(out, 8192);
}
/**
* Creates a new buffered output stream to write data to the
* specified underlying output stream with the specified buffer
* size.
*
* @param out the underlying output stream.
* @param size the buffer size.
* @exception IllegalArgumentException if size <= 0.
*/
public BufferedOutputStream(OutputStream out, int size) {
super(out);
if (size <= 0) {
throw new IllegalArgumentException("Buffer size <= 0");
}
this.buf = new byte[size];
}
/**
* Writes the specified byte to this buffered output stream.
*
* @param b the byte to be written.
* @exception IOException if an I/O error occurs.
*/
public void write(int b) throws IOException {
if (this.count >= this.buf.length) {
this.incBuffer();
}
this.buf[count++] = (byte)b;
}
/**
* Writes <code>len</code> bytes from the specified byte array
* starting at offset <code>off</code> to this buffered output stream.
*
* <p> Ordinarily this method stores bytes from the given array into this
* stream's buffer, flushing the buffer to the underlying output stream as
* needed. If the requested length is at least as large as this stream's
* buffer, however, then this method will flush the buffer and write the
* bytes directly to the underlying output stream. Thus redundant
* <code>BufferedOutputStream</code>s will not copy data unnecessarily.
*
* @param b the data.
* @param off the start offset in the data.
* @param len the number of bytes to write.
* @exception IOException if an I/O error occurs.
*/
public void write(byte b[], int off, int len) throws IOException {
while (len > buf.length - count) {
this.incBuffer();
}
System.arraycopy(b, off, buf, count, len);
count += len;
}
/**
* Flushes this buffered output stream.
* We don't flush here.
*
* @exception IOException if an I/O error occurs.
* @see java.io.FilterOutputStream#out
*/
public void flush() throws IOException {
}
/**
* Closes this buffered output stream.
* Flush before closing.
*
* @exception IOException if an I/O error occurs.
*/
public void close() throws IOException {
realFlush();
super.close ();
}
/**
* Flushes this buffered output stream.
* We don't flush here.
*/
public void realFlush() throws IOException {
this.writeBuffer();
this.out.flush();
}
/**
* Write the buffer
*/
private void writeBuffer()
throws IOException {
if (this.count > 0) {
this.out.write(this.buf, 0, this.count);
}
}
/**
* Increment the buffer
*/
private void incBuffer() {
// currently we double the buffer size
// this is not so fast but is a very simple logic
byte[] newBuf = new byte[this.buf.length * 2];
System.arraycopy(this.buf, 0, newBuf, 0, this.buf.length);
this.buf = newBuf;
}
/**
* Clear/reset the buffer
*/
public void clearBuffer() {
this.count = 0;
}
}