Alien-SVN
view release on metacpan or search on metacpan
src/subversion/subversion/libsvn_delta/text_delta.c view on Meta::CPAN
static APR_INLINE char *
patterning_copy(char *target, const char *source, apr_size_t len)
{
const char *end = source + len;
/* On many machines, we can do "chunky" copies. */
#if SVN_UNALIGNED_ACCESS_IS_OK
if (end + sizeof(apr_uint32_t) <= target)
{
/* Source and target are at least 4 bytes apart, so we can copy in
* 4-byte chunks. */
for (; source + sizeof(apr_uint32_t) <= end;
source += sizeof(apr_uint32_t),
target += sizeof(apr_uint32_t))
*(apr_uint32_t *)(target) = *(apr_uint32_t *)(source);
}
#endif
/* fall through to byte-wise copy (either for the below-chunk-size tail
* or the whole copy) */
for (; source != end; source++)
*(target++) = *source;
return target;
}
void
svn_txdelta_apply_instructions(svn_txdelta_window_t *window,
const char *sbuf, char *tbuf,
apr_size_t *tlen)
{
const svn_txdelta_op_t *op;
apr_size_t tpos = 0;
for (op = window->ops; op < window->ops + window->num_ops; op++)
{
const apr_size_t buf_len = (op->length < *tlen - tpos
? op->length : *tlen - tpos);
/* Check some invariants common to all instructions. */
assert(tpos + op->length <= window->tview_len);
switch (op->action_code)
{
case svn_txdelta_source:
/* Copy from source area. */
assert(sbuf);
assert(op->offset + op->length <= window->sview_len);
fast_memcpy(tbuf + tpos, sbuf + op->offset, buf_len);
break;
case svn_txdelta_target:
/* Copy from target area. We can't use memcpy() or the like
* since we need a specific semantics for overlapping copies:
* they must result in repeating patterns.
* Note that most copies won't have overlapping source and
* target ranges (they are just a result of self-compressed
* data) but a small percentage will. */
assert(op->offset < tpos);
patterning_copy(tbuf + tpos, tbuf + op->offset, buf_len);
break;
case svn_txdelta_new:
/* Copy from window new area. */
assert(op->offset + op->length <= window->new_data->len);
fast_memcpy(tbuf + tpos,
window->new_data->data + op->offset,
buf_len);
break;
default:
assert(!"Invalid delta instruction code");
}
tpos += op->length;
if (tpos >= *tlen)
return; /* The buffer is full. */
}
/* Check that we produced the right amount of data. */
assert(tpos == window->tview_len);
*tlen = tpos;
}
/* This is a private interlibrary compatibility wrapper. */
void
svn_txdelta__apply_instructions(svn_txdelta_window_t *window,
const char *sbuf, char *tbuf,
apr_size_t *tlen);
void
svn_txdelta__apply_instructions(svn_txdelta_window_t *window,
const char *sbuf, char *tbuf,
apr_size_t *tlen)
{
svn_txdelta_apply_instructions(window, sbuf, tbuf, tlen);
}
/* Apply WINDOW to the streams given by APPL. */
static svn_error_t *
apply_window(svn_txdelta_window_t *window, void *baton)
{
struct apply_baton *ab = (struct apply_baton *) baton;
apr_size_t len;
svn_error_t *err;
if (window == NULL)
{
/* We're done; just clean up. */
if (ab->result_digest)
apr_md5_final(ab->result_digest, &(ab->md5_context));
err = svn_stream_close(ab->target);
svn_pool_destroy(ab->pool);
return err;
}
( run in 0.849 second using v1.01-cache-2.11-cpan-13bb782fe5a )