Algorithm-GDiffDelta

 view release on metacpan or  search on metacpan

GDiffDelta.xs  view on Meta::CPAN


        dSP;
        ENTER;
        SAVETMPS;
        PUSHMARK(SP);
        XPUSHs(f);
        /* TODO - possibly use newSVpvn_share to avoid the memcpy
         * and extra allocation for buf? */
        XPUSHs(sv_2mortal(buf = newSVpvn("", 0)));
        XPUSHs(sv_2mortal(newSVuv(size)));
        PUTBACK;
        n = call_method("read", G_SCALAR);
        assert(n == 0 || n == 1);
        SPAGAIN;
        ret = n ? POPs : &PL_sv_undef;
        if (!SvOK(ret))
            croak("error reading from %s: %s", from,
                  SvPV_nolen(get_sv("!", FALSE)));
        if (SvUV(ret) != size)
            croak("%s ends unexpectedly", from);
        if (!SvPOK(buf) || SvCUR(buf) != size)
            croak("'read' method left buffer badly set up", from);
        str = SvPV(buf, len);
        assert(len == size);
        memcpy(ptr, str, size);
        PUTBACK;
        FREETMPS;
        LEAVE;
    }
    else {
        int r = PerlIO_read(IoIFP(sv_2io(f)), ptr, size);
        if (r < 0)
            croak("error reading from %s: %s", from, strerror(errno));
        else if ((size_t) r != size)
            croak("%s ends unexpectedly", from);
    }

GDiffDelta.xs  view on Meta::CPAN

#endif

    if (sv_isobject(f)) {
        dSP;
        ENTER;
        SAVETMPS;
        PUSHMARK(SP);
        XPUSHs(f);
        XPUSHs(sv_2mortal(newSVpvn(ptr, size)));
        XPUSHs(sv_2mortal(newSVuv(size)));
        PUTBACK;
        n = call_method("write", G_SCALAR);
        assert(n == 0 || n == 1);
        SPAGAIN;
        ret = n ? POPs : &PL_sv_no;
        n = SvTRUE(ret);
        PUTBACK;
        FREETMPS;
        LEAVE;
        if (!n)
            croak("error writing to %s: %s", to,
                  SvPV_nolen(get_sv("!", FALSE)));
    }
    else {
        if ((size_t) PerlIO_write(IoIFP(sv_2io(f)), ptr, size) != size)
            croak("error writing to %s: %s", to, strerror(errno));
    }

GDiffDelta.xs  view on Meta::CPAN

        I32 n;
        SV *ret;

        dSP;
        ENTER;
        SAVETMPS;
        PUSHMARK(SP);
        XPUSHs(f);
        XPUSHs(sv_2mortal(newSVuv(offset)));
        XPUSHs(sv_2mortal(newSVuv(whence)));
        PUTBACK;
        n = call_method("seek", G_SCALAR);
        assert(n == 0 || n == 1);
        SPAGAIN;
        ret = n ? POPs : &PL_sv_undef;
        n = SvTRUE(ret);
        PUTBACK;
        FREETMPS;
        LEAVE;
        if (!n)
            croak("error seeking in %s: %s", from,
                  SvPV_nolen(get_sv("!", FALSE)));
    }
    else {
        if (PerlIO_seek(IoIFP(sv_2io(f)), offset, whence))
            croak("error seeking in %s: %s", from, strerror(errno));
    }

GDiffDelta.xs  view on Meta::CPAN


    if (sv_isobject(f)) {
        I32 n;
        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));

GDiffDelta.xs  view on Meta::CPAN

    size_t headsz = 0;

    assert(size > 0);
    assert(size <= QEF_INT_MAX);
    assert(buf);

    if (size <= 246)
        buf[headsz++] = size;
    else if (size <= QEF_USHORT_MAX) {
        buf[headsz++] = 247;
        QEF_BE16_PUT(buf, headsz, size);
    }
    else {
        buf[headsz++] = 248;
        QEF_BE32_PUT(buf, headsz, size);
    }

    /* Write the opcode and size argument (if any).  */
    careful_fwrite(buf, headsz, delta, "delta");

    /* Copy the actual data to be inserted into the delta.  */
    careful_fseek(changed, offset, "changed file");
    copy_data(changed, delta, size, buf, "changed file", "delta");
}

