Algorithm-GDiffDelta
view release on metacpan or search on metacpan
GDiffDelta.xs view on Meta::CPAN
/* Algorithm::GDiffDelta implementation.
*
* Copyright (C) 2003 Davide Libenzi (code derived from libxdiff)
* Copyright 2004, Geoff Richards
*
* This library is free software; you can redistribute it and/or
* modify it under the terms of the GNU Lesser General Public
* License as published by the Free Software Foundation; either
* version 2.1 of the License, or (at your option) any later version.
*
* This library is distributed in the hope that it will be useful,
* but WITHOUT ANY WARRANTY; without even the implied warranty of
* MERCHANTABILITY or FITNESS FOR A PARTICULAR PURPOSE. See the GNU
* Lesser General Public License for more details.
*
* You should have received a copy of the GNU Lesser General Public
* License along with this library; if not, write to the Free Software
* Foundation, Inc., 59 Temple Place, Suite 330, Boston, MA 02111-1307 USA
*/
#ifdef __cplusplus
extern "C" {
#endif
#include "EXTERN.h"
#include "perl.h"
#include "XSUB.h"
#ifdef __cplusplus
}
#endif
#include <stdlib.h>
#include <stdio.h>
#include <string.h>
#include <errno.h>
#undef assert
#include <assert.h>
#define QEF_BUFSZ 8192
#if 0
#define QEF_DEBUG_IO
#endif
#include "util.c"
static void
careful_fread (void *ptr, size_t size, SV *f, const char *from)
{
#ifdef QEF_DEBUG_IO
fprintf(stderr, "read from %p (%s): %u bytes ->%p\n", (void *) f, from,
(unsigned int) size, ptr);
#endif
if (sv_isobject(f)) {
I32 n;
SV *ret, *buf;
STRLEN len;
char *str;
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);
}
}
static void
careful_fwrite (const void *ptr, size_t size, SV *f, const char *to)
{
I32 n;
SV *ret;
#ifdef QEF_DEBUG_IO
fprintf(stderr, "write to %p (%s): %u bytes <-%p\n", (void *) f, to,
(unsigned int) size, ptr);
#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));
}
}
static void
careful_fseek_whence (SV *f, Off_t offset, const char *from, int whence)
{
assert(whence == SEEK_SET || whence == SEEK_CUR || whence == SEEK_END);
#ifdef QEF_DEBUG_IO
fprintf(stderr, "seek %p (%s): %s %u\n", (void *) f, from,
(whence == SEEK_SET ? "SEEK_SET" :
whence == SEEK_CUR ? "SEEK_CUR" : "SEEK_END"),
(unsigned int) offset);
#endif
if (sv_isobject(f)) {
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));
}
}
QEF_INLINE static void
careful_fseek (SV *f, Off_t offset, const char *from)
{
careful_fseek_whence(f, offset, from, SEEK_SET);
}
static Off_t
careful_ftell (SV *f, const char *from)
{
Off_t offset;
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;
( run in 1.095 second using v1.01-cache-2.11-cpan-62a16548d74 )