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   183326 use 5.010001;
  2         25  
4 2     2   10 use strict;
  2         5  
  2         37  
5 2     2   10 use warnings;
  2         4  
  2         171  
6              
7             our $AUTHORITY = 'cpan:PERLANCAR'; # AUTHORITY
8             our $DATE = '2023-03-24'; # DATE
9             our $DIST = 'Data-Section-Seekable'; # DIST
10             our $VERSION = '0.092'; # VERSION
11              
12             sub new {
13 2     2   24 no strict 'refs'; ## no critic: TestingAndDebugging::ProhibitNoStrict
  2         4  
  2         1184  
14              
15 10     10 1 10449 my $class = shift;
16              
17 10         29 my $caller = caller;
18 10         309 my $self = bless {@_}, $class;
19              
20 10   100     44 $self->{handle} //= \*{"$caller\::DATA"};
  1         9  
21              
22             {
23 10         23 my $fh = $self->{handle};
  10         15  
24              
25             # BEGIN_BLOCK: read_dss_toc
26              
27 10         19 my $header_line;
28             my $header_found;
29 10         44 while (1) {
30 14         147 my $header_line = <$fh>;
31 14 100       150 defined($header_line)
32             or die "Unexpected end of data section while reading header line";
33 12         20 chomp($header_line);
34 12 100       32 if ($header_line eq 'Data::Section::Seekable v1') {
35 8         12 $header_found++;
36 8         16 last;
37             }
38             }
39 8 50       19 die "Can't find header 'Data::Section::Seekable v1'"
40             unless $header_found;
41              
42 8         16 my %toc;
43 8         11 my $i = 0;
44 8         12 while (1) {
45 15         25 $i++;
46 15         56 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       60 $toc_line =~ /^([^,]+),(\d+),(\d+)(?:,(.*))?$/
52             or die "Invalid TOC line #$i in data section: $toc_line";
53 7         54 $toc{$1} = [$2, $3, $4];
54             }
55 5         17 my $pos = tell $fh;
56 5         34 $toc{$_}[0] += $pos for keys %toc;
57              
58             # END_BLOCK: read_dss_toc
59              
60 5         18 $self->{_toc} = \%toc;
61             }
62              
63 5         16 $self;
64             }
65              
66             sub parts {
67 3     3 1 13 my $self = shift;
68 3         6 sort keys %{$self->{_toc}};
  3         30  
69             }
70              
71             sub read_part {
72 7     7 1 64 my ($self, $name) = @_;
73              
74 7 100       36 defined($self->{_toc}{$name})
75             or die "Unknown part '$name'";
76              
77 6         66 seek $self->{handle}, $self->{_toc}{$name}[0], 0;
78 6         101 read $self->{handle}, my($content), $self->{_toc}{$name}[1];
79              
80 6         73 $content;
81             }
82              
83             sub read_extra {
84 3     3 1 37 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__