File Coverage

blib/lib/IO/InnerFile.pm
Criterion Covered Total %
statement 65 111 58.5
branch 20 40 50.0
condition 2 6 33.3
subroutine 12 34 35.2
pod 21 21 100.0
total 120 212 56.6


line stmt bran cond sub pod time code
1             package IO::InnerFile;
2              
3 1     1   18780 use strict;
  1         7  
  1         21  
4 1     1   4 use warnings;
  1         1  
  1         19  
5 1     1   3 use Symbol;
  1         1  
  1         1075  
6              
7             our $VERSION = '2.113';
8              
9             sub new {
10 2     2 1 1443 my ($class, $fh, $start, $lg) = @_;
11 2 50 33     12 $start = 0 if (!$start or ($start < 0));
12 2 50 33     7 $lg = 0 if (!$lg or ($lg < 0));
13              
14             ### Create the underlying "object":
15 2         5 my $a = {
16             FH => $fh,
17             CRPOS => 0,
18             START => $start,
19             LG => $lg,
20             };
21              
22             ### Create a new filehandle tied to this object:
23 2         5 $fh = gensym;
24 2         29 tie(*$fh, $class, $a);
25 2         6 return bless($fh, $class);
26             }
27              
28             sub TIEHANDLE {
29 2     2   5 my ($class, $data) = @_;
30 2         5 return bless($data, $class);
31             }
32              
33             sub DESTROY {
34 4     4   462 my ($self) = @_;
35 4 50       141 $self->close() if (ref($self) eq 'SCALAR');
36             }
37              
38 0     0 1 0 sub set_length { tied(${$_[0]})->{LG} = $_[1]; }
  0         0  
39 0     0 1 0 sub get_length { tied(${$_[0]})->{LG}; }
  0         0  
40 0     0 1 0 sub add_length { tied(${$_[0]})->{LG} += $_[1]; }
  0         0  
41              
42 0     0 1 0 sub set_start { tied(${$_[0]})->{START} = $_[1]; }
  0         0  
43 0     0 1 0 sub get_start { tied(${$_[0]})->{START}; }
  0         0  
44 0     0 1 0 sub set_end { tied(${$_[0]})->{LG} = $_[1] - tied(${$_[0]})->{START}; }
  0         0  
  0         0  
45 0     0 1 0 sub get_end { tied(${$_[0]})->{LG} + tied(${$_[0]})->{START}; }
  0         0  
  0         0  
46              
47 0     0 1 0 sub write { shift->WRITE(@_) }
48 0     0 1 0 sub print { shift->PRINT(@_) }
49 0     0 1 0 sub printf { shift->PRINTF(@_) }
50 0     0 1 0 sub flush { "0 but true"; }
51       0 1   sub fileno { }
52 0     0 1 0 sub binmode { 1; }
53 0     0 1 0 sub getc { return GETC(tied(${$_[0]}) ); }
  0         0  
54 0     0 1 0 sub read { return READ( tied(${$_[0]}), @_[1,2,3] ); }
  0         0  
55 0     0 1 0 sub readline { return READLINE( tied(${$_[0]}) ); }
  0         0  
56              
57 0     0 1 0 sub getline { return READLINE( tied(${$_[0]}) ); }
  0         0  
58 1     1 1 283 sub close { return CLOSE(tied(${$_[0]}) ); }
  1         12  
