NAME
    Vcdiff - diff and patch for binary data

SYNOPSIS
    In order to use this module you must install one or more backend modules
    (see below)

        use Vcdiff;

        my $delta = Vcdiff::diff($source, $target);

        ## ... send the $delta string to someone who has $source ...

        my $target2 = Vcdiff::patch($source, $delta);

        ## $target2 is the same as $target

DESCRIPTION
    Given source data and target data, the "Vcdiff::diff" function computes
    a "delta" that encodes the information needed to turn source into
    target.

    Anyone who has source and delta can compute target with the
    "Vcdiff::patch" function.

    If the source and target inputs are related then delta can be very small
    relative to target, meaning it may be more efficient to send the delta
    string instead of the whole target.

    Even though source and target don't necessarily have to be binary data
    (regular data is fine too), the delta will always contain binary data
    including NUL bytes so if your transport protocols don't support this
    you will have to encode or escape it in some way (ie Base64).
    Compressing the delta before you do this might be worthwhile depending
    on the size of your changes and the entropy of your data.

    The delta format is described by <RFC 3284>, "The VCDIFF Generic
    Differencing and Compression Data Format".

STREAMING API
    The streaming API is sometimes more convenient than the in-memory API.
    It can also be more efficient since it uses less memory. Also, you can
    start processing output before Vcdiff has finished.

    Sometimes you have to use the streaming API in order to handle files
    that are too large to fit into your virtual address space (though note
    that some backends have size limitations apart from this).

    In order to send output to a stream, a file handle should be passed in
    as the 3rd argument to "diff" or "patch":

        Vcdiff::diff("hello", "hello world", \*STDOUT);

    In order to fully take advantage of streaming, the source and target
    parameters of "diff" and the source and delta parameters of "patch" can
    be file handles instead of strings:

        open(my $source_fh, '<', 'source.dat') || die $!;
        open(my $target_fh, '<', 'target.dat') || die $!;
        open(my $delta_fh, '>', 'delta.dat') || die $!;

        Vcdiff::diff($source_fh, $target_fh, $delta_fh);

    Note that in all current backends the source file handle must be backed
    by an lseek(2)able and/or mmap(2)able file descriptor (in other words, a
    real file, not a pipe or socket). Vcdiff will throw an exception if the
    source file handle is unsuitable.

MEMORY MAPPED INPUTS
    If the source or target/delta data is in a file, an alternative to the
    streaming API is to map the files into memory with mmap(2) and then pass
    the mappings in to "diff"/"patch" as strings.

    Doing so is more efficient than the streaming API for large files
    because fewer system calls are made and a kernel-space to user-space
    copy is avoided. As mentioned above, files that are too large to fit in
    your virtual address must be diffed with the streaming API (this is only
    an issue when diffing multi-gigabyte files on 32 bit systems).

    Here is an example using Sys::Mmap:

        use Sys::Mmap;

        open(my $source_fh, '<', 'source.dat') || die $!;
        open(my $target_fh, '<', 'target.dat') || die $!;
        open(my $delta_fh, '>', 'delta.dat') || die $!;

        my ($source_str, $target_str);

        mmap($source_str, 0, PROT_READ, MAP_SHARED, $source_fh) || die $!;
        mmap($target_str, 0, PROT_READ, MAP_SHARED, $target_fh) || die $!;

        Vcdiff::diff($source_str, $target_str, $delta_fh);

        munmap($source_str);
        munmap($target_str);

BACKENDS
    Vcdiff doesn't itself implement delta compression. Instead, it provides
    a consistent interface to various open-source VCDIFF (RFC 3284)
    implementations. The implementation libraries it interfaces to are
    called "backends".

    In other words, Vcdiff aims to be "the DBI" of VCDIFF implementations.

    The currently supported backends are described below. See the POD
    documentation in the backend module distributions for more details on
    the pros and cons of each backend.

  XDELTA3 BACKEND
    The Vcdiff::Xdelta3 backend module bundles Joshua MacDonald's <Xdelta3>
    library.

  OPEN-VCDIFF BACKEND
    The Vcdiff::OpenVcdiff backend module depends on Alien::OpenVcdiff which
    configures, builds, and installs Google's <open-vcdiff> library.

  FUTURE BACKENDS
    Another possible candidate would be Kiem-Phong Vo's <Vcodex> library
    which contains a vcdiff implementation.

    A really cool project would be a pure-perl VCDIFF implementation that
    could be used in environments that are unable to compile XS modules.

  CHOOSING A BACKEND
    In order to choose which backend to use, Vcdiff will first check to see
    if the $Vcdiff::backend variable is populated. If so, it will attempt to
    load that backend. This variable can be used to force a particular
    backend:

        {
            local $Vcdiff::backend = 'Vcdiff::OpenVcdiff';
            $delta = Vcdiff::diff($source, $target);
        }

    Otherwise, Vcdiff will check to see if any backends have been loaded
    already. If so, it will choose the first one it finds:

        use Vcdiff::Xdelta3;
        $delta = Vcdiff::diff($source, $target);

    If it doesn't find any loaded backends, it will try to load them in the
    following order: Xdelta3, OpenVcdiff.

    Finally, if none of these backends can be loaded, an exception is
    thrown.

SEE ALSO
    <Vcdiff github repo>

    <RFC 3284>, "The VCDIFF Generic Differencing and Compression Data
    Format"

AUTHOR
    Doug Hoyte, "<doug@hcsw.org>"

COPYRIGHT & LICENSE
    Copyright 2013 Doug Hoyte.

    This module is licensed under the same terms as perl itself.

