1 #define PERL_NO_GET_CONTEXT 2 3 #include "EXTERN.h" 4 #include "perl.h" 5 #include "XSUB.h" 6 7 #define NEED_sv_2pvbyte 8 #include "ppport.h" 9 10 #include <lz4.h> 11 #include <lz4hc.h> 12 13 MODULE = Compress::LZ4 PACKAGE = Compress::LZ4 14 15 PROTOTYPES: ENABLE 16 17 SV * 18 compress (sv, level=0) 19 SV *sv 20 IV level 21 ALIAS: 22 compress_hc = 1 23 lz4_compress = 2 24 lz4_compress_hc = 3 25 PREINIT: 26 char *src, *dest; 27 STRLEN src_len, dest_len; 28 int hc; 29 CODE: 30 SvGETMAGIC(sv); 31 if (SvROK(sv) && ! SvAMAGIC(sv)) { 32 sv = SvRV(sv); 33 SvGETMAGIC(sv); 34 } 35 if (! SvOK(sv)) 36 XSRETURN_NO; 37 src = SvPVbyte(sv, src_len); 38 if (! src_len) 39 XSRETURN_NO; 40 dest_len = LZ4_compressBound(src_len); 41 if (2 > ix) 42 dest_len += 4; 43 RETVAL = newSV(dest_len); 44 dest = SvPVX(RETVAL); 45 if (! dest) 46 XSRETURN_UNDEF; 47 48 hc = ix & 1; 49 if (2 > ix) { 50 /* Add the length header as 4 bytes in little endian. */ 51 dest[0] = src_len & 0xff; 52 dest[1] = (src_len>> 8) & 0xff; 53 dest[2] = (src_len>>16) & 0xff; 54 dest[3] = (src_len>>24) & 0xff; 55 56 dest_len = hc ? LZ4_compress_HC(src, dest + 4, src_len, dest_len, level) 57 : LZ4_compress_fast(src, dest + 4, src_len, dest_len, level); 58 dest_len += 4; 59 } 60 else { 61 dest_len = hc ? LZ4_compress_HC(src, dest, src_len, dest_len, level) 62 : LZ4_compress_fast(src, dest, src_len, dest_len, level); 63 } 64 65 if (! dest_len) { 66 SvREFCNT_dec(RETVAL); 67 XSRETURN_UNDEF; 68 } 69 SvCUR_set(RETVAL, dest_len); 70 SvPOK_on(RETVAL); 71 OUTPUT: 72 RETVAL 73 74 SV * 75 decompress (sv, len=0) 76 SV *sv 77 int len 78 ALIAS: 79 uncompress = 1 80 lz4_decompress = 2 81 lz4_uncompress = 3 82 PREINIT: 83 char *src, *dest; 84 STRLEN src_len, dest_len; 85 int ret; 86 CODE: 87 PERL_UNUSED_VAR(ix); /* -W */ 88 SvGETMAGIC(sv); 89 if (SvROK(sv) && ! SvAMAGIC(sv)) { 90 sv = SvRV(sv); 91 SvGETMAGIC(sv); 92 } 93 if (! SvOK(sv)) 94 XSRETURN_NO; 95 src = SvPVbyte(sv, src_len); 96 if (! src_len ) 97 XSRETURN_NO; 98 99 if (1 == items) { 100 if (src_len < 5) 101 XSRETURN_NO; 102 103 /* Decode the length header. */ 104 dest_len = (src[0] & 0xff) | (src[1] & 0xff) << 8 | (src[2] & 0xff) << 16 105 | (src[3] & 0xff) << 24; 106 } 107 else 108 dest_len = len; 109 110 if (0 >= dest_len) 111 XSRETURN_NO; 112 113 RETVAL = newSV(dest_len); 114 dest = SvPVX(RETVAL); 115 if (! dest) 116 XSRETURN_UNDEF; 117 118 if (1 == items) 119 ret = LZ4_decompress_safe(src + 4, dest, src_len - 4, dest_len); 120 else 121 ret = LZ4_decompress_safe(src, dest, src_len, dest_len); 122 123 if (0 > ret) { 124 SvREFCNT_dec(RETVAL); 125 XSRETURN_UNDEF; 126 } 127 SvCUR_set(RETVAL, ret); 128 SvPOK_on(RETVAL); 129 OUTPUT: 130 RETVAL 131