Blame Zlib.xs

Packit d03632
/* Filename: Zlib.xs
Packit d03632
 * Author  : Paul Marquess, <pmqs@cpan.org>
Packit d03632
 * Created : 22nd January 1996
Packit d03632
 * Version : 2.000
Packit d03632
 *
Packit d03632
 *   Copyright (c) 1995-2013 Paul Marquess. All rights reserved.
Packit d03632
 *   This program is free software; you can redistribute it and/or
Packit d03632
 *   modify it under the same terms as Perl itself.
Packit d03632
 *
Packit d03632
 */
Packit d03632
Packit d03632
/* Parts of this code are based on the files gzio.c and gzappend.c from 
Packit d03632
 * the standard zlib source distribution. Below are the copyright statements
Packit d03632
 * from each. 
Packit d03632
 */
Packit d03632
Packit d03632
/* gzio.c -- IO on .gz files
Packit d03632
 * Copyright (C) 1995 Jean-loup Gailly.
Packit d03632
 * For conditions of distribution and use, see copyright notice in zlib.h
Packit d03632
 */
Packit d03632
Packit d03632
/* gzappend -- command to append to a gzip file
Packit d03632
Packit d03632
  Copyright (C) 2003 Mark Adler, all rights reserved
Packit d03632
  version 1.1, 4 Nov 2003
Packit d03632
*/
Packit d03632
Packit d03632
Packit d03632
#define PERL_NO_GET_CONTEXT
Packit d03632
#include "EXTERN.h"
Packit d03632
#include "perl.h"
Packit d03632
#include "XSUB.h"
Packit d03632
Packit d03632
#include "zlib.h" 
Packit d03632
Packit d03632
/* zlib prior to 1.06 doesn't know about z_off_t */
Packit d03632
#ifndef z_off_t
Packit d03632
#  define z_off_t   long
Packit d03632
#endif
Packit d03632
Packit d03632
#if  ! defined(ZLIB_VERNUM) || ZLIB_VERNUM < 0x1200
Packit d03632
#  define NEED_DUMMY_BYTE_AT_END 
Packit d03632
#endif
Packit d03632
Packit d03632
#if  defined(ZLIB_VERNUM) && ZLIB_VERNUM >= 0x1210
Packit d03632
#  define MAGIC_APPEND
Packit d03632
#  define AT_LEAST_ZLIB_1_2_1
Packit d03632
#endif
Packit d03632
Packit d03632
#if  defined(ZLIB_VERNUM) && ZLIB_VERNUM >= 0x1221
Packit d03632
#  define AT_LEAST_ZLIB_1_2_2_1
Packit d03632
#endif
Packit d03632
Packit d03632
#if  defined(ZLIB_VERNUM) && ZLIB_VERNUM >= 0x1222
Packit d03632
#  define AT_LEAST_ZLIB_1_2_2_2
Packit d03632
#endif
Packit d03632
Packit d03632
#if  defined(ZLIB_VERNUM) && ZLIB_VERNUM >= 0x1223
Packit d03632
#  define AT_LEAST_ZLIB_1_2_2_3
Packit d03632
#endif
Packit d03632
Packit d03632
#if  defined(ZLIB_VERNUM) && ZLIB_VERNUM >= 0x1230
Packit d03632
#  define AT_LEAST_ZLIB_1_2_3
Packit d03632
#endif
Packit d03632
Packit d03632
#if  defined(ZLIB_VERNUM) && ZLIB_VERNUM >= 0x1252
Packit d03632
/* 
Packit d03632
    Use Z_SOLO to build source means need own malloc/free
Packit d03632
 */
Packit d03632
#  define AT_LEAST_ZLIB_1_2_5_2
Packit d03632
#endif
Packit d03632
Packit d03632
#if  defined(ZLIB_VERNUM) && ZLIB_VERNUM >= 0x1280
Packit d03632
#  define AT_LEAST_ZLIB_1_2_8
Packit d03632
#endif
Packit d03632
Packit d03632
#if  defined(ZLIB_VERNUM) && ZLIB_VERNUM >= 0x1290
Packit d03632
#  define AT_LEAST_ZLIB_1_2_9
Packit d03632
#endif
Packit d03632
Packit d03632
#ifdef USE_PPPORT_H
Packit d03632
#  define NEED_sv_2pvbyte
Packit d03632
#  define NEED_sv_2pv_nolen
Packit d03632
#  define NEED_sv_pvn_force_flags
Packit d03632
#  include "ppport.h"
Packit d03632
#endif
Packit d03632
Packit d03632
#if PERL_REVISION == 5 && PERL_VERSION == 9
Packit d03632
    /* For Andreas */
Packit d03632
#   define sv_pvbyte_force(sv,lp) sv_pvbyten_force(sv,lp)
Packit d03632
#endif
Packit d03632
Packit d03632
#if PERL_REVISION == 5 && (PERL_VERSION < 8 || (PERL_VERSION == 8 && PERL_SUBVERSION < 4 ))
Packit d03632
Packit d03632
#    ifdef SvPVbyte_force
Packit d03632
#        undef SvPVbyte_force
Packit d03632
#    endif
Packit d03632
Packit d03632
#    define SvPVbyte_force(sv,lp) SvPV_force(sv,lp)
Packit d03632
Packit d03632
#endif
Packit d03632
Packit d03632
#ifndef SvPVbyte_nolen
Packit d03632
#    define SvPVbyte_nolen SvPV_nolen
Packit d03632
#endif
Packit d03632
Packit d03632
Packit d03632
Packit d03632
#if 0
Packit d03632
#  ifndef SvPVbyte_nolen
Packit d03632
#    define SvPVbyte_nolen SvPV_nolen
Packit d03632
#  endif
Packit d03632
Packit d03632
#  ifndef SvPVbyte_force
Packit d03632
#    define SvPVbyte_force(sv,lp) SvPV_force(sv,lp)
Packit d03632
#  endif
Packit d03632
#endif
Packit d03632
Packit d03632
#if PERL_REVISION == 5 && (PERL_VERSION >= 8 || (PERL_VERSION == 8 && PERL_SUBVERSION < 4 ))
Packit d03632
#    define UTF8_AVAILABLE
Packit d03632
#endif
Packit d03632
Packit d03632
typedef int                     DualType ;
Packit d03632
typedef int                     int_undef ;
Packit d03632
Packit d03632
typedef struct di_stream {
Packit d03632
    int      flags ;
Packit d03632
#define FLAG_APPEND             1
Packit d03632
#define FLAG_CRC32              2
Packit d03632
#define FLAG_ADLER32            4
Packit d03632
#define FLAG_CONSUME_INPUT      8
Packit d03632
#define FLAG_LIMIT_OUTPUT       16
Packit d03632
    uLong    crc32 ;
Packit d03632
    uLong    adler32 ;
Packit d03632
    z_stream stream;
Packit d03632
    uLong     bufsize; 
Packit d03632
    SV *     dictionary ;
Packit d03632
    uLong    dict_adler ;
Packit d03632
    int      last_error ;
Packit d03632
    bool     zip_mode ;
Packit d03632
/* #define SETP_BYTE */
Packit d03632
#ifdef SETP_BYTE
Packit d03632
    /* SETP_BYTE only works with zlib up to 1.2.8 */
Packit d03632
    bool     deflateParams_out_valid ;
Packit d03632
    Bytef    deflateParams_out_byte;
Packit d03632
#else
Packit d03632
#define deflateParams_BUFFER_SIZE       0x40000
Packit d03632
    uLong    deflateParams_out_length;
Packit d03632
    Bytef*   deflateParams_out_buffer;
Packit d03632
#endif
Packit d03632
    int      Level;
Packit d03632
    int      Method;
Packit d03632
    int      WindowBits;
Packit d03632
    int      MemLevel;
Packit d03632
    int      Strategy;
Packit d03632
    uLong    bytesInflated ;
Packit d03632
    uLong    compressedBytes ;
Packit d03632
    uLong    uncompressedBytes ;
Packit d03632
#ifdef MAGIC_APPEND
Packit d03632
Packit d03632
#define WINDOW_SIZE 32768U
Packit d03632
Packit d03632
    bool     matchedEndBlock;
Packit d03632
    Bytef*   window ;
Packit d03632
    int      window_lastbit,  window_left,  window_full;
Packit d03632
    unsigned window_have;
Packit d03632
    off_t    window_lastoff, window_end;
Packit d03632
    off_t    window_endOffset;
Packit d03632
Packit d03632
    uLong    lastBlockOffset ;
Packit d03632
    unsigned char window_lastByte ;
Packit d03632
                
Packit d03632
Packit d03632
#endif
Packit d03632
} di_stream;
Packit d03632
Packit d03632
typedef di_stream * deflateStream ;
Packit d03632
typedef di_stream * Compress__Raw__Zlib__deflateStream ;
Packit d03632
typedef di_stream * inflateStream ;
Packit d03632
typedef di_stream * Compress__Raw__Zlib__inflateStream ;
Packit d03632
typedef di_stream * Compress__Raw__Zlib__inflateScanStream ;
Packit d03632
Packit d03632
#define ZMALLOC(to, typ) (to = (typ *)safecalloc(sizeof(typ), 1))
Packit d03632
Packit d03632
/* Figure out the Operating System */
Packit d03632
#ifdef MSDOS
Packit d03632
#  define OS_CODE  0x00
Packit d03632
#endif
Packit d03632
Packit d03632
#if defined(AMIGA) || defined(AMIGAOS) || defined(__amigaos4__)
Packit d03632
#  define OS_CODE  0x01
Packit d03632
#endif
Packit d03632
 
Packit d03632
#if defined(VAXC) || defined(VMS)
Packit d03632
#  define OS_CODE  0x02
Packit d03632
#endif
Packit d03632
Packit d03632
#if 0 /* VM/CMS */
Packit d03632
#  define OS_CODE  0x04
Packit d03632
#endif
Packit d03632
 
Packit d03632
#if defined(ATARI) || defined(atarist)
Packit d03632
#  define OS_CODE  0x05
Packit d03632
#endif
Packit d03632
 
Packit d03632
#ifdef OS2
Packit d03632
#  define OS_CODE  0x06
Packit d03632
#endif
Packit d03632
 
Packit d03632
#if defined(MACOS) || defined(TARGET_OS_MAC)
Packit d03632
#  define OS_CODE  0x07
Packit d03632
#endif
Packit d03632
Packit d03632
#if 0 /* Z-System */
Packit d03632
#  define OS_CODE  0x08
Packit d03632
#endif
Packit d03632
 
Packit d03632
#if 0 /* CP/M */
Packit d03632
#  define OS_CODE  0x09
Packit d03632
#endif
Packit d03632
 
Packit d03632
#ifdef TOPS20
Packit d03632
#  define OS_CODE  0x0a
Packit d03632
#endif
Packit d03632
Packit d03632
#ifdef WIN32 /* Window 95 & Windows NT */
Packit d03632
#  define OS_CODE  0x0b
Packit d03632
#endif
Packit d03632
 
Packit d03632
#if 0 /* QDOS */
Packit d03632
#  define OS_CODE  0x0c
Packit d03632
#endif
Packit d03632
 
Packit d03632
#if 0 /* Acorn RISCOS */
Packit d03632
#  define OS_CODE  0x0d
Packit d03632
#endif
Packit d03632
 
Packit d03632
#if 0 /* ???  */
Packit d03632
#  define OS_CODE  0x0e
Packit d03632
#endif
Packit d03632
 
Packit d03632
#ifdef __50SERIES /* Prime/PRIMOS */
Packit d03632
#  define OS_CODE  0x0F
Packit d03632
#endif
Packit d03632
 
Packit d03632
/* Default to UNIX */ 
Packit d03632
#ifndef OS_CODE
Packit d03632
#  define OS_CODE  0x03  /* assume Unix */
Packit d03632
#endif
Packit d03632
Packit d03632
#ifndef GZIP_OS_CODE
Packit d03632
#  define GZIP_OS_CODE OS_CODE
Packit d03632
#endif
Packit d03632
Packit d03632
#define adlerInitial adler32(0L, Z_NULL, 0)
Packit d03632
#define crcInitial crc32(0L, Z_NULL, 0)
Packit d03632
Packit d03632
/* static const char * const my_z_errmsg[] = { */
Packit d03632
static const char my_z_errmsg[][32] = {
Packit d03632
    "need dictionary",     /* Z_NEED_DICT     2 */
Packit d03632
    "stream end",          /* Z_STREAM_END    1 */
Packit d03632
    "",                    /* Z_OK            0 */
Packit d03632
    "file error",          /* Z_ERRNO        (-1) */
Packit d03632
    "stream error",        /* Z_STREAM_ERROR (-2) */
Packit d03632
    "data error",          /* Z_DATA_ERROR   (-3) */
Packit d03632
    "insufficient memory", /* Z_MEM_ERROR    (-4) */
Packit d03632
    "buffer error",        /* Z_BUF_ERROR    (-5) */
Packit d03632
    "incompatible version",/* Z_VERSION_ERROR(-6) */
Packit d03632
    ""};
