X-Git-Url: http://git.ieval.ro/?p=io-compress-brotli.git;a=blobdiff_plain;f=Brotli.xs;h=ffbde1e49c6cd6f0e5ac68c422bff6e7c555acdb;hp=c28e36cec9af935f85eb9471832de9146d7bd640;hb=c17e7d6329e8a24e6128a9f70e2b597fce1b5b0a;hpb=00ae8d0fa1b1a86190cf9229db8e5d0d860c1871 diff --git a/Brotli.xs b/Brotli.xs index c28e36c..ffbde1e 100644 --- a/Brotli.xs +++ b/Brotli.xs @@ -5,9 +5,8 @@ #include "ppport.h" -#include -#include -#include +#include +#include #define BUFFER_SIZE 1048576 @@ -24,24 +23,20 @@ MODULE = IO::Compress::Brotli PACKAGE = IO::Uncompress::Brotli PROTOTYPES: ENABLE SV* -unbro(buffer) +unbro(buffer, decoded_size) SV* buffer + size_t decoded_size PREINIT: - size_t decoded_size; STRLEN encoded_size; uint8_t *encoded_buffer, *decoded_buffer; CODE: encoded_buffer = (uint8_t*) SvPV(buffer, encoded_size); - if(!BrotliDecompressedSize(encoded_size, encoded_buffer, &decoded_size)){ - croak("Error in BrotliDecompressedSize"); - } - Newx(decoded_buffer, decoded_size+1, uint8_t); - decoded_buffer[decoded_size]=0; + Newx(decoded_buffer, decoded_size, uint8_t); if(!BrotliDecoderDecompress(encoded_size, encoded_buffer, &decoded_size, decoded_buffer)){ croak("Error in BrotliDecoderDecompress"); } RETVAL = newSV(0); - sv_usepvn_flags(RETVAL, decoded_buffer, decoded_size, SV_HAS_TRAILING_NUL); + sv_usepvn(RETVAL, decoded_buffer, decoded_size); OUTPUT: RETVAL @@ -73,8 +68,8 @@ decompress(self, in) next_in = (uint8_t*) SvPV(in, available_in); Newx(buffer, BUFFER_SIZE, uint8_t); RETVAL = newSVpv("", 0); - result = BROTLI_RESULT_NEEDS_MORE_OUTPUT; - while(result == BROTLI_RESULT_NEEDS_MORE_OUTPUT) { + result = BROTLI_DECODER_RESULT_NEEDS_MORE_OUTPUT; + while(result == BROTLI_DECODER_RESULT_NEEDS_MORE_OUTPUT) { next_out = buffer; available_out=BUFFER_SIZE; result = BrotliDecoderDecompressStream( self->decoder, @@ -93,17 +88,6 @@ decompress(self, in) OUTPUT: RETVAL -void -set_dictionary(self, dict) - IO::Uncompress::Brotli self - SV* dict - PREINIT: - size_t size; - uint8_t *data; - CODE: - data = SvPV(dict, size); - BrotliDecoderSetCustomDictionary(self->decoder, size, data); - MODULE = IO::Compress::Brotli PACKAGE = IO::Compress::Brotli PROTOTYPES: ENABLE @@ -122,7 +106,7 @@ bro(buffer, quality=BROTLI_DEFAULT_QUALITY, lgwin=BROTLI_DEFAULT_WINDOW) if( quality < BROTLI_MIN_QUALITY || quality > BROTLI_MAX_QUALITY ) { croak("Invalid quality value"); } - if( lgwin < kBrotliMinWindowBits || lgwin > kBrotliMaxWindowBits ) { + if( lgwin < BROTLI_MIN_WINDOW_BITS || lgwin > BROTLI_MAX_WINDOW_BITS ) { croak("Invalid window value"); } decoded_buffer = (uint8_t*) SvPV(buffer, decoded_size); @@ -157,139 +141,80 @@ create(class) OUTPUT: RETVAL -SV* -window(self, window) +bool BrotliEncoderSetParameter(self, value) IO::Compress::Brotli self - U32 window - CODE: - if( window < kBrotliMinWindowBits || window > kBrotliMaxWindowBits ) { - croak("Invalid window value"); - } - if( BrotliEncoderSetParameter(self->encoder, BROTLI_PARAM_LGWIN, window) ) - RETVAL = newSVuv(1); - else - RETVAL = newSVuv(0); - OUTPUT: - RETVAL - -SV* -quality(self, quality) - IO::Compress::Brotli self - U32 quality - CODE: - if( quality < BROTLI_MIN_QUALITY || quality > BROTLI_MAX_QUALITY ) { - croak("Invalid quality value"); + U32 value + ALIAS: + window = 1 + quality = 2 + _mode = 3 + PREINIT: + BrotliEncoderParameter param; + INIT: + switch(ix){ + case 0: + croak("BrotliEncoderSetParameter may not be called directly"); + break; + case 1: + if( value < BROTLI_MIN_WINDOW_BITS || value > BROTLI_MAX_WINDOW_BITS ) { + croak("Invalid window value"); + } + param = BROTLI_PARAM_LGWIN; + break; + case 2: + if( value < BROTLI_MIN_QUALITY || value > BROTLI_MAX_QUALITY ) { + croak("Invalid quality value"); + } + param = BROTLI_PARAM_QUALITY; + break; + case 3: + /* Validation done on Perl side */ + param = BROTLI_PARAM_MODE; + break; + default: + croak("Impossible ix in BrotliEncoderSetParameter"); + break; } - if( BrotliEncoderSetParameter(self->encoder, BROTLI_PARAM_QUALITY, quality) ) - RETVAL = newSVuv(1); - else - RETVAL = newSVuv(0); - OUTPUT: - RETVAL - -SV* -_mode(self, mode) - IO::Compress::Brotli self - U32 mode - CODE: - if( BrotliEncoderSetParameter(self->encoder, BROTLI_PARAM_MODE, mode) ) - RETVAL = newSVuv(1); - else - RETVAL = newSVuv(0); - OUTPUT: - RETVAL - -SV* -compress(self, in) - IO::Compress::Brotli self - SV* in - CODE: - ENTER; - SAVETMPS; - - PUSHMARK(SP); - XPUSHs(ST(0)); - XPUSHs(in); - XPUSHs(newSVuv(BROTLI_OPERATION_PROCESS)); - PUTBACK; - - call_method("_compress", G_SCALAR); - - SPAGAIN; - - RETVAL = POPs; - SvREFCNT_inc(RETVAL); - - PUTBACK; - FREETMPS; - LEAVE; - OUTPUT: - RETVAL - -SV* -flush(self) - IO::Compress::Brotli self - CODE: - ENTER; - SAVETMPS; - - PUSHMARK(SP); - XPUSHs(ST(0)); - XPUSHs(newSVpv("", 0)); - XPUSHs(newSVuv(BROTLI_OPERATION_FLUSH)); - PUTBACK; - - call_method("_compress", G_SCALAR); - - SPAGAIN; - - RETVAL = POPs; - SvREFCNT_inc(RETVAL); - - PUTBACK; - FREETMPS; - LEAVE; - OUTPUT: - RETVAL - -SV* -finish(self) - IO::Compress::Brotli self - CODE: - ENTER; - SAVETMPS; - - PUSHMARK(SP); - XPUSHs(ST(0)); - XPUSHs(newSVpv("", 0)); - XPUSHs(newSVuv(BROTLI_OPERATION_FINISH)); - PUTBACK; - - call_method("_compress", G_SCALAR); - - SPAGAIN; - - RETVAL = POPs; - SvREFCNT_inc(RETVAL); - - PUTBACK; - FREETMPS; - LEAVE; - OUTPUT: - RETVAL + C_ARGS: + self->encoder, param, value SV* -_compress(self, in, op) +_compress(self, in = &PL_sv_undef) IO::Compress::Brotli self SV* in - U8 op + ALIAS: + compress = 1 + flush = 2 + finish = 3 PREINIT: uint8_t *next_in, *next_out, *buffer; size_t available_in, available_out; BROTLI_BOOL result; - CODE: - next_in = (uint8_t*) SvPV(in, available_in); + BrotliEncoderOperation op; + CODE: + switch(ix) { + case 0: + croak("_compress may not be called directly"); + break; + case 1: + op = BROTLI_OPERATION_PROCESS; + break; + case 2: + op = BROTLI_OPERATION_FLUSH; + break; + case 3: + op = BROTLI_OPERATION_FINISH; + break; + default: + croak("Impossible ix in _compress"); + break; + } + Newx(buffer, BUFFER_SIZE, uint8_t); + if(in == &PL_sv_undef) + next_in = (uint8_t*) buffer, available_in = 0; + else + next_in = (uint8_t*) SvPV(in, available_in); RETVAL = newSVpv("", 0); while(1) { next_out = buffer; @@ -324,15 +249,4 @@ DESTROY(self) IO::Compress::Brotli self CODE: BrotliEncoderDestroyInstance(self->encoder); - -void -set_dictionary(self, dict) - IO::Compress::Brotli self - SV* dict - PREINIT: - size_t size; - uint8_t *data; - CODE: - data = SvPV(dict, size); - BrotliEncoderSetCustomDictionary(self->encoder, size, data); - + Safefree(self);