File Coverage

blib/lib/Text/CSV_Multiline.pm
Criterion Covered Total %
statement 36 48 75.0
branch 6 12 50.0
condition 1 6 16.6
subroutine 6 8 75.0
pod 0 4 0.0
total 49 78 62.8


line stmt bran cond sub pod time code
1             package Text::CSV_Multiline;
2              
3 2     2   43678 use strict;
  2         5  
  2         74  
4 2     2   11 use warnings;
  2         4  
  2         64  
5              
6 2     2   11 use base "Exporter";
  2         7  
  2         246  
7 2     2   11 use Fcntl ":seek";
  2         3  
  2         3261  
8              
9             our @EXPORT = qw(
10             csv_quote
11             csv_unquote
12             csv_read_record
13             csv_write_record
14             );
15              
16             our $VERSION = 0.01;
17             our $ALWAYS_USE_QUOTES = 0;
18              
19             sub csv_quote
20             {
21 0     0 0 0 my $value = shift;
22 0 0       0 $value = "" if not defined $value;
23 0 0 0     0 if ($value =~ /^[\w\d.]*$/s && !$ALWAYS_USE_QUOTES)
24             {
25 0         0 return $value;
26             }
27 0         0 $value =~ s/"/""/gs;
28 0         0 return "\"$value\"";
29             }
30              
31             sub csv_unquote
32             {
33 16     16 0 33 my $quoted = shift;
34 16         75 $quoted =~ s/^\s+//s;
35 16         44 $quoted =~ s/\s+$//s;
36 16 100       41 if ($quoted =~ /^"(.*)"$/s)
37             {
38 3         7 $quoted = $1;
39 3         6 $quoted =~ s/""/"/gs;
40             }
41             #print STDERR "found field: >$quoted<\n";
42 16         103 return $quoted;
43             }
44              
45             sub csv_read_record
46             {
47 5     5 0 1607 my $fh = shift;
48 5         12 my @parts = ();
49 5         9 my $line = "";
50 5         39 my $num_lines = 0;
51 5         6 local $_;
52 5 50 33     106 while (defined($_ = (ref($fh) && $fh->can("readline"))? $fh->readline : <$fh>))
53             {
54 18         31 $line .= $_;
55 18         261 my $quoted_field = qr/"(?:[^"]|"")*"/;
56 18         49 my $unquoted_field = qr/[^,"]*/;
57 18         144 my $field = qr/\s*(?:$quoted_field|$unquoted_field)\s*/;
58              
59 18         647 while ($line =~ s/^($field),//s)
60             {
61 12         30 push @parts, csv_unquote($1);
62             }
63              
64 18 100       467 if ($line =~ /^($field)$/s)
65             {
66             # last field
67 4         11 push @parts, csv_unquote($1);
68 4         31 return @parts;
69             }
70             }
71 1 50       4 if (length($line))
72             {
73 0         0 warn "detected eof before last field was finished\n";
74 0         0 warn "-->$line<--\n";
75             }
76 1         4 return @parts;
77             }
78              
79             sub csv_write_record
80             {
81 0     0 0   my $fh = shift;
82 0           my @values = @_;
83 0           print $fh join(",", map { csv_quote($_) } @values) . "\n";
  0            
84             }
85              
86             1;
87             __END__