File Coverage

blib/lib/Math/NumSeq/File.pm
Criterion Covered Total %
statement 48 54 88.8
branch 10 18 55.5
condition 4 11 36.3
subroutine 11 12 91.6
pod 2 2 100.0
total 75 97 77.3


line stmt bran cond sub pod time code
1             # Copyright 2011, 2012, 2013, 2014 Kevin Ryde
2              
3             # This file is part of Math-NumSeq.
4             #
5             # Math-NumSeq is free software; you can redistribute it and/or modify
6             # it under the terms of the GNU General Public License as published by the
7             # Free Software Foundation; either version 3, or (at your option) any later
8             # version.
9             #
10             # Math-NumSeq is distributed in the hope that it will be useful, but
11             # WITHOUT ANY WARRANTY; without even the implied warranty of MERCHANTABILITY
12             # or FITNESS FOR A PARTICULAR PURPOSE. See the GNU General Public License
13             # for more details.
14             #
15             # You should have received a copy of the GNU General Public License along
16             # with Math-NumSeq. If not, see .
17              
18              
19             # characteristic('increasing')
20             # characteristic('integer')
21             # only by reading the whole file
22             # assume seekable
23              
24              
25              
26             package Math::NumSeq::File;
27 1     1   4756 use 5.004;
  1         4  
  1         40  
28 1     1   6 use strict;
  1         2  
  1         33  
29 1     1   5 use Carp;
  1         2  
  1         69  
30 1     1   823 use POSIX ();
  1         8783  
  1         34  
31              
32 1     1   9 use vars '$VERSION', '@ISA';
  1         3  
  1         68  
33             $VERSION = 71;
34              
35 1     1   759 use Math::NumSeq;
  1         4  
  1         56  
36             @ISA = ('Math::NumSeq');
37             *_to_bigint = \&Math::NumSeq::_to_bigint;
38              
39             # uncomment this to run the ### lines
40             #use Smart::Comments;
41              
42              
43             # use constant name => Math::NumSeq::__('File');
44 1     1   7 use constant i_start => 0;
  1         2  
  1         73  
45 1     1   4 use constant description => Math::NumSeq::__('Numbers from a file');
  1         2  
  1         4  
46 1         3 use constant parameter_info_array =>
47             [ { name => 'filename',
48             type => 'filename',
49             display => Math::NumSeq::__('Filename'),
50             width => 40,
51             default => '',
52 1     1   4 } ];
  1         1  
53              
54             my $max_value = POSIX::FLT_RADIX() ** (POSIX::DBL_MANT_DIG()-5);
55             if ((~0 >> 1) > $max_value) {
56             $max_value = (~0 >> 1);
57             }
58             my $min_value = -$max_value;
59              
60             sub rewind {
61 1     1 1 3 my ($self) = @_;
62             ### Values-File rewind()
63              
64 1 50       5 if ($self->{'fh'}) {
65 0         0 _seek ($self, 0);
66             } else {
67 1         3 my $filename = $self->{'filename'};
68 1 50 33     11 if (defined $filename && $filename !~ /^\s*$/) {
69 1         2 my $fh;
70 1 50       109 ($] >= 5.006
    50          
71             ? open $fh, '<', $filename
72             : open $fh, "< $filename")
73             or croak "Cannot open ",$filename,": ",$!;
74 1         3 $self->{'fh'} = $fh;
75             }
76             }
77 1         13 $self->{'i'} = $self->i_start - 1;
78             }
79              
80             sub next {
81 4     4 1 29 my ($self) = @_;
82 4   50     10 my $fh = $self->{'fh'} || return;
83 4         5 for (;;) {
84 22         41 my $line = readline $fh;
85 22 100       37 if (! defined $line) {
86             ### EOF ...
87 1         3 return;
88             }
89              
90 21 100       53 if ($line =~ /^\s*(-?\d+)(\s+(-?(\d+(\.\d*)?|\.\d+)))?/) {
91 3         6 my ($i, $value);
92 3 50       8 if (defined $3) {
93 3         7 $i = $self->{'i'} = $1;
94 3         6 $value = $3;
95             } else {
96 0         0 $i = ++$self->{'i'};
97 0         0 $value = $1;
98             }
99              
100             # large integer values returned as Math::BigInt
101 3 50 33     16 if (($value > $max_value || $value < $min_value)
      33        
102             && $value !~ /\./) {
103 0         0 $value = _to_bigint($value);
104             }
105              
106 3         10 return ($i, $value);
107             }
108             }
109             }
110              
111             sub _seek {
112 0     0     my ($self, $pos) = @_;
113 0 0         seek ($self->{'fh'}, $pos, 0)
114             or croak "Cannot seek $self->{'filename'}: $!";
115             }
116              
117             1;
118             __END__