Hello,

I forget 'or' condition on the opening of gziped or bziped files,
attached is a good patch.
-- 
Daniel 'NebuchadnezzaR' Dehennin
Récupérer ma clef GPG:
gpg --keyserver pgp.mit.edu --recv-keys 0x2A408F69
--- Packages.pm.old     2005-08-26 02:58:55.000000000 +0200
+++ Packages.pm 2005-08-26 14:13:52.000000000 +0200
@@ -1,25 +1,63 @@
 use strict;
 package Parse::Debian::Packages;
-our $VERSION = '0.01';
+our $VERSION = "0.02";
+
+use Compress::Zlib;
+use Compress::Bzip2;
+use File::MMagic;
+use FileHandle;
 
 sub new {
     my $class = shift;
-    my $fh = shift;
+    my $file = shift;
+    my $fh;
 
-    return bless { fh => $fh }, $class;
+    if (! ref $file) {
+       # Caller give us a filename
+       return undef unless -f $file;
+
+       # Default magic is ok for application/x-gzip application/x-bzip2 and 
text/plain
+       my $magic = File::MMagic->new();
+       my $type = $magic->checktype_filename($file);
+
+      SWITCH: for ($type) {
+         /text\/plain/ && do {
+             $fh = new FileHandle;
+             $fh->open("< $file") or return undef;
+             last;
+         };
+         
+         /application\/x-gzip/ && do {
+             $fh = gzopen ($file, "rb") or return undef;
+             last;
+         };
+         
+         /application\/x-bzip2/ && do {
+             $fh = bzopen ($file, "rb") or return undef;
+             last;
+         };
+         # It's not a supported file format
+         return undef;
+      }
+       return bless { FH => $fh, TYPE => $type}, $class;
+    } else {
+       return bless { FH => $file, TYPE => "IOFile"}, $class;
+    }
 }
 
 sub next {
     my $self = shift;
-    my $fh   = $self->{fh};
 
     my %parsed;
-    while (<$fh>) {
+    while ($_ = $self->__readline) {
         last if /^$/;
-        if (my ($key, $value) = m/^(.*): (.*)/) {
-            $parsed{$key} = $value;
-        }
-        else {
+
+        if (my ($key, $value) = m/^([^\s:]*):\s?(.*)/) {
+           # Do not add an empty Files key when parsing Sources
+            $parsed{$key} = $value unless $key eq "Files";
+        } elsif (my ($md5, $size, $filename) = /^\s(\w{32})\s(\d+)\s(.*)/) {
+           $parsed{Files} = { $filename => { size => $size, MD5sum => $md5 } };
+       } else {
             s/ //;
             s/^\.$//;
             $parsed{body} .= $_;
@@ -29,7 +67,37 @@
     return %parsed;
 }
 
-1;
+sub __readline {
+    my $self = shift;
+    my $line = "";
+
+      SWITCH: for ($self->{TYPE}) {
+         /text\/plain|IOFile/ && do {
+             $line = $self->{FH}->getline;
+             last;
+         };
+         
+         /application\/x-gzip/ && do {
+             my $bytesread = $self->{FH}->gzreadline($line);
+             if ($bytesread == 0) {
+                 $line = "";
+             }
+             last;
+         };
+         
+         /application\/x-bzip2/ && do {
+             my $bytesread = $self->{FH}->bzreadline($line);
+             if ($bytesread == 0) {
+                 $line = "";
+             }
+             last;
+         };
+         die "Should Never Happend\n";
+      }
+    return $line;
+}
+
+1
 
 
 =head1 NAME
@@ -40,24 +108,48 @@
 
  use YAML;
  use IO::File;
+ use FileHandle;
  use Parse::Debian::Packages;
- my $fh = IO::File->new("Packages");
 
- my $parser = Parse::Debian::Packages->new( $fh );
- while (my %package = $parser->next) {
+ my $pkg_file = "Packages";
+ my $src_file = "Sources";
+ my $other_src_file = "Sources.bz2";
+
+ my $fh_io = IO::File->new($pkg_file);
+ my $fh_FH = new FileHandle;
+ $fh_FH->open("< $src_file");
+
+ my $parser_on_io = Parse::Debian::Packages->new( $fh_io );
+ my $parser_on_FH = Parse::Debian::Packages->new( $fh_FH );
+ my $parser_on_filename = Parse::Debian::Packages->new( $other_src_file );
+
+ my %pkg_with_io = $parser_on_io->next;
+ my %pkg_with_FH = $parser_on_FH->next;
+ my %pkg_with_filename = $parser_on_filename->next;
+
+ print Dump \%pkg_with_io;
+ print Dump \%pkg_with_FH;
+ print Dump \%pkg_with_filename;
+
+ while (my %package = $parser_on_io->next) {
      print Dump \%package;
  }
 
 =head1 DESCRIPTION
 
-This module parses the Packages files used by the debian package
-management tools.
+This module parses the Packages and Sources files used by the debian
+package management tools.
 
 It presents itself as an iterator.  Each call of the ->next method
 will return the next package found in the file.
 
-For laziness, we take a filehandle in to the constructor.  Please open
-the file for us.
+You can pass a FileHandle to the constructor of a filename, the
+advantage of the filename is that you can parse plain/text, gziped or
+bziped files.
+
+If the filename passed to the constructor don't repressent a file in
+supported format (text/plain, application/x-gzip,
+application/x-bzip2) or if that file can not be open, new() return undef.
 
 =head1 AUTHOR
 

Attachment: pgpETwFVfMYeD.pgp
Description: PGP signature



Reply via email to