File Coverage

blib/lib/Text/CSV_PP.pm
Criterion Covered Total %
statement 1856 1993 93.1
branch 1359 1550 87.6
condition 866 1065 81.2
subroutine 136 136 100.0
pod 68 69 98.5
total 4285 4813 89.0


line stmt bran cond sub pod time code
1             package Text::CSV_PP;
2              
3             ################################################################################
4             #
5             # Text::CSV_PP - Text::CSV_XS compatible pure-Perl module
6             #
7             ################################################################################
8             require 5.006001;
9              
10 39     39   123290 use strict;
  39         73  
  39         1572  
11 39     39   257 use Exporter ();
  39         81  
  39         1126  
12 39     39   297 use vars qw($VERSION @ISA @EXPORT_OK %EXPORT_TAGS);
  39         105  
  39         3076  
13 39     39   264 use Carp;
  39         130  
  39         25811  
14              
15             $VERSION = '2.06';
16             @ISA = qw(Exporter);
17              
18 12     12 1 239583 sub PV { 0 }
19 18     18 1 211043 sub IV { 1 }
20 16     16 1 73 sub NV { 2 }
21              
22 4     4 1 15 sub CSV_TYPE_PV { PV }
23 4     4 1 14 sub CSV_TYPE_IV { IV }
24 4     4 1 12 sub CSV_TYPE_NV { NV }
25              
26             sub IS_QUOTED () { 0x0001; }
27             sub IS_BINARY () { 0x0002; }
28             sub IS_ERROR () { 0x0004; }
29             sub IS_MISSING () { 0x0010; }
30              
31 3317     3317 1 7585 sub CSV_FLAGS_IS_QUOTED { IS_QUOTED }
32 12     12 1 60 sub CSV_FLAGS_IS_BINARY { IS_BINARY }
33 4     4 1 47 sub CSV_FLAGS_ERROR_IN_FIELD { IS_ERROR }
34 20     20 1 108 sub CSV_FLAGS_IS_MISSING { IS_MISSING }
35              
36             sub HOOK_ERROR () { 0x0001; }
37             sub HOOK_AFTER_PARSE () { 0x0002; }
38             sub HOOK_BEFORE_PRINT () { 0x0004; }
39              
40             sub EOL_TYPE_UNDEF () { 0 }
41             sub EOL_TYPE_NL () { 1 }
42             sub EOL_TYPE_CR () { 2 }
43             sub EOL_TYPE_CRNL () { 3 }
44             sub EOL_TYPE_OTHER () { 4 }
45              
46             sub useIO_EOF () { 0x0010; }
47              
48             %EXPORT_TAGS = (
49             CONSTANTS => [qw(
50             CSV_FLAGS_IS_QUOTED
51             CSV_FLAGS_IS_BINARY
52             CSV_FLAGS_ERROR_IN_FIELD
53             CSV_FLAGS_IS_MISSING
54              
55             CSV_TYPE_PV
56             CSV_TYPE_IV
57             CSV_TYPE_NV
58             )],
59             );
60             @EXPORT_OK = (qw(csv PV IV NV), @{$EXPORT_TAGS{'CONSTANTS'}});
61              
62             my $ERRORS = {
63             # Generic errors
64             1000 => "INI - constructor failed",
65             1001 => "INI - sep_char is equal to quote_char or escape_char",
66             1002 => "INI - allow_whitespace with escape_char or quote_char SP or TAB",
67             1003 => "INI - \\r or \\n in main attr not allowed",
68             1004 => "INI - callbacks should be undef or a hashref",
69             1005 => "INI - EOL too long",
70             1006 => "INI - SEP too long",
71             1007 => "INI - QUOTE too long",
72             1008 => "INI - SEP undefined",
73              
74             1010 => "INI - the header is empty",
75             1011 => "INI - the header contains more than one valid separator",
76             1012 => "INI - the header contains an empty field",
77             1013 => "INI - the header contains nun-unique fields",
78             1014 => "INI - header called on undefined stream",
79              
80             # Syntax errors
81             1500 => "PRM - Invalid/unsupported arguments(s)",
82             1501 => "PRM - The key attribute is passed as an unsupported type",
83             1502 => "PRM - The value attribute is passed without the key attribute",
84             1503 => "PRM - The value attribute is passed as an unsupported type",
85              
86             # Parse errors
87             2010 => "ECR - QUO char inside quotes followed by CR not part of EOL",
88             2011 => "ECR - Characters after end of quoted field",
89             2012 => "EOF - End of data in parsing input stream",
90             2013 => "ESP - Specification error for fragments RFC7111",
91             2014 => "ENF - Inconsistent number of fields",
92             2015 => "ERW - Empty row",
93             2016 => "EOL - Inconsistent EOL",
94              
95             # EIQ - Error Inside Quotes
96             2021 => "EIQ - NL char inside quotes, binary off",
97             2022 => "EIQ - CR char inside quotes, binary off",
98             2023 => "EIQ - QUO character not allowed",
99             2024 => "EIQ - EOF cannot be escaped, not even inside quotes",
100             2025 => "EIQ - Loose unescaped escape",
101             2026 => "EIQ - Binary character inside quoted field, binary off",
102             2027 => "EIQ - Quoted field not terminated",
103              
104             # EIF - Error Inside Field
105             2030 => "EIF - NL char inside unquoted verbatim, binary off",
106             2031 => "EIF - CR char is first char of field, not part of EOL",
107             2032 => "EIF - CR char inside unquoted, not part of EOL",
108             2034 => "EIF - Loose unescaped quote",
109             2035 => "EIF - Escaped EOF in unquoted field",
110             2036 => "EIF - ESC error",
111             2037 => "EIF - Binary character in unquoted field, binary off",
112              
113             # Combine errors
114             2110 => "ECB - Binary character in Combine, binary off",
115              
116             # IO errors
117             2200 => "EIO - print to IO failed. See errno",
118              
119             # Hash-Ref errors
120             3001 => "EHR - Unsupported syntax for column_names ()",
121             3002 => "EHR - getline_hr () called before column_names ()",
122             3003 => "EHR - bind_columns () and column_names () fields count mismatch",
123             3004 => "EHR - bind_columns () only accepts refs to scalars",
124             3006 => "EHR - bind_columns () did not pass enough refs for parsed fields",
125             3007 => "EHR - bind_columns needs refs to writable scalars",
126             3008 => "EHR - unexpected error in bound fields",
127             3009 => "EHR - print_hr () called before column_names ()",
128             3010 => "EHR - print_hr () called with invalid arguments",
129              
130             4001 => "PRM - The key does not exist as field in the data",
131              
132             5001 => "PRM - The result does not match the output to append to",
133             5002 => "PRM - Unsupported output",
134              
135             0 => "",
136             };
137              
138             BEGIN {
139 39 50   39   553 if ($] < 5.006) {
    50          
    50          
140 0 0       0 $INC{'bytes.pm'} = 1 unless $INC{'bytes.pm'}; # dummy
141 39     39   289 no strict 'refs';
  39         87  
  39         5302  
142 0         0 *{"utf8::is_utf8"} = sub { 0; };
  0         0  
  0         0  
143 0         0 *{"utf8::decode"} = sub { };
  0         0  
144             }
145             elsif ($] < 5.008) {
146 39     39   238 no strict 'refs';
  39         102  
  39         14802  
147 0         0 *{"utf8::is_utf8"} = sub { 0; };
  0         0  
  0         0  
148 0         0 *{"utf8::decode"} = sub { };
  0         0  
149 0         0 *{"utf8::encode"} = sub { };
  0         0  
150             }
151             elsif (!defined &utf8::is_utf8) {
152 0         0 require Encode;
153 0         0 *utf8::is_utf8 = *Encode::is_utf8;
154             }
155              
156 39         3019 eval q| require Scalar::Util |;
157 39 50       638185 if ($@) {
158 0         0 eval q| require B |;
159 0 0       0 if ($@) {
160 0         0 Carp::croak $@;
161             }
162             else {
163 0         0 my %tmap = qw(
164             B::NULL SCALAR
165             B::HV HASH
166             B::AV ARRAY
167             B::CV CODE
168             B::IO IO
169             B::GV GLOB
170             B::REGEXP REGEXP
171             );
172             *Scalar::Util::reftype = sub (\$) {
173 0         0 my $r = shift;
174 0 0       0 return undef unless length(ref($r));
175 0         0 my $t = ref(B::svref_2object($r));
176             return
177 0 0       0 exists $tmap{$t} ? $tmap{$t}
    0          
178             : length(ref($$r)) ? 'REF'
179             : 'SCALAR';
180 0         0 };
181             *Scalar::Util::readonly = sub (\$) {
182 0         0 my $b = B::svref_2object($_[0]);
183 0         0 $b->FLAGS & 0x00800000; # SVf_READONLY?
184 0         0 };
185             }
186             }
187             }
188              
189             ################################################################################
190             #
191             # Common pure perl methods, taken almost directly from Text::CSV_XS.
192             # (These should be moved into a common class eventually, so that
193             # both XS and PP don't need to apply the same changes.)
194             #
195             ################################################################################
196              
197             ################################################################################
198             # version
199             ################################################################################
200              
201             sub version {
202 2     2 1 1142 return $VERSION;
203             }
204              
205             ################################################################################
206             # new
207             ################################################################################
208              
209             my %def_attr = (
210             eol => '',
211             sep_char => ',',
212             quote_char => '"',
213             escape_char => '"',
214             binary => 0,
215             decode_utf8 => 1,
216             auto_diag => 0,
217             diag_verbose => 0,
218             strict => 0,
219             strict_eol => 0,
220             blank_is_undef => 0,
221             empty_is_undef => 0,
222             allow_whitespace => 0,
223             allow_loose_quotes => 0,
224             allow_loose_escapes => 0,
225             allow_unquoted_escape => 0,
226             always_quote => 0,
227             quote_empty => 0,
228             quote_space => 1,
229             quote_binary => 1,
230             escape_null => 1,
231             keep_meta_info => 0,
232             verbatim => 0,
233             formula => 0,
234             skip_empty_rows => 0,
235             undef_str => undef,
236             comment_str => undef,
237             types => undef,
238             callbacks => undef,
239              
240             _EOF => "",
241             _RECNO => 0,
242             _STATUS => undef,
243             _FIELDS => undef,
244             _FFLAGS => undef,
245             _STRING => undef,
246             _ERROR_INPUT => undef,
247             _COLUMN_NAMES => undef,
248             _BOUND_COLUMNS => undef,
249             _AHEAD => undef,
250             _FORMULA_CB => undef,
251             _EMPTROW_CB => undef,
252              
253             ENCODING => undef,
254             );
255              
256             my %attr_alias = (
257             quote_always => "always_quote",
258             verbose_diag => "diag_verbose",
259             quote_null => "escape_null",
260             escape => "escape_char",
261             comment => "comment_str",
262             );
263              
264             my $last_err = Text::CSV_PP->SetDiag(0);
265             my $ebcdic = ord("A") == 0xC1; # Faster than $Config{'ebcdic'}
266             my @internal_kh;
267              
268             # NOT a method: is also used before bless
269             sub _unhealthy_whitespace {
270 15757     15757   32216 my ($self, $aw) = @_;
271 15757 100       52818 $aw or return 0; # no checks needed without allow_whitespace
272              
273 3573         7049 my $quo = $self->{quote};
274 3573 100 100     12120 defined $quo && length($quo) or $quo = $self->{quote_char};
275 3573         7521 my $esc = $self->{escape_char};
276              
277 3573 100 100     21464 defined $quo && $quo =~ m/^[ \t]/ and return 1002;
278 3331 100 100     15601 defined $esc && $esc =~ m/^[ \t]/ and return 1002;
279              
280 3041         9331 return 0;
281             }
282              
283             sub _check_sanity {
284 12451     12451   19340 my $self = shift;
285              
286 12451         21357 my $eol = $self->{eol};
287 12451         21095 my $sep = $self->{sep};
288 12451 100 100     33352 defined $sep && length($sep) or $sep = $self->{sep_char};
289 12451         19448 my $quo = $self->{quote};
290 12451 100 100     32692 defined $quo && length($quo) or $quo = $self->{quote_char};
291 12451         19135 my $esc = $self->{escape_char};
292              
293             # use DP;::diag ("SEP: '", DPeek ($sep),
294             # "', QUO: '", DPeek ($quo),
295             # "', ESC: '", DPeek ($esc),"'");
296              
297             # sep_char should not be undefined
298 12451 100       28729 $sep ne "" or return 1008;
299 12449 100       27274 length($sep) > 16 and return 1006;
300 12448 100       38550 $sep =~ m/[\r\n]/ and return 1003;
301              
302 12442 100       24170 if (defined $quo) {
303 12431 100       27666 $quo eq $sep and return 1001;
304 12203 100       22792 length($quo) > 16 and return 1007;
305 12202 100       26160 $quo =~ m/[\r\n]/ and return 1003;
306             }
307 12207 100       22081 if (defined $esc) {
308 12191 100       26765 $esc eq $sep and return 1001;
309 12023 100       26473 $esc =~ m/[\r\n]/ and return 1003;
310             }
311 12033 100       23337 if (defined $eol) {
312 12028 100       21869 length($eol) > 16 and return 1005;
313             }
314              
315 12032         23676 return _unhealthy_whitespace($self, $self->{allow_whitespace});
316             }
317              
318             sub known_attributes {
319 3     3 1 738 sort grep !m/^_/ => "sep", "quote", keys %def_attr;
320             }
321              
322             sub new {
323 1025     1025 1 237114 $last_err = Text::CSV_PP->SetDiag(1000,
324             "usage: my \$csv = Text::CSV_PP->new ([{ option => value, ... }]);");
325              
326 1025         1996 my $proto = shift;
327 1025 100 66     5807 my $class = ref $proto || $proto or return;
328 1024 100 100     5695 @_ > 0 && ref $_[0] ne "HASH" and return;
329 1016   100     3068 my $attr = shift || {};
330             my %attr = map {
331 2801 100       11333 my $k = m/^[a-zA-Z]\w+$/ ? lc $_ : $_;
332 2801 100       7994 exists $attr_alias{$k} and $k = $attr_alias{$k};
333 2801         8196 ($k => $attr->{$_});
334 1016         1915 } keys %{$attr};
  1016         3796  
335              
336 1016         2716 my $sep_aliased = 0;
337 1016 100       3208 if (exists $attr{sep}) {
338 10         27 $attr{sep_char} = delete $attr{sep};
339 10         22 $sep_aliased = 1;
340             }
341 1016         1809 my $quote_aliased = 0;
342 1016 100       2691 if (exists $attr{quote}) {
343 25         52 $attr{quote_char} = delete $attr{quote};
344 25         57 $quote_aliased = 1;
345             }
346             exists $attr{formula_handling} and
347 1016 100       2726 $attr{formula} = delete $attr{formula_handling};
348 1016         2208 my $attr_formula = delete $attr{formula};
349              
350 1016         3027 for (keys %attr) {
351 2765 100 100     10829 if (m/^[a-z]/ && exists $def_attr{$_}) {
352             # uncoverable condition false
353 2758 100 100     10075 defined $attr{$_} && m/_char$/ and utf8::decode($attr{$_});
354 2758         4929 next;
355             }
356             # croak?
357 7         27 $last_err = Text::CSV_PP->SetDiag(1000, "INI - Unknown attribute '$_'");
358 7 100       43 $attr{auto_diag} and error_diag();
359 7         32 return;
360             }
361 1009 100       3135 if ($sep_aliased) {
362 10         57 my @b = unpack "U0C*", $attr{sep_char};
363 10 100       32 if (@b > 1) {
364 6         16 $attr{sep} = $attr{sep_char};
365 6         14 $attr{sep_char} = "\0";
366             }
367             else {
368 4         10 $attr{sep} = undef;
369             }
370             }
371 1009 100 100     6465 if ($quote_aliased and defined $attr{quote_char}) {
372 21         81 my @b = unpack "U0C*", $attr{quote_char};
373 21 100       46 if (@b > 1) {
374 7         19 $attr{quote} = $attr{quote_char};
375 7         16 $attr{quote_char} = "\0";
376             }
377             else {
378 14         29 $attr{quote} = undef;
379             }
380             }
381              
382 1009         26381 my $self = {%def_attr, %attr};
383 1009 100       5355 if (my $ec = _check_sanity($self)) {
384 35         102 $last_err = Text::CSV_PP->SetDiag($ec);
385 35 100       88 $attr{auto_diag} and error_diag();
386 35         250 return;
387             }
388 974 100 100     4009 if (defined $self->{callbacks} && ref $self->{callbacks} ne "HASH") {
389 6         826 carp("The 'callbacks' attribute is set but is not a hash: ignored\n");
390 6         34 $self->{callbacks} = undef;
391             }
392              
393 974         2972 $last_err = Text::CSV_PP->SetDiag(0);
394 974 100 100     4069 defined $\ && !exists $attr{eol} and $self->{eol} = $\;
395 974         1998 bless $self, $class;
396 974 100       3081 defined $self->{'types'} and $self->types($self->{'types'});
397 974 50       4334 defined $self->{'skip_empty_rows'} and $self->{'skip_empty_rows'} = _supported_skip_empty_rows($self, $self->{'skip_empty_rows'});
398 974 100       2438 defined $attr_formula and $self->{'formula'} = _supported_formula($self, $attr_formula);
399 973         5161 $self;
400             }
401              
402             # Keep in sync with XS!
403             my %_cache_id = ( # Only expose what is accessed from within PM
404             quote_char => 0,
405             escape_char => 1,
406             sep_char => 2,
407             always_quote => 4,
408             quote_empty => 5,
409             quote_space => 6,
410             quote_binary => 7,
411             allow_loose_quotes => 8,
412             allow_loose_escapes => 9,
413             allow_unquoted_escape => 10,
414             allow_whitespace => 11,
415             blank_is_undef => 12,
416             empty_is_undef => 13,
417             auto_diag => 14,
418             diag_verbose => 15,
419             escape_null => 16,
420             formula => 18,
421             decode_utf8 => 21,
422             verbatim => 23,
423             strict_eol => 24,
424             eol_type => 27,
425             strict => 28,
426             skip_empty_rows => 29,
427             binary => 30,
428             keep_meta_info => 31,
429             _has_hooks => 32,
430             _has_ahead => 33,
431             _is_bound => 44,
432             eol => 100,
433             sep => 116,
434             quote => 132,
435             undef_str => 148,
436             comment_str => 156,
437             types => 92,
438             );
439              
440             my %_hidden_cache_id = (
441             has_error_input => 20,
442             eol_is_cr => 26,
443             eol_len => 36,
444             sep_len => 37,
445             quo_len => 38,
446             );
447              
448             my %_reverse_cache_id = (
449             map({ $_cache_id{$_} => $_ } keys %_cache_id),
450             map({ $_hidden_cache_id{$_} => $_ } keys %_hidden_cache_id),
451             );
452              
453             # A `character'
454             sub _set_attr_C {
455 11109     11109   25986 my ($self, $name, $val, $ec) = @_;
456 11109 100       40034 defined $val and utf8::decode($val);
457 11109         23783 $self->{$name} = $val;
458 11109 100       23109 $ec = _check_sanity($self) and croak($self->SetDiag($ec));
459 10199         32316 $self->_cache_set($_cache_id{$name}, $val);
460             }
461              
462             # A flag
463             sub _set_attr_X {
464 5646     5646   15380 my ($self, $name, $val) = @_;
465 5646 100       13923 defined $val or $val = 0;
466 5646         12396 $self->{$name} = $val;
467 5646         20669 $self->_cache_set($_cache_id{$name}, 0 + $val);
468             }
469              
470             # A number
471             sub _set_attr_N {
472 68     68   171 my ($self, $name, $val) = @_;
473 68         156 $self->{$name} = $val;
474 68         308 $self->_cache_set($_cache_id{$name}, 0 + $val);
475             }
476              
477             # Accessor methods.
478             # It is unwise to change them halfway through a single file!
479             sub quote_char {
480 4836     4836 1 1026355 my $self = shift;
481 4836 100       14776 if (@_) {
482 3601         10119 $self->_set_attr_C("quote_char", shift);
483 3374         7748 $self->_cache_set($_cache_id{quote}, "");
484             }
485 4609         16167 $self->{quote_char};
486             }
487              
488             sub quote {
489 20     20 1 47 my $self = shift;
490 20 100       71 if (@_) {
491 11         23 my $quote = shift;
492 11 100       30 defined $quote or $quote = "";
493 11         35 utf8::decode($quote);
494 11         46 my @b = unpack "U0C*", $quote;
495 11 100       33 if (@b > 1) {
496 5 100       22 @b > 16 and croak($self->SetDiag(1007));
497 4         17 $self->quote_char("\0");
498             }
499             else {
500 6         18 $self->quote_char($quote);
501 6         9 $quote = "";
502             }
503 10         19 $self->{quote} = $quote;
504              
505 10         18 my $ec = _check_sanity($self);
506 10 100       27 $ec and croak($self->SetDiag($ec));
507              
508 9         51 $self->_cache_set($_cache_id{quote}, $quote);
509             }
510 18         36 my $quote = $self->{quote};
511 18 100 100     123 defined $quote && length($quote) ? $quote : $self->{quote_char};
512             }
513              
514             sub escape_char {
515 4827     4827 1 1004038 my $self = shift;
516 4827 100       14057 if (@_) {
517 3595         6276 my $ec = shift;
518 3595         10758 $self->_set_attr_C("escape_char", $ec);
519 3480 100       8641 $ec or $self->_set_attr_X("escape_null", 0);
520             }
521 4712         16823 $self->{escape_char};
522             }
523              
524             sub sep_char {
525 5156     5156 1 988618 my $self = shift;
526 5156 100       15129 if (@_) {
527 3913         12641 $self->_set_attr_C("sep_char", shift);
528 3345         7931 $self->_cache_set($_cache_id{sep}, "");
529             }
530 4588         16579 $self->{sep_char};
531             }
532              
533             sub sep {
534 360     360 1 4851 my $self = shift;
535 360 100       923 if (@_) {
536 327         606 my $sep = shift;
537 327 100       750 defined $sep or $sep = "";
538 327         1173 utf8::decode($sep);
539 327         1641 my @b = unpack "U0C*", $sep;
540 327 100       897 if (@b > 1) {
541 13 100       37 @b > 16 and croak($self->SetDiag(1006));
542 12         52 $self->sep_char("\0");
543             }
544             else {
545 314         934 $self->sep_char($sep);
546 311         484 $sep = "";
547             }
548 323         793 $self->{sep} = $sep;
549              
550 323         1021 my $ec = _check_sanity($self);
551 323 100       919 $ec and croak($self->SetDiag($ec));
552              
553 322         784 $self->_cache_set($_cache_id{sep}, $sep);
554             }
555 355         660 my $sep = $self->{sep};
556 355 100 100     1461 defined $sep && length($sep) ? $sep : $self->{sep_char};
557             }
558              
559             sub eol {
560 280     280 1 4556 my $self = shift;
561 280 100       718 if (@_) {
562 227         422 my $eol = shift;
563 227 100       604 defined $eol or $eol = ""; # Also reset strict_eol?
564 227 100       599 length($eol) > 16 and croak($self->SetDiag(1005));
565 226         459 $self->{eol} = $eol;
566 226         585 $self->_cache_set($_cache_id{eol}, $eol);
567             }
568 279         861 $self->{eol};
569             }
570              
571             sub eol_type {
572 32     32 1 45 my $self = shift;
573 32         175 $self->_cache_get_eolt;
574             }
575              
576             sub always_quote {
577 3033     3033 1 984392 my $self = shift;
578 3033 100       11999 @_ and $self->_set_attr_X("always_quote", shift);
579 3033         11557 $self->{always_quote};
580             }
581              
582             sub quote_space {
583 10     10 1 26 my $self = shift;
584 10 100       79 @_ and $self->_set_attr_X("quote_space", shift);
585 10         43 $self->{quote_space};
586             }
587              
588             sub quote_empty {
589 5     5 1 14 my $self = shift;
590 5 100       25 @_ and $self->_set_attr_X("quote_empty", shift);
591 5         26 $self->{quote_empty};
592             }
593              
594             sub escape_null {
595 6     6 1 11 my $self = shift;
596 6 100       29 @_ and $self->_set_attr_X("escape_null", shift);
597 6         24 $self->{escape_null};
598             }
599              
600 3     3 0 14 sub quote_null { goto &escape_null; }
601              
602             sub quote_binary {
603 7     7 1 16 my $self = shift;
604 7 100       30 @_ and $self->_set_attr_X("quote_binary", shift);
605 7         18 $self->{quote_binary};
606             }
607              
608             sub binary {
609 21     21 1 3791 my $self = shift;
610 21 100       118 @_ and $self->_set_attr_X("binary", shift);
611 21         81 $self->{binary};
612             }
613              
614             sub strict {
615 2     2 1 5 my $self = shift;
616 2 100       8 @_ and $self->_set_attr_X("strict", shift);
617 2         7 $self->{strict};
618             }
619              
620             sub strict_eol {
621 2     2 1 7 my $self = shift;
622 2 100       10 @_ and $self->_set_attr_X("strict_eol", shift);
623 2         31 $self->{'strict_eol'};
624             }
625              
626             sub _supported_skip_empty_rows {
627 995     995   2300 my ($self, $f) = @_;
628 995 100       2339 defined $f or return 0;
629 994 100 66     4975 if ($self && $f && ref $f && ref $f eq "CODE") {
      100        
      66        
630 5         16 $self->{'_EMPTROW_CB'} = $f;
631 5         16 return 6;
632             }
633             $f =~ m/^(?: 0 | undef )$/xi ? 0 :
634             $f =~ m/^(?: 1 | skip )$/xi ? 1 :
635             $f =~ m/^(?: 2 | eof | stop )$/xi ? 2 :
636             $f =~ m/^(?: 3 | die )$/xi ? 3 :
637             $f =~ m/^(?: 4 | croak )$/xi ? 4 :
638             $f =~ m/^(?: 5 | error )$/xi ? 5 :
639 989 0       5609 $f =~ m/^(?: 6 | cb )$/xi ? 6 : do {
    50          
    100          
    100          
    100          
    100          
    100          
640 0   0     0 $self ||= "Text::CSV_PP";
641 0         0 croak($self->_SetDiagInfo(1500, "skip_empty_rows '$f' is not supported"));
642             };
643             }
644              
645             sub skip_empty_rows {
646 23     23 1 39 my $self = shift;
647 23 100       72 @_ and $self->_set_attr_N("skip_empty_rows", _supported_skip_empty_rows($self, shift));
648 23         38 my $ser = $self->{'skip_empty_rows'};
649 23 100       48 $ser == 6 or $self->{'_EMPTROW_CB'} = undef;
650             $ser <= 1 ? $ser : $ser == 2 ? "eof" : $ser == 3 ? "die" :
651             $ser == 4 ? "croak" : $ser == 5 ? "error" :
652 23 100       141 $self->{'_EMPTROW_CB'};
    100          
    100          
    100          
    100          
653             }
654              
655             sub _SetDiagInfo {
656 17     17   42 my ($self, $err, $msg) = @_;
657 17         61 $self->SetDiag($err);
658 17         72 my $em = $self->error_diag();
659 17 50       77 $em =~ s/^\d+$// and $msg =~ s/^/# /;
660 17 50       35 my $sep = $em =~ m/[;\n]$/ ? "\n\t" : ": ";
661 17         68 join $sep => grep m/\S\S\S/ => $em, $msg;
662             }
663              
664             sub _supported_formula {
665 103     103   241 my ($self, $f) = @_;
666 103 100       228 defined $f or return 5;
667 102 100 66     579 if ($self && $f && ref $f && ref $f eq "CODE") {
      100        
      100        
668 6         18 $self->{_FORMULA_CB} = $f;
669 6         18 return 6;
670             }
671             $f =~ m/^(?: 0 | none )$/xi ? 0 :
672             $f =~ m/^(?: 1 | die )$/xi ? 1 :
673             $f =~ m/^(?: 2 | croak )$/xi ? 2 :
674             $f =~ m/^(?: 3 | diag )$/xi ? 3 :
675             $f =~ m/^(?: 4 | empty | )$/xi ? 4 :
676             $f =~ m/^(?: 5 | undef )$/xi ? 5 :
677 96 100       1079 $f =~ m/^(?: 6 | cb )$/xi ? 6 : do {
    100          
    100          
    100          
    100          
    100          
    100          
678 7   50     22 $self ||= "Text::CSV_PP";
679 7         38 croak($self->_SetDiagInfo(1500, "formula-handling '$f' is not supported"));
680             };
681             }
682              
683             sub formula {
684 44     44 1 2997 my $self = shift;
685 44 100       167 @_ and $self->_set_attr_N("formula", _supported_formula($self, shift));
686 38 100       120 $self->{formula} == 6 or $self->{_FORMULA_CB} = undef;
687 38         159 [qw( none die croak diag empty undef cb )]->[_supported_formula($self, $self->{formula})];
688             }
689             sub formula_handling {
690 7     7 1 16 my $self = shift;
691 7         22 $self->formula(@_);
692             }
693              
694             sub decode_utf8 {
695 2     2 1 4 my $self = shift;
696 2 100       8 @_ and $self->_set_attr_X("decode_utf8", shift);
697 2         8 $self->{decode_utf8};
698             }
699              
700             sub keep_meta_info {
701 12     12 1 232 my $self = shift;
702 12 100       42 if (@_) {
703 11         18 my $v = shift;
704 11 100 100     79 !defined $v || $v eq "" and $v = 0;
705 11 100       65 $v =~ m/^[0-9]/ or $v = lc $v eq "false" ? 0 : 1; # true/truth = 1
    100          
706 11         42 $self->_set_attr_X("keep_meta_info", $v);
707             }
708 12         71 $self->{keep_meta_info};
709             }
710              
711             sub allow_loose_quotes {
712 12     12 1 30 my $self = shift;
713 12 100       72 @_ and $self->_set_attr_X("allow_loose_quotes", shift);
714 12         42 $self->{allow_loose_quotes};
715             }
716              
717             sub allow_loose_escapes {
718 12     12 1 1942 my $self = shift;
719 12 100       69 @_ and $self->_set_attr_X("allow_loose_escapes", shift);
720 12         111 $self->{allow_loose_escapes};
721             }
722              
723             sub allow_whitespace {
724 4954     4954 1 2384595 my $self = shift;
725 4954 100       17944 if (@_) {
726 3725         6851 my $aw = shift;
727 3725 100       10572 _unhealthy_whitespace($self, $aw) and
728             croak($self->SetDiag(1002));
729 3721         12520 $self->_set_attr_X("allow_whitespace", $aw);
730             }
731 4950         18418 $self->{allow_whitespace};
732             }
733              
734             sub allow_unquoted_escape {
735 4     4 1 11 my $self = shift;
736 4 100       25 @_ and $self->_set_attr_X("allow_unquoted_escape", shift);
737 4         12 $self->{allow_unquoted_escape};
738             }
739              
740             sub blank_is_undef {
741 3     3 1 6 my $self = shift;
742 3 100       18 @_ and $self->_set_attr_X("blank_is_undef", shift);
743 3         10 $self->{blank_is_undef};
744             }
745              
746             sub empty_is_undef {
747 2     2 1 4 my $self = shift;
748 2 100       9 @_ and $self->_set_attr_X("empty_is_undef", shift);
749 2         7 $self->{empty_is_undef};
750             }
751              
752             sub verbatim {
753 9     9 1 7646 my $self = shift;
754 9 100       49 @_ and $self->_set_attr_X("verbatim", shift);
755 9         25 $self->{verbatim};
756             }
757              
758             sub undef_str {
759 12     12 1 5849 my $self = shift;
760 12 100       43 if (@_) {
761 11         28 my $v = shift;
762 11 100       58 $self->{undef_str} = defined $v ? "$v" : undef;
763 11         43 $self->_cache_set($_cache_id{undef_str}, $self->{undef_str});
764             }
765 12         60 $self->{undef_str};
766             }
767              
768             sub comment_str {
769 15     15 1 81 my $self = shift;
770 15 100       38 if (@_) {
771 14         58 my $v = shift;
772 14 100       53 $self->{comment_str} = defined $v ? "$v" : undef;
773 14         64 $self->_cache_set($_cache_id{comment_str}, $self->{comment_str});
774             }
775 15         37 $self->{comment_str};
776             }
777              
778             sub auto_diag {
779 12     12 1 361 my $self = shift;
780 12 100       35 if (@_) {
781 9         13 my $v = shift;
782 9 100 100     44 !defined $v || $v eq "" and $v = 0;
783 9 100       43 $v =~ m/^[0-9]/ or $v = lc $v eq "false" ? 0 : 1; # true/truth = 1
    100          
784 9         22 $self->_set_attr_X("auto_diag", $v);
785             }
786 12         57 $self->{auto_diag};
787             }
788              
789             sub diag_verbose {
790 10     10 1 984 my $self = shift;
791 10 100       35 if (@_) {
792 8         13 my $v = shift;
793 8 100 100     33 !defined $v || $v eq "" and $v = 0;
794 8 100       36 $v =~ m/^[0-9]/ or $v = lc $v eq "false" ? 0 : 1; # true/truth = 1
    100          
795 8         23 $self->_set_attr_X("diag_verbose", $v);
796             }
797 10         39 $self->{diag_verbose};
798             }
799              
800             ################################################################################
801             # status
802             ################################################################################
803              
804             sub status {
805 5     5 1 14 my $self = shift;
806 5         59 return $self->{_STATUS};
807             }
808              
809             sub eof {
810 33     33 1 595 my $self = shift;
811 33         190 return $self->{_EOF};
812             }
813              
814             sub types {
815 7     7 1 1513 my $self = shift;
816              
817 7 100       14 if (@_) {
818 2 100       5 if (my $types = shift) {
819 1         11 $self->{'_types'} = join "", map { chr } @{$types};
  3         10  
  1         2  
820 1         2 $self->{'types'} = $types;
821 1         10 $self->_cache_set($_cache_id{'types'}, $self->{'_types'});
822             }
823             else {
824 1         2 delete $self->{'types'};
825 1         2 delete $self->{'_types'};
826 1         4 $self->_cache_set($_cache_id{'types'}, undef);
827 1         3 undef;
828             }
829             }
830             else {
831 5         15 $self->{'types'};
832             }
833             }
834              
835             sub callbacks {
836 74     74 1 20919 my $self = shift;
837 74 100       199 if (@_) {
838 44         48 my $cb;
839 44         57 my $hf = 0x00;
840 44 100       92 if (defined $_[0]) {
    100          
841 42 100       65 grep { !defined } @_ and croak($self->SetDiag(1004));
  75         155  
842 40 100 100     189 $cb = @_ == 1 && ref $_[0] eq "HASH" ? shift
    100          
843             : @_ % 2 == 0 ? {@_}
844             : croak($self->SetDiag(1004));
845 35         61 foreach my $cbk (keys %{$cb}) {
  35         96  
846             # A key cannot be a ref. That would be stored as the *string
847             # 'SCALAR(0x1f3e710)' or 'ARRAY(0x1a5ae18)'
848 37 100 100     266 $cbk =~ m/^[\w.]+$/ && ref $cb->{$cbk} eq "CODE" or
849             croak($self->SetDiag(1004));
850             }
851 21 100       44 exists $cb->{error} and $hf |= 0x01;
852 21 100       46 exists $cb->{after_parse} and $hf |= 0x02;
853 21 100       55 exists $cb->{before_print} and $hf |= 0x04;
854             }
855             elsif (@_ > 1) {
856             # (undef, whatever)
857 1         4 croak($self->SetDiag(1004));
858             }
859 22         70 $self->_set_attr_X("_has_hooks", $hf);
860 22         42 $self->{callbacks} = $cb;
861             }
862 52         130 $self->{callbacks};
863             }
864              
865             ################################################################################
866             # error_diag
867             ################################################################################
868              
869             sub error_diag {
870 1864     1864 1 51350 my $self = shift;
871 1864         6768 my @diag = (0 + $last_err, $last_err, 0, 0, 0, 0);
872              
873             # Docs state to NEVER use UNIVERSAL::isa, because it will *never* call an
874             # overridden isa method in any class. Well, that is exacly what I want here
875 1864 100 100     17601 if ($self && ref $self and # Not a class method or direct call
      100        
      100        
876             UNIVERSAL::isa($self, __PACKAGE__) && exists $self->{_ERROR_DIAG}) {
877 1685         3685 $diag[0] = 0 + $self->{_ERROR_DIAG};
878 1685         2909 $diag[1] = $self->{_ERROR_DIAG};
879 1685 100       4451 $diag[2] = 1 + $self->{_ERROR_POS} if exists $self->{_ERROR_POS};
880 1685         3021 $diag[3] = $self->{_RECNO};
881 1685 100       3806 $diag[4] = $self->{_ERROR_FLD} if exists $self->{_ERROR_FLD};
882 1685 100 100     4690 $diag[5] = $self->{_ERROR_SRC} if exists $self->{_ERROR_SRC} && $self->{diag_verbose};
883              
884             $diag[0] && $self->{callbacks} && $self->{callbacks}{error} and
885 1685 100 100     7357 return $self->{callbacks}{error}->(@diag);
      100        
886             }
887              
888 1854         3522 my $context = wantarray;
889              
890 1854 100       4300 unless (defined $context) { # Void context, auto-diag
891 387 100 100     1459 if ($diag[0] && $diag[0] != 2012) {
892 80         434 my $msg = "# CSV_PP ERROR: $diag[0] - $diag[1] \@ rec $diag[3] pos $diag[2]\n";
893 80 100       792 $diag[4] and $msg =~ s/$/ field $diag[4]/;
894 80 100       288 $diag[5] and $msg =~ s/$/ (PP#$diag[5])/;
895              
896 80 100 100     378 unless ($self && ref $self) { # auto_diag
897             # called without args in void context
898 4         42 warn $msg;
899 4         30 return;
900             }
901              
902             $self->{diag_verbose} && $self->{_ERROR_INPUT} and
903 76 50 66     322 $msg .= $self->{_ERROR_INPUT} . "\n" .
904             (" " x ($diag[2] - 1)) . "^\n";
905              
906 76         168 my $lvl = $self->{auto_diag};
907 76 100       224 if ($lvl < 2) {
908 73         417 my @c = caller(2);
909 73 50 66     479 if (@c >= 11 && $c[10] && ref $c[10] eq "HASH") {
      33        
910 0         0 my $hints = $c[10];
911             (exists $hints->{autodie} && $hints->{autodie} or
912             exists $hints->{'guard Fatal'} &&
913 0 0 0     0 !exists $hints->{'no Fatal'}) and
      0        
      0        
914             $lvl++;
915             # Future releases of autodie will probably set $^H{autodie}
916             # to "autodie @args", like "autodie :all" or "autodie open"
917             # so we can/should check for "open" or "new"
918             }
919             }
920 76 100       1574 $lvl > 1 ? die $msg : warn $msg;
921             }
922 380         1283 return;
923             }
924              
925 1467 100       5524 return $context ? @diag : $diag[1];
926             }
927              
928             sub record_number {
929 14     14 1 3209 my $self = shift;
930 14         91 return $self->{_RECNO};
931             }
932              
933             ################################################################################
934             # string
935             ################################################################################
936              
937             *string = \&_string;
938             sub _string {
939 1401     1401   453696 my $self = shift;
940 1401 100       5406 return ref $self->{_STRING} ? ${$self->{_STRING}} : undef;
  1400         7658  
941             }
942              
943             ################################################################################
944             # fields
945             ################################################################################
946              
947             *fields = \&_fields;
948             sub _fields {
949 1617     1617   23712 my $self = shift;
950 1617 100       6038 return ref $self->{_FIELDS} ? @{$self->{_FIELDS}} : undef;
  1616         12395  
951             }
952              
953             ################################################################################
954             # meta_info
955             ################################################################################
956              
957             sub meta_info {
958 21     21 1 824 my $self = shift;
959 21 100       85 return ref $self->{_FFLAGS} ? @{$self->{_FFLAGS}} : undef;
  16         94  
960             }
961              
962             sub is_quoted {
963 29     29 1 84 my ($self, $idx) = @_;
964             ref $self->{_FFLAGS} &&
965 29 100 100     145 $idx >= 0 && $idx < @{$self->{_FFLAGS}} or return;
  25   100     86  
966 24 100       57 $self->{_FFLAGS}[$idx] & CSV_FLAGS_IS_QUOTED() ? 1 : 0;
967             }
968              
969             sub is_binary {
970 11     11 1 31 my ($self, $idx) = @_;
971             ref $self->{_FFLAGS} &&
972 11 100 100     71 $idx >= 0 && $idx < @{$self->{_FFLAGS}} or return;
  9   100     36  
973 8 100       23 $self->{_FFLAGS}[$idx] & CSV_FLAGS_IS_BINARY() ? 1 : 0;
974             }
975              
976             sub is_missing {
977 19     19 1 79 my ($self, $idx) = @_;
978 19 100 100     163 $idx < 0 || !ref $self->{_FFLAGS} and return;
979 11 100       21 $idx >= @{$self->{_FFLAGS}} and return 1;
  11         39  
980 10 100       36 $self->{_FFLAGS}[$idx] & CSV_FLAGS_IS_MISSING() ? 1 : 0;
981             }
982              
983             ################################################################################
984             # combine
985             ################################################################################
986             *combine = \&_combine;
987             sub _combine {
988 1399     1399   1016325 my $self = shift;
989 1399         4434 my $str = "";
990 1399         11577 $self->{_FIELDS} = \@_;
991 1399   100     13369 $self->{_STATUS} = (@_ > 0) && $self->__combine(\$str, \@_, 0);
992 1395         5060 $self->{_STRING} = \$str;
993 1395         6101 $self->{_STATUS};
994             }
995              
996             ################################################################################
997             # parse
998             ################################################################################
999             *parse = \&_parse;
1000             sub _parse {
1001 1962     1962   138293 my ($self, $str) = @_;
1002              
1003 1962 100       7008 ref $str and croak($self->SetDiag(1500));
1004              
1005 1958         4097 my $fields = [];
1006 1958         3118 my $fflags = [];
1007 1958         5345 $self->{_STRING} = \$str;
1008 1958 100 100     10433 if (defined $str && $self->__parse($fields, $fflags, $str, 0)) {
1009 1744         6292 $self->{_FIELDS} = $fields;
1010 1744         4182 $self->{_FFLAGS} = $fflags;
1011 1744         3710 $self->{_STATUS} = 1;
1012             }
1013             else {
1014 211         545 $self->{_FIELDS} = undef;
1015 211         396 $self->{_FFLAGS} = undef;
1016 211         366 $self->{_STATUS} = 0;
1017             }
1018 1955         13206 $self->{_STATUS};
1019             }
1020              
1021             sub column_names {
1022 1028     1028 1 55568 my ($self, @keys) = @_;
1023              
1024             @keys or
1025 1028 100       2666 return defined $self->{_COLUMN_NAMES} ? @{$self->{_COLUMN_NAMES}} : ();
  294 100       1327  
1026             @keys == 1 && !defined $keys[0] and
1027 691 100 100     2649 return $self->{_COLUMN_NAMES} = undef;
1028              
1029 553 100 100     1995 if (@keys == 1 && ref $keys[0] eq "ARRAY") {
    100          
1030 228         331 @keys = @{$keys[0]};
  228         715  
1031             }
1032 715 100       2329 elsif (join "", map { defined $_ ? ref $_ : "" } @keys) {
1033 5         20 croak($self->SetDiag(3001));
1034             }
1035              
1036 548 100 100     1572 $self->{_BOUND_COLUMNS} && @keys != @{$self->{_BOUND_COLUMNS}} and
  2         12  
1037             croak($self->SetDiag(3003));
1038              
1039 547 100       899 $self->{_COLUMN_NAMES} = [map { defined $_ ? $_ : "\cAUNDEF\cA" } @keys];
  1281         3340  
1040 547         922 @{$self->{_COLUMN_NAMES}};
  547         1406  
1041             }
1042              
1043             sub header {
1044 334     334 1 44416 my ($self, $fh, @args) = @_;
1045              
1046 334 100       1058 $fh or croak($self->SetDiag(1014));
1047              
1048 333         612 my (@seps, %args);
1049 333         760 for (@args) {
1050 226 100       665 if (ref $_ eq "ARRAY") {
1051 18         26 push @seps, @{$_};
  18         51  
1052 18         44 next;
1053             }
1054 208 100       527 if (ref $_ eq "HASH") {
1055 207         273 %args = %{$_};
  207         598  
1056 207         473 next;
1057             }
1058 1         256 croak('usage: $csv->header ($fh, [ seps ], { options })');
1059             }
1060              
1061             defined $args{munge} && !defined $args{munge_column_names} and
1062 332 100 66     1114 $args{munge_column_names} = $args{munge}; # munge as alias
1063 332 100       1426 defined $args{detect_bom} or $args{detect_bom} = 1;
1064 332 100       1133 defined $args{set_column_names} or $args{set_column_names} = 1;
1065 332 100       895 defined $args{munge_column_names} or $args{munge_column_names} = "lc";
1066              
1067             # Reset any previous leftovers
1068 332         598 $self->{_RECNO} = 0;
1069 332         558 $self->{_AHEAD} = undef;
1070 332 100       842 $self->{_COLUMN_NAMES} = undef if $args{set_column_names};
1071 332 100       843 $self->{_BOUND_COLUMNS} = undef if $args{set_column_names};
1072 332         1346 $self->_cache_set($_cache_id{'_has_ahead'}, 0);
1073              
1074 332 100       688 if (defined $args{sep_set}) {
1075 27 100       78 ref $args{sep_set} eq "ARRAY" or
1076             croak($self->_SetDiagInfo(1500, "sep_set should be an array ref"));
1077 22         30 @seps = @{$args{sep_set}};
  22         67  
1078             }
1079              
1080 327 50       1217 $^O eq "MSWin32" and binmode $fh;
1081 327         6763 my $hdr = <$fh>;
1082             # check if $hdr can be empty here, I don't think so
1083 327 100 66     1685 defined $hdr && $hdr ne "" or croak($self->SetDiag(1010));
1084              
1085 325         478 my %sep;
1086 325 100       1045 @seps or @seps = (",", ";");
1087 325         681 foreach my $sep (@seps) {
1088 734 100       2056 index($hdr, $sep) >= 0 and $sep{$sep}++;
1089             }
1090              
1091 325 100       751 keys %sep >= 2 and croak($self->SetDiag(1011));
1092              
1093 321         1346 $self->sep(keys %sep);
1094 321         585 my $enc = "";
1095 321 100       732 if ($args{detect_bom}) { # UTF-7 is not supported
1096 320 100       3413 if ($hdr =~ s/^\x00\x00\xfe\xff//) { $enc = "utf-32be" }
  24 100       57  
    100          
    100          
    100          
    100          
    100          
    100          
    100          
    100          
    100          
1097 24         59 elsif ($hdr =~ s/^\xff\xfe\x00\x00//) { $enc = "utf-32le" }
1098 25         57 elsif ($hdr =~ s/^\xfe\xff//) { $enc = "utf-16be" }
1099 24         58 elsif ($hdr =~ s/^\xff\xfe//) { $enc = "utf-16le" }
1100 48         90 elsif ($hdr =~ s/^\xef\xbb\xbf//) { $enc = "utf-8" }
1101 1         2 elsif ($hdr =~ s/^\xf7\x64\x4c//) { $enc = "utf-1" }
1102 1         5 elsif ($hdr =~ s/^\xdd\x73\x66\x73//) { $enc = "utf-ebcdic" }
1103 1         3 elsif ($hdr =~ s/^\x0e\xfe\xff//) { $enc = "scsu" }
1104 1         3 elsif ($hdr =~ s/^\xfb\xee\x28//) { $enc = "bocu-1" }
1105 1         2 elsif ($hdr =~ s/^\x84\x31\x95\x33//) { $enc = "gb-18030" }
1106 36         78 elsif ($hdr =~ s/^\x{feff}//) { $enc = "" }
1107              
1108 320 100       1023 $self->{ENCODING} = $enc ? uc $enc : undef;
1109              
1110 320 100       828 $hdr eq "" and croak($self->SetDiag(1010));
1111              
1112 314 100       755 if ($enc) {
1113 144 50 33     566 $ebcdic && $enc eq "utf-ebcdic" and $enc = "";
1114 144 100       723 if ($enc =~ m/([13]).le$/) {
1115 48         169 my $l = 0 + $1;
1116 48         99 my $x;
1117 48         167 $hdr .= "\0" x $l;
1118 48         228 read $fh, $x, $l;
1119             }
1120 144 50       356 if ($enc) {
1121 144 100       399 if ($enc ne "utf-8") {
1122 96         759 require Encode;
1123 96         917 $hdr = Encode::decode($enc, $hdr);
1124             }
1125 144     2   6595 binmode $fh, ":encoding($enc)";
  2         1627  
  2         32  
  2         14  
1126             }
1127             }
1128             }
1129              
1130 315         9211 my ($ahead, $eol);
1131 315 100 66     1438 if ($hdr and $hdr =~ s/\Asep=(\S)([\r\n]+)//i) { # Also look in xs:Parse
1132 1         5 $self->sep($1);
1133 1 50       9 length $hdr or $hdr = <$fh>;
1134             }
1135              
1136 315 100       2348 if ($hdr =~ s/^([^\r\n]+)([\r\n]+)([^\r\n].+)\z/$1/s) {
1137 142         358 $eol = $2;
1138 142         431 $ahead = $3;
1139             }
1140              
1141 315         594 my $hr = \$hdr; # Will cause croak on perl-5.6.x
1142 315 50       3615 open my $h, "<", $hr or croak($self->SetDiag(1010));
1143              
1144 315 100       1179 my $row = $self->getline($h) or croak();
1145 313         1146 close $h;
1146              
1147 313 100       880 if ($args{'munge_column_names'} eq "lc") {
    100          
    100          
1148 294         505 $_ = lc for @{$row};
  294         1387  
1149             }
1150             elsif ($args{'munge_column_names'} eq "uc") {
1151 7         12 $_ = uc for @{$row};
  7         30  
1152             }
1153             elsif ($args{'munge_column_names'} eq "db") {
1154 3         6 for (@{$row}) {
  3         7  
1155 7         17 s/\W+/_/g;
1156 7         16 s/^_+//;
1157 7         14 $_ = lc;
1158             }
1159             }
1160              
1161 313 100       820 if ($ahead) { # Must be after getline, which creates the cache
1162 142         506 $self->_cache_set($_cache_id{_has_ahead}, 1);
1163 142         291 $self->{_AHEAD} = $ahead;
1164 142 100       1034 $eol =~ m/^\r([^\n]|\z)/ and $self->eol($eol);
1165             }
1166              
1167 313         485 my @hdr = @{$row};
  313         971  
1168             ref $args{munge_column_names} eq "CODE" and
1169 313 100       842 @hdr = map { $args{munge_column_names}->($_) } @hdr;
  4         18  
1170             ref $args{munge_column_names} eq "HASH" and
1171 313 100       789 @hdr = map { $args{munge_column_names}->{$_} || $_ } @hdr;
  3 100       9  
1172 313         518 my %hdr; $hdr{$_}++ for @hdr;
  313         1402  
1173 313 100       774 exists $hdr{''} and croak($self->SetDiag(1012));
1174 311 100       742 unless (keys %hdr == @hdr) {
1175             croak($self->_SetDiagInfo(1013, join ", " =>
1176 1         3 map { "$_ ($hdr{$_})" } grep { $hdr{$_} > 1 } keys %hdr));
  1         13  
  2         4  
1177             }
1178 310 100       1347 $args{set_column_names} and $self->column_names(@hdr);
1179 310 100       3382 wantarray ? @hdr : $self;
1180             }
1181              
1182             sub bind_columns {
1183 36     36 1 10725 my ($self, @refs) = @_;
1184              
1185             @refs or
1186 36 100       158 return defined $self->{_BOUND_COLUMNS} ? @{$self->{_BOUND_COLUMNS}} : undef;
  2 100       15  
1187 32 100 100     171 if (@refs == 1 && !defined $refs[0]) {
1188 5         14 $self->{_COLUMN_NAMES} = undef;
1189 5         27 return $self->{_BOUND_COLUMNS} = undef;
1190             }
1191              
1192 27 100 100     132 $self->{_COLUMN_NAMES} && @refs != @{$self->{_COLUMN_NAMES}} and
  3         18  
1193             croak($self->SetDiag(3003));
1194 26 100       361 join "", map { ref $_ eq "SCALAR" ? "" : "*" } @refs and
  74632 100       144190  
1195             croak($self->SetDiag(3004));
1196              
1197 24         2594 $self->_set_attr_N("_is_bound", scalar @refs);
1198 24         4983 $self->{_BOUND_COLUMNS} = [@refs];
1199 24         1265 @refs;
1200             }
1201              
1202             sub getline_hr {
1203 132     132 1 23732 my ($self, @args, %hr) = @_;
1204 132 100       578 $self->{_COLUMN_NAMES} or croak($self->SetDiag(3002));
1205 131 100       442 my $fr = $self->getline(@args) or return;
1206 128 100       453 if (ref $self->{_FFLAGS}) { # missing
1207             $self->{_FFLAGS}[$_] = CSV_FLAGS_IS_MISSING()
1208 5 50       9 for (@{$fr} ? $#{$fr} + 1 : 0) .. $#{$self->{_COLUMN_NAMES}};
  5         14  
  5         14  
  5         26  
1209 5         35 @{$fr} == 1 && (!defined $fr->[0] || $fr->[0] eq "") and
1210 5 100 33     11 $self->{_FFLAGS}[0] ||= CSV_FLAGS_IS_MISSING();
      66        
      100        
1211             }
1212 128         202 @hr{@{$self->{_COLUMN_NAMES}}} = @{$fr};
  128         726  
  128         263  
1213 128         953 \%hr;
1214             }
1215              
1216             sub getline_hr_all {
1217 251     251 1 564 my ($self, @args) = @_;
1218              
1219 251 100       682 $self->{_COLUMN_NAMES} or croak($self->SetDiag(3002));
1220              
1221 249         408 my @cn = @{$self->{_COLUMN_NAMES}};
  249         663  
1222              
1223 249         403 [map { my %h; @h{@cn} = @{$_}; \%h } @{$self->getline_all(@args)}];
  376         586  
  376         508  
  376         1514  
  376         1926  
  249         766  
1224             }
1225              
1226             sub say {
1227 34     34 1 2500 my ($self, $io, @f) = @_;
1228 34         103 my $eol = $self->eol();
1229             # say ($fh, undef) does not propage actual undef to print ()
1230 34 100 66     231 my $state = $self->print($io, @f == 1 && !defined $f[0] ? undef : @f);
1231 34 100       642 unless (length $eol) {
1232 32   33     91 $eol = $self->eol_type() || $\ || $/;
1233 32         72 print $io $eol;
1234             }
1235 34         100 return $state;
1236             }
1237              
1238             sub print_hr {
1239 3     3 1 19 my ($self, $io, $hr) = @_;
1240 3 100       18 $self->{_COLUMN_NAMES} or croak($self->SetDiag(3009));
1241 2 100       14 ref $hr eq "HASH" or croak($self->SetDiag(3010));
1242 1         5 $self->print($io, [map { $hr->{$_} } $self->column_names()]);
  3         11  
1243             }
1244              
1245             sub fragment {
1246 58     58 1 28511 my ($self, $io, $spec) = @_;
1247              
1248 58         252 my $qd = qr{\s* [0-9]+ \s* }x; # digit
1249 58         151 my $qs = qr{\s* (?: [0-9]+ | \* ) \s*}x; # digit or star
1250 58         750 my $qr = qr{$qd (?: - $qs )?}x; # range
1251 58         670 my $qc = qr{$qr (?: ; $qr )*}x; # list
1252 58 100 100     2899 defined $spec && $spec =~ m{^ \s*
1253             \x23 ? \s* # optional leading #
1254             ( row | col | cell ) \s* =
1255             ( $qc # for row and col
1256             | $qd , $qd (?: - $qs , $qs)? # for cell (ranges)
1257             (?: ; $qd , $qd (?: - $qs , $qs)? )* # and cell (range) lists
1258             ) \s* $}xi or croak($self->SetDiag(2013));
1259 38         239 my ($type, $range) = (lc $1, $2);
1260              
1261 38         275 my @h = $self->column_names();
1262              
1263 38         66 my @c;
1264 38 100       108 if ($type eq "cell") {
1265 21         41 my @spec;
1266             my $min_row;
1267 21         39 my $max_row = 0;
1268 21         127 for (split m/\s*;\s*/ => $range) {
1269 37 100       258 my ($tlr, $tlc, $brr, $brc) = (m{
1270             ^ \s* ([0-9]+ ) \s* , \s* ([0-9]+ ) \s*
1271             (?: - \s* ([0-9]+ | \*) \s* , \s* ([0-9]+ | \*) \s* )?
1272             $}x) or croak($self->SetDiag(2013));
1273 36 100       94 defined $brr or ($brr, $brc) = ($tlr, $tlc);
1274 36 100 100     374 $tlr == 0 || $tlc == 0 ||
      66        
      100        
      100        
      66        
      100        
      100        
1275             ($brr ne "*" && ($brr == 0 || $brr < $tlr)) ||
1276             ($brc ne "*" && ($brc == 0 || $brc < $tlc))
1277             and croak($self->SetDiag(2013));
1278 28         40 $tlc--;
1279 28 100       51 $brc-- unless $brc eq "*";
1280 28 100       95 defined $min_row or $min_row = $tlr;
1281 28 100       50 $tlr < $min_row and $min_row = $tlr;
1282 28 100 100     108 $brr eq "*" || $brr > $max_row and
1283             $max_row = $brr;
1284 28         77 push @spec, [$tlr, $tlc, $brr, $brc];
1285             }
1286 12         14 my $r = 0;
1287 12         33 while (my $row = $self->getline($io)) {
1288 77 100       212 ++$r < $min_row and next;
1289 33         54 my %row;
1290             my $lc;
1291 33         61 foreach my $s (@spec) {
1292 77         92 my ($tlr, $tlc, $brr, $brc) = @{$s};
  77         139  
1293 77 100 100     235 $r < $tlr || ($brr ne "*" && $r > $brr) and next;
      100        
1294 45 100 100     91 !defined $lc || $tlc < $lc and $lc = $tlc;
1295 45 100       75 my $rr = $brc eq "*" ? $#{$row} : $brc;
  5         6  
1296 45         219 $row{$_} = $row->[$_] for $tlc .. $rr;
1297             }
1298 33         158 push @c, [@row{sort { $a <=> $b } keys %row}];
  63         155  
1299 33 100       75 if (@h) {
1300 2         3 my %h; @h{@h} = @{$c[-1]};
  2         2  
  2         7  
1301 2         5 $c[-1] = \%h;
1302             }
1303 33 100 100     173 $max_row ne "*" && $r == $max_row and last;
1304             }
1305 12         97 return \@c;
1306             }
1307              
1308             # row or col
1309 17         28 my @r;
1310 17         34 my $eod = 0;
1311 17         103 for (split m/\s*;\s*/ => $range) {
1312 25 50       149 my ($from, $to) = m/^\s* ([0-9]+) (?: \s* - \s* ([0-9]+ | \* ))? \s* $/x
1313             or croak($self->SetDiag(2013));
1314 25   100     88 $to ||= $from;
1315 25 100       60 $to eq "*" and ($to, $eod) = ($from, 1);
1316             # $to cannot be <= 0 due to regex and ||=
1317 25 100 100     103 $from <= 0 || $to < $from and croak($self->SetDiag(2013));
1318 22         82 $r[$_] = 1 for $from .. $to;
1319             }
1320              
1321 14         24 my $r = 0;
1322 14 100       60 $type eq "col" and shift @r;
1323 14   100     155 $_ ||= 0 for @r;
1324 14         50 while (my $row = $self->getline($io)) {
1325 109         165 $r++;
1326 109 100       197 if ($type eq "row") {
1327 64 100 100     301 if (($r > $#r && $eod) || $r[$r]) {
      100        
1328 20         36 push @c, $row;
1329 20 100       37 if (@h) {
1330 3         6 my %h; @h{@h} = @{$c[-1]};
  3         6  
  3         18  
1331 3         8 $c[-1] = \%h;
1332             }
1333             }
1334 64         202 next;
1335             }
1336 45 100 100     54 push @c, [map { ($_ > $#r && $eod) || $r[$_] ? $row->[$_] : () } 0 .. $#{$row}];
  405         1003  
  45         78  
1337 45 100       132 if (@h) {
1338 9         11 my %h; @h{@h} = @{$c[-1]};
  9         14  
  9         43  
1339 9         35 $c[-1] = \%h;
1340             }
1341             }
1342              
1343 14         118 return \@c;
1344             }
1345              
1346             my $csv_usage = q{usage: my $aoa = csv (in => $file);};
1347              
1348             sub _csv_attr {
1349 345 100 66 345   2617 my %attr = (@_ == 1 && ref $_[0] eq "HASH" ? %{$_[0]} : @_) or croak();
  4 50       24  
1350              
1351 345         1039 $attr{binary} = 1;
1352 345         767 $attr{strict_eol} = 1;
1353              
1354 345   100     2098 my $enc = delete $attr{enc} || delete $attr{encoding} || "";
1355 345 100       985 $enc eq "auto" and ($attr{detect_bom}, $enc) = (1, "");
1356 345 50       1172 my $stack = $enc =~ s/(:\w.*)// ? $1 : "";
1357 345 100       964 $enc =~ m/^[-\w.]+$/ and $enc = ":encoding($enc)";
1358 345         581 $enc .= $stack;
1359              
1360 345         707 my $hdrs = delete $attr{'headers'};
1361 345         659 my $frag = delete $attr{'fragment'};
1362 345         614 my $key = delete $attr{'key'};
1363 345         640 my $val = delete $attr{'value'};
1364             my $kh = delete $attr{'keep_headers'} ||
1365             delete $attr{'keep_column_names'} ||
1366 345   100     1738 delete $attr{'kh'};
1367              
1368             my $cbai = delete $attr{'callbacks'}{'after_in'} ||
1369             delete $attr{'after_in'} ||
1370             delete $attr{'callbacks'}{'after_parse'} ||
1371 345   100     2600 delete $attr{'after_parse'};
1372             my $cbbo = delete $attr{'callbacks'}{'before_out'} ||
1373 345   100     1113 delete $attr{'before_out'};
1374             my $cboi = delete $attr{'callbacks'}{'on_in'} ||
1375 345   100     1162 delete $attr{'on_in'};
1376             my $cboe = delete $attr{'callbacks'}{'on_error'} ||
1377 345   66     1233 delete $attr{'on_error'};
1378              
1379             my $hd_s = delete $attr{'sep_set'} ||
1380 345   100     1282 delete $attr{'seps'};
1381             my $hd_b = delete $attr{'detect_bom'} ||
1382 345   100     1131 delete $attr{'bom'};
1383             my $hd_m = delete $attr{'munge'} ||
1384 345   100     1133 delete $attr{'munge_column_names'};
1385 345         673 my $hd_c = delete $attr{'set_column_names'};
1386              
1387 345         473 my $fh;
1388 345         526 my $sink = 0;
1389 345         525 my $cls = 0; # If I open a file, I have to close it
1390 345 100 100     1902 my $in = delete $attr{in} || delete $attr{file} or croak($csv_usage);
1391             my $out = exists $attr{out} && !$attr{out} ? \"skip"
1392 342 100 100     2013 : delete $attr{out} || delete $attr{file};
      100        
1393              
1394 342 100 100     1463 ref $in eq "CODE" || ref $in eq "ARRAY" and $out ||= \*STDOUT;
      100        
1395              
1396 342         664 my ($fho, $fho_cls);
1397 342 100 66     1661 if ($in && $out and (!ref $in || ref $in eq "GLOB" || ref \$in eq "GLOB")
      66        
      100        
      66        
      66        
1398             and (!ref $out || ref $out eq "GLOB" || ref \$out eq "GLOB")) {
1399 7 100 66     38 if (ref $out or "GLOB" eq ref \$out) {
1400 2         6 $fho = $out;
1401             }
1402             else {
1403 5 50       815 open $fho, ">", $out or croak "$out: $!\n";
1404 5 50       33 if (my $e = $attr{'encoding'}) {
1405 0         0 binmode $fho, ":encoding($e)";
1406 0 0       0 $hd_b and print $fho "\x{feff}";
1407             }
1408 5         16 $fho_cls = 1;
1409             }
1410 7 100 66     33 if ($cboi && !$cbai) {
1411 1         2 $cbai = $cboi;
1412 1         3 $cboi = undef;
1413             }
1414 7 100       19 if ($cbai) {
1415 2         5 my $cb = $cbai;
1416 2     6   15 $cbai = sub { $cb->(@_); $_[0]->say($fho, $_[1]); 0 };
  6         25  
  6         41  
  6         17  
1417             }
1418             else {
1419 5     15   30 $cbai = sub { $_[0]->say($fho, $_[1]); 0 };
  15         62  
  15         37  
1420             }
1421              
1422             # Put all callbacks back in place for streaming behavior
1423 7         23 $attr{'callbacks'}{'after_parse'} = $cbai; $cbai = undef;
  7         16  
1424 7         16 $attr{'callbacks'}{'before_out'} = $cbbo; $cbbo = undef;
  7         14  
1425 7         16 $attr{'callbacks'}{'on_in'} = $cboi; $cboi = undef;
  7         13  
1426 7         17 $attr{'callbacks'}{'on_error'} = $cboe; $cboe = undef;
  7         11  
1427 7         13 $out = undef;
1428 7         16 $sink = 1;
1429             }
1430              
1431 342 100       993 if ($out) {
1432 33 100 100     416 if (ref $out and ("ARRAY" eq ref $out or "HASH" eq ref $out)) {
    100 100        
    100 100        
      100        
      66        
      66        
      66        
1433 5         11 delete $attr{out};
1434 5         10 $sink = 1;
1435             }
1436             elsif ((ref $out and "SCALAR" ne ref $out) or "GLOB" eq ref \$out) {
1437 14         36 $fh = $out;
1438             }
1439 7         31 elsif (ref $out and "SCALAR" eq ref $out and defined ${$out} and ${$out} eq "skip") {
  7         24  
1440 2         5 delete $attr{out};
1441 2         4 $sink = 1;
1442             }
1443             else {
1444 12 100       1148 open $fh, ">", $out or croak("$out: $!");
1445 11         45 $cls = 1;
1446             }
1447 32 100       117 if ($fh) {
1448 25 100       65 if ($enc) {
1449 1         18 binmode $fh, $enc;
1450 1         87 my $fn = fileno $fh; # This is a workaround for a bug in PerlIO::via::gzip
1451             }
1452 25 100 66     131 unless (defined $attr{eol} || defined $fho) {
1453 18         40 my @layers = eval { PerlIO::get_layers($fh) };
  18         140  
1454 18 100       147 $attr{eol} = (grep m/crlf/ => @layers) ? "\n" : "\r\n";
1455             }
1456             }
1457             }
1458              
1459 341 100 100     2751 if (ref $in eq "CODE" or ref $in eq "ARRAY") {
    100 100        
    100          
1460             # All done
1461             }
1462             elsif (ref $in eq "SCALAR") {
1463             # Strings with code points over 0xFF may not be mapped into in-memory file handles
1464             # "<$enc" does not change that :(
1465 30 50       463 open $fh, "<", $in or croak("Cannot open from SCALAR using PerlIO");
1466 30         89 $cls = 1;
1467             }
1468             elsif (ref $in or "GLOB" eq ref \$in) {
1469 18 50 66     62 if (!ref $in && $] < 5.008005) {
1470 0         0 $fh = \*{$in}; # uncoverable statement ancient perl version required
  0         0  
1471             }
1472             else {
1473 18         32 $fh = $in;
1474             }
1475             }
1476             else {
1477 269 100       14812 open $fh, "<$enc", $in or croak("$in: $!");
1478 267         2441 $cls = 1;
1479             }
1480 339 50 33     1082 $fh || $sink or croak(qq{No valid source passed. "in" is required});
1481              
1482 339         1585 for ([quo => "quote"],
1483             [esc => "escape"],
1484             [escape => "escape_char"],
1485             ) {
1486 1017         1242 my ($f, $t) = @{$_};
  1017         2207  
1487 1017 100 100     2761 exists $attr{$f} and !exists $attr{$t} and $attr{$t} = delete $attr{$f};
1488             }
1489              
1490 339         1090 my $fltr = delete $attr{filter};
1491             my %fltr = (
1492 10 100 33 10   18 not_blank => sub { @{$_[1]} > 1 or defined $_[1][0] && $_[1][0] ne "" },
  10         62  
1493 10 50   10   18 not_empty => sub { grep { defined && $_ ne "" } @{$_[1]} },
  26         123  
  10         26  
1494 10 50   10   16 filled => sub { grep { defined && m/\S/ } @{$_[1]} },
  26         115  
  10         22  
1495 339         3179 );
1496             defined $fltr && !ref $fltr && exists $fltr{$fltr} and
1497 339 50 100     1024 $fltr = {0 => $fltr{$fltr}};
      66        
1498 339 100       848 ref $fltr eq "CODE" and $fltr = {0 => $fltr};
1499 339 100       881 ref $fltr eq "HASH" or $fltr = undef;
1500              
1501 339         614 my $form = delete $attr{formula};
1502              
1503 339 100       1060 defined $attr{auto_diag} or $attr{auto_diag} = 1;
1504 339 100       945 defined $attr{escape_null} or $attr{escape_null} = 0;
1505 339 50 66     2412 my $csv = delete $attr{csv} || Text::CSV_PP->new(\%attr)
1506             or croak($last_err);
1507 339 100       788 defined $form and $csv->formula($form);
1508 339 100       762 defined $cboe and $csv->callbacks(error => $cboe);
1509              
1510 339 100 100     1085 $kh && !ref $kh && $kh =~ m/^(?:1|yes|true|internal|auto)$/i and
      100        
1511             $kh = \@internal_kh;
1512              
1513             return {
1514 339         9740 csv => $csv,
1515             attr => {%attr},
1516             fh => $fh,
1517             cls => $cls,
1518             in => $in,
1519             sink => $sink,
1520             out => $out,
1521             enc => $enc,
1522             fho => $fho,
1523             fhoc => $fho_cls,
1524             hdrs => $hdrs,
1525             key => $key,
1526             val => $val,
1527             kh => $kh,
1528             frag => $frag,
1529             fltr => $fltr,
1530             cbai => $cbai,
1531             cbbo => $cbbo,
1532             cboi => $cboi,
1533             hd_s => $hd_s,
1534             hd_b => $hd_b,
1535             hd_m => $hd_m,
1536             hd_c => $hd_c,
1537             };
1538             }
1539              
1540             sub csv {
1541 346 50 33 346 1 2199 @_ && (ref $_[0] eq __PACKAGE__ or ref $_[0] eq 'Text::CSV') and splice @_, 0, 0, "csv";
      66        
1542 346 100       976 @_ or croak($csv_usage);
1543              
1544 345         1287 my $c = _csv_attr(@_);
1545              
1546 339         840 my ($csv, $in, $fh, $hdrs) = @{$c}{qw( csv in fh hdrs )};
  339         1454  
1547 339         569 my %hdr;
1548 339 100       951 if (ref $hdrs eq "HASH") {
1549 2         4 %hdr = %{$hdrs};
  2         8  
1550 2         5 $hdrs = "auto";
1551             }
1552              
1553 339 100 100     1075 if ($c->{out} && !$c->{sink}) {
1554             !$hdrs && ref $c->{'kh'} && $c->{'kh'} == \@internal_kh and
1555 24 100 100     146 $hdrs = $c->{'kh'};
      66        
1556              
1557 24 100 100     75 if (ref $in eq "CODE") {
    100          
1558 3         7 my $hdr = 1;
1559 3         14 while (my $row = $in->($csv)) {
1560 7 100       76 if (ref $row eq "ARRAY") {
1561 3         11 $csv->print($fh, $row);
1562 3         65 next;
1563             }
1564 4 50       14 if (ref $row eq "HASH") {
1565 4 100       10 if ($hdr) {
1566 2 50 100     9 $hdrs ||= [map { $hdr{$_} || $_ } keys %{$row}];
  3         17  
  1         4  
1567 2         9 $csv->print($fh, $hdrs);
1568 2         46 $hdr = 0;
1569             }
1570 4         8 $csv->print($fh, [@{$row}{@{$hdrs}}]);
  4         20  
  4         10  
1571             }
1572             }
1573             }
1574 21         112 elsif (@{$in} == 0 or ref $in->[0] eq "ARRAY") { # aoa
1575 10 50       40 ref $hdrs and $csv->print($fh, $hdrs);
1576 10         17 for (@{$in}) {
  10         30  
1577 12 100       132 $c->{cboi} and $c->{cboi}->($csv, $_);
1578 12 50       1848 $c->{cbbo} and $c->{cbbo}->($csv, $_);
1579 12         46 $csv->print($fh, $_);
1580             }
1581             }
1582             else { # aoh
1583 11 100       28 my @hdrs = ref $hdrs ? @{$hdrs} : keys %{$in->[0]};
  5         21  
  6         43  
1584 11 100       34 defined $hdrs or $hdrs = "auto";
1585             ref $hdrs || $hdrs eq "auto" and @hdrs and
1586 11 100 100     74 $csv->print($fh, [map { $hdr{$_} || $_ } @hdrs]);
  20 100 66     122  
1587 11         172 for (@{$in}) {
  11         37  
1588 17         121 local %_;
1589 17         55 *_ = $_;
1590 17 50       82 $c->{cboi} and $c->{cboi}->($csv, $_);
1591 17 50       41 $c->{cbbo} and $c->{cbbo}->($csv, $_);
1592 17         35 $csv->print($fh, [@{$_}{@hdrs}]);
  17         81  
1593             }
1594             }
1595              
1596 24 100       1149 $c->{cls} and close $fh;
1597 24 50       90 $c->{fho_cls} and close $c->{fho};
1598 24         629 return 1;
1599             }
1600              
1601 315         492 my @row1;
1602 315 100 100     1976 if (defined $c->{hd_s} || defined $c->{hd_b} || defined $c->{hd_m} || defined $c->{hd_c}) {
      100        
      100        
1603 174         263 my %harg;
1604             !defined $c->{'hd_s'} && $c->{'attr'}{'sep_char'} and
1605 174 100 100     919 $c->{'hd_s'} = [$c->{'attr'}{'sep_char'}];
1606             !defined $c->{'hd_s'} && $c->{'attr'}{'sep'} and
1607 174 100 100     792 $c->{'hd_s'} = [$c->{'attr'}{'sep'}];
1608 174 100       577 defined $c->{'hd_s'} and $harg{'sep_set'} = $c->{'hd_s'};
1609 174 100       741 defined $c->{'hd_b'} and $harg{'detect_bom'} = $c->{'hd_b'};
1610 174 50       471 defined $c->{'hd_m'} and $harg{'munge_column_names'} = $hdrs ? "none" : $c->{'hd_m'};
    100          
1611 174 50       403 defined $c->{'hd_c'} and $harg{'set_column_names'} = $hdrs ? 0 : $c->{'hd_c'};
    100          
1612 174         737 @row1 = $csv->header($fh, \%harg);
1613 171         507 my @hdr = $csv->column_names();
1614 171 100 100     994 @hdr and $hdrs ||= \@hdr;
1615             }
1616              
1617 312 100       888 if ($c->{kh}) {
1618 15         33 @internal_kh = ();
1619 15 100       63 ref $c->{kh} eq "ARRAY" or croak($csv->SetDiag(1501));
1620 10   100     34 $hdrs ||= "auto";
1621             }
1622              
1623 307         633 my $key = $c->{key};
1624 307 100       699 if ($key) {
1625 27 100 100     141 !ref $key or ref $key eq "ARRAY" && @{$key} > 1 or croak($csv->SetDiag(1501));
  8   100     44  
1626 20   100     76 $hdrs ||= "auto";
1627             }
1628 300         763 my $val = $c->{val};
1629 300 100       719 if ($val) {
1630 9 100       30 $key or croak($csv->SetDiag(1502));
1631 8 100 100     37 !ref $val or ref $val eq "ARRAY" && @{$val} > 0 or croak($csv->SetDiag(1503));
  3   100     19  
1632             }
1633              
1634 296 100 100     1154 $c->{fltr} && grep m/\D/ => keys %{$c->{fltr}} and $hdrs ||= "auto";
  16   100     89  
1635 296 100       695 if (defined $hdrs) {
1636 224 100 100     971 if (!ref $hdrs or ref $hdrs eq "CODE") {
1637 52 100       210 my $h = $c->{'hd_b'}
1638             ? [$csv->column_names()]
1639             : $csv->getline($fh);
1640 52   33     209 my $has_h = $h && @$h;
1641              
1642 52 100       188 if (ref $hdrs) {
    100          
    100          
    100          
    50          
1643 1 50       3 $has_h or return;
1644 1         1 my $cr = $hdrs;
1645 1   33     2 $hdrs = [map { $cr->($hdr{$_} || $_) } @{$h}];
  3         43  
  1         2  
1646             }
1647             elsif ($hdrs eq "skip") {
1648             # discard;
1649             }
1650             elsif ($hdrs eq "auto") {
1651 48 50       99 $has_h or return;
1652 48 100       73 $hdrs = [map { $hdr{$_} || $_ } @{$h}];
  136         516  
  48         116  
1653             }
1654             elsif ($hdrs eq "lc") {
1655 1 50       4 $has_h or return;
1656 1   33     1 $hdrs = [map { lc($hdr{$_} || $_) } @{$h}];
  3         10  
  1         3  
1657             }
1658             elsif ($hdrs eq "uc") {
1659 1 50       3 $has_h or return;
1660 1   33     3 $hdrs = [map { uc($hdr{$_} || $_) } @{$h}];
  3         12  
  1         1  
1661             }
1662             }
1663 224 100 66     809 $c->{kh} and $hdrs and @{$c->{kh}} = @{$hdrs};
  10         34  
  10         19  
1664             }
1665              
1666 296 100       712 if ($c->{fltr}) {
1667 16         18 my %f = %{$c->{fltr}};
  16         43  
1668             # convert headers to index
1669 16         23 my @hdr;
1670 16 100       29 if (ref $hdrs) {
1671 7         9 @hdr = @{$hdrs};
  7         19  
1672 7         20 for (0 .. $#hdr) {
1673 21 100       49 exists $f{$hdr[$_]} and $f{$_ + 1} = delete $f{$hdr[$_]};
1674             }
1675             }
1676             $csv->callbacks(after_parse => sub {
1677 114     114   174 my ($CSV, $ROW) = @_; # lexical sub-variables in caps
1678 114         284 foreach my $FLD (sort keys %f) {
1679 115         276 local $_ = $ROW->[$FLD - 1];
1680 115         162 local %_;
1681 115 100       192 @hdr and @_{@hdr} = @{$ROW};
  51         141  
1682 115 100       290 $f{$FLD}->($CSV, $ROW) or return \"skip";
1683 52         312 $ROW->[$FLD - 1] = $_;
1684             }
1685 16         89 });
1686             }
1687              
1688 296         565 my $frag = $c->{frag};
1689             my $ref = ref $hdrs
1690             ? # aoh
1691 296 100       906 do {
    100          
1692 223         576 my @h = $csv->column_names($hdrs);
1693 223         346 my %h; $h{$_}++ for @h;
  223         871  
1694 223 50       660 exists $h{''} and croak($csv->SetDiag(1012));
1695 223 50       587 unless (keys %h == @h) {
1696             croak($csv->_SetDiagInfo(1013, join ", " =>
1697 0         0 map { "$_ ($h{$_})" } grep { $h{$_} > 1 } keys %h));
  0         0  
  0         0  
1698             }
1699             $frag ? $csv->fragment($fh, $frag) :
1700 223 100       1179 $key ? do {
    100          
    100          
1701 17 100       58 my ($k, $j, @f) = ref $key ? (undef, @{$key}) : ($key);
  5         17  
1702 17 100       41 if (my @mk = grep { !exists $h{$_} } grep { defined } $k, @f) {
  22         76  
  27         87  
1703 2         14 croak($csv->_SetDiagInfo(4001, join ", " => @mk));
1704             }
1705             +{map {
1706 26         44 my $r = $_;
1707 26 100       66 my $K = defined $k ? $r->{$k} : join $j => @{$r}{@f};
  4         15  
1708             ($K => (
1709             $val
1710             ? ref $val
1711 4         56 ? {map { $_ => $r->{$_} } @{$val}}
  2         5  
1712 26 100       157 : $r->{$val}
    100          
1713             : $r));
1714 15         23 } @{$csv->getline_hr_all($fh)}};
  15         47  
1715             }
1716             : $csv->getline_hr_all($fh);
1717             }
1718             : # aoa
1719             $frag ? $csv->fragment($fh, $frag)
1720             : $csv->getline_all($fh);
1721 288 50       674 if ($ref) {
1722 288 100 66     1532 @row1 && !$c->{hd_c} && !ref $hdrs and unshift @{$ref}, \@row1;
  4   100     11  
1723             }
1724             else {
1725 0         0 Text::CSV_PP->auto_diag();
1726             }
1727 288 100       5236 $c->{cls} and close $fh;
1728 288 50       975 $c->{fho_cls} and close $c->{fho};
1729 288 100 100     1737 if ($ref and $c->{cbai} || $c->{cboi}) {
      66        
1730             # Default is ARRAYref, but with key =>, you'll get a hashref
1731 23 100       60 foreach my $r (ref $ref eq "ARRAY" ? @{$ref} : values %{$ref}) {
  22         44  
  1         4  
1732 74         5773 local %_;
1733 74 100       151 ref $r eq "HASH" and *_ = $r;
1734 74 100       168 $c->{cbai} and $c->{cbai}->($csv, $r);
1735 74 100       3568 $c->{cboi} and $c->{cboi}->($csv, $r);
1736             }
1737             }
1738              
1739 288 100       1804 if ($c->{sink}) {
1740 14 100       525 my $ro = ref $c->{out} or return;
1741              
1742 7 100 66     28 $ro eq "SCALAR" && ${$c->{out}} eq "skip" and
  2         50  
1743             return;
1744              
1745 5 50       17 $ro eq ref $ref or
1746             croak($csv->_SetDiagInfo(5001, "Output type mismatch"));
1747              
1748 5 100       17 if ($ro eq "ARRAY") {
1749 4 100 33     9 if (@{$c->{out}} and @$ref and ref $c->{out}[0] eq ref $ref->[0]) {
  4   66     36  
1750 2         6 push @{$c->{out}} => @$ref;
  2         9  
1751 2         56 return $c->{out};
1752             }
1753 2         10 croak($csv->_SetDiagInfo(5001, "Output type mismatch"));
1754             }
1755              
1756 1 50       5 if ($ro eq "HASH") {
1757 1         3 @{$c->{out}}{keys %{$ref}} = values %{$ref};
  1         4  
  1         4  
  1         21  
1758 1         31 return $c->{out};
1759             }
1760              
1761 0         0 croak($csv->_SetDiagInfo(5002, "Unsupported output type"));
1762             }
1763              
1764             defined wantarray or
1765             return csv(
1766             in => $ref,
1767             headers => $hdrs,
1768 274 100       716 %{$c->{attr}},
  1         33  
1769             );
1770              
1771 273   100     1088 $last_err ||= $csv->{_ERROR_DIAG};
1772 273         7135 return $ref;
1773             }
1774              
1775             # The end of the common pure perl part.
1776              
1777             ################################################################################
1778             #
1779             # The following are methods implemented in XS in Text::CSV_XS or
1780             # helper methods for Text::CSV_PP only
1781             #
1782             ################################################################################
1783              
1784             my $last_error;
1785             sub _setup_ctx {
1786 28222     28222   51800 my $self = shift;
1787              
1788 28222         48389 $last_error = undef;
1789              
1790 28222         39474 my $ctx;
1791 28222 100       69030 if ($self->{_CACHE}) {
1792 27310         42985 %$ctx = %{$self->{_CACHE}};
  27310         489487  
1793             } else {
1794 912         2859 $ctx->{sep} = ',';
1795 912 50       2641 if (defined $self->{sep_char}) {
1796 912         2541 $ctx->{sep} = $self->{sep_char};
1797             }
1798 912 100 100     3162 if (defined $self->{sep} and $self->{sep} ne '') {
1799 39     39   23463 use bytes;
  39         20763  
  39         277  
1800 5         11 $ctx->{sep} = $self->{sep};
1801 5         11 my $sep_len = length($ctx->{sep});
1802 5 50       19 $ctx->{sep_len} = $sep_len if $sep_len > 1;
1803             }
1804              
1805 912         2329 $ctx->{quo} = '"';
1806 912 50       2368 if (exists $self->{quote_char}) {
1807 912         2117 my $quote_char = $self->{quote_char};
1808 912 100 66     4007 if (defined $quote_char and length $quote_char) {
1809 908         2191 $ctx->{quo} = $quote_char;
1810             } else {
1811 4         13 $ctx->{quo} = "\0";
1812             }
1813             }
1814 912 100 100     2693 if (defined $self->{quote} and $self->{quote} ne '') {
1815 39     39   5877 use bytes;
  39         91  
  39         154  
1816 4         8 $ctx->{quo} = $self->{quote};
1817 4         9 my $quote_len = length($ctx->{quo});
1818 4 50       12 $ctx->{quo_len} = $quote_len if $quote_len > 1;
1819             }
1820              
1821 912         2161 $ctx->{escape_char} = '"';
1822 912 50       2332 if (exists $self->{escape_char}) {
1823 912         1915 my $escape_char = $self->{escape_char};
1824 912 100 100     3302 if (defined $escape_char and length $escape_char) {
1825 904         2031 $ctx->{escape_char} = $escape_char;
1826             } else {
1827 8         26 $ctx->{escape_char} = "\0";
1828             }
1829             }
1830              
1831 912 100       2138 if (defined $self->{eol}) {
1832 907         1925 my $eol = $self->{eol};
1833 907         1622 my $eol_len = length($eol);
1834 907         1919 $ctx->{eol} = $eol;
1835 907         1775 $ctx->{eol_len} = $eol_len;
1836 907 100 100     5941 if ($eol_len == 1 and $eol eq "\015") {
    100 100        
    100 100        
1837 42         155 $ctx->{eol_is_cr} = 1;
1838 42         237 $ctx->{eol_type} = EOL_TYPE_CR;
1839             }
1840             elsif ($eol_len == 1 && $eol eq "\012") {
1841 57         219 $ctx->{eol_type} = EOL_TYPE_NL;
1842             }
1843             elsif ($eol_len == 2 && $eol eq "\015\012") {
1844 51         166 $ctx->{eol_type} = EOL_TYPE_CRNL;
1845             }
1846             }
1847              
1848 912         2543 $ctx->{undef_flg} = 0;
1849 912 100       2282 if (defined $self->{undef_str}) {
1850 1         3 $ctx->{undef_str} = $self->{undef_str};
1851 1 50       7 $ctx->{undef_flg} = 3 if utf8::is_utf8($self->{undef_str});
1852             } else {
1853 911         2201 $ctx->{undef_str} = undef;
1854             }
1855 912 100       2465 if (defined $self->{comment_str}) {
1856 21         49 $ctx->{comment_str} = $self->{comment_str};
1857             }
1858              
1859 912 100       2507 if (defined $self->{_types}) {
1860 1         2 $ctx->{types} = $self->{_types};
1861 1         2 $ctx->{types_len} = length($ctx->{types});
1862             }
1863              
1864 912 100       2395 if (defined $self->{_is_bound}) {
1865 12         40 $ctx->{is_bound} = $self->{_is_bound};
1866             }
1867              
1868 912 100       2422 if (defined $self->{callbacks}) {
1869 324         757 my $cb = $self->{callbacks};
1870 324         763 $ctx->{has_hooks} = 0;
1871 324 100 66     934 if (defined $cb->{after_parse} and ref $cb->{after_parse} eq 'CODE') {
1872 16         32 $ctx->{has_hooks} |= HOOK_AFTER_PARSE;
1873             }
1874 324 100 66     1000 if (defined $cb->{before_print} and ref $cb->{before_print} eq 'CODE') {
1875 3         9 $ctx->{has_hooks} |= HOOK_BEFORE_PRINT;
1876             }
1877             }
1878              
1879 912         2730 for (qw/
1880             binary decode_utf8 always_quote strict strict_eol quote_empty
1881             allow_loose_quotes allow_loose_escapes
1882             allow_unquoted_escape allow_whitespace blank_is_undef
1883             empty_is_undef verbatim auto_diag diag_verbose
1884             keep_meta_info formula skip_empty_rows
1885             /) {
1886 16416 50       42592 $ctx->{$_} = defined $self->{$_} ? $self->{$_} : 0;
1887             }
1888 912         2066 for (qw/quote_space escape_null quote_binary/) {
1889 2736 50       7211 $ctx->{$_} = defined $self->{$_} ? $self->{$_} : 1;
1890             }
1891 912 100       2706 if ($ctx->{escape_char} eq "\0") {
1892 8         19 $ctx->{escape_null} = 0;
1893             }
1894              
1895             # FIXME: readonly
1896 912         5861 %{$self->{_CACHE}} = %$ctx;
  912         9674  
1897             }
1898              
1899 28222         113239 $ctx->{utf8} = 0;
1900 28222         52192 $ctx->{size} = 0;
1901 28222         45289 $ctx->{used} = 0;
1902              
1903 28222 100       62979 if ($ctx->{is_bound}) {
1904 121         214 my $bound = $self->{_BOUND_COLUMNS};
1905 121 100 66     465 if ($bound and ref $bound eq 'ARRAY') {
1906 107         224 $ctx->{bound} = $bound;
1907             } else {
1908 14         30 $ctx->{is_bound} = 0;
1909             }
1910             }
1911              
1912 28222         49184 $ctx->{eol_pos} = -1;
1913             $ctx->{eolx} = $ctx->{eol_len}
1914             ? $ctx->{verbatim} || $ctx->{eol_len} >= 2
1915             ? 1
1916 28222 100 100     68044 : $ctx->{eol} =~ /\A[\015\012]/ ? 0 : 1
    100          
    100          
1917             : 0;
1918 28222 100 100     72537 if ($ctx->{eol_type} && $ctx->{strict_eol} && !$ctx->{eol}) {
      100        
1919 1029         2445 $ctx->{eol_is_cr} = 0;
1920             }
1921 28222 100 66     66305 if ($ctx->{sep_len} and $ctx->{sep_len} > 1 and _is_valid_utf8($ctx->{sep})) {
      100        
1922 13         23 $ctx->{utf8} = 1;
1923             }
1924 28222 50 66     68776 if ($ctx->{quo_len} and $ctx->{quo_len} > 1 and _is_valid_utf8($ctx->{quo})) {
      66        
1925 0         0 $ctx->{utf8} = 1;
1926             }
1927              
1928 28222 100 100     66269 if ($ctx->{strict} && !$ctx->{strict_n} && $self->{_COLUMN_NAMES} && ref $self->{_COLUMN_NAMES} eq 'ARRAY') {
      100        
      66        
1929 2         4 $ctx->{strict_n} = @{$self->{_COLUMN_NAMES}};
  2         7  
1930             }
1931 28222         66434 $ctx;
1932             }
1933              
1934             sub _eol_type {
1935 2876     2876   4979 my $c = shift;
1936 2876 100       7038 return EOL_TYPE_NL if $c eq "\012";
1937 900 100       1897 return EOL_TYPE_CR if $c eq "\015";
1938 791         1679 return EOL_TYPE_OTHER;
1939             }
1940              
1941             sub _set_eol_type {
1942 3337     3337   6168 my ($self, $ctx, $type) = @_;
1943 3337 100       8736 if (!$ctx->{eol_type}) {
1944 630         1756 $ctx->{eol_type} = $type;
1945 630         2319 $self->_cache_set($_cache_id{eol_type} => $type);
1946             }
1947             }
1948              
1949             sub _cache_get_eolt {
1950 32     32   48 my $self = shift;
1951 32 50       66 return unless exists $self->{_CACHE};
1952 32         53 my $cache = $self->{_CACHE};
1953              
1954 32   100     105 my $eol_type = $cache->{eol_type} || 0;
1955 32 50       79 return "\012" if $eol_type == EOL_TYPE_NL;
1956 32 50       62 return "\015" if $eol_type == EOL_TYPE_CR;
1957 32 100       107 return "\015\012" if $eol_type == EOL_TYPE_CRNL;
1958 11 50       72 return $cache->{eol} if $eol_type == EOL_TYPE_OTHER;
1959 11         59 return;
1960             }
1961              
1962             sub _cache_set {
1963 24322     24322   45005 my ($self, $idx, $value) = @_;
1964 24322 100       53176 return unless exists $self->{_CACHE};
1965 23327         35484 my $cache = $self->{_CACHE};
1966              
1967 23327         53734 my $key = $_reverse_cache_id{$idx};
1968 23327 100       110400 if (!defined $key) {
    100          
    100          
    100          
    100          
    100          
    100          
    100          
    100          
    100          
1969 2         30 warn(sprintf "Unknown cache index %d ignored\n", $idx);
1970             } elsif ($key eq 'sep_char') {
1971 3122         6939 $cache->{sep} = $value;
1972 3122         6566 $cache->{sep_len} = 0;
1973             }
1974             elsif ($key eq 'quote_char') {
1975 3369         7940 $cache->{quo} = $value;
1976 3369         8113 $cache->{quo_len} = 0;
1977             }
1978             elsif ($key eq '_has_ahead') {
1979 251         709 $cache->{has_ahead} = $value;
1980             }
1981             elsif ($key eq '_has_hooks') {
1982 11         15 $cache->{has_hooks} = $value;
1983             }
1984             elsif ($key eq '_is_bound') {
1985 12         36 $cache->{is_bound} = $value;
1986             }
1987             elsif ($key eq 'sep') {
1988 39     39   57958 use bytes;
  39         166  
  39         249  
1989 3223         11512 my $len = bytes::length($value);
1990 3223 100       17382 $cache->{sep} = $value if $len;
1991 3223 50       9423 $cache->{sep_len} = $len == 1 ? 0 : $len;
1992             }
1993             elsif ($key eq 'quote') {
1994 39     39   3689 use bytes;
  39         92  
  39         191  
1995 3377         11046 my $len = bytes::length($value);
1996 3377 100       18003 $cache->{quo} = $value if $len;
1997 3377 50       9247 $cache->{quo_len} = $len == 1 ? 0 : $len;
1998             }
1999             elsif ($key eq 'eol') {
2000 218         501 $cache->{eol} = $value;
2001 218 50       617 $cache->{eol_len} = my $len = defined $value ? length($value) : 0;
2002 218 100 100     1074 $cache->{eol_type} = $len == 0 ? EOL_TYPE_UNDEF
    100 100        
    100 66        
    100          
2003             : $len == 1 && $value eq "\012" ? EOL_TYPE_NL
2004             : $len == 1 && $value eq "\015" ? EOL_TYPE_CR
2005             : $len == 2 && $value eq "\015\012" ? EOL_TYPE_CRNL
2006             : EOL_TYPE_OTHER;
2007 218 100       1067 $cache->{eol_is_cr} = $cache->{eol_type} == EOL_TYPE_CR ? 1 : 0;
2008             }
2009             elsif ($key eq 'undef_str') {
2010 11 100       27 if (defined $value) {
2011 9         21 $cache->{undef_str} = $value;
2012 9 100       36 $cache->{undef_flg} = 3 if utf8::is_utf8($value);
2013             } else {
2014 2         6 $cache->{undef_str} = undef;
2015 2         4 $cache->{undef_flg} = 0;
2016             }
2017             }
2018             else {
2019 9731         19043 $cache->{$key} = $value;
2020             }
2021 23327         44527 return 1;
2022             }
2023              
2024             sub _cache_diag {
2025 2     2   6 my $self = shift;
2026 2 100       11 unless (exists $self->{_CACHE}) {
2027 1         15 warn("CACHE: invalid\n");
2028 1         10 return;
2029             }
2030              
2031 1         3 my $cache = $self->{_CACHE};
2032 1         94 warn("CACHE:\n");
2033 1         16 $self->__cache_show_char(quote_char => $cache->{quo});
2034 1         6 $self->__cache_show_char(escape_char => $cache->{escape_char});
2035 1         4 $self->__cache_show_char(sep_char => $cache->{sep});
2036 1         5 for (qw/
2037             binary decode_utf8 allow_loose_escapes allow_loose_quotes allow_unquoted_escape
2038             allow_whitespace always_quote quote_empty quote_space
2039             escape_null quote_binary auto_diag diag_verbose formula strict strict_n strict_eol eol_type skip_empty_rows
2040             has_error_input blank_is_undef empty_is_undef has_ahead
2041             keep_meta_info verbatim useIO has_hooks eol_is_cr eol_len
2042             /) {
2043 29         89 $self->__cache_show_byte($_ => $cache->{$_});
2044             }
2045 1         22 $self->__cache_show_str(eol => $cache->{eol_len}, $cache->{eol});
2046 1         5 $self->__cache_show_byte(sep_len => $cache->{sep_len});
2047 1 50 33     9 if ($cache->{sep_len} and $cache->{sep_len} > 1) {
2048 1         4 $self->__cache_show_str(sep => $cache->{sep_len}, $cache->{sep});
2049             }
2050 1         5 $self->__cache_show_byte(quo_len => $cache->{quo_len});
2051 1 50 33     8 if ($cache->{quo_len} and $cache->{quo_len} > 1) {
2052 1         4 $self->__cache_show_str(quote => $cache->{quo_len}, $cache->{quo});
2053             }
2054 1 50       5 if ($cache->{types_len}) {
2055 0         0 $self->__cache_show_str(types => $cache->{types_len}, $cache->{types});
2056             } else {
2057 1         3 $self->__cache_show_str(types => 0, "");
2058             }
2059 1 50       5 if ($cache->{bptr}) {
2060 0         0 $self->__cache_show_str(bptr => length($cache->{bptr}), $cache->{bptr});
2061             }
2062 1 50       6 if ($cache->{tmp}) {
2063 1         4 $self->__cache_show_str(tmp => length($cache->{tmp}), $cache->{tmp});
2064             }
2065             }
2066              
2067             sub __cache_show_byte {
2068 31     31   66 my ($self, $key, $value) = @_;
2069 31 100       490 warn(sprintf " %-21s %02x:%3d\n", $key, defined $value ? ord($value) : 0, defined $value ? $value : 0);
    100          
2070             }
2071              
2072             sub __cache_show_char {
2073 3     3   11 my ($self, $key, $value) = @_;
2074 3         6 my $v = $value;
2075 3 50       11 if (defined $value) {
2076 3         11 my @b = unpack "U0C*", $value;
2077 3         13 $v = pack "U*", $b[0];
2078             }
2079 3 50       16 warn(sprintf " %-21s %02x:%s\n", $key, defined $v ? ord($v) : 0, $self->__pretty_str($v, 1));
2080             }
2081              
2082             sub __cache_show_str {
2083 5     5   14 my ($self, $key, $len, $value) = @_;
2084 5         12 warn(sprintf " %-21s %02d:%s\n", $key, $len, $self->__pretty_str($value, $len));
2085             }
2086              
2087             sub __pretty_str { # FIXME
2088 8     8   17 my ($self, $str, $len) = @_;
2089 8 50       20 return '' unless defined $str;
2090 8         20 $str = substr($str, 0, $len);
2091 8         47 $str =~ s/"/\\"/g;
2092 8         18 $str =~ s/([^\x09\x20-\x7e])/sprintf '\\x{%x}', ord($1)/eg;
  0         0  
2093 8         187 qq{"$str"};
2094             }
2095              
2096             sub _hook {
2097 20453     20453   48909 my ($self, $name, $fields) = @_;
2098 20453 100       73590 return 0 unless $self->{callbacks};
2099              
2100 218         496 my $cb = $self->{callbacks}{$name};
2101 218 100 66     723 return 0 unless $cb && ref $cb eq 'CODE';
2102              
2103 152         307 my (@res) = $cb->($self, $fields);
2104 152 50       649 if (@res) {
2105 152 100 66     365 return 0 if ref $res[0] eq 'SCALAR' and ${$res[0]} eq "skip";
  64         236  
2106             }
2107 88         229 scalar @res;
2108             }
2109              
2110             ################################################################################
2111             # methods for combine
2112             ################################################################################
2113              
2114             sub __combine {
2115 21708     21708   47918 my ($self, $dst, $fields, $useIO) = @_;
2116              
2117 21708         65691 my $ctx = $self->_setup_ctx;
2118              
2119 21708         42783 my ($binary, $quot, $sep, $esc, $quote_space) = @{$ctx}{qw/binary quo sep escape_char quote_space/};
  21708         74718  
2120              
2121 21708 100 100     108494 if (!defined $quot or $quot eq "\0") { $quot = ''; }
  2         6  
2122              
2123 21708         33480 my $re_esc;
2124 21708 100 66     77035 if ($esc ne '' and $esc ne "\0") {
2125 21706 100       40333 if ($quot ne '') {
2126 21704   66     83488 $re_esc = $self->{_re_comb_escape}->{$quot}->{$esc} ||= qr/(\Q$quot\E|\Q$esc\E)/;
2127             } else {
2128 2   33     86 $re_esc = $self->{_re_comb_escape}->{$quot}->{$esc} ||= qr/(\Q$esc\E)/;
2129             }
2130             }
2131              
2132 21708         35110 my $bound = 0;
2133 21708         39236 my $n = @$fields - 1;
2134 21708 100 100     45794 if ($n < 0 and $ctx->{is_bound}) {
2135 5         10 $n = $ctx->{is_bound} - 1;
2136 5         8 $bound = 1;
2137             }
2138              
2139 21708 100 66     62493 my $check_meta = ($ctx->{keep_meta_info} >= 10 and @{$self->{_FFLAGS} || []} >= $n) ? 1 : 0;
2140              
2141 21708         37482 my $must_be_quoted;
2142             my @results;
2143 21708         53281 for (my $i = 0; $i <= $n; $i++) {
2144 54005         73072 my $v_ref;
2145 54005 100       95410 if ($bound) {
2146 14         66 $v_ref = $self->__bound_field($ctx, $i, 1);
2147             } else {
2148 53991 50       101275 if (@$fields > $i) {
2149 53991         93345 $v_ref = \($fields->[$i]);
2150             }
2151             }
2152 54005 50       101660 next unless $v_ref;
2153              
2154 54005         111362 my $value = $$v_ref;
2155              
2156 54005 100       100666 if (!defined $value) {
2157 56 100       148 if ($ctx->{undef_str}) {
2158 8 100       25 if ($ctx->{undef_flg}) {
2159 3         8 $ctx->{utf8} = 1;
2160 3         7 $ctx->{binary} = 1;
2161             }
2162 8         18 push @results, $ctx->{undef_str};
2163             } else {
2164 48         105 push @results, '';
2165             }
2166 56         167 next;
2167             }
2168              
2169 53949 100 100     467226 if (substr($value, 0, 1) eq '=' && $ctx->{formula}) {
2170 10         30 $value = $self->_formula($ctx, $value, $i);
2171 6 100       18 if (!defined $value) {
2172 2         5 push @results, '';
2173 2         7 next;
2174             }
2175             }
2176              
2177 53943 100       109185 $must_be_quoted = $ctx->{always_quote} ? 1 : 0;
2178 53943 100       96412 if ($value eq '') {
2179 1414 100 100     7875 $must_be_quoted++ if $ctx->{quote_empty} or ($check_meta && $self->is_quoted($i));
      100        
2180             }
2181             else {
2182              
2183 52529 100       140638 if (utf8::is_utf8 $value) {
2184 20041         36469 $ctx->{utf8} = 1;
2185 20041         32087 $ctx->{binary} = 1;
2186             }
2187              
2188 52529 100 100     101887 $must_be_quoted++ if $check_meta && $self->is_quoted($i);
2189              
2190 52529 100 100     164393 if (!$must_be_quoted and $quot ne '') {
2191 39     39   70700 use bytes;
  39         125  
  39         197  
2192             $must_be_quoted++ if
2193             ($value =~ /\Q$quot\E/) ||
2194             ($sep ne '' and $sep ne "\0" and $value =~ /\Q$sep\E/) ||
2195             ($esc ne '' and $esc ne "\0" and $value =~ /\Q$esc\E/) ||
2196             ($ctx->{quote_binary} && $value =~ /[\x00-\x1f\x7f-\xa0]/) ||
2197 46887 100 66     1033690 ($ctx->{quote_space} && $value =~ /[\x09\x20]/);
      100        
      100        
      66        
      100        
      100        
      100        
      100        
      100        
      100        
2198             }
2199              
2200 52529 100 100     134316 if (!$ctx->{binary} and $value =~ /[^\x09\x20-\x7E]/) {
2201             # an argument contained an invalid character...
2202 7         19 $self->{_ERROR_INPUT} = $value;
2203 7         52 $self->SetDiag(2110);
2204 7         90 return 0;
2205             }
2206              
2207 52522 100       98946 if ($re_esc) {
2208 52520         311540 $value =~ s/($re_esc)/$esc$1/g;
2209             }
2210 52522 100       113818 if ($ctx->{escape_null}) {
2211 52308         125107 $value =~ s/\0/${esc}0/g;
2212             }
2213             }
2214              
2215 53936 100       107086 if ($must_be_quoted) {
2216 29448         327794 $value = $quot . $value . $quot;
2217             }
2218 53936         297526 push @results, $value;
2219             }
2220              
2221 21697 100       327882 $$dst = join($sep, @results) . (defined $ctx->{eol} ? $ctx->{eol} : '');
2222              
2223 21697         206735 return 1;
2224             }
2225              
2226             sub _formula {
2227 37     37   80 my ($self, $ctx, $value, $i) = @_;
2228              
2229 37 50       117 my $fa = $ctx->{formula} or return;
2230 37 100       96 if ($fa == 1) { die "Formulas are forbidden\n" }
  3         74  
2231 34 100       93 if ($fa == 2) { die "Formulas are forbidden\n" } # XS croak behaves like PP's "die"
  3         75  
2232              
2233 31 100       65 if ($fa == 3) {
2234 6         12 my $rec = '';
2235 6 100       14 if ($ctx->{recno}) {
2236 3         12 $rec = sprintf " in record %lu", $ctx->{recno} + 1;
2237             }
2238 6         9 my $field = '';
2239 6         12 my $column_names = $self->{_COLUMN_NAMES};
2240 6 100 66     41 if (ref $column_names eq 'ARRAY' and @$column_names >= $i - 1) {
2241 1         4 my $column_name = $column_names->[$i - 1];
2242 1 50       9 $field = sprintf " (column: '%.100s')", $column_name if defined $column_name;
2243             }
2244 6         73 warn sprintf("Field %d%s%s contains formula '%s'\n", $i, $field, $rec, $value);
2245 6         45 return $value;
2246             }
2247              
2248 25 100       81 if ($fa == 4) {
2249 5         11 return '';
2250             }
2251 20 100       46 if ($fa == 5) {
2252 5         14 return undef;
2253             }
2254              
2255 15 50       41 if ($fa == 6) {
2256 15 50       54 if (ref $self->{_FORMULA_CB} eq 'CODE') {
2257 15         35 local $_ = $value;
2258 15         53 return $self->{_FORMULA_CB}->();
2259             }
2260             }
2261 0         0 return;
2262             }
2263              
2264             sub print {
2265 20315     20315 1 23648853 my ($self, $io, $fields) = @_;
2266              
2267 20315         137776 require IO::Handle;
2268              
2269 20315 100       182203 if (!defined $fields) {
    100          
2270 5         12 $fields = [];
2271             } elsif (ref($fields) ne 'ARRAY') {
2272 5         955 Carp::croak("Expected fields to be an array ref");
2273             }
2274              
2275 20310         67569 $self->_hook(before_print => $fields);
2276              
2277 20310         35981 my $str = "";
2278 20310 100       56837 $self->__combine(\$str, $fields, 1) or return '';
2279              
2280 20304         103237 local $\ = '';
2281              
2282 20304 100       89613 $io->print($str) or $self->_set_error_diag(2200);
2283             }
2284              
2285             ################################################################################
2286             # methods for parse
2287             ################################################################################
2288              
2289             sub __parse { # cx_xsParse
2290 3910     3910   10318 my ($self, $fields, $fflags, $src, $useIO) = @_;
2291              
2292 3910         12598 my $ctx = $self->_setup_ctx;
2293              
2294 3910         13115 my $state = $self->___parse($ctx, $fields, $fflags, $src, $useIO);
2295 3905 100 100     19963 if ($state and ($ctx->{has_hooks} || 0) & HOOK_AFTER_PARSE) {
      100        
2296 5         20 $self->_hook(after_parse => $fields);
2297             }
2298 3905   100     30612 return $state || !$last_error;
2299             }
2300              
2301             sub ___parse { # cx_c_xsParse
2302 5032     5032   13409 my ($self, $ctx, $fields, $fflags, $src, $useIO) = @_;
2303              
2304 5032 100 100     25246 local $/ = $ctx->{eol} if $ctx->{eolx} or $ctx->{eol_is_cr};
2305              
2306 5032 100       12675 if ($ctx->{useIO} = $useIO) {
2307 3080         33354 require IO::Handle;
2308              
2309 3080         148888 $ctx->{tmp} = undef;
2310 3080 100 66     8559 if ($ctx->{has_ahead} and defined $self->{_AHEAD}) {
2311 231         611 $ctx->{tmp} = $self->{_AHEAD};
2312 231         649 $ctx->{size} = length $ctx->{tmp};
2313 231         505 $ctx->{used} = 0;
2314             }
2315             } else {
2316 1952         4883 $ctx->{tmp} = $src;
2317 1952         5074 $ctx->{size} = length $src;
2318 1952         4511 $ctx->{used} = 0;
2319 1952         6598 $ctx->{utf8} = utf8::is_utf8($src);
2320             }
2321 5032 50       12240 if ($ctx->{has_error_input}) {
2322 0         0 $self->{_ERROR_INPUT} = undef;
2323 0         0 $ctx->{has_error_input} = 0;
2324             }
2325              
2326 5032         15359 my $result = $self->____parse($ctx, $src, $fields, $fflags);
2327 5021         12786 $self->{_RECNO} = ++($ctx->{recno});
2328 5021         11225 $self->{_EOF} = '';
2329              
2330 5021 100       12653 if ($ctx->{strict}) {
2331 60 100       122 my $nf = $ctx->{is_bound} ? $ctx->{fld_idx} : @$fields;
2332 60 100 100     166 if ($nf and !$ctx->{strict_n}) {
2333 20         62 $ctx->{strict_n} = $nf;
2334             }
2335 60 100 66     207 if ($ctx->{strict_n} > 0 and $nf != $ctx->{strict_n}) {
2336 25 100       64 unless ($ctx->{useIO} & useIO_EOF) {
2337 18 100 100     90 unless ($last_error || (!$ctx->{useIO} and $ctx->{has_ahead})) {
      100        
2338 16         55 $self->__parse_error($ctx, 2014, $ctx->{used});
2339             }
2340             }
2341 25 100       109 if ($last_error) {
2342 20         39 $result = undef;
2343             }
2344             }
2345             }
2346              
2347 5021 100       10617 if ($ctx->{useIO}) {
2348 3072 100 66     13593 if (defined $ctx->{tmp} and $ctx->{used} < $ctx->{size} and $ctx->{has_ahead}) {
      100        
2349 94         410 $self->{_AHEAD} = substr($ctx->{tmp}, $ctx->{used}, $ctx->{size} - $ctx->{used});
2350             } else {
2351 2978         4703 $ctx->{has_ahead} = 0;
2352 2978 100       6451 if ($ctx->{useIO} & useIO_EOF) {
2353 582         1138 $self->{_EOF} = 1;
2354             }
2355             }
2356 3072         27666 %{$self->{_CACHE}} = %$ctx;
  3072         57948  
2357              
2358 3072 100       14066 if ($fflags) {
2359 1956 100       3713 if ($ctx->{keep_meta_info}) {
2360 11         29 $self->{_FFLAGS} = $fflags;
2361             } else {
2362 1945         3282 undef $fflags;
2363             }
2364             }
2365             } else {
2366 1949         24941 %{$self->{_CACHE}} = %$ctx;
  1949         51782  
2367             }
2368              
2369 5021 100 100     23763 if ($result and $ctx->{types}) {
2370 2         3 my $len = @$fields;
2371 2   66     6 for (my $i = 0; $i <= $len && $i <= $ctx->{types_len}; $i++) {
2372 8         16 my $value = $fields->[$i];
2373 8 100       11 next unless defined $value;
2374 6         10 my $type = ord(substr($ctx->{types}, $i, 1));
2375 6 100       7 if ($type == IV) {
    100          
2376 2         23 $fields->[$i] = int($value);
2377             } elsif ($type == NV) {
2378 2         9 $fields->[$i] = $value + 0.0;
2379             }
2380             }
2381             }
2382              
2383 5021         13938 $result;
2384             }
2385              
2386             sub ____parse { # cx_Parse
2387 5036     5036   12055 my ($self, $ctx, $src, $fields, $fflags) = @_;
2388              
2389 5036         8902 my ($quot, $sep, $esc, $eol) = @{$ctx}{qw/quo sep escape_char eol/};
  5036         17718  
2390              
2391 5036 100 100     24206 utf8::encode($sep) if !$ctx->{utf8} and $ctx->{sep_len};
2392 5036 100 100     18925 utf8::encode($quot) if !$ctx->{utf8} and $ctx->{quo_len};
2393 5036 100 100     23093 utf8::encode($eol) if !$ctx->{utf8} and $ctx->{eol_len};
2394              
2395 5036         8182 my $seenSomething = 0;
2396 5036         7226 my $spl = -1;
2397 5036         7336 my $waitingForField = 1;
2398 5036         8064 my ($value, $v_ref, $c0);
2399 5036         9952 $ctx->{fld_idx} = my $fnum = 0;
2400 5036         11919 $ctx->{flag} = 0;
2401              
2402 5036 100       12545 my $re_str = join '|', map({ $_ eq "\0" ? '[\\0]' : quotemeta($_) } sort { length $b <=> length $a } grep { defined $_ and $_ ne '' } $sep, $quot, $esc, $eol), "\015", "\012", "\x09", " ";
  16226 100       49455  
  16602         32716  
  20144         74375  
2403 5036         101466 $ctx->{_re} = qr/$re_str/;
2404 5036         111975 my $re = qr/$re_str|[^\x09\x20-\x7E]|$/;
2405              
2406             LOOP:
2407 5036         20337 while ($self->__get_from_src($ctx, $src)) {
2408 5130         139254 while ($ctx->{tmp} =~ /\G(.*?)($re)/gs) {
2409 76615         186626 my ($hit, $c) = ($1, $2);
2410 76615         121949 $ctx->{used} = pos($ctx->{tmp});
2411 76615 100 100     197154 if (!$waitingForField and $c eq '' and $hit ne '' and $ctx->{useIO} and !($ctx->{useIO} & useIO_EOF)) {
      100        
      100        
      100        
2412 147         371 $self->{_AHEAD} = $hit;
2413 147         334 $ctx->{has_ahead} = 1;
2414 147         352 $ctx->{has_leftover} = 1;
2415 147         467 last;
2416             }
2417 76468 100 100     231302 last if $seenSomething and $hit eq '' and $c eq ''; # EOF
      100        
2418              
2419             # new field
2420 76097 100       125327 if (!$v_ref) {
2421 24070 100       41383 if ($ctx->{is_bound}) {
2422 152         363 $v_ref = $self->__bound_field($ctx, $fnum, 0);
2423             } else {
2424 23918         32334 $value = '';
2425 23918         34857 $v_ref = \$value;
2426             }
2427 24070         30900 $fnum++;
2428 24070 100       40123 return unless $v_ref;
2429 24066         35795 $ctx->{flag} = 0;
2430 24066         33828 $ctx->{fld_idx}++;
2431 24066         34564 $c0 = '';
2432             }
2433              
2434 76093         92463 $seenSomething = 1;
2435 76093         85998 $spl++;
2436              
2437 76093 100 66     206288 if (defined $hit and $hit ne '') {
2438 46993 100       77672 if ($waitingForField) {
2439 10901 100 100     24002 if (!$spl && $ctx->{comment_str} && $ctx->{tmp} =~ /\A\Q$ctx->{comment_str}/) {
      100        
2440 29         40 $ctx->{used} = $ctx->{size};
2441 29 100       58 $ctx->{fld_idx} = $ctx->{strict_n} ? $ctx->{strict_n} : 0;
2442 29         47 $seenSomething = 0;
2443 29 100       47 unless ($ctx->{useIO}) {
2444 1         5 $ctx->{has_ahead} = 214;
2445             }
2446 29         82 next LOOP;
2447             }
2448 10872         17313 $waitingForField = 0;
2449             }
2450 46964 50       97059 if ($hit =~ /[^\x09\x20-\x7E]/) {
2451 0         0 $ctx->{flag} |= IS_BINARY;
2452             }
2453 46964         73178 $$v_ref .= $hit;
2454             }
2455              
2456             RESTART:
2457 76799 100 66     832584 if (defined $c and defined $sep and $c eq $sep) {
    100 100        
    100 66        
    100 100        
    100 100        
      100        
      100        
      100        
      66        
      66        
      100        
      100        
2458 12548 100       29509 if ($waitingForField) {
    100          
2459             # ,1,"foo, 3",,bar,
2460             # ^ ^
2461 1311 100 100     5806 if ($ctx->{blank_is_undef} or $ctx->{empty_is_undef}) {
2462 53         130 $$v_ref = undef;
2463             } else {
2464 1258         2698 $$v_ref = "";
2465             }
2466 1311 50       3143 unless ($ctx->{is_bound}) {
2467 1311         3502 push @$fields, $$v_ref;
2468             }
2469 1311         2479 $v_ref = undef;
2470 1311 100 66     4084 if ($ctx->{keep_meta_info} and $fflags) {
2471 8         18 push @$fflags, $ctx->{flag};
2472             }
2473             } elsif ($ctx->{flag} & IS_QUOTED) {
2474             # ,1,"foo, 3",,bar,
2475             # ^
2476 2195         3425 $$v_ref .= $c;
2477             } else {
2478             # ,1,"foo, 3",,bar,
2479             # ^ ^ ^
2480 9042         26874 $self->__push_value($ctx, $v_ref, $fields, $fflags, $ctx->{flag}, $fnum);
2481 9040         12425 $v_ref = undef;
2482 9040         11962 $waitingForField = 1;
2483             }
2484             }
2485             elsif (defined $c and defined $quot and $quot ne "\0" and $c eq $quot) {
2486 23321 100       42702 if ($waitingForField) {
2487             # ,1,"foo, 3",,bar,\r\n
2488             # ^
2489 11127         18993 $ctx->{flag} |= IS_QUOTED;
2490 11127         13686 $waitingForField = 0;
2491 11127         65596 next;
2492             }
2493 12194 100       26991 if ($ctx->{flag} & IS_QUOTED) {
2494             # ,1,"foo, 3",,bar,\r\n
2495             # ^
2496 12126         15415 my $quoesc = 0;
2497 12126         29701 my $c2 = $self->__get($ctx, $src);
2498              
2499 12126 100       26804 if ($ctx->{allow_whitespace}) {
2500             # , 1 , "foo, 3" , , bar , \r\n
2501             # ^
2502 4290         12002 while ($self->__is_whitespace($ctx, $c2)) {
2503 90 100 33     417 if ($ctx->{allow_loose_quotes} and !(defined $esc and $c2 eq $esc)) {
      66        
2504 1         2 $$v_ref .= $c;
2505 1         1 $c = $c2;
2506             }
2507 90         177 $c2 = $self->__get($ctx, $src);
2508             }
2509             }
2510              
2511 12126 100       22500 if (!defined $c2) { # EOF
2512             # ,1,"foo, 3"
2513             # ^
2514 1313         4398 $self->__push_value($ctx, $v_ref, $fields, $fflags, $ctx->{flag}, $fnum);
2515 1313         6921 return 1;
2516             }
2517              
2518 10813 100 33     44752 if (defined $c2 and defined $sep and $c2 eq $sep) {
      66        
2519             # ,1,"foo, 3",,bar,\r\n
2520             # ^
2521 9089         26922 $self->__push_value($ctx, $v_ref, $fields, $fflags, $ctx->{flag}, $fnum);
2522 9089         15404 $v_ref = undef;
2523 9089         11222 $waitingForField = 1;
2524 9089         54891 next;
2525             }
2526 1724 100 100     9452 if (defined $c2 and ($c2 eq "\012" or (defined $eol and $c2 eq $eol))) { # FIXME: EOLX
      66        
2527             # ,1,"foo, 3",,"bar"\n
2528             # ^
2529 362         898 my $eolt = _eol_type($c2);
2530 362 100 100     1469 if ($ctx->{strict_eol} and $ctx->{eol_type} and $ctx->{eol_type} != $eolt) {
      100        
2531 27 100       82 $self->__error_eol($ctx) or return;
2532             }
2533 360         1170 $self->_set_eol_type($ctx, $eolt);
2534 360         1093 $self->__push_value($ctx, $v_ref, $fields, $fflags, $ctx->{flag}, $fnum);
2535 360         1577 return 1;
2536             }
2537              
2538 1362 100 100     4342 if (defined $esc and $c eq $esc) {
2539 1341         1949 $quoesc = 1;
2540 1341 100 66     4293 if (defined $c2 and $c2 eq '0') {
2541             # ,1,"foo, 3"056",,bar,\r\n
2542             # ^
2543 51         150 $$v_ref .= "\0";
2544 51         414 next;
2545             }
2546 1290 100 33     5322 if (defined $c2 and defined $quot and $c2 eq $quot) {
      66        
2547             # ,1,"foo, 3""56",,bar,\r\n
2548             # ^
2549 1081 100       2199 if ($ctx->{utf8}) {
2550 1         2 $ctx->{flag} |= IS_BINARY;
2551             }
2552 1081         1776 $$v_ref .= $c2;
2553 1081         6435 next;
2554             }
2555 209 100 66     720 if ($ctx->{allow_loose_escapes} and defined $c2 and $c2 ne "\015") {
      100        
2556             # ,1,"foo, 3"56",,bar,\r\n
2557             # ^
2558 4         10 $$v_ref .= $c;
2559 4         44 $c = $c2;
2560 4         693 goto RESTART;
2561             }
2562             }
2563 226 100 66     1035 if (defined $c2 and $c2 eq "\015") {
2564 169 50       395 if ($ctx->{eol_is_cr}) {
2565             # ,1,"foo, 3"\r
2566             # ^
2567 0         0 $self->__push_value($ctx, $v_ref, $fields, $fflags, $ctx->{flag}, $fnum);
2568 0         0 return 1;
2569             }
2570              
2571 169         392 my $c3 = $self->__get($ctx, $src);
2572 169 100 100     729 if (defined $c3 and $c3 eq "\012") {
2573             # ,1,"foo, 3"\r\n
2574             # ^
2575 137 100 100     694 if ($ctx->{strict_eol} and $ctx->{eol_type} and $ctx->{eol_type} != EOL_TYPE_CRNL) {
      100        
2576 21 50       94 $self->__error_eol($ctx) or return;
2577             }
2578 137         549 $self->_set_eol_type($ctx, EOL_TYPE_CRNL);
2579 137         470 $self->__push_value($ctx, $v_ref, $fields, $fflags, $ctx->{flag}, $fnum);
2580 137         665 return 1;
2581             }
2582              
2583 32 100 66     114 if ($ctx->{useIO} and !$ctx->{eol_len}) {
2584 19 100       48 if ($c3 eq "\015") { # \r followed by an empty line
2585             # ,1,"foo, 3"\r\r
2586             # ^
2587 8 100 100     41 if ($ctx->{strict_eol} and $ctx->{eol_type}) {
2588 2 50       8 unless ($ctx->{eol_type} == EOL_TYPE_CR) {
2589 2 50       8 $self->__error_eol($ctx) or return;
2590             }
2591 2         5 $ctx->{used}--;
2592 2         4 $ctx->{has_ahead}++;
2593 2         8 $self->__push_value($ctx, $v_ref, $fields, $fflags, $ctx->{flag}, $fnum);
2594 2         9 return 1;
2595             }
2596 6         22 $self->__set_eol_is_cr($ctx);
2597 6 50       21 if ($ctx->{flag} & IS_QUOTED) {
2598 6         12 $ctx->{flag} ^= IS_QUOTED;
2599             }
2600 6         15 $c = $c0 = "\015";
2601 6         409 goto EOLX;
2602             }
2603 11 50       47 if ($c3 !~ /[^\x09\x20-\x7E]/) {
2604             # ,1,"foo\n 3",,"bar"\r
2605             # baz,4
2606             # ^
2607 11 100 100     52 if ($ctx->{strict_eol} and $ctx->{eol_type}) {
2608 2 50       8 unless ($ctx->{eol_type} == EOL_TYPE_CR) {
2609 2 50       7 $self->__error_eol($ctx) or return;
2610             }
2611 2         4 $ctx->{eol_is_cr} = 1;
2612             } else {
2613 9         43 $self->__set_eol_is_cr($ctx);
2614             }
2615 11         18 $ctx->{used}--;
2616 11         18 $ctx->{has_ahead} = 1;
2617 11         38 $self->__push_value($ctx, $v_ref, $fields, $fflags, $ctx->{flag}, $fnum);
2618 11         77 return 1;
2619             }
2620             }
2621              
2622 13 100       46 $self->__parse_error($ctx, $quoesc ? 2023 : 2010, $ctx->{used} - 2);
2623 13         43 return;
2624             }
2625              
2626 57 100 100     208 if ($ctx->{allow_loose_quotes} and !$quoesc) {
2627             # ,1,"foo, 3"456",,bar,\r\n
2628             # ^
2629 10         15 $$v_ref .= $c;
2630 10         15 $c = $c2;
2631 10         1127 goto RESTART;
2632             }
2633             # 1,"foo" ",3
2634             # ^
2635 47 100       117 if ($quoesc) {
2636 39         74 $ctx->{used}--;
2637 39         202 $self->__error_inside_quotes($ctx, 2023);
2638 37         247 return;
2639             }
2640 8         55 $self->__error_inside_quotes($ctx, 2011);
2641 8         45 return;
2642             }
2643             # !waitingForField, !InsideQuotes
2644 68 100       178 if ($ctx->{allow_loose_quotes}) { # 1,foo "boo" d'uh,1
2645 16         22 $ctx->{flag} |= IS_ERROR;
2646 16         37 $$v_ref .= $c;
2647             } else {
2648 52         261 $self->__error_inside_field($ctx, 2034);
2649 52         290 return;
2650             }
2651             }
2652             elsif (defined $c and defined $esc and $esc ne "\0" and $c eq $esc) {
2653             # This means quote_char != escape_char
2654 4655 100       15236 if ($waitingForField) {
    100          
    50          
2655 34         59 $waitingForField = 0;
2656 34 100       111 if ($ctx->{allow_unquoted_escape}) {
2657             # The escape character is the first character of an
2658             # unquoted field
2659             # ... get and store next character
2660 4         101 my $c2 = $self->__get($ctx, $src);
2661 4         9 $$v_ref = "";
2662              
2663 4 100       13 if (!defined $c2) { # EOF
2664 1         2 $ctx->{used}--;
2665 1         5 $self->__error_inside_field($ctx, 2035);
2666 1         4 return;
2667             }
2668 3 100 33     49 if ($c2 eq '0') {
    50 33        
      33        
      0        
      33        
      0        
2669 1         3 $$v_ref .= "\0";
2670             }
2671             elsif (
2672             (defined $quot and $c2 eq $quot) or
2673             (defined $sep and $c2 eq $sep) or
2674             (defined $esc and $c2 eq $esc) or
2675             $ctx->{allow_loose_escapes}
2676             ) {
2677 2 50       8 if ($ctx->{utf8}) {
2678 0         0 $ctx->{flag} |= IS_BINARY;
2679             }
2680 2         6 $$v_ref .= $c2;
2681             } else {
2682 0         0 $self->__parse_inside_quotes($ctx, 2025);
2683 0         0 return;
2684             }
2685             }
2686             }
2687             elsif ($ctx->{flag} & IS_QUOTED) {
2688 4612         12093 my $c2 = $self->__get($ctx, $src);
2689 4612 100       10946 if (!defined $c2) { # EOF
2690 3         11 $ctx->{used}--;
2691 3         15 $self->__error_inside_quotes($ctx, 2024);
2692 3         16 return;
2693             }
2694 4609 100 66     33053 if ($c2 eq '0') {
    100 66        
      100        
      66        
      100        
      66        
2695 2         7 $$v_ref .= "\0";
2696             }
2697             elsif (
2698             (defined $quot and $c2 eq $quot) or
2699             (defined $sep and $c2 eq $sep) or
2700             (defined $esc and $c2 eq $esc) or
2701             $ctx->{allow_loose_escapes}
2702             ) {
2703 4581 50       10824 if ($ctx->{utf8}) {
2704 0         0 $ctx->{flag} |= IS_BINARY;
2705             }
2706 4581         7797 $$v_ref .= $c2;
2707             } else {
2708 26         56 $ctx->{used}--;
2709 26         105 $self->__error_inside_quotes($ctx, 2025);
2710 26         142 return;
2711             }
2712             }
2713             elsif ($v_ref) {
2714 9         28 my $c2 = $self->__get($ctx, $src);
2715 9 100       26 if (!defined $c2) { # EOF
2716 4         7 $ctx->{used}--;
2717 4         17 $self->__error_inside_field($ctx, 2035);
2718 4         16 return;
2719             }
2720 5         7 $$v_ref .= $c2;
2721             }
2722             else {
2723 0         0 $self->__error_inside_field($ctx, 2036);
2724 0         0 return;
2725             }
2726             }
2727             elsif (defined $c and ($c eq "\012" or $c eq '' or (defined $eol and $c eq $eol and $eol ne "\015"))) { # EOL
2728 3289 100 100     15799 EOLX:
2729             my $eolt = (($c eq "\012" || $c eq "\015") && $c0 eq "\015") ? EOL_TYPE_CRNL : _eol_type($c);
2730 3289         5329 $c0 = '';
2731 3289 100       8077 unless ($ctx->{flag} & CSV_FLAGS_IS_QUOTED) {
2732 2504 100 100     7675 if ($ctx->{strict_eol} and $ctx->{eol_type} and $ctx->{eol_type} != $eolt) {
      100        
2733 39 100       141 $self->__error_eol($ctx) or return;
2734             }
2735 2499         6626 $self->_set_eol_type($ctx, $eolt);
2736             }
2737 3284 100 100     9541 if ($fnum == 1 && $ctx->{flag} == 0 && (!$v_ref || $$v_ref eq '') && $ctx->{skip_empty_rows}) {
      66        
      100        
      100        
2738             ### SkipEmptyRow
2739 89         163 my $ser = $ctx->{skip_empty_rows};
2740 89 100       194 if ($ser == 3) { $self->SetDiag(2015); die "Empty row\n"; }
  3         15  
  3         220  
2741 86 100       224 if ($ser == 4) { $self->SetDiag(2015); die "Empty row\n"; }
  3         13  
  3         163  
2742 83 100       170 if ($ser == 5) { $self->SetDiag(2015); return undef; }
  2         15  
  2         12  
2743              
2744 81 100       208 if ($ser <= 2) { # skip & eof
2745 71         138 $ctx->{fld_idx} = 0;
2746 71         227 $c = $self->__get($ctx, $src);
2747 71 100 100     322 if (!defined $c or $ser == 2) { # EOF
2748 8         16 $v_ref = undef;
2749 8         13 $seenSomething = 0;
2750 8 100       22 if ($ser == 2) { return undef; }
  2         10  
2751 6         22 last LOOP;
2752             }
2753             }
2754              
2755 73 100       170 if ($ser == 6) {
2756 10         22 my $cb = $self->{_EMPTROW_CB};
2757 10 50 33     52 unless ($cb && ref $cb eq 'CODE') {
2758 0         0 return undef; # A callback is wanted, but none found
2759             }
2760 10         19 local $_ = $v_ref;
2761 10         38 my $rv = $cb->();
2762             # Result should be a ref to a list.
2763 10 100       52 unless (ref $rv eq 'ARRAY') {
2764 2         15 return undef;
2765             }
2766 8         14 my $n = @$rv;
2767 8 50       19 if ($n <= 0) {
2768 0         0 return 1;
2769             }
2770 8 50 33     24 if ($ctx->{is_bound} && $ctx->{is_bound} < $n) {
2771 0         0 $n = $ctx->{is_bound} - 1;
2772             }
2773 8         21 for (my $i = 0; $i < $n; $i++) {
2774 32         54 my $rvi = $rv->[$i];
2775 32         77 $self->__push_value($ctx, \$rvi, $fields, $fflags, $ctx->{flag}, $fnum);
2776             }
2777 8         45 return 1;
2778             }
2779 63         8261 goto RESTART;
2780             }
2781              
2782 3195 100       5992 if ($waitingForField) {
2783             # ,1,"foo, 3",,bar,
2784             # ^
2785 263 100 100     1172 if ($ctx->{blank_is_undef} or $ctx->{empty_is_undef}) {
2786 16         39 $$v_ref = undef;
2787             } else {
2788 247         465 $$v_ref = "";
2789             }
2790 263 100       658 unless ($ctx->{is_bound}) {
2791 262         782 push @$fields, $$v_ref;
2792             }
2793 263 100 66     713 if ($ctx->{keep_meta_info} and $fflags) {
2794 14         28 push @$fflags, $ctx->{flag};
2795             }
2796 263         1342 return 1;
2797             }
2798 2932 100       7349 if ($ctx->{flag} & IS_QUOTED) {
    100          
2799             # ,1,"foo\n 3",,bar,
2800             # ^
2801 785         1112 $ctx->{flag} |= IS_BINARY;
2802 785 100       1368 unless ($ctx->{binary}) {
2803 29         145 $self->__error_inside_quotes($ctx, 2021);
2804 29         156 return;
2805             }
2806 756         1080 $$v_ref .= $c;
2807             }
2808             elsif ($ctx->{verbatim}) {
2809             # ,1,foo\n 3,,bar,
2810             # This feature should be deprecated
2811 11         17 $ctx->{flag} |= IS_BINARY;
2812 11 100       24 unless ($ctx->{binary}) {
2813 1         5 $self->__error_inside_field($ctx, 2030);
2814 1         4 return;
2815             }
2816 10 100 100     36 $$v_ref .= $c unless $ctx->{eol} eq $c and $ctx->{useIO};
2817             }
2818             else {
2819             # sep=,
2820             # ^
2821 2136 100 100     6580 if (!$ctx->{recno} and $ctx->{fld_idx} == 1 and $ctx->{useIO} and $hit =~ /^sep=(.{1,16})$/i) {
      100        
      100        
2822 4         18 $ctx->{sep} = $1;
2823 39     39   185170 use bytes;
  39         108  
  39         248  
2824 4         9 my $len = length $ctx->{sep};
2825 4 50       10 if ($len <= 16) {
2826 4 100       16 $ctx->{sep_len} = $len == 1 ? 0 : $len;
2827 4         68 return $self->____parse($ctx, $src, $fields, $fflags);
2828             }
2829             }
2830              
2831             # ,1,"foo\n 3",,bar
2832             # ^
2833 2132         6330 $self->__push_value($ctx, $v_ref, $fields, $fflags, $ctx->{flag}, $fnum);
2834 2132         9976 return 1;
2835             }
2836             }
2837             elsif (defined $c and $c eq "\015" and !$ctx->{verbatim}) {
2838 1255         2106 $c0 = "\015";
2839 1255 100       2385 if ($waitingForField) {
2840 164 100       466 if ($ctx->{eol_is_cr}) {
2841             # ,1,"foo\n 3",,bar,\r
2842             # ^
2843 48         86 $c = "\012";
2844 48         4241 goto EOLX;
2845             }
2846              
2847 116         323 my $c2 = $self->__get($ctx, $src);
2848 116 100       347 if (!defined $c2) { # EOF
2849             # ,1,"foo\n 3",,bar,\r
2850             # ^
2851 5         14 $c = undef;
2852 5 50       14 last unless $seenSomething;
2853 5         1163 goto RESTART;
2854             }
2855 111 100       277 if ($c2 eq "\012") { # \r is not optional before EOLX!
2856             # ,1,"foo\n 3",,bar,\r\n
2857             # ^
2858 90 50 100     334 if ($ctx->{strict_eol} and $ctx->{eol_type} and $ctx->{eol_type} != EOL_TYPE_CRNL) {
      66        
2859 0 0       0 $self->__error_eol($ctx) or return;
2860             }
2861 90         327 $self->_set_eol_type($ctx, EOL_TYPE_CRNL);
2862 90         153 $c = $c2;
2863 90         6922 goto EOLX;
2864             }
2865              
2866 21 100 66     244 if ($ctx->{useIO} and !$ctx->{eol_len}) {
2867 16 50       48 if ($c2 eq "\012") { # \r followed by an empty line
2868             # ,1,"foo\n 3",,bar,\r\r
2869             # ^
2870 0 0 0     0 if ($ctx->{strict_eol} and $ctx->{eol_type}) {
2871 0 0       0 unless ($ctx->{eol_type} == EOL_TYPE_CR) {
2872 0 0       0 $self->__error_eol($ctx) or return;
2873             }
2874 0         0 $ctx->{eol_is_cr} = 1;
2875             } else {
2876 0         0 $self->__set_eol_is_cr($ctx);
2877             }
2878 0         0 goto EOLX;
2879             }
2880 16         26 $waitingForField = 0;
2881 16 100       52 if ($c2 !~ /[^\x09\x20-\x7E]/) {
2882             # ,1,"foo\n 3",,bar,\r
2883             # baz,4
2884             # ^
2885 13 100 100     57 if ($ctx->{strict_eol} and $ctx->{eol_type}) {
2886 4 50       13 unless ($ctx->{eol_type} == EOL_TYPE_CR) {
2887 4 50       14 $self->__error_eol($ctx) or return;
2888             }
2889             } else {
2890 9         31 $self->__set_eol_is_cr($ctx);
2891             }
2892 13         109 $ctx->{used}--;
2893 13         27 $ctx->{has_ahead} = 1;
2894 13 100 66     116 if ($fnum == 1 && $ctx->{flag} == 0 && (!$v_ref or $$v_ref eq '') && $ctx->{skip_empty_rows}) {
      33        
      66        
      66        
2895             ### SkipEmptyRow
2896 6         11 my $ser = $ctx->{skip_empty_rows};
2897 6 50       15 if ($ser == 3) { $self->SetDiag(2015); die "Empty row\n"; }
  0         0  
  0         0  
2898 6 50       15 if ($ser == 4) { $self->SetDiag(2015); die "Empty row\n"; }
  0         0  
  0         0  
2899 6 50       15 if ($ser == 5) { $self->SetDiag(2015); return undef; }
  0         0  
  0         0  
2900              
2901 6 50       15 if ($ser <= 2) { # skip & eof
2902 6         10 $ctx->{fld_idx} = 0;
2903 6         15 $c = $self->__get($ctx, $src);
2904 6 50       40 if (!defined $c) { # EOF
2905 0         0 $v_ref = undef;
2906 0         0 $waitingForField = 1;
2907 0         0 $seenSomething = 0;
2908 0         0 last LOOP;
2909             }
2910             }
2911              
2912 6 50       33 if ($ser == 6) {
2913 0         0 my $cb = $self->{_EMPTROW_CB};
2914 0 0 0     0 unless ($cb && ref $cb eq 'CODE') {
2915 0         0 return undef; # A callback is wanted, but none found
2916             }
2917 0         0 local $_ = $v_ref;
2918 0         0 my $rv = $cb->();
2919             # Result should be a ref to a list.
2920 0 0       0 unless (ref $rv eq 'ARRAY') {
2921 0         0 return undef;
2922             }
2923 0         0 my $n = @$rv;
2924 0 0       0 if ($n <= 0) {
2925 0         0 return 1;
2926             }
2927 0 0 0     0 if ($ctx->{is_bound} && $ctx->{is_bound} < $n) {
2928 0         0 $n = $ctx->{is_bound} - 1;
2929             }
2930 0         0 for (my $i = 0; $i < $n; $i++) {
2931 0         0 my $rvi = $rv->[$i];
2932 0         0 $self->__push_value($ctx, \$rvi, $fields, $fflags, $ctx->{flag}, $fnum);
2933             }
2934 0         0 return 1;
2935             }
2936              
2937 6         13 $$v_ref = $c2;
2938 6         694 goto RESTART;
2939             }
2940 7         34 $self->__push_value($ctx, $v_ref, $fields, $fflags, $ctx->{flag}, $fnum);
2941 7         39 return 1;
2942             }
2943             }
2944              
2945             # ,1,"foo\n 3",,bar,\r\t
2946             # ^
2947 8         19 $ctx->{used}--;
2948 8         67 $self->__error_inside_field($ctx, 2031);
2949 8         144 return;
2950             }
2951 1091 100       2391 if ($ctx->{flag} & IS_QUOTED) {
2952             # ,1,"foo\r 3",,bar,\r\t
2953             # ^
2954 614         1013 $ctx->{flag} |= IS_BINARY;
2955 614 100       1072 unless ($ctx->{binary}) {
2956 70         247 $self->__error_inside_quotes($ctx, 2022);
2957 70         329 return;
2958             }
2959 544         795 $$v_ref .= $c;
2960             }
2961             else {
2962 477 100       1100 if ($ctx->{eol_is_cr}) {
2963             # ,1,"foo\n 3",,bar\r
2964             # ^
2965 192         13671 goto EOLX;
2966             }
2967              
2968 285         924 my $c2 = $self->__get($ctx, $src);
2969 285 100 100     1146 if (defined $c2 and $c2 eq "\012") { # \r is not optional before EOLX!
2970             # ,1,"foo\n 3",,bar\r\n
2971             # ^
2972 251 100 100     2346 if ($ctx->{strict_eol} and $ctx->{eol_type} and $ctx->{eol_type} != EOL_TYPE_CRNL) {
      100        
2973 10 50       62 $self->__error_eol($ctx) or return;
2974             }
2975 251         895 $self->_set_eol_type($ctx, EOL_TYPE_CRNL);
2976 251         19361 goto EOLX;
2977             }
2978              
2979 34 100 66     163 if ($ctx->{useIO} and !$ctx->{eol_len}) {
2980 29 100 100     165 if ($c2 !~ /[^\x09\x20-\x7E]/
2981             # ,1,"foo\n 3",,bar\r
2982             # baz,4
2983             # ^
2984             or $c2 eq "\015"
2985             # ,1,"foo\n 3",,bar,\r\r
2986             # ^
2987             ) {
2988 23 100 100     87 if ($ctx->{strict_eol} and $ctx->{eol_type}) {
2989 4 50       13 unless ($ctx->{eol_type} == EOL_TYPE_CR) {
2990 4 50       10 $self->__error_eol($ctx) or return;
2991             }
2992             } else {
2993 19         89 $self->__set_eol_is_cr($ctx);
2994             }
2995 23         32 $ctx->{used}--;
2996 23         37 $ctx->{has_ahead} = 1;
2997 23 0 33     50 if ($fnum == 1 && $ctx->{flag} == 0 && (!$v_ref or $$v_ref eq '') && $ctx->{skip_empty_rows}) {
      0        
      33        
      0        
2998             ### SKipEmptyRow
2999 0         0 my $ser = $ctx->{skip_empty_rows};
3000 0 0       0 if ($ser == 3) { $self->SetDiag(2015); die "Empty row\n"; }
  0         0  
  0         0  
3001 0 0       0 if ($ser == 4) { $self->SetDiag(2015); die "Empty row\n"; }
  0         0  
  0         0  
3002 0 0       0 if ($ser == 5) { $self->SetDiag(2015); return undef; }
  0         0  
  0         0  
3003              
3004 0 0       0 if ($ser <= 2) { # skip & eof
3005 0         0 $ctx->{fld_idx} = 0;
3006 0         0 $c = $self->__get($ctx, $src);
3007 0 0       0 if (!defined $c) { # EOL
3008 0         0 $v_ref = undef;
3009 0         0 $seenSomething = 0;
3010 0         0 last LOOP;
3011             }
3012             }
3013              
3014 0 0       0 if ($ser == 6) {
3015 0         0 my $cb = $self->{_EMPTROW_CB};
3016 0 0 0     0 unless ($cb && ref $cb eq 'CODE') {
3017 0         0 return undef; # A callback is wanted, but none found
3018             }
3019 0         0 local $_ = $v_ref;
3020 0         0 my $rv = $cb->();
3021             # Result should be a ref to a list.
3022 0 0       0 unless (ref $rv eq 'ARRAY') {
3023 0         0 return undef;
3024             }
3025 0         0 my $n = @$rv;
3026 0 0       0 if ($n <= 0) {
3027 0         0 return 1;
3028             }
3029 0 0 0     0 if ($ctx->{is_bound} && $ctx->{is_bound} < $n) {
3030 0         0 $n = $ctx->{is_bound} - 1;
3031             }
3032 0         0 for (my $i = 0; $i < $n; $i++) {
3033 0         0 my $rvi = $rv->[$i];
3034 0         0 $self->__push_value($ctx, \$rvi, $fields, $fflags, $ctx->{flag}, $fnum);
3035             }
3036 0         0 return 1;
3037             }
3038 0         0 goto RESTART;
3039             }
3040 23         62 $self->__push_value($ctx, $v_ref, $fields, $fflags, $ctx->{flag}, $fnum);
3041 23         88 return 1;
3042             }
3043             }
3044              
3045             # ,1,"foo\n 3",,bar\r\t
3046             # ^
3047 11         43 $self->__error_inside_field($ctx, 2032);
3048 11         58 return;
3049             }
3050             }
3051             else {
3052 32318 50 66     72159 if ($ctx->{eolx} and $c eq $eol) {
3053 0         0 $c = '';
3054 0         0 goto EOLX;
3055             }
3056              
3057 32318 100       54659 if ($waitingForField) {
3058 654 100 100     2278 if (!$spl && $ctx->{comment_str} && $ctx->{tmp} =~ /\A$ctx->{comment_str}/) {
      100        
3059 6         9 $ctx->{used} = $ctx->{size};
3060 6 50       11 $ctx->{fld_idx} = $ctx->{strict_n} ? $ctx->{strict_n} - 1 : 0;
3061 6         7 $seenSomething = 0;
3062 6 50       10 unless ($ctx->{useIO}) {
3063 0         0 $ctx->{has_ahead} = 214; # abuse
3064             }
3065 6         17 next LOOP;
3066             }
3067 648 100 100     2219 if ($ctx->{allow_whitespace} and $self->__is_whitespace($ctx, $c)) {
3068 241         371 do {
3069 351         790 $c = $self->__get($ctx, $src);
3070 351 100       1054 last if !defined $c;
3071             } while $self->__is_whitespace($ctx, $c);
3072 240         28478 goto RESTART;
3073             }
3074 407         675 $waitingForField = 0;
3075 407         49571 goto RESTART;
3076             }
3077 31664 100       57597 if ($ctx->{flag} & IS_QUOTED) {
3078 29475 100 66     92263 if (!defined $c or $c =~ /[^\x09\x20-\x7E]/) {
3079 3297         5915 $ctx->{flag} |= IS_BINARY;
3080 3297 100 100     6437 unless ($ctx->{binary} or $ctx->{utf8}) {
3081 5         25 $self->__error_inside_quotes($ctx, 2026);
3082 5         29 return;
3083             }
3084             }
3085 29470         41887 $$v_ref .= $c;
3086             } else {
3087 2189 100 100     9325 if (!defined $c or $c =~ /[^\x09\x20-\x7E]/) {
3088 450 100 100     1489 last if $ctx->{useIO} && !defined $c;
3089 447         658 $ctx->{flag} |= IS_BINARY;
3090 447 50 66     968 unless ($ctx->{binary} or $ctx->{utf8}) {
3091 9         53 $self->__error_inside_field($ctx, 2037);
3092 9         46 return;
3093             }
3094             }
3095 2177         4012 $$v_ref .= $c;
3096             }
3097             }
3098 50140 100 100     324718 last LOOP if $ctx->{useIO} and $ctx->{verbatim} and $ctx->{used} == $ctx->{size};
      100        
3099             }
3100             }
3101              
3102 472 100       1292 if ($waitingForField) {
3103 417 100       1232 unless ($ctx->{useIO}) {
3104 25 100 66     112 if ($ctx->{has_ahead} and $ctx->{has_ahead} == 214) {
3105 1         3 return 1;
3106             }
3107 24         49 $seenSomething++;
3108             }
3109 416 100       1121 if ($seenSomething) {
3110             # new field
3111 33 100       124 if (!$v_ref) {
3112 32 50       111 if ($ctx->{is_bound}) {
3113 0         0 $v_ref = $self->__bound_field($ctx, $fnum, 0);
3114             } else {
3115 32         68 $value = '';
3116 32         79 $v_ref = \$value;
3117             }
3118 32         65 $fnum++;
3119 32 50       107 return unless $v_ref;
3120 32         71 $ctx->{flag} = 0;
3121 32         65 $ctx->{fld_idx}++;
3122             }
3123 33 100 100     264 if ($ctx->{blank_is_undef} or $ctx->{empty_is_undef}) {
3124 9         24 $$v_ref = undef;
3125             } else {
3126 24         62 $$v_ref = "";
3127             }
3128 33 50       98 unless ($ctx->{is_bound}) {
3129 33         93 push @$fields, $$v_ref;
3130             }
3131 33 100 66     134 if ($ctx->{keep_meta_info} and $fflags) {
3132 3         31 push @$fflags, $ctx->{flag};
3133             }
3134 33         210 return 1;
3135             }
3136 383         1342 $self->SetDiag(2012);
3137 383         1398 return;
3138             }
3139              
3140 55 100       204 if ($ctx->{flag} & IS_QUOTED) {
3141 14         68 $self->__error_inside_quotes($ctx, 2027);
3142 13         69 return;
3143             }
3144              
3145 41 50 0     107 if ($v_ref) {
    0 0        
3146 41         149 $self->__push_value($ctx, $v_ref, $fields, $fflags, $ctx->{flag}, $fnum);
3147             } elsif ($ctx->{flag} == 0 && $fnum == 1 && $ctx->{skip_empty_rows} == 1) {
3148 0         0 return undef;
3149             }
3150 41         194 return 1;
3151             }
3152              
3153             sub __get_from_src {
3154 6988     6988   14869 my ($self, $ctx, $src) = @_;
3155 6988 100 100     31130 return 1 if defined $ctx->{tmp} and $ctx->{used} <= 0;
3156 4805 50       12274 return 1 if $ctx->{used} < $ctx->{size};
3157 4805 100       13712 return unless $ctx->{useIO};
3158 3437         32087 my $res = $src->getline;
3159 3437 100       8860 if (defined $res) {
    100          
3160 2852 100       5617 if ($ctx->{has_ahead}) {
3161 4         13 $ctx->{tmp} = $self->{_AHEAD};
3162 4 100       15 $ctx->{tmp} .= $ctx->{eol} if $ctx->{eol_len};
3163 4         10 $ctx->{tmp} .= $res;
3164 4         7 $ctx->{has_ahead} = 0;
3165             } else {
3166 2848         5193 $ctx->{tmp} = $res;
3167             }
3168 2852 50       7016 if ($ctx->{size} = length $ctx->{tmp}) {
3169 2852         4532 $ctx->{used} = -1;
3170 2852 100       8122 $ctx->{utf8} = 1 if utf8::is_utf8($ctx->{tmp});
3171 2852         9121 pos($ctx->{tmp}) = 0;
3172 2852         9654 return 1;
3173             }
3174             } elsif (delete $ctx->{has_leftover}) {
3175 147         395 $ctx->{tmp} = $self->{_AHEAD};
3176 147         303 $ctx->{has_ahead} = 0;
3177 147         296 $ctx->{useIO} |= useIO_EOF;
3178 147 50       531 if ($ctx->{size} = length $ctx->{tmp}) {
3179 147         245 $ctx->{used} = -1;
3180 147 50       510 $ctx->{utf8} = 1 if utf8::is_utf8($ctx->{tmp});
3181 147         423 pos($ctx->{tmp}) = 0;
3182 147         502 return 1;
3183             }
3184             }
3185 438 100       1415 $ctx->{tmp} = '' unless defined $ctx->{tmp};
3186 438         837 $ctx->{useIO} |= useIO_EOF;
3187 438         1455 return;
3188             }
3189              
3190             sub __set_eol_is_cr {
3191 43     43   87 my ($self, $ctx) = @_;
3192 43         85 $ctx->{eol_is_cr} = 1;
3193 43         74 $ctx->{eol_len} = 1;
3194 43         75 $ctx->{eol} = "\015";
3195 43         65 $ctx->{eol_type} = EOL_TYPE_CR;
3196 43         326 %{$self->{_CACHE}} = %$ctx;
  43         930  
3197              
3198 43         238 $self->{eol} = $ctx->{eol};
3199             }
3200              
3201             sub __bound_field {
3202 166     166   292 my ($self, $ctx, $i, $keep) = @_;
3203 166 100       350 if ($i >= $ctx->{is_bound}) {
3204 3         18 $self->SetDiag(3006);
3205 3         7 return;
3206             }
3207 163 50       414 if (ref $ctx->{bound} eq 'ARRAY') {
3208 163         272 my $ref = $ctx->{bound}[$i];
3209 163 50       319 if (ref $ref) {
3210 163 100       374 if ($keep) {
3211 14         37 return $ref;
3212             }
3213 149 100       402 unless (Scalar::Util::readonly($$ref)) {
3214 148         227 $$ref = "";
3215 148         289 return $ref;
3216             }
3217             }
3218             }
3219 1         9 $self->SetDiag(3008);
3220 1         4 return;
3221             }
3222              
3223             sub __get {
3224 17891     17891   33355 my ($self, $ctx, $src) = @_;
3225 17891 50       34455 return unless defined $ctx->{used};
3226 17891 100       37585 if ($ctx->{used} >= $ctx->{size}) {
3227 1395 100       3785 if ($self->__get_from_src($ctx, $src)) {
3228 52         146 return $self->__get($ctx, $src);
3229             }
3230 1343         3641 return;
3231             }
3232 16496         24350 my $pos = pos($ctx->{tmp});
3233 16496 50       141230 if ($ctx->{tmp} =~ /\G($ctx->{_re}|.)/gs) {
3234 16496         33613 my $c = $1;
3235 16496 100       35292 if ($c =~ /[^\x09\012\015\x20-\x7e]/) {
3236 1222         2164 $ctx->{flag} |= IS_BINARY;
3237             }
3238 16496         24980 $ctx->{used} = pos($ctx->{tmp});
3239 16496         44923 return $c;
3240             } else {
3241 0 0       0 if ($self->__get_from_src($ctx, $src)) {
3242 0         0 return $self->__get($ctx, $src);
3243             }
3244 0         0 pos($ctx->{tmp}) = $pos;
3245 0         0 return;
3246             }
3247             }
3248              
3249             sub __error_inside_quotes {
3250 194     194   461 my ($self, $ctx, $error) = @_;
3251 194         706 $self->__parse_error($ctx, $error, $ctx->{used} - 1);
3252             }
3253              
3254             sub __error_inside_field {
3255 86     86   209 my ($self, $ctx, $error) = @_;
3256 86         397 $self->__parse_error($ctx, $error, $ctx->{used} - 1);
3257             }
3258              
3259             sub __parse_error {
3260 370     370   1106 my ($self, $ctx, $error, $pos, $line) = @_;
3261 370   33     3735 $line ||= (caller(1))[2];
3262 370         1109 $self->{_ERROR_POS} = $pos;
3263 370         848 $self->{_ERROR_FLD} = $ctx->{fld_idx};
3264 370 50       1270 $self->{_ERROR_INPUT} = $ctx->{tmp} if $ctx->{tmp};
3265 370         1353 $self->_set_diag($ctx, $error, $line);
3266 367         705 return;
3267             }
3268              
3269             sub __error_eol {
3270 109     109   261 my ($self, $ctx) = @_;
3271 109 100       330 unless ($ctx->{strict_eol} & 0x40) {
3272 61         297 $self->__parse_error($ctx, 2016, $ctx->{used} - 1);
3273             }
3274 109 100       321 if ($ctx->{strict_eol} & 0x0e) {
3275 7 50       19 if (!$ctx->{is_bound}) {
3276 7         46 return;
3277             }
3278             }
3279 102         355 $ctx->{strict_eol} |= 0x40;
3280             }
3281              
3282             sub __is_whitespace {
3283 5094     5094   9826 my ($self, $ctx, $c) = @_;
3284 5094 100       12511 return unless defined $c;
3285             return (
3286             (!defined $ctx->{sep} or $c ne $ctx->{sep}) &&
3287             (!defined $ctx->{quo} or $c ne $ctx->{quo}) &&
3288 4559   33     31357 (!defined $ctx->{escape_char} or $c ne $ctx->{escape_char}) &&
3289             ($c eq " " or $c eq "\t")
3290             );
3291             }
3292              
3293             sub __push_value { # AV_PUSH (part of)
3294 22189     22189   43338 my ($self, $ctx, $v_ref, $fields, $fflags, $flag, $fnum) = @_;
3295 22189 100       43404 utf8::encode($$v_ref) if $ctx->{utf8};
3296 22189 100 66     47073 if ($ctx->{formula} && defined $$v_ref && substr($$v_ref, 0, 1) eq '=') {
      100        
3297 27         72 my $value = $self->_formula($ctx, $$v_ref, $fnum);
3298 25 100       659 push @$fields, defined $value ? $value : undef;
3299 25         46 return;
3300             }
3301 22162 100 66     85528 if (
      66        
      100        
3302             (!defined $$v_ref or $$v_ref eq '') and
3303             ($ctx->{empty_is_undef} or (!($flag & IS_QUOTED) and $ctx->{blank_is_undef}))
3304             ) {
3305 12         24 $$v_ref = undef;
3306             } else {
3307 22150 100 100     54288 if ($ctx->{allow_whitespace} && !($flag & IS_QUOTED)) {
3308 1747         4879 $$v_ref =~ s/[ \t]+$//;
3309             }
3310 22150 100 66     55943 if ($flag & IS_BINARY and $ctx->{decode_utf8} and ($ctx->{utf8} || _is_valid_utf8($$v_ref))) {
      100        
      66        
3311 2182         7291 utf8::decode($$v_ref);
3312             }
3313             }
3314 22162 100       41807 unless ($ctx->{is_bound}) {
3315 22016         52955 push @$fields, $$v_ref;
3316             }
3317 22162 100 66     62388 if ($ctx->{keep_meta_info} and $fflags) {
3318 88         181 push @$fflags, $flag;
3319             }
3320             }
3321              
3322             sub getline {
3323 1958     1958 1 335671 my ($self, $io) = @_;
3324              
3325 1958         3210 my (@fields, @fflags);
3326 1958         6311 my $res = $self->__parse(\@fields, \@fflags, $io, 1);
3327 1956 100       10958 $res ? \@fields : undef;
3328             }
3329              
3330             sub getline_all {
3331 358     358 1 918 my ($self, $io, $offset, $len) = @_;
3332              
3333 358         938 my $ctx = $self->_setup_ctx;
3334              
3335 358         606 my $tail = 0;
3336 358         537 my $n = 0;
3337 358   100     1377 $offset ||= 0;
3338              
3339 358 100       830 if ($offset < 0) {
3340 12         26 $tail = -$offset;
3341 12         20 $offset = -1;
3342             }
3343              
3344 358         599 my (@row, @list);
3345 358         1364 while ($self->___parse($ctx, \@row, undef, $io, 1)) {
3346 796         2254 $ctx = $self->_setup_ctx;
3347              
3348 796 100       1924 if ($offset > 0) {
3349 20         31 $offset--;
3350 20         49 @row = ();
3351 20         60 next;
3352             }
3353 776 100 100     2698 if ($n++ >= $tail and $tail) {
3354 12         22 shift @list;
3355 12         27 $n--;
3356             }
3357 776 100 100     2865 if (($ctx->{has_hooks} || 0) & HOOK_AFTER_PARSE) {
3358 138 100       330 unless ($self->_hook(after_parse => \@row)) {
3359 63         92 @row = ();
3360 63         160 next;
3361             }
3362             }
3363 713         2511 push @list, [@row];
3364 713         1658 @row = ();
3365              
3366 713 100 100     3156 last if defined $len && $n >= $len and $offset >= 0; # exceeds limit size
      100        
3367             }
3368              
3369 352 100 100     1017 if (defined $len && $n > $len) {
3370 8         29 @list = splice(@list, 0, $len);
3371             }
3372              
3373 352         2497 return \@list;
3374             }
3375              
3376             sub _is_valid_utf8 {
3377 3759 100   3759   59993 return ($_[0] =~ /^(?:
3378             [\x00-\x7F]
3379             |[\xC2-\xDF][\x80-\xBF]
3380             |[\xE0][\xA0-\xBF][\x80-\xBF]
3381             |[\xE1-\xEC][\x80-\xBF][\x80-\xBF]
3382             |[\xED][\x80-\x9F][\x80-\xBF]
3383             |[\xEE-\xEF][\x80-\xBF][\x80-\xBF]
3384             |[\xF0][\x90-\xBF][\x80-\xBF][\x80-\xBF]
3385             |[\xF1-\xF3][\x80-\xBF][\x80-\xBF][\x80-\xBF]
3386             |[\xF4][\x80-\x8F][\x80-\xBF][\x80-\xBF]
3387             )+$/x) ? 1 : 0;
3388             }
3389              
3390             ################################################################################
3391             # methods for errors
3392             ################################################################################
3393              
3394             sub _set_error_diag {
3395 1     1   52 my ($self, $error, $pos) = @_;
3396              
3397 1         5 $self->SetDiag($error);
3398              
3399 1 50       4 if (defined $pos) {
3400 0         0 $_[0]->{_ERROR_POS} = $pos;
3401             }
3402              
3403 1         10 return;
3404             }
3405              
3406             sub error_input {
3407 8     8 1 960 my $self = shift;
3408 8 100 66     72 if ($self and ((Scalar::Util::reftype($self) || '') eq 'HASH' or (ref $self) =~ /^Text::CSV/)) {
      66        
3409 4         25 return $self->{_ERROR_INPUT};
3410             }
3411 4         23 return;
3412             }
3413              
3414             sub _sv_diag {
3415 3902     3902   7865 my ($self, $error) = @_;
3416 3902         23522 bless [$error, $ERRORS->{$error}], 'Text::CSV::ErrorDiag';
3417             }
3418              
3419             sub _set_diag {
3420 1820     1820   4205 my ($self, $ctx, $error, $line) = @_;
3421              
3422 1820         4661 $last_error = $self->_sv_diag($error);
3423 1820         5582 $self->{_ERROR_DIAG} = $last_error;
3424 1820 100       4661 if ($error == 0) {
3425 6         12 $self->{_ERROR_POS} = 0;
3426 6         10 $self->{_ERROR_FLD} = 0;
3427 6         13 $self->{_ERROR_INPUT} = undef;
3428 6         8 $ctx->{has_error_input} = 0;
3429             }
3430 1820 100       4380 if ($line) {
3431 370         903 $self->{_ERROR_SRC} = $line;
3432             }
3433 1820 100       4308 if ($error == 2012) { # EOF
3434 384         880 $self->{_EOF} = 1;
3435             }
3436 1820 100       4164 if ($ctx->{auto_diag}) {
3437 387         1190 $self->error_diag;
3438             }
3439 1817         9685 return $last_error;
3440             }
3441              
3442             sub SetDiag {
3443 3532     3532 1 13224 my ($self, $error, $errstr) = @_;
3444 3532         5261 my $res;
3445 3532 100       8378 if (ref $self) {
3446 1450         4250 my $ctx = $self->_setup_ctx;
3447 1450         4762 $res = $self->_set_diag($ctx, $error);
3448             } else {
3449 2082         3292 $last_error = $error;
3450 2082         5675 $res = $self->_sv_diag($error);
3451             }
3452 3532 100       10100 if (defined $errstr) {
3453 1032         3365 $res->[1] = $errstr;
3454             }
3455 3532         36870 $res;
3456             }
3457              
3458             ################################################################################
3459             package Text::CSV::ErrorDiag;
3460              
3461 39     39   232916 use strict;
  39         101  
  39         3333  
3462             use overload (
3463 39         9459 '""' => \&stringify,
3464             '+' => \&numeric,
3465             '-' => \&numeric,
3466             '*' => \&numeric,
3467             '/' => \&numeric,
3468             fallback => 1,
3469 39     39   29544 );
  39         113470  
3470              
3471             sub numeric {
3472 4707     4707   8319 my ($left, $right) = @_;
3473 4707 50       16792 return ref $left ? $left->[0] : $right->[0];
3474             }
3475              
3476             sub stringify {
3477 3282     3282   662485 $_[0]->[1];
3478             }
3479             ################################################################################
3480             1;
3481             __END__