File Coverage

blib/lib/Data/Section/Seekable/Reader.pm
Criterion Covered Total %
statement 52 52 100.0
branch 15 16 93.7
condition 2 2 100.0
subroutine 8 8 100.0
pod 4 4 100.0
total 81 82 98.7


line stmt bran cond sub pod time code
1             package Data::Section::Seekable::Reader;
2              
3 2     2   187207 use 5.010001;
  2         23  
4 2     2   12 use strict;
  2         6  
  2         39  
5 2     2   8 use warnings;
  2         4  
  2         172  
6              
7             our $AUTHORITY = 'cpan:PERLANCAR'; # AUTHORITY
8             our $DATE = '2023-01-20'; # DATE
9             our $DIST = 'Data-Section-Seekable'; # DIST
10             our $VERSION = '0.091'; # VERSION
11              
12             sub new {
13 2     2   22 no strict 'refs'; ## no critic: TestingAndDebugging::ProhibitNoStrict
  2         4  
  2         1162  
14              
15 10     10 1 10337 my $class = shift;
16              
17 10         33 my $caller = caller;
18 10         318 my $self = bless {@_}, $class;
19              
20 10   100     41 $self->{handle} //= \*{"$caller\::DATA"};
  1         8  
21              
22             {
23 10         22 my $fh = $self->{handle};
  10         19  
24              
25             # BEGIN_BLOCK: read_dss_toc
26              
27 10         17 my $header_line;
28             my $header_found;
29 10         17 while (1) {
30 14         129 my $header_line = <$fh>;
31 14 100       156 defined($header_line)
32             or die "Unexpected end of data section while reading header line";
33 12         23 chomp($header_line);
34 12 100       32 if ($header_line eq 'Data::Section::Seekable v1') {
35 8         13 $header_found++;
36 8         16 last;
37             }
38             }
39 8 50       20 die "Can't find header 'Data::Section::Seekable v1'"
40             unless $header_found;
41              
42 8         13 my %toc;
43 8         13 my $i = 0;
44 8         14 while (1) {
45 15         22 $i++;
46 15         54 my $toc_line = <$fh>;
47 15 100       172 defined($toc_line)
48             or die "Unexpected end of data section while reading TOC line #$i";
49 13         22 chomp($toc_line);
50 13 100       46 $toc_line =~ /\S/ or last;
51 8 100       58 $toc_line =~ /^([^,]+),(\d+),(\d+)(?:,(.*))?$/
52             or die "Invalid TOC line #$i in data section: $toc_line";
53 7         44 $toc{$1} = [$2, $3, $4];
54             }
55 5         52 my $pos = tell $fh;
56 5         42 $toc{$_}[0] += $pos for keys %toc;
57              
58             # END_BLOCK: read_dss_toc
59              
60 5         17 $self->{_toc} = \%toc;
61             }
62              
63 5         17 $self;
64             }
65              
66             sub parts {
67 3     3 1 13 my $self = shift;
68 3         7 sort keys %{$self->{_toc}};
  3         24  
69             }
70              
71             sub read_part {
72 7     7 1 69 my ($self, $name) = @_;
73              
74 7 100       35 defined($self->{_toc}{$name})
75             or die "Unknown part '$name'";
76              
77 6         66 seek $self->{handle}, $self->{_toc}{$name}[0], 0;
78 6         97 read $self->{handle}, my($content), $self->{_toc}{$name}[1];
79              
80 6         69 $content;
81             }
82              
83             sub read_extra {
84 3     3 1 38 my ($self, $name) = @_;
85              
86 3 100       21 defined($self->{_toc}{$name})
87             or die "Unknown part '$name'";
88              
89 2         9 $self->{_toc}{$name}[2];
90             }
91              
92             1;
93             # ABSTRACT: Read parts from data section
94              
95             __END__