Output Internals

The concepts embodied by a fz_output object, and details of how to use them were given in Output Output. The above, relatively rich, set of functions are implemented on a fairly simple basic structure.

To implement your own fz_output, simply define a creation function of the form:


\begin{lstlisting}
fz_output *fz_new_output_foo(fz_context *ctx, <more parameter...
...foo_seek>
<optionally set out->tell = foo_tell>
return out;
}
\end{lstlisting}

This has parallels with the implementation of fz_streams, but is not quite identical.

If state needs no destruction, then we can use NULL in place of foo_close. Otherwise foo_close should be a function of type:


\begin{lstlisting}
/*
fz_output_close_fn: A function type for use when implemen...
...ypedef void (fz_output_close_fn)(fz_context *ctx, void *state);
\end{lstlisting}

This can be as simple as doing fz_free(ctx, state), or (depending on the complexity of the state structure) can require more involved operations to clean up.Many fz_output implementations rely on close being called to ensure the output is correctly flushed, and no data lost.

The most important function and the only non-optional one is foo_write. This is a function of type:


\begin{lstlisting}
/*
fz_output_write_fn: A function type for use when implemen...
..._fn)(fz_context *ctx, void *state, const void *data, size_t n);
\end{lstlisting}

Optionally we can choose to have our output stream support fz_seek_output and fz_tell_output. To do that we must implement foo_seek and foo_tell respectively, and assign them out->seek and out->tell during creation.


\begin{lstlisting}
/*
fz_output_seek_fn: A function type for use when implement...
...pedef size_t (fz_output_tell_fn)(fz_context *ctx, void *state);
\end{lstlisting}