org.erights.e.elib.oldeio
Class TextReader

java.lang.Object
  |
  +--java.io.Reader
        |
        +--org.erights.e.elib.oldeio.TextReader

public class TextReader
extends Reader

Untamed: A non-blocking Reader for reading the text that appears in a shared StringBuffer.

This class in intended to be thread-safe, and to be used both from inside and outside a vat. When used in conjunction with StringWriter or our own TextWriter, the pair is like a non-blocking variant of PipedReader/PipedWriter. The sharing must be set up at creation time, as a TextReader encapsulates its StringBuffer.

In order to be non-blocking, we make the following change to the Reader contract: If a read(..) is attempted on a non-ready TextReader, it will throw an IOException, rather than blocking or returning zero.

In order to be thread-safe, it uses the StringBuffer as its Reader.lock.

This class does no newline conversion. This should normally be done by the object that writes into the shared StringBuffer.

Author:
Mark S. Miller, Terry Stanley

Field Summary
private  boolean myIsMarked
          True when after a mark() and before a corresponding reset().
private  int myNext
          The next character to be read will be myOptBuf[myNext].
private  StringBuffer myOptBuf
          null if closed.
private  Thunk myOptFiller
          If null, then myOptBuf is all that remains.
 
Fields inherited from class java.io.Reader
lock
 
Constructor Summary
(package private) TextReader(StringBuffer buf)
          optFiller defaults to null
(package private) TextReader(StringBuffer buf, Thunk optFiller)
          Makes a Reader for reading from 'buf' in a non-blocking fashion, and calling 'optFiller' to refill it when it's empty.
 
Method Summary
 void __printOn(TextWriter out)
          Enabled:
 int available()
          Enabled: How many characters are immediately available? If the buffer is empty, then give the filler one chance and try again.
 void close()
          Enabled:
private  void consumed(int len)
          Record that len characters have just been read.
private  void ensureOpen()
           
private  void ensureReady()
           
 void fill()
          Enabled: Fill the buffer with all available characters, calling the filler as many times as necessary.
 boolean isDone()
          Enabled: Are we at end-of-stream?
 void mark(int readAheadLimit)
          Enabled: readAheadLimit is ignored
 int read(char[] cbuf, int off, int len)
          Enabled: Reads up to len chars, as many as it can without blocking.
 Character readChar()
          Enabled: Returns the next available character, or null at end of file.
 String readReady()
          Enabled: Returns as much as is available, or null at end-of-stream.
 String readString(int size)
          Enabled: Reads no more than 'size' characters from the file, and return them as a String.
 String readText()
          Enabled: Reads everything else and returns it.
 boolean ready()
          Enabled: True if either at least one character is available, or we're at the end-of-stream.
 void reset()
          Enabled:
 
Methods inherited from class java.io.Reader
getText, getTwine, iterate, iterate, markSupported, read, read, skip
 
Methods inherited from class java.lang.Object
clone, equals, finalize, getClass, hashCode, notify, notifyAll, toString, wait, wait, wait
 

Field Detail

myOptBuf

private StringBuffer myOptBuf
null if closed.

The StringBuffer is still held on to as 'lock'.


myOptFiller

private Thunk myOptFiller
If null, then myOptBuf is all that remains.


myIsMarked

private boolean myIsMarked
True when after a mark() and before a corresponding reset().


myNext

private int myNext
The next character to be read will be myOptBuf[myNext]. If not myIsMarked, this will be 0.

Constructor Detail

TextReader

TextReader(StringBuffer buf)
optFiller defaults to null


TextReader

TextReader(StringBuffer buf,
           Thunk optFiller)
Makes a Reader for reading from 'buf' in a non-blocking fashion, and calling 'optFiller' to refill it when it's empty.

Parameters:
buf - The StringBuffer to read from, and to synchronize on.
optFiller - When a read is attempted but 'buf' is empty, then optFiller is called to refill 'buf' and to provide a successor to itself, which may be null. The next refill will be to this successor. If the buffer goes empty and the current filler is null, then the TextReader reports end-of-stream (ie, further reads will return -1).
Method Detail

close

public void close()
           throws IOException
Enabled:

Specified by:
close in class Reader
IOException

ensureOpen

private void ensureOpen()
                 throws IOException
IOException

available

public int available()
              throws IOException
Enabled: How many characters are immediately available? If the buffer is empty, then give the filler one chance and try again. If instead you want to know the largest number of characters that are available, and buffer then as a result, then call fill() first.

Currently, this entire operation is performed with 'lock' held. XXX Should we release 'lock' around the call to myOptFiller?

IOException

fill

public void fill()
          throws IOException
Enabled: Fill the buffer with all available characters, calling the filler as many times as necessary.

IOException

ready

public boolean ready()
              throws IOException
Enabled: True if either at least one character is available, or we're at the end-of-stream.

Overrides:
ready in class Reader
Returns:
True if the next read() is guaranteed not to block for input, false otherwise. Note that returning false does not guarantee that the next read will block.
IOException

isDone

public boolean isDone()
               throws IOException
Enabled: Are we at end-of-stream?

IOException

ensureReady

private void ensureReady()
                  throws IOException
IOException

consumed

private void consumed(int len)
Record that len characters have just been read.


read

public int read(char[] cbuf,
                int off,
                int len)
         throws IOException
Enabled: Reads up to len chars, as many as it can without blocking.

If it can't read even a single char without blocking, throw an IOException rather than blocking or returning 0.

Specified by:
read in class Reader
Parameters:
cbuf - Destination buffer
off - Offset at which to start storing characters
len - Maximum number of characters to read
Returns:
The number of characters read, or -1 if the end of the stream has been reached
IOException

mark

public void mark(int readAheadLimit)
          throws IOException
Enabled: readAheadLimit is ignored

Overrides:
mark in class Reader
Parameters:
readAheadLimit - Limit on the number of characters that may be read while still preserving the mark. After reading this many characters, attempting to reset the stream may fail.
IOException

reset

public void reset()
           throws IOException
Enabled:

Overrides:
reset in class Reader
IOException

readChar

public Character readChar()
                   throws IOException
Enabled: Returns the next available character, or null at end of file.

If nothing is currently available, throws rather than blocking or returning -1.

IOException

readString

public String readString(int size)
                  throws IOException
Enabled: Reads no more than 'size' characters from the file, and return them as a String. If at end-of-file, return null.

IOException

readReady

public String readReady()
                 throws IOException
Enabled: Returns as much as is available, or null at end-of-stream.

If nothing is currently available, return "" rather than throwing.

IOException

readText

public String readText()
                throws IOException
Enabled: Reads everything else and returns it.

If everything else isn't yet available, then throws rather than blocking or returning something funny, but characters have still been consumed anyway. If this doesn't suit you, use mark() and reset() to protect yourself.

IOException

__printOn

public void __printOn(TextWriter out)
               throws IOException
Enabled:

IOException


comments?