Text-CSV_XS
view release on metacpan or search on metacpan
my $fr = $self->getline (@args) or return;
if (ref $self->{'_FFLAGS'}) { # missing
$self->{'_FFLAGS'}[$_] = CSV_FLAGS_IS_MISSING ()
for (@{$fr} ? $#{$fr} + 1 : 0) .. $#{$self->{'_COLUMN_NAMES'}};
@{$fr} == 1 && (!defined $fr->[0] || $fr->[0] eq "") and
$self->{'_FFLAGS'}[0] ||= CSV_FLAGS_IS_MISSING ();
}
@hr{@{$self->{'_COLUMN_NAMES'}}} = @{$fr};
\%hr;
} # getline_hr
sub getline_hr_all {
my ($self, @args) = @_;
$self->{'_COLUMN_NAMES'} or croak ($self->SetDiag (3002));
my @cn = @{$self->{'_COLUMN_NAMES'}};
[ map { my %h; @h{@cn} = @{$_}; \%h } @{$self->getline_all (@args)} ];
} # getline_hr_all
sub say {
my ($self, $io, @f) = @_;
my $eol = $self->eol ();
# say ($fh, undef) does not propage actual undef to print ()
my $state = $self->print ($io, @f == 1 && !defined $f[0] ? undef : @f);
unless (length $eol) {
$eol = $self->eol_type () || $\ || $/;
print $io $eol;
}
return $state;
} # say
sub print_hr {
my ($self, $io, $hr) = @_;
$self->{'_COLUMN_NAMES'} or croak ($self->SetDiag (3009));
ref $hr eq "HASH" or croak ($self->SetDiag (3010));
$self->print ($io, [ map { $hr->{$_} } $self->column_names () ]);
} # print_hr
sub fragment {
my ($self, $io, $spec) = @_;
my $qd = qr{\s* [0-9]+ \s* }x; # digit
my $qs = qr{\s* (?: [0-9]+ | \* ) \s*}x; # digit or star
my $qr = qr{$qd (?: - $qs )?}x; # range
my $qc = qr{$qr (?: ; $qr )*}x; # list
defined $spec && $spec =~ m{^ \s*
\x23 ? \s* # optional leading #
( row | col | cell ) \s* =
( $qc # for row and col
| $qd , $qd (?: - $qs , $qs)? # for cell (ranges)
(?: ; $qd , $qd (?: - $qs , $qs)? )* # and cell (range) lists
) \s* $}xi or croak ($self->SetDiag (2013));
my ($type, $range) = (lc $1, $2);
my @h = $self->column_names ();
my @c;
if ($type eq "cell") {
my @spec;
my $min_row;
my $max_row = 0;
for (split m/\s*;\s*/ => $range) {
my ($tlr, $tlc, $brr, $brc) = (m{
^ \s* ([0-9]+ ) \s* , \s* ([0-9]+ ) \s*
(?: - \s* ([0-9]+ | \*) \s* , \s* ([0-9]+ | \*) \s* )?
$}x) or croak ($self->SetDiag (2013));
defined $brr or ($brr, $brc) = ($tlr, $tlc);
$tlr == 0 || $tlc == 0 ||
($brr ne "*" && ($brr == 0 || $brr < $tlr)) ||
($brc ne "*" && ($brc == 0 || $brc < $tlc))
and croak ($self->SetDiag (2013));
$tlc--;
$brc-- unless $brc eq "*";
defined $min_row or $min_row = $tlr;
$tlr < $min_row and $min_row = $tlr;
$brr eq "*" || $brr > $max_row and
$max_row = $brr;
push @spec, [ $tlr, $tlc, $brr, $brc ];
}
my $r = 0;
while (my $row = $self->getline ($io)) {
++$r < $min_row and next;
my %row;
my $lc;
foreach my $s (@spec) {
my ($tlr, $tlc, $brr, $brc) = @{$s};
$r < $tlr || ($brr ne "*" && $r > $brr) and next;
!defined $lc || $tlc < $lc and $lc = $tlc;
my $rr = $brc eq "*" ? $#{$row} : $brc;
$row{$_} = $row->[$_] for $tlc .. $rr;
}
push @c, [ @row{sort { $a <=> $b } keys %row } ];
if (@h) {
my %h; @h{@h} = @{$c[-1]};
$c[-1] = \%h;
}
$max_row ne "*" && $r == $max_row and last;
}
return \@c;
}
# row or col
my @r;
my $eod = 0;
for (split m/\s*;\s*/ => $range) {
my ($from, $to) = m/^\s* ([0-9]+) (?: \s* - \s* ([0-9]+ | \* ))? \s* $/x
or croak ($self->SetDiag (2013));
$to ||= $from;
$to eq "*" and ($to, $eod) = ($from, 1);
# $to cannot be <= 0 due to regex and ||=
$from <= 0 || $to < $from and croak ($self->SetDiag (2013));
$r[$_] = 1 for $from .. $to;
}
my $r = 0;
$type eq "col" and shift @r;
$_ ||= 0 for @r;
while (my $row = $self->getline ($io)) {
$r++;
if ($type eq "row") {
if (($r > $#r && $eod) || $r[$r]) {
push @c, $row;
if (@h) {
my %h; @h{@h} = @{$c[-1]};
$c[-1] = \%h;
}
}
next;
}
push @c, [ map { ($_ > $#r && $eod) || $r[$_] ? $row->[$_] : () } 0..$#{$row} ];
if (@h) {
my %h; @h{@h} = @{$c[-1]};
$c[-1] = \%h;
}
}
return \@c;
} # fragment
my $csv_usage = q{usage: my $aoa = csv (in => $file);};
sub _csv_attr {
my %attr;
if (@_ == 1 && ref $_[0] eq "HASH") {
%attr = %{$_[0]};
}
elsif (scalar @_ % 2) {
croak (Text::CSV_XS->SetDiag (1502));
}
else {
%attr = @_;
}
$attr{'binary'} = 1;
$attr{'strict_eol'} = 1;
my $enc = delete $attr{'enc'} || delete $attr{'encoding'} || "";
$enc eq "auto" and ($attr{'detect_bom'}, $enc) = (1, "");
my $stack = $enc =~ s/(:\w.*)// ? $1 : "";
$enc =~ m/^[-\w.]+$/ and $enc = ":encoding($enc)";
$enc .= $stack;
my $hdrs = delete $attr{'headers'};
my $frag = delete $attr{'fragment'};
my $key = delete $attr{'key'};
( run in 1.431 second using v1.01-cache-2.11-cpan-71847e10f99 )