home
***
CD-ROM
|
disk
|
FTP
|
other
***
search
/
ftp.f-secure.com
/
2014.06.ftp.f-secure.com.tar
/
ftp.f-secure.com
/
support
/
hotfix
/
fsis
/
IS-SpamControl.fsfix
/
iufssc
/
lib
/
Compress
/
Zlib.pm
Wrap
Text File
|
2006-11-29
|
33KB
|
1,273 lines
# File : Zlib.pm
# Author : Paul Marquess
# Created : 4 October 2005
# Version : 1.41
#
# Copyright (c) 1995-2005 Paul Marquess. All rights reserved.
# This program is free software; you can redistribute it and/or
# modify it under the same terms as Perl itself.
#
package Compress::Zlib;
require 5.004 ;
require Exporter;
use AutoLoader;
use Carp ;
use IO::Handle ;
use strict ;
use warnings ;
our ($VERSION, @ISA, @EXPORT, $AUTOLOAD);
our ($deflateDefault, $deflateParamsDefault, $inflateDefault);
$VERSION = "1.41" ;
@ISA = qw(Exporter);
# Items to export into callers namespace by default. Note: do not export
# names by default without a very good reason. Use EXPORT_OK instead.
# Do not simply export all your public functions/methods/constants.
@EXPORT = qw(
deflateInit
inflateInit
compress
uncompress
gzip gunzip
gzopen
$gzerrno
adler32
crc32
ZLIB_VERSION
ZLIB_VERNUM
DEF_WBITS
OS_CODE
MAX_MEM_LEVEL
MAX_WBITS
Z_ASCII
Z_BEST_COMPRESSION
Z_BEST_SPEED
Z_BINARY
Z_BUF_ERROR
Z_DATA_ERROR
Z_DEFAULT_COMPRESSION
Z_DEFAULT_STRATEGY
Z_DEFLATED
Z_ERRNO
Z_FILTERED
Z_FINISH
Z_FULL_FLUSH
Z_HUFFMAN_ONLY
Z_MEM_ERROR
Z_NEED_DICT
Z_NO_COMPRESSION
Z_NO_FLUSH
Z_NULL
Z_OK
Z_PARTIAL_FLUSH
Z_STREAM_END
Z_STREAM_ERROR
Z_SYNC_FLUSH
Z_UNKNOWN
Z_VERSION_ERROR
);
sub AUTOLOAD {
my($constname);
($constname = $AUTOLOAD) =~ s/.*:://;
my ($error, $val) = constant($constname);
Carp::croak $error if $error;
no strict 'refs';
*{$AUTOLOAD} = sub { $val };
goto &{$AUTOLOAD};
}
eval {
require XSLoader;
XSLoader::load('Compress::Zlib', $VERSION);
} or do {
require DynaLoader;
local @ISA = qw(DynaLoader);
bootstrap Compress::Zlib $VERSION ;
} ;
# Preloaded methods go here.
sub isaFilehandle($)
{
my $fh = shift ;
return ((UNIVERSAL::isa($fh,'GLOB') or UNIVERSAL::isa(\$fh,'GLOB'))
and defined fileno($fh) )
}
sub isaFilename($)
{
my $name = shift ;
return (! ref $name and UNIVERSAL::isa(\$name, 'SCALAR')) ;
}
sub gzopen($$)
{
my ($file, $mode) = @_ ;
if (isaFilehandle $file) {
IO::Handle::flush($file) ;
my $offset = tell($file) ;
gzdopen_(fileno($file), $mode, $offset) ;
}
elsif (isaFilename $file) {
gzopen_($file, $mode)
}
else {
croak "gzopen: file parameter is not a filehandle or filename"
}
}
sub ParseParameters($@)
{
my ($default, @rest) = @_ ;
my (%got) = %$default ;
my (@Bad) ;
my ($key, $value) ;
my $sub = (caller(1))[3] ;
my %options = () ;
# allow the options to be passed as a hash reference or
# as the complete hash.
if (@rest == 1) {
croak "$sub: parameter is not a reference to a hash"
if ref $rest[0] ne "HASH" ;
%options = %{ $rest[0] } ;
}
elsif (@rest >= 2) {
my $count = @rest;
croak "$sub: Expected even number of parameters, got $count"
if @rest % 2 != 0 ;
%options = @rest ;
}
while (($key, $value) = each %options)
{
$key =~ s/^-// ;
if (exists $default->{$key})
{ $got{$key} = $value }
else
{ push (@Bad, $key) }
}
if (@Bad) {
my ($bad) = join(", ", @Bad) ;
croak "unknown key value(s) @Bad" ;
}
return \%got ;
}
$deflateDefault = {
'Level' => Z_DEFAULT_COMPRESSION(),
'Method' => Z_DEFLATED(),
'WindowBits' => MAX_WBITS(),
'MemLevel' => MAX_MEM_LEVEL(),
'Strategy' => Z_DEFAULT_STRATEGY(),
'Bufsize' => 4096,
'Dictionary' => "",
} ;
$deflateParamsDefault = {
'Level' => undef,
'Strategy' => undef,
'Bufsize' => undef,
} ;
$inflateDefault = {
'WindowBits' => MAX_WBITS(),
'Bufsize' => 4096,
'Dictionary' => "",
} ;
sub deflateInit(@)
{
my ($got) = ParseParameters($deflateDefault, @_) ;
no warnings;
croak "deflateInit: Bufsize must be >= 1, you specified $got->{Bufsize}"
unless $got->{Bufsize} >= 1;
_deflateInit($got->{Level}, $got->{Method}, $got->{WindowBits},
$got->{MemLevel}, $got->{Strategy}, $got->{Bufsize},
$got->{Dictionary}) ;
}
sub inflateInit(@)
{
my ($got) = ParseParameters($inflateDefault, @_) ;
no warnings;
croak "inflateInit: Bufsize must be >= 1, you specified $got->{Bufsize}"
unless $got->{Bufsize} >= 1;
_inflateInit($got->{WindowBits}, $got->{Bufsize}, $got->{Dictionary});
}
sub Compress::Zlib::deflateStream::deflateParams
{
my $self = shift ;
my ($got) = ParseParameters($deflateParamsDefault, @_) ;
croak "deflateParams needs Level and/or Strategy"
unless defined $got->{Level} || defined $got->{Strategy};
no warnings;
croak "deflateParams: Bufsize must be >= 1, you specified $got->{Bufsize}"
unless !defined $got->{Bufsize} || $got->{Bufsize} >= 1;
my $flags = 0;
if (defined $got->{Level})
{ $flags |= 1 }
else
{ $got->{Level} = 0 }
if (defined $got->{Strategy})
{ $flags |= 2 }
else
{ $got->{Strategy} = 0 }
$got->{Bufsize} = 0
if !defined $got->{Bufsize};
$self->_deflateParams($flags, $got->{Level}, $got->{Strategy},
$got->{Bufsize});
}
sub compress($;$)
{
my ($x, $output, $out, $err, $in) ;
if (ref $_[0] ) {
$in = $_[0] ;
croak "not a scalar reference" unless ref $in eq 'SCALAR' ;
}
else {
$in = \$_[0] ;
}
my $level = (@_ == 2 ? $_[1] : Z_DEFAULT_COMPRESSION() );
if ( (($x, $err) = deflateInit(Level => $level))[1] == Z_OK()) {
($output, $err) = $x->deflate($in) ;
return undef unless $err == Z_OK() ;
($out, $err) = $x->flush() ;
return undef unless $err == Z_OK() ;
return ($output . $out) ;
}
return undef ;
}
sub uncompress($)
{
my ($x, $output, $err, $in) ;
if (ref $_[0] ) {
$in = $_[0] ;
croak "not a scalar reference" unless ref $in eq 'SCALAR' ;
}
else {
$in = \$_[0] ;
}
if ( (($x, $err) = inflateInit())[1] == Z_OK()) {
($output, $err) = $x->__unc_inflate($in) ;
return undef unless $err == Z_STREAM_END() ;
return $output ;
}
return undef ;
}
# Constants
use constant MAGIC1 => 0x1f ;
use constant MAGIC2 => 0x8b ;
use constant OSCODE => 3 ;
use constant FTEXT => 1 ;
use constant FHCRC => 2 ;
use constant FEXTRA => 4 ;
use constant FNAME => 8 ;
use constant FCOMMENT => 16 ;
use constant NULL => pack("C", 0) ;
use constant RESERVED => 0xE0 ;
use constant MIN_HDR_SIZE => 10 ; # minimum gzip header size
sub memGzip($)
{
my $x = deflateInit(
-Level => Z_BEST_COMPRESSION(),
-WindowBits => - MAX_WBITS(),
)
or return undef ;
# write a minimal gzip header
my(@m);
push @m, pack("C" . MIN_HDR_SIZE,
MAGIC1, MAGIC2, Z_DEFLATED(), 0,0,0,0,0,0, OSCODE) ;
# if the deflation buffer isn't a reference, make it one
my $string = (ref $_[0] ? $_[0] : \$_[0]) ;
my ($output, $status) = $x->deflate($string) ;
push @m, $output ;
$status == Z_OK()
or return undef ;
($output, $status) = $x->flush() ;
push @m, $output ;
$status == Z_OK()
or return undef ;
push @m, pack("V V", crc32($string), $x->total_in());
return join "", @m;
}
sub _removeGzipHeader($)
{
my $string = shift ;
return Z_DATA_ERROR()
if length($$string) < MIN_HDR_SIZE ;
my ($magic1, $magic2, $method, $flags, $time, $xflags, $oscode) =
unpack ('CCCCVCC', $$string);
return Z_DATA_ERROR()
unless $magic1 == MAGIC1 and $magic2 == MAGIC2 and
$method == Z_DEFLATED() and !($flags & RESERVED()) ;
substr($$string, 0, MIN_HDR_SIZE) = '' ;
# skip extra field
if ($flags & FEXTRA)
{
return Z_DATA_ERROR()
if length($$string) < 2 ;
my ($extra_len) = unpack ('v', $$string);
$extra_len += 2;
return Z_DATA_ERROR()
if length($$string) < $extra_len ;
substr($$string, 0, $extra_len) = '';
}
# skip orig name
if ($flags & FNAME)
{
my $name_end = index ($$string, NULL);
return Z_DATA_ERROR()
if $name_end == -1 ;
substr($$string, 0, $name_end + 1) = '';
}
# skip comment
if ($flags & FCOMMENT)
{
my $comment_end = index ($$string, NULL);
return Z_DATA_ERROR()
if $comment_end == -1 ;
substr($$string, 0, $comment_end + 1) = '';
}
# skip header crc
if ($flags & FHCRC)
{
return Z_DATA_ERROR()
if length ($$string) < 2 ;
substr($$string, 0, 2) = '';
}
return Z_OK();
}
sub memGunzip($)
{
# if the buffer isn't a reference, make it one
my $string = (ref $_[0] ? $_[0] : \$_[0]);
_removeGzipHeader($string) == Z_OK()
or return undef;
my $bufsize = length $$string > 4096 ? length $$string : 4096 ;
my $x = inflateInit( -WindowBits => - MAX_WBITS(),
-Bufsize => $bufsize)
or return undef;
my ($output, $status) = $x->inflate($string);
return undef
unless $status == Z_STREAM_END();
if (length $$string >= 8)
{
my ($crc, $len) = unpack ("VV", substr($$string, 0, 8));
substr($$string, 0, 8) = '';
return undef
unless $len == length($output) and
$crc == crc32($output);
}
else
{
$$string = '';
}
return $output;
}
# Autoload methods go after __END__, and are processed by the autosplit program.
1;
__END__
=head1 NAME
Compress::Zlib - Interface to zlib compression library
=head1 SYNOPSIS
use Compress::Zlib ;
($d, $status) = deflateInit( [OPT] ) ;
($out, $status) = $d->deflate($buffer) ;
$status = $d->deflateParams([OPT]) ;
($out, $status) = $d->flush() ;
$d->dict_adler() ;
$d->total_in() ;
$d->total_out() ;
$d->msg() ;
($i, $status) = inflateInit( [OPT] ) ;
($out, $status) = $i->inflate($buffer) ;
$status = $i->inflateSync($buffer) ;
$i->dict_adler() ;
$i->total_in() ;
$i->total_out() ;
$i->msg() ;
$dest = compress($source, [$level]) ;
$dest = uncompress($source) ;
$gz = gzopen($filename or filehandle, $mode) ;
$bytesread = $gz->gzread($buffer [,$size]) ;
$bytesread = $gz->gzreadline($line) ;
$byteswritten = $gz->gzwrite($buffer) ;
$status = $gz->gzflush($flush) ;
$status = $gz->gzclose() ;
$status = $gz->gzeof() ;
$status = $gz->gzsetparams($level, $strategy) ;
$errstring = $gz->gzerror() ;
$gzerrno
$dest = Compress::Zlib::memGzip($buffer) ;
$dest = Compress::Zlib::memGunzip($buffer) ;
$crc = adler32($buffer [,$crc]) ;
$crc = crc32($buffer [,$crc]) ;
ZLIB_VERSION
=head1 DESCRIPTION
The I<Compress::Zlib> module provides a Perl interface to the I<zlib>
compression library (see L</AUTHOR> for details about where to get
I<zlib>). Most of the functionality provided by I<zlib> is available
in I<Compress::Zlib>.
The module can be split into two general areas of functionality, namely
in-memory compression/decompression and read/write access to I<gzip>
files. Each of these areas will be discussed separately below.
=head1 DEFLATE
The interface I<Compress::Zlib> provides to the in-memory I<deflate>
(and I<inflate>) functions has been modified to fit into a Perl model.
The main difference is that for both inflation and deflation, the Perl
interface will I<always> consume the complete input buffer before
returning. Also the output buffer returned will be automatically grown
to fit the amount of output available.
Here is a definition of the interface available:
=head2 B<($d, $status) = deflateInit( [OPT] )>
Initialises a deflation stream.
It combines the features of the I<zlib> functions B<deflateInit>,
B<deflateInit2> and B<deflateSetDictionary>.
If successful, it will return the initialised deflation stream, B<$d>
and B<$status> of C<Z_OK> in a list context. In scalar context it
returns the deflation stream, B<$d>, only.
If not successful, the returned deflation stream (B<$d>) will be
I<undef> and B<$status> will hold the exact I<zlib> error code.
The function optionally takes a number of named options specified as
C<-Name=E<gt>value> pairs. This allows individual options to be
tailored without having to specify them all in the parameter list.
For backward compatibility, it is also possible to pass the parameters
as a reference to a hash containing the name=>value pairs.
The function takes one optional parameter, a reference to a hash. The
contents of the hash allow the deflation interface to be tailored.
Here is a list of the valid options:
=over 5
=item B<-Level>
Defines the compression level. Valid values are 0 through 9,
C<Z_NO_COMPRESSION>, C<Z_BEST_SPEED>, C<Z_BEST_COMPRESSION>, and
C<Z_DEFAULT_COMPRESSION>.
The default is C<-Level =E<gt>Z_DEFAULT_COMPRESSION>.
=item B<-Method>
Defines the compression method. The only valid value at present (and
the default) is C<-Method =E<gt>Z_DEFLATED>.
=item B<-WindowBits>
For a definition of the meaning and valid values for B<WindowBits>
refer to the I<zlib> documentation for I<deflateInit2>.
Defaults to C<-WindowBits =E<gt>MAX_WBITS>.
=item B<-MemLevel>
For a definition of the meaning and valid values for B<MemLevel>
refer to the I<zlib> documentation for I<deflateInit2>.
Defaults to C<-MemLevel =E<gt>MAX_MEM_LEVEL>.
=item B<-Strategy>
Defines the strategy used to tune the compression. The valid values are
C<Z_DEFAULT_STRATEGY>, C<Z_FILTERED> and C<Z_HUFFMAN_ONLY>.
The default is C<-Strategy =E<gt>Z_DEFAULT_STRATEGY>.
=item B<-Dictionary>
When a dictionary is specified I<Compress::Zlib> will automatically
call B<deflateSetDictionary> directly after calling B<deflateInit>. The
Adler32 value for the dictionary can be obtained by calling the method
C<$d->dict_adler()>.
The default is no dictionary.
=item B<-Bufsize>
Sets the initial size for the deflation buffer. If the buffer has to be
reallocated to increase the size, it will grow in increments of
B<Bufsize>.
The default is 4096.
=back
Here is an example of using the B<deflateInit> optional parameter list
to override the default buffer size and compression level. All other
options will take their default values.
deflateInit( -Bufsize => 300,
-Level => Z_BEST_SPEED ) ;
=head2 B<($out, $status) = $d-E<gt>deflate($buffer)>
Deflates the contents of B<$buffer>. The buffer can either be a scalar
or a scalar reference. When finished, B<$buffer> will be
completely processed (assuming there were no errors). If the deflation
was successful it returns the deflated output, B<$out>, and a status
value, B<$status>, of C<Z_OK>.
On error, B<$out> will be I<undef> and B<$status> will contain the
I<zlib> error code.
In a scalar context B<deflate> will return B<$out> only.
As with the I<deflate> function in I<zlib>, it is not necessarily the
case that any output will be produced by this method. So don't rely on
the fact that B<$out> is empty for an error test.
=head2 B<($out, $status) = $d-E<gt>flush([flush_type])>
Typically used to finish the deflation. Any pending output will be
returned via B<$out>.
B<$status> will have a value C<Z_OK> if successful.
In a scalar context B<flush> will return B<$out> only.
Note that flushing can seriously degrade the compression ratio, so it
should only be used to terminate a decompression (using C<Z_FINISH>) or
when you want to create a I<full flush point> (using C<Z_FULL_FLUSH>).
By default the C<flush_type> used is C<Z_FINISH>. Other valid values
for C<flush_type> are C<Z_NO_FLUSH>, C<Z_PARTIAL_FLUSH>, C<Z_SYNC_FLUSH>
and C<Z_FULL_FLUSH>. It is strongly recommended that you only set the
C<flush_type> parameter if you fully understand the implications of
what it does. See the C<zlib> documentation for details.
=head2 B<$status = $d-E<gt>deflateParams([OPT])>
Change settings for the deflate stream C<$d>.
The list of the valid options is shown below. Options not specified
will remain unchanged.
=over 5
=item B<-Level>
Defines the compression level. Valid values are 0 through 9,
C<Z_NO_COMPRESSION>, C<Z_BEST_SPEED>, C<Z_BEST_COMPRESSION>, and
C<Z_DEFAULT_COMPRESSION>.
=item B<-Strategy>
Defines the strategy used to tune the compression. The valid values are
C<Z_DEFAULT_STRATEGY>, C<Z_FILTERED> and C<Z_HUFFMAN_ONLY>.
=back
=head2 B<$d-E<gt>dict_adler()>
Returns the adler32 value for the dictionary.
=head2 B<$d-E<gt>msg()>
Returns the last error message generated by zlib.
=head2 B<$d-E<gt>total_in()>
Returns the total number of bytes uncompressed bytes input to deflate.
=head2 B<$d-E<gt>total_out()>
Returns the total number of compressed bytes output from deflate.
=head2 Example
Here is a trivial example of using B<deflate>. It simply reads standard
input, deflates it and writes it to standard output.
use strict ;
use warnings ;
use Compress::Zlib ;
binmode STDIN;
binmode STDOUT;
my $x = deflateInit()
or die "Cannot create a deflation stream\n" ;
my ($output, $status) ;
while (<>)
{
($output, $status) = $x->deflate($_) ;
$status == Z_OK
or die "deflation failed\n" ;
print $output ;
}
($output, $status) = $x->flush() ;
$status == Z_OK
or die "deflation failed\n" ;
print $output ;
=head1 INFLATE
Here is a definition of the interface:
=head2 B<($i, $status) = inflateInit()>
Initialises an inflation stream.
In a list context it returns the inflation stream, B<$i>, and the
I<zlib> status code (B<$status>). In a scalar context it returns the
inflation stream only.
If successful, B<$i> will hold the inflation stream and B<$status> will
be C<Z_OK>.
If not successful, B<$i> will be I<undef> and B<$status> will hold the
I<zlib> error code.
The function optionally takes a number of named options specified as
C<-Name=E<gt>value> pairs. This allows individual options to be
tailored without having to specify them all in the parameter list.
For backward compatibility, it is also possible to pass the parameters
as a reference to a hash containing the name=>value pairs.
The function takes one optional parameter, a reference to a hash. The
contents of the hash allow the deflation interface to be tailored.
Here is a list of the valid options:
=over 5
=item B<-WindowBits>
For a definition of the meaning and valid values for B<WindowBits>
refer to the I<zlib> documentation for I<inflateInit2>.
Defaults to C<-WindowBits =E<gt>MAX_WBITS>.
=item B<-Bufsize>
Sets the initial size for the inflation buffer. If the buffer has to be
reallocated to increase the size, it will grow in increments of
B<Bufsize>.
Default is 4096.
=item B<-Dictionary>
The default is no dictionary.
=back
Here is an example of using the B<inflateInit> optional parameter to
override the default buffer size.
inflateInit( -Bufsize => 300 ) ;
=head2 B<($out, $status) = $i-E<gt>inflate($buffer)>
Inflates the complete contents of B<$buffer>. The buffer can either be
a scalar or a scalar reference.
Returns C<Z_OK> if successful and C<Z_STREAM_END> if the end of the
compressed data has been successfully reached.
If not successful, B<$out> will be I<undef> and B<$status> will hold
the I<zlib> error code.
The C<$buffer> parameter is modified by C<inflate>. On completion it
will contain what remains of the input buffer after inflation. This
means that C<$buffer> will be an empty string when the return status is
C<Z_OK>. When the return status is C<Z_STREAM_END> the C<$buffer>
parameter will contains what (if anything) was stored in the input
buffer after the deflated data stream.
This feature is useful when processing a file format that encapsulates
a compressed data stream (e.g. gzip, zip).
=head2 B<$status = $i-E<gt>inflateSync($buffer)>
Scans C<$buffer> until it reaches either a I<full flush point> or the
end of the buffer.
If a I<full flush point> is found, C<Z_OK> is returned and C<$buffer>
will be have all data up to the flush point removed. This can then be
passed to the C<deflate> method.
Any other return code means that a flush point was not found. If more
data is available, C<inflateSync> can be called repeatedly with more
compressed data until the flush point is found.
=head2 B<$i-E<gt>dict_adler()>
Returns the adler32 value for the dictionary.
=head2 B<$i-E<gt>msg()>
Returns the last error message generated by zlib.
=head2 B<$i-E<gt>total_in()>
Returns the total number of bytes compressed bytes input to inflate.
=head2 B<$i-E<gt>total_out()>
Returns the total number of uncompressed bytes output from inflate.
=head2 Example
Here is an example of using B<inflate>.
use strict ;
use warnings ;
use Compress::Zlib ;
my $x = inflateInit()
or die "Cannot create a inflation stream\n" ;
my $input = '' ;
binmode STDIN;
binmode STDOUT;
my ($output, $status) ;
while (read(STDIN, $input, 4096))
{
($output, $status) = $x->inflate(\$input) ;
print $output
if $status == Z_OK or $status == Z_STREAM_END ;
last if $status != Z_OK ;
}
die "inflation failed\n"
unless $status == Z_STREAM_END ;
=head1 COMPRESS/UNCOMPRESS
Two high-level functions are provided by I<zlib> to perform in-memory
compression/uncompression of RFC1950 data streams. They are called
B<compress> and B<uncompress>.
The two Perl subs defined below provide the equivalent
functionality.
=over 5
=item B<$dest = compress($source [, $level] ) ;>
Compresses B<$source>. If successful it returns the
compressed data. Otherwise it returns I<undef>.
The source buffer can either be a scalar or a scalar reference.
The B<$level> paramter defines the compression level. Valid values are
0 through 9, C<Z_NO_COMPRESSION>, C<Z_BEST_SPEED>,
C<Z_BEST_COMPRESSION>, and C<Z_DEFAULT_COMPRESSION>.
If B<$level> is not specified C<Z_DEFAULT_COMPRESSION> will be used.
=item B<$dest = uncompress($source) ;>
Uncompresses B<$source>. If successful it returns the uncompressed
data. Otherwise it returns I<undef>.
The source buffer can either be a scalar or a scalar reference.
=back
Please note: the two functions defined above are I<not> compatible with
the Unix commands of the same name.
=head1 GZIP INTERFACE
A number of functions are supplied in I<zlib> for reading and writing
I<gzip> files. This module provides an interface to most of them. In
general the interface provided by this module operates identically to
the functions provided by I<zlib>. Any differences are explained
below.
=over 5
=item B<$gz = gzopen(filename or filehandle, mode)>
This function operates identically to the I<zlib> equivalent except
that it returns an object which is used to access the other I<gzip>
methods.
As with the I<zlib> equivalent, the B<mode> parameter is used to
specify both whether the file is opened for reading or writing and to
optionally specify a a compression level. Refer to the I<zlib>
documentation for the exact format of the B<mode> parameter.
If a reference to an open filehandle is passed in place of the
filename, gzdopen will be called behind the scenes. The third example
at the end of this section, I<gzstream>, uses this feature.
=item B<$bytesread = $gz-E<gt>gzread($buffer [, $size]) ;>
Reads B<$size> bytes from the compressed file into B<$buffer>. If
B<$size> is not specified, it will default to 4096. If the scalar
B<$buffer> is not large enough, it will be extended automatically.
Returns the number of bytes actually read. On EOF it returns 0 and in
the case of an error, -1.
=item B<$bytesread = $gz-E<gt>gzreadline($line) ;>
Reads the next line from the compressed file into B<$line>.
Returns the number of bytes actually read. On EOF it returns 0 and in
the case of an error, -1.
It is legal to intermix calls to B<gzread> and B<gzreadline>.
At this time B<gzreadline> ignores the variable C<$/>
(C<$INPUT_RECORD_SEPARATOR> or C<$RS> when C<English> is in use). The
end of a line is denoted by the C character C<'\n'>.
=item B<$byteswritten = $gz-E<gt>gzwrite($buffer) ;>
Writes the contents of B<$buffer> to the compressed file. Returns the
number of bytes actually written, or 0 on error.
=item B<$status = $gz-E<gt>gzflush($flush) ;>
Flushes all pending output to the compressed file.
Works identically to the I<zlib> function it interfaces to. Note that
the use of B<gzflush> can degrade compression.
Returns C<Z_OK> if B<$flush> is C<Z_FINISH> and all output could be
flushed. Otherwise the zlib error code is returned.
Refer to the I<zlib> documentation for the valid values of B<$flush>.
=item B<$status = $gz-E<gt>gzeof() ;>
Returns 1 if the end of file has been detected while reading the input
file, otherwise returns 0.
=item B<$gz-E<gt>gzclose>
Closes the compressed file. Any pending data is flushed to the file
before it is closed.
=item B<$gz-E<gt>gzsetparams($level, $strategy>
Change settings for the deflate stream C<$gz>.
The list of the valid options is shown below. Options not specified
will remain unchanged.
Note: This method is only available if you are running zlib 1.0.6 or better.
=over 5
=item B<$level>
Defines the compression level. Valid values are 0 through 9,
C<Z_NO_COMPRESSION>, C<Z_BEST_SPEED>, C<Z_BEST_COMPRESSION>, and
C<Z_DEFAULT_COMPRESSION>.
=item B<$strategy>
Defines the strategy used to tune the compression. The valid values are
C<Z_DEFAULT_STRATEGY>, C<Z_FILTERED> and C<Z_HUFFMAN_ONLY>.
=back
=item B<$gz-E<gt>gzerror>
Returns the I<zlib> error message or number for the last operation
associated with B<$gz>. The return value will be the I<zlib> error
number when used in a numeric context and the I<zlib> error message
when used in a string context. The I<zlib> error number constants,
shown below, are available for use.
Z_OK
Z_STREAM_END
Z_ERRNO
Z_STREAM_ERROR
Z_DATA_ERROR
Z_MEM_ERROR
Z_BUF_ERROR
=item B<$gzerrno>
The B<$gzerrno> scalar holds the error code associated with the most
recent I<gzip> routine. Note that unlike B<gzerror()>, the error is
I<not> associated with a particular file.
As with B<gzerror()> it returns an error number in numeric context and
an error message in string context. Unlike B<gzerror()> though, the
error message will correspond to the I<zlib> message when the error is
associated with I<zlib> itself, or the UNIX error message when it is
not (i.e. I<zlib> returned C<Z_ERRORNO>).
As there is an overlap between the error numbers used by I<zlib> and
UNIX, B<$gzerrno> should only be used to check for the presence of
I<an> error in numeric context. Use B<gzerror()> to check for specific
I<zlib> errors. The I<gzcat> example below shows how the variable can
be used safely.
=back
=head2 Examples
Here is an example script which uses the interface. It implements a
I<gzcat> function.
use strict ;
use warnings ;
use Compress::Zlib ;
die "Usage: gzcat file...\n"
unless @ARGV ;
my $file ;
foreach $file (@ARGV) {
my $buffer ;
my $gz = gzopen($file, "rb")
or die "Cannot open $file: $gzerrno\n" ;
print $buffer while $gz->gzread($buffer) > 0 ;
die "Error reading from $file: $gzerrno" . ($gzerrno+0) . "\n"
if $gzerrno != Z_STREAM_END ;
$gz->gzclose() ;
}
Below is a script which makes use of B<gzreadline>. It implements a
very simple I<grep> like script.
use strict ;
use warnings ;
use Compress::Zlib ;
die "Usage: gzgrep pattern file...\n"
unless @ARGV >= 2;
my $pattern = shift ;
my $file ;
foreach $file (@ARGV) {
my $gz = gzopen($file, "rb")
or die "Cannot open $file: $gzerrno\n" ;
while ($gz->gzreadline($_) > 0) {
print if /$pattern/ ;
}
die "Error reading from $file: $gzerrno\n"
if $gzerrno != Z_STREAM_END ;
$gz->gzclose() ;
}
This script, I<gzstream>, does the opposite of the I<gzcat> script
above. It reads from standard input and writes a gzip file to standard
output.
use strict ;
use warnings ;
use Compress::Zlib ;
binmode STDOUT; # gzopen only sets it on the fd
my $gz = gzopen(\*STDOUT, "wb")
or die "Cannot open stdout: $gzerrno\n" ;
while (<>) {
$gz->gzwrite($_)
or die "error writing: $gzerrno\n" ;
}
$gz->gzclose ;
=head2 Compress::Zlib::memGzip
This function is used to create an in-memory gzip file.
It creates a minimal gzip header.
$dest = Compress::Zlib::memGzip($buffer) ;
If successful, it returns the in-memory gzip file, otherwise it returns
undef.
The buffer parameter can either be a scalar or a scalar reference.
=head2 Compress::Zlib::memGunzip
This function is used to uncompress an in-memory gzip file.
$dest = Compress::Zlib::memGunzip($buffer) ;
If successful, it returns the uncompressed gzip file, otherwise it
returns undef.
The buffer parameter can either be a scalar or a scalar reference. The
contents of the buffer parameter are destroyed after calling this
function.
=head1 CHECKSUM FUNCTIONS
Two functions are provided by I<zlib> to calculate a checksum. For the
Perl interface, the order of the two parameters in both functions has
been reversed. This allows both running checksums and one off
calculations to be done.
$crc = adler32($buffer [,$crc]) ;
$crc = crc32($buffer [,$crc]) ;
The buffer parameters can either be a scalar or a scalar reference.
If the $crc parameters is C<undef>, the crc value will be reset.
=head1 FAQ
=head2 Compatibility with Unix compress/uncompress.
Although C<Compress::Zlib> has a pair of functions called C<compress>
and C<uncompress>, they are I<not> the same as the Unix programs of the
same name. The C<Compress::Zlib> library is not compatable with Unix
C<compress>.
If you have the C<uncompress> program available, you can use this to
read compressed files
open F, "uncompress -c $filename |";
while (<F>)
{
...
If you have the C<gunzip> program available, you can use this to read
compressed files
open F, "gunzip -c $filename |";
while (<F>)
{
...
and this to write compress files if you have the C<compress> program
available
open F, "| compress -c $filename ";
print F "data";
...
close F ;
=head2 Accessing .tar.Z files
The C<Archive::Tar> module can optionally use C<Compress::Zlib> (via
the C<IO::Zlib> module) to access tar files that have been compressed
with C<gzip>. Unfortunately tar files compressed with the Unix C<compress>
utility cannot be read by C<Compress::Zlib> and so cannot be directly
accesses by C<Archive::Tar>.
If the C<uncompress> or C<gunzip> programs are available, you can use
one of these workarounds to read C<.tar.Z> files from C<Archive::Tar>
Firstly with C<uncompress>
use strict;
use warnings;
use Archive::Tar;
open F, "uncompress -c $filename |";
my $tar = Archive::Tar->new(*F);
...
and this with C<gunzip>
use strict;
use warnings;
use Archive::Tar;
open F, "gunzip -c $filename |";
my $tar = Archive::Tar->new(*F);
...
Similarly, if the C<compress> program is available, you can use this to
write a C<.tar.Z> file
use strict;
use warnings;
use Archive::Tar;
use IO::File;
my $fh = newIO::File "| compress -c >$filename";
my $tar = Archive::Tar->new();
...
$tar->write($fh);
$fh->close ;
=head2 Accessing ZIP Files
Although it is possible to use this module to access .zip files, there
is a module on CPAN that will do all the hard work for you. Check out
http://www.cpan.org/modules/by-module/Archive/Archive-Zip-*.tar.gz
Assuming you don't want to use this module to access zip files there
are a number of undocumented features in the zlib library you need to
be aware of.
=over 5
=item 1.
When calling B<inflateInit> or B<deflateInit> the B<WindowBits> parameter
must be set to C<-MAX_WBITS>. This disables the creation of the zlib
header.
=item 2.
The zlib function B<inflate>, and so the B<inflate> method supplied in
this module, assume that there is at least one trailing byte after the
compressed data stream. Normally this isn't a problem because both
the gzip and zip file formats will guarantee that there is data directly
after the compressed data stream.
=back
=head1 CONSTANTS
All the I<zlib> constants are automatically imported when you make use
of I<Compress::Zlib>.
=head1 AUTHOR
The I<Compress::Zlib> module was written by Paul Marquess,
F<pmqs@cpan.org>. The latest copy of the module can be
found on CPAN in F<modules/by-module/Compress/Compress-Zlib-x.x.tar.gz>.
The primary site for the I<zlib> compression library is
F<http://www.zlib.org>.
=head1 MODIFICATION HISTORY
See the Changes file.