summaryrefslogtreecommitdiff
path: root/rsync/delta.c
Side-by-side diff
Diffstat (limited to 'rsync/delta.c') (more/less context) (ignore whitespace changes)
-rw-r--r--rsync/delta.c2
1 files changed, 2 insertions, 0 deletions
diff --git a/rsync/delta.c b/rsync/delta.c
index 323c079..42f3afb 100644
--- a/rsync/delta.c
+++ b/rsync/delta.c
@@ -242,110 +242,112 @@ rs_delta_scan(rs_job_t *job, rs_long_t avail_len, void *p)
* emit the copy command or keep searching. */
/* FIXME: At the moment, if you call with very short buffers,
* then you will get a series of very short LITERAL commands.
* Perhaps this is what you deserve, or perhaps we should try
* to get more readahead and avoid that. */
/* There's some literal data at the start of this window which
* we know is not in any block. */
rs_trace("got %d bytes of literal data", search_pos);
rs_emit_literal_cmd(job, search_pos);
rs_tube_copy(job, search_pos);
}
return RS_RUNNING;
}
static rs_result rs_delta_s_deferred_copy(rs_job_t *job)
{
if (!job->basis_len) {
rs_log(RS_LOG_ERR, "somehow got zero basis_len");
return RS_INTERNAL_ERROR;
}
rs_emit_copy_cmd(job, job->basis_pos, job->basis_len);
rs_scoop_advance(job, job->basis_len);
job->statefn = rs_delta_s_scan;
return RS_RUNNING;
}
/**
* \brief State function that does a slack delta containing only
* literal data to recreate the input.
*/
static rs_result rs_delta_s_slack(rs_job_t *job)
{
rs_buffers_t * const stream = job->stream;
size_t avail = stream->avail_in;
if (avail) {
rs_trace("emit slack delta for %.0f available bytes", (double) avail);
rs_emit_literal_cmd(job, avail);
rs_tube_copy(job, avail);
return RS_RUNNING;
} else {
if (rs_job_input_is_ending(job)) {
job->statefn = rs_delta_s_end;
return RS_RUNNING;
} else {
return RS_BLOCKED;
}
}
}
/**
* State function for writing out the header of the encoding job.
*/
static rs_result rs_delta_s_header(rs_job_t *job)
{
rs_emit_delta_header(job);
if (job->block_len) {
if (!job->signature) {
rs_error("no signature is loaded into the job");
return RS_PARAM_ERROR;
}
job->statefn = rs_delta_s_scan;
} else {
rs_trace("block length is zero for this delta; "
"therefore using slack deltas");
job->statefn = rs_delta_s_slack;
}
return RS_RUNNING;
}
/**
* Prepare to compute a streaming delta.
*/
rs_job_t *rs_delta_begin(rs_signature_t *sig)
{
rs_job_t *job;
job = rs_job_new("delta", rs_delta_s_header);
job->signature = sig;
if ((job->block_len = sig->block_len) < 0) {
rs_log(RS_LOG_ERR, "unreasonable block_len %d in signature",
job->block_len);
+ rs_job_free(job);
return NULL;
}
job->strong_sum_len = sig->strong_sum_len;
if (job->strong_sum_len < 0 || job->strong_sum_len > RS_MD4_LENGTH) {
rs_log(RS_LOG_ERR, "unreasonable strong_sum_len %d in signature",
job->strong_sum_len);
+ rs_job_free(job);
return NULL;
}
return job;
}