1 /* Filename: Zlib.xs 2 * Author : Paul Marquess, 3 * Created : 30 January 2005 4 * Version : 1.34 5 153 * 6 * Copyright (c) 1995-2005 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 153 * 10 153 */ 11 153 12 /* Part of this code is based on the file gzio.c */ 13 153 14 /* gzio.c -- IO on .gz files 15 * Copyright (C) 1995 Jean-loup Gailly. 16 * For conditions of distribution and use, see copyright notice in zlib.h 17 */ 18 19 20 153 21 #include "EXTERN.h" 22 #include "perl.h" 23 153 #include "XSUB.h" 24 25 ###### #include 26 ###### 27 ###### #ifndef PERL_VERSION 28 #include "patchlevel.h" 29 ###### #define PERL_REVISION 5 30 #define PERL_VERSION PATCHLEVEL 31 ###### #define PERL_SUBVERSION SUBVERSION 32 ###### #endif 33 34 148 #if PERL_REVISION == 5 && (PERL_VERSION < 4 || (PERL_VERSION == 4 && PERL_SUBVERSION <= 75 )) 35 148 36 148 # define PL_sv_undef sv_undef 37 148 # define PL_na na 38 # define PL_curcop curcop 39 # define PL_compiling compiling 40 41 #endif 42 43 #ifndef newSVuv 44 # define newSVuv newSViv 45 #endif 46 47 typedef struct di_stream { 48 z_stream stream; 49 uLong bufsize; 50 uLong bufinc; 51 5 SV * dictionary ; 52 5 uLong dict_adler ; 53 5 bool deflateParams_out_valid ; 54 5 Bytef deflateParams_out_byte; 55 int Level; 56 int Method; 57 int WindowBits; 58 int MemLevel; 59 int Strategy; 60 } di_stream; 61 62 typedef di_stream * deflateStream ; 63 typedef di_stream * Compress__Zlib__deflateStream ; 64 typedef di_stream * inflateStream ; 65 typedef di_stream * Compress__Zlib__inflateStream ; 66 67 /* typedef gzFile Compress__Zlib__gzFile ; */ 68 typedef struct gzType { 69 gzFile gz ; 70 SV * buffer ; 71 uLong offset ; 72 bool closed ; 73 } gzType ; 74 75 typedef gzType* Compress__Zlib__gzFile ; 76 77 78 79 #define GZERRNO "Compress::Zlib::gzerrno" 80 81 #define ZMALLOC(to, typ) ((to = (typ *)safemalloc(sizeof(typ))), \ 82 Zero(to,1,typ)) 83 ###### 84 #define adlerInitial adler32(0L, Z_NULL, 0) 85 #define crcInitial crc32(0L, Z_NULL, 0) 86 ###### 87 #if 1 88 static char *my_z_errmsg[] = { 89 "need dictionary", /* Z_NEED_DICT 2 */ 90 "stream end", /* Z_STREAM_END 1 */ 91 "", /* Z_OK 0 */ 92 "file error", /* Z_ERRNO (-1) */ 93 "stream error", /* Z_STREAM_ERROR (-2) */ 94 "data error", /* Z_DATA_ERROR (-3) */ 95 "insufficient memory", /* Z_MEM_ERROR (-4) */ 96 "buffer error", /* Z_BUF_ERROR (-5) */ 97 "incompatible version",/* Z_VERSION_ERROR(-6) */ 98 ""}; 99 #endif 100 101 102 static int trace = 0 ; 103 104 static void 105 #ifdef CAN_PROTOTYPE 106 SetGzErrorNo(int error_no) 107 #else 108 SetGzErrorNo(error_no) 109 int error_no ; 110 #endif 111 571 { 112 571 char * errstr ; 113 571 SV * gzerror_sv = perl_get_sv(GZERRNO, FALSE) ; 114 115 571 if (error_no == Z_ERRNO) { 116 3 error_no = errno ; 117 3 errstr = Strerror(errno) ; 118 } 119 else 120 /* errstr = gzerror(fil, &error_no) ; */ 121 568 errstr = (char*) my_z_errmsg[2 - error_no]; 122 123 571 if (SvIV(gzerror_sv) != error_no) { 124 76 sv_setiv(gzerror_sv, error_no) ; 125 76 sv_setpv(gzerror_sv, errstr) ; 126 76 SvIOK_on(gzerror_sv) ; 127 } 128 129 } 130 131 static void 132 #ifdef CAN_PROTOTYPE 133 SetGzError(gzFile file) 134 #else 135 SetGzError(file) 136 gzFile file ; 137 #endif 138 442 { 139 442 int error_no ; 140 141 442 (void)gzerror(file, &error_no) ; 142 442 SetGzErrorNo(error_no) ; 143 } 144 145 static void 146 #ifdef CAN_PROTOTYPE 147 DispHex(void * ptr, int length) 148 #else 149 DispHex(ptr, length) 150 void * ptr; 151 int length; 152 #endif 153 ###### { 154 ###### char * p = (char*)ptr; 155 ###### int i; 156 ###### for (i = 0; i < length; ++i) { 157 ###### printf(" %02x", 0xFF & *(p+i)); 158 } 159 } 160 161 162 static void 163 #ifdef CAN_PROTOTYPE 164 DispStream(di_stream * s, char * message) 165 #else 166 DispStream(s, message) 167 di_stream * s; 168 char * message; 169 #endif 170 ###### { 171 172 #if 0 173 if (! trace) 174 return ; 175 #endif 176 177 ###### printf("DispStream 0x%p - %s \n", s, message) ; 178 179 ###### if (!s) { 180 ###### printf(" stream pointer is NULL\n"); 181 } 182 else { 183 ###### printf(" stream 0x%p\n", &(s->stream)); 184 ###### printf(" zalloc 0x%p\n", s->stream.zalloc); 185 ###### printf(" zfree 0x%p\n", s->stream.zfree); 186 ###### printf(" opaque 0x%p\n", s->stream.opaque); 187 ###### if (s->stream.msg) 188 ###### printf(" msg %s\n", s->stream.msg); 189 else 190 ###### printf(" msg \n"); 191 ###### printf(" next_in 0x%p", s->stream.next_in); 192 ###### if (s->stream.next_in) { 193 ###### printf(" =>"); 194 ###### DispHex(s->stream.next_in, 4); 195 } 196 ###### printf("\n"); 197 198 ###### printf(" next_out 0x%p", s->stream.next_out); 199 ###### if (s->stream.next_out){ 200 ###### printf(" =>"); 201 ###### DispHex(s->stream.next_out, 4); 202 } 203 ###### printf("\n"); 204 205 ###### printf(" avail_in %ld\n", s->stream.avail_in); 206 ###### printf(" avail_out %ld\n", s->stream.avail_out); 207 ###### printf(" total_in %ld\n", s->stream.total_in); 208 ###### printf(" total_out %ld\n", s->stream.total_out); 209 ###### printf(" adler 0x%lx\n", s->stream.adler); 210 ###### printf(" reserved 0x%lx\n", s->stream.reserved); 211 ###### printf(" bufsize %ld\n", s->bufsize); 212 ###### printf(" dictionary 0x%p\n", s->dictionary); 213 ###### printf(" dict_adler 0x%ld\n", s->dict_adler); 214 ###### printf("\n"); 215 216 } 217 } 218 219 220 static di_stream * 221 #ifdef CAN_PROTOTYPE 222 InitStream(uLong bufsize) 223 #else 224 InitStream(bufsize) 225 uLong bufsize ; 226 #endif 227 78 { 228 78 di_stream *s ; 229 230 78 ZMALLOC(s, di_stream) ; 231 232 78 if (s) { 233 78 s->bufsize = bufsize ; 234 78 s->bufinc = bufsize ; 235 } 236 237 78 return s ; 238 239 } 240 241 #define SIZE 4096 242 243 static int 244 #ifdef CAN_PROTOTYPE 245 gzreadline(Compress__Zlib__gzFile file, SV * output) 246 #else 247 gzreadline(file, output) 248 Compress__Zlib__gzFile file ; 249 SV * output ; 250 #endif 251 40 { 252 253 40 SV * store = file->buffer ; 254 40 char *nl = "\n"; 255 40 char *p; 256 40 char *out_ptr = SvPVX(store) ; 257 57 int n; 258 259 57 while (1) { 260 261 /* anything left from last time */ 262 57 if ((n = SvCUR(store))) { 263 264 41 out_ptr = SvPVX(store) + file->offset ; 265 41 if ((p = ninstr(out_ptr, out_ptr + n - 1, nl, nl))) { 266 /* if (rschar != 0777 && */ 267 /* p = ninstr(out_ptr, out_ptr + n - 1, rs, rs+rslen-1)) { */ 268 269 32 sv_catpvn(output, out_ptr, p - out_ptr + 1); 270 271 32 file->offset += (p - out_ptr + 1) ; 272 32 n = n - (p - out_ptr + 1); 273 32 SvCUR_set(store, n) ; 274 32 return SvCUR(output); 275 } 276 else /* no EOL, so append the complete buffer */ 277 9 sv_catpvn(output, out_ptr, n); 278 279 } 280 281 282 25 SvCUR_set(store, 0) ; 283 25 file->offset = 0 ; 284 25 out_ptr = SvPVX(store) ; 285 286 25 n = gzread(file->gz, out_ptr, SIZE) ; 287 288 25 if (n <= 0) 289 /* Either EOF or an error */ 290 /* so return what we have so far else signal eof */ 291 8 return (SvCUR(output)>0) ? SvCUR(output) : n ; 292 293 17 SvCUR_set(store, n) ; 294 } 295 } 296 297 static SV* 298 #ifdef CAN_PROTOTYPE 299 deRef(SV * sv, char * string) 300 #else 301 deRef(sv, string) 302 SV * sv ; 303 char * string; 304 #endif 305 473 { 306 473 if (SvROK(sv)) { 307 60 sv = SvRV(sv) ; 308 60 switch(SvTYPE(sv)) { 309 case SVt_PVAV: 310 case SVt_PVHV: 311 case SVt_PVCV: 312 ###### croak("%s: buffer parameter is not a SCALAR reference", string); 313 } 314 60 if (SvROK(sv)) 315 ###### croak("%s: buffer parameter is a reference to a reference", string) ; 316 } 317 318 473 if (!SvOK(sv)) { 319 1 sv = newSVpv("", 0); 320 } 321 473 return sv ; 322 } 323 324 #include "constants.h" 325 326 MODULE = Compress::Zlib PACKAGE = Compress::Zlib PREFIX = Zip_ 327 328 REQUIRE: 1.924 329 PROTOTYPES: DISABLE 330 331 INCLUDE: constants.xs 332 333 BOOT: 334 /* Check this version of zlib is == 1 */ 335 25 if (zlibVersion()[0] != '1') 336 ###### croak("Compress::Zlib needs zlib version 1.x\n") ; 337 338 { 339 /* Create the $gzerror scalar */ 340 25 SV * gzerror_sv = perl_get_sv(GZERRNO, GV_ADDMULTI) ; 341 25 sv_setiv(gzerror_sv, 0) ; 342 25 sv_setpv(gzerror_sv, "") ; 343 25 SvIOK_on(gzerror_sv) ; 344 } 345 346 347 #define Zip_zlib_version() (char*)zlib_version 348 char* 349 Zip_zlib_version() 350 351 352 void 353 DispStream(s, message=NULL) 354 Compress::Zlib::inflateStream s 355 char * message 356 357 Compress::Zlib::gzFile 358 gzopen_(path, mode) 359 char * path 360 char * mode 361 CODE: 362 76 gzFile gz ; 363 76 gz = gzopen(path, mode) ; 364 76 if (gz) { 365 73 ZMALLOC(RETVAL, gzType) ; 366 73 RETVAL->buffer = newSV(SIZE) ; 367 73 SvPOK_only(RETVAL->buffer) ; 368 73 SvCUR_set(RETVAL->buffer, 0) ; 369 73 RETVAL->offset = 0 ; 370 73 RETVAL->gz = gz ; 371 73 RETVAL->closed = FALSE ; 372 73 SetGzErrorNo(0) ; 373 } 374 else { 375 3 RETVAL = NULL ; 376 3 SetGzErrorNo(errno ? Z_ERRNO : Z_MEM_ERROR) ; 377 } 378 OUTPUT: 379 RETVAL 380 381 382 Compress::Zlib::gzFile 383 gzdopen_(fh, mode, offset) 384 int fh 385 char * mode 386 long offset 387 CODE: 388 5 gzFile gz ; 389 5 if (offset != -1) 390 5 lseek(fh, offset, 0) ; 391 5 gz = gzdopen(fh, mode) ; 392 5 if (gz) { 393 5 ZMALLOC(RETVAL, gzType) ; 394 5 RETVAL->buffer = newSV(SIZE) ; 395 5 SvPOK_only(RETVAL->buffer) ; 396 5 SvCUR_set(RETVAL->buffer, 0) ; 397 5 RETVAL->offset = 0 ; 398 5 RETVAL->gz = gz ; 399 5 RETVAL->closed = FALSE ; 400 5 SetGzErrorNo(0) ; 401 } 402 else { 403 ###### RETVAL = NULL ; 404 ###### SetGzErrorNo(errno ? Z_ERRNO : Z_MEM_ERROR) ; 405 } 406 OUTPUT: 407 RETVAL 408 409 410 MODULE = Compress::Zlib PACKAGE = Compress::Zlib::gzFile PREFIX = Zip_ 411 412 #define Zip_gzread(file, buf, len) gzread(file->gz, bufp, len) 413 414 int 415 Zip_gzread(file, buf, len=4096) 416 Compress::Zlib::gzFile file 417 unsigned len 418 SV * buf 419 voidp bufp = NO_INIT 420 uLong bufsize = 0 ; 421 int RETVAL = 0 ; 422 CODE: 423 329 if (SvREADONLY(buf) && PL_curcop != &PL_compiling) 424 ###### croak("gzread: buffer parameter is read-only"); 425 329 SvUPGRADE(buf, SVt_PV); 426 329 SvPOK_only(buf); 427 329 SvCUR_set(buf, 0); 428 /* any left over from gzreadline ? */ 429 329 if ((bufsize = SvCUR(file->buffer)) > 0) { 430 3 uLong movesize ; 431 432 3 if (bufsize < len) { 433 1 movesize = bufsize ; 434 1 len -= movesize ; 435 } 436 else { 437 2 movesize = len ; 438 2 len = 0 ; 439 } 440 3 RETVAL = movesize ; 441 442 3 sv_catpvn(buf, SvPVX(file->buffer) + file->offset, movesize); 443 444 3 file->offset += movesize ; 445 3 SvCUR_set(file->buffer, bufsize - movesize) ; 446 } 447 448 329 if (len) { 449 325 bufp = (Byte*)SvGROW(buf, bufsize+len+1); 450 325 RETVAL = gzread(file->gz, ((Bytef*)bufp)+bufsize, len) ; 451 325 SetGzError(file->gz) ; 452 325 if (RETVAL >= 0) { 453 325 RETVAL += bufsize ; 454 325 SvCUR_set(buf, RETVAL) ; 455 325 *SvEND(buf) = '\0'; 456 } 457 } 458 OUTPUT: 459 RETVAL 460 buf 461 462 int 463 gzreadline(file, buf) 464 Compress::Zlib::gzFile file 465 SV * buf 466 int RETVAL = 0; 467 CODE: 468 40 if (SvREADONLY(buf) && PL_curcop != &PL_compiling) 469 ###### croak("gzreadline: buffer parameter is read-only"); 470 40 SvUPGRADE(buf, SVt_PV); 471 40 SvPOK_only(buf); 472 /* sv_setpvn(buf, "", SIZE) ; */ 473 40 SvGROW(buf, SIZE) ; 474 40 SvCUR_set(buf, 0); 475 40 RETVAL = gzreadline(file, buf) ; 476 40 SetGzError(file->gz) ; 477 OUTPUT: 478 RETVAL 479 buf 480 CLEANUP: 481 40 if (RETVAL >= 0) { 482 /* SvCUR(buf) = RETVAL; */ 483 /* Don't need to explicitly terminate with '\0', because 484 sv_catpvn aready has */ 485 } 486 487 #define Zip_gzwrite(file, buf) gzwrite(file->gz, buf, (unsigned)len) 488 int 489 Zip_gzwrite(file, buf) 490 Compress::Zlib::gzFile file 491 STRLEN len = NO_INIT 492 voidp buf = (voidp)SvPV(ST(1), len) ; 493 CLEANUP: 494 77 SetGzError(file->gz) ; 495 496 #define Zip_gzflush(file, flush) gzflush(file->gz, flush) 497 int 498 Zip_gzflush(file, flush) 499 Compress::Zlib::gzFile file 500 int flush 501 CLEANUP: 502 ###### SetGzError(file->gz) ; 503 504 #define Zip_gzclose(file) gzclose(file->gz) 505 int 506 Zip_gzclose(file) 507 Compress::Zlib::gzFile file 508 CLEANUP: 509 48 file->closed = TRUE ; 510 48 SetGzErrorNo(RETVAL) ; 511 512 513 #define Zip_gzeof(file) gzeof(file->gz) 514 int 515 Zip_gzeof(file) 516 Compress::Zlib::gzFile file 517 CODE: 518 #ifdef OLD_ZLIB 519 croak("gzeof needs zlib 1.0.6 or better") ; 520 #else 521 ###### RETVAL = gzeof(file->gz); 522 #endif 523 OUTPUT: 524 RETVAL 525 526 527 #define Zip_gzsetparams(file,l,s) gzsetparams(file->gz,l,s) 528 int 529 Zip_gzsetparams(file, level, strategy) 530 Compress::Zlib::gzFile file 531 int level 532 int strategy 533 CODE: 534 #ifdef OLD_ZLIB 535 croak("gzsetparams needs zlib 1.0.6 or better") ; 536 #else 537 1 RETVAL = gzsetparams(file->gz, level, strategy); 538 #endif 539 OUTPUT: 540 RETVAL 541 542 void 543 DESTROY(file) 544 Compress::Zlib::gzFile file 545 CODE: 546 78 if (! file->closed) 547 30 Zip_gzclose(file) ; 548 78 SvREFCNT_dec(file->buffer) ; 549 78 safefree((char*)file) ; 550 551 #define Zip_gzerror(file) (char*)gzerror(file->gz, &errnum) 552 553 char * 554 Zip_gzerror(file) 555 Compress::Zlib::gzFile file 556 int errnum = NO_INIT 557 CLEANUP: 558 ###### sv_setiv(ST(0), errnum) ; 559 ###### SvPOK_on(ST(0)) ; 560 561 562 563 MODULE = Compress::Zlib PACKAGE = Compress::Zlib PREFIX = Zip_ 564 565 566 #define Zip_adler32(buf, adler) adler32(adler, buf, (uInt)len) 567 568 uLong 569 Zip_adler32(buf, adler=adlerInitial) 570 uLong adler = NO_INIT 571 STRLEN len = NO_INIT 572 Bytef * buf = NO_INIT 573 SV * sv = ST(0) ; 574 INIT: 575 /* If the buffer is a reference, dereference it */ 576 ###### sv = deRef(sv, "adler32") ; 577 ###### buf = (Byte*)SvPV(sv, len) ; 578 579 ###### if (items < 2) 580 ###### adler = adlerInitial; 581 ###### else if (SvOK(ST(1))) 582 ###### adler = SvUV(ST(1)) ; 583 else 584 ###### adler = adlerInitial; 585 586 #define Zip_crc32(buf, crc) crc32(crc, buf, (uInt)len) 587 588 uLong 589 Zip_crc32(buf, crc=crcInitial) 590 uLong crc = NO_INIT 591 STRLEN len = NO_INIT 592 Bytef * buf = NO_INIT 593 SV * sv = ST(0) ; 594 INIT: 595 /* If the buffer is a reference, dereference it */ 596 7 sv = deRef(sv, "crc32") ; 597 7 buf = (Byte*)SvPV(sv, len) ; 598 599 7 if (items < 2) 600 7 crc = crcInitial; 601 ###### else if (SvOK(ST(1))) 602 ###### crc = SvUV(ST(1)) ; 603 else 604 ###### crc = crcInitial; 605 606 MODULE = Compress::Zlib PACKAGE = Compress::Zlib 607 608 void 609 _deflateInit(level, method, windowBits, memLevel, strategy, bufsize, dictionary) 610 int level 611 int method 612 int windowBits 613 int memLevel 614 int strategy 615 uLong bufsize 616 SV * dictionary 617 PPCODE: 618 619 47 int err ; 620 47 deflateStream s ; 621 622 47 if (trace) 623 ###### warn("in _deflateInit(level=%d, method=%d, windowBits=%d, memLevel=%d, strategy=%d, bufsize=%d\n", 624 level, method, windowBits, memLevel, strategy, bufsize) ; 625 47 if ((s = InitStream(bufsize)) ) { 626 627 47 s->Level = level; 628 47 s->Method = method; 629 47 s->WindowBits = windowBits; 630 47 s->MemLevel = memLevel; 631 47 s->Strategy = strategy; 632 633 47 err = deflateInit2(&(s->stream), level, 634 method, windowBits, memLevel, strategy); 635 636 /* Check if a dictionary has been specified */ 637 47 if (err == Z_OK && SvCUR(dictionary)) { 638 1 err = deflateSetDictionary(&(s->stream), (const Bytef*) SvPVX(dictionary), 639 SvCUR(dictionary)) ; 640 1 s->dict_adler = s->stream.adler ; 641 } 642 643 47 if (err != Z_OK) { 644 1 Safefree(s) ; 645 1 s = NULL ; 646 } 647 648 } 649 else 650 ###### err = Z_MEM_ERROR ; 651 652 XPUSHs(sv_setref_pv(sv_newmortal(), 653 47 "Compress::Zlib::deflateStream", (void*)s)); 654 47 if (GIMME == G_ARRAY) 655 37 XPUSHs(sv_2mortal(newSViv(err))) ; 656 657 void 658 _inflateInit(windowBits, bufsize, dictionary) 659 int windowBits 660 uLong bufsize 661 SV * dictionary 662 PPCODE: 663 664 31 int err = Z_OK ; 665 31 inflateStream s ; 666 667 31 if (trace) 668 ###### warn("in _inflateInit(windowBits=%d, bufsize=%d, dictionary=%d\n", 669 windowBits, bufsize, SvCUR(dictionary)) ; 670 31 if ((s = InitStream(bufsize)) ) { 671 672 31 s->WindowBits = windowBits; 673 674 31 err = inflateInit2(&(s->stream), windowBits); 675 676 31 if (err != Z_OK) { 677 ###### Safefree(s) ; 678 ###### s = NULL ; 679 } 680 31 else if (SvCUR(dictionary)) { 681 /* Dictionary specified - take a copy for use in inflate */ 682 1 s->dictionary = newSVsv(dictionary) ; 683 } 684 } 685 else 686 ###### err = Z_MEM_ERROR ; 687 688 XPUSHs(sv_setref_pv(sv_newmortal(), 689 31 "Compress::Zlib::inflateStream", (void*)s)); 690 31 if (GIMME == G_ARRAY) 691 14 XPUSHs(sv_2mortal(newSViv(err))) ; 692 693 694 695 MODULE = Compress::Zlib PACKAGE = Compress::Zlib::deflateStream 696 697 void 698 DispStream(s, message=NULL) 699 Compress::Zlib::deflateStream s 700 char * message 701 702 void 703 deflate (s, buf) 704 Compress::Zlib::deflateStream s 705 SV * buf 706 uLong outsize = NO_INIT 707 SV * output = NO_INIT 708 int err = 0; 709 PPCODE: 710 711 /* If the buffer is a reference, dereference it */ 712 124 buf = deRef(buf, "deflate") ; 713 714 /* initialise the input buffer */ 715 124 s->stream.next_in = (Bytef*)SvPV(buf, *(STRLEN*)&s->stream.avail_in) ; 716 /* s->stream.next_in = (Bytef*)SvPVX(buf); */ 717 124 s->stream.avail_in = SvCUR(buf) ; 718 719 /* and the output buffer */ 720 /* output = sv_2mortal(newSVpv("", s->bufinc)) ; */ 721 124 output = sv_2mortal(newSV(s->bufinc)) ; 722 124 SvPOK_only(output) ; 723 124 SvCUR_set(output, 0) ; 724 124 outsize = s->bufinc ; 725 124 s->stream.next_out = (Bytef*) SvPVX(output) ; 726 124 s->stream.avail_out = outsize; 727 728 /* Check for saved output from deflateParams */ 729 124 if (s->deflateParams_out_valid) { 730 2 *(s->stream.next_out) = s->deflateParams_out_byte; 731 2 ++ s->stream.next_out; 732 2 -- s->stream.avail_out ; 733 2 s->deflateParams_out_valid = FALSE; 734 } 735 736 247 while (s->stream.avail_in != 0) { 737 738 123 if (s->stream.avail_out == 0) { 739 3 s->bufinc *= 2 ; 740 3 SvGROW(output, outsize + s->bufinc) ; 741 3 s->stream.next_out = (Bytef*) SvPVX(output) + outsize ; 742 3 outsize += s->bufinc ; 743 3 s->stream.avail_out = s->bufinc ; 744 } 745 123 err = deflate(&(s->stream), Z_NO_FLUSH); 746 123 if (err != Z_OK) 747 124 break; 748 } 749 750 124 if (err == Z_OK) { 751 124 SvPOK_only(output); 752 124 SvCUR_set(output, outsize - s->stream.avail_out) ; 753 } 754 else 755 ###### output = &PL_sv_undef ; 756 124 XPUSHs(output) ; 757 124 if (GIMME == G_ARRAY) 758 124 XPUSHs(sv_2mortal(newSViv(err))) ; 759 760 761 762 void 763 flush(s, f=Z_FINISH) 764 Compress::Zlib::deflateStream s 765 int f 766 uLong outsize = NO_INIT 767 SV * output = NO_INIT 768 int err = Z_OK ; 769 PPCODE: 770 771 47 s->stream.avail_in = 0; /* should be zero already anyway */ 772 773 /* output = sv_2mortal(newSVpv("", s->bufinc)) ; */ 774 47 output = sv_2mortal(newSV(s->bufinc)) ; 775 47 SvPOK_only(output) ; 776 47 SvCUR_set(output, 0) ; 777 47 outsize = s->bufinc ; 778 47 s->stream.next_out = (Bytef*) SvPVX(output) ; 779 47 s->stream.avail_out = outsize; 780 781 /* Check for saved output from deflateParams */ 782 47 if (s->deflateParams_out_valid) { 783 ###### *(s->stream.next_out) = s->deflateParams_out_byte; 784 ###### ++ s->stream.next_out; 785 ###### -- s->stream.avail_out ; 786 ###### s->deflateParams_out_valid = FALSE; 787 } 788 789 107 for (;;) { 790 60 if (s->stream.avail_out == 0) { 791 /* consumed all the available output, so extend it */ 792 13 s->bufinc *= 2 ; 793 13 SvGROW(output, outsize + s->bufinc) ; 794 13 s->stream.next_out = (Bytef*)SvPVX(output) + outsize ; 795 13 outsize += s->bufinc ; 796 13 s->stream.avail_out = s->bufinc ; 797 } 798 60 err = deflate(&(s->stream), f); 799 800 /* deflate has finished flushing only when it hasn't used up 801 * all the available space in the output buffer: 802 */ 803 60 if (s->stream.avail_out != 0 || err != Z_OK ) 804 47 break; 805 } 806 807 47 err = (err == Z_STREAM_END ? Z_OK : err) ; 808 809 47 if (err == Z_OK) { 810 47 SvPOK_only(output); 811 47 SvCUR_set(output, outsize - s->stream.avail_out) ; 812 } 813 else 814 ###### output = &PL_sv_undef ; 815 47 XPUSHs(output) ; 816 47 if (GIMME == G_ARRAY) 817 47 XPUSHs(sv_2mortal(newSViv(err))) ; 818 819 int 820 _deflateParams(s, flags, level, strategy, bufsize) 821 Compress::Zlib::deflateStream s 822 int flags 823 int level 824 int strategy 825 uLong bufsize 826 CODE: 827 3 if (flags & 1) 828 2 s->Level = level ; 829 3 if (flags & 2) 830 2 s->Strategy = strategy ; 831 3 if (bufsize) { 832 ###### s->bufsize = bufsize; 833 ###### s->bufinc = bufsize; 834 } 835 3 s->stream.avail_in = 0; 836 3 s->stream.next_out = &(s->deflateParams_out_byte) ; 837 3 s->stream.avail_out = 1; 838 3 RETVAL = deflateParams(&(s->stream), s->Level, s->Strategy); 839 3 s->deflateParams_out_valid = 840 (RETVAL == Z_OK && s->stream.avail_out == 0) ; 841 OUTPUT: 842 RETVAL 843 844 845 int 846 get_Level(s) 847 Compress::Zlib::deflateStream s 848 CODE: 849 5 RETVAL = s->Level ; 850 OUTPUT: 851 RETVAL 852 853 int 854 get_Strategy(s) 855 Compress::Zlib::deflateStream s 856 CODE: 857 5 RETVAL = s->Strategy ; 858 OUTPUT: 859 RETVAL 860 861 void 862 DESTROY(s) 863 Compress::Zlib::deflateStream s 864 CODE: 865 46 deflateEnd(&s->stream) ; 866 46 if (s->dictionary) 867 ###### SvREFCNT_dec(s->dictionary) ; 868 46 Safefree(s) ; 869 870 871 uLong 872 dict_adler(s) 873 Compress::Zlib::deflateStream s 874 CODE: 875 1 RETVAL = s->dict_adler ; 876 OUTPUT: 877 RETVAL 878 879 uLong 880 total_in(s) 881 Compress::Zlib::deflateStream s 882 CODE: 883 4 RETVAL = s->stream.total_in ; 884 OUTPUT: 885 RETVAL 886 887 uLong 888 total_out(s) 889 Compress::Zlib::deflateStream s 890 CODE: 891 ###### RETVAL = s->stream.total_out ; 892 OUTPUT: 893 RETVAL 894 895 char* 896 msg(s) 897 Compress::Zlib::deflateStream s 898 CODE: 899 ###### RETVAL = s->stream.msg; 900 OUTPUT: 901 RETVAL 902 903 904 MODULE = Compress::Zlib PACKAGE = Compress::Zlib::inflateStream 905 906 void 907 DispStream(s, message=NULL) 908 Compress::Zlib::inflateStream s 909 char * message 910 911 void 912 inflate (s, buf) 913 Compress::Zlib::inflateStream s 914 SV * buf 915 uLong outsize = NO_INIT 916 SV * output = NO_INIT 917 int err = Z_OK ; 918 ALIAS: 919 __unc_inflate = 1 920 PPCODE: 921 922 /* If the buffer is a reference, dereference it */ 923 173 buf = deRef(buf, "inflate") ; 924 925 /* initialise the input buffer */ 926 173 s->stream.next_in = (Bytef*)SvPVX(buf) ; 927 173 s->stream.avail_in = SvCUR(buf) ; 928 929 /* and the output buffer */ 930 173 output = sv_2mortal(newSV(s->bufinc+1)) ; 931 173 SvPOK_only(output) ; 932 173 SvCUR_set(output, 0) ; 933 173 outsize = s->bufinc ; 934 173 s->stream.next_out = (Bytef*) SvPVX(output) ; 935 173 s->stream.avail_out = outsize; 936 937 329 while (1) { 938 939 329 if (s->stream.avail_out == 0) { 940 15 s->bufinc *= 2 ; 941 15 SvGROW(output, outsize + s->bufinc+1) ; 942 15 s->stream.next_out = (Bytef*) SvPVX(output) + outsize ; 943 15 outsize += s->bufinc ; 944 15 s->stream.avail_out = s->bufinc ; 945 } 946 947 329 err = inflate(&(s->stream), Z_SYNC_FLUSH); 948 329 if (err == Z_BUF_ERROR) { 949 143 if (s->stream.avail_out == 0) 950 ###### continue ; 951 143 if (s->stream.avail_in == 0) { 952 143 err = Z_OK ; 953 143 break ; 954 } 955 } 956 957 186 if (err == Z_NEED_DICT && s->dictionary) { 958 1 s->dict_adler = s->stream.adler ; 959 1 err = inflateSetDictionary(&(s->stream), 960 (const Bytef*)SvPVX(s->dictionary), 961 SvCUR(s->dictionary)); 962 } 963 964 186 if (err != Z_OK) 965 173 break; 966 } 967 968 173 if (err == Z_OK || err == Z_STREAM_END || err == Z_DATA_ERROR) { 969 173 unsigned in ; 970 971 173 SvPOK_only(output); 972 173 SvCUR_set(output, outsize - s->stream.avail_out) ; 973 173 *SvEND(output) = '\0'; 974 975 /* fix the input buffer */ 976 173 if (ix == 0) { 977 165 in = s->stream.avail_in ; 978 165 SvCUR_set(buf, in) ; 979 165 if (in) 980 12 Move(s->stream.next_in, SvPVX(buf), in, char) ; 981 165 *SvEND(buf) = '\0'; 982 165 SvSETMAGIC(buf); 983 } 984 } 985 else 986 ###### output = &PL_sv_undef ; 987 173 XPUSHs(output) ; 988 173 if (GIMME == G_ARRAY) 989 173 XPUSHs(sv_2mortal(newSViv(err))) ; 990 991 int 992 inflateSync (s, buf) 993 Compress::Zlib::inflateStream s 994 SV * buf 995 CODE: 996 997 /* If the buffer is a reference, dereference it */ 998 169 buf = deRef(buf, "inflateSync") ; 999 1000 /* initialise the input buffer */ 1001 169 s->stream.next_in = (Bytef*)SvPVX(buf) ; 1002 169 s->stream.avail_in = SvCUR(buf) ; 1003 1004 /* inflateSync doesn't create any output */ 1005 169 s->stream.next_out = (Bytef*) NULL; 1006 169 s->stream.avail_out = 0; 1007 1008 169 RETVAL = inflateSync(&(s->stream)); 1009 { 1010 /* fix the input buffer */ 1011 169 unsigned in = s->stream.avail_in ; 1012 1013 169 SvCUR_set(buf, in) ; 1014 169 if (in) 1015 1 Move(s->stream.next_in, SvPVX(buf), in, char) ; 1016 169 *SvEND(buf) = '\0'; 1017 169 SvSETMAGIC(buf); 1018 } 1019 OUTPUT: 1020 RETVAL 1021 1022 void 1023 DESTROY(s) 1024 Compress::Zlib::inflateStream s 1025 CODE: 1026 31 inflateEnd(&s->stream) ; 1027 31 if (s->dictionary) 1028 1 SvREFCNT_dec(s->dictionary) ; 1029 31 Safefree(s) ; 1030 1031 1032 uLong 1033 dict_adler(s) 1034 Compress::Zlib::inflateStream s 1035 CODE: 1036 1 RETVAL = s->dict_adler ; 1037 OUTPUT: 1038 RETVAL 1039 1040 uLong 1041 total_in(s) 1042 Compress::Zlib::inflateStream s 1043 CODE: 1044 ###### RETVAL = s->stream.total_in ; 1045 OUTPUT: 1046 RETVAL 1047 1048 uLong 1049 total_out(s) 1050 Compress::Zlib::inflateStream s 1051 CODE: 1052 ###### RETVAL = s->stream.total_out ; 1053 OUTPUT: 1054 RETVAL 1055 1056 char* 1057 msg(s) 1058 Compress::Zlib::inflateStream s 1059 CODE: 1060 ###### RETVAL = s->stream.msg; 1061 OUTPUT: 1062 RETVAL 1063 1064 1065