CHANGES
-------
+ 2.002 29 December 2006
+
+ * Documentation updates.
+
2.001 1 November 2006
* Remove beta status.
Compress::Raw::Zlib
- Version 2.001
+ Version 2.002
- 1st November 2006
+ 29th December 2006
Copyright (c) 2005-2006 Paul Marquess. All rights reserved.
use bytes ;
our ($VERSION, $XS_VERSION, @ISA, @EXPORT, $AUTOLOAD);
-$VERSION = '2.001';
+$VERSION = '2.002';
$XS_VERSION = $VERSION;
$VERSION = eval $VERSION;
CHANGES
-------
+ 2.002 29 December 2006
+
+ * Documentation updates.
+
+ * Fix append mode with gzopen.
+ rt-cpan.org 24041
+
+ * Allow gzopen to read from and write to a scalar reference.
+
2.001 1 November 2006
* Remove beta status.
Compress::Zlib
- Version 2.001
+ Version 2.002
- 1st November 2006
+ 29th December 2006
Copyright (c) 1995-2006 Paul Marquess. All rights reserved.
use bytes ;
our ($VERSION, $XS_VERSION, @ISA, @EXPORT, $AUTOLOAD);
-$VERSION = '2.001';
+$VERSION = '2.002';
$XS_VERSION = $VERSION;
$VERSION = eval $VERSION;
$defOpts{Level} = $1 if $mode =~ /(\d)/;
$defOpts{Strategy} = Z_FILTERED() if $mode =~ /f/i;
$defOpts{Strategy} = Z_HUFFMAN_ONLY() if $mode =~ /h/i;
+ $defOpts{Append} = 1 if $mode =~ /a/i;
my $infDef = $writing ? 'deflate' : 'inflate';
my @params = () ;
croak "gzopen: file parameter is not a filehandle or filename"
- unless isaFilehandle $file || isaFilename $file ;
+ unless isaFilehandle $file || isaFilename $file ||
+ (ref $file && ref $file eq 'SCALAR');
return undef unless $mode =~ /[rwa]/i ;
Transparent => 1,
Append => 0,
AutoClose => 1,
+ MultiStream => 1,
Strict => 0)
or $Compress::Zlib::gzerrno = $IO::Uncompress::Gunzip::GunzipError;
}
functionality, namely a simple read/write interface to I<gzip> files
and a low-level in-memory compression/decompression interface.
-Each of these areas will be discussed separately below.
+Each of these areas will be discussed in the following sections.
=head2 Notes for users of Compress::Zlib version 1
-Version 2 of this module is a total rewrite. The net result of this is that
-C<Compress::Zlib> does not now access the zlib library directly.
+The main change in C<Compress::Zlib> version 2.x is that it does not now
+interface directly to the zlib library. Instead it uses the
+C<IO::Compress::Gzip> and C<IO::Uncompress::Gunzip> modules for
+reading/writing gzip files, and the C<Compress::Raw::Zlib> module for some
+low-level zlib access.
-It now uses the C<IO::Compress::Gzip> and C<IO::Uncompress::Gunzip> modules
-for reading/writing gzip files, and the C<Compress::Raw::Zlib> module for
-low-level zlib access.
+The interface provided by version 2 should be 100% backward compatible with
+version 1. If you find a difference in the expected behaviour please
+contact the author (See L</AUTHOR>). See L<GZIP INTERFACE>
If you are writing new code, your first port of call should be to use one
these new modules.
I<gzip> files that conform to RFC 1952. This module provides an interface
to most of them.
-If you are upgrading from C<Compress::Zlib> 1.x, the following
+If you have previously used C<Compress::Zlib> 1.x, the following
enhancements/changes have been made to the C<gzopen> interface:
=over 5
writing or attaches to the opened filehandle, C<$filehandle>.
It returns an object on success and C<undef> on failure.
-When writing a gzip file this interface will always create the smallest
+When writing a gzip file this interface will I<always> create the smallest
possible gzip header (exactly 10 bytes). If you want greater control over
-the information stored in the gzip header (like the original filename or a
-comment) use L<IO::Compress::Gzip|IO::Compress::Gzip> instead.
+what gets stored in the gzip header (like the original filename or a
+comment) use L<IO::Compress::Gzip|IO::Compress::Gzip> instead. Similarly if
+you want to read the contents of the gzip header use
+L<IO::Uncompress::Gunzip|IO::Uncompress::Gunzip>.
The second parameter, C<$mode>, is used to specify whether the file is
opened for reading or writing and to optionally specify a compression
level and compression strategy when writing. The format of the C<$mode>
parameter is similar to the mode parameter to the 'C' function C<fopen>,
-so "rb" is used to open for reading and "wb" for writing.
+so "rb" is used to open for reading, "wb" for writing and "ab" for
+appending (writing at the end of the file).
To specify a compression level when writing, append a digit between 0
and 9 to the mode string -- 0 means no compression and 9 means maximum
Refer to the I<zlib> documentation for the exact format of the C<$mode>
parameter.
-
=item B<$bytesread = $gz-E<gt>gzread($buffer [, $size]) ;>
Reads C<$size> bytes from the compressed file into C<$buffer>. If
my $count = 0 ;
if ($] < 5.005) {
- $count = 353 ;
+ $count = 383 ;
}
else {
- $count = 364 ;
+ $count = 394 ;
}
{
title "Check all bytes can be handled";
- my $lex = "\r\n" . new LexFile my $name ;
+ my $lex = new LexFile my $name ;
my $data = join '', map { chr } 0x00 .. 0xFF;
$data .= "\r\nabd\r\n";
ok $@ =~ /^gzopen: file parameter is not a filehandle or filename at/
or print "# $@\n" ;
- my $x = Symbol::gensym() ;
- eval { gzopen($x, 0) ; } ;
- ok $@ =~ /^gzopen: file parameter is not a filehandle or filename at/
- or print "# $@\n" ;
+# my $x = Symbol::gensym() ;
+# eval { gzopen($x, 0) ; } ;
+# ok $@ =~ /^gzopen: file parameter is not a filehandle or filename at/
+# or print "# $@\n" ;
}
}
+sub slurp
+{
+ my $name = shift ;
+
+ my $input;
+ my $fil = gzopen($name, "rb") ;
+ ok $fil , "opened $name";
+ cmp_ok $fil->gzread($input, 50000), ">", 0, "read more than zero bytes";
+ ok ! $fil->gzclose(), "closed ok";
+
+ return $input;
+}
+
+sub trickle
+{
+ my $name = shift ;
+
+ my $got;
+ my $input;
+ $fil = gzopen($name, "rb") ;
+ ok $fil, "opened ok";
+ while ($fil->gzread($input, 50000) > 0)
+ {
+ $got .= $input;
+ $input = '';
+ }
+ ok ! $fil->gzclose(), "closed ok";
+ return $got;
+ return $input;
+}
+
+{
+
+ title "Append & MultiStream Tests";
+ # rt.24041
+
+ my $lex = new LexFile my $name ;
+ my $data1 = "the is the first";
+ my $data2 = "and this is the second";
+ my $trailing = "some trailing data";
+
+ my $fil;
+
+ title "One file";
+ $fil = gzopen($name, "wb") ;
+ ok $fil, "opened first file";
+ is $fil->gzwrite($data1), length $data1, "write data1" ;
+ ok ! $fil->gzclose(), "Closed";
+
+ is slurp($name), $data1, "got expected data from slurp";
+ is trickle($name), $data1, "got expected data from trickle";
+
+ title "Two files";
+ $fil = gzopen($name, "ab") ;
+ ok $fil, "opened second file";
+ is $fil->gzwrite($data2), length $data2, "write data2" ;
+ ok ! $fil->gzclose(), "Closed";
+
+ is slurp($name), $data1 . $data2, "got expected data from slurp";
+ is trickle($name), $data1 . $data2, "got expected data from trickle";
+
+ title "Trailing Data";
+ open F, ">>$name";
+ print F $trailing;
+ close F;
+
+ is slurp($name), $data1 . $data2 . $trailing, "got expected data from slurp" ;
+ is trickle($name), $data1 . $data2 . $trailing, "got expected data from trickle" ;
+}
SKIP:
{
my $lex = new LexFile my $name ;
+ skip "Cannot create non-readable file", 3
+ if $^O eq 'cygwin';
+
writeFile($name, "abc");
chmod 0222, $name ;
CHANGES
-------
+ 2.002 29 December 2006
+
+ * Documentation updates.
+
+ * Added IO::Handle to the ISA test in isaFilehandle
+
+ * Add an explicit use_ok test for Scalar::Util in the test harness.
+ The error message reported by 01misc implied the problem was
+ somewhere else.
+ Also explictly check that 'dualvar' is available.
+
2.001 1 November 2006
* Remove beta status.
IO::Compress::Base
- Version 2.001
+ Version 2.002
- 1st November 2006
+ 29th December 2006
Copyright (c) 2005-2006 Paul Marquess. All rights reserved.
our (@ISA, $VERSION, $got_encode);
#@ISA = qw(Exporter IO::File);
-$VERSION = '2.001';
+$VERSION = '2.002';
#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.
my $self = shift ;
$self->close() ;
-
# TODO - memory leak with 5.8.0 - this isn't called until
# global destruction
#
# This delete can set $! in older Perls, so reset the errno
$! = 0 ;
}
-
+
return 1;
}
require Exporter;
our ($VERSION, @ISA, @EXPORT, %EXPORT_TAGS);
@ISA = qw(Exporter);
-$VERSION = '2.001';
+$VERSION = '2.002';
@EXPORT = qw( isaFilehandle isaFilename whatIsInput whatIsOutput
isaFileGlobString cleanFileGlobString oneTarget
{
use utf8; # Pragma needed to keep Perl 5.6.0 happy
return (defined $_[0] and
- (UNIVERSAL::isa($_[0],'GLOB') or UNIVERSAL::isa(\$_[0],'GLOB'))
- and defined fileno($_[0]) )
+ (UNIVERSAL::isa($_[0],'GLOB') or
+ UNIVERSAL::isa($_[0],'IO::Handle') or
+ UNIVERSAL::isa(\$_[0],'GLOB'))
+ )
}
sub isaFilename($)
our ($VERSION, @ISA, @EXPORT_OK, %EXPORT_TAGS, $AnyUncompressError);
-$VERSION = '2.001';
+$VERSION = '2.002';
$AnyUncompressError = '';
@ISA = qw( Exporter IO::Uncompress::Base );
=item C<< Transparent => 0|1 >>
-If this option is set and the input file or buffer is not compressed data,
+If this option is set and the input file/buffer is not compressed data,
the module will allow reading of it anyway.
+In addition, if the input file/buffer does contain compressed data and
+there is non-compressed data immediately following it, setting this option
+will make this module treat the whole file/bufffer as a single data stream.
+
This option defaults to 1.
=item C<< BlockSize => $num >>
@ISA = qw(Exporter );
-$VERSION = '2.001';
+$VERSION = '2.002';
use constant G_EOF => 0 ;
use constant G_ERR => -1 ;
*$self->{CompSize}->reset();
my $magic = $self->ckMagic();
+ #*$self->{EndStream} = 0 ;
if ( ! $magic) {
- *$self->{EndStream} = 1 ;
- return 0;
- }
+ if (! *$self->{Transparent} )
+ {
+ *$self->{EndStream} = 1 ;
+ return 0;
+ }
- *$self->{Info} = $self->readHeader($magic);
+ $self->clearError();
+ *$self->{Type} = 'plain';
+ *$self->{Plain} = 1;
+ $self->pushBack(*$self->{HeaderPending}) ;
+ }
+ else
+ {
+ *$self->{Info} = $self->readHeader($magic);
- if ( ! defined *$self->{Info} ) {
- *$self->{EndStream} = 1 ;
- return -1;
+ if ( ! defined *$self->{Info} ) {
+ *$self->{EndStream} = 1 ;
+ return -1;
+ }
}
push @{ *$self->{InfoList} }, *$self->{Info} ;
# Need to jump through more hoops - either length or offset
# or both are specified.
- my $out_buffer = \*$self->{Pending} ;
+ my $out_buffer = *$self->{Pending} ;
- while (! *$self->{EndStream} && length($$out_buffer) < $length)
+ while (! *$self->{EndStream} && length($out_buffer) < $length)
{
- my $buf_len = $self->_raw_read($out_buffer);
+ my $buf_len = $self->_raw_read(\$out_buffer);
return $buf_len
if $buf_len < 0 ;
}
- $length = length $$out_buffer
- if length($$out_buffer) < $length ;
+ $length = length $out_buffer
+ if length($out_buffer) < $length ;
return 0
if $length == 0 ;
+ *$self->{Pending} = $out_buffer;
+ $out_buffer = \*$self->{Pending} ;
+
if ($offset) {
$$buffer .= "\x00" x ($offset - length($$buffer))
if $offset > length($$buffer) ;
$extra = 1
if eval { require Test::NoWarnings ; import Test::NoWarnings; 1 };
- plan tests => 76 + $extra ;
+ plan tests => 78 + $extra ;
+ use_ok('Scalar::Util');
use_ok('IO::Compress::Base::Common');
}
+
+ok gotScalarUtilXS(), "Got XS Version of Scalar::Util"
+ or diag <<EOM;
+You don't have the XS version of Scalar::Util
+EOM
+
# Compress::Zlib::Common;
sub My::testParseParameters()
CHANGES
-------
+ 2.002 29 December 2006
+
+ * Documentation updates.
+
2.001 1 November 2006
* Remove beta status.
IO::Compress::Zlib
- Version 2.001
+ Version 2.002
- 1st November 2006
+ 29th December 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.001';
+$VERSION = '2.002';
sub mkCompObject
{
use IO::Compress::Base::Common qw(:Status);
our ($VERSION);
-$VERSION = '2.001';
+$VERSION = '2.002';
sub mkCompObject
{
our ($VERSION, @ISA, @EXPORT_OK, %EXPORT_TAGS, $DeflateError);
-$VERSION = '2.001';
+$VERSION = '2.002';
$DeflateError = '';
@ISA = qw(Exporter IO::Compress::RawDeflate);
our ($VERSION, @ISA, @EXPORT_OK, %EXPORT_TAGS, $GzipError);
-$VERSION = '2.001';
+$VERSION = '2.002';
$GzipError = '' ;
@ISA = qw(Exporter IO::Compress::RawDeflate);
our ($VERSION, @ISA, @EXPORT, %GZIP_OS_Names);
our ($GZIP_FNAME_INVALID_CHAR_RE, $GZIP_FCOMMENT_INVALID_CHAR_RE);
-$VERSION = '2.001';
+$VERSION = '2.002';
@ISA = qw(Exporter);
our ($VERSION, @ISA, @EXPORT_OK, %DEFLATE_CONSTANTS, %EXPORT_TAGS, $RawDeflateError);
-$VERSION = '2.001';
+$VERSION = '2.002';
$RawDeflateError = '';
@ISA = qw(Exporter IO::Compress::Base);
our ($VERSION, @ISA, @EXPORT_OK, %EXPORT_TAGS, $ZipError);
-$VERSION = '2.001';
+$VERSION = '2.002';
$ZipError = '';
@ISA = qw(Exporter IO::Compress::RawDeflate);
our ($VERSION, @ISA, @EXPORT, %ZIP_CM_MIN_VERSIONS);
-$VERSION = '2.001';
+$VERSION = '2.002';
@ISA = qw(Exporter);
our ($VERSION, @ISA, @EXPORT);
-$VERSION = '2.001';
+$VERSION = '2.002';
@ISA = qw(Exporter);
our ($VERSION, @ISA, @EXPORT_OK, %EXPORT_TAGS);
-$VERSION = '2.001';
+$VERSION = '2.002';
use IO::Compress::Gzip::Constants;
our ($VERSION);
-$VERSION = '2.001';
+$VERSION = '2.002';
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.001';
+$VERSION = '2.002';
our ($VERSION, @ISA, @EXPORT_OK, %EXPORT_TAGS, $AnyInflateError);
-$VERSION = '2.001';
+$VERSION = '2.002';
$AnyInflateError = '';
@ISA = qw( Exporter IO::Uncompress::Base );
=item C<< Transparent => 0|1 >>
-If this option is set and the input file or buffer is not compressed data,
+If this option is set and the input file/buffer is not compressed data,
the module will allow reading of it anyway.
+In addition, if the input file/buffer does contain compressed data and
+there is non-compressed data immediately following it, setting this option
+will make this module treat the whole file/bufffer as a single data stream.
+
This option defaults to 1.
=item C<< BlockSize => $num >>
$GunzipError = '';
-$VERSION = '2.001';
+$VERSION = '2.002';
sub new
{
=item C<< Transparent => 0|1 >>
-If this option is set and the input file or buffer is not compressed data,
+If this option is set and the input file/buffer is not compressed data,
the module will allow reading of it anyway.
+In addition, if the input file/buffer does contain compressed data and
+there is non-compressed data immediately following it, setting this option
+will make this module treat the whole file/bufffer as a single data stream.
+
This option defaults to 1.
=item C<< BlockSize => $num >>
require Exporter ;
our ($VERSION, @ISA, @EXPORT_OK, %EXPORT_TAGS, $InflateError);
-$VERSION = '2.001';
+$VERSION = '2.002';
$InflateError = '';
@ISA = qw( Exporter IO::Uncompress::RawInflate );
=item C<< Transparent => 0|1 >>
-If this option is set and the input file or buffer is not compressed data,
+If this option is set and the input file/buffer is not compressed data,
the module will allow reading of it anyway.
+In addition, if the input file/buffer does contain compressed data and
+there is non-compressed data immediately following it, setting this option
+will make this module treat the whole file/bufffer as a single data stream.
+
This option defaults to 1.
=item C<< BlockSize => $num >>
require Exporter ;
our ($VERSION, @ISA, @EXPORT_OK, %EXPORT_TAGS, %DEFLATE_CONSTANTS, $RawInflateError);
-$VERSION = '2.001';
+$VERSION = '2.002';
$RawInflateError = '';
@ISA = qw( Exporter IO::Uncompress::Base );
-This option is a no-op.
+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.
+This parameter defaults to 0.
=item C<< Prime => $string >>
=item C<< Transparent => 0|1 >>
-If this option is set and the input file or buffer is not compressed data,
+If this option is set and the input file/buffer is not compressed data,
the module will allow reading of it anyway.
+In addition, if the input file/buffer does contain compressed data and
+there is non-compressed data immediately following it, setting this option
+will make this module treat the whole file/bufffer as a single data stream.
+
This option defaults to 1.
=item C<< BlockSize => $num >>
our ($VERSION, @ISA, @EXPORT_OK, %EXPORT_TAGS, $UnzipError, %headerLookup);
-$VERSION = '2.001';
+$VERSION = '2.002';
$UnzipError = '';
@ISA = qw(Exporter IO::Uncompress::RawInflate);
=item C<< Transparent => 0|1 >>
-If this option is set and the input file or buffer is not compressed data,
+If this option is set and the input file/buffer is not compressed data,
the module will allow reading of it anyway.
+In addition, if the input file/buffer does contain compressed data and
+there is non-compressed data immediately following it, setting this option
+will make this module treat the whole file/bufffer as a single data stream.
+
This option defaults to 1.
=item C<< BlockSize => $num >>
return (1,0);
}
+
+sub gotScalarUtilXS
+{
+ eval ' use Scalar::Util "dualvar" ';
+ return $@ ? 0 : 1 ;
+}
+
package CompTestUtils;
1;
ok $gz->close(), " close() ok"
or diag "errno $!\n" ;
- is $gz->streamCount(), $i +1, " streamCount ok"
+ is $gz->streamCount(), $i +1, " streamCount ok " . ($i +1)
or diag "Stream count is " . $gz->streamCount();
ok $un eq join('', @buffs), " expected output" ;
like $@, mkErr("^$TopType: input and output buffer are identical"),
' Input and Output buffer are the same';
- my $lex = new LexFile my $out_file ;
- open OUT, ">$out_file" ;
- eval { $a = $Func->(\*OUT, \*OUT) ;} ;
- like $@, mkErr("^$TopType: input and output handle are identical"),
- ' Input and Output handle are the same';
-
- close OUT;
- is -s $out_file, 0, " File zero length" ;
+ SKIP:
+ {
+ # Threaded 5.6.x seems to have a problem comparing filehandles.
+ use Config;
+
+ skip 'Cannot compare filehandles with threaded $]', 2
+ if $] >= 5.006 && $] < 5.007 && $Config{useithreads};
+
+ my $lex = new LexFile my $out_file ;
+ open OUT, ">$out_file" ;
+ eval { $a = $Func->(\*OUT, \*OUT) ;} ;
+ like $@, mkErr("^$TopType: input and output handle are identical"),
+ ' Input and Output handle are the same';
+
+ close OUT;
+ is -s $out_file, 0, " File zero length" ;
+ }
+
{
my %x = () ;
my $object = bless \%x, "someClass" ;