|
YAACC - UPNP Client and Server
|
A seekable source of known length that is read at explicit positions and closed without ever blocking the caller. More...


Public Member Functions | |
| final long | size () |
| final int | readAt (long position, byte[] buf, int off, int len) throws IOException |
Reads up to len bytes starting at position. | |
| final boolean | isClosing () |
| final void | close () |
| Refuses new reads and closes the backend: now if nothing is reading, else when the last running read ends. | |
Protected Member Functions | |
| PositionalSource (long size) | |
| abstract int | readAtInternal (long position, byte[] buf, int off, int len) throws IOException |
| Reads from the backend. | |
| abstract void | closeInternal () |
| Closes the backend. | |
A seekable source of known length that is read at explicit positions and closed without ever blocking the caller.
Plain Java (no android.*) so the closing rules can be unit tested on the JVM; the Android adapter extends it and implements the two protected hooks.
Reads are positional: there is no current position, so any number of threads can read different ranges of one open source. The rules:
close() marks the source as closing and returns at once. New reads fail with an IOException from then on. closeInternal()) happens exactly once: immediately if no read is running, otherwise by the last reader that finishes. It never runs while a read is inside readAtInternal, so the underlying handle cannot be recycled under a reader. close() (the registry's sweeper, the exit path).
|
protected |
| size | the number of readable bytes, >= 0 |
| IllegalArgumentException | for a negative size |
| final void de.yaacc.share.PositionalSource.close | ( | ) |
Refuses new reads and closes the backend: now if nothing is reading, else when the last running read ends.
Returns immediately, may be called any number of times and from any thread; the backend is closed exactly once. A failure of the backend's close is swallowed (the share is gone either way).
Referenced by de.yaacc.share.DeleteOnCloseSource.closeInternal(), and de.yaacc.share.WatchedCopy.copy().

|
abstractprotected |
Closes the backend.
Called exactly once, never while a read is running, possibly on a reader's thread. Should not throw; an exception is swallowed.
Reimplemented in de.yaacc.share.DeleteOnCloseSource, and de.yaacc.share.HeldFileSource.
| final boolean de.yaacc.share.PositionalSource.isClosing | ( | ) |
close() was called | final int de.yaacc.share.PositionalSource.readAt | ( | long | position, |
| byte[] | buf, | ||
| int | off, | ||
| int | len ) throws IOException |
Reads up to len bytes starting at position.
The request is clipped at size(): the backend is never asked for a byte at or beyond it.
len == 0, or -1 at or beyond the end | IOException | if the source is closing or closed, or the backend fails |
| IllegalArgumentException | for a negative position or an invalid buffer range |
Referenced by de.yaacc.share.RangeStreamer.read(), and de.yaacc.share.DeleteOnCloseSource.readAtInternal().


|
abstractprotected |
Reads from the backend.
Called with 0 <= position < size(), len > 0 and a valid buffer range; possibly from several threads at once; never after the backend was closed. May return fewer bytes than asked. Returns -1 (or 0) if the backend has no more data at that position.
Reimplemented in de.yaacc.share.DeleteOnCloseSource, and de.yaacc.share.HeldFileSource.
Referenced by de.yaacc.share.PositionalSource.readAt().

| final long de.yaacc.share.PositionalSource.size | ( | ) |
Referenced by de.yaacc.share.DeleteOnCloseSource.DeleteOnCloseSource().