Packit d03632
Packit d03632
#define setDUALstatus(var, err)                                         \
Packit d03632
                sv_setnv(var, (double)err) ;                            \
Packit d03632
                sv_setpv(var, ((err) ? GetErrorString(err) : "")) ;     \
Packit d03632
                SvNOK_on(var);
Packit d03632
Packit d03632
   
Packit d03632
#if defined(__SYMBIAN32__)
Packit d03632
# define NO_WRITEABLE_DATA
Packit d03632
#endif
Packit d03632
Packit d03632
/* Set TRACE_DEFAULT to a non-zero value to enable tracing */
Packit d03632
#define TRACE_DEFAULT 0
Packit d03632
Packit d03632
#if defined(NO_WRITEABLE_DATA) || TRACE_DEFAULT == 0
Packit d03632
#  define trace TRACE_DEFAULT
Packit d03632
#else
Packit d03632
  static int trace = TRACE_DEFAULT ;
Packit d03632
#endif
Packit d03632
Packit d03632
/* Dodge PerlIO hiding of these functions. */
Packit d03632
#undef printf
Packit d03632
Packit d03632
static char *
Packit d03632
#ifdef CAN_PROTOTYPE
Packit d03632
GetErrorString(int error_no)
Packit d03632
#else
Packit d03632
GetErrorString(error_no)
Packit d03632
int error_no ;
Packit d03632
#endif
Packit d03632
{
Packit d03632
    dTHX;
Packit d03632
    char * errstr ;
Packit d03632
  
Packit d03632
    if (error_no == Z_ERRNO) {
Packit d03632
        errstr = Strerror(errno) ;
Packit d03632
    }
Packit d03632
    else
Packit d03632
        /* errstr = gzerror(fil, &error_no) ; */
Packit d03632
        errstr = (char*) my_z_errmsg[2 - error_no]; 
Packit d03632
Packit d03632
    return errstr ;
Packit d03632
}
Packit d03632
Packit d03632
Packit d03632
#ifdef MAGIC_APPEND
Packit d03632
Packit d03632
/*
Packit d03632
   The following two functions are taken almost directly from
Packit d03632
   examples/gzappend.c. Only cosmetic changes have been made to conform to
Packit d03632
   the coding style of the rest of the code in this file.
Packit d03632
*/
Packit d03632
Packit d03632
Packit d03632
/* return the greatest common divisor of a and b using Euclid's algorithm,
Packit d03632
   modified to be fast when one argument much greater than the other, and
Packit d03632
   coded to avoid unnecessary swapping */
Packit d03632
static unsigned 
Packit d03632
#ifdef CAN_PROTOTYPE
Packit d03632
gcd(unsigned a, unsigned b)
Packit d03632
#else
Packit d03632
gcd(a, b)
Packit d03632
    unsigned a;
Packit d03632
    unsigned b;
Packit d03632
#endif
Packit d03632
{
Packit d03632
    unsigned c;
Packit d03632
Packit d03632
    while (a && b)
Packit d03632
        if (a > b) {
Packit d03632
            c = b;
Packit d03632
            while (a - c >= c)
Packit d03632
                c <<= 1;
Packit d03632
            a -= c;
Packit d03632
        }
Packit d03632
        else {
Packit d03632
            c = a;
Packit d03632
            while (b - c >= c)
Packit d03632
                c <<= 1;
Packit d03632
            b -= c;
Packit d03632
        }
Packit d03632
    return a + b;
Packit d03632
}
Packit d03632
Packit d03632
/* rotate list[0..len-1] left by rot positions, in place */
Packit d03632
static void 
Packit d03632
#ifdef CAN_PROTOTYPE
Packit d03632
rotate(unsigned char *list, unsigned len, unsigned rot)
Packit d03632
#else
Packit d03632
rotate(list, len, rot)
Packit d03632
    unsigned char *list;
Packit d03632
    unsigned len ;
Packit d03632
    unsigned rot;
Packit d03632
#endif
Packit d03632
{
Packit d03632
    unsigned char tmp;
Packit d03632
    unsigned cycles;
Packit d03632
    unsigned char *start, *last, *to, *from;
Packit d03632
Packit d03632
    /* normalize rot and handle degenerate cases */
Packit d03632
    if (len < 2) return;
Packit d03632
    if (rot >= len) rot %= len;
Packit d03632
    if (rot == 0) return;
Packit d03632
Packit d03632
    /* pointer to last entry in list */
Packit d03632
    last = list + (len - 1);
Packit d03632
Packit d03632
    /* do simple left shift by one */
Packit d03632
    if (rot == 1) {
Packit d03632
        tmp = *list;
Packit d03632
        memmove(list, list + 1, len - 1);
Packit d03632
        *last = tmp;
Packit d03632
        return;
Packit d03632
    }
Packit d03632
Packit d03632
    /* do simple right shift by one */
Packit d03632
    if (rot == len - 1) {
Packit d03632
        tmp = *last;
Packit d03632
        memmove(list + 1, list, len - 1);
Packit d03632
        *list = tmp;
Packit d03632
        return;
Packit d03632
    }
Packit d03632
Packit d03632
    /* otherwise do rotate as a set of cycles in place */
Packit d03632
    cycles = gcd(len, rot);             /* number of cycles */
Packit d03632
    do {
Packit d03632
        start = from = list + cycles;   /* start index is arbitrary */
Packit d03632
        tmp = *from;                    /* save entry to be overwritten */
Packit d03632
        for (;;) {
Packit d03632
            to = from;                  /* next step in cycle */
Packit d03632
            from += rot;                /* go right rot positions */
Packit d03632
            if (from > last) from -= len;   /* (pointer better not wrap) */
Packit d03632
            if (from == start) break;   /* all but one shifted */
Packit d03632
            *to = *from;                /* shift left */
Packit d03632
        }
Packit d03632
        *to = tmp;                      /* complete the circle */
Packit d03632
    } while (--cycles);
Packit d03632
}
Packit d03632
Packit d03632
#endif /* MAGIC_APPEND */
Packit d03632
Packit d03632
static void
Packit d03632
#ifdef CAN_PROTOTYPE
Packit d03632
DispHex(void * ptr, int length)
Packit d03632
#else
Packit d03632
DispHex(ptr, length)
Packit d03632
    void * ptr;
Packit d03632
    int length;
Packit d03632
#endif
Packit d03632
{
Packit d03632
    char * p = (char*)ptr;
Packit d03632
    int i;
Packit d03632
    for (i = 0; i < length; ++i) {
Packit d03632
        printf(" %02x", 0xFF & *(p+i));
Packit d03632
    }
Packit d03632
}
Packit d03632
Packit d03632
Packit d03632
static void
Packit d03632
#ifdef CAN_PROTOTYPE
Packit d03632
DispStream(di_stream * s, const char * message)
Packit d03632
#else
Packit d03632
DispStream(s, message)
Packit d03632
    di_stream * s;
Packit d03632
    const char * message;
Packit d03632
#endif
Packit d03632
{
Packit d03632
Packit d03632
#if 0
Packit d03632
    if (! trace)
Packit d03632
        return ;
Packit d03632
#endif
Packit d03632
Packit d03632
#define EnDis(f) (s->flags & f ? "Enabled" : "Disabled")
Packit d03632
Packit d03632
    printf("DispStream %p", s) ;
Packit d03632
    if (message)
Packit d03632
        printf("- %s \n", message) ;
Packit d03632
    printf("\n") ;
Packit d03632
Packit d03632
    if (!s)  {
Packit d03632
        printf("    stream pointer is NULL\n");
Packit d03632
    }
Packit d03632
    else     {
Packit d03632
        printf("    stream           %p\n", &(s->stream));
Packit d03632
        printf("           zalloc    %p\n", s->stream.zalloc);
Packit d03632
        printf("           zfree     %p\n", s->stream.zfree);
Packit d03632
        printf("           opaque    %p\n", s->stream.opaque);
Packit d03632
        printf("           state     %p\n", s->stream.state);
Packit d03632
        if (s->stream.msg)
Packit d03632
            printf("           msg       %s\n", s->stream.msg);
Packit d03632
        else
Packit d03632
            printf("           msg       \n");
Packit d03632
        printf("           next_in   %p", s->stream.next_in);
Packit d03632
        if (s->stream.next_in){
Packit d03632
            printf(" =>");
Packit d03632
            DispHex(s->stream.next_in, 4);
Packit d03632
        }
Packit d03632
        printf("\n");
Packit d03632
Packit d03632
        printf("           next_out  %p", s->stream.next_out);
Packit d03632
        if (s->stream.next_out){
Packit d03632
            printf(" =>");
Packit d03632
            DispHex(s->stream.next_out, 4);
Packit d03632
        }
Packit d03632
        printf("\n");
Packit d03632
Packit d03632
        printf("           avail_in  %lu\n",  (unsigned long)s->stream.avail_in);
Packit d03632
        printf("           avail_out %lu\n",  (unsigned long)s->stream.avail_out);
Packit d03632
        printf("           total_in  %ld\n",  s->stream.total_in);
Packit d03632
        printf("           total_out %ld\n",  s->stream.total_out);
Packit d03632
        printf("           adler     %ld\n",  s->stream.adler    );
Packit d03632
        printf("    bufsize          %ld\n",  s->bufsize);
Packit d03632
        printf("    dictionary       %p\n",   s->dictionary);
Packit d03632
        printf("    dict_adler       0x%ld\n",s->dict_adler);
Packit d03632
        printf("    zip_mode         %d\n",   s->zip_mode);
Packit d03632
        printf("    crc32            0x%x\n", (unsigned)s->crc32);
Packit d03632
        printf("    adler32          0x%x\n", (unsigned)s->adler32);
Packit d03632
        printf("    flags            0x%x\n", s->flags);
Packit d03632
        printf("           APPEND    %s\n",   EnDis(FLAG_APPEND));
Packit d03632
        printf("           CRC32     %s\n",   EnDis(FLAG_CRC32));
Packit d03632
        printf("           ADLER32   %s\n",   EnDis(FLAG_ADLER32));
Packit d03632
        printf("           CONSUME   %s\n",   EnDis(FLAG_CONSUME_INPUT));
Packit d03632
        printf("           LIMIT     %s\n",   EnDis(FLAG_LIMIT_OUTPUT));
Packit d03632
Packit d03632
Packit d03632
#ifdef MAGIC_APPEND
Packit d03632
        printf("    window           %p\n", s->window);
Packit d03632
#endif
Packit d03632
        printf("\n");
Packit d03632
Packit d03632
    }
Packit d03632
}
Packit d03632
Packit d03632
#ifdef AT_LEAST_ZLIB_1_2_5_2
Packit d03632
voidpf my_zcalloc (voidpf opaque, unsigned items, unsigned size)
Packit d03632
{
Packit d03632
    PERL_UNUSED_VAR(opaque);
Packit d03632
    /* TODO - put back to calloc */
Packit d03632
    /* return safecalloc(items, size); */
Packit d03632
    return safemalloc(items* size);
Packit d03632
}
Packit d03632
Packit d03632
Packit d03632
void my_zcfree (voidpf opaque, voidpf ptr)
Packit d03632
{
Packit d03632
    PERL_UNUSED_VAR(opaque);
Packit d03632
    safefree(ptr);
Packit d03632
    return; 
Packit d03632
}
Packit d03632
Packit d03632
#endif
Packit d03632
Packit d03632
static di_stream *
Packit d03632
#ifdef CAN_PROTOTYPE
Packit d03632
InitStream(void)
Packit d03632
#else
Packit d03632
InitStream()
Packit d03632
#endif
Packit d03632
{
Packit d03632
    di_stream *s ;
Packit d03632
Packit d03632
    ZMALLOC(s, di_stream) ;
Packit d03632
Packit d03632
#ifdef AT_LEAST_ZLIB_1_2_5_2
Packit d03632
    s->stream.zalloc = my_zcalloc;
Packit d03632
    s->stream.zfree = my_zcfree;
Packit d03632
#endif
Packit d03632
Packit d03632
    return s ;
Packit d03632
}
Packit d03632
Packit d03632
static void
Packit d03632
#ifdef CAN_PROTOTYPE
Packit d03632
PostInitStream(di_stream * s, int flags, int bufsize, int windowBits)
Packit d03632
#else
Packit d03632
PostInitStream(s, flags, bufsize, windowBits)
Packit d03632
    di_stream *s ;
Packit d03632
    int flags ;
Packit d03632
    int bufsize ;
Packit d03632
    int windowBits ;
