home *** CD-ROM | disk | FTP | other *** search
/ Netrunner 2004 October / NETRUNNER0410.ISO / regular / ActivePerl-5.8.4.810-MSWin32-x86.msi / _b31aef2d35be602f2bbc5c86c30e3ae2 < prev    next >
Text File  |  2004-06-01  |  6KB  |  296 lines

  1. package Archive::Zip::MemberRead;
  2.  
  3. #
  4. # Copyright (c) 2002 Sreeji K. Das. All rights reserved.  This program is free
  5. # software; you can redistribute it and/or modify it under the same terms
  6. # as Perl itself.
  7. #
  8. # $Revision: 1.4 $
  9.  
  10. =head1 NAME
  11.  
  12. Archive::Zip::MemberRead - A wrapper that lets you read Zip archive members as if they were files.
  13.  
  14. =cut
  15.  
  16. =head1 SYNOPSIS
  17.  
  18.   use Archive::Zip;
  19.   use Archive::Zip::MemberRead;
  20.   $zip = new Archive::Zip("file.zip");
  21.   $fh  = new Archive::Zip::MemberRead($zip, "subdir/abc.txt");
  22.   while (defined($line = $fh->getline()))
  23.   {
  24.       print $fh->input_line_number . "#: $line\n";
  25.   }
  26.  
  27.   $read = $fh->read($buffer, 32*1024);
  28.   print "Read $read bytes as :$buffer:\n";
  29.  
  30. =head1 DESCRIPTION
  31.  
  32. The Archive::Zip::MemberRead module lets you read Zip archive member data
  33. just like you read data from files.
  34.  
  35. =head1 METHODS
  36.  
  37. =over 4
  38.  
  39. =cut
  40.  
  41. use strict;
  42. use Archive::Zip qw( :ERROR_CODES :CONSTANTS );
  43.  
  44. =item Archive::Zip::Member::readFileHandle()
  45.  
  46. You can get a C<Archive::Zip::MemberRead> from an archive member by
  47. calling C<readFileHandle()>:
  48.  
  49.   my $member = $zip->memberNamed('abc/def.c');
  50.   my $fh = $member->readFileHandle();
  51.   while (defined($line = $fh->getline()))
  52.   {
  53.       # ...
  54.   }
  55.   $fh->close();
  56.  
  57. =cut
  58.  
  59. sub Archive::Zip::Member::readFileHandle
  60. {
  61.     return Archive::Zip::MemberRead->new( shift () );
  62. }
  63.  
  64. =item Archive::Zip::MemberRead->new($zip, $fileName)
  65.  
  66. =item Archive::Zip::MemberRead->new($zip, $member)
  67.  
  68. =item Archive::Zip::MemberRead->new($member)
  69.  
  70. Construct a new Archive::Zip::MemberRead on the specified member.
  71.  
  72.   my $fh = Archive::Zip::MemberRead->new($zip, 'fred.c')
  73.  
  74. =cut
  75.  
  76. sub new
  77. {
  78.     my ( $class, $zip, $file ) = @_;
  79.     my ( $self, $member );
  80.  
  81.     if ( $zip && $file )    # zip and filename, or zip and member
  82.     {
  83.         $member = ref($file) ? $file : $zip->memberNamed($file);
  84.     }
  85.     elsif ( $zip && !$file && ref($zip) )    # just member
  86.     {
  87.         $member = $zip;
  88.     }
  89.     else
  90.     {
  91.         die (
  92. 'Archive::Zip::MemberRead::new needs a zip and filename, zip and member, or member'
  93.         );
  94.     }
  95.  
  96.     $self = {};
  97.     bless( $self, $class );
  98.     $self->set_member($member);
  99.     return $self;
  100. }
  101.  
  102. sub set_member
  103. {
  104.     my ( $self, $member ) = @_;
  105.  
  106.     $self->{member} = $member;
  107.     $self->set_compression(COMPRESSION_STORED);
  108.     $self->rewind();
  109. }
  110.  
  111. sub set_compression
  112. {
  113.     my ( $self, $compression ) = @_;
  114.     $self->{member}->desiredCompressionMethod($compression) if $self->{member};
  115. }
  116.  
  117. =item rewind()
  118.  
  119. Rewinds an C<Archive::Zip::MemberRead> so that you can read from it again
  120. starting at the beginning.
  121.  
  122. =cut
  123.  
  124. sub rewind
  125. {
  126.     my $self = shift;
  127.  
  128.     $self->_reset_vars();
  129.     $self->{member}->rewindData() if $self->{member};
  130. }
  131.  
  132. sub _reset_vars
  133. {
  134.     my $self = shift;
  135.     $self->{lines}   = [];
  136.     $self->{partial} = 0;
  137.     $self->{line_no} = 0;
  138. }
  139.  
  140. =item input_line_number()
  141.  
  142. Returns the current line number, but only if you're using C<getline()>.
  143. Using C<read()> will not update the line number.
  144.  
  145. =cut
  146.  
  147. sub input_line_number
  148. {
  149.     my $self = shift;
  150.     return $self->{line_no};
  151. }
  152.  
  153. =item close()
  154.  
  155. Closes the given file handle.
  156.  
  157. =cut
  158.  
  159. sub close
  160. {
  161.     my $self = shift;
  162.  
  163.     $self->_reset_vars();
  164.     $self->{member}->endRead();
  165. }
  166.  
  167. =item buffer_size([ $size ])
  168.  
  169. Gets or sets the buffer size used for reads.
  170. Default is the chunk size used by Archive::Zip.
  171.  
  172. =cut
  173.  
  174. sub buffer_size
  175. {
  176.     my ( $self, $size ) = @_;
  177.  
  178.     if ( !$size )
  179.     {
  180.         return $self->{chunkSize} || Archive::Zip::chunkSize();
  181.     }
  182.     else
  183.     {
  184.         $self->{chunkSize} = $size;
  185.     }
  186. }
  187.  
  188. =item getline()
  189.  
  190. Returns the next line from the currently open member.
  191. Makes sense only for text files.
  192. A read error is considered fatal enough to die.
  193. Returns undef on eof. All subsequent calls would return undef,
  194. unless a rewind() is called.
  195. Note: The line returned has the newline removed.
  196.  
  197. =cut
  198.  
  199. # $self->{partial} flags whether the last line in the buffer is partial or not.
  200. # A line is treated as partial if it does not ends with \n
  201. sub getline
  202. {
  203.     my $self = shift;
  204.     my ( $temp, $status, $size, $buffer, @lines );
  205.  
  206.     $status = AZ_OK;
  207.     $size   = $self->buffer_size();
  208.     $temp   = \$status;
  209.     while ( $$temp !~ /\n/ && $status != AZ_STREAM_END )
  210.     {
  211.         ( $temp, $status ) = $self->{member}->readChunk($size);
  212.         if ( $status != AZ_OK && $status != AZ_STREAM_END )
  213.         {
  214.             die "ERROR: Error reading chunk from archive - $status\n";
  215.         }
  216.  
  217.         $buffer .= $$temp;
  218.     }
  219.  
  220.     @lines = split ( /\n/, $buffer );
  221.     $self->{line_no}++;
  222.     if ( $#lines == -1 )
  223.     {
  224.         return ( $#{ $self->{lines} } == -1 ) 
  225.           ? undef
  226.           : shift ( @{ $self->{lines} } );
  227.     }
  228.  
  229.     $self->{lines}->[ $#{ $self->{lines} } ] .= shift (@lines)
  230.       if $self->{partial};
  231.  
  232.     splice( @{ $self->{lines} }, @{ $self->{lines} }, 0, @lines );
  233.     $self->{partial} = !( $buffer =~ /\n$/ );
  234.     return shift ( @{ $self->{lines} } );
  235. }
  236.  
  237. =item read($buffer, $num_bytes_to_read)
  238.  
  239. Simulates a normal C<read()> system call.
  240. Returns the no. of bytes read. C<undef> on error, 0 on eof, I<e.g.>:
  241.  
  242.   $fh = new Archive::Zip::MemberRead($zip, "sreeji/secrets.bin");
  243.   while (1)
  244.   {
  245.     $read = $fh->read($buffer, 1024);
  246.     die "FATAL ERROR reading my secrets !\n" if (!defined($read));
  247.     last if (!$read);
  248.     # Do processing.
  249.     ....
  250.    }
  251.  
  252. =cut
  253.  
  254. #
  255. # All these $_ are required to emulate read().
  256. #
  257. sub read
  258. {
  259.     my $self = $_[0];
  260.     my $size = $_[2];
  261.     my ( $temp, $status, $ret );
  262.  
  263.     ( $temp, $status ) = $self->{member}->readChunk($size);
  264.     if ( $status != AZ_OK && $status != AZ_STREAM_END )
  265.     {
  266.         $_[1] = undef;
  267.         $ret = undef;
  268.     }
  269.     else
  270.     {
  271.         $_[1] = $$temp;
  272.         $ret = length($$temp);
  273.     }
  274.     return $ret;
  275. }
  276.  
  277. =back
  278.  
  279. =head1 AUTHOR
  280.  
  281. Sreeji K. Das, <sreeji_k@yahoo.com>
  282. See L<Archive::Zip> by Ned Konz without which this module does not make
  283. any sense! 
  284.  
  285. Minor mods by Ned Konz.
  286.  
  287. =head1 COPYRIGHT
  288.  
  289. Copyright (c) 2002 Sreeji K. Das. All rights reserved.  This program is free
  290. software; you can redistribute it and/or modify it under the same terms
  291. as Perl itself.
  292.  
  293. =cut
  294.  
  295. 1;
  296.