pax_global_header00006660000000000000000000000064135730560340014520gustar00rootroot0000000000000052 comment=c348adae20b4606d304798df38c7cd89272efaa6 libio-compress-lzma-perl-2.093/000077500000000000000000000000001357305603400163655ustar00rootroot00000000000000libio-compress-lzma-perl-2.093/Changes000066400000000000000000000077401357305603400176700ustar00rootroot00000000000000CHANGES ------- 2.093 7 December 2019 * Fixed minor typo in the pod. PR https://github.com/pmqs/IO-Compress-Lzma/pull/3 e50eb1253e779f79918a3c9bd6a6fd714d1ef261 2.092 5 December 2019 * t/oooprereq.t: Fix list of dumped packages 90ebd567797ac332b210ef01a5af19af86eb94bc * t/oooprereq.t:Dump version data 227544c3ee3ffc181d0ffa93d60e5846930b497f 2.091 23 November 2019 * No Changes 2.090 9 November 2019 * typo change lzstrem to xzstream 5dfc9c97be1529d546ae0b11c3cf1bfb2f190ad4 2.089 3 November 2019 * No Changes 2.088 31 October 2019 * Beef up reset for zip usecase d8be7b82c93d1ed8f7c396f7b19fef4b642cb7c8 * remove unnecessary commented code 7aaedd5c74335457c55a243e08180df69f35a4b7 * Add Support Details 5f34bf369cceabc8c06fb40ec6e9db32291a85b8 * Documentation Updates 1e5b9d5f99be6b7a104b96e3349c2c63acf3a7b5 2.087 10 August 2019 * No Changes 2.086 31 March 2019 * Moved source to github https://github.com/pmqs/IO-Compress-Lzma * Add META_MERGE to Makefile.PL * Added meta-json.t & meta-yaml.t 2.084 5 January 2019 * Added support for lzip with IO::Compress::Lzip and IO::Uncompress::UnLzip 2.083 30 December 2018 * No Changes 2.081 4 April 2018 * previous release used $^W instead of use warnings. Fixed. 2.080 2 April 2018 * No Changes 2.074 19 Feb 2017 * Fix bad 2.073 release 2.073 18 Feb 2017 * #120239: [PATCH] ISA fixes for c3 2.072 4 Feb 2017 * Makefile.PL #120084: Need Fix for Makefile.PL depending on . in @INC 2.070 28 Dec 2016 * No Changes 2.069 26 Sep 2015 * No Changes 2.068 23 Dec 2014 * No Changes 2.067 8 Dec 2014 * No Changes 2.066 21 Sept 2014 * No Changes 2.064 1 February 2014 * No Changes 2.062 11 August 2013 * typo fixes RT #86578 2.061 19 May 2013 * IO::Uncompress::UnXz v2.060 memLimit option bug RT #84966 2.060 7 January 2013 * No Changes 2.059 10 December 2012 * No Changes 2.058 12 November 2012 * No Changes 2.057 10 November 2012 * General Performance improvements. 2.055 5 August 2012 * No Changes 2.052 29 April 2012 * No Changes 2.049 18 February 2012 * No Changes 2.048 29 January 2012 * No Changes 2.047 28 January 2012 * Set minimum Perl version to 5.6 2.045 3 December 2011 * Moved FAQ.pod to IO::Compress 2.044 2 December 2011 * Moved FAQ.pod under the lib directory so it can get installed 2.043 20 November 2011 * No Changes 2.042 17 November 2011 * No Changes 2.041 29 October 2011 * t/001lzma.t - Remove debugging line that writes to /tmp RT #72023 2.040 28 October 2011 * No Changes 2.039 28 October 2011 * IO::Unompress::UnLzma - Fixed uncompression issue RT #71114 2.038 23 June 2011 * Fixed missing SKIP label in t/050interop-zip-lzma.t 2.037 20 June 2011 * Handle "Cannot Allocate Memory" issue with Extreme test in t/105oneshot-zip-lzma-only.t 2.036 18 June 2011 * IO::Compress::Adapter Added interface to allow creation of LZMA stream for use in a zip file * IO::Unxompress::Adapter Added interface to allow reading of LZMA stream in a zip file 2.035 6 May 2011 * RT #67931: Test failure on Windows 2.034 2 May 2011 * Updates to test harness 2.033 11 Jan 2011 * Made 001xz.t more forgiving when the tests run out of memory. 2.030 22 July 2010 * No Changes 2.027 24 April 2010 * No Changes 2.026 7 April 2010 * No Changes 2.025 27 March 2010 * No Changes 2.024 7 January 2010 * Documentation updates. 2.023 9 November 2009 * First public beta libio-compress-lzma-perl-2.093/MANIFEST000066400000000000000000000035371357305603400175260ustar00rootroot00000000000000README lib/IO/Uncompress/UnLzma.pm lib/IO/Uncompress/UnXz.pm lib/IO/Uncompress/UnLzip.pm lib/IO/Compress/Lzma.pm lib/IO/Compress/Xz.pm lib/IO/Compress/Lzip.pm lib/IO/Compress/Adapter/Lzma.pm lib/IO/Compress/Adapter/Xz.pm lib/IO/Compress/Adapter/Lzip.pm lib/IO/Uncompress/Adapter/UnLzma.pm lib/IO/Uncompress/Adapter/UnXz.pm lib/IO/Uncompress/Adapter/UnLzip.pm Makefile.PL t/000prereq.t t/001lzma.t t/001xz.t t/001lzip.t t/010examples-lzma.t t/010examples-xz.t t/050interop-lzma.t t/050interop-xz.t t/050interop-lzip.t t/050interop-zip-lzma.t t/100generic-lzma.t t/100generic-xz.t t/100generic-lzip.t t/101truncate-lzma.t t/101truncate-xz.t t/101truncate-lzip.t t/102tied-lzma.t t/102tied-xz.t t/102tied-lzip.t t/103newtied-lzma.t t/103newtied-xz.t t/103newtied-lzip.t t/104destroy-lzma.t t/104destroy-xz.t t/104destroy-lzip.t t/105oneshot-lzma.t t/105oneshot-xz.t t/105oneshot-lzip.t t/106prime-lzma.t t/106prime-xz.t t/106prime-lzip.t t/107multi-lzma.t t/107multi-xz.t t/107multi-lzip.t t/108anyunc-lzma.t t/108anyunc-xz.t t/108anyunc-lzip.t t/110encode-lzma.t t/110encode-xz.t t/110encode-lzip.t t/25interop-io-string.t t/999pod.t t/meta-json.t t/meta-yaml.t t/Test/Builder.pm t/Test/More.pm t/Test/Simple.pm t/compress/any.pl t/compress/anyunc.pl t/compress/destroy.pl t/compress/encode.pl t/compress/generic.pl t/compress/interop-io-string.pl t/compress/merge.pl t/compress/multi.pl t/compress/newtied.pl t/compress/oneshot.pl t/compress/prime.pl t/compress/tied.pl t/compress/truncate.pl t/compress/zlib-generic.pl t/compress/CompTestUtils.pm MANIFEST private/MakeUtil.pm Changes examples/lzcat perl examples/lzgrep perl examples/lzstream perl examples/xzcat perl examples/xzgrep perl examples/xzstream perl META.yml Module YAML meta-data (added by MakeMaker) META.json Module JSON meta-data (added by MakeMaker) libio-compress-lzma-perl-2.093/META.json000066400000000000000000000026341357305603400200130ustar00rootroot00000000000000{ "abstract" : "Write lzma files/buffers", "author" : [ "Paul Marquess " ], "dynamic_config" : 1, "generated_by" : "ExtUtils::MakeMaker version 7.34, CPAN::Meta::Converter version 2.150005", "license" : [ "perl_5" ], "meta-spec" : { "url" : "http://search.cpan.org/perldoc?CPAN::Meta::Spec", "version" : "2" }, "name" : "IO-Compress-Lzma", "no_index" : { "directory" : [ "t", "inc", "t", "private" ] }, "prereqs" : { "build" : { "requires" : { "ExtUtils::MakeMaker" : "0" } }, "configure" : { "requires" : { "ExtUtils::MakeMaker" : "0" } }, "runtime" : { "requires" : { "Compress::Raw::Lzma" : "2.093", "IO::Compress::Base" : "2.093", "IO::Uncompress::Base" : "2.093" } } }, "release_status" : "stable", "resources" : { "bugtracker" : { "web" : "https://github.com/pmqs/IO-Compress-Lzma/issues" }, "homepage" : "https://github.com/pmqs/IO-Compress-Lzma", "repository" : { "type" : "git", "url" : "git://github.com/pmqs/IO-Compress-Lzma.git", "web" : "https://github.com/pmqs/IO-Compress-Lzma" } }, "version" : "2.093", "x_serialization_backend" : "JSON::PP version 2.27300" } libio-compress-lzma-perl-2.093/META.yml000066400000000000000000000015021357305603400176340ustar00rootroot00000000000000--- abstract: 'Write lzma files/buffers' author: - 'Paul Marquess ' build_requires: ExtUtils::MakeMaker: '0' configure_requires: ExtUtils::MakeMaker: '0' dynamic_config: 1 generated_by: 'ExtUtils::MakeMaker version 7.34, CPAN::Meta::Converter version 2.150005' license: perl meta-spec: url: http://module-build.sourceforge.net/META-spec-v1.4.html version: '1.4' name: IO-Compress-Lzma no_index: directory: - t - inc - t - private requires: Compress::Raw::Lzma: '2.093' IO::Compress::Base: '2.093' IO::Uncompress::Base: '2.093' resources: bugtracker: https://github.com/pmqs/IO-Compress-Lzma/issues homepage: https://github.com/pmqs/IO-Compress-Lzma repository: git://github.com/pmqs/IO-Compress-Lzma.git version: '2.093' x_serialization_backend: 'CPAN::Meta::YAML version 0.018' libio-compress-lzma-perl-2.093/Makefile.PL000066400000000000000000000040611357305603400203400ustar00rootroot00000000000000#! perl -w use strict ; require 5.006 ; $::VERSION = '2.093' ; use lib '.'; use private::MakeUtil; use ExtUtils::MakeMaker 5.16 ; UpDowngrade(getPerlFiles('MANIFEST')) unless $ENV{PERL_CORE}; WriteMakefile( NAME => 'IO::Compress::Lzma', VERSION_FROM => 'lib/IO/Compress/Lzma.pm', 'dist' => { COMPRESS => 'gzip', TARFLAGS => '-chvf', SUFFIX => 'gz', DIST_DEFAULT => 'MyTrebleCheck tardist', }, ( $ENV{SKIP_FOR_CORE} ? (MAN3PODS => {}) : (PREREQ_PM => { 'Compress::Raw::Lzma' => $::VERSION, 'IO::Compress::Base' => $::VERSION, 'IO::Uncompress::Base' => $::VERSION, $] >= 5.005 && $] < 5.006 ? ('File::BSDGlob' => 0) : () } ) ), ( $] >= 5.005 ? (ABSTRACT_FROM => 'lib/IO/Compress/Lzma.pm', AUTHOR => 'Paul Marquess ') : () ), ( eval { ExtUtils::MakeMaker->VERSION(6.46) } ? ( META_MERGE => { "meta-spec" => { version => 2 }, no_index => { directory => [ 't', 'private' ], }, resources => { bugtracker => { web => 'https://github.com/pmqs/IO-Compress-Lzma/issues' }, homepage => 'https://github.com/pmqs/IO-Compress-Lzma', repository => { type => 'git', url => 'git://github.com/pmqs/IO-Compress-Lzma.git', web => 'https://github.com/pmqs/IO-Compress-Lzma', }, }, } ) : () ), ((ExtUtils::MakeMaker->VERSION() gt '6.30') ? ('LICENSE' => 'perl') : ()), ) ; # end of file Makefile.PL libio-compress-lzma-perl-2.093/README000066400000000000000000000047601357305603400172540ustar00rootroot00000000000000 IO-Compress-Lzma Version 2.093 7 December 2019 Copyright (c) 2009-2019 Paul Marquess. All rights reserved. This program is free software; you can redistribute it and/or modify it under the same terms as Perl itself. DESCRIPTION ----------- This module provides a Perl interface to allow reading and writing of lzma files/buffers. PREREQUISITES ------------- Before you can build IO-Compress-Lzma you need to have the following installed on your system: * Perl 5.006 or better. * Compress::Raw::Lzma * IO::Compress BUILDING THE MODULE ------------------- Assuming you have met all the prerequisites, the module can now be built using this sequence of commands: perl Makefile.PL make make test INSTALLATION ------------ To install IO-Compress-Lzma, run the command below: make install TROUBLESHOOTING --------------- SUPPORT ------- General feedback/questions/bug reports should be sent to https://github.com/pmqs/IO-Compress-Lzma/issues (preferred) or https://rt.cpan.org/Public/Dist/Display.html?Name=IO-Compress-Lzma. FEEDBACK -------- How to report a problem with IO-Compress-Lzma. To help me help you, I need all of the following information: 1. The Versions of everything relevant. This includes: a. The *complete* output from running this perl -V Do not edit the output in any way. Note, I want you to run "perl -V" and NOT "perl -v". If your perl does not understand the "-V" option it is too old. This module needs Perl version 5.004 or better. b. The version of IO-Compress-Lzma you have. If you have successfully installed IO-Compress-Lzma, this one-liner will tell you: perl -MIO::Compress::Lzma -e 'print qq[ver $IO::Compress::Lzma::VERSION\n]' If you are running windows use this perl -MIO::Compress::Lzma -e "print qq[ver $IO::Compress::Lzma::VERSION\n]" If you haven't installed IO-Compress-Lzma then search IO::Compress::Lzma.pm for a line like this: $VERSION = "2.093" ; 2. If you are having problems building IO-Compress-Lzma, send me a complete log of what happened. Start by unpacking the IO-Compress-Lzma module into a fresh directory and keep a log of all the steps [edit config.in, if necessary] perl Makefile.PL make make test TEST_VERBOSE=1 Paul Marquess libio-compress-lzma-perl-2.093/examples/000077500000000000000000000000001357305603400202035ustar00rootroot00000000000000libio-compress-lzma-perl-2.093/examples/lzcat000077500000000000000000000007701357305603400212520ustar00rootroot00000000000000#!/usr/local/bin/perl use IO::Uncompress::UnLzma qw( $UnLzmaError ); use strict ; use warnings ; #die "Usage: gzcat file...\n" # unless @ARGV ; my $file ; my $buffer ; my $s; @ARGV = '-' unless @ARGV ; foreach $file (@ARGV) { my $gz = new IO::Uncompress::UnLzma $file or die "Cannot open $file: $UnLzmaError\n" ; print $buffer while ($s = $gz->read($buffer)) > 0 ; die "Error reading from $file: $UnLzmaError\n" if $s < 0 ; $gz->close() ; } libio-compress-lzma-perl-2.093/examples/lzgrep000077500000000000000000000007511357305603400214370ustar00rootroot00000000000000#!/usr/bin/perl use strict ; use warnings ; use IO::Uncompress::UnLzma qw($UnLzmaError); die "Usage: gzgrep pattern [file...]\n" unless @ARGV >= 1; my $pattern = shift ; my $file ; @ARGV = '-' unless @ARGV ; foreach $file (@ARGV) { my $gz = new IO::Uncompress::UnLzma $file or die "Cannot uncompress $file: $UnLzmaError\n" ; while (<$gz>) { print if /$pattern/ ; } die "Error reading from $file: $UnLzmaError\n" if $UnLzmaError ; } libio-compress-lzma-perl-2.093/examples/lzstream000077500000000000000000000002121357305603400217650ustar00rootroot00000000000000#!/usr/local/bin/perl use strict ; use warnings ; use IO::Compress::Lzma qw(:all); lzma '-' => '-' or die "lzstream: $LzmaError\n" ; libio-compress-lzma-perl-2.093/examples/xzcat000077500000000000000000000007561357305603400212720ustar00rootroot00000000000000#!/usr/local/bin/perl use IO::Uncompress::UnXz qw( $UnXzError ); use strict ; use warnings ; #die "Usage: gzcat file...\n" # unless @ARGV ; my $file ; my $buffer ; my $s; @ARGV = '-' unless @ARGV ; foreach $file (@ARGV) { my $gz = new IO::Uncompress::UnXz $file or die "Cannot open $file: $UnXzError\n" ; print $buffer while ($s = $gz->read($buffer)) > 0 ; die "Error reading from $file: $UnXzError\n" if $s < 0 ; $gz->close() ; } libio-compress-lzma-perl-2.093/examples/xzgrep000077500000000000000000000007351357305603400214550ustar00rootroot00000000000000#!/usr/bin/perl use strict ; use warnings ; use IO::Uncompress::UnXz qw($UnXzError); die "Usage: gzgrep pattern [file...]\n" unless @ARGV >= 1; my $pattern = shift ; my $file ; @ARGV = '-' unless @ARGV ; foreach $file (@ARGV) { my $gz = new IO::Uncompress::UnXz $file or die "Cannot uncompress $file: $UnXzError\n" ; while (<$gz>) { print if /$pattern/ ; } die "Error reading from $file: $UnXzError\n" if $UnXzError ; } libio-compress-lzma-perl-2.093/examples/xzstream000077500000000000000000000001761357305603400220120ustar00rootroot00000000000000#!/usr/bin/perl use strict ; use warnings ; use IO::Compress::Xz qw(:all); xz '-' => '-' or die "xzstream: $XzError\n" ; libio-compress-lzma-perl-2.093/lib/000077500000000000000000000000001357305603400171335ustar00rootroot00000000000000libio-compress-lzma-perl-2.093/lib/IO/000077500000000000000000000000001357305603400174425ustar00rootroot00000000000000libio-compress-lzma-perl-2.093/lib/IO/Compress/000077500000000000000000000000001357305603400212355ustar00rootroot00000000000000libio-compress-lzma-perl-2.093/lib/IO/Compress/Adapter/000077500000000000000000000000001357305603400226155ustar00rootroot00000000000000libio-compress-lzma-perl-2.093/lib/IO/Compress/Adapter/Lzip.pm000066400000000000000000000055021357305603400240730ustar00rootroot00000000000000package IO::Compress::Adapter::Lzip ; use strict; use warnings; use bytes; use IO::Compress::Base::Common 2.093 qw(:Status); use Compress::Raw::Lzma 2.093 qw(LZMA_OK LZMA_STREAM_END) ; use Compress::Raw::Zlib 2.093 qw() ; our ($VERSION); $VERSION = '2.093'; sub mkCompObject { my $dictSize = shift ; my $filter = Lzma::Filter::Lzma1(DictSize => $dictSize); my ($def, $status) = Compress::Raw::Lzma::RawEncoder->new(AppendOutput => 1, ForZip => 0, Filter => $filter, #Filter => Lzma::Filter::Lzma1m ); return (undef, "Could not create RawEncoder object: $status", $status) if $status != LZMA_OK ; return bless {'Def' => $def, 'Error' => '', 'ErrorNo' => 0, 'CRC32' => 0, } ; } sub compr { my $self = shift ; my $def = $self->{Def}; $self->{CRC32} = Compress::Raw::Zlib::crc32($_[0], $self->{CRC32}) ; my $status = $def->code($_[0], $_[1]) ; $self->{ErrorNo} = $status; if ($status != LZMA_OK) { $self->{Error} = "Deflate Error: $status"; return STATUS_ERROR; } #${ $_[1] } .= $out if defined $out; return STATUS_OK; } sub flush { my $self = shift ; my $def = $self->{Def}; my $status = $def->flush($_[0]); $self->{ErrorNo} = $status; if ($status != LZMA_STREAM_END) { $self->{Error} = "Deflate Error: $status"; return STATUS_ERROR; } #${ $_[0] } .= $out if defined $out ; return STATUS_OK; } sub close { my $self = shift ; my $def = $self->{Def}; my $status = $def->flush($_[0]); $self->{ErrorNo} = $status; if ($status != LZMA_STREAM_END) { $self->{Error} = "Deflate Error: $status"; return STATUS_ERROR; } #${ $_[0] } .= $out if defined $out ; return STATUS_OK; } sub reset { my $self = shift ; my $outer = $self->{Outer}; my ($def, $status) = Compress::Raw::Lzma::RawEncoder->new(AppendOutput => 1); $self->{ErrorNo} = ($status == LZMA_OK) ? 0 : $status ; if ($status != LZMA_OK) { $self->{Error} = "Cannot create Deflate object: $status"; return STATUS_ERROR; } $self->{Def} = $def; return STATUS_OK; } sub compressedBytes { my $self = shift ; $self->{Def}->compressedBytes(); } sub uncompressedBytes { my $self = shift ; $self->{Def}->uncompressedBytes(); } #sub total_out #{ # my $self = shift ; # 0; #} # #sub total_in #{ # my $self = shift ; # $self->{Def}->total_in(); #} sub crc32 { my $self = shift ; return $self->{CRC32} ; } 1; __END__ libio-compress-lzma-perl-2.093/lib/IO/Compress/Adapter/Lzma.pm000066400000000000000000000066241357305603400240660ustar00rootroot00000000000000package IO::Compress::Adapter::Lzma ; use strict; use warnings; use bytes; use IO::Compress::Base::Common 2.093 qw(:Status); use Compress::Raw::Lzma 2.093 qw(LZMA_OK LZMA_STREAM_END) ; our ($VERSION); $VERSION = '2.093'; sub mkCompObject { my $Filter = shift ; my ($def, $status) = Compress::Raw::Lzma::AloneEncoder->new(AppendOutput => 1, Filter => $Filter); return (undef, "Could not create AloneEncoder object: $status", $status) if $status != LZMA_OK ; return bless {'Def' => $def, 'Error' => '', 'ErrorNo' => 0, } ; } sub mkRawZipCompObject { my $preset = shift ; my $extreme = shift; my $filter; if (defined $preset) { $preset |= Compress::Raw::Lzma::LZMA_PRESET_EXTREME() if $extreme; $filter = Lzma::Filter::Lzma1::Preset($preset) ; } else { $filter = Lzma::Filter::Lzma1 } my ($def, $status) = Compress::Raw::Lzma::RawEncoder->new(AppendOutput => 1, ForZip => 1, Filter => $filter, #Filter => Lzma::Filter::Lzma1m ); return (undef, "Could not create RawEncoder object: $status", $status) if $status != LZMA_OK ; return bless {'Def' => $def, 'Error' => '', 'ErrorNo' => 0, } ; } sub compr { my $self = shift ; my $def = $self->{Def}; my $status = $def->code($_[0], $_[1]) ; $self->{ErrorNo} = $status; if ($status != LZMA_OK) { $self->{Error} = "Deflate Error: $status"; return STATUS_ERROR; } #${ $_[1] } .= $out if defined $out; return STATUS_OK; } sub flush { my $self = shift ; my $def = $self->{Def}; my $status = $def->flush($_[0]); $self->{ErrorNo} = $status; if ($status != LZMA_STREAM_END) { $self->{Error} = "Deflate Error: $status"; return STATUS_ERROR; } #${ $_[0] } .= $out if defined $out ; return STATUS_OK; } sub close { my $self = shift ; my $def = $self->{Def}; my $status = $def->flush($_[0]); $self->{ErrorNo} = $status; if ($status != LZMA_STREAM_END) { $self->{Error} = "Deflate Error: $status"; return STATUS_ERROR; } #${ $_[0] } .= $out if defined $out ; return STATUS_OK; } sub reset { my $self = shift ; my $outer = $self->{Outer}; my ($def, $status) = Compress::Raw::Lzma::AloneEncoder->new(AppendOutput => 1); $self->{ErrorNo} = ($status == LZMA_OK) ? 0 : $status ; if ($status != LZMA_OK) { $self->{Error} = "Cannot create Deflate object: $status"; return STATUS_ERROR; } $self->{Def} = $def; return STATUS_OK; } sub compressedBytes { my $self = shift ; $self->{Def}->compressedBytes(); } sub uncompressedBytes { my $self = shift ; $self->{Def}->uncompressedBytes(); } #sub total_out #{ # my $self = shift ; # 0; #} # #sub total_in #{ # my $self = shift ; # $self->{Def}->total_in(); #} # #sub crc32 #{ # my $self = shift ; # $self->{Def}->crc32(); #} # #sub adler32 #{ # my $self = shift ; # $self->{Def}->adler32(); #} 1; __END__ libio-compress-lzma-perl-2.093/lib/IO/Compress/Adapter/Xz.pm000066400000000000000000000054071357305603400235620ustar00rootroot00000000000000package IO::Compress::Adapter::Xz ; use strict; use warnings; use bytes; use IO::Compress::Base::Common 2.093 qw(:Status); use Compress::Raw::Lzma 2.093 qw(LZMA_OK LZMA_STREAM_END LZMA_PRESET_DEFAULT LZMA_CHECK_CRC32) ; our ($VERSION); $VERSION = '2.093'; sub mkCompObject { my $Preset = shift ; my $Extreme = shift ; my $Check = shift ; my ($def, $status) = Compress::Raw::Lzma::EasyEncoder->new(AppendOutput => 1, Preset => $Preset, Extreme => $Extreme, Check => $Check); return (undef, "Could not create EasyEncoder object: $status", $status) if $status != LZMA_OK ; return bless {'Def' => $def, 'Error' => '', 'ErrorNo' => 0, } ; } sub compr { my $self = shift ; my $def = $self->{Def}; my $status = $def->code($_[0], $_[1]) ; $self->{ErrorNo} = $status; if ($status != LZMA_OK) { $self->{Error} = "Deflate Error: $status"; return STATUS_ERROR; } #${ $_[1] } .= $out if defined $out; return STATUS_OK; } sub flush { my $self = shift ; my $def = $self->{Def}; my $status = $def->flush($_[0]); $self->{ErrorNo} = $status; if ($status != LZMA_STREAM_END) { $self->{Error} = "Deflate Error: $status"; return STATUS_ERROR; } #${ $_[0] } .= $out if defined $out ; return STATUS_OK; } sub close { my $self = shift ; my $def = $self->{Def}; my $status = $def->flush($_[0]); $self->{ErrorNo} = $status; if ($status != LZMA_STREAM_END) { $self->{Error} = "Deflate Error: $status"; return STATUS_ERROR; } #${ $_[0] } .= $out if defined $out ; return STATUS_OK; } sub reset { my $self = shift ; my $outer = $self->{Outer}; my ($def, $status) = Compress::Raw::Lzma->lzma_easy_encoder(); $self->{ErrorNo} = ($status == LZMA_OK) ? 0 : $status ; if ($status != LZMA_OK) { $self->{Error} = "Cannot create Deflate object: $status"; return STATUS_ERROR; } $self->{Def} = $def; return STATUS_OK; } sub compressedBytes { my $self = shift ; $self->{Def}->compressedBytes(); } sub uncompressedBytes { my $self = shift ; $self->{Def}->uncompressedBytes(); } #sub total_out #{ # my $self = shift ; # 0; #} # #sub total_in #{ # my $self = shift ; # $self->{Def}->total_in(); #} # #sub crc32 #{ # my $self = shift ; # $self->{Def}->crc32(); #} # #sub adler32 #{ # my $self = shift ; # $self->{Def}->adler32(); #} 1; __END__ libio-compress-lzma-perl-2.093/lib/IO/Compress/Lzip.pm000066400000000000000000000502101357305603400225070ustar00rootroot00000000000000package IO::Compress::Lzip ; use strict ; use warnings; use bytes; require Exporter ; use IO::Compress::Base 2.093 ; use IO::Compress::Base::Common 2.093 qw(createSelfTiedObject); use IO::Compress::Adapter::Lzip 2.093 ; our ($VERSION, @ISA, @EXPORT_OK, %EXPORT_TAGS, $LzipError); $VERSION = '2.093'; $LzipError = ''; @ISA = qw(IO::Compress::Base Exporter); @EXPORT_OK = qw( $LzipError lzip ) ; %EXPORT_TAGS = %IO::Compress::Base::EXPORT_TAGS ; push @{ $EXPORT_TAGS{all} }, @EXPORT_OK ; Exporter::export_ok_tags('all'); sub new { my $class = shift ; my $obj = createSelfTiedObject($class, \$LzipError); return $obj->_create(undef, @_); } sub lzip { my $obj = createSelfTiedObject(undef, \$LzipError); $obj->_def(@_); } sub mkHeader { my $self = shift ; my $opts = shift ; my $header = "LZIP\x01" ; # Code below to calculate dictionary size derived from libarchive archive_write_add_filter_xz.c # Hard-wire size for now # my $dict_size = 1 << 12 ; my $dict_size = $opts->getValue('dictsize'); my ($ds, $log2dic, $wedges); $self->saveErrorString(undef, "Unacceptable dictionary size for lzip: $dict_size") if $dict_size < (1 << 12) || $dict_size > (1 << 27) ; for ($log2dic = 27; $log2dic >= 12; $log2dic--) { last if $dict_size & (1 << $log2dic) ; } if ($dict_size > (1 << $log2dic)) { ++ $log2dic ; $wedges = ((1 << $log2dic) - $dict_size) / (1 << ($log2dic - 4)); } else { $wedges = 0; } $ds = (($wedges << 5) & 0xe0) | ($log2dic & 0x1f); $header .= pack ("C", $ds) ; return $header; } our %PARAMS = ('dictsize' => [IO::Compress::Base::Common::Parse_unsigned, 1 << 23 ], # 8 Meg ); sub getExtraParams { return %PARAMS ; } sub ckParams { my $self = shift ; my $got = shift; return 1 ; } sub mkComp { my $self = shift ; my $got = shift ; my $DictSize = $got->getValue('dictsize'); my ($obj, $errstr, $errno) = IO::Compress::Adapter::Lzip::mkCompObject($DictSize); return $self->saveErrorString(undef, $errstr, $errno) if ! defined $obj; return $obj; } sub mkTrailer { my $self = shift ; *$self->{CompSize}->add( 6 + 20); # Compressed size + header + trailer return pack("V", *$self->{Compress}->crc32() ) . *$self->{UnCompSize}->getPacked_V64() . # Uncompressed size *$self->{CompSize}->getPacked_V64() ; # Compressed size } sub mkFinalTrailer { return ''; } #sub newHeader #{ # my $self = shift ; # return ''; #} sub getInverseClass { return ('IO::Uncompress::UnLzip'); } sub getFileInfo { my $self = shift ; my $params = shift; my $file = shift ; } 1; __END__ =head1 NAME IO::Compress::Lzip - Write lzip files/buffers =head1 SYNOPSIS use IO::Compress::Lzip qw(lzip $LzipError) ; my $status = lzip $input => $output [,OPTS] or die "lzip failed: $LzipError\n"; my $z = new IO::Compress::Lzip $output [,OPTS] or die "lzip failed: $LzipError\n"; $z->print($string); $z->printf($format, $string); $z->write($string); $z->syswrite($string [, $length, $offset]); $z->flush(); $z->tell(); $z->eof(); $z->seek($position, $whence); $z->binmode(); $z->fileno(); $z->opened(); $z->autoflush(); $z->input_line_number(); $z->newStream( [OPTS] ); $z->close() ; $LzipError ; # IO::File mode print $z $string; printf $z $format, $string; tell $z eof $z seek $z, $position, $whence binmode $z fileno $z close $z ; =head1 DESCRIPTION This module provides a Perl interface that allows writing lzip compressed data to files or buffer. For reading lzip files/buffers, see the companion module L. =head1 Functional Interface A top-level function, C, is provided to carry out "one-shot" compression between buffers and/or files. For finer control over the compression process, see the L section. use IO::Compress::Lzip qw(lzip $LzipError) ; lzip $input_filename_or_reference => $output_filename_or_reference [,OPTS] or die "lzip failed: $LzipError\n"; The functional interface needs Perl5.005 or better. =head2 lzip $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 uncompressed data. It can take one of the following forms: =over 5 =item A filename If the C<$input_filename_or_reference> parameter is a simple scalar, it is assumed to be a filename. This file will be opened for reading and the input data will be read from it. =item A filehandle If the C<$input_filename_or_reference> parameter is a filehandle, the input data will be read from it. The string '-' can be used as an alias for standard input. =item A scalar reference If C<$input_filename_or_reference> is a scalar reference, the input data will be read from C<$$input_filename_or_reference>. =item An array reference If C<$input_filename_or_reference> is an array reference, each element in the array must be a filename. The input data will be read from each file in turn. The complete array will be walked to ensure that it only contains valid filenames before any data is compressed. =item An Input FileGlob string If C<$input_filename_or_reference> is a string that is delimited by the characters "<" and ">" C 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 compressed data. This parameter can take one of these forms. =over 5 =item A filename If the C<$output_filename_or_reference> parameter is a simple scalar, it is assumed to be a filename. This file will be opened for writing and the compressed data will be written to it. =item A filehandle If the C<$output_filename_or_reference> parameter is a filehandle, the compressed data will be written to it. The string '-' can be used as an alias for standard output. =item A scalar reference If C<$output_filename_or_reference> is a scalar reference, the compressed data will be stored in C<$$output_filename_or_reference>. =item An Array Reference If C<$output_filename_or_reference> is an array reference, the compressed data will be pushed onto the array. =item An Output FileGlob If C<$output_filename_or_reference> is a string that is delimited by the characters "<" and ">" C will assume that it is an I. The output is the list of files that match the fileglob. When C<$output_filename_or_reference> is an fileglob string, C<$input_filename_or_reference> must also be a fileglob string. Anything else is an error. See L for more details. =back If the C<$output_filename_or_reference> parameter is any other type, C will be returned. =head2 Notes When C<$input_filename_or_reference> maps to multiple files/buffers and C<$output_filename_or_reference> is a single file/buffer the input files/buffers will be stored in C<$output_filename_or_reference> as a concatenated series of compressed data streams. =head2 Optional Parameters The optional parameters for the one-shot function C are (for the most part) identical to those used with the OO interface defined in the L section. The exceptions are listed below =over 5 =item C<< AutoClose => 0|1 >> This option applies to any input or output data streams to C that are filehandles. If C is specified, and the value is true, it will result in all input and/or output filehandles being closed once C has completed. This parameter defaults to 0. =item C<< BinModeIn => 0|1 >> This option is now a no-op. All files will be read in binmode. =item C<< Append => 0|1 >> The behaviour of this option is dependent on the type of output data stream. =over 5 =item * A Buffer If C is enabled, all compressed data will be append to the end of the output buffer. Otherwise the output buffer will be cleared before any compressed data is written to it. =item * A Filename If C is enabled, the file will be opened in append mode. Otherwise the contents of the file, if any, will be truncated before any compressed data is written to it. =item * A Filehandle If C is enabled, the filehandle will be positioned to the end of the file via a call to C before any compressed data is written to it. Otherwise the file pointer will not be moved. =back When C is specified, and set to true, it will I all compressed data to the output data stream. So when the output is a filehandle it will carry out a seek to the eof before writing any compressed data. If the output is a filename, it will be opened for appending. If the output is a buffer, all compressed data will be appended to the existing buffer. Conversely when C is not specified, or it is present and is set to false, it will operate as follows. When the output is a filename, it will truncate the contents of the file before writing any compressed data. If the output is a filehandle its position will not be changed. If the output is a buffer, it will be wiped before any compressed data is output. Defaults to 0. =back =head2 Examples Here are a few example that show the capabilities of the module. =head3 Streaming This very simple command line example demonstrates the streaming capabilities of the module. The code reads data from STDIN, compresses it, and writes the compressed data to STDOUT. $ echo hello world | perl -MIO::Compress::Lzip=lzip -e 'lzip \*STDIN => \*STDOUT' >output.lz The special filename "-" can be used as a standin for both C<\*STDIN> and C<\*STDOUT>, so the above can be rewritten as $ echo hello world | perl -MIO::Compress::Lzip=lzip -e 'lzip "-" => "-"' >output.lz =head3 Compressing a file from the filesystem To read the contents of the file C and write the compressed data to the file C. use strict ; use warnings ; use IO::Compress::Lzip qw(lzip $LzipError) ; my $input = "file1.txt"; lzip $input => "$input.lz" or die "lzip failed: $LzipError\n"; =head3 Reading from a Filehandle and writing to an in-memory buffer To read from an existing Perl filehandle, C<$input>, and write the compressed data to a buffer, C<$buffer>. use strict ; use warnings ; use IO::Compress::Lzip qw(lzip $LzipError) ; use IO::File ; my $input = new IO::File " \$buffer or die "lzip failed: $LzipError\n"; =head3 Compressing multiple files To compress all files in the directory "/my/home" that match "*.txt" and store the compressed data in the same directory use strict ; use warnings ; use IO::Compress::Lzip qw(lzip $LzipError) ; lzip '' => '<*.lz>' or die "lzip failed: $LzipError\n"; and if you want to compress each file one at a time, this will do the trick use strict ; use warnings ; use IO::Compress::Lzip qw(lzip $LzipError) ; for my $input ( glob "/my/home/*.txt" ) { my $output = "$input.lz" ; lzip $input => $output or die "Error compressing '$input': $LzipError\n"; } =head1 OO Interface =head2 Constructor The format of the constructor for C is shown below my $z = new IO::Compress::Lzip $output [,OPTS] or die "IO::Compress::Lzip failed: $LzipError\n"; It returns an C object on success and undef on failure. The variable C<$LzipError> will contain an error message on failure. If you are running Perl 5.005 or better the object, C<$z>, returned from IO::Compress::Lzip can be used exactly like an L filehandle. This means that all normal output file operations can be carried out with C<$z>. For example, to write to a compressed file/buffer you can use either of these forms $z->print("hello world\n"); print $z "hello world\n"; The mandatory parameter C<$output> is used to control the destination of the compressed data. This parameter can take one of these forms. =over 5 =item A filename If the C<$output> parameter is a simple scalar, it is assumed to be a filename. This file will be opened for writing and the compressed data will be written to it. =item A filehandle If the C<$output> parameter is a filehandle, the compressed data will be written to it. The string '-' can be used as an alias for standard output. =item A scalar reference If C<$output> is a scalar reference, the compressed data will be stored in C<$$output>. =back If the C<$output> parameter is any other type, C::new will return undef. =head2 Constructor Options C is any combination of zero or more the following options: =over 5 =item C<< AutoClose => 0|1 >> This option is only valid when the C<$output> parameter is a filehandle. If specified, and the value is true, it will result in the C<$output> being closed once either the C method is called or the C object is destroyed. This parameter defaults to 0. =item C<< Append => 0|1 >> Opens C<$output> in append mode. The behaviour of this option is dependent on the type of C<$output>. =over 5 =item * A Buffer If C<$output> is a buffer and C is enabled, all compressed data will be append to the end of C<$output>. Otherwise C<$output> will be cleared before any data is written to it. =item * A Filename If C<$output> is a filename and C is enabled, the file will be opened in append mode. Otherwise the contents of the file, if any, will be truncated before any compressed data is written to it. =item * A Filehandle If C<$output> is a filehandle, the file pointer will be positioned to the end of the file via a call to C before any compressed data is written to it. Otherwise the file pointer will not be moved. =back This parameter defaults to 0. =item C<< DictSize => number >> Valid values are between 4K and 128Meg Defaults to 8 Meg. =item C<< Strict => 0|1 >> This is a placeholder option. =back =head2 Examples TODO =head1 Methods =head2 print Usage is $z->print($data) print $z $data Compresses and outputs the contents of the C<$data> parameter. This has the same behaviour as the C built-in. Returns true if successful. =head2 printf Usage is $z->printf($format, $data) printf $z $format, $data Compresses and outputs the contents of the C<$data> parameter. Returns true if successful. =head2 syswrite Usage is $z->syswrite $data $z->syswrite $data, $length $z->syswrite $data, $length, $offset Compresses and outputs the contents of the C<$data> parameter. Returns the number of uncompressed bytes written, or C if unsuccessful. =head2 write Usage is $z->write $data $z->write $data, $length $z->write $data, $length, $offset Compresses and outputs the contents of the C<$data> parameter. Returns the number of uncompressed bytes written, or C if unsuccessful. =head2 flush Usage is $z->flush; Flushes any pending compressed data to the output file/buffer. Returns true on success. =head2 tell Usage is $z->tell() tell $z Returns the uncompressed file offset. =head2 eof Usage is $z->eof(); eof($z); Returns true if the C method has been called. =head2 seek $z->seek($position, $whence); seek($z, $position, $whence); Provides a sub-set of the C functionality, with the restriction that it is only legal to seek forward in the output file/buffer. It is a fatal error to attempt to seek backward. Empty parts of the file/buffer will have NULL (0x00) bytes written to them. The C<$whence> parameter takes one the usual values, namely SEEK_SET, SEEK_CUR or SEEK_END. Returns 1 on success, 0 on failure. =head2 binmode Usage is $z->binmode binmode $z ; This is a noop provided for completeness. =head2 opened $z->opened() Returns true if the object currently refers to a opened file/buffer. =head2 autoflush my $prev = $z->autoflush() my $prev = $z->autoflush(EXPR) If the C<$z> object is associated with a file or a filehandle, this method returns the current autoflush setting for the underlying filehandle. If C is present, and is non-zero, it will enable flushing after every write/print operation. If C<$z> is associated with a buffer, this method has no effect and always returns C. B that the special variable C<$|> B be used to set or retrieve the autoflush setting. =head2 input_line_number $z->input_line_number() $z->input_line_number(EXPR) This method always returns C when compressing. =head2 fileno $z->fileno() fileno($z) If the C<$z> object is associated with a file or a filehandle, C will return the underlying file descriptor. Once the C method is called C will return C. If the C<$z> object is associated with a buffer, this method will return C. =head2 close $z->close() ; close $z ; Flushes any pending compressed data and then closes the output file/buffer. For most versions of Perl this method will be automatically invoked if the IO::Compress::Lzip object is destroyed (either explicitly or by the variable with the reference to the object going out of scope). The exceptions are Perl versions 5.005 through 5.00504 and 5.8.0. In these cases, the C method will be called automatically, but not until global destruction of all live objects when the program is terminating. Therefore, if you want your scripts to be able to run on all versions of Perl, you should call C explicitly and not rely on automatic closing. Returns true on success, otherwise 0. If the C option has been enabled when the IO::Compress::Lzip object was created, and the object is associated with a file, the underlying file will also be closed. =head2 newStream([OPTS]) Usage is $z->newStream( [OPTS] ) Closes the current compressed data stream and starts a new one. OPTS consists of any of the options that are available when creating the C<$z> object. See the L section for more details. =head1 Importing No symbolic constants are required by this IO::Compress::Lzip at present. =over 5 =item :all Imports C and C<$LzipError>. Same as doing this use IO::Compress::Lzip qw(lzip $LzipError) ; =back =head1 EXAMPLES =head1 SUPPORT General feedback/questions/bug reports should be sent to L (preferred) or L. =head1 SEE ALSO L, L, L, L, L, L, L, L, L, L, L, L, L, L, L, L, L, L, L, L, L, L L L, L, L, L =head1 AUTHOR This module was written by Paul Marquess, C. =head1 MODIFICATION HISTORY See the Changes file. =head1 COPYRIGHT AND LICENSE Copyright (c) 2005-2019 Paul Marquess. All rights reserved. This program is free software; you can redistribute it and/or modify it under the same terms as Perl itself. libio-compress-lzma-perl-2.093/lib/IO/Compress/Lzma.pm000066400000000000000000000467111357305603400225070ustar00rootroot00000000000000package IO::Compress::Lzma ; use strict ; use warnings; use bytes; require Exporter ; use IO::Compress::Base 2.093 ; use IO::Compress::Base::Common 2.093 qw(createSelfTiedObject); use IO::Compress::Adapter::Lzma 2.093 ; our ($VERSION, @ISA, @EXPORT_OK, %EXPORT_TAGS, $LzmaError); $VERSION = '2.093'; $LzmaError = ''; @ISA = qw(IO::Compress::Base Exporter); @EXPORT_OK = qw( $LzmaError lzma ) ; %EXPORT_TAGS = %IO::Compress::Base::EXPORT_TAGS ; push @{ $EXPORT_TAGS{all} }, @EXPORT_OK ; Exporter::export_ok_tags('all'); sub new { my $class = shift ; my $obj = createSelfTiedObject($class, \$LzmaError); return $obj->_create(undef, @_); } sub lzma { my $obj = createSelfTiedObject(undef, \$LzmaError); $obj->_def(@_); } sub mkHeader { my $self = shift ; return ''; } our %PARAMS = ('filter' => [IO::Compress::Base::Common::Parse_any, [] ], ); sub getExtraParams { return %PARAMS ; } sub ckParams { my $self = shift ; my $got = shift; # TODO - test that Filter ISA Lzma::Filter::Lzma1 return 1 ; } sub mkComp { my $self = shift ; my $got = shift ; my ($obj, $errstr, $errno) = IO::Compress::Adapter::Lzma::mkCompObject($got->getValue('filter')); return $self->saveErrorString(undef, $errstr, $errno) if ! defined $obj; return $obj; } sub mkTrailer { my $self = shift ; return ''; } sub mkFinalTrailer { return ''; } #sub newHeader #{ # my $self = shift ; # return ''; #} sub getInverseClass { return ('IO::Uncompress::UnLzma'); } sub getFileInfo { my $self = shift ; my $params = shift; my $file = shift ; } 1; __END__ =head1 NAME IO::Compress::Lzma - Write lzma files/buffers =head1 SYNOPSIS use IO::Compress::Lzma qw(lzma $LzmaError) ; my $status = lzma $input => $output [,OPTS] or die "lzma failed: $LzmaError\n"; my $z = new IO::Compress::Lzma $output [,OPTS] or die "lzma failed: $LzmaError\n"; $z->print($string); $z->printf($format, $string); $z->write($string); $z->syswrite($string [, $length, $offset]); $z->flush(); $z->tell(); $z->eof(); $z->seek($position, $whence); $z->binmode(); $z->fileno(); $z->opened(); $z->autoflush(); $z->input_line_number(); $z->newStream( [OPTS] ); $z->close() ; $LzmaError ; # IO::File mode print $z $string; printf $z $format, $string; tell $z eof $z seek $z, $position, $whence binmode $z fileno $z close $z ; =head1 DESCRIPTION B. =over 5 =item * DO NOT use in production code. =item * The documentation is incomplete in places. =item * Parts of the interface defined here are tentative. =item * Please report any problems you find. =back This module provides a Perl interface that allows writing lzma compressed data to files or buffer. For reading lzma files/buffers, see the companion module L. =head1 Functional Interface A top-level function, C, is provided to carry out "one-shot" compression between buffers and/or files. For finer control over the compression process, see the L section. use IO::Compress::Lzma qw(lzma $LzmaError) ; lzma $input_filename_or_reference => $output_filename_or_reference [,OPTS] or die "lzma failed: $LzmaError\n"; The functional interface needs Perl5.005 or better. =head2 lzma $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 uncompressed data. It can take one of the following forms: =over 5 =item A filename If the C<$input_filename_or_reference> parameter is a simple scalar, it is assumed to be a filename. This file will be opened for reading and the input data will be read from it. =item A filehandle If the C<$input_filename_or_reference> parameter is a filehandle, the input data will be read from it. The string '-' can be used as an alias for standard input. =item A scalar reference If C<$input_filename_or_reference> is a scalar reference, the input data will be read from C<$$input_filename_or_reference>. =item An array reference If C<$input_filename_or_reference> is an array reference, each element in the array must be a filename. The input data will be read from each file in turn. The complete array will be walked to ensure that it only contains valid filenames before any data is compressed. =item An Input FileGlob string If C<$input_filename_or_reference> is a string that is delimited by the characters "<" and ">" C 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 compressed data. This parameter can take one of these forms. =over 5 =item A filename If the C<$output_filename_or_reference> parameter is a simple scalar, it is assumed to be a filename. This file will be opened for writing and the compressed data will be written to it. =item A filehandle If the C<$output_filename_or_reference> parameter is a filehandle, the compressed data will be written to it. The string '-' can be used as an alias for standard output. =item A scalar reference If C<$output_filename_or_reference> is a scalar reference, the compressed data will be stored in C<$$output_filename_or_reference>. =item An Array Reference If C<$output_filename_or_reference> is an array reference, the compressed data will be pushed onto the array. =item An Output FileGlob If C<$output_filename_or_reference> is a string that is delimited by the characters "<" and ">" C will assume that it is an I. The output is the list of files that match the fileglob. When C<$output_filename_or_reference> is an fileglob string, C<$input_filename_or_reference> must also be a fileglob string. Anything else is an error. See L for more details. =back If the C<$output_filename_or_reference> parameter is any other type, C will be returned. =head2 Notes When C<$input_filename_or_reference> maps to multiple files/buffers and C<$output_filename_or_reference> is a single file/buffer the input files/buffers will be stored in C<$output_filename_or_reference> as a concatenated series of compressed data streams. =head2 Optional Parameters The optional parameters for the one-shot function C are (for the most part) identical to those used with the OO interface defined in the L section. The exceptions are listed below =over 5 =item C<< AutoClose => 0|1 >> This option applies to any input or output data streams to C that are filehandles. If C is specified, and the value is true, it will result in all input and/or output filehandles being closed once C has completed. This parameter defaults to 0. =item C<< BinModeIn => 0|1 >> This option is now a no-op. All files will be read in binmode. =item C<< Append => 0|1 >> The behaviour of this option is dependent on the type of output data stream. =over 5 =item * A Buffer If C is enabled, all compressed data will be append to the end of the output buffer. Otherwise the output buffer will be cleared before any compressed data is written to it. =item * A Filename If C is enabled, the file will be opened in append mode. Otherwise the contents of the file, if any, will be truncated before any compressed data is written to it. =item * A Filehandle If C is enabled, the filehandle will be positioned to the end of the file via a call to C before any compressed data is written to it. Otherwise the file pointer will not be moved. =back When C is specified, and set to true, it will I all compressed data to the output data stream. So when the output is a filehandle it will carry out a seek to the eof before writing any compressed data. If the output is a filename, it will be opened for appending. If the output is a buffer, all compressed data will be appended to the existing buffer. Conversely when C is not specified, or it is present and is set to false, it will operate as follows. When the output is a filename, it will truncate the contents of the file before writing any compressed data. If the output is a filehandle its position will not be changed. If the output is a buffer, it will be wiped before any compressed data is output. Defaults to 0. =back =head2 Examples Here are a few example that show the capabilities of the module. =head3 Streaming This very simple command line example demonstrates the streaming capabilities of the module. The code reads data from STDIN, compresses it, and writes the compressed data to STDOUT. $ echo hello world | perl -MIO::Compress::Lzma=lzma -e 'lzma \*STDIN => \*STDOUT' >output.lzma The special filename "-" can be used as a standin for both C<\*STDIN> and C<\*STDOUT>, so the above can be rewritten as $ echo hello world | perl -MIO::Compress::Lzma=lzma -e 'lzma "-" => "-"' >output.lzma =head3 Compressing a file from the filesystem To read the contents of the file C and write the compressed data to the file C. use strict ; use warnings ; use IO::Compress::Lzma qw(lzma $LzmaError) ; my $input = "file1.txt"; lzma $input => "$input.lzma" or die "lzma failed: $LzmaError\n"; =head3 Reading from a Filehandle and writing to an in-memory buffer To read from an existing Perl filehandle, C<$input>, and write the compressed data to a buffer, C<$buffer>. use strict ; use warnings ; use IO::Compress::Lzma qw(lzma $LzmaError) ; use IO::File ; my $input = new IO::File " \$buffer or die "lzma failed: $LzmaError\n"; =head3 Compressing multiple files To compress all files in the directory "/my/home" that match "*.txt" and store the compressed data in the same directory use strict ; use warnings ; use IO::Compress::Lzma qw(lzma $LzmaError) ; lzma '' => '<*.lzma>' or die "lzma failed: $LzmaError\n"; and if you want to compress each file one at a time, this will do the trick use strict ; use warnings ; use IO::Compress::Lzma qw(lzma $LzmaError) ; for my $input ( glob "/my/home/*.txt" ) { my $output = "$input.lzma" ; lzma $input => $output or die "Error compressing '$input': $LzmaError\n"; } =head1 OO Interface =head2 Constructor The format of the constructor for C is shown below my $z = new IO::Compress::Lzma $output [,OPTS] or die "IO::Compress::Lzma failed: $LzmaError\n"; It returns an C object on success and undef on failure. The variable C<$LzmaError> will contain an error message on failure. If you are running Perl 5.005 or better the object, C<$z>, returned from IO::Compress::Lzma can be used exactly like an L filehandle. This means that all normal output file operations can be carried out with C<$z>. For example, to write to a compressed file/buffer you can use either of these forms $z->print("hello world\n"); print $z "hello world\n"; The mandatory parameter C<$output> is used to control the destination of the compressed data. This parameter can take one of these forms. =over 5 =item A filename If the C<$output> parameter is a simple scalar, it is assumed to be a filename. This file will be opened for writing and the compressed data will be written to it. =item A filehandle If the C<$output> parameter is a filehandle, the compressed data will be written to it. The string '-' can be used as an alias for standard output. =item A scalar reference If C<$output> is a scalar reference, the compressed data will be stored in C<$$output>. =back If the C<$output> parameter is any other type, C::new will return undef. =head2 Constructor Options C is any combination of zero or more the following options: =over 5 =item C<< AutoClose => 0|1 >> This option is only valid when the C<$output> parameter is a filehandle. If specified, and the value is true, it will result in the C<$output> being closed once either the C method is called or the C object is destroyed. This parameter defaults to 0. =item C<< Append => 0|1 >> Opens C<$output> in append mode. The behaviour of this option is dependent on the type of C<$output>. =over 5 =item * A Buffer If C<$output> is a buffer and C is enabled, all compressed data will be append to the end of C<$output>. Otherwise C<$output> will be cleared before any data is written to it. =item * A Filename If C<$output> is a filename and C is enabled, the file will be opened in append mode. Otherwise the contents of the file, if any, will be truncated before any compressed data is written to it. =item * A Filehandle If C<$output> is a filehandle, the file pointer will be positioned to the end of the file via a call to C before any compressed data is written to it. Otherwise the file pointer will not be moved. =back This parameter defaults to 0. =item C<< Filter => $filter >> When present C< $filter > option must be an object of type C. See L for a definition of C. If this option is not present an C object with default values will be used. =item C<< Strict => 0|1 >> This is a placeholder option. =back =head2 Examples TODO =head1 Methods =head2 print Usage is $z->print($data) print $z $data Compresses and outputs the contents of the C<$data> parameter. This has the same behaviour as the C built-in. Returns true if successful. =head2 printf Usage is $z->printf($format, $data) printf $z $format, $data Compresses and outputs the contents of the C<$data> parameter. Returns true if successful. =head2 syswrite Usage is $z->syswrite $data $z->syswrite $data, $length $z->syswrite $data, $length, $offset Compresses and outputs the contents of the C<$data> parameter. Returns the number of uncompressed bytes written, or C if unsuccessful. =head2 write Usage is $z->write $data $z->write $data, $length $z->write $data, $length, $offset Compresses and outputs the contents of the C<$data> parameter. Returns the number of uncompressed bytes written, or C if unsuccessful. =head2 flush Usage is $z->flush; Flushes any pending compressed data to the output file/buffer. Returns true on success. =head2 tell Usage is $z->tell() tell $z Returns the uncompressed file offset. =head2 eof Usage is $z->eof(); eof($z); Returns true if the C method has been called. =head2 seek $z->seek($position, $whence); seek($z, $position, $whence); Provides a sub-set of the C functionality, with the restriction that it is only legal to seek forward in the output file/buffer. It is a fatal error to attempt to seek backward. Empty parts of the file/buffer will have NULL (0x00) bytes written to them. The C<$whence> parameter takes one the usual values, namely SEEK_SET, SEEK_CUR or SEEK_END. Returns 1 on success, 0 on failure. =head2 binmode Usage is $z->binmode binmode $z ; This is a noop provided for completeness. =head2 opened $z->opened() Returns true if the object currently refers to a opened file/buffer. =head2 autoflush my $prev = $z->autoflush() my $prev = $z->autoflush(EXPR) If the C<$z> object is associated with a file or a filehandle, this method returns the current autoflush setting for the underlying filehandle. If C is present, and is non-zero, it will enable flushing after every write/print operation. If C<$z> is associated with a buffer, this method has no effect and always returns C. B that the special variable C<$|> B be used to set or retrieve the autoflush setting. =head2 input_line_number $z->input_line_number() $z->input_line_number(EXPR) This method always returns C when compressing. =head2 fileno $z->fileno() fileno($z) If the C<$z> object is associated with a file or a filehandle, C will return the underlying file descriptor. Once the C method is called C will return C. If the C<$z> object is associated with a buffer, this method will return C. =head2 close $z->close() ; close $z ; Flushes any pending compressed data and then closes the output file/buffer. For most versions of Perl this method will be automatically invoked if the IO::Compress::Lzma object is destroyed (either explicitly or by the variable with the reference to the object going out of scope). The exceptions are Perl versions 5.005 through 5.00504 and 5.8.0. In these cases, the C method will be called automatically, but not until global destruction of all live objects when the program is terminating. Therefore, if you want your scripts to be able to run on all versions of Perl, you should call C explicitly and not rely on automatic closing. Returns true on success, otherwise 0. If the C option has been enabled when the IO::Compress::Lzma object was created, and the object is associated with a file, the underlying file will also be closed. =head2 newStream([OPTS]) Usage is $z->newStream( [OPTS] ) Closes the current compressed data stream and starts a new one. OPTS consists of any of the options that are available when creating the C<$z> object. See the L section for more details. =head1 Importing No symbolic constants are required by this IO::Compress::Lzma at present. =over 5 =item :all Imports C and C<$LzmaError>. Same as doing this use IO::Compress::Lzma qw(lzma $LzmaError) ; =back =head1 EXAMPLES =head1 SUPPORT General feedback/questions/bug reports should be sent to L (preferred) or L. =head1 SEE ALSO L, L, L, L, L, L, L, L, L, L, L, L, L, L, L, L, L, L, L, L, L, L L L, L, L, L =head1 AUTHOR This module was written by Paul Marquess, C. =head1 MODIFICATION HISTORY See the Changes file. =head1 COPYRIGHT AND LICENSE Copyright (c) 2005-2019 Paul Marquess. All rights reserved. This program is free software; you can redistribute it and/or modify it under the same terms as Perl itself. libio-compress-lzma-perl-2.093/lib/IO/Compress/Xz.pm000066400000000000000000000502311357305603400221750ustar00rootroot00000000000000package IO::Compress::Xz ; use strict ; use warnings; use bytes; require Exporter ; use IO::Compress::Base 2.093 ; use IO::Compress::Base::Common 2.093 qw(createSelfTiedObject); use IO::Compress::Adapter::Xz 2.093 ; use Compress::Raw::Lzma 2.093 ; our ($VERSION, @ISA, @EXPORT_OK, %EXPORT_TAGS, $XzError); $VERSION = '2.093'; $XzError = ''; @ISA = qw(IO::Compress::Base Exporter); @EXPORT_OK = qw( $XzError xz ) ; %EXPORT_TAGS = %IO::Compress::Base::EXPORT_TAGS ; push @{ $EXPORT_TAGS{constants} }, @Compress::Raw::Lzma::EXPORT; $EXPORT_TAGS{all} = $EXPORT_TAGS{constants} ; push @{ $EXPORT_TAGS{all} }, @EXPORT_OK ; Exporter::export_ok_tags('all'); sub new { my $class = shift ; my $obj = createSelfTiedObject($class, \$XzError); return $obj->_create(undef, @_); } sub xz { my $obj = createSelfTiedObject(undef, \$XzError); $obj->_def(@_); } sub mkHeader { my $self = shift ; return ''; } our %PARAMS = ( 'preset' => [IO::Compress::Base::Common::Parse_unsigned, LZMA_PRESET_DEFAULT], 'extreme'=> [IO::Compress::Base::Common::Parse_boolean, 0], 'check' => [IO::Compress::Base::Common::Parse_unsigned, LZMA_CHECK_CRC32], ); sub getExtraParams { return %PARAMS ; } sub ckParams { my $self = shift ; my $got = shift; # TODO - validate the parameters return 1 ; } sub mkComp { my $self = shift ; my $got = shift ; my ($obj, $errstr, $errno) = IO::Compress::Adapter::Xz::mkCompObject($got->getValue('preset'), $got->getValue('extreme'), $got->getValue('check') ); return $self->saveErrorString(undef, $errstr, $errno) if ! defined $obj; return $obj; } sub mkTrailer { my $self = shift ; return ''; } sub mkFinalTrailer { return ''; } #sub newHeader #{ # my $self = shift ; # return ''; #} sub getInverseClass { return ('IO::Uncompress::UnXz'); } sub getFileInfo { my $self = shift ; my $params = shift; my $file = shift ; } 1; __END__ =head1 NAME IO::Compress::Xz - Write xz files/buffers =head1 SYNOPSIS use IO::Compress::Xz qw(xz $XzError) ; my $status = xz $input => $output [,OPTS] or die "xz failed: $XzError\n"; my $z = new IO::Compress::Xz $output [,OPTS] or die "xz failed: $XzError\n"; $z->print($string); $z->printf($format, $string); $z->write($string); $z->syswrite($string [, $length, $offset]); $z->flush(); $z->tell(); $z->eof(); $z->seek($position, $whence); $z->binmode(); $z->fileno(); $z->opened(); $z->autoflush(); $z->input_line_number(); $z->newStream( [OPTS] ); $z->close() ; $XzError ; # IO::File mode print $z $string; printf $z $format, $string; tell $z eof $z seek $z, $position, $whence binmode $z fileno $z close $z ; =head1 DESCRIPTION B. =over 5 =item * DO NOT use in production code. =item * The documentation is incomplete in places. =item * Parts of the interface defined here are tentative. =item * Please report any problems you find. =back This module provides a Perl interface that allows writing xz compressed data to files or buffer. For reading xz files/buffers, see the companion module L. =head1 Functional Interface A top-level function, C, is provided to carry out "one-shot" compression between buffers and/or files. For finer control over the compression process, see the L section. use IO::Compress::Xz qw(xz $XzError) ; xz $input_filename_or_reference => $output_filename_or_reference [,OPTS] or die "xz failed: $XzError\n"; The functional interface needs Perl5.005 or better. =head2 xz $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 uncompressed data. It can take one of the following forms: =over 5 =item A filename If the C<$input_filename_or_reference> parameter is a simple scalar, it is assumed to be a filename. This file will be opened for reading and the input data will be read from it. =item A filehandle If the C<$input_filename_or_reference> parameter is a filehandle, the input data will be read from it. The string '-' can be used as an alias for standard input. =item A scalar reference If C<$input_filename_or_reference> is a scalar reference, the input data will be read from C<$$input_filename_or_reference>. =item An array reference If C<$input_filename_or_reference> is an array reference, each element in the array must be a filename. The input data will be read from each file in turn. The complete array will be walked to ensure that it only contains valid filenames before any data is compressed. =item An Input FileGlob string If C<$input_filename_or_reference> is a string that is delimited by the characters "<" and ">" C 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 compressed data. This parameter can take one of these forms. =over 5 =item A filename If the C<$output_filename_or_reference> parameter is a simple scalar, it is assumed to be a filename. This file will be opened for writing and the compressed data will be written to it. =item A filehandle If the C<$output_filename_or_reference> parameter is a filehandle, the compressed data will be written to it. The string '-' can be used as an alias for standard output. =item A scalar reference If C<$output_filename_or_reference> is a scalar reference, the compressed data will be stored in C<$$output_filename_or_reference>. =item An Array Reference If C<$output_filename_or_reference> is an array reference, the compressed data will be pushed onto the array. =item An Output FileGlob If C<$output_filename_or_reference> is a string that is delimited by the characters "<" and ">" C will assume that it is an I. The output is the list of files that match the fileglob. When C<$output_filename_or_reference> is an fileglob string, C<$input_filename_or_reference> must also be a fileglob string. Anything else is an error. See L for more details. =back If the C<$output_filename_or_reference> parameter is any other type, C will be returned. =head2 Notes When C<$input_filename_or_reference> maps to multiple files/buffers and C<$output_filename_or_reference> is a single file/buffer the input files/buffers will be stored in C<$output_filename_or_reference> as a concatenated series of compressed data streams. =head2 Optional Parameters The optional parameters for the one-shot function C are (for the most part) identical to those used with the OO interface defined in the L section. The exceptions are listed below =over 5 =item C<< AutoClose => 0|1 >> This option applies to any input or output data streams to C that are filehandles. If C is specified, and the value is true, it will result in all input and/or output filehandles being closed once C has completed. This parameter defaults to 0. =item C<< BinModeIn => 0|1 >> This option is now a no-op. All files will be read in binmode. =item C<< Append => 0|1 >> The behaviour of this option is dependent on the type of output data stream. =over 5 =item * A Buffer If C is enabled, all compressed data will be append to the end of the output buffer. Otherwise the output buffer will be cleared before any compressed data is written to it. =item * A Filename If C is enabled, the file will be opened in append mode. Otherwise the contents of the file, if any, will be truncated before any compressed data is written to it. =item * A Filehandle If C is enabled, the filehandle will be positioned to the end of the file via a call to C before any compressed data is written to it. Otherwise the file pointer will not be moved. =back When C is specified, and set to true, it will I all compressed data to the output data stream. So when the output is a filehandle it will carry out a seek to the eof before writing any compressed data. If the output is a filename, it will be opened for appending. If the output is a buffer, all compressed data will be appended to the existing buffer. Conversely when C is not specified, or it is present and is set to false, it will operate as follows. When the output is a filename, it will truncate the contents of the file before writing any compressed data. If the output is a filehandle its position will not be changed. If the output is a buffer, it will be wiped before any compressed data is output. Defaults to 0. =back =head2 Examples Here are a few example that show the capabilities of the module. =head3 Streaming This very simple command line example demonstrates the streaming capabilities of the module. The code reads data from STDIN, compresses it, and writes the compressed data to STDOUT. $ echo hello world | perl -MIO::Compress::Xz=xz -e 'xz \*STDIN => \*STDOUT' >output.xz The special filename "-" can be used as a standin for both C<\*STDIN> and C<\*STDOUT>, so the above can be rewritten as $ echo hello world | perl -MIO::Compress::Xz=xz -e 'xz "-" => "-"' >output.xz =head3 Compressing a file from the filesystem To read the contents of the file C and write the compressed data to the file C. use strict ; use warnings ; use IO::Compress::Xz qw(xz $XzError) ; my $input = "file1.txt"; xz $input => "$input.xz" or die "xz failed: $XzError\n"; =head3 Reading from a Filehandle and writing to an in-memory buffer To read from an existing Perl filehandle, C<$input>, and write the compressed data to a buffer, C<$buffer>. use strict ; use warnings ; use IO::Compress::Xz qw(xz $XzError) ; use IO::File ; my $input = new IO::File " \$buffer or die "xz failed: $XzError\n"; =head3 Compressing multiple files To compress all files in the directory "/my/home" that match "*.txt" and store the compressed data in the same directory use strict ; use warnings ; use IO::Compress::Xz qw(xz $XzError) ; xz '' => '<*.xz>' or die "xz failed: $XzError\n"; and if you want to compress each file one at a time, this will do the trick use strict ; use warnings ; use IO::Compress::Xz qw(xz $XzError) ; for my $input ( glob "/my/home/*.txt" ) { my $output = "$input.xz" ; xz $input => $output or die "Error compressing '$input': $XzError\n"; } =head1 OO Interface =head2 Constructor The format of the constructor for C is shown below my $z = new IO::Compress::Xz $output [,OPTS] or die "IO::Compress::Xz failed: $XzError\n"; It returns an C object on success and undef on failure. The variable C<$XzError> will contain an error message on failure. If you are running Perl 5.005 or better the object, C<$z>, returned from IO::Compress::Xz can be used exactly like an L filehandle. This means that all normal output file operations can be carried out with C<$z>. For example, to write to a compressed file/buffer you can use either of these forms $z->print("hello world\n"); print $z "hello world\n"; The mandatory parameter C<$output> is used to control the destination of the compressed data. This parameter can take one of these forms. =over 5 =item A filename If the C<$output> parameter is a simple scalar, it is assumed to be a filename. This file will be opened for writing and the compressed data will be written to it. =item A filehandle If the C<$output> parameter is a filehandle, the compressed data will be written to it. The string '-' can be used as an alias for standard output. =item A scalar reference If C<$output> is a scalar reference, the compressed data will be stored in C<$$output>. =back If the C<$output> parameter is any other type, C::new will return undef. =head2 Constructor Options C is any combination of zero or more the following options: =over 5 =item C<< AutoClose => 0|1 >> This option is only valid when the C<$output> parameter is a filehandle. If specified, and the value is true, it will result in the C<$output> being closed once either the C method is called or the C object is destroyed. This parameter defaults to 0. =item C<< Append => 0|1 >> Opens C<$output> in append mode. The behaviour of this option is dependent on the type of C<$output>. =over 5 =item * A Buffer If C<$output> is a buffer and C is enabled, all compressed data will be append to the end of C<$output>. Otherwise C<$output> will be cleared before any data is written to it. =item * A Filename If C<$output> is a filename and C is enabled, the file will be opened in append mode. Otherwise the contents of the file, if any, will be truncated before any compressed data is written to it. =item * A Filehandle If C<$output> is a filehandle, the file pointer will be positioned to the end of the file via a call to C before any compressed data is written to it. Otherwise the file pointer will not be moved. =back This parameter defaults to 0. =item C<< Preset => $preset >> Used to choose the compression preset. Valid values are 0-9 and C. 0 is the fastest compression with the lowest memory usage and the lowest compression. 9 is the slowest compression with the highest memory usage but with the best compression. Defaults to C (6). =item C<< Extreme => 0|1 >> Makes the compression a lot slower, but a small compression gain. Defaults to 0. =item C<< Check => $check >> Used to specify the integrrity check used in the xz data stream. Valid values are C, C, C, C. Defaults to C. =item C<< Strict => 0|1 >> This is a placeholder option. =back =head2 Examples TODO =head1 Methods =head2 print Usage is $z->print($data) print $z $data Compresses and outputs the contents of the C<$data> parameter. This has the same behaviour as the C built-in. Returns true if successful. =head2 printf Usage is $z->printf($format, $data) printf $z $format, $data Compresses and outputs the contents of the C<$data> parameter. Returns true if successful. =head2 syswrite Usage is $z->syswrite $data $z->syswrite $data, $length $z->syswrite $data, $length, $offset Compresses and outputs the contents of the C<$data> parameter. Returns the number of uncompressed bytes written, or C if unsuccessful. =head2 write Usage is $z->write $data $z->write $data, $length $z->write $data, $length, $offset Compresses and outputs the contents of the C<$data> parameter. Returns the number of uncompressed bytes written, or C if unsuccessful. =head2 flush Usage is $z->flush; Flushes any pending compressed data to the output file/buffer. Returns true on success. =head2 tell Usage is $z->tell() tell $z Returns the uncompressed file offset. =head2 eof Usage is $z->eof(); eof($z); Returns true if the C method has been called. =head2 seek $z->seek($position, $whence); seek($z, $position, $whence); Provides a sub-set of the C functionality, with the restriction that it is only legal to seek forward in the output file/buffer. It is a fatal error to attempt to seek backward. Empty parts of the file/buffer will have NULL (0x00) bytes written to them. The C<$whence> parameter takes one the usual values, namely SEEK_SET, SEEK_CUR or SEEK_END. Returns 1 on success, 0 on failure. =head2 binmode Usage is $z->binmode binmode $z ; This is a noop provided for completeness. =head2 opened $z->opened() Returns true if the object currently refers to a opened file/buffer. =head2 autoflush my $prev = $z->autoflush() my $prev = $z->autoflush(EXPR) If the C<$z> object is associated with a file or a filehandle, this method returns the current autoflush setting for the underlying filehandle. If C is present, and is non-zero, it will enable flushing after every write/print operation. If C<$z> is associated with a buffer, this method has no effect and always returns C. B that the special variable C<$|> B be used to set or retrieve the autoflush setting. =head2 input_line_number $z->input_line_number() $z->input_line_number(EXPR) This method always returns C when compressing. =head2 fileno $z->fileno() fileno($z) If the C<$z> object is associated with a file or a filehandle, C will return the underlying file descriptor. Once the C method is called C will return C. If the C<$z> object is associated with a buffer, this method will return C. =head2 close $z->close() ; close $z ; Flushes any pending compressed data and then closes the output file/buffer. For most versions of Perl this method will be automatically invoked if the IO::Compress::Xz object is destroyed (either explicitly or by the variable with the reference to the object going out of scope). The exceptions are Perl versions 5.005 through 5.00504 and 5.8.0. In these cases, the C method will be called automatically, but not until global destruction of all live objects when the program is terminating. Therefore, if you want your scripts to be able to run on all versions of Perl, you should call C explicitly and not rely on automatic closing. Returns true on success, otherwise 0. If the C option has been enabled when the IO::Compress::Xz object was created, and the object is associated with a file, the underlying file will also be closed. =head2 newStream([OPTS]) Usage is $z->newStream( [OPTS] ) Closes the current compressed data stream and starts a new one. OPTS consists of any of the options that are available when creating the C<$z> object. See the L section for more details. =head1 Importing No symbolic constants are required by this IO::Compress::Xz at present. =over 5 =item :all Imports C and C<$XzError>. Same as doing this use IO::Compress::Xz qw(xz $XzError) ; =back =head1 EXAMPLES =head1 SUPPORT General feedback/questions/bug reports should be sent to L (preferred) or L. =head1 SEE ALSO L, L, L, L, L, L, L, L, L, L, L, L, L, L, L, L, L, L, L, L, L, L L L, L, L, L =head1 AUTHOR This module was written by Paul Marquess, C. =head1 MODIFICATION HISTORY See the Changes file. =head1 COPYRIGHT AND LICENSE Copyright (c) 2005-2019 Paul Marquess. All rights reserved. This program is free software; you can redistribute it and/or modify it under the same terms as Perl itself. libio-compress-lzma-perl-2.093/lib/IO/Uncompress/000077500000000000000000000000001357305603400216005ustar00rootroot00000000000000libio-compress-lzma-perl-2.093/lib/IO/Uncompress/Adapter/000077500000000000000000000000001357305603400231605ustar00rootroot00000000000000libio-compress-lzma-perl-2.093/lib/IO/Uncompress/Adapter/UnLzip.pm000066400000000000000000000102511357305603400247360ustar00rootroot00000000000000package IO::Uncompress::Adapter::UnLzip; use strict; use warnings; use bytes; use IO::Compress::Base::Common 2.093 qw(:Status); use Compress::Raw::Lzma 2.093 ; our ($VERSION, @ISA); $VERSION = '2.093'; #@ISA = qw( Compress::Raw::UnLzma ); sub mkUncompObject { my $dictSize = shift; # my $properties ; # my $filter = Lzma::Filter::Lzma1(DictSize => $dictSize, # #'PreserDict' => [1, 1, Parse_unsigned(), undef], # # 'Lc' => [1, 1, Parse_unsigned(), LZMA_LC_DEFAULT()], # # 'Lp' => [1, 1, Parse_unsigned(), LZMA_LP_DEFAULT()], # # 'Pb' => [1, 1, Parse_unsigned(), LZMA_PB_DEFAULT()], # # 'Mode' => [1, 1, Parse_unsigned(), LZMA_MODE_NORMAL()], # # 'Nice' => [1, 1, Parse_unsigned(), 64], # # 'Mf' => [1, 1, Parse_unsigned(), LZMA_MF_BT4()], # # 'Depth' => [1, 1, Parse_unsigned(), 0], # ); # From lzip_init (in archive_read_support_filter_xz.c) my $properties = pack("C V", 0x5D, 1 << ($dictSize & 0x1F)); my ($inflate, $status) = Compress::Raw::Lzma::RawDecoder->new(AppendOutput => 1, Properties => $properties, # Filter => $filter, ConsumeInput => 1, LimitOutput => 1); return (undef, "Could not create RawDecoder object: $status", $status) if $status != LZMA_OK ; return bless {'Inf' => $inflate, 'CompSize' => 0, 'UnCompSize' => 0, 'Error' => '', 'ErrorNo' => 0, 'ConsumesInput' => 1, 'CRC32' => 0, 'Properties' => $properties, } ; } sub uncompr { my $self = shift ; my $from = shift ; my $to = shift ; my $eof = shift ; my $len = length($$to) ; my $inf = $self->{Inf}; my $status = $inf->code($from, $to); $self->{ErrorNo} = $status; if ($status != LZMA_OK && $status != LZMA_STREAM_END ) { $self->{Error} = "Uncompression Error: $status"; return STATUS_ERROR; } $self->{CRC32} = Compress::Raw::Zlib::crc32(substr($$to, $len), $self->{CRC32}) if length($$to) > $len ; return STATUS_ENDSTREAM if $status == LZMA_STREAM_END || ($eof && length $$from == 0); return STATUS_OK if $status == LZMA_OK ; return STATUS_ERROR ; } sub reset { my $self = shift ; my ($inf, $status) = Compress::Raw::Lzma::RawDecoder->new(AppendOutput => 1, Properties => $self->{Properties}, # Filter => $filter, ConsumeInput => 1, LimitOutput => 1); # my ($inf, $status) = Compress::Raw::Lzma::RawDecoder->new(AppendOutput => 1, # ConsumeInput => 1, # LimitOutput => 1); $self->{ErrorNo} = ($status == LZMA_OK) ? 0 : $status ; if ($status != LZMA_OK) { $self->{Error} = "Cannot create UnLzma object: $status"; return STATUS_ERROR; } $self->{Inf} = $inf; $self->{CRC32} = 0 ; return STATUS_OK ; } #sub count #{ # my $self = shift ; # $self->{Inf}->inflateCount(); #} sub compressedBytes { my $self = shift ; $self->{Inf}->compressedBytes(); } sub uncompressedBytes { my $self = shift ; $self->{Inf}->uncompressedBytes(); } sub crc32 { my $self = shift ; $self->{CRC32}; } sub adler32 { my $self = shift ; #$self->{Inf}->adler32(); } sub sync { my $self = shift ; #( $self->{Inf}->inflateSync(@_) == LZMA_OK) # ? STATUS_OK # : STATUS_ERROR ; } 1; __END__ libio-compress-lzma-perl-2.093/lib/IO/Uncompress/Adapter/UnLzma.pm000066400000000000000000000073641357305603400247360ustar00rootroot00000000000000package IO::Uncompress::Adapter::UnLzma; use strict; use warnings; use bytes; use IO::Compress::Base::Common 2.093 qw(:Status); use Compress::Raw::Lzma 2.093 ; our ($VERSION, @ISA); $VERSION = '2.093'; #@ISA = qw( Compress::Raw::UnLzma ); sub mkUncompObject { #my $CompressedLength = shift; #my $UncompressedLength = shift; #my $small = shift || 0; #my $verbosity = shift || 0; my ($inflate, $status) = Compress::Raw::Lzma::AloneDecoder->new(AppendOutput => 1, ConsumeInput => 1, LimitOutput => 1); return (undef, "Could not create AloneDecoder object: $status", $status) if $status != LZMA_OK ; return bless {'Inf' => $inflate, 'CompSize' => 0, 'UnCompSize' => 0, 'Error' => '', 'ConsumesInput' => 1, #'CompressedLen' => $CompressedLength || 0, #'UncompressedLen' => $UncompressedLength || 0, } ; } sub mkUncompZipObject { my $properties = shift ; #my $CompressedLength = shift; #my $UncompressedLength = shift; #my $small = shift || 0; #my $verbosity = shift || 0; my ($inflate, $status) = Compress::Raw::Lzma::RawDecoder->new(AppendOutput => 1, Properties => $properties, ConsumeInput => 1, LimitOutput => 1); return (undef, "Could not create RawDecoder object: $status", $status) if $status != LZMA_OK ; return bless {'Inf' => $inflate, 'CompSize' => 0, 'UnCompSize' => 0, 'Error' => '', 'ConsumesInput' => 1, 'ResetData' => $properties, #'CompressedLen' => $CompressedLength || 0, #'UncompressedLen' => $UncompressedLength || 0, } ; } sub uncompr { my $self = shift ; my $from = shift ; my $to = shift ; my $eof = shift ; my $inf = $self->{Inf}; my $status = $inf->code($from, $to); $self->{ErrorNo} = $status; if ($status != LZMA_OK && $status != LZMA_STREAM_END ) { $self->{Error} = "Uncompression Error: $status"; return STATUS_ERROR; } return STATUS_ENDSTREAM if $status == LZMA_STREAM_END || ($eof && length $$from == 0); return STATUS_OK if $status == LZMA_OK ; return STATUS_ERROR ; } sub reset { my $self = shift ; my ($inf, $status) = Compress::Raw::Lzma::RawDecoder->new(AppendOutput => 1, Properties => $self->{'ResetData'}, ConsumeInput => 1, LimitOutput => 1); $self->{ErrorNo} = ($status == LZMA_OK) ? 0 : $status ; if ($status != LZMA_OK) { $self->{Error} = "Cannot create UnLzma object: $status"; return STATUS_ERROR; } $self->{Inf} = $inf; return STATUS_OK ; } #sub count #{ # my $self = shift ; # $self->{Inf}->inflateCount(); #} sub compressedBytes { my $self = shift ; $self->{Inf}->compressedBytes(); } sub uncompressedBytes { my $self = shift ; $self->{Inf}->uncompressedBytes(); } sub crc32 { my $self = shift ; #$self->{Inf}->crc32(); } sub adler32 { my $self = shift ; #$self->{Inf}->adler32(); } sub sync { my $self = shift ; #( $self->{Inf}->inflateSync(@_) == LZMA_OK) # ? STATUS_OK # : STATUS_ERROR ; } 1; __END__ libio-compress-lzma-perl-2.093/lib/IO/Uncompress/Adapter/UnXz.pm000066400000000000000000000051571357305603400244320ustar00rootroot00000000000000package IO::Uncompress::Adapter::UnXz; use strict; use warnings; use bytes; use IO::Compress::Base::Common 2.093 qw(:Status); use Compress::Raw::Lzma 2.093 ; our ($VERSION, @ISA); $VERSION = '2.093'; #@ISA = qw( Compress::Raw::UnLzma ); sub mkUncompObject { my $memlimit = shift || 128 * 1024 * 1024; my $flags = shift || 0; my ($inflate, $status) = Compress::Raw::Lzma::StreamDecoder->new(AppendOutput => 1, ConsumeInput => 1, LimitOutput => 1, MemLimit => $memlimit, Flags => $flags, ); return (undef, "Could not create StreamDecoder object: $status", $status) if $status != LZMA_OK ; return bless {'Inf' => $inflate, 'CompSize' => 0, 'UnCompSize' => 0, 'Error' => '', 'ConsumesInput' => 1, } ; } sub uncompr { my $self = shift ; my $from = shift ; my $to = shift ; my $eof = shift ; my $inf = $self->{Inf}; my $status = $inf->code($from, $to); $self->{ErrorNo} = $status; if ($status != LZMA_OK && $status != LZMA_STREAM_END ) { $self->{Error} = "Uncompression Error: $status"; return STATUS_ERROR; } return STATUS_OK if $status == LZMA_OK ; return STATUS_ENDSTREAM if $status == LZMA_STREAM_END ; return STATUS_ERROR ; } sub reset { my $self = shift ; my ($inf, $status) = Compress::Raw::Lzma::StreamDecoder->new(AppendOutput => 1, ConsumeInput => 1, LimitOutput => 1); $self->{ErrorNo} = ($status == LZMA_OK) ? 0 : $status ; if ($status != LZMA_OK) { $self->{Error} = "Cannot create UnXz object: $status"; return STATUS_ERROR; } $self->{Inf} = $inf; return STATUS_OK ; } #sub count #{ # my $self = shift ; # $self->{Inf}->inflateCount(); #} sub compressedBytes { my $self = shift ; $self->{Inf}->compressedBytes(); } sub uncompressedBytes { my $self = shift ; $self->{Inf}->uncompressedBytes(); } sub crc32 { my $self = shift ; #$self->{Inf}->crc32(); } sub adler32 { my $self = shift ; #$self->{Inf}->adler32(); } sub sync { my $self = shift ; #( $self->{Inf}->inflateSync(@_) == LZMA_OK) # ? STATUS_OK # : STATUS_ERROR ; } 1; __END__ libio-compress-lzma-perl-2.093/lib/IO/Uncompress/UnLzip.pm000066400000000000000000000645151357305603400233720ustar00rootroot00000000000000package IO::Uncompress::UnLzip ; use strict ; use warnings; use bytes; use IO::Compress::Base::Common 2.093 qw(:Status createSelfTiedObject); use IO::Uncompress::Base 2.093 ; use IO::Uncompress::Adapter::UnLzip 2.093 ; require Exporter ; our ($VERSION, @ISA, @EXPORT_OK, %EXPORT_TAGS, $UnLzipError); $VERSION = '2.093'; $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 = new IO::Uncompress::UnLzip $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 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. The output is the list of files that match the fileglob. When C<$output_filename_or_reference> is an fileglob string, C<$input_filename_or_reference> must also be a fileglob string. Anything else is an error. See L for more details. =back If the C<$output_filename_or_reference> parameter is any other type, C will be returned. =head2 Notes When C<$input_filename_or_reference> maps to multiple compressed files/buffers and C<$output_filename_or_reference> is a single file/buffer, after uncompression C<$output_filename_or_reference> will contain a concatenation of all the uncompressed data from each of the input files/buffers. =head2 Optional Parameters The optional parameters for the one-shot function C are (for the most part) identical to those used with the OO interface defined in the L section. The exceptions are listed below =over 5 =item C<< AutoClose => 0|1 >> This option applies to any input or output data streams to C that are filehandles. If C is specified, and the value is true, it will result in all input and/or output filehandles being closed once C has completed. This parameter defaults to 0. =item C<< BinModeOut => 0|1 >> This option is now a no-op. All files will be written in binmode. =item C<< Append => 0|1 >> The behaviour of this option is dependent on the type of output data stream. =over 5 =item * A Buffer If C is enabled, all uncompressed data will be append to the end of the output buffer. Otherwise the output buffer will be cleared before any uncompressed data is written to it. =item * A Filename If C is enabled, the file will be opened in append mode. Otherwise the contents of the file, if any, will be truncated before any uncompressed data is written to it. =item * A Filehandle If C is enabled, the filehandle will be positioned to the end of the file via a call to C before any uncompressed data is written to it. Otherwise the file pointer will not be moved. =back When C is specified, and set to true, it will I all uncompressed data to the output data stream. So when the output is a filehandle it will carry out a seek to the eof before writing any uncompressed data. If the output is a filename, it will be opened for appending. If the output is a buffer, all uncompressed data will be appended to the existing buffer. Conversely when C is not specified, or it is present and is set to false, it will operate as follows. When the output is a filename, it will truncate the contents of the file before writing any uncompressed data. If the output is a filehandle its position will not be changed. If the output is a buffer, it will be wiped before any uncompressed data is output. Defaults to 0. =item C<< MultiStream => 0|1 >> If the input file/buffer contains multiple compressed data streams, this option will uncompress the whole lot as a single data stream. Defaults to 0. =item C<< TrailingData => $scalar >> Returns the data, if any, that is present immediately after the compressed data stream once uncompression is complete. This option can be used when there is useful information immediately following the compressed data stream, and you don't know the length of the compressed data stream. If the input is a buffer, C will return everything from the end of the compressed data stream to the end of the buffer. If the input is a filehandle, C will return the data that is left in the filehandle input buffer once the end of the compressed data stream has been reached. You can then use the filehandle to read the rest of the input file. Don't bother using C if the input is a filename. If you know the length of the compressed data stream before you start uncompressing, you can avoid having to use C by setting the C option. =back =head2 Examples To read the contents of the file C and write the uncompressed data to the file C. use strict ; use warnings ; use IO::Uncompress::UnLzip qw(unlzip $UnLzipError) ; my $input = "file1.txt.xz"; my $output = "file1.txt"; unlzip $input => $output or die "unlzip failed: $UnLzipError\n"; To read from an existing Perl filehandle, C<$input>, and write the uncompressed data to a buffer, C<$buffer>. use strict ; use warnings ; use IO::Uncompress::UnLzip qw(unlzip $UnLzipError) ; use IO::File ; my $input = new IO::File " \$buffer or die "unlzip failed: $UnLzipError\n"; To uncompress all files in the directory "/my/home" that match "*.txt.xz" and store the compressed data in the same directory use strict ; use warnings ; use IO::Uncompress::UnLzip qw(unlzip $UnLzipError) ; unlzip '' => '' or die "unlzip failed: $UnLzipError\n"; and if you want to compress each file one at a time, this will do the trick use strict ; use warnings ; use IO::Uncompress::UnLzip qw(unlzip $UnLzipError) ; for my $input ( glob "/my/home/*.txt.xz" ) { my $output = $input; $output =~ s/.xz// ; unlzip $input => $output or die "Error compressing '$input': $UnLzipError\n"; } =head1 OO Interface =head2 Constructor The format of the constructor for IO::Uncompress::UnLzip is shown below my $z = new IO::Uncompress::UnLzip $input [OPTS] or die "IO::Uncompress::UnLzip failed: $UnLzipError\n"; Returns an C object on success and undef on failure. The variable C<$UnLzipError> will contain an error message on failure. If you are running Perl 5.005 or better the object, C<$z>, returned from IO::Uncompress::UnLzip can be used exactly like an L filehandle. This means that all normal input file operations can be carried out with C<$z>. For example, to read a line from a compressed file/buffer you can use either of these forms $line = $z->getline(); $line = <$z>; The mandatory parameter C<$input> is used to determine the source of the compressed data. This parameter can take one of three forms. =over 5 =item A filename If the C<$input> parameter is a scalar, it is assumed to be a filename. This file will be opened for reading and the compressed data will be read from it. =item A filehandle If the C<$input> parameter is a filehandle, the compressed data will be read from it. The string '-' can be used as an alias for standard input. =item A scalar reference If C<$input> is a scalar reference, the compressed data will be read from C<$$input>. =back =head2 Constructor Options The option names defined below are case insensitive and can be optionally prefixed by a '-'. So all of the following are valid -AutoClose -autoclose AUTOCLOSE autoclose OPTS is a combination of the following options: =over 5 =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 either the C method is called or the IO::Uncompress::UnLzip object is destroyed. This parameter defaults to 0. =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. This parameter defaults to 0. =item C<< Prime => $string >> This option will uncompress the contents of C<$string> before processing the input file/buffer. This option can be useful when the compressed data is embedded in another file/data structure and it is not possible to work out where the compressed data begins without having to read the first few bytes. If this is the case, the uncompression can be I with these bytes using this option. =item C<< Transparent => 0|1 >> 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/buffer as a single data stream. This option defaults to 1. =item C<< BlockSize => $num >> When reading the compressed input data, IO::Uncompress::UnLzip will read it in blocks of C<$num> bytes. This option defaults to 4096. =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 situation where there is useful data directly after the compressed data stream and you know beforehand the exact length of the compressed data stream. This option is mostly used when reading from a filehandle, in which case the file pointer will be left pointing to the first byte directly after the compressed data stream. This option defaults to off. =item C<< Append => 0|1 >> This option controls what the C method does with uncompressed data. If set to 1, all uncompressed data will be appended to the output parameter of the C method. If set to 0, the contents of the output parameter of the C method will be overwritten by the uncompressed data. Defaults to 0. =item C<< Strict => 0|1 >> This option controls whether the extra checks defined below are used when carrying out the decompression. When Strict is on, the extra tests are carried out, when Strict is off they are not. The default for this option is off. =back =head2 Examples TODO =head1 Methods =head2 read Usage is $status = $z->read($buffer) Reads a block of compressed data (the size of the compressed block is determined by the C option in the constructor), uncompresses it and writes any uncompressed data into C<$buffer>. If the C parameter is set in the constructor, the uncompressed data will be appended to the C<$buffer> parameter. Otherwise C<$buffer> will be overwritten. Returns the number of uncompressed bytes written to C<$buffer>, zero if eof or a negative number on error. =head2 read Usage is $status = $z->read($buffer, $length) $status = $z->read($buffer, $length, $offset) $status = read($z, $buffer, $length) $status = read($z, $buffer, $length, $offset) Attempt to read C<$length> bytes of uncompressed data into C<$buffer>. The main difference between this form of the C method and the previous one, is that this one will attempt to return I C<$length> bytes. The only circumstances that this function will not is if end-of-file or an IO error is encountered. Returns the number of uncompressed bytes written to C<$buffer>, zero if eof or a negative number on error. =head2 getline Usage is $line = $z->getline() $line = <$z> Reads a single line. This method fully supports the use of the variable C<$/> (or C<$INPUT_RECORD_SEPARATOR> or C<$RS> when C is in use) to determine what constitutes an end of line. Paragraph mode, record mode and file slurp mode are all supported. =head2 getc Usage is $char = $z->getc() Read a single character. =head2 ungetc Usage is $char = $z->ungetc($string) =head2 getHeaderInfo Usage is $hdr = $z->getHeaderInfo(); @hdrs = $z->getHeaderInfo(); This method returns either a hash reference (in scalar context) or a list or hash references (in array context) that contains information about each of the header fields in the compressed data stream(s). =head2 tell Usage is $z->tell() tell $z Returns the uncompressed file offset. =head2 eof Usage is $z->eof(); eof($z); Returns true if the end of the compressed input stream has been reached. =head2 seek $z->seek($position, $whence); seek($z, $position, $whence); Provides a sub-set of the C functionality, with the restriction that it is only legal to seek forward in the input file/buffer. It is a fatal error to attempt to seek backward. Note that the implementation of C in this module does not provide true random access to a compressed file/buffer. It works by uncompressing data from the current offset in the file/buffer until it reaches the uncompressed offset specified in the parameters to C. For very small files this may be acceptable behaviour. For large files it may cause an unacceptable delay. The C<$whence> parameter takes one the usual values, namely SEEK_SET, SEEK_CUR or SEEK_END. Returns 1 on success, 0 on failure. =head2 binmode Usage is $z->binmode binmode $z ; This is a noop provided for completeness. =head2 opened $z->opened() Returns true if the object currently refers to a opened file/buffer. =head2 autoflush my $prev = $z->autoflush() my $prev = $z->autoflush(EXPR) If the C<$z> object is associated with a file or a filehandle, this method returns the current autoflush setting for the underlying filehandle. If C is present, and is non-zero, it will enable flushing after every write/print operation. If C<$z> is associated with a buffer, this method has no effect and always returns C. B that the special variable C<$|> B be used to set or retrieve the autoflush setting. =head2 input_line_number $z->input_line_number() $z->input_line_number(EXPR) Returns the current uncompressed line number. If C is present it has the effect of setting the line number. Note that setting the line number does not change the current position within the file/buffer being read. The contents of C<$/> are used to determine what constitutes a line terminator. =head2 fileno $z->fileno() fileno($z) If the C<$z> object is associated with a file or a filehandle, C will return the underlying file descriptor. Once the C method is called C will return C. If the C<$z> object is associated with a buffer, this method will return C. =head2 close $z->close() ; close $z ; Closes the output file/buffer. For most versions of Perl this method will be automatically invoked if the IO::Uncompress::UnLzip object is destroyed (either explicitly or by the variable with the reference to the object going out of scope). The exceptions are Perl versions 5.005 through 5.00504 and 5.8.0. In these cases, the C method will be called automatically, but not until global destruction of all live objects when the program is terminating. Therefore, if you want your scripts to be able to run on all versions of Perl, you should call C explicitly and not rely on automatic closing. Returns true on success, otherwise 0. If the C option has been enabled when the IO::Uncompress::UnLzip object was created, and the object is associated with a file, the underlying file will also be closed. =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 and 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 the data, if any, that is present immediately after the compressed data stream once uncompression is complete. It only makes sense to call this method once the end of the compressed data stream has been encountered. This option can be used when there is useful information immediately following the compressed data stream, and you don't know the length of the compressed data stream. If the input is a buffer, C will return everything from the end of the compressed data stream to the end of the buffer. If the input is a filehandle, C will return the data that is left in the filehandle input buffer once the end of the compressed data stream has been reached. You can then use the filehandle to read the rest of the input file. Don't bother using C if the input is a filename. If you know the length of the compressed data stream before you start uncompressing, you can avoid having to use C by setting the C option in the constructor. =head1 Importing No symbolic constants are required by this IO::Uncompress::UnLzip at present. =over 5 =item :all Imports C and C<$UnLzipError>. Same as doing this use IO::Uncompress::UnLzip qw(unlzip $UnLzipError) ; =back =head1 EXAMPLES =head1 SUPPORT General feedback/questions/bug reports should be sent to L (preferred) or L. =head1 SEE ALSO L, L, L, L, L, L, L, L, L, L, L, L, L, L, L, L, L, L, L, L, L, L L L, L, L, L =head1 AUTHOR This module was written by Paul Marquess, C. =head1 MODIFICATION HISTORY See the Changes file. =head1 COPYRIGHT AND LICENSE Copyright (c) 2005-2019 Paul Marquess. All rights reserved. This program is free software; you can redistribute it and/or modify it under the same terms as Perl itself. libio-compress-lzma-perl-2.093/lib/IO/Uncompress/UnLzma.pm000066400000000000000000000641371357305603400233570ustar00rootroot00000000000000package IO::Uncompress::UnLzma ; use strict ; use warnings; use bytes; use IO::Compress::Base::Common 2.093 qw(:Status createSelfTiedObject); use IO::Uncompress::Base 2.093 ; use IO::Uncompress::Adapter::UnLzma 2.093 ; require Exporter ; our ($VERSION, @ISA, @EXPORT_OK, %EXPORT_TAGS, $UnLzmaError); $VERSION = '2.093'; $UnLzmaError = ''; @ISA = qw( IO::Uncompress::Base Exporter ); @EXPORT_OK = qw( $UnLzmaError unlzma ) ; #%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, \$UnLzmaError); $obj->_create(undef, 0, @_); } sub unlzma { my $obj = createSelfTiedObject(undef, \$UnLzmaError); 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 $Small = $got->getValue('small'); #my $Verbosity = $got->getValue('verbosity'); my ($obj, $errstr, $errno) = IO::Uncompress::Adapter::UnLzma::mkUncompObject( ); return $self->saveErrorString(undef, $errstr, $errno) if ! defined $obj; *$self->{Uncomp} = $obj; *$self->{Info} = $self->ckMagic() or return 0 ; return 1; } sub ckMagic { my $self = shift; my $got = $self->isLzma(@_); if ($got) { *$self->{Pending} = *$self->{HeaderPending} ; } else { $self->pushBack(*$self->{HeaderPending}); *$self->{Uncomp}->reset(); } *$self->{HeaderPending} = ''; return $got ; } sub isLzma { my $self = shift ; my $magic = shift; $magic = '' unless defined $magic ; my $buffer = ''; $self->smartRead(\$buffer, *$self->{BlockSize}) >= 0 or return $self->saveErrorString(undef, "No data to read"); my $temp_buf = $magic . $buffer ; *$self->{HeaderPending} = $temp_buf ; $buffer = ''; my $status = *$self->{Uncomp}->uncompr(\$temp_buf, \$buffer, $self->smartEof()) ; return $self->saveErrorString(undef, *$self->{Uncomp}{Error}, STATUS_ERROR) if $status == STATUS_ERROR; $self->pushBack($temp_buf) ; return $self->saveErrorString(undef, "unexpected end of file", STATUS_ERROR) if $self->smartEof() && $status != STATUS_ENDSTREAM; #my $buf_len = *$self->{Uncomp}->uncompressedBytes(); my $buf_len = length $buffer; if ($status == STATUS_ENDSTREAM) { if (*$self->{MultiStream} && (length $temp_buf || ! $self->smartEof())){ *$self->{NewStream} = 1 ; *$self->{EndStream} = 0 ; } else { *$self->{EndStream} = 1 ; } } *$self->{HeaderPending} = $buffer ; *$self->{InflatedBytesRead} = $buf_len ; *$self->{TotalInflatedBytesRead} += $buf_len ; *$self->{Type} = 'lzma'; $self->saveStatus(STATUS_OK); return { 'Type' => 'lzma', 'HeaderLength' => 0, 'TrailerLength' => 0, 'Header' => '' }; return ''; } sub readHeader { my $self = shift; my $magic = shift ; $self->pushBack($magic); *$self->{HeaderPending} = ''; return { 'Type' => 'lzma', 'FingerprintLength' => 0, 'HeaderLength' => 0, 'TrailerLength' => 0, 'Header' => '' }; } sub chkTrailer { return STATUS_OK; } 1 ; __END__ =head1 NAME IO::Uncompress::UnLzma - Read lzma files/buffers =head1 SYNOPSIS use IO::Uncompress::UnLzma qw(unlzma $UnLzmaError) ; my $status = unlzma $input => $output [,OPTS] or die "unlzma failed: $UnLzmaError\n"; my $z = new IO::Uncompress::UnLzma $input [OPTS] or die "unlzma failed: $UnLzmaError\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() $UnLzmaError ; # 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 B. =over 5 =item * DO NOT use in production code. =item * The documentation is incomplete in places. =item * Parts of the interface defined here are tentative. =item * Please report any problems you find. =back This module provides a Perl interface that allows the reading of lzma files/buffers. For writing lzma files/buffers, see the companion module IO::Compress::Lzma. =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 section. use IO::Uncompress::UnLzma qw(unlzma $UnLzmaError) ; unlzma $input_filename_or_reference => $output_filename_or_reference [,OPTS] or die "unlzma failed: $UnLzmaError\n"; The functional interface needs Perl5.005 or better. =head2 unlzma $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. The output is the list of files that match the fileglob. When C<$output_filename_or_reference> is an fileglob string, C<$input_filename_or_reference> must also be a fileglob string. Anything else is an error. See L for more details. =back If the C<$output_filename_or_reference> parameter is any other type, C will be returned. =head2 Notes When C<$input_filename_or_reference> maps to multiple compressed files/buffers and C<$output_filename_or_reference> is a single file/buffer, after uncompression C<$output_filename_or_reference> will contain a concatenation of all the uncompressed data from each of the input files/buffers. =head2 Optional Parameters The optional parameters for the one-shot function C are (for the most part) identical to those used with the OO interface defined in the L section. The exceptions are listed below =over 5 =item C<< AutoClose => 0|1 >> This option applies to any input or output data streams to C that are filehandles. If C is specified, and the value is true, it will result in all input and/or output filehandles being closed once C has completed. This parameter defaults to 0. =item C<< BinModeOut => 0|1 >> This option is now a no-op. All files will be written in binmode. =item C<< Append => 0|1 >> The behaviour of this option is dependent on the type of output data stream. =over 5 =item * A Buffer If C is enabled, all uncompressed data will be append to the end of the output buffer. Otherwise the output buffer will be cleared before any uncompressed data is written to it. =item * A Filename If C is enabled, the file will be opened in append mode. Otherwise the contents of the file, if any, will be truncated before any uncompressed data is written to it. =item * A Filehandle If C is enabled, the filehandle will be positioned to the end of the file via a call to C before any uncompressed data is written to it. Otherwise the file pointer will not be moved. =back When C is specified, and set to true, it will I all uncompressed data to the output data stream. So when the output is a filehandle it will carry out a seek to the eof before writing any uncompressed data. If the output is a filename, it will be opened for appending. If the output is a buffer, all uncompressed data will be appended to the existing buffer. Conversely when C is not specified, or it is present and is set to false, it will operate as follows. When the output is a filename, it will truncate the contents of the file before writing any uncompressed data. If the output is a filehandle its position will not be changed. If the output is a buffer, it will be wiped before any uncompressed data is output. Defaults to 0. =item C<< MultiStream => 0|1 >> If the input file/buffer contains multiple compressed data streams, this option will uncompress the whole lot as a single data stream. Defaults to 0. =item C<< TrailingData => $scalar >> Returns the data, if any, that is present immediately after the compressed data stream once uncompression is complete. This option can be used when there is useful information immediately following the compressed data stream, and you don't know the length of the compressed data stream. If the input is a buffer, C will return everything from the end of the compressed data stream to the end of the buffer. If the input is a filehandle, C will return the data that is left in the filehandle input buffer once the end of the compressed data stream has been reached. You can then use the filehandle to read the rest of the input file. Don't bother using C if the input is a filename. If you know the length of the compressed data stream before you start uncompressing, you can avoid having to use C by setting the C option. =back =head2 Examples To read the contents of the file C and write the uncompressed data to the file C. use strict ; use warnings ; use IO::Uncompress::UnLzma qw(unlzma $UnLzmaError) ; my $input = "file1.txt.lzma"; my $output = "file1.txt"; unlzma $input => $output or die "unlzma failed: $UnLzmaError\n"; To read from an existing Perl filehandle, C<$input>, and write the uncompressed data to a buffer, C<$buffer>. use strict ; use warnings ; use IO::Uncompress::UnLzma qw(unlzma $UnLzmaError) ; use IO::File ; my $input = new IO::File " \$buffer or die "unlzma failed: $UnLzmaError\n"; To uncompress all files in the directory "/my/home" that match "*.txt.lzma" and store the compressed data in the same directory use strict ; use warnings ; use IO::Uncompress::UnLzma qw(unlzma $UnLzmaError) ; unlzma '' => '' or die "unlzma failed: $UnLzmaError\n"; and if you want to compress each file one at a time, this will do the trick use strict ; use warnings ; use IO::Uncompress::UnLzma qw(unlzma $UnLzmaError) ; for my $input ( glob "/my/home/*.txt.lzma" ) { my $output = $input; $output =~ s/.lzma// ; unlzma $input => $output or die "Error compressing '$input': $UnLzmaError\n"; } =head1 OO Interface =head2 Constructor The format of the constructor for IO::Uncompress::UnLzma is shown below my $z = new IO::Uncompress::UnLzma $input [OPTS] or die "IO::Uncompress::UnLzma failed: $UnLzmaError\n"; Returns an C object on success and undef on failure. The variable C<$UnLzmaError> will contain an error message on failure. If you are running Perl 5.005 or better the object, C<$z>, returned from IO::Uncompress::UnLzma can be used exactly like an L filehandle. This means that all normal input file operations can be carried out with C<$z>. For example, to read a line from a compressed file/buffer you can use either of these forms $line = $z->getline(); $line = <$z>; The mandatory parameter C<$input> is used to determine the source of the compressed data. This parameter can take one of three forms. =over 5 =item A filename If the C<$input> parameter is a scalar, it is assumed to be a filename. This file will be opened for reading and the compressed data will be read from it. =item A filehandle If the C<$input> parameter is a filehandle, the compressed data will be read from it. The string '-' can be used as an alias for standard input. =item A scalar reference If C<$input> is a scalar reference, the compressed data will be read from C<$$input>. =back =head2 Constructor Options The option names defined below are case insensitive and can be optionally prefixed by a '-'. So all of the following are valid -AutoClose -autoclose AUTOCLOSE autoclose OPTS is a combination of the following options: =over 5 =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 either the C method is called or the IO::Uncompress::UnLzma object is destroyed. This parameter defaults to 0. =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. This parameter defaults to 0. =item C<< Prime => $string >> This option will uncompress the contents of C<$string> before processing the input file/buffer. This option can be useful when the compressed data is embedded in another file/data structure and it is not possible to work out where the compressed data begins without having to read the first few bytes. If this is the case, the uncompression can be I with these bytes using this option. =item C<< Transparent => 0|1 >> 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/buffer as a single data stream. This option defaults to 1. =item C<< BlockSize => $num >> When reading the compressed input data, IO::Uncompress::UnLzma will read it in blocks of C<$num> bytes. This option defaults to 4096. =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 situation where there is useful data directly after the compressed data stream and you know beforehand the exact length of the compressed data stream. This option is mostly used when reading from a filehandle, in which case the file pointer will be left pointing to the first byte directly after the compressed data stream. This option defaults to off. =item C<< Append => 0|1 >> This option controls what the C method does with uncompressed data. If set to 1, all uncompressed data will be appended to the output parameter of the C method. If set to 0, the contents of the output parameter of the C method will be overwritten by the uncompressed data. Defaults to 0. =item C<< Strict => 0|1 >> This option controls whether the extra checks defined below are used when carrying out the decompression. When Strict is on, the extra tests are carried out, when Strict is off they are not. The default for this option is off. =back =head2 Examples TODO =head1 Methods =head2 read Usage is $status = $z->read($buffer) Reads a block of compressed data (the size of the compressed block is determined by the C option in the constructor), uncompresses it and writes any uncompressed data into C<$buffer>. If the C parameter is set in the constructor, the uncompressed data will be appended to the C<$buffer> parameter. Otherwise C<$buffer> will be overwritten. Returns the number of uncompressed bytes written to C<$buffer>, zero if eof or a negative number on error. =head2 read Usage is $status = $z->read($buffer, $length) $status = $z->read($buffer, $length, $offset) $status = read($z, $buffer, $length) $status = read($z, $buffer, $length, $offset) Attempt to read C<$length> bytes of uncompressed data into C<$buffer>. The main difference between this form of the C method and the previous one, is that this one will attempt to return I C<$length> bytes. The only circumstances that this function will not is if end-of-file or an IO error is encountered. Returns the number of uncompressed bytes written to C<$buffer>, zero if eof or a negative number on error. =head2 getline Usage is $line = $z->getline() $line = <$z> Reads a single line. This method fully supports the use of the variable C<$/> (or C<$INPUT_RECORD_SEPARATOR> or C<$RS> when C is in use) to determine what constitutes an end of line. Paragraph mode, record mode and file slurp mode are all supported. =head2 getc Usage is $char = $z->getc() Read a single character. =head2 ungetc Usage is $char = $z->ungetc($string) =head2 getHeaderInfo Usage is $hdr = $z->getHeaderInfo(); @hdrs = $z->getHeaderInfo(); This method returns either a hash reference (in scalar context) or a list or hash references (in array context) that contains information about each of the header fields in the compressed data stream(s). =head2 tell Usage is $z->tell() tell $z Returns the uncompressed file offset. =head2 eof Usage is $z->eof(); eof($z); Returns true if the end of the compressed input stream has been reached. =head2 seek $z->seek($position, $whence); seek($z, $position, $whence); Provides a sub-set of the C functionality, with the restriction that it is only legal to seek forward in the input file/buffer. It is a fatal error to attempt to seek backward. Note that the implementation of C in this module does not provide true random access to a compressed file/buffer. It works by uncompressing data from the current offset in the file/buffer until it reaches the uncompressed offset specified in the parameters to C. For very small files this may be acceptable behaviour. For large files it may cause an unacceptable delay. The C<$whence> parameter takes one the usual values, namely SEEK_SET, SEEK_CUR or SEEK_END. Returns 1 on success, 0 on failure. =head2 binmode Usage is $z->binmode binmode $z ; This is a noop provided for completeness. =head2 opened $z->opened() Returns true if the object currently refers to a opened file/buffer. =head2 autoflush my $prev = $z->autoflush() my $prev = $z->autoflush(EXPR) If the C<$z> object is associated with a file or a filehandle, this method returns the current autoflush setting for the underlying filehandle. If C is present, and is non-zero, it will enable flushing after every write/print operation. If C<$z> is associated with a buffer, this method has no effect and always returns C. B that the special variable C<$|> B be used to set or retrieve the autoflush setting. =head2 input_line_number $z->input_line_number() $z->input_line_number(EXPR) Returns the current uncompressed line number. If C is present it has the effect of setting the line number. Note that setting the line number does not change the current position within the file/buffer being read. The contents of C<$/> are used to determine what constitutes a line terminator. =head2 fileno $z->fileno() fileno($z) If the C<$z> object is associated with a file or a filehandle, C will return the underlying file descriptor. Once the C method is called C will return C. If the C<$z> object is associated with a buffer, this method will return C. =head2 close $z->close() ; close $z ; Closes the output file/buffer. For most versions of Perl this method will be automatically invoked if the IO::Uncompress::UnLzma object is destroyed (either explicitly or by the variable with the reference to the object going out of scope). The exceptions are Perl versions 5.005 through 5.00504 and 5.8.0. In these cases, the C method will be called automatically, but not until global destruction of all live objects when the program is terminating. Therefore, if you want your scripts to be able to run on all versions of Perl, you should call C explicitly and not rely on automatic closing. Returns true on success, otherwise 0. If the C option has been enabled when the IO::Uncompress::UnLzma object was created, and the object is associated with a file, the underlying file will also be closed. =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 and 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 the data, if any, that is present immediately after the compressed data stream once uncompression is complete. It only makes sense to call this method once the end of the compressed data stream has been encountered. This option can be used when there is useful information immediately following the compressed data stream, and you don't know the length of the compressed data stream. If the input is a buffer, C will return everything from the end of the compressed data stream to the end of the buffer. If the input is a filehandle, C will return the data that is left in the filehandle input buffer once the end of the compressed data stream has been reached. You can then use the filehandle to read the rest of the input file. Don't bother using C if the input is a filename. If you know the length of the compressed data stream before you start uncompressing, you can avoid having to use C by setting the C option in the constructor. =head1 Importing No symbolic constants are required by this IO::Uncompress::UnLzma at present. =over 5 =item :all Imports C and C<$UnLzmaError>. Same as doing this use IO::Uncompress::UnLzma qw(unlzma $UnLzmaError) ; =back =head1 EXAMPLES =head1 SUPPORT General feedback/questions/bug reports should be sent to L (preferred) or L. =head1 SEE ALSO L, L, L, L, L, L, L, L, L, L, L, L, L, L, L, L, L, L, L, L, L, L L L, L, L, L =head1 AUTHOR This module was written by Paul Marquess, C. =head1 MODIFICATION HISTORY See the Changes file. =head1 COPYRIGHT AND LICENSE Copyright (c) 2005-2019 Paul Marquess. All rights reserved. This program is free software; you can redistribute it and/or modify it under the same terms as Perl itself. libio-compress-lzma-perl-2.093/lib/IO/Uncompress/UnXz.pm000066400000000000000000000617531357305603400230560ustar00rootroot00000000000000package IO::Uncompress::UnXz ; use strict ; use warnings; use bytes; use IO::Compress::Base::Common 2.093 qw(:Status createSelfTiedObject); use IO::Uncompress::Base 2.093 ; use IO::Uncompress::Adapter::UnXz 2.093 ; require Exporter ; our ($VERSION, @ISA, @EXPORT_OK, %EXPORT_TAGS, $UnXzError); $VERSION = '2.093'; $UnXzError = ''; @ISA = qw( IO::Uncompress::Base Exporter ); @EXPORT_OK = qw( $UnXzError unxz ) ; #%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, \$UnXzError); $obj->_create(undef, 0, @_); } sub unxz { my $obj = createSelfTiedObject(undef, \$UnXzError); return $obj->_inf(@_); } our %PARAMS = ( 'memlimit' => [IO::Compress::Base::Common::Parse_unsigned, 128 * 1024 * 1024], 'flags' => [IO::Compress::Base::Common::Parse_boolean, 0], ); sub getExtraParams { return %PARAMS ; } 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 $memlimit = $got->getValue('memlimit'); my $flags = $got->getValue('flags'); my ($obj, $errstr, $errno) = IO::Uncompress::Adapter::UnXz::mkUncompObject( $memlimit, $flags); return $self->saveErrorString(undef, $errstr, $errno) if ! defined $obj; *$self->{Uncomp} = $obj; return 1; } use constant XZ_ID_SIZE => 6; use constant XZ_MAGIC => "\0xFD". '7zXZ'. "\0x00" ; sub ckMagic { my $self = shift; my $magic ; $self->smartReadExact(\$magic, XZ_ID_SIZE); *$self->{HeaderPending} = $magic ; return $self->HeaderError("Header size is " . XZ_ID_SIZE . " bytes") if length $magic != XZ_ID_SIZE; return $self->HeaderError("Bad Magic.") if ! isXzMagic($magic) ; *$self->{Type} = 'xz'; return $magic; } sub readHeader { my $self = shift; my $magic = shift ; $self->pushBack($magic); *$self->{HeaderPending} = ''; return { 'Type' => 'xz', 'FingerprintLength' => XZ_ID_SIZE, 'HeaderLength' => XZ_ID_SIZE, 'TrailerLength' => 0, 'Header' => '$magic' }; } sub chkTrailer { return STATUS_OK; } sub isXzMagic { my $buffer = shift ; return $buffer =~ /^\xFD\x37\x7A\x58\x5A\x00/; } 1 ; __END__ =head1 NAME IO::Uncompress::UnXz - Read xz files/buffers =head1 SYNOPSIS use IO::Uncompress::UnXz qw(unxz $UnXzError) ; my $status = unxz $input => $output [,OPTS] or die "unxz failed: $UnXzError\n"; my $z = new IO::Uncompress::UnXz $input [OPTS] or die "unxz failed: $UnXzError\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() $UnXzError ; # 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 B. =over 5 =item * DO NOT use in production code. =item * The documentation is incomplete in places. =item * Parts of the interface defined here are tentative. =item * Please report any problems you find. =back This module provides a Perl interface that allows the reading of lzma files/buffers. For writing xz files/buffers, see the companion module IO::Compress::Xz. =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 section. use IO::Uncompress::UnXz qw(unxz $UnXzError) ; unxz $input_filename_or_reference => $output_filename_or_reference [,OPTS] or die "unxz failed: $UnXzError\n"; The functional interface needs Perl5.005 or better. =head2 unxz $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. The output is the list of files that match the fileglob. When C<$output_filename_or_reference> is an fileglob string, C<$input_filename_or_reference> must also be a fileglob string. Anything else is an error. See L for more details. =back If the C<$output_filename_or_reference> parameter is any other type, C will be returned. =head2 Notes When C<$input_filename_or_reference> maps to multiple compressed files/buffers and C<$output_filename_or_reference> is a single file/buffer, after uncompression C<$output_filename_or_reference> will contain a concatenation of all the uncompressed data from each of the input files/buffers. =head2 Optional Parameters The optional parameters for the one-shot function C are (for the most part) identical to those used with the OO interface defined in the L section. The exceptions are listed below =over 5 =item C<< AutoClose => 0|1 >> This option applies to any input or output data streams to C that are filehandles. If C is specified, and the value is true, it will result in all input and/or output filehandles being closed once C has completed. This parameter defaults to 0. =item C<< BinModeOut => 0|1 >> This option is now a no-op. All files will be written in binmode. =item C<< Append => 0|1 >> The behaviour of this option is dependent on the type of output data stream. =over 5 =item * A Buffer If C is enabled, all uncompressed data will be append to the end of the output buffer. Otherwise the output buffer will be cleared before any uncompressed data is written to it. =item * A Filename If C is enabled, the file will be opened in append mode. Otherwise the contents of the file, if any, will be truncated before any uncompressed data is written to it. =item * A Filehandle If C is enabled, the filehandle will be positioned to the end of the file via a call to C before any uncompressed data is written to it. Otherwise the file pointer will not be moved. =back When C is specified, and set to true, it will I all uncompressed data to the output data stream. So when the output is a filehandle it will carry out a seek to the eof before writing any uncompressed data. If the output is a filename, it will be opened for appending. If the output is a buffer, all uncompressed data will be appended to the existing buffer. Conversely when C is not specified, or it is present and is set to false, it will operate as follows. When the output is a filename, it will truncate the contents of the file before writing any uncompressed data. If the output is a filehandle its position will not be changed. If the output is a buffer, it will be wiped before any uncompressed data is output. Defaults to 0. =item C<< MultiStream => 0|1 >> If the input file/buffer contains multiple compressed data streams, this option will uncompress the whole lot as a single data stream. Defaults to 0. =item C<< TrailingData => $scalar >> Returns the data, if any, that is present immediately after the compressed data stream once uncompression is complete. This option can be used when there is useful information immediately following the compressed data stream, and you don't know the length of the compressed data stream. If the input is a buffer, C will return everything from the end of the compressed data stream to the end of the buffer. If the input is a filehandle, C will return the data that is left in the filehandle input buffer once the end of the compressed data stream has been reached. You can then use the filehandle to read the rest of the input file. Don't bother using C if the input is a filename. If you know the length of the compressed data stream before you start uncompressing, you can avoid having to use C by setting the C option. =back =head2 Examples To read the contents of the file C and write the uncompressed data to the file C. use strict ; use warnings ; use IO::Uncompress::UnXz qw(unxz $UnXzError) ; my $input = "file1.txt.xz"; my $output = "file1.txt"; unxz $input => $output or die "unxz failed: $UnXzError\n"; To read from an existing Perl filehandle, C<$input>, and write the uncompressed data to a buffer, C<$buffer>. use strict ; use warnings ; use IO::Uncompress::UnXz qw(unxz $UnXzError) ; use IO::File ; my $input = new IO::File " \$buffer or die "unxz failed: $UnXzError\n"; To uncompress all files in the directory "/my/home" that match "*.txt.xz" and store the compressed data in the same directory use strict ; use warnings ; use IO::Uncompress::UnXz qw(unxz $UnXzError) ; unxz '' => '' or die "unxz failed: $UnXzError\n"; and if you want to compress each file one at a time, this will do the trick use strict ; use warnings ; use IO::Uncompress::UnXz qw(unxz $UnXzError) ; for my $input ( glob "/my/home/*.txt.xz" ) { my $output = $input; $output =~ s/.xz// ; unxz $input => $output or die "Error compressing '$input': $UnXzError\n"; } =head1 OO Interface =head2 Constructor The format of the constructor for IO::Uncompress::UnXz is shown below my $z = new IO::Uncompress::UnXz $input [OPTS] or die "IO::Uncompress::UnXz failed: $UnXzError\n"; Returns an C object on success and undef on failure. The variable C<$UnXzError> will contain an error message on failure. If you are running Perl 5.005 or better the object, C<$z>, returned from IO::Uncompress::UnXz can be used exactly like an L filehandle. This means that all normal input file operations can be carried out with C<$z>. For example, to read a line from a compressed file/buffer you can use either of these forms $line = $z->getline(); $line = <$z>; The mandatory parameter C<$input> is used to determine the source of the compressed data. This parameter can take one of three forms. =over 5 =item A filename If the C<$input> parameter is a scalar, it is assumed to be a filename. This file will be opened for reading and the compressed data will be read from it. =item A filehandle If the C<$input> parameter is a filehandle, the compressed data will be read from it. The string '-' can be used as an alias for standard input. =item A scalar reference If C<$input> is a scalar reference, the compressed data will be read from C<$$input>. =back =head2 Constructor Options The option names defined below are case insensitive and can be optionally prefixed by a '-'. So all of the following are valid -AutoClose -autoclose AUTOCLOSE autoclose OPTS is a combination of the following options: =over 5 =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 either the C method is called or the IO::Uncompress::UnXz object is destroyed. This parameter defaults to 0. =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. This parameter defaults to 0. =item C<< Prime => $string >> This option will uncompress the contents of C<$string> before processing the input file/buffer. This option can be useful when the compressed data is embedded in another file/data structure and it is not possible to work out where the compressed data begins without having to read the first few bytes. If this is the case, the uncompression can be I with these bytes using this option. =item C<< Transparent => 0|1 >> 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/buffer as a single data stream. This option defaults to 1. =item C<< BlockSize => $num >> When reading the compressed input data, IO::Uncompress::UnXz will read it in blocks of C<$num> bytes. This option defaults to 4096. =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 situation where there is useful data directly after the compressed data stream and you know beforehand the exact length of the compressed data stream. This option is mostly used when reading from a filehandle, in which case the file pointer will be left pointing to the first byte directly after the compressed data stream. This option defaults to off. =item C<< Append => 0|1 >> This option controls what the C method does with uncompressed data. If set to 1, all uncompressed data will be appended to the output parameter of the C method. If set to 0, the contents of the output parameter of the C method will be overwritten by the uncompressed data. Defaults to 0. =item C<< Strict => 0|1 >> This option controls whether the extra checks defined below are used when carrying out the decompression. When Strict is on, the extra tests are carried out, when Strict is off they are not. The default for this option is off. =item C<< MemLimit => $number >> Default is 128Meg. =item C<< Flags => $flags >> Default is 0. =back =head2 Examples TODO =head1 Methods =head2 read Usage is $status = $z->read($buffer) Reads a block of compressed data (the size of the compressed block is determined by the C option in the constructor), uncompresses it and writes any uncompressed data into C<$buffer>. If the C parameter is set in the constructor, the uncompressed data will be appended to the C<$buffer> parameter. Otherwise C<$buffer> will be overwritten. Returns the number of uncompressed bytes written to C<$buffer>, zero if eof or a negative number on error. =head2 read Usage is $status = $z->read($buffer, $length) $status = $z->read($buffer, $length, $offset) $status = read($z, $buffer, $length) $status = read($z, $buffer, $length, $offset) Attempt to read C<$length> bytes of uncompressed data into C<$buffer>. The main difference between this form of the C method and the previous one, is that this one will attempt to return I C<$length> bytes. The only circumstances that this function will not is if end-of-file or an IO error is encountered. Returns the number of uncompressed bytes written to C<$buffer>, zero if eof or a negative number on error. =head2 getline Usage is $line = $z->getline() $line = <$z> Reads a single line. This method fully supports the use of the variable C<$/> (or C<$INPUT_RECORD_SEPARATOR> or C<$RS> when C is in use) to determine what constitutes an end of line. Paragraph mode, record mode and file slurp mode are all supported. =head2 getc Usage is $char = $z->getc() Read a single character. =head2 ungetc Usage is $char = $z->ungetc($string) =head2 getHeaderInfo Usage is $hdr = $z->getHeaderInfo(); @hdrs = $z->getHeaderInfo(); This method returns either a hash reference (in scalar context) or a list or hash references (in array context) that contains information about each of the header fields in the compressed data stream(s). =head2 tell Usage is $z->tell() tell $z Returns the uncompressed file offset. =head2 eof Usage is $z->eof(); eof($z); Returns true if the end of the compressed input stream has been reached. =head2 seek $z->seek($position, $whence); seek($z, $position, $whence); Provides a sub-set of the C functionality, with the restriction that it is only legal to seek forward in the input file/buffer. It is a fatal error to attempt to seek backward. Note that the implementation of C in this module does not provide true random access to a compressed file/buffer. It works by uncompressing data from the current offset in the file/buffer until it reaches the uncompressed offset specified in the parameters to C. For very small files this may be acceptable behaviour. For large files it may cause an unacceptable delay. The C<$whence> parameter takes one the usual values, namely SEEK_SET, SEEK_CUR or SEEK_END. Returns 1 on success, 0 on failure. =head2 binmode Usage is $z->binmode binmode $z ; This is a noop provided for completeness. =head2 opened $z->opened() Returns true if the object currently refers to a opened file/buffer. =head2 autoflush my $prev = $z->autoflush() my $prev = $z->autoflush(EXPR) If the C<$z> object is associated with a file or a filehandle, this method returns the current autoflush setting for the underlying filehandle. If C is present, and is non-zero, it will enable flushing after every write/print operation. If C<$z> is associated with a buffer, this method has no effect and always returns C. B that the special variable C<$|> B be used to set or retrieve the autoflush setting. =head2 input_line_number $z->input_line_number() $z->input_line_number(EXPR) Returns the current uncompressed line number. If C is present it has the effect of setting the line number. Note that setting the line number does not change the current position within the file/buffer being read. The contents of C<$/> are used to determine what constitutes a line terminator. =head2 fileno $z->fileno() fileno($z) If the C<$z> object is associated with a file or a filehandle, C will return the underlying file descriptor. Once the C method is called C will return C. If the C<$z> object is associated with a buffer, this method will return C. =head2 close $z->close() ; close $z ; Closes the output file/buffer. For most versions of Perl this method will be automatically invoked if the IO::Uncompress::UnXz object is destroyed (either explicitly or by the variable with the reference to the object going out of scope). The exceptions are Perl versions 5.005 through 5.00504 and 5.8.0. In these cases, the C method will be called automatically, but not until global destruction of all live objects when the program is terminating. Therefore, if you want your scripts to be able to run on all versions of Perl, you should call C explicitly and not rely on automatic closing. Returns true on success, otherwise 0. If the C option has been enabled when the IO::Uncompress::UnXz object was created, and the object is associated with a file, the underlying file will also be closed. =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 and 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 the data, if any, that is present immediately after the compressed data stream once uncompression is complete. It only makes sense to call this method once the end of the compressed data stream has been encountered. This option can be used when there is useful information immediately following the compressed data stream, and you don't know the length of the compressed data stream. If the input is a buffer, C will return everything from the end of the compressed data stream to the end of the buffer. If the input is a filehandle, C will return the data that is left in the filehandle input buffer once the end of the compressed data stream has been reached. You can then use the filehandle to read the rest of the input file. Don't bother using C if the input is a filename. If you know the length of the compressed data stream before you start uncompressing, you can avoid having to use C by setting the C option in the constructor. =head1 Importing No symbolic constants are required by this IO::Uncompress::UnXz at present. =over 5 =item :all Imports C and C<$UnXzError>. Same as doing this use IO::Uncompress::UnXz qw(unxz $UnXzError) ; =back =head1 EXAMPLES =head1 SUPPORT General feedback/questions/bug reports should be sent to L (preferred) or L. =head1 SEE ALSO L, L, L, L, L, L, L, L, L, L, L, L, L, L, L, L, L, L, L, L, L, L L L, L, L, L =head1 AUTHOR This module was written by Paul Marquess, C. =head1 MODIFICATION HISTORY See the Changes file. =head1 COPYRIGHT AND LICENSE Copyright (c) 2005-2019 Paul Marquess. All rights reserved. This program is free software; you can redistribute it and/or modify it under the same terms as Perl itself. libio-compress-lzma-perl-2.093/private/000077500000000000000000000000001357305603400200375ustar00rootroot00000000000000libio-compress-lzma-perl-2.093/private/MakeUtil.pm000066400000000000000000000176441357305603400221240ustar00rootroot00000000000000package MakeUtil ; package main ; use strict ; use Config qw(%Config); use File::Copy; my $VERSION = '1.0'; BEGIN { eval { require File::Spec::Functions ; File::Spec::Functions->import() } ; if ($@) { *catfile = sub { return "$_[0]/$_[1]" } } } require VMS::Filespec if $^O eq 'VMS'; unless($ENV{PERL_CORE}) { $ENV{PERL_CORE} = 1 if grep { $_ eq 'PERL_CORE=1' } @ARGV; } $ENV{SKIP_FOR_CORE} = 1 if $ENV{PERL_CORE} || $ENV{MY_PERL_CORE} ; sub MY::libscan { my $self = shift; my $path = shift; return undef if $path =~ /(~|\.bak|_bak)$/ || $path =~ /\..*\.sw(o|p)$/ || $path =~ /\B\.svn\b/; return $path; } sub MY::postamble { return '' if $ENV{PERL_CORE} ; my @files = getPerlFiles('MANIFEST'); # Note: Once you remove all the layers of shell/makefile escaping # the regular expression below reads # # /^\s*local\s*\(\s*\$^W\s*\)/ # my $postamble = ' MyTrebleCheck: @echo Checking for $$^W in files: '. "@files" . ' perl -ne \' \ exit 1 if /^\s*local\s*\(\s*\$$\^W\s*\)/; \' \ ' . " @files || " . ' \ (echo found unexpected $$^W ; exit 1) @echo All is ok. '; return $postamble; } sub getPerlFiles { my @manifests = @_ ; my @files = (); for my $manifest (@manifests) { my $prefix = './'; $prefix = $1 if $manifest =~ m#^(.*/)#; open M, "<$manifest" or die "Cannot open '$manifest': $!\n"; while () { chomp ; next if /^\s*#/ || /^\s*$/ ; s/^\s+//; s/\s+$//; #next if m#t/Test/More\.pm$# or m#t/Test/Builder\.pm$#; /^(\S+)\s*(.*)$/; my ($file, $rest) = ($1, $2); if ($file =~ /\.(pm|pl|t)$/ and $file !~ /MakeUtil.pm/) { push @files, "$prefix$file"; } elsif ($rest =~ /perl/i) { push @files, "$prefix$file"; } } close M; } return @files; } sub UpDowngrade { return if defined $ENV{TipTop}; my @files = @_ ; # our and use bytes/utf8 is stable from 5.6.0 onward # warnings is stable from 5.6.1 onward # Note: this code assumes that each statement it modifies is not # split across multiple lines. my $warn_sub = ''; my $our_sub = '' ; my $upgrade ; my $downgrade ; my $do_downgrade ; my $caller = (caller(1))[3] || ''; if ($caller =~ /downgrade/) { $downgrade = 1; } elsif ($caller =~ /upgrade/) { $upgrade = 1; } else { $do_downgrade = 1 if $] < 5.006001 ; } # else # { # my $opt = shift @ARGV || '' ; # $upgrade = ($opt =~ /^-upgrade/i); # $downgrade = ($opt =~ /^-downgrade/i); # push @ARGV, $opt unless $downgrade || $upgrade; # } if ($downgrade || $do_downgrade) { # From: use|no warnings "blah" # To: local ($^W) = 1; # use|no warnings "blah" $warn_sub = sub { s/^(\s*)(no\s+warnings)/${1}local (\$^W) = 0; #$2/ ; s/^(\s*)(use\s+warnings)/${1}local (\$^W) = 1; #$2/ ; }; } #elsif ($] >= 5.006001 || $upgrade) { elsif ($upgrade) { # From: local ($^W) = 1; # use|no warnings "blah" # To: use|no warnings "blah" $warn_sub = sub { s/^(\s*)local\s*\(\$\^W\)\s*=\s*\d+\s*;\s*#\s*((no|use)\s+warnings.*)/$1$2/ ; }; } if ($downgrade || $do_downgrade) { $our_sub = sub { if ( /^(\s*)our\s+\(\s*([^)]+\s*)\)/ ) { my $indent = $1; my $vars = join ' ', split /\s*,\s*/, $2; $_ = "${indent}use vars qw($vars);\n"; } elsif ( /^(\s*)((use|no)\s+(bytes|utf8)\s*;.*)$/) { $_ = "$1# $2\n"; } }; } #elsif ($] >= 5.006000 || $upgrade) { elsif ($upgrade) { $our_sub = sub { if ( /^(\s*)use\s+vars\s+qw\((.*?)\)/ ) { my $indent = $1; my $vars = join ', ', split ' ', $2; $_ = "${indent}our ($vars);\n"; } elsif ( /^(\s*)#\s*((use|no)\s+(bytes|utf8)\s*;.*)$/) { $_ = "$1$2\n"; } }; } if (! $our_sub && ! $warn_sub) { warn "Up/Downgrade not needed.\n"; if ($upgrade || $downgrade) { exit 0 } else { return } } foreach (@files) { #if (-l $_ ) { doUpDown($our_sub, $warn_sub, $_) } #else #{ doUpDownViaCopy($our_sub, $warn_sub, $_) } } warn "Up/Downgrade complete.\n" ; exit 0 if $upgrade || $downgrade; } sub doUpDown { my $our_sub = shift; my $warn_sub = shift; return if -d $_[0]; local ($^I) = ($^O eq 'VMS') ? "_bak" : ".bak"; local (@ARGV) = shift; while (<>) { print, last if /^__(END|DATA)__/ ; &{ $our_sub }() if $our_sub ; &{ $warn_sub }() if $warn_sub ; print ; } return if eof ; while (<>) { print } } sub doUpDownViaCopy { my $our_sub = shift; my $warn_sub = shift; my $file = shift ; use File::Copy ; return if -d $file ; my $backup = $file . ($^O eq 'VMS') ? "_bak" : ".bak"; copy($file, $backup) or die "Cannot copy $file to $backup: $!"; my @keep = (); { open F, "<$file" or die "Cannot open $file: $!\n" ; while () { if (/^__(END|DATA)__/) { push @keep, $_; last ; } &{ $our_sub }() if $our_sub ; &{ $warn_sub }() if $warn_sub ; push @keep, $_; } if (! eof F) { while () { push @keep, $_ } } close F; } { open F, ">$file" or die "Cannot open $file: $!\n"; print F @keep ; close F; } } sub FindBrokenDependencies { my $version = shift ; my %thisModule = map { $_ => 1} @_; my @modules = qw( IO::Compress::Base IO::Compress::Base::Common IO::Uncompress::Base Compress::Raw::Zlib Compress::Raw::Bzip2 IO::Compress::RawDeflate IO::Uncompress::RawInflate IO::Compress::Deflate IO::Uncompress::Inflate IO::Compress::Gzip IO::Compress::Gzip::Constants IO::Uncompress::Gunzip IO::Compress::Zip IO::Uncompress::Unzip IO::Compress::Bzip2 IO::Uncompress::Bunzip2 IO::Compress::Lzf IO::Uncompress::UnLzf IO::Compress::Lzop IO::Uncompress::UnLzop Compress::Zlib ); my @broken = (); foreach my $module ( grep { ! $thisModule{$_} } @modules) { my $hasVersion = getInstalledVersion($module); # No need to upgrade if the module isn't installed at all next if ! defined $hasVersion; # If already have C::Z version 1, then an upgrade to any of the # IO::Compress modules will not break it. next if $module eq 'Compress::Zlib' && $hasVersion < 2; if ($hasVersion < $version) { push @broken, $module } } return @broken; } sub getInstalledVersion { my $module = shift; my $version; eval " require $module; "; if ($@ eq '') { no strict 'refs'; $version = ${ $module . "::VERSION" }; $version = 0 } return $version; } package MakeUtil ; 1; libio-compress-lzma-perl-2.093/t/000077500000000000000000000000001357305603400166305ustar00rootroot00000000000000libio-compress-lzma-perl-2.093/t/000prereq.t000066400000000000000000000045171357305603400205420ustar00rootroot00000000000000BEGIN { if ($ENV{PERL_CORE}) { chdir 't' if -d 't'; @INC = ("../lib", "lib/compress"); } } use lib qw(t t/compress); use strict ; use warnings ; use Test::More ; BEGIN { # use Test::NoWarnings, if available my $extra = 0 ; $extra = 1 if eval { require Test::NoWarnings ; import Test::NoWarnings; 1 }; my $VERSION = '2.093'; my @NAMES = qw( Compress::Raw::Lzma IO::Compress::Base IO::Uncompress::Base ); my @OPT = qw( ); plan tests => @NAMES + @OPT + $extra ; foreach my $name (@NAMES) { use_ok($name, $VERSION); } foreach my $name (@OPT) { eval " require $name " ; if ($@) { ok 1, "$name not available" } else { my $ver = eval("\$${name}::VERSION"); is $ver, $VERSION, "$name version should be $VERSION" or diag "$name version is $ver, need $VERSION" ; } } } { # Print our versions of all modules used my @results = ( [ 'perl', $] ] ); my @modules = qw( IO::Compress::Base IO::Compress::Zip IO::Compress::Lzma IO::Uncompress::Base IO::Uncompress::Unzip IO::Uncompress::UnLzma Compress::Raw::Zlib Compress::Raw::Bzip2 Compress::Raw::Lzma ); my %have = (); for my $module (@modules) { my $ver = packageVer($module) ; my $v = defined $ver ? $ver : "Not Installed" ; push @results, [$module, $v] ; $have{$module} ++ if $ver ; } if ($have{"Compress::Raw::Lzma"}) { my $ver = eval { Compress::Raw::Lzma::lzma_version_string(); } || "unknown"; push @results, ["lzma", $ver] ; } use List::Util qw(max); my $width = max map { length $_->[0] } @results; diag "\n\n" ; for my $m (@results) { my ($name, $ver) = @$m; my $b = " " x (1 + $width - length $name); diag $name . $b . $ver . "\n" ; } diag "\n\n" ; } sub packageVer { no strict 'refs'; my $package = shift; eval "use $package;"; return ${ "${package}::VERSION" }; } libio-compress-lzma-perl-2.093/t/001lzip.t000066400000000000000000000150461357305603400202220ustar00rootroot00000000000000BEGIN { if ($ENV{PERL_CORE}) { chdir 't' if -d 't'; @INC = ("../lib", "lib/compress"); } } use lib qw(t t/compress); use strict; use warnings; use bytes; use Test::More ; use CompTestUtils; BEGIN { # use Test::NoWarnings, if available my $extra = 0 ; $extra = 1 if eval { require Test::NoWarnings ; import Test::NoWarnings; 1 }; plan tests => 13 + $extra ; }; use IO::Compress::Lzip qw(:all); use IO::Uncompress::UnLzip qw($UnLzipError) ; my $CompressClass = 'IO::Compress::Lzip'; my $UncompressClass = getInverse($CompressClass); my $Error = getErrorRef($CompressClass); my $UnError = getErrorRef($UncompressClass); sub myLzipReadFile { my $filename = shift ; my $init = shift ; my $fil = new $UncompressClass $filename, -Strict => 1, -Append => 1 ; my $data = ''; $data = $init if defined $init ; 1 while $fil->read($data) > 0; my $status = $fil->error() . "" ; ok ! $fil->error(), " no error" or diag "$$UnError " ; $fil->close ; return ($status, $data) ; } sub memError { my $err = shift ; #my $re = "(" . LZMA_MEM_ERROR . "|" . LZMA_MEMLIMIT_ERROR . ")"; #my $re .= LZMA_MEM_ERROR; my $re = "(Memory usage limit was reached|Cannot allocate memory)"; return $err =~/$re/ ; } if(0) { title "Testing $CompressClass Errors"; my $buffer ; for my $value (undef, -1, 'fred') { my $stringValue = defined $value ? $value : 'undef'; title "BlockSize100K => $stringValue"; my $err = "Parameter 'BlockSize100K' must be an unsigned int, got '$stringValue'"; my $bz ; eval { $bz = new IO::Compress::Lzip(\$buffer, BlockSize100K => $value) }; like $@, mkErr("IO::Compress::Lzip: $err"), " value $stringValue is bad"; is $LzipError, "IO::Compress::Lzip: $err", " value $stringValue is bad"; ok ! $bz, " no bz object"; } for my $value (0, 10, 99999) { my $stringValue = defined $value ? $value : 'undef'; title "BlockSize100K => $stringValue"; my $err = "Parameter 'BlockSize100K' not between 1 and 9, got $stringValue"; my $bz ; eval { $bz = new IO::Compress::Lzip(\$buffer, BlockSize100K => $value) }; like $@, mkErr("IO::Compress::Lzip: $err"), " value $stringValue is bad"; is $LzipError, "IO::Compress::Lzip: $err", " value $stringValue is bad"; ok ! $bz, " no bz object"; } for my $value (undef, -1, 'fred') { my $stringValue = defined $value ? $value : 'undef'; title "WorkFactor => $stringValue"; my $err = "Parameter 'WorkFactor' must be an unsigned int, got '$stringValue'"; my $bz ; eval { $bz = new IO::Compress::Lzip(\$buffer, WorkFactor => $value) }; like $@, mkErr("IO::Compress::Lzip: $err"), " value $stringValue is bad"; is $LzipError, "IO::Compress::Lzip: $err", " value $stringValue is bad"; ok ! $bz, " no bz object"; } for my $value (251, 99999) { my $stringValue = defined $value ? $value : 'undef'; title "WorkFactor => $stringValue"; my $err = "Parameter 'WorkFactor' not between 0 and 250, got $stringValue"; my $bz ; eval { $bz = new IO::Compress::Lzip(\$buffer, WorkFactor => $value) }; like $@, mkErr("IO::Compress::Lzip: $err"), " value $stringValue is bad"; is $LzipError, "IO::Compress::Lzip: $err", " value $stringValue is bad"; ok ! $bz, " no bz object"; } } if(0) { title "Testing $UncompressClass Errors"; my $buffer ; for my $value (-1, 'fred') { my $stringValue = defined $value ? $value : 'undef'; title "Small => $stringValue"; my $err = "Parameter 'Small' must be an int, got '$stringValue'"; my $bz ; eval { $bz = new IO::Uncompress::UnLzip(\$buffer, Small => $value) }; like $@, mkErr("IO::Uncompress::UnLzip: $err"), " value $stringValue is bad"; is $UnLzipError, "IO::Uncompress::UnLzip: $err", " value $stringValue is bad"; ok ! $bz, " no bz object"; } } { title "Testing $CompressClass and $UncompressClass"; my $hello = < $check, # Extreme => $extreme, # Preset => $preset ) ; skip "Not enough memory - Check $check, Extreme $extreme, Preset $preset", 5 if memError($IO::Compress::Lzip::LzipError); ok $lzip, " lzip object ok"; isa_ok $lzip, "IO::Compress::Lzip"; my $status = $lzip->write($hello); ok $status, " wrote ok" ; ok $lzip->close(), " closed ok"; my ($s, $data) = myLzipReadFile($name); skip "Not enough memory to read with $UncompressClass", 1 if memError($s); is $data, $hello, " got expected content"; } } } } { title "$UncompressClass "; my $lex = new LexFile my $name ; my $lzip ; $lzip = new IO::Compress::Lzip($name); ok $lzip, " lzip object ok"; isa_ok $lzip, "IO::Compress::Lzip"; $lzip->write($hello); $lzip->close(); my $fil = new $UncompressClass $name, Append => 1, ; isa_ok $fil, "IO::Uncompress::UnLzip"; my $data = ''; 1 while $fil->read($data) > 0; $fil->close ; is $data, $hello, " got expected"; } } 1; libio-compress-lzma-perl-2.093/t/001lzma.t000066400000000000000000000137561357305603400202150ustar00rootroot00000000000000BEGIN { if ($ENV{PERL_CORE}) { chdir 't' if -d 't'; @INC = ("../lib", "lib/compress"); } } use lib qw(t t/compress); use strict; use warnings; use bytes; use Test::More ; use CompTestUtils; BEGIN { # use Test::NoWarnings, if available my $extra = 0 ; $extra = 1 if eval { require Test::NoWarnings ; import Test::NoWarnings; 1 }; plan tests => 4 + $extra ; }; use IO::Compress::Lzma qw($LzmaError) ; use IO::Uncompress::UnLzma qw($UnLzmaError) ; my $CompressClass = 'IO::Compress::Lzma'; my $UncompressClass = getInverse($CompressClass); my $Error = getErrorRef($CompressClass); my $UnError = getErrorRef($UncompressClass); sub myLzmaReadFile { my $filename = shift ; my $init = shift ; my $fil = new $UncompressClass $filename, -Strict => 1, -Append => 1 ; my $data = ''; $data = $init if defined $init ; 1 while $fil->read($data) > 0; $fil->close ; return $data ; } if(0) { title "Testing $CompressClass Errors"; my $buffer ; for my $value (undef, -1, 'fred') { my $stringValue = defined $value ? $value : 'undef'; title "BlockSize100K => $stringValue"; my $err = "Parameter 'BlockSize100K' must be an unsigned int, got '$stringValue'"; my $bz ; eval { $bz = new IO::Compress::Lzma(\$buffer, BlockSize100K => $value) }; like $@, mkErr("IO::Compress::Lzma: $err"), " value $stringValue is bad"; is $LzmaError, "IO::Compress::Lzma: $err", " value $stringValue is bad"; ok ! $bz, " no bz object"; } for my $value (0, 10, 99999) { my $stringValue = defined $value ? $value : 'undef'; title "BlockSize100K => $stringValue"; my $err = "Parameter 'BlockSize100K' not between 1 and 9, got $stringValue"; my $bz ; eval { $bz = new IO::Compress::Lzma(\$buffer, BlockSize100K => $value) }; like $@, mkErr("IO::Compress::Lzma: $err"), " value $stringValue is bad"; is $LzmaError, "IO::Compress::Lzma: $err", " value $stringValue is bad"; ok ! $bz, " no bz object"; } for my $value (undef, -1, 'fred') { my $stringValue = defined $value ? $value : 'undef'; title "WorkFactor => $stringValue"; my $err = "Parameter 'WorkFactor' must be an unsigned int, got '$stringValue'"; my $bz ; eval { $bz = new IO::Compress::Lzma(\$buffer, WorkFactor => $value) }; like $@, mkErr("IO::Compress::Lzma: $err"), " value $stringValue is bad"; is $LzmaError, "IO::Compress::Lzma: $err", " value $stringValue is bad"; ok ! $bz, " no bz object"; } for my $value (251, 99999) { my $stringValue = defined $value ? $value : 'undef'; title "WorkFactor => $stringValue"; my $err = "Parameter 'WorkFactor' not between 0 and 250, got $stringValue"; my $bz ; eval { $bz = new IO::Compress::Lzma(\$buffer, WorkFactor => $value) }; like $@, mkErr("IO::Compress::Lzma: $err"), " value $stringValue is bad"; is $LzmaError, "IO::Compress::Lzma: $err", " value $stringValue is bad"; ok ! $bz, " no bz object"; } } if(0) { title "Testing $UncompressClass Errors"; my $buffer ; for my $value (-1, 'fred') { my $stringValue = defined $value ? $value : 'undef'; title "Small => $stringValue"; my $err = "Parameter 'Small' must be an int, got '$stringValue'"; my $bz ; eval { $bz = new IO::Uncompress::UnLzma(\$buffer, Small => $value) }; like $@, mkErr("IO::Uncompress::UnLzma: $err"), " value $stringValue is bad"; is $UnLzmaError, "IO::Uncompress::UnLzma: $err", " value $stringValue is bad"; ok ! $bz, " no bz object"; } } { title "Testing $CompressClass and $UncompressClass"; my $hello = <write($hello); $bz->close($hello); #is myLzmaReadFile($name), $hello, " got expected content"; ok myLzmaReadFile($name) eq $hello, " got expected content"; } # TODO - add filter tests # for my $value ( 1 .. 9 ) # { # title "$CompressClass - BlockSize100K => $value"; # my $lex = new LexFile my $name ; # my $bz ; # $bz = new IO::Compress::Lzma($name, BlockSize100K => $value) # or diag $IO::Compress::Lzma::LzmaError ; # ok $bz, " bz object ok"; # $bz->write($hello); # $bz->close($hello); # # is myLzmaReadFile($name), $hello, " got expected content"; # } # # for my $value ( 0 .. 250 ) # { # title "$CompressClass - WorkFactor => $value"; # my $lex = new LexFile my $name ; # my $bz ; # $bz = new IO::Compress::Lzma($name, WorkFactor => $value); # ok $bz, " bz object ok"; # $bz->write($hello); # $bz->close($hello); # # is myLzmaReadFile($name), $hello, " got expected content"; # } # # for my $value ( 0 .. 1 ) # { # title "$UncompressClass - Small => $value"; # my $lex = new LexFile my $name ; # my $bz ; # $bz = new IO::Compress::Lzma($name); # ok $bz, " bz object ok"; # $bz->write($hello); # $bz->close($hello); # # my $fil = new $UncompressClass $name, # Append => 1, # Small => $value ; # # my $data = ''; # 1 while $fil->read($data) > 0; # # $fil->close ; # # is $data, $hello, " got expected"; # } } 1; libio-compress-lzma-perl-2.093/t/001xz.t000066400000000000000000000147611357305603400177100ustar00rootroot00000000000000BEGIN { if ($ENV{PERL_CORE}) { chdir 't' if -d 't'; @INC = ("../lib", "lib/compress"); } } use lib qw(t t/compress); use strict; use warnings; use bytes; use Test::More ; use CompTestUtils; BEGIN { # use Test::NoWarnings, if available my $extra = 0 ; $extra = 1 if eval { require Test::NoWarnings ; import Test::NoWarnings; 1 }; plan tests => 486 + $extra ; }; #use IO::Compress::Xz qw($XzError) ; use IO::Compress::Xz qw(:all); use IO::Uncompress::UnXz qw($UnXzError) ; my $CompressClass = 'IO::Compress::Xz'; my $UncompressClass = getInverse($CompressClass); my $Error = getErrorRef($CompressClass); my $UnError = getErrorRef($UncompressClass); sub myXzReadFile { my $filename = shift ; my $init = shift ; my $fil = new $UncompressClass $filename, -Strict => 1, -Append => 1 ; my $data = ''; $data = $init if defined $init ; 1 while $fil->read($data) > 0; my $status = $fil->error() . "" ; #ok ! $fil->error(), " no error" # or diag "$$UnError " ; $fil->close ; return ($status, $data) ; } sub memError { my $err = shift ; #my $re = "(" . LZMA_MEM_ERROR . "|" . LZMA_MEMLIMIT_ERROR . ")"; #my $re .= LZMA_MEM_ERROR; my $re = "(Memory usage limit was reached|Cannot allocate memory)"; return $err =~/$re/ ; } if(0) { title "Testing $CompressClass Errors"; my $buffer ; for my $value (undef, -1, 'fred') { my $stringValue = defined $value ? $value : 'undef'; title "BlockSize100K => $stringValue"; my $err = "Parameter 'BlockSize100K' must be an unsigned int, got '$stringValue'"; my $bz ; eval { $bz = new IO::Compress::Xz(\$buffer, BlockSize100K => $value) }; like $@, mkErr("IO::Compress::Xz: $err"), " value $stringValue is bad"; is $XzError, "IO::Compress::Xz: $err", " value $stringValue is bad"; ok ! $bz, " no bz object"; } for my $value (0, 10, 99999) { my $stringValue = defined $value ? $value : 'undef'; title "BlockSize100K => $stringValue"; my $err = "Parameter 'BlockSize100K' not between 1 and 9, got $stringValue"; my $bz ; eval { $bz = new IO::Compress::Xz(\$buffer, BlockSize100K => $value) }; like $@, mkErr("IO::Compress::Xz: $err"), " value $stringValue is bad"; is $XzError, "IO::Compress::Xz: $err", " value $stringValue is bad"; ok ! $bz, " no bz object"; } for my $value (undef, -1, 'fred') { my $stringValue = defined $value ? $value : 'undef'; title "WorkFactor => $stringValue"; my $err = "Parameter 'WorkFactor' must be an unsigned int, got '$stringValue'"; my $bz ; eval { $bz = new IO::Compress::Xz(\$buffer, WorkFactor => $value) }; like $@, mkErr("IO::Compress::Xz: $err"), " value $stringValue is bad"; is $XzError, "IO::Compress::Xz: $err", " value $stringValue is bad"; ok ! $bz, " no bz object"; } for my $value (251, 99999) { my $stringValue = defined $value ? $value : 'undef'; title "WorkFactor => $stringValue"; my $err = "Parameter 'WorkFactor' not between 0 and 250, got $stringValue"; my $bz ; eval { $bz = new IO::Compress::Xz(\$buffer, WorkFactor => $value) }; like $@, mkErr("IO::Compress::Xz: $err"), " value $stringValue is bad"; is $XzError, "IO::Compress::Xz: $err", " value $stringValue is bad"; ok ! $bz, " no bz object"; } } if(0) { title "Testing $UncompressClass Errors"; my $buffer ; for my $value (-1, 'fred') { my $stringValue = defined $value ? $value : 'undef'; title "Small => $stringValue"; my $err = "Parameter 'Small' must be an int, got '$stringValue'"; my $bz ; eval { $bz = new IO::Uncompress::UnXz(\$buffer, Small => $value) }; like $@, mkErr("IO::Uncompress::UnXz: $err"), " value $stringValue is bad"; is $UnXzError, "IO::Uncompress::UnXz: $err", " value $stringValue is bad"; ok ! $bz, " no bz object"; } } { title "Testing $CompressClass and $UncompressClass"; my $hello = < $check, Extreme => $extreme, Preset => $preset ) ; skip "Not enough memory - Check $check, Extreme $extreme, Preset $preset", 5 if memError($IO::Compress::Xz::XzError); ok $xz, " xz object ok"; isa_ok $xz, "IO::Compress::Xz"; my $status = $xz->write($hello); ok $status, " wrote ok" ; ok $xz->close(), " closed ok"; my ($s, $data) = myXzReadFile($name); skip "Not enough memory to read with $UncompressClass", 1 if memError($s); is $data, $hello, " got expected content"; } } } } { title "$UncompressClass "; my $lex = new LexFile my $name ; my $xz ; $xz = new IO::Compress::Xz($name); ok $xz, " xz object ok"; isa_ok $xz, "IO::Compress::Xz"; $xz->write($hello); $xz->close(); my $fil = new $UncompressClass $name, Append => 1, ; isa_ok $fil, "IO::Uncompress::UnXz"; my $data = ''; 1 while $fil->read($data) > 0; $fil->close ; is $data, $hello, " got expected"; } } 1; libio-compress-lzma-perl-2.093/t/010examples-lzma.t000066400000000000000000000046041357305603400220210ustar00rootroot00000000000000BEGIN { if ($ENV{PERL_CORE}) { chdir 't' if -d 't'; @INC = ("../lib", "lib/compress"); } } use lib qw(t t/compress); use strict; use warnings; use bytes; use Test::More ; use CompTestUtils; use IO::Compress::Lzma ':all' ; BEGIN { plan(skip_all => "Examples needs Perl 5.005 or better - you have Perl $]" ) if $] < 5.005 ; # use Test::NoWarnings, if available my $extra = 0 ; $extra = 1 if eval { require Test::NoWarnings ; import Test::NoWarnings; 1 }; plan tests => 19 + $extra ; } my $Inc = join " ", map qq["-I$_"] => @INC; $Inc = '"-MExtUtils::testlib"' if ! $ENV{PERL_CORE} && eval " require ExtUtils::testlib; " ; my $Perl = ($ENV{'FULLPERL'} or $^X or 'perl') ; $Perl = qq["$Perl"] if $^O eq 'MSWin32' ; $Perl = "$Perl $Inc -w" ; #$Perl .= " -Mblib " ; my $examples = "./examples"; my $hello1 = < $file1 ; lzma \$hello2 => $file2 ; sub check { my $command = shift ; my $expected = shift ; my $lex = new LexFile my $stderr ; my $cmd = "$command 2>$stderr"; my $stdout = `$cmd` ; my $aok = 1 ; $aok &= is $?, 0, " exit status is 0" ; $aok &= is readFile($stderr), '', " no stderr" ; $aok &= is $stdout, $expected, " expected content is ok" if defined $expected ; if (! $aok) { diag "Command line: $cmd"; my ($file, $line) = (caller)[1,2]; diag "Test called from $file, line $line"; } 1 while unlink $stderr; } # lzcat # ##### title "lzcat - command line" ; check "$Perl ${examples}/lzcat $file1 $file2", $hello1 . $hello2; title "xzcat - stdin" ; check "$Perl ${examples}/lzcat <$file1 ", $hello1; # lzgrep # ###### title "xzgrep"; check "$Perl ${examples}/lzgrep the $file1 $file2", join('', grep(/the/, @hello1, @hello2)); for ($file1, $file2, $stderr) { 1 while unlink $_ } ; # lzstream # ######## { title "lzstream" ; writeFile($file1, $hello1) ; check "$Perl ${examples}/lzstream <$file1 >$file2"; title "lzcat" ; check "$Perl ${examples}/lzcat $file2", $hello1 ; } libio-compress-lzma-perl-2.093/t/010examples-xz.t000066400000000000000000000046321357305603400215200ustar00rootroot00000000000000BEGIN { if ($ENV{PERL_CORE}) { chdir 't' if -d 't'; @INC = ("../lib", "lib/compress"); } } use lib qw(t t/compress); use strict; use warnings; use bytes; use Test::More ; use CompTestUtils; use IO::Compress::Xz ':all' ; use IO::Compress::Lzma ':all' ; BEGIN { plan(skip_all => "Examples needs Perl 5.005 or better - you have Perl $]" ) if $] < 5.005 ; # use Test::NoWarnings, if available my $extra = 0 ; $extra = 1 if eval { require Test::NoWarnings ; import Test::NoWarnings; 1 }; plan tests => 19 + $extra ; } my $Inc = join " ", map qq["-I$_"] => @INC; $Inc = '"-MExtUtils::testlib"' if ! $ENV{PERL_CORE} && eval " require ExtUtils::testlib; " ; my $Perl = ($ENV{'FULLPERL'} or $^X or 'perl') ; $Perl = qq["$Perl"] if $^O eq 'MSWin32' ; $Perl = "$Perl $Inc -w" ; #$Perl .= " -Mblib " ; my $examples = "./examples"; my $hello1 = < $file1 ; xz \$hello2 => $file2 ; sub check { my $command = shift ; my $expected = shift ; my $lex = new LexFile my $stderr ; my $cmd = "$command 2>$stderr"; my $stdout = `$cmd` ; my $aok = 1 ; $aok &= is $?, 0, " exit status is 0" ; $aok &= is readFile($stderr), '', " no stderr" ; $aok &= is $stdout, $expected, " expected content is ok" if defined $expected ; if (! $aok) { diag "Command line: $cmd"; my ($file, $line) = (caller)[1,2]; diag "Test called from $file, line $line"; } 1 while unlink $stderr; } # xzcat # ##### title "xzcat - command line" ; check "$Perl ${examples}/xzcat $file1 $file2", $hello1 . $hello2; title "xzcat - stdin" ; check "$Perl ${examples}/xzcat <$file1 ", $hello1; # xzgrep # ###### title "xzgrep"; check "$Perl ${examples}/xzgrep the $file1 $file2", join('', grep(/the/, @hello1, @hello2)); for ($file1, $file2, $stderr) { 1 while unlink $_ } ; # xzstream # ######## { title "xzstream" ; writeFile($file1, $hello1) ; check "$Perl ${examples}/xzstream <$file1 >$file2"; title "xzcat" ; check "$Perl ${examples}/xzcat $file2", $hello1 ; } libio-compress-lzma-perl-2.093/t/050interop-lzip.t000066400000000000000000000060101357305603400216730ustar00rootroot00000000000000BEGIN { if ($ENV{PERL_CORE}) { chdir 't' if -d 't'; @INC = ("../lib", "lib/compress"); } } use lib qw(t t/compress); use strict; use warnings; use bytes; use File::Spec ; use Test::More ; use CompTestUtils; my $LZIP ; sub ExternalLzipWorks { my $lex = new LexFile my $outfile; my $content = qq { Lorem ipsum dolor sit amet, consectetuer adipiscing elit. Ut tempus odio id dolor. Camelus perlus. Larrius in lumen numen. Dolor en quiquum filia est. Quintus cenum parat. }; writeWithLzip($outfile, $content) or return 0; my $got ; readWithLzip($outfile, $got) or return 0; if ($content ne $got) { diag "Uncompressed content is wrong"; return 0 ; } return 1 ; } sub readWithLzip { my $file = shift ; my $lex = new LexFile my $outfile; my $comp = "$LZIP -dc" ; if (system("$comp $file >$outfile") == 0 ) { $_[0] = readFile($outfile); return 1 ; } diag "'$comp' failed: $?"; return 0 ; } sub writeWithLzip { my $file = shift ; my $content = shift ; my $options = shift || ''; my $lex = new LexFile my $infile; writeFile($infile, $content); unlink $file ; my $comp = "$LZIP -c $options $infile >$file" ; return 1 if system($comp) == 0 ; diag "'$comp' failed: $?"; return 0 ; } BEGIN { # Check external lzip is available my $name = $^O =~ /mswin/i ? 'lzip.exe' : 'lzip'; my $split = $^O =~ /mswin/i ? ";" : ":"; for my $dir (reverse split $split, $ENV{PATH}) { $LZIP = File::Spec->catfile($dir,$name) if -x File::Spec->catfile($dir,$name); } # Handle spaces in path to lzip $LZIP = "\"$LZIP\"" if defined $LZIP && $LZIP =~ /\s/; plan(skip_all => "Cannot find $name") if ! $LZIP ; plan(skip_all => "$name doesn't work as expected") if ! ExternalLzipWorks(); # use Test::NoWarnings, if available my $extra = 0 ; $extra = 1 if eval { require Test::NoWarnings ; import Test::NoWarnings; 1 }; plan tests => 12 + $extra ; use_ok('IO::Compress::Lzip', ':all') ; use_ok('IO::Uncompress::UnLzip', ':all') ; } { title "Test interop with $LZIP" ; my ($file, $file1); my $lex = new LexFile $file, $file1; my $content = "hello world\n" ; my $got; ok writeWithLzip($file, $content), "writeWithLzip ok"; unlzip $file => \$got ; is $got, $content; lzip \$content => $file1; $got = ''; ok readWithLzip($file1, $got), "readWithLzip returns 0"; is $got, $content, "got content"; } { title "Test interop with $LZIP - empty file" ; my ($file, $file1); my $lex = new LexFile $file, $file1; my $content = "" ; my $got; ok writeWithLzip($file, $content), "writeWithLzip ok"; unlzip $file => \$got ; is $got, $content; lzip \$content => $file1; $got = ''; ok readWithLzip($file1, $got), "readWithLzip returns 0"; is $got, $content, "got content"; } libio-compress-lzma-perl-2.093/t/050interop-lzma.t000066400000000000000000000065331357305603400216720ustar00rootroot00000000000000BEGIN { if ($ENV{PERL_CORE}) { chdir 't' if -d 't'; @INC = ("../lib", "lib/compress"); } } use lib qw(t t/compress); use strict; use warnings; use bytes; use File::Spec ; use Test::More ; use CompTestUtils; my $LZMA ; my $UNLZMA ; sub ExternalLzmaWorks { my $lex = new LexFile my $outfile; my $content = qq { Lorem ipsum dolor sit amet, consectetuer adipiscing elit. Ut tempus odio id dolor. Camelus perlus. Larrius in lumen numen. Dolor en quiquum filia est. Quintus cenum parat. }; writeWithLzma($outfile, $content) or return 0; my $got ; readWithLzma($outfile, $got) or return 0; if ($content ne $got) { diag "Uncompressed content is wrong"; return 0 ; } return 1 ; } sub readWithLzma { my $file = shift ; my $lex = new LexFile my $outfile; my $comp = "$UNLZMA -c " ; if (system("$comp <$file >$outfile") == 0 ) { $_[0] = readFile($outfile); return 1 ; } diag "'$comp' failed: $?"; return 0 ; } sub writeWithLzma { my $file = shift ; my $content = shift ; my $options = shift || ''; my $lex = new LexFile my $infile; writeFile($infile, $content); unlink $file ; my $comp = "$LZMA -c $options $infile >$file" ; return 1 if system($comp) == 0 ; diag "'$comp' failed: $?"; return 0 ; } BEGIN { # Check external lzma is available my $nameLZ = $^O =~ /mswin/i ? 'lzma.exe' : 'lzma'; my $nameUNLZ = $^O =~ /mswin/i ? 'unlzma.exe' : 'unlzma'; my $split = $^O =~ /mswin/i ? ";" : ":"; for my $dir (reverse split $split, $ENV{PATH}) { $LZMA = File::Spec->catfile($dir,$nameLZ) if -x File::Spec->catfile($dir,$nameLZ); $UNLZMA = File::Spec->catfile($dir,$nameUNLZ) if -x File::Spec->catfile($dir,$nameUNLZ); } # Handle spaces in path to lzma $LZMA = "\"$LZMA\"" if defined $LZMA && $LZMA =~ /\s/; $UNLZMA = "\"$UNLZMA\"" if defined $UNLZMA && $UNLZMA =~ /\s/; plan(skip_all => "Cannot find $nameLZ") if ! $LZMA ; plan(skip_all => "Cannot find $nameUNLZ") if ! $UNLZMA ; plan(skip_all => "$nameLZ doesn't work as expected") if ! ExternalLzmaWorks(); # use Test::NoWarnings, if available my $extra = 0 ; $extra = 1 if eval { require Test::NoWarnings ; import Test::NoWarnings; 1 }; plan tests => 12 + $extra ; use_ok('IO::Compress::Lzma', ':all') ; use_ok('IO::Uncompress::UnLzma', ':all') ; } { title "Test interop with $LZMA" ; my ($file, $file1); my $lex = new LexFile $file, $file1; my $content = "hello world\n" ; my $got; ok writeWithLzma($file, $content), "writeWithLzma ok"; unlzma $file => \$got ; is $got, $content; lzma \$content => $file1; $got = ''; ok readWithLzma($file1, $got), "readWithLzma returns 0"; is $got, $content, "got content"; } { title "Test interop with $LZMA - empty file" ; my ($file, $file1); my $lex = new LexFile $file, $file1; my $content = "" ; my $got; ok writeWithLzma($file, $content), "writeWithLzma ok"; unlzma $file => \$got ; is $got, $content; lzma \$content => $file1; $got = ''; ok readWithLzma($file1, $got), "readWithLzma returns 0"; is $got, $content, "got content"; } libio-compress-lzma-perl-2.093/t/050interop-xz.t000066400000000000000000000057571357305603400213770ustar00rootroot00000000000000BEGIN { if ($ENV{PERL_CORE}) { chdir 't' if -d 't'; @INC = ("../lib", "lib/compress"); } } use lib qw(t t/compress); use strict; use warnings; use bytes; use File::Spec ; use Test::More ; use CompTestUtils; my $XZ ; sub ExternalXzWorks { my $lex = new LexFile my $outfile; my $content = qq { Lorem ipsum dolor sit amet, consectetuer adipiscing elit. Ut tempus odio id dolor. Camelus perlus. Larrius in lumen numen. Dolor en quiquum filia est. Quintus cenum parat. }; writeWithXz($outfile, $content) or return 0; my $got ; readWithXz($outfile, $got) or return 0; if ($content ne $got) { diag "Uncompressed content is wrong"; return 0 ; } return 1 ; } sub readWithXz { my $file = shift ; my $lex = new LexFile my $outfile; my $comp = "$XZ -dc" ; if (system("$comp $file >$outfile") == 0 ) { $_[0] = readFile($outfile); return 1 ; } diag "'$comp' failed: $?"; return 0 ; } sub getBzip2Info { my $file = shift ; } sub writeWithXz { my $file = shift ; my $content = shift ; my $options = shift || ''; my $lex = new LexFile my $infile; writeFile($infile, $content); unlink $file ; my $comp = "$XZ -c $options $infile >$file" ; return 1 if system($comp) == 0 ; diag "'$comp' failed: $?"; return 0 ; } BEGIN { # Check external xz is available my $name = $^O =~ /mswin/i ? 'xz.exe' : 'xz'; my $split = $^O =~ /mswin/i ? ";" : ":"; for my $dir (reverse split $split, $ENV{PATH}) { $XZ = File::Spec->catfile($dir,$name) if -x File::Spec->catfile($dir,$name); } # Handle spaces in path to xz $XZ = "\"$XZ\"" if defined $XZ && $XZ =~ /\s/; plan(skip_all => "Cannot find $name") if ! $XZ ; plan(skip_all => "$name doesn't work as expected") if ! ExternalXzWorks(); # use Test::NoWarnings, if available my $extra = 0 ; $extra = 1 if eval { require Test::NoWarnings ; import Test::NoWarnings; 1 }; plan tests => 12 + $extra ; use_ok('IO::Compress::Xz', ':all') ; use_ok('IO::Uncompress::UnXz', ':all') ; } { title "Test interop with $XZ" ; my ($file, $file1); my $lex = new LexFile $file, $file1; my $content = "hello world\n" ; my $got; ok writeWithXz($file, $content), "writeWithXz ok"; unxz $file => \$got ; is $got, $content; xz \$content => $file1; $got = ''; ok readWithXz($file1, $got), "readWithXz returns 0"; is $got, $content, "got content"; } { title "Test interop with $XZ - empty file" ; my ($file, $file1); my $lex = new LexFile $file, $file1; my $content = "" ; my $got; ok writeWithXz($file, $content), "writeWithXz ok"; unxz $file => \$got ; is $got, $content; xz \$content => $file1; $got = ''; ok readWithXz($file1, $got), "readWithXz returns 0"; is $got, $content, "got content"; } libio-compress-lzma-perl-2.093/t/050interop-zip-lzma.t000066400000000000000000000126451357305603400224730ustar00rootroot00000000000000BEGIN { if ($ENV{PERL_CORE}) { chdir 't' if -d 't'; @INC = ("../lib", "lib/compress"); } } use lib qw(t t/compress); use strict; use File::Spec ; use Test::More ; use CompTestUtils; BEGIN { #plan(skip_all => "temp disabled until IO::Compress::RawLzma is ready") # if 1; plan(skip_all => "needs Perl 5.6 or better - you have Perl $]" ) if $] < 5.006 ; } use bytes; use warnings; my $P7ZIP ='7z'; sub ExternalP7ZipWorks { my $lex = new LexFile my $outfile; my $content = qq { Lorem ipsum dolor sit amet, consectetuer adipiscing elit. Ut tempus odio id dolor. Camelus perlus. Larrius in lumen numen. Dolor en quiquum filia est. Quintus cenum parat. }; writeWithP7Zip($outfile, $content, "-mm=Lzma") or return 0; my $got ; readWithP7Zip($outfile, $got) or return 0; if ($content ne $got) { diag "Uncompressed content is wrong"; return 0 ; } return 1 ; } sub readWithP7Zip { my $file = shift ; my ($outfile, $stderr) ; my $lex = new LexFile $outfile, $stderr; my $comp = "$P7ZIP" ; if ( system("$comp e -tZip -so $file >$outfile 2>$stderr") == 0 ) { $_[0] = readFile($outfile); return 1 } my $bad = readFile($stderr); diag "'$comp' failed: $? [$bad]"; return 0 ; } sub writeWithP7Zip { my $file = shift ; my $content = shift ; my $options = shift || ''; my $lex = new LexFile my $infile; writeFile($infile, $content); unlink $file ; my $comp = "$P7ZIP a -tZip $options $file $infile >/dev/null" ; return 1 if system($comp) == 0 ; diag "'$comp' failed: $?"; return 0 ; } sub testWithP7Zip { my $file = shift ; my $lex = new LexFile my $outfile; my $status = ( system("$P7ZIP t -tZip $file >$outfile 2>/dev/null") == 0 ) ; $_[0] = readFile($outfile); return $status ; } sub memError { my $err = shift ; #my $re = "(" . LZMA_MEM_ERROR . "|" . LZMA_MEMLIMIT_ERROR . ")"; #my $re .= LZMA_MEM_ERROR; my $re = "(Memory usage limit was reached|Cannot allocate memory)"; return $err =~/$re/ ; } BEGIN { # Check external 7za exists my $p7zip = '7z'; for my $dir (reverse split ":", $ENV{PATH}) { $P7ZIP = "$dir/$p7zip" if -x "$dir/$p7zip" ; } plan(skip_all => "Cannot find $p7zip") if ! $P7ZIP ; plan(skip_all => "$p7zip don't work as expected") if ! ExternalP7ZipWorks(); # use Test::NoWarnings, if available my $extra = 0 ; $extra = 1 if eval { require Test::NoWarnings ; import Test::NoWarnings; 1 }; plan tests => 575 + $extra ; use_ok('IO::Compress::Zip', ':all') ; use_ok('IO::Uncompress::Unzip', ':all') ; } { title "Test interop with $P7ZIP" ; my $file ; my $file1; my $file2; my $lex = new LexFile $file, $file1, $file2; my @content = ("", qq { Lorem ipsum dolor sit amet, consectetuer adipiscing elit. Ut tempus odio id dolor. Camelus perlus. Larrius in lumen numen. Dolor en quiquum filia est. Quintus cenum parat. Hello World }); my $got; #for my $method (qw(Copy Deflate Bzip2 LZMA)) for my $content (@content) { for my $method (qw(LZMA)) { title "unzip with Method $method"; ok writeWithP7Zip($file, $content, "-mm=$method"), " writeWithP7Zip ok"; $got = ''; ok readWithP7Zip($file, $got), " readWithP7Zip ok"; is $got, $content, " got content"; $got = ''; ok unzip($file => \$got), " unzipped ok" ; is $got, $content, " got content with unzip"; } } for my $content (@content) { #for my $method (ZIP_CM_STORE, ZIP_CM_DEFLATE, ZIP_CM_BZIP2, ZIP_CM_LZMA) for my $method (ZIP_CM_LZMA) { for my $streamed (1, 0) { for my $preset (0 .. 9) { for my $extreme (0, 1) { SKIP: { title "zip with Method $method, Streamed $streamed, Preset $preset, Extreme $extreme"; my $status = zip(\$content => $file1, Name => "fred", Preset => $preset, Extreme => $extreme, Stream => $streamed, Method => $method); skip "Not enough memory - Preset $preset, Extreme $extreme, Preset $preset", 6 if memError($ZipError); ok $status, "zip ok" or diag $ZipError; $got = ''; ok unzip($file1 => \$got), "unzipped" or diag $UnzipError ; is $got, $content, " got content with unzip"; $got = ''; ok readWithP7Zip($file1, $got), " readWithP7Zip ok"; is $got, $content, " got content"; ok testWithP7Zip($file1, $got), " testWithP7Zip ok" or diag " got $got"; } } } } } } } libio-compress-lzma-perl-2.093/t/100generic-lzip.t000066400000000000000000000005021357305603400216230ustar00rootroot00000000000000BEGIN { if ($ENV{PERL_CORE}) { chdir 't' if -d 't'; @INC = ("../lib", "lib/compress"); } } use lib qw(t t/compress); use strict; use warnings; use IO::Compress::Lzip qw($LzipError) ; use IO::Uncompress::UnLzip qw($UnLzipError) ; sub identify { 'IO::Compress::Lzip'; } require "generic.pl" ; run(); libio-compress-lzma-perl-2.093/t/100generic-lzma.t000066400000000000000000000005021357305603400216100ustar00rootroot00000000000000BEGIN { if ($ENV{PERL_CORE}) { chdir 't' if -d 't'; @INC = ("../lib", "lib/compress"); } } use lib qw(t t/compress); use strict; use warnings; use IO::Compress::Lzma qw($LzmaError) ; use IO::Uncompress::UnLzma qw($UnLzmaError) ; sub identify { 'IO::Compress::Lzma'; } require "generic.pl" ; run(); libio-compress-lzma-perl-2.093/t/100generic-xz.t000066400000000000000000000004701357305603400213120ustar00rootroot00000000000000BEGIN { if ($ENV{PERL_CORE}) { chdir 't' if -d 't'; @INC = ("../lib", "lib/compress"); } } use lib qw(t t/compress); use strict; use warnings; use IO::Compress::Xz qw($XzError) ; use IO::Uncompress::UnXz qw($UnXzError) ; sub identify { 'IO::Compress::Xz'; } require "generic.pl" ; run(); libio-compress-lzma-perl-2.093/t/101truncate-lzip.t000066400000000000000000000011161357305603400220370ustar00rootroot00000000000000BEGIN { if ($ENV{PERL_CORE}) { chdir 't' if -d 't'; @INC = ("../lib", "lib/compress"); } } use lib qw(t t/compress); use strict; use warnings; use Test::More ; BEGIN { # use Test::NoWarnings, if available my $extra = 0 ; $extra = 1 if eval { require Test::NoWarnings ; import Test::NoWarnings; 1 }; plan tests => 3700 + $extra; }; #use Test::More skip_all => "not implemented yet"; use IO::Compress::Lzip qw($LzipError) ; use IO::Uncompress::UnLzip qw($UnLzipError) ; sub identify { 'IO::Compress::Lzip'; } require "truncate.pl" ; run(); libio-compress-lzma-perl-2.093/t/101truncate-lzma.t000066400000000000000000000012131357305603400220220ustar00rootroot00000000000000BEGIN { if ($ENV{PERL_CORE}) { chdir 't' if -d 't'; @INC = ("../lib", "lib/compress"); } } use lib qw(t t/compress); use strict; use warnings; use Test::More ; BEGIN { # use Test::NoWarnings, if available #my $extra = 0 ; #$extra = 1 # if eval { require Test::NoWarnings ; import Test::NoWarnings; 1 }; #plan tests => 912 + $extra; plan(skip_all => "Truncate not supported with Lzma"); }; #use Test::More skip_all => "not implemented yet"; use IO::Compress::Lzma qw($LzmaError) ; use IO::Uncompress::UnLzma qw($UnLzmaError) ; sub identify { 'IO::Compress::Lzma'; } require "truncate.pl" ; run(); libio-compress-lzma-perl-2.093/t/101truncate-xz.t000066400000000000000000000011041357305603400215170ustar00rootroot00000000000000BEGIN { if ($ENV{PERL_CORE}) { chdir 't' if -d 't'; @INC = ("../lib", "lib/compress"); } } use lib qw(t t/compress); use strict; use warnings; use Test::More ; BEGIN { # use Test::NoWarnings, if available my $extra = 0 ; $extra = 1 if eval { require Test::NoWarnings ; import Test::NoWarnings; 1 }; plan tests => 4420 + $extra; }; #use Test::More skip_all => "not implemented yet"; use IO::Compress::Xz qw($XzError) ; use IO::Uncompress::UnXz qw($UnXzError) ; sub identify { 'IO::Compress::Xz'; } require "truncate.pl" ; run(); libio-compress-lzma-perl-2.093/t/102tied-lzip.t000066400000000000000000000004751357305603400211470ustar00rootroot00000000000000BEGIN { if ($ENV{PERL_CORE}) { chdir 't' if -d 't'; @INC = ("../lib", "lib/compress"); } } use lib qw(t t/compress); use strict; use warnings; use IO::Compress::Lzip qw($LzipError) ; use IO::Uncompress::UnLzip qw($UnLzipError) ; sub identify { 'IO::Compress::Lzip'; } require "tied.pl" ; run(); libio-compress-lzma-perl-2.093/t/102tied-lzma.t000066400000000000000000000004751357305603400211340ustar00rootroot00000000000000BEGIN { if ($ENV{PERL_CORE}) { chdir 't' if -d 't'; @INC = ("../lib", "lib/compress"); } } use lib qw(t t/compress); use strict; use warnings; use IO::Compress::Lzma qw($LzmaError) ; use IO::Uncompress::UnLzma qw($UnLzmaError) ; sub identify { 'IO::Compress::Lzma'; } require "tied.pl" ; run(); libio-compress-lzma-perl-2.093/t/102tied-xz.t000066400000000000000000000004631357305603400206270ustar00rootroot00000000000000BEGIN { if ($ENV{PERL_CORE}) { chdir 't' if -d 't'; @INC = ("../lib", "lib/compress"); } } use lib qw(t t/compress); use strict; use warnings; use IO::Compress::Xz qw($XzError) ; use IO::Uncompress::UnXz qw($UnXzError) ; sub identify { 'IO::Compress::Xz'; } require "tied.pl" ; run(); libio-compress-lzma-perl-2.093/t/103newtied-lzip.t000066400000000000000000000005001357305603400216470ustar00rootroot00000000000000BEGIN { if ($ENV{PERL_CORE}) { chdir 't' if -d 't'; @INC = ("../lib", "lib/compress"); } } use lib qw(t t/compress); use strict; use warnings; use IO::Compress::Lzip qw($LzipError) ; use IO::Uncompress::UnLzip qw($UnLzipError) ; sub identify { 'IO::Compress::Lzip'; } require "newtied.pl" ; run(); libio-compress-lzma-perl-2.093/t/103newtied-lzma.t000066400000000000000000000005001357305603400216340ustar00rootroot00000000000000BEGIN { if ($ENV{PERL_CORE}) { chdir 't' if -d 't'; @INC = ("../lib", "lib/compress"); } } use lib qw(t t/compress); use strict; use warnings; use IO::Compress::Lzma qw($LzmaError) ; use IO::Uncompress::UnLzma qw($UnLzmaError) ; sub identify { 'IO::Compress::Lzma'; } require "newtied.pl" ; run(); libio-compress-lzma-perl-2.093/t/103newtied-xz.t000066400000000000000000000004661357305603400213450ustar00rootroot00000000000000BEGIN { if ($ENV{PERL_CORE}) { chdir 't' if -d 't'; @INC = ("../lib", "lib/compress"); } } use lib qw(t t/compress); use strict; use warnings; use IO::Compress::Xz qw($XzError) ; use IO::Uncompress::UnXz qw($UnXzError) ; sub identify { 'IO::Compress::Xz'; } require "newtied.pl" ; run(); libio-compress-lzma-perl-2.093/t/104destroy-lzip.t000066400000000000000000000005001357305603400217020ustar00rootroot00000000000000BEGIN { if ($ENV{PERL_CORE}) { chdir 't' if -d 't'; @INC = ("../lib", "lib/compress"); } } use lib qw(t t/compress); use strict; use warnings; use IO::Compress::Lzip qw($LzipError) ; use IO::Uncompress::UnLzip qw($UnLzipError) ; sub identify { 'IO::Compress::Lzip'; } require "destroy.pl" ; run(); libio-compress-lzma-perl-2.093/t/104destroy-lzma.t000066400000000000000000000005001357305603400216670ustar00rootroot00000000000000BEGIN { if ($ENV{PERL_CORE}) { chdir 't' if -d 't'; @INC = ("../lib", "lib/compress"); } } use lib qw(t t/compress); use strict; use warnings; use IO::Compress::Lzma qw($LzmaError) ; use IO::Uncompress::UnLzma qw($UnLzmaError) ; sub identify { 'IO::Compress::Lzma'; } require "destroy.pl" ; run(); libio-compress-lzma-perl-2.093/t/104destroy-xz.t000066400000000000000000000004661357305603400214000ustar00rootroot00000000000000BEGIN { if ($ENV{PERL_CORE}) { chdir 't' if -d 't'; @INC = ("../lib", "lib/compress"); } } use lib qw(t t/compress); use strict; use warnings; use IO::Compress::Xz qw($XzError) ; use IO::Uncompress::UnXz qw($UnXzError) ; sub identify { 'IO::Compress::Xz'; } require "destroy.pl" ; run(); libio-compress-lzma-perl-2.093/t/105oneshot-lzip.t000066400000000000000000000005011357305603400216720ustar00rootroot00000000000000BEGIN { if ($ENV{PERL_CORE}) { chdir 't' if -d 't'; @INC = ("../lib", "lib/compress"); } } use lib qw(t t/compress); use strict; use warnings; use IO::Compress::Lzip qw($LzipError) ; use IO::Uncompress::UnLzip qw($UnLzipError) ; sub identify { 'IO::Compress::Lzip'; } require "oneshot.pl" ; run(); libio-compress-lzma-perl-2.093/t/105oneshot-lzma.t000066400000000000000000000005011357305603400216570ustar00rootroot00000000000000BEGIN { if ($ENV{PERL_CORE}) { chdir 't' if -d 't'; @INC = ("../lib", "lib/compress"); } } use lib qw(t t/compress); use strict; use warnings; use IO::Compress::Lzma qw($LzmaError) ; use IO::Uncompress::UnLzma qw($UnLzmaError) ; sub identify { 'IO::Compress::Lzma'; } require "oneshot.pl" ; run(); libio-compress-lzma-perl-2.093/t/105oneshot-xz.t000066400000000000000000000004671357305603400213700ustar00rootroot00000000000000BEGIN { if ($ENV{PERL_CORE}) { chdir 't' if -d 't'; @INC = ("../lib", "lib/compress"); } } use lib qw(t t/compress); use strict; use warnings; use IO::Compress::Xz qw($XzError) ; use IO::Uncompress::UnXz qw($UnXzError) ; sub identify { 'IO::Compress::Xz'; } require "oneshot.pl" ; run(); libio-compress-lzma-perl-2.093/t/106prime-lzip.t000066400000000000000000000004761357305603400213430ustar00rootroot00000000000000BEGIN { if ($ENV{PERL_CORE}) { chdir 't' if -d 't'; @INC = ("../lib", "lib/compress"); } } use lib qw(t t/compress); use strict; use warnings; use IO::Compress::Lzip qw($LzipError) ; use IO::Uncompress::UnLzip qw($UnLzipError) ; sub identify { 'IO::Compress::Lzip'; } require "prime.pl" ; run(); libio-compress-lzma-perl-2.093/t/106prime-lzma.t000066400000000000000000000004761357305603400213300ustar00rootroot00000000000000BEGIN { if ($ENV{PERL_CORE}) { chdir 't' if -d 't'; @INC = ("../lib", "lib/compress"); } } use lib qw(t t/compress); use strict; use warnings; use IO::Compress::Lzma qw($LzmaError) ; use IO::Uncompress::UnLzma qw($UnLzmaError) ; sub identify { 'IO::Compress::Lzma'; } require "prime.pl" ; run(); libio-compress-lzma-perl-2.093/t/106prime-xz.t000066400000000000000000000004641357305603400210230ustar00rootroot00000000000000BEGIN { if ($ENV{PERL_CORE}) { chdir 't' if -d 't'; @INC = ("../lib", "lib/compress"); } } use lib qw(t t/compress); use strict; use warnings; use IO::Compress::Xz qw($XzError) ; use IO::Uncompress::UnXz qw($UnXzError) ; sub identify { 'IO::Compress::Xz'; } require "prime.pl" ; run(); libio-compress-lzma-perl-2.093/t/107multi-lzip.t000066400000000000000000000004761357305603400213620ustar00rootroot00000000000000BEGIN { if ($ENV{PERL_CORE}) { chdir 't' if -d 't'; @INC = ("../lib", "lib/compress"); } } use lib qw(t t/compress); use strict; use warnings; use IO::Compress::Lzip qw($LzipError) ; use IO::Uncompress::UnLzip qw($UnLzipError) ; sub identify { 'IO::Compress::Lzip'; } require "multi.pl" ; run(); libio-compress-lzma-perl-2.093/t/107multi-lzma.t000066400000000000000000000006241357305603400213420ustar00rootroot00000000000000BEGIN { if ($ENV{PERL_CORE}) { chdir 't' if -d 't'; @INC = ("../lib", "lib/compress"); } } use lib qw(t t/compress); use strict; use warnings; use Test::More; BEGIN { plan(skip_all => "MultiStream not supported by Lzma"); } use IO::Compress::Lzma qw($LzmaError) ; use IO::Uncompress::UnLzma qw($UnLzmaError) ; sub identify { 'IO::Compress::Lzma'; } require "multi.pl" ; run(); libio-compress-lzma-perl-2.093/t/107multi-xz.t000066400000000000000000000004641357305603400210420ustar00rootroot00000000000000BEGIN { if ($ENV{PERL_CORE}) { chdir 't' if -d 't'; @INC = ("../lib", "lib/compress"); } } use lib qw(t t/compress); use strict; use warnings; use IO::Compress::Xz qw($XzError) ; use IO::Uncompress::UnXz qw($UnXzError) ; sub identify { 'IO::Compress::Xz'; } require "multi.pl" ; run(); libio-compress-lzma-perl-2.093/t/108anyunc-lzip.t000066400000000000000000000006411357305603400215200ustar00rootroot00000000000000BEGIN { if ($ENV{PERL_CORE}) { chdir 't' if -d 't'; @INC = ("../lib", "lib/compress"); } } use lib qw(t t/compress); use strict; use warnings; use IO::Uncompress::AnyUncompress qw($AnyUncompressError) ; use IO::Compress::Lzip qw($LzipError) ; use IO::Uncompress::UnLzip qw($UnLzipError) ; sub getClass { 'AnyUncompress'; } sub identify { 'IO::Compress::Lzip'; } require "any.pl" ; run(); libio-compress-lzma-perl-2.093/t/108anyunc-lzma.t000066400000000000000000000006411357305603400215050ustar00rootroot00000000000000BEGIN { if ($ENV{PERL_CORE}) { chdir 't' if -d 't'; @INC = ("../lib", "lib/compress"); } } use lib qw(t t/compress); use strict; use warnings; use IO::Uncompress::AnyUncompress qw($AnyUncompressError) ; use IO::Compress::Lzma qw($LzmaError) ; use IO::Uncompress::UnLzma qw($UnLzmaError) ; sub getClass { 'AnyUncompress'; } sub identify { 'IO::Compress::Lzma'; } require "any.pl" ; run(); libio-compress-lzma-perl-2.093/t/108anyunc-xz.t000066400000000000000000000006271357305603400212070ustar00rootroot00000000000000BEGIN { if ($ENV{PERL_CORE}) { chdir 't' if -d 't'; @INC = ("../lib", "lib/compress"); } } use lib qw(t t/compress); use strict; use warnings; use IO::Uncompress::AnyUncompress qw($AnyUncompressError) ; use IO::Compress::Xz qw($XzError) ; use IO::Uncompress::UnXz qw($UnXzError) ; sub getClass { 'AnyUncompress'; } sub identify { 'IO::Compress::Xz'; } require "any.pl" ; run(); libio-compress-lzma-perl-2.093/t/110encode-lzip.t000066400000000000000000000004771357305603400214600ustar00rootroot00000000000000BEGIN { if ($ENV{PERL_CORE}) { chdir 't' if -d 't'; @INC = ("../lib", "lib/compress"); } } use lib qw(t t/compress); use strict; use warnings; use IO::Compress::Lzip qw($LzipError) ; use IO::Uncompress::UnLzip qw($UnLzipError) ; sub identify { 'IO::Compress::Lzip'; } require "encode.pl" ; run(); libio-compress-lzma-perl-2.093/t/110encode-lzma.t000066400000000000000000000004771357305603400214450ustar00rootroot00000000000000BEGIN { if ($ENV{PERL_CORE}) { chdir 't' if -d 't'; @INC = ("../lib", "lib/compress"); } } use lib qw(t t/compress); use strict; use warnings; use IO::Compress::Lzma qw($LzmaError) ; use IO::Uncompress::UnLzma qw($UnLzmaError) ; sub identify { 'IO::Compress::Lzma'; } require "encode.pl" ; run(); libio-compress-lzma-perl-2.093/t/110encode-xz.t000066400000000000000000000004651357305603400211400ustar00rootroot00000000000000BEGIN { if ($ENV{PERL_CORE}) { chdir 't' if -d 't'; @INC = ("../lib", "lib/compress"); } } use lib qw(t t/compress); use strict; use warnings; use IO::Compress::Xz qw($XzError) ; use IO::Uncompress::UnXz qw($UnXzError) ; sub identify { 'IO::Compress::Xz'; } require "encode.pl" ; run(); libio-compress-lzma-perl-2.093/t/25interop-io-string.t000066400000000000000000000005331357305603400225560ustar00rootroot00000000000000BEGIN { if ($ENV{PERL_CORE}) { chdir 't' if -d 't'; @INC = ("../lib", "lib/compress"); } } use lib qw(t t/compress); use strict; #use warnings; use IO::Compress::Lzma qw($LzmaError) ; use IO::Uncompress::UnLzma qw($UnLzmaError) ; sub identify { 'IO::Compress::Lzma'; } require "interop-io-string.pl" ; run(); libio-compress-lzma-perl-2.093/t/999pod.t000066400000000000000000000004051357305603400200510ustar00rootroot00000000000000BEGIN { if ($ENV{PERL_CORE}) { chdir 't' if -d 't'; @INC = ("../lib", "lib/compress"); } } use lib qw(t t/compress); use Test::More; eval "use Test::Pod 1.00"; plan skip_all => "Test::Pod 1.00 required for testing POD" if $@; all_pod_files_ok(); libio-compress-lzma-perl-2.093/t/Test/000077500000000000000000000000001357305603400175475ustar00rootroot00000000000000libio-compress-lzma-perl-2.093/t/Test/Builder.pm000066400000000000000000001105431357305603400214770ustar00rootroot00000000000000package Test::Builder; use 5.004; # $^C was only introduced in 5.005-ish. We do this to prevent # use of uninitialized value warnings in older perls. $^C ||= 0; use strict; our ($VERSION); $VERSION = '0.30'; $VERSION = eval $VERSION; # make the alpha version come out as a number # Make Test::Builder thread-safe for ithreads. BEGIN { use Config; # Load threads::shared when threads are turned on if( $] >= 5.008 && $Config{useithreads} && $INC{'threads.pm'}) { require threads::shared; # Hack around YET ANOTHER threads::shared bug. It would # occassionally forget the contents of the variable when sharing it. # So we first copy the data, then share, then put our copy back. *share = sub (\[$@%]) { my $type = ref $_[0]; my $data; if( $type eq 'HASH' ) { %$data = %{$_[0]}; } elsif( $type eq 'ARRAY' ) { @$data = @{$_[0]}; } elsif( $type eq 'SCALAR' ) { $$data = ${$_[0]}; } else { die "Unknown type: ".$type; } $_[0] = &threads::shared::share($_[0]); if( $type eq 'HASH' ) { %{$_[0]} = %$data; } elsif( $type eq 'ARRAY' ) { @{$_[0]} = @$data; } elsif( $type eq 'SCALAR' ) { ${$_[0]} = $$data; } else { die "Unknown type: ".$type; } return $_[0]; }; } # 5.8.0's threads::shared is busted when threads are off. # We emulate it here. else { *share = sub { return $_[0] }; *lock = sub { 0 }; } } =head1 NAME Test::Builder - Backend for building test libraries =head1 SYNOPSIS package My::Test::Module; use Test::Builder; require Exporter; @ISA = qw(Exporter); @EXPORT = qw(ok); my $Test = Test::Builder->new; $Test->output('my_logfile'); sub import { my($self) = shift; my $pack = caller; $Test->exported_to($pack); $Test->plan(@_); $self->export_to_level(1, $self, 'ok'); } sub ok { my($test, $name) = @_; $Test->ok($test, $name); } =head1 DESCRIPTION Test::Simple and Test::More have proven to be popular testing modules, but they're not always flexible enough. Test::Builder provides the a building block upon which to write your own test libraries I. =head2 Construction =over 4 =item B my $Test = Test::Builder->new; Returns a Test::Builder object representing the current state of the test. Since you only run one test per program C always returns the same Test::Builder object. No matter how many times you call new(), you're getting the same object. This is called a singleton. This is done so that multiple modules share such global information as the test counter and where test output is going. If you want a completely new Test::Builder object different from the singleton, use C. =cut my $Test = Test::Builder->new; sub new { my($class) = shift; $Test ||= $class->create; return $Test; } =item B my $Test = Test::Builder->create; Ok, so there can be more than one Test::Builder object and this is how you get it. You might use this instead of C if you're testing a Test::Builder based module, but otherwise you probably want C. B: the implementation is not complete. C, for example, is still shared amongst B Test::Builder objects, even ones created using this method. Also, the method name may change in the future. =cut sub create { my $class = shift; my $self = bless {}, $class; $self->reset; return $self; } =item B $Test->reset; Reinitializes the Test::Builder singleton to its original state. Mostly useful for tests run in persistent environments where the same test might be run multiple times in the same process. =cut our ($Level); sub reset { my ($self) = @_; # We leave this a global because it has to be localized and localizing # hash keys is just asking for pain. Also, it was documented. $Level = 1; $self->{Test_Died} = 0; $self->{Have_Plan} = 0; $self->{No_Plan} = 0; $self->{Original_Pid} = $$; share($self->{Curr_Test}); $self->{Curr_Test} = 0; $self->{Test_Results} = &share([]); $self->{Exported_To} = undef; $self->{Expected_Tests} = 0; $self->{Skip_All} = 0; $self->{Use_Nums} = 1; $self->{No_Header} = 0; $self->{No_Ending} = 0; $self->_dup_stdhandles unless $^C; return undef; } =back =head2 Setting up tests These methods are for setting up tests and declaring how many there are. You usually only want to call one of these methods. =over 4 =item B my $pack = $Test->exported_to; $Test->exported_to($pack); Tells Test::Builder what package you exported your functions to. This is important for getting TODO tests right. =cut sub exported_to { my($self, $pack) = @_; if( defined $pack ) { $self->{Exported_To} = $pack; } return $self->{Exported_To}; } =item B $Test->plan('no_plan'); $Test->plan( skip_all => $reason ); $Test->plan( tests => $num_tests ); A convenient way to set up your tests. Call this and Test::Builder will print the appropriate headers and take the appropriate actions. If you call plan(), don't call any of the other methods below. =cut sub plan { my($self, $cmd, $arg) = @_; return unless $cmd; if( $self->{Have_Plan} ) { die sprintf "You tried to plan twice! Second plan at %s line %d\n", ($self->caller)[1,2]; } if( $cmd eq 'no_plan' ) { $self->no_plan; } elsif( $cmd eq 'skip_all' ) { return $self->skip_all($arg); } elsif( $cmd eq 'tests' ) { if( $arg ) { return $self->expected_tests($arg); } elsif( !defined $arg ) { die "Got an undefined number of tests. Looks like you tried to ". "say how many tests you plan to run but made a mistake.\n"; } elsif( !$arg ) { die "You said to run 0 tests! You've got to run something.\n"; } } else { require Carp; my @args = grep { defined } ($cmd, $arg); Carp::croak("plan() doesn't understand @args"); } return 1; } =item B my $max = $Test->expected_tests; $Test->expected_tests($max); Gets/sets the # of tests we expect this test to run and prints out the appropriate headers. =cut sub expected_tests { my $self = shift; my($max) = @_; if( @_ ) { die "Number of tests must be a postive integer. You gave it '$max'.\n" unless $max =~ /^\+?\d+$/ and $max > 0; $self->{Expected_Tests} = $max; $self->{Have_Plan} = 1; $self->_print("1..$max\n") unless $self->no_header; } return $self->{Expected_Tests}; } =item B $Test->no_plan; Declares that this test will run an indeterminate # of tests. =cut sub no_plan { my $self = shift; $self->{No_Plan} = 1; $self->{Have_Plan} = 1; } =item B $plan = $Test->has_plan Find out whether a plan has been defined. $plan is either C (no plan has been set), C (indeterminate # of tests) or an integer (the number of expected tests). =cut sub has_plan { my $self = shift; return($self->{Expected_Tests}) if $self->{Expected_Tests}; return('no_plan') if $self->{No_Plan}; return(undef); }; =item B $Test->skip_all; $Test->skip_all($reason); Skips all the tests, using the given $reason. Exits immediately with 0. =cut sub skip_all { my($self, $reason) = @_; my $out = "1..0"; $out .= " # Skip $reason" if $reason; $out .= "\n"; $self->{Skip_All} = 1; $self->_print($out) unless $self->no_header; exit(0); } =back =head2 Running tests These actually run the tests, analogous to the functions in Test::More. $name is always optional. =over 4 =item B $Test->ok($test, $name); Your basic test. Pass if $test is true, fail if $test is false. Just like Test::Simple's ok(). =cut sub ok { my($self, $test, $name) = @_; # $test might contain an object which we don't want to accidentally # store, so we turn it into a boolean. $test = $test ? 1 : 0; unless( $self->{Have_Plan} ) { require Carp; Carp::croak("You tried to run a test without a plan! Gotta have a plan."); } lock $self->{Curr_Test}; $self->{Curr_Test}++; # In case $name is a string overloaded object, force it to stringify. $self->_unoverload(\$name); $self->diag(<caller; my $todo = $self->todo($pack); $self->_unoverload(\$todo); my $out; my $result = &share({}); unless( $test ) { $out .= "not "; @$result{ 'ok', 'actual_ok' } = ( ( $todo ? 1 : 0 ), 0 ); } else { @$result{ 'ok', 'actual_ok' } = ( 1, $test ); } $out .= "ok"; $out .= " $self->{Curr_Test}" if $self->use_numbers; if( defined $name ) { $name =~ s|#|\\#|g; # # in a name can confuse Test::Harness. $out .= " - $name"; $result->{name} = $name; } else { $result->{name} = ''; } if( $todo ) { $out .= " # TODO $todo"; $result->{reason} = $todo; $result->{type} = 'todo'; } else { $result->{reason} = ''; $result->{type} = ''; } $self->{Test_Results}[$self->{Curr_Test}-1] = $result; $out .= "\n"; $self->_print($out); unless( $test ) { my $msg = $todo ? "Failed (TODO)" : "Failed"; $self->_print_diag("\n") if $ENV{HARNESS_ACTIVE}; $self->diag(" $msg test ($file at line $line)\n"); } return $test ? 1 : 0; } sub _unoverload { my $self = shift; local($@,$!); eval { require overload } || return; foreach my $thing (@_) { eval { if( defined $$thing ) { if( my $string_meth = overload::Method($$thing, '""') ) { $$thing = $$thing->$string_meth(); } } }; } } =item B $Test->is_eq($got, $expected, $name); Like Test::More's is(). Checks if $got eq $expected. This is the string version. =item B $Test->is_num($got, $expected, $name); Like Test::More's is(). Checks if $got == $expected. This is the numeric version. =cut sub is_eq { my($self, $got, $expect, $name) = @_; local $Level = $Level + 1; if( !defined $got || !defined $expect ) { # undef only matches undef and nothing else my $test = !defined $got && !defined $expect; $self->ok($test, $name); $self->_is_diag($got, 'eq', $expect) unless $test; return $test; } return $self->cmp_ok($got, 'eq', $expect, $name); } sub is_num { my($self, $got, $expect, $name) = @_; local $Level = $Level + 1; if( !defined $got || !defined $expect ) { # undef only matches undef and nothing else my $test = !defined $got && !defined $expect; $self->ok($test, $name); $self->_is_diag($got, '==', $expect) unless $test; return $test; } return $self->cmp_ok($got, '==', $expect, $name); } sub _is_diag { my($self, $got, $type, $expect) = @_; foreach my $val (\$got, \$expect) { if( defined $$val ) { if( $type eq 'eq' ) { # quote and force string context $$val = "'$$val'" } else { # force numeric context $$val = $$val+0; } } else { $$val = 'undef'; } } return $self->diag(sprintf < $Test->isnt_eq($got, $dont_expect, $name); Like Test::More's isnt(). Checks if $got ne $dont_expect. This is the string version. =item B $Test->is_num($got, $dont_expect, $name); Like Test::More's isnt(). Checks if $got ne $dont_expect. This is the numeric version. =cut sub isnt_eq { my($self, $got, $dont_expect, $name) = @_; local $Level = $Level + 1; if( !defined $got || !defined $dont_expect ) { # undef only matches undef and nothing else my $test = defined $got || defined $dont_expect; $self->ok($test, $name); $self->_cmp_diag($got, 'ne', $dont_expect) unless $test; return $test; } return $self->cmp_ok($got, 'ne', $dont_expect, $name); } sub isnt_num { my($self, $got, $dont_expect, $name) = @_; local $Level = $Level + 1; if( !defined $got || !defined $dont_expect ) { # undef only matches undef and nothing else my $test = defined $got || defined $dont_expect; $self->ok($test, $name); $self->_cmp_diag($got, '!=', $dont_expect) unless $test; return $test; } return $self->cmp_ok($got, '!=', $dont_expect, $name); } =item B $Test->like($this, qr/$regex/, $name); $Test->like($this, '/$regex/', $name); Like Test::More's like(). Checks if $this matches the given $regex. You'll want to avoid qr// if you want your tests to work before 5.005. =item B $Test->unlike($this, qr/$regex/, $name); $Test->unlike($this, '/$regex/', $name); Like Test::More's unlike(). Checks if $this B the given $regex. =cut sub like { my($self, $this, $regex, $name) = @_; local $Level = $Level + 1; $self->_regex_ok($this, $regex, '=~', $name); } sub unlike { my($self, $this, $regex, $name) = @_; local $Level = $Level + 1; $self->_regex_ok($this, $regex, '!~', $name); } =item B $Test->maybe_regex(qr/$regex/); $Test->maybe_regex('/$regex/'); Convenience method for building testing functions that take regular expressions as arguments, but need to work before perl 5.005. Takes a quoted regular expression produced by qr//, or a string representing a regular expression. Returns a Perl value which may be used instead of the corresponding regular expression, or undef if it's argument is not recognised. For example, a version of like(), sans the useful diagnostic messages, could be written as: sub laconic_like { my ($self, $this, $regex, $name) = @_; my $usable_regex = $self->maybe_regex($regex); die "expecting regex, found '$regex'\n" unless $usable_regex; $self->ok($this =~ m/$usable_regex/, $name); } =cut sub maybe_regex { my ($self, $regex) = @_; my $usable_regex = undef; return $usable_regex unless defined $regex; my($re, $opts); # Check for qr/foo/ if( ref $regex eq 'Regexp' ) { $usable_regex = $regex; } # Check for '/foo/' or 'm,foo,' elsif( ($re, $opts) = $regex =~ m{^ /(.*)/ (\w*) $ }sx or (undef, $re, $opts) = $regex =~ m,^ m([^\w\s]) (.+) \1 (\w*) $,sx ) { $usable_regex = length $opts ? "(?$opts)$re" : $re; } return $usable_regex; }; sub _regex_ok { my($self, $this, $regex, $cmp, $name) = @_; local $Level = $Level + 1; my $ok = 0; my $usable_regex = $self->maybe_regex($regex); unless (defined $usable_regex) { $ok = $self->ok( 0, $name ); $self->diag(" '$regex' doesn't look much like a regex to me."); return $ok; } { local $^W = 0; my $test = $this =~ /$usable_regex/ ? 1 : 0; $test = !$test if $cmp eq '!~'; $ok = $self->ok( $test, $name ); } unless( $ok ) { $this = defined $this ? "'$this'" : 'undef'; my $match = $cmp eq '=~' ? "doesn't match" : "matches"; $self->diag(sprintf < $Test->cmp_ok($this, $type, $that, $name); Works just like Test::More's cmp_ok(). $Test->cmp_ok($big_num, '!=', $other_big_num); =cut sub cmp_ok { my($self, $got, $type, $expect, $name) = @_; my $test; { local $^W = 0; local($@,$!); # don't interfere with $@ # eval() sometimes resets $! $test = eval "\$got $type \$expect"; } local $Level = $Level + 1; my $ok = $self->ok($test, $name); unless( $ok ) { if( $type =~ /^(eq|==)$/ ) { $self->_is_diag($got, $type, $expect); } else { $self->_cmp_diag($got, $type, $expect); } } return $ok; } sub _cmp_diag { my($self, $got, $type, $expect) = @_; $got = defined $got ? "'$got'" : 'undef'; $expect = defined $expect ? "'$expect'" : 'undef'; return $self->diag(sprintf < $Test->BAILOUT($reason); Indicates to the Test::Harness that things are going so badly all testing should terminate. This includes running any additional test scripts. It will exit with 255. =cut sub BAILOUT { my($self, $reason) = @_; $self->_print("Bail out! $reason"); exit 255; } =item B $Test->skip; $Test->skip($why); Skips the current test, reporting $why. =cut sub skip { my($self, $why) = @_; $why ||= ''; $self->_unoverload(\$why); unless( $self->{Have_Plan} ) { require Carp; Carp::croak("You tried to run tests without a plan! Gotta have a plan."); } lock($self->{Curr_Test}); $self->{Curr_Test}++; $self->{Test_Results}[$self->{Curr_Test}-1] = &share({ 'ok' => 1, actual_ok => 1, name => '', type => 'skip', reason => $why, }); my $out = "ok"; $out .= " $self->{Curr_Test}" if $self->use_numbers; $out .= " # skip"; $out .= " $why" if length $why; $out .= "\n"; $self->_print($out); return 1; } =item B $Test->todo_skip; $Test->todo_skip($why); Like skip(), only it will declare the test as failing and TODO. Similar to print "not ok $tnum # TODO $why\n"; =cut sub todo_skip { my($self, $why) = @_; $why ||= ''; unless( $self->{Have_Plan} ) { require Carp; Carp::croak("You tried to run tests without a plan! Gotta have a plan."); } lock($self->{Curr_Test}); $self->{Curr_Test}++; $self->{Test_Results}[$self->{Curr_Test}-1] = &share({ 'ok' => 1, actual_ok => 0, name => '', type => 'todo_skip', reason => $why, }); my $out = "not ok"; $out .= " $self->{Curr_Test}" if $self->use_numbers; $out .= " # TODO & SKIP $why\n"; $self->_print($out); return 1; } =begin _unimplemented =item B $Test->skip_rest; $Test->skip_rest($reason); Like skip(), only it skips all the rest of the tests you plan to run and terminates the test. If you're running under no_plan, it skips once and terminates the test. =end _unimplemented =back =head2 Test style =over 4 =item B $Test->level($how_high); How far up the call stack should $Test look when reporting where the test failed. Defaults to 1. Setting $Test::Builder::Level overrides. This is typically useful localized: { local $Test::Builder::Level = 2; $Test->ok($test); } =cut sub level { my($self, $level) = @_; if( defined $level ) { $Level = $level; } return $Level; } =item B $Test->use_numbers($on_or_off); Whether or not the test should output numbers. That is, this if true: ok 1 ok 2 ok 3 or this if false ok ok ok Most useful when you can't depend on the test output order, such as when threads or forking is involved. Test::Harness will accept either, but avoid mixing the two styles. Defaults to on. =cut sub use_numbers { my($self, $use_nums) = @_; if( defined $use_nums ) { $self->{Use_Nums} = $use_nums; } return $self->{Use_Nums}; } =item B $Test->no_header($no_header); If set to true, no "1..N" header will be printed. =item B $Test->no_ending($no_ending); Normally, Test::Builder does some extra diagnostics when the test ends. It also changes the exit code as described below. If this is true, none of that will be done. =cut sub no_header { my($self, $no_header) = @_; if( defined $no_header ) { $self->{No_Header} = $no_header; } return $self->{No_Header}; } sub no_ending { my($self, $no_ending) = @_; if( defined $no_ending ) { $self->{No_Ending} = $no_ending; } return $self->{No_Ending}; } =back =head2 Output Controlling where the test output goes. It's ok for your test to change where STDOUT and STDERR point to, Test::Builder's default output settings will not be affected. =over 4 =item B $Test->diag(@msgs); Prints out the given @msgs. Like C, arguments are simply appended together. Normally, it uses the failure_output() handle, but if this is for a TODO test, the todo_output() handle is used. Output will be indented and marked with a # so as not to interfere with test output. A newline will be put on the end if there isn't one already. We encourage using this rather than calling print directly. Returns false. Why? Because diag() is often used in conjunction with a failing test (C) it "passes through" the failure. return ok(...) || diag(...); =for blame transfer Mark Fowler =cut sub diag { my($self, @msgs) = @_; return unless @msgs; # Prevent printing headers when compiling (i.e. -c) return if $^C; # Smash args together like print does. # Convert undef to 'undef' so its readable. my $msg = join '', map { defined($_) ? $_ : 'undef' } @msgs; # Escape each line with a #. $msg =~ s/^/# /gm; # Stick a newline on the end if it needs it. $msg .= "\n" unless $msg =~ /\n\Z/; local $Level = $Level + 1; $self->_print_diag($msg); return 0; } =begin _private =item B<_print> $Test->_print(@msgs); Prints to the output() filehandle. =end _private =cut sub _print { my($self, @msgs) = @_; # Prevent printing headers when only compiling. Mostly for when # tests are deparsed with B::Deparse return if $^C; my $msg = join '', @msgs; local($\, $", $,) = (undef, ' ', ''); my $fh = $self->output; # Escape each line after the first with a # so we don't # confuse Test::Harness. $msg =~ s/\n(.)/\n# $1/sg; # Stick a newline on the end if it needs it. $msg .= "\n" unless $msg =~ /\n\Z/; print $fh $msg; } =item B<_print_diag> $Test->_print_diag(@msg); Like _print, but prints to the current diagnostic filehandle. =cut sub _print_diag { my $self = shift; local($\, $", $,) = (undef, ' ', ''); my $fh = $self->todo ? $self->todo_output : $self->failure_output; print $fh @_; } =item B $Test->output($fh); $Test->output($file); Where normal "ok/not ok" test output should go. Defaults to STDOUT. =item B $Test->failure_output($fh); $Test->failure_output($file); Where diagnostic output on test failures and diag() should go. Defaults to STDERR. =item B $Test->todo_output($fh); $Test->todo_output($file); Where diagnostics about todo test failures and diag() should go. Defaults to STDOUT. =cut sub output { my($self, $fh) = @_; if( defined $fh ) { $self->{Out_FH} = _new_fh($fh); } return $self->{Out_FH}; } sub failure_output { my($self, $fh) = @_; if( defined $fh ) { $self->{Fail_FH} = _new_fh($fh); } return $self->{Fail_FH}; } sub todo_output { my($self, $fh) = @_; if( defined $fh ) { $self->{Todo_FH} = _new_fh($fh); } return $self->{Todo_FH}; } sub _new_fh { my($file_or_fh) = shift; my $fh; if( _is_fh($file_or_fh) ) { $fh = $file_or_fh; } else { $fh = do { local *FH }; open $fh, ">$file_or_fh" or die "Can't open test output log $file_or_fh: $!"; _autoflush($fh); } return $fh; } sub _is_fh { my $maybe_fh = shift; return 1 if ref \$maybe_fh eq 'GLOB'; # its a glob return UNIVERSAL::isa($maybe_fh, 'GLOB') || UNIVERSAL::isa($maybe_fh, 'IO::Handle') || # 5.5.4's tied() and can() doesn't like getting undef UNIVERSAL::can((tied($maybe_fh) || ''), 'TIEHANDLE'); } sub _autoflush { my($fh) = shift; my $old_fh = select $fh; $| = 1; select $old_fh; } sub _dup_stdhandles { my $self = shift; $self->_open_testhandles; # Set everything to unbuffered else plain prints to STDOUT will # come out in the wrong order from our own prints. _autoflush(\*TESTOUT); _autoflush(\*STDOUT); _autoflush(\*TESTERR); _autoflush(\*STDERR); $self->output(\*TESTOUT); $self->failure_output(\*TESTERR); $self->todo_output(\*TESTOUT); } my $Opened_Testhandles = 0; sub _open_testhandles { return if $Opened_Testhandles; # We dup STDOUT and STDERR so people can change them in their # test suites while still getting normal test output. open(TESTOUT, ">&STDOUT") or die "Can't dup STDOUT: $!"; open(TESTERR, ">&STDERR") or die "Can't dup STDERR: $!"; $Opened_Testhandles = 1; } =back =head2 Test Status and Info =over 4 =item B my $curr_test = $Test->current_test; $Test->current_test($num); Gets/sets the current test number we're on. You usually shouldn't have to set this. If set forward, the details of the missing tests are filled in as 'unknown'. if set backward, the details of the intervening tests are deleted. You can erase history if you really want to. =cut sub current_test { my($self, $num) = @_; lock($self->{Curr_Test}); if( defined $num ) { unless( $self->{Have_Plan} ) { require Carp; Carp::croak("Can't change the current test number without a plan!"); } $self->{Curr_Test} = $num; # If the test counter is being pushed forward fill in the details. my $test_results = $self->{Test_Results}; if( $num > @$test_results ) { my $start = @$test_results ? @$test_results : 0; for ($start..$num-1) { $test_results->[$_] = &share({ 'ok' => 1, actual_ok => undef, reason => 'incrementing test number', type => 'unknown', name => undef }); } } # If backward, wipe history. Its their funeral. elsif( $num < @$test_results ) { $#{$test_results} = $num - 1; } } return $self->{Curr_Test}; } =item B my @tests = $Test->summary; A simple summary of the tests so far. True for pass, false for fail. This is a logical pass/fail, so todos are passes. Of course, test #1 is $tests[0], etc... =cut sub summary { my($self) = shift; return map { $_->{'ok'} } @{ $self->{Test_Results} }; } =item B
my @tests = $Test->details; Like summary(), but with a lot more detail. $tests[$test_num - 1] = { 'ok' => is the test considered a pass? actual_ok => did it literally say 'ok'? name => name of the test (if any) type => type of test (if any, see below). reason => reason for the above (if any) }; 'ok' is true if Test::Harness will consider the test to be a pass. 'actual_ok' is a reflection of whether or not the test literally printed 'ok' or 'not ok'. This is for examining the result of 'todo' tests. 'name' is the name of the test. 'type' indicates if it was a special test. Normal tests have a type of ''. Type can be one of the following: skip see skip() todo see todo() todo_skip see todo_skip() unknown see below Sometimes the Test::Builder test counter is incremented without it printing any test output, for example, when current_test() is changed. In these cases, Test::Builder doesn't know the result of the test, so it's type is 'unkown'. These details for these tests are filled in. They are considered ok, but the name and actual_ok is left undef. For example "not ok 23 - hole count # TODO insufficient donuts" would result in this structure: $tests[22] = # 23 - 1, since arrays start from 0. { ok => 1, # logically, the test passed since it's todo actual_ok => 0, # in absolute terms, it failed name => 'hole count', type => 'todo', reason => 'insufficient donuts' }; =cut sub details { my $self = shift; return @{ $self->{Test_Results} }; } =item B my $todo_reason = $Test->todo; my $todo_reason = $Test->todo($pack); todo() looks for a $TODO variable in your tests. If set, all tests will be considered 'todo' (see Test::More and Test::Harness for details). Returns the reason (ie. the value of $TODO) if running as todo tests, false otherwise. todo() is about finding the right package to look for $TODO in. It uses the exported_to() package to find it. If that's not set, it's pretty good at guessing the right package to look at based on $Level. Sometimes there is some confusion about where todo() should be looking for the $TODO variable. If you want to be sure, tell it explicitly what $pack to use. =cut sub todo { my($self, $pack) = @_; $pack = $pack || $self->exported_to || $self->caller($Level); return 0 unless $pack; no strict 'refs'; return defined ${$pack.'::TODO'} ? ${$pack.'::TODO'} : 0; } =item B my $package = $Test->caller; my($pack, $file, $line) = $Test->caller; my($pack, $file, $line) = $Test->caller($height); Like the normal caller(), except it reports according to your level(). =cut sub caller { my($self, $height) = @_; $height ||= 0; my @caller = CORE::caller($self->level + $height + 1); return wantarray ? @caller : $caller[0]; } =back =cut =begin _private =over 4 =item B<_sanity_check> $self->_sanity_check(); Runs a bunch of end of test sanity checks to make sure reality came through ok. If anything is wrong it will die with a fairly friendly error message. =cut #'# sub _sanity_check { my $self = shift; _whoa($self->{Curr_Test} < 0, 'Says here you ran a negative number of tests!'); _whoa(!$self->{Have_Plan} and $self->{Curr_Test}, 'Somehow your tests ran without a plan!'); _whoa($self->{Curr_Test} != @{ $self->{Test_Results} }, 'Somehow you got a different number of results than tests ran!'); } =item B<_whoa> _whoa($check, $description); A sanity check, similar to assert(). If the $check is true, something has gone horribly wrong. It will die with the given $description and a note to contact the author. =cut sub _whoa { my($check, $desc) = @_; if( $check ) { die < _my_exit($exit_num); Perl seems to have some trouble with exiting inside an END block. 5.005_03 and 5.6.1 both seem to do odd things. Instead, this function edits $? directly. It should ONLY be called from inside an END block. It doesn't actually exit, that's your job. =cut sub _my_exit { $? = $_[0]; return 1; } =back =end _private =cut $SIG{__DIE__} = sub { # We don't want to muck with death in an eval, but $^S isn't # totally reliable. 5.005_03 and 5.6.1 both do the wrong thing # with it. Instead, we use caller. This also means it runs under # 5.004! my $in_eval = 0; for( my $stack = 1; my $sub = (CORE::caller($stack))[3]; $stack++ ) { $in_eval = 1 if $sub =~ /^\(eval\)/; } $Test->{Test_Died} = 1 unless $in_eval; }; sub _ending { my $self = shift; $self->_sanity_check(); # Don't bother with an ending if this is a forked copy. Only the parent # should do the ending. # Exit if plan() was never called. This is so "require Test::Simple" # doesn't puke. if( ($self->{Original_Pid} != $$) or (!$self->{Have_Plan} && !$self->{Test_Died}) ) { _my_exit($?); return; } # Figure out if we passed or failed and print helpful messages. my $test_results = $self->{Test_Results}; if( @$test_results ) { # The plan? We have no plan. if( $self->{No_Plan} ) { $self->_print("1..$self->{Curr_Test}\n") unless $self->no_header; $self->{Expected_Tests} = $self->{Curr_Test}; } # Auto-extended arrays and elements which aren't explicitly # filled in with a shared reference will puke under 5.8.0 # ithreads. So we have to fill them in by hand. :( my $empty_result = &share({}); for my $idx ( 0..$self->{Expected_Tests}-1 ) { $test_results->[$idx] = $empty_result unless defined $test_results->[$idx]; } my $num_failed = grep !$_->{'ok'}, @{$test_results}[0..$self->{Expected_Tests}-1]; $num_failed += abs($self->{Expected_Tests} - @$test_results); if( $self->{Curr_Test} < $self->{Expected_Tests} ) { my $s = $self->{Expected_Tests} == 1 ? '' : 's'; $self->diag(<<"FAIL"); Looks like you planned $self->{Expected_Tests} test$s but only ran $self->{Curr_Test}. FAIL } elsif( $self->{Curr_Test} > $self->{Expected_Tests} ) { my $num_extra = $self->{Curr_Test} - $self->{Expected_Tests}; my $s = $self->{Expected_Tests} == 1 ? '' : 's'; $self->diag(<<"FAIL"); Looks like you planned $self->{Expected_Tests} test$s but ran $num_extra extra. FAIL } elsif ( $num_failed ) { my $s = $num_failed == 1 ? '' : 's'; $self->diag(<<"FAIL"); Looks like you failed $num_failed test$s of $self->{Expected_Tests}. FAIL } if( $self->{Test_Died} ) { $self->diag(<<"FAIL"); Looks like your test died just after $self->{Curr_Test}. FAIL _my_exit( 255 ) && return; } _my_exit( $num_failed <= 254 ? $num_failed : 254 ) && return; } elsif ( $self->{Skip_All} ) { _my_exit( 0 ) && return; } elsif ( $self->{Test_Died} ) { $self->diag(<<'FAIL'); Looks like your test died before it could output anything. FAIL _my_exit( 255 ) && return; } else { $self->diag("No tests run!\n"); _my_exit( 255 ) && return; } } END { $Test->_ending if defined $Test and !$Test->no_ending; } =head1 EXIT CODES If all your tests passed, Test::Builder will exit with zero (which is normal). If anything failed it will exit with how many failed. If you run less (or more) tests than you planned, the missing (or extras) will be considered failures. If no tests were ever run Test::Builder will throw a warning and exit with 255. If the test died, even after having successfully completed all its tests, it will still be considered a failure and will exit with 255. So the exit codes are... 0 all tests successful 255 test died any other number how many failed (including missing or extras) If you fail more than 254 tests, it will be reported as 254. =head1 THREADS In perl 5.8.0 and later, Test::Builder is thread-safe. The test number is shared amongst all threads. This means if one thread sets the test number using current_test() they will all be effected. Test::Builder is only thread-aware if threads.pm is loaded I Test::Builder. =head1 EXAMPLES CPAN can provide the best examples. Test::Simple, Test::More, Test::Exception and Test::Differences all use Test::Builder. =head1 SEE ALSO Test::Simple, Test::More, Test::Harness =head1 AUTHORS Original code by chromatic, maintained by Michael G Schwern Eschwern@pobox.comE =head1 COPYRIGHT Copyright 2002, 2004 by chromatic Echromatic@wgz.orgE and Michael G Schwern Eschwern@pobox.comE. This program is free software; you can redistribute it and/or modify it under the same terms as Perl itself. See F =cut 1; libio-compress-lzma-perl-2.093/t/Test/More.pm000066400000000000000000001113531357305603400210130ustar00rootroot00000000000000package Test::More; use 5.004; use strict; use Test::Builder; # Can't use Carp because it might cause use_ok() to accidentally succeed # even though the module being used forgot to use Carp. Yes, this # actually happened. sub _carp { my($file, $line) = (caller(1))[1,2]; warn @_, " at $file line $line\n"; } require Exporter; our ($VERSION, @ISA, @EXPORT, %EXPORT_TAGS, $TODO); $VERSION = '0.60'; $VERSION = eval $VERSION; # make the alpha version come out as a number @ISA = qw(Exporter); @EXPORT = qw(ok use_ok require_ok is isnt like unlike is_deeply cmp_ok skip todo todo_skip pass fail eq_array eq_hash eq_set $TODO plan can_ok isa_ok diag ); my $Test = Test::Builder->new; my $Show_Diag = 1; # 5.004's Exporter doesn't have export_to_level. sub _export_to_level { my $pkg = shift; my $level = shift; (undef) = shift; # redundant arg my $callpkg = caller($level); $pkg->export($callpkg, @_); } =head1 NAME Test::More - yet another framework for writing test scripts =head1 SYNOPSIS use Test::More tests => $Num_Tests; # or use Test::More qw(no_plan); # or use Test::More skip_all => $reason; BEGIN { use_ok( 'Some::Module' ); } require_ok( 'Some::Module' ); # Various ways to say "ok" ok($this eq $that, $test_name); is ($this, $that, $test_name); isnt($this, $that, $test_name); # Rather than print STDERR "# here's what went wrong\n" diag("here's what went wrong"); like ($this, qr/that/, $test_name); unlike($this, qr/that/, $test_name); cmp_ok($this, '==', $that, $test_name); is_deeply($complex_structure1, $complex_structure2, $test_name); SKIP: { skip $why, $how_many unless $have_some_feature; ok( foo(), $test_name ); is( foo(42), 23, $test_name ); }; TODO: { local $TODO = $why; ok( foo(), $test_name ); is( foo(42), 23, $test_name ); }; can_ok($module, @methods); isa_ok($object, $class); pass($test_name); fail($test_name); # UNIMPLEMENTED!!! my @status = Test::More::status; # UNIMPLEMENTED!!! BAIL_OUT($why); =head1 DESCRIPTION B If you're just getting started writing tests, have a look at Test::Simple first. This is a drop in replacement for Test::Simple which you can switch to once you get the hang of basic testing. The purpose of this module is to provide a wide range of testing utilities. Various ways to say "ok" with better diagnostics, facilities to skip tests, test future features and compare complicated data structures. While you can do almost anything with a simple C function, it doesn't provide good diagnostic output. =head2 I love it when a plan comes together Before anything else, you need a testing plan. This basically declares how many tests your script is going to run to protect against premature failure. The preferred way to do this is to declare a plan when you C. use Test::More tests => $Num_Tests; There are rare cases when you will not know beforehand how many tests your script is going to run. In this case, you can declare that you have no plan. (Try to avoid using this as it weakens your test.) use Test::More qw(no_plan); B: using no_plan requires a Test::Harness upgrade else it will think everything has failed. See L) In some cases, you'll want to completely skip an entire testing script. use Test::More skip_all => $skip_reason; Your script will declare a skip with the reason why you skipped and exit immediately with a zero (success). See L for details. If you want to control what functions Test::More will export, you have to use the 'import' option. For example, to import everything but 'fail', you'd do: use Test::More tests => 23, import => ['!fail']; Alternatively, you can use the plan() function. Useful for when you have to calculate the number of tests. use Test::More; plan tests => keys %Stuff * 3; or for deciding between running the tests at all: use Test::More; if( $^O eq 'MacOS' ) { plan skip_all => 'Test irrelevant on MacOS'; } else { plan tests => 42; } =cut sub plan { my(@plan) = @_; my $idx = 0; my @cleaned_plan; while( $idx <= $#plan ) { my $item = $plan[$idx]; if( $item eq 'no_diag' ) { $Show_Diag = 0; } else { push @cleaned_plan, $item; } $idx++; } $Test->plan(@cleaned_plan); } sub import { my($class) = shift; my $caller = caller; $Test->exported_to($caller); my $idx = 0; my @plan; my @imports; while( $idx <= $#_ ) { my $item = $_[$idx]; if( $item eq 'import' ) { push @imports, @{$_[$idx+1]}; $idx++; } else { push @plan, $item; } $idx++; } plan(@plan); __PACKAGE__->_export_to_level(1, __PACKAGE__, @imports); } =head2 Test names By convention, each test is assigned a number in order. This is largely done automatically for you. However, it's often very useful to assign a name to each test. Which would you rather see: ok 4 not ok 5 ok 6 or ok 4 - basic multi-variable not ok 5 - simple exponential ok 6 - force == mass * acceleration The later gives you some idea of what failed. It also makes it easier to find the test in your script, simply search for "simple exponential". All test functions take a name argument. It's optional, but highly suggested that you use it. =head2 I'm ok, you're not ok. The basic purpose of this module is to print out either "ok #" or "not ok #" depending on if a given test succeeded or failed. Everything else is just gravy. All of the following print "ok" or "not ok" depending on if the test succeeded or failed. They all also return true or false, respectively. =over 4 =item B ok($this eq $that, $test_name); This simply evaluates any expression (C<$this eq $that> is just a simple example) and uses that to determine if the test succeeded or failed. A true expression passes, a false one fails. Very simple. For example: ok( $exp{9} == 81, 'simple exponential' ); ok( Film->can('db_Main'), 'set_db()' ); ok( $p->tests == 4, 'saw tests' ); ok( !grep !defined $_, @items, 'items populated' ); (Mnemonic: "This is ok.") $test_name is a very short description of the test that will be printed out. It makes it very easy to find a test in your script when it fails and gives others an idea of your intentions. $test_name is optional, but we B strongly encourage its use. Should an ok() fail, it will produce some diagnostics: not ok 18 - sufficient mucus # Failed test 18 (foo.t at line 42) This is actually Test::Simple's ok() routine. =cut sub ok ($;$) { my($test, $name) = @_; $Test->ok($test, $name); } =item B =item B is ( $this, $that, $test_name ); isnt( $this, $that, $test_name ); Similar to ok(), is() and isnt() compare their two arguments with C and C respectively and use the result of that to determine if the test succeeded or failed. So these: # Is the ultimate answer 42? is( ultimate_answer(), 42, "Meaning of Life" ); # $foo isn't empty isnt( $foo, '', "Got some foo" ); are similar to these: ok( ultimate_answer() eq 42, "Meaning of Life" ); ok( $foo ne '', "Got some foo" ); (Mnemonic: "This is that." "This isn't that.") So why use these? They produce better diagnostics on failure. ok() cannot know what you are testing for (beyond the name), but is() and isnt() know what the test was and why it failed. For example this test: my $foo = 'waffle'; my $bar = 'yarblokos'; is( $foo, $bar, 'Is foo the same as bar?' ); Will produce something like this: not ok 17 - Is foo the same as bar? # Failed test (foo.t at line 139) # got: 'waffle' # expected: 'yarblokos' So you can figure out what went wrong without rerunning the test. You are encouraged to use is() and isnt() over ok() where possible, however do not be tempted to use them to find out if something is true or false! # XXX BAD! is( exists $brooklyn{tree}, 1, 'A tree grows in Brooklyn' ); This does not check if C is true, it checks if it returns 1. Very different. Similar caveats exist for false and 0. In these cases, use ok(). ok( exists $brooklyn{tree}, 'A tree grows in Brooklyn' ); For those grammatical pedants out there, there's an C function which is an alias of isnt(). =cut sub is ($$;$) { $Test->is_eq(@_); } sub isnt ($$;$) { $Test->isnt_eq(@_); } *isn't = \&isnt; =item B like( $this, qr/that/, $test_name ); Similar to ok(), like() matches $this against the regex C. So this: like($this, qr/that/, 'this is like that'); is similar to: ok( $this =~ /that/, 'this is like that'); (Mnemonic "This is like that".) The second argument is a regular expression. It may be given as a regex reference (i.e. C) or (for better compatibility with older perls) as a string that looks like a regex (alternative delimiters are currently not supported): like( $this, '/that/', 'this is like that' ); Regex options may be placed on the end (C<'/that/i'>). Its advantages over ok() are similar to that of is() and isnt(). Better diagnostics on failure. =cut sub like ($$;$) { $Test->like(@_); } =item B unlike( $this, qr/that/, $test_name ); Works exactly as like(), only it checks if $this B match the given pattern. =cut sub unlike ($$;$) { $Test->unlike(@_); } =item B cmp_ok( $this, $op, $that, $test_name ); Halfway between ok() and is() lies cmp_ok(). This allows you to compare two arguments using any binary perl operator. # ok( $this eq $that ); cmp_ok( $this, 'eq', $that, 'this eq that' ); # ok( $this == $that ); cmp_ok( $this, '==', $that, 'this == that' ); # ok( $this && $that ); cmp_ok( $this, '&&', $that, 'this && that' ); ...etc... Its advantage over ok() is when the test fails you'll know what $this and $that were: not ok 1 # Failed test (foo.t at line 12) # '23' # && # undef It's also useful in those cases where you are comparing numbers and is()'s use of C will interfere: cmp_ok( $big_hairy_number, '==', $another_big_hairy_number ); =cut sub cmp_ok($$$;$) { $Test->cmp_ok(@_); } =item B can_ok($module, @methods); can_ok($object, @methods); Checks to make sure the $module or $object can do these @methods (works with functions, too). can_ok('Foo', qw(this that whatever)); is almost exactly like saying: ok( Foo->can('this') && Foo->can('that') && Foo->can('whatever') ); only without all the typing and with a better interface. Handy for quickly testing an interface. No matter how many @methods you check, a single can_ok() call counts as one test. If you desire otherwise, use: foreach my $meth (@methods) { can_ok('Foo', $meth); } =cut sub can_ok ($@) { my($proto, @methods) = @_; my $class = ref $proto || $proto; unless( @methods ) { my $ok = $Test->ok( 0, "$class->can(...)" ); $Test->diag(' can_ok() called with no methods'); return $ok; } my @nok = (); foreach my $method (@methods) { local($!, $@); # don't interfere with caller's $@ # eval sometimes resets $! eval { $proto->can($method) } || push @nok, $method; } my $name; $name = @methods == 1 ? "$class->can('$methods[0]')" : "$class->can(...)"; my $ok = $Test->ok( !@nok, $name ); $Test->diag(map " $class->can('$_') failed\n", @nok); return $ok; } =item B isa_ok($object, $class, $object_name); isa_ok($ref, $type, $ref_name); Checks to see if the given C<< $object->isa($class) >>. Also checks to make sure the object was defined in the first place. Handy for this sort of thing: my $obj = Some::Module->new; isa_ok( $obj, 'Some::Module' ); where you'd otherwise have to write my $obj = Some::Module->new; ok( defined $obj && $obj->isa('Some::Module') ); to safeguard against your test script blowing up. It works on references, too: isa_ok( $array_ref, 'ARRAY' ); The diagnostics of this test normally just refer to 'the object'. If you'd like them to be more specific, you can supply an $object_name (for example 'Test customer'). =cut sub isa_ok ($$;$) { my($object, $class, $obj_name) = @_; my $diag; $obj_name = 'The object' unless defined $obj_name; my $name = "$obj_name isa $class"; if( !defined $object ) { $diag = "$obj_name isn't defined"; } elsif( !ref $object ) { $diag = "$obj_name isn't a reference"; } else { # We can't use UNIVERSAL::isa because we want to honor isa() overrides local($@, $!); # eval sometimes resets $! my $rslt = eval { $object->isa($class) }; if( $@ ) { if( $@ =~ /^Can't call method "isa" on unblessed reference/ ) { if( !UNIVERSAL::isa($object, $class) ) { my $ref = ref $object; $diag = "$obj_name isn't a '$class' it's a '$ref'"; } } else { die <isa on your object and got some weird error. This should never happen. Please contact the author immediately. Here's the error. $@ WHOA } } elsif( !$rslt ) { my $ref = ref $object; $diag = "$obj_name isn't a '$class' it's a '$ref'"; } } my $ok; if( $diag ) { $ok = $Test->ok( 0, $name ); $Test->diag(" $diag\n"); } else { $ok = $Test->ok( 1, $name ); } return $ok; } =item B =item B pass($test_name); fail($test_name); Sometimes you just want to say that the tests have passed. Usually the case is you've got some complicated condition that is difficult to wedge into an ok(). In this case, you can simply use pass() (to declare the test ok) or fail (for not ok). They are synonyms for ok(1) and ok(0). Use these very, very, very sparingly. =cut sub pass (;$) { $Test->ok(1, @_); } sub fail (;$) { $Test->ok(0, @_); } =back =head2 Diagnostics If you pick the right test function, you'll usually get a good idea of what went wrong when it failed. But sometimes it doesn't work out that way. So here we have ways for you to write your own diagnostic messages which are safer than just C. =over 4 =item B diag(@diagnostic_message); Prints a diagnostic message which is guaranteed not to interfere with test output. Like C @diagnostic_message is simply concatinated together. Handy for this sort of thing: ok( grep(/foo/, @users), "There's a foo user" ) or diag("Since there's no foo, check that /etc/bar is set up right"); which would produce: not ok 42 - There's a foo user # Failed test (foo.t at line 52) # Since there's no foo, check that /etc/bar is set up right. You might remember C with the mnemonic C. All diag()s can be made silent by passing the "no_diag" option to Test::More. C 1, 'no_diag'>. This is useful if you have diagnostics for personal testing but then wish to make them silent for release without commenting out each individual statement. B The exact formatting of the diagnostic output is still changing, but it is guaranteed that whatever you throw at it it won't interfere with the test. =cut sub diag { return unless $Show_Diag; $Test->diag(@_); } =back =head2 Module tests You usually want to test if the module you're testing loads ok, rather than just vomiting if its load fails. For such purposes we have C and C. =over 4 =item B BEGIN { use_ok($module); } BEGIN { use_ok($module, @imports); } These simply use the given $module and test to make sure the load happened ok. It's recommended that you run use_ok() inside a BEGIN block so its functions are exported at compile-time and prototypes are properly honored. If @imports are given, they are passed through to the use. So this: BEGIN { use_ok('Some::Module', qw(foo bar)) } is like doing this: use Some::Module qw(foo bar); Version numbers can be checked like so: # Just like "use Some::Module 1.02" BEGIN { use_ok('Some::Module', 1.02) } Don't try to do this: BEGIN { use_ok('Some::Module'); ...some code that depends on the use... ...happening at compile time... } because the notion of "compile-time" is relative. Instead, you want: BEGIN { use_ok('Some::Module') } BEGIN { ...some code that depends on the use... } =cut sub use_ok ($;@) { my($module, @imports) = @_; @imports = () unless @imports; my($pack,$filename,$line) = caller; local($@,$!); # eval sometimes interferes with $! if( @imports == 1 and $imports[0] =~ /^\d+(?:\.\d+)?$/ ) { # probably a version check. Perl needs to see the bare number # for it to work with non-Exporter based modules. eval <ok( !$@, "use $module;" ); unless( $ok ) { chomp $@; $@ =~ s{^BEGIN failed--compilation aborted at .*$} {BEGIN failed--compilation aborted at $filename line $line.}m; $Test->diag(< require_ok($module); require_ok($file); Like use_ok(), except it requires the $module or $file. =cut sub require_ok ($) { my($module) = shift; my $pack = caller; # Try to deterine if we've been given a module name or file. # Module names must be barewords, files not. $module = qq['$module'] unless _is_module_name($module); local($!, $@); # eval sometimes interferes with $! eval <ok( !$@, "require $module;" ); unless( $ok ) { chomp $@; $Test->diag(<. The way Test::More handles this is with a named block. Basically, a block of tests which can be skipped over or made todo. It's best if I just show you... =over 4 =item B SKIP: { skip $why, $how_many if $condition; ...normal testing code goes here... } This declares a block of tests that might be skipped, $how_many tests there are, $why and under what $condition to skip them. An example is the easiest way to illustrate: SKIP: { eval { require HTML::Lint }; skip "HTML::Lint not installed", 2 if $@; my $lint = new HTML::Lint; isa_ok( $lint, "HTML::Lint" ); $lint->parse( $html ); is( $lint->errors, 0, "No errors found in HTML" ); } If the user does not have HTML::Lint installed, the whole block of code I. Test::More will output special ok's which Test::Harness interprets as skipped, but passing, tests. It's important that $how_many accurately reflects the number of tests in the SKIP block so the # of tests run will match up with your plan. If your plan is C $how_many is optional and will default to 1. It's perfectly safe to nest SKIP blocks. Each SKIP block must have the label C, or Test::More can't work its magic. You don't skip tests which are failing because there's a bug in your program, or for which you don't yet have code written. For that you use TODO. Read on. =cut #'# sub skip { my($why, $how_many) = @_; unless( defined $how_many ) { # $how_many can only be avoided when no_plan is in use. _carp "skip() needs to know \$how_many tests are in the block" unless $Test->has_plan eq 'no_plan'; $how_many = 1; } for( 1..$how_many ) { $Test->skip($why); } local $^W = 0; last SKIP; } =item B TODO: { local $TODO = $why if $condition; ...normal testing code goes here... } Declares a block of tests you expect to fail and $why. Perhaps it's because you haven't fixed a bug or haven't finished a new feature: TODO: { local $TODO = "URI::Geller not finished"; my $card = "Eight of clubs"; is( URI::Geller->your_card, $card, 'Is THIS your card?' ); my $spoon; URI::Geller->bend_spoon; is( $spoon, 'bent', "Spoon bending, that's original" ); } With a todo block, the tests inside are expected to fail. Test::More will run the tests normally, but print out special flags indicating they are "todo". Test::Harness will interpret failures as being ok. Should anything succeed, it will report it as an unexpected success. You then know the thing you had todo is done and can remove the TODO flag. The nice part about todo tests, as opposed to simply commenting out a block of tests, is it's like having a programmatic todo list. You know how much work is left to be done, you're aware of what bugs there are, and you'll know immediately when they're fixed. Once a todo test starts succeeding, simply move it outside the block. When the block is empty, delete it. B: TODO tests require a Test::Harness upgrade else it will treat it as a normal failure. See L) =item B TODO: { todo_skip $why, $how_many if $condition; ...normal testing code... } With todo tests, it's best to have the tests actually run. That way you'll know when they start passing. Sometimes this isn't possible. Often a failing test will cause the whole program to die or hang, even inside an C with and using C. In these extreme cases you have no choice but to skip over the broken tests entirely. The syntax and behavior is similar to a C except the tests will be marked as failing but todo. Test::Harness will interpret them as passing. =cut sub todo_skip { my($why, $how_many) = @_; unless( defined $how_many ) { # $how_many can only be avoided when no_plan is in use. _carp "todo_skip() needs to know \$how_many tests are in the block" unless $Test->has_plan eq 'no_plan'; $how_many = 1; } for( 1..$how_many ) { $Test->todo_skip($why); } local $^W = 0; last TODO; } =item When do I use SKIP vs. TODO? B, use SKIP. This includes optional modules that aren't installed, running under an OS that doesn't have some feature (like fork() or symlinks), or maybe you need an Internet connection and one isn't available. B, use TODO. This is for any code you haven't written yet, or bugs you have yet to fix, but want to put tests in your testing script (always a good idea). =back =head2 Complex data structures Not everything is a simple eq check or regex. There are times you need to see if two data structures are equivalent. For these instances Test::More provides a handful of useful functions. B I'm not quite sure what will happen with filehandles. =over 4 =item B is_deeply( $this, $that, $test_name ); Similar to is(), except that if $this and $that are hash or array references, it does a deep comparison walking each data structure to see if they are equivalent. If the two structures are different, it will display the place where they start differing. Test::Differences and Test::Deep provide more in-depth functionality along these lines. =back =cut our (@Data_Stack, %Refs_Seen); my $DNE = bless [], 'Does::Not::Exist'; sub is_deeply { unless( @_ == 2 or @_ == 3 ) { my $msg = <ok(0); } my($this, $that, $name) = @_; my $ok; if( !ref $this and !ref $that ) { # neither is a reference $ok = $Test->is_eq($this, $that, $name); } elsif( !ref $this xor !ref $that ) { # one's a reference, one isn't $ok = $Test->ok(0, $name); $Test->diag( _format_stack({ vals => [ $this, $that ] }) ); } else { # both references local @Data_Stack = (); if( _deep_check($this, $that) ) { $ok = $Test->ok(1, $name); } else { $ok = $Test->ok(0, $name); $Test->diag(_format_stack(@Data_Stack)); } } return $ok; } sub _format_stack { my(@Stack) = @_; my $var = '$FOO'; my $did_arrow = 0; foreach my $entry (@Stack) { my $type = $entry->{type} || ''; my $idx = $entry->{'idx'}; if( $type eq 'HASH' ) { $var .= "->" unless $did_arrow++; $var .= "{$idx}"; } elsif( $type eq 'ARRAY' ) { $var .= "->" unless $did_arrow++; $var .= "[$idx]"; } elsif( $type eq 'REF' ) { $var = "\${$var}"; } } my @vals = @{$Stack[-1]{vals}}[0,1]; my @vars = (); ($vars[0] = $var) =~ s/\$FOO/ \$got/; ($vars[1] = $var) =~ s/\$FOO/\$expected/; my $out = "Structures begin differing at:\n"; foreach my $idx (0..$#vals) { my $val = $vals[$idx]; $vals[$idx] = !defined $val ? 'undef' : $val eq $DNE ? "Does not exist" : ref $val ? "$val" : "'$val'"; } $out .= "$vars[0] = $vals[0]\n"; $out .= "$vars[1] = $vals[1]\n"; $out =~ s/^/ /msg; return $out; } sub _type { my $thing = shift; return '' if !ref $thing; for my $type (qw(ARRAY HASH REF SCALAR GLOB Regexp)) { return $type if UNIVERSAL::isa($thing, $type); } return ''; } =head2 Discouraged comparison functions The use of the following functions is discouraged as they are not actually testing functions and produce no diagnostics to help figure out what went wrong. They were written before is_deeply() existed because I couldn't figure out how to display a useful diff of two arbitrary data structures. These functions are usually used inside an ok(). ok( eq_array(\@this, \@that) ); C can do that better and with diagnostics. is_deeply( \@this, \@that ); They may be deprecated in future versions. =over 4 =item B my $is_eq = eq_array(\@this, \@that); Checks if two arrays are equivalent. This is a deep check, so multi-level structures are handled correctly. =cut #'# sub eq_array { local @Data_Stack; _deep_check(@_); } sub _eq_array { my($a1, $a2) = @_; if( grep !_type($_) eq 'ARRAY', $a1, $a2 ) { warn "eq_array passed a non-array ref"; return 0; } return 1 if $a1 eq $a2; my $ok = 1; my $max = $#$a1 > $#$a2 ? $#$a1 : $#$a2; for (0..$max) { my $e1 = $_ > $#$a1 ? $DNE : $a1->[$_]; my $e2 = $_ > $#$a2 ? $DNE : $a2->[$_]; push @Data_Stack, { type => 'ARRAY', idx => $_, vals => [$e1, $e2] }; $ok = _deep_check($e1,$e2); pop @Data_Stack if $ok; last unless $ok; } return $ok; } sub _deep_check { my($e1, $e2) = @_; my $ok = 0; # Effectively turn %Refs_Seen into a stack. This avoids picking up # the same referenced used twice (such as [\$a, \$a]) to be considered # circular. local %Refs_Seen = %Refs_Seen; { # Quiet uninitialized value warnings when comparing undefs. local $^W = 0; $Test->_unoverload(\$e1, \$e2); # Either they're both references or both not. my $same_ref = !(!ref $e1 xor !ref $e2); my $not_ref = (!ref $e1 and !ref $e2); if( defined $e1 xor defined $e2 ) { $ok = 0; } elsif ( $e1 == $DNE xor $e2 == $DNE ) { $ok = 0; } elsif ( $same_ref and ($e1 eq $e2) ) { $ok = 1; } elsif ( $not_ref ) { push @Data_Stack, { type => '', vals => [$e1, $e2] }; $ok = 0; } else { if( $Refs_Seen{$e1} ) { return $Refs_Seen{$e1} eq $e2; } else { $Refs_Seen{$e1} = "$e2"; } my $type = _type($e1); $type = 'DIFFERENT' unless _type($e2) eq $type; if( $type eq 'DIFFERENT' ) { push @Data_Stack, { type => $type, vals => [$e1, $e2] }; $ok = 0; } elsif( $type eq 'ARRAY' ) { $ok = _eq_array($e1, $e2); } elsif( $type eq 'HASH' ) { $ok = _eq_hash($e1, $e2); } elsif( $type eq 'REF' ) { push @Data_Stack, { type => $type, vals => [$e1, $e2] }; $ok = _deep_check($$e1, $$e2); pop @Data_Stack if $ok; } elsif( $type eq 'SCALAR' ) { push @Data_Stack, { type => 'REF', vals => [$e1, $e2] }; $ok = _deep_check($$e1, $$e2); pop @Data_Stack if $ok; } else { _whoa(1, "No type in _deep_check"); } } } return $ok; } sub _whoa { my($check, $desc) = @_; if( $check ) { die < my $is_eq = eq_hash(\%this, \%that); Determines if the two hashes contain the same keys and values. This is a deep check. =cut sub eq_hash { local @Data_Stack; return _deep_check(@_); } sub _eq_hash { my($a1, $a2) = @_; if( grep !_type($_) eq 'HASH', $a1, $a2 ) { warn "eq_hash passed a non-hash ref"; return 0; } return 1 if $a1 eq $a2; my $ok = 1; my $bigger = keys %$a1 > keys %$a2 ? $a1 : $a2; foreach my $k (keys %$bigger) { my $e1 = exists $a1->{$k} ? $a1->{$k} : $DNE; my $e2 = exists $a2->{$k} ? $a2->{$k} : $DNE; push @Data_Stack, { type => 'HASH', idx => $k, vals => [$e1, $e2] }; $ok = _deep_check($e1, $e2); pop @Data_Stack if $ok; last unless $ok; } return $ok; } =item B my $is_eq = eq_set(\@this, \@that); Similar to eq_array(), except the order of the elements is B important. This is a deep check, but the irrelevancy of order only applies to the top level. ok( eq_set(\@this, \@that) ); Is better written: is_deeply( [sort @this], [sort @that] ); B By historical accident, this is not a true set comparision. While the order of elements does not matter, duplicate elements do. Test::Deep contains much better set comparison functions. =cut sub eq_set { my($a1, $a2) = @_; return 0 unless @$a1 == @$a2; # There's faster ways to do this, but this is easiest. local $^W = 0; # We must make sure that references are treated neutrally. It really # doesn't matter how we sort them, as long as both arrays are sorted # with the same algorithm. # Have to inline the sort routine due to a threading/sort bug. # See [rt.cpan.org 6782] return eq_array( [sort { ref $a ? -1 : ref $b ? 1 : $a cmp $b } @$a1], [sort { ref $a ? -1 : ref $b ? 1 : $a cmp $b } @$a2] ); } =back =head2 Extending and Embedding Test::More Sometimes the Test::More interface isn't quite enough. Fortunately, Test::More is built on top of Test::Builder which provides a single, unified backend for any test library to use. This means two test libraries which both use Test::Builder B. If you simply want to do a little tweaking of how the tests behave, you can access the underlying Test::Builder object like so: =over 4 =item B my $test_builder = Test::More->builder; Returns the Test::Builder object underlying Test::More for you to play with. =cut sub builder { return Test::Builder->new; } =back =head1 EXIT CODES If all your tests passed, Test::Builder will exit with zero (which is normal). If anything failed it will exit with how many failed. If you run less (or more) tests than you planned, the missing (or extras) will be considered failures. If no tests were ever run Test::Builder will throw a warning and exit with 255. If the test died, even after having successfully completed all its tests, it will still be considered a failure and will exit with 255. So the exit codes are... 0 all tests successful 255 test died any other number how many failed (including missing or extras) If you fail more than 254 tests, it will be reported as 254. B This behavior may go away in future versions. =head1 CAVEATS and NOTES =over 4 =item Backwards compatibility Test::More works with Perls as old as 5.004_05. =item Overloaded objects String overloaded objects are compared B. This prevents Test::More from piercing an object's interface allowing better blackbox testing. So if a function starts returning overloaded objects instead of bare strings your tests won't notice the difference. This is good. However, it does mean that functions like is_deeply() cannot be used to test the internals of string overloaded objects. In this case I would suggest Test::Deep which contains more flexible testing functions for complex data structures. =item Threads Test::More will only be aware of threads if "use threads" has been done I Test::More is loaded. This is ok: use threads; use Test::More; This may cause problems: use Test::More use threads; =item Test::Harness upgrade no_plan and todo depend on new Test::Harness features and fixes. If you're going to distribute tests that use no_plan or todo your end-users will have to upgrade Test::Harness to the latest one on CPAN. If you avoid no_plan and TODO tests, the stock Test::Harness will work fine. Installing Test::More should also upgrade Test::Harness. =back =head1 HISTORY This is a case of convergent evolution with Joshua Pritikin's Test module. I was largely unaware of its existence when I'd first written my own ok() routines. This module exists because I can't figure out how to easily wedge test names into Test's interface (along with a few other problems). The goal here is to have a testing utility that's simple to learn, quick to use and difficult to trip yourself up with while still providing more flexibility than the existing Test.pm. As such, the names of the most common routines are kept tiny, special cases and magic side-effects are kept to a minimum. WYSIWYG. =head1 SEE ALSO L if all this confuses you and you just want to write some tests. You can upgrade to Test::More later (it's forward compatible). L is the old testing module. Its main benefit is that it has been distributed with Perl since 5.004_05. L for details on how your test results are interpreted by Perl. L for more ways to test complex data structures. And it plays well with Test::More. L is like XUnit but more perlish. L gives you more powerful complex data structure testing. L is XUnit style testing. L shows the idea of embedded testing. L installs a whole bunch of useful test modules. =head1 AUTHORS Michael G Schwern Eschwern@pobox.comE with much inspiration from Joshua Pritikin's Test module and lots of help from Barrie Slaymaker, Tony Bowden, blackstar.co.uk, chromatic, Fergal Daly and the perl-qa gang. =head1 BUGS See F to report and view bugs. =head1 COPYRIGHT Copyright 2001, 2002, 2004 by Michael G Schwern Eschwern@pobox.comE. This program is free software; you can redistribute it and/or modify it under the same terms as Perl itself. See F =cut 1; libio-compress-lzma-perl-2.093/t/Test/Simple.pm000066400000000000000000000147031357305603400213430ustar00rootroot00000000000000package Test::Simple; use 5.004; use strict 'vars'; our ($VERSION); $VERSION = '0.60'; $VERSION = eval $VERSION; # make the alpha version come out as a number use Test::Builder; my $Test = Test::Builder->new; sub import { my $self = shift; my $caller = caller; *{$caller.'::ok'} = \&ok; $Test->exported_to($caller); $Test->plan(@_); } =head1 NAME Test::Simple - Basic utilities for writing tests. =head1 SYNOPSIS use Test::Simple tests => 1; ok( $foo eq $bar, 'foo is bar' ); =head1 DESCRIPTION ** If you are unfamiliar with testing B first! ** This is an extremely simple, extremely basic module for writing tests suitable for CPAN modules and other pursuits. If you wish to do more complicated testing, use the Test::More module (a drop-in replacement for this one). The basic unit of Perl testing is the ok. For each thing you want to test your program will print out an "ok" or "not ok" to indicate pass or fail. You do this with the ok() function (see below). The only other constraint is you must pre-declare how many tests you plan to run. This is in case something goes horribly wrong during the test and your test program aborts, or skips a test or whatever. You do this like so: use Test::Simple tests => 23; You must have a plan. =over 4 =item B ok( $foo eq $bar, $name ); ok( $foo eq $bar ); ok() is given an expression (in this case C<$foo eq $bar>). If it's true, the test passed. If it's false, it didn't. That's about it. ok() prints out either "ok" or "not ok" along with a test number (it keeps track of that for you). # This produces "ok 1 - Hell not yet frozen over" (or not ok) ok( get_temperature($hell) > 0, 'Hell not yet frozen over' ); If you provide a $name, that will be printed along with the "ok/not ok" to make it easier to find your test when if fails (just search for the name). It also makes it easier for the next guy to understand what your test is for. It's highly recommended you use test names. All tests are run in scalar context. So this: ok( @stuff, 'I have some stuff' ); will do what you mean (fail if stuff is empty) =cut sub ok ($;$) { $Test->ok(@_); } =back Test::Simple will start by printing number of tests run in the form "1..M" (so "1..5" means you're going to run 5 tests). This strange format lets Test::Harness know how many tests you plan on running in case something goes horribly wrong. If all your tests passed, Test::Simple will exit with zero (which is normal). If anything failed it will exit with how many failed. If you run less (or more) tests than you planned, the missing (or extras) will be considered failures. If no tests were ever run Test::Simple will throw a warning and exit with 255. If the test died, even after having successfully completed all its tests, it will still be considered a failure and will exit with 255. So the exit codes are... 0 all tests successful 255 test died any other number how many failed (including missing or extras) If you fail more than 254 tests, it will be reported as 254. This module is by no means trying to be a complete testing system. It's just to get you started. Once you're off the ground its recommended you look at L. =head1 EXAMPLE Here's an example of a simple .t file for the fictional Film module. use Test::Simple tests => 5; use Film; # What you're testing. my $btaste = Film->new({ Title => 'Bad Taste', Director => 'Peter Jackson', Rating => 'R', NumExplodingSheep => 1 }); ok( defined($btaste) && ref $btaste eq 'Film, 'new() works' ); ok( $btaste->Title eq 'Bad Taste', 'Title() get' ); ok( $btaste->Director eq 'Peter Jackson', 'Director() get' ); ok( $btaste->Rating eq 'R', 'Rating() get' ); ok( $btaste->NumExplodingSheep == 1, 'NumExplodingSheep() get' ); It will produce output like this: 1..5 ok 1 - new() works ok 2 - Title() get ok 3 - Director() get not ok 4 - Rating() get # Failed test (t/film.t at line 14) ok 5 - NumExplodingSheep() get # Looks like you failed 1 tests of 5 Indicating the Film::Rating() method is broken. =head1 CAVEATS Test::Simple will only report a maximum of 254 failures in its exit code. If this is a problem, you probably have a huge test script. Split it into multiple files. (Otherwise blame the Unix folks for using an unsigned short integer as the exit status). Because VMS's exit codes are much, much different than the rest of the universe, and perl does horrible mangling to them that gets in my way, it works like this on VMS. 0 SS$_NORMAL all tests successful 4 SS$_ABORT something went wrong Unfortunately, I can't differentiate any further. =head1 NOTES Test::Simple is B tested all the way back to perl 5.004. Test::Simple is thread-safe in perl 5.8.0 and up. =head1 HISTORY This module was conceived while talking with Tony Bowden in his kitchen one night about the problems I was having writing some really complicated feature into the new Testing module. He observed that the main problem is not dealing with these edge cases but that people hate to write tests B. What was needed was a dead simple module that took all the hard work out of testing and was really, really easy to learn. Paul Johnson simultaneously had this idea (unfortunately, he wasn't in Tony's kitchen). This is it. =head1 SEE ALSO =over 4 =item L More testing functions! Once you outgrow Test::Simple, look at Test::More. Test::Simple is 100% forward compatible with Test::More (i.e. you can just use Test::More instead of Test::Simple in your programs and things will still work). =item L The original Perl testing module. =item L Elaborate unit testing. =item L, L Embed tests in your code! =item L Interprets the output of your test program. =back =head1 AUTHORS Idea by Tony Bowden and Paul Johnson, code by Michael G Schwern Eschwern@pobox.comE, wardrobe by Calvin Klein. =head1 COPYRIGHT Copyright 2001, 2002, 2004 by Michael G Schwern Eschwern@pobox.comE. This program is free software; you can redistribute it and/or modify it under the same terms as Perl itself. See F =cut 1; libio-compress-lzma-perl-2.093/t/compress/000077500000000000000000000000001357305603400204635ustar00rootroot00000000000000libio-compress-lzma-perl-2.093/t/compress/CompTestUtils.pm000066400000000000000000000464301357305603400236070ustar00rootroot00000000000000package CompTestUtils; package main ; use strict ; use warnings; use bytes; #use lib qw(t t/compress); use Carp ; #use Test::More ; sub title { #diag "" ; ok(1, $_[0]) ; #diag "" ; } sub like_eval { like $@, @_ ; } BEGIN { eval { require File::Temp; } ; } { package LexFile ; our ($index); $index = '00000'; sub new { my $self = shift ; foreach (@_) { Carp::croak "NO!!!!" if defined $_; # autogenerate the name if none supplied $_ = "tst" . $$ . "X" . $index ++ . ".tmp" unless defined $_; } chmod 0777, @_; for (@_) { 1 while unlink $_ } ; bless [ @_ ], $self ; } sub DESTROY { my $self = shift ; chmod 0777, @{ $self } ; for (@$self) { 1 while unlink $_ } ; } } { package LexDir ; use File::Path; our ($index); $index = '00000'; our ($useTempFile); our ($useTempDir); sub new { my $self = shift ; if ( $useTempDir) { foreach (@_) { Carp::croak "NO!!!!" if defined $_; $_ = File::Temp->newdir(DIR => '.'); # Subsequent manipulations assume Unix syntax, metacharacters, etc. if ($^O eq 'VMS') { $_->{DIRNAME} = VMS::Filespec::unixify($_->{DIRNAME}); $_->{DIRNAME} =~ s/\/$//; } } bless [ @_ ], $self ; } elsif ( $useTempFile) { foreach (@_) { Carp::croak "NO!!!!" if defined $_; $_ = File::Temp::tempdir(DIR => '.', CLEANUP => 1); # Subsequent manipulations assume Unix syntax, metacharacters, etc. if ($^O eq 'VMS') { $_ = VMS::Filespec::unixify($_); $_ =~ s/\/$//; } } bless [ @_ ], $self ; } else { foreach (@_) { Carp::croak "NO!!!!" if defined $_; # autogenerate the name if none supplied $_ = "tmpdir" . $$ . "X" . $index ++ . ".tmp" ; } foreach (@_) { rmtree $_, {verbose => 0, safe => 1} if -d $_; mkdir $_, 0777 } bless [ @_ ], $self ; } } sub DESTROY { if (! $useTempFile) { my $self = shift ; foreach (@$self) { rmtree $_, {verbose => 0, safe => 1} if -d $_ ; } } } } sub readFile { my $f = shift ; my @strings ; if (IO::Compress::Base::Common::isaFilehandle($f)) { my $pos = tell($f); seek($f, 0,0); @strings = <$f> ; seek($f, 0, $pos); } else { open (F, "<$f") or croak "Cannot open $f: $!\n" ; binmode F; @strings = ; close F ; } return @strings if wantarray ; return join "", @strings ; } sub touch { foreach (@_) { writeFile($_, '') } } sub writeFile { my($filename, @strings) = @_ ; 1 while unlink $filename ; open (F, ">$filename") or croak "Cannot open $filename: $!\n" ; binmode F; foreach (@strings) { no warnings ; print F $_ ; } close F ; } sub GZreadFile { my ($filename) = shift ; my ($uncomp) = "" ; my $line = "" ; my $fil = gzopen($filename, "rb") or croak "Cannopt open '$filename': $Compress::Zlib::gzerrno" ; $uncomp .= $line while $fil->gzread($line) > 0; $fil->gzclose ; return $uncomp ; } sub hexDump { my $d = shift ; if (IO::Compress::Base::Common::isaFilehandle($d)) { $d = readFile($d); } elsif (IO::Compress::Base::Common::isaFilename($d)) { $d = readFile($d); } else { $d = $$d ; } my $offset = 0 ; $d = '' unless defined $d ; #while (read(STDIN, $data, 16)) { while (my $data = substr($d, 0, 16)) { substr($d, 0, 16) = '' ; printf "# %8.8lx ", $offset; $offset += 16; my @array = unpack('C*', $data); foreach (@array) { printf('%2.2x ', $_); } print " " x (16 - @array) if @array < 16 ; $data =~ tr/\0-\37\177-\377/./; print " $data\n"; } } sub readHeaderInfo { my $name = shift ; my %opts = @_ ; my $string = <write($string) ; ok $x->close ; #is GZreadFile($name), $string ; ok my $gunz = new IO::Uncompress::Gunzip $name, Strict => 0 or diag "GunzipError is $IO::Uncompress::Gunzip::GunzipError" ; ok my $hdr = $gunz->getHeaderInfo(); my $uncomp ; ok $gunz->read($uncomp) ; ok $uncomp eq $string; ok $gunz->close ; return $hdr ; } sub cmpFile { my ($filename, $uue) = @_ ; return readFile($filename) eq unpack("u", $uue) ; } #sub isRawFormat #{ # my $class = shift; # # TODO -- add Lzma here? # my %raw = map { $_ => 1 } qw( RawDeflate ); # # return defined $raw{$class}; #} my %TOP = ( 'IO::Uncompress::AnyInflate' => { Inverse => 'IO::Compress::Gzip', Error => 'AnyInflateError', TopLevel => 'anyinflate', Raw => 0, }, 'IO::Uncompress::AnyUncompress' => { Inverse => 'IO::Compress::Gzip', Error => 'AnyUncompressError', TopLevel => 'anyuncompress', Raw => 0, }, 'IO::Compress::Gzip' => { Inverse => 'IO::Uncompress::Gunzip', Error => 'GzipError', TopLevel => 'gzip', Raw => 0, }, 'IO::Uncompress::Gunzip' => { Inverse => 'IO::Compress::Gzip', Error => 'GunzipError', TopLevel => 'gunzip', Raw => 0, }, 'IO::Compress::Deflate' => { Inverse => 'IO::Uncompress::Inflate', Error => 'DeflateError', TopLevel => 'deflate', Raw => 0, }, 'IO::Uncompress::Inflate' => { Inverse => 'IO::Compress::Deflate', Error => 'InflateError', TopLevel => 'inflate', Raw => 0, }, 'IO::Compress::RawDeflate' => { Inverse => 'IO::Uncompress::RawInflate', Error => 'RawDeflateError', TopLevel => 'rawdeflate', Raw => 1, }, 'IO::Uncompress::RawInflate' => { Inverse => 'IO::Compress::RawDeflate', Error => 'RawInflateError', TopLevel => 'rawinflate', Raw => 1, }, 'IO::Compress::Zip' => { Inverse => 'IO::Uncompress::Unzip', Error => 'ZipError', TopLevel => 'zip', Raw => 0, }, 'IO::Uncompress::Unzip' => { Inverse => 'IO::Compress::Zip', Error => 'UnzipError', TopLevel => 'unzip', Raw => 0, }, 'IO::Compress::Bzip2' => { Inverse => 'IO::Uncompress::Bunzip2', Error => 'Bzip2Error', TopLevel => 'bzip2', Raw => 0, }, 'IO::Uncompress::Bunzip2' => { Inverse => 'IO::Compress::Bzip2', Error => 'Bunzip2Error', TopLevel => 'bunzip2', Raw => 0, }, 'IO::Compress::Lzop' => { Inverse => 'IO::Uncompress::UnLzop', Error => 'LzopError', TopLevel => 'lzop', Raw => 0, }, 'IO::Uncompress::UnLzop' => { Inverse => 'IO::Compress::Lzop', Error => 'UnLzopError', TopLevel => 'unlzop', Raw => 0, }, 'IO::Compress::Lzf' => { Inverse => 'IO::Uncompress::UnLzf', Error => 'LzfError', TopLevel => 'lzf', Raw => 0, }, 'IO::Uncompress::UnLzf' => { Inverse => 'IO::Compress::Lzf', Error => 'UnLzfError', TopLevel => 'unlzf', Raw => 0, }, 'IO::Compress::Lzma' => { Inverse => 'IO::Uncompress::UnLzma', Error => 'LzmaError', TopLevel => 'lzma', Raw => 1, }, 'IO::Uncompress::UnLzma' => { Inverse => 'IO::Compress::Lzma', Error => 'UnLzmaError', TopLevel => 'unlzma', Raw => 1, }, 'IO::Compress::Xz' => { Inverse => 'IO::Uncompress::UnXz', Error => 'XzError', TopLevel => 'xz', Raw => 0, }, 'IO::Uncompress::UnXz' => { Inverse => 'IO::Compress::Xz', Error => 'UnXzError', TopLevel => 'unxz', Raw => 0, }, 'IO::Compress::Lzip' => { Inverse => 'IO::Uncompress::UnLzip', Error => 'LzipError', TopLevel => 'lzip', Raw => 0, }, 'IO::Uncompress::UnLzip' => { Inverse => 'IO::Compress::Lzip', Error => 'UnLzipError', TopLevel => 'unlzip', Raw => 0, }, 'IO::Compress::PPMd' => { Inverse => 'IO::Uncompress::UnPPMd', Error => 'PPMdError', TopLevel => 'ppmd', Raw => 0, }, 'IO::Uncompress::UnPPMd' => { Inverse => 'IO::Compress::PPMd', Error => 'UnPPMdError', TopLevel => 'unppmd', Raw => 0, }, 'IO::Compress::Zstd' => { Inverse => 'IO::Uncompress::UnZstd', Error => 'ZstdError', TopLevel => 'zstd', Raw => 0, }, 'IO::Uncompress::UnZstd' => { Inverse => 'IO::Compress::Zstd', Error => 'UnZstdError', TopLevel => 'unzstd', Raw => 0, }, 'IO::Compress::DummyComp' => { Inverse => 'IO::Uncompress::DummyUnComp', Error => 'DummyCompError', TopLevel => 'dummycomp', Raw => 0, }, 'IO::Uncompress::DummyUnComp' => { Inverse => 'IO::Compress::DummyComp', Error => 'DummyUnCompError', TopLevel => 'dummyunComp', Raw => 0, }, ); for my $key (keys %TOP) { no strict; no warnings; $TOP{$key}{Error} = \${ $key . '::' . $TOP{$key}{Error} }; $TOP{$key}{TopLevel} = $key . '::' . $TOP{$key}{TopLevel} ; # Silence used once warning in really old perl my $dummy = \${ $key . '::' . $TOP{$key}{Error} }; #$TOP{$key . "::" . $TOP{$key}{TopLevel} } = $TOP{$key}; } sub uncompressBuffer { my $compWith = shift ; my $buffer = shift ; my $out ; my $obj = $TOP{$compWith}{Inverse}->new( \$buffer, -Append => 1); 1 while $obj->read($out) > 0 ; return $out ; } sub getInverse { my $class = shift ; return $TOP{$class}{Inverse}; } sub getErrorRef { my $class = shift ; return $TOP{$class}{Error}; } sub getTopFuncRef { my $class = shift ; die "Cannot find $class" if ! defined $TOP{$class}{TopLevel}; return \&{ $TOP{$class}{TopLevel} } ; } sub getTopFuncName { my $class = shift ; return $TOP{$class}{TopLevel} ; } sub compressBuffer { my $compWith = shift ; my $buffer = shift ; my $out ; die "Cannot find $compWith" if ! defined $TOP{$compWith}{Inverse}; my $obj = $TOP{$compWith}{Inverse}->new( \$out); $obj->write($buffer) ; $obj->close(); return $out ; } our ($AnyUncompressError); BEGIN { eval ' use IO::Uncompress::AnyUncompress qw(anyuncompress $AnyUncompressError); '; } sub anyUncompress { my $buffer = shift ; my $already = shift; my @opts = (); if (ref $buffer && ref $buffer eq 'ARRAY') { @opts = @$buffer; $buffer = shift @opts; } if (ref $buffer) { croak "buffer is undef" unless defined $$buffer; croak "buffer is empty" unless length $$buffer; } my $data ; if (IO::Compress::Base::Common::isaFilehandle($buffer)) { $data = readFile($buffer); } elsif (IO::Compress::Base::Common::isaFilename($buffer)) { $data = readFile($buffer); } else { $data = $$buffer ; } if (defined $already && length $already) { my $got = substr($data, 0, length($already)); substr($data, 0, length($already)) = ''; is $got, $already, ' Already OK' ; } my $out = ''; my $o = new IO::Uncompress::AnyUncompress \$data, Append => 1, Transparent => 0, RawInflate => 1, UnLzma => 1, @opts or croak "Cannot open buffer/file: $AnyUncompressError" ; 1 while $o->read($out) > 0 ; croak "Error uncompressing -- " . $o->error() if $o->error() ; return $out ; } sub getHeaders { my $buffer = shift ; my $already = shift; my @opts = (); if (ref $buffer && ref $buffer eq 'ARRAY') { @opts = @$buffer; $buffer = shift @opts; } if (ref $buffer) { croak "buffer is undef" unless defined $$buffer; croak "buffer is empty" unless length $$buffer; } my $data ; if (IO::Compress::Base::Common::isaFilehandle($buffer)) { $data = readFile($buffer); } elsif (IO::Compress::Base::Common::isaFilename($buffer)) { $data = readFile($buffer); } else { $data = $$buffer ; } if (defined $already && length $already) { my $got = substr($data, 0, length($already)); substr($data, 0, length($already)) = ''; is $got, $already, ' Already OK' ; } my $out = ''; my $o = new IO::Uncompress::AnyUncompress \$data, MultiStream => 1, Append => 1, Transparent => 0, RawInflate => 1, UnLzma => 1, @opts or croak "Cannot open buffer/file: $AnyUncompressError" ; 1 while $o->read($out) > 0 ; croak "Error uncompressing -- " . $o->error() if $o->error() ; return ($o->getHeaderInfo()) ; } sub mkComplete { my $class = shift ; my $data = shift; my $Error = getErrorRef($class); my $buffer ; my %params = (); if ($class eq 'IO::Compress::Gzip') { %params = ( Name => "My name", Comment => "a comment", ExtraField => ['ab' => "extra"], HeaderCRC => 1); } elsif ($class eq 'IO::Compress::Zip'){ %params = ( Name => "My name", Comment => "a comment", ZipComment => "last comment", exTime => [100, 200, 300], ExtraFieldLocal => ["ab" => "extra1"], ExtraFieldCentral => ["cd" => "extra2"], ); } my $z = new $class( \$buffer, %params) or croak "Cannot create $class object: $$Error"; $z->write($data); $z->close(); my $unc = getInverse($class); anyUncompress(\$buffer) eq $data or die "bad bad bad"; my $u = new $unc( \$buffer); my $info = $u->getHeaderInfo() ; return wantarray ? ($info, $buffer) : $buffer ; } sub mkErr { my $string = shift ; my ($dummy, $file, $line) = caller ; -- $line ; $file = quotemeta($file); #return "/$string\\s+at $file line $line/" if $] >= 5.006 ; return "/$string\\s+at /" ; } sub mkEvalErr { my $string = shift ; #return "/$string\\s+at \\(eval /" if $] > 5.006 ; return "/$string\\s+at /" ; } sub dumpObj { my $obj = shift ; my ($dummy, $file, $line) = caller ; if (@_) { print "#\n# dumpOBJ from $file line $line @_\n" ; } else { print "#\n# dumpOBJ from $file line $line \n" ; } my $max = 0 ;; foreach my $k (keys %{ *$obj }) { $max = length $k if length $k > $max ; } foreach my $k (sort keys %{ *$obj }) { my $v = $obj->{$k} ; $v = '-undef-' unless defined $v; my $pad = ' ' x ($max - length($k) + 2) ; print "# $k$pad: [$v]\n"; } print "#\n" ; } sub getMultiValues { my $class = shift ; return (0,0) if $class =~ /lzf|lzma|zstd/i; return (1,0); } sub gotScalarUtilXS { eval ' use Scalar::Util "dualvar" '; return $@ ? 0 : 1 ; } package CompTestUtils; 1; __END__ t/Test/Builder.pm t/Test/More.pm t/Test/Simple.pm t/compress/CompTestUtils.pm t/compress/any.pl t/compress/anyunc.pl t/compress/destroy.pl t/compress/generic.pl t/compress/merge.pl t/compress/multi.pl t/compress/newtied.pl t/compress/oneshot.pl t/compress/prime.pl t/compress/tied.pl t/compress/truncate.pl t/compress/zlib-generic.plParsing config.in... Building Zlib enabled Auto Detect Gzip OS Code.. Setting Gzip OS Code to 3 [Unix/Default] Looks Good. libio-compress-lzma-perl-2.093/t/compress/any.pl000066400000000000000000000057451357305603400216220ustar00rootroot00000000000000 use lib 't'; use strict; use warnings; use bytes; use Test::More ; use CompTestUtils; BEGIN { # use Test::NoWarnings, if available my $extra = 0 ; $extra = 1 if eval { require Test::NoWarnings ; import Test::NoWarnings; 1 }; plan tests => 48 + $extra ; } sub run { my $CompressClass = identify(); my $AnyClass = getClass(); my $UncompressClass = getInverse($CompressClass); my $Error = getErrorRef($CompressClass); my $UnError = getErrorRef($UncompressClass); my @anyUnLz = (); @anyUnLz = (UnLzma => 1 ) if $CompressClass =~ /lzma/i ; my $AnyConstruct = "IO::Uncompress::${AnyClass}" ; no strict 'refs'; my $AnyError = \${ "IO::Uncompress::${AnyClass}::${AnyClass}Error" }; for my $trans ( 0, 1 ) { for my $file ( 0, 1 ) { title "$AnyClass(Transparent => $trans, File=>$file) with $CompressClass" ; my $string = "some text" x 100 ; my $buffer ; my $x = new $CompressClass(\$buffer) ; ok $x, " create $CompressClass object" ; ok $x->write($string), " write to object" ; ok $x->close, " close ok" ; my $lex = new LexFile my $output; my $input ; if ($file) { writeFile($output, $buffer); $input = $output; } else { $input = \$buffer; } { my $unc = new $AnyConstruct $input, Transparent => $trans, RawInflate => 1, @anyUnLz, Append => 1 ; ok $unc, " Created $AnyClass object" or print "# $$AnyError\n"; my $uncomp ; 1 while $unc->read($uncomp) > 0 ; #ok $unc->read($uncomp) > 0 # or print "# $$AnyError\n"; my $y; is $unc->read($y, 1), 0, " at eof" ; ok $unc->eof(), " at eof" ; #ok $unc->type eq $Type; is $uncomp, $string, " expected output" ; } { my $unc = new $AnyConstruct $input, Transparent => $trans, RawInflate => 1, @anyUnLz, Append => 1 ; ok $unc, " Created $AnyClass object" or print "# $$AnyError\n"; my $uncomp ; 1 while $unc->read($uncomp, 100) > 0 ; #ok $unc->read($uncomp) > 0 # or print "# $$AnyError\n"; my $y; is $unc->read($y, 1), 0, " at eof" ; ok $unc->eof(), " at eof" ; #ok $unc->type eq $Type; is $uncomp, $string, " expected output" ; } } } } 1; libio-compress-lzma-perl-2.093/t/compress/anyunc.pl000066400000000000000000000051351357305603400223210ustar00rootroot00000000000000 use lib 't'; use strict; use warnings; use bytes; use Test::More ; use CompTestUtils; BEGIN { # use Test::NoWarnings, if available my $extra = 0 ; $extra = 1 if eval { require Test::NoWarnings ; import Test::NoWarnings; 1 }; plan tests => 36 + $extra ; } sub run { my $CompressClass = identify(); my $AnyClass = getClass(); my $UncompressClass = getInverse($CompressClass); my $Error = getErrorRef($CompressClass); my $UnError = getErrorRef($UncompressClass); my $AnyConstruct = "IO::Uncompress::${AnyClass}" ; no strict refs; my $AnyError = \${ "IO::Uncompress::${AnyClass}::${AnyClass}Error" }; for my $trans ( 0, 1 ) { for my $file ( 0, 1 ) { title "$AnyClass(Transparent => $trans, File=>$file) with $CompressClass" ; my $string = "some text" x 100 ; my $buffer ; my $x = new $CompressClass(\$buffer) ; ok $x, " create $CompressClass object" ; ok $x->write($string), " write to object" ; ok $x->close, " close ok" ; my $lex = new LexFile my $output; my $input ; if ($file) { writeFile($output, $buffer); $input = $output; } else { $input = \$buffer; } { my $unc = new $AnyConstruct $input, Transparent => $trans Append => 1 ; ok $unc, " Created $AnyClass object" or print "# $$AnyError\n"; my $uncomp ; 1 while $unc->read($uncomp) > 0 ; #ok $unc->read($uncomp) > 0 # or print "# $$AnyError\n"; my $y; is $unc->read($y, 1), 0, " at eof" ; ok $unc->eof(), " at eof" ; #ok $unc->type eq $Type; is $uncomp, $string, " expected output" ; } { my $unc = new $AnyConstruct $input, Transparent => $trans, Append =>1 ; ok $unc, " Created $AnyClass object" or print "# $$AnyError\n"; my $uncomp ; 1 while $unc->read($uncomp, 10) > 0 ; my $y; is $unc->read($y, 1), 0, " at eof" ; ok $unc->eof(), " at eof" ; #ok $unc->type eq $Type; is $uncomp, $string, " expected output" ; } } } } 1; libio-compress-lzma-perl-2.093/t/compress/destroy.pl000066400000000000000000000044321357305603400225140ustar00rootroot00000000000000 use lib 't'; use strict; use warnings; use bytes; use Test::More ; use CompTestUtils; BEGIN { plan(skip_all => "Destroy not supported in Perl $]") if $] == 5.008 || ( $] >= 5.005 && $] < 5.006) ; # use Test::NoWarnings, if available my $extra = 0 ; $extra = 1 if eval { require Test::NoWarnings ; import Test::NoWarnings; 1 }; plan tests => 15 + $extra ; use_ok('IO::File') ; } sub run { my $CompressClass = identify(); my $UncompressClass = getInverse($CompressClass); my $Error = getErrorRef($CompressClass); my $UnError = getErrorRef($UncompressClass); title "Testing $CompressClass"; { # Check that the class destructor will call close my $lex = new LexFile my $name ; my $hello = < 1 ; ok $x->write($hello) ; } is anyUncompress($name), $hello ; } { # Tied filehandle destructor my $lex = new LexFile my $name ; my $hello = < $name" ; { ok my $x = new $CompressClass $fh, -AutoClose => 1 ; $x->write($hello) ; } ok anyUncompress($name) eq $hello ; } { title "Testing DESTROY doesn't clobber \$! etc "; my $lex = new LexFile my $name ; my $out; my $result; { ok my $z = new $CompressClass($name); $z->write("abc") ; $! = 22 ; cmp_ok $!, '==', 22, ' $! is 22'; } cmp_ok $!, '==', 22, " \$! has not been changed by $CompressClass destructor"; { my $uncomp; ok my $x = new $UncompressClass($name, -Append => 1) ; my $len ; 1 while ($len = $x->read($result)) > 0 ; $! = 22 ; cmp_ok $!, '==', 22, ' $! is 22'; } cmp_ok $!, '==', 22, " \$! has not been changed by $UncompressClass destructor"; is $result, "abc", " Got uncompressed content ok"; } } 1; libio-compress-lzma-perl-2.093/t/compress/encode.pl000066400000000000000000000113701357305603400222570ustar00rootroot00000000000000 use strict; use warnings; use bytes; use Test::More ; use CompTestUtils; BEGIN { plan skip_all => "Encode is not available" if $] < 5.006 ; eval { require Encode; Encode->import(); }; plan skip_all => "Encode is not available" if $@ ; # use Test::NoWarnings, if available my $extra = 0 ; my $st = eval { require Test::NoWarnings ; import Test::NoWarnings; 1; }; $extra = 1 if $st ; plan(tests => 29 + $extra) ; } sub run { my $CompressClass = identify(); my $UncompressClass = getInverse($CompressClass); my $Error = getErrorRef($CompressClass); my $UnError = getErrorRef($UncompressClass); my $string = "\x{df}\x{100}\x80"; my $encString = Encode::encode_utf8($string); my $buffer = $encString; #for my $from ( qw(filename filehandle buffer) ) { # my $input ; # my $lex = new LexFile my $name ; # # # if ($from eq 'buffer') # { $input = \$buffer } # elsif ($from eq 'filename') # { # $input = $name ; # writeFile($name, $buffer); # } # elsif ($from eq 'filehandle') # { # $input = new IO::File "<$name" ; # } for my $to ( qw(filehandle buffer)) { title "OO Mode: To $to, Encode by hand"; my $lex2 = new LexFile my $name2 ; my $output; my $buffer; if ($to eq 'buffer') { $output = \$buffer } elsif ($to eq 'filename') { $output = $name2 ; } elsif ($to eq 'filehandle') { $output = new IO::File ">$name2" ; } my $out ; my $cs = new $CompressClass($output, AutoClose =>1); $cs->print($encString); $cs->close(); my $input; if ($to eq 'buffer') { $input = \$buffer } else { $input = $name2 ; } my $ucs = new $UncompressClass($input, Append => 1); my $got; 1 while $ucs->read($got) > 0 ; is $got, $encString, " Expected output"; my $decode = Encode::decode_utf8($got); is $decode, $string, " Expected output"; } } { title "Catch wide characters"; my $out; my $cs = new $CompressClass(\$out); my $a = "a\xFF\x{100}"; eval { $cs->syswrite($a) }; like($@, qr/Wide character in ${CompressClass}::write/, " wide characters in ${CompressClass}::write"); } { title "Unknown encoding"; my $output; eval { my $cs = new $CompressClass(\$output, Encode => 'fred'); } ; like($@, qr/${CompressClass}: Encoding 'fred' is not available/, " Encoding 'fred' is not available"); } { title "Encode option"; for my $to ( qw(filehandle filename buffer)) { title "Encode: To $to, Encode option"; my $lex2 = new LexFile my $name2 ; my $output; my $buffer; if ($to eq 'buffer') { $output = \$buffer } elsif ($to eq 'filename') { $output = $name2 ; } elsif ($to eq 'filehandle') { $output = new IO::File ">$name2" ; } my $out ; my $cs = new $CompressClass($output, AutoClose =>1, Encode => 'utf8'); ok $cs->print($string); ok $cs->close(); my $input; if ($to eq 'buffer') { $input = \$buffer } elsif ($to eq 'filename') { $input = $name2 ; } else { $input = new IO::File "<$name2" ; } { my $ucs = new $UncompressClass($input, AutoClose =>1, Append => 1); my $got; 1 while $ucs->read($got) > 0 ; ok length($got) > 0; is $got, $encString, " Expected output"; my $decode = Encode::decode_utf8($got); is $decode, $string, " Expected output"; } # { # my $ucs = new $UncompressClass($input, Append => 1, Decode => 'utf8'); # my $got; # 1 while $ucs->read($got) > 0 ; # ok length($got) > 0; # is $got, $string, " Expected output"; # } } } } 1; libio-compress-lzma-perl-2.093/t/compress/generic.pl000066400000000000000000001502221357305603400224360ustar00rootroot00000000000000 use strict; use warnings; use bytes; use Test::More ; use IO::Handle qw(SEEK_SET SEEK_CUR SEEK_END); use CompTestUtils; our ($UncompressClass); BEGIN { # use Test::NoWarnings, if available my $extra = 0 ; my $st = eval { require Test::NoWarnings ; import Test::NoWarnings; 1; }; $extra = 1 if $st ; plan(tests => 799 + $extra) ; } sub myGZreadFile { my $filename = shift ; my $init = shift ; my $fil = new $UncompressClass $filename, -Strict => 0, -Append => 1 ; my $data = ''; $data = $init if defined $init ; 1 while $fil->read($data) > 0; $fil->close ; return $data ; } sub run { my $CompressClass = identify(); $UncompressClass = getInverse($CompressClass); my $Error = getErrorRef($CompressClass); my $UnError = getErrorRef($UncompressClass); if(1) { title "Testing $CompressClass Errors"; # Buffer not writable eval qq[\$a = new $CompressClass(\\1) ;] ; like $@, mkEvalErr("^$CompressClass: output buffer is read-only") ; my($out, $gz); my $x ; $gz = new $CompressClass(\$x); foreach my $name (qw(read readline getc)) { eval " \$gz->$name() " ; like $@, mkEvalErr("^$name Not Available: File opened only for output"); } eval ' $gz->write({})' ; like $@, mkEvalErr("^${CompressClass}::write: not a scalar reference"); eval ' $gz->syswrite("abc", 1, 5)' ; like $@, mkEvalErr("^${CompressClass}::write: offset outside string"); eval ' $gz->syswrite("abc", 1, -4)' ; like $@, mkEvalErr("^${CompressClass}::write: offset outside string"), "write outside string"; } { title "Testing $UncompressClass Errors"; my $out = "" ; my $lex = new LexFile my $name ; ok ! -e $name, " $name does not exist"; $a = new $UncompressClass "$name" ; is $a, undef; my $gc ; my $guz = new $CompressClass(\$gc); $guz->write("abc") ; $guz->close(); my $x ; my $gz = new $UncompressClass(\$gc); foreach my $name (qw(print printf write)) { eval " \$gz->$name() " ; like $@, mkEvalErr("^$name Not Available: File opened only for intput"); } } { title "Testing $CompressClass and $UncompressClass"; { my ($a, $x, @x) = ("","","") ; # Buffer not a scalar reference eval qq[\$a = new $CompressClass \\\@x ;] ; like $@, mkEvalErr("^$CompressClass: output parameter not a filename, filehandle or scalar ref"); # Buffer not a scalar reference eval qq[\$a = new $UncompressClass \\\@x ;] ; like $@, mkEvalErr("^$UncompressClass: input parameter not a filename, filehandle, array ref or scalar ref"); } foreach my $Type ( $CompressClass, $UncompressClass) { # Check error handling with IO::Compress::Deflate and IO::Uncompress::Inflate my ($a, $x, @x) = ("","","") ; # Odd number of parameters eval qq[\$a = new $Type "abc", -Output ] ; like $@, mkEvalErr("^$Type: Expected even number of parameters, got 1"); # Unknown parameter eval qq[\$a = new $Type "anc", -Fred => 123 ;] ; like $@, mkEvalErr("^$Type: unknown key value\\(s\\) Fred"); # no in or out param eval qq[\$a = new $Type ;] ; like $@, mkEvalErr("^$Type: Missing (Input|Output) parameter"); } { # write a very simple compressed file # and read back #======================================== my $lex = new LexFile my $name ; my $hello = <autoflush(1), 0, "autoflush"; is $x->autoflush(1), 1, "autoflush"; ok $x->opened(), "opened"; ok $x->write($hello), "write" ; ok $x->flush(), "flush"; ok $x->close, "close" ; ok ! $x->opened(), "! opened"; } { my $uncomp; ok my $x = new $UncompressClass $name, -Append => 1 ; ok $x->opened(), "opened"; my $len ; 1 while ($len = $x->read($uncomp)) > 0 ; is $len, 0, "read returned 0" or diag $$UnError ; ok $x->close ; is $uncomp, $hello ; ok !$x->opened(), "! opened"; } } { # write a very simple compressed file # and read back #======================================== my $lex = new LexFile my $name ; my $hello = <write(''), 0, "Write empty string is ok"; is $x->write(undef), 0, "Write undef is ok"; ok $x->write($hello), "Write ok" ; ok $x->close, "Close ok" ; } { my $uncomp; my $x = new $UncompressClass $name ; ok $x, "creates $UncompressClass $name" ; my $data = ''; $data .= $uncomp while $x->read($uncomp) > 0 ; ok $x->close, "close ok" ; is $data, $hello, "expected output" ; } } { # write a very simple file with using an IO filehandle # and read back #======================================== my $lex = new LexFile my $name ; my $hello = <$name" ; ok $fh, "opened file $name ok"; my $x = new $CompressClass $fh ; ok $x, " created $CompressClass $fh" ; is $x->fileno(), fileno($fh), "fileno match" ; is $x->write(''), 0, "Write empty string is ok"; is $x->write(undef), 0, "Write undef is ok"; ok $x->write($hello), "write ok" ; ok $x->flush(), "flush"; ok $x->close,"close" ; $fh->close() ; } my $uncomp; { my $x ; ok my $fh1 = new IO::File "<$name" ; ok $x = new $UncompressClass $fh1, -Append => 1 ; ok $x->fileno() == fileno $fh1 ; 1 while $x->read($uncomp) > 0 ; ok $x->close ; } ok $hello eq $uncomp ; } { # write a very simple file with using a glob filehandle # and read back #======================================== my $lex = new LexFile my $name ; #my $name = "/tmp/fred"; my $hello = <$name" ; my $x = new $CompressClass *FH ; ok $x, " create $CompressClass" ; is $x->fileno(), fileno(*FH), " fileno" ; is $x->write(''), 0, " Write empty string is ok"; is $x->write(undef), 0, " Write undef is ok"; ok $x->write($hello), " Write ok" ; ok $x->flush(), " Flush"; ok $x->close, " Close" ; close FH; } my $uncomp; { title "$UncompressClass: Input from typeglob filehandle, append output"; my $x ; ok open FH, "<$name" ; ok $x = new $UncompressClass *FH, -Append => 1, Transparent => 0 or diag $$UnError ; is $x->fileno(), fileno FH, " fileno ok" ; 1 while $x->read($uncomp) > 0 ; ok $x->close, " close" ; close FH; } is $uncomp, $hello, " expected output" ; } { my $lex = new LexFile my $name ; #my $name = "/tmp/fred"; my $hello = <&STDOUT"); my $dummy = fileno SAVEOUT; open STDOUT, ">$name" ; my $x = new $CompressClass '-' ; $x->write($hello); $x->close; open(STDOUT, ">&SAVEOUT"); ok 1, " wrote to stdout" ; } is myGZreadFile($name), $hello, " wrote OK"; #hexDump($name); { title "Input from stdin via filename '-'"; my $x ; my $uncomp ; my $stdinFileno = fileno(STDIN); # open below doesn't return 1 sometimes on XP open(SAVEIN, "<&STDIN"); ok open(STDIN, "<$name"), " redirect STDIN"; my $dummy = fileno SAVEIN; $x = new $UncompressClass '-', Append => 1, Transparent => 0 or diag $$UnError ; ok $x, " created object" ; is $x->fileno(), $stdinFileno, " fileno ok" ; 1 while $x->read($uncomp) > 0 ; ok $x->close, " close" ; open(STDIN, "<&SAVEIN"); is $uncomp, $hello, " expected output" ; } } { # write a compressed file to memory # and read back #======================================== #my $name = "test.gz" ; my $lex = new LexFile my $name ; my $hello = <autoflush(1) ; ok ! defined $x->autoflush(1) ; ok ! defined $x->fileno() ; is $x->write(''), 0, "Write empty string is ok"; is $x->write(undef), 0, "Write undef is ok"; ok $x->write($hello) ; ok $x->flush(); ok $x->close ; writeFile($name, $buffer) ; #is anyUncompress(\$buffer), $hello, " any ok"; } my $keep = $buffer ; my $uncomp; { my $x ; ok $x = new $UncompressClass(\$buffer, Append => 1) ; ok ! defined $x->autoflush(1) ; ok ! defined $x->autoflush(1) ; ok ! defined $x->fileno() ; 1 while $x->read($uncomp) > 0 ; ok $x->close, "closed" ; } is $uncomp, $hello, "got expected uncompressed data" ; ok $buffer eq $keep, "compressed input not changed" ; } if ($CompressClass ne 'RawDeflate') { # write empty file #======================================== my $buffer = ''; { my $x ; $x = new $CompressClass(\$buffer); ok $x, "new $CompressClass" ; ok $x->close, "close ok" ; } my $keep = $buffer ; my $uncomp= ''; { my $x ; ok $x = new $UncompressClass(\$buffer, Append => 1) ; 1 while $x->read($uncomp) > 0 ; ok $x->close ; } ok $uncomp eq '' ; ok $buffer eq $keep ; } { # write a larger file #======================================== my $lex = new LexFile my $name ; my $hello = <write($hello), " write ok" ; $input .= $hello ; ok $x->write("another line"), " write ok" ; $input .= "another line" ; # all characters foreach (0 .. 255) { $contents .= chr int $_ } # generate a long random string foreach (1 .. 5000) { $contents .= chr int rand 256 } ok $x->write($contents), " write ok" ; $input .= $contents ; ok $x->close, " close ok" ; } ok myGZreadFile($name) eq $input ; my $x = readFile($name) ; #print "length " . length($x) . " \n"; } SKIP: { # embed a compressed file in another file #================================ skip "zstd doesn't support trailing data", 11 if $CompressClass =~ /zstd/i ; my $lex = new LexFile my $name ; my $hello = <$name" ; print $fh $header ; my $x ; ok $x = new $CompressClass $fh, -AutoClose => 0 ; ok $x->binmode(); ok $x->write($hello) ; ok $x->close ; print $fh $trailer ; $fh->close() ; } my ($fil, $uncomp) ; my $fh1 ; ok $fh1 = new IO::File "<$name" ; # skip leading junk my $line = <$fh1> ; ok $line eq $header ; ok my $x = new $UncompressClass $fh1, Append => 1 ; ok $x->binmode(); 1 while $x->read($uncomp) > 0 ; is $uncomp, $hello ; my $rest ; read($fh1, $rest, 5000); is $x->trailingData() . $rest, $trailer ; #print "# [".$x->trailingData() . "][$rest]\n" ; } SKIP: { # embed a compressed file in another buffer #================================ skip "zstd doesn't support trailing data", 6 if $CompressClass =~ /zstd/i ; my $hello = <write($hello) ; ok $x->close ; $compressed .= $trailer ; } my $uncomp; ok my $x = new $UncompressClass(\$compressed, Append => 1) ; 1 while $x->read($uncomp) > 0 ; ok $uncomp eq $hello ; is $x->trailingData(), $trailer ; } { # Write # these tests come almost 100% from IO::String my $lex = new LexFile my $name ; my $io = $CompressClass->new($name); is $io->tell(), 0, " tell returns 0"; ; my $heisan = "Heisan\n"; $io->print($heisan) ; ok ! $io->eof(), " ! eof"; is $io->tell(), length($heisan), " tell is " . length($heisan) ; $io->print("a", "b", "c"); { local($\) = "\n"; $io->print("d", "e"); local($,) = ","; $io->print("f", "g", "h"); } { local($\) ; $io->print("D", "E"); local($,) = "."; $io->print("F", "G", "H"); } my $foo = "1234567890"; is $io->syswrite($foo, length($foo)), length($foo), " syswrite ok" ; if ( $] < 5.6 ) { is $io->syswrite($foo, length $foo), length $foo, " syswrite ok" } else { is $io->syswrite($foo), length $foo, " syswrite ok" } is $io->syswrite($foo, length($foo)), length $foo, " syswrite ok"; is $io->write($foo, length($foo), 5), 5, " write 5"; is $io->write("xxx\n", 100, -1), 1, " write 1"; for (1..3) { $io->printf("i(%d)", $_); $io->printf("[%d]\n", $_); } $io->print("\n"); $io->close ; ok $io->eof(), " eof"; is myGZreadFile($name), "Heisan\nabcde\nf,g,h\nDEF.G.H" . ("1234567890" x 3) . "67890\n" . "i(1)[1]\ni(2)[2]\ni(3)[3]\n\n", "myGZreadFile ok"; } { # Read my $str = <input_line_number, undef; $iow->print($str) ; is $iow->input_line_number, undef; $iow->close ; my @tmp; my $buf; { my $io = new $UncompressClass $name ; is $., 0; is $io->input_line_number, 0; ok ! $io->eof, "eof"; is $io->tell(), 0, "tell 0" ; #my @lines = <$io>; my @lines = $io->getlines(); is @lines, 6 or print "# Got " . scalar(@lines) . " lines, expected 6\n" ; is $lines[1], "of a paragraph\n" ; is join('', @lines), $str ; is $., 6; is $io->input_line_number, 6; is $io->tell(), length($str) ; ok $io->eof; ok ! ( defined($io->getline) || (@tmp = $io->getlines) || defined($io->getline) || defined($io->getc) || $io->read($buf, 100) != 0) ; } { local $/; # slurp mode my $io = $UncompressClass->new($name); is $., 0, "line 0"; is $io->input_line_number, 0; ok ! $io->eof, "eof"; my @lines = $io->getlines; is $., 1, "line 1"; is $io->input_line_number, 1, "line number 1"; ok $io->eof, "eof" ; ok @lines == 1 && $lines[0] eq $str; $io = $UncompressClass->new($name); ok ! $io->eof; my $line = $io->getline(); ok $line eq $str; ok $io->eof; } { local $/ = ""; # paragraph mode my $io = $UncompressClass->new($name); is $., 0; is $io->input_line_number, 0; ok ! $io->eof; my @lines = $io->getlines(); is $., 2; is $io->input_line_number, 2; ok $io->eof; ok @lines == 2 or print "# Got " . scalar(@lines) . " lines, expected 2\n" ; ok $lines[0] eq "This is an example\nof a paragraph\n\n\n" or print "# $lines[0]\n"; ok $lines[1] eq "and a single line.\n\n"; } { # Record mode my $reclen = 7 ; my $expected_records = int(length($str) / $reclen) + (length($str) % $reclen ? 1 : 0); local $/ = \$reclen; my $io = $UncompressClass->new($name); is $., 0; is $io->input_line_number, 0; ok ! $io->eof; my @lines = $io->getlines(); is $., $expected_records; is $io->input_line_number, $expected_records; ok $io->eof; is @lines, $expected_records, "Got $expected_records records\n" ; ok $lines[0] eq substr($str, 0, $reclen) or print "# $lines[0]\n"; ok $lines[1] eq substr($str, $reclen, $reclen); } { local $/ = "is"; my $io = $UncompressClass->new($name); my @lines = (); my $no = 0; my $err = 0; ok ! $io->eof; while (my $a = $io->getline()) { push(@lines, $a); $err++ if $. != ++$no; } ok $err == 0 ; ok $io->eof; is $., 3; is $io->input_line_number, 3; ok @lines == 3 or print "# Got " . scalar(@lines) . " lines, expected 3\n" ; ok join("-", @lines) eq "This- is- an example\n" . "of a paragraph\n\n\n" . "and a single line.\n\n"; } # Test read { my $io = $UncompressClass->new($name); eval { $io->read(1) } ; like $@, mkErr("buffer parameter is read-only"); $buf = "abcd"; is $io->read($buf, 0), 0, "Requested 0 bytes" ; is $buf, "", "Buffer empty"; is $io->read($buf, 3), 3 ; is $buf, "Thi"; is $io->sysread($buf, 3, 2), 3 ; is $buf, "Ths i" or print "# [$buf]\n" ;; ok ! $io->eof; $buf = "ab" ; is $io->read($buf, 3, 4), 3 ; is $buf, "ab" . "\x00" x 2 . "s a" or print "# [$buf]\n" ;; ok ! $io->eof; # read the rest of the file $buf = ''; my $remain = length($str) - 9; is $io->read($buf, $remain+1), $remain ; is $buf, substr($str, 9); ok $io->eof; $buf = "hello"; is $io->read($buf, 10), 0 ; is $buf, "", "Buffer empty"; ok $io->eof; ok $io->close(); $buf = "hello"; is $io->read($buf, 10), 0 ; is $buf, "hello", "Buffer not empty"; ok $io->eof; # $io->seek(-4, 2); # # ok ! $io->eof; # # ok read($io, $buf, 20) == 4 ; # ok $buf eq "e.\n\n"; # # ok read($io, $buf, 20) == 0 ; # ok $buf eq ""; # # ok ! $io->eof; } } { # Read from non-compressed file my $str = < 1 ; isa_ok $io, $UncompressClass ; ok ! $io->eof, "eof"; is $io->tell(), 0, "tell == 0" ; my @lines = $io->getlines(); is @lines, 6, "got 6 lines"; ok $lines[1] eq "of a paragraph\n" ; ok join('', @lines) eq $str ; is $., 6; is $io->input_line_number, 6; ok $io->tell() == length($str) ; ok $io->eof; ok ! ( defined($io->getline) || (@tmp = $io->getlines) || defined($io->getline) || defined($io->getc) || $io->read($buf, 100) != 0) ; } { local $/; # slurp mode my $io = $UncompressClass->new($name); ok ! $io->eof; my @lines = $io->getlines; is $., 1; is $io->input_line_number, 1; ok $io->eof; ok @lines == 1 && $lines[0] eq $str; $io = $UncompressClass->new($name); ok ! $io->eof; my $line = $io->getline; is $., 1; is $io->input_line_number, 1; is $line, $str; ok $io->eof; } { local $/ = ""; # paragraph mode my $io = $UncompressClass->new($name); ok ! $io->eof; my @lines = $io->getlines; is $., 2; is $io->input_line_number, 2; ok $io->eof; ok @lines == 2 or print "# expected 2 lines, got " . scalar(@lines) . "\n"; ok $lines[0] eq "This is an example\nof a paragraph\n\n\n" or print "# [$lines[0]]\n" ; ok $lines[1] eq "and a single line.\n\n"; } { # Record mode my $reclen = 7 ; my $expected_records = int(length($str) / $reclen) + (length($str) % $reclen ? 1 : 0); local $/ = \$reclen; my $io = $UncompressClass->new($name); is $., 0; is $io->input_line_number, 0; ok ! $io->eof; my @lines = $io->getlines(); is $., $expected_records; is $io->input_line_number, $expected_records; ok $io->eof; is @lines, $expected_records, "Got $expected_records records\n" ; ok $lines[0] eq substr($str, 0, $reclen) or print "# $lines[0]\n"; ok $lines[1] eq substr($str, $reclen, $reclen); } { local $/ = "is"; my $io = $UncompressClass->new($name); my @lines = (); my $no = 0; my $err = 0; ok ! $io->eof; while (my $a = $io->getline) { push(@lines, $a); $err++ if $. != ++$no; } is $., 3; is $io->input_line_number, 3; ok $err == 0 ; ok $io->eof; ok @lines == 3 ; ok join("-", @lines) eq "This- is- an example\n" . "of a paragraph\n\n\n" . "and a single line.\n\n"; } # Test Read { my $io = $UncompressClass->new($name); $buf = "abcd"; is $io->read($buf, 0), 0, "Requested 0 bytes" ; is $buf, "", "Buffer empty"; ok $io->read($buf, 3) == 3 ; ok $buf eq "Thi"; ok $io->sysread($buf, 3, 2) == 3 ; ok $buf eq "Ths i"; ok ! $io->eof; $buf = "ab" ; is $io->read($buf, 3, 4), 3 ; is $buf, "ab" . "\x00" x 2 . "s a" or print "# [$buf]\n" ;; ok ! $io->eof; # read the rest of the file $buf = ''; my $remain = length($str) - 9; is $io->read($buf, $remain), $remain ; is $buf, substr($str, 9); ok $io->eof; $buf = "hello"; is $io->read($buf, 10), 0 ; is $buf, "", "Buffer empty"; ok $io->eof; ok $io->close(); $buf = "hello"; is $io->read($buf, 10), 0 ; is $buf, "hello", "Buffer not empty"; ok $io->eof; # $io->seek(-4, 2); # # ok ! $io->eof; # # ok read($io, $buf, 20) == 4 ; # ok $buf eq "e.\n\n"; # # ok read($io, $buf, 20) == 0 ; # ok $buf eq ""; # # ok ! $io->eof; } } { # Vary the length parameter in a read my $str = <print($str) ; $iow->close ; } my $io = $UncompressClass->new($name, -Append => $append, -Transparent => $trans); my $buf; is $io->tell(), 0; if ($append) { 1 while $io->read($buf, $bufsize) > 0; } else { my $tmp ; $buf .= $tmp while $io->read($tmp, $bufsize) > 0 ; } is length $buf, length $str; ok $buf eq $str ; ok ! $io->error() ; ok $io->eof; } } } } foreach my $file (0, 1) { foreach my $trans (0, 1) { title "seek tests - file $file trans $trans" ; my $buffer ; my $buff ; my $lex = new LexFile my $name ; my $first = "beginning" ; my $last = "the end" ; if ($trans) { $buffer = $first . "\x00" x 10 . $last; writeFile($name, $buffer); } else { my $output ; if ($file) { $output = $name ; } else { $output = \$buffer; } my $iow = new $CompressClass $output ; $iow->print($first) ; ok $iow->seek(5, SEEK_CUR) ; ok $iow->tell() == length($first)+5; ok $iow->seek(0, SEEK_CUR) ; ok $iow->tell() == length($first)+5; ok $iow->seek(length($first)+10, SEEK_SET) ; ok $iow->tell() == length($first)+10; $iow->print($last) ; $iow->close ; } my $input ; if ($file) { $input = $name ; } else { $input = \$buffer ; } ok myGZreadFile($input) eq $first . "\x00" x 10 . $last ; my $io = $UncompressClass->new($input, Strict => 1); ok $io->seek(length($first), SEEK_CUR) or diag $$UnError ; ok ! $io->eof; is $io->tell(), length($first); ok $io->read($buff, 5) ; is $buff, "\x00" x 5 ; is $io->tell(), length($first) + 5; ok $io->seek(0, SEEK_CUR) ; my $here = $io->tell() ; is $here, length($first)+5; ok $io->seek($here+5, SEEK_SET) ; is $io->tell(), $here+5 ; ok $io->read($buff, 100) ; ok $buff eq $last ; ok $io->eof; } } { title "seek error cases" ; my $b ; my $a = new $CompressClass(\$b) ; ok ! $a->error() or die $a->error() ; eval { $a->seek(-1, 10) ; }; like $@, mkErr("^${CompressClass}::seek: unknown value, 10, for whence parameter"); eval { $a->seek(-1, SEEK_END) ; }; like $@, mkErr("^${CompressClass}::seek: cannot seek backwards"); $a->write("fred"); $a->close ; my $u = new $UncompressClass(\$b) ; eval { $u->seek(-1, 10) ; }; like $@, mkErr("^${UncompressClass}::seek: unknown value, 10, for whence parameter"); eval { $u->seek(-1, SEEK_END) ; }; like $@, mkErr("^${UncompressClass}::seek: SEEK_END not allowed"); eval { $u->seek(-1, SEEK_CUR) ; }; like $@, mkErr("^${UncompressClass}::seek: cannot seek backwards"); } foreach my $fb (qw(filename buffer filehandle)) { foreach my $append (0, 1) { { title "$CompressClass -- Append $append, Output to $fb" ; my $lex = new LexFile my $name ; my $already = 'already'; my $buffer = $already; my $output; if ($fb eq 'buffer') { $output = \$buffer } elsif ($fb eq 'filename') { $output = $name ; writeFile($name, $buffer); } elsif ($fb eq 'filehandle') { $output = new IO::File ">$name" ; print $output $buffer; } my $a = new $CompressClass($output, Append => $append) ; ok $a, " Created $CompressClass"; my $string = "appended"; $a->write($string); $a->close ; my $data ; if ($fb eq 'buffer') { $data = $buffer; } else { $output->close if $fb eq 'filehandle'; $data = readFile($name); } if ($append || $fb eq 'filehandle') { is substr($data, 0, length($already)), $already, " got prefix"; substr($data, 0, length($already)) = ''; } my $uncomp; my $x = new $UncompressClass(\$data, Append => 1) ; ok $x, " created $UncompressClass"; my $len ; 1 while ($len = $x->read($uncomp)) > 0 ; $x->close ; is $uncomp, $string, ' Got uncompressed data' ; } } } foreach my $type (qw(buffer filename filehandle)) { foreach my $good (0, 1) { title "$UncompressClass -- InputLength, read from $type, good data => $good"; my $compressed ; my $string = "some data"; my $appended = "append"; if ($good) { my $c = new $CompressClass(\$compressed); $c->write($string); $c->close(); } else { $compressed = $string ; } my $comp_len = length $compressed; $compressed .= $appended; my $lex = new LexFile my $name ; my $input ; writeFile ($name, $compressed); if ($type eq 'buffer') { $input = \$compressed; } if ($type eq 'filename') { $input = $name; } elsif ($type eq 'filehandle') { my $fh = new IO::File "<$name" ; ok $fh, "opened file $name ok"; $input = $fh ; } my $x = new $UncompressClass($input, InputLength => $comp_len, Transparent => 1) ; ok $x, " created $UncompressClass"; my $len ; my $output; $len = $x->read($output, 100); is $len, length($string); is $output, $string; if ($type eq 'filehandle') { my $rest ; $input->read($rest, 1000); is $rest, $appended; } } } foreach my $append (0, 1) { title "$UncompressClass -- Append $append" ; my $lex = new LexFile my $name ; my $string = "appended"; my $compressed ; my $c = new $CompressClass(\$compressed); $c->write($string); $c->close(); my $x = new $UncompressClass(\$compressed, Append => $append) ; ok $x, " created $UncompressClass"; my $already = 'already'; my $output = $already; my $len ; $len = $x->read($output, 100); is $len, length($string); $x->close ; if ($append) { is substr($output, 0, length($already)), $already, " got prefix"; substr($output, 0, length($already)) = ''; } is $output, $string, ' Got uncompressed data' ; } foreach my $file (0, 1) { foreach my $trans (0, 1) { title "ungetc, File $file, Transparent $trans" ; my $lex = new LexFile my $name ; my $string = 'abcdeABCDE'; my $b ; if ($trans) { $b = $string ; } else { my $a = new $CompressClass(\$b) ; $a->write($string); $a->close ; } my $from ; if ($file) { writeFile($name, $b); $from = $name ; } else { $from = \$b ; } my $u = $UncompressClass->new($from, Transparent => 1) ; my $first; my $buff ; # do an ungetc before reading $u->ungetc("X"); $first = $u->getc(); is $first, 'X'; $first = $u->getc(); is $first, substr($string, 0,1); $u->ungetc($first); $first = $u->getc(); is $first, substr($string, 0,1); $u->ungetc($first); is $u->read($buff, 5), 5 ; is $buff, substr($string, 0, 5); $u->ungetc($buff) ; is $u->read($buff, length($string)), length($string) ; is $buff, $string; is $u->read($buff, 1), 0; ok $u->eof() ; my $extra = 'extra'; $u->ungetc($extra); ok ! $u->eof(); is $u->read($buff), length($extra) ; is $buff, $extra; is $u->read($buff, 1), 0; ok $u->eof() ; # getc returns undef on eof is $u->getc(), undef; $u->close(); } } { title "write tests - invalid data" ; #my $lex = new LexFile my $name1 ; my($Answer); #ok ! -e $name1, " File $name1 does not exist"; my @data = ( [ '{ }', "${CompressClass}::write: input parameter not a filename, filehandle, array ref or scalar ref" ], [ '[ { } ]', "${CompressClass}::write: input parameter not a filename, filehandle, array ref or scalar ref" ], [ '[ [ { } ] ]', "${CompressClass}::write: input parameter not a filename, filehandle, array ref or scalar ref" ], [ '[ "" ]', "${CompressClass}::write: input filename is undef or null string" ], [ '[ undef ]', "${CompressClass}::write: input filename is undef or null string" ], [ '[ \$Answer ]',"${CompressClass}::write: input and output buffer are identical" ], #[ "not readable", 'xx' ], # same filehandle twice, 'xx' ) ; foreach my $data (@data) { my ($send, $get) = @$data ; title "${CompressClass}::write( $send )"; my($copy); eval "\$copy = $send"; my $x = new $CompressClass(\$Answer); ok $x, " Created $CompressClass object"; eval { $x->write($copy) } ; #like $@, "/^$get/", " error - $get"; like $@, "/not a scalar reference /", " error - not a scalar reference"; } # @data = ( # [ '[ $name1 ]', "input file '$name1' does not exist" ], # #[ "not readable", 'xx' ], # # same filehandle twice, 'xx' # ) ; # # foreach my $data (@data) # { # my ($send, $get) = @$data ; # title "${CompressClass}::write( $send )"; # my $copy; # eval "\$copy = $send"; # my $x = new $CompressClass(\$Answer); # ok $x, " Created $CompressClass object"; # ok ! $x->write($copy), " write fails" ; # like $$Error, "/^$get/", " error - $get"; # } #exit; } # sub deepCopy # { # if (! ref $_[0] || ref $_[0] eq 'SCALAR') # { # return $_[0] ; # } # # if (ref $_[0] eq 'ARRAY') # { # my @a ; # for my $x ( @{ $_[0] }) # { # push @a, deepCopy($x); # } # # return \@a ; # } # # croak "bad! $_[0]"; # # } # # sub deepSubst # { # #my $data = shift ; # my $from = $_[1] ; # my $to = $_[2] ; # # if (! ref $_[0]) # { # $_[0] = $to # if $_[0] eq $from ; # return ; # # } # # if (ref $_[0] eq 'SCALAR') # { # $_[0] = \$to # if defined ${ $_[0] } && ${ $_[0] } eq $from ; # return ; # # } # # if (ref $_[0] eq 'ARRAY') # { # for my $x ( @{ $_[0] }) # { # deepSubst($x, $from, $to); # } # return ; # } # #croak "bad! $_[0]"; # } # { # title "More write tests" ; # # my $file1 = "file1" ; # my $file2 = "file2" ; # my $file3 = "file3" ; # my $lex = new LexFile $file1, $file2, $file3 ; # # writeFile($file1, "F1"); # writeFile($file2, "F2"); # writeFile($file3, "F3"); # # my @data = ( # [ '""', "" ], # [ 'undef', "" ], # [ '"abcd"', "abcd" ], # # [ '\""', "" ], # [ '\undef', "" ], # [ '\"abcd"', "abcd" ], # # [ '[]', "" ], # [ '[[]]', "" ], # [ '[[[]]]', "" ], # [ '[\""]', "" ], # [ '[\undef]', "" ], # [ '[\"abcd"]', "abcd" ], # [ '[\"ab", \"cd"]', "abcd" ], # [ '[[\"ab"], [\"cd"]]', "abcd" ], # # [ '$file1', $file1 ], # [ '$fh2', "F2" ], # [ '[$file1, \"abc"]', "F1abc"], # [ '[\"a", $file1, \"bc"]', "aF1bc"], # [ '[\"a", $fh1, \"bc"]', "aF1bc"], # [ '[\"a", $fh1, \"bc", $file2]', "aF1bcF2"], # [ '[\"a", $fh1, \"bc", $file2, $fh3]', "aF1bcF2F3"], # ) ; # # # foreach my $data (@data) # { # my ($send, $get) = @$data ; # # my $fh1 = new IO::File "< $file1" ; # my $fh2 = new IO::File "< $file2" ; # my $fh3 = new IO::File "< $file3" ; # # title "${CompressClass}::write( $send )"; # my $copy; # eval "\$copy = $send"; # my $Answer ; # my $x = new $CompressClass(\$Answer); # ok $x, " Created $CompressClass object"; # my $len = length $get; # is $x->write($copy), length($get), " write $len bytes"; # ok $x->close(), " close ok" ; # # is myGZreadFile(\$Answer), $get, " got expected output" ; # cmp_ok $$Error, '==', 0, " no error"; # # # } # # } } { # Check can handle empty compressed files # Test is for rt.cpan #67554 foreach my $type (qw(filename filehandle buffer )) { foreach my $append (0, 1) { title "$UncompressClass -- empty file read from $type, Append => $append"; my $appended = "append"; my $string = "some data"; my $compressed ; my $c = new $CompressClass(\$compressed); $c->close(); my $comp_len = length $compressed; $compressed .= $appended if $append && $CompressClass !~ /zstd/i; my $lex = new LexFile my $name ; my $input ; writeFile ($name, $compressed); if ($type eq 'buffer') { $input = \$compressed; } elsif ($type eq 'filename') { $input = $name; } elsif ($type eq 'filehandle') { my $fh = new IO::File "<$name" ; ok $fh, "opened file $name ok"; $input = $fh ; } { # Check that eof is true immediately after creating the # uncompression object. # Check that readline returns undef my $x = new $UncompressClass $input, Transparent => 0 or diag "$$UnError" ; isa_ok $x, $UncompressClass; # should be EOF immediately is $x->eof(), 1, "eof true"; is <$x>, undef, "getline is undef"; is $x->eof(), 1, "eof true"; } { # Check that read returns an empty string if ($type eq 'filehandle') { my $fh = new IO::File "<$name" ; ok $fh, "opened file $name ok"; $input = $fh ; } my $x = new $UncompressClass $input, Transparent => 0 or diag "$$UnError" ; isa_ok $x, $UncompressClass; my $buffer; is $x->read($buffer), 0, "read 0 bytes" or diag "read returned $$UnError"; ok defined $buffer, "buffer is defined"; is $buffer, "", "buffer is empty string"; is $x->eof(), 1, "eof true"; } { # Check that read return an empty string in Append Mode # to empty string if ($type eq 'filehandle') { my $fh = new IO::File "<$name" ; ok $fh, "opened file $name ok"; $input = $fh ; } my $x = new $UncompressClass $input, Transparent => 0, Append => 1 or diag "$$UnError" ; isa_ok $x, $UncompressClass; my $buffer; is $x->read($buffer), 0, "read 0 bytes"; ok defined $buffer, "buffer is defined"; is $buffer, "", "buffer is empty string"; is $x->eof(), 1, "eof true"; } { # Check that read return an empty string in Append Mode # to non-empty string if ($type eq 'filehandle') { my $fh = new IO::File "<$name" ; ok $fh, "opened file $name ok"; $input = $fh ; } my $x = new $UncompressClass($input, Append => 1 ); isa_ok $x, $UncompressClass; my $buffer = "123"; is $x->read($buffer), 0, "read 0 bytes"; ok defined $buffer, "buffer is defined"; is $buffer, "123", "buffer orig string"; is $x->eof(), 1, "eof true"; } } } } { # Round trip binary data that happens to contain \r\n # via the filesystem my $original = join '', map { chr } 0x00 .. 0xff ; $original .= "data1\r\ndata2\r\ndata3\r\n" ; title "$UncompressClass -- round trip test"; my $string = $original; my $lex = new LexFile( my $name, my $compressed) ; my $input ; writeFile ($name, $original); my $c = new $CompressClass($compressed); isa_ok $c, $CompressClass; $c->print($string); $c->close(); my $u = new $UncompressClass $compressed, Transparent => 0 or diag "$$UnError" ; isa_ok $u, $UncompressClass; my $buffer; is $u->read($buffer), length($original), "read bytes"; is $buffer, $original, " round tripped ok"; } } 1; libio-compress-lzma-perl-2.093/t/compress/interop-io-string.pl000066400000000000000000000061371357305603400244200ustar00rootroot00000000000000use lib 't'; use strict; #use warnings; use bytes; use Test::More ; use CompTestUtils; BEGIN { eval { require IO::String ; import IO::String; 1 } or plan(skip_all => "IO::String not installed"); # use Test::NoWarnings, if available my $extra = 0 ; $extra = 1 if eval { require Test::NoWarnings ; import Test::NoWarnings; 1 }; plan tests => 4 + $extra ; } sub run { my $CompressClass = identify(); my $UncompressClass = getInverse($CompressClass); my $Error = getErrorRef($CompressClass); my $UnError = getErrorRef($UncompressClass); my $TopFuncName = getTopFuncName($CompressClass); my $Func = getTopFuncRef($CompressClass); my $FuncInverse = getTopFuncRef($UncompressClass); { use IO::String; #use IO::Scalar; #use IO::Wrap; #use IO::All; my $content = "hello world" ; my $string = $content; my $StrFH = new IO::String $string; #my $StrFH = new IO::Scalar \$string; #my $fh = new IO::String $string; #my $StrFH = wraphandle($fh); #my $lex = new LexFile my $filename ; #writeFile($filename, $content); #my $StrFH = io "$filename"; ok $StrFH, "Created IO::String Object"; my $outStr; my $out = \$outStr; ok $Func->($StrFH, $out), "Compressed" or diag $$Error ; my $got; ok $FuncInverse->($out, \$got), "Uncompressed" or diag $$UnError ; is $got, $content, "got expected content"; } # if (0) # { # my $content = "hello world" ; # my $string = $content; # my $StrFH = new IO::String $string; # # use File::Copy qw(cp); # #my $lex = new LexFile my $filename ; # #my $filename = "/tmp/freddy"; # my $lex1 = new LexFile my $filename, my $filename1, my $filename2 ; # writeFile($filename1, "hello moto\n"); # # my $x = $CompressClass->new($filename); # cp $StrFH, $x; # # #my $y = $UncompressClass->new($filename1); # #cp $y => $filename2; # # #is readFile($filename2), "hello moto\n", "expected content"; # } } 1; __END__ sub readWithBzip2 { my $file = shift ; my $comp = "$BZIP2 -dc" ; open F, "$comp $file |"; local $/; $_[0] = ; close F; return $? ; } sub getBzip2Info { my $file = shift ; } sub writeWithBzip2 { my $file = shift ; my $content = shift ; my $options = shift || ''; unlink $file ; my $bzip2 = "$BZIP2 -c $options >$file" ; open F, "| $bzip2" ; print F $content ; close F ; return $? ; } { title "Test interop with $BZIP2" ; my $file = 'a.bz2'; my $file1 = 'b.bz2'; my $lex = new LexFile $file, $file1; my $content = "hello world\n" ; my $got; is writeWithBzip2($file, $content), 0, "writeWithBzip2 ok"; bunzip2 $file => \$got ; is $got, $content; bzip2 \$content => $file1; $got = ''; is readWithBzip2($file1, $got), 0, "readWithBzip2 returns 0"; is $got, $content, "got content"; } libio-compress-lzma-perl-2.093/t/compress/merge.pl000066400000000000000000000223671357305603400221310ustar00rootroot00000000000000use lib 't'; use strict; use warnings; use bytes; use Test::More ; use CompTestUtils; use Compress::Raw::Zlib 2 ; BEGIN { plan(skip_all => "Merge needs Zlib 1.2.1 or better - you have Zlib " . Compress::Raw::Zlib::zlib_version()) if ZLIB_VERNUM() < 0x1210 ; # use Test::NoWarnings, if available my $extra = 0 ; $extra = 1 if eval { require Test::NoWarnings ; import Test::NoWarnings; 1 }; plan tests => 165 + $extra ; } sub run { my $CompressClass = identify(); my $UncompressClass = getInverse($CompressClass); my $Error = getErrorRef($CompressClass); my $UnError = getErrorRef($UncompressClass); # Tests # destination is a file that doesn't exist -- should work ok unless AnyDeflate # destination isn't compressed at all # destination is compressed but wrong format # destination is corrupt - error messages should be correct # use apend mode with old zlib - check that this is trapped # destination is not seekable, readable, writable - test for filename & handle { title "Misc error cases"; eval { new Compress::Raw::Zlib::InflateScan Bufsize => 0} ; like $@, mkErr("^Compress::Raw::Zlib::InflateScan::new: Bufsize must be >= 1, you specified 0"), " catch bufsize == 0"; eval { Compress::Raw::Zlib::inflateScanStream::createDeflateStream(undef, Bufsize => 0) } ; like $@, mkErr("^Compress::Raw::Zlib::InflateScan::createDeflateStream: Bufsize must be >= 1, you specified 0"), " catch bufsize == 0"; } # output file/handle not writable { foreach my $to_file (0,1) { if ($to_file) { title "$CompressClass - Merge to filename that isn't writable" } else { title "$CompressClass - Merge to filehandle that isn't writable" } my $lex = new LexFile my $out_file ; # create empty file open F, ">$out_file" ; print F "x"; close F; ok -e $out_file, " file exists" ; ok !-z $out_file, " and is not empty" ; # make unwritable is chmod(0444, $out_file), 1, " chmod worked" ; ok -e $out_file, " still exists after chmod" ; SKIP: { skip "Cannot create non-writable file", 3 if -w $out_file ; ok ! -w $out_file, " chmod made file unwritable" ; my $dest ; if ($to_file) { $dest = $out_file } else { $dest = new IO::File "<$out_file" } my $gz = $CompressClass->new($dest, Merge => 1) ; ok ! $gz, " Did not create $CompressClass object"; ok $$Error, " Got error message" ; } chmod 0777, $out_file ; } } # output is not compressed at all { my $lex = new LexFile my $out_file ; foreach my $to_file ( qw(buffer file handle ) ) { title "$CompressClass to $to_file, content is not compressed"; my $content = "abc" x 300 ; my $buffer ; my $disp_content = defined $content ? $content : '' ; my $str_content = defined $content ? $content : '' ; if ($to_file eq 'buffer') { $buffer = \$content ; } else { writeFile($out_file, $content); if ($to_file eq 'handle') { $buffer = new IO::File "+<$out_file" or die "# Cannot open $out_file: $!"; } else { $buffer = $out_file } } ok ! $CompressClass->new($buffer, Merge => 1), " constructor fails"; { like $$Error, '/Cannot create InflateScan object: (Header Error|unexpected end of file|Inflation Error: data error)?/', " got Bad Magic" ; } } } # output is empty { my $lex = new LexFile my $out_file ; foreach my $to_file ( qw(buffer file handle ) ) { title "$CompressClass to $to_file, content is empty"; my $content = ''; my $buffer ; my $dest ; if ($to_file eq 'buffer') { $dest = $buffer = \$content ; } else { writeFile($out_file, $content); $dest = $out_file; if ($to_file eq 'handle') { $buffer = new IO::File "+<$out_file" or die "# Cannot open $out_file: $!"; } else { $buffer = $out_file } } ok my $gz = $CompressClass->new($buffer, Merge => 1, AutoClose => 1), " constructor passes" or diag $$Error; $gz->write("FGHI"); $gz->close(); #hexDump($buffer); my $out = anyUncompress($dest); is $out, "FGHI", ' Merge OK'; } } { title "$CompressClass - Merge to file that doesn't exist"; my $lex = new LexFile my $out_file ; ok ! -e $out_file, " Destination file, '$out_file', does not exist"; ok my $gz1 = $CompressClass->new($out_file, Merge => 1) or die "# $CompressClass->new failed: $$Error\n"; #hexDump($buffer); $gz1->write("FGHI"); $gz1->close(); #hexDump($buffer); my $out = anyUncompress($out_file); is $out, "FGHI", ' Merged OK'; } { my $lex = new LexFile my $out_file ; foreach my $to_file ( qw( buffer file handle ) ) { foreach my $content (undef, '', 'x', 'abcde') { #next if ! defined $content && $to_file; my $buffer ; my $disp_content = defined $content ? $content : '' ; my $str_content = defined $content ? $content : '' ; if ($to_file eq 'buffer') { my $x ; $buffer = \$x ; title "$CompressClass to Buffer, content is '$disp_content'"; } else { $buffer = $out_file ; if ($to_file eq 'handle') { title "$CompressClass to Filehandle, content is '$disp_content'"; } else { title "$CompressClass to File, content is '$disp_content'"; } } my $gz = $CompressClass->new($buffer); my $len = defined $content ? length($content) : 0 ; is $gz->write($content), $len, " write ok"; ok $gz->close(), " close ok"; #hexDump($buffer); is anyUncompress($buffer), $str_content, ' Destination is ok'; #if ($corruption) #{ # next if $TopTypes eq 'RawDeflate' && $content eq ''; # #} my $dest = $buffer ; if ($to_file eq 'handle') { $dest = new IO::File "+<$buffer" ; } my $gz1 = $CompressClass->new($dest, Merge => 1, AutoClose => 1) or die "## Error is $$Error\n"; #print "YYY\n"; #hexDump($buffer); #print "XXX\n"; is $gz1->write("FGHI"), 4, " write returned 4"; ok $gz1->close(), " close ok"; #hexDump($buffer); my $out = anyUncompress($buffer); is $out, $str_content . "FGHI", ' Merged OK'; #exit; } } } { my $Func = getTopFuncRef($CompressClass); my $TopType = getTopFuncName($CompressClass); my $buffer ; my $lex = new LexFile my $out_file ; foreach my $to_file (0, 1) { foreach my $content (undef, '', 'x', 'abcde') { my $disp_content = defined $content ? $content : '' ; my $str_content = defined $content ? $content : '' ; my $buffer ; if ($to_file) { $buffer = $out_file ; title "$TopType to File, content is '$disp_content'"; } else { my $x = ''; $buffer = \$x ; title "$TopType to Buffer, content is '$disp_content'"; } ok $Func->(\$content, $buffer), " Compress content"; #hexDump($buffer); is anyUncompress($buffer), $str_content, ' Destination is ok'; ok $Func->(\"FGHI", $buffer, Merge => 1), " Merge content"; #hexDump($buffer); my $out = anyUncompress($buffer); is $out, $str_content . "FGHI", ' Merged OK'; } } } } 1; libio-compress-lzma-perl-2.093/t/compress/multi.pl000066400000000000000000000225641357305603400221630ustar00rootroot00000000000000 use lib 't'; use strict; use warnings; use bytes; use Test::More ; use CompTestUtils; BEGIN { # use Test::NoWarnings, if available my $extra = 0 ; $extra = 1 if eval { require Test::NoWarnings ; import Test::NoWarnings; 1 }; plan tests => 1828 + $extra ; use_ok('IO::Uncompress::AnyUncompress', qw($AnyUncompressError)) ; } sub run { my $CompressClass = identify(); my $UncompressClass = getInverse($CompressClass); my $Error = getErrorRef($CompressClass); my $UnError = getErrorRef($UncompressClass); my @buffers ; push @buffers, < 1, Comment => "this is a comment", ExtraField => ["so" => "me extra"], HeaderCRC => 1); } my $lex = new LexFile my $name ; my $output ; if ($fb eq 'buffer') { my $compressed = ''; $output = \$compressed; } elsif ($fb eq 'filehandle') { $output = new IO::File ">$name" ; } else { $output = $name ; } my $x = new $CompressClass($output, AutoClose => 1, %headers); isa_ok $x, $CompressClass, ' $x' ; foreach my $buffer (@buffs) { ok $x->write($buffer), " Write OK" ; # this will add an extra "empty" stream ok $x->newStream(), " newStream OK" ; } ok $x->close, " Close ok" ; foreach my $unc ($UncompressClass, 'IO::Uncompress::AnyUncompress') { title " Testing $CompressClass with $unc and $i streams, from $fb"; $cc = $output ; if ($fb eq 'filehandle') { $cc = new IO::File "<$name" ; } my @opts = $unc ne $UncompressClass ? (RawInflate => 1) : (); my $gz = new $unc($cc, @opts, Strict => 1, AutoClose => 1, Append => 1, MultiStream => 1, Transparent => 0) or diag $$UnError; isa_ok $gz, $UncompressClass, ' $gz' ; 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()"; ok $gz->close(), " close() ok" or diag "errno $!\n" ; is $gz->streamCount(), $i +1, " streamCount ok " . ($i +1) or diag "Stream count is " . $gz->streamCount(); ok $un eq join('', @buffs), " expected output" ; } foreach my $unc ($UncompressClass, 'IO::Uncompress::AnyUncompress') { foreach my $blk (1, 20, $b0length - 1, $b0length, $b0length +1) { title " Testing $CompressClass with $unc, BlockSize $blk and $i streams, from $fb"; $cc = $output ; if ($fb eq 'filehandle') { $cc = new IO::File "<$name" ; } my @opts = $unc ne $UncompressClass ? (RawInflate => 1) : (); my $gz = new $unc($cc, @opts, Strict => 1, AutoClose => 1, Append => 1, MultiStream => 1, Transparent => 0) or diag $$UnError; isa_ok $gz, $UncompressClass, ' $gz' ; my $un = ''; my $b = $blk; # Want the first read to be in the middle of a stream # and the second to cross a stream boundary $b = 1000 while $gz->read($un, $b) > 0 ; #print "[[$un]]\n" while $gz->read($un) > 0 ; ok ! $gz->error(), " ! error()" or diag "Error is " . $gz->error() ; ok $gz->eof(), " eof()"; ok $gz->close(), " close() ok" or diag "errno $!\n" ; is $gz->streamCount(), $i +1, " streamCount ok " . ($i +1) or diag "Stream count is " . $gz->streamCount(); ok $un eq join('', @buffs), " expected output" ; } } foreach my $unc ($UncompressClass, 'IO::Uncompress::AnyUncompress') { foreach my $trans (0, 1) { title " Testing $CompressClass with $unc nextStream and $i streams, from $fb, Transparent => $trans"; $cc = $output ; if ($fb eq 'filehandle') { $cc = new IO::File "<$name" ; } my @opts = $unc ne $UncompressClass ? (RawInflate => 1) : (); my $gz = new $unc($cc, @opts, Strict => 1, AutoClose => 1, Append => 1, MultiStream => 0, Transparent => $trans) 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>) { while ($_ = $gz->getline()) { $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 ; is $., 0, " \$. is 0"; $gz->read($un) ; #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 $gz->nextStream(), 0, " nextStream ok" or diag $gz->error() ; 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 # check that "tell" works ok 1; libio-compress-lzma-perl-2.093/t/compress/newtied.pl000066400000000000000000000233341357305603400224640ustar00rootroot00000000000000use lib 't'; use strict; use warnings; use bytes; use Test::More ; use CompTestUtils; our ($BadPerl, $UncompressClass); BEGIN { plan(skip_all => "Extra Tied Filehandle needs Perl 5.6 or better - you have Perl $]" ) if $] < 5.006 ; my $tests ; $BadPerl = ($] >= 5.006 and $] <= 5.008) ; if ($BadPerl) { $tests = 78 ; } else { $tests = 84 ; } # use Test::NoWarnings, if available my $extra = 0 ; $extra = 1 if eval { require Test::NoWarnings ; import Test::NoWarnings; 1 }; plan tests => $tests + $extra ; } use IO::Handle qw(SEEK_SET SEEK_CUR SEEK_END); sub myGZreadFile { my $filename = shift ; my $init = shift ; my $fil = new $UncompressClass $filename, -Strict => 1, -Append => 1 ; my $data ; $data = $init if defined $init ; 1 while $fil->read($data) > 0; $fil->close ; return $data ; } sub run { my $CompressClass = identify(); $UncompressClass = getInverse($CompressClass); my $Error = getErrorRef($CompressClass); my $UnError = getErrorRef($UncompressClass); { title "Testing $CompressClass and $UncompressClass"; { # Write # these tests come almost 100% from IO::String my $lex = new LexFile my $name ; my $io = $CompressClass->new($name); is tell($io), 0 ; is $io->tell(), 0 ; my $heisan = "Heisan\n"; print $io $heisan ; ok ! eof($io); ok ! $io->eof(); is tell($io), length($heisan) ; is $io->tell(), length($heisan) ; $io->print("a", "b", "c"); { local($\) = "\n"; print $io "d", "e"; local($,) = ","; print $io "f", "g", "h"; } my $foo = "1234567890"; ok syswrite($io, $foo, length($foo)) == length($foo) ; if ( $] < 5.6 ) { is $io->syswrite($foo, length $foo), length $foo } else { is $io->syswrite($foo), length $foo } ok $io->syswrite($foo, length($foo)) == length $foo; ok $io->write($foo, length($foo), 5) == 5; ok $io->write("xxx\n", 100, -1) == 1; for (1..3) { printf $io "i(%d)", $_; $io->printf("[%d]\n", $_); } select $io; print "\n"; select STDOUT; close $io ; ok eof($io); ok $io->eof(); is myGZreadFile($name), "Heisan\nabcde\nf,g,h\n" . ("1234567890" x 3) . "67890\n" . "i(1)[1]\ni(2)[2]\ni(3)[3]\n\n"; } { # Read my $str = <eof; ok ! eof $io; is $io->tell(), 0 ; is tell($io), 0 ; my @lines = <$io>; is @lines, 6 or print "# Got " . scalar(@lines) . " lines, expected 6\n" ; is $lines[1], "of a paragraph\n" ; is join('', @lines), $str ; is $., 6; #print "TELL says " . tell($io) , " should be ${ \length($str) }\n" ; is $io->tell(), length($str) ; is tell($io), length($str) ; ok $io->eof; ok eof $io; ok ! ( defined($io->getline) || (@tmp = $io->getlines) || defined(<$io>) || defined($io->getc) || read($io, $buf, 100) != 0) ; } { local $/; # slurp mode my $io = $UncompressClass->new($name); ok ! $io->eof; my @lines = $io->getlines; ok $io->eof; ok @lines == 1 && $lines[0] eq $str; $io = $UncompressClass->new($name); ok ! $io->eof; my $line = <$io>; ok $line eq $str; ok $io->eof; } { local $/ = ""; # paragraph mode my $io = $UncompressClass->new($name); ok ! $io->eof; my @lines = <$io>; ok $io->eof; ok @lines == 2 or print "# Got " . scalar(@lines) . " lines, expected 2\n" ; ok $lines[0] eq "This is an example\nof a paragraph\n\n\n" or print "# $lines[0]\n"; ok $lines[1] eq "and a single line.\n\n"; } { local $/ = "is"; my $io = $UncompressClass->new($name); my @lines = (); my $no = 0; my $err = 0; ok ! $io->eof; while (<$io>) { push(@lines, $_); $err++ if $. != ++$no; } ok $err == 0 ; ok $io->eof; ok @lines == 3 or print "# Got " . scalar(@lines) . " lines, expected 3\n" ; ok join("-", @lines) eq "This- is- an example\n" . "of a paragraph\n\n\n" . "and a single line.\n\n"; } # Test read { my $io = $UncompressClass->new($name); ok $io, "opened ok" ; #eval { read($io, $buf, -1); } ; #like $@, mkErr("length parameter is negative"), "xxx $io $UncompressClass $RawInflateError" ; #eval { read($io, 1) } ; #like $@, mkErr("buffer parameter is read-only"); is read($io, $buf, 0), 0, "Requested 0 bytes" ; ok read($io, $buf, 3) == 3 ; ok $buf eq "Thi"; ok sysread($io, $buf, 3, 2) == 3 ; ok $buf eq "Ths i" or print "# [$buf]\n" ;; ok ! $io->eof; # $io->seek(-4, 2); # # ok ! $io->eof; # # ok read($io, $buf, 20) == 4 ; # ok $buf eq "e.\n\n"; # # ok read($io, $buf, 20) == 0 ; # ok $buf eq ""; # # ok ! $io->eof; } } { title "seek tests" ; my $lex = new LexFile my $name ; my $first = "beginning" ; my $last = "the end" ; my $iow = new $CompressClass $name ; print $iow $first ; ok seek $iow, 10, SEEK_CUR ; is tell($iow), length($first)+10; ok $iow->seek(0, SEEK_CUR) ; is tell($iow), length($first)+10; print $iow $last ; close $iow; my $io = $UncompressClass->new($name); ok myGZreadFile($name) eq $first . "\x00" x 10 . $last ; $io = $UncompressClass->new($name); ok seek $io, length($first)+10, SEEK_CUR ; ok ! $io->eof; is tell($io), length($first)+10; ok seek $io, 0, SEEK_CUR ; is tell($io), length($first)+10; my $buff ; ok read $io, $buff, 100 ; ok $buff eq $last ; ok $io->eof; } if (! $BadPerl) { # seek error cases my $b ; my $a = new $CompressClass(\$b) ; ok ! $a->error() ; eval { seek($a, -1, 10) ; }; like $@, mkErr("seek: unknown value, 10, for whence parameter"); eval { seek($a, -1, SEEK_END) ; }; like $@, mkErr("cannot seek backwards"); print $a "fred"; close $a ; my $u = new $UncompressClass(\$b) ; eval { seek($u, -1, 10) ; }; like $@, mkErr("seek: unknown value, 10, for whence parameter"); eval { seek($u, -1, SEEK_END) ; }; like $@, mkErr("seek: SEEK_END not allowed"); eval { seek($u, -1, SEEK_CUR) ; }; like $@, mkErr("cannot seek backwards"); } { title 'fileno' ; my $lex = new LexFile my $name ; my $hello = <$name" ; my $x ; ok $x = new $CompressClass $fh ; ok $x->fileno() == fileno($fh) ; ok $x->fileno() == fileno($x) ; ok $x->write($hello) ; ok $x->close ; $fh->close() ; } my $uncomp; { my $x ; ok my $fh1 = new IO::File "<$name" ; ok $x = new $UncompressClass $fh1, -Append => 1 ; ok $x->fileno() == fileno $fh1 ; ok $x->fileno() == fileno $x ; 1 while $x->read($uncomp) > 0 ; ok $x->close ; } ok $hello eq $uncomp ; } } } 1; libio-compress-lzma-perl-2.093/t/compress/oneshot.pl000077500000000000000000001572421357305603400225150ustar00rootroot00000000000000use lib 't'; use strict; use warnings; use bytes; use Test::More ; use CompTestUtils; BEGIN { plan(skip_all => "oneshot needs Perl 5.005 or better - you have Perl $]" ) if $] < 5.005 ; # use Test::NoWarnings, if available my $extra = 0 ; $extra = 1 if eval { require Test::NoWarnings ; import Test::NoWarnings; 1 }; plan tests => 1007 + $extra ; use_ok('IO::Uncompress::AnyUncompress', qw(anyuncompress $AnyUncompressError)) ; } my $OriginalContent1 = <(\$a => \$x, Fred => 1) ;} ; like $@, mkErr("^$TopType: unknown key value\\(s\\) Fred"), ' Illegal Parameters'; eval { $a = $Func->() ;} ; like $@, "/^$TopType: expected at least 1 parameters/", ' No Parameters'; eval { $a = $Func->(\$x, \1) ;} ; like $$Error, "/^$TopType: output buffer is read-only/", ' Output is read-only' ; my $in ; eval { $a = $Func->($in, \$x) ;} ; like $@, mkErr("^$TopType: input filename is undef or null string"), ' Input filename undef' ; $in = ''; eval { $a = $Func->($in, \$x) ;} ; like $@, mkErr("^$TopType: input filename is undef or null string"), ' Input filename empty' ; { my $lex1 = new LexFile my $in ; writeFile($in, "abc"); my $out = $in ; eval { $a = $Func->($in, $out) ;} ; like $@, mkErr("^$TopType: input and output filename are identical"), ' Input and Output filename are the same'; } { my $dir ; my $lex = new LexDir $dir ; my $d = quotemeta $dir; $a = $Func->("$dir", \$x) ; is $a, undef, " $TopType returned undef"; like $$Error, "/input file '$d' is a directory/", ' Input filename is a directory'; $a = $Func->(\$x, "$dir") ; is $a, undef, " $TopType returned undef"; like $$Error, "/output file '$d' 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'; 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" ; # Buffer not a scalar reference #eval { $a = $Func->(\$x, \%x) ;} ; eval { $a = $Func->(\$x, $object) ;} ; like $@, mkErr("^$TopType: illegal output parameter"), ' Bad Output Param'; # Buffer not a scalar reference eval { $a = $Func->(\$x, \%x) ;} ; like $@, mkErr("^$TopType: illegal output parameter"), ' Bad Output Param'; eval { $a = $Func->(\%x, \$x) ;} ; like $@, mkErr("^$TopType: illegal input parameter"), ' Bad Input Param'; #eval { $a = $Func->(\%x, \$x) ;} ; eval { $a = $Func->($object, \$x) ;} ; like $@, mkErr("^$TopType: illegal input parameter"), ' Bad Input Param'; } my $filename = 'abc.def'; ok ! -e $filename, " input file '$filename' does not exist"; $a = $Func->($filename, \$x) ; is $a, undef, " $TopType returned undef"; like $$Error, "/^input file '$filename' does not exist\$/", " input File '$filename' does not exist"; $filename = '/tmp/abd/abc.def'; ok ! -e $filename, " output File '$filename' does not exist"; $a = $Func->(\$x, $filename) ; is $a, undef, " $TopType returned undef"; like $$Error, ("/^(cannot open file '$filename'|input file '$filename' does not exist):/"), " output File '$filename' does not exist"; eval { $a = $Func->(\$x, '') } ; like $$Error, "/Need input fileglob for outout fileglob/", ' Output fileglob with no input fileglob'; is $a, undef, " $TopType returned undef"; $a = $Func->('', '') ; is $a, undef, " $TopType returned undef"; like $$Error, "/Unmatched \\) in input fileglob/", " Unmatched ) in input fileglob"; } foreach my $bit ($UncompressClass, 'IO::Uncompress::AnyUncompress', ) { my $Error = getErrorRef($bit); my $Func = getTopFuncRef($bit); my $TopType = getTopFuncName($bit); { my $in ; my $out ; my @x ; SKIP: { use Config; skip 'readonly + threads', 1 if $Config{useithreads} ; skip '\\ returns mutable value in 5.19.3', 1 if $] >= 5.019003; eval { $a = $Func->(\$in, \$out, TrailingData => \"abc") ;} ; like $@, mkErr("^$TopType: Parameter 'TrailingData' not writable"), ' TrailingData output not writable'; } eval { $a = $Func->(\$in, \$out, TrailingData => \@x) ;} ; like $@, mkErr("^$TopType: Parameter 'TrailingData' not a scalar reference"), ' TrailingData output not scalar reference'; } } foreach my $bit ($UncompressClass, 'IO::Uncompress::AnyUncompress', ) { my $Error = getErrorRef($bit); my $Func = getTopFuncRef($bit); my $TopType = getTopFuncName($bit); my $data = "mary had a little lamb" ; my $keep = $data ; for my $trans ( 0, 1) { title "Non-compressed data with $TopType, Transparent => $trans "; my $a; my $x ; my $out = '' ; $a = $Func->(\$data, \$out, Transparent => $trans) ; is $data, $keep, " Input buffer not changed" ; if ($trans) { ok $a, " $TopType returned true" ; is $out, $data, " got expected output" ; ok ! $$Error, " no error [$$Error]" ; } else { ok ! $a, " $TopType returned false" ; #like $$Error, '/xxx/', " error" ; ok $$Error, " error is '$$Error'" ; } } } foreach my $bit ($CompressClass ) { my $Error = getErrorRef($bit); my $Func = getTopFuncRef($bit); my $TopType = getTopFuncName($bit); my $TopTypeInverse = getInverse($bit); my $FuncInverse = getTopFuncRef($TopTypeInverse); my $ErrorInverse = getErrorRef($TopTypeInverse); title "$TopTypeInverse - corrupt data"; my $data = "abcd" x 100 ; my $out; ok $Func->(\$data, \$out), " $TopType ok"; # corrupt the compressed data #substr($out, -10, 10) = "x" x 10 ; substr($out, int(length($out)/3), 10) = 'abcdeabcde'; my $result; ok ! $FuncInverse->(\$out => \$result, Transparent => 0), " $TopTypeInverse ok"; ok $$ErrorInverse, " Got error '$$ErrorInverse'" ; #is $result, $data, " data ok"; ok ! anyuncompress(\$out => \$result, Transparent => 0), "anyuncompress ok"; ok $AnyUncompressError, " Got error '$AnyUncompressError'" ; } foreach my $bit ($CompressClass ) { my $Error = getErrorRef($bit); my $Func = getTopFuncRef($bit); my $TopType = getTopFuncName($bit); my $TopTypeInverse = getInverse($bit); my $FuncInverse = getTopFuncRef($TopTypeInverse); my @opts = (); @opts = (RawInflate => 1, UnLzma => 1) if $CompressClass eq 'IO::Compress::RawInflate'; for my $append ( 1, 0 ) { my $already = ''; $already = 'abcde' if $append ; for my $buffer ( undef, '', $OriginalContent1 ) { my $disp_content = defined $buffer ? $buffer : '' ; my $keep = $buffer; my $out_file = "abcde.out"; my $in_file = "abcde.in"; { title "$TopType - From Buff to Buff content '$disp_content' Append $append" ; my $output = $already; ok &$Func(\$buffer, \$output, Append => $append), ' Compressed ok' ; is $keep, $buffer, " Input buffer not changed" ; my $got = anyUncompress(\$output, $already); $got = undef if ! defined $buffer && $got eq '' ; ok ! $$Error, " no error [$$Error]" ; is $got, $buffer, " Uncompressed matches original"; } { title "$TopType - From Buff to Array Ref content '$disp_content' Append $append" ; my @output = ('first') ; ok &$Func(\$buffer, \@output, Append => $append), ' Compressed ok' ; is $output[0], 'first', " Array[0] unchanged"; is $keep, $buffer, " Input buffer not changed" ; my $got = anyUncompress($output[1]); $got = undef if ! defined $buffer && $got eq '' ; is $got, $buffer, " Uncompressed matches original"; } { title "$TopType - From Array Ref to Array Ref content '$disp_content' Append $append" ; my $lex = new LexFile my $in_file ; writeFile($in_file, $buffer); my @output = ('first') ; my @input = ($in_file); ok &$Func(\@input, \@output, Append => $append), ' Compressed ok' ; is $output[0], 'first', " Array[0] unchanged"; my $got = anyUncompress($output[1]); $got = undef if ! defined $buffer && $got eq '' ; is $got, $buffer, " Uncompressed matches original"; } { title "$TopType - From Buff to Filename content '$disp_content' Append $append" ; my $lex = new LexFile my $out_file ; ok ! -e $out_file, " Output file does not exist"; writeFile($out_file, $already); ok &$Func(\$buffer, $out_file, Append => $append), ' Compressed ok' ; ok -e $out_file, " Created output file"; my $got = anyUncompress($out_file, $already); $got = undef if ! defined $buffer && $got eq '' ; is $got, $buffer, " Uncompressed matches original"; } { title "$TopType - From Buff to Handle content '$disp_content' Append $append" ; my $lex = new LexFile my $out_file ; ok ! -e $out_file, " Output file does not exist"; writeFile($out_file, $already); my $of = new IO::File ">>$out_file" ; ok $of, " Created output filehandle" ; ok &$Func(\$buffer, $of, AutoClose => 1, Append => $append), ' Compressed ok' ; ok -e $out_file, " Created output file"; my $got = anyUncompress($out_file, $already); $got = undef if ! defined $buffer && $got eq '' ; is $got, $buffer, " Uncompressed matches original"; } { title "$TopType - From Filename to Filename content '$disp_content' Append $append" ; my $lex = new LexFile(my $in_file, my $out_file) ; writeFile($in_file, $buffer); ok ! -e $out_file, " Output file does not exist"; writeFile($out_file, $already); ok &$Func($in_file => $out_file, Append => $append), ' Compressed ok' ; ok -e $out_file, " Created output file"; my $got = anyUncompress($out_file, $already); $got = undef if ! defined $buffer && $got eq '' ; is $got, $buffer, " Uncompressed matches original"; } { title "$TopType - From Filename to Handle content '$disp_content' Append $append" ; my $lex = new LexFile(my $in_file, my $out_file) ; writeFile($in_file, $buffer); ok ! -e $out_file, " Output file does not exist"; writeFile($out_file, $already); my $out = new IO::File ">>$out_file" ; ok &$Func($in_file, $out, AutoClose => 1, Append => $append), ' Compressed ok' ; ok -e $out_file, " Created output file"; my $got = anyUncompress($out_file, $already); $got = undef if ! defined $buffer && $got eq '' ; is $got, $buffer, " Uncompressed matches original"; } { title "$TopType - From Filename to Buffer content '$disp_content' Append $append" ; my $lex = new LexFile(my $in_file, my $out_file) ; writeFile($in_file, $buffer); my $out = $already; ok &$Func($in_file => \$out, Append => $append), ' Compressed ok' ; my $got = anyUncompress(\$out, $already); $got = undef if ! defined $buffer && $got eq '' ; is $got, $buffer, " Uncompressed matches original"; } { title "$TopType - From Handle to Filename content '$disp_content' Append $append" ; my $lex = new LexFile(my $in_file, my $out_file) ; writeFile($in_file, $buffer); my $in = new IO::File "<$in_file" ; ok ! -e $out_file, " Output file does not exist"; writeFile($out_file, $already); ok &$Func($in, $out_file, Append => $append), ' Compressed ok' or diag "error is $$Error" ; ok -e $out_file, " Created output file"; my $got = anyUncompress($out_file, $already); $got = undef if ! defined $buffer && $got eq '' ; is $buffer, $got, " Uncompressed matches original"; } { title "$TopType - From Handle to Handle content '$disp_content' Append $append" ; my $lex = new LexFile(my $in_file, my $out_file) ; writeFile($in_file, $buffer); my $in = new IO::File "<$in_file" ; ok ! -e $out_file, " Output file does not exist"; writeFile($out_file, $already); my $out = new IO::File ">>$out_file" ; ok &$Func($in, $out, AutoClose => 1, Append => $append), ' Compressed ok' ; ok -e $out_file, " Created output file"; my $got = anyUncompress($out_file, $already); $got = undef if ! defined $buffer && $got eq '' ; is $buffer, $got, " Uncompressed matches original"; } { title "$TopType - From Handle to Buffer content '$disp_content' Append $append" ; my $lex = new LexFile(my $in_file, my $out_file) ; writeFile($in_file, $buffer); my $in = new IO::File "<$in_file" ; my $out = $already ; ok &$Func($in, \$out, Append => $append), ' Compressed ok' ; my $got = anyUncompress(\$out, $already); $got = undef if ! defined $buffer && $got eq '' ; is $buffer, $got, " Uncompressed matches original"; } { title "$TopType - From stdin (via '-') to Buffer content '$disp_content' Append $append" ; my $lex = new LexFile(my $in_file, my $out_file) ; writeFile($in_file, $buffer); open(SAVEIN, "<&STDIN"); my $dummy = fileno SAVEIN ; ok open(STDIN, "<$in_file"), " redirect STDIN"; my $out = $already; ok &$Func('-', \$out, Append => $append), ' Compressed ok' or diag $$Error ; open(STDIN, "<&SAVEIN"); my $got = anyUncompress(\$out, $already); $got = undef if ! defined $buffer && $got eq '' ; is $buffer, $got, " Uncompressed matches original"; } } } } foreach my $bit ($CompressClass) { my $Error = getErrorRef($bit); my $Func = getTopFuncRef($bit); my $TopType = getTopFuncName($bit); my $TopTypeInverse = getInverse($bit); my $FuncInverse = getTopFuncRef($TopTypeInverse); my $ErrorInverse = getErrorRef($TopTypeInverse); my $lex = new LexFile(my $file1, my $file2) ; writeFile($file1, $OriginalContent1); writeFile($file2, $OriginalContent2); my $of = new IO::File "<$file1" ; ok $of, " Created output filehandle" ; #my @input = ( undef, "", $file2, \undef, \'', \"abcde", $of) ; #my @expected = ("", "", $file2, "", "", "abcde", $OriginalContent1); #my @uexpected = ("", "", $OriginalContent2, "", "", "abcde", $OriginalContent1); #my @input = ( $file2, \"abcde", $of) ; #my @expected = ( $file2, "abcde", $OriginalContent1); #my @uexpected = ($OriginalContent2, "abcde", $OriginalContent1); my @input = ( $file1, $file2) ; #my @expected = ( $file1, $file2); my @expected = ($OriginalContent1, $OriginalContent2); my @uexpected = ($OriginalContent1, $OriginalContent2); my @keep = @input ; { title "$TopType - From Array Ref to Array Ref" ; my @output = ('first') ; ok &$Func(\@input, \@output, AutoClose => 0), ' Compressed ok' ; is $output[0], 'first', " Array[0] unchanged"; is_deeply \@input, \@keep, " Input array not changed" ; my @got = shift @output; foreach (@output) { push @got, anyUncompress($_) } is_deeply \@got, ['first', @expected], " Got Expected uncompressed data"; } foreach my $ms (@MultiValues) { { title "$TopType - From Array Ref to Buffer, MultiStream $ms" ; # rewind the filehandle $of->open("<$file1") ; my $output ; ok &$Func(\@input, \$output, MultiStream => $ms, AutoClose => 0), ' Compressed ok' or diag $$Error; my $got = anyUncompress([ \$output, MultiStream => $ms ]); is $got, join('', @uexpected), " Got Expected uncompressed data"; my @headers = getHeaders(\$output); is @headers, $ms ? @input : 1, " Header count ok"; } { title "$TopType - From Array Ref to Filename, MultiStream $ms" ; my $lex = new LexFile( my $file3) ; # rewind the filehandle $of->open("<$file1") ; my $output ; ok &$Func(\@input, $file3, MultiStream => $ms, AutoClose => 0), ' Compressed ok' ; my $got = anyUncompress([ $file3, MultiStream => $ms ]); is $got, join('', @uexpected), " Got Expected uncompressed data"; my @headers = getHeaders($file3); is @headers, $ms ? @input : 1, " Header count ok"; } { title "$TopType - From Array Ref to Filehandle, MultiStream $ms" ; my $lex = new LexFile(my $file3) ; my $fh3 = new IO::File ">$file3"; # rewind the filehandle $of->open("<$file1") ; my $output ; ok &$Func(\@input, $fh3, MultiStream => $ms, AutoClose => 0), ' Compressed ok' ; $fh3->close(); my $got = anyUncompress([ $file3, MultiStream => $ms ]); is $got, join('', @uexpected), " Got Expected uncompressed data"; my @headers = getHeaders($file3); is @headers, $ms ? @input : 1, " Header count ok"; } SKIP: { title "Truncated file"; skip '', 7 if $CompressClass =~ /lzop|lzf|lzma|zstd|lzip/i ; my @in ; push @in, "abcde" x 10; push @in, "defgh" x 1000; push @in, "12345" x 50000; my $out; for (@in) { ok &$Func(\$_ , \$out, Append => 1 ), ' Compressed ok' or diag $$Error; } #ok &$Func(\@in, \$out, MultiStream => 1 ), ' Compressed ok' substr($out, -179) = ''; my $got; my $status ; ok $status = &$FuncInverse(\$out => \$got, MultiStream => 0), " Uncompressed stream 1 ok"; is $got, "abcde" x 10 ; ok ! &$FuncInverse(\$out => \$got, MultiStream => 1), " Didn't uncompress"; is $$ErrorInverse, "unexpected end of file", " Got unexpected eof"; } } } foreach my $bit ($CompressClass) { my $Error = getErrorRef($bit); my $Func = getTopFuncRef($bit); my $TopType = getTopFuncName($bit); my $TopTypeInverse = getInverse($bit); my $FuncInverse = getTopFuncRef($TopTypeInverse); my $ErrorInverse = getErrorRef($TopTypeInverse); title 'Round trip binary data that happens to include \r\n' ; my $lex = new LexFile(my $file1, my $file2, my $file3) ; my $original = join '', map { chr } 0x00 .. 0xff ; $original .= "data1\r\ndata2\r\ndata3\r\n" ; writeFile($file1, $original); is readFile($file1), $original; ok &$Func($file1 => $file2), ' Compressed ok' ; ok &$FuncInverse($file2 => $file3), ' Uncompressed ok' ; is readFile($file3), $original, " round tripped ok"; } foreach my $bit ($UncompressClass, #'IO::Uncompress::AnyUncompress', ) { my $Error = getErrorRef($bit); my $Func = getTopFuncRef($bit); my $TopType = getTopFuncName($bit); my $CompressClass = getInverse($bit); my $C_Func = getTopFuncRef($CompressClass); my $data = "mary had a little lamb" ; my $keep = $data ; my $extra = "after the main event"; SKIP: foreach my $fb ( qw( filehandle buffer ) ) { title "Trailingdata with $TopType, from $fb"; skip "zstd doesn't support trailing data", 9 if $CompressClass =~ /zstd/i ; my $lex = new LexFile my $name ; my $input ; my $compressed ; ok &$C_Func(\$data, \$compressed), ' Compressed ok' ; $compressed .= $extra; if ($fb eq 'buffer') { $input = \$compressed; } else { writeFile($name, $compressed); $input = new IO::File "<$name" ; } my $trailing; my $out; ok $Func->($input, \$out, TrailingData => $trailing), " Uncompressed OK" ; is $out, $keep, " Got uncompressed data"; my $rest = ''; if ($fb eq 'filehandle') { read($input, $rest, 10000) ; } is $trailing . $rest, $extra, " Got trailing data"; } } # foreach my $bit ($CompressClass) # { # my $Error = getErrorRef($bit); # my $Func = getTopFuncRef($bit); # my $TopType = getTopFuncName($bit); # # my $TopTypeInverse = getInverse($bit); # my $FuncInverse = getTopFuncRef($TopTypeInverse); # # my @inFiles = map { "in$_.tmp" } 1..4; # my @outFiles = map { "out$_.tmp" } 1..4; # my $lex = new LexFile(@inFiles, @outFiles); # # writeFile($_, "data $_") foreach @inFiles ; # # { # title "$TopType - Hash Ref: to filename" ; # # my $output ; # ok &$Func( { $inFiles[0] => $outFiles[0], # $inFiles[1] => $outFiles[1], # $inFiles[2] => $outFiles[2] } ), ' Compressed ok' ; # # foreach (0 .. 2) # { # my $got = anyUncompress($outFiles[$_]); # is $got, "data $inFiles[$_]", " Uncompressed $_ matches original"; # } # } # # { # title "$TopType - Hash Ref: to buffer" ; # # my @buffer ; # ok &$Func( { $inFiles[0] => \$buffer[0], # $inFiles[1] => \$buffer[1], # $inFiles[2] => \$buffer[2] } ), ' Compressed ok' ; # # foreach (0 .. 2) # { # my $got = anyUncompress(\$buffer[$_]); # is $got, "data $inFiles[$_]", " Uncompressed $_ matches original"; # } # } # # { # title "$TopType - Hash Ref: to undef" ; # # my @buffer ; # my %hash = ( $inFiles[0] => undef, # $inFiles[1] => undef, # $inFiles[2] => undef, # ); # # ok &$Func( \%hash ), ' Compressed ok' ; # # foreach (keys %hash) # { # my $got = anyUncompress(\$hash{$_}); # is $got, "data $_", " Uncompressed $_ matches original"; # } # } # # { # title "$TopType - Filename to Hash Ref" ; # # my %output ; # ok &$Func( $inFiles[0] => \%output), ' Compressed ok' ; # # is keys %output, 1, " one pair in hash" ; # my ($k, $v) = each %output; # is $k, $inFiles[0], " key is '$inFiles[0]'"; # my $got = anyUncompress($v); # is $got, "data $inFiles[0]", " Uncompressed matches original"; # } # # { # title "$TopType - File Glob to Hash Ref" ; # # my %output ; # ok &$Func( '' => \%output), ' Compressed ok' ; # # is keys %output, 4, " four pairs in hash" ; # foreach my $fil (@inFiles) # { # ok exists $output{$fil}, " key '$fil' exists" ; # my $got = anyUncompress($output{$fil}); # is $got, "data $fil", " Uncompressed matches original"; # } # } # # # } # foreach my $bit ($CompressClass) # { # my $Error = getErrorRef($bit); # my $Func = getTopFuncRef($bit); # my $TopType = getTopFuncName($bit); # # my $TopTypeInverse = getInverse($bit); # my $FuncInverse = getTopFuncRef($TopTypeInverse); # # my @inFiles = map { "in$_.tmp" } 1..4; # my @outFiles = map { "out$_.tmp" } 1..4; # my $lex = new LexFile(@inFiles, @outFiles); # # writeFile($_, "data $_") foreach @inFiles ; # # # # # if (0) # # { # # title "$TopType - Hash Ref to Array Ref" ; # # # # my @output = ('first') ; # # ok &$Func( { \@input, \@output } , AutoClose => 0), ' Compressed ok' ; # # # # is $output[0], 'first', " Array[0] unchanged"; # # # # is_deeply \@input, \@keep, " Input array not changed" ; # # my @got = shift @output; # # foreach (@output) { push @got, anyUncompress($_) } # # # # is_deeply \@got, ['first', @expected], " Got Expected uncompressed data"; # # # # } # # # # if (0) # # { # # title "$TopType - From Array Ref to Buffer" ; # # # # # rewind the filehandle # # $of->open("<$file1") ; # # # # my $output ; # # ok &$Func(\@input, \$output, AutoClose => 0), ' Compressed ok' ; # # # # my $got = anyUncompress(\$output); # # # # is $got, join('', @expected), " Got Expected uncompressed data"; # # } # # # # if (0) # # { # # title "$TopType - From Array Ref to Filename" ; # # # # my ($file3) = ("file3"); # # my $lex = new LexFile($file3) ; # # # # # rewind the filehandle # # $of->open("<$file1") ; # # # # my $output ; # # ok &$Func(\@input, $file3, AutoClose => 0), ' Compressed ok' ; # # # # my $got = anyUncompress($file3); # # # # is $got, join('', @expected), " Got Expected uncompressed data"; # # } # # # # if (0) # # { # # title "$TopType - From Array Ref to Filehandle" ; # # # # my ($file3) = ("file3"); # # my $lex = new LexFile($file3) ; # # # # my $fh3 = new IO::File ">$file3"; # # # # # rewind the filehandle # # $of->open("<$file1") ; # # # # my $output ; # # ok &$Func(\@input, $fh3, AutoClose => 0), ' Compressed ok' ; # # # # $fh3->close(); # # # # my $got = anyUncompress($file3); # # # # is $got, join('', @expected), " Got Expected uncompressed data"; # # } # } foreach my $bit ($CompressClass ) { my $Error = getErrorRef($bit); my $Func = getTopFuncRef($bit); my $TopType = getTopFuncName($bit); for my $files ( [qw(a1)], [qw(a1 a2 a3)] ) { my $tmpDir1 ; my $tmpDir2 ; my $lex = new LexDir($tmpDir1, $tmpDir2) ; my $d1 = quotemeta $tmpDir1 ; my $d2 = quotemeta $tmpDir2 ; ok -d $tmpDir1, " Temp Directory $tmpDir1 exists"; my @files = map { "$tmpDir1/$_.tmp" } @$files ; foreach (@files) { writeFile($_, "abc $_") } my @expected = map { "abc $_" } @files ; my @outFiles = map { s/$d1/$tmpDir2/; $_ } @files ; { title "$TopType - From FileGlob to FileGlob files [@$files]" ; ok &$Func("<$tmpDir1/a*.tmp>" => "<$tmpDir2/a#1.tmp>"), ' Compressed ok' or diag $$Error ; my @copy = @expected; for my $file (@outFiles) { is anyUncompress($file), shift @copy, " got expected from $file" ; } is @copy, 0, " got all files"; } { title "$TopType - From FileGlob to Array files [@$files]" ; my @buffer = ('first') ; ok &$Func("<$tmpDir1/a*.tmp>" => \@buffer), ' Compressed ok' or diag $$Error ; is shift @buffer, 'first'; my @copy = @expected; for my $buffer (@buffer) { is anyUncompress($buffer), shift @copy, " got expected " ; } is @copy, 0, " got all files"; } foreach my $ms (@MultiValues) { { title "$TopType - From FileGlob to Buffer files [@$files], MS $ms" ; my $buffer ; ok &$Func("<$tmpDir1/a*.tmp>" => \$buffer, MultiStream => $ms), ' Compressed ok' or diag $$Error ; #hexDump(\$buffer); my $got = anyUncompress([ \$buffer, MultiStream => $ms ]); is $got, join("", @expected), " got expected" ; my @headers = getHeaders(\$buffer); is @headers, $ms ? @files : 1, " Header count ok"; } { title "$TopType - From FileGlob to Filename files [@$files], MS $ms" ; my $lex = new LexFile(my $filename) ; ok &$Func("<$tmpDir1/a*.tmp>" => $filename, MultiStream => $ms), ' Compressed ok' or diag $$Error ; #hexDump(\$buffer); my $got = anyUncompress([$filename, MultiStream => $ms]); is $got, join("", @expected), " got expected" ; my @headers = getHeaders($filename); is @headers, $ms ? @files : 1, " Header count ok"; } { title "$TopType - From FileGlob to Filehandle files [@$files], MS $ms" ; my $lex = new LexFile(my $filename) ; my $fh = new IO::File ">$filename"; ok &$Func("<$tmpDir1/a*.tmp>" => $fh, MultiStream => $ms, AutoClose => 1), ' Compressed ok' or diag $$Error ; #hexDump(\$buffer); my $got = anyUncompress([$filename, MultiStream => $ms]); is $got, join("", @expected), " got expected" ; my @headers = getHeaders($filename); is @headers, $ms ? @files : 1, " Header count ok"; } } } } foreach my $bit ($UncompressClass, 'IO::Uncompress::AnyUncompress', ) { my $Error = getErrorRef($bit); my $Func = getTopFuncRef($bit); my $TopType = getTopFuncName($bit); my $buffer = $OriginalContent1; my $buffer2 = $OriginalContent2; my $keep_orig = $buffer; my $comp = compressBuffer($UncompressClass, $buffer) ; my $comp2 = compressBuffer($UncompressClass, $buffer2) ; my $keep_comp = $comp; my $incumbent = "incumbent data" ; my @opts = (Strict => 1); push @opts, (RawInflate => 1, UnLzma => 1) if $bit eq 'IO::Uncompress::AnyUncompress'; for my $append (0, 1) { my $expected = $buffer ; $expected = $incumbent . $buffer if $append ; { title "$TopType - From Buff to Buff, Append($append)" ; my $output ; $output = $incumbent if $append ; ok &$Func(\$comp, \$output, Append => $append, @opts), ' Uncompressed ok' ; is $keep_comp, $comp, " Input buffer not changed" ; is $output, $expected, " Uncompressed matches original"; } { title "$TopType - From Buff to Array, Append($append)" ; my @output = ('first'); #$output = $incumbent if $append ; ok &$Func(\$comp, \@output, Append => $append, @opts), ' Uncompressed ok' ; is $keep_comp, $comp, " Input buffer not changed" ; is $output[0], 'first', " Uncompressed matches original"; is ${ $output[1] }, $buffer, " Uncompressed matches original" or diag $output[1] ; is @output, 2, " only 2 elements in the array" ; } { title "$TopType - From Buff to Filename, Append($append)" ; my $lex = new LexFile(my $out_file) ; if ($append) { writeFile($out_file, $incumbent) } else { ok ! -e $out_file, " Output file does not exist" } ok &$Func(\$comp, $out_file, Append => $append, @opts), ' Uncompressed ok' ; ok -e $out_file, " Created output file"; my $content = readFile($out_file) ; is $keep_comp, $comp, " Input buffer not changed" ; is $content, $expected, " Uncompressed matches original"; } { title "$TopType - From Buff to Handle, Append($append)" ; my $lex = new LexFile(my $out_file) ; my $of ; if ($append) { writeFile($out_file, $incumbent) ; $of = new IO::File "+< $out_file" ; } else { ok ! -e $out_file, " Output file does not exist" ; $of = new IO::File "> $out_file" ; } isa_ok $of, 'IO::File', ' $of' ; ok &$Func(\$comp, $of, Append => $append, AutoClose => 1, @opts), ' Uncompressed ok' ; ok -e $out_file, " Created output file"; my $content = readFile($out_file) ; is $keep_comp, $comp, " Input buffer not changed" ; is $content, $expected, " Uncompressed matches original"; } { title "$TopType - From Filename to Filename, Append($append)" ; my $lex = new LexFile(my $in_file, my $out_file) ; if ($append) { writeFile($out_file, $incumbent) } else { ok ! -e $out_file, " Output file does not exist" } writeFile($in_file, $comp); ok &$Func($in_file, $out_file, Append => $append, @opts), ' Uncompressed ok' ; ok -e $out_file, " Created output file"; my $content = readFile($out_file) ; is $keep_comp, $comp, " Input buffer not changed" ; is $content, $expected, " Uncompressed matches original"; } { title "$TopType - From Filename to Handle, Append($append)" ; my $lex = new LexFile(my $in_file, my $out_file) ; my $out ; if ($append) { writeFile($out_file, $incumbent) ; $out = new IO::File "+< $out_file" ; } else { ok ! -e $out_file, " Output file does not exist" ; $out = new IO::File "> $out_file" ; } isa_ok $out, 'IO::File', ' $out' ; writeFile($in_file, $comp); ok &$Func($in_file, $out, Append => $append, AutoClose => 1, @opts), ' Uncompressed ok' ; ok -e $out_file, " Created output file"; my $content = readFile($out_file) ; is $keep_comp, $comp, " Input buffer not changed" ; is $content, $expected, " Uncompressed matches original"; } { title "$TopType - From Filename to Buffer, Append($append)" ; my $lex = new LexFile(my $in_file) ; writeFile($in_file, $comp); my $output ; $output = $incumbent if $append ; ok &$Func($in_file, \$output, Append => $append, @opts), ' Uncompressed ok' ; is $keep_comp, $comp, " Input buffer not changed" ; is $output, $expected, " Uncompressed matches original"; } { title "$TopType - From Handle to Filename, Append($append)" ; my $lex = new LexFile(my $in_file, my $out_file) ; if ($append) { writeFile($out_file, $incumbent) } else { ok ! -e $out_file, " Output file does not exist" } writeFile($in_file, $comp); my $in = new IO::File "<$in_file" ; ok &$Func($in, $out_file, Append => $append, @opts), ' Uncompressed ok' ; ok -e $out_file, " Created output file"; my $content = readFile($out_file) ; is $keep_comp, $comp, " Input buffer not changed" ; is $content, $expected, " Uncompressed matches original"; } { title "$TopType - From Handle to Handle, Append($append)" ; my $lex = new LexFile(my $in_file, my $out_file) ; my $out ; if ($append) { writeFile($out_file, $incumbent) ; $out = new IO::File "+< $out_file" ; } else { ok ! -e $out_file, " Output file does not exist" ; $out = new IO::File "> $out_file" ; } isa_ok $out, 'IO::File', ' $out' ; writeFile($in_file, $comp); my $in = new IO::File "<$in_file" ; ok &$Func($in, $out, Append => $append, AutoClose => 1, @opts), ' Uncompressed ok' ; ok -e $out_file, " Created output file"; my $content = readFile($out_file) ; is $keep_comp, $comp, " Input buffer not changed" ; is $content, $expected, " Uncompressed matches original"; } { title "$TopType - From Filename to Buffer, Append($append)" ; my $lex = new LexFile(my $in_file) ; writeFile($in_file, $comp); my $in = new IO::File "<$in_file" ; my $output ; $output = $incumbent if $append ; ok &$Func($in, \$output, Append => $append, @opts), ' Uncompressed ok' ; is $keep_comp, $comp, " Input buffer not changed" ; is $output, $expected, " Uncompressed matches original"; } { title "$TopType - From stdin (via '-') to Buffer content, Append($append) " ; my $lex = new LexFile(my $in_file) ; writeFile($in_file, $comp); open(SAVEIN, "<&STDIN"); my $dummy = fileno SAVEIN ; ok open(STDIN, "<$in_file"), " redirect STDIN"; my $output ; $output = $incumbent if $append ; ok &$Func('-', \$output, Append => $append, @opts), ' Uncompressed ok' or diag $$Error ; open(STDIN, "<&SAVEIN"); is $keep_comp, $comp, " Input buffer not changed" ; is $output, $expected, " Uncompressed matches original"; } } { title "$TopType - From Handle to Buffer, InputLength" ; my $lex = new LexFile(my $in_file, my $out_file) ; my $out ; my $expected = $buffer ; my $appended = 'appended'; my $len_appended = length $appended; writeFile($in_file, $comp . $appended . $comp . $appended) ; my $in = new IO::File "<$in_file" ; ok &$Func($in, \$out, Transparent => 0, InputLength => length $comp, @opts), ' Uncompressed ok' ; is $out, $expected, " Uncompressed matches original"; my $buff; is $in->read($buff, $len_appended), $len_appended, " Length of Appended data ok"; is $buff, $appended, " Appended data ok"; $out = ''; ok &$Func($in, \$out, Transparent => 0, InputLength => length $comp, @opts), ' Uncompressed ok' ; is $out, $expected, " Uncompressed matches original"; $buff = ''; is $in->read($buff, $len_appended), $len_appended, " Length of Appended data ok"; is $buff, $appended, " Appended data ok"; } for my $stdin ('-', *STDIN) # , \*STDIN) { title "$TopType - From stdin (via $stdin) to Buffer content, InputLength" ; my $lex = new LexFile my $in_file ; my $expected = $buffer ; my $appended = 'appended'; my $len_appended = length $appended; writeFile($in_file, $comp . $appended ) ; open(SAVEIN, "<&STDIN"); my $dummy = fileno SAVEIN ; ok open(STDIN, "<$in_file"), " redirect STDIN"; my $output ; ok &$Func($stdin, \$output, Transparent => 0, InputLength => length $comp, @opts), ' Uncompressed ok' or diag $$Error ; my $buff ; is read(STDIN, $buff, $len_appended), $len_appended, " Length of Appended data ok"; is $output, $expected, " Uncompressed matches original"; is $buff, $appended, " Appended data ok"; open(STDIN, "<&SAVEIN"); } } foreach my $bit ($UncompressClass, 'IO::Uncompress::AnyUncompress', ) { # TODO -- Add Append mode tests my $Error = getErrorRef($bit); my $Func = getTopFuncRef($bit); my $TopType = getTopFuncName($bit); my $buffer = "abcde" ; my $keep_orig = $buffer; my $null = compressBuffer($UncompressClass, "") ; my $undef = compressBuffer($UncompressClass, undef) ; my $comp = compressBuffer($UncompressClass, $buffer) ; my $keep_comp = $comp; my @opts = (); @opts = (RawInflate => 1, UnLzma => 1) if $bit eq 'IO::Uncompress::AnyUncompress'; my $incumbent = "incumbent data" ; my $lex = new LexFile(my $file1, my $file2) ; writeFile($file1, compressBuffer($UncompressClass, $OriginalContent1)); writeFile($file2, compressBuffer($UncompressClass, $OriginalContent2)); my $of = new IO::File "<$file1" ; ok $of, " Created output filehandle" ; #my @input = ($file2, \$undef, \$null, \$comp, $of) ; #my @expected = ('data2', '', '', 'abcde', 'data1'); my @input = ($file1, $file2); my @expected = ($OriginalContent1, $OriginalContent2); my @keep = @input ; { title "$TopType - From ArrayRef to Buffer" ; my $output ; ok &$Func(\@input, \$output, AutoClose => 0, @opts), ' UnCompressed ok' ; is $output, join('', @expected) } { title "$TopType - From ArrayRef to Filename" ; my $lex = new LexFile my $output; $of->open("<$file1") ; ok &$Func(\@input, $output, AutoClose => 0, @opts), ' UnCompressed ok' ; is readFile($output), join('', @expected) } { title "$TopType - From ArrayRef to Filehandle" ; my $lex = new LexFile my $output; my $fh = new IO::File ">$output" ; $of->open("<$file1") ; ok &$Func(\@input, $fh, AutoClose => 0, @opts), ' UnCompressed ok' ; $fh->close; is readFile($output), join('', @expected) } { title "$TopType - From Array Ref to Array Ref" ; my @output = (\'first') ; $of->open("<$file1") ; ok &$Func(\@input, \@output, AutoClose => 0, @opts), ' UnCompressed ok' ; is_deeply \@input, \@keep, " Input array not changed" ; is_deeply [map { defined $$_ ? $$_ : "" } @output], ['first', @expected], " Got Expected uncompressed data"; } } foreach my $bit ($UncompressClass, 'IO::Uncompress::AnyUncompress', ) { # TODO -- Add Append mode tests my $Error = getErrorRef($bit); my $Func = getTopFuncRef($bit); my $TopType = getTopFuncName($bit); my $tmpDir1 ; my $tmpDir2 ; my $lex = new LexDir($tmpDir1, $tmpDir2) ; my $d1 = quotemeta $tmpDir1 ; my $d2 = quotemeta $tmpDir2 ; my @opts = (); @opts = (RawInflate => 1, UnLzma => 1) if $bit eq 'IO::Uncompress::AnyUncompress'; ok -d $tmpDir1, " Temp Directory $tmpDir1 exists"; my @files = map { "$tmpDir1/$_.tmp" } qw( a1 a2 a3) ; foreach (@files) { writeFile($_, compressBuffer($UncompressClass, "abc $_")) } my @expected = map { "abc $_" } @files ; my @outFiles = map { s/$d1/$tmpDir2/; $_ } @files ; { title "$TopType - From FileGlob to FileGlob" ; ok &$Func("<$tmpDir1/a*.tmp>" => "<$tmpDir2/a#1.tmp>", @opts), ' UnCompressed ok' or diag $$Error ; my @copy = @expected; for my $file (@outFiles) { is readFile($file), shift @copy, " got expected from $file" ; } is @copy, 0, " got all files"; } { title "$TopType - From FileGlob to Arrayref" ; my @output = (\'first'); ok &$Func("<$tmpDir1/a*.tmp>" => \@output, @opts), ' UnCompressed ok' or diag $$Error ; my @copy = ('first', @expected); for my $data (@output) { is $$data, shift @copy, " got expected data" ; } is @copy, 0, " got all files"; } { title "$TopType - From FileGlob to Buffer" ; my $output ; ok &$Func("<$tmpDir1/a*.tmp>" => \$output, @opts), ' UnCompressed ok' or diag $$Error ; is $output, join('', @expected), " got expected uncompressed data"; } { title "$TopType - From FileGlob to Filename" ; my $lex = new LexFile my $output ; ok ! -e $output, " $output does not exist" ; ok &$Func("<$tmpDir1/a*.tmp>" => $output, @opts), ' UnCompressed ok' or diag $$Error ; ok -e $output, " $output does exist" ; is readFile($output), join('', @expected), " got expected uncompressed data"; } { title "$TopType - From FileGlob to Filehandle" ; my $lex = new LexFile my $output ; my $fh = new IO::File ">$output" ; ok &$Func("<$tmpDir1/a*.tmp>" => $fh, AutoClose => 1, @opts), ' UnCompressed ok' or diag $$Error ; ok -e $output, " $output does exist" ; is readFile($output), join('', @expected), " got expected uncompressed data"; } } foreach my $TopType ($CompressClass # TODO -- add the inflate classes ) { my $Error = getErrorRef($TopType); my $Func = getTopFuncRef($TopType); my $Name = getTopFuncName($TopType); title "More write tests" ; my $lex = new LexFile(my $file1, my $file2, my $file3) ; writeFile($file1, "F1"); writeFile($file2, "F2"); writeFile($file3, "F3"); # my @data = ( # [ '[\"ab", \"cd"]', "abcd" ], # # [ '[\"a", $fh1, \"bc"]', "aF1bc"], # ) ; # # # foreach my $data (@data) # { # my ($send, $get) = @$data ; # # my $fh1 = new IO::File "< $file1" ; # my $fh2 = new IO::File "< $file2" ; # my $fh3 = new IO::File "< $file3" ; # # title "$send"; # my ($copy); # eval "\$copy = $send"; # my $Answer ; # ok &$Func($copy, \$Answer), " $Name ok"; # # my $got = anyUncompress(\$Answer); # is $got, $get, " got expected output" ; # ok ! $$Error, " no error" # or diag "Error is $$Error"; # # } title "Array Input Error tests" ; my @data = ( [ '[]', "empty array reference"], [ '[[]]', "unknown input parameter"], [ '[[[]]]', "unknown input parameter"], [ '[[\"ab"], [\"cd"]]', "unknown input parameter"], [ '[\""]', "not a filename"], [ '[\undef]', "not a filename"], [ '[\"abcd"]', "not a filename"], [ '[\&xx]', "unknown input parameter"], [ '[$fh2]', "not a filename"], ) ; foreach my $data (@data) { my ($send, $get) = @$data ; my $fh1 = new IO::File "< $file1" ; my $fh2 = new IO::File "< $file2" ; my $fh3 = new IO::File "< $file3" ; title "$send"; my($copy); eval "\$copy = $send"; my $Answer ; my $a ; eval { $a = &$Func($copy, \$Answer) }; ok ! $a, " $Name fails"; is $$Error, $get, " got error message"; } @data = ( '[""]', '[undef]', ) ; foreach my $send (@data) { title "$send"; my($copy); eval "\$copy = $send"; my $Answer ; eval { &$Func($copy, \$Answer) } ; like $@, mkErr("^$TopFuncName: input filename is undef or null string"), " got error message"; } } { # check setting $\ my $CompFunc = getTopFuncRef($CompressClass); my $UncompFunc = getTopFuncRef($UncompressClass); my $lex = new LexFile my $file ; local $\ = "\n" ; my $input = "hello world"; my $compressed ; my $output; ok &$CompFunc(\$input => \$compressed), ' Compressed ok' ; ok &$UncompFunc(\$compressed => $file), ' UnCompressed ok' ; my $content = readFile($file) ; is $content, $input, "round trip ok" ; } SKIP: { #95494: IO::Uncompress::Gunzip: Can no longer gunzip to in-memory file handle skip "open filehandle to buffer not supported in Perl $]", 7 if $] < 5.008 ; my $CompFunc = getTopFuncRef($CompressClass); my $UncompFunc = getTopFuncRef($UncompressClass); my $input = "hello world"; my $compressed ; ok open my $fh_in1, '<', \$input ; ok open my $fh_out1, '>', \$compressed ; ok &$CompFunc($fh_in1 => $fh_out1), ' Compressed ok' ; my $output; ok open my $fh_in2, '<', \$compressed ; ok open my $fh_out2, '>', \$output ; ok &$UncompFunc($fh_in2 => $fh_out2), ' UnCompressed ok' ; is $output, $input, "round trip ok" ; } } # TODO add more error cases 1; libio-compress-lzma-perl-2.093/t/compress/prime.pl000066400000000000000000000050331357305603400221350ustar00rootroot00000000000000 use lib 't'; use strict; use warnings; use bytes; use Test::More ; use CompTestUtils; our ($extra); BEGIN { plan skip_all => "Lengthy Tests Disabled\n" . "set COMPRESS_ZLIB_RUN_ALL or COMPRESS_ZLIB_RUN_MOST to run this test suite" unless defined $ENV{COMPRESS_ZLIB_RUN_ALL} or defined $ENV{COMPRESS_ZLIB_RUN_MOST}; # use Test::NoWarnings, if available $extra = 0 ; $extra = 1 if eval { require Test::NoWarnings ; import Test::NoWarnings; 1 }; } sub run { my $CompressClass = identify(); my $UncompressClass = getInverse($CompressClass); my $Error = getErrorRef($CompressClass); my $UnError = getErrorRef($UncompressClass); my $hello = < (length($compressed) * 6 * 7) + 1 + $extra ; is anyUncompress(\$cc), $hello ; for my $blocksize (1, 2, 13) { for my $i (0 .. length($compressed) - 1) { for my $useBuf (0 .. 1) { print "#\n# BlockSize $blocksize, Length $i, Buffer $useBuf\n#\n" ; my $lex = new LexFile my $name ; my $prime = substr($compressed, 0, $i); my $rest = substr($compressed, $i); my $start ; if ($useBuf) { $start = \$rest ; } else { $start = $name ; writeFile($name, $rest); } #my $gz = new $UncompressClass $name, my $gz = new $UncompressClass $start, -Append => 1, -BlockSize => $blocksize, -Prime => $prime, -Transparent => 0 ; ok $gz; ok ! $gz->error() ; my $un ; my $status = 1 ; $status = $gz->read($un) while $status > 0 ; is $status, 0 ; ok ! $gz->error() or print "Error is '" . $gz->error() . "'\n"; is $un, $hello ; ok $gz->eof() ; ok $gz->close() ; } } } } 1; libio-compress-lzma-perl-2.093/t/compress/tied.pl000066400000000000000000000320271357305603400217510ustar00rootroot00000000000000 use lib 't'; use strict; use warnings; use bytes; use Test::More ; use CompTestUtils; our ($BadPerl, $UncompressClass); BEGIN { plan(skip_all => "Tied Filehandle needs Perl 5.005 or better" ) if $] < 5.005 ; # use Test::NoWarnings, if available my $extra = 0 ; $extra = 1 if eval { require Test::NoWarnings ; import Test::NoWarnings; 1 }; my $tests ; $BadPerl = ($] >= 5.006 and $] <= 5.008) ; if ($BadPerl) { $tests = 241 ; } else { $tests = 249 ; } plan tests => $tests + $extra ; } use IO::Handle qw(SEEK_SET SEEK_CUR SEEK_END); sub myGZreadFile { my $filename = shift ; my $init = shift ; my $fil = new $UncompressClass $filename, -Strict => 1, -Append => 1 ; my $data ; $data = $init if defined $init ; 1 while $fil->read($data) > 0; $fil->close ; return $data ; } sub run { my $CompressClass = identify(); $UncompressClass = getInverse($CompressClass); my $Error = getErrorRef($CompressClass); my $UnError = getErrorRef($UncompressClass); { next if $BadPerl ; title "Testing $CompressClass"; my $x ; my $gz = new $CompressClass(\$x); my $buff ; eval { getc($gz) } ; like $@, mkErr("^getc Not Available: File opened only for output"); eval { read($gz, $buff, 1) } ; like $@, mkErr("^read Not Available: File opened only for output"); eval { <$gz> } ; like $@, mkErr("^readline Not Available: File opened only for output"); } { next if $BadPerl; $UncompressClass = getInverse($CompressClass); title "Testing $UncompressClass"; my $gc ; my $guz = new $CompressClass(\$gc); $guz->write("abc") ; $guz->close(); my $x ; my $gz = new $UncompressClass(\$gc); my $buff ; eval { print $gz "abc" } ; like $@, mkErr("^print Not Available: File opened only for intput"); eval { printf $gz "fmt", "abc" } ; like $@, mkErr("^printf Not Available: File opened only for intput"); #eval { write($gz, $buff, 1) } ; #like $@, mkErr("^write Not Available: File opened only for intput"); } { $UncompressClass = getInverse($CompressClass); title "Testing $CompressClass and $UncompressClass"; { # Write # these tests come almost 100% from IO::String my $lex = new LexFile my $name ; my $io = $CompressClass->new($name); is $io->tell(), 0 ; my $heisan = "Heisan\n"; print $io $heisan ; ok ! $io->eof; is $io->tell(), length($heisan) ; print($io "a", "b", "c"); { local($\) = "\n"; print $io "d", "e"; local($,) = ","; print $io "f", "g", "h"; } my $foo = "1234567890"; ok syswrite($io, $foo, length($foo)) == length($foo) ; if ( $] < 5.6 ) { is $io->syswrite($foo, length $foo), length $foo } else { is $io->syswrite($foo), length $foo } ok $io->syswrite($foo, length($foo)) == length $foo; ok $io->write($foo, length($foo), 5) == 5; ok $io->write("xxx\n", 100, -1) == 1; for (1..3) { printf $io "i(%d)", $_; $io->printf("[%d]\n", $_); } select $io; print "\n"; select STDOUT; close $io ; ok $io->eof; is myGZreadFile($name), "Heisan\nabcde\nf,g,h\n" . ("1234567890" x 3) . "67890\n" . "i(1)[1]\ni(2)[2]\ni(3)[3]\n\n"; } { # Read my $str = <eof, " Not EOF"; is $io->tell(), 0, " Tell is 0" ; my @lines = <$io>; is @lines, 6, " Line is 6" or print "# Got " . scalar(@lines) . " lines, expected 6\n" ; is $lines[1], "of a paragraph\n" ; is join('', @lines), $str ; is $., 6; is $io->tell(), length($str) ; ok $io->eof; ok ! ( defined($io->getline) || (@tmp = $io->getlines) || defined(<$io>) || defined($io->getc) || read($io, $buf, 100) != 0) ; } { local $/; # slurp mode my $io = $UncompressClass->new($name); ok !$io->eof; my @lines = $io->getlines; ok $io->eof; ok @lines == 1 && $lines[0] eq $str; $io = $UncompressClass->new($name); ok ! $io->eof; my $line = <$io>; ok $line eq $str; ok $io->eof; } { local $/ = ""; # paragraph mode my $io = $UncompressClass->new($name); ok ! $io->eof; my @lines = <$io>; ok $io->eof; ok @lines == 2 or print "# Got " . scalar(@lines) . " lines, expected 2\n" ; ok $lines[0] eq "This is an example\nof a paragraph\n\n\n" or print "# $lines[0]\n"; ok $lines[1] eq "and a single line.\n\n"; } { local $/ = "is"; my $io = $UncompressClass->new($name); my @lines = (); my $no = 0; my $err = 0; ok ! $io->eof; while (<$io>) { push(@lines, $_); $err++ if $. != ++$no; } ok $err == 0 ; ok $io->eof; ok @lines == 3 or print "# Got " . scalar(@lines) . " lines, expected 3\n" ; ok join("-", @lines) eq "This- is- an example\n" . "of a paragraph\n\n\n" . "and a single line.\n\n"; } # Test read { my $io = $UncompressClass->new($name); if (! $BadPerl) { eval { read($io, $buf, -1) } ; like $@, mkErr("length parameter is negative"); } is read($io, $buf, 0), 0, "Requested 0 bytes" ; ok read($io, $buf, 3) == 3 ; ok $buf eq "Thi"; ok sysread($io, $buf, 3, 2) == 3 ; ok $buf eq "Ths i" or print "# [$buf]\n" ;; ok ! $io->eof; # $io->seek(-4, 2); # # ok ! $io->eof; # # ok read($io, $buf, 20) == 4 ; # ok $buf eq "e.\n\n"; # # ok read($io, $buf, 20) == 0 ; # ok $buf eq ""; # # ok ! $io->eof; } } { # Read from non-compressed file my $str = < 1 ; ok defined $io; ok ! $io->eof; ok $io->tell() == 0 ; my @lines = <$io>; ok @lines == 6; ok $lines[1] eq "of a paragraph\n" ; ok join('', @lines) eq $str ; ok $. == 6; ok $io->tell() == length($str) ; ok $io->eof; ok ! ( defined($io->getline) || (@tmp = $io->getlines) || defined(<$io>) || defined($io->getc) || read($io, $buf, 100) != 0) ; } { local $/; # slurp mode my $io = $UncompressClass->new($name); ok ! $io->eof; my @lines = $io->getlines; ok $io->eof; ok @lines == 1 && $lines[0] eq $str; $io = $UncompressClass->new($name); ok ! $io->eof; my $line = <$io>; ok $line eq $str; ok $io->eof; } { local $/ = ""; # paragraph mode my $io = $UncompressClass->new($name); ok ! $io->eof; my @lines = <$io>; ok $io->eof; ok @lines == 2 or print "# expected 2 lines, got " . scalar(@lines) . "\n"; ok $lines[0] eq "This is an example\nof a paragraph\n\n\n" or print "# [$lines[0]]\n" ; ok $lines[1] eq "and a single line.\n\n"; } { local $/ = "is"; my $io = $UncompressClass->new($name); my @lines = (); my $no = 0; my $err = 0; ok ! $io->eof; while (<$io>) { push(@lines, $_); $err++ if $. != ++$no; } ok $err == 0 ; ok $io->eof; ok @lines == 3 ; ok join("-", @lines) eq "This- is- an example\n" . "of a paragraph\n\n\n" . "and a single line.\n\n"; } # Test read { my $io = $UncompressClass->new($name); ok read($io, $buf, 3) == 3 ; ok $buf eq "Thi"; ok sysread($io, $buf, 3, 2) == 3 ; ok $buf eq "Ths i"; ok ! $io->eof; # $io->seek(-4, 2); # # ok ! $io->eof; # # ok read($io, $buf, 20) == 4 ; # ok $buf eq "e.\n\n"; # # ok read($io, $buf, 20) == 0 ; # ok $buf eq ""; # # ok ! $io->eof; } } { # Vary the length parameter in a read my $str = <new($name, -Append => $append, -Transparent => $trans); my $buf; is $io->tell(), 0; if ($append) { 1 while $io->read($buf, $bufsize) > 0; } else { my $tmp ; $buf .= $tmp while $io->read($tmp, $bufsize) > 0 ; } is length $buf, length $str; ok $buf eq $str ; ok ! $io->error() ; ok $io->eof; } } } } } } 1; libio-compress-lzma-perl-2.093/t/compress/truncate.pl000066400000000000000000000242211357305603400226460ustar00rootroot00000000000000 use lib 't'; use strict; use warnings; use bytes; use Test::More ; use CompTestUtils; sub run { my $CompressClass = identify(); my $UncompressClass = getInverse($CompressClass); my $Error = getErrorRef($CompressClass); my $UnError = getErrorRef($UncompressClass); # my $hello = <{HeaderLength}; my $trailer_size = $info->{TrailerLength}; my $fingerprint_size = $info->{FingerprintLength}; ok 1, "Compressed size is " . length($compressed) ; ok 1, "Fingerprint size is $fingerprint_size" ; ok 1, "Header size is $header_size" ; ok 1, "Trailer size is $trailer_size" ; foreach my $fb ( qw( filehandle buffer ) ) { for my $trans ( 0 .. 1) { title "Truncating $CompressClass, Source $fb, Transparent $trans"; foreach my $i (1 .. $fingerprint_size-1) { my $lex = new LexFile my $name ; my $input; title "Fingerprint Truncation - length $i, Transparent $trans"; my $part = substr($compressed, 0, $i); if ($fb eq 'filehandle') { writeFile($name, $part); $input = $name ; } else { $input = \$part; } my $gz = new $UncompressClass $input, -BlockSize => $blocksize, -Transparent => $trans; if ($trans) { ok $gz; ok ! $gz->error() ; my $buff ; is $gz->read($buff, 5000), length($part) ; ok $buff eq $part ; ok $gz->eof() ; $gz->close(); } else { ok !$gz; } } # # Any header corruption past the fingerprint is considered catastrophic # so even if Transparent is set, it should still fail # foreach my $i ($fingerprint_size .. $header_size -1) { my $lex = new LexFile my $name ; my $input; title "Header Truncation - length $i, Source $fb, Transparent $trans"; my $part = substr($compressed, 0, $i); if ($fb eq 'filehandle') { writeFile($name, $part); $input = $name ; } else { $input = \$part; } ok ! defined new $UncompressClass $input, -BlockSize => $blocksize, -Transparent => $trans; #ok $gz->eof() ; } # Test corruption directly after the header # In this case the uncompression object will have been created, # so need to check that subsequent reads from the object fail if ($header_size > 0) { for my $mode (qw(block line para record slurp)) { title "Corruption after header - Mode $mode, Source $fb, Transparent $trans"; my $lex = new LexFile my $name ; my $input; my $part = substr($compressed, 0, $header_size); # Append corrupt data $part .= "\xFF" x 100 ; if ($fb eq 'filehandle') { writeFile($name, $part); $input = $name ; } else { $input = \$part; } ok my $gz = new $UncompressClass $input, -Strict => 1, -BlockSize => $blocksize, -Transparent => $trans or diag $$UnError; my $un ; my $status = 1; if ($mode eq 'block') { $status = $gz->read($un) ; is $status, -1, "got -1"; } else { if ($mode eq 'line') { $status = <$gz>; } elsif ($mode eq 'para') { local $/ = "\n\n"; $status = <$gz>; } elsif ($mode eq 'record') { local $/ = \ 4; $status = <$gz>; } elsif ($mode eq 'slurp') { local $/ ; $status = <$gz>; } is $status, undef, "got undef"; } ok $gz->error() ; $gz->close(); } } # Back to truncation tests foreach my $i ($header_size .. length($compressed) - 1 - $trailer_size) { next if $i == 0 ; for my $mode (qw(block line)) { title "Compressed Data Truncation - length $i, MOde $mode, Source $fb, Transparent $trans"; my $lex = new LexFile my $name ; my $input; my $part = substr($compressed, 0, $i); if ($fb eq 'filehandle') { writeFile($name, $part); $input = $name ; } else { $input = \$part; } ok my $gz = new $UncompressClass $input, -Strict => 1, -BlockSize => $blocksize, -Transparent => $trans or diag $$UnError; my $un ; if ($mode eq 'block') { my $status = 1 ; $status = $gz->read($un) while $status > 0 ; cmp_ok $status, "<", 0 ; } else { 1 while <$gz> ; } ok $gz->error() ; cmp_ok $gz->errorNo(), '<', 0 ; # ok $gz->eof() # or die "EOF"; $gz->close(); } } # RawDeflate and Zstandard do not have a trailer next if $CompressClass eq 'IO::Compress::RawDeflate' ; next if $CompressClass eq 'IO::Compress::Zstd' ; title "Compressed Trailer Truncation"; foreach my $i (length($compressed) - $trailer_size .. length($compressed) -1 ) { foreach my $lax (0, 1) { my $lex = new LexFile my $name ; my $input; ok 1, "Compressed Trailer Truncation - Length $i, Lax $lax, Transparent $trans" ; my $part = substr($compressed, 0, $i); if ($fb eq 'filehandle') { writeFile($name, $part); $input = $name ; } else { $input = \$part; } ok my $gz = new $UncompressClass $input, -BlockSize => $blocksize, -Strict => !$lax, -Append => 1, -Transparent => $trans; my $un = ''; my $status = 1 ; $status = $gz->read($un) while $status > 0 ; if ($lax) { is $un, $hello; is $status, 0 or diag "Status $status Error is " . $gz->error() ; ok $gz->eof() or diag "Status $status Error is " . $gz->error() ; ok ! $gz->error() ; } else { cmp_ok $status, "<", 0 or diag "Status $status Error is " . $gz->error() ; ok $gz->eof() or diag "Status $status Error is " . $gz->error() ; ok $gz->error() ; } $gz->close(); } } } } } 1; libio-compress-lzma-perl-2.093/t/compress/zlib-generic.pl000066400000000000000000000112671357305603400234010ustar00rootroot00000000000000 use strict; use warnings; use bytes; use Test::More ; use CompTestUtils; BEGIN { # use Test::NoWarnings, if available my $extra = 0 ; $extra = 1 if eval { require Test::NoWarnings ; import Test::NoWarnings; 1 }; plan tests => 49 + $extra ; } my $CompressClass = identify(); my $UncompressClass = getInverse($CompressClass); my $Error = getErrorRef($CompressClass); my $UnError = getErrorRef($UncompressClass); use Compress::Raw::Zlib; use IO::Handle qw(SEEK_SET SEEK_CUR SEEK_END); sub myGZreadFile { my $filename = shift ; my $init = shift ; my $fil = new $UncompressClass $filename, -Strict => 1, -Append => 1 ; my $data = ''; $data = $init if defined $init ; 1 while $fil->read($data) > 0; $fil->close ; return $data ; } { title "Testing $CompressClass Errors"; } { title "Testing $UncompressClass Errors"; } { title "Testing $CompressClass and $UncompressClass"; { title "flush" ; my $lex = new LexFile my $name ; my $hello = <write($hello), "write" ; ok $x->flush(Z_FINISH), "flush"; ok $x->close, "close" ; } { my $uncomp; ok my $x = new $UncompressClass $name, -Append => 1 ; my $len ; 1 while ($len = $x->read($uncomp)) > 0 ; is $len, 0, "read returned 0"; ok $x->close ; is $uncomp, $hello ; } } if ($CompressClass ne 'RawDeflate') { # write empty file #======================================== my $buffer = ''; { my $x ; ok $x = new $CompressClass(\$buffer) ; ok $x->close ; } my $keep = $buffer ; my $uncomp= ''; { my $x ; ok $x = new $UncompressClass(\$buffer, Append => 1) ; 1 while $x->read($uncomp) > 0 ; ok $x->close ; } ok $uncomp eq '' ; ok $buffer eq $keep ; } { title "inflateSync on plain file"; my $hello = "I am a HAL 9000 computer" x 2001 ; my $k = new $UncompressClass(\$hello, Transparent => 1); ok $k ; # Skip to the flush point -- no-op for plain file my $status = $k->inflateSync(); is $status, 1 or diag $k->error() ; my $rest; is $k->read($rest, length($hello)), length($hello) or diag $k->error() ; ok $rest eq $hello ; ok $k->close(); } { title "$CompressClass: inflateSync for real"; # create a deflate stream with flush points my $hello = "I am a HAL 9000 computer" x 2001 ; my $goodbye = "Will I dream?" x 2010; my ($x, $err, $answer, $X, $Z, $status); my $Answer ; ok ($x = new $CompressClass(\$Answer)); ok $x ; is $x->write($hello), length($hello); # create a flush point ok $x->flush(Z_FULL_FLUSH) ; is $x->write($goodbye), length($goodbye); ok $x->close() ; my $k; $k = new $UncompressClass(\$Answer, BlockSize => 1); ok $k ; my $initial; is $k->read($initial, 1), 1 ; is $initial, substr($hello, 0, 1); # Skip to the flush point $status = $k->inflateSync(); is $status, 1, " inflateSync returned 1" or diag $k->error() ; my $rest; is $k->read($rest, length($hello) + length($goodbye)), length($goodbye) or diag $k->error() ; ok $rest eq $goodbye, " got expected output" ; ok $k->close(); } { title "$CompressClass: inflateSync no FLUSH point"; # create a deflate stream with flush points my $hello = "I am a HAL 9000 computer" x 2001 ; my ($x, $err, $answer, $X, $Z, $status); my $Answer ; ok ($x = new $CompressClass(\$Answer)); ok $x ; is $x->write($hello), length($hello); ok $x->close() ; my $k = new $UncompressClass(\$Answer, BlockSize => 1); ok $k ; my $initial; is $k->read($initial, 1), 1 ; is $initial, substr($hello, 0, 1); # Skip to the flush point $status = $k->inflateSync(); is $status, 0 or diag $k->error() ; ok $k->close(); is $k->inflateSync(), 0 ; } } 1; libio-compress-lzma-perl-2.093/t/meta-json.t000066400000000000000000000004401357305603400207100ustar00rootroot00000000000000BEGIN { if ($ENV{PERL_CORE}) { chdir 't' if -d 't'; @INC = ("../lib", "lib/compress"); } } use lib qw(t t/compress); use Test::More; eval "use Test::CPAN::Meta::JSON"; plan skip_all => "Test::CPAN::Meta::JSON required for testing META.json" if $@; meta_json_ok();libio-compress-lzma-perl-2.093/t/meta-yaml.t000066400000000000000000000004231357305603400207020ustar00rootroot00000000000000BEGIN { if ($ENV{PERL_CORE}) { chdir 't' if -d 't'; @INC = ("../lib", "lib/compress"); } } use lib qw(t t/compress); use Test::More; eval "use Test::CPAN::Meta"; plan skip_all => "Test::CPAN::Meta required for testing META.yml" if $@; meta_yaml_ok();