Packit d03632
#endif
Packit d03632
{
Packit d03632
    s->bufsize = bufsize ;
Packit d03632
    s->compressedBytes =
Packit d03632
    s->uncompressedBytes =
Packit d03632
    s->last_error = 0 ;
Packit d03632
    s->flags    = flags ;
Packit d03632
    s->zip_mode = (windowBits < 0) ;
Packit d03632
    if (flags & FLAG_CRC32) 
Packit d03632
        s->crc32 = crcInitial ;
Packit d03632
    if (flags & FLAG_ADLER32) 
Packit d03632
        s->adler32 = adlerInitial ;
Packit d03632
}
Packit d03632
Packit d03632
Packit d03632
static SV* 
Packit d03632
#ifdef CAN_PROTOTYPE
Packit d03632
deRef(SV * sv, const char * string)
Packit d03632
#else
Packit d03632
deRef(sv, string)
Packit d03632
SV * sv ;
Packit d03632
char * string;
Packit d03632
#endif
Packit d03632
{
Packit d03632
    dTHX;
Packit d03632
    SvGETMAGIC(sv);
Packit d03632
Packit d03632
    if (SvROK(sv)) {
Packit d03632
        sv = SvRV(sv) ;
Packit d03632
        SvGETMAGIC(sv);
Packit d03632
        switch(SvTYPE(sv)) {
Packit d03632
            case SVt_PVAV:
Packit d03632
            case SVt_PVHV:
Packit d03632
            case SVt_PVCV:
Packit d03632
                croak("%s: buffer parameter is not a SCALAR reference", string);
Packit d03632
            default:
Packit d03632
                break;
Packit d03632
        }
Packit d03632
        if (SvROK(sv))
Packit d03632
            croak("%s: buffer parameter is a reference to a reference", string) ;
Packit d03632
    }
Packit d03632
Packit d03632
    if (!SvOK(sv))
Packit d03632
        sv = sv_2mortal(newSVpv("", 0));
Packit d03632
Packit d03632
    return sv ;
Packit d03632
}
Packit d03632
Packit d03632
static SV*
Packit d03632
#ifdef CAN_PROTOTYPE
Packit d03632
deRef_l(SV * sv, const char * string)
Packit d03632
#else
Packit d03632
deRef_l(sv, string)
Packit d03632
SV * sv ;
Packit d03632
char * string ;
Packit d03632
#endif
Packit d03632
{
Packit d03632
    dTHX;
Packit d03632
    bool wipe = 0 ;
Packit d03632
    STRLEN na;
Packit d03632
    
Packit d03632
    SvGETMAGIC(sv);
Packit d03632
    wipe = ! SvOK(sv) ;
Packit d03632
Packit d03632
    if (SvROK(sv)) {
Packit d03632
        sv = SvRV(sv) ;
Packit d03632
        SvGETMAGIC(sv);
Packit d03632
        wipe = ! SvOK(sv) ;
Packit d03632
Packit d03632
        switch(SvTYPE(sv)) {
Packit d03632
            case SVt_PVAV:
Packit d03632
            case SVt_PVHV:
Packit d03632
            case SVt_PVCV:
Packit d03632
                croak("%s: buffer parameter is not a SCALAR reference", string);
Packit d03632
            default:
Packit d03632
                break;
Packit d03632
        }
Packit d03632
        if (SvROK(sv))
Packit d03632
            croak("%s: buffer parameter is a reference to a reference", string) ;
Packit d03632
    }
Packit d03632
Packit d03632
    if (SvREADONLY(sv) && PL_curcop != &PL_compiling)
Packit d03632
        croak("%s: buffer parameter is read-only", string);
Packit d03632
Packit d03632
    SvUPGRADE(sv, SVt_PV);
Packit d03632
Packit d03632
    if (wipe)
Packit d03632
        sv_setpv(sv, "") ;
Packit d03632
    else
Packit d03632
        (void)SvPVbyte_force(sv, na) ;
Packit d03632
Packit d03632
    return sv ;
Packit d03632
}
Packit d03632
Packit d03632
#if 0
Packit d03632
int
Packit d03632
flushToBuffer(di_stream* s, int flush)
Packit d03632
{
Packit d03632
    dTHX;
Packit d03632
    int ret ;
Packit d03632
    z_stream * strm = &s->stream;
Packit d03632
Packit d03632
    Bytef* output = s->deflateParams_out_buffer ;
Packit d03632
Packit d03632
    strm->next_in = NULL;
Packit d03632
    strm->avail_in = 0;
Packit d03632
    
Packit d03632
    uLong total_output = 0;
Packit d03632
    uLong have = 0;
Packit d03632
Packit d03632
    do 
Packit d03632
    {
Packit d03632
        if (output)
Packit d03632
            output = (unsigned char *)saferealloc(output, total_output + s->bufsize);
Packit d03632
        else
Packit d03632
            output = (unsigned char *)safemalloc(s->bufsize);
Packit d03632
Packit d03632
        strm->next_out  = output + total_output;
Packit d03632
        strm->avail_out = s->bufsize;
Packit d03632
Packit d03632
        ret = deflate(strm, flush);    /* no bad return value */
Packit d03632
        //assert(ret != Z_STREAM_ERROR);  /* state not clobbered */
Packit d03632
        if(ret == Z_STREAM_ERROR)
Packit d03632
        {
Packit d03632
            safefree(output);
Packit d03632
            return ret;
Packit d03632
        }
Packit d03632
        have = s->bufsize - strm->avail_out;
Packit d03632
        total_output += have;
Packit d03632
Packit d03632
        //fprintf(stderr, "FLUSH %s %d, return %d\n", flush_flags[flush], have, ret);
Packit d03632
Packit d03632
    } while (strm->avail_out == 0);
Packit d03632
Packit d03632
    s->deflateParams_out_buffer = output;
Packit d03632
    s->deflateParams_out_length = total_output; 
Packit d03632
Packit d03632
    return Z_OK;
Packit d03632
}
Packit d03632
#endif
Packit d03632
Packit d03632
#ifndef SETP_BYTE
Packit d03632
int
Packit d03632
flushParams(di_stream* s)
Packit d03632
{
Packit d03632
    dTHX;
Packit d03632
    int ret ;
Packit d03632
    z_stream * strm = &s->stream;
Packit d03632
Packit d03632
    Bytef* output = s->deflateParams_out_buffer ;
Packit d03632
    uLong total_output = s->deflateParams_out_length;
Packit d03632
    uLong have = 0;
Packit d03632
Packit d03632
    strm->next_in = NULL;
Packit d03632
    strm->avail_in = 0;
Packit d03632
    
Packit d03632
Packit d03632
    do 
Packit d03632
    {
Packit d03632
        if (output)
Packit d03632
            output = (unsigned char *)saferealloc(output, total_output + s->bufsize);
Packit d03632
        else
Packit d03632
            output = (unsigned char *)safemalloc(s->bufsize);
Packit d03632
Packit d03632
        strm->next_out  = output + total_output;
Packit d03632
        strm->avail_out = s->bufsize;
Packit d03632
Packit d03632
        ret = deflateParams(&(s->stream), s->Level, s->Strategy);
Packit d03632
        /* fprintf(stderr, "deflateParams %d %s %lu\n", ret,
Packit d03632
            GetErrorString(ret),  s->bufsize - strm->avail_out); */
Packit d03632
Packit d03632
        if (ret == Z_STREAM_ERROR) 
Packit d03632
            break;
Packit d03632
Packit d03632
        have = s->bufsize - strm->avail_out;
Packit d03632
        total_output += have;
Packit d03632
Packit d03632
Packit d03632
    } while (ret == Z_BUF_ERROR) ;
Packit d03632
Packit d03632
    if(ret == Z_STREAM_ERROR)
Packit d03632
        safefree(output);
Packit d03632
    else 
Packit d03632
    {
Packit d03632
        s->deflateParams_out_buffer = output;
Packit d03632
        s->deflateParams_out_length = total_output; 
Packit d03632
    }
Packit d03632
Packit d03632
    return ret;
Packit d03632
}
Packit d03632
#endif /* ! SETP_BYTE */
Packit d03632
Packit d03632
#include "constants.h"
Packit d03632
Packit d03632
MODULE = Compress::Raw::Zlib PACKAGE = Compress::Raw::Zlib        PREFIX = Zip_
Packit d03632
Packit d03632
REQUIRE:	1.924
Packit d03632
PROTOTYPES:	DISABLE
Packit d03632
Packit d03632
INCLUDE: constants.xs
Packit d03632
Packit d03632
BOOT:
Packit d03632
    /* Check this version of zlib is == 1 */
Packit d03632
    if (zlibVersion()[0] != '1')
Packit d03632
	croak("Compress::Raw::Zlib needs zlib version 1.x\n") ;
Packit d03632
	
Packit d03632
    {
Packit d03632
        /* Create the $os_code scalar */
Packit d03632
        SV * os_code_sv = perl_get_sv("Compress::Raw::Zlib::gzip_os_code", GV_ADDMULTI) ;
Packit d03632
        sv_setiv(os_code_sv, GZIP_OS_CODE) ;
Packit d03632
    }
Packit d03632
Packit d03632
Packit d03632
#define Zip_zlib_version()	(const char*)zlib_version
Packit d03632
const char*
Packit d03632
Zip_zlib_version()
Packit d03632
Packit d03632
unsigned
Packit d03632
ZLIB_VERNUM()
Packit d03632
    CODE:
Packit d03632
#ifdef ZLIB_VERNUM
Packit d03632
        RETVAL = ZLIB_VERNUM ;
Packit d03632
#else
Packit d03632
        /* 1.1.4 => 0x1140 */
Packit d03632
        RETVAL  = (ZLIB_VERSION[0] - '0') << 12 ;
Packit d03632
        RETVAL += (ZLIB_VERSION[2] - '0') <<  8 ;
Packit d03632
        RETVAL += (ZLIB_VERSION[4] - '0') <<  4 ;
Packit d03632
        if (strlen(ZLIB_VERSION) > 5)
Packit d03632
            RETVAL += (ZLIB_VERSION[6] - '0')  ;
Packit d03632
#endif
Packit d03632
    OUTPUT:
Packit d03632
        RETVAL
Packit d03632
Packit d03632
Packit d03632
#ifndef AT_LEAST_ZLIB_1_2_1
Packit d03632
#define zlibCompileFlags() 0
Packit d03632
#endif
Packit d03632
uLong
Packit d03632
zlibCompileFlags()
Packit d03632
Packit d03632
MODULE = Compress::Raw::Zlib	PACKAGE = Compress::Raw::Zlib	PREFIX = Zip_
Packit d03632
Packit d03632
#define Zip_adler32(buf, adler) adler32(adler, buf, (uInt)len)
Packit d03632
Packit d03632
uLong
Packit d03632
Zip_adler32(buf, adler=adlerInitial)
Packit d03632
        uLong    adler = NO_INIT
Packit d03632
        STRLEN   len = NO_INIT
Packit d03632
        Bytef *  buf = NO_INIT
Packit d03632
	SV *	 sv = ST(0) ;
Packit d03632
	INIT:
Packit d03632
    	/* If the buffer is a reference, dereference it */
Packit d03632
	sv = deRef(sv, "adler32") ;
Packit d03632
#ifdef UTF8_AVAILABLE    
Packit d03632
    if (DO_UTF8(sv) && !sv_utf8_downgrade(sv, 1))
Packit d03632
         croak("Wide character in Compress::Raw::Zlib::adler32");
Packit d03632
#endif         
Packit d03632
	buf = (Byte*)SvPVbyte(sv, len) ;
Packit d03632
Packit d03632
	if (items < 2)
Packit d03632
	  adler = adlerInitial;
Packit d03632
	else if (SvOK(ST(1)))
Packit d03632
	  adler = SvUV(ST(1)) ;
Packit d03632
	else
Packit d03632
	  adler = adlerInitial;
Packit d03632
    OUTPUT:
Packit d03632
        RETVAL
Packit d03632
 
Packit d03632
#define Zip_crc32(buf, crc, offset) crc32(crc, buf+offset, (uInt)len-offset)
Packit d03632
Packit d03632
uLong
Packit d03632
Zip_crc32(buf, crc=crcInitial, offset=0)
Packit d03632
        uLong    crc = NO_INIT
Packit d03632
        STRLEN   len = NO_INIT
Packit d03632
        Bytef *  buf = NO_INIT
Packit d03632
        STRLEN   offset       
Packit d03632
	SV *	 sv = ST(0) ;
Packit d03632
	INIT:
Packit d03632
    	/* If the buffer is a reference, dereference it */
Packit d03632
	sv = deRef(sv, "crc32") ;
Packit d03632
#ifdef UTF8_AVAILABLE    
Packit d03632
    if (DO_UTF8(sv) && !sv_utf8_downgrade(sv, 1))
Packit d03632
         croak("Wide character in Compress::Raw::Zlib::crc32");
Packit d03632
#endif         
Packit d03632
	buf = (Byte*)SvPVbyte(sv, len) ;
Packit d03632
Packit d03632
	if (offset > len)
Packit d03632
	  croak("Offset out of range in Compress::Raw::Zlib::crc32");
Packit d03632
Packit d03632
	if (items < 2)
Packit d03632
	  crc = crcInitial;
Packit d03632
	else if (SvOK(ST(1)))
Packit d03632
	  crc = SvUV(ST(1)) ;
Packit d03632
	else
Packit d03632
	  crc = crcInitial;
Packit d03632
 
Packit d03632
uLong
Packit d03632
crc32_combine(crc1, crc2, len2)
Packit d03632
        uLong    crc1 
Packit d03632
        uLong    crc2 
