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