1 # Callback API {#api_pull}
3 As an alternative to \ref api_streaming, librsync provides a
"pull-mode"
4 callback
interface where it will repeatedly call application-provided
5 callbacks to get more input data and to accept output data.
10 However, rather than calling
rs_job_iter(), the application should then call
12 an opaque pointer for both the input and output callback: this could be a
13 `FILE*` or some similar object telling them what to read and write.
17 The librsync interface allows non-blocking streaming processing of data.
18 This means that the library will accept input and produce output when it
19 suits the application. If nonblocking file IO is used and the IO
20 callbacks support it, then librsync will never block waiting for IO.
22 Normally callbacks will read/write the whole buffer when they're called,
23 but in some cases they might not be able to process all of it, or
24 perhaps not process any at all. This might happen if the callbacks are
25 connected to a nonblocking socket. Either of two things can happen in
29 When an IO callback blocks, it is the responsibility of the application
30 to work out when it will be able to make progress and therefore when it
31 is worth calling
rs_job_iter() again. Typically this involves a mechanism
32 like `poll` or `select` to wait for the file descriptor to be ready.
36 The IO callbacks are allowed to block.
37 This will of course mean that the application's call to
42 IO callbacks are also allowed to process or provide only part of the requested
43 data, as will commonly happen with socket IO.
45 The library might not get as much input as it wanted when it is first
46 called. If it gets a partial read, it needs to hold onto that
47 valuable and irreplaceable data.
49 It cannot keep it on the stack, because it will be lost if the read
50 blocks. It needs to be kept in the job structure, or in somewhere
51 referenced from there.
53 The state function probably cannot proceed until it has all the needed
54 input. So possibly this can be expressed at a high level of the job
55 structure. Or perhaps it should just be done by each particular state
58 When the library has output to write out, the callback might not be
59 able to accept all of it at the time it is called. Deferred outgoing
60 data needs to be stored in a buffer referenced from the job structure.
62 I think it's always OK to try to flush this when entering
rs_job_iter.
63 I think it's OK to not do anything else until all the outgoing data
66 In many cases we would like to pass a pointer into the input (or
67 pread) buffer straight to the output callback. In other cases, we
68 need a different buffer to build up literal outgoing data.
70 librsync deals with short, bounded-size headers and checksums, and
71 with arbitrarily-large streaming data. Although the commands are of
72 bounded size, they are not of fixed size, because there are different
73 encodings to suit different situations.
75 The situation is very similar to fetching variable-length headers from
76 a socket. We cannot read the whole command in a single input, because
77 we don't know how long it is. As a general principle I think we
78 should *not* read in too much data and buffer it, because this
79 complicates things. Therefore we need to read the type byte first,
80 and then possibly read some parameters.
LIBRSYNC_EXPORT rs_job_t * rs_sig_begin(size_t block_len, size_t strong_len, rs_magic_number sig_magic)
Start generating a signature.
rs_result rs_job_iter(rs_job_t *job, rs_buffers_t *buffers)
Run a rs_job state machine until it blocks (RS_BLOCKED), returns an error, or completes (RS_DONE)...
LIBRSYNC_EXPORT rs_job_t * rs_loadsig_begin(rs_signature_t **)
Read a signature from a file into an rs_signature structure in memory.
rs_job_t * rs_delta_begin(rs_signature_t *sig)
Prepare to compute a streaming delta.
Blocked waiting for more data.
LIBRSYNC_EXPORT rs_job_t * rs_patch_begin(rs_copy_cb *copy_cb, void *copy_arg)
Apply a delta to a basis file to recreate the new file.
rs_result rs_job_drive(rs_job_t *job, rs_buffers_t *buf, rs_driven_cb in_cb, void *in_opaque, rs_driven_cb out_cb, void *out_opaque)
Actively process a job, by making callbacks to fill and empty the buffers until the job is done...