Packit d03632
        z_off_t   len2 
Packit d03632
	CODE:
Packit d03632
#ifndef AT_LEAST_ZLIB_1_2_2_1
Packit d03632
        crc1 = crc1; crc2 = crc2 ; len2 = len2; /* Silence -Wall */
Packit d03632
        croak("crc32_combine needs zlib 1.2.3 or better");
Packit d03632
#else
Packit d03632
        RETVAL = crc32_combine(crc1, crc2, len2);
Packit d03632
#endif
Packit d03632
    OUTPUT:
Packit d03632
        RETVAL
Packit d03632
Packit d03632
Packit d03632
uLong
Packit d03632
adler32_combine(adler1, adler2, len2)
Packit d03632
        uLong    adler1 
Packit d03632
        uLong    adler2 
Packit d03632
        z_off_t   len2 
Packit d03632
	CODE:
Packit d03632
#ifndef AT_LEAST_ZLIB_1_2_2_1
Packit d03632
        adler1 = adler1; adler2 = adler2 ; len2 = len2; /* Silence -Wall */
Packit d03632
        croak("adler32_combine needs zlib 1.2.3 or better");
Packit d03632
#else
Packit d03632
        RETVAL = adler32_combine(adler1, adler2, len2);
Packit d03632
#endif
Packit d03632
    OUTPUT:
Packit d03632
        RETVAL
Packit d03632
Packit d03632
Packit d03632
MODULE = Compress::Raw::Zlib PACKAGE = Compress::Raw::Zlib
Packit d03632
Packit d03632
void
Packit d03632
_deflateInit(flags,level, method, windowBits, memLevel, strategy, bufsize, dictionary)
Packit d03632
    int flags
Packit d03632
    int	level
Packit d03632
    int method
Packit d03632
    int windowBits
Packit d03632
    int memLevel
Packit d03632
    int strategy
Packit d03632
    uLong bufsize
Packit d03632
    SV* dictionary
Packit d03632
  PPCODE:
Packit d03632
    int err ;
Packit d03632
    deflateStream s ;
Packit d03632
Packit d03632
    if (trace) 
Packit d03632
        warn("in _deflateInit(level=%d, method=%d, windowBits=%d, memLevel=%d, strategy=%d, bufsize=%ld dictionary=%p)\n", 
Packit d03632
	level, method, windowBits, memLevel, strategy, bufsize, dictionary) ;
Packit d03632
    if ((s = InitStream() )) {
Packit d03632
Packit d03632
        s->Level      = level;
Packit d03632
        s->Method     = method;
Packit d03632
        s->WindowBits = windowBits;
Packit d03632
        s->MemLevel   = memLevel;
Packit d03632
        s->Strategy   = strategy;
Packit d03632
Packit d03632
        err = deflateInit2(&(s->stream), level, 
Packit d03632
			   method, windowBits, memLevel, strategy);
Packit d03632
Packit d03632
        if (trace) {
Packit d03632
            warn(" _deflateInit2 returned %d (state %p)\n", err, s);
Packit d03632
            DispStream(s, "INIT");
Packit d03632
        }
Packit d03632
Packit d03632
	/* Check if a dictionary has been specified */
Packit d03632
	SvGETMAGIC(dictionary);
Packit d03632
	if (err == Z_OK && SvPOK(dictionary) && SvCUR(dictionary)) {
Packit d03632
#ifdef UTF8_AVAILABLE    
Packit d03632
            if (DO_UTF8(dictionary) && !sv_utf8_downgrade(dictionary, 1))
Packit d03632
                croak("Wide character in Compress::Raw::Zlib::Deflate::new dicrionary parameter");
Packit d03632
#endif         
Packit d03632
	    err = deflateSetDictionary(&(s->stream), (const Bytef*) SvPVX(dictionary), SvCUR(dictionary)) ;
Packit d03632
        if (trace) 
Packit d03632
            warn("deflateSetDictionary returned %d\n", err);
Packit d03632
	    s->dict_adler = s->stream.adler ;
Packit d03632
	}
Packit d03632
Packit d03632
        if (err != Z_OK) {
Packit d03632
            Safefree(s) ;
Packit d03632
            s = NULL ;
Packit d03632
	}
Packit d03632
	else
Packit d03632
	    PostInitStream(s, flags, bufsize, windowBits) ;
Packit d03632
        
Packit d03632
    }
Packit d03632
    else
Packit d03632
        err = Z_MEM_ERROR ;
Packit d03632
Packit d03632
    {
Packit d03632
        SV* obj = sv_setref_pv(sv_newmortal(), 
Packit d03632
            "Compress::Raw::Zlib::deflateStream", (void*)s);
Packit d03632
        XPUSHs(obj);
Packit d03632
    }
Packit d03632
    if (GIMME == G_ARRAY) {
Packit d03632
        SV * sv = sv_2mortal(newSViv(err)) ;
Packit d03632
	setDUALstatus(sv, err);
Packit d03632
        XPUSHs(sv) ;
Packit d03632
    }
Packit d03632
Packit d03632
void
Packit d03632
_inflateInit(flags, windowBits, bufsize, dictionary)
Packit d03632
    int flags
Packit d03632
    int windowBits
Packit d03632
    uLong bufsize
Packit d03632
    SV * dictionary
Packit d03632
  ALIAS:
Packit d03632
    _inflateScanInit = 1
Packit d03632
  PPCODE:
Packit d03632
 
Packit d03632
    int err = Z_OK ;
Packit d03632
    inflateStream s ;
Packit d03632
#ifndef MAGIC_APPEND
Packit d03632
    if (ix == 1)
Packit d03632
        croak("inflateScanInit needs zlib 1.2.1 or better");
Packit d03632
#endif
Packit d03632
    if (trace)
Packit d03632
        warn("in _inflateInit(windowBits=%d, bufsize=%lu, dictionary=%lu\n",
Packit d03632
                windowBits, bufsize, (unsigned long)SvCUR(dictionary)) ;
Packit d03632
    if ((s = InitStream() )) {
Packit d03632
Packit d03632
        s->WindowBits = windowBits;
Packit d03632
Packit d03632
        err = inflateInit2(&(s->stream), windowBits);
Packit d03632
        if (err != Z_OK) {
Packit d03632
            Safefree(s) ;
Packit d03632
            s = NULL ;
Packit d03632
	}
Packit d03632
	else if (sv_len(dictionary)) {
Packit d03632
#ifdef AT_LEAST_ZLIB_1_2_2_1
Packit d03632
        /* Zlib 1.2.2.1 or better allows a dictionary with raw inflate */
Packit d03632
        if (s->WindowBits < 0) {
Packit d03632
            STRLEN dlen;
Packit d03632
            const Bytef* b = (const Bytef*)SvPVbyte(dictionary, dlen);
Packit d03632
            err = inflateSetDictionary(&(s->stream), 
Packit d03632
                b, dlen);
Packit d03632
            if (err != Z_OK) {
Packit d03632
                Safefree(s) ;
Packit d03632
                s = NULL ;
Packit d03632
            }
Packit d03632
        }
Packit d03632
        else
Packit d03632
#endif
Packit d03632
            /* Dictionary specified - take a copy for use in inflate */
Packit d03632
	    s->dictionary = newSVsv(dictionary) ;
Packit d03632
	}
Packit d03632
	if (s) {
Packit d03632
	    PostInitStream(s, flags, bufsize, windowBits) ;
Packit d03632
#ifdef MAGIC_APPEND
Packit d03632
            if (ix == 1)
Packit d03632
            {
Packit d03632
                s->window = (unsigned char *)safemalloc(WINDOW_SIZE);
Packit d03632
            }
Packit d03632
#endif
Packit d03632
        }
Packit d03632
    }
Packit d03632
    else
Packit d03632
	err = Z_MEM_ERROR ;
Packit d03632
Packit d03632
    {
Packit d03632
        SV* obj = sv_setref_pv(sv_newmortal(), 
Packit d03632
                   ix == 1 
Packit d03632
                   ? "Compress::Raw::Zlib::inflateScanStream" 
Packit d03632
                   :  "Compress::Raw::Zlib::inflateStream",
Packit d03632
                   (void*)s);
Packit d03632
        XPUSHs(obj);
Packit d03632
    }
Packit d03632
    if (GIMME == G_ARRAY) {
Packit d03632
        SV * sv = sv_2mortal(newSViv(err)) ;
Packit d03632
	setDUALstatus(sv, err);
Packit d03632
        XPUSHs(sv) ;
Packit d03632
    }
Packit d03632
 
Packit d03632
Packit d03632
Packit d03632
MODULE = Compress::Raw::Zlib PACKAGE = Compress::Raw::Zlib::deflateStream
Packit d03632
Packit d03632
void
Packit d03632
DispStream(s, message=NULL)
Packit d03632
    Compress::Raw::Zlib::deflateStream   s
Packit d03632
    const char *  message
Packit d03632
Packit d03632
DualType
Packit d03632
deflateReset(s)
Packit d03632
    Compress::Raw::Zlib::deflateStream   s
Packit d03632
  CODE:
Packit d03632
      RETVAL = deflateReset(&(s->stream)) ;
Packit d03632
      if (RETVAL == Z_OK) {
Packit d03632
	  PostInitStream(s, s->flags, s->bufsize, s->WindowBits) ;
Packit d03632
      }
Packit d03632
    OUTPUT:
Packit d03632
      RETVAL
Packit d03632
Packit d03632
DualType 
Packit d03632
deflate (s, buf, output)
Packit d03632
    Compress::Raw::Zlib::deflateStream	s
Packit d03632
    SV *	buf
Packit d03632
    SV * 	output 
Packit d03632
    uInt	cur_length = NO_INIT
Packit d03632
    uInt	increment = NO_INIT
Packit d03632
    uInt	prefix    = NO_INIT
Packit d03632
    int		RETVAL = 0;
Packit d03632
    uLong     bufinc = NO_INIT
Packit d03632
    STRLEN    origlen = NO_INIT
Packit d03632
  CODE:
Packit d03632
    bufinc = s->bufsize;
Packit d03632
Packit d03632
    /* If the input buffer is a reference, dereference it */
Packit d03632
    buf = deRef(buf, "deflate") ;
Packit d03632
 
Packit d03632
    /* initialise the input buffer */
Packit d03632
#ifdef UTF8_AVAILABLE    
Packit d03632
    if (DO_UTF8(buf) && !sv_utf8_downgrade(buf, 1))
Packit d03632
         croak("Wide character in Compress::Raw::Zlib::Deflate::deflate input parameter");
Packit d03632
#endif         
Packit d03632
    s->stream.next_in = (Bytef*)SvPV_nomg(buf, origlen) ;
Packit d03632
    s->stream.avail_in = origlen;
Packit d03632
    
Packit d03632
    if (s->flags & FLAG_CRC32)
Packit d03632
        s->crc32 = crc32(s->crc32, s->stream.next_in, s->stream.avail_in) ;
Packit d03632
Packit d03632
    if (s->flags & FLAG_ADLER32)
Packit d03632
        s->adler32 = adler32(s->adler32, s->stream.next_in, s->stream.avail_in) ;
Packit d03632
Packit d03632
    /* and retrieve the output buffer */
Packit d03632
    output = deRef_l(output, "deflate") ;
Packit d03632
#ifdef UTF8_AVAILABLE    
Packit d03632
    if (DO_UTF8(output) && !sv_utf8_downgrade(output, 1))
Packit d03632
         croak("Wide character in Compress::Raw::Zlib::Deflate::deflate output parameter");
Packit d03632
#endif         
Packit d03632
Packit d03632
    if((s->flags & FLAG_APPEND) != FLAG_APPEND) {
Packit d03632
        SvCUR_set(output, 0);
Packit d03632
        /* sv_setpvn(output, "", 0); */
Packit d03632
    }
Packit d03632
    prefix = cur_length =  SvCUR(output) ;
Packit d03632
    s->stream.next_out = (Bytef*) SvPVX(output) + cur_length;
Packit d03632
    increment =  SvLEN(output) -  cur_length;
Packit d03632
    s->stream.avail_out =  increment;
Packit d03632
#ifdef SETP_BYTE
Packit d03632
    /* Check for saved output from deflateParams */
Packit d03632
    if (s->deflateParams_out_valid) {
Packit d03632
	*(s->stream.next_out) = s->deflateParams_out_byte;
Packit d03632
	++ s->stream.next_out;
Packit d03632
	-- s->stream.avail_out ;
Packit d03632
	s->deflateParams_out_valid = FALSE;
Packit d03632
    }
Packit d03632
#else
Packit d03632
    /* Check for saved output from deflateParams */
