api guide
This guide intends to give you a quick start to the Xdelta3 programming
interface. This is not a complete reference, the comments inside source file
xdelta3.h and the command-line application,
xdelta3-main.h offer more complete information.
Have you read the command-line interface?
stream interface
To begin with, there are three external structures, only two of which are
discussed here. The xd3_stream struct plays the main role, one
of these contains the state necessary to encode or decode one stream of data.
An xd3_source struct maintains state about the (optional) source
file, against which differences are computed. The third structure,
xd3_config deals with configuring various encoder parameters.
At a glance, the interface resembles Zlib. The program puts data in, which
the xd3_stream consumes. After computing over the data, the xd3_stream in
turn generates output for the application to consume, or it requests more
input. The xd3_stream also issues requests to the application to read a block
of source data. The request to read a source block may be handled in one of
two ways, according to application preference. If a xd3_getblk
callback function is provided, the application handler will be called from
within the library, suspending computation until the request completes. If no
callback function is provided the library returns a special code
(XD3_GETSRCBLK), allowing the application to issue the request and resume
computation whenever it likes. In both cases, the xd3_source struct contains
the requested block number and a place to store the result.
setup
The code to declare and initialize the xd3_stream:
int ret;
xd3_stream stream;
xd3_config config;
xd3_init_config (&config, 0 /* flags */);
config.winsize = 32768;
ret = xd3_config_stream (&stream, &config);
if (ret != 0) { /* error */ }
xd3_init_config() initializes the xd3_config struct
with default values. Many settings remain undocumented in the beta release.
The most relevant setting, xd3_config.winsize , sets the encoder
window size. The encoder allocates a buffer of this size if the program
supplies input in smaller units (unless the XD3_FLUSH flag is
set). xd3_config_stream() initializes the xd3_stream
object with the supplied configuration.
setting the source
The stream is ready for input at this point, though for encoding the source
data must be supplied now. To declare an initialize the xd3_source:
xd3_source source;
void *IO_handle = ...;
source.name = "...";
source.size = file_size;
source.ioh= IO_handle;
source.blksize= 32768;
source.curblkno = (xoff_t) -1;
source.curblk = NULL;
ret = xd3_set_source (&stream, &source);
if (ret != 0) { /* error */ }
The decoder sets source data in the same manner, but it may delay this step
until the application header has been received (XD3_GOTHEADER ).
The application can also check whether source data is required for decoding
with the xd3_decoder_needs_source() .
xd3_source.blksize determines the block size used for requesting
source blocks. If the first source block (or the entire source) is already in
memory, set curblkno to 0 and curblk to that block
of data.
input/output loop
The stream is now ready for input, which the application provides by
calling xd3_avail_input() . The application initiates
encoding or decoding at this point by calling one of two functions:
int xd3_encode_input (xd3_stream *stream)
int xd3_decode_input (xd3_stream *stream)
Unless there is an error, these routines return one of six result
codes which the application must handle. In many cases, all or most
of the handler code is shared between encoding and decoding. The
codes are:
-
XD3_INPUT : The stream is ready for (or requires) more input. The
application should call xd3_avail_input when (if) more data is
available.
-
XD3_OUTPUT : The stream has pending output. The application
should write or otherwise consume the block of data found in the
xd3_stream fields next_out and avail_out ,
then call xd3_consume_output .
-
XD3_GETSRCBLK : The stream is requesting a source block be read,
as described above. This is only ever returned if the xd3_getblk
callback was not provided.
-
XD3_GOTHEADER : This decoder-specific code indicates that the
first VCDIFF window header has been received. This gives the
application a chance to inspect the application header before
encoding the first window.
-
XD3_WINSTART : This is returned by both encoder and decoder prior to
processing a window. For encoding, this code is returned once there is enough
available input. For decoding, this is returned following each window header
(except the first, when XD3_GOTHEADER is returned instead).
-
XD3_WINFINISH : This is called when the output from a single
window has been fully consumed.
An application could be structured something like this:
do {
read (&indata, &insize);
if (reached_EOF) {
xd3_set_flags (&stream, XD3_FLUSH);
}
xd3_avail_input (&stream, indata, insize);
process:
ret = xd3_xxcode_input (&stream);
switch (ret) {
case XD3_INPUT:
continue;
case XD3_OUTPUT:
/* write data */
goto process;
case XD3_GETSRCBLK:
/* set source block */
goto process;
case XD3_GOTHEADER:
case XD3_WINSTART:
case XD3_WINFINISH:
/* no action necessary */
goto process;
default:
/* error */
}
} while (! reached_EOF);
All that remains is to close the stream and free its resources. The
xd3_close_stream() checks several error conditions but otherwise
involves no input or output. The xd3_free_stream() routine frees
all memory allocated by the stream.
misc
There are two convenience functions for encoding to and decoding from
in-memory buffers. See the xd3_encode_completely and
xd3_decode_completely interfaces.
There are two routines to get and set the application header. When
encoding, sthe application header must be set before the first
XD3_WINSTART . When decoding, the application header is available
after after the first XD3_GOTHEADER .
|