Compress-LZ4Frame
view release on metacpan or search on metacpan
CompressLZ4Frame.xs view on Meta::CPAN
bytes_read = src_len;
if (!dest) {
warn("Could not allocate enough memory (%zu Bytes)", dest_len);
LZ4F_freeDecompressionContext(ctx);
return NULL;
}
result = LZ4F_decompress(ctx, dest + dest_offset, ¤t_chunk, src + src_offset, &bytes_read, NULL);
if (LZ4F_isError(result) || !current_chunk) {
if (LZ4F_isError(result))
warn("Error during decompression: %s", LZ4F_getErrorName(result));
Safefree(dest);
LZ4F_freeDecompressionContext(ctx);
return NULL;
}
// bytes_processed is relevant for concatenated frames
*bytes_processed += bytes_read;
// current_chunk contains how much was read
// dest_offset is where the current chunk started
// result contains the number of bytes that LZ4F is still expecting
// in combination this should be the full new size of the destination buffer
dest_len = dest_offset + current_chunk + result;
if (!result) // 0 means no more data in this frame
break;
// where the next chunk will be read to
dest_offset += current_chunk;
// the size of the next chunk
current_chunk = result;
// how much is left to read from the source buffer
src_len -= bytes_read;
// where to read from
src_offset += bytes_read;
Renew(dest, dest_len, char);
}
// done uncompressing, now put the stuff into a scalar
decompressed = newSV(0);
sv_usepvn_flags(decompressed, dest, dest_len, SV_SMAGIC);
LZ4F_freeDecompressionContext(ctx);
}
return decompressed;
}
MODULE = Compress::LZ4Frame PACKAGE = Compress::LZ4Frame
PROTOTYPES: ENABLE
SV *
compress(sv, level = 0)
SV * sv
int level
ALIAS:
compress_checksum = 1
PREINIT:
LZ4F_preferences_t prefs = { 0 };
char * src, * dest;
size_t src_len, dest_len;
CODE:
SvGETMAGIC(sv);
if (SvROK(sv) && !SvAMAGIC(sv)) {
sv = SvRV(sv);
SvGETMAGIC(sv);
}
if (!SvOK(sv))
XSRETURN_NO;
src = SvPVbyte(sv, src_len);
if (!src_len)
XSRETURN_NO;
prefs.frameInfo.contentChecksumFlag = (ix == 1 ? LZ4F_contentChecksumEnabled : LZ4F_noContentChecksum);
prefs.frameInfo.contentSize = (unsigned long long)src_len;
prefs.compressionLevel = level;
prefs.autoFlush = 1u;
dest_len = LZ4F_compressFrameBound(src_len, &prefs);
RETVAL = newSV(dest_len);
dest = SvPVX(RETVAL);
if (!dest) {
warn("Could not allocate enough memory (%zu Bytes)", dest_len);
SvREFCNT_dec(RETVAL);
XSRETURN_UNDEF;
}
dest_len = LZ4F_compressFrame(dest, dest_len, src, src_len, &prefs);
if (LZ4F_isError(dest_len)) {
warn("Error during compression: %s", LZ4F_getErrorName(dest_len));
SvREFCNT_dec(RETVAL);
XSRETURN_UNDEF;
}
SvCUR_set(RETVAL, dest_len);
SvPOK_on(RETVAL);
OUTPUT:
RETVAL
SV *
decompress(sv)
SV * sv
PREINIT:
char * src;
size_t src_len, bytes_read;
SV * current = (SV*)1; /* simply not NULL */
CODE:
SvGETMAGIC(sv);
if (SvROK(sv) && !SvAMAGIC(sv)) {
sv = SvRV(sv);
SvGETMAGIC(sv);
}
if (!SvOK(sv))
XSRETURN_NO;
src = SvPVbyte(sv, src_len);
if (!src_len)
XSRETURN_NO;
RETVAL = decompress_single_frame(aTHX_ src, src_len, &bytes_read);
if (RETVAL == NULL)
XSRETURN_UNDEF;
src += bytes_read;
src_len = src_len >= bytes_read ? src_len - bytes_read : 0u;
while (src_len && (current = decompress_single_frame(aTHX_ src, src_len, &bytes_read)) && (bytes_read > 0))
{
sv_catsv(RETVAL, current);
SvREFCNT_dec(current);
src += bytes_read;
src_len = src_len >= bytes_read ? src_len - bytes_read : 0u;
}
if (current == NULL)
{
SvREFCNT_dec(RETVAL);
XSRETURN_UNDEF;
}
OUTPUT:
RETVAL
int
looks_like_lz4frame(sv)
SV * sv
PREINIT:
LZ4F_decompressionContext_t ctx;
LZ4F_frameInfo_t info;
char * src;
size_t src_len;
( run in 1.496 second using v1.01-cache-2.11-cpan-0bb4e1dffa6 )