Packit d03632
    if (s->deflateParams_out_length) {
Packit d03632
        uLong plen = s->deflateParams_out_length ;
Packit d03632
        /* printf("Copy %lu bytes saved data\n", plen); */
Packit d03632
        if (s->stream.avail_out < plen) {
Packit d03632
            /* printf("GROW from %d to %lu\n", s->stream.avail_out,
Packit d03632
                        SvLEN(output) + plen - s->stream.avail_out);  */
Packit d03632
             s->stream.next_out = (Bytef*) Sv_Grow(output, SvLEN(output) + plen - s->stream.avail_out) ;
Packit d03632
             s->stream.next_out += cur_length;
Packit d03632
        }
Packit d03632
        
Packit d03632
        Copy(s->deflateParams_out_buffer, s->stream.next_out, plen, Bytef) ;	
Packit d03632
        cur_length += plen;
Packit d03632
        SvCUR_set(output, cur_length);
Packit d03632
        s->stream.next_out += plen ;
Packit d03632
        s->stream.avail_out = SvLEN(output) - cur_length ;
Packit d03632
        increment = s->stream.avail_out;
Packit d03632
Packit d03632
        s->deflateParams_out_length = 0;
Packit d03632
        Safefree(s->deflateParams_out_buffer);
Packit d03632
        s->deflateParams_out_buffer = NULL;
Packit d03632
    }
Packit d03632
#endif
Packit d03632
    RETVAL = Z_OK ;
Packit d03632
    while (s->stream.avail_in != 0) {
Packit d03632
Packit d03632
        if (s->stream.avail_out == 0) {
Packit d03632
	    /* out of space in the output buffer so make it bigger */
Packit d03632
            s->stream.next_out = (Bytef*) Sv_Grow(output, SvLEN(output) + bufinc) ;
Packit d03632
            cur_length += increment ;
Packit d03632
            s->stream.next_out += cur_length ;
Packit d03632
            increment = bufinc ;
Packit d03632
            s->stream.avail_out = increment;
Packit d03632
            bufinc *= 2 ;
Packit d03632
        }
Packit d03632
Packit d03632
        if (trace) {
Packit d03632
          printf("DEFLATE Avail In %d, Out %d\n", s->stream.avail_in, s->stream.avail_out); 
Packit d03632
          DispStream(s, "BEFORE");
Packit d03632
          /* Perl_sv_dump(output); */
Packit d03632
        }
Packit d03632
Packit d03632
        RETVAL = deflate(&(s->stream), Z_NO_FLUSH);
Packit d03632
        /*
Packit d03632
        if (RETVAL != Z_STREAM_ERROR) {
Packit d03632
            int done = increment -  s->stream.avail_out ;
Packit d03632
            printf("std DEFLATEr returned %d '%s'  avail in %d, out %d wrote %d\n", RETVAL,
Packit d03632
            GetErrorString(RETVAL), s->stream.avail_in,
Packit d03632
s->stream.avail_out, done); 
Packit d03632
        }
Packit d03632
        */
Packit d03632
    
Packit d03632
        if (trace) {
Packit d03632
            printf("DEFLATE returned %d %s, avail in %d, out %d\n", RETVAL,
Packit d03632
           GetErrorString(RETVAL), s->stream.avail_in, s->stream.avail_out); 
Packit d03632
            DispStream(s, "AFTER");
Packit d03632
        }
Packit d03632
Packit d03632
        if (RETVAL != Z_OK) 
Packit d03632
            break;
Packit d03632
    }
Packit d03632
Packit d03632
    s->compressedBytes += cur_length + increment - prefix - s->stream.avail_out ;
Packit d03632
    s->uncompressedBytes  += origlen - s->stream.avail_in  ;
Packit d03632
Packit d03632
    s->last_error = RETVAL ;
Packit d03632
    if (RETVAL == Z_OK) {
Packit d03632
        SvPOK_only(output);
Packit d03632
        SvCUR_set(output, cur_length + increment - s->stream.avail_out) ;
Packit d03632
        SvSETMAGIC(output);
Packit d03632
    }
Packit d03632
    OUTPUT:
Packit d03632
	RETVAL
Packit d03632
  
Packit d03632
Packit d03632
void
Packit d03632
DESTROY(s)
Packit d03632
    Compress::Raw::Zlib::deflateStream	s
Packit d03632
  CODE:
Packit d03632
    if (trace)
Packit d03632
        printf("Compress::Raw::Zlib::deflateStream::DESTROY %p\n", s);
Packit d03632
    deflateEnd(&s->stream) ;
Packit d03632
    if (s->dictionary)
Packit d03632
	SvREFCNT_dec(s->dictionary) ;
Packit d03632
#ifndef SETP_BYTE
Packit d03632
    if (s->deflateParams_out_buffer)
Packit d03632
        Safefree(s->deflateParams_out_buffer);
Packit d03632
#endif
Packit d03632
    Safefree(s) ;
Packit d03632
Packit d03632
Packit d03632
DualType
Packit d03632
flush(s, output, f=Z_FINISH)
Packit d03632
    Compress::Raw::Zlib::deflateStream	s
Packit d03632
    SV * output 
Packit d03632
    int  f
Packit d03632
    uInt	cur_length = NO_INIT
Packit d03632
    uInt	increment = NO_INIT
Packit d03632
    uInt	prefix    = NO_INIT
Packit d03632
    uLong     bufinc = NO_INIT
Packit d03632
    uLong     availableout = NO_INIT    
Packit d03632
  CODE:
Packit d03632
    bufinc = s->bufsize;
Packit d03632
    
Packit d03632
  
Packit d03632
  
Packit d03632
    /* retrieve the output buffer */
Packit d03632
    output = deRef_l(output, "flush") ;
Packit d03632
#ifdef UTF8_AVAILABLE    
Packit d03632
    if (DO_UTF8(output) && !sv_utf8_downgrade(output, 1))
Packit d03632
         croak("Wide character in Compress::Raw::Zlib::Deflate::flush input parameter");
Packit d03632
#endif         
Packit d03632
    if((s->flags & FLAG_APPEND) != FLAG_APPEND) {
Packit d03632
        SvCUR_set(output, 0);
Packit d03632
        /* sv_setpvn(output, "", 0); */
Packit d03632
    }
Packit d03632
    prefix = cur_length =  SvCUR(output) ;
Packit d03632
    s->stream.next_out = (Bytef*) SvPVX(output) + cur_length;
Packit d03632
    increment =  SvLEN(output) -  cur_length;
Packit d03632
    s->stream.avail_out =  increment;
Packit d03632
#ifdef SETP_BYTE
Packit d03632
    /* Check for saved output from deflateParams */
Packit d03632
    if (s->deflateParams_out_valid) {
Packit d03632
	*(s->stream.next_out) = s->deflateParams_out_byte;
Packit d03632
	++ s->stream.next_out;
Packit d03632
	-- s->stream.avail_out ;
Packit d03632
	s->deflateParams_out_valid = FALSE;
Packit d03632
    }
Packit d03632
#else
Packit d03632
    /* Check for saved output from deflateParams */
Packit d03632
    if (s->deflateParams_out_length) {
Packit d03632
        uLong plen = s->deflateParams_out_length ;
Packit d03632
        /* printf("Copy %lu bytes saved data\n", plen); */
Packit d03632
        if (s->stream.avail_out < plen) {
Packit d03632
            /* printf("GROW from %d to %lu\n", s->stream.avail_out, 
Packit d03632
                        SvLEN(output) + plen - s->stream.avail_out); */
Packit d03632
            s->stream.next_out = (Bytef*) Sv_Grow(output, SvLEN(output) + plen - s->stream.avail_out) ;
Packit d03632
            s->stream.next_out += cur_length;
Packit d03632
        }
Packit d03632
        
Packit d03632
        Copy(s->deflateParams_out_buffer, s->stream.next_out, plen, Bytef) ;	
Packit d03632
        cur_length += plen;
Packit d03632
        SvCUR_set(output, cur_length);
Packit d03632
        s->stream.next_out += plen ;
Packit d03632
        s->stream.avail_out = SvLEN(output) - cur_length ;
Packit d03632
        increment = s->stream.avail_out;
Packit d03632
Packit d03632
        s->deflateParams_out_length = 0;
Packit d03632
        Safefree(s->deflateParams_out_buffer);
Packit d03632
        s->deflateParams_out_buffer = NULL;
Packit d03632
    }
Packit d03632
#endif
Packit d03632
Packit d03632
    for (;;) {
Packit d03632
        if (s->stream.avail_out == 0) {        
Packit d03632
            /* consumed all the available output, so extend it */
Packit d03632
            s->stream.next_out = (Bytef*) Sv_Grow(output, SvLEN(output) + bufinc) ;
Packit d03632
            cur_length += increment ;
Packit d03632
            s->stream.next_out += cur_length ;
Packit d03632
            increment = bufinc ;
Packit d03632
            s->stream.avail_out = increment;
Packit d03632
            bufinc *= 2 ;
Packit d03632
        }
Packit d03632
        
Packit d03632
        availableout = s->stream.avail_out ;
Packit d03632
        
Packit d03632
        if (trace) {
Packit d03632
          printf("flush (%d) DEFLATE Avail In %d, Out %d\n", f, s->stream.avail_in, s->stream.avail_out); 
Packit d03632
          DispStream(s, "BEFORE");
Packit d03632
          /* Perl_sv_dump(output); */
Packit d03632
        }
Packit d03632
Packit d03632
        RETVAL = deflate(&(s->stream), f);
Packit d03632
        /*
Packit d03632
        if (RETVAL != Z_STREAM_ERROR) {
Packit d03632
            int done = availableout -  s->stream.avail_out ;
Packit d03632
            printf("flush DEFLATEr returned %d '%s'  avail in %d, out %d wrote %d\n", RETVAL,
Packit d03632
            GetErrorString(RETVAL), s->stream.avail_in,
Packit d03632
s->stream.avail_out, done);
Packit d03632
        }
Packit d03632
        */
Packit d03632
    
Packit d03632
        if (trace) {
Packit d03632
            printf("flush DEFLATE returned %d '%s', avail in %d, out %d\n", RETVAL,
Packit d03632
            GetErrorString(RETVAL), s->stream.avail_in, s->stream.avail_out); 
Packit d03632
            DispStream(s, "AFTER");
Packit d03632
        }
Packit d03632
Packit d03632
        /* Ignore the second of two consecutive flushes: */
Packit d03632
        if (availableout == s->stream.avail_out && RETVAL == Z_BUF_ERROR) 
Packit d03632
            RETVAL = Z_OK; 
Packit d03632
        
Packit d03632
        /* deflate has finished flushing only when it hasn't used up
Packit d03632
         * all the available space in the output buffer: 
Packit d03632
         */
Packit d03632
        if (s->stream.avail_out != 0 || RETVAL != Z_OK )
Packit d03632
            break;
Packit d03632
    }
Packit d03632
  
Packit d03632
    RETVAL =  (RETVAL == Z_STREAM_END ? Z_OK : RETVAL) ;
Packit d03632
    s->last_error = RETVAL ;
Packit d03632
Packit d03632
    s->compressedBytes    += cur_length + increment - prefix - s->stream.avail_out ;
Packit d03632
  
Packit d03632
    if (RETVAL == Z_OK) {
Packit d03632
        SvPOK_only(output);
Packit d03632
        SvCUR_set(output, cur_length + increment - s->stream.avail_out) ;
Packit d03632
        SvSETMAGIC(output);
Packit d03632
    }
Packit d03632
    OUTPUT:
Packit d03632
	RETVAL
Packit d03632
Packit d03632
Packit d03632
DualType
Packit d03632
_deflateParams(s, flags, level, strategy, bufsize)
Packit d03632
  	Compress::Raw::Zlib::deflateStream	s
Packit d03632
	int 	flags
Packit d03632
	int	level
Packit d03632
	int	strategy
Packit d03632
    	uLong	bufsize
Packit d03632
	bool changed = FALSE;
Packit d03632
    CODE:
Packit d03632
        /* printf("_deflateParams(Flags %d Level %d Strategy %d Bufsize %d)\n", flags, level, strategy, bufsize); 
Packit d03632
        printf("Before -- Level %d, Strategy %d, Bufsize %d\n", s->Level, s->Strategy, s->bufsize); */
Packit d03632
        if (flags & 1 && level != s->Level) {
Packit d03632
            s->Level = level ;
Packit d03632
            changed = TRUE;
Packit d03632
        }
Packit d03632
        if (flags & 2 && strategy != s->Strategy) {
Packit d03632
            s->Strategy = strategy ;
Packit d03632
            changed = TRUE;
Packit d03632
        }
Packit d03632
        if (flags & 4)
Packit d03632
            s->bufsize = bufsize; 
Packit d03632
        if (changed) {
Packit d03632
#ifdef SETP_BYTE
Packit d03632
            s->stream.avail_in = 0; 
Packit d03632
            s->stream.next_out = &(s->deflateParams_out_byte) ;
Packit d03632
            s->stream.avail_out = 1;
Packit d03632
            RETVAL = deflateParams(&(s->stream), s->Level, s->Strategy);
Packit d03632
            s->deflateParams_out_valid = 
Packit d03632
            (RETVAL == Z_OK && s->stream.avail_out == 0) ;
Packit d03632
#else
Packit d03632
            /* printf("Level %d Strategy %d, Prev Len %d\n", 
Packit d03632
                s->Level, s->Strategy, s->deflateParams_out_length); */
Packit d03632
            RETVAL = flushParams(s);
Packit d03632
#endif
Packit d03632
        }
