X-Git-Url: http://git.ieval.ro/?a=blobdiff_plain;f=Brotli.xs;h=5b7d008594a958e07e8a12f5be841a9655bd52d8;hb=390e0fef70ee97b173f25b04ce6308c572a0660a;hp=8de3dd525c6cf371c2fce2cde24096e05b7d829a;hpb=9d6eec245de326a70986bd7098753569f6a1aa1e;p=io-compress-brotli.git diff --git a/Brotli.xs b/Brotli.xs index 8de3dd5..5b7d008 100644 --- a/Brotli.xs +++ b/Brotli.xs @@ -11,10 +11,20 @@ #define BUFFER_SIZE 1048576 +typedef struct brotli_decoder { + BrotliDecoderState *decoder; +}* IO__Uncompress__Brotli; + +typedef struct brotli_encoder { + BrotliEncoderState *encoder; +}* IO__Compress__Brotli; + + MODULE = IO::Compress::Brotli PACKAGE = IO::Uncompress::Brotli PROTOTYPES: ENABLE -SV* unbro(buffer) +SV* +unbro(buffer) SV* buffer PREINIT: size_t decoded_size; @@ -35,19 +45,25 @@ SV* unbro(buffer) OUTPUT: RETVAL -SV* BrotliDecoderCreateInstance() +IO::Uncompress::Brotli +create(class) + SV* class CODE: - RETVAL = newSViv((IV)BrotliDecoderCreateInstance(NULL, NULL, NULL)); + Newx(RETVAL, 1, struct brotli_decoder); + RETVAL->decoder = BrotliDecoderCreateInstance(NULL, NULL, NULL); OUTPUT: RETVAL -void BrotliDecoderDestroyInstance(state) - SV* state +void +DESTROY(self) + IO::Uncompress::Brotli self CODE: - BrotliDecoderDestroyInstance((BrotliDecoderState*)SvIV(state)); + BrotliDecoderDestroyInstance(self->decoder); + Safefree(self); -SV* BrotliDecoderDecompressStream(state, in) - SV* state +SV* +decompress(self, in) + IO::Uncompress::Brotli self SV* in PREINIT: uint8_t *next_in, *next_out, *buffer; @@ -61,7 +77,7 @@ SV* BrotliDecoderDecompressStream(state, in) while(result == BROTLI_RESULT_NEEDS_MORE_OUTPUT) { next_out = buffer; available_out=BUFFER_SIZE; - result = BrotliDecoderDecompressStream( (BrotliDecoderState*) SvIV(state), + result = BrotliDecoderDecompressStream( self->decoder, &available_in, (const uint8_t**) &next_in, &available_out, @@ -77,21 +93,23 @@ SV* BrotliDecoderDecompressStream(state, in) OUTPUT: RETVAL -void BrotliDecoderSetCustomDictionary(state, dict) - SV* state +void +set_dictionary(self, dict) + IO::Uncompress::Brotli self SV* dict PREINIT: size_t size; uint8_t *data; CODE: data = SvPV(dict, size); - BrotliDecoderSetCustomDictionary((BrotliDecoderState*) SvIV(state), size, data); + BrotliDecoderSetCustomDictionary(self->decoder, size, data); MODULE = IO::Compress::Brotli PACKAGE = IO::Compress::Brotli PROTOTYPES: ENABLE -SV* bro(buffer, quality=BROTLI_DEFAULT_QUALITY, lgwin=BROTLI_DEFAULT_WINDOW) +SV* +bro(buffer, quality=BROTLI_DEFAULT_QUALITY, lgwin=BROTLI_DEFAULT_WINDOW) SV* buffer U32 quality U32 lgwin @@ -130,67 +148,94 @@ SV* bro(buffer, quality=BROTLI_DEFAULT_QUALITY, lgwin=BROTLI_DEFAULT_WINDOW) OUTPUT: RETVAL -SV* BrotliEncoderCreateInstance() +IO::Compress::Brotli +create(class) + SV* class CODE: - RETVAL = newSViv((IV)BrotliEncoderCreateInstance(NULL, NULL, NULL)); + Newx(RETVAL, 1, struct brotli_encoder); + RETVAL->encoder = BrotliEncoderCreateInstance(NULL, NULL, NULL); OUTPUT: RETVAL -SV* BrotliEncoderSetWindow(state, window) - SV* state - U32 window - CODE: - if( window < kBrotliMinWindowBits || window > kBrotliMaxWindowBits ) { - croak("Invalid window value"); - } - if( BrotliEncoderSetParameter((BrotliEncoderState*) SvIV(state), BROTLI_PARAM_LGWIN, window) ) - RETVAL = newSVuv(1); - else - RETVAL = newSVuv(0); - OUTPUT: - RETVAL - -SV* BrotliEncoderSetQuality(state, quality) - SV* state - U32 quality - CODE: - if( quality < BROTLI_MIN_QUALITY || quality > BROTLI_MAX_QUALITY ) { - croak("Invalid quality value"); +bool BrotliEncoderSetParameter(self, value) + IO::Compress::Brotli self + 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 < kBrotliMinWindowBits || value > kBrotliMaxWindowBits ) { + 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((BrotliEncoderState*) SvIV(state), BROTLI_PARAM_QUALITY, quality) ) - RETVAL = newSVuv(1); - else - RETVAL = newSVuv(0); - OUTPUT: - RETVAL - -SV* BrotliEncoderSetMode(state, mode) - SV* state - U32 mode - CODE: - if( BrotliEncoderSetParameter((BrotliEncoderState*) SvIV(state), BROTLI_PARAM_MODE, mode) ) - RETVAL = newSVuv(1); - else - RETVAL = newSVuv(0); - OUTPUT: - RETVAL + C_ARGS: + self->encoder, param, value -SV* BrotliEncoderCompressStream(state, in, op) - SV* state +SV* +_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; + BrotliEncoderOperation op; CODE: - next_in = (uint8_t*) SvPV(in, available_in); + 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; available_out = BUFFER_SIZE; - result = BrotliEncoderCompressStream( (BrotliEncoderState*) SvIV(state), + result = BrotliEncoderCompressStream( self->encoder, (BrotliEncoderOperation) op, &available_in, (const uint8_t**) &next_in, @@ -207,25 +252,28 @@ SV* BrotliEncoderCompressStream(state, in, op) } if( - BrotliEncoderIsFinished((BrotliEncoderState*) SvIV(state)) || - (!available_in && !BrotliEncoderHasMoreOutput((BrotliEncoderState*) SvIV(state))) + BrotliEncoderIsFinished(self->encoder) || + (!available_in && !BrotliEncoderHasMoreOutput(self->encoder)) ) break; } Safefree(buffer); OUTPUT: RETVAL -void BrotliEncoderDestroyInstance(state) - SV* state +void +DESTROY(self) + IO::Compress::Brotli self CODE: - BrotliEncoderDestroyInstance((BrotliEncoderState*)SvIV(state)); + BrotliEncoderDestroyInstance(self->encoder); + Safefree(self); -void BrotliEncoderSetCustomDictionary(state, dict) - SV* state +void +set_dictionary(self, dict) + IO::Compress::Brotli self SV* dict PREINIT: size_t size; uint8_t *data; CODE: data = SvPV(dict, size); - BrotliEncoderSetCustomDictionary((BrotliEncoderState*) SvIV(state), size, data); + BrotliEncoderSetCustomDictionary(self->encoder, size, data);