ewe.io
Class MemoryStream

java.lang.Object
  extended byewe.util.Errorable
      extended byewe.io.BasicStreamObject
          extended byewe.io.StreamObject
              extended byewe.io.MemoryStream
All Implemented Interfaces:
BasicStream, Runnable, Stream, Streamable

public class MemoryStream
extends StreamObject
implements Runnable

A MemoryStream is a Stream that stores all data written to it using standard Stream write() calls, in an array of bytes and then allows that data to be read out again, usually through standard Stream read() calls. Essentially a memory pipe.

You can also use it to provide a standard Streaming interface to a non-Streaming data source/sink, by setting it to be read-only/write-only and overriding the methods that provide or use the data.


Field Summary
protected  Lock backgroundLock
           
protected  boolean readOnly
          Set this true to allow for read() calls only.
protected  boolean useBackgroundThread
          Set this true to allow the getMoreData() method to start and control a background thread for retrieving data for reading.
protected  boolean writeOnly
          Set this true to allow for write() calls only.
 
Fields inherited from class ewe.io.StreamObject
napIterations, napTime, READWRITE_CLOSED, READWRITE_ERROR, READWRITE_WOULDBLOCK
 
Fields inherited from class ewe.io.BasicStreamObject
closed
 
Fields inherited from class ewe.util.Errorable
error
 
Constructor Summary
MemoryStream()
           
MemoryStream(boolean useBackgroundThread)
          Create a read-only MemoryStream that may or may not use a background thread for retrieving data for reading.
MemoryStream(boolean useBackgroundThread, boolean forReading)
          Create a uni-directional MemoryStream that may or may not use a background thread for retrieving data for reading/writing.
MemoryStream(int maxCapacity)
           
 
Method Summary
 boolean closeStream()
          This is non-blocking.
 boolean flushStream()
          This is non-blocking.
 int generateError(String message)
          Cause an error to be generated on the Stream.
protected  byte[] getFromBuffer()
          Get a all the bytes from the internal data buffer.
protected  int getFromBuffer(byte[] buff, int start, int count)
          Get a number of bytes from the internal data buffer.
protected  void getMoreData()
          Override this method if you are implementing a read-only Stream, but are not using a background thread to do so.
protected  boolean loadAndPutDataBlock()
          Override this method if you are using a background thread to get data from a source to place in the stream's buffer for reading.
protected  void noMoreDataToTake()
          If this is a write-only Stream, this method is called when the Stream has been closed and there will be no more data to take.
 int nonBlockingRead(byte[] buff, int start, int count)
          This is the non-blocking read operation.
 int nonBlockingWrite(byte[] buff, int start, int count)
          This is the non-blocking write operation.
static Object[] pipe()
          Create a MemoryStream and return an InputStream and an OutputStream for it.
static Stream[] pipe2()
          Create two Streams that represent either end of a memory based communication stream.
protected  void putInBuffer(byte[] buff, int start, int count)
          Use this to put data into the buffer, for later reading out.
 void run()
           
protected  int sizeOfBuffer()
           
protected  boolean takeAndUseDataBlock()
          Override this method if you are using a background thread to use data written into the buffer place in the stream's buffer for reading.
protected  void useMoreData()
          Override this method if you are implementing a wite-only Stream, but are not using a background thread to do so.
 
Methods inherited from class ewe.io.StreamObject
close, doRead, doWrite, flush, isOpen, nap, nap, read, readAByte, readBytes, readBytes, write, writeAByte, writeBytes, writeBytes
 
Methods inherited from class ewe.io.BasicStreamObject
getException, getName, read, read, throwIOException, toInputStream, toOutputStream, toStream, write, write
 
Methods inherited from class ewe.util.Errorable
returnError, returnError, returnError
 
Methods inherited from class java.lang.Object
clone, equals, finalize, getClass, hashCode, toString
 

Field Detail

readOnly

protected boolean readOnly
Set this true to allow for read() calls only. You will then have to place data into the Stream directly using putInBuffer().


writeOnly

protected boolean writeOnly
Set this true to allow for write() calls only. You will then have to read data from the Stream directly using getFromBuffer().


useBackgroundThread

protected boolean useBackgroundThread
Set this true to allow the getMoreData() method to start and control a background thread for retrieving data for reading. If you set this true then you must override the loadAndPutDataBlock() method.


backgroundLock

protected Lock backgroundLock
Constructor Detail

MemoryStream

public MemoryStream()

MemoryStream

public MemoryStream(int maxCapacity)

MemoryStream

public MemoryStream(boolean useBackgroundThread)
Create a read-only MemoryStream that may or may not use a background thread for retrieving data for reading.

Parameters:
useBackgroundThread - if this is true then a background thread will be used to load data for reading. In that case the loadAndPutDataBlock() method must be overridden.

MemoryStream

public MemoryStream(boolean useBackgroundThread,
                    boolean forReading)
Create a uni-directional MemoryStream that may or may not use a background thread for retrieving data for reading/writing.

Parameters:
useBackgroundThread - if this is true then a background thread will be used to load data for reading or to accept data that's been written. In that case the loadAndPutDataBlock() method OR takeAndUseDataBlock() method must be overridden.
forReading - true for read-only stream, false for a write-only stream.
Method Detail

flushStream

public boolean flushStream()
                    throws IOException
Description copied from interface: BasicStream
This is non-blocking. It returns true if the flush completed, false if it did not, or throws an exception on error.

Specified by:
flushStream in interface BasicStream
Throws:
IOException

