File Coverage

blib/lib/MARC/File.pm
Criterion Covered Total %
statement 45 70 64.2
branch 6 18 33.3
condition n/a
subroutine 9 16 56.2
pod 8 8 100.0
total 68 112 60.7


line stmt bran cond sub pod time code
1             package MARC::File;
2              
3             =head1 NAME
4              
5             MARC::File - Base class for files of MARC records
6              
7             =cut
8              
9 30     30   4529 use strict;
  30         70  
  30         770  
10 30     30   148 use warnings;
  30         61  
  30         746  
11 30     30   151 use integer;
  30         58  
  30         170  
12              
13 30     30   653 use vars qw( $ERROR );
  30         65  
  30         2253  
14              
15             =head1 SYNOPSIS
16              
17             use MARC::File::USMARC;
18              
19             # If you have weird control fields...
20             use MARC::Field;
21             MARC::Field->allow_controlfield_tags('FMT', 'LDX');
22              
23             my $file = MARC::File::USMARC->in( $filename );
24              
25             while ( my $marc = $file->next() ) {
26             # Do something
27             }
28             $file->close();
29             undef $file;
30              
31             =head1 EXPORT
32              
33             None.
34              
35             =head1 METHODS
36              
37             =head2 in()
38              
39             Opens a file for import. Ordinarily you will use C
40             or C to do this.
41              
42             my $file = MARC::File::USMARC->in( 'file.marc' );
43              
44             Returns a C object, or C on failure. If you
45             encountered an error the error message will be stored in
46             C<$MARC::File::ERROR>.
47              
48             Optionally you can also pass in a filehandle, and C.
49             will "do the right thing".
50              
51             my $handle = IO::File->new( 'gunzip -c file.marc.gz |' );
52             my $file = MARC::File::USMARC->in( $handle );
53              
54             =cut
55              
56             sub in {
57 48     48 1 2998 my $class = shift;
58 48         119 my $arg = shift;
59 48         115 my ( $filename, $fh );
60              
61             ## if a valid filehandle was passed in
62 30     30   211 my $ishandle = do { no strict; defined fileno($arg); };
  30         114  
  30         14514  
  48         102  
  48         317  
63 48 100       186 if ( $ishandle ) {
64 11         24 $filename = scalar( $arg );
65 11         19 $fh = $arg;
66             }
67              
68             ## otherwise check if it's a filename, and
69             ## return undef if we weren't able to open it
70             else {
71 37         85 $filename = $arg;
72 37 50       232 $fh = eval { local *FH; open( FH, '<', $arg ) or die; *FH{IO}; };
  37         106  
  37         1325  
  37         195  
73 37 50       159 if ( $@ ) {
74 0         0 $MARC::File::ERROR = "Couldn't open $filename: $@";
75 0         0 return;
76             }
77             }
78              
79 48         268 my $self = {
80             filename => $filename,
81             fh => $fh,
82             recnum => 0,
83             warnings => [],
84             };
85              
86 48         353 return( bless $self, $class );
87              
88             } # new()
89              
90             sub out {
91 0     0 1 0 die "Not yet written";
92             }
93              
94             =head2 next( [\&filter_func] )
95              
96             Reads the next record from the file handle passed in.
97              
98             The C<$filter_func> is a reference to a filtering function. Currently,
99             only USMARC records support this. See L's C
100             function for details.
101              
102             Returns a MARC::Record reference, or C on error.
103              
104             =cut
105              
106             sub next {
107 409     409 1 63489 my $self = shift;
108 409         941 $self->{recnum}++;
109 409 100       1489 my $rec = $self->_next() or return;
110 387         1828 return $self->decode($rec, @_);
111             }
112              
113             =head2 skip()
114              
115             Skips over the next record in the file. Same as C,
116             without the overhead of parsing a record you're going to throw away
117             anyway.
118              
119             Returns 1 or undef.
120              
121             =cut
122              
123             sub skip {
124 0     0 1 0 my $self = shift;
125 0 0       0 my $rec = $self->_next() or return;
126 0         0 return 1;
127             }
128              
129             =head2 warnings()
130              
131             Simlilar to the methods in L and L,
132             C will return any warnings that have accumulated while
133             processing this file; and as a side-effect will clear the warnings buffer.
134              
135             =cut
136              
137             sub warnings {
138 288     288 1 2690 my $self = shift;
139 288         568 my @warnings = @{ $self->{warnings} };
  288         944  
140 288         839 $self->{warnings} = [];
141 288         977 return(@warnings);
142             }
143              
144             =head2 close()
145              
146             Closes the file, both from the object's point of view, and the actual file.
147              
148             =cut
149              
150             sub close {
151 13     13 1 4115 my $self = shift;
152 13         321 close( $self->{fh} );
153 13         60 delete $self->{fh};
154 13         38 delete $self->{filename};
155 13         302 return;
156             }
157              
158             sub _unimplemented {
159 0     0     my $self = shift;
160 0           my $method = shift;
161 0           warn "Method $method must be overridden";
162             }
163              
164             =head2 write()
165              
166             Writes a record to the output file. This method must be overridden
167             in your subclass.
168              
169             =head2 decode()
170              
171             Decodes a record into a USMARC format. This method must be overridden
172             in your subclass.
173              
174             =cut
175              
176 0     0 1   sub write { $_[0]->_unimplemented("write"); }
177 0     0 1   sub decode { $_[0]->_unimplemented("decode"); }
178              
179             # NOTE: _warn must be called as an object method
180              
181             sub _warn {
182 0     0     my ($self,$warning) = @_;
183 0           push( @{ $self->{warnings} }, "$warning in record ".$self->{recnum} );
  0            
184 0           return( $self );
185             }
186              
187             # NOTE: _gripe can be called as an object method, or not. Your choice.
188             # NOTE: it's use is now deprecated use _warn instead
189             sub _gripe {
190 0     0     my @parms = @_;
191 0 0         if ( @parms ) {
192 0           my $self = shift @parms;
193              
194 0 0         if ( ref($self) =~ /^MARC::File/ ) {
195             push( @parms, " at byte ", tell($self->{fh}) )
196 0 0         if $self->{fh};
197 0 0         push( @parms, " in file ", $self->{filename} ) if $self->{filename};
198             } else {
199 0           unshift( @parms, $self );
200             }
201              
202 0           $ERROR = join( "", @parms );
203 0           warn $ERROR;
204             }
205              
206 0           return;
207             }
208              
209             1;
210              
211             __END__