59              
60             sub seek {
61 1     1 1 1220 my ($self, $ofs, $whence) = @_;
62 1         3 $self = tied( $$self );
63              
64 1 50       4 $self->{CRPOS} = $ofs if ($whence == 0);
65 1 50       3 $self->{CRPOS}+= $ofs if ($whence == 1);
66 1 50       3 $self->{CRPOS} = $self->{LG} + $ofs if ($whence == 2);
67              
68 1 50       3 $self->{CRPOS} = 0 if ($self->{CRPOS} < 0);
69 1 50       4 $self->{CRPOS} = $self->{LG} if ($self->{CRPOS} > $self->{LG});
70 1         2 return 1;
71             }
72              
73             sub tell {
74 0     0 1 0 return tied(${$_[0]})->{CRPOS};
  0         0  
75             }
76              
77             sub WRITE {
78 0     0   0 die "inner files can only open for reading\n";
79             }
80              
81             sub PRINT {
82 0     0   0 die "inner files can only open for reading\n";
83             }
84              
85             sub PRINTF {
86 0     0   0 die "inner files can only open for reading\n";
87             }
88              
89             sub GETC {
90 0     0   0 my ($self) = @_;
91 0 0       0 return 0 if ($self->{CRPOS} >= $self->{LG});
92              
93 0         0 my $data;
94              
95             ### Save and seek...
96 0         0 my $old_pos = $self->{FH}->tell;
97 0         0 $self->{FH}->seek($self->{CRPOS}+$self->{START}, 0);
98              
99             ### ...read...
100 0         0 my $lg = $self->{FH}->read($data, 1);
101 0         0 $self->{CRPOS} += $lg;
102              
103             ### ...and restore:
104 0         0 $self->{FH}->seek($old_pos, 0);
105              
106 0 0       0 $self->{LG} = $self->{CRPOS} unless ($lg);
107 0 0       0 return ($lg ? $data : undef);
108             }
109              
110             sub READ {
111 1     1   2 my ($self, $undefined, $lg, $ofs) = @_;
112 1         2 $undefined = undef;
113              
114 1 50       3 return 0 if ($self->{CRPOS} >= $self->{LG});
115 1 50       3 $lg = $self->{LG} - $self->{CRPOS} if ($self->{CRPOS} + $lg > $self->{LG});
116 1 50       2 return 0 unless ($lg);
117              
118             ### Save and seek...
119 1         3 my $old_pos = $self->{FH}->tell;
120 1         8 $self->{FH}->seek($self->{CRPOS}+$self->{START}, 0);
121              
122             ### ...read...
123 1         18 $lg = $self->{FH}->read($_[1], $lg, $_[3] );
124 1         28 $self->{CRPOS} += $lg;
125              
126             ### ...and restore:
127 1         4 $self->{FH}->seek($old_pos, 0);
128              
129 1 50       25 $self->{LG} = $self->{CRPOS} unless ($lg);
130 1         2 return $lg;
131             }
132              
133             sub READLINE {
134 5     5   994 my ($self) = @_;
135 5 100       16 return $self->_readline_helper() unless wantarray;
136 1         1 my @arr;
137 1         3 while(defined(my $line = $self->_readline_helper())) {
138 2         5 push(@arr, $line);
139             }
140 1         4 return @arr;
141             }
142              
143             sub _readline_helper {
144 7     7   9 my ($self) = @_;
145 7 100       16 return undef if ($self->{CRPOS} >= $self->{LG});
146              
147             # Handle slurp mode (CPAN ticket #72710)
148 5 100       12 if (! defined($/)) {
149 1         2 my $text;
150 1         4 $self->READ($text, $self->{LG} - $self->{CRPOS});
151 1         3 return $text;
152             }
153              
154             ### Save and seek...
155 4         16 my $old_pos = $self->{FH}->tell;
156 4         28 $self->{FH}->seek($self->{CRPOS}+$self->{START}, 0);
157              
158             ### ...read...
159 4         120 my $text = $self->{FH}->getline;
160              
161             ### ...and restore:
162 4         116 $self->{FH}->seek($old_pos, 0);
163              
164             #### If we detected a new EOF ...
165 4 50       47 unless (defined $text) {
166 0         0 $self->{LG} = $self->{CRPOS};
167 0         0 return undef;
168             }
169              
170 4         6 my $lg=length($text);
171              
172 4 50       9 $lg = $self->{LG} - $self->{CRPOS} if ($self->{CRPOS} + $lg > $self->{LG});
173 4         6 $self->{CRPOS} += $lg;
174              
175 4         14 return substr($text, 0,$lg);
176             }
177              
178 1     1   2 sub CLOSE { %{$_[0]}=(); }
  1         7  
179              
180              
181              
182             1;
183             __END__