File Coverage

blib/lib/oEdtk/Record.pm
Criterion Covered Total %
statement 9 98 9.1
branch 0 18 0.0
condition 0 10 0.0
subroutine 3 11 27.2
pod 0 8 0.0
total 12 145 8.2


line stmt bran cond sub pod time code
1             package oEdtk::Record;
2              
3 1     1   577 use strict;
  1         3  
  1         30  
4 1     1   5 use warnings;
  1         2  
  1         27  
5              
6 1     1   6 use Scalar::Util qw(blessed);
  1         1  
  1         1131  
7             our $VERSION = 0.7005;
8              
9             sub debug {
10 0     0 0   my ($self)= @_;
11 0           $self->{'_DEBUG'} = 1;
12             }
13              
14              
15             # A RECORD IS A SEQUENCE OF FIELDS.
16             sub new {
17 0     0 0   my ($class, @fields) = @_;
18              
19 0           my $template = '';
20 0           foreach my $i (0 .. $#fields) {
21 0           my $field = $fields[$i];
22 0 0 0       if (!blessed($field) || !$field->isa('oEdtk::Field')) {
23 0           die "ERROR: oEdtk::Record::new only accepts oEdtk::Field objects\n";
24             }
25 0           my $len = $field->get_len();
26 0 0 0       if ($len eq '*' && $i < $#fields) {
27 0           die "ERROR: oEdtk::Record::new: catch-all field must be the last\n";
28             }
29             # if ($i != 0) {
30             # $template .= ' ';
31             # }
32 0           $template .= "A$len";
33             }
34              
35 0           my $self = {
36             seek_key => "LIGNE.{153}(.{10})",
37             fields_offset => 10,
38             fields => \@fields,
39             template => $template,
40             bound => {}
41             };
42 0           bless $self, $class;
43 0           return $self;
44             }
45              
46              
47             sub set_seek_key{
48 0     0 0   my ($self, $seek_key)= @_;
49            
50 0   0       $self->{'seek_key'} = $seek_key || "LIGNE.{153}(.{10})";
51             }
52              
53              
54             sub set_fields_offset {
55 0     0 0   my ($self, $fields_offset)= @_;
56            
57 0   0       $self->{'fields_offset'} = $fields_offset || 10;
58             }
59              
60              
61             sub parse {
62 0     0 0   my ($self, $line) = @_;
63 0           my @values;
64              
65 0           my $bound = $self->{'bound'};
66             # my $fields_offset = $self->{'fields_offset'};
67             # if ($line !~ /^.{$fields_offset}(.*)$/) {
68             # die "ERROR: Line too short\n";
69             # }
70             # $line = $1;
71              
72 0           my @vals = unpack($self->{'template'}, $line);
73 0           my %hvals = ();
74 0           foreach my $i (0 .. $#{$self->{'fields'}}) {
  0            
75 0           my $field= $self->{'fields'}->[$i];
76 0           my $name = $field->get_name();
77 0 0         if (exists($bound->{$name})) {
78 0           $hvals{$name} = $field->process($vals[$i]);
79             }
80             }
81 0           return %hvals;
82             }
83              
84              
85             sub bind {
86 0     0 0   my ($self, %map) = @_;
87              
88 0           my %bound;
89 0           foreach my $field (@{$self->{'fields'}}) {
  0            
90 0           my $name = $field->get_name();
91 0 0         if (exists($map{$name})) {
92 0           my $new = $map{$name};
93 0           $field->set_name($new);
94 0           $bound{$new} = 1;
95             }
96             }
97 0           $self->{'bound'} = { %{$self->{'bound'}}, %bound };
  0            
98             }
99              
100              
101             sub bind_all {
102 0     0 0   my ($self) = @_;
103              
104 0           my $count = 0;
105 0           my $pos = 0;
106 0           my %identifiers;
107 0           foreach my $field (@{$self->{'fields'}}) {
  0            
108 0           my $name = $field->get_name();
109 0           $name =~ s/(?:-\d+)?$//;
110              
111             # Select the longest component.
112 0           my @parts = split(/-/, $name);
113 0           my $id = (reverse sort { length($a) <=> length($b) } @parts)[0];
  0            
114              
115 0           my $orig= $field->get_name();
116 0           my $len = $field->get_len();
117 0 0         warn "DEBUG: $id \tindex: $count \tpos: $pos \tlength: $len \tfrom $orig\n" if $self->{'_DEBUG'};
118 0 0         $pos += $len if ($len ne '*');
119            
120 0           $field->set_name($id);
121 0           $identifiers{$id} = 1;
122              
123 0           $self->{'bound'} = { %{$self->{'bound'}}, $id => 1 };
  0            
124 0           $count++;
125             }
126             }
127              
128              
129             # Bind all the fields in a record, following the old Compuset convention.
130             sub bind_all_c7 {
131 0     0 0   my ($self) = @_;
132              
133 0           my $count = 0;
134 0           my $pos = 0;
135 0           my %identifiers;
136 0           foreach my $field (@{$self->{'fields'}}) {
  0            
137 0           my $name = $field->get_name();
138 0           $name =~ s/(?:-\d+)?$//;
139              
140             # Select the longest component.
141 0           my @parts = split(/-/, $name);
142 0           my $id = (reverse sort { length($a) <=> length($b) } @parts)[0];
  0            
143 0           $id = substr($id, 0, 7);
144 0           $id .= 'x' x (7 - length($id));
145 0 0         if (exists($identifiers{$id})) {
146 0           $id = substr($id, 0, 4) . sprintf("%03d", $count);
147 0           my $char = ord('a');
148 0           while (exists($identifiers{$id})) {
149 0           $id = substr($id, 0, 3) . $count . chr($char);
150             }
151             }
152              
153 0           my $orig= $field->get_name();
154 0           my $len = $field->get_len();
155 0 0         warn "DEBUG: $id \tindex: $count \tpos: $pos \tlength: $len \tfrom $orig\n" if $self->{'_DEBUG'};
156 0 0         $pos += $len if ($len ne '*');
157            
158 0           $field->set_name($id);
159 0           $identifiers{$id} = 1;
160              
161 0           $self->{'bound'} = { %{$self->{'bound'}}, $id => 1 };
  0            
162 0           $count++;
163             }
164             }
165              
166              
167             1;