Packit d03632
        else
Packit d03632
            RETVAL = Z_OK;
Packit d03632
    OUTPUT:
Packit d03632
        RETVAL
Packit d03632
Packit d03632
Packit d03632
int
Packit d03632
get_Level(s)
Packit d03632
        Compress::Raw::Zlib::deflateStream   s
Packit d03632
    CODE:
Packit d03632
	RETVAL = s->Level ;
Packit d03632
    OUTPUT:
Packit d03632
	RETVAL
Packit d03632
Packit d03632
int
Packit d03632
get_Strategy(s)
Packit d03632
        Compress::Raw::Zlib::deflateStream   s
Packit d03632
    CODE:
Packit d03632
	RETVAL = s->Strategy ;
Packit d03632
    OUTPUT:
Packit d03632
	RETVAL
Packit d03632
Packit d03632
Packit d03632
uLong
Packit d03632
get_Bufsize(s)
Packit d03632
        Compress::Raw::Zlib::deflateStream   s
Packit d03632
    CODE:
Packit d03632
	RETVAL = s->bufsize ;
Packit d03632
    OUTPUT:
Packit d03632
	RETVAL
Packit d03632
Packit d03632
Packit d03632
int
Packit d03632
status(s)
Packit d03632
        Compress::Raw::Zlib::deflateStream   s
Packit d03632
    CODE:
Packit d03632
	RETVAL = s->last_error ;
Packit d03632
    OUTPUT:
Packit d03632
	RETVAL
Packit d03632
Packit d03632
uLong
Packit d03632
crc32(s)
Packit d03632
        Compress::Raw::Zlib::deflateStream   s
Packit d03632
    CODE:
Packit d03632
	RETVAL = s->crc32 ;
Packit d03632
    OUTPUT:
Packit d03632
	RETVAL
Packit d03632
Packit d03632
uLong
Packit d03632
dict_adler(s)
Packit d03632
        Compress::Raw::Zlib::deflateStream   s
Packit d03632
    CODE:
Packit d03632
	RETVAL = s->dict_adler ;
Packit d03632
    OUTPUT:
Packit d03632
	RETVAL
Packit d03632
Packit d03632
uLong
Packit d03632
adler32(s)
Packit d03632
        Compress::Raw::Zlib::deflateStream   s
Packit d03632
    CODE:
Packit d03632
	RETVAL = s->adler32 ;
Packit d03632
    OUTPUT:
Packit d03632
	RETVAL
Packit d03632
Packit d03632
uLong
Packit d03632
compressedBytes(s)
Packit d03632
    Compress::Raw::Zlib::deflateStream	s
Packit d03632
    CODE:
Packit d03632
        RETVAL = s->compressedBytes;
Packit d03632
  OUTPUT:
Packit d03632
	RETVAL
Packit d03632
Packit d03632
uLong
Packit d03632
uncompressedBytes(s)
Packit d03632
    Compress::Raw::Zlib::deflateStream	s
Packit d03632
    CODE:
Packit d03632
        RETVAL = s->uncompressedBytes;
Packit d03632
  OUTPUT:
Packit d03632
	RETVAL
Packit d03632
Packit d03632
uLong
Packit d03632
total_in(s)
Packit d03632
        Compress::Raw::Zlib::deflateStream   s
Packit d03632
    CODE:
Packit d03632
        RETVAL = s->stream.total_in ;
Packit d03632
    OUTPUT:
Packit d03632
	RETVAL
Packit d03632
Packit d03632
uLong
Packit d03632
total_out(s)
Packit d03632
        Compress::Raw::Zlib::deflateStream   s
Packit d03632
    CODE:
Packit d03632
        RETVAL = s->stream.total_out ;
Packit d03632
    OUTPUT:
Packit d03632
	RETVAL
Packit d03632
Packit d03632
char*
Packit d03632
msg(s)
Packit d03632
        Compress::Raw::Zlib::deflateStream   s
Packit d03632
    CODE:
Packit d03632
	RETVAL = s->stream.msg;
Packit d03632
    OUTPUT:
Packit d03632
	RETVAL
Packit d03632
Packit d03632
int 
Packit d03632
deflateTune(s, good_length, max_lazy, nice_length, max_chain)
Packit d03632
            Compress::Raw::Zlib::deflateStream   s
Packit d03632
            int good_length
Packit d03632
            int max_lazy
Packit d03632
            int nice_length
Packit d03632
            int max_chain
Packit d03632
    CODE:
Packit d03632
#ifndef AT_LEAST_ZLIB_1_2_2_3
Packit d03632
        good_length = good_length; max_lazy = max_lazy ; /* Silence -Wall */
Packit d03632
        nice_length = nice_length; max_chain = max_chain; /* Silence -Wall */
Packit d03632
        croak("deflateTune needs zlib 1.2.2.3 or better");
Packit d03632
#else
Packit d03632
	RETVAL = deflateTune(&(s->stream), good_length, max_lazy, nice_length, max_chain);
Packit d03632
#endif
Packit d03632
    OUTPUT:
Packit d03632
	RETVAL
Packit d03632
    
Packit d03632
Packit d03632
MODULE = Compress::Raw::Zlib PACKAGE = Compress::Raw::Zlib::inflateStream
Packit d03632
Packit d03632
void
Packit d03632
DispStream(s, message=NULL)
Packit d03632
    Compress::Raw::Zlib::inflateStream   s
Packit d03632
    const char *  message
Packit d03632
Packit d03632
DualType
Packit d03632
inflateReset(s)
Packit d03632
    Compress::Raw::Zlib::inflateStream   s
Packit d03632
  CODE:
Packit d03632
      RETVAL = inflateReset(&(s->stream)) ;
Packit d03632
      if (RETVAL == Z_OK) {
Packit d03632
	  PostInitStream(s, s->flags, s->bufsize, s->WindowBits) ;
Packit d03632
      }
Packit d03632
    OUTPUT:
Packit d03632
      RETVAL
Packit d03632
Packit d03632
DualType 
Packit d03632
inflate (s, buf, output, eof=FALSE)
Packit d03632
    Compress::Raw::Zlib::inflateStream	s
Packit d03632
    SV *	buf
Packit d03632
    SV * 	output 
Packit d03632
    bool 	eof 
Packit d03632
    uInt	cur_length = 0;
Packit d03632
    uInt	prefix_length = 0;
Packit d03632
    int	    increment = 0;
Packit d03632
    uLong   bufinc = NO_INIT
Packit d03632
    STRLEN  na = NO_INIT ;
Packit d03632
  PREINIT:
Packit d03632
#ifdef UTF8_AVAILABLE    
Packit d03632
    bool	out_utf8  = FALSE;
Packit d03632
#endif    
Packit d03632
    STRLEN	origlen;
Packit d03632
  CODE: 
Packit d03632
    bufinc = s->bufsize;
Packit d03632
    /* If the buffer is a reference, dereference it */
Packit d03632
    buf = deRef(buf, "inflate") ;
Packit d03632
Packit d03632
    if (s->flags & FLAG_CONSUME_INPUT) {
Packit d03632
        if (SvREADONLY(buf))
Packit d03632
            croak("Compress::Raw::Zlib::Inflate::inflate input parameter cannot be read-only when ConsumeInput is specified");
Packit d03632
        SvPV_force(buf, na);
Packit d03632
    }
Packit d03632
#ifdef UTF8_AVAILABLE    
Packit d03632
    if (DO_UTF8(buf) && !sv_utf8_downgrade(buf, 1))
Packit d03632
         croak("Wide character in Compress::Raw::Zlib::Inflate::inflate input parameter");
Packit d03632
#endif         
Packit d03632
    
Packit d03632
    /* initialise the input buffer */
Packit d03632
    s->stream.next_in = (Bytef*)SvPV_nomg(buf, origlen) ;
Packit d03632
    s->stream.avail_in = origlen ;
Packit d03632
	
Packit d03632
    /* and retrieve the output buffer */
Packit d03632
    output = deRef_l(output, "inflate") ;
Packit d03632
#ifdef UTF8_AVAILABLE    
Packit d03632
    if (DO_UTF8(output))
Packit d03632
         out_utf8 = TRUE ;
Packit d03632
    if (DO_UTF8(output) && !sv_utf8_downgrade(output, 1))
Packit d03632
         croak("Wide character in Compress::Raw::Zlib::Inflate::inflate output parameter");
Packit d03632
#endif         
Packit d03632
    if((s->flags & FLAG_APPEND) != FLAG_APPEND) {
Packit d03632
        SvCUR_set(output, 0);
Packit d03632
    }
Packit d03632
   
Packit d03632
    /* Assume no output buffer - the code below will update if there is any available */
Packit d03632
    s->stream.avail_out = 0;
Packit d03632
Packit d03632
Packit d03632
    if (SvLEN(output)) {
Packit d03632
        prefix_length = cur_length =  SvCUR(output) ;
Packit d03632
    
Packit d03632
        if (s->flags & FLAG_LIMIT_OUTPUT && SvLEN(output) - cur_length - 1 < bufinc)
Packit d03632
        {
Packit d03632
            Sv_Grow(output, bufinc + cur_length + 1) ;
Packit d03632
        }
Packit d03632
    
Packit d03632
        /* Only setup the stream output pointers if there is spare 
Packit d03632
           capacity in the outout SV
Packit d03632
        */
Packit d03632
        if (SvLEN(output) > cur_length + 1)
Packit d03632
        {
Packit d03632
            s->stream.next_out = (Bytef*) SvPV_nomg_nolen(output) + cur_length;
Packit d03632
            increment = SvLEN(output) -  cur_length - 1;
Packit d03632
            s->stream.avail_out = increment;
Packit d03632
        }
Packit d03632
    }
Packit d03632
    
Packit d03632
Packit d03632
    s->bytesInflated = 0;
Packit d03632
    
Packit d03632
    RETVAL = Z_OK;
Packit d03632
Packit d03632
    while (RETVAL == Z_OK) {
Packit d03632
        if (s->stream.avail_out == 0) {
Packit d03632
	    /* out of space in the output buffer so make it bigger */
Packit d03632
            s->stream.next_out = (Bytef*) Sv_Grow(output, SvLEN(output) + bufinc +1) ;
Packit d03632
            cur_length += increment ;
Packit d03632
            s->stream.next_out += cur_length ;
Packit d03632
            increment = bufinc ;
Packit d03632
            s->stream.avail_out = increment;
Packit d03632
            bufinc *= 2 ; 
Packit d03632
        }
Packit d03632
Packit d03632
        /* printf("INFLATE Availl In %d, Out %d\n", s->stream.avail_in,
Packit d03632
 s->stream.avail_out); 
Packit d03632
DispStream(s, "BEFORE");
Packit d03632
Perl_sv_dump(output); */
Packit d03632
        RETVAL = inflate(&(s->stream), Z_SYNC_FLUSH);
Packit d03632
        /* printf("INFLATE returned %d %s, avail in %d, out %d\n", RETVAL,
Packit d03632
 GetErrorString(RETVAL), s->stream.avail_in, s->stream.avail_out); */
Packit d03632
Packit d03632
    
Packit d03632
        if (RETVAL == Z_NEED_DICT && s->dictionary) {
Packit d03632
            STRLEN dlen;
Packit d03632
            const Bytef* b = (const Bytef*)SvPV(s->dictionary, dlen) ;
Packit d03632
            s->dict_adler = s->stream.adler ;
Packit d03632
            RETVAL = inflateSetDictionary(&(s->stream), 
Packit d03632
                b, dlen);
Packit d03632
            if (RETVAL == Z_OK)
Packit d03632
                continue;
Packit d03632
        }
Packit d03632
        
Packit d03632
        if (s->flags & FLAG_LIMIT_OUTPUT && 
Packit d03632
                (RETVAL == Z_OK || RETVAL == Z_BUF_ERROR )) {
Packit d03632
            if (s->stream.avail_out == 0)
Packit d03632
                RETVAL = Z_BUF_ERROR;
Packit d03632
            break;
Packit d03632
        }
Packit d03632
        if (s->flags & FLAG_LIMIT_OUTPUT && 
Packit d03632
                (RETVAL == Z_OK || RETVAL == Z_BUF_ERROR ))
Packit d03632
            break;
Packit d03632
Packit d03632
        if (RETVAL == Z_STREAM_ERROR || RETVAL == Z_MEM_ERROR ||
Packit d03632
            RETVAL == Z_DATA_ERROR   || RETVAL == Z_STREAM_END )
Packit d03632
            break ;
Packit d03632
Packit d03632
        if (RETVAL == Z_BUF_ERROR) {
Packit d03632
            if (s->stream.avail_out == 0)
Packit d03632
                continue ;
Packit d03632
            if (s->stream.avail_in == 0) {
Packit d03632
                RETVAL = Z_OK ;
Packit d03632
                break ;
Packit d03632
            }
Packit d03632
        }
Packit d03632
    }
