File Coverage

blib/lib/Math/OEIS/Stripped.pm
Criterion Covered Total %
statement 55 57 96.4
branch 14 18 77.7
condition 6 11 54.5
subroutine 14 14 100.0
pod 5 7 71.4
total 94 107 87.8


line stmt bran cond sub pod time code
1             # Copyright 2010, 2011, 2012, 2013, 2014, 2015, 2016, 2017, 2019, 2020 Kevin Ryde
2              
3             # This file is part of Math-OEIS.
4             #
5             # Math-OEIS is free software; you can redistribute it and/or modify it
6             # under the terms of the GNU General Public License as published by the Free
7             # Software Foundation; either version 3, or (at your option) any later
8             # version.
9             #
10             # Math-OEIS 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-OEIS. If not, see .
17              
18              
19             package Math::OEIS::Stripped;
20 3     3   75942 use 5.006;
  3         20  
21 3     3   16 use strict;
  3         5  
  3         72  
22 3     3   15 use warnings;
  3         15  
  3         107  
23 3     3   29 use Carp 'croak';
  3         4  
  3         167  
24              
25 3     3   460 use Math::OEIS::SortedFile;
  3         6  
  3         173  
26             our @ISA = ('Math::OEIS::SortedFile');
27              
28             # uncomment this to run the ### lines
29             # use Smart::Comments;
30              
31             our $VERSION = 15;
32              
33 3     3   20 use constant base_filename => 'stripped';
  3         5  
  3         312  
34              
35             # Maximum number of decimal digits which fit within a Perl UV integer.
36             # For example a 32-bit IV goes up to 2^31-1 = 2147483647 and in that case
37             # _IV_DECIMAL_DIGITS_MAX is 9 since values up to and including 9 digits
38             # fit into a UV. Some 10 digit values fit too, but not all 10 digits.
39             #
40 3     3   22 use constant _IV_DECIMAL_DIGITS_MAX => length((~0)>>1)-1;
  3         5  
  3         2011  
41              
42             sub new {
43 3     3 1 1923 my $class = shift;
44 3         17 return $class->SUPER::new (use_bigint => 'if_necessary',
45             @_);
46             }
47              
48             sub anum_to_values_str {
49 12     12 1 2234 my ($self, $anum) = @_;
50             ### Stripped anum_to_values_str(): $anum
51              
52 12         43 my $line = $self->anum_to_line($anum);
53 12 100       33 if (! defined $line) { return undef; }
  6         17  
54              
55 6 100       16 my ($got_anum, $values_str) = $self->line_split_anum($line)
56             or return undef; # draft sequence ,, treated same as no such A-number
57              
58 4         11 return $values_str;
59             }
60              
61             sub anum_to_values {
62 7     7 1 3903 my ($self, $anum) = @_;
63 7 50       22 if (! ref $self) { $self = $self->instance; }
  0         0  
64 7         13 my @values;
65 7         14 my $values_str = $self->anum_to_values_str($anum);
66 7 100       19 if (defined $values_str) {
67 3         11 @values = $self->values_split($values_str);
68             }
69 7         30 return @values;
70             }
71              
72             sub values_split {
73 3     3 1 6 my ($self, $values_str) = @_;
74 3 50       10 if (! ref $self) { $self = $self->instance; }
  0         0  
75             ### values_split(): $self
76              
77 3         15 my @values = split /,/, $values_str;
78 3 50       11 if (my $use_bigint = $self->{'use_bigint'}) {
79 3         7 foreach my $value (@values) {
80 9 100 66     46 if ($use_bigint eq '1'
      66        
81             || ($use_bigint eq 'if_necessary'
82             && length($value) > _IV_DECIMAL_DIGITS_MAX)) {
83             ### bignum of: $value
84 1         3 $value = $self->bigint_class_load->new($value); # mutate array
85             }
86             }
87             }
88 3         25576 return @values;
89             }
90              
91             # Not documented yet.
92             # Return a class name which is the BigInt class to use for values from the
93             # stripped file. This class has been loaded ready for use.
94             sub bigint_class_load {
95 1     1 0 4 my ($self) = @_;
96 1   33     6 return ($self->{'bigint_class_load'} ||= do {
97 1         712 require Module::Load;
98 1         1293 my $bigint_class = $self->bigint_class;
99 1         4 Module::Load::load($bigint_class);
100             ### $bigint_class
101 1         29087 $bigint_class
102             });
103             }
104              
105             # Not documented yet.
106             # Return a class name which is the BigInt class to use for values from the
107             # stripped file. This is the C specified in the object, or
108             # default C<'Math::BigInt'>.
109             #
110             # If you want a particular Math::BigInt back-end then have a usual
111             # use Math::BigInt try => 'GMP';
112             # or similar in your mainline code. No C is applied here since it is a
113             # global.
114             #
115             sub bigint_class {
116 1     1 0 3 my ($self) = @_;
117 1   50     9 return ($self->{'bigint_class'} || 'Math::BigInt');
118             }
119              
120             sub line_split_anum {
121 9     9 1 1349 my ($self, $line) = @_;
122             ### Stripped line_split_anum(): $line
123 9 100       94 $line =~ /^(A\d+)(\s+)(,+)([-0-9].*?)(\s|,)*$/
124             or return; # no match of comment line "# ..." or maybe a blank
125 5 50       23 if (length($3) > 1) {
126             # initial ,, is empty values for a draft sequence
127             }
128              
129             # use substr() to preserve taintedness of input $line
130 5         53 return (substr($line,0,length($1)),
131             substr($line,
132             length($1)+length($2)+length($3),
133             length($4)));
134             }
135              
136             1;
137             __END__