File Coverage

blib/lib/Archive/SevenZip/API/ArchiveZip.pm
Criterion Covered Total %
statement 38 99 38.3
branch 1 18 5.5
condition 0 18 0.0
subroutine 13 27 48.1
pod 3 18 16.6
total 55 180 30.5


line stmt bran cond sub pod time code
1             package Archive::SevenZip::API::ArchiveZip;
2 1     1   7 use strict;
  1         2  
  1         33  
3 1     1   6 use warnings;
  1         2  
  1         28  
4 1     1   5 use Carp qw(croak);
  1         2  
  1         53  
5 1     1   7 use Encode qw( decode encode );
  1         3  
  1         44  
6 1     1   5 use File::Basename qw(dirname basename);
  1         2  
  1         44  
7 1     1   5 use File::Copy;
  1         2  
  1         66  
8 1     1   7 use Archive::SevenZip 'AZ_OK';
  1         3  
  1         1232  
9              
10             our $VERSION= '0.19';
11              
12             sub new {
13 1     1 0 3 my( $class, %options )= @_;
14 1         5 $options{ sevenZip } = Archive::SevenZip->new();
15 1         4 bless \%options => $class;
16             };
17              
18 2     2 0 12 sub sevenZip { $_[0]->{sevenZip} }
19              
20             =head1 NAME
21              
22             Archive::SevenZip::API::ArchiveZip - Archive::Zip compatibility API
23              
24             =head1 SYNOPSIS
25              
26             my $ar = Archive::SevenZip->archiveZipApi(
27             find => 1,
28             archivename => $archivename,
29             verbose => $verbose,
30             );
31              
32             This module implements just enough of the L
33             API to pass some of the Archive::Zip test files. Ideally you can
34             use this API to enable a script that uses Archive::Zip
35             to also read other archive files supported by 7z.
36              
37             =cut
38              
39             # Helper to decode the hashref/named API
40             sub _params {
41 2     2   6 my( $args, @names ) = @_;
42 2 50       7 if( ref $args->[1] eq 'HASH' ) {
43 0         0 return( $args->[0], @{ $args }{ @names } )
  0         0  
44             } else {
45 2         7 return @$args
46             }
47             }
48              
49             sub read {
50 1     1 0 657 my( $self, $filename ) = _params(\@_, qw(filename));
51 1         4 $self->sevenZip->{archivename} = $filename;
52 1         6 return AZ_OK;
53             }
54              
55             sub writeToFileNamed {
56 1     1 0 3 my( $self, $targetName ) = _params(\@_, qw(fileName));
57              
58 1         4 my $source = $self->sevenZip->archive_or_temp;
59 1         12 copy( $source, $targetName );
60 1         446 return AZ_OK;
61             }
62              
63             sub addFileOrDirectory {
64 0     0 0   my($self, $name, $newName, $compressionLevel)
65             = _params(\@_, qw(name zipName compressionLevel));
66 0 0         $newName = $name
67             unless defined $newName;
68 0           $self->sevenZip->add(
69             items => [ [$name, $newName] ],
70             compression => $compressionLevel
71             );
72             }
73              
74             sub addString {
75 0     0 0   my( $self, $content, $name, %options )
76             = _params(\@_, qw( string zipName compressionLevel ));
77 0           $self->sevenZip->add_scalar($name => $content);
78 0           $self->memberNamed($name, %options);
79             }
80              
81             sub addDirectory {
82             # Create just a directory name
83 0     0 0   my( $self, $name, $target, %options )
84             = _params(\@_, qw( directoryName zipName ));
85 0   0       $target ||= $name;
86              
87 0           $self->sevenZip->add_directory($name, $target, %options);
88 0           $self->memberNamed($target, %options);
89             }
90              
91             sub members {
92 0     0 0   my( $self ) = @_;
93 0           $self->sevenZip->members;
94             }
95              
96             sub memberNames {
97 0     0 0   my( $self ) = @_;
98 0           map { $_->fileName } $self->sevenZip->members;
  0            
99             }
100              
101             sub membersMatching {
102 0     0 0   my( $self, $re, %options ) = @_;
103 0           grep { $_->fileName =~ /$re/ } $self->sevenZip->members;
  0            
104             }
105              
106             =head2 C<< $ar->numberOfMembers >>
107              
108             my $count = $az->numberOfMembers();
109              
110             =cut
111              
112             sub numberOfMembers {
113 0     0 1   my( $self, %options ) = @_;
114 0           my @m = $self->members( %options );
115 0           0+@m
116             }
117              
118             =head2 C<< $az->memberNamed >>
119              
120             my $entry = $az->memberNamed('hello_world.txt');
121             print $entry->fileName, "\n";
122              
123             =cut
124              
125             # Archive::Zip API
126             sub memberNamed {
127             #my( $self, $name, %options )
128 0     0 1   my( $self, $name )
129             = _params( \@_, qw( zipName ));
130             #$self->sevenZip->memberNamed($name, %options );
131 0           $self->sevenZip->memberNamed($name);
132             }
133              
134             sub extractMember {
135             #my( $self, $name, $target, %options ) = @_;
136 0     0 0   my( $self, $name, $target )
137             = _params(\@_, qw( memberOrZipName name ));
138 0 0 0       if( ref $name and $name->can('fileName')) {
139 0           $name = $name->fileName;
140             };
141             #$self->sevenZip->extractMember( $name, $target, %options );
142 0           $self->sevenZip->extractMember( $name, $target );
143             }
144              
145             sub removeMember {
146             #my( $self, $name, $target, %options ) = @_;
147 0     0 0   my( $self, $name )
148             = _params( \@_, qw(memberOrZipName ));
149             # Just for the result:
150 0 0         my $res = ref $name ? $name : $self->memberNamed( $name );
151              
152 0 0 0       if( ref $name and $name->can('fileName')) {
153 0           $name = $name->fileName;
154             };
155             #$self->sevenZip->removeMember( $name, %options );
156 0           $self->sevenZip->removeMember( $name );
157              
158 0           $res
159             }
160              
161             =head2 C<< $ar->replaceMember >>
162              
163             $ar->replaceMember('backup.txt', 'new-backup.txt');
164              
165             Replaces the member in the archive. This is just delete then add.
166              
167             I clearly don't understand the utility of this method. It clearly
168             does not update the content of one file with the content of another
169             file, as the name of the new file can be different.
170              
171             =cut
172              
173             # strikingly similar to Archive::Zip API
174             sub replaceMember {
175 0     0 1   my( $self, $name, $replacement, %_options ) = @_;
176              
177 0           my %options = (%$self, %_options);
178              
179 0 0         if( $^O =~ /MSWin/ ) {
180 0           $name =~ s!/!\\!g;
181             }
182              
183 0           my $res = $self->removeMember( $name );
184 0           $self->add( $replacement );
185              
186 0           $res
187             };
188              
189              
190             sub addFile {
191 0     0 0   my( $self, $name, $target, $compressionLevel )
192             = _params(\@_, qw(filename zipName compressionLevel ));
193 0 0 0       if( ref $name and $name->can('fileName')) {
194 0           $name = $name->fileName;
195             };
196 0   0       $target ||= $name;
197 0           $self->sevenZip->add( items => [[ $name, $target ]]);
198 0           return $self->memberNamed($target);
199             }
200              
201             sub addMember {
202             #my( $self, $name, $target, %options ) = @_;
203 0     0 0   my( $self, $member ) = _param( \@_, qw(member));
204 0           my $target = $member->fileName;
205 0           my $fh = $member->open( binmode => ':raw' );
206 0           local $/;
207 0           my $content = <$fh>;
208 0           $self->sevenZip->add_scalar( $target => $content );
209 0           return $self->memberNamed($target );
210             }
211 1     1   8 { no warnings 'once';
  1         2  
  1         176  
212             *add = \&addMember;
213             }
214              
215             sub addTree {
216 0     0 0   my( $self, $sourceDir, $target, $predicate, %options ) = @_;
217              
218 0 0         croak "Predicates are not supported, sorry"
219             if $predicate;
220              
221 0   0       $target ||= $sourceDir;
222 0 0         croak "Different target for ->addTree not supported, sorry"
223             if $target ne $sourceDir;
224              
225 0           $self->sevenZip->add( items => [[ $sourceDir, $target ]], recursive => 1, %options );
226 0           return $self->memberNamed($target, %options);
227             }
228             *add = \&addMember;
229              
230             __END__