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
CRZ_zlibVersion(void)135 const char *CRZ_zlibVersion(void) { return ""; }
CRZ_zlib_version(void)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
zlibng_version(void)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
zlibng_version(void)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
GetErrorString(int error_no)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
gcd(unsigned a,unsigned b)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
rotate(unsigned char * list,unsigned len,unsigned rot)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
DispHex(const void * ptr,int length)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
DispStream(di_stream * s,const char * message)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
my_zcalloc(voidpf opaque,unsigned items,unsigned size)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
my_zcfree(voidpf opaque,voidpf ptr)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
InitStream(void)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
PostInitStream(di_stream * s,int flags,int bufsize,int windowBits)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
deRef(SV * sv,const char * string)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
deRef_l(SV * sv,const char * string)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
flushParams(di_stream * s)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
_deflateInit(flags,level,method,windowBits,memLevel,strategy,bufsize,dictionary)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
_createDeflateStream(inf_s,flags,level,method,windowBits,memLevel,strategy,bufsize)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