File Coverage

blib/lib/MARC/Leader.pm
Criterion Covered Total %
statement 48 48 100.0
branch 10 10 100.0
condition 3 3 100.0
subroutine 11 11 100.0
pod 3 3 100.0
total 75 75 100.0


line stmt bran cond sub pod time code
1             package MARC::Leader;
2              
3 5     5   225847 use strict;
  5         10  
  5         174  
4 5     5   38 use warnings;
  5         12  
  5         346  
5              
6 5     5   2359 use Class::Utils qw(set_params);
  5         43076  
  5         119  
7 5     5   2546 use Data::MARC::Leader 0.05;
  5         34326  
  5         221  
8 5     5   36 use Error::Pure qw(err);
  5         8  
  5         280  
9 5     5   25 use Mo::utils 0.06 qw(check_bool);
  5         73  
  5         223  
10 5     5   26 use Scalar::Util qw(blessed);
  5         8  
  5         3889  
11              
12             our $VERSION = 0.08;
13              
14             # Constructor.
15             sub new {
16 12     12 1 1069081 my ($class, @params) = @_;
17              
18             # Create object.
19 12         40 my $self = bless {}, $class;
20              
21             # Verbose mode.
22 12         48 $self->{'verbose'} = 0;
23              
24             # Process parameters.
25 12         69 set_params($self, @params);
26              
27             # Check verbose.
28 12         181 check_bool($self, 'verbose');
29              
30 11         329 return $self;
31             }
32              
33             sub parse {
34 7     7 1 1817 my ($self, $leader) = @_;
35              
36             # Check length.
37 7 100       64 if (length($leader) != 24) {
38 1         8 err 'Bad length of MARC leader.',
39             'Length', length($leader),
40             ;
41             }
42              
43 6         30 $leader =~ s/\-/\ /msg;
44              
45 6 100       21 if ($self->{'verbose'}) {
46 1         66 print "Leader: |$leader|\n";
47             }
48              
49 6         29 my %params = (
50             'raw' => $leader,
51              
52             'length' => $self->_int($leader, 0, 5, 'Bad number in length.'),
53             'status' => (substr $leader, 5, 1),
54             'type' => (substr $leader, 6, 1),
55             'bibliographic_level' => (substr $leader, 7, 1),
56             'type_of_control' => (substr $leader, 8, 1),
57             'char_coding_scheme' => (substr $leader, 9, 1),
58             'indicator_count' => (substr $leader, 10, 1),
59             'subfield_code_count' => (substr $leader, 11, 1),
60             'data_base_addr' => $self->_int($leader, 12, 5, 'Bad number in data base address.'),
61             'encoding_level' => (substr $leader, 17, 1),
62             'descriptive_cataloging_form' => (substr $leader, 18, 1),
63             'multipart_resource_record_level' => (substr $leader, 19, 1),
64             'length_of_field_portion_len' => (substr $leader, 20, 1),
65             'starting_char_pos_portion_len' => (substr $leader, 21, 1),
66             'impl_def_portion_len' => (substr $leader, 22, 1),
67             'undefined' => (substr $leader, 23, 1),
68             );
69              
70 4         53 return Data::MARC::Leader->new(%params);
71             }
72              
73             sub serialize {
74 3     3 1 529 my ($self, $leader_obj) = @_;
75              
76             # Check object.
77 3 100 100     22 if (! blessed($leader_obj) || ! $leader_obj->isa('Data::MARC::Leader')) {
78 2         47 err "Bad 'Data::MARC::Leader' instance to serialize.";
79             }
80              
81 1         6 my $leader = sprintf('%05d', $leader_obj->length).
82             $leader_obj->status.
83             $leader_obj->type.
84             $leader_obj->bibliographic_level.
85             $leader_obj->type_of_control.
86             $leader_obj->char_coding_scheme.
87             $leader_obj->indicator_count.
88             $leader_obj->subfield_code_count.
89             sprintf('%05d', $leader_obj->data_base_addr).
90             $leader_obj->encoding_level.
91             $leader_obj->descriptive_cataloging_form.
92             $leader_obj->multipart_resource_record_level.
93             $leader_obj->length_of_field_portion_len.
94             $leader_obj->starting_char_pos_portion_len.
95             $leader_obj->impl_def_portion_len.
96             $leader_obj->undefined;
97              
98 1         84 return $leader;
99             }
100              
101             sub _int {
102 11     11   33 my ($self, $leader, $pos, $length, $err_message) = @_;
103              
104 11         30 my $ret = substr $leader, $pos, $length;
105 11 100       61 if ($ret !~ m/^[\s\d]+$/ms) {
106 2         9 err $err_message,
107             'String', $ret,
108             ;
109             }
110 9 100       38 if ($ret =~ m/^\s+$/ms) {
111 6         13 $ret = 0;
112             } else {
113 3         10 $ret = int($ret);
114             }
115              
116 9         159 return $ret;
117             }
118              
119             1;
120              
121             __END__
122              
123             =pod
124              
125             =encoding utf8
126              
127             =head1 NAME
128              
129             MARC::Leader - MARC leader class.
130              
131             =head1 SYNOPSIS
132              
133             use MARC::Leader;
134              
135             my $obj = MARC::Leader->new(%params);
136             my $leader_obj = $obj->parse($leader_str);
137             my $leader_str = $obj->serialize($leader_obj);
138              
139             =head1 METHODS
140              
141             =head2 C<new>
142              
143             my $obj = MARC::Leader->new(%params);
144              
145             Constructor.
146              
147             =over 8
148              
149             =item * C<verbose>
150              
151             Verbose mode flag.
152             It's boolean value.
153              
154             Default value is 0.
155              
156             =back
157              
158             Returns instance of object.
159              
160             =head2 C<parse>
161              
162             my $leader_obj = $obj->parse($leader_str);
163              
164             Parse MARC leader string to object.
165              
166             Returns instance of 'Data::MARC::Leader' object.
167              
168             =head2 C<serialize>
169              
170             my $leader_str = $obj->serialize($leader_obj);
171              
172             Serialize MARC leader object to string.
173              
174             Returns string.
175              
176             =head1 ERRORS
177              
178             new():
179             From Class::Utils::set_params():
180             Unknown parameter '%s'.
181             From Mo::utils::check_bool():
182             Parameter 'verbose' must be a bool (0/1).
183             Value: %s
184              
185             parse():
186             Bad length of MARC leader.
187             Length: %s
188             Bad number in data base address.
189             String: %s
190             Bad number in length.
191             String: %s
192              
193             serialize():
194             Bad 'Data::MARC::Leader' instance to serialize.
195              
196              
197             =head1 EXAMPLE1
198              
199             =for comment filename=parse_marc_leader_and_dump.pl
200              
201             use strict;
202             use warnings;
203              
204             use Data::Printer;
205             use MARC::Leader;
206              
207             if (@ARGV < 1) {
208             print "Usage: $0 marc_leader\n";
209             exit 1;
210             }
211             my $marc_leader = $ARGV[0];
212              
213             # Object.
214             my $obj = MARC::Leader->new;
215              
216             # Parse.
217             my $leader_obj = $obj->parse($marc_leader);
218              
219             # Dump to output.
220             p $leader_obj;
221              
222             # Output for '02200cem a2200541 i 4500':
223             # Data::MARC::Leader {
224             # parents: Mo::Object
225             # public methods (3):
226             # BUILD
227             # Mo::utils:
228             # check_strings
229             # Readonly:
230             # Readonly
231             # private methods (0)
232             # internals: {
233             # bibliographic_level "m",
234             # char_coding_scheme "a",
235             # data_base_addr 541,
236             # descriptive_cataloging_form "i",
237             # encoding_level " ",
238             # impl_def_portion_len 0,
239             # indicator_count 2,
240             # length 2200,
241             # length_of_field_portion_len 4,
242             # multipart_resource_record_level " ",
243             # starting_char_pos_portion_len 5,
244             # status "c",
245             # subfield_code_count 2,
246             # type "e",
247             # type_of_control " ",
248             # undefined 0
249             # }
250             # }
251              
252             =head1 EXAMPLE2
253              
254             =for comment filename=parse_marc_leader_and_print.pl
255              
256             use strict;
257             use warnings;
258              
259             use MARC::Leader;
260             use MARC::Leader::Print;
261              
262             if (@ARGV < 1) {
263             print "Usage: $0 marc_leader\n";
264             exit 1;
265             }
266             my $marc_leader = $ARGV[0];
267              
268             # Object.
269             my $obj = MARC::Leader->new;
270              
271             # Parse.
272             my $leader_obj = $obj->parse($marc_leader);
273              
274             # Print to output.
275             print scalar MARC::Leader::Print->new->print($leader_obj), "\n";
276              
277             # Output for '02200cem a2200541 i 4500':
278             # Record length: 2200
279             # Record status: Corrected or revised
280             # Type of record: Cartographic material
281             # Bibliographic level: Monograph/Item
282             # Type of control: No specified type
283             # Character coding scheme: UCS/Unicode
284             # Indicator count: Number of character positions used for indicators
285             # Subfield code count: Number of character positions used for a subfield code (2)
286             # Base address of data: 541
287             # Encoding level: Full level
288             # Descriptive cataloging form: ISBD punctuation included
289             # Multipart resource record level: Not specified or not applicable
290             # Length of the length-of-field portion: Number of characters in the length-of-field portion of a Directory entry (4)
291             # Length of the starting-character-position portion: Number of characters in the starting-character-position portion of a Directory entry (5)
292             # Length of the implementation-defined portion: Number of characters in the implementation-defined portion of a Directory entry (0)
293             # Undefined: Undefined
294              
295             =head1 EXAMPLE3
296              
297             =for comment filename=serialize_marc_leader.pl
298              
299             use strict;
300             use warnings;
301              
302             use Data::MARC::Leader;
303             use MARC::Leader;
304              
305             # Object.
306             my $obj = MARC::Leader->new;
307              
308             # Data object.
309             my $data_marc_leader = Data::MARC::Leader->new(
310             'bibliographic_level' => 'm',
311             'char_coding_scheme' => 'a',
312             'data_base_addr' => 541,
313             'descriptive_cataloging_form' => 'i',
314             'encoding_level' => ' ',
315             'impl_def_portion_len' => '0',
316             'indicator_count' => '2',
317             'length' => 2200,
318             'length_of_field_portion_len' => '4',
319             'multipart_resource_record_level' => ' ',
320             'starting_char_pos_portion_len' => '5',
321             'status' => 'c',
322             'subfield_code_count' => '2',
323             'type' => 'e',
324             'type_of_control' => ' ',
325             'undefined' => '0',
326             );
327              
328             # Serialize.
329             my $leader = $obj->serialize($data_marc_leader);
330              
331             # Print to output.
332             print $leader."\n";
333              
334             # Output:
335             # 02200cem a2200541 i 4500
336              
337             =head1 DEPENDENCIES
338              
339             L<Class::Utils>,
340             L<Data::MARC::Leader>,
341             L<Error::Pure>,
342             L<Mo::utils>,
343             L<Scalar::Util>.
344              
345             =head1 SEE ALSO
346              
347             =over
348              
349             =item L<Data::MARC::Leader>
350              
351             Data object for MARC leader.
352              
353             =back
354              
355             =head1 REPOSITORY
356              
357             L<https://github.com/michal-josef-spacek/MARC-Leader>
358              
359             =head1 AUTHOR
360              
361             Michal Josef Špaček L<mailto:skim@cpan.org>
362              
363             L<http://skim.cz>
364              
365             =head1 LICENSE AND COPYRIGHT
366              
367             © 2023-2026 Michal Josef Špaček
368              
369             BSD 2-Clause License
370              
371             =head1 ACKNOWLEDGEMENTS
372              
373             Development of this software has been made possible by institutional support
374             for the long-term strategic development of the National Library of the Czech
375             Republic as a research organization provided by the Ministry of Culture of
376             the Czech Republic (DKRVO 2024–2028), Area 11: Linked Open Data.
377              
378             =head1 VERSION
379              
380             0.08
381              
382             =cut