Packit d03632
#ifdef NEED_DUMMY_BYTE_AT_END 
Packit d03632
    if (eof && RETVAL == Z_OK && s->flags & FLAG_LIMIT_OUTPUT == 0) {
Packit d03632
        Bytef* nextIn =  s->stream.next_in;
Packit d03632
        uInt availIn =  s->stream.avail_in;
Packit d03632
        s->stream.next_in = (Bytef*) " ";
Packit d03632
        s->stream.avail_in = 1;
Packit d03632
        if (s->stream.avail_out == 0) {
Packit d03632
	    /* out of space in the output buffer so make it bigger */
Packit d03632
            s->stream.next_out = Sv_Grow(output, SvLEN(output) + bufinc) ;
Packit d03632
            cur_length += increment ;
Packit d03632
            s->stream.next_out += cur_length ;
Packit d03632
            increment = bufinc ;
Packit d03632
            s->stream.avail_out = increment;
Packit d03632
            bufinc *= 2 ;
Packit d03632
        }
Packit d03632
        RETVAL = inflate(&(s->stream), Z_SYNC_FLUSH);
Packit d03632
        s->stream.next_in = nextIn ;
Packit d03632
        s->stream.avail_in  = availIn ;
Packit d03632
    }
Packit d03632
#else
Packit d03632
    PERL_UNUSED_VAR(eof);
Packit d03632
#endif
Packit d03632
    
Packit d03632
    s->last_error = RETVAL ;
Packit d03632
    if (RETVAL == Z_OK || RETVAL == Z_STREAM_END || RETVAL == Z_BUF_ERROR || RETVAL == Z_DATA_ERROR) {
Packit d03632
	   unsigned in ;
Packit d03632
Packit d03632
        s->bytesInflated = cur_length + increment - s->stream.avail_out - prefix_length;
Packit d03632
        s->uncompressedBytes += s->bytesInflated ;
Packit d03632
        s->compressedBytes   += origlen - s->stream.avail_in  ;
Packit d03632
Packit d03632
        SvPOK_only(output);
Packit d03632
        SvCUR_set(output, prefix_length + s->bytesInflated) ;
Packit d03632
	*SvEND(output) = '\0';
Packit d03632
#ifdef UTF8_AVAILABLE    
Packit d03632
        if (out_utf8)
Packit d03632
            sv_utf8_upgrade(output);
Packit d03632
#endif        
Packit d03632
        SvSETMAGIC(output);
Packit d03632
Packit d03632
        if (s->flags & FLAG_CRC32 )
Packit d03632
            s->crc32 = crc32(s->crc32, 
Packit d03632
				(const Bytef*)SvPVX(output)+prefix_length, 
Packit d03632
            			SvCUR(output)-prefix_length) ;
Packit d03632
Packit d03632
        if (s->flags & FLAG_ADLER32) 
Packit d03632
            s->adler32 = adler32(s->adler32, 
Packit d03632
				(const Bytef*)SvPVX(output)+prefix_length, 
Packit d03632
            			SvCUR(output)-prefix_length) ;
Packit d03632
Packit d03632
	/* fix the input buffer */
Packit d03632
	if (s->flags & FLAG_CONSUME_INPUT || s->flags & FLAG_LIMIT_OUTPUT) {
Packit d03632
	    in = s->stream.avail_in ;
Packit d03632
	    SvCUR_set(buf, in) ;
Packit d03632
	    if (in)
Packit d03632
	        Move(s->stream.next_in, SvPVX(buf), in, char) ;	
Packit d03632
            *SvEND(buf) = '\0';
Packit d03632
            SvSETMAGIC(buf);
Packit d03632
	}
Packit d03632
Packit d03632
    }
Packit d03632
    OUTPUT:
Packit d03632
	RETVAL
Packit d03632
Packit d03632
uLong
Packit d03632
inflateCount(s)
Packit d03632
    Compress::Raw::Zlib::inflateStream	s
Packit d03632
    CODE:
Packit d03632
        RETVAL = s->bytesInflated;
Packit d03632
  OUTPUT:
Packit d03632
	RETVAL
Packit d03632
Packit d03632
uLong
Packit d03632
compressedBytes(s)
Packit d03632
    Compress::Raw::Zlib::inflateStream	s
Packit d03632
    CODE:
Packit d03632
        RETVAL = s->compressedBytes;
Packit d03632
  OUTPUT:
Packit d03632
	RETVAL
Packit d03632
Packit d03632
uLong
Packit d03632
uncompressedBytes(s)
Packit d03632
    Compress::Raw::Zlib::inflateStream	s
Packit d03632
    CODE:
Packit d03632
        RETVAL = s->uncompressedBytes;
Packit d03632
  OUTPUT:
Packit d03632
	RETVAL
Packit d03632
Packit d03632
Packit d03632
DualType 
Packit d03632
inflateSync (s, buf)
Packit d03632
    Compress::Raw::Zlib::inflateStream	s
Packit d03632
    SV *	buf
Packit d03632
  CODE:
Packit d03632
  
Packit d03632
    /* If the buffer is a reference, dereference it */
Packit d03632
    buf = deRef(buf, "inflateSync") ;
Packit d03632
#ifdef UTF8_AVAILABLE    
Packit d03632
    if (DO_UTF8(buf) && !sv_utf8_downgrade(buf, 1))
Packit d03632
         croak("Wide character in Compress::Raw::Zlib::Inflate::inflateSync");
Packit d03632
#endif         
Packit d03632
    
Packit d03632
    /* initialise the input buffer */
Packit d03632
    s->stream.next_in = (Bytef*)SvPV_force_nomg_nolen(buf) ;
Packit d03632
    s->stream.avail_in = SvCUR(buf) ;
Packit d03632
	
Packit d03632
    /* inflateSync doesn't create any output */
Packit d03632
    s->stream.next_out = (Bytef*) NULL;
Packit d03632
    s->stream.avail_out = 0;
Packit d03632
Packit d03632
    RETVAL = inflateSync(&(s->stream));
Packit d03632
    s->last_error = RETVAL ;
Packit d03632
Packit d03632
    /* fix the input buffer */
Packit d03632
    {
Packit d03632
	unsigned in = s->stream.avail_in ;
Packit d03632
 	SvCUR_set(buf, in) ;
Packit d03632
 	if (in)
Packit d03632
     	    Move(s->stream.next_in, SvPVX(buf), in, char) ;	
Packit d03632
        *SvEND(buf) = '\0';
Packit d03632
        SvSETMAGIC(buf);
Packit d03632
    }
Packit d03632
    OUTPUT:
Packit d03632
	RETVAL
Packit d03632
Packit d03632
void
Packit d03632
DESTROY(s)
Packit d03632
    Compress::Raw::Zlib::inflateStream	s
Packit d03632
  CODE:
Packit d03632
    inflateEnd(&s->stream) ;
Packit d03632
    if (s->dictionary)
Packit d03632
	SvREFCNT_dec(s->dictionary) ;
Packit d03632
#ifndef SETP_BYTE
Packit d03632
    if (s->deflateParams_out_buffer)
Packit d03632
        Safefree(s->deflateParams_out_buffer);
Packit d03632
#endif
Packit d03632
#ifdef MAGIC_APPEND
Packit d03632
    if (s->window)
Packit d03632
        Safefree(s->window);
Packit d03632
#endif
Packit d03632
    Safefree(s) ;
Packit d03632
Packit d03632
Packit d03632
uLong
Packit d03632
status(s)
Packit d03632
        Compress::Raw::Zlib::inflateStream   s
Packit d03632
    CODE:
Packit d03632
	RETVAL = s->last_error ;
Packit d03632
    OUTPUT:
Packit d03632
	RETVAL
Packit d03632
Packit d03632
uLong
Packit d03632
crc32(s)
Packit d03632
        Compress::Raw::Zlib::inflateStream   s
Packit d03632
    CODE:
Packit d03632
	RETVAL = s->crc32 ;
Packit d03632
    OUTPUT:
Packit d03632
	RETVAL
Packit d03632
Packit d03632
uLong
Packit d03632
dict_adler(s)
Packit d03632
        Compress::Raw::Zlib::inflateStream   s
Packit d03632
    CODE:
Packit d03632
	RETVAL = s->dict_adler ;
Packit d03632
    OUTPUT:
Packit d03632
	RETVAL
Packit d03632
Packit d03632
uLong
Packit d03632
total_in(s)
Packit d03632
        Compress::Raw::Zlib::inflateStream   s
Packit d03632
    CODE:
Packit d03632
        RETVAL = s->stream.total_in ;
Packit d03632
    OUTPUT:
Packit d03632
	RETVAL
Packit d03632
Packit d03632
uLong
Packit d03632
adler32(s)
Packit d03632
        Compress::Raw::Zlib::inflateStream   s
Packit d03632
    CODE:
Packit d03632
	RETVAL = s->adler32 ;
Packit d03632
    OUTPUT:
Packit d03632
	RETVAL
Packit d03632
Packit d03632
uLong
Packit d03632
total_out(s)
Packit d03632
        Compress::Raw::Zlib::inflateStream   s
Packit d03632
    CODE:
Packit d03632
        RETVAL = s->stream.total_out ;
Packit d03632
    OUTPUT:
Packit d03632
	RETVAL
Packit d03632
Packit d03632
char*
Packit d03632
msg(s)
Packit d03632
	Compress::Raw::Zlib::inflateStream   s
Packit d03632
    CODE:
Packit d03632
	RETVAL = s->stream.msg;
Packit d03632
    OUTPUT:
Packit d03632
	RETVAL
Packit d03632
Packit d03632
Packit d03632
uLong
Packit d03632
get_Bufsize(s)
Packit d03632
        Compress::Raw::Zlib::inflateStream   s
Packit d03632
    CODE:
Packit d03632
	RETVAL = s->bufsize ;
Packit d03632
    OUTPUT:
Packit d03632
	RETVAL
Packit d03632
Packit d03632
bool
Packit d03632
set_Append(s, mode)
Packit d03632
        Compress::Raw::Zlib::inflateStream   s
Packit d03632
	bool	mode
Packit d03632
    CODE:
Packit d03632
        RETVAL = ((s->flags & FLAG_APPEND) == FLAG_APPEND);
Packit d03632
	if (mode)
Packit d03632
	    s->flags |= FLAG_APPEND ;
Packit d03632
	else
Packit d03632
	    s->flags &= ~FLAG_APPEND ;
Packit d03632
    OUTPUT:
Packit d03632
        RETVAL
Packit d03632
Packit d03632
MODULE = Compress::Raw::Zlib PACKAGE = Compress::Raw::Zlib::inflateScanStream
Packit d03632
Packit d03632
void
Packit d03632
DESTROY(s)
Packit d03632
    Compress::Raw::Zlib::inflateScanStream	s
Packit d03632
  CODE:
Packit d03632
    inflateEnd(&s->stream) ;
Packit d03632
    if (s->dictionary)
Packit d03632
	SvREFCNT_dec(s->dictionary) ;
Packit d03632
#ifndef SETP_BYTE
Packit d03632
    if (s->deflateParams_out_buffer)
Packit d03632
        Safefree(s->deflateParams_out_buffer);
Packit d03632
#endif
Packit d03632
#ifdef MAGIC_APPEND
Packit d03632
    if (s->window)
Packit d03632
        Safefree(s->window);
Packit d03632
#endif
Packit d03632
    Safefree(s) ;
Packit d03632
Packit d03632
void
Packit d03632
DispStream(s, message=NULL)
Packit d03632
    Compress::Raw::Zlib::inflateScanStream   s
Packit d03632
    const char *  message
Packit d03632
Packit d03632
DualType
Packit d03632
inflateReset(s)
Packit d03632
    Compress::Raw::Zlib::inflateScanStream   s
Packit d03632
  CODE:
Packit d03632
      RETVAL = inflateReset(&(s->stream)) ;
Packit d03632
      if (RETVAL == Z_OK) {
Packit d03632
	  PostInitStream(s, s->flags, s->bufsize, s->WindowBits) ;
Packit d03632
      }
Packit d03632
    OUTPUT:
Packit d03632
      RETVAL
Packit d03632
Packit d03632
DualType 
Packit d03632
scan(s, buf, out=NULL, eof=FALSE)
Packit d03632
    Compress::Raw::Zlib::inflateScanStream	s
Packit d03632
    SV *	buf
Packit d03632
    SV *	out
Packit d03632
    bool	eof
Packit d03632
    bool	eof_mode = FALSE;
Packit d03632
    int    start_len = NO_INIT
Packit d03632
  CODE:
Packit d03632
    PERL_UNUSED_VAR(out);
Packit d03632
    PERL_UNUSED_VAR(eof);
Packit d03632
    /* If the input buffer is a reference, dereference it */
Packit d03632
#ifndef MAGIC_APPEND
Packit d03632
        buf = buf;
Packit d03632
        croak("scan needs zlib 1.2.1 or better");
Packit d03632
#else
Packit d03632
    buf = deRef(buf, "inflateScan") ;
Packit d03632
#ifdef UTF8_AVAILABLE    
Packit d03632
    if (DO_UTF8(buf) && !sv_utf8_downgrade(buf, 1))
