The concepts embodied by a fz_stream object, and details of how to use them were given in Stream Stream. The above, relatively rich, set of functions are implemented on a fairly simple basic structure.
To implement your own fz_stream, simply define a creation function, of the form:
Note that some fz_try/fz_catch-ery may be required as part of the setup for state.
The hard work for this function is done using fz_new_stream, and two `foo' specific functions, foo_next and foo_close. First let's look at fz_new_stream:
This creates the main fz_stream structure, populates it with the given pointers (state, foo_next and foo_close) and sets the internal buffer pointers up to indicate an empty buffer.
As soon as anyone tries to read from the buffer (or to find out how many bytes are available), the MuPDF stream functions will cause foo_next to be called. This is a function of the following type:
When the stream is closed, the foo_close function will be called. This should be a function of type fz_stream_close_fn:
In our example, if the state was created by a simple fz_malloc_struct(ctx, foo_state) then foo_close might be as simple as a fz_free(ctx, state). If the internal state of the stream is more complex then the destructor will be similarly more complex.
These three functions (creation, next and close) are all that is required to define a stream.
Optionally, you can also define a seek and/or a meta function, using functions of the following types: