File Coverage

blib/lib/Data/All/IO/File.pm
Criterion Covered Total %
statement 60 66 90.9
branch 11 14 78.5
condition 2 3 66.6
subroutine 16 18 88.8
pod 0 10 0.0
total 89 111 80.1


line stmt bran cond sub pod time code
1             package Data::All::IO::File;
2              
3              
4 1     1   937 use strict;
  1         3  
  1         45  
5 1     1   5 use warnings;
  1         2  
  1         34  
6              
7 1     1   5 use Data::Dumper;
  1         1  
  1         67  
8 1     1   1366 use Data::All::IO::Base;
  1         4  
  1         124  
9 1     1   1200 use IO::File;
  1         12117  
  1         200  
10 1     1   1024 use FileHandle;
  1         1130  
  1         8  
11              
12              
13             our $VERSION = 0.11;
14              
15             internal 'IO';
16             internal 'fh';
17              
18             attribute 'format';
19             attribute 'fields';
20             attribute 'ioconf';
21             attribute 'path';
22              
23             attribute 'is_open' => 0;
24              
25             internal 'FORMAT';
26             internal 'curpos' => -1;
27             internal 'added_fields' => {};
28              
29              
30             sub create_path()
31             {
32 10     10 0 14 my $self = shift;
33 10         12 return join '', @{ $self->path };
  10         26  
34             }
35              
36             sub open($)
37             {
38 6     6 0 10 my $self = shift;
39 6         14 my $path = $self->create_path();
40            
41 6 100       33 unless ($self->is_open())
42             {
43             #warn " -> Opening $path for ", $self->ioconf()->{'perm'};
44             #warn " -> path:", join ', ', @{ $self->path() };
45             #warn " -> format:", $self->format()->{'type'};
46             #warn " -> io:", $self->ioconf->{'type'};
47            
48 4 50 66     15 die("The file: $path does not exist")
49             if (($self->ioconf()->{'perm'} eq 'r') && !(-f $path));
50            
51             # We create out own filehandle for better read/write control
52 4         13 my $fh = FileHandle->new($self->create_path(), $self->ioconf()->{'perm'});
53            
54 4         764 $self->__IO( $fh );
55 4         14 $self->__fh( $fh );
56            
57 4         12 $self->is_open(1);
58            
59 4         11 $self->_extract_fields(); # Initialize field names
60             }
61            
62 6         19 return $self->is_open();
63             }
64              
65             sub close()
66             {
67 2     2 0 4 my $self = shift;
68            
69 2         6 $self->__fh()->close();
70            
71 2         45 $self->__IO()->close();
72 2         15 $self->is_open(0);
73             }
74              
75             sub nextrecord()
76             {
77 12     12 0 15 my $self = shift;
78 12         15 my $r;
79            
80             # TODO: Write an actual solution for converting from
81             # one line terminator to another.
82              
83             # Incrememnt cursor and remove trailing line
84 12 100       187 if ($r = $self->__fh()->getline())
85             {
86 8         380 $r =~ s/\r\n/\n/g; # NOTE: a quick hack to convert DOS to UNIX
87 8         14 chomp($r);
88 8         27 $self->_next();
89             }
90            
91 12         495 return $r;
92             }
93              
94             sub hash_to_record()
95             {
96 3     3 0 5 my ($self, $hash) = @_;
97            
98             # we do it like this to make sure the order is the same
99 3         9 return $self->array_to_record($self->hash_to_array($hash));
100             }
101              
102             sub array_to_record()
103             {
104 3     3 0 4 my ($self, $array) = @_;
105 3         8 return $self->__FORMAT()->contract($array);
106             }
107              
108              
109              
110             sub getrecord_array()
111             # With original = include original record from file
112             {
113 12     12 0 22 my ($self, $with_original) = @_;
114 12         12 my $raw;
115            
116 12 100       23 return undef unless ($raw = $self->nextrecord());
117            
118             # We return the original record first b/c if we do it
119             # last and there are empty values at the end the order will be confused
120 8 50       197 my $rec_arrayref = ($with_original)
121             ? [$raw, $self->__FORMAT()->expand($raw)]
122             : [$self->__FORMAT()->expand($raw)];
123            
124 8 100       36 return !wantarray ? $rec_arrayref : @{ $rec_arrayref };
  2         14  
125             }
126            
127             sub putfields()
128             {
129 0     0 0 0 my $self = shift;
130 0         0 $self->__IO()->print($self->array_to_record($self->fields));
131             }
132              
133             sub putrecord($)
134             {
135 3     3 0 5 my $self = shift;
136 3         5 my $record = shift;
137            
138 3         82 $self->__IO()->print($self->hash_to_record($record));
139            
140 3         30 return 1;
141             }
142              
143              
144             sub _extract_fields()
145             {
146 4     4   6 my $self = shift;
147 4 50       13 return if ($self->fields());
148 4         12 $self->fields([$self->getrecord_array(0)]);
149             }
150              
151             sub count()
152             {
153 0     0 0 0 my $self = shift;
154 0         0 my $count;
155            
156             # From the Perl Cookbook. It doesn't actually replace every
157             # new line with a new new line -- it's a legacy feature.
158 0         0 $count += tr/\n/\n/ while sysread($self->__fh(), $_, 2 ** 20);
159            
160 0         0 return $count;
161             }
162 8     8   29 sub _next() { $_[0]->__curpos( $_[0]->__curpos() + 1) }
163              
164              
165             1;