generateError

public int generateError(String message)
Cause an error to be generated on the Stream.


loadAndPutDataBlock

protected boolean loadAndPutDataBlock()
                               throws IOException
Override this method if you are using a background thread to get data from a source to place in the stream's buffer for reading. This method should block until at least one byte of data has been read and placed in the buffer using putInBuffer(). If there is no more data to read the method should return false. If an IOException occurs it should throw it.

Returns:
true if data was loaded and placed in the buffer, false if there is no more data.
Throws:
IOException - if an error occured retrieving the data.

takeAndUseDataBlock

protected boolean takeAndUseDataBlock()
                               throws IOException
Override this method if you are using a background thread to use data written into the buffer place in the stream's buffer for reading. This method should block until at least one byte of data has been read and placed in the buffer using putInBuffer(). If there is no more data to read the method should return false. If an IOException occurs it should throw it.

Returns:
true if data was loaded and placed in the buffer, false if there is no more data.
Throws:
IOException - if an error occured retrieving the data.

run

public void run()
Specified by:
run in interface Runnable

getMoreData

protected void getMoreData()
Override this method if you are implementing a read-only Stream, but are not using a background thread to do so. It is called if a read() has been called but there is no data in the buffer left to read. This method should be non-blocking. If necessary start a new thread to fetch more data and put it in the buffer using putInBuffer(). If that thread determines there is no more data it should call close(). The default implmentation of this will generate an error if this Stream is marked as readOnly.


useMoreData

protected void useMoreData()
Override this method if you are implementing a wite-only Stream, but are not using a background thread to do so. It is called when a write() operation has been called placing data in the buffer. You should use the sizeOfBuffer() method and then the getFromBuffer() method to take the data out of the buffer.

This method should be non-blocking. If necessary start a new thread to take the data out of the buffer so that this thread can return. The default implmentation of this will generate an error ifthis Stream is marked as writeOnly.


noMoreDataToTake

protected void noMoreDataToTake()
If this is a write-only Stream, this method is called when the Stream has been closed and there will be no more data to take. It effectively notifies an end of incoming data.


sizeOfBuffer

protected int sizeOfBuffer()

getFromBuffer

protected byte[] getFromBuffer()
                        throws IOException
Get a all the bytes from the internal data buffer. The data in the buffer would have been placed usually with a write() operation.

Returns:
an array of bytes from the buffer. If there were no bytes in the buffer the returned array will be empty.
Throws:
IOException - if the Stream has been flagged with an error.

getFromBuffer

protected int getFromBuffer(byte[] buff,
                            int start,
                            int count)
                     throws IOException
Get a number of bytes from the internal data buffer. The data in the buffer would have been placed usually with a write() operation. Use sizeOfBuffer() to determine how many bytes are waiting in the buffer.

Returns:
the number of bytes read from the buffer.
Throws:
IOException - if the Stream has been flagged with an error.

nonBlockingRead

public int nonBlockingRead(byte[] buff,
                           int start,
                           int count)
Description copied from class: StreamObject
This is the non-blocking read operation. It should never attempt to wait() or sleep() in a Coroutine. It should return as quickly as possible. This makes it safe to be called from within a native method. Note that this should NEVER be called with a count of zero.

The default StreamObject implementation of this uses the single byte read() method.

Specified by:
nonBlockingRead in interface BasicStream
Overrides:
nonBlockingRead in class StreamObject
Parameters:
buff - Destination byte array to hold incoming data.
start - Starting index in buff for incoming data.
count - Maximum number of bytes to read - should never be zero.
Returns:
greater than 0 = Number of bytes read.
0 = No bytes available to read at this time.
-1 = Stream end reached no further bytes to read.
-2 = IO Error.
Note that these values are different to the Stream.readBytes method.

putInBuffer

protected void putInBuffer(byte[] buff,
                           int start,
                           int count)
                    throws IOException
Use this to put data into the buffer, for later reading out.

Throws:
IOException

nonBlockingWrite

public int nonBlockingWrite(byte[] buff,
                            int start,
                            int count)
Description copied from class: StreamObject
This is the non-blocking write operation. It should never attempt to wait() or sleep() in a Coroutine. It should return as quickly as possible. This makes it safe to be called from within a native method.

The default StreamObject implementation of this uses the single byte write() method.

Specified by:
nonBlockingWrite in interface BasicStream
Overrides:
nonBlockingWrite in class StreamObject
Parameters:
buff - Source byte array holding data to be written.
start - Starting index in buff for data to be written.
count - Number of bytes to write - should never be zero.
Returns:
greater than 0 = Number of bytes actually written.
0 = No bytes could be written yet - but the stream is still open.
-1 = Stream has been closed - no further writes are possible.
-2 = IO error - something went wrong.
Note that these values are different to the Stream.writeBytes method.

closeStream

public boolean closeStream()
                    throws IOException
Description copied from interface: BasicStream
This is non-blocking. It returns true if the close completed, false if it did not, or throws an exception on error.

Specified by:
closeStream in interface BasicStream
Overrides:
closeStream in class StreamObject
Throws:
IOException

pipe

public static Object[] pipe()
Create a MemoryStream and return an InputStream and an OutputStream for it. Any data written to the OutputStream will be read by the InputStream.

Returns:
an array of two object - the one at index 0 will be an InputStream and the one at index 1 will be the OutputStream.

pipe2

public static Stream[] pipe2()
Create two Streams that represent either end of a memory based communication stream. Data written to one Stream can be read by the other.