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