source: trunk/soft/ObsData/ObsData/Archive.pm @ 240

Last change on this file since 240 was 240, checked in by nanardon, 18 years ago
  • add partial lha/lzh support
  • Property cvs2svn:cvs-rev set to 1.16
  • Property svn:keywords set to Author Date Id Revision
File size: 3.1 KB
Line 
1# $Id$
2
3package ObsData::Archive;
4
5use strict;
6use warnings;
7require ObsData::Archive::FlatFile;
8require ObsData::Archive::Compressed;
9require ObsData::Archive::Tar;
10require ObsData::Archive::Zip;
11require ObsData::Archive::Rar;
12require ObsData::Archive::Lha;
13
14our $CVSID = q$Id$;
15our $CVSREV = (q$Revision$ =~ /^Revision: (.*) $/)[0];
16
17my $error = {};
18
19my @dynload = ();
20
21sub register {
22    my ($rule, $class, $priority) = @_;
23    push(
24        @ObsData::Archive::dynload,
25        {
26            rule => $rule,
27            class => $class,
28            priority => $priority,
29        }
30    );
31    1;
32}
33
34sub load_format {
35    my ($module) = @_;
36    eval { require $module };
37    return($@ ? 0 : 1);
38}
39
40sub new {
41    my ($class, $archive, %options) = @_;
42    my $beclass;
43
44    if (!$archive) {
45        seterror("No archive to read");
46        return undef;
47    }
48    if (!-r $archive) {
49        seterror("No such file or directory");
50        return undef;
51    }
52    my $o;
53   
54    foreach (keys %options) {
55        $o->{$_} = $options{$_};
56    }
57    $o->{archive} = $archive;
58   
59    for ($archive) {
60        foreach my $r (sort { $a->{priority} <=> $b->{priority} } @ObsData::Archive::dynload) {
61            if (ref($r->{rule}) eq 'CODE' ?
62                $r->{rule}->($_) :
63                /$r->{rule}/) {
64                $beclass = $r->{class};
65                last;
66            }
67        }
68    }
69   
70    if ($beclass) {
71        my $obj;
72        # eval("require $class\:\:$beclass;");
73        eval("\$obj = $class\:\:$beclass->new(\$o);");
74        return $obj;
75    }
76}
77
78### Global functions
79
80sub error {
81    return $error->{error};
82}
83
84sub seterror {
85    my ($package, $filename, $line) = caller;
86    $error = {
87        'package' => $package,
88        'filename' => $filename,
89        'line' => $line,
90        'error' => $_[1] || $_[0],
91    };
92}
93
94package ObsData::Archive::template;
95
96our @ISA = qw(ObsData::Archive);
97
98sub new {
99    my ($class, $o) = @_;
100    bless($o, $class);
101}
102
103sub DESTROY {
104    my ($self) = @_;
105}
106
107sub ls {
108    my ($self) = @_;
109    seterror("ls not implement in class " . ref($self));
110    return;
111}
112
113sub extract {
114    my ($self, $file, $dest) = @_;
115    seterror("extract not implement in class " . ref($self));
116    return;
117}
118
119### Private method
120
121sub _tempdir {
122    my ($self) = @_;
123    $self->{tmpdir} || $ENV{TMPDIR}
124}
125
1261;
127
128__END__
129
130=head1 NAME
131
132ObsData::Archive - Transparently extract files from arbitrary archives
133
134=head1 SYNOPSIS
135
136    use ObsData::Archive;
137    my $file = "foo.tar.gz";
138    my $oa = ObsData::Archive->new($file) or die ObsData::Archive->error;
139    my @content = $oa->ls;
140    foreach (@content) {
141        $oa->extract($_, "./$_") or die ObsData::Archive->error;
142    }
143
144=head1 METHODS
145
146=head2 new($file, %options)
147
148Create a new archive object by reading $file.
149
150Return undef on error and set error status.
151See L<error>.
152
153=head2 ls
154
155list the content of the archive
156
157=head2 extract
158
159Extract a file from the archive and return the filename of extract file
160
161=head1 CLASS METHODS
162
163=head2 error
164
165Return the last error encoutered
166
167=head1 AUTHORS
168
169Olivier Thauvin <olivier.thauvin@aerov.jussieu.fr>
170
171=cut
Note: See TracBrowser for help on using the repository browser.