YAACC - UPNP Client and Server
Loading...
Searching...
No Matches
de.yaacc.share.PositionalSource Class Referenceabstract

A seekable source of known length that is read at explicit positions and closed without ever blocking the caller. More...

Inheritance diagram for de.yaacc.share.PositionalSource:
Inheritance graph
Collaboration diagram for de.yaacc.share.PositionalSource:
Collaboration graph

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.
 

Detailed Description

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.
  • The real close (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.
  • A thread stuck in a slow read (a provider that blocks) therefore delays only the real close, never the caller of close() (the registry's sweeper, the exit path).

Constructor & Destructor Documentation

◆ PositionalSource()

de.yaacc.share.PositionalSource.PositionalSource ( long size)
protected
Parameters
sizethe number of readable bytes, >= 0
Exceptions
IllegalArgumentExceptionfor a negative size

Member Function Documentation

◆ close()

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().

Here is the caller graph for this function:

◆ closeInternal()

abstract void de.yaacc.share.PositionalSource.closeInternal ( )
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.

◆ isClosing()

final boolean de.yaacc.share.PositionalSource.isClosing ( )
Returns
true once close() was called

◆ readAt()

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.

Returns
the number of bytes read (> 0), 0 only for len == 0, or -1 at or beyond the end
Exceptions
IOExceptionif the source is closing or closed, or the backend fails
IllegalArgumentExceptionfor a negative position or an invalid buffer range

Referenced by de.yaacc.share.RangeStreamer.read(), and de.yaacc.share.DeleteOnCloseSource.readAtInternal().

Here is the call graph for this function:
Here is the caller graph for this function:

◆ readAtInternal()

abstract int de.yaacc.share.PositionalSource.readAtInternal ( long position,
byte[] buf,
int off,
int len ) throws IOException
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().

Here is the caller graph for this function:

◆ size()

final long de.yaacc.share.PositionalSource.size ( )
Returns
the number of readable bytes

Referenced by de.yaacc.share.DeleteOnCloseSource.DeleteOnCloseSource().

Here is the caller graph for this function:

The documentation for this class was generated from the following file: