ext/Compress/Raw/Zlib/Makefile.PL Compress::Raw::Zlib
ext/Compress/Raw/Zlib/ppport.h Compress::Raw::Zlib
ext/Compress/Raw/Zlib/config.in Compress::Raw::Zlib
+ext/Compress/Raw/Zlib/Changes Compress::Raw::Zlib
ext/Compress/Raw/Zlib/zlib-src/adler32.c Compress::Raw::Zlib
ext/Compress/Raw/Zlib/zlib-src/compress.c Compress::Raw::Zlib
ext/Compress/Raw/Zlib/zlib-src/crc32.c Compress::Raw::Zlib
ext/Compress/IO/Zlib/lib/IO/Compress/Zip/Constants.pm IO::Compress::Zlib
ext/Compress/IO/Zlib/lib/IO/Compress/Gzip/Constants.pm IO::Compress::Zlib
ext/Compress/IO/Zlib/lib/IO/Compress/Zlib/Constants.pm IO::Compress::Zlib
+ext/Compress/IO/Zlib/lib/IO/Compress/Zlib/Extra.pm IO::Compress::Zlib
ext/Compress/IO/Zlib/lib/IO/Compress/Adapter/Deflate.pm IO::Compress::Zlib
ext/Compress/IO/Zlib/lib/IO/Compress/Adapter/Identity.pm IO::Compress::Zlib
ext/Compress/IO/Zlib/Makefile.PL IO::Compress::Zlib
IO::Compress::Base
- Version 2.000_10
+ Version 2.000_12
- 13 Mar 2006
+ 17 May 2006
Copyright (c) 2005-2006 Paul Marquess. All rights reserved.
our (@ISA, $VERSION, $got_encode);
#@ISA = qw(Exporter IO::File);
-$VERSION = '2.000_11';
+$VERSION = '2.000_12';
#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.
require Exporter;
our ($VERSION, @ISA, @EXPORT, %EXPORT_TAGS);
@ISA = qw(Exporter);
-$VERSION = '2.000_11';
+$VERSION = '2.000_12';
@EXPORT = qw( isaFilehandle isaFilename whatIsInput whatIsOutput
isaFileGlobString cleanFileGlobString oneTarget
our ($VERSION, @ISA, @EXPORT_OK, %EXPORT_TAGS, $AnyUncompressError);
-$VERSION = '2.000_11';
+$VERSION = '2.000_12';
$AnyUncompressError = '';
@ISA = qw( Exporter IO::Uncompress::Base );
=head2 Notes
-When C<$input> maps to multiple files/buffers and C<$output> is a single
-file/buffer the uncompressed input files/buffers will all be stored
-in C<$output> as a single uncompressed stream.
+
+When C<$input> maps to multiple compressed files/buffers and C<$output> is
+a single file/buffer, after uncompression C<$output> will contain a
+concatenation of all the uncompressed data from each of the input
+files/buffers.
+
+
@ISA = qw(Exporter );
-$VERSION = '2.000_11';
+$VERSION = '2.000_12';
use constant G_EOF => 0 ;
use constant G_ERR => -1 ;
$extra = 1
if eval { require Test::NoWarnings ; import Test::NoWarnings; 1 };
- plan tests => 29 + $extra ;
+ plan tests => 33 + $extra ;
use_ok('IO::Compress::Base::Common');
$got = ParseParameters(1, {'Fred' => [1, 1, 0x1000000, 0]}, Fred => 'abc') ;
is $got->value('Fred'), "abc", "other" ;
+ $got = ParseParameters(1, {'Fred' => [0, 1, Parse_any, undef]}, Fred =>
+undef) ;
+ ok $got->parsed('Fred'), "undef" ;
+ ok ! defined $got->value('Fred'), "undef" ;
+
+ $got = ParseParameters(1, {'Fred' => [0, 1, Parse_string, undef]}, Fred =>
+undef) ;
+ ok $got->parsed('Fred'), "undef" ;
+ is $got->value('Fred'), "", "empty string" ;
+
}
My::testParseParameters();
CHANGES
-------
+ 2.000_12 3 May 2006
+
+ * Moved the code for creating and parsing the gzip extra field into
+ IO::Compress::Zlib::Extra.pm so that IO::Compress::Zip &
+ IO::Uncompress::Unzip can use it as well.
+
+ * Added ExtraFieldLocal & ExtraFieldCentral options to IO::Compress::Zip.
+ These allow the creation of user-defined extra fields in the local
+ and central headers, just like the ExtraField option in
+ IO::Compress::Gzip.
+
+ * Moved the zip constants into IO::Compress::Zip::Constants
+
+ * Added exTime option to IO::Compress::Zip.
+ This allows creation of the extended timestamp extra field.
+
+ * Added Minimal option to IO::Compress::Zip.
+ This disables the creation of all extended fields.
+
+ * Added TextFlag option to IO::Compress::Zip.
+
+ * Documented Comment and ZipComment options in IO::Compress::Zip.
+
2.000_11 10 April 2006
* Updated Documentation for zip modules.
IO::Compress::Zlib
- Version 2.000_11
+ Version 2.000_12
- 10 April 2006
+ 17 May 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_11';
+$VERSION = '2.000_12';
sub mkCompObject
{
use IO::Compress::Base::Common qw(:Status);
our ($VERSION);
-$VERSION = '2.000_11';
+$VERSION = '2.000_12';
sub mkCompObject
{
our ($VERSION, @ISA, @EXPORT_OK, %EXPORT_TAGS, $DeflateError);
-$VERSION = '2.000_11';
+$VERSION = '2.000_12';
$DeflateError = '';
@ISA = qw(Exporter IO::Compress::RawDeflate);
=head2 Notes
+
+
When C<$input> maps to multiple files/buffers and C<$output> is a single
-file/buffer the compressed input files/buffers will all be stored
-in C<$output> as a single compressed stream.
+file/buffer the input files/buffers will be stored
+in C<$output> as a concatenated series of compressed data streams.
+
+
+
use Compress::Raw::Zlib ;
use IO::Compress::Base::Common qw(:Status :Parse createSelfTiedObject);
use IO::Compress::Gzip::Constants;
+use IO::Compress::Zlib::Extra;
BEGIN
{
our ($VERSION, @ISA, @EXPORT_OK, %EXPORT_TAGS, $GzipError);
-$VERSION = '2.000_11';
+$VERSION = '2.000_12';
$GzipError = '' ;
@ISA = qw(Exporter IO::Compress::RawDeflate);
'TextFlag' => [0, 1, Parse_boolean, 0],
'HeaderCRC' => [0, 1, Parse_boolean, 0],
'OS_Code' => [0, 1, Parse_unsigned, $Compress::Raw::Zlib::gzip_os_code],
- 'ExtraField'=> [0, 1, Parse_string, undef],
+ 'ExtraField'=> [0, 1, Parse_any, undef],
'ExtraFlags'=> [0, 1, Parse_any, undef],
);
return 1
if $got->value('Merge') ;
- my $lax = ! $got->value('Strict') ;
+ my $strict = $got->value('Strict') ;
{
return $self->saveErrorString(undef, "Null Character found in Name",
Z_DATA_ERROR)
- if ! $lax && $name =~ /\x00/ ;
+ if $strict && $name =~ /\x00/ ;
return $self->saveErrorString(undef, "Non ISO 8859-1 Character found in Name",
Z_DATA_ERROR)
- if ! $lax && $name =~ /$GZIP_FNAME_INVALID_CHAR_RE/o ;
+ if $strict && $name =~ /$GZIP_FNAME_INVALID_CHAR_RE/o ;
}
if ($got->parsed('Comment') && defined $got->value('Comment')) {
return $self->saveErrorString(undef, "Null Character found in Comment",
Z_DATA_ERROR)
- if ! $lax && $comment =~ /\x00/ ;
+ if $strict && $comment =~ /\x00/ ;
return $self->saveErrorString(undef, "Non ISO 8859-1 Character found in Comment",
Z_DATA_ERROR)
- if ! $lax && $comment =~ /$GZIP_FCOMMENT_INVALID_CHAR_RE/o;
+ if $strict && $comment =~ /$GZIP_FCOMMENT_INVALID_CHAR_RE/o;
}
if ($got->parsed('OS_Code') ) {
if $got->value('Level') == Z_BEST_COMPRESSION ;
}
- if ($got->parsed('ExtraField')) {
-
- my $bad = $self->parseExtraField($got, $lax) ;
- return $self->saveErrorString(undef, $bad, Z_DATA_ERROR)
+ my $data = $got->value('ExtraField') ;
+ if (defined $data) {
+ my $bad = IO::Compress::Zlib::Extra::parseExtraField($data, $strict, 1) ;
+ return $self->saveErrorString(undef, "Error with ExtraField Parameter: $bad", Z_DATA_ERROR)
if $bad ;
- my $len = length $got->value('ExtraField') ;
- return $self->saveErrorString(undef, ExtraFieldError("Too Large"),
- Z_DATA_ERROR)
- if $len > GZIP_FEXTRA_MAX_SIZE;
+ $got->value('ExtraField', $data) ;
}
}
return $out ;
}
-sub ExtraFieldError
-{
- return "Error with ExtraField Parameter: $_[0]" ;
-}
-
-sub validateExtraFieldPair
-{
- my $pair = shift ;
- my $lax = 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 ! $lax && 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 parseExtra
-{
- my $data = 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("FEXTRA Body")
- 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("FEXTRA Body")
- if $offset + $subLen > $XLEN ;
-
- my $bad = validateExtraFieldPair( [$id,
- substr($data, $offset, $subLen)], $lax );
- return $bad if $bad ;
-
- $offset += $subLen ;
- }
-
- return undef ;
-}
-
-sub parseExtraField
-{
- my $self = shift ;
- my $got = shift ;
- my $lax = shift ;
-
- # ExtraField can be any of
- #
- # -ExtraField => $data
- # -ExtraField => [$id1, $data1,
- # $id2, $data2]
- # ...
- # ]
- # -ExtraField => [ [$id1 => $data1],
- # [$id2 => $data2],
- # ...
- # ]
- # -ExtraField => { $id1 => $data1,
- # $id2 => $data2,
- # ...
- # }
-
-
- return undef
- unless $got->parsed('ExtraField') ;
-
- return parseExtra($got->value('ExtraField'), $lax)
- unless ref $got->value('ExtraField') ;
-
- my $data = $got->value('ExtraField');
- 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, $lax) ;
- return $bad if $bad ;
-
- $out .= $pair->[0] . pack("v", length $pair->[1]) .
- $pair->[1] ;
- }
- }
- else {
- return ExtraFieldError("Not even number of elements")
- unless @$data % 2 == 0;
-
- for (my $ix = 0; $ix <= length(@$data) -1 ; $ix += 2) {
- my $bad = validateExtraFieldPair([$data->[$ix], $data->[$ix+1]], $lax) ;
- return $bad if $bad ;
-
- $out .= $data->[$ix] . pack("v", length $data->[$ix+1]) .
- $data->[$ix+1] ;
- }
- }
- }
- elsif (ref $data eq 'HASH') {
- while (my ($id, $info) = each %$data) {
- my $bad = validateExtraFieldPair([$id, $info], $lax);
- return $bad if $bad ;
-
- $out .= $id . pack("v", length $info) . $info ;
- }
- }
- else {
- return ExtraFieldError("Not a scalar, array ref or hash ref") ;
- }
-
- $got->value('ExtraField' => $out);
-
- return undef;
-}
-
sub mkFinalTrailer
{
return '';
=head2 Notes
+
+
When C<$input> maps to multiple files/buffers and C<$output> is a single
-file/buffer the compressed input files/buffers will all be stored
-in C<$output> as a single compressed stream.
+file/buffer the input files/buffers will be stored
+in C<$output> as a concatenated series of compressed data streams.
+
+
+
our ($VERSION, @ISA, @EXPORT, %GZIP_OS_Names);
our ($GZIP_FNAME_INVALID_CHAR_RE, $GZIP_FCOMMENT_INVALID_CHAR_RE);
-$VERSION = '2.000_11';
+$VERSION = '2.000_12';
@ISA = qw(Exporter);
our ($VERSION, @ISA, @EXPORT_OK, %DEFLATE_CONSTANTS, %EXPORT_TAGS, $RawDeflateError);
-$VERSION = '2.000_11';
+$VERSION = '2.000_12';
$RawDeflateError = '';
@ISA = qw(Exporter IO::Compress::Base);
=head2 Notes
+
+
When C<$input> maps to multiple files/buffers and C<$output> is a single
-file/buffer the compressed input files/buffers will all be stored
-in C<$output> as a single compressed stream.
+file/buffer the input files/buffers will be stored
+in C<$output> as a concatenated series of compressed data streams.
+
+
+
use IO::Compress::RawDeflate;
use IO::Compress::Adapter::Deflate;
use IO::Compress::Adapter::Identity;
+use IO::Compress::Zip::Constants;
+
use Compress::Raw::Zlib qw(crc32) ;
BEGIN
{
eval { require IO::Compress::Adapter::Bzip2;
- import IO::Compress::Adapter::Bzip2;
+ import IO::Compress::Adapter::Bzip2;
require IO::Compress::Bzip2;
- import IO::Compress::Bzip2;
+ import IO::Compress::Bzip2;
} ;
}
our ($VERSION, @ISA, @EXPORT_OK, %EXPORT_TAGS, $ZipError);
-$VERSION = '2.000_11';
+$VERSION = '2.000_12';
$ZipError = '';
@ISA = qw(Exporter IO::Compress::RawDeflate);
Exporter::export_ok_tags('all');
-use constant ZIP_CM_STORE => 0 ;
-use constant ZIP_CM_DEFLATE => 8 ;
-use constant ZIP_CM_BZIP2 => 12 ;
-
-use constant ZIP_LOCAL_HDR_SIG => 0x04034b50;
-use constant ZIP_DATA_HDR_SIG => 0x08074b50;
-use constant ZIP_CENTRAL_HDR_SIG => 0x02014b50;
-use constant ZIP_END_CENTRAL_HDR_SIG => 0x06054b50;
-
-
-our (%ZIP_CM_MIN_VERSIONS);
-%ZIP_CM_MIN_VERSIONS = (
- ZIP_CM_STORE() => 20,
- ZIP_CM_DEFLATE() => 20,
- ZIP_CM_BZIP2() => 46,
- );
-
sub new
{
my $class = shift ;
my $self = shift;
my $param = shift ;
+ *$self->{ZipData}{StartOffset} = *$self->{ZipData}{Offset} ;
+
my $filename = '';
$filename = $param->value('Name') || '';
my $hdr = '';
my $time = _unixToDosTime($param->value('Time'));
- *$self->{ZipData}{StartOffset} = *$self->{ZipData}{Offset} ;
- my $strm = *$self->{ZipData}{Stream} ? 8 : 0 ;
- # bzip2 is 12, deflate is 8
+ my $extra = '';
+ my $ctlExtra = '';
+
+ if (! $param->value('Minimal')) {
+ if (defined $param->value('exTime'))
+ {
+ $extra .= mkExtendedTime($param->value('MTime'),
+ $param->value('ATime'),
+ $param->value('CTime'));
+
+ $ctlExtra .= mkExtendedTime($param->value('MTime'));
+ }
+
+ # if ( $param->value('UID'))
+ # {
+ # $extra .= mkUnixExtra( $param->value('UID'), $param->value('GID'));
+ # $ctlExtra .= mkUnixExtra();
+ # }
+
+ $extra .= $param->value('ExtraFieldLocal')
+ if defined $param->value('ExtraFieldLocal');
+
+ $ctlExtra .= $param->value('ExtraFieldCentral')
+ if defined $param->value('ExtraFieldCentral');
+ }
+
+ my $extAttr = 0;
+ $extAttr = $param->value('Mode') << 16
+ if defined $param->value('Mode') ;
+
+ my $gpFlag = 0 ;
+ $gpFlag |= ZIP_GP_FLAG_STREAMING_MASK
+ if *$self->{ZipData}{Stream} ;
+
my $method = *$self->{ZipData}{Method} ;
# deflate is 20
# bzip2 is 46
- my $extract = $param->value('OS_Code') << 8 +
+ my $madeBy = ($param->value('OS_Code') << 8) +
$ZIP_CM_MIN_VERSIONS{$method};
+ my $extract = $ZIP_CM_MIN_VERSIONS{$method};
+
+ my $ifa = 0;
+ $ifa |= ZIP_IFA_TEXT_MASK
+ if $param->value('TextFlag');
$hdr .= pack "V", ZIP_LOCAL_HDR_SIG ; # signature
$hdr .= pack 'v', $extract ; # extract Version & OS
- $hdr .= pack 'v', $strm ; # general purpose flag (set streaming mode)
+ $hdr .= pack 'v', $gpFlag ; # general purpose flag (set streaming mode)
$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', length $filename ; # filename length
- $hdr .= pack 'v', 0 ; # extra length
+ $hdr .= pack 'v', length $extra ; # extra length
$hdr .= $filename ;
+ $hdr .= $extra ;
my $ctl = '';
$ctl .= pack "V", ZIP_CENTRAL_HDR_SIG ; # signature
- $ctl .= pack 'v', $extract ; # version made by
+ $ctl .= pack 'v', $madeBy ; # version made by
$ctl .= pack 'v', $extract ; # extract Version
- $ctl .= pack 'v', $strm ; # general purpose flag (streaming mode)
+ $ctl .= pack 'v', $gpFlag ; # general purpose flag (streaming mode)
$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', length $filename ; # filename length
- $ctl .= pack 'v', 0 ; # extra 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', 0 ; # internal file attributes
- $ctl .= pack 'V', 0 ; # external file attributes
+ $ctl .= pack 'v', $ifa ; # internal file attributes
+ $ctl .= pack 'V', $extAttr ; # external file attributes
$ctl .= pack 'V', *$self->{ZipData}{Offset} ; # offset to local header
$ctl .= $filename ;
- #$ctl .= $extra ;
+ $ctl .= $ctlExtra ;
$ctl .= $comment ;
*$self->{ZipData}{Offset} += length $hdr ;
my $ctl = *$self->{ZipData}{CentralHeader} ;
substr($ctl, 16, 12) = $data ;
- #substr($ctl, 16, 4) = pack "V", $crc32 ; # CRC32
- #substr($ctl, 20, 4) = pack "V", $compressedBytes ; # Compressed Size
- #substr($ctl, 24, 4) = pack "V", $uncompressedBytes ; # Uncompressed Size
*$self->{ZipData}{Offset} += length($hdr) + $compressedBytes;
push @{ *$self->{ZipData}{CentralDir} }, $ctl ;
$got->value('Time' => time) ;
}
+ if (! $got->parsed('exTime') ) {
+ my $timeRef = $got->value('exTime');
+ if ( defined $timeRef) {
+ return $self->saveErrorString(undef, "exTime not a 3-element array ref")
+ if ref $timeRef ne 'ARRAY' || @$timeRef != 3;
+ }
+
+ $got->value("MTime", $timeRef->[1]);
+ $got->value("ATime", $timeRef->[0]);
+ $got->value("CTime", $timeRef->[2]);
+ }
+
*$self->{ZipData}{Stream} = $got->value('Stream');
- #*$self->{ZipData}{Store} = $got->value('Store');
my $method = $got->value('Method');
- #if ($method != 0 && $method != 8 && $method != 12) {
return $self->saveErrorString(undef, "Unknown Method '$method'")
if ! defined $ZIP_CM_MIN_VERSIONS{$method};
*$self->{ZipData}{ZipComment} = $got->value('ZipComment') ;
+ for my $name (qw( ExtraFieldLocal ExtraFieldCentral ))
+ {
+ my $data = $got->value($name) ;
+ if (defined $data) {
+ my $bad = IO::Compress::Zlib::Extra::parseExtraField($data, 1, 0) ;
+ return $self->saveErrorString(undef, "Error with $name Parameter: $bad")
+ if $bad ;
+
+ $got->value($name, $data) ;
+ }
+ }
+
return undef
if defined $IO::Compress::Bzip2::VERSION
and ! IO::Compress::Bzip2::ckParams($self, $got);
'Method' => [0, 1, Parse_unsigned, ZIP_CM_DEFLATE],
# # Zip header fields
-# 'Minimal' => [0, 1, Parse_boolean, 0],
+ 'Minimal' => [0, 1, Parse_boolean, 0],
'Comment' => [0, 1, Parse_any, ''],
'ZipComment'=> [0, 1, Parse_any, ''],
'Name' => [0, 1, Parse_any, ''],
'Time' => [0, 1, Parse_any, undef],
+ 'exTime' => [0, 1, Parse_any, undef],
'OS_Code' => [0, 1, Parse_unsigned, $Compress::Raw::Zlib::gzip_os_code],
-# 'TextFlag' => [0, 1, Parse_boolean, 0],
-# 'ExtraField'=> [0, 1, Parse_string, ''],
+ 'TextFlag' => [0, 1, Parse_boolean, 0],
+ 'ExtraFieldLocal' => [0, 1, Parse_any, undef],
+ 'ExtraFieldCentral'=> [0, 1, Parse_any, undef],
@Bzip2,
);
my $params = shift;
my $filename = shift ;
- my $defaultTime = (stat($filename))[9] ;
+ my ($mode, $uid, $gid, $atime, $mtime, $ctime)
+ = (stat($filename))[2, 4,5, 8,9,10] ;
$params->value('Name' => $filename)
if ! $params->parsed('Name') ;
- $params->value('Time' => $defaultTime)
+ $params->value('Time' => $mtime)
if ! $params->parsed('Time') ;
+ if ( ! $params->parsed('exTime'))
+ {
+ $params->value('MTime' => $mtime) ;
+ $params->value('ATime' => $atime) ;
+ $params->value('CTime' => $ctime) ;
+ }
+
+ $params->value('Mode' => $mode) ;
+
+ $params->value('UID' => $uid) ;
+ $params->value('GID' => $gid) ;
}
+sub mkExtendedTime
+{
+ # order expected is m, a, c
+
+ my $times = '';
+ my $bit = 1 ;
+ my $flags = 0;
+
+ for my $time (@_)
+ {
+ if (defined $time)
+ {
+ $flags |= $bit;
+ $times .= pack("V", $time);
+ }
+
+ $bit <<= 1 ;
+ }
+
+ #return "UT" . pack("v C", length($times) + 1, $flags) . $times;
+ return IO::Compress::Zlib::Extra::mkSubField(ZIP_EXTRA_ID_EXT_TIMESTAMP,
+ pack("C", $flags) . $times);
+}
+
+sub mkUnixExtra
+{
+ my $ids = '';
+ for my $id (@_)
+ {
+ $ids .= pack("v", $id);
+ }
+
+ #return "Ux" . pack("v", length $ids) . $ids;
+ return IO::Compress::Zlib::Extra::mkSubField(ZIP_EXTRA_ID_INFO_ZIP_UNIX, $ids);
+}
+
+
# from Archive::Zip
sub _unixToDosTime # Archive::Zip::Member
{
In addition, if C<$input> is a simple filename, the default values for
-the C<Name> and C<Time> options will be sourced from that file.
+the C<Name>, C<Time> and C<exTime> options will be sourced from that file.
If you do not want to use these defaults they can be overridden by
-explicitly setting the C<Name> and C<Time> options or by setting the
+explicitly setting the C<Name>, C<Time> and C<exTime> options or by setting the
C<Minimal> parameter.
=head2 Notes
+
+
When C<$input> maps to multiple files/buffers and C<$output> is a single
-file/buffer the compressed input files/buffers will all be stored
-in C<$output> as a single compressed stream.
+file/buffer the input files/buffers will each be stored
+in C<$output> as a distinct entry.
+
+
+
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]
+
+This option expects an array reference with exactly three elements:
+C<$atime>, C<mtime> and C<$ctime>. These correspond to the last access
+time, last modification time and creation time respectively.
+
+It uses these values to set the extended timestamp field in the local zip
+header to the three values, $atime, $mtime, $ctime and sets the extended
+timestamp field in the central zip header to C<$mtime>.
+
+If the C<Minimal> option is set to true, this option will be ignored.
+
+By default no extended time field is created.
+
+=item -Comment =E<gt> $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
+
+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
Controls which compression method is used. At present three compression
The default method is ZIP_CM_DEFLATE.
-=item -Stream =E<gt> 0|1
+=item Stream =E<gt> 0|1
This option controls whether the zip file/buffer output is created in
streaming mode.
+Note that when outputting to a file with streaming mode disabled (C<Stream>
+is 0), the output file must be seekable.
+
The default is 1.
+=item -TextFlag =E<gt> 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
+text.
+
+The default is 0.
+
+=item ExtraFieldLocal =E<gt> $data
+=item ExtraFieldCentral =E<gt> $data
+
+These options allows additional metadata to be stored in the local and
+central headers in the zip file/buffer.
+
+An extra field consists of zero or more subfields. Each subfield consists
+of a two byte header followed by the subfield data.
+
+The list of subfields can be supplied in any of the following formats
+
+ ExtraFieldLocal => [$id1, $data1,
+ $id2, $data2,
+ ...
+ ]
+
+ ExtraFieldLocal => [ [$id1 => $data1],
+ [$id2 => $data2],
+ ...
+ ]
+
+ ExtraFieldLocal => { $id1 => $data1,
+ $id2 => $data2,
+ ...
+ }
+
+Where C<$id1>, C<$id2> are two byte subfield ID's.
+
+If you use the hash syntax, you have no control over the order in which
+the ExtraSubFields are stored, plus you cannot have SubFields with
+duplicate ID.
+
+Alternatively the list of subfields can by supplied as a scalar, thus
+
+ ExtraField => $rawdata
+
+
+
+If the C<Minimal> option is set to true, this option will be ignored.
+
+The maximum size of an extra field 65535 bytes.
+
+=item Minimal =E<gt> 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
Specify the number of 100K blocks bzip2 uses during compression.
require Exporter;
-our ($VERSION, @ISA, @EXPORT, %GZIP_OS_Names);
+our ($VERSION, @ISA, @EXPORT, %ZIP_CM_MIN_VERSIONS);
-$VERSION = '2.000_11';
+$VERSION = '2.000_12';
@ISA = qw(Exporter);
@EXPORT= qw(
- ZIP_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
-
ZIP_CM_STORE
- ZIP_CM_DEFLATED
+ ZIP_CM_DEFLATE
ZIP_CM_BZIP2
+
+ ZIP_LOCAL_HDR_SIG
+ ZIP_DATA_HDR_SIG
+ ZIP_CENTRAL_HDR_SIG
+ ZIP_END_CENTRAL_HDR_SIG
- GZIP_MIN_HEADER_SIZE
- GZIP_TRAILER_SIZE
-
- GZIP_MTIME_DEFAULT
- GZIP_FEXTRA_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
+ ZIP_GP_FLAG_STREAMING_MASK
- GZIP_ISIZE_MAX
- GZIP_ISIZE_MOD_VALUE
+ ZIP_EXTRA_ID_EXT_TIMESTAMP
+ ZIP_EXTRA_ID_INFO_ZIP_UNIX
+ ZIP_IFA_TEXT_MASK
- GZIP_NULL_BYTE
-
- GZIP_OS_DEFAULT
-
- %GZIP_OS_Names
-
- GZIP_MINIMUM_HEADER
+ %ZIP_CM_MIN_VERSIONS
);
+# Compression types supported
+use constant ZIP_CM_STORE => 0 ;
+use constant ZIP_CM_DEFLATE => 8 ;
+use constant ZIP_CM_BZIP2 => 12 ;
-# Constants for the Zip Local Header
-
-use constant ZIP_ID_SIZE => 4 ;
-use constant ZIP_LOCAL_ID => 0x02014B50;
-use constant ZIP_LOCAL_ID1 => 0x04;
-use constant ZIP_LOCAL_ID2 => 0x03;
-use constant ZIP_LOCAL_ID3 => 0x4B;
-use constant ZIP_LOCAL_ID4 => 0x50;
-
-use constant ZIP_MIN_HEADER_SIZE => 30 ;
-use constant ZIP_TRAILER_SIZE => 0 ;
+# General Purpose Flag
+use constant ZIP_GP_FLAG_ENCRYPTED_MASK => 1 ;
+use constant ZIP_GP_FLAG_STREAMING_MASK => 8 ;
+# Internal File Attributes
+use constant ZIP_IFA_TEXT_MASK => 1;
-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) ;
+# Signatures for each of the headers
+use constant ZIP_LOCAL_HDR_SIG => 0x04034b50;
+use constant ZIP_DATA_HDR_SIG => 0x08074b50;
+use constant ZIP_CENTRAL_HDR_SIG => 0x02014b50;
+use constant ZIP_END_CENTRAL_HDR_SIG => 0x06054b50;
-use constant GZIP_MTIME_DEFAULT => 0x00 ;
-use constant GZIP_FEXTRA_DEFAULT => 0x00 ;
-use constant GZIP_FEXTRA_HEADER_SIZE => 2 ;
-use constant GZIP_FEXTRA_MAX_SIZE => 0xFFFF ;
-use constant GZIP_FEXTRA_SUBFIELD_HEADER_SIZE => 4 ;
-use constant GZIP_FEXTRA_SUBFIELD_ID_SIZE => 2 ;
-use constant GZIP_FEXTRA_SUBFIELD_LEN_SIZE => 2 ;
-use constant GZIP_FEXTRA_SUBFIELD_MAX_SIZE => 0xFFFF ;
+# Extra Field ID's
+use constant ZIP_EXTRA_ID_EXT_TIMESTAMP => "UT";
+use constant ZIP_EXTRA_ID_INFO_ZIP_UNIX => "Ux";
-use constant GZIP_FNAME_INVALID_CHAR_RE => qr/[\x00-\x1F\x7F-\x9F]/;
-use constant GZIP_FCOMMENT_INVALID_CHAR_RE => qr/[\x00-\x09\x11-\x1F\x7F-\x9F]/;
+%ZIP_CM_MIN_VERSIONS = (
+ ZIP_CM_STORE() => 20,
+ ZIP_CM_DEFLATE() => 20,
+ ZIP_CM_BZIP2() => 46,
+ );
-use constant GZIP_FHCRC_SIZE => 2 ; # aka CONTINUATION in gzip
-use constant ZIP_CM_STORE => 0 ;
-use constant ZIP_CM_DEFLATE => 8 ;
-use constant ZIP_CM_BZIP2 => 12 ;
+1;
-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 ;
-%ZIP_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',
- ) ;
+__END__
-1;
our ($VERSION, @ISA, @EXPORT);
-$VERSION = '2.000_11';
+$VERSION = '2.000_12';
@ISA = qw(Exporter);
--- /dev/null
+package IO::Compress::Zlib::Extra;
+
+require 5.004 ;
+
+use strict ;
+use warnings;
+use bytes;
+
+our ($VERSION, @ISA, @EXPORT_OK, %EXPORT_TAGS);
+
+$VERSION = '2.000_12';
+
+use IO::Compress::Gzip::Constants;
+
+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 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 $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);
+ #$out .= $pair->[0] . pack("v", length $pair->[1]) .
+ # $pair->[1] ;
+ }
+ }
+ else {
+ return ExtraFieldError("Not even number of elements")
+ unless @$data % 2 == 0;
+
+ for (my $ix = 0; $ix <= length(@$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]);
+ #$out .= $data->[$ix] . pack("v", length $data->[$ix+1]) .
+ # $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);
+ #$out .= $id . pack("v", length $info) . $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__
our ($VERSION);
-$VERSION = '2.000_11';
+$VERSION = '2.000_12';
use Compress::Raw::Zlib ();
use Compress::Raw::Zlib qw(Z_OK Z_DATA_ERROR Z_STREAM_END Z_FINISH MAX_WBITS);
our ($VERSION);
-$VERSION = '2.000_11';
+$VERSION = '2.000_12';
our ($VERSION, @ISA, @EXPORT_OK, %EXPORT_TAGS, $AnyInflateError);
-$VERSION = '2.000_11';
+$VERSION = '2.000_12';
$AnyInflateError = '';
@ISA = qw( Exporter IO::Uncompress::Base );
=head2 Notes
-When C<$input> maps to multiple files/buffers and C<$output> is a single
-file/buffer the uncompressed input files/buffers will all be stored
-in C<$output> as a single uncompressed stream.
+
+When C<$input> maps to multiple compressed files/buffers and C<$output> is
+a single file/buffer, after uncompression C<$output> will contain a
+concatenation of all the uncompressed data from each of the input
+files/buffers.
+
+
use Compress::Raw::Zlib qw( crc32 ) ;
use IO::Compress::Base::Common qw(:Status createSelfTiedObject);
use IO::Compress::Gzip::Constants;
+use IO::Compress::Zlib::Extra;
require Exporter ;
$GunzipError = '';
-$VERSION = '2.000_11';
+$VERSION = '2.000_12';
sub new
{
$keep .= $buffer . $EXTRA ;
if ($XLEN && *$self->{'ParseExtra'}) {
- my $offset = 0 ;
- while ($offset < $XLEN) {
-
- return $self->TruncatedHeader("FEXTRA Body")
- if $offset + GZIP_FEXTRA_SUBFIELD_HEADER_SIZE > $XLEN ;
-
- my $id = substr($EXTRA, $offset, GZIP_FEXTRA_SUBFIELD_ID_SIZE);
- $offset += GZIP_FEXTRA_SUBFIELD_ID_SIZE ;
-
- return $self->HeaderError("SubField ID 2nd byte is 0x00")
- if *$self->{Strict} && substr($id, 1, 1) eq "\x00" ;
-
- my ($subLen) = unpack("v", substr($EXTRA, $offset,
- GZIP_FEXTRA_SUBFIELD_LEN_SIZE)) ;
- $offset += GZIP_FEXTRA_SUBFIELD_LEN_SIZE ;
-
- return $self->TruncatedHeader("FEXTRA Body")
- if $offset + $subLen > $XLEN ;
-
- push @EXTRA, [$id => substr($EXTRA, $offset, $subLen)];
- $offset += $subLen ;
- }
+ my $bad = IO::Compress::Zlib::Extra::parseRawExtra($EXTRA,
+ \@EXTRA, 1, 1);
+ return $self->HeaderError($bad)
+ if defined $bad;
}
}
=head2 Notes
-When C<$input> maps to multiple files/buffers and C<$output> is a single
-file/buffer the uncompressed input files/buffers will all be stored
-in C<$output> as a single uncompressed stream.
+
+When C<$input> maps to multiple compressed files/buffers and C<$output> is
+a single file/buffer, after uncompression C<$output> will contain a
+concatenation of all the uncompressed data from each of the input
+files/buffers.
+
+
require Exporter ;
our ($VERSION, @ISA, @EXPORT_OK, %EXPORT_TAGS, $InflateError);
-$VERSION = '2.000_11';
+$VERSION = '2.000_12';
$InflateError = '';
@ISA = qw( Exporter IO::Uncompress::RawInflate );
=head2 Notes
-When C<$input> maps to multiple files/buffers and C<$output> is a single
-file/buffer the uncompressed input files/buffers will all be stored
-in C<$output> as a single uncompressed stream.
+
+When C<$input> maps to multiple compressed files/buffers and C<$output> is
+a single file/buffer, after uncompression C<$output> will contain a
+concatenation of all the uncompressed data from each of the input
+files/buffers.
+
+
require Exporter ;
our ($VERSION, @ISA, @EXPORT_OK, %EXPORT_TAGS, %DEFLATE_CONSTANTS, $RawInflateError);
-$VERSION = '2.000_11';
+$VERSION = '2.000_12';
$RawInflateError = '';
@ISA = qw( Exporter IO::Uncompress::Base );
=head2 Notes
-When C<$input> maps to multiple files/buffers and C<$output> is a single
-file/buffer the uncompressed input files/buffers will all be stored
-in C<$output> as a single uncompressed stream.
+
+When C<$input> maps to multiple compressed files/buffers and C<$output> is
+a single file/buffer, after uncompression C<$output> will contain a
+concatenation of all the uncompressed data from each of the input
+files/buffers.
+
+
use IO::Uncompress::RawInflate ;
use IO::Compress::Base::Common qw(:Status createSelfTiedObject);
use IO::Uncompress::Adapter::Identity;
+use IO::Compress::Zlib::Extra;
+use IO::Compress::Zip::Constants;
use Compress::Raw::Zlib qw(crc32) ;
+
BEGIN
{
- eval { require IO::Uncompress::Adapter::Bunzip2 ;
- import IO::Uncompress::Adapter::Bunzip2 } ;
+ eval { require IO::Uncompress::Adapter::Bunzip2 ;
+ import IO::Uncompress::Adapter::Bunzip2 } ;
}
our ($VERSION, @ISA, @EXPORT_OK, %EXPORT_TAGS, $UnzipError);
-$VERSION = '2.000_11';
+$VERSION = '2.000_12';
$UnzipError = '';
@ISA = qw(Exporter IO::Uncompress::RawInflate);
push @{ $EXPORT_TAGS{all} }, @EXPORT_OK ;
Exporter::export_ok_tags('all');
-
sub new
{
my $class = shift ;
if (*$self->{ZipData}{Streaming}) {
($sig, $CRC32, $cSize, $uSize) = unpack("V V V V", $trailer) ;
return $self->TrailerError("Data Descriptor signature, got $sig")
- if $sig != 0x08074b50;
+ if $sig != ZIP_DATA_HDR_SIG;
}
else {
($CRC32, $cSize, $uSize) =
my $sig = unpack("V", $magic) ;
- if ($sig == 0x02014b50)
+ if ($sig == ZIP_CENTRAL_HDR_SIG)
{
if ($self->skipCentralDirectory($magic) != STATUS_OK ) {
if (*$self->{Strict}) {
}
}
}
- elsif ($sig == 0x06054b50)
+ elsif ($sig == ZIP_END_CENTRAL_HDR_SIG)
{
if ($self->skipEndCentralDirectory($magic) != STATUS_OK) {
if (*$self->{Strict}) {
return STATUS_OK ;
last;
}
- elsif ($sig == 0x04034b50)
+ elsif ($sig == ZIP_LOCAL_HDR_SIG)
{
$self->pushBack($magic) ;
return STATUS_OK ;
my $buffer = shift ;
return 0 if length $buffer < 4 ;
my $sig = unpack("V", $buffer) ;
- return $sig == 0x04034b50 ;
+ return $sig == ZIP_LOCAL_HDR_SIG ;
}
my $filename;
my $extraField;
- my $streamingMode = ($gpFlag & 0x08) ? 1 : 0 ;
+ my @EXTRA = ();
+ my $streamingMode = ($gpFlag & ZIP_GP_FLAG_STREAMING_MASK) ? 1 : 0 ;
return $self->HeaderError("Streamed Stored content not supported")
if $streamingMode && $compressedMethod == 0 ;
if ($filename_length)
{
$self->smartReadExact(\$filename, $filename_length)
- or return $self->HeaderError("xxx");
+ or return $self->TruncatedHeader("Filename");
$keep .= $filename ;
}
if ($extra_length)
{
$self->smartReadExact(\$extraField, $extra_length)
- or return $self->HeaderError("xxx");
+ or return $self->TruncatedHeader("Extra Field");
+
+ my $bad = IO::Compress::Zlib::Extra::parseRawExtra($extraField,
+ \@EXTRA, 1, 0);
+ return $self->HeaderError($bad)
+ if defined $bad;
+
$keep .= $extraField ;
}
*$self->{ZipData}{Method} = $compressedMethod;
- if ($compressedMethod == 8)
+ if ($compressedMethod == ZIP_CM_DEFLATE)
{
*$self->{Type} = 'zip-deflate';
}
- elsif ($compressedMethod == 12)
+ elsif ($compressedMethod == ZIP_CM_BZIP2)
{
#if (! defined $IO::Uncompress::Adapter::Bunzip2::VERSION)
*$self->{ZipData}{CRC32} = crc32(undef);
}
- elsif ($compressedMethod == 0)
+ elsif ($compressedMethod == ZIP_CM_STORE)
{
# TODO -- add support for reading uncompressed
'Stream' => $streamingMode,
'MethodID' => $compressedMethod,
- 'MethodName' => $compressedMethod == 8
+ 'MethodName' => $compressedMethod == ZIP_CM_DEFLATE
? "Deflated"
- : $compressedMethod == 0
- ? "Stored"
- : "Unknown" ,
+ : $compressedMethod == ZIP_CM_BZIP2
+ ? "Bzip2"
+ : $compressedMethod == ZIP_CM_STORE
+ ? "Stored"
+ : "Unknown" ,
# 'TextFlag' => $flag & GZIP_FLG_FTEXT ? 1 : 0,
# 'HeaderCRCFlag' => $flag & GZIP_FLG_FHCRC ? 1 : 0,
# 'HeaderCRC' => $HeaderCRC,
# 'Flags' => $flag,
# 'ExtraFlags' => $xfl,
-# 'ExtraFieldRaw' => $EXTRA,
-# 'ExtraField' => [ @EXTRA ],
+ 'ExtraFieldRaw' => $extraField,
+ 'ExtraField' => [ @EXTRA ],
}
=head2 Notes
-When C<$input> maps to multiple files/buffers and C<$output> is a single
-file/buffer the uncompressed input files/buffers will all be stored
-in C<$output> as a single uncompressed stream.
+
+When C<$input> maps to multiple compressed files/buffers and C<$output> is
+a single file/buffer, after uncompression C<$output> will contain a
+concatenation of all the uncompressed data from each of the input
+files/buffers.
+
+
my @tests = (
["Sub-field truncated",
- "Error with ExtraField Parameter: FEXTRA Body",
+ "Error with ExtraField Parameter: Truncated in FEXTRA Body Section",
"Header Error: Truncated in FEXTRA Body Section",
['a', undef, undef] ],
["Length of field incorrect",
- "Error with ExtraField Parameter: FEXTRA Body",
+ "Error with ExtraField Parameter: Truncated in FEXTRA Body Section",
"Header Error: Truncated in FEXTRA Body Section",
["ab", 255, "abc"] ],
["Length of 2nd field incorrect",
- "Error with ExtraField Parameter: FEXTRA Body",
+ "Error with ExtraField Parameter: Truncated in FEXTRA Body Section",
"Header Error: Truncated in FEXTRA Body Section",
["ab", 3, "abc"], ["de", 7, "x"] ],
["Length of 2nd field incorrect",
"Error with ExtraField Parameter: SubField ID 2nd byte is 0x00",
- "Header Error: Truncated in FEXTRA Body Section",
+ "Header Error: SubField ID 2nd byte is 0x00",
["a\x00", 3, "abc"], ["de", 7, "x"] ],
);
foreach my $check (0, 1)
{
- ok $x = new IO::Compress::Gzip \$buffer, -ExtraField => $input, Strict => 0
- or diag "GzipError is $GzipError" ; ;
+ ok $x = new IO::Compress::Gzip \$buffer,
+ ExtraField => $input,
+ Strict => 0
+ or diag "GzipError is $GzipError" ;
my $string = "abcd" ;
$x->write($string) ;
$x->close ;
is anyUncompress(\$buffer), $string ;
- $x = new IO::Uncompress::Gunzip \$buffer, Strict => 0,
+ $x = new IO::Uncompress::Gunzip \$buffer,
+ Strict => 0,
Transparent => 0,
- ParseExtra => $check;
+ ParseExtra => $check;
if ($check) {
ok ! $x ;
like $GunzipError, "/^$gunzip_error/";
$extra = 1
if eval { require Test::NoWarnings ; import Test::NoWarnings; 1 };
- plan tests => 1986 + $extra;
+ plan tests => 2316 + $extra;
};
--- /dev/null
+CHANGES
+-------
+
+ 2.000_10 13 March 2006
+
+ * Fixed a potential NULL pointer dereference problem in
+ Compress::Raw::Zlib::resetLastBlockByte.
+ Issue highlighted by David Dyck and reproduced by Marcus Holland-Moritz.
+
+ 2.000_09 3 March 2006
+
+ * Released onto CPAN
+
+ * Documentation updates.
+
+ 2.000_08 2 March 2006
+
+ * Moved the IO::* modules out into their own distributions.
+
+ * Breakout zlib specific code into separate modules.
+
+ * Limited support for reading/writing zip files added.
+
+ 2.000_06 5 October 2005
+
+ * Added eof parameter to Compress::Zlib::inflate method.
+
+ * Fixed issue with 64-bit
+
+ 2.000_05 4 October 2005
+
+ * Renamed IO::* to IO::Compress::* & IO::Uncompress::*
+
+ 2.000_04 23 September 2005
+
+ * Fixed some more non-portable test that were failing on VMS.
+
+ * fixed problem where error messages in the oneshot interface were
+ getting lost.
+
+ 2.000_03 12 September 2005
+
+ * Fixed some non-portable test that were failing on VMS.
+
+ * Fixed export of zlib constants from the IO::* classes
+
+ 2.000_02 6 September 2005
+
+ * Split Append mode into Append and Merge
+
+ * Fixed typos in the documentation.
+
+ * Added pod/FAQ.pod
+
+ * Added libscan to Makefile.PL
+
+ * Added InputLength for IO::Gunzip et al
+
+ 2.000_01 22 August 2005
+
+ * Fixed VERSION in Compress::Gzip::Constants
+
+ * Removed Compress::Gzip::Info from the distribution.
+
+ 2.000_00 21 August 2005
+
+ * First Beta relase of Compress::zlib rewrite.
+
Compress::Raw::Zlib
- Version 2.000_11
+ Version 2.000_12
- 10 April 2006
+ 17 May 2006
Copyright (c) 2005-2006 Paul Marquess. All rights reserved.
use bytes ;
our ($VERSION, $XS_VERSION, @ISA, @EXPORT, $AUTOLOAD);
-$VERSION = '2.000_11';
+$VERSION = '2.000_12';
$XS_VERSION = $VERSION;
$VERSION = eval $VERSION;
CHANGES
-------
+ 2.000_12 16 April 2006
+
+ * Fixed gzread to zap the output buffer to an empty string when zero
+ bytes are requested. This matches the behaviour of C::Z 1.x
+
+ 2.000_11 10 April 2006
+
+ * No changes.
+
2.000_10 13 March 2006
* Changed gzread so that its behaviour matches C::Z::gzread 1.x if it
Compress::Zlib
- Version 2.000_11
+ Version 2.000_12
- 10 April 2006
+ 17 May 2006
Copyright (c) 1995-2006 Paul Marquess. All rights reserved.
use bytes ;
our ($VERSION, $XS_VERSION, @ISA, @EXPORT, $AUTOLOAD);
-$VERSION = '2.000_11';
+$VERSION = '2.000_12';
$XS_VERSION = $VERSION;
$VERSION = eval $VERSION;
if ($class eq 'IO::Compress::Gzip') {
%params = (
- -Name => "My name",
- -Comment => "a comment",
- -ExtraField => ['ab' => "extra"],
- -HeaderCRC => 1);
+ Name => "My name",
+ Comment => "a comment",
+ ExtraField => ['ab' => "extra"],
+ HeaderCRC => 1);
}
elsif ($class eq 'IO::Compress::Zip'){
%params = (
- # TODO -- add more here
- -Name => "My name",
- -Comment => "a comment",
+ Name => "My name",
+ Comment => "a comment",
+ ZipComment => "last comment",
+ exTime => [100, 200, 300],
+ ExtraFieldLocal => ["ab" => "extra1"],
+ ExtraFieldCentral => ["cd" => "extra2"],
);
}