FileDocCategorySizeDatePackage
DemuxOutputStream.javaAPI DocApache Ant 1.707988Wed Dec 13 06:16:20 GMT 2006org.apache.tools.ant

DemuxOutputStream

public class DemuxOutputStream extends OutputStream
Logs content written by a thread and forwards the buffers onto the project object which will forward the content to the appropriate task.
since
1.4

Fields Summary
private static final int
MAX_SIZE
Maximum buffer size.
private static final int
INTIAL_SIZE
Initial buffer size.
private static final int
CR
Carriage return
private static final int
LF
Linefeed
private WeakHashMap
buffers
Mapping from thread to buffer (Thread to BufferInfo).
private Project
project
The project to send output to.
private boolean
isErrorStream
Whether or not this stream represents an error stream.
Constructors Summary
public DemuxOutputStream(Project project, boolean isErrorStream)
Creates a new instance of this class.

param
project The project instance for which output is being demultiplexed. Must not be null.
param
isErrorStream true if this is the error string, otherwise a normal output stream. This is passed to the project so it knows which stream it is receiving.


                                                                                                                                         
         
        this.project = project;
        this.isErrorStream = isErrorStream;
    
Methods Summary
public voidclose()
Equivalent to flushing the stream.

exception
IOException if there is a problem closing the stream.
see
#flush

        flush();
        removeBuffer();
    
public voidflush()
Writes all remaining data in the buffer associated with the current thread to the project.

exception
IOException if there is a problem flushing the stream.

        BufferInfo bufferInfo = getBufferInfo();
        if (bufferInfo.buffer.size() > 0) {
            processFlush(bufferInfo.buffer);
        }
    
private org.apache.tools.ant.DemuxOutputStream$BufferInfogetBufferInfo()
Returns the buffer associated with the current thread.

return
a BufferInfo for the current thread to write data to

        Thread current = Thread.currentThread();
        BufferInfo bufferInfo = (BufferInfo) buffers.get(current);
        if (bufferInfo == null) {
            bufferInfo = new BufferInfo();
            bufferInfo.buffer = new ByteArrayOutputStream(INTIAL_SIZE);
            bufferInfo.crSeen = false;
            buffers.put(current, bufferInfo);
        }
        return bufferInfo;
    
protected voidprocessBuffer(java.io.ByteArrayOutputStream buffer)
Converts the buffer to a string and sends it to the project.

param
buffer the ByteArrayOutputStream used to collect the output until a line separator is seen.
see
Project#demuxOutput(String,boolean)

        String output = buffer.toString();
        project.demuxOutput(output, isErrorStream);
        resetBufferInfo();
    
protected voidprocessFlush(java.io.ByteArrayOutputStream buffer)
Converts the buffer to a string and sends it to the project.

param
buffer the ByteArrayOutputStream used to collect the output until a line separator is seen.
see
Project#demuxOutput(String,boolean)

        String output = buffer.toString();
        project.demuxFlush(output, isErrorStream);
        resetBufferInfo();
    
private voidremoveBuffer()
Removes the buffer for the current thread.

        Thread current = Thread.currentThread();
        buffers.remove (current);
    
private voidresetBufferInfo()
Resets the buffer for the current thread.

        Thread current = Thread.currentThread();
        BufferInfo bufferInfo = (BufferInfo) buffers.get(current);
        try {
            bufferInfo.buffer.close();
        } catch (IOException e) {
            // Shouldn't happen
        }
        bufferInfo.buffer = new ByteArrayOutputStream();
        bufferInfo.crSeen = false;
    
public voidwrite(byte[] b, int off, int len)
Write a block of characters to the output stream

param
b the array containing the data
param
off the offset into the array where data starts
param
len the length of block
throws
IOException if the data cannot be written into the stream.

        // find the line breaks and pass other chars through in blocks
        int offset = off;
        int blockStartOffset = offset;
        int remaining = len;
        BufferInfo bufferInfo = getBufferInfo();
        while (remaining > 0) {
            while (remaining > 0 && b[offset] != LF && b[offset] != CR) {
                offset++;
                remaining--;
            }
            // either end of buffer or a line separator char
            int blockLength = offset - blockStartOffset;
            if (blockLength > 0) {
                bufferInfo.buffer.write(b, blockStartOffset, blockLength);
            }
            while (remaining > 0 && (b[offset] == LF || b[offset] == CR)) {
                write(b[offset]);
                offset++;
                remaining--;
            }
            blockStartOffset = offset;
        }
    
public voidwrite(int cc)
Writes the data to the buffer and flushes the buffer if a line separator is detected or if the buffer has reached its maximum size.

param
cc data to log (byte).
exception
IOException if the data cannot be written to the stream

        final byte c = (byte) cc;

        BufferInfo bufferInfo = getBufferInfo();

        if (c == '\n") {
            // LF is always end of line (i.e. CRLF or single LF)
            bufferInfo.buffer.write(cc);
            processBuffer(bufferInfo.buffer);
        } else {
            if (bufferInfo.crSeen) {
                // CR without LF - send buffer then add char
                processBuffer(bufferInfo.buffer);
            }
            // add into buffer
            bufferInfo.buffer.write(cc);
        }
        bufferInfo.crSeen = (c == '\r");
        if (!bufferInfo.crSeen && bufferInfo.buffer.size() > MAX_SIZE) {
            processBuffer(bufferInfo.buffer);
        }