1 package Archive
::Zip
::MemberRead
;
5 Archive::Zip::MemberRead - A wrapper that lets you read Zip archive members as if they were files.
12 use Archive::Zip::MemberRead;
13 $zip = Archive::Zip->new("file.zip");
14 $fh = Archive::Zip::MemberRead->new($zip, "subdir/abc.txt");
15 while (defined($line = $fh->getline()))
17 print $fh->input_line_number . "#: $line\n";
20 $read = $fh->read($buffer, 32*1024);
21 print "Read $read bytes as :$buffer:\n";
25 The Archive::Zip::MemberRead module lets you read Zip archive member data
26 just like you read data from files.
36 use Archive
::Zip
qw( :ERROR_CODES :CONSTANTS );
38 use vars
qw{$VERSION};
44 $VERSION = eval $VERSION;
45 # Requirement for newline conversion. Should check for e.g., DOS and OS/2 as well, but am too lazy.
46 $nl = $^O
eq 'MSWin32' ?
"\r\n" : "\n";
49 =item Archive::Zip::Member::readFileHandle()
51 You can get a C<Archive::Zip::MemberRead> from an archive member by
52 calling C<readFileHandle()>:
54 my $member = $zip->memberNamed('abc/def.c');
55 my $fh = $member->readFileHandle();
56 while (defined($line = $fh->getline()))
64 sub Archive
::Zip
::Member
::readFileHandle
{
65 return Archive
::Zip
::MemberRead
->new( shift() );
68 =item Archive::Zip::MemberRead->new($zip, $fileName)
70 =item Archive::Zip::MemberRead->new($zip, $member)
72 =item Archive::Zip::MemberRead->new($member)
74 Construct a new Archive::Zip::MemberRead on the specified member.
76 my $fh = Archive::Zip::MemberRead->new($zip, 'fred.c')
81 my ( $class, $zip, $file ) = @_;
82 my ( $self, $member );
84 if ( $zip && $file ) # zip and filename, or zip and member
86 $member = ref($file) ?
$file : $zip->memberNamed($file);
88 elsif ( $zip && !$file && ref($zip) ) # just member
94 'Archive::Zip::MemberRead::new needs a zip and filename, zip and member, or member'
99 bless( $self, $class );
100 $self->set_member($member);
105 my ( $self, $member ) = @_;
107 $self->{member
} = $member;
108 $self->set_compression(COMPRESSION_STORED
);
112 sub set_compression
{
113 my ( $self, $compression ) = @_;
114 $self->{member
}->desiredCompressionMethod($compression) if $self->{member
};
117 =item setLineEnd(expr)
119 Set the line end character to use. This is set to \n by default
120 except on Windows systems where it is set to \r\n. You will
121 only need to set this on systems which are not Windows or Unix
122 based and require a line end diffrent from \n.
123 This is a class method so call as C<Archive::Zip::MemberRead>->C<setLineEnd($nl)>
134 Rewinds an C<Archive::Zip::MemberRead> so that you can read from it again
135 starting at the beginning.
142 $self->_reset_vars();
143 $self->{member
}->rewindData() if $self->{member
};
149 $self->{line_no
} = 0;
152 delete $self->{buffer
};
155 =item input_record_separator(expr)
157 If the argumnet is given, input_record_separator for this
158 instance is set to it. The current setting (which may be
159 the global $/) is always returned.
163 sub input_record_separator
{
166 $self->{sep
} = shift;
167 $self->{sep_re
} = _sep_as_re
($self->{sep
}); # Cache the RE as an optimization
169 return exists $self->{sep
} ?
$self->{sep
} : $/;
172 # Return the input_record_separator in use as an RE fragment
173 # Note that if we have a per-instance input_record_separator
174 # we can just return the already converted value. Otherwise,
175 # the conversion must be done on $/ every time since we cannot
176 # know whether it has changed or not.
179 # Important to phrase this way: sep's value may be undef.
180 return exists $self->{sep
} ?
$self->{sep_re
} : _sep_as_re
($/);
183 # Convert the input record separator into an RE and return it.
188 return "(?:$nl){2,}";
191 return quotemeta $sep;
198 =item input_line_number()
200 Returns the current line number, but only if you're using C<getline()>.
201 Using C<read()> will not update the line number.
205 sub input_line_number
{
207 return $self->{line_no
};
212 Closes the given file handle.
219 $self->_reset_vars();
220 $self->{member
}->endRead();
223 =item buffer_size([ $size ])
225 Gets or sets the buffer size used for reads.
226 Default is the chunk size used by Archive::Zip.
231 my ( $self, $size ) = @_;
234 return $self->{chunkSize
} || Archive
::Zip
::chunkSize
();
237 $self->{chunkSize
} = $size;
243 Returns the next line from the currently open member.
244 Makes sense only for text files.
245 A read error is considered fatal enough to die.
246 Returns undef on eof. All subsequent calls would return undef,
247 unless a rewind() is called.
248 Note: The line returned has the input_record_separator (default: newline) removed.
254 my $size = $self->buffer_size();
255 my $sep = $self->_sep_re();
259 && defined($self->{buffer
})
260 && $self->{buffer
} =~ s/^(.*?)$sep//s
264 } elsif ($self->{at_end
}) {
265 $self->{line_no
}++ if $self->{buffer
};
266 return delete $self->{buffer
};
268 my ($temp,$status) = $self->{member
}->readChunk($size);
269 if ($status != AZ_OK
&& $status != AZ_STREAM_END
) {
270 die "ERROR: Error reading chunk from archive - $status";
272 $self->{at_end
} = $status == AZ_STREAM_END
;
273 $self->{buffer
} .= $$temp;
277 =item read($buffer, $num_bytes_to_read)
279 Simulates a normal C<read()> system call.
280 Returns the no. of bytes read. C<undef> on error, 0 on eof, I<e.g.>:
282 $fh = Archive::Zip::MemberRead->new($zip, "sreeji/secrets.bin");
285 $read = $fh->read($buffer, 1024);
286 die "FATAL ERROR reading my secrets !\n" if (!defined($read));
295 # All these $_ are required to emulate read().
300 my ( $temp, $status, $ret );
302 ( $temp, $status ) = $self->{member
}->readChunk($size);
303 if ( $status != AZ_OK
&& $status != AZ_STREAM_END
) {
309 $ret = length($$temp);
320 Sreeji K. Das, <sreeji_k@yahoo.com>
321 See L<Archive::Zip> by Ned Konz without which this module does not make
324 Minor mods by Ned Konz.
328 Copyright 2002 Sreeji K. Das.
330 This program is free software; you can redistribute it and/or modify it under
331 the same terms as Perl itself.