| line | stmt | bran | cond | sub | pod | time | code | 
| 1 |  |  |  |  |  |  | #define PERL_NO_GET_CONTEXT | 
| 2 |  |  |  |  |  |  | #include "EXTERN.h" | 
| 3 |  |  |  |  |  |  | #include "perl.h" | 
| 4 |  |  |  |  |  |  | #include "XSUB.h" | 
| 5 |  |  |  |  |  |  |  | 
| 6 |  |  |  |  |  |  | #include "ppport.h" | 
| 7 |  |  |  |  |  |  |  | 
| 8 |  |  |  |  |  |  | #include | 
| 9 |  |  |  |  |  |  | #include | 
| 10 |  |  |  |  |  |  |  | 
| 11 |  |  |  |  |  |  | #define BUFFER_SIZE 1048576 | 
| 12 |  |  |  |  |  |  |  | 
| 13 |  |  |  |  |  |  | typedef struct brotli_decoder { | 
| 14 |  |  |  |  |  |  | BrotliDecoderState *decoder; | 
| 15 |  |  |  |  |  |  | }* IO__Uncompress__Brotli; | 
| 16 |  |  |  |  |  |  |  | 
| 17 |  |  |  |  |  |  | typedef struct brotli_encoder { | 
| 18 |  |  |  |  |  |  | BrotliEncoderState *encoder; | 
| 19 |  |  |  |  |  |  | }* IO__Compress__Brotli; | 
| 20 |  |  |  |  |  |  |  | 
| 21 |  |  |  |  |  |  |  | 
| 22 |  |  |  |  |  |  | MODULE = IO::Compress::Brotli		PACKAGE = IO::Uncompress::Brotli | 
| 23 |  |  |  |  |  |  | PROTOTYPES: ENABLE | 
| 24 |  |  |  |  |  |  |  | 
| 25 |  |  |  |  |  |  | SV* | 
| 26 |  |  |  |  |  |  | unbro(buffer, decoded_size) | 
| 27 |  |  |  |  |  |  | SV* buffer | 
| 28 |  |  |  |  |  |  | size_t decoded_size | 
| 29 |  |  |  |  |  |  | PREINIT: | 
| 30 |  |  |  |  |  |  | STRLEN encoded_size; | 
| 31 |  |  |  |  |  |  | uint8_t *encoded_buffer, *decoded_buffer; | 
| 32 |  |  |  |  |  |  | CODE: | 
| 33 | 80 | 50 |  |  |  |  | encoded_buffer = (uint8_t*) SvPV(buffer, encoded_size); | 
| 34 | 80 |  |  |  |  |  | Newx(decoded_buffer, decoded_size, uint8_t); | 
| 35 | 80 | 50 |  |  |  |  | if(!BrotliDecoderDecompress(encoded_size, encoded_buffer, &decoded_size, decoded_buffer)){ | 
| 36 | 0 |  |  |  |  |  | croak("Error in BrotliDecoderDecompress"); | 
| 37 |  |  |  |  |  |  | } | 
| 38 | 80 |  |  |  |  |  | RETVAL = newSV(0); | 
| 39 | 80 |  |  |  |  |  | sv_usepvn(RETVAL, decoded_buffer, decoded_size); | 
| 40 |  |  |  |  |  |  | OUTPUT: | 
| 41 |  |  |  |  |  |  | RETVAL | 
| 42 |  |  |  |  |  |  |  | 
| 43 |  |  |  |  |  |  | IO::Uncompress::Brotli | 
| 44 |  |  |  |  |  |  | create(class) | 
| 45 |  |  |  |  |  |  | SV* class | 
| 46 |  |  |  |  |  |  | CODE: | 
| 47 | 118 |  |  |  |  |  | Newx(RETVAL, 1, struct brotli_decoder); | 
| 48 | 118 |  |  |  |  |  | RETVAL->decoder = BrotliDecoderCreateInstance(NULL, NULL, NULL); | 
| 49 |  |  |  |  |  |  | OUTPUT: | 
| 50 |  |  |  |  |  |  | RETVAL | 
| 51 |  |  |  |  |  |  |  | 
| 52 |  |  |  |  |  |  | void | 
| 53 |  |  |  |  |  |  | DESTROY(self) | 
| 54 |  |  |  |  |  |  | IO::Uncompress::Brotli self | 
| 55 |  |  |  |  |  |  | CODE: | 
| 56 | 118 |  |  |  |  |  | BrotliDecoderDestroyInstance(self->decoder); | 
| 57 | 118 |  |  |  |  |  | Safefree(self); | 
| 58 |  |  |  |  |  |  |  | 
| 59 |  |  |  |  |  |  | SV* | 
| 60 |  |  |  |  |  |  | decompress(self, in) | 
| 61 |  |  |  |  |  |  | IO::Uncompress::Brotli self | 
| 62 |  |  |  |  |  |  | SV* in | 
| 63 |  |  |  |  |  |  | PREINIT: | 
| 64 |  |  |  |  |  |  | uint8_t *next_in, *next_out, *buffer; | 
| 65 |  |  |  |  |  |  | size_t available_in, available_out; | 
| 66 |  |  |  |  |  |  | BrotliDecoderResult result; | 
| 67 |  |  |  |  |  |  | CODE: | 
| 68 | 9412 | 50 |  |  |  |  | next_in = (uint8_t*) SvPV(in, available_in); | 
| 69 | 9412 |  |  |  |  |  | Newx(buffer, BUFFER_SIZE, uint8_t); | 
| 70 | 9412 |  |  |  |  |  | RETVAL = newSVpv("", 0); | 
| 71 | 9412 |  |  |  |  |  | result = BROTLI_DECODER_RESULT_NEEDS_MORE_OUTPUT; | 
| 72 | 18824 | 100 |  |  |  |  | while(result == BROTLI_DECODER_RESULT_NEEDS_MORE_OUTPUT) { | 
| 73 | 9412 |  |  |  |  |  | next_out = buffer; | 
| 74 | 9412 |  |  |  |  |  | available_out=BUFFER_SIZE; | 
| 75 | 9412 |  |  |  |  |  | result = BrotliDecoderDecompressStream( self->decoder, | 
| 76 |  |  |  |  |  |  | &available_in, | 
| 77 |  |  |  |  |  |  | (const uint8_t**) &next_in, | 
| 78 |  |  |  |  |  |  | &available_out, | 
| 79 |  |  |  |  |  |  | &next_out, | 
| 80 |  |  |  |  |  |  | NULL ); | 
| 81 | 9412 | 50 |  |  |  |  | if(!result){ | 
| 82 | 0 |  |  |  |  |  | Safefree(buffer); | 
| 83 | 0 |  |  |  |  |  | croak("Error in BrotliDecoderDecompressStream"); | 
| 84 |  |  |  |  |  |  | } | 
| 85 | 9412 |  |  |  |  |  | sv_catpvn(RETVAL, (const char*)buffer, BUFFER_SIZE-available_out); | 
| 86 |  |  |  |  |  |  | } | 
| 87 | 9412 |  |  |  |  |  | Safefree(buffer); | 
| 88 |  |  |  |  |  |  | OUTPUT: | 
| 89 |  |  |  |  |  |  | RETVAL | 
| 90 |  |  |  |  |  |  |  | 
| 91 |  |  |  |  |  |  |  | 
| 92 |  |  |  |  |  |  | MODULE = IO::Compress::Brotli		PACKAGE = IO::Compress::Brotli | 
| 93 |  |  |  |  |  |  | PROTOTYPES: ENABLE | 
| 94 |  |  |  |  |  |  |  | 
| 95 |  |  |  |  |  |  | SV* | 
| 96 |  |  |  |  |  |  | bro(buffer, quality=BROTLI_DEFAULT_QUALITY, lgwin=BROTLI_DEFAULT_WINDOW) | 
| 97 |  |  |  |  |  |  | SV* buffer | 
| 98 |  |  |  |  |  |  | U32 quality | 
| 99 |  |  |  |  |  |  | U32 lgwin | 
| 100 |  |  |  |  |  |  | PREINIT: | 
| 101 |  |  |  |  |  |  | size_t encoded_size; | 
| 102 |  |  |  |  |  |  | STRLEN decoded_size; | 
| 103 |  |  |  |  |  |  | uint8_t *encoded_buffer, *decoded_buffer; | 
| 104 |  |  |  |  |  |  | BROTLI_BOOL result; | 
| 105 |  |  |  |  |  |  | CODE: | 
| 106 | 38 | 50 |  |  |  |  | if( quality < BROTLI_MIN_QUALITY || quality > BROTLI_MAX_QUALITY ) { | 
| 107 | 0 |  |  |  |  |  | croak("Invalid quality value"); | 
| 108 |  |  |  |  |  |  | } | 
| 109 | 38 | 50 |  |  |  |  | if( lgwin < BROTLI_MIN_WINDOW_BITS || lgwin > BROTLI_MAX_WINDOW_BITS ) { | 
|  |  | 50 |  |  |  |  |  | 
| 110 | 0 |  |  |  |  |  | croak("Invalid window value"); | 
| 111 |  |  |  |  |  |  | } | 
| 112 | 38 | 50 |  |  |  |  | decoded_buffer = (uint8_t*) SvPV(buffer, decoded_size); | 
| 113 | 38 |  |  |  |  |  | encoded_size = BrotliEncoderMaxCompressedSize(decoded_size); | 
| 114 | 38 | 50 |  |  |  |  | if(!encoded_size){ | 
| 115 | 0 |  |  |  |  |  | croak("Compressed size overflow"); | 
| 116 |  |  |  |  |  |  | } | 
| 117 | 38 |  |  |  |  |  | Newx(encoded_buffer, encoded_size+1, uint8_t); | 
| 118 | 38 |  |  |  |  |  | result = BrotliEncoderCompress( quality, | 
| 119 |  |  |  |  |  |  | lgwin, | 
| 120 |  |  |  |  |  |  | BROTLI_DEFAULT_MODE, | 
| 121 |  |  |  |  |  |  | decoded_size, | 
| 122 |  |  |  |  |  |  | decoded_buffer, | 
| 123 |  |  |  |  |  |  | &encoded_size, | 
| 124 |  |  |  |  |  |  | encoded_buffer ); | 
| 125 | 38 | 50 |  |  |  |  | if(!result){ | 
| 126 | 0 |  |  |  |  |  | Safefree(buffer); | 
| 127 | 0 |  |  |  |  |  | croak("Error in BrotliEncoderCompress"); | 
| 128 |  |  |  |  |  |  | } | 
| 129 | 38 |  |  |  |  |  | encoded_buffer[encoded_size]=0; | 
| 130 | 38 |  |  |  |  |  | RETVAL = newSV(0); | 
| 131 | 38 |  |  |  |  |  | sv_usepvn_flags(RETVAL, encoded_buffer, encoded_size, SV_SMAGIC | SV_HAS_TRAILING_NUL); | 
| 132 |  |  |  |  |  |  | OUTPUT: | 
| 133 |  |  |  |  |  |  | RETVAL | 
| 134 |  |  |  |  |  |  |  | 
| 135 |  |  |  |  |  |  | IO::Compress::Brotli | 
| 136 |  |  |  |  |  |  | create(class) | 
| 137 |  |  |  |  |  |  | SV* class | 
| 138 |  |  |  |  |  |  | CODE: | 
| 139 | 76 |  |  |  |  |  | Newx(RETVAL, 1, struct brotli_encoder); | 
| 140 | 76 |  |  |  |  |  | RETVAL->encoder = BrotliEncoderCreateInstance(NULL, NULL, NULL); | 
| 141 |  |  |  |  |  |  | OUTPUT: | 
| 142 |  |  |  |  |  |  | RETVAL | 
| 143 |  |  |  |  |  |  |  | 
| 144 |  |  |  |  |  |  | bool BrotliEncoderSetParameter(self, value) | 
| 145 |  |  |  |  |  |  | IO::Compress::Brotli self | 
| 146 |  |  |  |  |  |  | U32 value | 
| 147 |  |  |  |  |  |  | ALIAS: | 
| 148 |  |  |  |  |  |  | window  = 1 | 
| 149 |  |  |  |  |  |  | quality = 2 | 
| 150 |  |  |  |  |  |  | _mode   = 3 | 
| 151 |  |  |  |  |  |  | PREINIT: | 
| 152 |  |  |  |  |  |  | BrotliEncoderParameter param; | 
| 153 |  |  |  |  |  |  | INIT: | 
| 154 | 76 |  |  |  |  |  | switch(ix){ | 
| 155 |  |  |  |  |  |  | case 0: | 
| 156 | 0 |  |  |  |  |  | croak("BrotliEncoderSetParameter may not be called directly"); | 
| 157 |  |  |  |  |  |  | break; | 
| 158 |  |  |  |  |  |  | case 1: | 
| 159 | 0 | 0 |  |  |  |  | if( value < BROTLI_MIN_WINDOW_BITS || value > BROTLI_MAX_WINDOW_BITS ) { | 
|  |  | 0 |  |  |  |  |  | 
| 160 | 0 |  |  |  |  |  | croak("Invalid window value"); | 
| 161 |  |  |  |  |  |  | } | 
| 162 | 0 |  |  |  |  |  | param = BROTLI_PARAM_LGWIN; | 
| 163 | 0 |  |  |  |  |  | break; | 
| 164 |  |  |  |  |  |  | case 2: | 
| 165 | 76 | 50 |  |  |  |  | if( value < BROTLI_MIN_QUALITY || value > BROTLI_MAX_QUALITY ) { | 
| 166 | 0 |  |  |  |  |  | croak("Invalid quality value"); | 
| 167 |  |  |  |  |  |  | } | 
| 168 | 76 |  |  |  |  |  | param = BROTLI_PARAM_QUALITY; | 
| 169 | 76 |  |  |  |  |  | break; | 
| 170 |  |  |  |  |  |  | case 3: | 
| 171 |  |  |  |  |  |  | /* Validation done on Perl side */ | 
| 172 | 0 |  |  |  |  |  | param = BROTLI_PARAM_MODE; | 
| 173 | 0 |  |  |  |  |  | break; | 
| 174 |  |  |  |  |  |  | default: | 
| 175 | 0 |  |  |  |  |  | croak("Impossible ix in BrotliEncoderSetParameter"); | 
| 176 |  |  |  |  |  |  | break; | 
| 177 |  |  |  |  |  |  | } | 
| 178 |  |  |  |  |  |  | C_ARGS: | 
| 179 |  |  |  |  |  |  | self->encoder, param, value | 
| 180 |  |  |  |  |  |  |  | 
| 181 |  |  |  |  |  |  | SV* | 
| 182 |  |  |  |  |  |  | _compress(self, in = &PL_sv_undef) | 
| 183 |  |  |  |  |  |  | IO::Compress::Brotli self | 
| 184 |  |  |  |  |  |  | SV* in | 
| 185 |  |  |  |  |  |  | ALIAS: | 
| 186 |  |  |  |  |  |  | compress = 1 | 
| 187 |  |  |  |  |  |  | flush = 2 | 
| 188 |  |  |  |  |  |  | finish = 3 | 
| 189 |  |  |  |  |  |  | PREINIT: | 
| 190 |  |  |  |  |  |  | uint8_t *next_in, *next_out, *buffer; | 
| 191 |  |  |  |  |  |  | size_t available_in, available_out; | 
| 192 |  |  |  |  |  |  | BROTLI_BOOL result; | 
| 193 |  |  |  |  |  |  | BrotliEncoderOperation op; | 
| 194 |  |  |  |  |  |  | CODE: | 
| 195 | 152 |  |  |  |  |  | switch(ix) { | 
| 196 |  |  |  |  |  |  | case 0: | 
| 197 | 0 |  |  |  |  |  | croak("_compress may not be called directly"); | 
| 198 |  |  |  |  |  |  | break; | 
| 199 |  |  |  |  |  |  | case 1: | 
| 200 | 76 |  |  |  |  |  | op = BROTLI_OPERATION_PROCESS; | 
| 201 | 76 |  |  |  |  |  | break; | 
| 202 |  |  |  |  |  |  | case 2: | 
| 203 | 0 |  |  |  |  |  | op = BROTLI_OPERATION_FLUSH; | 
| 204 | 0 |  |  |  |  |  | break; | 
| 205 |  |  |  |  |  |  | case 3: | 
| 206 | 76 |  |  |  |  |  | op = BROTLI_OPERATION_FINISH; | 
| 207 | 76 |  |  |  |  |  | break; | 
| 208 |  |  |  |  |  |  | default: | 
| 209 | 0 |  |  |  |  |  | croak("Impossible ix in _compress"); | 
| 210 |  |  |  |  |  |  | break; | 
| 211 |  |  |  |  |  |  | } | 
| 212 |  |  |  |  |  |  |  | 
| 213 | 152 |  |  |  |  |  | Newx(buffer, BUFFER_SIZE, uint8_t); | 
| 214 | 152 | 100 |  |  |  |  | if(in == &PL_sv_undef) | 
| 215 | 76 |  |  |  |  |  | next_in = (uint8_t*) buffer, available_in = 0; | 
| 216 |  |  |  |  |  |  | else | 
| 217 | 76 | 50 |  |  |  |  | next_in = (uint8_t*) SvPV(in, available_in); | 
| 218 | 152 |  |  |  |  |  | RETVAL = newSVpv("", 0); | 
| 219 |  |  |  |  |  |  | while(1) { | 
| 220 | 152 |  |  |  |  |  | next_out = buffer; | 
| 221 | 152 |  |  |  |  |  | available_out = BUFFER_SIZE; | 
| 222 | 152 |  |  |  |  |  | result = BrotliEncoderCompressStream( self->encoder, | 
| 223 |  |  |  |  |  |  | (BrotliEncoderOperation) op, | 
| 224 |  |  |  |  |  |  | &available_in, | 
| 225 |  |  |  |  |  |  | (const uint8_t**) &next_in, | 
| 226 |  |  |  |  |  |  | &available_out, | 
| 227 |  |  |  |  |  |  | &next_out, | 
| 228 |  |  |  |  |  |  | NULL ); | 
| 229 | 152 | 50 |  |  |  |  | if(!result) { | 
| 230 | 0 |  |  |  |  |  | Safefree(buffer); | 
| 231 | 0 |  |  |  |  |  | croak("Error in BrotliEncoderCompressStream"); | 
| 232 |  |  |  |  |  |  | } | 
| 233 |  |  |  |  |  |  |  | 
| 234 | 152 | 100 |  |  |  |  | if( available_out != BUFFER_SIZE ) { | 
| 235 | 94 |  |  |  |  |  | sv_catpvn(RETVAL, (const char*)buffer, BUFFER_SIZE-available_out); | 
| 236 |  |  |  |  |  |  | } | 
| 237 |  |  |  |  |  |  |  | 
| 238 | 152 | 100 |  |  |  |  | if( | 
| 239 | 228 | 50 |  |  |  |  | BrotliEncoderIsFinished(self->encoder) || | 
| 240 | 76 | 50 |  |  |  |  | (!available_in && !BrotliEncoderHasMoreOutput(self->encoder)) | 
| 241 |  |  |  |  |  |  | ) break; | 
| 242 | 0 |  |  |  |  |  | } | 
| 243 | 152 |  |  |  |  |  | Safefree(buffer); | 
| 244 |  |  |  |  |  |  | OUTPUT: | 
| 245 |  |  |  |  |  |  | RETVAL | 
| 246 |  |  |  |  |  |  |  | 
| 247 |  |  |  |  |  |  | void | 
| 248 |  |  |  |  |  |  | DESTROY(self) | 
| 249 |  |  |  |  |  |  | IO::Compress::Brotli self | 
| 250 |  |  |  |  |  |  | CODE: | 
| 251 | 76 |  |  |  |  |  | BrotliEncoderDestroyInstance(self->encoder); | 
| 252 | 76 |  |  |  |  |  | Safefree(self); |