You can not select more than 25 topics
Topics must start with a letter or number, can include dashes ('-') and can be up to 35 characters long.
1020 lines
27 KiB
1020 lines
27 KiB
# File : Zlib.pm
|
|
# Author : Paul Marquess
|
|
# Created : 28th April 2001
|
|
# Version : 1.13
|
|
#
|
|
# Copyright (c) 1995-2001 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;
|
|
require DynaLoader;
|
|
use AutoLoader;
|
|
use Carp ;
|
|
use IO::Handle ;
|
|
|
|
use strict ;
|
|
use warnings ;
|
|
use vars qw($VERSION @ISA @EXPORT $AUTOLOAD
|
|
$deflateDefault $deflateParamsDefault $inflateDefault) ;
|
|
|
|
$VERSION = "1.13" ;
|
|
|
|
@ISA = qw(Exporter DynaLoader);
|
|
# 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
|
|
|
|
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 {
|
|
# This AUTOLOAD is used to 'autoload' constants from the constant()
|
|
# XS function. If a constant is not found then control is passed
|
|
# to the AUTOLOAD in AutoLoader.
|
|
|
|
my($constname);
|
|
($constname = $AUTOLOAD) =~ s/.*:://;
|
|
my $val = constant($constname, @_ ? $_[0] : 0);
|
|
if ($! != 0) {
|
|
if ($! =~ /Invalid/) {
|
|
$AutoLoader::AUTOLOAD = $AUTOLOAD;
|
|
goto &AutoLoader::AUTOLOAD;
|
|
}
|
|
else {
|
|
croak "Your vendor has not defined Compress::Zlib macro $constname"
|
|
}
|
|
}
|
|
eval "sub $AUTOLOAD { $val }";
|
|
goto &$AUTOLOAD;
|
|
}
|
|
|
|
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) ;
|
|
gzdopen_(fileno($file), $mode, tell($file))
|
|
}
|
|
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) {
|
|
%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' => Z_DEFAULT_COMPRESSION(),
|
|
'Strategy' => Z_DEFAULT_STRATEGY(),
|
|
} ;
|
|
|
|
$inflateDefault = {
|
|
'WindowBits' => MAX_WBITS(),
|
|
'Bufsize' => 4096,
|
|
'Dictionary' => "",
|
|
} ;
|
|
|
|
|
|
sub deflateInit
|
|
{
|
|
my ($got) = ParseParameters($deflateDefault, @_) ;
|
|
_deflateInit($got->{Level}, $got->{Method}, $got->{WindowBits},
|
|
$got->{MemLevel}, $got->{Strategy}, $got->{Bufsize},
|
|
$got->{Dictionary}) ;
|
|
|
|
}
|
|
|
|
sub inflateInit
|
|
{
|
|
my ($got) = ParseParameters($inflateDefault, @_) ;
|
|
_inflateInit($got->{WindowBits}, $got->{Bufsize}, $got->{Dictionary}) ;
|
|
|
|
}
|
|
|
|
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] ;
|
|
}
|
|
|
|
if ( (($x, $err) = deflateInit())[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), length($$string)) ;
|
|
|
|
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 $x = inflateInit( -WindowBits => - MAX_WBITS())
|
|
or return undef;
|
|
my ($output, $status) = $x->inflate($string);
|
|
return undef
|
|
unless $status == Z_STREAM_END();
|
|
my ($crc, $len) = unpack ("VV", substr($$string, 0, 8));
|
|
substr($$string, 0, 8) = '';
|
|
return undef
|
|
unless $len == length($output) and
|
|
$crc == crc32($output);
|
|
return $output;
|
|
}
|
|
|
|
# Autoload methods go after __END__, and are processed by the autosplit program.
|
|
|
|
1;
|
|
__END__
|
|
|
|
=cut
|
|
|
|
=head1 NAME
|
|
|
|
Compress::Zlib - Interface to zlib compression library
|
|
|
|
=head1 SYNOPSIS
|
|
|
|
use Compress::Zlib ;
|
|
|
|
($d, $status) = deflateInit( [OPT] ) ;
|
|
($out, $status) = $d->deflate($buffer) ;
|
|
($out, $status) = $d->flush() ;
|
|
$d->dict_adler() ;
|
|
|
|
($i, $status) = inflateInit( [OPT] ) ;
|
|
($out, $status) = $i->inflate($buffer) ;
|
|
$i->dict_adler() ;
|
|
|
|
$dest = compress($source) ;
|
|
$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() ;
|
|
$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 1 through 9,
|
|
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])>
|
|
|
|
Finishes 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 degrade the compression ratio, so it should only
|
|
be used to terminate a decompression.
|
|
|
|
By default the C<flush_type> used is C<Z_FINISH>. Other valid values
|
|
for C<flush_type> are Z_NO_FLUSH, Z_PARTIAL_FLUSH, Z_SYNC_FLUSH
|
|
and Z_FULL_FLUSH. It is strongly recommended that you only set the
|
|
C<flush_type> parameter if you fully understand what it does. See the
|
|
C<zlib> documentation for details.
|
|
|
|
=head2 B<$d-E<gt>dict_adler()>
|
|
|
|
Returns the adler32 value for the dictionary.
|
|
|
|
=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<$i-E<gt>dict_adler()>
|
|
|
|
Returns the adler32 value for the dictionary.
|
|
|
|
=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. They are B<compress> and B<uncompress>. Two Perl subs are
|
|
provided which provide similar functionality.
|
|
|
|
=over 5
|
|
|
|
=item B<$dest = compress($source) ;>
|
|
|
|
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.
|
|
|
|
=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
|
|
|
|
=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 into the compressed file.
|
|
Works identically to the I<zlib> function it interfaces to. Note that
|
|
the use of B<gzflush> can degrade compression.
|
|
|
|
Refer to the I<zlib> documentation for the valid values of B<$flush>.
|
|
|
|
=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>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 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<[email protected]>. 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.info-zip.org/pub/infozip/zlib/>.
|
|
|
|
=head1 MODIFICATION HISTORY
|
|
|
|
See the README file.
|