CHANGES
-------
+ 2.000_13 20 June 2006
+
+ * Store compress & uncompressed sizes as 64-bit.
+
+ * For one-shot uncompression, like this
+
+ unzip "some.zip" => \@a, MultiStream => 1;
+
+ Push each uncompressed stream from "some.zip" onto @a.
+
+ * Added IO::Compress::Base::FilterEnvelope
+
+ * Added IO::Uncompress::Base::nextStream
+
+ * The '-' filehandle now maps to either *STDIN or *STDOUT.
+ This keeps mod_perl happier. Was using these before
+
+ new IO::File("<-")
+ new IO::File(">-")
+
+ 2.000_12 3 May 2006
+
2.000_11 10 April 2006
* Transparent + InputLength made more robust where input data is not
IO::Compress::Base
- Version 2.000_12
+ Version 2.000_13
- 17 May 2006
+ 20 June 2006
Copyright (c) 2005-2006 Paul Marquess. All rights reserved.
our (@ISA, $VERSION, $got_encode);
#@ISA = qw(Exporter IO::File);
-$VERSION = '2.000_12';
+$VERSION = '2.000_13';
#Can't locate object method "SWASHNEW" via package "utf8" (perhaps you forgot to load "utf8"?) at .../ext/Compress-Zlib/Gzip/blib/lib/Compress/Zlib/Common.pm line 16.
return 1;
}
+sub output
+{
+ my $self = shift ;
+ my $data = shift ;
+ my $last = shift ;
+
+ return 1
+ if length $data == 0 && ! $last ;
+
+ if ( *$self->{FilterEnvelope} ) {
+ *_ = \$data;
+ &{ *$self->{FilterEnvelope} }();
+ }
+
+ if ( defined *$self->{FH} ) {
+ defined *$self->{FH}->write( $data, length $data )
+ or return $self->saveErrorString(0, $!, $!);
+ }
+ else {
+ ${ *$self->{Buffer} } .= $data ;
+ }
+
+ return 1;
+}
+
sub getOneShotParams
{
return ( 'MultiStream' => [1, 1, Parse_boolean, 1],
'Append' => [1, 1, Parse_boolean, 0],
'BinModeIn' => [1, 1, Parse_boolean, 0],
+ 'FilterEnvelope' => [1, 1, Parse_any, undef],
+
$self->getExtraParams(),
*$self->{OneShot} ? $self->getOneShotParams()
: (),
# Merge implies Append
my $merge = $got->value('Merge') ;
my $appendOutput = $got->value('Append') || $merge ;
+ *$obj->{Append} = $appendOutput;
+ *$obj->{FilterEnvelope} = $got->value('FilterEnvelope') ;
if ($merge)
{
*$obj->{Compress} = $obj->mkComp($class, $got)
or return undef;
- *$obj->{BytesWritten} = 0 ;
- *$obj->{UnCompSize_32bit} = 0 ;
-
- *$obj->{Header} = $obj->mkHeader($got) ;
+ *$obj->{UnCompSize} = new U64 ;
+ *$obj->{CompSize} = new U64 ;
if ( $outType eq 'buffer') {
${ *$obj->{Buffer} } = ''
unless $appendOutput ;
- ${ *$obj->{Buffer} } .= *$obj->{Header};
}
else {
if ($outType eq 'handle') {
*$obj->{StdIO} = ($outValue eq '-');
setBinModeOutput(*$obj->{FH}) ;
}
-
-
- if (length *$obj->{Header}) {
- defined *$obj->{FH}->write(*$obj->{Header}, length(*$obj->{Header}))
- or return $obj->saveErrorString(undef, $!, $!) ;
- }
}
+
+ *$obj->{Header} = $obj->mkHeader($got) ;
+ $obj->output( *$obj->{Header} )
+ or return undef;
}
else
{
my $status ;
my $buff ;
my $count = 0 ;
- while (($status = read($fh, $buff, 4096)) > 0) {
+ while (($status = read($fh, $buff, 16 * 1024)) > 0) {
$count += length $buff;
defined $self->syswrite($buff, @_)
or return undef ;
my $self = shift ;
$self->close() ;
+
# TODO - memory leak with 5.8.0 - this isn't called until
# global destruction
#
return 0 if ! defined $$buffer || length $$buffer == 0 ;
my $buffer_length = defined $$buffer ? length($$buffer) : 0 ;
- *$self->{BytesWritten} += $buffer_length ;
- my $rest = 0xFFFFFFFF - *$self->{UnCompSize_32bit} ;
- if ($buffer_length > $rest) {
- *$self->{UnCompSize_32bit} = $buffer_length - $rest - 1;
- }
- else {
- *$self->{UnCompSize_32bit} += $buffer_length ;
- }
+ *$self->{UnCompSize}->add($buffer_length) ;
$self->filterUncompressed($buffer);
# $$buffer = *$self->{Encoding}->encode($$buffer);
# }
- #my $length = length $$buffer;
-
- my $status = *$self->{Compress}->compr($buffer, *$self->{Buffer}) ;
+ my $outBuffer='';
+ my $status = *$self->{Compress}->compr($buffer, $outBuffer) ;
return $self->saveErrorString(undef, *$self->{Compress}{Error},
*$self->{Compress}{ErrorNo})
if $status == STATUS_ERROR;
+ *$self->{CompSize}->add(length $outBuffer) ;
- if ( defined *$self->{FH} and length ${ *$self->{Buffer} }) {
- defined *$self->{FH}->write( ${ *$self->{Buffer} }, length ${ *$self->{Buffer} } )
- or return $self->saveErrorString(undef, $!, $!);
- ${ *$self->{Buffer} } = '' ;
- }
+ $self->output($outBuffer)
+ or return undef;
return $buffer_length;
}
{
my $self = shift ;
- my $status = *$self->{Compress}->flush(*$self->{Buffer}, @_) ;
+ my $outBuffer='';
+ my $status = *$self->{Compress}->flush($outBuffer, @_) ;
return $self->saveErrorString(0, *$self->{Compress}{Error},
*$self->{Compress}{ErrorNo})
if $status == STATUS_ERROR;
if ( defined *$self->{FH} ) {
*$self->{FH}->clearerr();
- defined *$self->{FH}->write(${ *$self->{Buffer} }, length ${ *$self->{Buffer} })
- or return $self->saveErrorString(0, $!, $!);
+ }
+
+ *$self->{CompSize}->add(length $outBuffer) ;
+
+ $self->output($outBuffer)
+ or return 0;
+
+ if ( defined *$self->{FH} ) {
defined *$self->{FH}->flush()
or return $self->saveErrorString(0, $!, $!);
- ${ *$self->{Buffer} } = '' ;
}
return 1;
or $self->croakError("newStream: $self->{Error}");
*$self->{Header} = $self->mkHeader($got) ;
- ${ *$self->{Buffer} } .= *$self->{Header} ;
-
- if (defined *$self->{FH})
- {
- defined *$self->{FH}->write(${ *$self->{Buffer} },
- length ${ *$self->{Buffer} })
- or return $self->saveErrorString(0, $!, $!);
- ${ *$self->{Buffer} } = '' ;
- }
+ $self->output(*$self->{Header} )
+ or return 0;
- #my $status = *$self->{Compress}->reset() ;
my $status = $self->reset() ;
return $self->saveErrorString(0, *$self->{Compress}{Error},
*$self->{Compress}{ErrorNo})
if $status == STATUS_ERROR;
- *$self->{BytesWritten} = 0 ;
- *$self->{UnCompSize_32bit} = 0 ;
+ *$self->{UnCompSize}->reset();
+ *$self->{CompSize}->reset();
return 1 ;
}
{
my $self = shift ;
- my $status = *$self->{Compress}->close(*$self->{Buffer}) ;
+ my $trailer = '';
+
+ my $status = *$self->{Compress}->close($trailer) ;
return $self->saveErrorString(0, *$self->{Compress}{Error}, *$self->{Compress}{ErrorNo})
if $status == STATUS_ERROR;
- my $trailer = $self->mkTrailer();
+ *$self->{CompSize}->add(length $trailer) ;
+
+ $trailer .= $self->mkTrailer();
defined $trailer
or return 0;
- ${ *$self->{Buffer} } .= $trailer;
-
- return 1 if ! defined *$self->{FH} ;
-
- defined *$self->{FH}->write(${ *$self->{Buffer} }, length ${ *$self->{Buffer} })
- or return $self->saveErrorString(0, $!, $!);
-
- ${ *$self->{Buffer} } = '' ;
-
- return 1;
+ return $self->output($trailer);
}
sub _writeFinalTrailer
{
my $self = shift ;
- ${ *$self->{Buffer} } .= $self->mkFinalTrailer();
-
- return 1 if ! defined *$self->{FH} ;
-
- defined *$self->{FH}->write(${ *$self->{Buffer} }, length ${ *$self->{Buffer} })
- or return $self->saveErrorString(0, $!, $!);
-
- ${ *$self->{Buffer} } = '' ;
-
- return 1;
+ return $self->output($self->mkFinalTrailer());
}
sub close
$self->_writeFinalTrailer()
or return 0 ;
+ $self->output( "", 1 )
+ or return 0;
+
if (defined *$self->{FH}) {
+
#if (! *$self->{Handle} || *$self->{AutoClose}) {
if ((! *$self->{Handle} || *$self->{AutoClose}) && ! *$self->{StdIO}) {
$! = 0 ;
{
my $self = shift ;
- return *$self->{BytesWritten} ;
+ return *$self->{UnCompSize}->get32bit() ;
}
sub eof
require Exporter;
our ($VERSION, @ISA, @EXPORT, %EXPORT_TAGS);
@ISA = qw(Exporter);
-$VERSION = '2.000_12';
+$VERSION = '2.000_13';
@EXPORT = qw( isaFilehandle isaFilename whatIsInput whatIsOutput
isaFileGlobString cleanFileGlobString oneTarget
{
$obj->croakError("$reportClass: output filename is undef or null string")
if ! defined $_[1] || $_[1] eq '' ;
+
+ if (-e $_[1])
+ {
+ if (-d _ )
+ {
+ return $obj->saveErrorString("output file '$_[1]' is a directory");
+ }
+ }
}
return $obj ;
return $self->saveErrorString("input file '$filename' does not exist");
}
- if (! -r $filename )
+ if (-d _ )
+ {
+ return $self->saveErrorString("input file '$filename' is a directory");
+ }
+
+ if (! -r _ )
{
return $self->saveErrorString("cannot open file '$filename': $!");
}
return bless $obj, 'IO::Compress::Base::Parameters' ;
}
+package U64;
+
+use constant MAX32 => 0xFFFFFFFF ;
+use constant LOW => 0 ;
+use constant HIGH => 1;
+
+sub new
+{
+ my $class = shift ;
+
+ my $high = 0 ;
+ my $low = 0 ;
+
+ if (@_ == 2) {
+ $high = shift ;
+ $low = shift ;
+ }
+ elsif (@_ == 1) {
+ $low = shift ;
+ }
+
+ bless [$low, $high], $class;
+}
+
+sub newUnpack_V64
+{
+ my $string = shift;
+
+ my ($low, $hi) = unpack "V V", $string ;
+ bless [ $low, $hi ], "U64";
+}
+
+sub newUnpack_V32
+{
+ my $string = shift;
+
+ my $low = unpack "V", $string ;
+ bless [ $low, 0 ], "U64";
+}
+
+sub reset
+{
+ my $self = shift;
+ $self->[HIGH] = $self->[LOW] = 0;
+}
+
+sub clone
+{
+ my $self = shift;
+ bless [ @$self ], ref $self ;
+}
+
+sub getHigh
+{
+ my $self = shift;
+ return $self->[HIGH];
+}
+
+sub getLow
+{
+ my $self = shift;
+ return $self->[LOW];
+}
+
+sub get32bit
+{
+ my $self = shift;
+ return $self->[LOW];
+}
+
+sub add
+{
+ my $self = shift;
+ my $value = shift;
+
+ if (ref $value eq 'U64') {
+ $self->[HIGH] += $value->[HIGH] ;
+ $value = $value->[LOW];
+ }
+
+ my $available = MAX32 - $self->[LOW] ;
+
+ if ($value > $available) {
+ ++ $self->[HIGH] ;
+ $self->[LOW] = $value - $available - 1;
+ }
+ else {
+ $self->[LOW] += $value ;
+ }
+}
+
+sub equal
+{
+ my $self = shift;
+ my $other = shift;
+
+ return $self->[LOW] == $other->[LOW] &&
+ $self->[HIGH] == $other->[HIGH] ;
+}
+
+sub getPacked_V64
+{
+ my $self = shift;
+
+ return pack "V V", @$self ;
+}
+
+sub getPacked_V32
+{
+ my $self = shift;
+
+ return pack "V", $self->[LOW] ;
+}
+
+sub pack_V64
+{
+ my $low = shift;
+
+ return pack "V V", $low, 0;
+}
+
+
package IO::Compress::Base::Common;
1;
our ($VERSION, @ISA, @EXPORT_OK, %EXPORT_TAGS, $AnyUncompressError);
-$VERSION = '2.000_12';
+$VERSION = '2.000_13';
$AnyUncompressError = '';
@ISA = qw( Exporter IO::Uncompress::Base );
$char = $z->ungetc()
$char = $z->opened()
- $z->trailingData()
+ $data = $z->trailingData()
+ $status = $z->nextStream()
$data = $z->getHeaderInfo()
$z->tell()
$z->seek($position, $whence)
=over 5
-=item AutoClose =E<gt> 0|1
+=item C<< AutoClose => 0|1 >>
This option applies to any input or output data streams to
C<anyuncompress> that are filehandles.
This parameter defaults to 0.
-
-=item BinModeOut =E<gt> 0|1
+=item C<< BinModeOut => 0|1 >>
When writing to a file or filehandle, set C<binmode> before writing to the
file.
-=item -Append =E<gt> 0|1
+=item C<< Append => 0|1 >>
TODO
-=item -MultiStream =E<gt> 0|1
+=item C<< MultiStream => 0|1 >>
-Creates a new stream after each file.
+If the input file/buffer contains multiple compressed data streams, this
+option will uncompress the whole lot as a single data stream.
-Defaults to 1.
+Defaults to 0.
=over 5
-=item -AutoClose =E<gt> 0|1
+=item C<< AutoClose => 0|1 >>
This option is only valid when the C<$input> parameter is a filehandle. If
specified, and the value is true, it will result in the file being closed once
This parameter defaults to 0.
-=item -MultiStream =E<gt> 0|1
+=item C<< MultiStream => 0|1 >>
This parameter defaults to 0.
-
-=item -Prime =E<gt> $string
+=item C<< Prime => $string >>
This option will uncompress the contents of C<$string> before processing the
input file/buffer.
case, the uncompression can be I<primed> with these bytes using this
option.
-=item -Transparent =E<gt> 0|1
+=item C<< Transparent => 0|1 >>
If this option is set and the input file or buffer is not compressed data,
the module will allow reading of it anyway.
This option defaults to 1.
-=item -BlockSize =E<gt> $num
+=item C<< BlockSize => $num >>
When reading the compressed input data, IO::Uncompress::AnyUncompress will read it in
blocks of C<$num> bytes.
This option defaults to 4096.
-=item -InputLength =E<gt> $size
+=item C<< InputLength => $size >>
When present this option will limit the number of compressed bytes read
from the input file/buffer to C<$size>. This option can be used in the
This option defaults to off.
-=item -Append =E<gt> 0|1
+=item C<< Append => 0|1 >>
This option controls what the C<read> method does with uncompressed data.
Defaults to 0.
-=item -Strict =E<gt> 0|1
+=item C<< Strict => 0|1 >>
+=head2 nextStream
+
+Usage is
+
+ my $status = $z->nextStream();
+
+Skips to the next compressed data stream in the input file/buffer. If a new
+compressed data stream is found, the eof marker will be cleared, C<$.> will
+be reset to 0.
+
+Returns 1 if a new stream was found, 0 if none was found, and -1 if an
+error was encountered.
+
+=head2 trailingData
+
+Usage is
+
+ my $data = $z->trailingData();
+
+Returns any data that
+
=head1 Importing
No symbolic constants are required by this IO::Uncompress::AnyUncompress at present.
@ISA = qw(Exporter );
-$VERSION = '2.000_12';
+$VERSION = '2.000_13';
use constant G_EOF => 0 ;
use constant G_ERR => -1 ;
$$buf = '' unless defined $$buf ;
#$$out = '' unless defined $$out ;
substr($$out, $offset) = substr($$buf, *$self->{BufferOffset}, $get_size);
- *$self->{BufferOffset} += length($$out) - $offset ;
+ if (*$self->{ConsumeInput})
+ { substr($$buf, 0, $get_size) = '' }
+ else
+ { *$self->{BufferOffset} += length($$out) - $offset }
}
*$self->{InputLengthRemaining} -= length $$out;
my ($self) = $_[0];
local $.;
- return 0 if length *$self->{Prime};
+ return 0 if length *$self->{Prime} || *$self->{PushMode};
if (defined *$self->{FH})
{ *$self->{FH}->eof() }
'Scan' => [1, 1, Parse_boolean, 0],
'InputLength' => [1, 1, Parse_unsigned, undef],
'BinModeOut' => [1, 1, Parse_boolean, 0],
+ #'ConsumeInput' => [1, 1, Parse_boolean, 0],
$self->getExtraParams(),
*$obj->{BufferOffset} = 0 ;
*$obj->{AutoClose} = $got->value('AutoClose');
*$obj->{Strict} = $got->value('Strict');
- #*$obj->{Strict} = ! $got->value('Lax');
*$obj->{BlockSize} = $got->value('BlockSize');
*$obj->{Append} = $got->value('Append');
*$obj->{AppendOutput} = $append_mode || $got->value('Append');
+ *$obj->{ConsumeInput} = $got->value('ConsumeInput');
*$obj->{Transparent} = $got->value('Transparent');
*$obj->{MultiStream} = $got->value('MultiStream');
*$obj->{Scan} = $got->value('Scan');
*$obj->{ParseExtra} = $got->value('ParseExtra')
|| $got->value('Strict') ;
- #|| ! $got->value('Lax') ;
*$obj->{Type} = '';
*$obj->{Prime} = $got->value('Prime') || '' ;
*$obj->{Pending} = '';
*$obj->{Plain} = 0;
*$obj->{PlainBytesRead} = 0;
*$obj->{InflatedBytesRead} = 0;
- *$obj->{UnCompSize_32bit} = 0;
+ *$obj->{UnCompSize} = new U64;
+ *$obj->{CompSize} = new U64;
*$obj->{TotalInflatedBytesRead} = 0;
*$obj->{NewStream} = 0 ;
*$obj->{EventEof} = 0 ;
*$obj->{ClassName} = $class ;
*$obj->{Params} = $got ;
+ if (*$obj->{ConsumeInput}) {
+ *$obj->{InNew} = 0;
+ *$obj->{Closed} = 0;
+ return $obj
+ }
+
my $status = $obj->mkUncomp($class, $got);
return undef
my $got = $obj->checkParams($name, undef, @_)
or return undef ;
- $x->{Got} = $got ;
-
- if ($x->{Hash})
- {
- while (my($k, $v) = each %$input)
- {
- $v = \$input->{$k}
- unless defined $v ;
+ *$obj->{MultiStream} = $got->value('MultiStream');
+ $got->value('MultiStream', 0);
- $obj->_singleTarget($x, 1, $k, $v, @_)
- or return undef ;
- }
+ $x->{Got} = $got ;
- return keys %$input ;
- }
+# if ($x->{Hash})
+# {
+# while (my($k, $v) = each %$input)
+# {
+# $v = \$input->{$k}
+# unless defined $v ;
+#
+# $obj->_singleTarget($x, $k, $v, @_)
+# or return undef ;
+# }
+#
+# return keys %$input ;
+# }
if ($x->{GlobMap})
{
foreach my $pair (@{ $x->{Pairs} })
{
my ($from, $to) = @$pair ;
- $obj->_singleTarget($x, 1, $from, $to, @_)
+ $obj->_singleTarget($x, $from, $to, @_)
or return undef ;
}
return scalar @{ $x->{Pairs} } ;
}
- #if ($x->{outType} eq 'array' || $x->{outType} eq 'hash')
if (! $x->{oneOutput} )
{
my $inFile = ($x->{inType} eq 'filenames'
|| $x->{inType} eq 'filename');
$x->{inType} = $inFile ? 'filename' : 'buffer';
- my $ot = $x->{outType} ;
- $x->{outType} = 'buffer';
foreach my $in ($x->{oneInput} ? $input : @$input)
{
my $out ;
$x->{oneInput} = 1 ;
- $obj->_singleTarget($x, $inFile, $in, \$out, @_)
+ $obj->_singleTarget($x, $in, $output, @_)
or return undef ;
-
- if ($ot eq 'array')
- { push @$output, \$out }
- else
- { $output->{$in} = \$out }
}
return 1 ;
}
# finally the 1 to 1 and n to 1
- return $obj->_singleTarget($x, 1, $input, $output, @_);
+ return $obj->_singleTarget($x, $input, $output, @_);
croak "should not be here" ;
}
{
my $self = shift ;
my $x = shift ;
- my $inputIsFilename = shift;
my $input = shift;
my $output = shift;
- $x->{buff} = '' ;
+ my $buff = '';
+ $x->{buff} = \$buff ;
my $fh ;
if ($x->{outType} eq 'filename') {
if ($x->{oneInput})
{
- defined $self->_rd2($x, $input, $inputIsFilename)
+ defined $self->_rd2($x, $input, $output)
or return undef;
}
else
{
- my $inputIsFilename = ($x->{inType} ne 'array');
-
for my $element ( ($x->{inType} eq 'hash') ? keys %$input : @$input)
{
- defined $self->_rd2($x, $element, $inputIsFilename)
+ defined $self->_rd2($x, $element, $output)
or return undef ;
}
}
($x->{outType} eq 'handle' && $x->{Got}->value('AutoClose'))) {
$x->{fh}->close()
or return retErr($x, $!);
- #or return $gunzip->saveErrorString(undef, $!, $!);
delete $x->{fh};
}
my $self = shift ;
my $x = shift ;
my $input = shift;
- my $inputIsFilename = shift;
+ my $output = shift;
my $z = createSelfTiedObject($x->{Class}, *$self->{Error});
my $status ;
my $fh = $x->{fh};
- while (($status = $z->read($x->{buff})) > 0) {
- if ($fh) {
- print $fh $x->{buff}
- or return $z->saveErrorString(undef, "Error writing to output file: $!", $!);
- $x->{buff} = '' ;
+ while (1) {
+
+ while (($status = $z->read($x->{buff})) > 0) {
+ if ($fh) {
+ print $fh ${ $x->{buff} }
+ or return $z->saveErrorString(undef, "Error writing to output file: $!", $!);
+ ${ $x->{buff} } = '' ;
+ }
+ }
+
+ if (! $x->{oneOutput} ) {
+ my $ot = $x->{outType} ;
+
+ if ($ot eq 'array')
+ { push @$output, $x->{buff} }
+ elsif ($ot eq 'hash')
+ { $output->{$input} = $x->{buff} }
+
+ my $buff = '';
+ $x->{buff} = \$buff;
}
+
+ last
+ unless *$self->{MultiStream};
+
+ $status = $z->nextStream();
+
+ last
+ unless $status == 1 ;
}
return $z->closeError(undef)
}
return STATUS_OK;
-
}
sub postBlockChk
if (*$self->{NewStream}) {
- *$self->{NewStream} = 0 ;
- *$self->{EndStream} = 0 ;
- $self->reset();
-
- return G_ERR
- unless my $magic = $self->ckMagic();
- *$self->{Info} = $self->readHeader($magic);
-
- return G_ERR unless defined *$self->{Info} ;
-
- push @{ *$self->{InfoList} }, *$self->{Info} ;
+ $self->gotoNextStream() > 0
+ or return G_ERR;
# For the headers that actually uncompressed data, put the
# uncompressed data into the output buffer.
return $len;
}
- my $temp_buf ;
+ my $temp_buf = '';
my $outSize = 0;
my $status = $self->readBlock(\$temp_buf, *$self->{BlockSize}, $outSize) ;
return G_ERR
if $status == STATUS_ERROR ;
+
my $buf_len = 0;
if ($status == STATUS_OK) {
+ my $beforeC_len = length $temp_buf;
my $before_len = defined $$buffer ? length $$buffer : 0 ;
$status = *$self->{Uncomp}->uncompr(\$temp_buf, $buffer,
defined *$self->{CompressedInputLengthDone} ||
$self->smartEof(), $outSize);
-# (defined *$self->{CompressedInputLength} &&
-# *$self->{CompressedInputLengthRemaining} < 0) ||
-# $self->smartEof(), $outSize);
return $self->saveErrorString(G_ERR, *$self->{Uncomp}{Error}, *$self->{Uncomp}{ErrorNo})
if $self->saveStatus($status) == STATUS_ERROR;
$self->filterUncompressed($buffer);
- #$buf_len = *$self->{Uncomp}->count();
$buf_len = length($$buffer) - $before_len;
+ *$self->{CompSize}->add($beforeC_len - length $temp_buf) ;
+
*$self->{InflatedBytesRead} += $buf_len ;
*$self->{TotalInflatedBytesRead} += $buf_len ;
- my $rest = 0xFFFFFFFF - *$self->{UnCompSize_32bit} ;
- if ($buf_len > $rest) {
- *$self->{UnCompSize_32bit} = $buf_len - $rest - 1;
- }
- else {
- *$self->{UnCompSize_32bit} += $buf_len ;
- }
+ *$self->{UnCompSize}->add($buf_len) ;
}
if ($status == STATUS_ENDSTREAM) {
$self->pushBack($trailer) ;
}
- if (*$self->{MultiStream} && ! $self->smartEof()) {
- #&& (length $temp_buf || ! $self->smartEof())){
+ if (! $self->smartEof()) {
*$self->{NewStream} = 1 ;
- *$self->{EndStream} = 0 ;
- return $buf_len ;
+
+ if (*$self->{MultiStream}) {
+ *$self->{EndStream} = 0 ;
+ return $buf_len ;
+ }
}
}
# *$self->{EndStream} ;
#}
+sub nextStream
+{
+ my $self = shift ;
+
+ my $status = $self->gotoNextStream();
+ $status == 1
+ or return $status ;
+
+ *$self->{TotalInflatedBytesRead} = 0 ;
+ *$self->{LineNo} = $. = 0;
+
+ return 1;
+}
+
+sub gotoNextStream
+{
+ my $self = shift ;
+
+ if (! *$self->{NewStream}) {
+ my $status = 1;
+ my $buffer ;
+
+ # TODO - make this more efficient if know the offset for the end of
+ # the stream and seekable
+ $status = $self->read($buffer)
+ while $status > 0 ;
+
+ return $status
+ if $status < 0;
+ }
+
+ *$self->{NewStream} = 0 ;
+ *$self->{EndStream} = 0 ;
+ $self->reset();
+ *$self->{UnCompSize}->reset();
+ *$self->{CompSize}->reset();
+
+ return 0
+ unless my $magic = $self->ckMagic();
+ *$self->{Info} = $self->readHeader($magic);
+
+ return -1
+ unless defined *$self->{Info} ;
+
+
+ push @{ *$self->{InfoList} }, *$self->{Info} ;
+
+ return 1;
+}
+
sub streamCount
{
my $self = shift ;
#*sysread = \&read;
#*syswrite = \&_notAvailable;
-#package IO::_infScan ;
-#
-#*_raw_read = \&IO::Uncompress::Base::_raw_read ;
-#*smartRead = \&IO::Uncompress::Base::smartRead ;
-#*smartWrite = \&IO::Uncompress::Base::smartWrite ;
-#*smartSeek = \&IO::Uncompress::Base::smartSeek ;
-
-#sub mkIdentityUncomp
-#{
-# my $self = shift ;
-# my $class = shift ;
-# my $got = shift ;
-#
-# *$self->{Uncomp} = UncompressPlugin::Identity::mkUncompObject($self, $class, $got)
-# or return undef;
-#
-# return 1;
-#
-#}
-#
-#
-#package UncompressPlugin::Identity;
-#
-#use strict ;
-#use warnings;
-#
-#our ($VERSION, @ISA, @EXPORT);
-#
-#$VERSION = '2.000_05';
-#
-#use constant STATUS_OK => 0;
-#use constant STATUS_ENDSTREAM => 1;
-#use constant STATUS_ERROR => 2;
-#
-#sub mkUncompObject
-#{
-# my $class = shift ;
-#
-# bless { 'CompSize' => 0,
-# 'UnCompSize' => 0,
-# 'CRC32' => 0,
-# 'ADLER32' => 0,
-# }, __PACKAGE__ ;
-#}
-#
-#sub uncompr
-#{
-# my $self = shift ;
-# my $from = shift ;
-# my $to = shift ;
-# my $eof = shift ;
-#
-#
-# $self->{CompSize} += length $$from ;
-# $self->{UnCompSize} = $self->{CompSize} ;
-#
-# $$to = $$from ;
-#
-# return STATUS_ENDSTREAM if $eof;
-# return STATUS_OK ;
-#}
-#
-#sub count
-#{
-# my $self = shift ;
-# return $self->{UnCompSize} ;
-#}
-#
-#sub sync
-#{
-# return STATUS_OK ;
-#}
-#
-#
package IO::Uncompress::Base ;
$extra = 1
if eval { require Test::NoWarnings ; import Test::NoWarnings; 1 };
- plan tests => 33 + $extra ;
+ plan tests => 69 + $extra ;
use_ok('IO::Compress::Base::Common');
is whatIsOutput(sub { 1 }), '' , "Don't match code";
}
+
+# U64
+
+{
+ title "U64" ;
+
+ my $x = new U64();
+ is $x->getHigh, 0, " getHigh is 0";
+ is $x->getLow, 0, " getLow is 0";
+
+ $x = new U64(1,2);
+ $x = new U64(1,2);
+ is $x->getHigh, 1, " getHigh is 1";
+ is $x->getLow, 2, " getLow is 2";
+
+ $x = new U64(0xFFFFFFFF,2);
+ is $x->getHigh, 0xFFFFFFFF, " getHigh is 0xFFFFFFFF";
+ is $x->getLow, 2, " getLow is 2";
+
+ $x = new U64(7, 0xFFFFFFFF);
+ is $x->getHigh, 7, " getHigh is 7";
+ is $x->getLow, 0xFFFFFFFF, " getLow is 0xFFFFFFFF";
+
+ $x = new U64(666);
+ is $x->getHigh, 0, " getHigh is 0";
+ is $x->getLow, 666, " getLow is 666";
+
+ title "U64 - add" ;
+
+ $x = new U64(0, 1);
+ is $x->getHigh, 0, " getHigh is 0";
+ is $x->getLow, 1, " getLow is 1";
+
+ $x->add(1);
+ is $x->getHigh, 0, " getHigh is 0";
+ is $x->getLow, 2, " getLow is 2";
+
+ $x = new U64(0, 0xFFFFFFFE);
+ is $x->getHigh, 0, " getHigh is 0";
+ is $x->getLow, 0xFFFFFFFE, " getLow is 0xFFFFFFFE";
+
+ $x->add(1);
+ is $x->getHigh, 0, " getHigh is 0";
+ is $x->getLow, 0xFFFFFFFF, " getLow is 0xFFFFFFFF";
+
+ $x->add(1);
+ is $x->getHigh, 1, " getHigh is 1";
+ is $x->getLow, 0, " getLow is 0";
+
+ $x->add(1);
+ is $x->getHigh, 1, " getHigh is 1";
+ is $x->getLow, 1, " getLow is 1";
+
+ $x = new U64(1, 0xFFFFFFFE);
+ my $y = new U64(2, 3);
+
+ $x->add($y);
+ is $x->getHigh, 4, " getHigh is 4";
+ is $x->getLow, 1, " getLow is 1";
+
+ title "U64 - equal" ;
+
+ $x = new U64(0, 1);
+ is $x->getHigh, 0, " getHigh is 0";
+ is $x->getLow, 1, " getLow is 1";
+
+ $y = new U64(0, 1);
+ is $x->getHigh, 0, " getHigh is 0";
+ is $x->getLow, 1, " getLow is 1";
+
+ my $z = new U64(0, 2);
+ is $x->getHigh, 0, " getHigh is 0";
+ is $x->getLow, 1, " getLow is 1";
+
+ ok $x->equal($y), " equal";
+ ok !$x->equal($z), " ! equal";
+
+ title "U64 - pack_V" ;
+}
CHANGES
-------
+ 2.000_13 20 June 2006
+
+ * Preliminary support for reading zip files with zip64 members.
+
2.000_12 3 May 2006
* Moved the code for creating and parsing the gzip extra field into
IO::Compress::Zlib
- Version 2.000_12
+ Version 2.000_13
- 17 May 2006
+ 20 June 2006
Copyright (c) 2005-2006 Paul Marquess. All rights reserved.
use Compress::Raw::Zlib qw(Z_OK Z_FINISH MAX_WBITS) ;
our ($VERSION);
-$VERSION = '2.000_12';
+$VERSION = '2.000_13';
sub mkCompObject
{
use IO::Compress::Base::Common qw(:Status);
our ($VERSION);
-$VERSION = '2.000_12';
+$VERSION = '2.000_13';
sub mkCompObject
{
$self->{CompSize} += length ${ $_[0] } ;
$self->{UnCompSize} = $self->{CompSize} ;
- ${ $_[1] } .= ${ $_[0] };
+ if ( ref $_[1] )
+ { ${ $_[1] } .= ${ $_[0] } }
+ else
+ { $_[1] .= ${ $_[0] } }
}
return STATUS_OK ;
our ($VERSION, @ISA, @EXPORT_OK, %EXPORT_TAGS, $DeflateError);
-$VERSION = '2.000_12';
+$VERSION = '2.000_13';
$DeflateError = '';
@ISA = qw(Exporter IO::Compress::RawDeflate);
=over 5
-=item AutoClose =E<gt> 0|1
+=item C<< AutoClose => 0|1 >>
This option applies to any input or output data streams to
C<deflate> that are filehandles.
This parameter defaults to 0.
-
-=item BinModeIn =E<gt> 0|1
+=item C<< BinModeIn => 0|1 >>
When reading from a file or filehandle, set C<binmode> before reading.
-=item -Append =E<gt> 0|1
+=item C<< Append => 0|1 >>
TODO
=over 5
-=item AutoClose =E<gt> 0|1
+=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
This parameter defaults to 0.
-=item Append =E<gt> 0|1
+=item C<< Append => 0|1 >>
Opens C<$output> in append mode.
-=item Merge =E<gt> 0|1
+=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
-=item -Strict =E<gt> 0|1
+=item C<< Strict => 0|1 >>
Closes the current compressed data stream and starts a new one.
-OPTS consists of the following sub-set of the the options that are
-available when creating the C<$z> object,
-
-=over 5
-
-
-
-=item * Level
-
+OPTS consists of any of the the options that are available when creating
+the C<$z> object.
-
-=back
+See the L</"Constructor Options"> section for more details.
=head2 deflateParams
+
+
+
+
+
=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::Lzop>, L<IO::Uncompress::UnLzop>, L<IO::Uncompress::AnyInflate>, L<IO::Uncompress::AnyUncompress>
our ($VERSION, @ISA, @EXPORT_OK, %EXPORT_TAGS, $GzipError);
-$VERSION = '2.000_12';
+$VERSION = '2.000_13';
$GzipError = '' ;
@ISA = qw(Exporter IO::Compress::RawDeflate);
{
my $self = shift ;
return pack("V V", *$self->{Compress}->crc32(),
- *$self->{UnCompSize_32bit});
+ *$self->{UnCompSize}->get32bit());
}
sub getInverseClass
=over 5
-=item AutoClose =E<gt> 0|1
+=item C<< AutoClose => 0|1 >>
This option applies to any input or output data streams to
C<gzip> that are filehandles.
This parameter defaults to 0.
-
-=item BinModeIn =E<gt> 0|1
+=item C<< BinModeIn => 0|1 >>
When reading from a file or filehandle, set C<binmode> before reading.
-=item -Append =E<gt> 0|1
+=item C<< Append => 0|1 >>
TODO
=over 5
-=item AutoClose =E<gt> 0|1
+=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
This parameter defaults to 0.
-=item Append =E<gt> 0|1
+=item C<< Append => 0|1 >>
Opens C<$output> in append mode.
-=item Merge =E<gt> 0|1
+=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
-=item -Minimal =E<gt> 0|1
+=item C<< Minimal => 0|1 >>
If specified, this option will force the creation of the smallest possible
compliant gzip header (which is exactly 10 bytes long) as defined in
This parameter defaults to 0.
-=item -Comment =E<gt> $comment
+=item C<< Comment => $comment >>
Stores the contents of C<$comment> in the COMMENT field in
the gzip header.
character except NULL. If any null characters are present, the field
will be truncated at the first NULL.
-=item -Name =E<gt> $string
+=item C<< Name => $string >>
Stores the contents of C<$string> in the gzip NAME header field. If
C<Name> is not specified, no gzip NAME field will be created.
except NULL. If any null characters are present, the field will be
truncated at the first NULL.
-=item -Time =E<gt> $number
+=item C<< Time => $number >>
Sets the MTIME field in the gzip header to $number.
This field defaults to the time the C<IO::Compress::Gzip> object was created
if this option is not specified.
-=item -TextFlag =E<gt> 0|1
+=item C<< TextFlag => 0|1 >>
This parameter controls the setting of the FLG.FTEXT bit in the gzip
header. It is used to signal that the data stored in the gzip file/buffer
The default is 0.
-=item -HeaderCRC =E<gt> 0|1
+=item C<< HeaderCRC => 0|1 >>
When true this parameter will set the FLG.FHCRC bit to 1 in the gzip header
and set the CRC16 header field to the CRC of the complete gzip header
This parameter defaults to 0.
-=item -OS_Code =E<gt> $value
+=item C<< OS_Code => $value >>
Stores C<$value> in the gzip OS header field. A number between 0 and 255 is
valid.
System this module was built on. The value 3 is used as a catch-all for all
Unix variants and unknown Operating Systems.
-=item -ExtraField =E<gt> $data
+=item C<< ExtraField => $data >>
This parameter allows additional metadata to be stored in the ExtraField in
the gzip header. An RFC 1952 compliant ExtraField consists of zero or more
The maximum size of the Extra Field 65535 bytes.
-=item -ExtraFlags =E<gt> $value
+=item C<< ExtraFlags => $value >>
Sets the XFL byte in the gzip header to C<$value>.
If this option is not present, the value stored in XFL field will be
determined by the setting of the C<Level> option.
-If C<Level =E<gt> Z_BEST_SPEED> has been specified then XFL is set to 2.
-If C<Level =E<gt> Z_BEST_COMPRESSION> has been specified then XFL is set to 4.
+If C<< Level => Z_BEST_SPEED >> has been specified then XFL is set to 2.
+If C<< Level => Z_BEST_COMPRESSION >> has been specified then XFL is set to 4.
Otherwise XFL is set to 0.
-=item -Strict =E<gt> 0|1
+=item C<< Strict => 0|1 >>
Closes the current compressed data stream and starts a new one.
-OPTS consists of the following sub-set of the the options that are
-available when creating the C<$z> object,
-
-=over 5
-
-
-
-=item * Level
-
+OPTS consists of any of the the options that are available when creating
+the C<$z> object.
-
-=back
+See the L</"Constructor Options"> section for more details.
=head2 deflateParams
+
+
+
+
+
=head1 SEE ALSO
L<Compress::Zlib>, 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::Lzop>, L<IO::Uncompress::UnLzop>, L<IO::Uncompress::AnyInflate>, L<IO::Uncompress::AnyUncompress>
our ($VERSION, @ISA, @EXPORT, %GZIP_OS_Names);
our ($GZIP_FNAME_INVALID_CHAR_RE, $GZIP_FCOMMENT_INVALID_CHAR_RE);
-$VERSION = '2.000_12';
+$VERSION = '2.000_13';
@ISA = qw(Exporter);
our ($VERSION, @ISA, @EXPORT_OK, %DEFLATE_CONSTANTS, %EXPORT_TAGS, $RawDeflateError);
-$VERSION = '2.000_12';
+$VERSION = '2.000_13';
$RawDeflateError = '';
@ISA = qw(Exporter IO::Compress::Base);
my $def = *$self->{Compress} = $inf->createDeflate();
*$self->{Header} = *$inf->{Info}{Header};
- *$self->{UnCompSize_32bit} =
- *$self->{BytesWritten} = *$inf->{UnCompSize_32bit} ;
+ *$self->{UnCompSize} = *$inf->{UnCompSize}->clone();
+ *$self->{CompSize} = *$inf->{CompSize}->clone();
+ # TODO -- fix this
+ #*$self->{CompSize} = new U64(0, *$self->{UnCompSize_32bit});
if ( $outType eq 'buffer')
=over 5
-=item AutoClose =E<gt> 0|1
+=item C<< AutoClose => 0|1 >>
This option applies to any input or output data streams to
C<rawdeflate> that are filehandles.
This parameter defaults to 0.
-
-=item BinModeIn =E<gt> 0|1
+=item C<< BinModeIn => 0|1 >>
When reading from a file or filehandle, set C<binmode> before reading.
-=item -Append =E<gt> 0|1
+=item C<< Append => 0|1 >>
TODO
=over 5
-=item AutoClose =E<gt> 0|1
+=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
This parameter defaults to 0.
-=item Append =E<gt> 0|1
+=item C<< Append => 0|1 >>
Opens C<$output> in append mode.
-=item Merge =E<gt> 0|1
+=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
-=item -Strict =E<gt> 0|1
+=item C<< Strict => 0|1 >>
Closes the current compressed data stream and starts a new one.
-OPTS consists of the following sub-set of the the options that are
-available when creating the C<$z> object,
-
-=over 5
-
-
-
-=item * Level
-
+OPTS consists of any of the the options that are available when creating
+the C<$z> object.
-
-=back
+See the L</"Constructor Options"> section for more details.
=head2 deflateParams
+
+
+
+
+
=head1 SEE ALSO
L<Compress::Zlib>, L<IO::Compress::Gzip>, L<IO::Uncompress::Gunzip>, L<IO::Compress::Deflate>, L<IO::Uncompress::Inflate>, L<IO::Uncompress::RawInflate>, L<IO::Compress::Bzip2>, L<IO::Uncompress::Bunzip2>, L<IO::Compress::Lzop>, L<IO::Uncompress::UnLzop>, L<IO::Uncompress::AnyInflate>, L<IO::Uncompress::AnyUncompress>
use IO::Compress::RawDeflate;
use IO::Compress::Adapter::Deflate;
use IO::Compress::Adapter::Identity;
+use IO::Compress::Zlib::Extra;
use IO::Compress::Zip::Constants;
our ($VERSION, @ISA, @EXPORT_OK, %EXPORT_TAGS, $ZipError);
-$VERSION = '2.000_12';
+$VERSION = '2.000_13';
$ZipError = '';
@ISA = qw(Exporter IO::Compress::RawDeflate);
if ! defined $obj;
if (! defined *$self->{ZipData}{StartOffset}) {
- *$self->{ZipData}{StartOffset} = *$self->{ZipData}{Offset} = 0;
+ *$self->{ZipData}{StartOffset} = 0;
+ *$self->{ZipData}{Offset} = new U64 ;
}
return $obj;
my $self = shift;
my $param = shift ;
- *$self->{ZipData}{StartOffset} = *$self->{ZipData}{Offset} ;
+ *$self->{ZipData}{StartOffset} = *$self->{ZipData}{Offset}->get32bit() ;
my $filename = '';
$filename = $param->value('Name') || '';
my $extra = '';
my $ctlExtra = '';
+ my $empty = 0;
+
+ if (*$self->{ZipData}{Zip64}) {
+ $empty = 0xFFFF;
+
+ my $x = '';
+ $x .= pack "V V", 0, 0 ; # uncompressedLength
+ $x .= pack "V V", 0, 0 ; # compressedLength
+ $x .= *$self->{ZipData}{Offset}->getPacked_V64() ; # offset to local hdr
+ #$x .= pack "V ", 0 ; # disk no
+
+ $x = IO::Compress::Zlib::Extra::mkSubField(ZIP_EXTRA_ID_ZIP64, $x);
+ $extra .= $x;
+ $ctlExtra .= $x;
+ }
if (! $param->value('Minimal')) {
if (defined $param->value('exTime'))
if defined $param->value('ExtraFieldCentral');
}
+
my $extAttr = 0;
$extAttr = $param->value('Mode') << 16
if defined $param->value('Mode') ;
my $method = *$self->{ZipData}{Method} ;
- # deflate is 20
- # bzip2 is 46
- my $madeBy = ($param->value('OS_Code') << 8) +
- $ZIP_CM_MIN_VERSIONS{$method};
- my $extract = $ZIP_CM_MIN_VERSIONS{$method};
+ my $version = $ZIP_CM_MIN_VERSIONS{$method};
+ $version = ZIP64_MIN_VERSION
+ if ZIP64_MIN_VERSION > $version && *$self->{ZipData}{Zip64};
+ my $madeBy = ($param->value('OS_Code') << 8) + $version;
+ my $extract = $version;
+
+ *$self->{ZipData}{Version} = $version;
+ *$self->{ZipData}{MadeBy} = $madeBy;
my $ifa = 0;
$ifa |= ZIP_IFA_TEXT_MASK
$hdr .= pack 'v', $method ; # compression method (deflate)
$hdr .= pack 'V', $time ; # last mod date/time
$hdr .= pack 'V', 0 ; # crc32 - 0 when streaming
- $hdr .= pack 'V', 0 ; # compressed length - 0 when streaming
- $hdr .= pack 'V', 0 ; # uncompressed length - 0 when streaming
+ $hdr .= pack 'V', $empty ; # compressed length - 0 when streaming
+ $hdr .= pack 'V', $empty ; # uncompressed length - 0 when streaming
$hdr .= pack 'v', length $filename ; # filename length
$hdr .= pack 'v', length $extra ; # extra length
$ctl .= pack 'v', $method ; # compression method (deflate)
$ctl .= pack 'V', $time ; # last mod date/time
$ctl .= pack 'V', 0 ; # crc32
- $ctl .= pack 'V', 0 ; # compressed length
- $ctl .= pack 'V', 0 ; # uncompressed length
+ $ctl .= pack 'V', $empty ; # compressed length
+ $ctl .= pack 'V', $empty ; # uncompressed length
$ctl .= pack 'v', length $filename ; # filename length
$ctl .= pack 'v', length $ctlExtra ; # extra length
$ctl .= pack 'v', length $comment ; # file comment length
$ctl .= pack 'v', 0 ; # disk number start
$ctl .= pack 'v', $ifa ; # internal file attributes
$ctl .= pack 'V', $extAttr ; # external file attributes
- $ctl .= pack 'V', *$self->{ZipData}{Offset} ; # offset to local header
+ if (! *$self->{ZipData}{Zip64}) {
+ $ctl .= pack 'V', *$self->{ZipData}{Offset}->get32bit() ; # offset to local header
+ }
+ else {
+ $ctl .= pack 'V', $empty ; # offset to local header
+ }
$ctl .= $filename ;
+ *$self->{ZipData}{StartOffset64} = 4 + length $ctl;
$ctl .= $ctlExtra ;
$ctl .= $comment ;
- *$self->{ZipData}{Offset} += length $hdr ;
+ *$self->{ZipData}{Offset}->add(length $hdr) ;
*$self->{ZipData}{CentralHeader} = $ctl;
my $crc32 ;
if (*$self->{ZipData}{Method} == ZIP_CM_DEFLATE) {
- $crc32 = *$self->{Compress}->crc32();
+ $crc32 = pack "V", *$self->{Compress}->crc32();
}
else {
- $crc32 = *$self->{ZipData}{CRC32};
+ $crc32 = pack "V", *$self->{ZipData}{CRC32};
}
- my $compressedBytes = *$self->{Compress}->compressedBytes();
- my $uncompressedBytes = *$self->{Compress}->uncompressedBytes();
+ my $ctl = *$self->{ZipData}{CentralHeader} ;
+
+ my $sizes ;
+ if (! *$self->{ZipData}{Zip64}) {
+ $sizes .= *$self->{CompSize}->getPacked_V32() ; # Compressed size
+ $sizes .= *$self->{UnCompSize}->getPacked_V32() ; # Uncompressed size
+ }
+ else {
+ $sizes .= *$self->{CompSize}->getPacked_V64() ; # Compressed size
+ $sizes .= *$self->{UnCompSize}->getPacked_V64() ; # Uncompressed size
+ }
+
+ my $data = $crc32 . $sizes ;
- my $data ;
- $data .= pack "V", $crc32 ; # CRC32
- $data .= pack "V", $compressedBytes ; # Compressed Size
- $data .= pack "V", $uncompressedBytes; # Uncompressed Size
my $hdr = '';
or return undef;
}
- my $ctl = *$self->{ZipData}{CentralHeader} ;
- substr($ctl, 16, 12) = $data ;
+ if (! *$self->{ZipData}{Zip64})
+ { substr($ctl, 16, length $data) = $data }
+ else {
+ substr($ctl, 16, length $crc32) = $crc32 ;
+ my $s = *$self->{UnCompSize}->getPacked_V64() ; # Uncompressed size
+ $s .= *$self->{CompSize}->getPacked_V64() ; # Compressed size
+ substr($ctl, *$self->{ZipData}{StartOffset64}, length $s) = $s ;
+ }
- *$self->{ZipData}{Offset} += length($hdr) + $compressedBytes;
+ *$self->{ZipData}{Offset}->add(length($hdr));
+ *$self->{ZipData}{Offset}->add( *$self->{CompSize} );
push @{ *$self->{ZipData}{CentralDir} }, $ctl ;
return $hdr;
my $comment = '';
$comment = *$self->{ZipData}{ZipComment} ;
+ my $cd_offset = *$self->{ZipData}{Offset}->get32bit() ; # offset to start central dir
+
my $entries = @{ *$self->{ZipData}{CentralDir} };
my $cd = join '', @{ *$self->{ZipData}{CentralDir} };
+ my $cd_len = length $cd ;
+
+ my $z64e = '';
+
+ if ( *$self->{ZipData}{Zip64} ) {
+
+ my $v = *$self->{ZipData}{Version} ;
+ my $mb = *$self->{ZipData}{MadeBy} ;
+ $z64e .= pack 'v', $v ; # Version made by
+ $z64e .= pack 'v', $mb ; # Version to extract
+ $z64e .= pack 'V', 0 ; # number of disk
+ $z64e .= pack 'V', 0 ; # number of disk with central dir
+ $z64e .= U64::pack_V64 $entries ; # entries in central dir on this disk
+ $z64e .= U64::pack_V64 $entries ; # entries in central dir
+ $z64e .= U64::pack_V64 $cd_len ; # size of central dir
+ $z64e .= *$self->{ZipData}{Offset}->getPacked_V64() ; # offset to start central dir
+
+ $z64e = pack("V", ZIP64_END_CENTRAL_REC_HDR_SIG) # signature
+ . U64::pack_V64(length $z64e)
+ . $z64e ;
+
+ *$self->{ZipData}{Offset}->add(length $cd) ;
+
+ $z64e .= pack "V", ZIP64_END_CENTRAL_LOC_HDR_SIG; # signature
+ $z64e .= pack 'V', 0 ; # number of disk with central dir
+ $z64e .= *$self->{ZipData}{Offset}->getPacked_V64() ; # offset to end zip64 central dir
+ $z64e .= pack 'V', 1 ; # Total number of disks
+
+ # TODO - fix these when info-zip 3 is fixed.
+ #$cd_len =
+ #$cd_offset =
+ $entries = 0xFFFF ;
+ }
my $ecd = '';
$ecd .= pack "V", ZIP_END_CENTRAL_HDR_SIG ; # signature
$ecd .= pack 'v', 0 ; # number of disk
- $ecd .= pack 'v', 0 ; # number if disk with central dir
+ $ecd .= pack 'v', 0 ; # number of disk with central dir
$ecd .= pack 'v', $entries ; # entries in central dir on this disk
$ecd .= pack 'v', $entries ; # entries in central dir
- $ecd .= pack 'V', length $cd ; # size of central dir
- $ecd .= pack 'V', *$self->{ZipData}{Offset} ; # offset to start central dir
+ $ecd .= pack 'V', $cd_len ; # size of central dir
+ $ecd .= pack 'V', $cd_offset ; # offset to start central dir
$ecd .= pack 'v', length $comment ; # zipfile comment length
$ecd .= $comment;
- return $cd . $ecd ;
+ return $cd . $z64e . $ecd ;
}
sub ckParams
$got->value("CTime", $timeRef->[2]);
}
+ *$self->{ZipData}{Zip64} = $got->value('Zip64');
*$self->{ZipData}{Stream} = $got->value('Stream');
+ return $self->saveErrorString(undef, "Zip64 only supported if Stream enabled")
+ if *$self->{ZipData}{Zip64} && ! *$self->{ZipData}{Stream} ;
+
my $method = $got->value('Method');
return $self->saveErrorString(undef, "Unknown Method '$method'")
if ! defined $ZIP_CM_MIN_VERSIONS{$method};
# # Zip header fields
'Minimal' => [0, 1, Parse_boolean, 0],
+ 'Zip64' => [0, 1, Parse_boolean, 0],
'Comment' => [0, 1, Parse_any, ''],
'ZipComment'=> [0, 1, Parse_any, ''],
'Name' => [0, 1, Parse_any, ''],
=over 5
-=item AutoClose =E<gt> 0|1
+=item C<< AutoClose => 0|1 >>
This option applies to any input or output data streams to
C<zip> that are filehandles.
This parameter defaults to 0.
-
-=item BinModeIn =E<gt> 0|1
+=item C<< BinModeIn => 0|1 >>
When reading from a file or filehandle, set C<binmode> before reading.
-=item -Append =E<gt> 0|1
+=item C<< Append => 0|1 >>
TODO
=over 5
-=item AutoClose =E<gt> 0|1
+=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
This parameter defaults to 0.
-=item Append =E<gt> 0|1
+=item C<< Append => 0|1 >>
Opens C<$output> in append mode.
-=item -Name =E<gt> $string
+=item C<< Name => $string >>
Stores the contents of C<$string> in the zip filename header field. If
C<Name> is not specified, no zip filename field will be created.
-=item -Time =E<gt> $number
+=item C<< Time => $number >>
Sets the last modified time field in the zip header to $number.
This field defaults to the time the C<IO::Compress::Zip> object was created
if this option is not specified.
-=item -exTime =E<gt> [$atime, $mtime, $ctime]
+=item C<< exTime => [$atime, $mtime, $ctime] >>
This option expects an array reference with exactly three elements:
C<$atime>, C<mtime> and C<$ctime>. These correspond to the last access
By default no extended time field is created.
-=item -Comment =E<gt> $comment
+=item C<< Comment => $comment >>
Stores the contents of C<$comment> in the Central File Header of
the zip file.
By default, no comment field is written to the zip file.
-=item -ZipComment =E<gt> $comment
+=item C<< ZipComment => $comment >>
Stores the contents of C<$comment> in the End of Central Directory record
of the zip file.
By default, no comment field is written to the zip file.
-=item Method =E<gt> $method
+=item C<< Method => $method >>
Controls which compression method is used. At present three compression
methods are supported, namely Store (no compression at all), Deflate and
The default method is ZIP_CM_DEFLATE.
-=item Stream =E<gt> 0|1
+=item C<< Stream => 0|1 >>
This option controls whether the zip file/buffer output is created in
streaming mode.
The default is 1.
-=item -TextFlag =E<gt> 0|1
+=item C<< TextFlag => 0|1 >>
This parameter controls the setting of a bit in the zip central header. It
is used to signal that the data stored in the zip file/buffer is probably
The default is 0.
-=item ExtraFieldLocal =E<gt> $data
-=item ExtraFieldCentral =E<gt> $data
+=item C<< ExtraFieldLocal => $data >>
+=item C<< ExtraFieldCentral => $data >>
These options allows additional metadata to be stored in the local and
central headers in the zip file/buffer.
The maximum size of an extra field 65535 bytes.
-=item Minimal =E<gt> 1|0
+=item C<< Minimal => 1|0 >>
If specified, this option will disable the creation of all extended fields
in the zip local and central headers.
This parameter defaults to 0.
-=item BlockSize100K =E<gt> number
+=item C<< BlockSize100K => number >>
Specify the number of 100K blocks bzip2 uses during compression.
The default is 1.
-=item WorkFactor =E<gt> number
+=item C<< WorkFactor => number >>
Specifies how much effort bzip2 should take before resorting to a slower
fallback compression algorithm.
-=item -Strict =E<gt> 0|1
+=item C<< Strict => 0|1 >>
Closes the current compressed data stream and starts a new one.
-OPTS consists of the following sub-set of the the options that are
-available when creating the C<$z> object,
-
-=over 5
-
-
-
-=item * Level
+OPTS consists of any of the the options that are available when creating
+the C<$z> object.
-
-
-=back
+See the L</"Constructor Options"> section for more details.
=head2 deflateParams
+
+
+
+
+
=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::Lzop>, L<IO::Uncompress::UnLzop>, L<IO::Uncompress::AnyInflate>, L<IO::Uncompress::AnyUncompress>
our ($VERSION, @ISA, @EXPORT, %ZIP_CM_MIN_VERSIONS);
-$VERSION = '2.000_12';
+$VERSION = '2.000_13';
@ISA = qw(Exporter);
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_STREAMING_MASK
+ ZIP_EXTRA_ID_ZIP64
ZIP_EXTRA_ID_EXT_TIMESTAMP
ZIP_EXTRA_ID_INFO_ZIP_UNIX
ZIP_IFA_TEXT_MASK
%ZIP_CM_MIN_VERSIONS
+ ZIP64_MIN_VERSION
);
use constant ZIP_DATA_HDR_SIG => 0x08074b50;
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;
# 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_UNIX => "Ux";
+use constant ZIP64_MIN_VERSION => 45;
+
%ZIP_CM_MIN_VERSIONS = (
ZIP_CM_STORE() => 20,
ZIP_CM_DEFLATE() => 20,
our ($VERSION, @ISA, @EXPORT);
-$VERSION = '2.000_12';
+$VERSION = '2.000_13';
@ISA = qw(Exporter);
our ($VERSION, @ISA, @EXPORT_OK, %EXPORT_TAGS);
-$VERSION = '2.000_12';
+$VERSION = '2.000_13';
use IO::Compress::Gzip::Constants;
return $bad if $bad ;
$out .= mkSubField(@$pair);
- #$out .= $pair->[0] . pack("v", length $pair->[1]) .
- # $pair->[1] ;
}
}
else {
return $bad if $bad ;
$out .= mkSubField($data->[$ix], $data->[$ix+1]);
- #$out .= $data->[$ix] . pack("v", length $data->[$ix+1]) .
- # $data->[$ix+1] ;
}
}
}
return $bad if $bad ;
$out .= mkSubField($id, $info);
- #$out .= $id . pack("v", length $info) . $info ;
}
}
else {
our ($VERSION);
-$VERSION = '2.000_12';
+$VERSION = '2.000_13';
use Compress::Raw::Zlib ();
$self->{CompSize} = 0;
$self->{UnCompSize} = 0;
- $self->{CRC32} = Compress::Zlib::crc32('');
- $self->{ADLER32} = Compress::Zlib::adler32('');
+ $self->{CRC32} = Compress::Raw::Zlib::crc32('');
+ $self->{ADLER32} = Compress::Raw::Zlib::adler32('');
return STATUS_OK ;
}
use Compress::Raw::Zlib qw(Z_OK Z_DATA_ERROR Z_STREAM_END Z_FINISH MAX_WBITS);
our ($VERSION);
-$VERSION = '2.000_12';
+$VERSION = '2.000_13';
our ($VERSION, @ISA, @EXPORT_OK, %EXPORT_TAGS, $AnyInflateError);
-$VERSION = '2.000_12';
+$VERSION = '2.000_13';
$AnyInflateError = '';
@ISA = qw( Exporter IO::Uncompress::Base );
$status = $z->inflateSync()
- $z->trailingData()
+ $data = $z->trailingData()
+ $status = $z->nextStream()
$data = $z->getHeaderInfo()
$z->tell()
$z->seek($position, $whence)
=over 5
-=item AutoClose =E<gt> 0|1
+=item C<< AutoClose => 0|1 >>
This option applies to any input or output data streams to
C<anyinflate> that are filehandles.
This parameter defaults to 0.
-
-=item BinModeOut =E<gt> 0|1
+=item C<< BinModeOut => 0|1 >>
When writing to a file or filehandle, set C<binmode> before writing to the
file.
-=item -Append =E<gt> 0|1
+=item C<< Append => 0|1 >>
TODO
-=item -MultiStream =E<gt> 0|1
+=item C<< MultiStream => 0|1 >>
-Creates a new stream after each file.
+If the input file/buffer contains multiple compressed data streams, this
+option will uncompress the whole lot as a single data stream.
-Defaults to 1.
+Defaults to 0.
=over 5
-=item -AutoClose =E<gt> 0|1
+=item C<< AutoClose => 0|1 >>
This option is only valid when the C<$input> parameter is a filehandle. If
specified, and the value is true, it will result in the file being closed once
This parameter defaults to 0.
-=item -MultiStream =E<gt> 0|1
+=item C<< MultiStream => 0|1 >>
This parameter defaults to 0.
-
-=item -Prime =E<gt> $string
+=item C<< Prime => $string >>
This option will uncompress the contents of C<$string> before processing the
input file/buffer.
case, the uncompression can be I<primed> with these bytes using this
option.
-=item -Transparent =E<gt> 0|1
+=item C<< Transparent => 0|1 >>
If this option is set and the input file or buffer is not compressed data,
the module will allow reading of it anyway.
This option defaults to 1.
-=item -BlockSize =E<gt> $num
+=item C<< BlockSize => $num >>
When reading the compressed input data, IO::Uncompress::AnyInflate will read it in
blocks of C<$num> bytes.
This option defaults to 4096.
-=item -InputLength =E<gt> $size
+=item C<< InputLength => $size >>
When present this option will limit the number of compressed bytes read
from the input file/buffer to C<$size>. This option can be used in the
This option defaults to off.
-=item -Append =E<gt> 0|1
+=item C<< Append => 0|1 >>
This option controls what the C<read> method does with uncompressed data.
Defaults to 0.
-=item -Strict =E<gt> 0|1
+=item C<< Strict => 0|1 >>
-=item -ParseExtra =E<gt> 0|1
+=item C<< ParseExtra => 0|1 >>
If the gzip FEXTRA header field is present and this option is set, it will
force the module to check that it conforms to the sub-field structure as
+=head2 nextStream
+
+Usage is
+
+ my $status = $z->nextStream();
+
+Skips to the next compressed data stream in the input file/buffer. If a new
+compressed data stream is found, the eof marker will be cleared, C<$.> will
+be reset to 0.
+
+Returns 1 if a new stream was found, 0 if none was found, and -1 if an
+error was encountered.
+
+=head2 trailingData
+
+Usage is
+
+ my $data = $z->trailingData();
+
+Returns any data that
+
=head1 Importing
No symbolic constants are required by this IO::Uncompress::AnyInflate at present.
$GunzipError = '';
-$VERSION = '2.000_12';
+$VERSION = '2.000_13';
sub new
{
return $self->TrailerError("CRC mismatch")
if $CRC32 != *$self->{Uncomp}->crc32() ;
- my $exp_isize = *$self->{Uncomp}->uncompressedBytes();
+ my $exp_isize = *$self->{UnCompSize}->get32bit();
return $self->TrailerError("ISIZE mismatch. Got $ISIZE"
. ", expected $exp_isize")
if $ISIZE != $exp_isize ;
$status = $z->inflateSync()
- $z->trailingData()
+ $data = $z->trailingData()
+ $status = $z->nextStream()
$data = $z->getHeaderInfo()
$z->tell()
$z->seek($position, $whence)
=over 5
-=item AutoClose =E<gt> 0|1
+=item C<< AutoClose => 0|1 >>
This option applies to any input or output data streams to
C<gunzip> that are filehandles.
This parameter defaults to 0.
-
-=item BinModeOut =E<gt> 0|1
+=item C<< BinModeOut => 0|1 >>
When writing to a file or filehandle, set C<binmode> before writing to the
file.
-=item -Append =E<gt> 0|1
+=item C<< Append => 0|1 >>
TODO
-=item -MultiStream =E<gt> 0|1
+=item C<< MultiStream => 0|1 >>
-Creates a new stream after each file.
+If the input file/buffer contains multiple compressed data streams, this
+option will uncompress the whole lot as a single data stream.
-Defaults to 1.
+Defaults to 0.
=over 5
-=item -AutoClose =E<gt> 0|1
+=item C<< AutoClose => 0|1 >>
This option is only valid when the C<$input> parameter is a filehandle. If
specified, and the value is true, it will result in the file being closed once
This parameter defaults to 0.
-=item -MultiStream =E<gt> 0|1
+=item C<< MultiStream => 0|1 >>
This parameter defaults to 0.
-
-=item -Prime =E<gt> $string
+=item C<< Prime => $string >>
This option will uncompress the contents of C<$string> before processing the
input file/buffer.
case, the uncompression can be I<primed> with these bytes using this
option.
-=item -Transparent =E<gt> 0|1
+=item C<< Transparent => 0|1 >>
If this option is set and the input file or buffer is not compressed data,
the module will allow reading of it anyway.
This option defaults to 1.
-=item -BlockSize =E<gt> $num
+=item C<< BlockSize => $num >>
When reading the compressed input data, IO::Uncompress::Gunzip will read it in
blocks of C<$num> bytes.
This option defaults to 4096.
-=item -InputLength =E<gt> $size
+=item C<< InputLength => $size >>
When present this option will limit the number of compressed bytes read
from the input file/buffer to C<$size>. This option can be used in the
This option defaults to off.
-=item -Append =E<gt> 0|1
+=item C<< Append => 0|1 >>
This option controls what the C<read> method does with uncompressed data.
Defaults to 0.
-=item -Strict =E<gt> 0|1
+=item C<< Strict => 0|1 >>
-=item -ParseExtra =E<gt> 0|1
+=item C<< ParseExtra => 0|1 >>
If the gzip FEXTRA header field is present and this option is set, it will
force the module to check that it conforms to the sub-field structure as
+=head2 nextStream
+
+Usage is
+
+ my $status = $z->nextStream();
+
+Skips to the next compressed data stream in the input file/buffer. If a new
+compressed data stream is found, the eof marker will be cleared, C<$.> will
+be reset to 0.
+
+Returns 1 if a new stream was found, 0 if none was found, and -1 if an
+error was encountered.
+
+=head2 trailingData
+
+Usage is
+
+ my $data = $z->trailingData();
+
+Returns any data that
+
=head1 Importing
No symbolic constants are required by this IO::Uncompress::Gunzip at present.
require Exporter ;
our ($VERSION, @ISA, @EXPORT_OK, %EXPORT_TAGS, $InflateError);
-$VERSION = '2.000_12';
+$VERSION = '2.000_13';
$InflateError = '';
@ISA = qw( Exporter IO::Uncompress::RawInflate );
$status = $z->inflateSync()
- $z->trailingData()
+ $data = $z->trailingData()
+ $status = $z->nextStream()
$data = $z->getHeaderInfo()
$z->tell()
$z->seek($position, $whence)
=over 5
-=item AutoClose =E<gt> 0|1
+=item C<< AutoClose => 0|1 >>
This option applies to any input or output data streams to
C<inflate> that are filehandles.
This parameter defaults to 0.
-
-=item BinModeOut =E<gt> 0|1
+=item C<< BinModeOut => 0|1 >>
When writing to a file or filehandle, set C<binmode> before writing to the
file.
-=item -Append =E<gt> 0|1
+=item C<< Append => 0|1 >>
TODO
-=item -MultiStream =E<gt> 0|1
+=item C<< MultiStream => 0|1 >>
-Creates a new stream after each file.
+If the input file/buffer contains multiple compressed data streams, this
+option will uncompress the whole lot as a single data stream.
-Defaults to 1.
+Defaults to 0.
=over 5
-=item -AutoClose =E<gt> 0|1
+=item C<< AutoClose => 0|1 >>
This option is only valid when the C<$input> parameter is a filehandle. If
specified, and the value is true, it will result in the file being closed once
This parameter defaults to 0.
-=item -MultiStream =E<gt> 0|1
+=item C<< MultiStream => 0|1 >>
This parameter defaults to 0.
-
-=item -Prime =E<gt> $string
+=item C<< Prime => $string >>
This option will uncompress the contents of C<$string> before processing the
input file/buffer.
case, the uncompression can be I<primed> with these bytes using this
option.
-=item -Transparent =E<gt> 0|1
+=item C<< Transparent => 0|1 >>
If this option is set and the input file or buffer is not compressed data,
the module will allow reading of it anyway.
This option defaults to 1.
-=item -BlockSize =E<gt> $num
+=item C<< BlockSize => $num >>
When reading the compressed input data, IO::Uncompress::Inflate will read it in
blocks of C<$num> bytes.
This option defaults to 4096.
-=item -InputLength =E<gt> $size
+=item C<< InputLength => $size >>
When present this option will limit the number of compressed bytes read
from the input file/buffer to C<$size>. This option can be used in the
This option defaults to off.
-=item -Append =E<gt> 0|1
+=item C<< Append => 0|1 >>
This option controls what the C<read> method does with uncompressed data.
Defaults to 0.
-=item -Strict =E<gt> 0|1
+=item C<< Strict => 0|1 >>
+=head2 nextStream
+
+Usage is
+
+ my $status = $z->nextStream();
+
+Skips to the next compressed data stream in the input file/buffer. If a new
+compressed data stream is found, the eof marker will be cleared, C<$.> will
+be reset to 0.
+
+Returns 1 if a new stream was found, 0 if none was found, and -1 if an
+error was encountered.
+
+=head2 trailingData
+
+Usage is
+
+ my $data = $z->trailingData();
+
+Returns any data that
+
=head1 Importing
No symbolic constants are required by this IO::Uncompress::Inflate at present.
require Exporter ;
our ($VERSION, @ISA, @EXPORT_OK, %EXPORT_TAGS, %DEFLATE_CONSTANTS, $RawInflateError);
-$VERSION = '2.000_12';
+$VERSION = '2.000_13';
$RawInflateError = '';
@ISA = qw( Exporter IO::Uncompress::Base );
return $self->saveErrorString(undef, *$self->{Uncomp}{Error}, STATUS_ERROR)
if $status == STATUS_ERROR;
- my $buf_len = *$self->{Uncomp}->uncompressedBytes();
+ #my $buf_len = *$self->{Uncomp}->uncompressedBytes();
+ my $buf_len = length $buffer;
if ($status == STATUS_ENDSTREAM) {
if (*$self->{MultiStream}
$status = $z->inflateSync()
- $z->trailingData()
+ $data = $z->trailingData()
+ $status = $z->nextStream()
$data = $z->getHeaderInfo()
$z->tell()
$z->seek($position, $whence)
=over 5
-=item AutoClose =E<gt> 0|1
+=item C<< AutoClose => 0|1 >>
This option applies to any input or output data streams to
C<rawinflate> that are filehandles.
This parameter defaults to 0.
-
-=item BinModeOut =E<gt> 0|1
+=item C<< BinModeOut => 0|1 >>
When writing to a file or filehandle, set C<binmode> before writing to the
file.
-=item -Append =E<gt> 0|1
+=item C<< Append => 0|1 >>
TODO
-=item -MultiStream =E<gt> 0|1
+=item C<< MultiStream => 0|1 >>
-Creates a new stream after each file.
+If the input file/buffer contains multiple compressed data streams, this
+option will uncompress the whole lot as a single data stream.
-Defaults to 1.
+Defaults to 0.
=over 5
-=item -AutoClose =E<gt> 0|1
+=item C<< AutoClose => 0|1 >>
This option is only valid when the C<$input> parameter is a filehandle. If
specified, and the value is true, it will result in the file being closed once
This parameter defaults to 0.
-=item -MultiStream =E<gt> 0|1
+=item C<< MultiStream => 0|1 >>
-=item -Prime =E<gt> $string
+=item C<< Prime => $string >>
This option will uncompress the contents of C<$string> before processing the
input file/buffer.
case, the uncompression can be I<primed> with these bytes using this
option.
-=item -Transparent =E<gt> 0|1
+=item C<< Transparent => 0|1 >>
If this option is set and the input file or buffer is not compressed data,
the module will allow reading of it anyway.
This option defaults to 1.
-=item -BlockSize =E<gt> $num
+=item C<< BlockSize => $num >>
When reading the compressed input data, IO::Uncompress::RawInflate will read it in
blocks of C<$num> bytes.
This option defaults to 4096.
-=item -InputLength =E<gt> $size
+=item C<< InputLength => $size >>
When present this option will limit the number of compressed bytes read
from the input file/buffer to C<$size>. This option can be used in the
This option defaults to off.
-=item -Append =E<gt> 0|1
+=item C<< Append => 0|1 >>
This option controls what the C<read> method does with uncompressed data.
Defaults to 0.
-=item -Strict =E<gt> 0|1
+=item C<< Strict => 0|1 >>
+=head2 nextStream
+
+Usage is
+
+ my $status = $z->nextStream();
+
+Skips to the next compressed data stream in the input file/buffer. If a new
+compressed data stream is found, the eof marker will be cleared, C<$.> will
+be reset to 0.
+
+Returns 1 if a new stream was found, 0 if none was found, and -1 if an
+error was encountered.
+
+=head2 trailingData
+
+Usage is
+
+ my $data = $z->trailingData();
+
+Returns any data that
+
=head1 Importing
No symbolic constants are required by this IO::Uncompress::RawInflate at present.
require Exporter ;
-our ($VERSION, @ISA, @EXPORT_OK, %EXPORT_TAGS, $UnzipError);
+our ($VERSION, @ISA, @EXPORT_OK, %EXPORT_TAGS, $UnzipError, %headerLookup);
-$VERSION = '2.000_12';
+$VERSION = '2.000_13';
$UnzipError = '';
@ISA = qw(Exporter IO::Uncompress::RawInflate);
push @{ $EXPORT_TAGS{all} }, @EXPORT_OK ;
Exporter::export_ok_tags('all');
+%headerLookup = (
+ ZIP_CENTRAL_HDR_SIG, \&skipCentralDirectory,
+ ZIP_END_CENTRAL_HDR_SIG, \&skipEndCentralDirectory,
+ ZIP64_END_CENTRAL_REC_HDR_SIG, \&skipCentralDirectory64Rec,
+ ZIP64_END_CENTRAL_LOC_HDR_SIG, \&skipCentralDirectory64Loc,
+ ZIP64_ARCHIVE_EXTRA_SIG, \&skipArchiveExtra,
+ ZIP64_DIGITAL_SIGNATURE_SIG, \&skipDigitalSignature,
+ );
+
sub new
{
my $class = shift ;
or return $self->saveErrorString(undef, "Truncated file");
}
else {
- my $c = $hdr->{CompressedLength};
+ my $c = $hdr->{CompressedLength}->get32bit();
$self->smartReadExact(\$buffer, $c)
or return $self->saveErrorString(undef, "Truncated file");
$buffer = '';
my $trailer = shift;
my ($sig, $CRC32, $cSize, $uSize) ;
+ my ($cSizeHi, $uSizeHi) = (0, 0);
if (*$self->{ZipData}{Streaming}) {
- ($sig, $CRC32, $cSize, $uSize) = unpack("V V V V", $trailer) ;
+ $sig = unpack ("V", substr($trailer, 0, 4));
+ $CRC32 = unpack ("V", substr($trailer, 4, 4));
+
+ if (*$self->{ZipData}{Zip64} ) {
+ $cSize = U64::newUnpack_V64 substr($trailer, 8, 8);
+ $uSize = U64::newUnpack_V64 substr($trailer, 16, 8);
+ }
+ else {
+ $cSize = U64::newUnpack_V32 substr($trailer, 8, 4);
+ $uSize = U64::newUnpack_V32 substr($trailer, 12, 4);
+ }
+
return $self->TrailerError("Data Descriptor signature, got $sig")
if $sig != ZIP_DATA_HDR_SIG;
}
return $self->TrailerError("CRC mismatch")
if $CRC32 != *$self->{ZipData}{CRC32} ;
- my $exp_isize = *$self->{Uncomp}->compressedBytes();
- return $self->TrailerError("CSIZE mismatch. Got $cSize"
- . ", expected $exp_isize")
- if $cSize != $exp_isize ;
+ return $self->TrailerError("CSIZE mismatch.")
+ if ! $cSize->equal(*$self->{CompSize});
- $exp_isize = *$self->{Uncomp}->uncompressedBytes();
- return $self->TrailerError("USIZE mismatch. Got $uSize"
- . ", expected $exp_isize")
- if $uSize != $exp_isize ;
+ return $self->TrailerError("USIZE mismatch.")
+ if ! $uSize->equal(*$self->{UnCompSize});
}
my $reachedEnd = STATUS_ERROR ;
my $sig = unpack("V", $magic) ;
- if ($sig == ZIP_CENTRAL_HDR_SIG)
+ if ($headerLookup{$sig})
{
- if ($self->skipCentralDirectory($magic) != STATUS_OK ) {
+ if ($headerLookup{$sig}($self, $magic) != STATUS_OK ) {
if (*$self->{Strict}) {
return STATUS_ERROR ;
}
return STATUS_OK ;
}
}
- }
- elsif ($sig == ZIP_END_CENTRAL_HDR_SIG)
- {
- if ($self->skipEndCentralDirectory($magic) != STATUS_OK) {
- if (*$self->{Strict}) {
- return STATUS_ERROR ;
- }
- else {
- $self->clearError();
- return STATUS_OK ;
- }
+
+ if ($sig == ZIP_END_CENTRAL_HDR_SIG)
+ {
+ return STATUS_OK ;
+ last;
}
- # $reachedEnd = STATUS_OK ;
- return STATUS_OK ;
- last;
}
elsif ($sig == ZIP_LOCAL_HDR_SIG)
{
#my $compressedMethod = unpack ("v", substr($buffer, 10-4, 2));
#my $lastModTime = unpack ("V", substr($buffer, 12-4, 4));
#my $crc32 = unpack ("V", substr($buffer, 16-4, 4));
- #my $compressedLength = unpack ("V", substr($buffer, 20-4, 4));
- #my $uncompressedLength = unpack ("V", substr($buffer, 24-4, 4));
+ my $compressedLength = unpack ("V", substr($buffer, 20-4, 4));
+ my $uncompressedLength = unpack ("V", substr($buffer, 24-4, 4));
my $filename_length = unpack ("v", substr($buffer, 28-4, 2));
my $extra_length = unpack ("v", substr($buffer, 30-4, 2));
my $comment_length = unpack ("v", substr($buffer, 32-4, 2));
return STATUS_OK ;
}
+sub skipArchiveExtra
+{
+ my $self = shift;
+ my $magic = shift ;
+
+ my $buffer;
+ $self->smartReadExact(\$buffer, 4)
+ or return $self->TrailerError("Minimum header size is " .
+ 4 . " bytes") ;
+
+ my $keep = $magic . $buffer ;
+
+ my $size = unpack ("V", $buffer);
+
+ $self->smartReadExact(\$buffer, $size)
+ or return $self->TrailerError("Minimum header size is " .
+ $size . " bytes") ;
+
+ $keep .= $buffer ;
+ *$self->{HeaderPending} = $keep ;
+
+ return STATUS_OK ;
+}
+
+
+sub skipCentralDirectory64Rec
+{
+ my $self = shift;
+ my $magic = shift ;
+
+ my $buffer;
+ $self->smartReadExact(\$buffer, 8)
+ or return $self->TrailerError("Minimum header size is " .
+ 8 . " bytes") ;
+
+ my $keep = $magic . $buffer ;
+
+ my ($sizeLo, $sizeHi) = unpack ("V V", $buffer);
+
+ # TODO - take SizeHi into account
+ $self->smartReadExact(\$buffer, $sizeLo)
+ or return $self->TrailerError("Minimum header size is " .
+ $sizeLo . " bytes") ;
+
+ $keep .= $buffer ;
+ *$self->{HeaderPending} = $keep ;
+
+ #my $versionMadeBy = unpack ("v", substr($buffer, 0, 2));
+ #my $extractVersion = unpack ("v", substr($buffer, 2, 2));
+ #my $diskNumber = unpack ("V", substr($buffer, 4, 4));
+ #my $cntrlDirDiskNo = unpack ("V", substr($buffer, 8, 4));
+ #my $entriesInThisCD = unpack ("V V", substr($buffer, 12, 8));
+ #my $entriesInCD = unpack ("V V", substr($buffer, 20, 8));
+ #my $sizeOfCD = unpack ("V V", substr($buffer, 28, 8));
+ #my $offsetToCD = unpack ("V V", substr($buffer, 36, 8));
+
+ return STATUS_OK ;
+}
+
+sub skipCentralDirectory64Loc
+{
+ my $self = shift;
+ my $magic = shift ;
+
+ my $buffer;
+ $self->smartReadExact(\$buffer, 20 - 4)
+ or return $self->TrailerError("Minimum header size is " .
+ 20 . " bytes") ;
+
+ my $keep = $magic . $buffer ;
+ *$self->{HeaderPending} = $keep ;
+
+ #my $startCdDisk = unpack ("V", substr($buffer, 4-4, 4));
+ #my $offsetToCD = unpack ("V V", substr($buffer, 8-4, 8));
+ #my $diskCount = unpack ("V", substr($buffer, 16-4, 4));
+
+ return STATUS_OK ;
+}
+
sub skipEndCentralDirectory
{
my $self = shift;
}
-
-
sub _isZipMagic
{
my $buffer = shift ;
my $compressedMethod = unpack ("v", substr($buffer, 8-4, 2));
my $lastModTime = unpack ("V", substr($buffer, 10-4, 4));
my $crc32 = unpack ("V", substr($buffer, 14-4, 4));
- my $compressedLength = unpack ("V", substr($buffer, 18-4, 4));
- my $uncompressedLength = unpack ("V", substr($buffer, 22-4, 4));
+ my $compressedLength = new U64 unpack ("V", substr($buffer, 18-4, 4));
+ my $uncompressedLength = new U64 unpack ("V", substr($buffer, 22-4, 4));
my $filename_length = unpack ("v", substr($buffer, 26-4, 2));
my $extra_length = unpack ("v", substr($buffer, 28-4, 2));
*$self->{ZipData}{Streaming} = $streamingMode;
- if (! $streamingMode) {
- *$self->{ZipData}{Streaming} = 0;
- *$self->{ZipData}{Crc32} = $crc32;
- *$self->{ZipData}{CompressedLen} = $compressedLength;
- *$self->{ZipData}{UnCompressedLen} = $uncompressedLength;
- *$self->{CompressedInputLengthRemaining} =
- *$self->{CompressedInputLength} = $compressedLength;
- }
-
if ($filename_length)
{
$keep .= $filename ;
}
+ my $zip64 = 0 ;
+
if ($extra_length)
{
$self->smartReadExact(\$extraField, $extra_length)
if defined $bad;
$keep .= $extraField ;
+
+ my %Extra ;
+ for (@EXTRA)
+ {
+ $Extra{$_->[0]} = \$_->[1];
+ }
+
+ if (defined $Extra{ZIP_EXTRA_ID_ZIP64()})
+ {
+ $zip64 = 1 ;
+
+ my $buff = ${ $Extra{ZIP_EXTRA_ID_ZIP64()} };
+
+ $uncompressedLength = U64::newUnpack_V64 substr($buff, 0, 8);
+ $compressedLength = U64::newUnpack_V64 substr($buff, 8, 8);
+ #my $cheaderOffset = U64::newUnpack_V64 substr($buff, 16, 8);
+ #my $diskNumber = unpack ("V", substr($buff, 24, 4));
+ }
+ }
+
+ *$self->{ZipData}{Zip64} = $zip64;
+
+ if (! $streamingMode) {
+ *$self->{ZipData}{Streaming} = 0;
+ *$self->{ZipData}{Crc32} = $crc32;
+ *$self->{ZipData}{CompressedLen} = $compressedLength;
+ *$self->{ZipData}{UnCompressedLen} = $uncompressedLength;
+ *$self->{CompressedInputLengthRemaining} =
+ *$self->{CompressedInputLength} = $compressedLength->get32bit();
}
*$self->{ZipData}{Method} = $compressedMethod;
'FingerprintLength' => 4,
#'HeaderLength' => $compressedMethod == 8 ? length $keep : 0,
'HeaderLength' => length $keep,
- 'TrailerLength' => $streamingMode ? 16 : 0,
+ 'Zip64' => $zip64,
+ 'TrailerLength' => ! $streamingMode ? 0 : $zip64 ? 24 : 16,
'Header' => $keep,
'CompressedLength' => $compressedLength ,
'UncompressedLength' => $uncompressedLength ,
$status = $z->inflateSync()
- $z->trailingData()
+ $data = $z->trailingData()
+ $status = $z->nextStream()
$data = $z->getHeaderInfo()
$z->tell()
$z->seek($position, $whence)
=over 5
-=item AutoClose =E<gt> 0|1
+=item C<< AutoClose => 0|1 >>
This option applies to any input or output data streams to
C<unzip> that are filehandles.
This parameter defaults to 0.
-
-=item BinModeOut =E<gt> 0|1
+=item C<< BinModeOut => 0|1 >>
When writing to a file or filehandle, set C<binmode> before writing to the
file.
-=item -Append =E<gt> 0|1
+=item C<< Append => 0|1 >>
TODO
-=item -MultiStream =E<gt> 0|1
+=item C<< MultiStream => 0|1 >>
-Creates a new stream after each file.
+If the input file/buffer contains multiple compressed data streams, this
+option will uncompress the whole lot as a single data stream.
-Defaults to 1.
+Defaults to 0.
=over 5
-=item -AutoClose =E<gt> 0|1
+=item C<< AutoClose => 0|1 >>
This option is only valid when the C<$input> parameter is a filehandle. If
specified, and the value is true, it will result in the file being closed once
This parameter defaults to 0.
-=item -MultiStream =E<gt> 0|1
+=item C<< MultiStream => 0|1 >>
-Allows multiple concatenated compressed streams to be treated as a single
-compressed stream. Decompression will stop once either the end of the
-file/buffer is reached, an error is encountered (premature eof, corrupt
-compressed data) or the end of a stream is not immediately followed by the
-start of another stream.
+Treats the complete zip file/buffer as a single compressed data
+stream. When reading in multi-stream mode each member of the zip
+file/buffer will be uncompressed in turn until the end of the file/buffer
+is encountered.
This parameter defaults to 0.
-
-=item -Prime =E<gt> $string
+=item C<< Prime => $string >>
This option will uncompress the contents of C<$string> before processing the
input file/buffer.
case, the uncompression can be I<primed> with these bytes using this
option.
-=item -Transparent =E<gt> 0|1
+=item C<< Transparent => 0|1 >>
If this option is set and the input file or buffer is not compressed data,
the module will allow reading of it anyway.
This option defaults to 1.
-=item -BlockSize =E<gt> $num
+=item C<< BlockSize => $num >>
When reading the compressed input data, IO::Uncompress::Unzip will read it in
blocks of C<$num> bytes.
This option defaults to 4096.
-=item -InputLength =E<gt> $size
+=item C<< InputLength => $size >>
When present this option will limit the number of compressed bytes read
from the input file/buffer to C<$size>. This option can be used in the
This option defaults to off.
-=item -Append =E<gt> 0|1
+=item C<< Append => 0|1 >>
This option controls what the C<read> method does with uncompressed data.
Defaults to 0.
-=item -Strict =E<gt> 0|1
+=item C<< Strict => 0|1 >>
+=head2 nextStream
+
+Usage is
+
+ my $status = $z->nextStream();
+
+Skips to the next compressed data stream in the input file/buffer. If a new
+compressed data stream is found, the eof marker will be cleared, C<$.> will
+be reset to 0.
+
+Returns 1 if a new stream was found, 0 if none was found, and -1 if an
+error was encountered.
+
+=head2 trailingData
+
+Usage is
+
+ my $data = $z->trailingData();
+
+Returns any data that
+
=head1 Importing
No symbolic constants are required by this IO::Uncompress::Unzip at present.
$extra = 1
if eval { require Test::NoWarnings ; import Test::NoWarnings; 1 };
- plan tests => 119 + $extra ;
+ plan tests => 146 + $extra ;
#use_ok('IO::Compress::Zip', qw(zip $ZipError :zip_method)) ;
use_ok('IO::Compress::Zip', qw(:all)) ;
for my $stream (0, 1)
{
- for my $method (ZIP_CM_STORE, ZIP_CM_DEFLATE)
+ for my $zip64 (0, 1)
{
- title "Stream $stream, Method $method";
+ next if $zip64 && ! $stream;
- my $lex = new LexFile my $file1;
+ for my $method (ZIP_CM_STORE, ZIP_CM_DEFLATE)
+ {
- my $content = "hello ";
- #writeFile($file1, $content);
+ title "Stream $stream, Zip64 $zip64, Method $method";
- ok zip(\$content => $file1 , Method => $method, Stream => $stream), " zip ok"
- or diag $ZipError ;
+ my $lex = new LexFile my $file1;
- my $got ;
- if ($stream && $method == ZIP_CM_STORE ) {
- #eval ' unzip($file1 => \$got) ';
- ok ! unzip($file1 => \$got), " unzip fails";
- like $UnzipError, "/Streamed Stored content not supported/",
- " Streamed Stored content not supported";
- next ;
- }
+ my $content = "hello ";
+ #writeFile($file1, $content);
- ok unzip($file1 => \$got), " unzip ok"
- or diag $UnzipError ;
+ my $status = zip(\$content => $file1 ,
+ Method => $method,
+ Stream => $stream,
+ Zip64 => $zip64);
- is $got, $content, " content ok";
+ ok $status, " zip ok"
+ or diag $ZipError ;
- my $u = new IO::Uncompress::Unzip $file1
- or diag $ZipError ;
+ my $got ;
+ if ($stream && $method == ZIP_CM_STORE ) {
+ #eval ' unzip($file1 => \$got) ';
+ ok ! unzip($file1 => \$got), " unzip fails";
+ like $UnzipError, "/Streamed Stored content not supported/",
+ " Streamed Stored content not supported";
+ next ;
+ }
- my $hdr = $u->getHeaderInfo();
- ok $hdr, " got header";
+ ok unzip($file1 => \$got), " unzip ok"
+ or diag $UnzipError ;
+
+ is $got, $content, " content ok";
+
+ my $u = new IO::Uncompress::Unzip $file1
+ or diag $ZipError ;
- is $hdr->{Stream}, $stream, " stream is $stream" ;
- is $hdr->{MethodID}, $method, " MethodID is $method" ;
+ my $hdr = $u->getHeaderInfo();
+ ok $hdr, " got header";
+
+ is $hdr->{Stream}, $stream, " stream is $stream" ;
+ is $hdr->{MethodID}, $method, " MethodID is $method" ;
+ is $hdr->{Zip64}, $zip64, " Zip64 is $zip64" ;
+ }
}
}
for my $stream (0, 1)
{
- for my $method (ZIP_CM_STORE, ZIP_CM_DEFLATE)
+ for my $zip64 (0, 1)
{
- title "Stream $stream, Method $method";
-
- my $file1;
- my $file2;
- my $zipfile;
- my $lex = new LexFile $file1, $file2, $zipfile;
-
- my $content1 = "hello ";
- writeFile($file1, $content1);
-
- my $content2 = "goodbye ";
- writeFile($file2, $content2);
-
- my %content = ( $file1 => $content1,
- $file2 => $content2,
- );
-
- ok zip([$file1, $file2] => $zipfile , Method => $method, Stream => $stream), " zip ok"
- or diag $ZipError ;
-
- for my $file ($file1, $file2)
+ next if $zip64 && ! $stream;
+ for my $method (ZIP_CM_STORE, ZIP_CM_DEFLATE)
{
- my $got ;
- if ($stream && $method == ZIP_CM_STORE ) {
- #eval ' unzip($zipfile => \$got) ';
- ok ! unzip($zipfile => \$got, Name => $file), " unzip fails";
- like $UnzipError, "/Streamed Stored content not supported/",
- " Streamed Stored content not supported";
- next ;
+ title "Stream $stream, Zip64 $zip64, Method $method";
+
+ my $file1;
+ my $file2;
+ my $zipfile;
+ my $lex = new LexFile $file1, $file2, $zipfile;
+
+ my $content1 = "hello ";
+ writeFile($file1, $content1);
+
+ my $content2 = "goodbye ";
+ writeFile($file2, $content2);
+
+ my %content = ( $file1 => $content1,
+ $file2 => $content2,
+ );
+
+ ok zip([$file1, $file2] => $zipfile , Method => $method,
+ Zip64 => $zip64,
+ Stream => $stream), " zip ok"
+ or diag $ZipError ;
+
+ for my $file ($file1, $file2)
+ {
+ my $got ;
+ if ($stream && $method == ZIP_CM_STORE ) {
+ #eval ' unzip($zipfile => \$got) ';
+ ok ! unzip($zipfile => \$got, Name => $file), " unzip fails";
+ like $UnzipError, "/Streamed Stored content not supported/",
+ " Streamed Stored content not supported";
+ next ;
+ }
+
+ ok unzip($zipfile => \$got, Name => $file), " unzip $file ok"
+ or diag $UnzipError ;
+
+ is $got, $content{$file}, " content ok";
}
-
- ok unzip($zipfile => \$got, Name => $file), " unzip $file ok"
- or diag $UnzipError ;
-
- is $got, $content{$file}, " content ok";
}
}
}
Compress::Raw::Zlib
- Version 2.000_12
+ Version 2.000_13
- 17 May 2006
+ 20 June 2006
Copyright (c) 2005-2006 Paul Marquess. All rights reserved.
use bytes ;
our ($VERSION, $XS_VERSION, @ISA, @EXPORT, $AUTOLOAD);
-$VERSION = '2.000_12';
+$VERSION = '2.000_13';
$XS_VERSION = $VERSION;
$VERSION = eval $VERSION;
I<undef> and C<$status> will hold the a I<zlib> error code.
The function optionally takes a number of named options specified as
-C<-Name =E<gt> value> pairs. This allows individual options to be
+C<< Name => value >> pairs. This allows individual options to be
tailored without having to specify them all in the parameter list.
For backward compatibility, it is also possible to pass the parameters
C<Z_NO_COMPRESSION>, C<Z_BEST_SPEED>, C<Z_BEST_COMPRESSION>, and
C<Z_DEFAULT_COMPRESSION>.
-The default is C<-Level =E<gt> Z_DEFAULT_COMPRESSION>.
+The default is Z_DEFAULT_COMPRESSION.
=item B<-Method>
Defines the compression method. The only valid value at present (and
-the default) is C<-Method =E<gt> Z_DEFLATED>.
+the default) is Z_DEFLATED.
=item B<-WindowBits>
For a definition of the meaning and valid values for C<WindowBits>
refer to the I<zlib> documentation for I<deflateInit2>.
-Defaults to C<-WindowBits =E<gt> MAX_WBITS>.
+Defaults to MAX_WBITS.
=item B<-MemLevel>
For a definition of the meaning and valid values for C<MemLevel>
refer to the I<zlib> documentation for I<deflateInit2>.
-Defaults to C<-MemLevel =E<gt> MAX_MEM_LEVEL>.
+Defaults to MAX_MEM_LEVEL.
=item B<-Strategy>
C<Z_DEFAULT_STRATEGY>, C<Z_FILTERED>, C<Z_RLE>, C<Z_FIXED> and
C<Z_HUFFMAN_ONLY>.
-The default is C<-Strategy =E<gt>Z_DEFAULT_STRATEGY>.
+The default is Z_DEFAULT_STRATEGY.
=item B<-Dictionary>
I<zlib> error code.
The function optionally takes a number of named options specified as
-C<-Name =E<gt> value> pairs. This allows individual options to be
+C<< -Name => value >> pairs. This allows individual options to be
tailored without having to specify them all in the parameter list.
For backward compatibility, it is also possible to pass the parameters
-as a reference to a hash containing the name=E<gt>value pairs.
+as a reference to a hash containing the C<< name=>value >> pairs.
Here is a list of the valid options:
For a full definition of the meaning and valid values for C<WindowBits>
refer to the I<zlib> documentation for I<inflateInit2>.
-Defaults to C<-WindowBits =E<gt>MAX_WBITS>.
+Defaults to MAX_WBITS.
=item B<-Bufsize>
CHANGES
-------
+ 2.000_13 20 June 2006
+
+ * No changes.
+
2.000_12 16 April 2006
* Fixed gzread to zap the output buffer to an empty string when zero
Compress::Zlib
- Version 2.000_12
+ Version 2.000_13
- 17 May 2006
+ 20 June 2006
Copyright (c) 1995-2006 Paul Marquess. All rights reserved.
use bytes ;
our ($VERSION, $XS_VERSION, @ISA, @EXPORT, $AUTOLOAD);
-$VERSION = '2.000_12';
+$VERSION = '2.000_13';
$XS_VERSION = $VERSION;
$VERSION = eval $VERSION;
=back
A more complete and flexible interface for reading/writing gzip
-files/buffers is included with the module C<IO-Compress-ZLib>. See
+files/buffers is included with the module C<IO-Compress-Zlib>. See
L<IO::Compress::Gzip|IO::Compress::Gzip> and
L<IO::Uncompress::Gunzip|IO::Uncompress::Gunzip> for more details.
I<undef> and C<$status> will hold the exact I<zlib> error code.
The function optionally takes a number of named options specified as
-C<-Name=E<gt>value> pairs. This allows individual options to be
+C<< -Name=>value >> pairs. This allows individual options to be
tailored without having to specify them all in the parameter list.
For backward compatibility, it is also possible to pass the parameters
C<Z_NO_COMPRESSION>, C<Z_BEST_SPEED>, C<Z_BEST_COMPRESSION>, and
C<Z_DEFAULT_COMPRESSION>.
-The default is C<-Level =E<gt>Z_DEFAULT_COMPRESSION>.
+The default is Z_DEFAULT_COMPRESSION.
=item B<-Method>
Defines the compression method. The only valid value at present (and
-the default) is C<-Method =E<gt>Z_DEFLATED>.
+the default) is Z_DEFLATED.
=item B<-WindowBits>
For a full definition of the meaning and valid values for C<WindowBits> refer
to the I<zlib> documentation for I<deflateInit2>.
-Defaults to C<-WindowBits =E<gt>MAX_WBITS>.
+Defaults to MAX_WBITS.
=item B<-MemLevel>
For a definition of the meaning and valid values for C<MemLevel>
refer to the I<zlib> documentation for I<deflateInit2>.
-Defaults to C<-MemLevel =E<gt>MAX_MEM_LEVEL>.
+Defaults to MAX_MEM_LEVEL.
=item B<-Strategy>
Defines the strategy used to tune the compression. The valid values are
C<Z_DEFAULT_STRATEGY>, C<Z_FILTERED> and C<Z_HUFFMAN_ONLY>.
-The default is C<-Strategy =E<gt>Z_DEFAULT_STRATEGY>.
+The default is Z_DEFAULT_STRATEGY.
=item B<-Dictionary>
I<zlib> error code.
The function optionally takes a number of named options specified as
-C<-Name=E<gt>value> pairs. This allows individual options to be
+C<< -Name=>value >> pairs. This allows individual options to be
tailored without having to specify them all in the parameter list.
For backward compatibility, it is also possible to pass the parameters
For a full definition of the meaning and valid values for C<WindowBits> refer
to the I<zlib> documentation for I<inflateInit2>.
-Defaults to C<-WindowBits =E<gt>MAX_WBITS>.
+Defaults to MAX_WBITS.
=item B<-Bufsize>
These functions allow checksums to be merged.
-=head1 ACCESSING ZIP FILES
-
-Although it is possible (with some effort on your part) to use this
-module to access .zip files, there is a module on CPAN that will do all
-the hard work for you. Check out the C<Archive::Zip> module on CPAN at
-
- http://www.cpan.org/modules/by-module/Archive/Archive-Zip-*.tar.gz
-
-
=head1 CONSTANTS
All the I<zlib> constants are automatically imported when you make use
$extra = 1
if eval { require Test::NoWarnings ; import Test::NoWarnings; 1 };
- plan tests => 190 + $extra ;
+ plan tests => 694 + $extra ;
use_ok('IO::Uncompress::AnyUncompress', qw($AnyUncompressError)) ;
push @buffers, <<EOM ;
some more stuff
+line 2
EOM
push @buffers, <<EOM ;
ok $un eq join('', @buffs), " expected output" ;
}
+
+ foreach my $unc ($UncompressClass, 'IO::Uncompress::AnyUncompress') {
+ title " Testing $CompressClass with $unc nextStream and $i streams, from $fb";
+ $cc = $output ;
+ if ($fb eq 'filehandle')
+ {
+ $cc = new IO::File "<$name" ;
+ }
+ my $gz = new $unc($cc,
+ Strict => 1,
+ AutoClose => 1,
+ Append => 1,
+ MultiStream => 0,
+ Transparent => 0)
+ or diag $$UnError;
+ isa_ok $gz, $UncompressClass, ' $gz' ;
+
+ for my $stream (1 .. $i)
+ {
+ my $buff = $buffs[$stream-1];
+ my @lines = split("\n", $buff);
+ my $lines = @lines;
+
+ my $un = '';
+ while (<$gz>) {
+ $un .= $_;
+ }
+ is $., $lines, " \$. is $lines";
+
+ ok ! $gz->error(), " ! error()"
+ or diag "Error is " . $gz->error() ;
+ ok $gz->eof(), " eof()";
+ is $gz->streamCount(), $stream, " streamCount is $stream"
+ or diag "Stream count is " . $gz->streamCount();
+ ok $un eq $buff, " expected output" ;
+ #is $gz->tell(), length $buff, " tell is ok";
+ is $gz->nextStream(), 1, " nextStream ok";
+ is $gz->tell(), 0, " tell is 0";
+ is $., 0, ' $. is 0';
+ }
+
+ {
+ my $un = '';
+ 1 while $gz->read($un) > 0 ;
+ #print "[[$un]]\n" while $gz->read($un) > 0 ;
+ ok ! $gz->error(), " ! error()"
+ or diag "Error is " . $gz->error() ;
+ ok $gz->eof(), " eof()";
+ is $gz->streamCount(), $i+1, " streamCount is ok"
+ or diag "Stream count is " . $gz->streamCount();
+ ok $un eq "", " expected output" ;
+ is $gz->tell(), 0, " tell is 0";
+ is $., 0, " \$. is 0";
+ }
+
+ is $gz->nextStream(), 0, " nextStream ok";
+ ok $gz->eof(), " eof()";
+ ok $gz->close(), " close() ok"
+ or diag "errno $!\n" ;
+
+ is $gz->streamCount(), $i +1, " streamCount ok"
+ or diag "Stream count is " . $gz->streamCount();
+
+ }
}
}
}
# corrupt one of the streams - all previous should be ok
# trailing stuff
-# need a way to skip to the start of the next stream.
# check that "tell" works ok
1;
$extra = 1
if eval { require Test::NoWarnings ; import Test::NoWarnings; 1 };
- plan tests => 944 + $extra ;
+ plan tests => 956 + $extra ;
use_ok('IO::Uncompress::AnyUncompress', qw(anyuncompress $AnyUncompressError)) ;
' Input and Output filename are the same';
}
+ {
+ my $dir = "tmpdir";
+ my $lex = new LexDir $dir ;
+ mkdir $dir, 0777 ;
+
+ $a = $Func->($dir, \$x) ;
+ is $a, undef, " $TopType returned undef";
+ like $$Error, "/input file '$dir' is a directory/",
+ ' Input filename is a directory';
+
+ $a = $Func->(\$x, $dir) ;
+ is $a, undef, " $TopType returned undef";
+ like $$Error, "/output file '$dir' is a directory/",
+ ' Output filename is a directory';
+ }
+
eval { $a = $Func->(\$in, \$in) ;} ;
like $@, mkErr("^$TopType: input and output buffer are identical"),
' Input and Output buffer are the same';