Algorithm-GDiffDelta

 view release on metacpan or  search on metacpan

GDiffDelta.xs  view on Meta::CPAN

        SV *ret;

        dSP;
        ENTER;
        SAVETMPS;
        PUSHMARK(SP);
        XPUSHs(f);
        PUTBACK;
        n = call_method("tell", G_SCALAR);
        assert(n == 0 || n == 1);
        SPAGAIN;
        offset = (Off_t) -1;
        if (n) {
            ret = POPs;
            if (SvOK(ret))
                offset = SvUV(ret);
        }
        PUTBACK;
        FREETMPS;
        LEAVE;
        if (offset == (Off_t) -1)
            croak("error getting position in %s: %s", from,
                  SvPV_nolen(get_sv("!", FALSE)));
    }
    else {
        offset = PerlIO_tell(IoIFP(sv_2io(f)));
        if (offset == (Off_t) -1)
            croak("error getting position in %s: %s", from, strerror(errno));
    }

    return offset;
}

QEF_INLINE static size_t
read_ubyte (SV *f)
{
    unsigned char buf;
    careful_fread(&buf, 1, f, "delta");
    return buf;
}

QEF_INLINE static size_t
read_ushort (SV *f)
{
    unsigned char buf[2];
    careful_fread(buf, 2, f, "delta");
    return buf[0] * 0x100 + buf[1];
}

QEF_INLINE static size_t
read_int (SV *f)
{
    unsigned char buf[4];
    careful_fread(buf, 4, f, "delta");
    if (buf[0] >= 0x7F)
        croak("delta contains negative int value");
    return buf[0] * 0x1000000 + buf[1] * 0x10000 +
           buf[2] * 0x100 + buf[3];
}

/* The buffer is supplied by the parent so that we can avoid allocating
 * it on the stack every time this is called, even though that probably
 * wouldn't be very expensive in most implementations.  */
static void
copy_data (SV *in, SV *out, size_t num_bytes, unsigned char *buf,
           const char *from, const char *to)
{
    assert(buf);

    while (num_bytes >= QEF_BUFSZ) {
        careful_fread(buf, QEF_BUFSZ, in, from);
        careful_fwrite(buf, QEF_BUFSZ, out, to);
        num_bytes -= QEF_BUFSZ;
    }

    careful_fread(buf, num_bytes, in, from);
    careful_fwrite(buf, num_bytes, out, to);
}

/* Work out the size of the file by seeking to the end.  */
static Off_t
file_size (SV *f, const char *from)
{
    careful_fseek_whence(f, 0, from, SEEK_END);
    return careful_ftell(f, from);
}


/* largest prime smaller than 65536 */
#define QEF_BASE 65521L

/* NMAX is the largest n such that 255n(n+1)/2 + (n+1)(BASE-1) <= 2^32-1 */
#define QEF_NMAX 5552

#define QEF_DO1(buf, i)  { s1 += buf[i]; s2 += s1; }
#define QEF_DO2(buf, i)  QEF_DO1(buf, i); QEF_DO1(buf, i + 1);
#define QEF_DO4(buf, i)  QEF_DO2(buf, i); QEF_DO2(buf, i + 2);
#define QEF_DO8(buf, i)  QEF_DO4(buf, i); QEF_DO4(buf, i + 4);
#define QEF_DO16(buf)    QEF_DO8(buf, 0); QEF_DO8(buf, 8);

static U32
adler32(U32 adler, const unsigned char *buf, size_t len)
{
    int k;
    U32 s1 = adler & 0xffff;
    U32 s2 = (adler >> 16) & 0xffff;

    assert(buf);

    while (len > 0) {
        k = len < QEF_NMAX ? len : QEF_NMAX;
        len -= k;
        while (k >= 16) {
            QEF_DO16(buf);
            buf += 16;
            k -= 16;
        }
        if (k != 0)
            do {
                s1 += *buf++;
                s2 += s1;



( run in 0.775 second using v1.01-cache-2.11-cpan-f0fbb3f571b )