1 /* Filename: Zlib.xs 2 * Author : Paul Marquess, <pmqs@cpan.org> 3 * Created : 22nd January 1996 4 * Version : 2.000 5 * 6 * Copyright (c) 1995-2013 Paul Marquess. All rights reserved. 7 * This program is free software; you can redistribute it and/or 8 * modify it under the same terms as Perl itself. 9 * 10 */ 11 12 /* Parts of this code are based on the files gzio.c and gzappend.c from 13 * the standard zlib source distribution. Below are the copyright statements 14 * from each. 15 */ 16 17 /* gzio.c -- IO on .gz files 18 * Copyright (C) 1995 Jean-loup Gailly. 19 * For conditions of distribution and use, see copyright notice in zlib.h 20 */ 21 22 /* gzappend -- command to append to a gzip file 23 24 Copyright (C) 2003 Mark Adler, all rights reserved 25 version 1.1, 4 Nov 2003 26 */ 27 28 29 #define PERL_NO_GET_CONTEXT 30 #include "EXTERN.h" 31 #include "perl.h" 32 #include "XSUB.h" 33 34 #if USE_ZLIB_NG 35 # include "zlib-ng.h" 36 #else 37 # include "zlib.h" 38 #endif 39 40 41 /* zlib prior to 1.06 doesn't know about z_off_t */ 42 #ifndef z_off_t 43 # define z_off_t long 44 #endif 45 46 #if ! USE_ZLIB_NG && (! defined(ZLIB_VERNUM) || ZLIB_VERNUM < 0x1200) 47 # define NEED_DUMMY_BYTE_AT_END 48 #endif 49 50 #if USE_ZLIB_NG || (defined(ZLIB_VERNUM) && ZLIB_VERNUM >= 0x1210) 51 # define MAGIC_APPEND 52 # define AT_LEAST_ZLIB_1_2_1 53 #endif 54 55 #if USE_ZLIB_NG || (defined(ZLIB_VERNUM) && ZLIB_VERNUM >= 0x1221) 56 # define AT_LEAST_ZLIB_1_2_2_1 57 #endif 58 59 #if USE_ZLIB_NG || (defined(ZLIB_VERNUM) && ZLIB_VERNUM >= 0x1222) 60 # define AT_LEAST_ZLIB_1_2_2_2 61 #endif 62 63 #if USE_ZLIB_NG || (defined(ZLIB_VERNUM) && ZLIB_VERNUM >= 0x1223) 64 # define AT_LEAST_ZLIB_1_2_2_3 65 #endif 66 67 #if USE_ZLIB_NG || (defined(ZLIB_VERNUM) && ZLIB_VERNUM >= 0x1230) 68 # define AT_LEAST_ZLIB_1_2_3 69 #endif 70 71 #if USE_ZLIB_NG || (defined(ZLIB_VERNUM) && ZLIB_VERNUM >= 0x1252) 72 /* 73 Use Z_SOLO to build source means need own malloc/free 74 */ 75 # define AT_LEAST_ZLIB_1_2_5_2 76 #endif 77 78 79 /* zlib vs zlib-ng */ 80 81 #if USE_ZLIB_NG 82 83 /* zlibng native */ 84 85 # define HAVE_ZLIB_NG_NATIVE TRUE 86 # define HAVE_ZLIB_NG_COMPAT FALSE 87 88 # ifndef ZLIBNG_VER_STATUS 89 # define ZLIBNG_VER_STATUS 0 90 # endif 91 92 # ifndef ZLIBNG_VER_MODIFIED 93 # define ZLIBNG_VER_MODIFIED 0 94 # endif 95 96 # define CRZ_adlerInitial zng_adler32(0L, Z_NULL, 0) 97 # define CRZ_crcInitial zng_crc32(0L, Z_NULL, 0) 98 99 # define CRZ_ZSTREAM zng_stream 100 101 102 103 # define CRZ_adler32 zng_adler32 104 # define CRZ_adler32_combine zng_adler32_combine 105 # define CRZ_crc32 zng_crc32 106 # define CRZ_crc32_combine zng_crc32_combine 107 # define CRZ_deflate zng_deflate 108 # define CRZ_deflateEnd zng_deflateEnd 109 # define CRZ_deflateInit zng_deflateInit 110 # define CRZ_deflateInit2 zng_deflateInit2 111 # define CRZ_deflateParams zng_deflateParams 112 # define CRZ_deflatePrime zng_deflatePrime 113 # define CRZ_deflateReset zng_deflateReset 114 # define CRZ_deflateSetDictionary zng_deflateSetDictionary 115 # define CRZ_deflateTune zng_deflateTune 116 # define CRZ_inflate zng_inflate 117 # define CRZ_inflateEnd zng_inflateEnd 118 # define CRZ_inflateInit2 zng_inflateInit2 119 # define CRZ_inflateReset zng_inflateReset 120 # define CRZ_inflateSetDictionary zng_inflateSetDictionary 121 # define CRZ_inflateSync zng_inflateSync 122 # define CRZ_zlibCompileFlags zng_zlibCompileFlags 123 124 125 /* zlib symbols & functions */ 126 127 // # define CRZ_ZLIB_VERSION ZLIBNG_VERSION 128 // # define ZLIB_VERSION ZLIBNG_VERSION 129 # define CRZ_ZLIB_VERSION "" 130 # define ZLIB_VERSION "" 131 132 // # define CRZ_zlibVersion zlibng_version 133 // # define CRZ_zlib_version zlibng_version 134 135 const char *CRZ_zlibVersion(void) { return ""; } 136 const char *CRZ_zlib_version(void) { return ""; } 137 138 139 #else /* zlib specific */ 140 141 142 # define HAVE_ZLIB_NG_NATIVE FALSE 143 144 /* Is this real zlib or zlib-ng in compat mode */ 145 # ifdef ZLIBNG_VERSION 146 /* zlib-ng in compat mode */ 147 # define HAVE_ZLIB_NG_COMPAT TRUE 148 149 # ifndef ZLIBNG_VER_STATUS 150 # define ZLIBNG_VER_STATUS 0 151 # endif 152 153 # ifndef ZLIBNG_VER_MODIFIED 154 # define ZLIBNG_VER_MODIFIED 0 155 # endif 156 157 const char *zlibng_version(void) { return ZLIBNG_VERSION ; } 158 159 160 # else 161 /* zlib native mode */ 162 163 # define HAVE_ZLIB_NG_COMPAT FALSE 164 165 /* zlib doesn't have the ZLIBNG synbols, so create them */ 166 # define ZLIBNG_VERSION "" 167 # define ZLIBNG_VERNUM 0 168 # define ZLIBNG_VER_MAJOR 0 169 # define ZLIBNG_VER_MINOR 0 170 # define ZLIBNG_VER_REVISION 0 171 # define ZLIBNG_VER_STATUS 0 172 # define ZLIBNG_VER_MODIFIED 0 173 # define ZLIBNG_VERNUM 0 174 175 const char *zlibng_version(void) { return ""; } 176 177 # endif 178 179 180 181 # define CRZ_adlerInitial adler32(0L, Z_NULL, 0) 182 # define CRZ_crcInitial crc32(0L, Z_NULL, 0) 183 184 # define CRZ_ZSTREAM z_stream 185 186 # define CRZ_adler32 adler32 187 # define CRZ_adler32_combine adler32_combine 188 # define CRZ_crc32 crc32 189 # define CRZ_crc32_combine crc32_combine 190 # define CRZ_deflate deflate 191 # define CRZ_deflateEnd deflateEnd 192 # define CRZ_deflateInit deflateInit 193 # define CRZ_deflateInit2 deflateInit2 194 # define CRZ_deflateParams deflateParams 195 # define CRZ_deflatePrime deflatePrime 196 # define CRZ_deflateReset deflateReset 197 # define CRZ_deflateSetDictionary deflateSetDictionary 198 # define CRZ_deflateTune deflateTune 199 # define CRZ_inflate inflate 200 # define CRZ_inflateEnd inflateEnd 201 # define CRZ_inflateInit2 inflateInit2 202 # define CRZ_inflateReset inflateReset 203 # define CRZ_inflateSetDictionary inflateSetDictionary 204 # define CRZ_inflateSync inflateSync 205 # define CRZ_zlibCompileFlags zlibCompileFlags 206 # define CRZ_zlibVersion zlibVersion 207 # define CRZ_zlib_version zlibVersion 208 209 #endif 210 211 212 #ifdef USE_PPPORT_H 213 # define NEED_sv_2pvbyte 214 # define NEED_sv_2pv_nolen 215 # define NEED_sv_pvn_force_flags 216 # include "ppport.h" 217 218 /* Proposed fix for https://github.com/Dual-Life/Devel-PPPort/issues/231 */ 219 220 # if PERL_VERSION < 18 221 # ifdef sv_2pv 222 # undef sv_2pv 223 # endif 224 225 # if defined(__GNUC__) && !defined(PERL_GCC_BRACE_GROUPS_FORBIDDEN) 226 # define sv_2pv(sv, lp) ({ SV *_sv_2pv = (sv); SvPOKp(_sv_2pv) ? ((*(lp) = SvCUR(_sv_2pv)), SvPVX(_sv_2pv)) : Perl_sv_2pv(aTHX_ _sv_2pv, (lp)); }) 227 # else 228 # define sv_2pv(sv, lp) (SvPOKp(sv) ? ((*(lp) = SvCUR(sv)), SvPVX(sv)) : Perl_sv_2pv(aTHX_ (sv), (lp))) 229 # endif 230 231 #endif 232 233 #endif 234 235 #if PERL_REVISION == 5 && PERL_VERSION == 9 236 /* For Andreas */ 237 # define sv_pvbyte_force(sv,lp) sv_pvbyten_force(sv,lp) 238 #endif 239 240 #if PERL_REVISION == 5 && (PERL_VERSION < 8 || (PERL_VERSION == 8 && PERL_SUBVERSION < 4 )) 241 242 # ifdef SvPVbyte_force 243 # undef SvPVbyte_force 244 # endif 245 246 # define SvPVbyte_force(sv,lp) SvPV_force(sv,lp) 247 248 #endif 249 250 #ifndef SvPVbyte_nolen 251 # define SvPVbyte_nolen SvPV_nolen 252 #endif 253 254 255 256 #if 0 257 # ifndef SvPVbyte_nolen 258 # define SvPVbyte_nolen SvPV_nolen 259 # endif 260 261 # ifndef SvPVbyte_force 262 # define SvPVbyte_force(sv,lp) SvPV_force(sv,lp) 263 # endif 264 #endif 265 266 #if PERL_REVISION == 5 && (PERL_VERSION >= 8 || (PERL_VERSION == 8 && PERL_SUBVERSION < 4 )) 267 # define UTF8_AVAILABLE 268 #endif 269 270 typedef int DualType ; 271 typedef int int_undef ; 272 273 typedef struct di_stream { 274 int flags ; 275 #define FLAG_APPEND 1 276 #define FLAG_CRC32 2 277 #define FLAG_ADLER32 4 278 #define FLAG_CONSUME_INPUT 8 279 #define FLAG_LIMIT_OUTPUT 16 280 uLong crc32 ; 281 uLong adler32 ; 282 CRZ_ZSTREAM stream; 283 uLong bufsize; 284 SV * dictionary ; 285 uLong dict_adler ; 286 int last_error ; 287 bool zip_mode ; 288 /* #define SETP_BYTE */ 289 #ifdef SETP_BYTE 290 /* SETP_BYTE only works with zlib up to 1.2.8 */ 291 bool deflateParams_out_valid ; 292 Bytef deflateParams_out_byte; 293 #else 294 #define deflateParams_BUFFER_SIZE 0x40000 295 uLong deflateParams_out_length; 296 Bytef* deflateParams_out_buffer; 297 #endif 298 int Level; 299 int Method; 300 int WindowBits; 301 int MemLevel; 302 int Strategy; 303 uLong bytesInflated ; 304 uLong compressedBytes ; 305 uLong uncompressedBytes ; 306 #ifdef MAGIC_APPEND 307 308 #define WINDOW_SIZE 32768U 309 310 bool matchedEndBlock; 311 Bytef* window ; 312 int window_lastbit, window_left, window_full; 313 unsigned window_have; 314 off_t window_lastoff, window_end; 315 off_t window_endOffset; 316 317 uLong lastBlockOffset ; 318 unsigned char window_lastByte ; 319 320 321 #endif 322 } di_stream; 323 324 typedef di_stream * deflateStream ; 325 typedef di_stream * Compress__Raw__Zlib__deflateStream ; 326 typedef di_stream * inflateStream ; 327 typedef di_stream * Compress__Raw__Zlib__inflateStream ; 328 typedef di_stream * Compress__Raw__Zlib__inflateScanStream ; 329 330 #define ZMALLOC(to, typ) (to = (typ *)safecalloc(sizeof(typ), 1)) 331 332 /* Figure out the Operating System */ 333 #ifdef MSDOS 334 # define OS_CODE 0x00 335 #endif 336 337 #if defined(AMIGA) || defined(AMIGAOS) || defined(__amigaos4__) 338 # define OS_CODE 0x01 339 #endif 340 341 #if defined(VAXC) || defined(VMS) 342 # define OS_CODE 0x02 343 #endif 344 345 #if 0 /* VM/CMS */ 346 # define OS_CODE 0x04 347 #endif 348 349 #if defined(ATARI) || defined(atarist) 350 # define OS_CODE 0x05 351 #endif 352 353 #ifdef OS2 354 # define OS_CODE 0x06 355 #endif 356 357 #if defined(MACOS) || defined(TARGET_OS_MAC) 358 # define OS_CODE 0x07 359 #endif 360 361 #if 0 /* Z-System */ 362 # define OS_CODE 0x08 363 #endif 364 365 #if 0 /* CP/M */ 366 # define OS_CODE 0x09 367 #endif 368 369 #ifdef TOPS20 370 # define OS_CODE 0x0a 371 #endif 372 373 #ifdef WIN32 /* Window 95 & Windows NT */ 374 # define OS_CODE 0x0b 375 #endif 376 377 #if 0 /* QDOS */ 378 # define OS_CODE 0x0c 379 #endif 380 381 #if 0 /* Acorn RISCOS */ 382 # define OS_CODE 0x0d 383 #endif 384 385 #if 0 /* ??? */ 386 # define OS_CODE 0x0e 387 #endif 388 389 #ifdef __50SERIES /* Prime/PRIMOS */ 390 # define OS_CODE 0x0F 391 #endif 392 393 /* Default to UNIX */ 394 #ifndef OS_CODE 395 # define OS_CODE 0x03 /* assume Unix */ 396 #endif 397 398 #ifndef GZIP_OS_CODE 399 # define GZIP_OS_CODE OS_CODE 400 #endif 401 402 403 /* static const char * const my_z_errmsg[] = { */ 404 static const char my_z_errmsg[][32] = { 405 "need dictionary", /* Z_NEED_DICT 2 */ 406 "stream end", /* Z_STREAM_END 1 */ 407 "", /* Z_OK 0 */ 408 "file error", /* Z_ERRNO (-1) */ 409 "stream error", /* Z_STREAM_ERROR (-2) */ 410 "data error", /* Z_DATA_ERROR (-3) */ 411 "insufficient memory", /* Z_MEM_ERROR (-4) */ 412 "buffer error", /* Z_BUF_ERROR (-5) */ 413 "incompatible version",/* Z_VERSION_ERROR(-6) */ 414 ""}; 415 416 #define setDUALstatus(var, err) \ 417 sv_setnv(var, (double)err) ; \ 418 sv_setpv(var, ((err) ? GetErrorString(err) : "")) ; \ 419 SvNOK_on(var); 420 421 422 #if defined(__SYMBIAN32__) 423 # define NO_WRITEABLE_DATA 424 #endif 425 426 /* Set TRACE_DEFAULT to a non-zero value to enable tracing */ 427 #define TRACE_DEFAULT 0 428 429 #if defined(NO_WRITEABLE_DATA) || TRACE_DEFAULT == 0 430 # define trace TRACE_DEFAULT 431 #else 432 static int trace = TRACE_DEFAULT ; 433 #endif 434 435 /* Dodge PerlIO hiding of these functions. */ 436 #undef printf 437 438 static char * 439 #ifdef CAN_PROTOTYPE 440 GetErrorString(int error_no) 441 #else 442 GetErrorString(error_no) 443 int error_no ; 444 #endif 445 { 446 dTHX; 447 char * errstr ; 448 449 if (error_no == Z_ERRNO) { 450 errstr = Strerror(errno) ; 451 } 452 else 453 /* errstr = gzerror(fil, &error_no) ; */ 454 errstr = (char*) my_z_errmsg[2 - error_no]; 455 456 return errstr ; 457 } 458 459 460 #ifdef MAGIC_APPEND 461 462 /* 463 The following two functions are taken almost directly from 464 examples/gzappend.c. Only cosmetic changes have been made to conform to 465 the coding style of the rest of the code in this file. 466 */ 467 468 469 /* return the greatest common divisor of a and b using Euclid's algorithm, 470 modified to be fast when one argument much greater than the other, and 471 coded to avoid unnecessary swapping */ 472 static unsigned 473 #ifdef CAN_PROTOTYPE 474 gcd(unsigned a, unsigned b) 475 #else 476 gcd(a, b) 477 unsigned a; 478 unsigned b; 479 #endif 480 { 481 unsigned c; 482 483 while (a && b) 484 if (a > b) { 485 c = b; 486 while (a - c >= c) 487 c <<= 1; 488 a -= c; 489 } 490 else { 491 c = a; 492 while (b - c >= c) 493 c <<= 1; 494 b -= c; 495 } 496 return a + b; 497 } 498 499 /* rotate list[0..len-1] left by rot positions, in place */ 500 static void 501 #ifdef CAN_PROTOTYPE 502 rotate(unsigned char *list, unsigned len, unsigned rot) 503 #else 504 rotate(list, len, rot) 505 unsigned char *list; 506 unsigned len ; 507 unsigned rot; 508 #endif 509 { 510 unsigned char tmp; 511 unsigned cycles; 512 unsigned char *start, *last, *to, *from; 513 514 /* normalize rot and handle degenerate cases */ 515 if (len < 2) return; 516 if (rot >= len) rot %= len; 517 if (rot == 0) return; 518 519 /* pointer to last entry in list */ 520 last = list + (len - 1); 521 522 /* do simple left shift by one */ 523 if (rot == 1) { 524 tmp = *list; 525 memmove(list, list + 1, len - 1); 526 *last = tmp; 527 return; 528 } 529 530 /* do simple right shift by one */ 531 if (rot == len - 1) { 532 tmp = *last; 533 memmove(list + 1, list, len - 1); 534 *list = tmp; 535 return; 536 } 537 538 /* otherwise do rotate as a set of cycles in place */ 539 cycles = gcd(len, rot); /* number of cycles */ 540 do { 541 start = from = list + cycles; /* start index is arbitrary */ 542 tmp = *from; /* save entry to be overwritten */ 543 for (;;) { 544 to = from; /* next step in cycle */ 545 from += rot; /* go right rot positions */ 546 if (from > last) from -= len; /* (pointer better not wrap) */ 547 if (from == start) break; /* all but one shifted */ 548 *to = *from; /* shift left */ 549 } 550 *to = tmp; /* complete the circle */ 551 } while (--cycles); 552 } 553 554 #endif /* MAGIC_APPEND */ 555 556 static void 557 #ifdef CAN_PROTOTYPE 558 DispHex(const void * ptr, int length) 559 #else 560 DispHex(ptr, length) 561 const void * ptr; 562 int length; 563 #endif 564 { 565 char * p = (char*)ptr; 566 int i; 567 for (i = 0; i < length; ++i) { 568 printf(" %02x", 0xFF & *(p+i)); 569 } 570 } 571 572 573 static void 574 #ifdef CAN_PROTOTYPE 575 DispStream(di_stream * s, const char * message) 576 #else 577 DispStream(s, message) 578 di_stream * s; 579 const char * message; 580 #endif 581 { 582 583 #if 0 584 if (! trace) 585 return ; 586 #endif 587 588 #define EnDis(f) (s->flags & f ? "Enabled" : "Disabled") 589 590 printf("DispStream %p", s) ; 591 if (message) 592 printf("- %s \n", message) ; 593 printf("\n") ; 594 595 if (!s) { 596 printf(" stream pointer is NULL\n"); 597 } 598 else { 599 printf(" stream %p\n", &(s->stream)); 600 printf(" zalloc %p\n", s->stream.zalloc); 601 printf(" zfree %p\n", s->stream.zfree); 602 printf(" opaque %p\n", s->stream.opaque); 603 printf(" state %p\n", s->stream.state); 604 if (s->stream.msg) 605 printf(" msg %s\n", s->stream.msg); 606 else 607 printf(" msg \n"); 608 printf(" next_in %p", s->stream.next_in); 609 if (s->stream.next_in){ 610 printf(" =>"); 611 DispHex(s->stream.next_in, 4); 612 } 613 printf("\n"); 614 615 printf(" next_out %p", s->stream.next_out); 616 if (s->stream.next_out){ 617 printf(" =>"); 618 DispHex(s->stream.next_out, 4); 619 } 620 printf("\n"); 621 622 printf(" avail_in %lu\n", (unsigned long)s->stream.avail_in); 623 printf(" avail_out %lu\n", (unsigned long)s->stream.avail_out); 624 printf(" total_in %ld\n", s->stream.total_in); 625 printf(" total_out %ld\n", s->stream.total_out); 626 #if ! USE_ZLIB_NG 627 printf(" adler %ld\n", s->stream.adler ); 628 #else 629 printf(" adler %u\n", s->stream.adler ); 630 #endif 631 printf(" bufsize %ld\n", s->bufsize); 632 printf(" dictionary %p\n", s->dictionary); 633 printf(" dict_adler 0x%ld\n",s->dict_adler); 634 printf(" zip_mode %d\n", s->zip_mode); 635 printf(" crc32 0x%x\n", (unsigned)s->crc32); 636 printf(" adler32 0x%x\n", (unsigned)s->adler32); 637 printf(" flags 0x%x\n", s->flags); 638 printf(" APPEND %s\n", EnDis(FLAG_APPEND)); 639 printf(" CRC32 %s\n", EnDis(FLAG_CRC32)); 640 printf(" ADLER32 %s\n", EnDis(FLAG_ADLER32)); 641 printf(" CONSUME %s\n", EnDis(FLAG_CONSUME_INPUT)); 642 printf(" LIMIT %s\n", EnDis(FLAG_LIMIT_OUTPUT)); 643 644 645 #ifdef MAGIC_APPEND 646 printf(" window %p\n", s->window); 647 #endif 648 printf("\n"); 649 650 } 651 } 652 653 #ifdef AT_LEAST_ZLIB_1_2_5_2 654 voidpf my_zcalloc (voidpf opaque, unsigned items, unsigned size) 655 { 656 PERL_UNUSED_VAR(opaque); 657 /* TODO - put back to calloc */ 658 /* return safecalloc(items, size); */ 659 return (voidpf)safemalloc(items* size); 660 } 661 662 663 void my_zcfree (voidpf opaque, voidpf ptr) 664 { 665 PERL_UNUSED_VAR(opaque); 666 safefree(ptr); 667 return; 668 } 669 670 #endif 671 672 static di_stream * 673 #ifdef CAN_PROTOTYPE 674 InitStream(void) 675 #else 676 InitStream() 677 #endif 678 { 679 di_stream *s ; 680 681 ZMALLOC(s, di_stream) ; 682 683 #ifdef AT_LEAST_ZLIB_1_2_5_2 684 s->stream.zalloc = my_zcalloc; 685 s->stream.zfree = my_zcfree; 686 #endif 687 688 return s ; 689 } 690 691 static void 692 #ifdef CAN_PROTOTYPE 693 PostInitStream(di_stream * s, int flags, int bufsize, int windowBits) 694 #else 695 PostInitStream(s, flags, bufsize, windowBits) 696 di_stream *s ; 697 int flags ; 698 int bufsize ; 699 int windowBits ; 700 #endif 701 { 702 s->bufsize = bufsize ; 703 s->compressedBytes = 704 s->uncompressedBytes = 705 s->last_error = 0 ; 706 s->flags = flags ; 707 s->zip_mode = (windowBits < 0) ; 708 if (flags & FLAG_CRC32) 709 s->crc32 = CRZ_crcInitial ; 710 if (flags & FLAG_ADLER32) 711 s->adler32 = CRZ_adlerInitial ; 712 } 713 714 715 static SV* 716 #ifdef CAN_PROTOTYPE 717 deRef(SV * sv, const char * string) 718 #else 719 deRef(sv, string) 720 SV * sv ; 721 char * string; 722 #endif 723 { 724 dTHX; 725 SvGETMAGIC(sv); 726 727 if (SvROK(sv)) { 728 sv = SvRV(sv) ; 729 SvGETMAGIC(sv); 730 switch(SvTYPE(sv)) { 731 case SVt_PVAV: 732 case SVt_PVHV: 733 case SVt_PVCV: 734 croak("%s: buffer parameter is not a SCALAR reference", string); 735 default: 736 break; 737 } 738 if (SvROK(sv)) 739 croak("%s: buffer parameter is a reference to a reference", string) ; 740 } 741 742 if (!SvOK(sv)) 743 sv = sv_2mortal(newSVpv("", 0)); 744 745 return sv ; 746 } 747 748 static SV* 749 #ifdef CAN_PROTOTYPE 750 deRef_l(SV * sv, const char * string) 751 #else 752 deRef_l(sv, string) 753 SV * sv ; 754 char * string ; 755 #endif 756 { 757 dTHX; 758 bool wipe = 0 ; 759 STRLEN na; 760 761 SvGETMAGIC(sv); 762 wipe = ! SvOK(sv) ; 763 764 if (SvROK(sv)) { 765 sv = SvRV(sv) ; 766 SvGETMAGIC(sv); 767 wipe = ! SvOK(sv) ; 768 769 switch(SvTYPE(sv)) { 770 case SVt_PVAV: 771 case SVt_PVHV: 772 case SVt_PVCV: 773 croak("%s: buffer parameter is not a SCALAR reference", string); 774 default: 775 break; 776 } 777 if (SvROK(sv)) 778 croak("%s: buffer parameter is a reference to a reference", string) ; 779 } 780 781 if (SvREADONLY(sv) && PL_curcop != &PL_compiling) 782 croak("%s: buffer parameter is read-only", string); 783 784 SvUPGRADE(sv, SVt_PV); 785 786 if (wipe) 787 sv_setpv(sv, "") ; 788 else 789 (void)SvPVbyte_force(sv, na) ; 790 791 return sv ; 792 } 793 794 #if 0 795 int 796 flushToBuffer(di_stream* s, int flush) 797 { 798 dTHX; 799 int ret ; 800 CRZ_ZSTREAM * strm = &s->stream; 801 802 Bytef* output = s->deflateParams_out_buffer ; 803 804 strm->next_in = NULL; 805 strm->avail_in = 0; 806 807 uLong total_output = 0; 808 uLong have = 0; 809 810 do 811 { 812 if (output) 813 output = (unsigned char *)saferealloc(output, total_output + s->bufsize); 814 else 815 output = (unsigned char *)safemalloc(s->bufsize); 816 817 strm->next_out = output + total_output; 818 strm->avail_out = s->bufsize; 819 820 ret = deflate(strm, flush); /* no bad return value */ 821 //assert(ret != Z_STREAM_ERROR); /* state not clobbered */ 822 if(ret == Z_STREAM_ERROR) 823 { 824 safefree(output); 825 return ret; 826 } 827 have = s->bufsize - strm->avail_out; 828 total_output += have; 829 830 //fprintf(stderr, "FLUSH %s %d, return %d\n", flush_flags[flush], have, ret); 831 832 } while (strm->avail_out == 0); 833 834 s->deflateParams_out_buffer = output; 835 s->deflateParams_out_length = total_output; 836 837 return Z_OK; 838 } 839 #endif 840 841 #ifndef SETP_BYTE 842 int 843 flushParams(di_stream* s) 844 { 845 dTHX; 846 int ret ; 847 CRZ_ZSTREAM * strm = &s->stream; 848 849 Bytef* output = s->deflateParams_out_buffer ; 850 uLong total_output = s->deflateParams_out_length; 851 uLong have = 0; 852 853 strm->next_in = NULL; 854 strm->avail_in = 0; 855 856 857 do 858 { 859 if (output) 860 output = (unsigned char *)saferealloc(output, total_output + s->bufsize); 861 else 862 output = (unsigned char *)safemalloc(s->bufsize); 863 864 strm->next_out = output + total_output; 865 strm->avail_out = s->bufsize; 866 867 ret = CRZ_deflateParams(&(s->stream), s->Level, s->Strategy); 868 /* fprintf(stderr, "deflateParams %d %s %lu\n", ret, 869 GetErrorString(ret), s->bufsize - strm->avail_out); */ 870 871 if (ret == Z_STREAM_ERROR) 872 break; 873 874 have = s->bufsize - strm->avail_out; 875 total_output += have; 876 877 878 } while (ret == Z_BUF_ERROR) ; 879 880 if(ret == Z_STREAM_ERROR) 881 safefree(output); 882 else 883 { 884 s->deflateParams_out_buffer = output; 885 s->deflateParams_out_length = total_output; 886 } 887 888 return ret; 889 } 890 #endif /* ! SETP_BYTE */ 891 892 #include "constants.h" 893 894 MODULE = Compress::Raw::Zlib PACKAGE = Compress::Raw::Zlib PREFIX = Zip_ 895 896 REQUIRE: 1.924 897 PROTOTYPES: DISABLE 898 899 INCLUDE: constants.xs 900 901 BOOT: 902 #if ! USE_ZLIB_NG 903 /* Check this version of zlib is == 1 */ 904 if (CRZ_zlibVersion()[0] != '1') 905 croak("Compress::Raw::Zlib needs zlib version 1.x\n") ; 906 #endif 907 908 { 909 /* Create the $os_code scalar */ 910 SV * os_code_sv = perl_get_sv("Compress::Raw::Zlib::gzip_os_code", GV_ADDMULTI) ; 911 sv_setiv(os_code_sv, GZIP_OS_CODE) ; 912 } 913 914 { 915 /* BUILD_ZLIB */ 916 SV * os_code_sv = perl_get_sv("Compress::Raw::Zlib::BUILD_ZLIB", GV_ADDMULTI) ; 917 sv_setiv(os_code_sv, Perl_crz_BUILD_ZLIB) ; 918 } 919 920 #define Zip_zlib_version() (const char*)CRZ_zlib_version() 921 const char* 922 Zip_zlib_version() 923 924 const char* 925 zlibng_version() 926 927 #define Zip_is_zlib_native() (! (HAVE_ZLIB_NG_NATIVE || HAVE_ZLIB_NG_COMPAT)) 928 bool 929 Zip_is_zlib_native() 930 931 #define Zip_is_zlibng_native() (bool)HAVE_ZLIB_NG_NATIVE 932 bool 933 Zip_is_zlibng_native() 934 935 #define Zip_is_zlibng_compat() (bool)HAVE_ZLIB_NG_COMPAT 936 bool 937 Zip_is_zlibng_compat() 938 939 #define Zip_is_zlibng() (bool)(HAVE_ZLIB_NG_NATIVE || HAVE_ZLIB_NG_COMPAT) 940 bool 941 Zip_is_zlibng() 942 943 unsigned 944 ZLIB_VERNUM() 945 CODE: 946 #ifdef ZLIB_VERNUM 947 RETVAL = ZLIB_VERNUM ; 948 #elif USE_ZLIB_NG 949 RETVAL = 0 ; 950 #else 951 /* 1.1.4 => 0x1140 */ 952 RETVAL = (CRZ_ZLIB_VERSION[0] - '0') << 12 ; 953 RETVAL += (CRZ_ZLIB_VERSION[2] - '0') << 8 ; 954 RETVAL += (CRZ_ZLIB_VERSION[4] - '0') << 4 ; 955 if (strlen(CRZ_ZLIB_VERSION) > 5) 956 RETVAL += (CRZ_ZLIB_VERSION[6] - '0') ; 957 #endif 958 OUTPUT: 959 RETVAL 960 961 962 #ifndef AT_LEAST_ZLIB_1_2_1 963 # define Zip_zlibCompileFlags 0 964 #else 965 # define Zip_zlibCompileFlags CRZ_zlibCompileFlags 966 #endif 967 uLong 968 Zip_zlibCompileFlags() 969 970 const char* 971 ZLIBNG_VER_STATUS() 972 CODE: 973 #ifdef ZLIBNG_VER_STATUS 974 RETVAL = STRINGIFY(ZLIBNG_VER_STATUS); 975 #else 976 RETVAL = "0"; 977 #endif 978 OUTPUT: 979 RETVAL 980 981 MODULE = Compress::Raw::Zlib PACKAGE = Compress::Raw::Zlib PREFIX = Zip_ 982 983 #define Zip_adler32(buf, adler) CRZ_adler32(adler, buf, (uInt)len) 984 985 uLong 986 Zip_adler32(buf, adler=CRZ_adlerInitial) 987 uLong adler = NO_INIT 988 STRLEN len = NO_INIT 989 Bytef * buf = NO_INIT 990 SV * sv = ST(0) ; 991 INIT: 992 /* If the buffer is a reference, dereference it */ 993 sv = deRef(sv, "adler32") ; 994 #ifdef UTF8_AVAILABLE 995 if (DO_UTF8(sv) && !sv_utf8_downgrade(sv, 1)) 996 croak("Wide character in Compress::Raw::Zlib::adler32"); 997 #endif 998 buf = (Byte*)SvPVbyte(sv, len) ; 999 1000 if (items < 2) 1001 adler = CRZ_adlerInitial; 1002 else if (SvOK(ST(1))) 1003 adler = SvUV(ST(1)) ; 1004 else 1005 adler = CRZ_adlerInitial; 1006 OUTPUT: 1007 RETVAL 1008 1009 #define Zip_crc32(buf, crc, offset) CRZ_crc32(crc, buf+offset, (uInt)len-offset) 1010 1011 uLong 1012 Zip_crc32(buf, crc=CRZ_crcInitial, offset=0) 1013 uLong crc = NO_INIT 1014 STRLEN len = NO_INIT 1015 Bytef * buf = NO_INIT 1016 STRLEN offset 1017 SV * sv = ST(0) ; 1018 INIT: 1019 /* If the buffer is a reference, dereference it */ 1020 sv = deRef(sv, "crc32") ; 1021 #ifdef UTF8_AVAILABLE 1022 if (DO_UTF8(sv) && !sv_utf8_downgrade(sv, 1)) 1023 croak("Wide character in Compress::Raw::Zlib::crc32"); 1024 #endif 1025 buf = (Byte*)SvPVbyte(sv, len) ; 1026 1027 if (offset > len) 1028 croak("Offset out of range in Compress::Raw::Zlib::crc32"); 1029 1030 if (items < 2) 1031 crc = CRZ_crcInitial; 1032 else if (SvOK(ST(1))) 1033 crc = SvUV(ST(1)) ; 1034 else 1035 crc = CRZ_crcInitial; 1036 1037 uLong 1038 crc32_combine(crc1, crc2, len2) 1039 uLong crc1 1040 uLong crc2 1041 z_off_t len2 1042 CODE: 1043 #ifndef AT_LEAST_ZLIB_1_2_2_1 1044 crc1 = crc1; crc2 = crc2 ; len2 = len2; /* Silence -Wall */ 1045 croak("crc32_combine needs zlib 1.2.3 or better"); 1046 #else 1047 RETVAL = CRZ_crc32_combine(crc1, crc2, len2); 1048 #endif 1049 OUTPUT: 1050 RETVAL 1051 1052 1053 uLong 1054 adler32_combine(adler1, adler2, len2) 1055 uLong adler1 1056 uLong adler2 1057 z_off_t len2 1058 CODE: 1059 #ifndef AT_LEAST_ZLIB_1_2_2_1 1060 adler1 = adler1; adler2 = adler2 ; len2 = len2; /* Silence -Wall */ 1061 croak("adler32_combine needs zlib 1.2.3 or better"); 1062 #else 1063 RETVAL = CRZ_adler32_combine(adler1, adler2, len2); 1064 #endif 1065 OUTPUT: 1066 RETVAL 1067 1068 1069 MODULE = Compress::Raw::Zlib PACKAGE = Compress::Raw::Zlib 1070 1071 void 1072 _deflateInit(flags,level, method, windowBits, memLevel, strategy, bufsize, dictionary) 1073 int flags 1074 int level 1075 int method 1076 int windowBits 1077 int memLevel 1078 int strategy 1079 uLong bufsize 1080 SV* dictionary 1081 PPCODE: 1082 int err ; 1083 deflateStream s ; 1084 1085 if (trace) 1086 warn("in _deflateInit(level=%d, method=%d, windowBits=%d, memLevel=%d, strategy=%d, bufsize=%ld dictionary=%p)\n", 1087 level, method, windowBits, memLevel, strategy, bufsize, dictionary) ; 1088 if ((s = InitStream() )) { 1089 1090 s->Level = level; 1091 s->Method = method; 1092 s->WindowBits = windowBits; 1093 s->MemLevel = memLevel; 1094 s->Strategy = strategy; 1095 1096 err = CRZ_deflateInit2(&(s->stream), level, 1097 method, windowBits, memLevel, strategy); 1098 1099 if (trace) { 1100 warn(" _deflateInit2 returned %d (state %p)\n", err, s); 1101 DispStream(s, "INIT"); 1102 } 1103 1104 /* Check if a dictionary has been specified */ 1105 SvGETMAGIC(dictionary); 1106 if (err == Z_OK && SvPOK(dictionary) && SvCUR(dictionary)) { 1107 #ifdef UTF8_AVAILABLE 1108 if (DO_UTF8(dictionary) && !sv_utf8_downgrade(dictionary, 1)) 1109 croak("Wide character in Compress::Raw::Zlib::Deflate::new dicrionary parameter"); 1110 #endif 1111 err = CRZ_deflateSetDictionary(&(s->stream), (const Bytef*) SvPVX(dictionary), SvCUR(dictionary)) ; 1112 if (trace) 1113 warn("deflateSetDictionary returned %d\n", err); 1114 s->dict_adler = s->stream.adler ; 1115 } 1116 1117 if (err != Z_OK) { 1118 Safefree(s) ; 1119 s = NULL ; 1120 } 1121 else 1122 PostInitStream(s, flags, bufsize, windowBits) ; 1123 1124 } 1125 else 1126 err = Z_MEM_ERROR ; 1127 1128 { 1129 SV* obj = sv_setref_pv(sv_newmortal(), 1130 "Compress::Raw::Zlib::deflateStream", (void*)s); 1131 XPUSHs(obj); 1132 } 1133 if (GIMME_V == G_ARRAY) { 1134 SV * sv = sv_2mortal(newSViv(err)) ; 1135 setDUALstatus(sv, err); 1136 XPUSHs(sv) ; 1137 } 1138 1139 void 1140 _inflateInit(flags, windowBits, bufsize, dictionary) 1141 int flags 1142 int windowBits 1143 uLong bufsize 1144 SV * dictionary 1145 ALIAS: 1146 _inflateScanInit = 1 1147 PPCODE: 1148 1149 int err = Z_OK ; 1150 inflateStream s ; 1151 #ifndef MAGIC_APPEND 1152 if (ix == 1) 1153 croak("inflateScanInit needs zlib 1.2.1 or better"); 1154 #endif 1155 if (trace) 1156 warn("in _inflateInit(windowBits=%d, bufsize=%lu, dictionary=%lu\n", 1157 windowBits, bufsize, (unsigned long)SvCUR(dictionary)) ; 1158 if ((s = InitStream() )) { 1159 1160 s->WindowBits = windowBits; 1161 1162 err = CRZ_inflateInit2(&(s->stream), windowBits); 1163 if (err != Z_OK) { 1164 Safefree(s) ; 1165 s = NULL ; 1166 } 1167 else if (sv_len(dictionary)) { 1168 #ifdef AT_LEAST_ZLIB_1_2_2_1 1169 /* Zlib 1.2.2.1 or better allows a dictionary with raw inflate */ 1170 if (s->WindowBits < 0) { 1171 STRLEN dlen; 1172 const Bytef* b = (const Bytef*)SvPVbyte(dictionary, dlen); 1173 err = CRZ_inflateSetDictionary(&(s->stream), 1174 b, dlen); 1175 if (err != Z_OK) { 1176 Safefree(s) ; 1177 s = NULL ; 1178 } 1179 } 1180 else 1181 #endif 1182 /* Dictionary specified - take a copy for use in inflate */ 1183 s->dictionary = newSVsv(dictionary) ; 1184 } 1185 if (s) { 1186 PostInitStream(s, flags, bufsize, windowBits) ; 1187 #ifdef MAGIC_APPEND 1188 if (ix == 1) 1189 { 1190 s->window = (unsigned char *)safemalloc(WINDOW_SIZE); 1191 } 1192 #endif 1193 } 1194 } 1195 else 1196 err = Z_MEM_ERROR ; 1197 1198 { 1199 SV* obj = sv_setref_pv(sv_newmortal(), 1200 ix == 1 1201 ? "Compress::Raw::Zlib::inflateScanStream" 1202 : "Compress::Raw::Zlib::inflateStream", 1203 (void*)s); 1204 XPUSHs(obj); 1205 } 1206 if (GIMME_V == G_ARRAY) { 1207 SV * sv = sv_2mortal(newSViv(err)) ; 1208 setDUALstatus(sv, err); 1209 XPUSHs(sv) ; 1210 } 1211 1212 1213 1214 MODULE = Compress::Raw::Zlib PACKAGE = Compress::Raw::Zlib::deflateStream 1215 1216 void 1217 DispStream(s, message=NULL) 1218 Compress::Raw::Zlib::deflateStream s 1219 const char * message 1220 1221 DualType 1222 deflateReset(s) 1223 Compress::Raw::Zlib::deflateStream s 1224 CODE: 1225 RETVAL = CRZ_deflateReset(&(s->stream)) ; 1226 if (RETVAL == Z_OK) { 1227 PostInitStream(s, s->flags, s->bufsize, s->WindowBits) ; 1228 } 1229 OUTPUT: 1230 RETVAL 1231 1232 DualType 1233 deflate (s, buf, output) 1234 Compress::Raw::Zlib::deflateStream s 1235 SV * buf 1236 SV * output 1237 uInt cur_length = NO_INIT 1238 uInt increment = NO_INIT 1239 uInt prefix = NO_INIT 1240 int RETVAL = 0; 1241 uLong bufinc = NO_INIT 1242 STRLEN origlen = NO_INIT 1243 CODE: 1244 bufinc = s->bufsize; 1245 1246 /* 1247 if (trace) { 1248 printf("\nDEFLATE Before deRef of input buffer\n"); 1249 printf("\nPerl_sv_dump\n"); 1250 Perl_sv_dump(buf); 1251 printf("\n"); 1252 } 1253 */ 1254 1255 /* If the input buffer is a reference, dereference it */ 1256 buf = deRef(buf, "deflate") ; 1257 1258 /* initialise the input buffer */ 1259 #ifdef UTF8_AVAILABLE 1260 if (DO_UTF8(buf) && !sv_utf8_downgrade(buf, 1)) 1261 croak("Wide character in Compress::Raw::Zlib::Deflate::deflate input parameter"); 1262 #endif 1263 s->stream.next_in = (Bytef*)SvPV_nomg(buf, origlen) ; 1264 s->stream.avail_in = origlen; 1265 1266 if (trace) { 1267 printf("\nDEFLATE Starts\n"); 1268 DispStream(s, "START"); 1269 /* 1270 printf("\nPerl_sv_dump\n"); 1271 Perl_sv_dump(buf); 1272 printf("\n"); 1273 */ 1274 } 1275 1276 if (s->flags & FLAG_CRC32) 1277 s->crc32 = CRZ_crc32(s->crc32, s->stream.next_in, s->stream.avail_in) ; 1278 1279 if (s->flags & FLAG_ADLER32) 1280 s->adler32 = CRZ_adler32(s->adler32, s->stream.next_in, s->stream.avail_in) ; 1281 1282 /* and retrieve the output buffer */ 1283 output = deRef_l(output, "deflate") ; 1284 #ifdef UTF8_AVAILABLE 1285 if (DO_UTF8(output) && !sv_utf8_downgrade(output, 1)) 1286 croak("Wide character in Compress::Raw::Zlib::Deflate::deflate output parameter"); 1287 #endif 1288 1289 if((s->flags & FLAG_APPEND) == FLAG_APPEND) { 1290 SvOOK_off(output); 1291 } else { 1292 SvCUR_set(output, 0); 1293 } 1294 prefix = cur_length = SvCUR(output) ; 1295 s->stream.next_out = (Bytef*) SvPVX(output) + cur_length; 1296 increment = SvLEN(output) - cur_length; 1297 s->stream.avail_out = increment; 1298 #ifdef SETP_BYTE 1299 /* Check for saved output from deflateParams */ 1300 if (s->deflateParams_out_valid) { 1301 *(s->stream.next_out) = s->deflateParams_out_byte; 1302 ++ s->stream.next_out; 1303 -- s->stream.avail_out ; 1304 s->deflateParams_out_valid = FALSE; 1305 } 1306 #else 1307 /* Check for saved output from deflateParams */ 1308 if (s->deflateParams_out_length) { 1309 uLong plen = s->deflateParams_out_length ; 1310 /* printf("Copy %lu bytes saved data\n", plen); */ 1311 if (s->stream.avail_out < plen) { 1312 /* printf("GROW from %d to %lu\n", s->stream.avail_out, 1313 SvLEN(output) + plen - s->stream.avail_out); */ 1314 s->stream.next_out = (Bytef*) Sv_Grow(output, SvLEN(output) + plen - s->stream.avail_out) ; 1315 s->stream.next_out += cur_length; 1316 } 1317 1318 Copy(s->deflateParams_out_buffer, s->stream.next_out, plen, Bytef) ; 1319 cur_length += plen; 1320 SvCUR_set(output, cur_length); 1321 s->stream.next_out += plen ; 1322 s->stream.avail_out = SvLEN(output) - cur_length ; 1323 increment = s->stream.avail_out; 1324 1325 s->deflateParams_out_length = 0; 1326 Safefree(s->deflateParams_out_buffer); 1327 s->deflateParams_out_buffer = NULL; 1328 } 1329 #endif 1330 RETVAL = Z_OK ; 1331 while (s->stream.avail_in != 0) { 1332 1333 if (s->stream.avail_out == 0) { 1334 /* out of space in the output buffer so make it bigger */ 1335 s->stream.next_out = (Bytef*) Sv_Grow(output, SvLEN(output) + bufinc) ; 1336 cur_length += increment ; 1337 s->stream.next_out += cur_length ; 1338 increment = bufinc ; 1339 s->stream.avail_out = increment; 1340 bufinc *= 2 ; 1341 } 1342 1343 if (trace) { 1344 printf("DEFLATE Avail In %d, Out %d\n", s->stream.avail_in, s->stream.avail_out); 1345 DispStream(s, "BEFORE"); 1346 /* Perl_sv_dump(output); */ 1347 } 1348 1349 RETVAL = CRZ_deflate(&(s->stream), Z_NO_FLUSH); 1350 /* 1351 if (RETVAL != Z_STREAM_ERROR) { 1352 int done = increment - s->stream.avail_out ; 1353 printf("std DEFLATEr returned %d '%s' avail in %d, out %d wrote %d\n", RETVAL, 1354 GetErrorString(RETVAL), s->stream.avail_in, s->stream.avail_out, done); 1355 } 1356 */ 1357 1358 if (trace) { 1359 printf("DEFLATE returned %d %s, avail in %d, out %d\n", RETVAL, 1360 GetErrorString(RETVAL), s->stream.avail_in, s->stream.avail_out); 1361 DispStream(s, "AFTER"); 1362 } 1363 1364 if (RETVAL != Z_OK) 1365 break; 1366 } 1367 1368 s->compressedBytes += cur_length + increment - prefix - s->stream.avail_out ; 1369 s->uncompressedBytes += origlen - s->stream.avail_in ; 1370 1371 s->last_error = RETVAL ; 1372 if (RETVAL == Z_OK) { 1373 SvPOK_only(output); 1374 SvCUR_set(output, cur_length + increment - s->stream.avail_out) ; 1375 SvSETMAGIC(output); 1376 } 1377 OUTPUT: 1378 RETVAL 1379 1380 1381 void 1382 DESTROY(s) 1383 Compress::Raw::Zlib::deflateStream s 1384 CODE: 1385 if (trace) 1386 printf("Compress::Raw::Zlib::deflateStream::DESTROY %p\n", s); 1387 CRZ_deflateEnd(&s->stream) ; 1388 if (s->dictionary) 1389 SvREFCNT_dec(s->dictionary) ; 1390 #ifndef SETP_BYTE 1391 if (s->deflateParams_out_buffer) 1392 Safefree(s->deflateParams_out_buffer); 1393 #endif 1394 Safefree(s) ; 1395 1396 1397 DualType 1398 flush(s, output, f=Z_FINISH) 1399 Compress::Raw::Zlib::deflateStream s 1400 SV * output 1401 int f 1402 uInt cur_length = NO_INIT 1403 uInt increment = NO_INIT 1404 uInt prefix = NO_INIT 1405 uLong bufinc = NO_INIT 1406 uLong availableout = NO_INIT 1407 CODE: 1408 bufinc = s->bufsize; 1409 1410 1411 1412 /* retrieve the output buffer */ 1413 output = deRef_l(output, "flush") ; 1414 #ifdef UTF8_AVAILABLE 1415 if (DO_UTF8(output) && !sv_utf8_downgrade(output, 1)) 1416 croak("Wide character in Compress::Raw::Zlib::Deflate::flush input parameter"); 1417 #endif 1418 if((s->flags & FLAG_APPEND) == FLAG_APPEND) { 1419 SvOOK_off(output); 1420 } else { 1421 SvCUR_set(output, 0); 1422 } 1423 prefix = cur_length = SvCUR(output) ; 1424 s->stream.next_out = (Bytef*) SvPVX(output) + cur_length; 1425 increment = SvLEN(output) - cur_length; 1426 s->stream.avail_out = increment; 1427 #ifdef SETP_BYTE 1428 /* Check for saved output from deflateParams */ 1429 if (s->deflateParams_out_valid) { 1430 *(s->stream.next_out) = s->deflateParams_out_byte; 1431 ++ s->stream.next_out; 1432 -- s->stream.avail_out ; 1433 s->deflateParams_out_valid = FALSE; 1434 } 1435 #else 1436 /* Check for saved output from deflateParams */ 1437 if (s->deflateParams_out_length) { 1438 uLong plen = s->deflateParams_out_length ; 1439 /* printf("Copy %lu bytes saved data\n", plen); */ 1440 if (s->stream.avail_out < plen) { 1441 /* printf("GROW from %d to %lu\n", s->stream.avail_out, 1442 SvLEN(output) + plen - s->stream.avail_out); */ 1443 s->stream.next_out = (Bytef*) Sv_Grow(output, SvLEN(output) + plen - s->stream.avail_out) ; 1444 s->stream.next_out += cur_length; 1445 } 1446 1447 Copy(s->deflateParams_out_buffer, s->stream.next_out, plen, Bytef) ; 1448 cur_length += plen; 1449 SvCUR_set(output, cur_length); 1450 s->stream.next_out += plen ; 1451 s->stream.avail_out = SvLEN(output) - cur_length ; 1452 increment = s->stream.avail_out; 1453 1454 s->deflateParams_out_length = 0; 1455 Safefree(s->deflateParams_out_buffer); 1456 s->deflateParams_out_buffer = NULL; 1457 } 1458 #endif 1459 1460 for (;;) { 1461 if (s->stream.avail_out == 0) { 1462 /* consumed all the available output, so extend it */ 1463 s->stream.next_out = (Bytef*) Sv_Grow(output, SvLEN(output) + bufinc) ; 1464 cur_length += increment ; 1465 s->stream.next_out += cur_length ; 1466 increment = bufinc ; 1467 s->stream.avail_out = increment; 1468 bufinc *= 2 ; 1469 } 1470 1471 availableout = s->stream.avail_out ; 1472 1473 if (trace) { 1474 printf("flush (%d) DEFLATE Avail In %d, Out %d\n", f, s->stream.avail_in, s->stream.avail_out); 1475 DispStream(s, "BEFORE"); 1476 /* Perl_sv_dump(output); */ 1477 } 1478 1479 RETVAL = CRZ_deflate(&(s->stream), f); 1480 /* 1481 if (RETVAL != Z_STREAM_ERROR) { 1482 int done = availableout - s->stream.avail_out ; 1483 printf("flush DEFLATEr returned %d '%s' avail in %d, out %d wrote %d\n", RETVAL, 1484 GetErrorString(RETVAL), s->stream.avail_in, 1485 s->stream.avail_out, done); 1486 } 1487 */ 1488 1489 if (trace) { 1490 printf("flush DEFLATE returned %d '%s', avail in %d, out %d\n", RETVAL, 1491 GetErrorString(RETVAL), s->stream.avail_in, s->stream.avail_out); 1492 DispStream(s, "AFTER"); 1493 } 1494 1495 /* Ignore the second of two consecutive flushes: */ 1496 if (availableout == s->stream.avail_out && RETVAL == Z_BUF_ERROR) 1497 RETVAL = Z_OK; 1498 1499 /* deflate has finished flushing only when it hasn't used up 1500 * all the available space in the output buffer: 1501 */ 1502 if (s->stream.avail_out != 0 || RETVAL != Z_OK ) 1503 break; 1504 } 1505 1506 RETVAL = (RETVAL == Z_STREAM_END ? Z_OK : RETVAL) ; 1507 s->last_error = RETVAL ; 1508 1509 s->compressedBytes += cur_length + increment - prefix - s->stream.avail_out ; 1510 1511 if (RETVAL == Z_OK) { 1512 SvPOK_only(output); 1513 SvCUR_set(output, cur_length + increment - s->stream.avail_out) ; 1514 SvSETMAGIC(output); 1515 } 1516 OUTPUT: 1517 RETVAL 1518 1519 1520 DualType 1521 _deflateParams(s, flags, level, strategy, bufsize) 1522 Compress::Raw::Zlib::deflateStream s 1523 int flags 1524 int level 1525 int strategy 1526 uLong bufsize 1527 bool changed = FALSE; 1528 CODE: 1529 /* printf("_deflateParams(Flags %d Level %d Strategy %d Bufsize %d)\n", flags, level, strategy, bufsize); 1530 printf("Before -- Level %d, Strategy %d, Bufsize %d\n", s->Level, s->Strategy, s->bufsize); */ 1531 if (flags & 1 && level != s->Level) { 1532 s->Level = level ; 1533 changed = TRUE; 1534 } 1535 if (flags & 2 && strategy != s->Strategy) { 1536 s->Strategy = strategy ; 1537 changed = TRUE; 1538 } 1539 if (flags & 4) 1540 s->bufsize = bufsize; 1541 if (changed) { 1542 #ifdef SETP_BYTE 1543 s->stream.avail_in = 0; 1544 s->stream.next_out = &(s->deflateParams_out_byte) ; 1545 s->stream.avail_out = 1; 1546 RETVAL = deflateParams(&(s->stream), s->Level, s->Strategy); 1547 s->deflateParams_out_valid = 1548 (RETVAL == Z_OK && s->stream.avail_out == 0) ; 1549 #else 1550 /* printf("Level %d Strategy %d, Prev Len %d\n", 1551 s->Level, s->Strategy, s->deflateParams_out_length); */ 1552 RETVAL = flushParams(s); 1553 #endif 1554 } 1555 else 1556 RETVAL = Z_OK; 1557 OUTPUT: 1558 RETVAL 1559 1560 1561 int 1562 get_Level(s) 1563 Compress::Raw::Zlib::deflateStream s 1564 CODE: 1565 RETVAL = s->Level ; 1566 OUTPUT: 1567 RETVAL 1568 1569 int 1570 get_Strategy(s) 1571 Compress::Raw::Zlib::deflateStream s 1572 CODE: 1573 RETVAL = s->Strategy ; 1574 OUTPUT: 1575 RETVAL 1576 1577 1578 uLong 1579 get_Bufsize(s) 1580 Compress::Raw::Zlib::deflateStream s 1581 CODE: 1582 RETVAL = s->bufsize ; 1583 OUTPUT: 1584 RETVAL 1585 1586 1587 int 1588 status(s) 1589 Compress::Raw::Zlib::deflateStream s 1590 CODE: 1591 RETVAL = s->last_error ; 1592 OUTPUT: 1593 RETVAL 1594 1595 uLong 1596 crc32(s) 1597 Compress::Raw::Zlib::deflateStream s 1598 CODE: 1599 RETVAL = s->crc32 ; 1600 OUTPUT: 1601 RETVAL 1602 1603 uLong 1604 dict_adler(s) 1605 Compress::Raw::Zlib::deflateStream s 1606 CODE: 1607 RETVAL = s->dict_adler ; 1608 OUTPUT: 1609 RETVAL 1610 1611 uLong 1612 adler32(s) 1613 Compress::Raw::Zlib::deflateStream s 1614 CODE: 1615 RETVAL = s->adler32 ; 1616 OUTPUT: 1617 RETVAL 1618 1619 uLong 1620 compressedBytes(s) 1621 Compress::Raw::Zlib::deflateStream s 1622 CODE: 1623 RETVAL = s->compressedBytes; 1624 OUTPUT: 1625 RETVAL 1626 1627 uLong 1628 uncompressedBytes(s) 1629 Compress::Raw::Zlib::deflateStream s 1630 CODE: 1631 RETVAL = s->uncompressedBytes; 1632 OUTPUT: 1633 RETVAL 1634 1635 uLong 1636 total_in(s) 1637 Compress::Raw::Zlib::deflateStream s 1638 CODE: 1639 RETVAL = s->stream.total_in ; 1640 OUTPUT: 1641 RETVAL 1642 1643 uLong 1644 total_out(s) 1645 Compress::Raw::Zlib::deflateStream s 1646 CODE: 1647 RETVAL = s->stream.total_out ; 1648 OUTPUT: 1649 RETVAL 1650 1651 char* 1652 msg(s) 1653 Compress::Raw::Zlib::deflateStream s 1654 CODE: 1655 RETVAL = (char*)s->stream.msg; 1656 OUTPUT: 1657 RETVAL 1658 1659 int 1660 deflateTune(s, good_length, max_lazy, nice_length, max_chain) 1661 Compress::Raw::Zlib::deflateStream s 1662 int good_length 1663 int max_lazy 1664 int nice_length 1665 int max_chain 1666 CODE: 1667 #ifndef AT_LEAST_ZLIB_1_2_2_3 1668 good_length = good_length; max_lazy = max_lazy ; /* Silence -Wall */ 1669 nice_length = nice_length; max_chain = max_chain; /* Silence -Wall */ 1670 croak("deflateTune needs zlib 1.2.2.3 or better"); 1671 #else 1672 RETVAL = CRZ_deflateTune(&(s->stream), good_length, max_lazy, nice_length, max_chain); 1673 #endif 1674 OUTPUT: 1675 RETVAL 1676 1677 1678 MODULE = Compress::Raw::Zlib PACKAGE = Compress::Raw::Zlib::inflateStream 1679 1680 void 1681 DispStream(s, message=NULL) 1682 Compress::Raw::Zlib::inflateStream s 1683 const char * message 1684 1685 DualType 1686 inflateReset(s) 1687 Compress::Raw::Zlib::inflateStream s 1688 CODE: 1689 RETVAL = CRZ_inflateReset(&(s->stream)) ; 1690 if (RETVAL == Z_OK) { 1691 PostInitStream(s, s->flags, s->bufsize, s->WindowBits) ; 1692 } 1693 OUTPUT: 1694 RETVAL 1695 1696 DualType 1697 inflate (s, buf, output, eof=FALSE) 1698 Compress::Raw::Zlib::inflateStream s 1699 SV * buf 1700 SV * output 1701 bool eof 1702 uInt cur_length = 0; 1703 uInt prefix_length = 0; 1704 int increment = 0; 1705 uLong bufinc = NO_INIT 1706 STRLEN na = NO_INIT ; 1707 PREINIT: 1708 #ifdef UTF8_AVAILABLE 1709 bool out_utf8 = FALSE; 1710 #endif 1711 STRLEN origlen; 1712 CODE: 1713 bufinc = s->bufsize; 1714 /* If the buffer is a reference, dereference it */ 1715 buf = deRef(buf, "inflate") ; 1716 1717 if (s->flags & FLAG_CONSUME_INPUT) { 1718 if (SvREADONLY(buf)) 1719 croak("Compress::Raw::Zlib::Inflate::inflate input parameter cannot be read-only when ConsumeInput is specified"); 1720 SvPV_force(buf, na); 1721 } 1722 #ifdef UTF8_AVAILABLE 1723 if (DO_UTF8(buf) && !sv_utf8_downgrade(buf, 1)) 1724 croak("Wide character in Compress::Raw::Zlib::Inflate::inflate input parameter"); 1725 #endif 1726 1727 /* initialise the input buffer */ 1728 s->stream.next_in = (Bytef*)SvPV_nomg(buf, origlen) ; 1729 s->stream.avail_in = origlen ; 1730 1731 /* and retrieve the output buffer */ 1732 output = deRef_l(output, "inflate") ; 1733 #ifdef UTF8_AVAILABLE 1734 if (DO_UTF8(output)) 1735 out_utf8 = TRUE ; 1736 if (DO_UTF8(output) && !sv_utf8_downgrade(output, 1)) 1737 croak("Wide character in Compress::Raw::Zlib::Inflate::inflate output parameter"); 1738 #endif 1739 if((s->flags & FLAG_APPEND) == FLAG_APPEND) { 1740 SvOOK_off(output); 1741 } else { 1742 SvCUR_set(output, 0); 1743 } 1744 1745 /* Assume no output buffer - the code below will update if there is any available */ 1746 s->stream.avail_out = 0; 1747 1748 1749 if (SvLEN(output)) { 1750 prefix_length = cur_length = SvCUR(output) ; 1751 1752 if (s->flags & FLAG_LIMIT_OUTPUT && SvLEN(output) - cur_length - 1 < bufinc) 1753 { 1754 Sv_Grow(output, bufinc + cur_length + 1) ; 1755 } 1756 1757 /* Only setup the stream output pointers if there is spare 1758 capacity in the outout SV 1759 */ 1760 if (SvLEN(output) > cur_length + 1) 1761 { 1762 s->stream.next_out = (Bytef*) SvPV_nomg_nolen(output) + cur_length; 1763 increment = SvLEN(output) - cur_length - 1; 1764 s->stream.avail_out = increment; 1765 } 1766 } 1767 1768 1769 s->bytesInflated = 0; 1770 1771 RETVAL = Z_OK; 1772 1773 while (RETVAL == Z_OK) { 1774 if (s->stream.avail_out == 0) { 1775 /* out of space in the output buffer so make it bigger */ 1776 s->stream.next_out = (Bytef*) Sv_Grow(output, SvLEN(output) + bufinc +1) ; 1777 cur_length += increment ; 1778 s->stream.next_out += cur_length ; 1779 increment = bufinc ; 1780 s->stream.avail_out = increment; 1781 bufinc *= 2 ; 1782 } 1783 1784 /* printf("INFLATE Availl In %d, Out %d\n", s->stream.avail_in, 1785 s->stream.avail_out); 1786 DispStream(s, "BEFORE"); 1787 Perl_sv_dump(output); */ 1788 RETVAL = CRZ_inflate(&(s->stream), Z_SYNC_FLUSH); 1789 /* printf("INFLATE returned %d %s, avail in %d, out %d\n", RETVAL, 1790 GetErrorString(RETVAL), s->stream.avail_in, s->stream.avail_out); */ 1791 1792 1793 if (RETVAL == Z_NEED_DICT && s->dictionary) { 1794 STRLEN dlen; 1795 const Bytef* b = (const Bytef*)SvPV(s->dictionary, dlen) ; 1796 s->dict_adler = s->stream.adler ; 1797 RETVAL = CRZ_inflateSetDictionary(&(s->stream), 1798 b, dlen); 1799 if (RETVAL == Z_OK) 1800 continue; 1801 } 1802 1803 if (s->flags & FLAG_LIMIT_OUTPUT && 1804 (RETVAL == Z_OK || RETVAL == Z_BUF_ERROR )) { 1805 if (s->stream.avail_out == 0) 1806 RETVAL = Z_BUF_ERROR; 1807 break; 1808 } 1809 if (s->flags & FLAG_LIMIT_OUTPUT && 1810 (RETVAL == Z_OK || RETVAL == Z_BUF_ERROR )) 1811 break; 1812 1813 if (RETVAL == Z_STREAM_ERROR || RETVAL == Z_MEM_ERROR || 1814 RETVAL == Z_DATA_ERROR || RETVAL == Z_STREAM_END ) 1815 break ; 1816 1817 if (RETVAL == Z_BUF_ERROR) { 1818 if (s->stream.avail_out == 0) 1819 continue ; 1820 if (s->stream.avail_in == 0) { 1821 RETVAL = Z_OK ; 1822 break ; 1823 } 1824 } 1825 } 1826 #ifdef NEED_DUMMY_BYTE_AT_END 1827 if (eof && RETVAL == Z_OK && (s->flags & FLAG_LIMIT_OUTPUT) == 0) { 1828 Bytef* nextIn = (Bytef*)s->stream.next_in; 1829 uInt availIn = s->stream.avail_in; 1830 s->stream.next_in = (Bytef*) " "; 1831 s->stream.avail_in = 1; 1832 if (s->stream.avail_out == 0) { 1833 /* out of space in the output buffer so make it bigger */ 1834 s->stream.next_out = Sv_Grow(output, SvLEN(output) + bufinc) ; 1835 cur_length += increment ; 1836 s->stream.next_out += cur_length ; 1837 increment = bufinc ; 1838 s->stream.avail_out = increment; 1839 bufinc *= 2 ; 1840 } 1841 RETVAL = CRZ_inflate(&(s->stream), Z_SYNC_FLUSH); 1842 s->stream.next_in = nextIn ; 1843 s->stream.avail_in = availIn ; 1844 } 1845 #else 1846 PERL_UNUSED_VAR(eof); 1847 #endif 1848 1849 s->last_error = RETVAL ; 1850 if (RETVAL == Z_OK || RETVAL == Z_STREAM_END || RETVAL == Z_BUF_ERROR || RETVAL == Z_DATA_ERROR) { 1851 unsigned in ; 1852 1853 s->bytesInflated = cur_length + increment - s->stream.avail_out - prefix_length; 1854 s->uncompressedBytes += s->bytesInflated ; 1855 s->compressedBytes += origlen - s->stream.avail_in ; 1856 1857 SvPOK_only(output); 1858 SvCUR_set(output, prefix_length + s->bytesInflated) ; 1859 *SvEND(output) = '\0'; 1860 #ifdef UTF8_AVAILABLE 1861 if (out_utf8) 1862 sv_utf8_upgrade(output); 1863 #endif 1864 SvSETMAGIC(output); 1865 1866 if (s->flags & FLAG_CRC32 ) 1867 s->crc32 = CRZ_crc32(s->crc32, 1868 (const Bytef*)SvPVX(output)+prefix_length, 1869 SvCUR(output)-prefix_length) ; 1870 1871 if (s->flags & FLAG_ADLER32) 1872 s->adler32 = CRZ_adler32(s->adler32, 1873 (const Bytef*)SvPVX(output)+prefix_length, 1874 SvCUR(output)-prefix_length) ; 1875 1876 /* fix the input buffer */ 1877 if (s->flags & FLAG_CONSUME_INPUT || s->flags & FLAG_LIMIT_OUTPUT) { 1878 in = s->stream.avail_in ; 1879 SvCUR_set(buf, in) ; 1880 if (in) 1881 Move(s->stream.next_in, SvPVX(buf), in, char) ; 1882 *SvEND(buf) = '\0'; 1883 SvSETMAGIC(buf); 1884 } 1885 1886 } 1887 OUTPUT: 1888 RETVAL 1889 1890 uLong 1891 inflateCount(s) 1892 Compress::Raw::Zlib::inflateStream s 1893 CODE: 1894 RETVAL = s->bytesInflated; 1895 OUTPUT: 1896 RETVAL 1897 1898 uLong 1899 compressedBytes(s) 1900 Compress::Raw::Zlib::inflateStream s 1901 CODE: 1902 RETVAL = s->compressedBytes; 1903 OUTPUT: 1904 RETVAL 1905 1906 uLong 1907 uncompressedBytes(s) 1908 Compress::Raw::Zlib::inflateStream s 1909 CODE: 1910 RETVAL = s->uncompressedBytes; 1911 OUTPUT: 1912 RETVAL 1913 1914 1915 DualType 1916 inflateSync (s, buf) 1917 Compress::Raw::Zlib::inflateStream s 1918 SV * buf 1919 CODE: 1920 1921 /* If the buffer is a reference, dereference it */ 1922 buf = deRef(buf, "inflateSync") ; 1923 #ifdef UTF8_AVAILABLE 1924 if (DO_UTF8(buf) && !sv_utf8_downgrade(buf, 1)) 1925 croak("Wide character in Compress::Raw::Zlib::Inflate::inflateSync"); 1926 #endif 1927 1928 /* initialise the input buffer */ 1929 s->stream.next_in = (Bytef*)SvPV_force_nomg_nolen(buf) ; 1930 s->stream.avail_in = SvCUR(buf) ; 1931 1932 /* inflateSync doesn't create any output */ 1933 s->stream.next_out = (Bytef*) NULL; 1934 s->stream.avail_out = 0; 1935 1936 RETVAL = CRZ_inflateSync(&(s->stream)); 1937 s->last_error = RETVAL ; 1938 1939 /* fix the input buffer */ 1940 { 1941 unsigned in = s->stream.avail_in ; 1942 SvCUR_set(buf, in) ; 1943 if (in) 1944 Move(s->stream.next_in, SvPVX(buf), in, char) ; 1945 *SvEND(buf) = '\0'; 1946 SvSETMAGIC(buf); 1947 } 1948 OUTPUT: 1949 RETVAL 1950 1951 void 1952 DESTROY(s) 1953 Compress::Raw::Zlib::inflateStream s 1954 CODE: 1955 CRZ_inflateEnd(&s->stream) ; 1956 if (s->dictionary) 1957 SvREFCNT_dec(s->dictionary) ; 1958 #ifndef SETP_BYTE 1959 if (s->deflateParams_out_buffer) 1960 Safefree(s->deflateParams_out_buffer); 1961 #endif 1962 #ifdef MAGIC_APPEND 1963 if (s->window) 1964 Safefree(s->window); 1965 #endif 1966 Safefree(s) ; 1967 1968 1969 uLong 1970 status(s) 1971 Compress::Raw::Zlib::inflateStream s 1972 CODE: 1973 RETVAL = s->last_error ; 1974 OUTPUT: 1975 RETVAL 1976 1977 uLong 1978 crc32(s) 1979 Compress::Raw::Zlib::inflateStream s 1980 CODE: 1981 RETVAL = s->crc32 ; 1982 OUTPUT: 1983 RETVAL 1984 1985 uLong 1986 dict_adler(s) 1987 Compress::Raw::Zlib::inflateStream s 1988 CODE: 1989 RETVAL = s->dict_adler ; 1990 OUTPUT: 1991 RETVAL 1992 1993 uLong 1994 total_in(s) 1995 Compress::Raw::Zlib::inflateStream s 1996 CODE: 1997 RETVAL = s->stream.total_in ; 1998 OUTPUT: 1999 RETVAL 2000 2001 uLong 2002 adler32(s) 2003 Compress::Raw::Zlib::inflateStream s 2004 CODE: 2005 RETVAL = s->adler32 ; 2006 OUTPUT: 2007 RETVAL 2008 2009 uLong 2010 total_out(s) 2011 Compress::Raw::Zlib::inflateStream s 2012 CODE: 2013 RETVAL = s->stream.total_out ; 2014 OUTPUT: 2015 RETVAL 2016 2017 char* 2018 msg(s) 2019 Compress::Raw::Zlib::inflateStream s 2020 CODE: 2021 RETVAL = (char*)s->stream.msg; 2022 OUTPUT: 2023 RETVAL 2024 2025 2026 uLong 2027 get_Bufsize(s) 2028 Compress::Raw::Zlib::inflateStream s 2029 CODE: 2030 RETVAL = s->bufsize ; 2031 OUTPUT: 2032 RETVAL 2033 2034 bool 2035 set_Append(s, mode) 2036 Compress::Raw::Zlib::inflateStream s 2037 bool mode 2038 CODE: 2039 RETVAL = ((s->flags & FLAG_APPEND) == FLAG_APPEND); 2040 if (mode) 2041 s->flags |= FLAG_APPEND ; 2042 else 2043 s->flags &= ~FLAG_APPEND ; 2044 OUTPUT: 2045 RETVAL 2046 2047 MODULE = Compress::Raw::Zlib PACKAGE = Compress::Raw::Zlib::inflateScanStream 2048 2049 void 2050 DESTROY(s) 2051 Compress::Raw::Zlib::inflateScanStream s 2052 CODE: 2053 CRZ_inflateEnd(&s->stream) ; 2054 if (s->dictionary) 2055 SvREFCNT_dec(s->dictionary) ; 2056 #ifndef SETP_BYTE 2057 if (s->deflateParams_out_buffer) 2058 Safefree(s->deflateParams_out_buffer); 2059 #endif 2060 #ifdef MAGIC_APPEND 2061 if (s->window) 2062 Safefree(s->window); 2063 #endif 2064 Safefree(s) ; 2065 2066 void 2067 DispStream(s, message=NULL) 2068 Compress::Raw::Zlib::inflateScanStream s 2069 const char * message 2070 2071 DualType 2072 inflateReset(s) 2073 Compress::Raw::Zlib::inflateScanStream s 2074 CODE: 2075 RETVAL = CRZ_inflateReset(&(s->stream)) ; 2076 if (RETVAL == Z_OK) { 2077 PostInitStream(s, s->flags, s->bufsize, s->WindowBits) ; 2078 } 2079 OUTPUT: 2080 RETVAL 2081 2082 DualType 2083 scan(s, buf, out=NULL, eof=FALSE) 2084 Compress::Raw::Zlib::inflateScanStream s 2085 SV * buf 2086 SV * out 2087 bool eof 2088 bool eof_mode = FALSE; 2089 int start_len = NO_INIT 2090 CODE: 2091 PERL_UNUSED_VAR(out); 2092 PERL_UNUSED_VAR(eof); 2093 /* If the input buffer is a reference, dereference it */ 2094 #ifndef MAGIC_APPEND 2095 buf = buf; 2096 croak("scan needs zlib 1.2.1 or better"); 2097 #else 2098 buf = deRef(buf, "inflateScan") ; 2099 #ifdef UTF8_AVAILABLE 2100 if (DO_UTF8(buf) && !sv_utf8_downgrade(buf, 1)) 2101 croak("Wide character in Compress::Raw::Zlib::InflateScan::scan input parameter"); 2102 #endif 2103 /* initialise the input buffer */ 2104 s->stream.next_in = (Bytef*)SvPV_force_nomg_nolen(buf) ; 2105 s->stream.avail_in = SvCUR(buf) ; 2106 start_len = s->stream.avail_in ; 2107 s->bytesInflated = 0 ; 2108 do 2109 { 2110 if (s->stream.avail_in == 0) { 2111 RETVAL = Z_OK ; 2112 break ; 2113 } 2114 2115 /* set up output to next available section of sliding window */ 2116 s->stream.avail_out = WINDOW_SIZE - s->window_have; 2117 s->stream.next_out = s->window + s->window_have; 2118 2119 /* DispStream(s, "before inflate\n"); */ 2120 2121 /* inflate and check for errors */ 2122 RETVAL = CRZ_inflate(&(s->stream), Z_BLOCK); 2123 2124 if (start_len > 1 && ! eof_mode) 2125 s->window_lastByte = *(s->stream.next_in - 1 ) ; 2126 2127 if (RETVAL == Z_STREAM_ERROR || RETVAL == Z_MEM_ERROR || 2128 RETVAL == Z_DATA_ERROR ) 2129 break ; 2130 2131 if (s->flags & FLAG_CRC32 ) 2132 s->crc32 = CRZ_crc32(s->crc32, s->window + s->window_have, 2133 WINDOW_SIZE - s->window_have - s->stream.avail_out); 2134 2135 if (s->flags & FLAG_ADLER32) 2136 s->adler32 = CRZ_adler32(s->adler32, s->window + s->window_have, 2137 WINDOW_SIZE - s->window_have - s->stream.avail_out); 2138 2139 s->uncompressedBytes = 2140 s->bytesInflated += WINDOW_SIZE - s->window_have - s->stream.avail_out; 2141 2142 if (s->stream.avail_out) 2143 s->window_have = WINDOW_SIZE - s->stream.avail_out; 2144 else { 2145 s->window_have = 0; 2146 s->window_full = 1; 2147 } 2148 2149 /* process end of block */ 2150 if (s->stream.data_type & 128) { 2151 if (s->stream.data_type & 64) { 2152 s->window_left = s->stream.data_type & 0x1f; 2153 } 2154 else { 2155 s->window_lastbit = s->stream.data_type & 0x1f; 2156 s->lastBlockOffset = s->stream.total_in; 2157 } 2158 } 2159 2160 } while (RETVAL != Z_STREAM_END); 2161 2162 s->last_error = RETVAL ; 2163 s->window_lastoff = s->stream.total_in ; 2164 s->compressedBytes += SvCUR(buf) - s->stream.avail_in ; 2165 2166 if (RETVAL == Z_STREAM_END) 2167 { 2168 s->matchedEndBlock = 1 ; 2169 2170 /* save the location of the end of the compressed data */ 2171 s->window_end = SvCUR(buf) - s->stream.avail_in - 1 ; 2172 s->window_endOffset = s->stream.total_in ; 2173 if (s->window_left) 2174 { 2175 -- s->window_endOffset ; 2176 } 2177 2178 /* if window wrapped, build dictionary from window by rotating */ 2179 if (s->window_full) { 2180 rotate(s->window, WINDOW_SIZE, s->window_have); 2181 s->window_have = WINDOW_SIZE; 2182 } 2183 2184 /* if (s->flags & FLAG_CONSUME_INPUT) { */ 2185 if (1) { 2186 unsigned in = s->stream.avail_in ; 2187 SvCUR_set(buf, in) ; 2188 if (in) 2189 Move(s->stream.next_in, SvPVX(buf), in, char) ; 2190 *SvEND(buf) = '\0'; 2191 SvSETMAGIC(buf); 2192 } 2193 } 2194 #endif 2195 OUTPUT: 2196 RETVAL 2197 2198 2199 uLong 2200 getEndOffset(s) 2201 Compress::Raw::Zlib::inflateScanStream s 2202 CODE: 2203 #ifndef MAGIC_APPEND 2204 croak("getEndOffset needs zlib 1.2.1 or better"); 2205 #else 2206 RETVAL = s->window_endOffset; 2207 #endif 2208 OUTPUT: 2209 RETVAL 2210 2211 uLong 2212 inflateCount(s) 2213 Compress::Raw::Zlib::inflateScanStream s 2214 CODE: 2215 #ifndef MAGIC_APPEND 2216 croak("inflateCount needs zlib 1.2.1 or better"); 2217 #else 2218 RETVAL = s->bytesInflated; 2219 #endif 2220 OUTPUT: 2221 RETVAL 2222 2223 uLong 2224 compressedBytes(s) 2225 Compress::Raw::Zlib::inflateScanStream s 2226 CODE: 2227 RETVAL = s->compressedBytes; 2228 OUTPUT: 2229 RETVAL 2230 2231 uLong 2232 uncompressedBytes(s) 2233 Compress::Raw::Zlib::inflateScanStream s 2234 CODE: 2235 RETVAL = s->uncompressedBytes; 2236 OUTPUT: 2237 RETVAL 2238 2239 2240 uLong 2241 getLastBlockOffset(s) 2242 Compress::Raw::Zlib::inflateScanStream s 2243 CODE: 2244 #ifndef MAGIC_APPEND 2245 croak("getLastBlockOffset needs zlib 1.2.1 or better"); 2246 #else 2247 RETVAL = s->lastBlockOffset - (s->window_lastbit != 0); 2248 #endif 2249 OUTPUT: 2250 RETVAL 2251 2252 uLong 2253 getLastBufferOffset(s) 2254 Compress::Raw::Zlib::inflateScanStream s 2255 CODE: 2256 #ifndef MAGIC_APPEND 2257 croak("getLastBufferOffset needs zlib 1.2.1 or better"); 2258 #else 2259 RETVAL = s->window_lastoff; 2260 #endif 2261 OUTPUT: 2262 RETVAL 2263 2264 void 2265 resetLastBlockByte(s, byte) 2266 Compress::Raw::Zlib::inflateScanStream s 2267 unsigned char* byte 2268 CODE: 2269 #ifndef MAGIC_APPEND 2270 croak("resetLastBlockByte needs zlib 1.2.1 or better"); 2271 #else 2272 if (byte != NULL) 2273 *byte = *byte ^ (1 << ((8 - s->window_lastbit) & 7)); 2274 #endif 2275 2276 2277 void 2278 _createDeflateStream(inf_s, flags,level, method, windowBits, memLevel, strategy, bufsize) 2279 Compress::Raw::Zlib::inflateScanStream inf_s 2280 int flags 2281 int level 2282 int method 2283 int windowBits 2284 int memLevel 2285 int strategy 2286 uLong bufsize 2287 PPCODE: 2288 { 2289 #ifndef MAGIC_APPEND 2290 flags = flags; 2291 level = level ; 2292 method = method; 2293 windowBits = windowBits; 2294 memLevel = memLevel; 2295 strategy = strategy; 2296 bufsize= bufsize; 2297 croak("_createDeflateStream needs zlib 1.2.1 or better"); 2298 #else 2299 int err ; 2300 deflateStream s ; 2301 2302 if (trace) 2303 warn("in _createDeflateStream(level=%d, method=%d, windowBits=%d, memLevel=%d, strategy=%d, bufsize=%lu\n", 2304 level, method, windowBits, memLevel, strategy, bufsize) ; 2305 if ((s = InitStream() )) { 2306 2307 s->Level = level; 2308 s->Method = method; 2309 s->WindowBits = windowBits; 2310 s->MemLevel = memLevel; 2311 s->Strategy = strategy; 2312 2313 err = CRZ_deflateInit2(&(s->stream), level, 2314 method, windowBits, memLevel, strategy); 2315 2316 if (err == Z_OK) { 2317 err = CRZ_deflateSetDictionary(&(s->stream), inf_s->window, inf_s->window_have); 2318 s->dict_adler = s->stream.adler ; 2319 } 2320 2321 if (err != Z_OK) { 2322 Safefree(s) ; 2323 s = NULL ; 2324 } 2325 else { 2326 PostInitStream(s, flags, bufsize, windowBits) ; 2327 s->crc32 = inf_s->crc32; 2328 s->adler32 = inf_s->adler32; 2329 s->stream.adler = inf_s->stream.adler ; 2330 /* s->stream.total_out = inf_s->bytesInflated ; */ 2331 s->stream.total_in = inf_s->stream.total_out ; 2332 if (inf_s->window_left) { 2333 /* printf("** window_left %d, window_lastByte %d\n", inf_s->window_left, inf_s->window_lastByte); */ 2334 CRZ_deflatePrime(&(s->stream), 8 - inf_s->window_left, inf_s->window_lastByte); 2335 } 2336 } 2337 } 2338 else 2339 err = Z_MEM_ERROR ; 2340 2341 XPUSHs(sv_setref_pv(sv_newmortal(), 2342 "Compress::Raw::Zlib::deflateStream", (void*)s)); 2343 if (GIMME_V == G_ARRAY) { 2344 SV * sv = sv_2mortal(newSViv(err)) ; 2345 setDUALstatus(sv, err); 2346 XPUSHs(sv) ; 2347 } 2348 #endif 2349 } 2350 2351 DualType 2352 status(s) 2353 Compress::Raw::Zlib::inflateScanStream s 2354 CODE: 2355 RETVAL = s->last_error ; 2356 OUTPUT: 2357 RETVAL 2358 2359 uLong 2360 crc32(s) 2361 Compress::Raw::Zlib::inflateScanStream s 2362 CODE: 2363 RETVAL = s->crc32 ; 2364 OUTPUT: 2365 RETVAL 2366 2367 2368 uLong 2369 adler32(s) 2370 Compress::Raw::Zlib::inflateScanStream s 2371 CODE: 2372 RETVAL = s->adler32 ; 2373 OUTPUT: 2374 RETVAL 2375