Chapter 28
Output Internals

The concepts embodied by a fz_output object, and details of how to use them were given in chapter 13 The Output interface. 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:

fz_output *fz_new_output_foo(fz_context *ctx, <more parameters here>) 
{ 
   fz_output *out = fz_new_output(ctx, <state>, foo_write, foo_close); 
   <optionally set out->seek = foo_seek> 
   <optionally set out->tell = foo_tell> 
   return out; 
}

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:

/* 
   fz_output_close_fn: A function type for use when implementing 
   fz_outputs. The supplied function of this type is called 
   when the output stream is closed, to release the stream specific 
   state information. 
 
   state: The output stream state to release. 
*/ 
typedef void (fz_output_close_fn)(fz_context *ctx, void *state);

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:

/* 
   fz_output_write_fn: A function type for use when implementing 
   fz_outputs. The supplied function of this type is called 
   whenever data is written to the output. 
 
   state: The state for the output stream. 
 
   data: a pointer to a buffer of data to write. 
 
   n: The number of bytes of data to write. 
*/ 
typedef void (fz_output_write_fn)(fz_context *ctx, void *state, const void *data, size_t n);

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.

/* 
   fz_output_seek_fn: A function type for use when implementing 
   fz_outputs. The supplied function of this type is called when 
   fz_seek_output is requested. 
 
   state: The output stream state to seek within. 
 
   offset, whence: as defined for fs_seek_output. 
*/ 
typedef void (fz_output_seek_fn)(fz_context *ctx, void *state, fz_off_t offset, int whence); 
 
/* 
   fz_output_tell_fn: A function type for use when implementing 
   fz_outputs. The supplied function of this type is called when 
   fz_tell_output is requested. 
 
   state: The output stream state to report on. 
 
   Returns the offset within the output stream. 
*/ 
typedef size_t (fz_output_tell_fn)(fz_context *ctx, void *state);