File Coverage

blib/lib/Text/FixedLength.pm
Criterion Covered Total %
statement 62 81 76.5
branch 16 40 40.0
condition 12 28 42.8
subroutine 6 10 60.0
pod 0 8 0.0
total 96 167 57.4


line stmt bran cond sub pod time code
1             # ----------------------------------------------------------------------------
2             # Name: Text::FixedLength.pm
3             # Auth: Dion Almaer (dion)
4             # Desc: Manipulate fixed length fields, from creating to parsing
5             # Date Created: Sun Nov 15 17:50:29 1998
6             # Version: 0.12
7             # $Modified: Wed Nov 18 16:55:46 CST 1998 by dion $
8             # ----------------------------------------------------------------------------
9             package Text::FixedLength;
10 2     2   4591 use strict;
  2         4  
  2         65  
11 2     2   10 use Exporter;
  2         4  
  2         2640  
12              
13             # ----------------------------------------------------------------------------
14             # Package Variables
15             # ----------------------------------------------------------------------------
16             @Text::FixedLength::ISA = qw(Exporter);
17             @Text::FixedLength::EXPORT = qw(delim2fixed fixed2delim setJustify setCrop);
18             $Text::FixedLength::VERSION = '0.12';
19             my $defaultJustification = 'L'; # -- left justified by default (setJustify)
20             my $cropRecords = 1; # -- force fixed format by cropping records
21              
22             # ----------------------------------------------------------------------------
23             # Module Subroutines
24             # ----------------------------------------------------------------------------
25              
26             # ----------------------------------------------------------------------------
27             # DELIMITED DATA - > FIXED LENGTH FIELD DATA
28             # ----------------------------------------------------------------------------
29              
30             # ----------------------------------------------------------------------------
31             # Subroutine: delim2fixed - given an array of delimited text, or file with
32             # delimited text, create an array of fixed text
33             # SEE THE POD DOCUMENTATION BELOW (perldoc Text::FixedLength)
34             # ----------------------------------------------------------------------------
35             sub delim2fixed {
36 2   50 2 0 30 my $delimData = shift || die 'delim2fixed: need data';
37 2   50     6 my $delim = shift || die 'delim2fixed: need a delimiter';
38 2   50     7 my $format = shift || die 'delim2fixed: need a fixed format array';
39 2         3 my $outfile = shift; # -- if set then save data to outfile
40              
41 2 50       8 my @delimdata = ( ref $delimData eq 'ARRAY' ) ? @{ $delimData }
  2         4  
42             : getFile($delimData);
43 2         5 my @fixeddata = map { getFixed($_, $delim, $format) } @delimdata;
  2         7  
44 2 50       5 if ($outfile) {
45 0         0 savetoFile($outfile, \@fixeddata);
46             }
47 2         3 my $w = wantarray;
48 2 50       7 return unless defined $w;
49 2 50       10 return $w ? @fixeddata : \@fixeddata;
50             }
51              
52             # ----------------------------------------------------------------------------
53             # Subroutine: getFixed - given a string, delimiter, and format return a string
54             # ----------------------------------------------------------------------------
55             sub getFixed {
56 2   50 2 0 6 my $s = shift || die 'getFixed: need a string';
57 2   50     7 my $delim = shift || die 'getFixed: need a delimiter';
58 2   50     9 my $format = shift || die 'getFixed: need a format';
59 2         4 my $out = '';
60 2 50       18 die "getFixed: no delimiter in $s" unless $s =~ /$delim/;
61              
62             # -- get each piece
63 2         13 my @records = split /$delim/, $s;
64              
65             # -- setup the sprintf format (e.g. "%-8s%3s...")
66 2         4 my $count = 0;
67 2         5 foreach ( @$format ) {
68 8         9 my $f = $_; # -- copy the format as we chop it later
69 8 50       18 my $just = ($defaultJustification eq 'L') ? '-' : '';
70 8 50       28 if ( uc substr($f, -1) =~ /[RL]/ ) {
71 8         13 my $c = uc chop $f;
72 8 100       20 if ( $c eq 'L' ) { $just = '-'; } elsif ( $c eq 'R' ) { $just = ''; }
  4 50       7  
  4         6  
73             }
74 8         15 $out .= "%${just}${f}s";
75              
76             # -- Crop the record if it is longer than it is meant to be
77 8 50       14 if ($cropRecords) {
78 8 50       22 $records[$count] = substr($records[$count], 0, $f)
79             if length $records[$count] > $f;
80             }
81 8         12 $count++;
82             }
83 2         15 return sprintf $out, @records;
84             }
85              
86             # ----------------------------------------------------------------------------
87             # FIXED LENGTH FIELD DATA -> DELIMITED DATA
88             # ----------------------------------------------------------------------------
89              
90             # ----------------------------------------------------------------------------
91             # Subroutine: fixed2delim
92             # SEE THE POD DOCUMENTATION BELOW (perldoc Text::FixedLength)
93             # ----------------------------------------------------------------------------
94             sub fixed2delim {
95 1   50 1 0 17 my $fixedData = shift || die 'fixed2delim: need data';
96 1   50     5 my $fixedFormat = shift || die 'fixed2delim: need fixed format aref';
97 1   50     7 my $delim = shift || die 'fixed2delim: need the delim you want';
98 1         2 my $outfile = shift; # -- the file that you want the data to output to
99              
100 1 50       7 my @fixeddata = ( ref $fixedData eq 'ARRAY' ) ? @{ $fixedData }
  1         4  
101             : getFile($fixedData);
102              
103 1         5 my @delimdata = map { getDelim($_, $delim, $fixedFormat) } @fixeddata;
  1         5  
104              
105 1 50       5 if ($outfile) {
106 0         0 savetoFile($outfile, \@delimdata);
107             }
108 1         3 my $w = wantarray;
109 1 50       8 return unless defined $w;
110 1 50       8 return $w ? @delimdata : \@delimdata;
111             }
112              
113             # ----------------------------------------------------------------------------
114             # Subroutine: getDelim - given a string, delimiter, and format return a string
115             # ----------------------------------------------------------------------------
116             sub getDelim {
117 1   50 1 0 5 my $s = shift || die 'getDelim: need a string';
118 1   50     4 my $delim = shift || die 'getDelim: need a delimiter';
119 1   50     5 my $format = shift || die 'getDelim: need a format';
120 1         2 my @out = ();
121              
122 1         4 foreach ( @$format ) {
123 4         14 s/\D//g; # - save only digits
124 4         11 my $sub = substr($s,0,$_); $sub =~ s/^\s+//; $sub =~ s/\s+$//;
  4         10  
  4         9  
125 4         9 push @out, $sub;
126 4         9 substr($s,0,$_) = '';
127             }
128 1         8 return join $delim, @out;
129             }
130              
131             # ----------------------------------------------------------------------------
132             # UTILITY / SHARED FUNCTIONS
133             # ----------------------------------------------------------------------------
134              
135             # ----------------------------------------------------------------------------
136             # Subroutine: setJustify - given either 'l' 'L' 'r' 'R' set the justification
137             # ----------------------------------------------------------------------------
138             sub setJustify {
139 0     0 0   my $char = uc shift;
140 0 0         die 'setJustify: need one of: l, L, r, R' unless $char =~ /[LR]/;
141 0           $defaultJustification = $char;
142             }
143              
144             # ----------------------------------------------------------------------------
145             # Subroutine: setCrop - set the cropRecords value (whether to force the fixed
146             # format by constraining a string to the size of its format)
147             # ----------------------------------------------------------------------------
148             sub setCrop {
149 0 0   0 0   my $arg = shift; die 'setCrop: need either 1 or 0' unless defined $arg;
  0            
150 0 0         $cropRecords = ($arg) ? 1 : 0;
151             }
152              
153             # ----------------------------------------------------------------------------
154             # Subroutine: savetoFile - save fixeddata array ref to outfile
155             # ----------------------------------------------------------------------------
156             sub savetoFile {
157 0   0 0 0   my $outfile = shift || die 'savetoFile: need a filename to save to';
158 0   0       my $dataref = shift || die 'savetoFile: need data to save';
159              
160 0 0         open F, "> $outfile" or die "savetoFile: couldn't open $outfile: $!";
161 0           foreach (@$dataref) { print F "$_\n"; }
  0            
162 0           close F;
163             }
164              
165             # ----------------------------------------------------------------------------
166             # Subroutine: getFile - given a filename return it lines in an array
167             # ----------------------------------------------------------------------------
168             sub getFile {
169 0     0 0   my $file = shift;
170 0 0         open F, $file or die "getDelimData: couldn't open file $file: $!";
171 0           chomp( my @data = );
172 0           close F;
173 0           return @data;
174             }
175              
176             # ----------------------------------------------------------------------------
177             1; # End of Text::FixedLength
178             # ----------------------------------------------------------------------------
179              
180             __END__