Packit d03632
        croak("Wide character in Compress::Raw::Zlib::InflateScan::scan input parameter");
Packit d03632
#endif         
Packit d03632
    /* initialise the input buffer */
Packit d03632
    s->stream.next_in = (Bytef*)SvPV_force_nomg_nolen(buf) ;
Packit d03632
    s->stream.avail_in = SvCUR(buf) ;
Packit d03632
    start_len = s->stream.avail_in ;
Packit d03632
    s->bytesInflated = 0 ; 
Packit d03632
    do
Packit d03632
    {
Packit d03632
        if (s->stream.avail_in == 0) {
Packit d03632
            RETVAL = Z_OK ;
Packit d03632
            break ;
Packit d03632
        }
Packit d03632
Packit d03632
        /* set up output to next available section of sliding window */
Packit d03632
        s->stream.avail_out = WINDOW_SIZE - s->window_have;
Packit d03632
        s->stream.next_out = s->window + s->window_have;
Packit d03632
Packit d03632
        /* DispStream(s, "before inflate\n"); */
Packit d03632
Packit d03632
        /* inflate and check for errors */
Packit d03632
        RETVAL = inflate(&(s->stream), Z_BLOCK);
Packit d03632
Packit d03632
        if (start_len > 1 && ! eof_mode)
Packit d03632
            s->window_lastByte = *(s->stream.next_in - 1 ) ;
Packit d03632
Packit d03632
        if (RETVAL == Z_STREAM_ERROR || RETVAL == Z_MEM_ERROR ||
Packit d03632
            RETVAL == Z_DATA_ERROR )
Packit d03632
            break ;
Packit d03632
Packit d03632
        if (s->flags & FLAG_CRC32 )
Packit d03632
            s->crc32 = crc32(s->crc32, s->window + s->window_have, 
Packit d03632
                             WINDOW_SIZE - s->window_have - s->stream.avail_out);
Packit d03632
Packit d03632
        if (s->flags & FLAG_ADLER32) 
Packit d03632
            s->adler32 = adler32(s->adler32, s->window + s->window_have, 
Packit d03632
                                 WINDOW_SIZE - s->window_have - s->stream.avail_out);
Packit d03632
Packit d03632
        s->uncompressedBytes =
Packit d03632
        s->bytesInflated += WINDOW_SIZE - s->window_have - s->stream.avail_out;
Packit d03632
Packit d03632
        if (s->stream.avail_out)
Packit d03632
            s->window_have = WINDOW_SIZE - s->stream.avail_out;
Packit d03632
        else {
Packit d03632
            s->window_have = 0;
Packit d03632
            s->window_full = 1;
Packit d03632
        }
Packit d03632
Packit d03632
        /* process end of block */
Packit d03632
        if (s->stream.data_type & 128) {
Packit d03632
            if (s->stream.data_type & 64) {
Packit d03632
                s->window_left = s->stream.data_type & 0x1f;
Packit d03632
            }
Packit d03632
            else {
Packit d03632
                s->window_lastbit = s->stream.data_type & 0x1f;
Packit d03632
                s->lastBlockOffset = s->stream.total_in;
Packit d03632
            }
Packit d03632
        }
Packit d03632
Packit d03632
    } while (RETVAL != Z_STREAM_END);
Packit d03632
Packit d03632
    s->last_error = RETVAL ;
Packit d03632
    s->window_lastoff = s->stream.total_in ;
Packit d03632
    s->compressedBytes += SvCUR(buf) - s->stream.avail_in  ;
Packit d03632
Packit d03632
    if (RETVAL == Z_STREAM_END)
Packit d03632
    {
Packit d03632
        s->matchedEndBlock = 1 ;
Packit d03632
Packit d03632
        /* save the location of the end of the compressed data */
Packit d03632
        s->window_end = SvCUR(buf) - s->stream.avail_in - 1 ;
Packit d03632
        s->window_endOffset = s->stream.total_in ;
Packit d03632
        if (s->window_left)
Packit d03632
        {
Packit d03632
            -- s->window_endOffset ;
Packit d03632
        }
Packit d03632
Packit d03632
        /* if window wrapped, build dictionary from window by rotating */
Packit d03632
        if (s->window_full) {
Packit d03632
            rotate(s->window, WINDOW_SIZE, s->window_have);
Packit d03632
            s->window_have = WINDOW_SIZE;
Packit d03632
        }
Packit d03632
Packit d03632
        /* if (s->flags & FLAG_CONSUME_INPUT) { */
Packit d03632
        if (1) {
Packit d03632
            unsigned in = s->stream.avail_in ;
Packit d03632
            SvCUR_set(buf, in) ;
Packit d03632
            if (in)
Packit d03632
                Move(s->stream.next_in, SvPVX(buf), in, char) ;	
Packit d03632
            *SvEND(buf) = '\0';
Packit d03632
            SvSETMAGIC(buf);
Packit d03632
        }
Packit d03632
    }
Packit d03632
#endif
Packit d03632
  OUTPUT:
Packit d03632
	RETVAL
Packit d03632
Packit d03632
Packit d03632
uLong
Packit d03632
getEndOffset(s)
Packit d03632
    Compress::Raw::Zlib::inflateScanStream	s
Packit d03632
    CODE:
Packit d03632
#ifndef MAGIC_APPEND
Packit d03632
        croak("getEndOffset needs zlib 1.2.1 or better");
Packit d03632
#else
Packit d03632
        RETVAL = s->window_endOffset;
Packit d03632
#endif
Packit d03632
  OUTPUT:
Packit d03632
	RETVAL
Packit d03632
Packit d03632
uLong
Packit d03632
inflateCount(s)
Packit d03632
    Compress::Raw::Zlib::inflateScanStream	s
Packit d03632
    CODE:
Packit d03632
#ifndef MAGIC_APPEND
Packit d03632
        croak("inflateCount needs zlib 1.2.1 or better");
Packit d03632
#else
Packit d03632
        RETVAL = s->bytesInflated;
Packit d03632
#endif
Packit d03632
  OUTPUT:
Packit d03632
	RETVAL
Packit d03632
Packit d03632
uLong
Packit d03632
compressedBytes(s)
Packit d03632
    Compress::Raw::Zlib::inflateScanStream	s
Packit d03632
    CODE:
Packit d03632
        RETVAL = s->compressedBytes;
Packit d03632
  OUTPUT:
Packit d03632
	RETVAL
Packit d03632
Packit d03632
uLong
Packit d03632
uncompressedBytes(s)
Packit d03632
    Compress::Raw::Zlib::inflateScanStream	s
Packit d03632
    CODE:
Packit d03632
        RETVAL = s->uncompressedBytes;
Packit d03632
  OUTPUT:
Packit d03632
	RETVAL
Packit d03632
Packit d03632
Packit d03632
uLong
Packit d03632
getLastBlockOffset(s)
Packit d03632
    Compress::Raw::Zlib::inflateScanStream	s
Packit d03632
    CODE:
Packit d03632
#ifndef MAGIC_APPEND
Packit d03632
        croak("getLastBlockOffset needs zlib 1.2.1 or better");
Packit d03632
#else
Packit d03632
        RETVAL = s->lastBlockOffset - (s->window_lastbit != 0);
Packit d03632
#endif
Packit d03632
  OUTPUT:
Packit d03632
	RETVAL
Packit d03632
Packit d03632
uLong
Packit d03632
getLastBufferOffset(s)
Packit d03632
    Compress::Raw::Zlib::inflateScanStream	s
Packit d03632
    CODE:
Packit d03632
#ifndef MAGIC_APPEND
Packit d03632
        croak("getLastBufferOffset needs zlib 1.2.1 or better");
Packit d03632
#else
Packit d03632
        RETVAL = s->window_lastoff;
Packit d03632
#endif
Packit d03632
  OUTPUT:
Packit d03632
	RETVAL
Packit d03632
Packit d03632
void
Packit d03632
resetLastBlockByte(s, byte)
Packit d03632
    Compress::Raw::Zlib::inflateScanStream	s
Packit d03632
    unsigned char*                      byte
Packit d03632
    CODE:
Packit d03632
#ifndef MAGIC_APPEND
Packit d03632
        croak("resetLastBlockByte needs zlib 1.2.1 or better");
Packit d03632
#else
Packit d03632
        if (byte != NULL)
Packit d03632
            *byte = *byte ^ (1 << ((8 - s->window_lastbit) & 7));
Packit d03632
#endif
Packit d03632
Packit d03632
Packit d03632
void
Packit d03632
_createDeflateStream(inf_s, flags,level, method, windowBits, memLevel, strategy, bufsize)
Packit d03632
    Compress::Raw::Zlib::inflateScanStream	inf_s
Packit d03632
    int flags
Packit d03632
    int	level
Packit d03632
    int method
Packit d03632
    int windowBits
Packit d03632
    int memLevel
Packit d03632
    int strategy
Packit d03632
    uLong bufsize
Packit d03632
  PPCODE:
Packit d03632
  {
Packit d03632
#ifndef MAGIC_APPEND
Packit d03632
        flags = flags;
Packit d03632
        level = level ;
Packit d03632
        method = method;
Packit d03632
        windowBits = windowBits;
Packit d03632
        memLevel = memLevel;
Packit d03632
        strategy = strategy;
Packit d03632
        bufsize= bufsize;
Packit d03632
        croak("_createDeflateStream needs zlib 1.2.1 or better");
Packit d03632
#else
Packit d03632
    int err ;
Packit d03632
    deflateStream s ;
Packit d03632
Packit d03632
    if (trace)
Packit d03632
        warn("in _createDeflateStream(level=%d, method=%d, windowBits=%d, memLevel=%d, strategy=%d, bufsize=%lu\n",
Packit d03632
	level, method, windowBits, memLevel, strategy, bufsize) ;
Packit d03632
    if ((s = InitStream() )) {
Packit d03632
Packit d03632
        s->Level      = level;
Packit d03632
        s->Method     = method;
Packit d03632
        s->WindowBits = windowBits;
Packit d03632
        s->MemLevel   = memLevel;
Packit d03632
        s->Strategy   = strategy;
Packit d03632
Packit d03632
        err = deflateInit2(&(s->stream), level, 
Packit d03632
			   method, windowBits, memLevel, strategy);
Packit d03632
Packit d03632
	if (err == Z_OK) {
Packit d03632
	    err = deflateSetDictionary(&(s->stream), inf_s->window, inf_s->window_have);
Packit d03632
	    s->dict_adler = s->stream.adler ;
Packit d03632
	}
Packit d03632
Packit d03632
        if (err != Z_OK) {
Packit d03632
            Safefree(s) ;
Packit d03632
            s = NULL ;
Packit d03632
	}
Packit d03632
	else {
Packit d03632
	    PostInitStream(s, flags, bufsize, windowBits) ;
Packit d03632
            s->crc32            = inf_s->crc32;
Packit d03632
            s->adler32          = inf_s->adler32;
Packit d03632
            s->stream.adler     = inf_s->stream.adler ;
Packit d03632
            /* s->stream.total_out = inf_s->bytesInflated ; */
Packit d03632
            s->stream.total_in  = inf_s->stream.total_out ;
Packit d03632
            if (inf_s->window_left) {
Packit d03632
                /* printf("** window_left %d, window_lastByte %d\n", inf_s->window_left, inf_s->window_lastByte); */
Packit d03632
                deflatePrime(&(s->stream), 8 - inf_s->window_left, inf_s->window_lastByte);
Packit d03632
            }
Packit d03632
        }
Packit d03632
    }
Packit d03632
    else
Packit d03632
        err = Z_MEM_ERROR ;
Packit d03632
Packit d03632
    XPUSHs(sv_setref_pv(sv_newmortal(), 
Packit d03632
            "Compress::Raw::Zlib::deflateStream", (void*)s));
Packit d03632
    if (GIMME == G_ARRAY) {
Packit d03632
        SV * sv = sv_2mortal(newSViv(err)) ;
Packit d03632
        setDUALstatus(sv, err);
Packit d03632
        XPUSHs(sv) ;
Packit d03632
    }
Packit d03632
#endif
Packit d03632
  }
Packit d03632
Packit d03632
DualType
Packit d03632
status(s)
Packit d03632
        Compress::Raw::Zlib::inflateScanStream   s
Packit d03632
    CODE:
Packit d03632
	RETVAL = s->last_error ;
Packit d03632
    OUTPUT:
Packit d03632
	RETVAL
Packit d03632
Packit d03632
uLong
Packit d03632
crc32(s)
Packit d03632
        Compress::Raw::Zlib::inflateScanStream   s
Packit d03632
    CODE:
Packit d03632
	RETVAL = s->crc32 ;
Packit d03632
    OUTPUT:
Packit d03632
	RETVAL
Packit d03632
Packit d03632
Packit d03632
uLong
Packit d03632
adler32(s)
Packit d03632
        Compress::Raw::Zlib::inflateScanStream   s
Packit d03632
    CODE:
Packit d03632
	RETVAL = s->adler32 ;
Packit d03632
    OUTPUT:
Packit d03632
	RETVAL
Packit d03632