#include "EXTERN.h" #include "perl.h" #include "XSUB.h" /* try to be compatible with older perls */ /* SvPV_nolen() macro first defined in 5.005_55 */ /* this is slow, not threadsafe, but works */ #include "patchlevel.h" #if (PATCHLEVEL == 4) || ((PATCHLEVEL == 5) && (SUBVERSION < 55)) static STRLEN nolen_na; # define SvPV_nolen(sv) SvPV ((sv), nolen_na) #endif #include "lzv1/lzv1.c" MODULE = Compress::LZV1 PACKAGE = Compress::LZV1 SV * compress(data) SV * data PROTOTYPE: $ CODE: { STRLEN usize, csize; void *src = SvPV(data, usize); unsigned char *dst; unsigned short heap[HSIZ]; /* need not be initialized */ if (usize) { RETVAL = NEWSV (0, usize + 1); SvPOK_only (RETVAL); dst = (unsigned char *)SvPV_nolen (RETVAL); /* compress */ csize = wLZV1 ((uch *)src, (uch *)(dst + 4), heap, usize, usize - 5); if (csize) { dst[0] = 'L'; /* compressed flag */ dst[1] = usize >> 16; dst[2] = usize >> 8; dst[3] = usize >> 0; SvCUR_set (RETVAL, csize + 4); } else { dst[0] = 'U'; Move ((void *)src, (void *)(dst + 1), usize, unsigned char); SvCUR_set (RETVAL, usize + 1); } } else RETVAL = newSVpv ("", 0); } OUTPUT: RETVAL SV * decompress(data) SV * data PROTOTYPE: $ CODE: { STRLEN usize, csize; unsigned char *src = (unsigned char *)SvPV(data, csize); void *dst; if (csize) { switch (src[0]) { case 'U': usize = csize - 1; RETVAL = NEWSV (0, usize); SvPOK_only (RETVAL); dst = SvPV_nolen (RETVAL); Move ((void *)(src + 1), (void *)dst, usize, unsigned char); break; case 'L': usize = (src[1] << 16) | (src[2] << 8) | (src[3] << 0); RETVAL = NEWSV (0, usize); SvPOK_only (RETVAL); dst = SvPV_nolen (RETVAL); if (rLZV1 ((uch *)(src + 4), (uch *)dst, csize - 4, usize) != usize) croak ("LZV1: compressed data corrupted (2)"); break; default: croak ("LZV1: compressed data corrupted (1)"); } SvCUR_set (RETVAL, usize); } else RETVAL = newSVpvn ("", 0); } OUTPUT: RETVAL