GDiffDelta.xs  view on Meta::CPAN

copy_op (SV *delta, Off_t offset, Off_t size)
{
    unsigned char buf[QEF_COPY_MAX];
    size_t headsz = 0;

    assert(size > 0);

    if (offset <= QEF_USHORT_MAX) {
        if (size <= QEF_UBYTE_MAX) {
            buf[headsz++] = 249;
            QEF_BE16_PUT(buf, headsz, offset);
            buf[headsz++] = size;
        }
        else if (size <= QEF_USHORT_MAX) {
            buf[headsz++] = 250;
            QEF_BE16_PUT(buf, headsz, offset);
            QEF_BE16_PUT(buf, headsz, size);
        }
        else if (size <= QEF_INT_MAX) {
            buf[headsz++] = 251;
            QEF_BE16_PUT(buf, headsz, offset);
            QEF_BE32_PUT(buf, headsz, size);
        }
        else {
            /* TODO - break copy ops for bigger than 2Gb into smaller ones */
            assert(0);
        }
    }
    else if (offset <= QEF_INT_MAX) {
        if (size <= QEF_UBYTE_MAX) {
            buf[headsz++] = 252;
            QEF_BE32_PUT(buf, headsz, offset);
            buf[headsz++] = size;
        }
        else if (size <= QEF_USHORT_MAX) {
            buf[headsz++] = 253;
            QEF_BE32_PUT(buf, headsz, offset);
            QEF_BE16_PUT(buf, headsz, size);
        }
        else if (size <= QEF_INT_MAX) {
            buf[headsz++] = 254;
            QEF_BE32_PUT(buf, headsz, offset);
            QEF_BE32_PUT(buf, headsz, size);
        }
        else {
            /* TODO - break copy ops for bigger than 2Gb into smaller ones */
            assert(0);
        }
    }
    else {
        /* TODO - allow 64bit offsets */
        assert(0);
    }

GDiffDelta.xs  view on Meta::CPAN



U32
qefgdiff_gdiff_adler32 (U32 init, SV *s)
    PREINIT:
        STRLEN len;
        const unsigned char *buf;
    CODE:
        buf = (unsigned char *) SvPV(s, len);
        RETVAL = adler32(init, buf, len);
    OUTPUT:
        RETVAL


void
qefgdiff_gdiff_delta (SV *orig, SV *changed, SV *delta)
    CODE:
        careful_fwrite("\xD1\xFF\xD1\xFF\x04", 5, delta, "delta");
        do_delta(orig, changed, delta);
        careful_fwrite("\0", 1, delta, "delta");

util.h  view on Meta::CPAN

#define QEF_UBYTE_MAX 0xFFUL

/* Maximum value of a GDIFF ushort (unsigned 16 bit value).  */
#define QEF_USHORT_MAX 0xFFFFUL

/* Maximum value of a GDIFF int (signed 32 bit value).  */
#define QEF_INT_MAX 0x7FFFFFFFUL

/* Copy a number into a buffer in big-endian format, using a counter as an
 * index into the buffer and moving it along the right number of bytes.  */
#define QEF_BE16_PUT(buf, idx, num) \
    do { \
        buf[idx++] = ((num) >> 8) & 0xFF; \
        buf[idx++] = (num) & 0xFF; \
    } while (0)
#define QEF_BE32_PUT(buf, idx, num) \
    do { \
        buf[idx++] = ((num) >> 24) & 0xFF; \
        buf[idx++] = ((num) >> 16) & 0xFF; \
        buf[idx++] = ((num) >> 8) & 0xFF; \
        buf[idx++] = (num) & 0xFF; \
    } while (0)


/* Data structures for the hashes of the original file.  */
struct QefChaNode {



( run in 0.489 second using v1.01-cache-2.11-cpan-d6f9594c0a5 )