line |
stmt |
bran |
cond |
sub |
pod |
time |
code |
1
|
|
|
|
|
|
|
package Test2::Harness::Util::File::Stream; |
2
|
2
|
|
|
2
|
|
139276
|
use strict; |
|
2
|
|
|
|
|
5
|
|
|
2
|
|
|
|
|
45
|
|
3
|
2
|
|
|
2
|
|
8
|
use warnings; |
|
2
|
|
|
|
|
3
|
|
|
2
|
|
|
|
|
65
|
|
4
|
|
|
|
|
|
|
|
5
|
|
|
|
|
|
|
our $VERSION = '0.001007'; |
6
|
|
|
|
|
|
|
|
7
|
2
|
|
|
2
|
|
8
|
use Carp qw/croak/; |
|
2
|
|
|
|
|
4
|
|
|
2
|
|
|
|
|
80
|
|
8
|
2
|
|
|
2
|
|
9
|
use Fcntl qw/LOCK_EX LOCK_UN SEEK_SET/; |
|
2
|
|
|
|
|
3
|
|
|
2
|
|
|
|
|
78
|
|
9
|
|
|
|
|
|
|
|
10
|
2
|
|
|
2
|
|
216
|
use parent 'Test2::Harness::Util::File'; |
|
2
|
|
|
|
|
213
|
|
|
2
|
|
|
|
|
9
|
|
11
|
2
|
|
|
2
|
|
78
|
use Test2::Harness::Util::HashBase qw/use_write_lock/; |
|
2
|
|
|
|
|
3
|
|
|
2
|
|
|
|
|
7
|
|
12
|
|
|
|
|
|
|
|
13
|
|
|
|
|
|
|
sub poll_with_index { |
14
|
10
|
|
|
10
|
0
|
15
|
my $self = shift; |
15
|
10
|
|
|
|
|
17
|
my %params = @_; |
16
|
|
|
|
|
|
|
|
17
|
10
|
|
50
|
|
|
36
|
my $max = delete $params{max} || 0; |
18
|
|
|
|
|
|
|
|
19
|
10
|
|
|
|
|
15
|
my $pos = $params{from}; |
20
|
10
|
100
|
100
|
|
|
27
|
$pos = $self->{+LINE_POS} ||= 0 unless defined $pos; |
21
|
|
|
|
|
|
|
|
22
|
10
|
|
|
|
|
15
|
my @out; |
23
|
10
|
|
33
|
|
|
25
|
while (!$max || @out < $max) { |
24
|
36
|
|
|
|
|
78
|
my ($spos, $epos, $line) = $self->read_line(%params, from => $pos); |
25
|
36
|
50
|
66
|
|
|
90
|
last unless defined($line) || defined($spos) || defined($epos); |
|
|
|
66
|
|
|
|
|
26
|
|
|
|
|
|
|
|
27
|
26
|
100
|
66
|
|
|
75
|
$self->{+LINE_POS} = $epos unless $params{peek} || defined $params{from}; |
28
|
26
|
|
|
|
|
46
|
push @out => [$spos, $epos, $line]; |
29
|
26
|
|
|
|
|
57
|
$pos = $epos; |
30
|
|
|
|
|
|
|
} |
31
|
|
|
|
|
|
|
|
32
|
10
|
|
|
|
|
24
|
return @out; |
33
|
|
|
|
|
|
|
} |
34
|
|
|
|
|
|
|
|
35
|
|
|
|
|
|
|
sub read { |
36
|
3
|
|
|
3
|
0
|
24
|
my $self = shift; |
37
|
|
|
|
|
|
|
|
38
|
3
|
|
|
|
|
11
|
return $self->poll(from => 0); |
39
|
|
|
|
|
|
|
} |
40
|
|
|
|
|
|
|
|
41
|
|
|
|
|
|
|
sub poll { |
42
|
10
|
|
|
10
|
0
|
21
|
my $self = shift; |
43
|
10
|
|
|
|
|
24
|
my @lines = $self->poll_with_index(@_); |
44
|
10
|
|
|
|
|
24
|
return map { $_->[-1] } @lines; |
|
26
|
|
|
|
|
81
|
|
45
|
|
|
|
|
|
|
} |
46
|
|
|
|
|
|
|
|
47
|
|
|
|
|
|
|
sub write { |
48
|
7
|
|
|
7
|
0
|
12
|
my $self = shift; |
49
|
|
|
|
|
|
|
|
50
|
7
|
|
|
|
|
11
|
my $name = $self->{+NAME}; |
51
|
|
|
|
|
|
|
|
52
|
7
|
|
|
|
|
19
|
my $fh = $self->open_file('>>'); |
53
|
|
|
|
|
|
|
|
54
|
|
|
|
|
|
|
flock($fh, LOCK_EX) or die "Could not lock file '$name': $!" |
55
|
7
|
50
|
0
|
|
|
18
|
if $self->{+USE_WRITE_LOCK}; |
56
|
|
|
|
|
|
|
|
57
|
7
|
|
|
|
|
26
|
print $fh $self->encode($_) for @_; |
58
|
7
|
|
|
|
|
102
|
$fh->flush; |
59
|
|
|
|
|
|
|
|
60
|
|
|
|
|
|
|
flock($fh, LOCK_UN) or die "Could not unlock file '$name': $!" |
61
|
7
|
50
|
0
|
|
|
18
|
if $self->{+USE_WRITE_LOCK}; |
62
|
|
|
|
|
|
|
|
63
|
7
|
50
|
|
|
|
37
|
close($fh) or die "Could not clone file '$name': $!"; |
64
|
|
|
|
|
|
|
|
65
|
7
|
|
|
|
|
27
|
return @_; |
66
|
|
|
|
|
|
|
} |
67
|
|
|
|
|
|
|
|
68
|
|
|
|
|
|
|
sub seek { |
69
|
1
|
|
|
1
|
0
|
4
|
my $self = shift; |
70
|
1
|
|
|
|
|
2
|
my ($pos) = @_; |
71
|
|
|
|
|
|
|
|
72
|
1
|
|
|
|
|
3
|
my $fh = $self->fh; |
73
|
1
|
|
|
|
|
2
|
my $name = $self->{+NAME}; |
74
|
|
|
|
|
|
|
|
75
|
1
|
50
|
|
|
|
5
|
seek($fh, $pos, SEEK_SET) or die "Could not seek to position $pos in file '$name': $!"; |
76
|
1
|
|
|
|
|
3
|
$self->{+LINE_POS} = $pos; |
77
|
|
|
|
|
|
|
} |
78
|
|
|
|
|
|
|
|
79
|
|
|
|
|
|
|
1; |
80
|
|
|
|
|
|
|
|
81
|
|
|
|
|
|
|
__END__ |