org.erights.e.elib.eio
Interface Stream

All Known Subinterfaces:
InStream, OutStream

public interface Stream

Untamed: A connector through which an EIO uni-directional stream of elements flow.

There are two kinds of connector: InStream and OutStream. You use an OutStream to place elements into a stream, and you use a downstream InStream to obtain elements from the stream. Either may or may not be ready to do so depending on how much it has available(). For an InStream, the issue is how many elements are now ready to be read. For an OutStream, the issue is how much spare capacity (unallocated buffer space) it has to accept elements that are to be written.

Author:
Mark S. Miller

Method Summary
 int available()
          Enabled: What are the largest number of elements that are guaranteed to be transferable now (immediately read or written) through connector?
 Object closex()
          Enabled: Terminate the stream successfully, unless it has already terminated.
 Object fail(IOException problem)
          Enabled: Terminate the stream with failure, reporting problem as the reason.
 Class getElementType()
          Enabled: The type of elements that may appear in this stream.
 boolean isTerminated()
          Enabled: Has this connector terminated?
 int maxAvailable()
          Enabled: The most that might ever be available at once through this connector.
 Object terminatesx()
          Enabled: Returns a vow for the terminator.
 Object whenAvailable(int atLeast, Thunk availReactor)
          Enabled: Registers a reactor to be immediately called once there's enough available, or once this connector terminatesx().
 

Method Detail

getElementType

public Class getElementType()
Enabled: The type of elements that may appear in this stream.

If this class represents a scalar type, then all elements must be instances of the elementType. Otherwise, the elements may either be instances of the elementType or be null.

A later version of this API may allow a guard here instead of a class.


maxAvailable

public int maxAvailable()
Enabled: The most that might ever be available at once through this connector.

This is typically the same as the buffer size, but only if the buffer will never be grown. If this isn't known, isn't meaningful, or isn't a fixed value, then ALL must be returned.


available

public int available()
Enabled: What are the largest number of elements that are guaranteed to be transferable now (immediately read or written) through connector?

Must be >= 0, <= maxAvailable(), and < ALL


whenAvailable

public Object whenAvailable(int atLeast,
                            Thunk availReactor)
Enabled: Registers a reactor to be immediately called once there's enough available, or once this connector terminatesx().

At most one reactor may be registered. The reactor is registered exactly until it is triggered. A registered reactor has first claim on the next available elements to be read or capacity to be written, so while a reactor is registered the connector reports that 0 is available().

Unlike most E callbacks, the reactor is invoked synchronously in the same turn as the occurrence of its triggering condition, such that this condition will still be true at the moment the reactor is called. If the condition is already true at the time whenAvailable is called, then the reactor will be immediately called back from whenAvailable rather than being registered.

The triggering condition? Either:

Parameters:
atLeast - How many elements should be available at the time this reactor is called. atLeast must be >= 1, <= maxAvailable(), and != ALL.
availReactor - To be called by this connected when its triggering occurs.
Returns:
A vow for the result of calling availReactor. If availReactor is called during the whenAvailable, then this is immediately the result of that call.

terminatesx

public Object terminatesx()
Enabled: Returns a vow for the terminator.

The terminator represents the terminating condition that occured after all the elements of the stream.

The terminator is either true, meaning a closex() happened and the stream terminated successfully, or it's a reference broken by the terminal problem (an IOException), in which case the stream failed reporting this problem as the reason.

If the stream is already done, then terminates() returns the terminator immediately. Otherwise it returns a vow that must not resolve until the stream is done.

The funny name for this method was chosen so that it would read smoothly in the following context:

     when (c.terminates()) -> done(_) {
         # ... deal with successful close ...
     } catch problem {
         # ... deal with failure ...
     }
 }
Note that the done parameter is "_", meaning "ignore", since in the success case it will always be true. Unlike whenAvailable, this when/catch will only be invoked eventually in its own turn. But since termination is monotonic (once failed always failed), this introduces no race conditions.


isTerminated

public boolean isTerminated()
Enabled: Has this connector terminated?

c.isTerminated() is equivalent to Ref.isResolved(c.terminates()).


closex

public Object closex()
Enabled: Terminate the stream successfully, unless it has already terminated.

On the writing side, a close() implies a flush(). One closes a writer to indicate that no more elements will ever be written to the stream. One closes a reader to indicate that no one will pay any attention to any elements not yet read from the stream.

Returns:
The stream's terminator. This is just what terminates() returns, but following a call to close/0, it must be resolved.

fail

public Object fail(IOException problem)
Enabled: Terminate the stream with failure, reporting problem as the reason.

On the writing side, a fail(..) implies a flush(). A stream may fail spontaneously, or one may call fail to indicate a problem that should terminate the stream.

Returns:
The stream's terminator. This is just what terminates() returns, but following a call to close/0, it must be resolved.


comments?