Initial Commit
This commit is contained in:
153
database/perl/lib/IO/Compress/Adapter/Bzip2.pm
Normal file
153
database/perl/lib/IO/Compress/Adapter/Bzip2.pm
Normal file
@@ -0,0 +1,153 @@
|
||||
package IO::Compress::Adapter::Bzip2 ;
|
||||
|
||||
use strict;
|
||||
use warnings;
|
||||
use bytes;
|
||||
|
||||
use IO::Compress::Base::Common 2.100 qw(:Status);
|
||||
|
||||
use Compress::Raw::Bzip2 2.100 ;
|
||||
|
||||
our ($VERSION);
|
||||
$VERSION = '2.100';
|
||||
|
||||
sub mkCompObject
|
||||
{
|
||||
my $BlockSize100K = shift ;
|
||||
my $WorkFactor = shift ;
|
||||
my $Verbosity = shift ;
|
||||
|
||||
$BlockSize100K = 1 if ! defined $BlockSize100K ;
|
||||
$WorkFactor = 0 if ! defined $WorkFactor ;
|
||||
$Verbosity = 0 if ! defined $Verbosity ;
|
||||
|
||||
my ($def, $status) = Compress::Raw::Bzip2->new(1, $BlockSize100K,
|
||||
$WorkFactor, $Verbosity);
|
||||
|
||||
return (undef, "Could not create Deflate object: $status", $status)
|
||||
if $status != BZ_OK ;
|
||||
|
||||
return bless {'Def' => $def,
|
||||
'Error' => '',
|
||||
'ErrorNo' => 0,
|
||||
} ;
|
||||
}
|
||||
|
||||
sub compr
|
||||
{
|
||||
my $self = shift ;
|
||||
|
||||
my $def = $self->{Def};
|
||||
|
||||
my $status = $def->bzdeflate($_[0], $_[1]) ;
|
||||
$self->{ErrorNo} = $status;
|
||||
|
||||
if ($status != BZ_RUN_OK)
|
||||
{
|
||||
$self->{Error} = "Deflate Error: $status";
|
||||
return STATUS_ERROR;
|
||||
}
|
||||
|
||||
return STATUS_OK;
|
||||
}
|
||||
|
||||
sub flush
|
||||
{
|
||||
my $self = shift ;
|
||||
|
||||
my $def = $self->{Def};
|
||||
|
||||
my $status = $def->bzflush($_[0]);
|
||||
$self->{ErrorNo} = $status;
|
||||
|
||||
if ($status != BZ_RUN_OK)
|
||||
{
|
||||
$self->{Error} = "Deflate Error: $status";
|
||||
return STATUS_ERROR;
|
||||
}
|
||||
|
||||
return STATUS_OK;
|
||||
|
||||
}
|
||||
|
||||
sub close
|
||||
{
|
||||
my $self = shift ;
|
||||
|
||||
my $def = $self->{Def};
|
||||
|
||||
my $status = $def->bzclose($_[0]);
|
||||
$self->{ErrorNo} = $status;
|
||||
|
||||
if ($status != BZ_STREAM_END)
|
||||
{
|
||||
$self->{Error} = "Deflate Error: $status";
|
||||
return STATUS_ERROR;
|
||||
}
|
||||
|
||||
return STATUS_OK;
|
||||
|
||||
}
|
||||
|
||||
|
||||
sub reset
|
||||
{
|
||||
my $self = shift ;
|
||||
|
||||
my $outer = $self->{Outer};
|
||||
|
||||
my ($def, $status) = Compress::Raw::Bzip2->new();
|
||||
$self->{ErrorNo} = ($status == BZ_OK) ? 0 : $status ;
|
||||
|
||||
if ($status != BZ_OK)
|
||||
{
|
||||
$self->{Error} = "Cannot create Deflate object: $status";
|
||||
return STATUS_ERROR;
|
||||
}
|
||||
|
||||
$self->{Def} = $def;
|
||||
|
||||
return STATUS_OK;
|
||||
}
|
||||
|
||||
sub compressedBytes
|
||||
{
|
||||
my $self = shift ;
|
||||
$self->{Def}->compressedBytes();
|
||||
}
|
||||
|
||||
sub uncompressedBytes
|
||||
{
|
||||
my $self = shift ;
|
||||
$self->{Def}->uncompressedBytes();
|
||||
}
|
||||
|
||||
#sub total_out
|
||||
#{
|
||||
# my $self = shift ;
|
||||
# 0;
|
||||
#}
|
||||
#
|
||||
|
||||
#sub total_in
|
||||
#{
|
||||
# my $self = shift ;
|
||||
# $self->{Def}->total_in();
|
||||
#}
|
||||
#
|
||||
#sub crc32
|
||||
#{
|
||||
# my $self = shift ;
|
||||
# $self->{Def}->crc32();
|
||||
#}
|
||||
#
|
||||
#sub adler32
|
||||
#{
|
||||
# my $self = shift ;
|
||||
# $self->{Def}->adler32();
|
||||
#}
|
||||
|
||||
|
||||
1;
|
||||
|
||||
__END__
|
||||
169
database/perl/lib/IO/Compress/Adapter/Deflate.pm
Normal file
169
database/perl/lib/IO/Compress/Adapter/Deflate.pm
Normal file
@@ -0,0 +1,169 @@
|
||||
package IO::Compress::Adapter::Deflate ;
|
||||
|
||||
use strict;
|
||||
use warnings;
|
||||
use bytes;
|
||||
|
||||
use IO::Compress::Base::Common 2.100 qw(:Status);
|
||||
use Compress::Raw::Zlib 2.100 qw( !crc32 !adler32 ) ;
|
||||
|
||||
require Exporter;
|
||||
our ($VERSION, @ISA, @EXPORT_OK, %EXPORT_TAGS, @EXPORT, %DEFLATE_CONSTANTS);
|
||||
|
||||
$VERSION = '2.100';
|
||||
@ISA = qw(Exporter);
|
||||
@EXPORT_OK = @Compress::Raw::Zlib::DEFLATE_CONSTANTS;
|
||||
%EXPORT_TAGS = %Compress::Raw::Zlib::DEFLATE_CONSTANTS;
|
||||
@EXPORT = @EXPORT_OK;
|
||||
%DEFLATE_CONSTANTS = %EXPORT_TAGS ;
|
||||
|
||||
sub mkCompObject
|
||||
{
|
||||
my $crc32 = shift ;
|
||||
my $adler32 = shift ;
|
||||
my $level = shift ;
|
||||
my $strategy = shift ;
|
||||
|
||||
my ($def, $status) = Compress::Raw::Zlib::Deflate->new(
|
||||
-AppendOutput => 1,
|
||||
-CRC32 => $crc32,
|
||||
-ADLER32 => $adler32,
|
||||
-Level => $level,
|
||||
-Strategy => $strategy,
|
||||
-WindowBits => - MAX_WBITS);
|
||||
|
||||
return (undef, "Cannot create Deflate object: $status", $status)
|
||||
if $status != Z_OK;
|
||||
|
||||
return bless {'Def' => $def,
|
||||
'Error' => '',
|
||||
} ;
|
||||
}
|
||||
|
||||
sub compr
|
||||
{
|
||||
my $self = shift ;
|
||||
|
||||
my $def = $self->{Def};
|
||||
|
||||
my $status = $def->deflate($_[0], $_[1]) ;
|
||||
$self->{ErrorNo} = $status;
|
||||
|
||||
if ($status != Z_OK)
|
||||
{
|
||||
$self->{Error} = "Deflate Error: $status";
|
||||
return STATUS_ERROR;
|
||||
}
|
||||
|
||||
return STATUS_OK;
|
||||
}
|
||||
|
||||
sub flush
|
||||
{
|
||||
my $self = shift ;
|
||||
|
||||
my $def = $self->{Def};
|
||||
|
||||
my $opt = $_[1] || Z_FINISH;
|
||||
my $status = $def->flush($_[0], $opt);
|
||||
$self->{ErrorNo} = $status;
|
||||
|
||||
if ($status != Z_OK)
|
||||
{
|
||||
$self->{Error} = "Deflate Error: $status";
|
||||
return STATUS_ERROR;
|
||||
}
|
||||
|
||||
return STATUS_OK;
|
||||
}
|
||||
|
||||
sub close
|
||||
{
|
||||
my $self = shift ;
|
||||
|
||||
my $def = $self->{Def};
|
||||
|
||||
$def->flush($_[0], Z_FINISH)
|
||||
if defined $def ;
|
||||
}
|
||||
|
||||
sub reset
|
||||
{
|
||||
my $self = shift ;
|
||||
|
||||
my $def = $self->{Def};
|
||||
|
||||
my $status = $def->deflateReset() ;
|
||||
$self->{ErrorNo} = $status;
|
||||
if ($status != Z_OK)
|
||||
{
|
||||
$self->{Error} = "Deflate Error: $status";
|
||||
return STATUS_ERROR;
|
||||
}
|
||||
|
||||
return STATUS_OK;
|
||||
}
|
||||
|
||||
sub deflateParams
|
||||
{
|
||||
my $self = shift ;
|
||||
|
||||
my $def = $self->{Def};
|
||||
|
||||
my $status = $def->deflateParams(@_);
|
||||
$self->{ErrorNo} = $status;
|
||||
if ($status != Z_OK)
|
||||
{
|
||||
$self->{Error} = "deflateParams Error: $status";
|
||||
return STATUS_ERROR;
|
||||
}
|
||||
|
||||
return STATUS_OK;
|
||||
}
|
||||
|
||||
|
||||
|
||||
#sub total_out
|
||||
#{
|
||||
# my $self = shift ;
|
||||
# $self->{Def}->total_out();
|
||||
#}
|
||||
#
|
||||
#sub total_in
|
||||
#{
|
||||
# my $self = shift ;
|
||||
# $self->{Def}->total_in();
|
||||
#}
|
||||
|
||||
sub compressedBytes
|
||||
{
|
||||
my $self = shift ;
|
||||
|
||||
$self->{Def}->compressedBytes();
|
||||
}
|
||||
|
||||
sub uncompressedBytes
|
||||
{
|
||||
my $self = shift ;
|
||||
$self->{Def}->uncompressedBytes();
|
||||
}
|
||||
|
||||
|
||||
|
||||
|
||||
sub crc32
|
||||
{
|
||||
my $self = shift ;
|
||||
$self->{Def}->crc32();
|
||||
}
|
||||
|
||||
sub adler32
|
||||
{
|
||||
my $self = shift ;
|
||||
$self->{Def}->adler32();
|
||||
}
|
||||
|
||||
|
||||
1;
|
||||
|
||||
__END__
|
||||
100
database/perl/lib/IO/Compress/Adapter/Identity.pm
Normal file
100
database/perl/lib/IO/Compress/Adapter/Identity.pm
Normal file
@@ -0,0 +1,100 @@
|
||||
package IO::Compress::Adapter::Identity ;
|
||||
|
||||
use strict;
|
||||
use warnings;
|
||||
use bytes;
|
||||
|
||||
use IO::Compress::Base::Common 2.100 qw(:Status);
|
||||
our ($VERSION);
|
||||
|
||||
$VERSION = '2.100';
|
||||
|
||||
sub mkCompObject
|
||||
{
|
||||
my $level = shift ;
|
||||
my $strategy = shift ;
|
||||
|
||||
return bless {
|
||||
'CompSize' => 0,
|
||||
'UnCompSize' => 0,
|
||||
'Error' => '',
|
||||
'ErrorNo' => 0,
|
||||
} ;
|
||||
}
|
||||
|
||||
sub compr
|
||||
{
|
||||
my $self = shift ;
|
||||
|
||||
if (defined ${ $_[0] } && length ${ $_[0] }) {
|
||||
$self->{CompSize} += length ${ $_[0] } ;
|
||||
$self->{UnCompSize} = $self->{CompSize} ;
|
||||
|
||||
if ( ref $_[1] )
|
||||
{ ${ $_[1] } .= ${ $_[0] } }
|
||||
else
|
||||
{ $_[1] .= ${ $_[0] } }
|
||||
}
|
||||
|
||||
return STATUS_OK ;
|
||||
}
|
||||
|
||||
sub flush
|
||||
{
|
||||
my $self = shift ;
|
||||
|
||||
return STATUS_OK;
|
||||
}
|
||||
|
||||
sub close
|
||||
{
|
||||
my $self = shift ;
|
||||
|
||||
return STATUS_OK;
|
||||
}
|
||||
|
||||
sub reset
|
||||
{
|
||||
my $self = shift ;
|
||||
|
||||
$self->{CompSize} = 0;
|
||||
$self->{UnCompSize} = 0;
|
||||
|
||||
return STATUS_OK;
|
||||
}
|
||||
|
||||
sub deflateParams
|
||||
{
|
||||
my $self = shift ;
|
||||
|
||||
return STATUS_OK;
|
||||
}
|
||||
|
||||
#sub total_out
|
||||
#{
|
||||
# my $self = shift ;
|
||||
# return $self->{UnCompSize} ;
|
||||
#}
|
||||
#
|
||||
#sub total_in
|
||||
#{
|
||||
# my $self = shift ;
|
||||
# return $self->{UnCompSize} ;
|
||||
#}
|
||||
|
||||
sub compressedBytes
|
||||
{
|
||||
my $self = shift ;
|
||||
return $self->{UnCompSize} ;
|
||||
}
|
||||
|
||||
sub uncompressedBytes
|
||||
{
|
||||
my $self = shift ;
|
||||
return $self->{UnCompSize} ;
|
||||
}
|
||||
|
||||
1;
|
||||
|
||||
|
||||
__END__
|
||||
1057
database/perl/lib/IO/Compress/Base.pm
Normal file
1057
database/perl/lib/IO/Compress/Base.pm
Normal file
File diff suppressed because it is too large
Load Diff
1053
database/perl/lib/IO/Compress/Base/Common.pm
Normal file
1053
database/perl/lib/IO/Compress/Base/Common.pm
Normal file
File diff suppressed because it is too large
Load Diff
824
database/perl/lib/IO/Compress/Bzip2.pm
Normal file
824
database/perl/lib/IO/Compress/Bzip2.pm
Normal file
@@ -0,0 +1,824 @@
|
||||
package IO::Compress::Bzip2 ;
|
||||
|
||||
use strict ;
|
||||
use warnings;
|
||||
use bytes;
|
||||
require Exporter ;
|
||||
|
||||
use IO::Compress::Base 2.100 ;
|
||||
|
||||
use IO::Compress::Base::Common 2.100 qw();
|
||||
use IO::Compress::Adapter::Bzip2 2.100 ;
|
||||
|
||||
|
||||
|
||||
our ($VERSION, @ISA, @EXPORT_OK, %EXPORT_TAGS, $Bzip2Error);
|
||||
|
||||
$VERSION = '2.100';
|
||||
$Bzip2Error = '';
|
||||
|
||||
@ISA = qw(IO::Compress::Base Exporter);
|
||||
@EXPORT_OK = qw( $Bzip2Error bzip2 ) ;
|
||||
%EXPORT_TAGS = %IO::Compress::Base::EXPORT_TAGS ;
|
||||
push @{ $EXPORT_TAGS{all} }, @EXPORT_OK ;
|
||||
Exporter::export_ok_tags('all');
|
||||
|
||||
|
||||
|
||||
sub new
|
||||
{
|
||||
my $class = shift ;
|
||||
|
||||
my $obj = IO::Compress::Base::Common::createSelfTiedObject($class, \$Bzip2Error);
|
||||
return $obj->_create(undef, @_);
|
||||
}
|
||||
|
||||
sub bzip2
|
||||
{
|
||||
my $obj = IO::Compress::Base::Common::createSelfTiedObject(undef, \$Bzip2Error);
|
||||
$obj->_def(@_);
|
||||
}
|
||||
|
||||
|
||||
sub mkHeader
|
||||
{
|
||||
my $self = shift ;
|
||||
return '';
|
||||
|
||||
}
|
||||
|
||||
sub getExtraParams
|
||||
{
|
||||
my $self = shift ;
|
||||
|
||||
use IO::Compress::Base::Common 2.100 qw(:Parse);
|
||||
|
||||
return (
|
||||
'blocksize100k' => [IO::Compress::Base::Common::Parse_unsigned, 1],
|
||||
'workfactor' => [IO::Compress::Base::Common::Parse_unsigned, 0],
|
||||
'verbosity' => [IO::Compress::Base::Common::Parse_boolean, 0],
|
||||
);
|
||||
}
|
||||
|
||||
|
||||
|
||||
sub ckParams
|
||||
{
|
||||
my $self = shift ;
|
||||
my $got = shift;
|
||||
|
||||
# check that BlockSize100K is a number between 1 & 9
|
||||
if ($got->parsed('blocksize100k')) {
|
||||
my $value = $got->getValue('blocksize100k');
|
||||
return $self->saveErrorString(undef, "Parameter 'BlockSize100K' not between 1 and 9, got $value")
|
||||
unless defined $value && $value >= 1 && $value <= 9;
|
||||
|
||||
}
|
||||
|
||||
# check that WorkFactor between 0 & 250
|
||||
if ($got->parsed('workfactor')) {
|
||||
my $value = $got->getValue('workfactor');
|
||||
return $self->saveErrorString(undef, "Parameter 'WorkFactor' not between 0 and 250, got $value")
|
||||
unless $value >= 0 && $value <= 250;
|
||||
}
|
||||
|
||||
return 1 ;
|
||||
}
|
||||
|
||||
|
||||
sub mkComp
|
||||
{
|
||||
my $self = shift ;
|
||||
my $got = shift ;
|
||||
|
||||
my $BlockSize100K = $got->getValue('blocksize100k');
|
||||
my $WorkFactor = $got->getValue('workfactor');
|
||||
my $Verbosity = $got->getValue('verbosity');
|
||||
|
||||
my ($obj, $errstr, $errno) = IO::Compress::Adapter::Bzip2::mkCompObject(
|
||||
$BlockSize100K, $WorkFactor,
|
||||
$Verbosity);
|
||||
|
||||
return $self->saveErrorString(undef, $errstr, $errno)
|
||||
if ! defined $obj;
|
||||
|
||||
return $obj;
|
||||
}
|
||||
|
||||
|
||||
sub mkTrailer
|
||||
{
|
||||
my $self = shift ;
|
||||
return '';
|
||||
}
|
||||
|
||||
sub mkFinalTrailer
|
||||
{
|
||||
return '';
|
||||
}
|
||||
|
||||
#sub newHeader
|
||||
#{
|
||||
# my $self = shift ;
|
||||
# return '';
|
||||
#}
|
||||
|
||||
sub getInverseClass
|
||||
{
|
||||
return ('IO::Uncompress::Bunzip2');
|
||||
}
|
||||
|
||||
sub getFileInfo
|
||||
{
|
||||
my $self = shift ;
|
||||
my $params = shift;
|
||||
my $file = shift ;
|
||||
|
||||
}
|
||||
|
||||
1;
|
||||
|
||||
__END__
|
||||
|
||||
=head1 NAME
|
||||
|
||||
IO::Compress::Bzip2 - Write bzip2 files/buffers
|
||||
|
||||
=head1 SYNOPSIS
|
||||
|
||||
use IO::Compress::Bzip2 qw(bzip2 $Bzip2Error) ;
|
||||
|
||||
my $status = bzip2 $input => $output [,OPTS]
|
||||
or die "bzip2 failed: $Bzip2Error\n";
|
||||
|
||||
my $z = IO::Compress::Bzip2->new( $output [,OPTS] )
|
||||
or die "bzip2 failed: $Bzip2Error\n";
|
||||
|
||||
$z->print($string);
|
||||
$z->printf($format, $string);
|
||||
$z->write($string);
|
||||
$z->syswrite($string [, $length, $offset]);
|
||||
$z->flush();
|
||||
$z->tell();
|
||||
$z->eof();
|
||||
$z->seek($position, $whence);
|
||||
$z->binmode();
|
||||
$z->fileno();
|
||||
$z->opened();
|
||||
$z->autoflush();
|
||||
$z->input_line_number();
|
||||
$z->newStream( [OPTS] );
|
||||
|
||||
$z->close() ;
|
||||
|
||||
$Bzip2Error ;
|
||||
|
||||
# IO::File mode
|
||||
|
||||
print $z $string;
|
||||
printf $z $format, $string;
|
||||
tell $z
|
||||
eof $z
|
||||
seek $z, $position, $whence
|
||||
binmode $z
|
||||
fileno $z
|
||||
close $z ;
|
||||
|
||||
=head1 DESCRIPTION
|
||||
|
||||
This module provides a Perl interface that allows writing bzip2
|
||||
compressed data to files or buffer.
|
||||
|
||||
For reading bzip2 files/buffers, see the companion module
|
||||
L<IO::Uncompress::Bunzip2|IO::Uncompress::Bunzip2>.
|
||||
|
||||
=head1 Functional Interface
|
||||
|
||||
A top-level function, C<bzip2>, is provided to carry out
|
||||
"one-shot" compression between buffers and/or files. For finer
|
||||
control over the compression process, see the L</"OO Interface">
|
||||
section.
|
||||
|
||||
use IO::Compress::Bzip2 qw(bzip2 $Bzip2Error) ;
|
||||
|
||||
bzip2 $input_filename_or_reference => $output_filename_or_reference [,OPTS]
|
||||
or die "bzip2 failed: $Bzip2Error\n";
|
||||
|
||||
The functional interface needs Perl5.005 or better.
|
||||
|
||||
=head2 bzip2 $input_filename_or_reference => $output_filename_or_reference [, OPTS]
|
||||
|
||||
C<bzip2> expects at least two parameters,
|
||||
C<$input_filename_or_reference> and C<$output_filename_or_reference>
|
||||
and zero or more optional parameters (see L</Optional Parameters>)
|
||||
|
||||
=head3 The C<$input_filename_or_reference> parameter
|
||||
|
||||
The parameter, C<$input_filename_or_reference>, is used to define the
|
||||
source of the uncompressed data.
|
||||
|
||||
It can take one of the following forms:
|
||||
|
||||
=over 5
|
||||
|
||||
=item A filename
|
||||
|
||||
If the C<$input_filename_or_reference> parameter is a simple scalar, it is
|
||||
assumed to be a filename. This file will be opened for reading and the
|
||||
input data will be read from it.
|
||||
|
||||
=item A filehandle
|
||||
|
||||
If the C<$input_filename_or_reference> parameter is a filehandle, the input
|
||||
data will be read from it. The string '-' can be used as an alias for
|
||||
standard input.
|
||||
|
||||
=item A scalar reference
|
||||
|
||||
If C<$input_filename_or_reference> is a scalar reference, the input data
|
||||
will be read from C<$$input_filename_or_reference>.
|
||||
|
||||
=item An array reference
|
||||
|
||||
If C<$input_filename_or_reference> is an array reference, each element in
|
||||
the array must be a filename.
|
||||
|
||||
The input data will be read from each file in turn.
|
||||
|
||||
The complete array will be walked to ensure that it only
|
||||
contains valid filenames before any data is compressed.
|
||||
|
||||
=item An Input FileGlob string
|
||||
|
||||
If C<$input_filename_or_reference> is a string that is delimited by the
|
||||
characters "<" and ">" C<bzip2> will assume that it is an
|
||||
I<input fileglob string>. The input is the list of files that match the
|
||||
fileglob.
|
||||
|
||||
See L<File::GlobMapper|File::GlobMapper> for more details.
|
||||
|
||||
=back
|
||||
|
||||
If the C<$input_filename_or_reference> parameter is any other type,
|
||||
C<undef> will be returned.
|
||||
|
||||
=head3 The C<$output_filename_or_reference> parameter
|
||||
|
||||
The parameter C<$output_filename_or_reference> is used to control the
|
||||
destination of the compressed data. This parameter can take one of
|
||||
these forms.
|
||||
|
||||
=over 5
|
||||
|
||||
=item A filename
|
||||
|
||||
If the C<$output_filename_or_reference> parameter is a simple scalar, it is
|
||||
assumed to be a filename. This file will be opened for writing and the
|
||||
compressed data will be written to it.
|
||||
|
||||
=item A filehandle
|
||||
|
||||
If the C<$output_filename_or_reference> parameter is a filehandle, the
|
||||
compressed data will be written to it. The string '-' can be used as
|
||||
an alias for standard output.
|
||||
|
||||
=item A scalar reference
|
||||
|
||||
If C<$output_filename_or_reference> is a scalar reference, the
|
||||
compressed data will be stored in C<$$output_filename_or_reference>.
|
||||
|
||||
=item An Array Reference
|
||||
|
||||
If C<$output_filename_or_reference> is an array reference,
|
||||
the compressed data will be pushed onto the array.
|
||||
|
||||
=item An Output FileGlob
|
||||
|
||||
If C<$output_filename_or_reference> is a string that is delimited by the
|
||||
characters "<" and ">" C<bzip2> will assume that it is an
|
||||
I<output fileglob string>. The output is the list of files that match the
|
||||
fileglob.
|
||||
|
||||
When C<$output_filename_or_reference> is an fileglob string,
|
||||
C<$input_filename_or_reference> must also be a fileglob string. Anything
|
||||
else is an error.
|
||||
|
||||
See L<File::GlobMapper|File::GlobMapper> for more details.
|
||||
|
||||
=back
|
||||
|
||||
If the C<$output_filename_or_reference> parameter is any other type,
|
||||
C<undef> will be returned.
|
||||
|
||||
=head2 Notes
|
||||
|
||||
When C<$input_filename_or_reference> maps to multiple files/buffers and
|
||||
C<$output_filename_or_reference> is a single
|
||||
file/buffer the input files/buffers will be stored
|
||||
in C<$output_filename_or_reference> as a concatenated series of compressed data streams.
|
||||
|
||||
=head2 Optional Parameters
|
||||
|
||||
The optional parameters for the one-shot function C<bzip2>
|
||||
are (for the most part) identical to those used with the OO interface defined in the
|
||||
L</"Constructor Options"> section. The exceptions are listed below
|
||||
|
||||
=over 5
|
||||
|
||||
=item C<< AutoClose => 0|1 >>
|
||||
|
||||
This option applies to any input or output data streams to
|
||||
C<bzip2> that are filehandles.
|
||||
|
||||
If C<AutoClose> is specified, and the value is true, it will result in all
|
||||
input and/or output filehandles being closed once C<bzip2> has
|
||||
completed.
|
||||
|
||||
This parameter defaults to 0.
|
||||
|
||||
=item C<< BinModeIn => 0|1 >>
|
||||
|
||||
This option is now a no-op. All files will be read in binmode.
|
||||
|
||||
=item C<< Append => 0|1 >>
|
||||
|
||||
The behaviour of this option is dependent on the type of output data
|
||||
stream.
|
||||
|
||||
=over 5
|
||||
|
||||
=item * A Buffer
|
||||
|
||||
If C<Append> is enabled, all compressed data will be append to the end of
|
||||
the output buffer. Otherwise the output buffer will be cleared before any
|
||||
compressed data is written to it.
|
||||
|
||||
=item * A Filename
|
||||
|
||||
If C<Append> is enabled, the file will be opened in append mode. Otherwise
|
||||
the contents of the file, if any, will be truncated before any compressed
|
||||
data is written to it.
|
||||
|
||||
=item * A Filehandle
|
||||
|
||||
If C<Append> is enabled, the filehandle will be positioned to the end of
|
||||
the file via a call to C<seek> before any compressed data is
|
||||
written to it. Otherwise the file pointer will not be moved.
|
||||
|
||||
=back
|
||||
|
||||
When C<Append> is specified, and set to true, it will I<append> all compressed
|
||||
data to the output data stream.
|
||||
|
||||
So when the output is a filehandle it will carry out a seek to the eof
|
||||
before writing any compressed data. If the output is a filename, it will be opened for
|
||||
appending. If the output is a buffer, all compressed data will be
|
||||
appended to the existing buffer.
|
||||
|
||||
Conversely when C<Append> is not specified, or it is present and is set to
|
||||
false, it will operate as follows.
|
||||
|
||||
When the output is a filename, it will truncate the contents of the file
|
||||
before writing any compressed data. If the output is a filehandle
|
||||
its position will not be changed. If the output is a buffer, it will be
|
||||
wiped before any compressed data is output.
|
||||
|
||||
Defaults to 0.
|
||||
|
||||
=back
|
||||
|
||||
=head2 Examples
|
||||
|
||||
Here are a few example that show the capabilities of the module.
|
||||
|
||||
=head3 Streaming
|
||||
|
||||
This very simple command line example demonstrates the streaming capabilities of the module.
|
||||
The code reads data from STDIN, compresses it, and writes the compressed data to STDOUT.
|
||||
|
||||
$ echo hello world | perl -MIO::Compress::Bzip2=bzip2 -e 'bzip2 \*STDIN => \*STDOUT' >output.bz2
|
||||
|
||||
The special filename "-" can be used as a standin for both C<\*STDIN> and C<\*STDOUT>,
|
||||
so the above can be rewritten as
|
||||
|
||||
$ echo hello world | perl -MIO::Compress::Bzip2=bzip2 -e 'bzip2 "-" => "-"' >output.bz2
|
||||
|
||||
=head3 Compressing a file from the filesystem
|
||||
|
||||
To read the contents of the file C<file1.txt> and write the compressed
|
||||
data to the file C<file1.txt.bz2>.
|
||||
|
||||
use strict ;
|
||||
use warnings ;
|
||||
use IO::Compress::Bzip2 qw(bzip2 $Bzip2Error) ;
|
||||
|
||||
my $input = "file1.txt";
|
||||
bzip2 $input => "$input.bz2"
|
||||
or die "bzip2 failed: $Bzip2Error\n";
|
||||
|
||||
=head3 Reading from a Filehandle and writing to an in-memory buffer
|
||||
|
||||
To read from an existing Perl filehandle, C<$input>, and write the
|
||||
compressed data to a buffer, C<$buffer>.
|
||||
|
||||
use strict ;
|
||||
use warnings ;
|
||||
use IO::Compress::Bzip2 qw(bzip2 $Bzip2Error) ;
|
||||
use IO::File ;
|
||||
|
||||
my $input = IO::File->new( "<file1.txt" )
|
||||
or die "Cannot open 'file1.txt': $!\n" ;
|
||||
my $buffer ;
|
||||
bzip2 $input => \$buffer
|
||||
or die "bzip2 failed: $Bzip2Error\n";
|
||||
|
||||
=head3 Compressing multiple files
|
||||
|
||||
To compress all files in the directory "/my/home" that match "*.txt"
|
||||
and store the compressed data in the same directory
|
||||
|
||||
use strict ;
|
||||
use warnings ;
|
||||
use IO::Compress::Bzip2 qw(bzip2 $Bzip2Error) ;
|
||||
|
||||
bzip2 '</my/home/*.txt>' => '<*.bz2>'
|
||||
or die "bzip2 failed: $Bzip2Error\n";
|
||||
|
||||
and if you want to compress each file one at a time, this will do the trick
|
||||
|
||||
use strict ;
|
||||
use warnings ;
|
||||
use IO::Compress::Bzip2 qw(bzip2 $Bzip2Error) ;
|
||||
|
||||
for my $input ( glob "/my/home/*.txt" )
|
||||
{
|
||||
my $output = "$input.bz2" ;
|
||||
bzip2 $input => $output
|
||||
or die "Error compressing '$input': $Bzip2Error\n";
|
||||
}
|
||||
|
||||
=head1 OO Interface
|
||||
|
||||
=head2 Constructor
|
||||
|
||||
The format of the constructor for C<IO::Compress::Bzip2> is shown below
|
||||
|
||||
my $z = IO::Compress::Bzip2->new( $output [,OPTS] )
|
||||
or die "IO::Compress::Bzip2 failed: $Bzip2Error\n";
|
||||
|
||||
It returns an C<IO::Compress::Bzip2> object on success and undef on failure.
|
||||
The variable C<$Bzip2Error> will contain an error message on failure.
|
||||
|
||||
If you are running Perl 5.005 or better the object, C<$z>, returned from
|
||||
IO::Compress::Bzip2 can be used exactly like an L<IO::File|IO::File> filehandle.
|
||||
This means that all normal output file operations can be carried out
|
||||
with C<$z>.
|
||||
For example, to write to a compressed file/buffer you can use either of
|
||||
these forms
|
||||
|
||||
$z->print("hello world\n");
|
||||
print $z "hello world\n";
|
||||
|
||||
The mandatory parameter C<$output> is used to control the destination
|
||||
of the compressed data. This parameter can take one of these forms.
|
||||
|
||||
=over 5
|
||||
|
||||
=item A filename
|
||||
|
||||
If the C<$output> parameter is a simple scalar, it is assumed to be a
|
||||
filename. This file will be opened for writing and the compressed data
|
||||
will be written to it.
|
||||
|
||||
=item A filehandle
|
||||
|
||||
If the C<$output> parameter is a filehandle, the compressed data will be
|
||||
written to it.
|
||||
The string '-' can be used as an alias for standard output.
|
||||
|
||||
=item A scalar reference
|
||||
|
||||
If C<$output> is a scalar reference, the compressed data will be stored
|
||||
in C<$$output>.
|
||||
|
||||
=back
|
||||
|
||||
If the C<$output> parameter is any other type, C<IO::Compress::Bzip2>::new will
|
||||
return undef.
|
||||
|
||||
=head2 Constructor Options
|
||||
|
||||
C<OPTS> is any combination of zero or more the following options:
|
||||
|
||||
=over 5
|
||||
|
||||
=item C<< AutoClose => 0|1 >>
|
||||
|
||||
This option is only valid when the C<$output> parameter is a filehandle. If
|
||||
specified, and the value is true, it will result in the C<$output> being
|
||||
closed once either the C<close> method is called or the C<IO::Compress::Bzip2>
|
||||
object is destroyed.
|
||||
|
||||
This parameter defaults to 0.
|
||||
|
||||
=item C<< Append => 0|1 >>
|
||||
|
||||
Opens C<$output> in append mode.
|
||||
|
||||
The behaviour of this option is dependent on the type of C<$output>.
|
||||
|
||||
=over 5
|
||||
|
||||
=item * A Buffer
|
||||
|
||||
If C<$output> is a buffer and C<Append> is enabled, all compressed data
|
||||
will be append to the end of C<$output>. Otherwise C<$output> will be
|
||||
cleared before any data is written to it.
|
||||
|
||||
=item * A Filename
|
||||
|
||||
If C<$output> is a filename and C<Append> is enabled, the file will be
|
||||
opened in append mode. Otherwise the contents of the file, if any, will be
|
||||
truncated before any compressed data is written to it.
|
||||
|
||||
=item * A Filehandle
|
||||
|
||||
If C<$output> is a filehandle, the file pointer will be positioned to the
|
||||
end of the file via a call to C<seek> before any compressed data is written
|
||||
to it. Otherwise the file pointer will not be moved.
|
||||
|
||||
=back
|
||||
|
||||
This parameter defaults to 0.
|
||||
|
||||
=item C<< BlockSize100K => number >>
|
||||
|
||||
Specify the number of 100K blocks bzip2 uses during compression.
|
||||
|
||||
Valid values are from 1 to 9, where 9 is best compression.
|
||||
|
||||
The default is 1.
|
||||
|
||||
=item C<< WorkFactor => number >>
|
||||
|
||||
Specifies how much effort bzip2 should take before resorting to a slower
|
||||
fallback compression algorithm.
|
||||
|
||||
Valid values range from 0 to 250, where 0 means use the default value 30.
|
||||
|
||||
The default is 0.
|
||||
|
||||
=item C<< Strict => 0|1 >>
|
||||
|
||||
This is a placeholder option.
|
||||
|
||||
=back
|
||||
|
||||
=head2 Examples
|
||||
|
||||
TODO
|
||||
|
||||
=head1 Methods
|
||||
|
||||
=head2 print
|
||||
|
||||
Usage is
|
||||
|
||||
$z->print($data)
|
||||
print $z $data
|
||||
|
||||
Compresses and outputs the contents of the C<$data> parameter. This
|
||||
has the same behaviour as the C<print> built-in.
|
||||
|
||||
Returns true if successful.
|
||||
|
||||
=head2 printf
|
||||
|
||||
Usage is
|
||||
|
||||
$z->printf($format, $data)
|
||||
printf $z $format, $data
|
||||
|
||||
Compresses and outputs the contents of the C<$data> parameter.
|
||||
|
||||
Returns true if successful.
|
||||
|
||||
=head2 syswrite
|
||||
|
||||
Usage is
|
||||
|
||||
$z->syswrite $data
|
||||
$z->syswrite $data, $length
|
||||
$z->syswrite $data, $length, $offset
|
||||
|
||||
Compresses and outputs the contents of the C<$data> parameter.
|
||||
|
||||
Returns the number of uncompressed bytes written, or C<undef> if
|
||||
unsuccessful.
|
||||
|
||||
=head2 write
|
||||
|
||||
Usage is
|
||||
|
||||
$z->write $data
|
||||
$z->write $data, $length
|
||||
$z->write $data, $length, $offset
|
||||
|
||||
Compresses and outputs the contents of the C<$data> parameter.
|
||||
|
||||
Returns the number of uncompressed bytes written, or C<undef> if
|
||||
unsuccessful.
|
||||
|
||||
=head2 flush
|
||||
|
||||
Usage is
|
||||
|
||||
$z->flush;
|
||||
|
||||
Flushes any pending compressed data to the output file/buffer.
|
||||
|
||||
TODO
|
||||
|
||||
Returns true on success.
|
||||
|
||||
=head2 tell
|
||||
|
||||
Usage is
|
||||
|
||||
$z->tell()
|
||||
tell $z
|
||||
|
||||
Returns the uncompressed file offset.
|
||||
|
||||
=head2 eof
|
||||
|
||||
Usage is
|
||||
|
||||
$z->eof();
|
||||
eof($z);
|
||||
|
||||
Returns true if the C<close> method has been called.
|
||||
|
||||
=head2 seek
|
||||
|
||||
$z->seek($position, $whence);
|
||||
seek($z, $position, $whence);
|
||||
|
||||
Provides a sub-set of the C<seek> functionality, with the restriction
|
||||
that it is only legal to seek forward in the output file/buffer.
|
||||
It is a fatal error to attempt to seek backward.
|
||||
|
||||
Empty parts of the file/buffer will have NULL (0x00) bytes written to them.
|
||||
|
||||
The C<$whence> parameter takes one the usual values, namely SEEK_SET,
|
||||
SEEK_CUR or SEEK_END.
|
||||
|
||||
Returns 1 on success, 0 on failure.
|
||||
|
||||
=head2 binmode
|
||||
|
||||
Usage is
|
||||
|
||||
$z->binmode
|
||||
binmode $z ;
|
||||
|
||||
This is a noop provided for completeness.
|
||||
|
||||
=head2 opened
|
||||
|
||||
$z->opened()
|
||||
|
||||
Returns true if the object currently refers to a opened file/buffer.
|
||||
|
||||
=head2 autoflush
|
||||
|
||||
my $prev = $z->autoflush()
|
||||
my $prev = $z->autoflush(EXPR)
|
||||
|
||||
If the C<$z> object is associated with a file or a filehandle, this method
|
||||
returns the current autoflush setting for the underlying filehandle. If
|
||||
C<EXPR> is present, and is non-zero, it will enable flushing after every
|
||||
write/print operation.
|
||||
|
||||
If C<$z> is associated with a buffer, this method has no effect and always
|
||||
returns C<undef>.
|
||||
|
||||
B<Note> that the special variable C<$|> B<cannot> be used to set or
|
||||
retrieve the autoflush setting.
|
||||
|
||||
=head2 input_line_number
|
||||
|
||||
$z->input_line_number()
|
||||
$z->input_line_number(EXPR)
|
||||
|
||||
This method always returns C<undef> when compressing.
|
||||
|
||||
=head2 fileno
|
||||
|
||||
$z->fileno()
|
||||
fileno($z)
|
||||
|
||||
If the C<$z> object is associated with a file or a filehandle, C<fileno>
|
||||
will return the underlying file descriptor. Once the C<close> method is
|
||||
called C<fileno> will return C<undef>.
|
||||
|
||||
If the C<$z> object is associated with a buffer, this method will return
|
||||
C<undef>.
|
||||
|
||||
=head2 close
|
||||
|
||||
$z->close() ;
|
||||
close $z ;
|
||||
|
||||
Flushes any pending compressed data and then closes the output file/buffer.
|
||||
|
||||
For most versions of Perl this method will be automatically invoked if
|
||||
the IO::Compress::Bzip2 object is destroyed (either explicitly or by the
|
||||
variable with the reference to the object going out of scope). The
|
||||
exceptions are Perl versions 5.005 through 5.00504 and 5.8.0. In
|
||||
these cases, the C<close> method will be called automatically, but
|
||||
not until global destruction of all live objects when the program is
|
||||
terminating.
|
||||
|
||||
Therefore, if you want your scripts to be able to run on all versions
|
||||
of Perl, you should call C<close> explicitly and not rely on automatic
|
||||
closing.
|
||||
|
||||
Returns true on success, otherwise 0.
|
||||
|
||||
If the C<AutoClose> option has been enabled when the IO::Compress::Bzip2
|
||||
object was created, and the object is associated with a file, the
|
||||
underlying file will also be closed.
|
||||
|
||||
=head2 newStream([OPTS])
|
||||
|
||||
Usage is
|
||||
|
||||
$z->newStream( [OPTS] )
|
||||
|
||||
Closes the current compressed data stream and starts a new one.
|
||||
|
||||
OPTS consists of any of the options that are available when creating
|
||||
the C<$z> object.
|
||||
|
||||
See the L</"Constructor Options"> section for more details.
|
||||
|
||||
=head1 Importing
|
||||
|
||||
No symbolic constants are required by IO::Compress::Bzip2 at present.
|
||||
|
||||
=over 5
|
||||
|
||||
=item :all
|
||||
|
||||
Imports C<bzip2> and C<$Bzip2Error>.
|
||||
Same as doing this
|
||||
|
||||
use IO::Compress::Bzip2 qw(bzip2 $Bzip2Error) ;
|
||||
|
||||
=back
|
||||
|
||||
=head1 EXAMPLES
|
||||
|
||||
=head2 Apache::GZip Revisited
|
||||
|
||||
See L<IO::Compress::FAQ|IO::Compress::FAQ/"Apache::GZip Revisited">
|
||||
|
||||
=head2 Working with Net::FTP
|
||||
|
||||
See L<IO::Compress::FAQ|IO::Compress::FAQ/"Compressed files and Net::FTP">
|
||||
|
||||
=head1 SUPPORT
|
||||
|
||||
General feedback/questions/bug reports should be sent to
|
||||
L<https://github.com/pmqs/IO-Compress/issues> (preferred) or
|
||||
L<https://rt.cpan.org/Public/Dist/Display.html?Name=IO-Compress>.
|
||||
|
||||
=head1 SEE ALSO
|
||||
|
||||
L<Compress::Zlib>, L<IO::Compress::Gzip>, L<IO::Uncompress::Gunzip>, L<IO::Compress::Deflate>, L<IO::Uncompress::Inflate>, L<IO::Compress::RawDeflate>, L<IO::Uncompress::RawInflate>, L<IO::Uncompress::Bunzip2>, L<IO::Compress::Lzma>, L<IO::Uncompress::UnLzma>, L<IO::Compress::Xz>, L<IO::Uncompress::UnXz>, L<IO::Compress::Lzip>, L<IO::Uncompress::UnLzip>, L<IO::Compress::Lzop>, L<IO::Uncompress::UnLzop>, L<IO::Compress::Lzf>, L<IO::Uncompress::UnLzf>, L<IO::Compress::Zstd>, L<IO::Uncompress::UnZstd>, L<IO::Uncompress::AnyInflate>, L<IO::Uncompress::AnyUncompress>
|
||||
|
||||
L<IO::Compress::FAQ|IO::Compress::FAQ>
|
||||
|
||||
L<File::GlobMapper|File::GlobMapper>, L<Archive::Zip|Archive::Zip>,
|
||||
L<Archive::Tar|Archive::Tar>,
|
||||
L<IO::Zlib|IO::Zlib>
|
||||
|
||||
The primary site for the bzip2 program is L<https://sourceware.org/bzip2/>.
|
||||
|
||||
See the module L<Compress::Bzip2|Compress::Bzip2>
|
||||
|
||||
=head1 AUTHOR
|
||||
|
||||
This module was written by Paul Marquess, C<pmqs@cpan.org>.
|
||||
|
||||
=head1 MODIFICATION HISTORY
|
||||
|
||||
See the Changes file.
|
||||
|
||||
=head1 COPYRIGHT AND LICENSE
|
||||
|
||||
Copyright (c) 2005-2021 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.
|
||||
958
database/perl/lib/IO/Compress/Deflate.pm
Normal file
958
database/perl/lib/IO/Compress/Deflate.pm
Normal file
@@ -0,0 +1,958 @@
|
||||
package IO::Compress::Deflate ;
|
||||
|
||||
require 5.006 ;
|
||||
|
||||
use strict ;
|
||||
use warnings;
|
||||
use bytes;
|
||||
|
||||
require Exporter ;
|
||||
|
||||
use IO::Compress::RawDeflate 2.100 ();
|
||||
use IO::Compress::Adapter::Deflate 2.100 ;
|
||||
|
||||
use IO::Compress::Zlib::Constants 2.100 ;
|
||||
use IO::Compress::Base::Common 2.100 qw();
|
||||
|
||||
|
||||
our ($VERSION, @ISA, @EXPORT_OK, %EXPORT_TAGS, %DEFLATE_CONSTANTS, $DeflateError);
|
||||
|
||||
$VERSION = '2.100';
|
||||
$DeflateError = '';
|
||||
|
||||
@ISA = qw(IO::Compress::RawDeflate Exporter);
|
||||
@EXPORT_OK = qw( $DeflateError deflate ) ;
|
||||
%EXPORT_TAGS = %IO::Compress::RawDeflate::DEFLATE_CONSTANTS ;
|
||||
|
||||
push @{ $EXPORT_TAGS{all} }, @EXPORT_OK ;
|
||||
Exporter::export_ok_tags('all');
|
||||
|
||||
|
||||
sub new
|
||||
{
|
||||
my $class = shift ;
|
||||
|
||||
my $obj = IO::Compress::Base::Common::createSelfTiedObject($class, \$DeflateError);
|
||||
return $obj->_create(undef, @_);
|
||||
}
|
||||
|
||||
sub deflate
|
||||
{
|
||||
my $obj = IO::Compress::Base::Common::createSelfTiedObject(undef, \$DeflateError);
|
||||
return $obj->_def(@_);
|
||||
}
|
||||
|
||||
|
||||
sub bitmask($$$$)
|
||||
{
|
||||
my $into = shift ;
|
||||
my $value = shift ;
|
||||
my $offset = shift ;
|
||||
my $mask = shift ;
|
||||
|
||||
return $into | (($value & $mask) << $offset ) ;
|
||||
}
|
||||
|
||||
sub mkDeflateHdr($$$;$)
|
||||
{
|
||||
my $method = shift ;
|
||||
my $cinfo = shift;
|
||||
my $level = shift;
|
||||
my $fdict_adler = shift ;
|
||||
|
||||
my $cmf = 0;
|
||||
my $flg = 0;
|
||||
my $fdict = 0;
|
||||
$fdict = 1 if defined $fdict_adler;
|
||||
|
||||
$cmf = bitmask($cmf, $method, ZLIB_CMF_CM_OFFSET, ZLIB_CMF_CM_BITS);
|
||||
$cmf = bitmask($cmf, $cinfo, ZLIB_CMF_CINFO_OFFSET, ZLIB_CMF_CINFO_BITS);
|
||||
|
||||
$flg = bitmask($flg, $fdict, ZLIB_FLG_FDICT_OFFSET, ZLIB_FLG_FDICT_BITS);
|
||||
$flg = bitmask($flg, $level, ZLIB_FLG_LEVEL_OFFSET, ZLIB_FLG_LEVEL_BITS);
|
||||
|
||||
my $fcheck = 31 - ($cmf * 256 + $flg) % 31 ;
|
||||
$flg = bitmask($flg, $fcheck, ZLIB_FLG_FCHECK_OFFSET, ZLIB_FLG_FCHECK_BITS);
|
||||
|
||||
my $hdr = pack("CC", $cmf, $flg) ;
|
||||
$hdr .= pack("N", $fdict_adler) if $fdict ;
|
||||
|
||||
return $hdr;
|
||||
}
|
||||
|
||||
sub mkHeader
|
||||
{
|
||||
my $self = shift ;
|
||||
my $param = shift ;
|
||||
|
||||
my $level = $param->getValue('level');
|
||||
my $strategy = $param->getValue('strategy');
|
||||
|
||||
my $lflag ;
|
||||
$level = 6
|
||||
if $level == Z_DEFAULT_COMPRESSION ;
|
||||
|
||||
if (ZLIB_VERNUM >= 0x1210)
|
||||
{
|
||||
if ($strategy >= Z_HUFFMAN_ONLY || $level < 2)
|
||||
{ $lflag = ZLIB_FLG_LEVEL_FASTEST }
|
||||
elsif ($level < 6)
|
||||
{ $lflag = ZLIB_FLG_LEVEL_FAST }
|
||||
elsif ($level == 6)
|
||||
{ $lflag = ZLIB_FLG_LEVEL_DEFAULT }
|
||||
else
|
||||
{ $lflag = ZLIB_FLG_LEVEL_SLOWEST }
|
||||
}
|
||||
else
|
||||
{
|
||||
$lflag = ($level - 1) >> 1 ;
|
||||
$lflag = 3 if $lflag > 3 ;
|
||||
}
|
||||
|
||||
#my $wbits = (MAX_WBITS - 8) << 4 ;
|
||||
my $wbits = 7;
|
||||
mkDeflateHdr(ZLIB_CMF_CM_DEFLATED, $wbits, $lflag);
|
||||
}
|
||||
|
||||
sub ckParams
|
||||
{
|
||||
my $self = shift ;
|
||||
my $got = shift;
|
||||
|
||||
$got->setValue('adler32' => 1);
|
||||
return 1 ;
|
||||
}
|
||||
|
||||
|
||||
sub mkTrailer
|
||||
{
|
||||
my $self = shift ;
|
||||
return pack("N", *$self->{Compress}->adler32()) ;
|
||||
}
|
||||
|
||||
sub mkFinalTrailer
|
||||
{
|
||||
return '';
|
||||
}
|
||||
|
||||
#sub newHeader
|
||||
#{
|
||||
# my $self = shift ;
|
||||
# return *$self->{Header};
|
||||
#}
|
||||
|
||||
sub getExtraParams
|
||||
{
|
||||
my $self = shift ;
|
||||
return $self->getZlibParams(),
|
||||
}
|
||||
|
||||
sub getInverseClass
|
||||
{
|
||||
no warnings 'once';
|
||||
return ('IO::Uncompress::Inflate',
|
||||
\$IO::Uncompress::Inflate::InflateError);
|
||||
}
|
||||
|
||||
sub getFileInfo
|
||||
{
|
||||
my $self = shift ;
|
||||
my $params = shift;
|
||||
my $file = shift ;
|
||||
|
||||
}
|
||||
|
||||
|
||||
|
||||
1;
|
||||
|
||||
__END__
|
||||
|
||||
=head1 NAME
|
||||
|
||||
IO::Compress::Deflate - Write RFC 1950 files/buffers
|
||||
|
||||
=head1 SYNOPSIS
|
||||
|
||||
use IO::Compress::Deflate qw(deflate $DeflateError) ;
|
||||
|
||||
my $status = deflate $input => $output [,OPTS]
|
||||
or die "deflate failed: $DeflateError\n";
|
||||
|
||||
my $z = IO::Compress::Deflate->new( $output [,OPTS] )
|
||||
or die "deflate failed: $DeflateError\n";
|
||||
|
||||
$z->print($string);
|
||||
$z->printf($format, $string);
|
||||
$z->write($string);
|
||||
$z->syswrite($string [, $length, $offset]);
|
||||
$z->flush();
|
||||
$z->tell();
|
||||
$z->eof();
|
||||
$z->seek($position, $whence);
|
||||
$z->binmode();
|
||||
$z->fileno();
|
||||
$z->opened();
|
||||
$z->autoflush();
|
||||
$z->input_line_number();
|
||||
$z->newStream( [OPTS] );
|
||||
|
||||
$z->deflateParams();
|
||||
|
||||
$z->close() ;
|
||||
|
||||
$DeflateError ;
|
||||
|
||||
# IO::File mode
|
||||
|
||||
print $z $string;
|
||||
printf $z $format, $string;
|
||||
tell $z
|
||||
eof $z
|
||||
seek $z, $position, $whence
|
||||
binmode $z
|
||||
fileno $z
|
||||
close $z ;
|
||||
|
||||
=head1 DESCRIPTION
|
||||
|
||||
This module provides a Perl interface that allows writing compressed
|
||||
data to files or buffer as defined in RFC 1950.
|
||||
|
||||
For reading RFC 1950 files/buffers, see the companion module
|
||||
L<IO::Uncompress::Inflate|IO::Uncompress::Inflate>.
|
||||
|
||||
=head1 Functional Interface
|
||||
|
||||
A top-level function, C<deflate>, is provided to carry out
|
||||
"one-shot" compression between buffers and/or files. For finer
|
||||
control over the compression process, see the L</"OO Interface">
|
||||
section.
|
||||
|
||||
use IO::Compress::Deflate qw(deflate $DeflateError) ;
|
||||
|
||||
deflate $input_filename_or_reference => $output_filename_or_reference [,OPTS]
|
||||
or die "deflate failed: $DeflateError\n";
|
||||
|
||||
The functional interface needs Perl5.005 or better.
|
||||
|
||||
=head2 deflate $input_filename_or_reference => $output_filename_or_reference [, OPTS]
|
||||
|
||||
C<deflate> expects at least two parameters,
|
||||
C<$input_filename_or_reference> and C<$output_filename_or_reference>
|
||||
and zero or more optional parameters (see L</Optional Parameters>)
|
||||
|
||||
=head3 The C<$input_filename_or_reference> parameter
|
||||
|
||||
The parameter, C<$input_filename_or_reference>, is used to define the
|
||||
source of the uncompressed data.
|
||||
|
||||
It can take one of the following forms:
|
||||
|
||||
=over 5
|
||||
|
||||
=item A filename
|
||||
|
||||
If the C<$input_filename_or_reference> parameter is a simple scalar, it is
|
||||
assumed to be a filename. This file will be opened for reading and the
|
||||
input data will be read from it.
|
||||
|
||||
=item A filehandle
|
||||
|
||||
If the C<$input_filename_or_reference> parameter is a filehandle, the input
|
||||
data will be read from it. The string '-' can be used as an alias for
|
||||
standard input.
|
||||
|
||||
=item A scalar reference
|
||||
|
||||
If C<$input_filename_or_reference> is a scalar reference, the input data
|
||||
will be read from C<$$input_filename_or_reference>.
|
||||
|
||||
=item An array reference
|
||||
|
||||
If C<$input_filename_or_reference> is an array reference, each element in
|
||||
the array must be a filename.
|
||||
|
||||
The input data will be read from each file in turn.
|
||||
|
||||
The complete array will be walked to ensure that it only
|
||||
contains valid filenames before any data is compressed.
|
||||
|
||||
=item An Input FileGlob string
|
||||
|
||||
If C<$input_filename_or_reference> is a string that is delimited by the
|
||||
characters "<" and ">" C<deflate> will assume that it is an
|
||||
I<input fileglob string>. The input is the list of files that match the
|
||||
fileglob.
|
||||
|
||||
See L<File::GlobMapper|File::GlobMapper> for more details.
|
||||
|
||||
=back
|
||||
|
||||
If the C<$input_filename_or_reference> parameter is any other type,
|
||||
C<undef> will be returned.
|
||||
|
||||
=head3 The C<$output_filename_or_reference> parameter
|
||||
|
||||
The parameter C<$output_filename_or_reference> is used to control the
|
||||
destination of the compressed data. This parameter can take one of
|
||||
these forms.
|
||||
|
||||
=over 5
|
||||
|
||||
=item A filename
|
||||
|
||||
If the C<$output_filename_or_reference> parameter is a simple scalar, it is
|
||||
assumed to be a filename. This file will be opened for writing and the
|
||||
compressed data will be written to it.
|
||||
|
||||
=item A filehandle
|
||||
|
||||
If the C<$output_filename_or_reference> parameter is a filehandle, the
|
||||
compressed data will be written to it. The string '-' can be used as
|
||||
an alias for standard output.
|
||||
|
||||
=item A scalar reference
|
||||
|
||||
If C<$output_filename_or_reference> is a scalar reference, the
|
||||
compressed data will be stored in C<$$output_filename_or_reference>.
|
||||
|
||||
=item An Array Reference
|
||||
|
||||
If C<$output_filename_or_reference> is an array reference,
|
||||
the compressed data will be pushed onto the array.
|
||||
|
||||
=item An Output FileGlob
|
||||
|
||||
If C<$output_filename_or_reference> is a string that is delimited by the
|
||||
characters "<" and ">" C<deflate> will assume that it is an
|
||||
I<output fileglob string>. The output is the list of files that match the
|
||||
fileglob.
|
||||
|
||||
When C<$output_filename_or_reference> is an fileglob string,
|
||||
C<$input_filename_or_reference> must also be a fileglob string. Anything
|
||||
else is an error.
|
||||
|
||||
See L<File::GlobMapper|File::GlobMapper> for more details.
|
||||
|
||||
=back
|
||||
|
||||
If the C<$output_filename_or_reference> parameter is any other type,
|
||||
C<undef> will be returned.
|
||||
|
||||
=head2 Notes
|
||||
|
||||
When C<$input_filename_or_reference> maps to multiple files/buffers and
|
||||
C<$output_filename_or_reference> is a single
|
||||
file/buffer the input files/buffers will be stored
|
||||
in C<$output_filename_or_reference> as a concatenated series of compressed data streams.
|
||||
|
||||
=head2 Optional Parameters
|
||||
|
||||
The optional parameters for the one-shot function C<deflate>
|
||||
are (for the most part) identical to those used with the OO interface defined in the
|
||||
L</"Constructor Options"> section. The exceptions are listed below
|
||||
|
||||
=over 5
|
||||
|
||||
=item C<< AutoClose => 0|1 >>
|
||||
|
||||
This option applies to any input or output data streams to
|
||||
C<deflate> that are filehandles.
|
||||
|
||||
If C<AutoClose> is specified, and the value is true, it will result in all
|
||||
input and/or output filehandles being closed once C<deflate> has
|
||||
completed.
|
||||
|
||||
This parameter defaults to 0.
|
||||
|
||||
=item C<< BinModeIn => 0|1 >>
|
||||
|
||||
This option is now a no-op. All files will be read in binmode.
|
||||
|
||||
=item C<< Append => 0|1 >>
|
||||
|
||||
The behaviour of this option is dependent on the type of output data
|
||||
stream.
|
||||
|
||||
=over 5
|
||||
|
||||
=item * A Buffer
|
||||
|
||||
If C<Append> is enabled, all compressed data will be append to the end of
|
||||
the output buffer. Otherwise the output buffer will be cleared before any
|
||||
compressed data is written to it.
|
||||
|
||||
=item * A Filename
|
||||
|
||||
If C<Append> is enabled, the file will be opened in append mode. Otherwise
|
||||
the contents of the file, if any, will be truncated before any compressed
|
||||
data is written to it.
|
||||
|
||||
=item * A Filehandle
|
||||
|
||||
If C<Append> is enabled, the filehandle will be positioned to the end of
|
||||
the file via a call to C<seek> before any compressed data is
|
||||
written to it. Otherwise the file pointer will not be moved.
|
||||
|
||||
=back
|
||||
|
||||
When C<Append> is specified, and set to true, it will I<append> all compressed
|
||||
data to the output data stream.
|
||||
|
||||
So when the output is a filehandle it will carry out a seek to the eof
|
||||
before writing any compressed data. If the output is a filename, it will be opened for
|
||||
appending. If the output is a buffer, all compressed data will be
|
||||
appended to the existing buffer.
|
||||
|
||||
Conversely when C<Append> is not specified, or it is present and is set to
|
||||
false, it will operate as follows.
|
||||
|
||||
When the output is a filename, it will truncate the contents of the file
|
||||
before writing any compressed data. If the output is a filehandle
|
||||
its position will not be changed. If the output is a buffer, it will be
|
||||
wiped before any compressed data is output.
|
||||
|
||||
Defaults to 0.
|
||||
|
||||
=back
|
||||
|
||||
=head2 Examples
|
||||
|
||||
Here are a few example that show the capabilities of the module.
|
||||
|
||||
=head3 Streaming
|
||||
|
||||
This very simple command line example demonstrates the streaming capabilities of the module.
|
||||
The code reads data from STDIN, compresses it, and writes the compressed data to STDOUT.
|
||||
|
||||
$ echo hello world | perl -MIO::Compress::Deflate=deflate -e 'deflate \*STDIN => \*STDOUT' >output.1950
|
||||
|
||||
The special filename "-" can be used as a standin for both C<\*STDIN> and C<\*STDOUT>,
|
||||
so the above can be rewritten as
|
||||
|
||||
$ echo hello world | perl -MIO::Compress::Deflate=deflate -e 'deflate "-" => "-"' >output.1950
|
||||
|
||||
=head3 Compressing a file from the filesystem
|
||||
|
||||
To read the contents of the file C<file1.txt> and write the compressed
|
||||
data to the file C<file1.txt.1950>.
|
||||
|
||||
use strict ;
|
||||
use warnings ;
|
||||
use IO::Compress::Deflate qw(deflate $DeflateError) ;
|
||||
|
||||
my $input = "file1.txt";
|
||||
deflate $input => "$input.1950"
|
||||
or die "deflate failed: $DeflateError\n";
|
||||
|
||||
=head3 Reading from a Filehandle and writing to an in-memory buffer
|
||||
|
||||
To read from an existing Perl filehandle, C<$input>, and write the
|
||||
compressed data to a buffer, C<$buffer>.
|
||||
|
||||
use strict ;
|
||||
use warnings ;
|
||||
use IO::Compress::Deflate qw(deflate $DeflateError) ;
|
||||
use IO::File ;
|
||||
|
||||
my $input = IO::File->new( "<file1.txt" )
|
||||
or die "Cannot open 'file1.txt': $!\n" ;
|
||||
my $buffer ;
|
||||
deflate $input => \$buffer
|
||||
or die "deflate failed: $DeflateError\n";
|
||||
|
||||
=head3 Compressing multiple files
|
||||
|
||||
To compress all files in the directory "/my/home" that match "*.txt"
|
||||
and store the compressed data in the same directory
|
||||
|
||||
use strict ;
|
||||
use warnings ;
|
||||
use IO::Compress::Deflate qw(deflate $DeflateError) ;
|
||||
|
||||
deflate '</my/home/*.txt>' => '<*.1950>'
|
||||
or die "deflate failed: $DeflateError\n";
|
||||
|
||||
and if you want to compress each file one at a time, this will do the trick
|
||||
|
||||
use strict ;
|
||||
use warnings ;
|
||||
use IO::Compress::Deflate qw(deflate $DeflateError) ;
|
||||
|
||||
for my $input ( glob "/my/home/*.txt" )
|
||||
{
|
||||
my $output = "$input.1950" ;
|
||||
deflate $input => $output
|
||||
or die "Error compressing '$input': $DeflateError\n";
|
||||
}
|
||||
|
||||
=head1 OO Interface
|
||||
|
||||
=head2 Constructor
|
||||
|
||||
The format of the constructor for C<IO::Compress::Deflate> is shown below
|
||||
|
||||
my $z = IO::Compress::Deflate->new( $output [,OPTS] )
|
||||
or die "IO::Compress::Deflate failed: $DeflateError\n";
|
||||
|
||||
It returns an C<IO::Compress::Deflate> object on success and undef on failure.
|
||||
The variable C<$DeflateError> will contain an error message on failure.
|
||||
|
||||
If you are running Perl 5.005 or better the object, C<$z>, returned from
|
||||
IO::Compress::Deflate can be used exactly like an L<IO::File|IO::File> filehandle.
|
||||
This means that all normal output file operations can be carried out
|
||||
with C<$z>.
|
||||
For example, to write to a compressed file/buffer you can use either of
|
||||
these forms
|
||||
|
||||
$z->print("hello world\n");
|
||||
print $z "hello world\n";
|
||||
|
||||
The mandatory parameter C<$output> is used to control the destination
|
||||
of the compressed data. This parameter can take one of these forms.
|
||||
|
||||
=over 5
|
||||
|
||||
=item A filename
|
||||
|
||||
If the C<$output> parameter is a simple scalar, it is assumed to be a
|
||||
filename. This file will be opened for writing and the compressed data
|
||||
will be written to it.
|
||||
|
||||
=item A filehandle
|
||||
|
||||
If the C<$output> parameter is a filehandle, the compressed data will be
|
||||
written to it.
|
||||
The string '-' can be used as an alias for standard output.
|
||||
|
||||
=item A scalar reference
|
||||
|
||||
If C<$output> is a scalar reference, the compressed data will be stored
|
||||
in C<$$output>.
|
||||
|
||||
=back
|
||||
|
||||
If the C<$output> parameter is any other type, C<IO::Compress::Deflate>::new will
|
||||
return undef.
|
||||
|
||||
=head2 Constructor Options
|
||||
|
||||
C<OPTS> is any combination of zero or more the following options:
|
||||
|
||||
=over 5
|
||||
|
||||
=item C<< AutoClose => 0|1 >>
|
||||
|
||||
This option is only valid when the C<$output> parameter is a filehandle. If
|
||||
specified, and the value is true, it will result in the C<$output> being
|
||||
closed once either the C<close> method is called or the C<IO::Compress::Deflate>
|
||||
object is destroyed.
|
||||
|
||||
This parameter defaults to 0.
|
||||
|
||||
=item C<< Append => 0|1 >>
|
||||
|
||||
Opens C<$output> in append mode.
|
||||
|
||||
The behaviour of this option is dependent on the type of C<$output>.
|
||||
|
||||
=over 5
|
||||
|
||||
=item * A Buffer
|
||||
|
||||
If C<$output> is a buffer and C<Append> is enabled, all compressed data
|
||||
will be append to the end of C<$output>. Otherwise C<$output> will be
|
||||
cleared before any data is written to it.
|
||||
|
||||
=item * A Filename
|
||||
|
||||
If C<$output> is a filename and C<Append> is enabled, the file will be
|
||||
opened in append mode. Otherwise the contents of the file, if any, will be
|
||||
truncated before any compressed data is written to it.
|
||||
|
||||
=item * A Filehandle
|
||||
|
||||
If C<$output> is a filehandle, the file pointer will be positioned to the
|
||||
end of the file via a call to C<seek> before any compressed data is written
|
||||
to it. Otherwise the file pointer will not be moved.
|
||||
|
||||
=back
|
||||
|
||||
This parameter defaults to 0.
|
||||
|
||||
=item C<< Merge => 0|1 >>
|
||||
|
||||
This option is used to compress input data and append it to an existing
|
||||
compressed data stream in C<$output>. The end result is a single compressed
|
||||
data stream stored in C<$output>.
|
||||
|
||||
It is a fatal error to attempt to use this option when C<$output> is not an
|
||||
RFC 1950 data stream.
|
||||
|
||||
There are a number of other limitations with the C<Merge> option:
|
||||
|
||||
=over 5
|
||||
|
||||
=item 1
|
||||
|
||||
This module needs to have been built with zlib 1.2.1 or better to work. A
|
||||
fatal error will be thrown if C<Merge> is used with an older version of
|
||||
zlib.
|
||||
|
||||
=item 2
|
||||
|
||||
If C<$output> is a file or a filehandle, it must be seekable.
|
||||
|
||||
=back
|
||||
|
||||
This parameter defaults to 0.
|
||||
|
||||
=item -Level
|
||||
|
||||
Defines the compression level used by zlib. The value should either be
|
||||
a number between 0 and 9 (0 means no compression and 9 is maximum
|
||||
compression), or one of the symbolic constants defined below.
|
||||
|
||||
Z_NO_COMPRESSION
|
||||
Z_BEST_SPEED
|
||||
Z_BEST_COMPRESSION
|
||||
Z_DEFAULT_COMPRESSION
|
||||
|
||||
The default is Z_DEFAULT_COMPRESSION.
|
||||
|
||||
Note, these constants are not imported by C<IO::Compress::Deflate> by default.
|
||||
|
||||
use IO::Compress::Deflate qw(:strategy);
|
||||
use IO::Compress::Deflate qw(:constants);
|
||||
use IO::Compress::Deflate qw(:all);
|
||||
|
||||
=item -Strategy
|
||||
|
||||
Defines the strategy used to tune the compression. Use one of the symbolic
|
||||
constants defined below.
|
||||
|
||||
Z_FILTERED
|
||||
Z_HUFFMAN_ONLY
|
||||
Z_RLE
|
||||
Z_FIXED
|
||||
Z_DEFAULT_STRATEGY
|
||||
|
||||
The default is Z_DEFAULT_STRATEGY.
|
||||
|
||||
=item C<< Strict => 0|1 >>
|
||||
|
||||
This is a placeholder option.
|
||||
|
||||
=back
|
||||
|
||||
=head2 Examples
|
||||
|
||||
TODO
|
||||
|
||||
=head1 Methods
|
||||
|
||||
=head2 print
|
||||
|
||||
Usage is
|
||||
|
||||
$z->print($data)
|
||||
print $z $data
|
||||
|
||||
Compresses and outputs the contents of the C<$data> parameter. This
|
||||
has the same behaviour as the C<print> built-in.
|
||||
|
||||
Returns true if successful.
|
||||
|
||||
=head2 printf
|
||||
|
||||
Usage is
|
||||
|
||||
$z->printf($format, $data)
|
||||
printf $z $format, $data
|
||||
|
||||
Compresses and outputs the contents of the C<$data> parameter.
|
||||
|
||||
Returns true if successful.
|
||||
|
||||
=head2 syswrite
|
||||
|
||||
Usage is
|
||||
|
||||
$z->syswrite $data
|
||||
$z->syswrite $data, $length
|
||||
$z->syswrite $data, $length, $offset
|
||||
|
||||
Compresses and outputs the contents of the C<$data> parameter.
|
||||
|
||||
Returns the number of uncompressed bytes written, or C<undef> if
|
||||
unsuccessful.
|
||||
|
||||
=head2 write
|
||||
|
||||
Usage is
|
||||
|
||||
$z->write $data
|
||||
$z->write $data, $length
|
||||
$z->write $data, $length, $offset
|
||||
|
||||
Compresses and outputs the contents of the C<$data> parameter.
|
||||
|
||||
Returns the number of uncompressed bytes written, or C<undef> if
|
||||
unsuccessful.
|
||||
|
||||
=head2 flush
|
||||
|
||||
Usage is
|
||||
|
||||
$z->flush;
|
||||
$z->flush($flush_type);
|
||||
|
||||
Flushes any pending compressed data to the output file/buffer.
|
||||
|
||||
This method takes an optional parameter, C<$flush_type>, that controls
|
||||
how the flushing will be carried out. 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_SYNC_FLUSH>, C<Z_FULL_FLUSH> and C<Z_BLOCK>. It is
|
||||
strongly recommended that you only set the C<flush_type> parameter if
|
||||
you fully understand the implications of what it does - overuse of C<flush>
|
||||
can seriously degrade the level of compression achieved. See the C<zlib>
|
||||
documentation for details.
|
||||
|
||||
Returns true on success.
|
||||
|
||||
=head2 tell
|
||||
|
||||
Usage is
|
||||
|
||||
$z->tell()
|
||||
tell $z
|
||||
|
||||
Returns the uncompressed file offset.
|
||||
|
||||
=head2 eof
|
||||
|
||||
Usage is
|
||||
|
||||
$z->eof();
|
||||
eof($z);
|
||||
|
||||
Returns true if the C<close> method has been called.
|
||||
|
||||
=head2 seek
|
||||
|
||||
$z->seek($position, $whence);
|
||||
seek($z, $position, $whence);
|
||||
|
||||
Provides a sub-set of the C<seek> functionality, with the restriction
|
||||
that it is only legal to seek forward in the output file/buffer.
|
||||
It is a fatal error to attempt to seek backward.
|
||||
|
||||
Empty parts of the file/buffer will have NULL (0x00) bytes written to them.
|
||||
|
||||
The C<$whence> parameter takes one the usual values, namely SEEK_SET,
|
||||
SEEK_CUR or SEEK_END.
|
||||
|
||||
Returns 1 on success, 0 on failure.
|
||||
|
||||
=head2 binmode
|
||||
|
||||
Usage is
|
||||
|
||||
$z->binmode
|
||||
binmode $z ;
|
||||
|
||||
This is a noop provided for completeness.
|
||||
|
||||
=head2 opened
|
||||
|
||||
$z->opened()
|
||||
|
||||
Returns true if the object currently refers to a opened file/buffer.
|
||||
|
||||
=head2 autoflush
|
||||
|
||||
my $prev = $z->autoflush()
|
||||
my $prev = $z->autoflush(EXPR)
|
||||
|
||||
If the C<$z> object is associated with a file or a filehandle, this method
|
||||
returns the current autoflush setting for the underlying filehandle. If
|
||||
C<EXPR> is present, and is non-zero, it will enable flushing after every
|
||||
write/print operation.
|
||||
|
||||
If C<$z> is associated with a buffer, this method has no effect and always
|
||||
returns C<undef>.
|
||||
|
||||
B<Note> that the special variable C<$|> B<cannot> be used to set or
|
||||
retrieve the autoflush setting.
|
||||
|
||||
=head2 input_line_number
|
||||
|
||||
$z->input_line_number()
|
||||
$z->input_line_number(EXPR)
|
||||
|
||||
This method always returns C<undef> when compressing.
|
||||
|
||||
=head2 fileno
|
||||
|
||||
$z->fileno()
|
||||
fileno($z)
|
||||
|
||||
If the C<$z> object is associated with a file or a filehandle, C<fileno>
|
||||
will return the underlying file descriptor. Once the C<close> method is
|
||||
called C<fileno> will return C<undef>.
|
||||
|
||||
If the C<$z> object is associated with a buffer, this method will return
|
||||
C<undef>.
|
||||
|
||||
=head2 close
|
||||
|
||||
$z->close() ;
|
||||
close $z ;
|
||||
|
||||
Flushes any pending compressed data and then closes the output file/buffer.
|
||||
|
||||
For most versions of Perl this method will be automatically invoked if
|
||||
the IO::Compress::Deflate object is destroyed (either explicitly or by the
|
||||
variable with the reference to the object going out of scope). The
|
||||
exceptions are Perl versions 5.005 through 5.00504 and 5.8.0. In
|
||||
these cases, the C<close> method will be called automatically, but
|
||||
not until global destruction of all live objects when the program is
|
||||
terminating.
|
||||
|
||||
Therefore, if you want your scripts to be able to run on all versions
|
||||
of Perl, you should call C<close> explicitly and not rely on automatic
|
||||
closing.
|
||||
|
||||
Returns true on success, otherwise 0.
|
||||
|
||||
If the C<AutoClose> option has been enabled when the IO::Compress::Deflate
|
||||
object was created, and the object is associated with a file, the
|
||||
underlying file will also be closed.
|
||||
|
||||
=head2 newStream([OPTS])
|
||||
|
||||
Usage is
|
||||
|
||||
$z->newStream( [OPTS] )
|
||||
|
||||
Closes the current compressed data stream and starts a new one.
|
||||
|
||||
OPTS consists of any of the options that are available when creating
|
||||
the C<$z> object.
|
||||
|
||||
See the L</"Constructor Options"> section for more details.
|
||||
|
||||
=head2 deflateParams
|
||||
|
||||
Usage is
|
||||
|
||||
$z->deflateParams
|
||||
|
||||
TODO
|
||||
|
||||
=head1 Importing
|
||||
|
||||
A number of symbolic constants are required by some methods in
|
||||
C<IO::Compress::Deflate>. None are imported by default.
|
||||
|
||||
=over 5
|
||||
|
||||
=item :all
|
||||
|
||||
Imports C<deflate>, C<$DeflateError> and all symbolic
|
||||
constants that can be used by C<IO::Compress::Deflate>. Same as doing this
|
||||
|
||||
use IO::Compress::Deflate qw(deflate $DeflateError :constants) ;
|
||||
|
||||
=item :constants
|
||||
|
||||
Import all symbolic constants. Same as doing this
|
||||
|
||||
use IO::Compress::Deflate qw(:flush :level :strategy) ;
|
||||
|
||||
=item :flush
|
||||
|
||||
These symbolic constants are used by the C<flush> method.
|
||||
|
||||
Z_NO_FLUSH
|
||||
Z_PARTIAL_FLUSH
|
||||
Z_SYNC_FLUSH
|
||||
Z_FULL_FLUSH
|
||||
Z_FINISH
|
||||
Z_BLOCK
|
||||
|
||||
=item :level
|
||||
|
||||
These symbolic constants are used by the C<Level> option in the constructor.
|
||||
|
||||
Z_NO_COMPRESSION
|
||||
Z_BEST_SPEED
|
||||
Z_BEST_COMPRESSION
|
||||
Z_DEFAULT_COMPRESSION
|
||||
|
||||
=item :strategy
|
||||
|
||||
These symbolic constants are used by the C<Strategy> option in the constructor.
|
||||
|
||||
Z_FILTERED
|
||||
Z_HUFFMAN_ONLY
|
||||
Z_RLE
|
||||
Z_FIXED
|
||||
Z_DEFAULT_STRATEGY
|
||||
|
||||
=back
|
||||
|
||||
=head1 EXAMPLES
|
||||
|
||||
=head2 Apache::GZip Revisited
|
||||
|
||||
See L<IO::Compress::FAQ|IO::Compress::FAQ/"Apache::GZip Revisited">
|
||||
|
||||
=head2 Working with Net::FTP
|
||||
|
||||
See L<IO::Compress::FAQ|IO::Compress::FAQ/"Compressed files and Net::FTP">
|
||||
|
||||
=head1 SUPPORT
|
||||
|
||||
General feedback/questions/bug reports should be sent to
|
||||
L<https://github.com/pmqs/IO-Compress/issues> (preferred) or
|
||||
L<https://rt.cpan.org/Public/Dist/Display.html?Name=IO-Compress>.
|
||||
|
||||
=head1 SEE ALSO
|
||||
|
||||
L<Compress::Zlib>, L<IO::Compress::Gzip>, L<IO::Uncompress::Gunzip>, L<IO::Uncompress::Inflate>, L<IO::Compress::RawDeflate>, L<IO::Uncompress::RawInflate>, L<IO::Compress::Bzip2>, L<IO::Uncompress::Bunzip2>, L<IO::Compress::Lzma>, L<IO::Uncompress::UnLzma>, L<IO::Compress::Xz>, L<IO::Uncompress::UnXz>, L<IO::Compress::Lzip>, L<IO::Uncompress::UnLzip>, L<IO::Compress::Lzop>, L<IO::Uncompress::UnLzop>, L<IO::Compress::Lzf>, L<IO::Uncompress::UnLzf>, L<IO::Compress::Zstd>, L<IO::Uncompress::UnZstd>, L<IO::Uncompress::AnyInflate>, L<IO::Uncompress::AnyUncompress>
|
||||
|
||||
L<IO::Compress::FAQ|IO::Compress::FAQ>
|
||||
|
||||
L<File::GlobMapper|File::GlobMapper>, L<Archive::Zip|Archive::Zip>,
|
||||
L<Archive::Tar|Archive::Tar>,
|
||||
L<IO::Zlib|IO::Zlib>
|
||||
|
||||
For RFC 1950, 1951 and 1952 see
|
||||
L<http://www.faqs.org/rfcs/rfc1950.html>,
|
||||
L<http://www.faqs.org/rfcs/rfc1951.html> and
|
||||
L<http://www.faqs.org/rfcs/rfc1952.html>
|
||||
|
||||
The I<zlib> compression library was written by Jean-loup Gailly
|
||||
C<gzip@prep.ai.mit.edu> and Mark Adler C<madler@alumni.caltech.edu>.
|
||||
|
||||
The primary site for the I<zlib> compression library is
|
||||
L<http://www.zlib.org>.
|
||||
|
||||
The primary site for gzip is L<http://www.gzip.org>.
|
||||
|
||||
=head1 AUTHOR
|
||||
|
||||
This module was written by Paul Marquess, C<pmqs@cpan.org>.
|
||||
|
||||
=head1 MODIFICATION HISTORY
|
||||
|
||||
See the Changes file.
|
||||
|
||||
=head1 COPYRIGHT AND LICENSE
|
||||
|
||||
Copyright (c) 2005-2021 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.
|
||||
689
database/perl/lib/IO/Compress/FAQ.pod
Normal file
689
database/perl/lib/IO/Compress/FAQ.pod
Normal file
@@ -0,0 +1,689 @@
|
||||
|
||||
=head1 NAME
|
||||
|
||||
IO::Compress::FAQ -- Frequently Asked Questions about IO::Compress
|
||||
|
||||
=head1 DESCRIPTION
|
||||
|
||||
Common questions answered.
|
||||
|
||||
=head1 GENERAL
|
||||
|
||||
=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> related to the Unix programs of the same
|
||||
name. The C<Compress::Zlib> module is not compatible 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>)
|
||||
{
|
||||
...
|
||||
|
||||
Alternatively, 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
|
||||
accessed 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 = IO::File->new( "| compress -c >$filename" );
|
||||
my $tar = Archive::Tar->new();
|
||||
...
|
||||
$tar->write($fh);
|
||||
$fh->close ;
|
||||
|
||||
=head2 How do I recompress using a different compression?
|
||||
|
||||
This is easier that you might expect if you realise that all the
|
||||
C<IO::Compress::*> objects are derived from C<IO::File> and that all the
|
||||
C<IO::Uncompress::*> modules can read from an C<IO::File> filehandle.
|
||||
|
||||
So, for example, say you have a file compressed with gzip that you want to
|
||||
recompress with bzip2. Here is all that is needed to carry out the
|
||||
recompression.
|
||||
|
||||
use IO::Uncompress::Gunzip ':all';
|
||||
use IO::Compress::Bzip2 ':all';
|
||||
|
||||
my $gzipFile = "somefile.gz";
|
||||
my $bzipFile = "somefile.bz2";
|
||||
|
||||
my $gunzip = IO::Uncompress::Gunzip->new( $gzipFile )
|
||||
or die "Cannot gunzip $gzipFile: $GunzipError\n" ;
|
||||
|
||||
bzip2 $gunzip => $bzipFile
|
||||
or die "Cannot bzip2 to $bzipFile: $Bzip2Error\n" ;
|
||||
|
||||
Note, there is a limitation of this technique. Some compression file
|
||||
formats store extra information along with the compressed data payload. For
|
||||
example, gzip can optionally store the original filename and Zip stores a
|
||||
lot of information about the original file. If the original compressed file
|
||||
contains any of this extra information, it will not be transferred to the
|
||||
new compressed file using the technique above.
|
||||
|
||||
=head1 ZIP
|
||||
|
||||
=head2 What Compression Types do IO::Compress::Zip & IO::Uncompress::Unzip support?
|
||||
|
||||
The following compression formats are supported by C<IO::Compress::Zip> and
|
||||
C<IO::Uncompress::Unzip>
|
||||
|
||||
=over 5
|
||||
|
||||
=item * Store (method 0)
|
||||
|
||||
No compression at all.
|
||||
|
||||
=item * Deflate (method 8)
|
||||
|
||||
This is the default compression used when creating a zip file with
|
||||
C<IO::Compress::Zip>.
|
||||
|
||||
=item * Bzip2 (method 12)
|
||||
|
||||
Only supported if the C<IO-Compress-Bzip2> module is installed.
|
||||
|
||||
=item * Lzma (method 14)
|
||||
|
||||
Only supported if the C<IO-Compress-Lzma> module is installed.
|
||||
|
||||
=back
|
||||
|
||||
=head2 Can I Read/Write Zip files larger the 4 Gig?
|
||||
|
||||
Yes, both the C<IO-Compress-Zip> and C<IO-Uncompress-Unzip> modules
|
||||
support the zip feature called I<Zip64>. That allows them to read/write
|
||||
files/buffers larger than 4Gig.
|
||||
|
||||
If you are creating a Zip file using the one-shot interface, and any of the
|
||||
input files is greater than 4Gig, a zip64 complaint zip file will be
|
||||
created.
|
||||
|
||||
zip "really-large-file" => "my.zip";
|
||||
|
||||
Similarly with the one-shot interface, if the input is a buffer larger than
|
||||
4 Gig, a zip64 complaint zip file will be created.
|
||||
|
||||
zip \$really_large_buffer => "my.zip";
|
||||
|
||||
The one-shot interface allows you to force the creation of a zip64 zip file
|
||||
by including the C<Zip64> option.
|
||||
|
||||
zip $filehandle => "my.zip", Zip64 => 1;
|
||||
|
||||
If you want to create a zip64 zip file with the OO interface you must
|
||||
specify the C<Zip64> option.
|
||||
|
||||
my $zip = IO::Compress::Zip->new( "whatever", Zip64 => 1 );
|
||||
|
||||
When uncompressing with C<IO-Uncompress-Unzip>, it will automatically
|
||||
detect if the zip file is zip64.
|
||||
|
||||
If you intend to manipulate the Zip64 zip files created with
|
||||
C<IO-Compress-Zip> using an external zip/unzip, make sure that it supports
|
||||
Zip64.
|
||||
|
||||
In particular, if you are using Info-Zip you need to have zip version 3.x
|
||||
or better to update a Zip64 archive and unzip version 6.x to read a zip64
|
||||
archive.
|
||||
|
||||
=head2 Can I write more that 64K entries is a Zip files?
|
||||
|
||||
Yes. Zip64 allows this. See previous question.
|
||||
|
||||
=head2 Zip Resources
|
||||
|
||||
The primary reference for zip files is the "appnote" document available at
|
||||
L<http://www.pkware.com/documents/casestudies/APPNOTE.TXT>
|
||||
|
||||
An alternatively is the Info-Zip appnote. This is available from
|
||||
L<ftp://ftp.info-zip.org/pub/infozip/doc/>
|
||||
|
||||
=head1 GZIP
|
||||
|
||||
=head2 Gzip Resources
|
||||
|
||||
The primary reference for gzip files is RFC 1952
|
||||
L<http://www.faqs.org/rfcs/rfc1952.html>
|
||||
|
||||
The primary site for gzip is L<http://www.gzip.org>.
|
||||
|
||||
=head2 Dealing with concatenated gzip files
|
||||
|
||||
If the gunzip program encounters a file containing multiple gzip files
|
||||
concatenated together it will automatically uncompress them all.
|
||||
The example below illustrates this behaviour
|
||||
|
||||
$ echo abc | gzip -c >x.gz
|
||||
$ echo def | gzip -c >>x.gz
|
||||
$ gunzip -c x.gz
|
||||
abc
|
||||
def
|
||||
|
||||
By default C<IO::Uncompress::Gunzip> will I<not> behave like the gunzip
|
||||
program. It will only uncompress the first gzip data stream in the file, as
|
||||
shown below
|
||||
|
||||
$ perl -MIO::Uncompress::Gunzip=:all -e 'gunzip "x.gz" => \*STDOUT'
|
||||
abc
|
||||
|
||||
To force C<IO::Uncompress::Gunzip> to uncompress all the gzip data streams,
|
||||
include the C<MultiStream> option, as shown below
|
||||
|
||||
$ perl -MIO::Uncompress::Gunzip=:all -e 'gunzip "x.gz" => \*STDOUT, MultiStream => 1'
|
||||
abc
|
||||
def
|
||||
|
||||
=head2 Reading bgzip files with IO::Uncompress::Gunzip
|
||||
|
||||
A C<bgzip> file consists of a series of valid gzip-compliant data streams
|
||||
concatenated together. To read a file created by C<bgzip> with
|
||||
C<IO::Uncompress::Gunzip> use the C<MultiStream> option as shown in the
|
||||
previous section.
|
||||
|
||||
See the section titled "The BGZF compression format" in
|
||||
L<http://samtools.github.io/hts-specs/SAMv1.pdf> for a definition of
|
||||
C<bgzip>.
|
||||
|
||||
=head1 ZLIB
|
||||
|
||||
=head2 Zlib Resources
|
||||
|
||||
The primary site for the I<zlib> compression library is
|
||||
L<http://www.zlib.org>.
|
||||
|
||||
=head1 Bzip2
|
||||
|
||||
=head2 Bzip2 Resources
|
||||
|
||||
The primary site for bzip2 is L<http://www.bzip.org>.
|
||||
|
||||
=head2 Dealing with Concatenated bzip2 files
|
||||
|
||||
If the bunzip2 program encounters a file containing multiple bzip2 files
|
||||
concatenated together it will automatically uncompress them all.
|
||||
The example below illustrates this behaviour
|
||||
|
||||
$ echo abc | bzip2 -c >x.bz2
|
||||
$ echo def | bzip2 -c >>x.bz2
|
||||
$ bunzip2 -c x.bz2
|
||||
abc
|
||||
def
|
||||
|
||||
By default C<IO::Uncompress::Bunzip2> will I<not> behave like the bunzip2
|
||||
program. It will only uncompress the first bunzip2 data stream in the file, as
|
||||
shown below
|
||||
|
||||
$ perl -MIO::Uncompress::Bunzip2=:all -e 'bunzip2 "x.bz2" => \*STDOUT'
|
||||
abc
|
||||
|
||||
To force C<IO::Uncompress::Bunzip2> to uncompress all the bzip2 data streams,
|
||||
include the C<MultiStream> option, as shown below
|
||||
|
||||
$ perl -MIO::Uncompress::Bunzip2=:all -e 'bunzip2 "x.bz2" => \*STDOUT, MultiStream => 1'
|
||||
abc
|
||||
def
|
||||
|
||||
=head2 Interoperating with Pbzip2
|
||||
|
||||
Pbzip2 (L<http://compression.ca/pbzip2/>) is a parallel implementation of
|
||||
bzip2. The output from pbzip2 consists of a series of concatenated bzip2
|
||||
data streams.
|
||||
|
||||
By default C<IO::Uncompress::Bzip2> will only uncompress the first bzip2
|
||||
data stream in a pbzip2 file. To uncompress the complete pbzip2 file you
|
||||
must include the C<MultiStream> option, like this.
|
||||
|
||||
bunzip2 $input => \$output, MultiStream => 1
|
||||
or die "bunzip2 failed: $Bunzip2Error\n";
|
||||
|
||||
=head1 HTTP & NETWORK
|
||||
|
||||
=head2 Apache::GZip Revisited
|
||||
|
||||
Below is a mod_perl Apache compression module, called C<Apache::GZip>,
|
||||
taken from
|
||||
L<http://perl.apache.org/docs/tutorials/tips/mod_perl_tricks/mod_perl_tricks.html#On_the_Fly_Compression>
|
||||
|
||||
package Apache::GZip;
|
||||
#File: Apache::GZip.pm
|
||||
|
||||
use strict vars;
|
||||
use Apache::Constants ':common';
|
||||
use Compress::Zlib;
|
||||
use IO::File;
|
||||
use constant GZIP_MAGIC => 0x1f8b;
|
||||
use constant OS_MAGIC => 0x03;
|
||||
|
||||
sub handler {
|
||||
my $r = shift;
|
||||
my ($fh,$gz);
|
||||
my $file = $r->filename;
|
||||
return DECLINED unless $fh=IO::File->new($file);
|
||||
$r->header_out('Content-Encoding'=>'gzip');
|
||||
$r->send_http_header;
|
||||
return OK if $r->header_only;
|
||||
|
||||
tie *STDOUT,'Apache::GZip',$r;
|
||||
print($_) while <$fh>;
|
||||
untie *STDOUT;
|
||||
return OK;
|
||||
}
|
||||
|
||||
sub TIEHANDLE {
|
||||
my($class,$r) = @_;
|
||||
# initialize a deflation stream
|
||||
my $d = deflateInit(-WindowBits=>-MAX_WBITS()) || return undef;
|
||||
|
||||
# gzip header -- don't ask how I found out
|
||||
$r->print(pack("nccVcc",GZIP_MAGIC,Z_DEFLATED,0,time(),0,OS_MAGIC));
|
||||
|
||||
return bless { r => $r,
|
||||
crc => crc32(undef),
|
||||
d => $d,
|
||||
l => 0
|
||||
},$class;
|
||||
}
|
||||
|
||||
sub PRINT {
|
||||
my $self = shift;
|
||||
foreach (@_) {
|
||||
# deflate the data
|
||||
my $data = $self->{d}->deflate($_);
|
||||
$self->{r}->print($data);
|
||||
# keep track of its length and crc
|
||||
$self->{l} += length($_);
|
||||
$self->{crc} = crc32($_,$self->{crc});
|
||||
}
|
||||
}
|
||||
|
||||
sub DESTROY {
|
||||
my $self = shift;
|
||||
|
||||
# flush the output buffers
|
||||
my $data = $self->{d}->flush;
|
||||
$self->{r}->print($data);
|
||||
|
||||
# print the CRC and the total length (uncompressed)
|
||||
$self->{r}->print(pack("LL",@{$self}{qw/crc l/}));
|
||||
}
|
||||
|
||||
1;
|
||||
|
||||
Here's the Apache configuration entry you'll need to make use of it. Once
|
||||
set it will result in everything in the /compressed directory will be
|
||||
compressed automagically.
|
||||
|
||||
<Location /compressed>
|
||||
SetHandler perl-script
|
||||
PerlHandler Apache::GZip
|
||||
</Location>
|
||||
|
||||
Although at first sight there seems to be quite a lot going on in
|
||||
C<Apache::GZip>, you could sum up what the code was doing as follows --
|
||||
read the contents of the file in C<< $r->filename >>, compress it and write
|
||||
the compressed data to standard output. That's all.
|
||||
|
||||
This code has to jump through a few hoops to achieve this because
|
||||
|
||||
=over
|
||||
|
||||
=item 1.
|
||||
|
||||
The gzip support in C<Compress::Zlib> version 1.x can only work with a real
|
||||
filesystem filehandle. The filehandles used by Apache modules are not
|
||||
associated with the filesystem.
|
||||
|
||||
=item 2.
|
||||
|
||||
That means all the gzip support has to be done by hand - in this case by
|
||||
creating a tied filehandle to deal with creating the gzip header and
|
||||
trailer.
|
||||
|
||||
=back
|
||||
|
||||
C<IO::Compress::Gzip> doesn't have that filehandle limitation (this was one
|
||||
of the reasons for writing it in the first place). So if
|
||||
C<IO::Compress::Gzip> is used instead of C<Compress::Zlib> the whole tied
|
||||
filehandle code can be removed. Here is the rewritten code.
|
||||
|
||||
package Apache::GZip;
|
||||
|
||||
use strict vars;
|
||||
use Apache::Constants ':common';
|
||||
use IO::Compress::Gzip;
|
||||
use IO::File;
|
||||
|
||||
sub handler {
|
||||
my $r = shift;
|
||||
my ($fh,$gz);
|
||||
my $file = $r->filename;
|
||||
return DECLINED unless $fh=IO::File->new($file);
|
||||
$r->header_out('Content-Encoding'=>'gzip');
|
||||
$r->send_http_header;
|
||||
return OK if $r->header_only;
|
||||
|
||||
my $gz = IO::Compress::Gzip->new( '-', Minimal => 1 )
|
||||
or return DECLINED ;
|
||||
|
||||
print $gz $_ while <$fh>;
|
||||
|
||||
return OK;
|
||||
}
|
||||
|
||||
or even more succinctly, like this, using a one-shot gzip
|
||||
|
||||
package Apache::GZip;
|
||||
|
||||
use strict vars;
|
||||
use Apache::Constants ':common';
|
||||
use IO::Compress::Gzip qw(gzip);
|
||||
|
||||
sub handler {
|
||||
my $r = shift;
|
||||
$r->header_out('Content-Encoding'=>'gzip');
|
||||
$r->send_http_header;
|
||||
return OK if $r->header_only;
|
||||
|
||||
gzip $r->filename => '-', Minimal => 1
|
||||
or return DECLINED ;
|
||||
|
||||
return OK;
|
||||
}
|
||||
|
||||
1;
|
||||
|
||||
The use of one-shot C<gzip> above just reads from C<< $r->filename >> and
|
||||
writes the compressed data to standard output.
|
||||
|
||||
Note the use of the C<Minimal> option in the code above. When using gzip
|
||||
for Content-Encoding you should I<always> use this option. In the example
|
||||
above it will prevent the filename being included in the gzip header and
|
||||
make the size of the gzip data stream a slight bit smaller.
|
||||
|
||||
=head2 Compressed files and Net::FTP
|
||||
|
||||
The C<Net::FTP> module provides two low-level methods called C<stor> and
|
||||
C<retr> that both return filehandles. These filehandles can used with the
|
||||
C<IO::Compress/Uncompress> modules to compress or uncompress files read
|
||||
from or written to an FTP Server on the fly, without having to create a
|
||||
temporary file.
|
||||
|
||||
Firstly, here is code that uses C<retr> to uncompressed a file as it is
|
||||
read from the FTP Server.
|
||||
|
||||
use Net::FTP;
|
||||
use IO::Uncompress::Gunzip qw(:all);
|
||||
|
||||
my $ftp = Net::FTP->new( ... )
|
||||
|
||||
my $retr_fh = $ftp->retr($compressed_filename);
|
||||
gunzip $retr_fh => $outFilename, AutoClose => 1
|
||||
or die "Cannot uncompress '$compressed_file': $GunzipError\n";
|
||||
|
||||
and this to compress a file as it is written to the FTP Server
|
||||
|
||||
use Net::FTP;
|
||||
use IO::Compress::Gzip qw(:all);
|
||||
|
||||
my $stor_fh = $ftp->stor($filename);
|
||||
gzip "filename" => $stor_fh, AutoClose => 1
|
||||
or die "Cannot compress '$filename': $GzipError\n";
|
||||
|
||||
=head1 MISC
|
||||
|
||||
=head2 Using C<InputLength> to uncompress data embedded in a larger file/buffer.
|
||||
|
||||
A fairly common use-case is where compressed data is embedded in a larger
|
||||
file/buffer and you want to read both.
|
||||
|
||||
As an example consider the structure of a zip file. This is a well-defined
|
||||
file format that mixes both compressed and uncompressed sections of data in
|
||||
a single file.
|
||||
|
||||
For the purposes of this discussion you can think of a zip file as sequence
|
||||
of compressed data streams, each of which is prefixed by an uncompressed
|
||||
local header. The local header contains information about the compressed
|
||||
data stream, including the name of the compressed file and, in particular,
|
||||
the length of the compressed data stream.
|
||||
|
||||
To illustrate how to use C<InputLength> here is a script that walks a zip
|
||||
file and prints out how many lines are in each compressed file (if you
|
||||
intend write code to walking through a zip file for real see
|
||||
L<IO::Uncompress::Unzip/"Walking through a zip file"> ). Also, although
|
||||
this example uses the zlib-based compression, the technique can be used by
|
||||
the other C<IO::Uncompress::*> modules.
|
||||
|
||||
use strict;
|
||||
use warnings;
|
||||
|
||||
use IO::File;
|
||||
use IO::Uncompress::RawInflate qw(:all);
|
||||
|
||||
use constant ZIP_LOCAL_HDR_SIG => 0x04034b50;
|
||||
use constant ZIP_LOCAL_HDR_LENGTH => 30;
|
||||
|
||||
my $file = $ARGV[0] ;
|
||||
|
||||
my $fh = IO::File->new( "<$file" )
|
||||
or die "Cannot open '$file': $!\n";
|
||||
|
||||
while (1)
|
||||
{
|
||||
my $sig;
|
||||
my $buffer;
|
||||
|
||||
my $x ;
|
||||
($x = $fh->read($buffer, ZIP_LOCAL_HDR_LENGTH)) == ZIP_LOCAL_HDR_LENGTH
|
||||
or die "Truncated file: $!\n";
|
||||
|
||||
my $signature = unpack ("V", substr($buffer, 0, 4));
|
||||
|
||||
last unless $signature == ZIP_LOCAL_HDR_SIG;
|
||||
|
||||
# Read Local Header
|
||||
my $gpFlag = unpack ("v", substr($buffer, 6, 2));
|
||||
my $compressedMethod = unpack ("v", substr($buffer, 8, 2));
|
||||
my $compressedLength = unpack ("V", substr($buffer, 18, 4));
|
||||
my $uncompressedLength = unpack ("V", substr($buffer, 22, 4));
|
||||
my $filename_length = unpack ("v", substr($buffer, 26, 2));
|
||||
my $extra_length = unpack ("v", substr($buffer, 28, 2));
|
||||
|
||||
my $filename ;
|
||||
$fh->read($filename, $filename_length) == $filename_length
|
||||
or die "Truncated file\n";
|
||||
|
||||
$fh->read($buffer, $extra_length) == $extra_length
|
||||
or die "Truncated file\n";
|
||||
|
||||
if ($compressedMethod != 8 && $compressedMethod != 0)
|
||||
{
|
||||
warn "Skipping file '$filename' - not deflated $compressedMethod\n";
|
||||
$fh->read($buffer, $compressedLength) == $compressedLength
|
||||
or die "Truncated file\n";
|
||||
next;
|
||||
}
|
||||
|
||||
if ($compressedMethod == 0 && $gpFlag & 8 == 8)
|
||||
{
|
||||
die "Streamed Stored not supported for '$filename'\n";
|
||||
}
|
||||
|
||||
next if $compressedLength == 0;
|
||||
|
||||
# Done reading the Local Header
|
||||
|
||||
my $inf = IO::Uncompress::RawInflate->new( $fh,
|
||||
Transparent => 1,
|
||||
InputLength => $compressedLength )
|
||||
or die "Cannot uncompress $file [$filename]: $RawInflateError\n" ;
|
||||
|
||||
my $line_count = 0;
|
||||
|
||||
while (<$inf>)
|
||||
{
|
||||
++ $line_count;
|
||||
}
|
||||
|
||||
print "$filename: $line_count\n";
|
||||
}
|
||||
|
||||
The majority of the code above is concerned with reading the zip local
|
||||
header data. The code that I want to focus on is at the bottom.
|
||||
|
||||
while (1) {
|
||||
|
||||
# read local zip header data
|
||||
# get $filename
|
||||
# get $compressedLength
|
||||
|
||||
my $inf = IO::Uncompress::RawInflate->new( $fh,
|
||||
Transparent => 1,
|
||||
InputLength => $compressedLength )
|
||||
or die "Cannot uncompress $file [$filename]: $RawInflateError\n" ;
|
||||
|
||||
my $line_count = 0;
|
||||
|
||||
while (<$inf>)
|
||||
{
|
||||
++ $line_count;
|
||||
}
|
||||
|
||||
print "$filename: $line_count\n";
|
||||
}
|
||||
|
||||
The call to C<IO::Uncompress::RawInflate> creates a new filehandle C<$inf>
|
||||
that can be used to read from the parent filehandle C<$fh>, uncompressing
|
||||
it as it goes. The use of the C<InputLength> option will guarantee that
|
||||
I<at most> C<$compressedLength> bytes of compressed data will be read from
|
||||
the C<$fh> filehandle (The only exception is for an error case like a
|
||||
truncated file or a corrupt data stream).
|
||||
|
||||
This means that once RawInflate is finished C<$fh> will be left at the
|
||||
byte directly after the compressed data stream.
|
||||
|
||||
Now consider what the code looks like without C<InputLength>
|
||||
|
||||
while (1) {
|
||||
|
||||
# read local zip header data
|
||||
# get $filename
|
||||
# get $compressedLength
|
||||
|
||||
# read all the compressed data into $data
|
||||
read($fh, $data, $compressedLength);
|
||||
|
||||
my $inf = IO::Uncompress::RawInflate->new( \$data,
|
||||
Transparent => 1 )
|
||||
or die "Cannot uncompress $file [$filename]: $RawInflateError\n" ;
|
||||
|
||||
my $line_count = 0;
|
||||
|
||||
while (<$inf>)
|
||||
{
|
||||
++ $line_count;
|
||||
}
|
||||
|
||||
print "$filename: $line_count\n";
|
||||
}
|
||||
|
||||
The difference here is the addition of the temporary variable C<$data>.
|
||||
This is used to store a copy of the compressed data while it is being
|
||||
uncompressed.
|
||||
|
||||
If you know that C<$compressedLength> isn't that big then using temporary
|
||||
storage won't be a problem. But if C<$compressedLength> is very large or
|
||||
you are writing an application that other people will use, and so have no
|
||||
idea how big C<$compressedLength> will be, it could be an issue.
|
||||
|
||||
Using C<InputLength> avoids the use of temporary storage and means the
|
||||
application can cope with large compressed data streams.
|
||||
|
||||
One final point -- obviously C<InputLength> can only be used whenever you
|
||||
know the length of the compressed data beforehand, like here with a zip
|
||||
file.
|
||||
|
||||
=head1 SUPPORT
|
||||
|
||||
General feedback/questions/bug reports should be sent to
|
||||
L<https://github.com/pmqs//issues> (preferred) or
|
||||
L<https://rt.cpan.org/Public/Dist/Display.html?Name=>.
|
||||
|
||||
=head1 SEE ALSO
|
||||
|
||||
L<Compress::Zlib>, L<IO::Compress::Gzip>, L<IO::Uncompress::Gunzip>, L<IO::Compress::Deflate>, L<IO::Uncompress::Inflate>, L<IO::Compress::RawDeflate>, L<IO::Uncompress::RawInflate>, L<IO::Compress::Bzip2>, L<IO::Uncompress::Bunzip2>, L<IO::Compress::Lzma>, L<IO::Uncompress::UnLzma>, L<IO::Compress::Xz>, L<IO::Uncompress::UnXz>, L<IO::Compress::Lzip>, L<IO::Uncompress::UnLzip>, L<IO::Compress::Lzop>, L<IO::Uncompress::UnLzop>, L<IO::Compress::Lzf>, L<IO::Uncompress::UnLzf>, L<IO::Compress::Zstd>, L<IO::Uncompress::UnZstd>, L<IO::Uncompress::AnyInflate>, L<IO::Uncompress::AnyUncompress>
|
||||
|
||||
L<IO::Compress::FAQ|IO::Compress::FAQ>
|
||||
|
||||
L<File::GlobMapper|File::GlobMapper>, L<Archive::Zip|Archive::Zip>,
|
||||
L<Archive::Tar|Archive::Tar>,
|
||||
L<IO::Zlib|IO::Zlib>
|
||||
|
||||
=head1 AUTHOR
|
||||
|
||||
This module was written by Paul Marquess, C<pmqs@cpan.org>.
|
||||
|
||||
=head1 MODIFICATION HISTORY
|
||||
|
||||
See the Changes file.
|
||||
|
||||
=head1 COPYRIGHT AND LICENSE
|
||||
|
||||
Copyright (c) 2005-2021 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.
|
||||
|
||||
1270
database/perl/lib/IO/Compress/Gzip.pm
Normal file
1270
database/perl/lib/IO/Compress/Gzip.pm
Normal file
File diff suppressed because it is too large
Load Diff
148
database/perl/lib/IO/Compress/Gzip/Constants.pm
Normal file
148
database/perl/lib/IO/Compress/Gzip/Constants.pm
Normal file
@@ -0,0 +1,148 @@
|
||||
package IO::Compress::Gzip::Constants;
|
||||
|
||||
use strict ;
|
||||
use warnings;
|
||||
use bytes;
|
||||
|
||||
require Exporter;
|
||||
|
||||
our ($VERSION, @ISA, @EXPORT, %GZIP_OS_Names);
|
||||
our ($GZIP_FNAME_INVALID_CHAR_RE, $GZIP_FCOMMENT_INVALID_CHAR_RE);
|
||||
|
||||
$VERSION = '2.100';
|
||||
|
||||
@ISA = qw(Exporter);
|
||||
|
||||
@EXPORT= qw(
|
||||
|
||||
GZIP_ID_SIZE
|
||||
GZIP_ID1
|
||||
GZIP_ID2
|
||||
|
||||
GZIP_FLG_DEFAULT
|
||||
GZIP_FLG_FTEXT
|
||||
GZIP_FLG_FHCRC
|
||||
GZIP_FLG_FEXTRA
|
||||
GZIP_FLG_FNAME
|
||||
GZIP_FLG_FCOMMENT
|
||||
GZIP_FLG_RESERVED
|
||||
|
||||
GZIP_CM_DEFLATED
|
||||
|
||||
GZIP_MIN_HEADER_SIZE
|
||||
GZIP_TRAILER_SIZE
|
||||
|
||||
GZIP_MTIME_DEFAULT
|
||||
GZIP_XFL_DEFAULT
|
||||
GZIP_FEXTRA_HEADER_SIZE
|
||||
GZIP_FEXTRA_MAX_SIZE
|
||||
GZIP_FEXTRA_SUBFIELD_HEADER_SIZE
|
||||
GZIP_FEXTRA_SUBFIELD_ID_SIZE
|
||||
GZIP_FEXTRA_SUBFIELD_LEN_SIZE
|
||||
GZIP_FEXTRA_SUBFIELD_MAX_SIZE
|
||||
|
||||
$GZIP_FNAME_INVALID_CHAR_RE
|
||||
$GZIP_FCOMMENT_INVALID_CHAR_RE
|
||||
|
||||
GZIP_FHCRC_SIZE
|
||||
|
||||
GZIP_ISIZE_MAX
|
||||
GZIP_ISIZE_MOD_VALUE
|
||||
|
||||
|
||||
GZIP_NULL_BYTE
|
||||
|
||||
GZIP_OS_DEFAULT
|
||||
|
||||
%GZIP_OS_Names
|
||||
|
||||
GZIP_MINIMUM_HEADER
|
||||
|
||||
);
|
||||
|
||||
# Constant names derived from RFC 1952
|
||||
|
||||
use constant GZIP_ID_SIZE => 2 ;
|
||||
use constant GZIP_ID1 => 0x1F;
|
||||
use constant GZIP_ID2 => 0x8B;
|
||||
|
||||
use constant GZIP_MIN_HEADER_SIZE => 10 ;# minimum gzip header size
|
||||
use constant GZIP_TRAILER_SIZE => 8 ;
|
||||
|
||||
|
||||
use constant GZIP_FLG_DEFAULT => 0x00 ;
|
||||
use constant GZIP_FLG_FTEXT => 0x01 ;
|
||||
use constant GZIP_FLG_FHCRC => 0x02 ; # called CONTINUATION in gzip
|
||||
use constant GZIP_FLG_FEXTRA => 0x04 ;
|
||||
use constant GZIP_FLG_FNAME => 0x08 ;
|
||||
use constant GZIP_FLG_FCOMMENT => 0x10 ;
|
||||
#use constant GZIP_FLG_ENCRYPTED => 0x20 ; # documented in gzip sources
|
||||
use constant GZIP_FLG_RESERVED => (0x20 | 0x40 | 0x80) ;
|
||||
|
||||
use constant GZIP_XFL_DEFAULT => 0x00 ;
|
||||
|
||||
use constant GZIP_MTIME_DEFAULT => 0x00 ;
|
||||
|
||||
use constant GZIP_FEXTRA_HEADER_SIZE => 2 ;
|
||||
use constant GZIP_FEXTRA_MAX_SIZE => 0xFFFF ;
|
||||
use constant GZIP_FEXTRA_SUBFIELD_ID_SIZE => 2 ;
|
||||
use constant GZIP_FEXTRA_SUBFIELD_LEN_SIZE => 2 ;
|
||||
use constant GZIP_FEXTRA_SUBFIELD_HEADER_SIZE => GZIP_FEXTRA_SUBFIELD_ID_SIZE +
|
||||
GZIP_FEXTRA_SUBFIELD_LEN_SIZE;
|
||||
use constant GZIP_FEXTRA_SUBFIELD_MAX_SIZE => GZIP_FEXTRA_MAX_SIZE -
|
||||
GZIP_FEXTRA_SUBFIELD_HEADER_SIZE ;
|
||||
|
||||
|
||||
if (ord('A') == 193)
|
||||
{
|
||||
# EBCDIC
|
||||
$GZIP_FNAME_INVALID_CHAR_RE = '[\x00-\x3f\xff]';
|
||||
$GZIP_FCOMMENT_INVALID_CHAR_RE = '[\x00-\x0a\x11-\x14\x16-\x3f\xff]';
|
||||
|
||||
}
|
||||
else
|
||||
{
|
||||
$GZIP_FNAME_INVALID_CHAR_RE = '[\x00-\x1F\x7F-\x9F]';
|
||||
$GZIP_FCOMMENT_INVALID_CHAR_RE = '[\x00-\x09\x11-\x1F\x7F-\x9F]';
|
||||
}
|
||||
|
||||
use constant GZIP_FHCRC_SIZE => 2 ; # aka CONTINUATION in gzip
|
||||
|
||||
use constant GZIP_CM_DEFLATED => 8 ;
|
||||
|
||||
use constant GZIP_NULL_BYTE => "\x00";
|
||||
use constant GZIP_ISIZE_MAX => 0xFFFFFFFF ;
|
||||
use constant GZIP_ISIZE_MOD_VALUE => GZIP_ISIZE_MAX + 1 ;
|
||||
|
||||
# OS Names sourced from http://www.gzip.org/format.txt
|
||||
|
||||
use constant GZIP_OS_DEFAULT=> 0xFF ;
|
||||
%GZIP_OS_Names = (
|
||||
0 => 'MS-DOS',
|
||||
1 => 'Amiga',
|
||||
2 => 'VMS',
|
||||
3 => 'Unix',
|
||||
4 => 'VM/CMS',
|
||||
5 => 'Atari TOS',
|
||||
6 => 'HPFS (OS/2, NT)',
|
||||
7 => 'Macintosh',
|
||||
8 => 'Z-System',
|
||||
9 => 'CP/M',
|
||||
10 => 'TOPS-20',
|
||||
11 => 'NTFS (NT)',
|
||||
12 => 'SMS QDOS',
|
||||
13 => 'Acorn RISCOS',
|
||||
14 => 'VFAT file system (Win95, NT)',
|
||||
15 => 'MVS',
|
||||
16 => 'BeOS',
|
||||
17 => 'Tandem/NSK',
|
||||
18 => 'THEOS',
|
||||
GZIP_OS_DEFAULT() => 'Unknown',
|
||||
) ;
|
||||
|
||||
use constant GZIP_MINIMUM_HEADER => pack("C4 V C C",
|
||||
GZIP_ID1, GZIP_ID2, GZIP_CM_DEFLATED, GZIP_FLG_DEFAULT,
|
||||
GZIP_MTIME_DEFAULT, GZIP_XFL_DEFAULT, GZIP_OS_DEFAULT) ;
|
||||
|
||||
|
||||
1;
|
||||
1013
database/perl/lib/IO/Compress/RawDeflate.pm
Normal file
1013
database/perl/lib/IO/Compress/RawDeflate.pm
Normal file
File diff suppressed because it is too large
Load Diff
2149
database/perl/lib/IO/Compress/Zip.pm
Normal file
2149
database/perl/lib/IO/Compress/Zip.pm
Normal file
File diff suppressed because it is too large
Load Diff
130
database/perl/lib/IO/Compress/Zip/Constants.pm
Normal file
130
database/perl/lib/IO/Compress/Zip/Constants.pm
Normal file
@@ -0,0 +1,130 @@
|
||||
package IO::Compress::Zip::Constants;
|
||||
|
||||
use strict ;
|
||||
use warnings;
|
||||
|
||||
require Exporter;
|
||||
|
||||
our ($VERSION, @ISA, @EXPORT, %ZIP_CM_MIN_VERSIONS);
|
||||
|
||||
$VERSION = '2.100';
|
||||
|
||||
@ISA = qw(Exporter);
|
||||
|
||||
@EXPORT= qw(
|
||||
|
||||
ZIP_CM_STORE
|
||||
ZIP_CM_DEFLATE
|
||||
ZIP_CM_BZIP2
|
||||
ZIP_CM_LZMA
|
||||
ZIP_CM_PPMD
|
||||
ZIP_CM_XZ
|
||||
ZIP_CM_ZSTD
|
||||
|
||||
ZIP_LOCAL_HDR_SIG
|
||||
ZIP_DATA_HDR_SIG
|
||||
ZIP_CENTRAL_HDR_SIG
|
||||
ZIP_END_CENTRAL_HDR_SIG
|
||||
ZIP64_END_CENTRAL_REC_HDR_SIG
|
||||
ZIP64_END_CENTRAL_LOC_HDR_SIG
|
||||
ZIP64_ARCHIVE_EXTRA_SIG
|
||||
ZIP64_DIGITAL_SIGNATURE_SIG
|
||||
|
||||
ZIP_GP_FLAG_ENCRYPTED_MASK
|
||||
ZIP_GP_FLAG_STREAMING_MASK
|
||||
ZIP_GP_FLAG_PATCHED_MASK
|
||||
ZIP_GP_FLAG_STRONG_ENCRYPTED_MASK
|
||||
ZIP_GP_FLAG_LZMA_EOS_PRESENT
|
||||
ZIP_GP_FLAG_LANGUAGE_ENCODING
|
||||
|
||||
ZIP_EXTRA_ID_ZIP64
|
||||
ZIP_EXTRA_ID_EXT_TIMESTAMP
|
||||
ZIP_EXTRA_ID_INFO_ZIP_UNIX2
|
||||
ZIP_EXTRA_ID_INFO_ZIP_UNIXN
|
||||
ZIP_EXTRA_ID_INFO_ZIP_Upath
|
||||
ZIP_EXTRA_ID_INFO_ZIP_Ucom
|
||||
ZIP_EXTRA_ID_JAVA_EXE
|
||||
|
||||
ZIP_OS_CODE_UNIX
|
||||
ZIP_OS_CODE_DEFAULT
|
||||
|
||||
ZIP_IFA_TEXT_MASK
|
||||
|
||||
%ZIP_CM_MIN_VERSIONS
|
||||
ZIP64_MIN_VERSION
|
||||
|
||||
ZIP_A_RONLY
|
||||
ZIP_A_HIDDEN
|
||||
ZIP_A_SYSTEM
|
||||
ZIP_A_LABEL
|
||||
ZIP_A_DIR
|
||||
ZIP_A_ARCHIVE
|
||||
);
|
||||
|
||||
# Compression types supported
|
||||
use constant ZIP_CM_STORE => 0 ;
|
||||
use constant ZIP_CM_DEFLATE => 8 ;
|
||||
use constant ZIP_CM_BZIP2 => 12 ;
|
||||
use constant ZIP_CM_LZMA => 14 ;
|
||||
use constant ZIP_CM_ZSTD => 93 ;
|
||||
use constant ZIP_CM_XZ => 95 ;
|
||||
use constant ZIP_CM_PPMD => 98 ; # Not Supported yet
|
||||
|
||||
# General Purpose Flag
|
||||
use constant ZIP_GP_FLAG_ENCRYPTED_MASK => (1 << 0) ;
|
||||
use constant ZIP_GP_FLAG_STREAMING_MASK => (1 << 3) ;
|
||||
use constant ZIP_GP_FLAG_PATCHED_MASK => (1 << 5) ;
|
||||
use constant ZIP_GP_FLAG_STRONG_ENCRYPTED_MASK => (1 << 6) ;
|
||||
use constant ZIP_GP_FLAG_LZMA_EOS_PRESENT => (1 << 1) ;
|
||||
use constant ZIP_GP_FLAG_LANGUAGE_ENCODING => (1 << 11) ;
|
||||
|
||||
# Internal File Attributes
|
||||
use constant ZIP_IFA_TEXT_MASK => 1;
|
||||
|
||||
# Signatures for each of the headers
|
||||
use constant ZIP_LOCAL_HDR_SIG => 0x04034b50;
|
||||
use constant ZIP_DATA_HDR_SIG => 0x08074b50;
|
||||
use constant packed_ZIP_DATA_HDR_SIG => pack "V", ZIP_DATA_HDR_SIG;
|
||||
use constant ZIP_CENTRAL_HDR_SIG => 0x02014b50;
|
||||
use constant ZIP_END_CENTRAL_HDR_SIG => 0x06054b50;
|
||||
use constant ZIP64_END_CENTRAL_REC_HDR_SIG => 0x06064b50;
|
||||
use constant ZIP64_END_CENTRAL_LOC_HDR_SIG => 0x07064b50;
|
||||
use constant ZIP64_ARCHIVE_EXTRA_SIG => 0x08064b50;
|
||||
use constant ZIP64_DIGITAL_SIGNATURE_SIG => 0x05054b50;
|
||||
|
||||
use constant ZIP_OS_CODE_UNIX => 3;
|
||||
use constant ZIP_OS_CODE_DEFAULT => 3;
|
||||
|
||||
# Extra Field ID's
|
||||
use constant ZIP_EXTRA_ID_ZIP64 => pack "v", 1;
|
||||
use constant ZIP_EXTRA_ID_EXT_TIMESTAMP => "UT";
|
||||
use constant ZIP_EXTRA_ID_INFO_ZIP_UNIX2 => "Ux";
|
||||
use constant ZIP_EXTRA_ID_INFO_ZIP_UNIXN => "ux";
|
||||
use constant ZIP_EXTRA_ID_INFO_ZIP_Upath => "up";
|
||||
use constant ZIP_EXTRA_ID_INFO_ZIP_Ucom => "uc";
|
||||
use constant ZIP_EXTRA_ID_JAVA_EXE => pack "v", 0xCAFE;
|
||||
|
||||
# DOS Attributes
|
||||
use constant ZIP_A_RONLY => 0x01;
|
||||
use constant ZIP_A_HIDDEN => 0x02;
|
||||
use constant ZIP_A_SYSTEM => 0x04;
|
||||
use constant ZIP_A_LABEL => 0x08;
|
||||
use constant ZIP_A_DIR => 0x10;
|
||||
use constant ZIP_A_ARCHIVE => 0x20;
|
||||
|
||||
use constant ZIP64_MIN_VERSION => 45;
|
||||
|
||||
%ZIP_CM_MIN_VERSIONS = (
|
||||
ZIP_CM_STORE() => 20,
|
||||
ZIP_CM_DEFLATE() => 20,
|
||||
ZIP_CM_BZIP2() => 46,
|
||||
ZIP_CM_LZMA() => 63,
|
||||
ZIP_CM_PPMD() => 63,
|
||||
ZIP_CM_ZSTD() => 20, # Winzip needs these to be 20
|
||||
ZIP_CM_XZ() => 20,
|
||||
);
|
||||
|
||||
|
||||
1;
|
||||
|
||||
__END__
|
||||
77
database/perl/lib/IO/Compress/Zlib/Constants.pm
Normal file
77
database/perl/lib/IO/Compress/Zlib/Constants.pm
Normal file
@@ -0,0 +1,77 @@
|
||||
|
||||
package IO::Compress::Zlib::Constants ;
|
||||
|
||||
use strict ;
|
||||
use warnings;
|
||||
use bytes;
|
||||
|
||||
require Exporter;
|
||||
|
||||
our ($VERSION, @ISA, @EXPORT);
|
||||
|
||||
$VERSION = '2.100';
|
||||
|
||||
@ISA = qw(Exporter);
|
||||
|
||||
@EXPORT= qw(
|
||||
|
||||
ZLIB_HEADER_SIZE
|
||||
ZLIB_TRAILER_SIZE
|
||||
|
||||
ZLIB_CMF_CM_OFFSET
|
||||
ZLIB_CMF_CM_BITS
|
||||
ZLIB_CMF_CM_DEFLATED
|
||||
|
||||
ZLIB_CMF_CINFO_OFFSET
|
||||
ZLIB_CMF_CINFO_BITS
|
||||
ZLIB_CMF_CINFO_MAX
|
||||
|
||||
ZLIB_FLG_FCHECK_OFFSET
|
||||
ZLIB_FLG_FCHECK_BITS
|
||||
|
||||
ZLIB_FLG_FDICT_OFFSET
|
||||
ZLIB_FLG_FDICT_BITS
|
||||
|
||||
ZLIB_FLG_LEVEL_OFFSET
|
||||
ZLIB_FLG_LEVEL_BITS
|
||||
|
||||
ZLIB_FLG_LEVEL_FASTEST
|
||||
ZLIB_FLG_LEVEL_FAST
|
||||
ZLIB_FLG_LEVEL_DEFAULT
|
||||
ZLIB_FLG_LEVEL_SLOWEST
|
||||
|
||||
ZLIB_FDICT_SIZE
|
||||
|
||||
);
|
||||
|
||||
# Constant names derived from RFC1950
|
||||
|
||||
use constant ZLIB_HEADER_SIZE => 2;
|
||||
use constant ZLIB_TRAILER_SIZE => 4;
|
||||
|
||||
use constant ZLIB_CMF_CM_OFFSET => 0;
|
||||
use constant ZLIB_CMF_CM_BITS => 0xF ; # 0b1111
|
||||
use constant ZLIB_CMF_CM_DEFLATED => 8;
|
||||
|
||||
use constant ZLIB_CMF_CINFO_OFFSET => 4;
|
||||
use constant ZLIB_CMF_CINFO_BITS => 0xF ; # 0b1111;
|
||||
use constant ZLIB_CMF_CINFO_MAX => 7;
|
||||
|
||||
use constant ZLIB_FLG_FCHECK_OFFSET => 0;
|
||||
use constant ZLIB_FLG_FCHECK_BITS => 0x1F ; # 0b11111;
|
||||
|
||||
use constant ZLIB_FLG_FDICT_OFFSET => 5;
|
||||
use constant ZLIB_FLG_FDICT_BITS => 0x1 ; # 0b1;
|
||||
|
||||
use constant ZLIB_FLG_LEVEL_OFFSET => 6;
|
||||
use constant ZLIB_FLG_LEVEL_BITS => 0x3 ; # 0b11;
|
||||
|
||||
use constant ZLIB_FLG_LEVEL_FASTEST => 0;
|
||||
use constant ZLIB_FLG_LEVEL_FAST => 1;
|
||||
use constant ZLIB_FLG_LEVEL_DEFAULT => 2;
|
||||
use constant ZLIB_FLG_LEVEL_SLOWEST => 3;
|
||||
|
||||
use constant ZLIB_FDICT_SIZE => 4;
|
||||
|
||||
|
||||
1;
|
||||
229
database/perl/lib/IO/Compress/Zlib/Extra.pm
Normal file
229
database/perl/lib/IO/Compress/Zlib/Extra.pm
Normal file
@@ -0,0 +1,229 @@
|
||||
package IO::Compress::Zlib::Extra;
|
||||
|
||||
require 5.006 ;
|
||||
|
||||
use strict ;
|
||||
use warnings;
|
||||
use bytes;
|
||||
|
||||
our ($VERSION, @ISA, @EXPORT_OK, %EXPORT_TAGS);
|
||||
|
||||
$VERSION = '2.100';
|
||||
|
||||
use IO::Compress::Gzip::Constants 2.100 ;
|
||||
|
||||
sub ExtraFieldError
|
||||
{
|
||||
return $_[0];
|
||||
return "Error with ExtraField Parameter: $_[0]" ;
|
||||
}
|
||||
|
||||
sub validateExtraFieldPair
|
||||
{
|
||||
my $pair = shift ;
|
||||
my $strict = shift;
|
||||
my $gzipMode = shift ;
|
||||
|
||||
return ExtraFieldError("Not an array ref")
|
||||
unless ref $pair && ref $pair eq 'ARRAY';
|
||||
|
||||
return ExtraFieldError("SubField must have two parts")
|
||||
unless @$pair == 2 ;
|
||||
|
||||
return ExtraFieldError("SubField ID is a reference")
|
||||
if ref $pair->[0] ;
|
||||
|
||||
return ExtraFieldError("SubField Data is a reference")
|
||||
if ref $pair->[1] ;
|
||||
|
||||
# ID is exactly two chars
|
||||
return ExtraFieldError("SubField ID not two chars long")
|
||||
unless length $pair->[0] == GZIP_FEXTRA_SUBFIELD_ID_SIZE ;
|
||||
|
||||
# Check that the 2nd byte of the ID isn't 0
|
||||
return ExtraFieldError("SubField ID 2nd byte is 0x00")
|
||||
if $strict && $gzipMode && substr($pair->[0], 1, 1) eq "\x00" ;
|
||||
|
||||
return ExtraFieldError("SubField Data too long")
|
||||
if length $pair->[1] > GZIP_FEXTRA_SUBFIELD_MAX_SIZE ;
|
||||
|
||||
|
||||
return undef ;
|
||||
}
|
||||
|
||||
sub parseRawExtra
|
||||
{
|
||||
my $data = shift ;
|
||||
my $extraRef = shift;
|
||||
my $strict = shift;
|
||||
my $gzipMode = shift ;
|
||||
|
||||
#my $lax = shift ;
|
||||
|
||||
#return undef
|
||||
# if $lax ;
|
||||
|
||||
my $XLEN = length $data ;
|
||||
|
||||
return ExtraFieldError("Too Large")
|
||||
if $XLEN > GZIP_FEXTRA_MAX_SIZE;
|
||||
|
||||
my $offset = 0 ;
|
||||
while ($offset < $XLEN) {
|
||||
|
||||
return ExtraFieldError("Truncated in FEXTRA Body Section")
|
||||
if $offset + GZIP_FEXTRA_SUBFIELD_HEADER_SIZE > $XLEN ;
|
||||
|
||||
my $id = substr($data, $offset, GZIP_FEXTRA_SUBFIELD_ID_SIZE);
|
||||
$offset += GZIP_FEXTRA_SUBFIELD_ID_SIZE;
|
||||
|
||||
my $subLen = unpack("v", substr($data, $offset,
|
||||
GZIP_FEXTRA_SUBFIELD_LEN_SIZE));
|
||||
$offset += GZIP_FEXTRA_SUBFIELD_LEN_SIZE ;
|
||||
|
||||
return ExtraFieldError("Truncated in FEXTRA Body Section")
|
||||
if $offset + $subLen > $XLEN ;
|
||||
|
||||
my $bad = validateExtraFieldPair( [$id,
|
||||
substr($data, $offset, $subLen)],
|
||||
$strict, $gzipMode );
|
||||
return $bad if $bad ;
|
||||
push @$extraRef, [$id => substr($data, $offset, $subLen)]
|
||||
if defined $extraRef;;
|
||||
|
||||
$offset += $subLen ;
|
||||
}
|
||||
|
||||
|
||||
return undef ;
|
||||
}
|
||||
|
||||
sub findID
|
||||
{
|
||||
my $id_want = shift ;
|
||||
my $data = shift;
|
||||
|
||||
my $XLEN = length $data ;
|
||||
|
||||
my $offset = 0 ;
|
||||
while ($offset < $XLEN) {
|
||||
|
||||
return undef
|
||||
if $offset + GZIP_FEXTRA_SUBFIELD_HEADER_SIZE > $XLEN ;
|
||||
|
||||
my $id = substr($data, $offset, GZIP_FEXTRA_SUBFIELD_ID_SIZE);
|
||||
$offset += GZIP_FEXTRA_SUBFIELD_ID_SIZE;
|
||||
|
||||
my $subLen = unpack("v", substr($data, $offset,
|
||||
GZIP_FEXTRA_SUBFIELD_LEN_SIZE));
|
||||
$offset += GZIP_FEXTRA_SUBFIELD_LEN_SIZE ;
|
||||
|
||||
return undef
|
||||
if $offset + $subLen > $XLEN ;
|
||||
|
||||
return substr($data, $offset, $subLen)
|
||||
if $id eq $id_want ;
|
||||
|
||||
$offset += $subLen ;
|
||||
}
|
||||
|
||||
return undef ;
|
||||
}
|
||||
|
||||
|
||||
sub mkSubField
|
||||
{
|
||||
my $id = shift ;
|
||||
my $data = shift ;
|
||||
|
||||
return $id . pack("v", length $data) . $data ;
|
||||
}
|
||||
|
||||
sub parseExtraField
|
||||
{
|
||||
my $dataRef = $_[0];
|
||||
my $strict = $_[1];
|
||||
my $gzipMode = $_[2];
|
||||
#my $lax = @_ == 2 ? $_[1] : 1;
|
||||
|
||||
|
||||
# ExtraField can be any of
|
||||
#
|
||||
# -ExtraField => $data
|
||||
#
|
||||
# -ExtraField => [$id1, $data1,
|
||||
# $id2, $data2]
|
||||
# ...
|
||||
# ]
|
||||
#
|
||||
# -ExtraField => [ [$id1 => $data1],
|
||||
# [$id2 => $data2],
|
||||
# ...
|
||||
# ]
|
||||
#
|
||||
# -ExtraField => { $id1 => $data1,
|
||||
# $id2 => $data2,
|
||||
# ...
|
||||
# }
|
||||
|
||||
if ( ! ref $dataRef ) {
|
||||
|
||||
return undef
|
||||
if ! $strict;
|
||||
|
||||
return parseRawExtra($dataRef, undef, 1, $gzipMode);
|
||||
}
|
||||
|
||||
my $data = $dataRef;
|
||||
my $out = '' ;
|
||||
|
||||
if (ref $data eq 'ARRAY') {
|
||||
if (ref $data->[0]) {
|
||||
|
||||
foreach my $pair (@$data) {
|
||||
return ExtraFieldError("Not list of lists")
|
||||
unless ref $pair eq 'ARRAY' ;
|
||||
|
||||
my $bad = validateExtraFieldPair($pair, $strict, $gzipMode) ;
|
||||
return $bad if $bad ;
|
||||
|
||||
$out .= mkSubField(@$pair);
|
||||
}
|
||||
}
|
||||
else {
|
||||
return ExtraFieldError("Not even number of elements")
|
||||
unless @$data % 2 == 0;
|
||||
|
||||
for (my $ix = 0; $ix <= @$data -1 ; $ix += 2) {
|
||||
my $bad = validateExtraFieldPair([$data->[$ix],
|
||||
$data->[$ix+1]],
|
||||
$strict, $gzipMode) ;
|
||||
return $bad if $bad ;
|
||||
|
||||
$out .= mkSubField($data->[$ix], $data->[$ix+1]);
|
||||
}
|
||||
}
|
||||
}
|
||||
elsif (ref $data eq 'HASH') {
|
||||
while (my ($id, $info) = each %$data) {
|
||||
my $bad = validateExtraFieldPair([$id, $info], $strict, $gzipMode);
|
||||
return $bad if $bad ;
|
||||
|
||||
$out .= mkSubField($id, $info);
|
||||
}
|
||||
}
|
||||
else {
|
||||
return ExtraFieldError("Not a scalar, array ref or hash ref") ;
|
||||
}
|
||||
|
||||
return ExtraFieldError("Too Large")
|
||||
if length $out > GZIP_FEXTRA_MAX_SIZE;
|
||||
|
||||
$_[0] = $out ;
|
||||
|
||||
return undef;
|
||||
}
|
||||
|
||||
1;
|
||||
|
||||
__END__
|
||||
Reference in New Issue
Block a user