ByteSource abstracts the source of data from the core workings of BinaryDecoder. This is very important for performance reasons because InputStream's API is a barrier to performance due to several quirks: InputStream does not in general require that as many bytes as possible have been read when filling a buffer.
InputStream's terminating conditions for a read are two-fold: EOFException and '-1' on the return from read(). Implementations are supposed to return '-1' on EOF but often do not. The extra terminating conditions cause extra conditionals on both sides of the API, and slow performance significantly.
ByteSource implementations provide read() and skip() variants that have stronger guarantees than InputStream, freeing client code to be simplified and faster.
{@link skipSourceBytes} and {@link readRaw} are guaranteed to have read orskipped as many bytes as possible, or throw EOFException. {@link trySkipBytes} and {@link tryRead} are guaranteed to attempt to reador skip as many bytes as possible and never throw EOFException, while returning the exact number of bytes skipped or read. {@link isEof} returnstrue if all the source bytes have been read or skipped. This condition can also be detected by a client if an EOFException is thrown from {@link skipSourceBytes} or {@link readRaw}, or if {@link trySkipBytes} or{@link tryRead} return 0;
A ByteSource also implements the InputStream contract for use by APIs that require it. The InputStream interface must take into account buffering in any decoder that this ByteSource is attached to. The other methods do not account for buffering.