📄 zlib.pm
字号:
# File : Zlib.pm
# Author : Paul Marquess
# Created : 8th July 1996
# Version : 1.01
#
# Copyright (c) 1995, 1996, 1997 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.003_05 ;
require Exporter;
require DynaLoader;
use AutoLoader;
use Carp ;
use IO::Handle ;
use strict ;
use vars qw($VERSION @ISA @EXPORT $AUTOLOAD
$deflateDefault $deflateParamsDefault $inflateDefault) ;
@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
);
$VERSION = "1.01" ;
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->inflate($in) ;
return undef unless $err == Z_STREAM_END() ;
return $output ;
}
return undef ;
}
sub MAGIC1() { 0x1f }
sub MAGIC2() { 0x8b }
sub OSCODE() { 3 }
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("c10", 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;
}
1 ;
# 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 filenamdle, $mode) ;
$status = $gz->gzread($buffer [,$size]) ;
$status = $gz->gzreadline($line) ;
$status = $gz->gzwrite($buffer) ;
$status = $gz->gzflush($flush) ;
$status = $gz->gzclose() ;
$errstring = $gz->gzerror() ;
$gzerrno
$dest = Compress::Zlib::memGzip($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</AUTHORS> 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 compatability, 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 tht 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()>
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.
=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.
⌨️ 快捷键说明
复制代码
Ctrl + C
搜索代码
Ctrl + F
全屏模式
F11
切换主题
Ctrl + Shift + D
显示快捷键
?
增大字号
Ctrl + =
减小字号
Ctrl + -