Reading bytes

The simplest way to read bytes from a stream is to call fz_read_byte to read the next byte from a file. Akin to the standard fgetc, this returns -1 for end of data, or the next byte available.


\begin{lstlisting}
/*
fz_read_byte: Read the next byte from a stream.
\par
stm:...
...ceptions.
*/
int fz_read_byte(fz_context *ctx, fz_stream *stm);
\end{lstlisting}

To read more than 1 byte at a time, there are two different options.

Firstly, and most efficiently, bytes can be read directly from the streams underlying buffer. For a given fz_stream *stm, the current position in the stream is pointed to by stm->rp. Bytes can simply be read out, and the pointer incremented by the number read.

To do this, you must first know how many bytes there are available to be read out. This is achieved by calling fz_available. If there are no bytes already decoded and awaiting reading, this call will trigger a refill of the underlying buffer, which may take noticeable time.


\begin{lstlisting}
/*
fz_available: Ask how many bytes are available immediatel...
...ze_t fz_available(fz_context *ctx, fz_stream *stm, size_t max);
\end{lstlisting}

To avoid needless work, a `max' value can be supplied as a hint, telling any buffer refill operation that is triggered how many bytes are actually required. Specifying a max value does not guarantee you anything about the number of bytes actually made available.

Some callers may find this awkward - the need to potentially repeatedly call until you get enough bytes to fill a buffer of the required length may be tedious. Therefore as an alternative, we provide a simpler call, fz_read.

Designed to be similar to the standard fread call, this attempts to read as many bytes as possible into a supplied data block, returning the actual number of bytes successfully read.


\begin{lstlisting}
/*
fz_read: Read from a stream into a given data block.
\par...
...context *ctx, fz_stream *stm, unsigned char *data, size_t len);
\end{lstlisting}

Typically the only reason that fz_read will not return the requested number of bytes is if we hit the end of the stream. This implies that calls to fz_read will block until such data is ready. For streams based on `fast' sources like files or memory, this is an unimportant distinction.

For streams based on (say) an http download, this might result in significant delays, and an unacceptable user experience. To alleviate this problem we have a mechanism whereby such streams can signal a temporary end of data by throwing the FZ_ERROR_TRYLATER error. See ProgressiveMode ProgressiveMode for more details.

To facilitate reading without blocking (or using buffers larger than required), fz_available can be called to find out the number of bytes that can safely be requested.

If data within a stream is not required, it can be skipped over using fz_skip:


\begin{lstlisting}
/*
fz_skip: Read from a stream discarding data.
\par
stm: Th...
...*/
size_t fz_skip(fz_context *ctx, fz_stream *stm, size_t len);
\end{lstlisting}

As a special case, after a single byte is read, it can be pushed back into the stream, using fz_unread_byte:


\begin{lstlisting}
/*
fz_unread_byte: Unread the single last byte successfully
...
...void fz_unread_byte(fz_context *ctx FZ_UNUSED, fz_stream *stm);
\end{lstlisting}

The act of reading a byte, and then, if successful pushing it back again is encapsulated in a convenience function, fz_peek_byte:


\begin{lstlisting}
/*
fz_peek_byte: Peek at the next byte in a stream.
\par
stm...
... be read.
*/
int fz_peek_byte(fz_context *ctx, fz_stream *stm);
\end{lstlisting}