package IO::Uncompress::UnLzip ;
use strict ;
use warnings;
use bytes;
use IO::Compress::Base::Common 2.101 qw(:Status createSelfTiedObject);
use IO::Uncompress::Base 2.101 ;
use IO::Uncompress::Adapter::UnLzip 2.101 ;
require Exporter ;
our ($VERSION, @ISA, @EXPORT_OK, %EXPORT_TAGS, $UnLzipError);
$VERSION = '2.101';
$UnLzipError = '';
@ISA = qw( IO::Uncompress::Base Exporter );
@EXPORT_OK = qw( $UnLzipError unlzip ) ;
#%EXPORT_TAGS = %IO::Uncompress::Base::EXPORT_TAGS ;
push @{ $EXPORT_TAGS{all} }, @EXPORT_OK ;
#Exporter::export_ok_tags('all');
sub new
{
my $class = shift ;
my $obj = createSelfTiedObject($class, \$UnLzipError);
$obj->_create(undef, 0, @_);
}
sub unlzip
{
my $obj = createSelfTiedObject(undef, \$UnLzipError);
return $obj->_inf(@_);
}
#our %PARAMS = (
#'verbosity' => [IO::Compress::Base::Common::Parse_boolean, 0],
#'small' => [IO::Compress::Base::Common::Parse_boolean, 0],
# );
sub getExtraParams
{
return ();
}
sub ckParams
{
my $self = shift ;
my $got = shift ;
return 1;
}
sub mkUncomp
{
my $self = shift ;
my $got = shift ;
my $magic = $self->ckMagic()
or return 0;
*$self->{Info} = $self->readHeader($magic)
or return undef ;
my $Small = $got->getValue('small');
my $Verbosity = $got->getValue('verbosity');
my ($obj, $errstr, $errno) = IO::Uncompress::Adapter::UnLzip::mkUncompObject(
*$self->{Info}{DictSize});
return $self->saveErrorString(undef, $errstr, $errno)
if ! defined $obj;
*$self->{Uncomp} = $obj;
return 1;
}
sub ckMagic
{
my $self = shift;
my $magic ;
$self->smartReadExact(\$magic, 4);
*$self->{HeaderPending} = $magic ;
return $self->HeaderError("Minimum header size is " .
4 . " bytes")
if length $magic != 4 ;
return $self->HeaderError("Bad Magic")
if $magic ne 'LZIP' ;
*$self->{Type} = 'lzip';
return $magic ;
}
sub readHeader
{
my $self = shift;
my $magic = shift ;
my ($buffer) = '' ;
$self->smartReadExact(\$buffer, 2)
or return $self->HeaderError("Minimum header size is " .
2 . " bytes") ;
my $keep = $magic . $buffer ;
*$self->{HeaderPending} = $keep ;
my ($VN, $DS) = unpack("C C", $buffer) ;
# Version should be 0 or 1
return $self->HeaderError("lzip version not 0 or 1: $VN")
unless $VN == 0 or $VN == 1 ;
# Dictionary logic derived from libarchive archive_read_support_filter_xz.c
my $log2dic = $DS & 0x1f;
return $self->HeaderError("Bad Dictionary Value")
if $log2dic < 12 || $log2dic > 27 ;
my $dicsize = 1 << $log2dic;
$dicsize -= ($dicsize / 16) * ($DS >> 5)
if $log2dic > 12 ;
return {
'Type' => 'lzip',
'Version' => $VN,
'FingerprintLength' => 4,
'HeaderLength' => 6,
'TrailerLength' => $VN ? 20 : 12,
'Header' => $keep,
'Version' => $VN,
'DictSize' => $dicsize,
};
}
sub chkTrailer
{
my $self = shift;
my $trailer = shift;
my $not_version_0 = *$self->{Info}{Version} != 0;
# Check CRC & ISIZE
my $CRC32 = unpack("V", $trailer) ;
my $uSize = U64::newUnpack_V64 substr($trailer, 4, 8);
my $mSize;
if ($not_version_0)
{
$mSize = U64::newUnpack_V64 substr($trailer, 12, 8);
*$self->{Info}{CompressedLength} = $mSize->get64bit();
}
*$self->{Info}{CRC32} = $CRC32;
*$self->{Info}{UncompressedLength} = $uSize->get64bit();
if (*$self->{Strict}) {
return $self->TrailerError("CRC mismatch")
if $CRC32 != *$self->{Uncomp}->crc32() ;
return $self->TrailerError("USIZE mismatch.")
if ! $uSize->equal(*$self->{UnCompSize});
if ($not_version_0)
{
$mSize->subtract(6 + 20); # header & trailer
return $self->TrailerError("CSIZE mismatch.")
if ! $mSize->equal(*$self->{CompSize});
}
}
return STATUS_OK;
}
1 ;
__END__
=head1 NAME
IO::Uncompress::UnLzip - Read lzip files/buffers
=head1 SYNOPSIS
use IO::Uncompress::UnLzip qw(unlzip $UnLzipError) ;
my $status = unlzip $input => $output [,OPTS]
or die "unlzip failed: $UnLzipError\n";
my $z = IO::Uncompress::UnLzip->new( $input [OPTS] )
or die "unlzip failed: $UnLzipError\n";
$status = $z->read($buffer)
$status = $z->read($buffer, $length)
$status = $z->read($buffer, $length, $offset)
$line = $z->getline()
$char = $z->getc()
$char = $z->ungetc()
$char = $z->opened()
$data = $z->trailingData()
$status = $z->nextStream()
$data = $z->getHeaderInfo()
$z->tell()
$z->seek($position, $whence)
$z->binmode()
$z->fileno()
$z->eof()
$z->close()
$UnLzipError ;
# IO::File mode
<$z>
read($z, $buffer);
read($z, $buffer, $length);
read($z, $buffer, $length, $offset);
tell($z)
seek($z, $position, $whence)
binmode($z)
fileno($z)
eof($z)
close($z)
=head1 DESCRIPTION
This module provides a Perl interface that allows the reading of
lzma files/buffers.
For writing lzip files/buffers, see the companion module IO::Compress::Lzip.
=head1 Functional Interface
A top-level function, C, is provided to carry out
"one-shot" uncompression between buffers and/or files. For finer
control over the uncompression process, see the L"OO Interface">
section.
use IO::Uncompress::UnLzip qw(unlzip $UnLzipError) ;
unlzip $input_filename_or_reference => $output_filename_or_reference [,OPTS]
or die "unlzip failed: $UnLzipError\n";
The functional interface needs Perl5.005 or better.
=head2 unlzip $input_filename_or_reference => $output_filename_or_reference [, OPTS]
C expects at least two parameters,
C<$input_filename_or_reference> and C<$output_filename_or_reference>
and zero or more optional parameters (see L)
=head3 The C<$input_filename_or_reference> parameter
The parameter, C<$input_filename_or_reference>, is used to define the
source of the compressed data.
It can take one of the following forms:
=over 5
=item A filename
If the C<$input_filename_or_reference> parameter is a simple scalar, it is
assumed to be a filename. This file will be opened for reading and the
input data will be read from it.
=item A filehandle
If the C<$input_filename_or_reference> parameter is a filehandle, the input
data will be read from it. The string '-' can be used as an alias for
standard input.
=item A scalar reference
If C<$input_filename_or_reference> is a scalar reference, the input data
will be read from C<$$input_filename_or_reference>.
=item An array reference
If C<$input_filename_or_reference> is an array reference, each element in
the array must be a filename.
The input data will be read from each file in turn.
The complete array will be walked to ensure that it only
contains valid filenames before any data is uncompressed.
=item An Input FileGlob string
If C<$input_filename_or_reference> is a string that is delimited by the
characters "<" and ">" C will assume that it is an
I. The input is the list of files that match the
fileglob.
See L for more details.
=back
If the C<$input_filename_or_reference> parameter is any other type,
C will be returned.
=head3 The C<$output_filename_or_reference> parameter
The parameter C<$output_filename_or_reference> is used to control the
destination of the uncompressed data. This parameter can take one of
these forms.
=over 5
=item A filename
If the C<$output_filename_or_reference> parameter is a simple scalar, it is
assumed to be a filename. This file will be opened for writing and the
uncompressed data will be written to it.
=item A filehandle
If the C<$output_filename_or_reference> parameter is a filehandle, the
uncompressed data will be written to it. The string '-' can be used as
an alias for standard output.
=item A scalar reference
If C<$output_filename_or_reference> is a scalar reference, the
uncompressed data will be stored in C<$$output_filename_or_reference>.
=item An Array Reference
If C<$output_filename_or_reference> is an array reference,
the uncompressed data will be pushed onto the array.
=item An Output FileGlob
If C<$output_filename_or_reference> is a string that is delimited by the
characters "<" and ">" C will assume that it is an
I