Package net.fortytwo.ripple.control

Source Code of net.fortytwo.ripple.control.ThreadedInputStream

package net.fortytwo.ripple.control;

import net.fortytwo.ripple.RippleException;

import java.io.InputStream;
import java.io.PipedInputStream;
import java.io.PipedOutputStream;

/**
* An InputStream which optionally spawns a new thread to read bytes from a
* source InputStream into a buffer as soon as they are available.  Otherwise,
* it acts as a simple wrapper for the source InputStream, reading from the
* source only when its own read() method is called.
*
* @author Joshua Shinavier (http://fortytwo.net)
*/
public class ThreadedInputStream extends InputStream {
    private final InputStream source;
    private final PipedInputStream writeIn;
    private final PipedOutputStream readOut;

    private boolean eager;

    private Task readerTask;

    public ThreadedInputStream(final InputStream is)
            throws RippleException {
        source = is;

        eager = false;
        readerTask = null;

        try {
            writeIn = new PipedInputStream();
            readOut = new PipedOutputStream(writeIn);
        } catch (java.io.IOException e) {
            throw new RippleException(e);
        }
    }

    public void setEager(final boolean eager) throws RippleException {
//System.out.println( "setEager( " + eager + " )" );
        if (eager) {
            if (!this.eager) {
//System.out.println( "    enabling reader task" );
                this.eager = true;

                if (null == readerTask) {
                    createTask();
                }

                Scheduler.add(readerTask);
            }
        } else {
            if (this.eager) {
//System.out.println( "    disabling reader task" );
                this.eager = false;
                readerTask.stop();
            }
        }
//System.out.println( "    done." );
    }

    public int available() throws java.io.IOException {
        synchronized (writeIn) {
            return writeIn.available();
        }
    }

    public int read() throws java.io.IOException {
//System.out.println( "query()" );
        if (0 == available()) {
            requestByte(true);
        }

        synchronized (writeIn) {
            return writeIn.read();
        }
    }

    synchronized void requestByte(final boolean forRead)
            throws java.io.IOException {
//System.out.println( "requestByte( " + forRead + " )" );
//System.out.println( "    writeIn.available() = " + writeIn.available() );
        if ((!forRead || !(writeIn.available() > 0))
                && (forRead || eager)) {
//System.out.println( "    reading..." );
            // This will sometimes block.
            int c = source.read();
//System.out.println( "    done reading" );

            synchronized (writeIn) {
                readOut.write(c);
            }
        }
    }

    private void createTask() {
        readerTask = new Task() {
            private boolean active = false;

            protected void executeProtected() throws RippleException {
                active = true;

                while (active) {
                    try {
                        requestByte(false);
                    } catch (java.io.IOException e) {
                        throw new RippleException(e);
                    }
                }
            }

            protected void stopProtected() {
                active = false;
            }
        };
    }
}
TOP

Related Classes of net.fortytwo.ripple.control.ThreadedInputStream

TOP
Copyright © 2018 www.massapi.com. All rights reserved.
All source code are property of their respective owners. Java is a trademark of Sun Microsystems, Inc and owned by ORACLE Inc. Contact coftware#gmail.com.