File Coverage

blib/lib/Text/CSV_PP.pm
Criterion Covered Total %
statement 1687 1819 92.8
branch 1251 1414 88.4
condition 763 948 80.3
subroutine 128 128 100.0
pod 66 67 98.5
total 3895 4376 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 37     37   70714 use strict;
  37         70  
  37         1074  
11 37     37   190 use Exporter ();
  37         62  
  37         858  
12 37     37   199 use vars qw($VERSION @ISA @EXPORT_OK %EXPORT_TAGS);
  37         66  
  37         2390  
13 37     37   221 use Carp;
  37         79  
  37         20809  
14              
15             $VERSION = '2.03';
16             @ISA = qw(Exporter);
17              
18 12     12 1 138 sub PV { 0 }
19 18     18 1 1784 sub IV { 1 }
20 16     16 1 67 sub NV { 2 }
21              
22 4     4 1 10 sub CSV_TYPE_PV { PV }
23 4     4 1 12 sub CSV_TYPE_IV { IV }
24 4     4 1 9 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 4     4 1 15 sub CSV_FLAGS_IS_QUOTED { IS_QUOTED }
32 4     4 1 14 sub CSV_FLAGS_IS_BINARY { IS_BINARY }
33 4     4 1 24 sub CSV_FLAGS_ERROR_IN_FIELD { IS_ERROR }
34 4     4 1 15 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 useIO_EOF () { 0x0010; }
41              
42             %EXPORT_TAGS = (
43             CONSTANTS => [qw(
44             CSV_FLAGS_IS_QUOTED
45             CSV_FLAGS_IS_BINARY
46             CSV_FLAGS_ERROR_IN_FIELD
47             CSV_FLAGS_IS_MISSING
48              
49             CSV_TYPE_PV
50             CSV_TYPE_IV
51             CSV_TYPE_NV
52             )],
53             );
54             @EXPORT_OK = (qw(csv PV IV NV), @{$EXPORT_TAGS{'CONSTANTS'}});
55              
56             my $ERRORS = {
57             # Generic errors
58             1000 => "INI - constructor failed",
59             1001 => "INI - sep_char is equal to quote_char or escape_char",
60             1002 => "INI - allow_whitespace with escape_char or quote_char SP or TAB",
61             1003 => "INI - \\r or \\n in main attr not allowed",
62             1004 => "INI - callbacks should be undef or a hashref",
63             1005 => "INI - EOL too long",
64             1006 => "INI - SEP too long",
65             1007 => "INI - QUOTE too long",
66             1008 => "INI - SEP undefined",
67              
68             1010 => "INI - the header is empty",
69             1011 => "INI - the header contains more than one valid separator",
70             1012 => "INI - the header contains an empty field",
71             1013 => "INI - the header contains nun-unique fields",
72             1014 => "INI - header called on undefined stream",
73              
74             # Syntax errors
75             1500 => "PRM - Invalid/unsupported arguments(s)",
76             1501 => "PRM - The key attribute is passed as an unsupported type",
77             1502 => "PRM - The value attribute is passed without the key attribute",
78             1503 => "PRM - The value attribute is passed as an unsupported type",
79              
80             # Parse errors
81             2010 => "ECR - QUO char inside quotes followed by CR not part of EOL",
82             2011 => "ECR - Characters after end of quoted field",
83             2012 => "EOF - End of data in parsing input stream",
84             2013 => "ESP - Specification error for fragments RFC7111",
85             2014 => "ENF - Inconsistent number of fields",
86             2015 => "ERW - Empty row",
87              
88             # EIQ - Error Inside Quotes
89             2021 => "EIQ - NL char inside quotes, binary off",
90             2022 => "EIQ - CR char inside quotes, binary off",
91             2023 => "EIQ - QUO character not allowed",
92             2024 => "EIQ - EOF cannot be escaped, not even inside quotes",
93             2025 => "EIQ - Loose unescaped escape",
94             2026 => "EIQ - Binary character inside quoted field, binary off",
95             2027 => "EIQ - Quoted field not terminated",
96              
97             # EIF - Error Inside Field
98             2030 => "EIF - NL char inside unquoted verbatim, binary off",
99             2031 => "EIF - CR char is first char of field, not part of EOL",
100             2032 => "EIF - CR char inside unquoted, not part of EOL",
101             2034 => "EIF - Loose unescaped quote",
102             2035 => "EIF - Escaped EOF in unquoted field",
103             2036 => "EIF - ESC error",
104             2037 => "EIF - Binary character in unquoted field, binary off",
105              
106             # Combine errors
107             2110 => "ECB - Binary character in Combine, binary off",
108              
109             # IO errors
110             2200 => "EIO - print to IO failed. See errno",
111              
112             # Hash-Ref errors
113             3001 => "EHR - Unsupported syntax for column_names ()",
114             3002 => "EHR - getline_hr () called before column_names ()",
115             3003 => "EHR - bind_columns () and column_names () fields count mismatch",
116             3004 => "EHR - bind_columns () only accepts refs to scalars",
117             3006 => "EHR - bind_columns () did not pass enough refs for parsed fields",
118             3007 => "EHR - bind_columns needs refs to writable scalars",
119             3008 => "EHR - unexpected error in bound fields",
120             3009 => "EHR - print_hr () called before column_names ()",
121             3010 => "EHR - print_hr () called with invalid arguments",
122              
123             4001 => "PRM - The key does not exist as field in the data",
124              
125             5001 => "PRM - The result does not match the output to append to",
126             5002 => "PRM - Unsupported output",
127              
128             0 => "",
129             };
130              
131             BEGIN {
132 37 50   37   406 if ( $] < 5.006 ) {
    50          
    50          
133 0 0       0 $INC{'bytes.pm'} = 1 unless $INC{'bytes.pm'}; # dummy
134 37     37   293 no strict 'refs';
  37         90  
  37         3222  
135 0         0 *{"utf8::is_utf8"} = sub { 0; };
  0         0  
  0         0  
136 0         0 *{"utf8::decode"} = sub { };
  0         0  
137             }
138             elsif ( $] < 5.008 ) {
139 37     37   269 no strict 'refs';
  37         80  
  37         11302  
140 0         0 *{"utf8::is_utf8"} = sub { 0; };
  0         0  
  0         0  
141 0         0 *{"utf8::decode"} = sub { };
  0         0  
142 0         0 *{"utf8::encode"} = sub { };
  0         0  
143             }
144             elsif ( !defined &utf8::is_utf8 ) {
145 0         0 require Encode;
146 0         0 *utf8::is_utf8 = *Encode::is_utf8;
147             }
148              
149 37         2317 eval q| require Scalar::Util |;
150 37 50       450909 if ( $@ ) {
151 0         0 eval q| require B |;
152 0 0       0 if ( $@ ) {
153 0         0 Carp::croak $@;
154             }
155             else {
156 0         0 my %tmap = qw(
157             B::NULL SCALAR
158             B::HV HASH
159             B::AV ARRAY
160             B::CV CODE
161             B::IO IO
162             B::GV GLOB
163             B::REGEXP REGEXP
164             );
165             *Scalar::Util::reftype = sub (\$) {
166 0         0 my $r = shift;
167 0 0       0 return undef unless length(ref($r));
168 0         0 my $t = ref(B::svref_2object($r));
169             return
170 0 0       0 exists $tmap{$t} ? $tmap{$t}
    0          
171             : length(ref($$r)) ? 'REF'
172             : 'SCALAR';
173 0         0 };
174             *Scalar::Util::readonly = sub (\$) {
175 0         0 my $b = B::svref_2object( $_[0] );
176 0         0 $b->FLAGS & 0x00800000; # SVf_READONLY?
177 0         0 };
178             }
179             }
180             }
181              
182             ################################################################################
183             #
184             # Common pure perl methods, taken almost directly from Text::CSV_XS.
185             # (These should be moved into a common class eventually, so that
186             # both XS and PP don't need to apply the same changes.)
187             #
188             ################################################################################
189              
190             ################################################################################
191             # version
192             ################################################################################
193              
194             sub version {
195 2     2 1 633 return $VERSION;
196             }
197              
198             ################################################################################
199             # new
200             ################################################################################
201              
202             my %def_attr = (
203             eol => '',
204             sep_char => ',',
205             quote_char => '"',
206             escape_char => '"',
207             binary => 0,
208             decode_utf8 => 1,
209             auto_diag => 0,
210             diag_verbose => 0,
211             strict => 0,
212             blank_is_undef => 0,
213             empty_is_undef => 0,
214             allow_whitespace => 0,
215             allow_loose_quotes => 0,
216             allow_loose_escapes => 0,
217             allow_unquoted_escape => 0,
218             always_quote => 0,
219             quote_empty => 0,
220             quote_space => 1,
221             quote_binary => 1,
222             escape_null => 1,
223             keep_meta_info => 0,
224             verbatim => 0,
225             formula => 0,
226             skip_empty_rows => 0,
227             undef_str => undef,
228             comment_str => undef,
229             types => undef,
230             callbacks => undef,
231              
232             _EOF => 0,
233             _RECNO => 0,
234             _STATUS => undef,
235             _FIELDS => undef,
236             _FFLAGS => undef,
237             _STRING => undef,
238             _ERROR_INPUT => undef,
239             _COLUMN_NAMES => undef,
240             _BOUND_COLUMNS => undef,
241             _AHEAD => undef,
242             _FORMULA_CB => undef,
243             _EMPTROW_CB => undef,
244              
245             ENCODING => undef,
246             );
247              
248             my %attr_alias = (
249             quote_always => "always_quote",
250             verbose_diag => "diag_verbose",
251             quote_null => "escape_null",
252             escape => "escape_char",
253             comment => "comment_str",
254             );
255              
256             my $last_new_error = Text::CSV_PP->SetDiag(0);
257             my $ebcdic = ord("A") == 0xC1; # Faster than $Config{'ebcdic'}
258             my @internal_kh;
259             my $last_error;
260              
261             # NOT a method: is also used before bless
262             sub _unhealthy_whitespace {
263 15687     15687   27521 my ($self, $aw) = @_;
264 15687 100       43473 $aw or return 0; # no checks needed without allow_whitespace
265              
266 3568         5077 my $quo = $self->{quote};
267 3568 100 100     8297 defined $quo && length ($quo) or $quo = $self->{quote_char};
268 3568         5129 my $esc = $self->{escape_char};
269              
270 3568 100 100     16011 defined $quo && $quo =~ m/^[ \t]/ and return 1002;
271 3326 100 100     11434 defined $esc && $esc =~ m/^[ \t]/ and return 1002;
272              
273 3036         7015 return 0;
274             }
275              
276             sub _check_sanity {
277 12381     12381   16955 my $self = shift;
278              
279 12381         19061 my $eol = $self->{eol};
280 12381         17335 my $sep = $self->{sep};
281 12381 100 100     29481 defined $sep && length ($sep) or $sep = $self->{sep_char};
282 12381         17523 my $quo = $self->{quote};
283 12381 100 100     26087 defined $quo && length ($quo) or $quo = $self->{quote_char};
284 12381         19515 my $esc = $self->{escape_char};
285              
286             # use DP;::diag ("SEP: '", DPeek ($sep),
287             # "', QUO: '", DPeek ($quo),
288             # "', ESC: '", DPeek ($esc),"'");
289              
290             # sep_char should not be undefined
291 12381 100       23955 $sep ne "" or return 1008;
292 12379 100       22910 length ($sep) > 16 and return 1006;
293 12378 100       33430 $sep =~ m/[\r\n]/ and return 1003;
294              
295 12372 100       21081 if (defined $quo) {
296 12361 100       22065 $quo eq $sep and return 1001;
297 12133 100       20857 length ($quo) > 16 and return 1007;
298 12132 100       23073 $quo =~ m/[\r\n]/ and return 1003;
299             }
300 12137 100       20153 if (defined $esc) {
301 12121 100       20534 $esc eq $sep and return 1001;
302 11953 100       22917 $esc =~ m/[\r\n]/ and return 1003;
303             }
304 11963 100       19908 if (defined $eol) {
305 11959 100       19704 length ($eol) > 16 and return 1005;
306             }
307              
308 11962         21838 return _unhealthy_whitespace ($self, $self->{allow_whitespace});
309             }
310              
311             sub known_attributes {
312 3     3 1 643 sort grep !m/^_/ => "sep", "quote", keys %def_attr;
313             }
314              
315             sub new {
316 955     955 1 2986 $last_new_error = Text::CSV_PP->SetDiag(1000,
317             'usage: my $csv = Text::CSV_PP->new ([{ option => value, ... }]);');
318              
319 955         1662 my $proto = shift;
320 955 100 66     3620 my $class = ref $proto || $proto or return;
321 954 100 100     3998 @_ > 0 && ref $_[0] ne "HASH" and return;
322 946   100     2218 my $attr = shift || {};
323             my %attr = map {
324 946 100       3124 my $k = m/^[a-zA-Z]\w+$/ ? lc $_ : $_;
  2209         9351  
325 2209 100       4650 exists $attr_alias{$k} and $k = $attr_alias{$k};
326 2209         6339 ($k => $attr->{$_});
327             } keys %$attr;
328              
329 946         1996 my $sep_aliased = 0;
330 946 100       2148 if (exists $attr{sep}) {
331 10         28 $attr{sep_char} = delete $attr{sep};
332 10         17 $sep_aliased = 1;
333             }
334 946         1321 my $quote_aliased = 0;
335 946 100       1902 if (exists $attr{quote}) {
336 25         57 $attr{quote_char} = delete $attr{quote};
337 25         43 $quote_aliased = 1;
338             }
339             exists $attr{formula_handling} and
340 946 100       1877 $attr{formula} = delete $attr{formula_handling};
341 946         1450 my $attr_formula = delete $attr{formula};
342              
343 946         2316 for (keys %attr) {
344 2172 100 100     7859 if (m/^[a-z]/ && exists $def_attr{$_}) {
345             # uncoverable condition false
346 2165 100 100     7547 defined $attr{$_} && m/_char$/ and utf8::decode ($attr{$_});
347 2165         3631 next;
348             }
349             # croak?
350 7         35 $last_new_error = Text::CSV_PP->SetDiag(1000, "INI - Unknown attribute '$_'");
351 7 100       23 $attr{auto_diag} and error_diag ();
352 7         33 return;
353             }
354 939 100       2237 if ($sep_aliased) {
355 10         58 my @b = unpack "U0C*", $attr{sep_char};
356 10 100       30 if (@b > 1) {
357 6         14 $attr{sep} = $attr{sep_char};
358 6         17 $attr{sep_char} = "\0";
359             }
360             else {
361 4         12 $attr{sep} = undef;
362             }
363             }
364 939 100 100     2126 if ($quote_aliased and defined $attr{quote_char}) {
365 21         80 my @b = unpack "U0C*", $attr{quote_char};
366 21 100       51 if (@b > 1) {
367 7         18 $attr{quote} = $attr{quote_char};
368 7         16 $attr{quote_char} = "\0";
369             }
370             else {
371 14         32 $attr{quote} = undef;
372             }
373             }
374              
375 939         17006 my $self = { %def_attr, %attr };
376 939 100       3538 if (my $ec = _check_sanity ($self)) {
377 35         91 $last_new_error = Text::CSV_PP->SetDiag($ec);
378 35 100       75 $attr{auto_diag} and error_diag ();
379 35         231 return;
380             }
381 904 100 100     2920 if (defined $self->{callbacks} && ref $self->{callbacks} ne "HASH") {
382 6         910 Carp::carp "The 'callbacks' attribute is set but is not a hash: ignored\n";
383 6         210 $self->{callbacks} = undef;
384             }
385              
386 904         2030 $last_new_error = Text::CSV_PP->SetDiag(0);
387 904 100 100     2882 defined $\ && !exists $attr{eol} and $self->{eol} = $\;
388 904         1551 bless $self, $class;
389 904 100       2141 defined $self->{'types'} and $self->types($self->{'types'});
390 904 50       2870 defined $self->{'skip_empty_rows'} and $self->{'skip_empty_rows'} = _supported_skip_empty_rows($self, $self->{'skip_empty_rows'});
391 904 100       2099 defined $attr_formula and $self->{'formula'} = _supported_formula($self, $attr_formula);
392 903         3955 $self;
393             }
394              
395             # Keep in sync with XS!
396             my %_cache_id = ( # Only expose what is accessed from within PM
397             quote_char => 0,
398             escape_char => 1,
399             sep_char => 2,
400             sep => 39, # 39 .. 55
401             binary => 3,
402             keep_meta_info => 4,
403             always_quote => 5,
404             allow_loose_quotes => 6,
405             allow_loose_escapes => 7,
406             allow_unquoted_escape => 8,
407             allow_whitespace => 9,
408             blank_is_undef => 10,
409             eol => 11,
410             quote => 15,
411             verbatim => 22,
412             empty_is_undef => 23,
413             auto_diag => 24,
414             diag_verbose => 33,
415             quote_space => 25,
416             quote_empty => 37,
417             quote_binary => 32,
418             escape_null => 31,
419             decode_utf8 => 35,
420             _has_ahead => 30,
421             _has_hooks => 36,
422             _is_bound => 26, # 26 .. 29
423             formula => 38,
424             strict => 42,
425             skip_empty_rows => 43,
426             undef_str => 46,
427             comment_str => 54,
428             types => 62,
429             );
430              
431             my %_hidden_cache_id = qw(
432             sep_len 38
433             eol_len 12
434             eol_is_cr 13
435             quo_len 16
436             has_error_input 34
437             );
438              
439             my %_reverse_cache_id = (
440             map({$_cache_id{$_} => $_} keys %_cache_id),
441             map({$_hidden_cache_id{$_} => $_} keys %_hidden_cache_id),
442             );
443              
444             # A `character'
445             sub _set_attr_C {
446 11109     11109   22517 my ($self, $name, $val, $ec) = @_;
447 11109 100       34173 defined $val and utf8::decode($val);
448 11109         18187 $self->{$name} = $val;
449 11109 100       17900 $ec = _check_sanity ($self) and croak ($self->SetDiag ($ec));
450 10199         23463 $self->_cache_set ($_cache_id{$name}, $val);
451             }
452              
453             # A flag
454             sub _set_attr_X {
455 5644     5644   10651 my ($self, $name, $val) = @_;
456 5644 100       11064 defined $val or $val = 0;
457 5644         9490 $self->{$name} = $val;
458 5644         14624 $self->_cache_set ($_cache_id{$name}, 0 + $val);
459             }
460              
461             # A number
462             sub _set_attr_N {
463 59     59   131 my ($self, $name, $val) = @_;
464 59         120 $self->{$name} = $val;
465 59         220 $self->_cache_set ($_cache_id{$name}, 0 + $val);
466             }
467              
468             # Accessor methods.
469             # It is unwise to change them halfway through a single file!
470             sub quote_char {
471 4836     4836 1 663985 my $self = shift;
472 4836 100       10570 if (@_) {
473 3601         8237 $self->_set_attr_C ("quote_char", shift);
474 3374         6167 $self->_cache_set ($_cache_id{quote}, "");
475             }
476 4609         13554 $self->{quote_char};
477             }
478              
479             sub quote {
480 20     20 1 49 my $self = shift;
481 20 100       58 if (@_) {
482 11         20 my $quote = shift;
483 11 100       27 defined $quote or $quote = "";
484 11         30 utf8::decode ($quote);
485 11         47 my @b = unpack "U0C*", $quote;
486 11 100       31 if (@b > 1) {
487 5 100       14 @b > 16 and croak ($self->SetDiag (1007));
488 4         15 $self->quote_char ("\0");
489             }
490             else {
491 6         35 $self->quote_char ($quote);
492 6         11 $quote = "";
493             }
494 10         18 $self->{quote} = $quote;
495              
496 10         18 my $ec = _check_sanity ($self);
497 10 100       30 $ec and croak ($self->SetDiag ($ec));
498              
499 9         19 $self->_cache_set ($_cache_id{quote}, $quote);
500             }
501 18         33 my $quote = $self->{quote};
502 18 100 100     125 defined $quote && length ($quote) ? $quote : $self->{quote_char};
503             }
504              
505             sub escape_char {
506 4827     4827 1 668335 my $self = shift;
507 4827 100       10909 if (@_) {
508 3595         5299 my $ec = shift;
509 3595         9288 $self->_set_attr_C ("escape_char", $ec);
510 3480 100       7331 $ec or $self->_set_attr_X ("escape_null", 0);
511             }
512 4712         13859 $self->{escape_char};
513             }
514              
515             sub sep_char {
516 5156     5156 1 662034 my $self = shift;
517 5156 100       12092 if (@_) {
518 3913         8665 $self->_set_attr_C ("sep_char", shift);
519 3345         6174 $self->_cache_set ($_cache_id{sep}, "");
520             }
521 4588         13359 $self->{sep_char};
522             }
523              
524             sub sep {
525 360     360 1 3240 my $self = shift;
526 360 100       759 if (@_) {
527 327         645 my $sep = shift;
528 327 100       646 defined $sep or $sep = "";
529 327         1127 utf8::decode ($sep);
530 327         1279 my @b = unpack "U0C*", $sep;
531 327 100       726 if (@b > 1) {
532 13 100       32 @b > 16 and croak ($self->SetDiag (1006));
533 12         64 $self->sep_char ("\0");
534             }
535             else {
536 314         798 $self->sep_char ($sep);
537 311         429 $sep = "";
538             }
539 323         634 $self->{sep} = $sep;
540              
541 323         529 my $ec = _check_sanity ($self);
542 323 100       613 $ec and croak ($self->SetDiag ($ec));
543              
544 322         762 $self->_cache_set ($_cache_id{sep}, $sep);
545             }
546 355         561 my $sep = $self->{sep};
547 355 100 100     1357 defined $sep && length ($sep) ? $sep : $self->{sep_char};
548             }
549              
550             sub eol {
551 157     157 1 3436 my $self = shift;
552 157 100       366 if (@_) {
553 125         242 my $eol = shift;
554 125 100       295 defined $eol or $eol = "";
555 125 100       330 length ($eol) > 16 and croak ($self->SetDiag (1005));
556 124         235 $self->{eol} = $eol;
557 124         289 $self->_cache_set ($_cache_id{eol}, $eol);
558             }
559 156         345 $self->{eol};
560             }
561              
562             sub always_quote {
563 3033     3033 1 674188 my $self = shift;
564 3033 100       9163 @_ and $self->_set_attr_X ("always_quote", shift);
565 3033         9269 $self->{always_quote};
566             }
567              
568             sub quote_space {
569 10     10 1 30 my $self = shift;
570 10 100       37 @_ and $self->_set_attr_X ("quote_space", shift);
571 10         37 $self->{quote_space};
572             }
573              
574             sub quote_empty {
575 5     5 1 13 my $self = shift;
576 5 100       25 @_ and $self->_set_attr_X ("quote_empty", shift);
577 5         23 $self->{quote_empty};
578             }
579              
580             sub escape_null {
581 6     6 1 18 my $self = shift;
582 6 100       21 @_ and $self->_set_attr_X ("escape_null", shift);
583 6         39 $self->{escape_null};
584             }
585              
586 3     3 0 20 sub quote_null { goto &escape_null; }
587              
588             sub quote_binary {
589 7     7 1 25 my $self = shift;
590 7 100       26 @_ and $self->_set_attr_X ("quote_binary", shift);
591 7         23 $self->{quote_binary};
592             }
593              
594             sub binary {
595 21     21 1 3165 my $self = shift;
596 21 100       124 @_ and $self->_set_attr_X ("binary", shift);
597 21         59 $self->{binary};
598             }
599              
600             sub strict {
601 2     2 1 5 my $self = shift;
602 2 100       8 @_ and $self->_set_attr_X ("strict", shift);
603 2         10 $self->{strict};
604             }
605              
606             sub _supported_skip_empty_rows {
607 925     925   1699 my ($self, $f) = @_;
608 925 100       1829 defined $f or return 0;
609 924 100 66     3775 if ($self && $f && ref $f && ref $f eq "CODE") {
      100        
      66        
610 5         9 $self->{'_EMPTROW_CB'} = $f;
611 5         12 return 6;
612             }
613             $f =~ m/^(?: 0 | undef )$/xi ? 0 :
614             $f =~ m/^(?: 1 | skip )$/xi ? 1 :
615             $f =~ m/^(?: 2 | eof | stop )$/xi ? 2 :
616             $f =~ m/^(?: 3 | die )$/xi ? 3 :
617             $f =~ m/^(?: 4 | croak )$/xi ? 4 :
618             $f =~ m/^(?: 5 | error )$/xi ? 5 :
619 919 0       4532 $f =~ m/^(?: 6 | cb )$/xi ? 6 : do {
    50          
    100          
    100          
    100          
    100          
    100          
620 0   0     0 $self ||= "Text::CSV_PP";
621 0         0 croak ($self->_SetDiagInfo (1500, "skip_empty_rows '$f' is not supported"));
622             };
623             }
624              
625             sub skip_empty_rows {
626 23     23 1 45 my $self = shift;
627 23 100       77 @_ and $self->_set_attr_N ("skip_empty_rows", _supported_skip_empty_rows ($self, shift));
628 23         39 my $ser = $self->{'skip_empty_rows'};
629 23 100       52 $ser == 6 or $self->{'_EMPTROW_CB'} = undef;
630             $ser <= 1 ? $ser : $ser == 2 ? "eof" : $ser == 3 ? "die" :
631             $ser == 4 ? "croak" : $ser == 5 ? "error" :
632 23 100       155 $self->{'_EMPTROW_CB'};
    100          
    100          
    100          
    100          
633             }
634              
635             sub _SetDiagInfo {
636 17     17   40 my ($self, $err, $msg) = @_;
637 17         84 $self->SetDiag ($err);
638 17         44 my $em = $self->error_diag;
639 17 50       44 $em =~ s/^\d+$// and $msg =~ s/^/# /;
640 17 50       33 my $sep = $em =~ m/[;\n]$/ ? "\n\t" : ": ";
641 17         43 join $sep => grep m/\S\S\S/ => $em, $msg;
642             }
643              
644             sub _supported_formula {
645 103     103   184 my ($self, $f) = @_;
646 103 100       188 defined $f or return 5;
647 102 100 66     485 if ($self && $f && ref $f && ref $f eq "CODE") {
      100        
      100        
648 6         12 $self->{_FORMULA_CB} = $f;
649 6         17 return 6;
650             }
651             $f =~ m/^(?: 0 | none )$/xi ? 0 :
652             $f =~ m/^(?: 1 | die )$/xi ? 1 :
653             $f =~ m/^(?: 2 | croak )$/xi ? 2 :
654             $f =~ m/^(?: 3 | diag )$/xi ? 3 :
655             $f =~ m/^(?: 4 | empty | )$/xi ? 4 :
656             $f =~ m/^(?: 5 | undef )$/xi ? 5 :
657 96 100       828 $f =~ m/^(?: 6 | cb )$/xi ? 6 : do {
    100          
    100          
    100          
    100          
    100          
    100          
658 7   50     16 $self ||= "Text::CSV_PP";
659 7         36 croak ($self->_SetDiagInfo (1500, "formula-handling '$f' is not supported"));
660             };
661             }
662              
663             sub formula {
664 44     44 1 3215 my $self = shift;
665 44 100       134 @_ and $self->_set_attr_N ("formula", _supported_formula ($self, shift));
666 38 100       95 $self->{formula} == 6 or $self->{_FORMULA_CB} = undef;
667 38         126 [qw( none die croak diag empty undef cb )]->[_supported_formula ($self, $self->{formula})];
668             }
669             sub formula_handling {
670 7     7 1 12 my $self = shift;
671 7         18 $self->formula (@_);
672             }
673              
674             sub decode_utf8 {
675 2     2 1 5 my $self = shift;
676 2 100       11 @_ and $self->_set_attr_X ("decode_utf8", shift);
677 2         14 $self->{decode_utf8};
678             }
679              
680             sub keep_meta_info {
681 12     12 1 191 my $self = shift;
682 12 100       39 if (@_) {
683 11         23 my $v = shift;
684 11 100 100     60 !defined $v || $v eq "" and $v = 0;
685 11 100       62 $v =~ m/^[0-9]/ or $v = lc $v eq "false" ? 0 : 1; # true/truth = 1
    100          
686 11         40 $self->_set_attr_X ("keep_meta_info", $v);
687             }
688 12         80 $self->{keep_meta_info};
689             }
690              
691             sub allow_loose_quotes {
692 12     12 1 24 my $self = shift;
693 12 100       47 @_ and $self->_set_attr_X ("allow_loose_quotes", shift);
694 12         27 $self->{allow_loose_quotes};
695             }
696              
697             sub allow_loose_escapes {
698 12     12 1 1392 my $self = shift;
699 12 100       58 @_ and $self->_set_attr_X ("allow_loose_escapes", shift);
700 12         29 $self->{allow_loose_escapes};
701             }
702              
703             sub allow_whitespace {
704 4954     4954 1 1840205 my $self = shift;
705 4954 100       12584 if (@_) {
706 3725         5059 my $aw = shift;
707 3725 100       7151 _unhealthy_whitespace ($self, $aw) and
708             croak ($self->SetDiag (1002));
709 3721         8349 $self->_set_attr_X ("allow_whitespace", $aw);
710             }
711 4950         15615 $self->{allow_whitespace};
712             }
713              
714             sub allow_unquoted_escape {
715 4     4 1 12 my $self = shift;
716 4 100       25 @_ and $self->_set_attr_X ("allow_unquoted_escape", shift);
717 4         13 $self->{allow_unquoted_escape};
718             }
719              
720             sub blank_is_undef {
721 3     3 1 9 my $self = shift;
722 3 100       18 @_ and $self->_set_attr_X ("blank_is_undef", shift);
723 3         13 $self->{blank_is_undef};
724             }
725              
726             sub empty_is_undef {
727 2     2 1 5 my $self = shift;
728 2 100       10 @_ and $self->_set_attr_X ("empty_is_undef", shift);
729 2         9 $self->{empty_is_undef};
730             }
731              
732             sub verbatim {
733 9     9 1 13052 my $self = shift;
734 9 100       41 @_ and $self->_set_attr_X ("verbatim", shift);
735 9         32 $self->{verbatim};
736             }
737              
738             sub undef_str {
739 12     12 1 3355 my $self = shift;
740 12 100       31 if (@_) {
741 11         21 my $v = shift;
742 11 100       44 $self->{undef_str} = defined $v ? "$v" : undef;
743 11         30 $self->_cache_set ($_cache_id{undef_str}, $self->{undef_str});
744             }
745 12         45 $self->{undef_str};
746             }
747              
748             sub comment_str {
749 15     15 1 80 my $self = shift;
750 15 100       37 if (@_) {
751 14         19 my $v = shift;
752 14 100       44 $self->{comment_str} = defined $v ? "$v" : undef;
753 14         49 $self->_cache_set ($_cache_id{comment_str}, $self->{comment_str});
754             }
755 15         37 $self->{comment_str};
756             }
757              
758             sub auto_diag {
759 12     12 1 380 my $self = shift;
760 12 100       36 if (@_) {
761 9         26 my $v = shift;
762 9 100 100     48 !defined $v || $v eq "" and $v = 0;
763 9 100       47 $v =~ m/^[0-9]/ or $v = lc $v eq "false" ? 0 : 1; # true/truth = 1
    100          
764 9         22 $self->_set_attr_X ("auto_diag", $v);
765             }
766 12         73 $self->{auto_diag};
767             }
768              
769             sub diag_verbose {
770 10     10 1 595 my $self = shift;
771 10 100       27 if (@_) {
772 8         14 my $v = shift;
773 8 100 100     42 !defined $v || $v eq "" and $v = 0;
774 8 100       39 $v =~ m/^[0-9]/ or $v = lc $v eq "false" ? 0 : 1; # true/truth = 1
    100          
775 8         23 $self->_set_attr_X ("diag_verbose", $v);
776             }
777 10         44 $self->{diag_verbose};
778             }
779              
780             ################################################################################
781             # status
782             ################################################################################
783              
784             sub status {
785 5     5 1 24 $_[0]->{_STATUS};
786             }
787              
788             sub eof {
789 33     33 1 798 $_[0]->{_EOF};
790             }
791              
792             sub types {
793 7     7 1 1886 my $self = shift;
794              
795 7 100       19 if (@_) {
796 2 100       8 if (my $types = shift) {
797 1         3 $self->{'_types'} = join("", map{ chr($_) } @$types);
  3         11  
798 1         3 $self->{'types'} = $types;
799 1         6 $self->_cache_set ($_cache_id{'types'}, $self->{'_types'});
800             }
801             else {
802 1         3 delete $self->{'types'};
803 1         2 delete $self->{'_types'};
804 1         11 $self->_cache_set ($_cache_id{'types'}, undef);
805 1         4 undef;
806             }
807             }
808             else {
809 5         23 $self->{'types'};
810             }
811             }
812              
813             sub callbacks {
814 73     73 1 20145 my $self = shift;
815 73 100       173 if (@_) {
816 43         58 my $cb;
817 43         67 my $hf = 0x00;
818 43 100       93 if (defined $_[0]) {
    100          
819 41 100       77 grep { !defined } @_ and croak ($self->SetDiag (1004));
  73         199  
820 39 100 100     227 $cb = @_ == 1 && ref $_[0] eq "HASH" ? shift
    100          
821             : @_ % 2 == 0 ? { @_ }
822             : croak ($self->SetDiag (1004));
823 34         111 foreach my $cbk (keys %$cb) {
824             # A key cannot be a ref. That would be stored as the *string
825             # 'SCALAR(0x1f3e710)' or 'ARRAY(0x1a5ae18)'
826 36 100 100     291 $cbk =~ m/^[\w.]+$/ && ref $cb->{$cbk} eq "CODE" or
827             croak ($self->SetDiag (1004));
828             }
829 20 100       64 exists $cb->{error} and $hf |= 0x01;
830 20 100       50 exists $cb->{after_parse} and $hf |= 0x02;
831 20 100       49 exists $cb->{before_print} and $hf |= 0x04;
832             }
833             elsif (@_ > 1) {
834             # (undef, whatever)
835 1         4 croak ($self->SetDiag (1004));
836             }
837 21         81 $self->_set_attr_X ("_has_hooks", $hf);
838 21         51 $self->{callbacks} = $cb;
839             }
840 51         152 $self->{callbacks};
841             }
842              
843             ################################################################################
844             # error_diag
845             ################################################################################
846              
847             sub error_diag {
848 1718     1718 1 38883 my $self = shift;
849 1718         4635 my @diag = (0 + $last_new_error, $last_new_error, 0, 0, 0);
850              
851             # Docs state to NEVER use UNIVERSAL::isa, because it will *never* call an
852             # overridden isa method in any class. Well, that is exacly what I want here
853 1718 100 100     14421 if ($self && ref $self && # Not a class method or direct call
      100        
      100        
854             UNIVERSAL::isa ($self, __PACKAGE__) && exists $self->{_ERROR_DIAG}) {
855 1543         3440 $diag[0] = 0 + $self->{_ERROR_DIAG};
856 1543         2800 $diag[1] = $self->{_ERROR_DIAG};
857 1543 100       3428 $diag[2] = 1 + $self->{_ERROR_POS} if exists $self->{_ERROR_POS};
858 1543         2404 $diag[3] = $self->{_RECNO};
859 1543 100       3056 $diag[4] = $self->{_ERROR_FLD} if exists $self->{_ERROR_FLD};
860              
861             $diag[0] && $self->{callbacks} && $self->{callbacks}{error} and
862 1543 100 100     6769 return $self->{callbacks}{error}->(@diag);
      100        
863             }
864              
865 1709         2807 my $context = wantarray;
866              
867 1709 100       3821 unless (defined $context) { # Void context, auto-diag
868 285 100 100     943 if ($diag[0] && $diag[0] != 2012) {
869 19         79 my $msg = "# CSV_PP ERROR: $diag[0] - $diag[1] \@ rec $diag[3] pos $diag[2]\n";
870 19 100       107 $diag[4] and $msg =~ s/$/ field $diag[4]/;
871              
872 19 100 100     103 unless ($self && ref $self) { # auto_diag
873             # called without args in void context
874 4         45 warn $msg;
875 4         32 return;
876             }
877              
878             $self->{diag_verbose} and $self->{_ERROR_INPUT} and
879 15 50 66     56 $msg .= "$self->{_ERROR_INPUT}'\n".
880             (" " x ($diag[2] - 1))."^\n";
881              
882 15         30 my $lvl = $self->{auto_diag};
883 15 100       42 if ($lvl < 2) {
884 12         103 my @c = caller (2);
885 12 50 66     119 if (@c >= 11 && $c[10] && ref $c[10] eq "HASH") {
      33        
886 0         0 my $hints = $c[10];
887             (exists $hints->{autodie} && $hints->{autodie} or
888             exists $hints->{"guard Fatal"} &&
889 0 0 0     0 !exists $hints->{"no Fatal"}) and
      0        
      0        
890             $lvl++;
891             # Future releases of autodie will probably set $^H{autodie}
892             # to "autodie @args", like "autodie :all" or "autodie open"
893             # so we can/should check for "open" or "new"
894             }
895             }
896 15 100       195 $lvl > 1 ? die $msg : warn $msg;
897             }
898 278         722 return;
899             }
900              
901 1424 100       4727 return $context ? @diag : $diag[1];
902             }
903              
904             sub record_number {
905 14     14 1 2314 return shift->{_RECNO};
906             }
907              
908             ################################################################################
909             # string
910             ################################################################################
911              
912             *string = \&_string;
913             sub _string {
914 1401 100   1401   373026 defined $_[0]->{_STRING} ? ${ $_[0]->{_STRING} } : undef;
  1400         5588  
915             }
916              
917             ################################################################################
918             # fields
919             ################################################################################
920              
921             *fields = \&_fields;
922             sub _fields {
923 1614 100   1614   25550 ref($_[0]->{_FIELDS}) ? @{$_[0]->{_FIELDS}} : undef;
  1613         9710  
924             }
925              
926             ################################################################################
927             # meta_info
928             ################################################################################
929              
930             sub meta_info {
931 21 100   21 1 692 $_[0]->{_FFLAGS} ? @{ $_[0]->{_FFLAGS} } : undef;
  16         89  
932             }
933              
934             sub is_quoted {
935 29 100   29 1 103 return unless (defined $_[0]->{_FFLAGS});
936 26 100 66     134 return if( $_[1] =~ /\D/ or $_[1] < 0 or $_[1] > $#{ $_[0]->{_FFLAGS} } );
  25   100     88  
937              
938 24 100       100 $_[0]->{_FFLAGS}->[$_[1]] & IS_QUOTED ? 1 : 0;
939             }
940              
941             sub is_binary {
942 11 100   11 1 46 return unless (defined $_[0]->{_FFLAGS});
943 10 100 66     79 return if( $_[1] =~ /\D/ or $_[1] < 0 or $_[1] > $#{ $_[0]->{_FFLAGS} } );
  9   100     38  
944 8 100       54 $_[0]->{_FFLAGS}->[$_[1]] & IS_BINARY ? 1 : 0;
945             }
946              
947             sub is_missing {
948 19     19 1 50 my ($self, $idx, $val) = @_;
949 19 100       75 return unless $self->{keep_meta_info}; # FIXME
950 13 100 100     73 $idx < 0 || !ref $self->{_FFLAGS} and return;
951 11 100       18 $idx >= @{$self->{_FFLAGS}} and return 1;
  11         34  
952 10 100       69 $self->{_FFLAGS}[$idx] & IS_MISSING ? 1 : 0;
953             }
954              
955             ################################################################################
956             # combine
957             ################################################################################
958             *combine = \&_combine;
959             sub _combine {
960 1399     1399   703467 my ($self, @fields) = @_;
961 1399         2711 my $str = "";
962 1399         4736 $self->{_FIELDS} = \@fields;
963 1399   100     6071 $self->{_STATUS} = (@fields > 0) && $self->__combine(\$str, \@fields, 0);
964 1395         3382 $self->{_STRING} = \$str;
965 1395         4399 $self->{_STATUS};
966             }
967              
968             ################################################################################
969             # parse
970             ################################################################################
971             *parse = \&_parse;
972             sub _parse {
973 1953     1953   97921 my ($self, $str) = @_;
974              
975 1953 100       4537 ref $str and croak ($self->SetDiag (1500));
976              
977 1949         3334 my $fields = [];
978 1949         2924 my $fflags = [];
979 1949         4333 $self->{_STRING} = \$str;
980 1949 100 100     6701 if (defined $str && $self->__parse ($fields, $fflags, $str, 0)) {
981 1739         4419 $self->{_FIELDS} = $fields;
982 1739         2759 $self->{_FFLAGS} = $fflags;
983 1739         2842 $self->{_STATUS} = 1;
984             }
985             else {
986 207         418 $self->{_FIELDS} = undef;
987 207         328 $self->{_FFLAGS} = undef;
988 207         314 $self->{_STATUS} = 0;
989             }
990 1946         9247 $self->{_STATUS};
991             }
992              
993             sub column_names {
994 1021     1021 1 51700 my ( $self, @columns ) = @_;
995              
996 1021 100       2697 @columns or return defined $self->{_COLUMN_NAMES} ? @{$self->{_COLUMN_NAMES}} : ();
  294 100       1299  
997 684 100 100     2802 @columns == 1 && ! defined $columns[0] and return $self->{_COLUMN_NAMES} = undef;
998              
999 546 100 100     1846 if ( @columns == 1 && ref $columns[0] eq "ARRAY" ) {
    100          
1000 224         312 @columns = @{ $columns[0] };
  224         550  
1001             }
1002 705 100       2217 elsif ( join "", map { defined $_ ? ref $_ : "" } @columns ) {
1003 5         19 croak $self->SetDiag( 3001 );
1004             }
1005              
1006 541 100 100     1439 if ( $self->{_BOUND_COLUMNS} && @columns != @{$self->{_BOUND_COLUMNS}} ) {
  2         9  
1007 1         7 croak $self->SetDiag( 3003 );
1008             }
1009              
1010 540 100       900 $self->{_COLUMN_NAMES} = [ map { defined $_ ? $_ : "\cAUNDEF\cA" } @columns ];
  1263         3227  
1011 540         876 @{ $self->{_COLUMN_NAMES} };
  540         1368  
1012             }
1013              
1014             sub header {
1015 334     334 1 41148 my ($self, $fh, @args) = @_;
1016              
1017 334 100       770 $fh or croak ($self->SetDiag (1014));
1018              
1019 333         557 my (@seps, %args);
1020 333         712 for (@args) {
1021 226 100       556 if (ref $_ eq "ARRAY") {
1022 18         47 push @seps, @$_;
1023 18         35 next;
1024             }
1025 208 100       550 if (ref $_ eq "HASH") {
1026 207         526 %args = %$_;
1027 207         481 next;
1028             }
1029 1         186 croak (q{usage: $csv->header ($fh, [ seps ], { options })});
1030             }
1031              
1032             defined $args{munge} && !defined $args{munge_column_names} and
1033 332 100 66     852 $args{munge_column_names} = $args{munge}; # munge as alias
1034 332 100       733 defined $args{detect_bom} or $args{detect_bom} = 1;
1035 332 100       785 defined $args{set_column_names} or $args{set_column_names} = 1;
1036 332 100       832 defined $args{munge_column_names} or $args{munge_column_names} = "lc";
1037              
1038             # Reset any previous leftovers
1039 332         527 $self->{_RECNO} = 0;
1040 332         578 $self->{_AHEAD} = undef;
1041 332 100       747 $self->{_COLUMN_NAMES} = undef if $args{set_column_names};
1042 332 100       679 $self->{_BOUND_COLUMNS} = undef if $args{set_column_names};
1043 332         1056 $self->_cache_set($_cache_id{'_has_ahead'}, 0);
1044              
1045 332 100       653 if (defined $args{sep_set}) {
1046 27 100       78 ref $args{sep_set} eq "ARRAY" or
1047             croak ($self->_SetDiagInfo (1500, "sep_set should be an array ref"));
1048 22         38 @seps = @{$args{sep_set}};
  22         48  
1049             }
1050              
1051 327 50       954 $^O eq "MSWin32" and binmode $fh;
1052 327         6271 my $hdr = <$fh>;
1053             # check if $hdr can be empty here, I don't think so
1054 327 100 66     2300 defined $hdr && $hdr ne "" or croak ($self->SetDiag (1010));
1055              
1056 325         580 my %sep;
1057 325 100       1000 @seps or @seps = (",", ";");
1058 325         725 foreach my $sep (@seps) {
1059 734 100       2297 index ($hdr, $sep) >= 0 and $sep{$sep}++;
1060             }
1061              
1062 325 100       755 keys %sep >= 2 and croak ($self->SetDiag (1011));
1063              
1064 321         1242 $self->sep (keys %sep);
1065 321         533 my $enc = "";
1066 321 100       711 if ($args{detect_bom}) { # UTF-7 is not supported
1067 320 100       2988 if ($hdr =~ s/^\x00\x00\xfe\xff//) { $enc = "utf-32be" }
  24 100       53  
    100          
    100          
    100          
    100          
    100          
    100          
    100          
    100          
    100          
1068 24         57 elsif ($hdr =~ s/^\xff\xfe\x00\x00//) { $enc = "utf-32le" }
1069 25         56 elsif ($hdr =~ s/^\xfe\xff//) { $enc = "utf-16be" }
1070 24         49 elsif ($hdr =~ s/^\xff\xfe//) { $enc = "utf-16le" }
1071 48         131 elsif ($hdr =~ s/^\xef\xbb\xbf//) { $enc = "utf-8" }
1072 1         7 elsif ($hdr =~ s/^\xf7\x64\x4c//) { $enc = "utf-1" }
1073 1         2 elsif ($hdr =~ s/^\xdd\x73\x66\x73//) { $enc = "utf-ebcdic" }
1074 1         3 elsif ($hdr =~ s/^\x0e\xfe\xff//) { $enc = "scsu" }
1075 1         2 elsif ($hdr =~ s/^\xfb\xee\x28//) { $enc = "bocu-1" }
1076 1         4 elsif ($hdr =~ s/^\x84\x31\x95\x33//) { $enc = "gb-18030" }
1077 36         78 elsif ($hdr =~ s/^\x{feff}//) { $enc = "" }
1078              
1079 320 100       932 $self->{ENCODING} = $enc ? uc $enc : undef;
1080              
1081 320 100       658 $hdr eq "" and croak ($self->SetDiag (1010));
1082              
1083 314 100       621 if ($enc) {
1084 144 50 33     358 $ebcdic && $enc eq "utf-ebcdic" and $enc = "";
1085 144 100       433 if ($enc =~ m/([13]).le$/) {
1086 48         153 my $l = 0 + $1;
1087 48         81 my $x;
1088 48         115 $hdr .= "\0" x $l;
1089 48         194 read $fh, $x, $l;
1090             }
1091 144 50       292 if ($enc) {
1092 144 100       332 if ($enc ne "utf-8") {
1093 96         518 require Encode;
1094 96         535 $hdr = Encode::decode ($enc, $hdr);
1095             }
1096 144         5921 binmode $fh, ":encoding($enc)";
1097             }
1098             }
1099             }
1100              
1101 315         8754 my ($ahead, $eol);
1102 315 100 66     1662 if ($hdr and $hdr =~ s/\Asep=(\S)([\r\n]+)//i) { # Also look in xs:Parse
1103 1         8 $self->sep ($1);
1104 1 50       5 length $hdr or $hdr = <$fh>;
1105             }
1106              
1107 315 100       2072 if ($hdr =~ s/^([^\r\n]+)([\r\n]+)([^\r\n].+)\z/$1/s) {
1108 142         345 $eol = $2;
1109 142         269 $ahead = $3;
1110             }
1111              
1112 315         591 my $hr = \$hdr; # Will cause croak on perl-5.6.x
1113 315 50   8   3583 open my $h, "<", $hr or croak ($self->SetDiag (1010));
  8         58  
  8         15  
  8         75  
1114              
1115 315 100       4243 my $row = $self->getline ($h) or croak;
1116 313         935 close $h;
1117              
1118 313 100       814 if ( $args{'munge_column_names'} eq "lc") {
    100          
    100          
1119 294         415 $_ = lc for @{$row};
  294         1123  
1120             }
1121             elsif ($args{'munge_column_names'} eq "uc") {
1122 7         15 $_ = uc for @{$row};
  7         34  
1123             }
1124             elsif ($args{'munge_column_names'} eq "db") {
1125 3         8 for (@{$row}) {
  3         8  
1126 7         18 s/\W+/_/g;
1127 7         16 s/^_+//;
1128 7         14 $_ = lc;
1129             }
1130             }
1131              
1132 313 100       686 if ($ahead) { # Must be after getline, which creates the cache
1133 142         468 $self->_cache_set ($_cache_id{_has_ahead}, 1);
1134 142         252 $self->{_AHEAD} = $ahead;
1135 142 100       654 $eol =~ m/^\r([^\n]|\z)/ and $self->eol ($eol);
1136             }
1137              
1138 313         849 my @hdr = @$row;
1139             ref $args{munge_column_names} eq "CODE" and
1140 313 100       722 @hdr = map { $args{munge_column_names}->($_) } @hdr;
  4         16  
1141             ref $args{munge_column_names} eq "HASH" and
1142 313 100       597 @hdr = map { $args{munge_column_names}->{$_} || $_ } @hdr;
  3 100       12  
1143 313         455 my %hdr; $hdr{$_}++ for @hdr;
  313         1069  
1144 313 100       656 exists $hdr{''} and croak ($self->SetDiag (1012));
1145 311 100       731 unless (keys %hdr == @hdr) {
1146             croak ($self->_SetDiagInfo (1013, join ", " =>
1147 1         3 map { "$_ ($hdr{$_})" } grep { $hdr{$_} > 1 } keys %hdr));
  1         13  
  2         7  
1148             }
1149 310 100       1170 $args{set_column_names} and $self->column_names (@hdr);
1150 310 100       2730 wantarray ? @hdr : $self;
1151             }
1152              
1153             sub bind_columns {
1154 27     27 1 9749 my ( $self, @refs ) = @_;
1155              
1156 27 100       106 @refs or return defined $self->{_BOUND_COLUMNS} ? @{$self->{_BOUND_COLUMNS}} : undef;
  2 100       12  
1157 23 100 100     150 @refs == 1 && ! defined $refs[0] and return $self->{_BOUND_COLUMNS} = undef;
1158              
1159 18 100 100     79 if ( $self->{_COLUMN_NAMES} && @refs != @{$self->{_COLUMN_NAMES}} ) {
  3         12  
1160 1         4 croak $self->SetDiag( 3003 );
1161             }
1162              
1163 17 100       199 if ( grep { ref $_ ne "SCALAR" } @refs ) { # why don't use grep?
  74606         105411  
1164 2         12 croak $self->SetDiag( 3004 );
1165             }
1166              
1167 15         144 $self->_set_attr_N("_is_bound", scalar @refs);
1168 15         5567 $self->{_BOUND_COLUMNS} = [ @refs ];
1169 15         1541 @refs;
1170             }
1171              
1172             sub getline_hr {
1173 126     126 1 17383 my ($self, @args, %hr) = @_;
1174 126 100       396 $self->{_COLUMN_NAMES} or croak ($self->SetDiag (3002));
1175 125 100       361 my $fr = $self->getline (@args) or return;
1176 123 100       326 if (ref $self->{_FFLAGS}) { # missing
1177             $self->{_FFLAGS}[$_] = IS_MISSING
1178 5 50       21 for (@$fr ? $#{$fr} + 1 : 0) .. $#{$self->{_COLUMN_NAMES}};
  5         9  
  5         24  
1179             @$fr == 1 && (!defined $fr->[0] || $fr->[0] eq "") and
1180 5 100 50     32 $self->{_FFLAGS}[0] ||= IS_MISSING;
      66        
      100        
1181             }
1182 123         209 @hr{@{$self->{_COLUMN_NAMES}}} = @$fr;
  123         495  
1183 123         696 \%hr;
1184             }
1185              
1186             sub getline_hr_all {
1187 247     247 1 503 my ( $self, $io, @args ) = @_;
1188              
1189 247 100       536 unless ( $self->{_COLUMN_NAMES} ) {
1190 2         9 croak $self->SetDiag( 3002 );
1191             }
1192              
1193 245         327 my @cn = @{$self->{_COLUMN_NAMES}};
  245         551  
1194              
1195 245         395 return [ map { my %h; @h{ @cn } = @$_; \%h } @{ $self->getline_all( $io, @args ) } ];
  371         515  
  371         1187  
  371         1584  
  245         550  
1196             }
1197              
1198             sub say {
1199 13     13 1 2153 my ($self, $io, @f) = @_;
1200 13         38 my $eol = $self->eol;
1201 13 100 33     82 $eol eq "" and $self->eol ($\ || $/);
1202             # say ($fh, undef) does not propage actual undef to print ()
1203 13 100 66     82 my $state = $self->print ($io, @f == 1 && !defined $f[0] ? undef : @f);
1204 13         180 $self->eol ($eol);
1205 13         87 return $state;
1206             }
1207              
1208             sub print_hr {
1209 3     3 1 13 my ($self, $io, $hr) = @_;
1210 3 100       16 $self->{_COLUMN_NAMES} or croak($self->SetDiag(3009));
1211 2 100       11 ref $hr eq "HASH" or croak($self->SetDiag(3010));
1212 1         5 $self->print ($io, [ map { $hr->{$_} } $self->column_names ]);
  3         10  
1213             }
1214              
1215             sub fragment {
1216 58     58 1 30060 my ($self, $io, $spec) = @_;
1217              
1218 58         232 my $qd = qr{\s* [0-9]+ \s* }x; # digit
1219 58         147 my $qs = qr{\s* (?: [0-9]+ | \* ) \s*}x; # digit or star
1220 58         385 my $qr = qr{$qd (?: - $qs )?}x; # range
1221 58         319 my $qc = qr{$qr (?: ; $qr )*}x; # list
1222 58 100 100     1259 defined $spec && $spec =~ m{^ \s*
1223             \x23 ? \s* # optional leading #
1224             ( row | col | cell ) \s* =
1225             ( $qc # for row and col
1226             | $qd , $qd (?: - $qs , $qs)? # for cell (ranges)
1227             (?: ; $qd , $qd (?: - $qs , $qs)? )* # and cell (range) lists
1228             ) \s* $}xi or croak ($self->SetDiag (2013));
1229 38         209 my ($type, $range) = (lc $1, $2);
1230              
1231 38         113 my @h = $self->column_names ();
1232              
1233 38         60 my @c;
1234 38 100       101 if ($type eq "cell") {
1235 21         32 my @spec;
1236             my $min_row;
1237 21         35 my $max_row = 0;
1238 21         105 for (split m/\s*;\s*/ => $range) {
1239 37 100       225 my ($tlr, $tlc, $brr, $brc) = (m{
1240             ^ \s* ([0-9]+ ) \s* , \s* ([0-9]+ ) \s*
1241             (?: - \s* ([0-9]+ | \*) \s* , \s* ([0-9]+ | \*) \s* )?
1242             $}x) or croak ($self->SetDiag (2013));
1243 36 100       113 defined $brr or ($brr, $brc) = ($tlr, $tlc);
1244 36 100 100     323 $tlr == 0 || $tlc == 0 ||
      66        
      100        
      100        
      66        
      100        
      100        
1245             ($brr ne "*" && ($brr == 0 || $brr < $tlr)) ||
1246             ($brc ne "*" && ($brc == 0 || $brc < $tlc))
1247             and croak ($self->SetDiag (2013));
1248 28         69 $tlc--;
1249 28 100       56 $brc-- unless $brc eq "*";
1250 28 100       52 defined $min_row or $min_row = $tlr;
1251 28 100       53 $tlr < $min_row and $min_row = $tlr;
1252 28 100 100     85 $brr eq "*" || $brr > $max_row and
1253             $max_row = $brr;
1254 28         83 push @spec, [ $tlr, $tlc, $brr, $brc ];
1255             }
1256 12         22 my $r = 0;
1257 12         32 while (my $row = $self->getline ($io)) {
1258 77 100       247 ++$r < $min_row and next;
1259 33         54 my %row;
1260             my $lc;
1261 33         65 foreach my $s (@spec) {
1262 77         144 my ($tlr, $tlc, $brr, $brc) = @$s;
1263 77 100 100     264 $r < $tlr || ($brr ne "*" && $r > $brr) and next;
      100        
1264 45 100 100     113 !defined $lc || $tlc < $lc and $lc = $tlc;
1265 45 100       101 my $rr = $brc eq "*" ? $#$row : $brc;
1266 45         221 $row{$_} = $row->[$_] for $tlc .. $rr;
1267             }
1268 33         129 push @c, [ @row{sort { $a <=> $b } keys %row } ];
  66         185  
1269 33 100       161 if (@h) {
1270 2         5 my %h; @h{@h} = @{$c[-1]};
  2         3  
  2         8  
1271 2         6 $c[-1] = \%h;
1272             }
1273 33 100 100     179 $max_row ne "*" && $r == $max_row and last;
1274             }
1275 12         92 return \@c;
1276             }
1277              
1278             # row or col
1279 17         37 my @r;
1280 17         26 my $eod = 0;
1281 17         79 for (split m/\s*;\s*/ => $range) {
1282 25 50       149 my ($from, $to) = m/^\s* ([0-9]+) (?: \s* - \s* ([0-9]+ | \* ))? \s* $/x
1283             or croak ($self->SetDiag (2013));
1284 25   100     104 $to ||= $from;
1285 25 100       63 $to eq "*" and ($to, $eod) = ($from, 1);
1286             # $to cannot be <= 0 due to regex and ||=
1287 25 100 100     98 $from <= 0 || $to < $from and croak ($self->SetDiag (2013));
1288 22         90 $r[$_] = 1 for $from .. $to;
1289             }
1290              
1291 14         27 my $r = 0;
1292 14 100       35 $type eq "col" and shift @r;
1293 14   100     149 $_ ||= 0 for @r;
1294 14         48 while (my $row = $self->getline ($io)) {
1295 109         150 $r++;
1296 109 100       232 if ($type eq "row") {
1297 64 100 100     270 if (($r > $#r && $eod) || $r[$r]) {
      100        
1298 20         42 push @c, $row;
1299 20 100       43 if (@h) {
1300 3         6 my %h; @h{@h} = @{$c[-1]};
  3         7  
  3         13  
1301 3         7 $c[-1] = \%h;
1302             }
1303             }
1304 64         221 next;
1305             }
1306 45 100 100     115 push @c, [ map { ($_ > $#r && $eod) || $r[$_] ? $row->[$_] : () } 0..$#$row ];
  405         1446  
1307 45 100       190 if (@h) {
1308 9         12 my %h; @h{@h} = @{$c[-1]};
  9         12  
  9         26  
1309 9         38 $c[-1] = \%h;
1310             }
1311             }
1312              
1313 14         99 return \@c;
1314             }
1315              
1316             my $csv_usage = q{usage: my $aoa = csv (in => $file);};
1317              
1318             sub _csv_attr {
1319 324 100 66 324   1770 my %attr = (@_ == 1 && ref $_[0] eq "HASH" ? %{$_[0]} : @_) or croak;
  4 50       20  
1320              
1321 324         677 $attr{binary} = 1;
1322              
1323 324   100     1416 my $enc = delete $attr{enc} || delete $attr{encoding} || "";
1324 324 100       759 $enc eq "auto" and ($attr{detect_bom}, $enc) = (1, "");
1325 324 50       841 my $stack = $enc =~ s/(:\w.*)// ? $1 : "";
1326 324 100       699 $enc =~ m/^[-\w.]+$/ and $enc = ":encoding($enc)";
1327 324         507 $enc .= $stack;
1328              
1329 324         416 my $fh;
1330 324         442 my $sink = 0;
1331 324         464 my $cls = 0; # If I open a file, I have to close it
1332 324 100 100     1511 my $in = delete $attr{in} || delete $attr{file} or croak $csv_usage;
1333             my $out = exists $attr{out} && !$attr{out} ? \"skip"
1334 321 50 66     1374 : delete $attr{out} || delete $attr{file};
      100        
1335              
1336 321 100 100     1163 ref $in eq "CODE" || ref $in eq "ARRAY" and $out ||= \*STDOUT;
      100        
1337              
1338 321 100 66     1420 $in && $out && !ref $in && !ref $out and croak join "\n" =>
      100        
      100        
1339             qq{Cannot use a string for both in and out. Instead use:},
1340             qq{ csv (in => csv (in => "$in"), out => "$out");\n};
1341              
1342 320 100       641 if ($out) {
1343 32 100 100     306 if (ref $out and ("ARRAY" eq ref $out or "HASH" eq ref $out)) {
    100 100        
    100 100        
      100        
      66        
      66        
      66        
1344 5         9 delete $attr{out};
1345 5         8 $sink = 1;
1346             }
1347             elsif ((ref $out and "SCALAR" ne ref $out) or "GLOB" eq ref \$out) {
1348 14         26 $fh = $out;
1349             }
1350             elsif (ref $out and "SCALAR" eq ref $out and defined $$out and $$out eq "skip") {
1351 1         16 delete $attr{out};
1352 1         3 $sink = 1;
1353             }
1354             else {
1355 12 100       727 open $fh, ">", $out or croak "$out: $!";
1356 11         43 $cls = 1;
1357             }
1358 31 100       74 if ($fh) {
1359 25 100       57 if ($enc) {
1360 1         14 binmode $fh, $enc;
1361 1         80 my $fn = fileno $fh; # This is a workaround for a bug in PerlIO::via::gzip
1362             }
1363 25 100       72 unless (defined $attr{eol}) {
1364 18         36 my @layers = eval { PerlIO::get_layers ($fh) };
  18         129  
1365 18 100       124 $attr{eol} = (grep m/crlf/ => @layers) ? "\n" : "\r\n";
1366             }
1367             }
1368             }
1369              
1370 319 100 100     1774 if ( ref $in eq "CODE" or ref $in eq "ARRAY") {
    100 100        
    100          
1371             # All done
1372             }
1373             elsif (ref $in eq "SCALAR") {
1374             # Strings with code points over 0xFF may not be mapped into in-memory file handles
1375             # "<$enc" does not change that :(
1376 25 50       377 open $fh, "<", $in or croak "Cannot open from SCALAR using PerlIO";
1377 25         1835 $cls = 1;
1378             }
1379             elsif (ref $in or "GLOB" eq ref \$in) {
1380 16 50 66     45 if (!ref $in && $] < 5.008005) {
1381 0         0 $fh = \*$in; # uncoverable statement ancient perl version required
1382             }
1383             else {
1384 16         28 $fh = $in;
1385             }
1386             }
1387             else {
1388 254 100       10742 open $fh, "<$enc", $in or croak "$in: $!";
1389 252         17460 $cls = 1;
1390             }
1391 317 50 33     911 $fh || $sink or croak qq{No valid source passed. "in" is required};
1392              
1393 317         697 my $hdrs = delete $attr{headers};
1394 317         597 my $frag = delete $attr{fragment};
1395 317         508 my $key = delete $attr{key};
1396 317         560 my $val = delete $attr{value};
1397             my $kh = delete $attr{keep_headers} ||
1398             delete $attr{keep_column_names} ||
1399 317   100     1462 delete $attr{kh};
1400              
1401             my $cbai = delete $attr{callbacks}{after_in} ||
1402             delete $attr{after_in} ||
1403             delete $attr{callbacks}{after_parse} ||
1404 317   100     2043 delete $attr{after_parse};
1405             my $cbbo = delete $attr{callbacks}{before_out} ||
1406 317   100     1015 delete $attr{before_out};
1407             my $cboi = delete $attr{callbacks}{on_in} ||
1408 317   100     864 delete $attr{on_in};
1409              
1410             my $hd_s = delete $attr{sep_set} ||
1411 317   100     844 delete $attr{seps};
1412             my $hd_b = delete $attr{detect_bom} ||
1413 317   100     866 delete $attr{bom};
1414             my $hd_m = delete $attr{munge} ||
1415 317   100     912 delete $attr{munge_column_names};
1416 317         469 my $hd_c = delete $attr{set_column_names};
1417              
1418 317         1268 for ([ quo => "quote" ],
1419             [ esc => "escape" ],
1420             [ escape => "escape_char" ],
1421             ) {
1422 951         1598 my ($f, $t) = @$_;
1423 951 100 100     2354 exists $attr{$f} and !exists $attr{$t} and $attr{$t} = delete $attr{$f};
1424             }
1425              
1426 317         704 my $fltr = delete $attr{filter};
1427             my %fltr = (
1428 10 100 33 10   14 not_blank => sub { @{$_[1]} > 1 or defined $_[1][0] && $_[1][0] ne "" },
  10         49  
1429 10 50   10   15 not_empty => sub { grep { defined && $_ ne "" } @{$_[1]} },
  26         104  
  10         21  
1430 10 50   10   13 filled => sub { grep { defined && m/\S/ } @{$_[1]} },
  26         113  
  10         20  
1431 317         2439 );
1432             defined $fltr && !ref $fltr && exists $fltr{$fltr} and
1433 317 50 100     848 $fltr = { 0 => $fltr{$fltr} };
      66        
1434 317 100       717 ref $fltr eq "CODE" and $fltr = { 0 => $fltr };
1435 317 100       745 ref $fltr eq "HASH" or $fltr = undef;
1436              
1437 317         444 my $form = delete $attr{formula};
1438              
1439 317 100       760 defined $attr{auto_diag} or $attr{auto_diag} = 1;
1440 317 100       786 defined $attr{escape_null} or $attr{escape_null} = 0;
1441 317 50 66     1727 my $csv = delete $attr{csv} || Text::CSV_PP->new (\%attr)
1442             or croak $last_new_error;
1443 317 100       676 defined $form and $csv->formula ($form);
1444              
1445 317 100 100     760 $kh && !ref $kh && $kh =~ m/^(?:1|yes|true|internal|auto)$/i and
      100        
1446             $kh = \@internal_kh;
1447              
1448             return {
1449 317         5936 csv => $csv,
1450             attr => { %attr },
1451             fh => $fh,
1452             cls => $cls,
1453             in => $in,
1454             sink => $sink,
1455             out => $out,
1456             enc => $enc,
1457             hdrs => $hdrs,
1458             key => $key,
1459             val => $val,
1460             kh => $kh,
1461             frag => $frag,
1462             fltr => $fltr,
1463             cbai => $cbai,
1464             cbbo => $cbbo,
1465             cboi => $cboi,
1466             hd_s => $hd_s,
1467             hd_b => $hd_b,
1468             hd_m => $hd_m,
1469             hd_c => $hd_c,
1470             };
1471             }
1472              
1473             sub csv {
1474 325 50 33 325 1 1610 @_ && (ref $_[0] eq __PACKAGE__ or ref $_[0] eq 'Text::CSV') and splice @_, 0, 0, "csv";
      66        
1475 325 100       770 @_ or croak $csv_usage;
1476              
1477 324         752 my $c = _csv_attr (@_);
1478              
1479 317         628 my ($csv, $in, $fh, $hdrs) = @{$c}{qw( csv in fh hdrs )};
  317         899  
1480 317         520 my %hdr;
1481 317 100       716 if (ref $hdrs eq "HASH") {
1482 2         8 %hdr = %$hdrs;
1483 2         5 $hdrs = "auto";
1484             }
1485              
1486 317 100 100     803 if ($c->{out} && !$c->{sink}) {
1487             !$hdrs && ref $c->{'kh'} && $c->{'kh'} == \@internal_kh and
1488 24 100 100     101 $hdrs = $c->{'kh'};
      66        
1489              
1490 24 100 100     64 if (ref $in eq "CODE") {
    100          
1491 3         5 my $hdr = 1;
1492 3         12 while (my $row = $in->($csv)) {
1493 7 100       60 if (ref $row eq "ARRAY") {
1494 3         9 $csv->print ($fh, $row);
1495 3         35 next;
1496             }
1497 4 50       12 if (ref $row eq "HASH") {
1498 4 100       9 if ($hdr) {
1499 2 50 100     8 $hdrs ||= [ map { $hdr{$_} || $_ } keys %$row ];
  3         13  
1500 2         7 $csv->print ($fh, $hdrs);
1501 2         30 $hdr = 0;
1502             }
1503 4         9 $csv->print ($fh, [ @{$row}{@$hdrs} ]);
  4         14  
1504             }
1505             }
1506             }
1507 21         98 elsif (@{$in} == 0 or ref $in->[0] eq "ARRAY") { # aoa
1508 10 50       29 ref $hdrs and $csv->print ($fh, $hdrs);
1509 10         14 for (@{$in}) {
  10         25  
1510 12 100       86 $c->{cboi} and $c->{cboi}->($csv, $_);
1511 12 50       1079 $c->{cbbo} and $c->{cbbo}->($csv, $_);
1512 12         36 $csv->print ($fh, $_);
1513             }
1514             }
1515             else { # aoh
1516 11 100       26 my @hdrs = ref $hdrs ? @{$hdrs} : keys %{$in->[0]};
  5         15  
  6         23  
1517 11 100       26 defined $hdrs or $hdrs = "auto";
1518             ref $hdrs || $hdrs eq "auto" and @hdrs and
1519 11 100 100     63 $csv->print ($fh, [ map { $hdr{$_} || $_ } @hdrs ]);
  20 100 66     92  
1520 11         153 for (@{$in}) {
  11         29  
1521 17         86 local %_;
1522 17         35 *_ = $_;
1523 17 50       42 $c->{cboi} and $c->{cboi}->($csv, $_);
1524 17 50       32 $c->{cbbo} and $c->{cbbo}->($csv, $_);
1525 17         31 $csv->print ($fh, [ @{$_}{@hdrs} ]);
  17         74  
1526             }
1527             }
1528              
1529 24 100       878 $c->{cls} and close $fh;
1530 24         376 return 1;
1531             }
1532              
1533 293         413 my @row1;
1534 293 100 100     1539 if (defined $c->{hd_s} || defined $c->{hd_b} || defined $c->{hd_m} || defined $c->{hd_c}) {
      100        
      100        
1535 174         265 my %harg;
1536             !defined $c->{'hd_s'} && $c->{'attr'}{'sep_char'} and
1537 174 100 100     645 $c->{'hd_s'} = [ $c->{'attr'}{'sep_char'} ];
1538             !defined $c->{'hd_s'} && $c->{'attr'}{'sep'} and
1539 174 100 100     586 $c->{'hd_s'} = [ $c->{'attr'}{'sep'} ];
1540 174 100       336 defined $c->{'hd_s'} and $harg{'sep_set'} = $c->{'hd_s'};
1541 174 100       442 defined $c->{'hd_b'} and $harg{'detect_bom'} = $c->{'hd_b'};
1542 174 50       357 defined $c->{'hd_m'} and $harg{'munge_column_names'} = $hdrs ? "none" : $c->{'hd_m'};
    100          
1543 174 50       358 defined $c->{'hd_c'} and $harg{'set_column_names'} = $hdrs ? 0 : $c->{'hd_c'};
    100          
1544 174         484 @row1 = $csv->header ($fh, \%harg);
1545 171         400 my @hdr = $csv->column_names;
1546 171 100 100     848 @hdr and $hdrs ||= \@hdr;
1547             }
1548              
1549 290 100       663 if ($c->{kh}) {
1550 15         28 @internal_kh = ();
1551 15 100       42 ref $c->{kh} eq "ARRAY" or croak ($csv->SetDiag (1501));
1552 10   100     29 $hdrs ||= "auto";
1553             }
1554              
1555 285         449 my $key = $c->{key};
1556 285 100       579 if ($key) {
1557 27 100 100     119 !ref $key or ref $key eq "ARRAY" && @$key > 1 or croak ($csv->SetDiag (1501));
      100        
1558 20   100     60 $hdrs ||= "auto";
1559             }
1560 278         430 my $val = $c->{val};
1561 278 100       514 if ($val) {
1562 9 100       23 $key or croak ($csv->SetDiag (1502));
1563 8 100 100     86 !ref $val or ref $val eq "ARRAY" && @$val > 0 or croak ($csv->SetDiag (1503));
      100        
1564             }
1565              
1566 274 100 100     616 $c->{fltr} && grep m/\D/ => keys %{$c->{fltr}} and $hdrs ||= "auto";
  16   100     115  
1567 274 100       699 if (defined $hdrs) {
1568 220 100 100     891 if (!ref $hdrs or ref $hdrs eq "CODE") {
1569 48 100       155 my $h = $c->{'hd_b'}
1570             ? [ $csv->column_names () ]
1571             : $csv->getline ($fh);
1572 48   33     158 my $has_h = $h && @$h;
1573              
1574 48 100       204 if (ref $hdrs) {
    100          
    100          
    100          
    50          
1575 1 50       5 $has_h or return;
1576 1         2 my $cr = $hdrs;
1577 1   33     2 $hdrs = [ map { $cr->($hdr{$_} || $_) } @{$h} ];
  3         20  
  1         3  
1578             }
1579             elsif ($hdrs eq "skip") {
1580             # discard;
1581             }
1582             elsif ($hdrs eq "auto") {
1583 44 50       99 $has_h or return;
1584 44 100       101 $hdrs = [ map { $hdr{$_} || $_ } @$h ];
  128         498  
1585             }
1586             elsif ($hdrs eq "lc") {
1587 1 50       4 $has_h or return;
1588 1   33     3 $hdrs = [ map { lc ($hdr{$_} || $_) } @$h ];
  3         14  
1589             }
1590             elsif ($hdrs eq "uc") {
1591 1 50       5 $has_h or return;
1592 1   33     3 $hdrs = [ map { uc ($hdr{$_} || $_) } @$h ];
  3         17  
1593             }
1594             }
1595 220 100 66     619 $c->{kh} and $hdrs and @{$c->{kh}} = @$hdrs;
  10         27  
1596             }
1597              
1598 274 100       574 if ($c->{fltr}) {
1599 16         22 my %f = %{$c->{fltr}};
  16         46  
1600             # convert headers to index
1601 16         30 my @hdr;
1602 16 100       35 if (ref $hdrs) {
1603 7         10 @hdr = @{$hdrs};
  7         20  
1604 7         22 for (0 .. $#hdr) {
1605 21 100       58 exists $f{$hdr[$_]} and $f{$_ + 1} = delete $f{$hdr[$_]};
1606             }
1607             }
1608             $csv->callbacks (after_parse => sub {
1609 114     114   197 my ($CSV, $ROW) = @_; # lexical sub-variables in caps
1610 114         367 foreach my $FLD (sort keys %f) {
1611 115         314 local $_ = $ROW->[$FLD - 1];
1612 115         183 local %_;
1613 115 100       329 @hdr and @_{@hdr} = @$ROW;
1614 115 100       308 $f{$FLD}->($CSV, $ROW) or return \"skip";
1615 52         389 $ROW->[$FLD - 1] = $_;
1616             }
1617 16         92 });
1618             }
1619              
1620 274         408 my $frag = $c->{frag};
1621             my $ref = ref $hdrs
1622             ? # aoh
1623 274 100       721 do {
    100          
1624 219         431 my @h = $csv->column_names ($hdrs);
1625 219         330 my %h; $h{$_}++ for @h;
  219         741  
1626 219 50       468 exists $h{''} and croak ($csv->SetDiag (1012));
1627 219 50       494 unless (keys %h == @h) {
1628             croak ($csv->_SetDiagInfo (1013, join ", " =>
1629 0         0 map { "$_ ($h{$_})" } grep { $h{$_} > 1 } keys %h));
  0         0  
  0         0  
1630             }
1631             $frag ? $csv->fragment ($fh, $frag) :
1632 219 100       775 $key ? do {
    100          
1633 17 100       57 my ($k, $j, @f) = ref $key ? (undef, @$key) : ($key);
1634 17 100       43 if (my @mk = grep { !exists $h{$_} } grep { defined } $k, @f) {
  22         72  
  27         58  
1635 2         10 croak ($csv->_SetDiagInfo (4001, join ", " => @mk));
1636             }
1637             +{ map {
1638 26         44 my $r = $_;
1639 26 100       62 my $K = defined $k ? $r->{$k} : join $j => @{$r}{@f};
  4         11  
1640             ( $K => (
1641             $val
1642             ? ref $val
1643 4         21 ? { map { $_ => $r->{$_} } @$val }
1644 26 100       110 : $r->{$val}
    100          
1645             : $r ));
1646 15         26 } @{$csv->getline_hr_all ($fh)} }
  15         37  
1647             }
1648             : $csv->getline_hr_all ($fh);
1649             }
1650             : # aoa
1651             $frag ? $csv->fragment ($fh, $frag)
1652             : $csv->getline_all ($fh);
1653 266 50       583 if ($ref) {
1654 266 100 66     1294 @row1 && !$c->{hd_c} && !ref $hdrs and unshift @$ref, \@row1;
      100        
1655             }
1656             else {
1657 0         0 Text::CSV_PP->auto_diag;
1658             }
1659 266 100       3795 $c->{cls} and close $fh;
1660 266 100 100     1696 if ($ref and $c->{cbai} || $c->{cboi}) {
      66        
1661             # Default is ARRAYref, but with key =>, you'll get a hashref
1662 22 100       67 foreach my $r (ref $ref eq "ARRAY" ? @{$ref} : values %{$ref}) {
  21         56  
  1         5  
1663 71         6971 local %_;
1664 71 100       167 ref $r eq "HASH" and *_ = $r;
1665 71 100       181 $c->{cbai} and $c->{cbai}->($csv, $r);
1666 71 100       4272 $c->{cboi} and $c->{cboi}->($csv, $r);
1667             }
1668             }
1669              
1670 266 100       1952 if ($c->{sink}) {
1671 6 50       25 my $ro = ref $c->{out} or return;
1672              
1673 6 100 66     25 $ro eq "SCALAR" && ${$c->{out}} eq "skip" and
  1         18  
1674             return;
1675              
1676 5 50       14 $ro eq ref $ref or
1677             croak ($csv->_SetDiagInfo (5001, "Output type mismatch"));
1678              
1679 5 100       15 if ($ro eq "ARRAY") {
1680 4 100 33     5 if (@{$c->{out}} and @$ref and ref $c->{out}[0] eq ref $ref->[0]) {
  4   66     35  
1681 2         4 push @{$c->{out}} => @$ref;
  2         7  
1682 2         32 return $c->{out};
1683             }
1684 2         10 croak ($csv->_SetDiagInfo (5001, "Output type mismatch"));
1685             }
1686              
1687 1 50       5 if ($ro eq "HASH") {
1688 1         3 @{$c->{out}}{keys %{$ref}} = values %{$ref};
  1         4  
  1         2  
  1         3  
1689 1         16 return $c->{out};
1690             }
1691              
1692 0         0 croak ($csv->_SetDiagInfo (5002, "Unsupported output type"));
1693             }
1694              
1695             defined wantarray or
1696             return csv (
1697             in => $ref,
1698             headers => $hdrs,
1699 260 100       582 %{$c->{attr}},
  1         19  
1700             );
1701              
1702 259         4996 return $ref;
1703             }
1704              
1705             # The end of the common pure perl part.
1706              
1707             ################################################################################
1708             #
1709             # The following are methods implemented in XS in Text::CSV_XS or
1710             # helper methods for Text::CSV_PP only
1711             #
1712             ################################################################################
1713              
1714             sub _setup_ctx {
1715 28022     28022   43967 my $self = shift;
1716              
1717 28022         39067 $last_error = undef;
1718              
1719 28022         38396 my $ctx;
1720 28022 100       61935 if ($self->{_CACHE}) {
1721 27179         37223 %$ctx = %{$self->{_CACHE}};
  27179         398142  
1722             } else {
1723 843         1984 $ctx->{sep} = ',';
1724 843 50       1961 if (defined $self->{sep_char}) {
1725 843         1617 $ctx->{sep} = $self->{sep_char};
1726             }
1727 843 100 100     2474 if (defined $self->{sep} and $self->{sep} ne '') {
1728 37     37   24171 use bytes;
  37         590  
  37         237  
1729 5         11 $ctx->{sep} = $self->{sep};
1730 5         10 my $sep_len = length($ctx->{sep});
1731 5 50       16 $ctx->{sep_len} = $sep_len if $sep_len > 1;
1732             }
1733              
1734 843         1535 $ctx->{quo} = '"';
1735 843 50       1787 if (exists $self->{quote_char}) {
1736 843         1380 my $quote_char = $self->{quote_char};
1737 843 100 66     2900 if (defined $quote_char and length $quote_char) {
1738 839         1638 $ctx->{quo} = $quote_char;
1739             } else {
1740 4         13 $ctx->{quo} = "\0";
1741             }
1742             }
1743 843 100 100     2022 if (defined $self->{quote} and $self->{quote} ne '') {
1744 37     37   4596 use bytes;
  37         94  
  37         132  
1745 4         9 $ctx->{quo} = $self->{quote};
1746 4         8 my $quote_len = length($ctx->{quo});
1747 4 50       11 $ctx->{quo_len} = $quote_len if $quote_len > 1;
1748             }
1749              
1750 843         1504 $ctx->{escape_char} = '"';
1751 843 50       1663 if (exists $self->{escape_char}) {
1752 843         1352 my $escape_char = $self->{escape_char};
1753 843 100 100     2648 if (defined $escape_char and length $escape_char) {
1754 835         1585 $ctx->{escape_char} = $escape_char;
1755             } else {
1756 8         23 $ctx->{escape_char} = "\0";
1757             }
1758             }
1759              
1760 843 100       1709 if (defined $self->{eol}) {
1761 839         1365 my $eol = $self->{eol};
1762 839         1236 my $eol_len = length($eol);
1763 839         1317 $ctx->{eol} = $eol;
1764 839         1314 $ctx->{eol_len} = $eol_len;
1765 839 100 100     2232 if ($eol_len == 1 and $eol eq "\015") {
1766 42         82 $ctx->{eol_is_cr} = 1;
1767             }
1768             }
1769              
1770 843         1411 $ctx->{undef_flg} = 0;
1771 843 100       1623 if (defined $self->{undef_str}) {
1772 1         2 $ctx->{undef_str} = $self->{undef_str};
1773 1 50       14 $ctx->{undef_flg} = 3 if utf8::is_utf8($self->{undef_str});
1774             } else {
1775 842         1411 $ctx->{undef_str} = undef;
1776             }
1777 843 100       1731 if (defined $self->{comment_str}) {
1778 12         37 $ctx->{comment_str} = $self->{comment_str};
1779             }
1780              
1781 843 100       1714 if (defined $self->{_types}) {
1782 1         6 $ctx->{types} = $self->{_types};
1783 1         3 $ctx->{types_len} = length($ctx->{types});
1784             }
1785              
1786 843 100       1664 if (defined $self->{_is_bound}) {
1787 4         17 $ctx->{is_bound} = $self->{_is_bound};
1788             }
1789              
1790 843 100       1667 if (defined $self->{callbacks}) {
1791 301         469 my $cb = $self->{callbacks};
1792 301         722 $ctx->{has_hooks} = 0;
1793 301 100 66     738 if (defined $cb->{after_parse} and ref $cb->{after_parse} eq 'CODE') {
1794 9         17 $ctx->{has_hooks} |= HOOK_AFTER_PARSE;
1795             }
1796 301 100 66     708 if (defined $cb->{before_print} and ref $cb->{before_print} eq 'CODE') {
1797 1         4 $ctx->{has_hooks} |= HOOK_BEFORE_PRINT;
1798             }
1799             }
1800              
1801 843         1946 for (qw/
1802             binary decode_utf8 always_quote strict quote_empty
1803             allow_loose_quotes allow_loose_escapes
1804             allow_unquoted_escape allow_whitespace blank_is_undef
1805             empty_is_undef verbatim auto_diag diag_verbose
1806             keep_meta_info formula skip_empty_rows
1807             /) {
1808 14331 50       31331 $ctx->{$_} = defined $self->{$_} ? $self->{$_} : 0;
1809             }
1810 843         1520 for (qw/quote_space escape_null quote_binary/) {
1811 2529 50       5687 $ctx->{$_} = defined $self->{$_} ? $self->{$_} : 1;
1812             }
1813 843 100       2030 if ($ctx->{escape_char} eq "\0") {
1814 8         29 $ctx->{escape_null} = 0;
1815             }
1816              
1817             # FIXME: readonly
1818 843         4105 %{$self->{_CACHE}} = %$ctx;
  843         6846  
1819             }
1820              
1821 28022         89293 $ctx->{utf8} = 0;
1822 28022         47982 $ctx->{size} = 0;
1823 28022         42870 $ctx->{used} = 0;
1824              
1825 28022 100       61462 if ($ctx->{is_bound}) {
1826 89         146 my $bound = $self->{_BOUND_COLUMNS};
1827 89 100 66     379 if ($bound and ref $bound eq 'ARRAY') {
1828 75         175 $ctx->{bound} = $bound;
1829             } else {
1830 14         28 $ctx->{is_bound} = 0;
1831             }
1832             }
1833              
1834 28022         43730 $ctx->{eol_pos} = -1;
1835             $ctx->{eolx} = $ctx->{eol_len}
1836             ? $ctx->{verbatim} || $ctx->{eol_len} >= 2
1837             ? 1
1838 28022 100 100     88319 : $ctx->{eol} =~ /\A[\015\012]/ ? 0 : 1
    100          
    100          
1839             : 0;
1840              
1841 28022 100 66     61884 if ($ctx->{sep_len} and $ctx->{sep_len} > 1 and _is_valid_utf8($ctx->{sep})) {
      100        
1842 14         27 $ctx->{utf8} = 1;
1843             }
1844 28022 50 66     53855 if ($ctx->{quo_len} and $ctx->{quo_len} > 1 and _is_valid_utf8($ctx->{quo})) {
      66        
1845 0         0 $ctx->{utf8} = 1;
1846             }
1847              
1848 28022         50608 $ctx;
1849             }
1850              
1851             sub _cache_set {
1852 23579     23579   40282 my ($self, $idx, $value) = @_;
1853 23579 100       44567 return unless exists $self->{_CACHE};
1854 22589         30466 my $cache = $self->{_CACHE};
1855              
1856 22589         38616 my $key = $_reverse_cache_id{$idx};
1857 22589 100       89994 if (!defined $key) {
    100          
    100          
    100          
    100          
    100          
    100          
    100          
    100          
    100          
1858 1         13 warn (sprintf "Unknown cache index %d ignored\n", $idx);
1859             } elsif ($key eq 'sep_char') {
1860 3122         5016 $cache->{sep} = $value;
1861 3122         4949 $cache->{sep_len} = 0;
1862             }
1863             elsif ($key eq 'quote_char') {
1864 3369         5356 $cache->{quo} = $value;
1865 3369         5240 $cache->{quo_len} = 0;
1866             }
1867             elsif ($key eq '_has_ahead') {
1868 251         507 $cache->{has_ahead} = $value;
1869             }
1870             elsif ($key eq '_has_hooks') {
1871 11         24 $cache->{has_hooks} = $value;
1872             }
1873             elsif ($key eq '_is_bound') {
1874 11         34 $cache->{is_bound} = $value;
1875             }
1876             elsif ($key eq 'sep') {
1877 37     37   30986 use bytes;
  37         108  
  37         364  
1878 3223         7285 my $len = bytes::length($value);
1879 3223 100       16620 $cache->{sep} = $value if $len;
1880 3223 50       6430 $cache->{sep_len} = $len == 1 ? 0 : $len;
1881             }
1882             elsif ($key eq 'quote') {
1883 37     37   2771 use bytes;
  37         100  
  37         170  
1884 3377         9077 my $len = bytes::length($value);
1885 3377 100       13175 $cache->{quo} = $value if $len;
1886 3377 50       7138 $cache->{quo_len} = $len == 1 ? 0 : $len;
1887             }
1888             elsif ($key eq 'eol') {
1889 112 50       230 if (defined($value)) {
1890 112         211 $cache->{eol} = $value;
1891 112         193 $cache->{eol_len} = length($value);
1892             }
1893 112 100       270 $cache->{eol_is_cr} = $value eq "\015" ? 1 : 0;
1894             }
1895             elsif ($key eq 'undef_str') {
1896 11 100       20 if (defined $value) {
1897 9         19 $cache->{undef_str} = $value;
1898 9 100       26 $cache->{undef_flg} = 3 if utf8::is_utf8($value);
1899             } else {
1900 2         11 $cache->{undef_str} = undef;
1901 2         5 $cache->{undef_flg} = 0;
1902             }
1903             }
1904             else {
1905 9101         13754 $cache->{$key} = $value;
1906             }
1907 22589         36607 return 1;
1908             }
1909              
1910             sub _cache_diag {
1911 2     2   6 my $self = shift;
1912 2 100       8 unless (exists $self->{_CACHE}) {
1913 1         8 warn ("CACHE: invalid\n");
1914 1         8 return;
1915             }
1916              
1917 1         3 my $cache = $self->{_CACHE};
1918 1         53 warn ("CACHE:\n");
1919 1         15 $self->__cache_show_char(quote_char => $cache->{quo});
1920 1         8 $self->__cache_show_char(escape_char => $cache->{escape_char});
1921 1         8 $self->__cache_show_char(sep_char => $cache->{sep});
1922 1         6 for (qw/
1923             binary decode_utf8 allow_loose_escapes allow_loose_quotes allow_unquoted_escape
1924             allow_whitespace always_quote quote_empty quote_space
1925             escape_null quote_binary auto_diag diag_verbose formula strict skip_empty_rows
1926             has_error_input blank_is_undef empty_is_undef has_ahead
1927             keep_meta_info verbatim has_hooks eol_is_cr eol_len
1928             /) {
1929 25         110 $self->__cache_show_byte($_ => $cache->{$_});
1930             }
1931 1         24 $self->__cache_show_str(eol => $cache->{eol_len}, $cache->{eol});
1932 1         7 $self->__cache_show_byte(sep_len => $cache->{sep_len});
1933 1 50 33     15 if ($cache->{sep_len} and $cache->{sep_len} > 1) {
1934 1         4 $self->__cache_show_str(sep => $cache->{sep_len}, $cache->{sep});
1935             }
1936 1         11 $self->__cache_show_byte(quo_len => $cache->{quo_len});
1937 1 50 33     12 if ($cache->{quo_len} and $cache->{quo_len} > 1) {
1938 1         12 $self->__cache_show_str(quote => $cache->{quo_len}, $cache->{quo});
1939             }
1940 1 50       7 if ($cache->{types_len}) {
1941 0         0 $self->__cache_show_str(types => $cache->{types_len}, $cache->{types});
1942             } else {
1943 1         5 $self->__cache_show_str(types => 0, "");
1944             }
1945 1 50       7 if ($cache->{bptr}) {
1946 0         0 $self->__cache_show_str(bptr => length($cache->{bptr}), $cache->{bptr});
1947             }
1948 1 50       6 if ($cache->{tmp}) {
1949 1         4 $self->__cache_show_str(tmp => length($cache->{tmp}), $cache->{tmp});
1950             }
1951             }
1952              
1953             sub __cache_show_byte {
1954 27     27   56 my ($self, $key, $value) = @_;
1955 27 100       408 warn (sprintf " %-21s %02x:%3d\n", $key, defined $value ? ord($value) : 0, defined $value ? $value : 0);
    100          
1956             }
1957              
1958             sub __cache_show_char {
1959 3     3   10 my ($self, $key, $value) = @_;
1960 3         7 my $v = $value;
1961 3 50       9 if (defined $value) {
1962 3         11 my @b = unpack "U0C*", $value;
1963 3         15 $v = pack "U*", $b[0];
1964             }
1965 3 50       17 warn (sprintf " %-21s %02x:%s\n", $key, defined $v ? ord($v) : 0, $self->__pretty_str($v, 1));
1966             }
1967              
1968             sub __cache_show_str {
1969 5     5   15 my ($self, $key, $len, $value) = @_;
1970 5         13 warn (sprintf " %-21s %02d:%s\n", $key, $len, $self->__pretty_str($value, $len));
1971             }
1972              
1973             sub __pretty_str { # FIXME
1974 8     8   50 my ($self, $str, $len) = @_;
1975 8 50       16 return '' unless defined $str;
1976 8         19 $str = substr($str, 0, $len);
1977 8         21 $str =~ s/"/\\"/g;
1978 8         17 $str =~ s/([^\x09\x20-\x7e])/sprintf '\\x{%x}', ord($1)/eg;
  0         0  
1979 8         150 qq{"$str"};
1980             }
1981              
1982             sub _hook {
1983 20406     20406   37816 my ($self, $name, $fields) = @_;
1984 20406 100       63006 return 0 unless $self->{callbacks};
1985              
1986 173         293 my $cb = $self->{callbacks}{$name};
1987 173 100 66     581 return 0 unless $cb && ref $cb eq 'CODE';
1988              
1989 125         260 my (@res) = $cb->($self, $fields);
1990 125 50       650 if (@res) {
1991 125 100 66     301 return 0 if ref $res[0] eq 'SCALAR' and ${$res[0]} eq "skip";
  64         268  
1992             }
1993 61         154 scalar @res;
1994             }
1995              
1996             ################################################################################
1997             # methods for combine
1998             ################################################################################
1999              
2000             sub __combine {
2001 21682     21682   40397 my ($self, $dst, $fields, $useIO) = @_;
2002              
2003 21682         47566 my $ctx = $self->_setup_ctx;
2004              
2005 21682         34488 my ($binary, $quot, $sep, $esc, $quote_space) = @{$ctx}{qw/binary quo sep escape_char quote_space/};
  21682         59886  
2006              
2007 21682 100 100     100985 if(!defined $quot or $quot eq "\0"){ $quot = ''; }
  2         6  
2008              
2009 21682         31490 my $re_esc;
2010 21682 100 66     72995 if ($esc ne '' and $esc ne "\0") {
2011 21680 100       36578 if ($quot ne '') {
2012 21678   66     65561 $re_esc = $self->{_re_comb_escape}->{$quot}->{$esc} ||= qr/(\Q$quot\E|\Q$esc\E)/;
2013             } else {
2014 2   33     69 $re_esc = $self->{_re_comb_escape}->{$quot}->{$esc} ||= qr/(\Q$esc\E)/;
2015             }
2016             }
2017              
2018 21682         30773 my $bound = 0;
2019 21682         34704 my $n = @$fields - 1;
2020 21682 100 100     43579 if ($n < 0 and $ctx->{is_bound}) {
2021 5         10 $n = $ctx->{is_bound} - 1;
2022 5         8 $bound = 1;
2023             }
2024              
2025 21682 100 66     53228 my $check_meta = ($ctx->{keep_meta_info} >= 10 and @{$self->{_FFLAGS} || []} >= $n) ? 1 : 0;
2026              
2027 21682         32191 my $must_be_quoted;
2028             my @results;
2029 21682         49091 for(my $i = 0; $i <= $n; $i++) {
2030 53903         74567 my $v_ref;
2031 53903 100       83461 if ($bound) {
2032 14         47 $v_ref = $self->__bound_field($ctx, $i, 1);
2033             } else {
2034 53889 50       99840 if (@$fields > $i) {
2035 53889         97162 $v_ref = \($fields->[$i]);
2036             }
2037             }
2038 53903 50       102767 next unless $v_ref;
2039              
2040 53903         81552 my $value = $$v_ref;
2041              
2042 53903 100       89290 if (!defined $value) {
2043 56 100       148 if ($ctx->{undef_str}) {
2044 8 100       16 if ($ctx->{undef_flg}) {
2045 3         9 $ctx->{utf8} = 1;
2046 3         4 $ctx->{binary} = 1;
2047             }
2048 8         16 push @results, $ctx->{undef_str};
2049             } else {
2050 48         96 push @results, '';
2051             }
2052 56         130 next;
2053             }
2054              
2055 53847 100 100     2473463 if ( substr($value, 0, 1) eq '=' && $ctx->{formula} ) {
2056 10         24 $value = $self->_formula($ctx, $value, $i);
2057 6 100       15 if (!defined $value) {
2058 2         3 push @results, '';
2059 2         7 next;
2060             }
2061             }
2062              
2063 53841 100       102305 $must_be_quoted = $ctx->{always_quote} ? 1 : 0;
2064 53841 100       88812 if ($value eq '') {
2065 1406 100 100     4512 $must_be_quoted++ if $ctx->{quote_empty} or ($check_meta && $self->is_quoted($i));
      100        
2066             }
2067             else {
2068              
2069 52435 100       122572 if (utf8::is_utf8 $value) {
2070 20041         30334 $ctx->{utf8} = 1;
2071 20041         27095 $ctx->{binary} = 1;
2072             }
2073              
2074 52435 100 100     101302 $must_be_quoted++ if $check_meta && $self->is_quoted($i);
2075              
2076 52435 100 100     146196 if (!$must_be_quoted and $quot ne '') {
2077 37     37   51508 use bytes;
  37         85  
  37         167  
2078             $must_be_quoted++ if
2079             ($value =~ /\Q$quot\E/) ||
2080             ($sep ne '' and $sep ne "\0" and $value =~ /\Q$sep\E/) ||
2081             ($esc ne '' and $esc ne "\0" and $value =~ /\Q$esc\E/) ||
2082             ($ctx->{quote_binary} && $value =~ /[\x00-\x1f\x7f-\xa0]/) ||
2083 46793 100 66     823998 ($ctx->{quote_space} && $value =~ /[\x09\x20]/);
      100        
      100        
      66        
      100        
      100        
      100        
      100        
      100        
      100        
2084             }
2085              
2086 52435 100 100     124997 if (!$ctx->{binary} and $value =~ /[^\x09\x20-\x7E]/) {
2087             # an argument contained an invalid character...
2088 7         28 $self->{_ERROR_INPUT} = $value;
2089 7         40 $self->SetDiag(2110);
2090 7         105 return 0;
2091             }
2092              
2093 52428 100       99414 if ($re_esc) {
2094 52426         2557741 $value =~ s/($re_esc)/$esc$1/g;
2095             }
2096 52428 100       114180 if ($ctx->{escape_null}) {
2097 52291         2423354 $value =~ s/\0/${esc}0/g;
2098             }
2099             }
2100              
2101 53834 100       94036 if ($must_be_quoted) {
2102 29446         324414 $value = $quot . $value . $quot;
2103             }
2104 53834         169561 push @results, $value;
2105             }
2106              
2107 21671 100       566106 $$dst = join($sep, @results) . ( defined $ctx->{eol} ? $ctx->{eol} : '' );
2108              
2109 21671         161281 return 1;
2110             }
2111              
2112             sub _formula {
2113 37     37   121 my ($self, $ctx, $value, $i) = @_;
2114              
2115 37 50       103 my $fa = $ctx->{formula} or return;
2116 37 100       84 if ($fa == 1) { die "Formulas are forbidden\n" }
  3         58  
2117 34 100       66 if ($fa == 2) { die "Formulas are forbidden\n" } # XS croak behaves like PP's "die"
  3         53  
2118              
2119 31 100       55 if ($fa == 3) {
2120 6         10 my $rec = '';
2121 6 100       13 if ($ctx->{recno}) {
2122 3         12 $rec = sprintf " in record %lu", $ctx->{recno} + 1;
2123             }
2124 6         12 my $field = '';
2125 6         10 my $column_names = $self->{_COLUMN_NAMES};
2126 6 100 66     23 if (ref $column_names eq 'ARRAY' and @$column_names >= $i - 1) {
2127 1         4 my $column_name = $column_names->[$i - 1];
2128 1 50       7 $field = sprintf " (column: '%.100s')", $column_name if defined $column_name;
2129             }
2130 6         81 warn sprintf("Field %d%s%s contains formula '%s'\n", $i, $field, $rec, $value);
2131 6         46 return $value;
2132             }
2133              
2134 25 100       45 if ($fa == 4) {
2135 5         13 return '';
2136             }
2137 20 100       44 if ($fa == 5) {
2138 5         12 return undef;
2139             }
2140              
2141 15 50       28 if ($fa == 6) {
2142 15 50       40 if (ref $self->{_FORMULA_CB} eq 'CODE') {
2143 15         27 local $_ = $value;
2144 15         37 return $self->{_FORMULA_CB}->();
2145             }
2146             }
2147 0         0 return;
2148             }
2149              
2150             sub print {
2151 20289     20289 1 38115990 my ($self, $io, $fields) = @_;
2152              
2153 20289         106851 require IO::Handle;
2154              
2155 20289 100       147011 if (!defined $fields) {
    100          
2156 5         11 $fields = [];
2157             } elsif(ref($fields) ne 'ARRAY'){
2158 5         550 Carp::croak("Expected fields to be an array ref");
2159             }
2160              
2161 20284         54490 $self->_hook(before_print => $fields);
2162              
2163 20284         34355 my $str = "";
2164 20284 100       47728 $self->__combine(\$str, $fields, 1) or return '';
2165              
2166 20278         90423 local $\ = '';
2167              
2168 20278 100       70541 $io->print( $str ) or $self->_set_error_diag(2200);
2169             }
2170              
2171             ################################################################################
2172             # methods for parse
2173             ################################################################################
2174              
2175              
2176             sub __parse { # cx_xsParse
2177 3564     3564   7408 my ($self, $fields, $fflags, $src, $useIO) = @_;
2178              
2179 3564         7771 my $ctx = $self->_setup_ctx;
2180              
2181 3564         8601 my $state = $self->___parse($ctx, $fields, $fflags, $src, $useIO);
2182 3559 100 100     15247 if ($state and ($ctx->{has_hooks} || 0) & HOOK_AFTER_PARSE) {
      100        
2183 5         23 $self->_hook(after_parse => $fields);
2184             }
2185 3559   100     22477 return $state || !$last_error;
2186             }
2187              
2188             sub ___parse { # cx_c_xsParse
2189 4608     4608   9481 my ($self, $ctx, $fields, $fflags, $src, $useIO) = @_;
2190              
2191 4608 100 100     18962 local $/ = $ctx->{eol} if $ctx->{eolx} or $ctx->{eol_is_cr};
2192              
2193 4608 100       9209 if ($ctx->{useIO} = $useIO) {
2194 2665         24726 require IO::Handle;
2195              
2196 2665         114677 $ctx->{tmp} = undef;
2197 2665 100 66     6642 if ($ctx->{has_ahead} and defined $self->{_AHEAD}) {
2198 175         323 $ctx->{tmp} = $self->{_AHEAD};
2199 175         346 $ctx->{size} = length $ctx->{tmp};
2200 175         290 $ctx->{used} = 0;
2201             }
2202             } else {
2203 1943         2861 $ctx->{tmp} = $src;
2204 1943         2974 $ctx->{size} = length $src;
2205 1943         2874 $ctx->{used} = 0;
2206 1943         4569 $ctx->{utf8} = utf8::is_utf8($src);
2207             }
2208 4608 50       9287 if ($ctx->{has_error_input}) {
2209 0         0 $self->{_ERROR_INPUT} = undef;
2210 0         0 $ctx->{has_error_input} = 0;
2211             }
2212              
2213 4608         10404 my $result = $self->____parse($ctx, $src, $fields, $fflags);
2214 4597         9309 $self->{_RECNO} = ++($ctx->{recno});
2215 4597         8249 $self->{_EOF} = '';
2216              
2217 4597 100       9259 if ($ctx->{strict}) {
2218 27   66     85 $ctx->{strict_n} ||= $ctx->{fld_idx};
2219 27 100       64 if ($ctx->{strict_n} != $ctx->{fld_idx}) {
2220 12 100       36 unless ($ctx->{useIO} & useIO_EOF) {
2221 8         48 $self->__parse_error($ctx, 2014, $ctx->{used});
2222             }
2223 12 100       36 if ($last_error) {
2224 8         14 $result = undef;
2225             }
2226             }
2227             }
2228              
2229 4597 100       8091 if ($ctx->{useIO}) {
2230 2657 100 66     10226 if (defined $ctx->{tmp} and $ctx->{used} < $ctx->{size} and $ctx->{has_ahead}) {
      100        
2231 37         138 $self->{_AHEAD} = substr($ctx->{tmp}, $ctx->{used}, $ctx->{size} - $ctx->{used});
2232             } else {
2233 2620         4060 $ctx->{has_ahead} = 0;
2234 2620 100       5360 if ($ctx->{useIO} & useIO_EOF) {
2235 534         877 $self->{_EOF} = 1;
2236             }
2237             }
2238 2657         20405 %{$self->{_CACHE}} = %$ctx;
  2657         36887  
2239              
2240 2657 100       10394 if ($fflags) {
2241 1619 100       3082 if ($ctx->{keep_meta_info}) {
2242 11         31 $self->{_FFLAGS} = $fflags;
2243             } else {
2244 1608         2704 undef $fflags;
2245             }
2246             }
2247             } else {
2248 1940         17175 %{$self->{_CACHE}} = %$ctx;
  1940         31911  
2249             }
2250              
2251 4597 100 100     19129 if ($result and $ctx->{types}) {
2252 2         5 my $len = @$fields;
2253 2   66     9 for(my $i = 0; $i <= $len && $i <= $ctx->{types_len}; $i++) {
2254 8         23 my $value = $fields->[$i];
2255 8 100       19 next unless defined $value;
2256 6         29 my $type = ord(substr($ctx->{types}, $i, 1));
2257 6 100       12 if ($type == IV) {
    100          
2258 2         27 $fields->[$i] = int($value);
2259             } elsif ($type == NV) {
2260 2         10 $fields->[$i] = $value + 0.0;
2261             }
2262             }
2263             }
2264              
2265 4597         11344 $result;
2266             }
2267              
2268             sub ____parse { # cx_Parse
2269 4612     4612   8349 my ($self, $ctx, $src, $fields, $fflags) = @_;
2270              
2271 4612         6455 my ($quot, $sep, $esc, $eol) = @{$ctx}{qw/quo sep escape_char eol/};
  4612         11858  
2272              
2273 4612 100 100     19412 utf8::encode($sep) if !$ctx->{utf8} and $ctx->{sep_len};
2274 4612 100 100     14703 utf8::encode($quot) if !$ctx->{utf8} and $ctx->{quo_len};
2275 4612 100 100     15521 utf8::encode($eol) if !$ctx->{utf8} and $ctx->{eol_len};
2276              
2277 4612         6341 my $seenSomething = 0;
2278 4612         5725 my $spl = -1;
2279 4612         5790 my $waitingForField = 1;
2280 4612         6688 my ($value, $v_ref);
2281 4612         7034 $ctx->{fld_idx} = my $fnum = 0;
2282 4612         6472 $ctx->{flag} = 0;
2283              
2284 4612 100       8850 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", " ";
  14905 100       39741  
  15281         26956  
  18448         64091  
2285 4612         63780 $ctx->{_re} = qr/$re_str/;
2286 4612         61355 my $re = qr/$re_str|[^\x09\x20-\x7E]|$/;
2287              
2288             LOOP:
2289 4612         14792 while($self->__get_from_src($ctx, $src)) {
2290 4733         85354 while($ctx->{tmp} =~ /\G(.*?)($re)/gs) {
2291 75268         190573 my ($hit, $c) = ($1, $2);
2292 75268         111000 $ctx->{used} = pos($ctx->{tmp});
2293 75268 100 100     202295 if (!$waitingForField and $c eq '' and $hit ne '' and $ctx->{useIO} and !($ctx->{useIO} & useIO_EOF)) {
      100        
      100        
      100        
2294 147         300 $self->{_AHEAD} = $hit;
2295 147         261 $ctx->{has_ahead} = 1;
2296 147         226 $ctx->{has_leftover} = 1;
2297 147         486 last;
2298             }
2299 75121 100 100     230230 last if $seenSomething and $hit eq '' and $c eq ''; # EOF
      100        
2300              
2301             # new field
2302 74757 100       121565 if (!$v_ref) {
2303 22980 100       39123 if ($ctx->{is_bound}) {
2304 87         229 $v_ref = $self->__bound_field($ctx, $fnum, 0);
2305             } else {
2306 22893         31096 $value = '';
2307 22893         34227 $v_ref = \$value;
2308             }
2309 22980         29726 $fnum++;
2310 22980 100       38108 return unless $v_ref;
2311 22976         30139 $ctx->{flag} = 0;
2312 22976         29101 $ctx->{fld_idx}++;
2313             }
2314              
2315 74753         92897 $seenSomething = 1;
2316 74753         87846 $spl++;
2317              
2318 74753 100 66     201172 if (defined $hit and $hit ne '') {
2319 46016 100       74692 if ($waitingForField) {
2320 10142 100 100     20557 if (!$spl && $ctx->{comment_str} && $ctx->{tmp} =~ /\A\Q$ctx->{comment_str}/) {
      100        
2321 18         35 $ctx->{used} = $ctx->{size};
2322 18         63 next LOOP;
2323             }
2324 10124         12738 $waitingForField = 0;
2325             }
2326 45998 50       92519 if ($hit =~ /[^\x09\x20-\x7E]/) {
2327 0         0 $ctx->{flag} |= IS_BINARY;
2328             }
2329 45998         71158 $$v_ref .= $hit;
2330             }
2331              
2332             RESTART:
2333 75385 100 66     773981 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        
2334 11851 100       24633 if ($waitingForField) {
    100          
2335             # ,1,"foo, 3",,bar,
2336             # ^ ^
2337 1174 100 100     3687 if ($ctx->{blank_is_undef} or $ctx->{empty_is_undef}) {
2338 53         89 $$v_ref = undef;
2339             } else {
2340 1121         1805 $$v_ref = "";
2341             }
2342 1174 50       2280 unless ($ctx->{is_bound}) {
2343 1174         2701 push @$fields, $$v_ref;
2344             }
2345 1174         1888 $v_ref = undef;
2346 1174 100 66     2676 if ($ctx->{keep_meta_info} and $fflags) {
2347 8         18 push @$fflags, $ctx->{flag};
2348             }
2349             } elsif ($ctx->{flag} & IS_QUOTED) {
2350             # ,1,"foo, 3",,bar,
2351             # ^
2352 2195         3329 $$v_ref .= $c;
2353             } else {
2354             # ,1,"foo, 3",,bar,
2355             # ^ ^ ^
2356 8482         22535 $self->__push_value($ctx, $v_ref, $fields, $fflags, $ctx->{flag}, $fnum);
2357 8480         11244 $v_ref = undef;
2358 8480         11370 $waitingForField = 1;
2359             }
2360             }
2361             elsif (defined $c and defined $quot and $quot ne "\0" and $c eq $quot) {
2362 23081 100       38939 if ($waitingForField) {
2363             # ,1,"foo, 3",,bar,\r\n
2364             # ^
2365 11010         16046 $ctx->{flag} |= IS_QUOTED;
2366 11010         13325 $waitingForField = 0;
2367 11010         57195 next;
2368             }
2369 12071 100       24760 if ($ctx->{flag} & IS_QUOTED) {
2370             # ,1,"foo, 3",,bar,\r\n
2371             # ^
2372 12005         15363 my $quoesc = 0;
2373 12005         25604 my $c2 = $self->__get($ctx, $src);
2374              
2375 12005 100       24315 if ($ctx->{allow_whitespace}) {
2376             # , 1 , "foo, 3" , , bar , \r\n
2377             # ^
2378 4290         8743 while($self->__is_whitespace($ctx, $c2)) {
2379 90 100 33     245 if ($ctx->{allow_loose_quotes} and !(defined $esc and $c2 eq $esc)) {
      66        
2380 1         3 $$v_ref .= $c;
2381 1         2 $c = $c2;
2382             }
2383 90         155 $c2 = $self->__get($ctx, $src);
2384             }
2385             }
2386              
2387 12005 100       21410 if (!defined $c2) { # EOF
2388             # ,1,"foo, 3"
2389             # ^
2390 1311         3537 $self->__push_value($ctx, $v_ref, $fields, $fflags, $ctx->{flag}, $fnum);
2391 1311         5878 return 1;
2392             }
2393              
2394 10694 100 33     41421 if (defined $c2 and defined $sep and $c2 eq $sep) {
      66        
2395             # ,1,"foo, 3",,bar,\r\n
2396             # ^
2397 9079         23627 $self->__push_value($ctx, $v_ref, $fields, $fflags, $ctx->{flag}, $fnum);
2398 9079         13452 $v_ref = undef;
2399 9079         11933 $waitingForField = 1;
2400 9079         49575 next;
2401             }
2402 1615 100 100     7611 if (defined $c2 and ($c2 eq "\012" or (defined $eol and $c2 eq $eol))) { # FIXME: EOLX
      66        
2403             # ,1,"foo, 3",,"bar"\n
2404             # ^
2405 336         968 $self->__push_value($ctx, $v_ref, $fields, $fflags, $ctx->{flag}, $fnum);
2406 336         1398 return 1;
2407             }
2408              
2409 1279 100 100     3932 if (defined $esc and $c eq $esc) {
2410 1258         1631 $quoesc = 1;
2411 1258 100 66     3589 if (defined $c2 and $c2 eq '0') {
2412             # ,1,"foo, 3"056",,bar,\r\n
2413             # ^
2414 51         82 $$v_ref .= "\0";
2415 51         247 next;
2416             }
2417 1207 100 33     4624 if (defined $c2 and defined $quot and $c2 eq $quot) {
      66        
2418             # ,1,"foo, 3""56",,bar,\r\n
2419             # ^
2420 1077 100       2041 if ($ctx->{utf8}) {
2421 1         4 $ctx->{flag} |= IS_BINARY;
2422             }
2423 1077         1749 $$v_ref .= $c2;
2424 1077         5772 next;
2425             }
2426 130 100 66     427 if ($ctx->{allow_loose_escapes} and defined $c2 and $c2 ne "\015") {
      100        
2427             # ,1,"foo, 3"56",,bar,\r\n
2428             # ^
2429 4         7 $$v_ref .= $c;
2430 4         10 $c = $c2;
2431 4         416 goto RESTART;
2432             }
2433             }
2434 147 100 66     504 if (defined $c2 and $c2 eq "\015") {
2435 90 50       189 if ($ctx->{eol_is_cr}) {
2436             # ,1,"foo, 3"\r
2437             # ^
2438 0         0 $self->__push_value($ctx, $v_ref, $fields, $fflags, $ctx->{flag}, $fnum);
2439 0         0 return 1;
2440             }
2441              
2442 90         192 my $c3 = $self->__get($ctx, $src);
2443 90 100 100     334 if (defined $c3 and $c3 eq "\012") {
2444             # ,1,"foo, 3"\r\n
2445             # ^
2446 76         286 $self->__push_value($ctx, $v_ref, $fields, $fflags, $ctx->{flag}, $fnum);
2447 76         382 return 1;
2448             }
2449              
2450 14 100 66     46 if ($ctx->{useIO} and !$ctx->{eol_len}) {
2451 1 50       5 if ($c3 eq "\015") { # \r followed by an empty line
2452             # ,1,"foo, 3"\r\r
2453             # ^
2454 0         0 $self->__set_eol_is_cr($ctx);
2455 0         0 goto EOLX;
2456             }
2457 1 50       4 if ($c3 !~ /[^\x09\x20-\x7E]/) {
2458             # ,1,"foo\n 3",,"bar"\r
2459             # baz,4
2460             # ^
2461 1         12 $self->__set_eol_is_cr($ctx);
2462 1         2 $ctx->{used}--;
2463 1         3 $ctx->{has_ahead} = 1;
2464 1         4 $self->__push_value($ctx, $v_ref, $fields, $fflags, $ctx->{flag}, $fnum);
2465 1         5 return 1;
2466             }
2467             }
2468              
2469 13 100       53 $self->__parse_error($ctx, $quoesc ? 2023 : 2010, $ctx->{used} - 2);
2470 13         44 return;
2471             }
2472              
2473 57 100 100     174 if ($ctx->{allow_loose_quotes} and !$quoesc) {
2474             # ,1,"foo, 3"456",,bar,\r\n
2475             # ^
2476 10         20 $$v_ref .= $c;
2477 10         15 $c = $c2;
2478 10         819 goto RESTART;
2479             }
2480             # 1,"foo" ",3
2481             # ^
2482 47 100       105 if ($quoesc) {
2483 39         65 $ctx->{used}--;
2484 39         143 $self->__error_inside_quotes($ctx, 2023);
2485 37         143 return;
2486             }
2487 8         59 $self->__error_inside_quotes($ctx, 2011);
2488 8         89 return;
2489             }
2490             # !waitingForField, !InsideQuotes
2491 66 100       137 if ($ctx->{allow_loose_quotes}) { # 1,foo "boo" d'uh,1
2492 16         24 $ctx->{flag} |= IS_ERROR;
2493 16         28 $$v_ref .= $c;
2494             } else {
2495 50         220 $self->__error_inside_field($ctx, 2034);
2496 50         203 return;
2497             }
2498             }
2499             elsif (defined $c and defined $esc and $esc ne "\0" and $c eq $esc) {
2500             # This means quote_char != escape_char
2501 4655 100       10357 if ($waitingForField) {
    100          
    50          
2502 34         58 $waitingForField = 0;
2503 34 100       87 if ($ctx->{allow_unquoted_escape}) {
2504             # The escape character is the first character of an
2505             # unquoted field
2506             # ... get and store next character
2507 4         15 my $c2 = $self->__get($ctx, $src);
2508 4         11 $$v_ref = "";
2509              
2510 4 100       18 if (!defined $c2) { # EOF
2511 1         2 $ctx->{used}--;
2512 1         5 $self->__error_inside_field($ctx, 2035);
2513 1         4 return;
2514             }
2515 3 100 33     37 if ($c2 eq '0') {
    50 33        
      33        
      0        
      33        
      0        
2516 1         3 $$v_ref .= "\0";
2517             }
2518             elsif (
2519             (defined $quot and $c2 eq $quot) or
2520             (defined $sep and $c2 eq $sep) or
2521             (defined $esc and $c2 eq $esc) or
2522             $ctx->{allow_loose_escapes}
2523             ) {
2524 2 50       8 if ($ctx->{utf8}) {
2525 0         0 $ctx->{flag} |= IS_BINARY;
2526             }
2527 2         6 $$v_ref .= $c2;
2528             } else {
2529 0         0 $self->__parse_inside_quotes($ctx, 2025);
2530 0         0 return;
2531             }
2532             }
2533             }
2534             elsif ($ctx->{flag} & IS_QUOTED) {
2535 4612         9874 my $c2 = $self->__get($ctx, $src);
2536 4612 100       9263 if (!defined $c2) { # EOF
2537 3         7 $ctx->{used}--;
2538 3         23 $self->__error_inside_quotes($ctx, 2024);
2539 3         11 return;
2540             }
2541 4609 100 66     26994 if ($c2 eq '0') {
    100 66        
      100        
      66        
      100        
      66        
2542 2         5 $$v_ref .= "\0";
2543             }
2544             elsif (
2545             (defined $quot and $c2 eq $quot) or
2546             (defined $sep and $c2 eq $sep) or
2547             (defined $esc and $c2 eq $esc) or
2548             $ctx->{allow_loose_escapes}
2549             ) {
2550 4581 50       8262 if ($ctx->{utf8}) {
2551 0         0 $ctx->{flag} |= IS_BINARY;
2552             }
2553 4581         7166 $$v_ref .= $c2;
2554             } else {
2555 26         52 $ctx->{used}--;
2556 26         88 $self->__error_inside_quotes($ctx, 2025);
2557 26         125 return;
2558             }
2559             }
2560             elsif ($v_ref) {
2561 9         26 my $c2 = $self->__get($ctx, $src);
2562 9 100       25 if (!defined $c2) { # EOF
2563 4         9 $ctx->{used}--;
2564 4         11 $self->__error_inside_field($ctx, 2035);
2565 4         16 return;
2566             }
2567 5         7 $$v_ref .= $c2;
2568             }
2569             else {
2570 0         0 $self->__error_inside_field($ctx, 2036);
2571 0         0 return;
2572             }
2573             }
2574             elsif (defined $c and ($c eq "\012" or $c eq '' or (defined $eol and $c eq $eol and $eol ne "\015"))) { # EOL
2575             EOLX:
2576 2997 100 100     8063 if ($fnum == 1 && $ctx->{flag} == 0 && (!$v_ref || $$v_ref eq '') && $ctx->{skip_empty_rows}) {
      66        
      100        
      100        
2577             ### SkipEmptyRow
2578 51         83 my $ser = $ctx->{skip_empty_rows};
2579 51 100       107 if ($ser == 3) { $self->SetDiag(2015); die "Empty row\n"; }
  3         12  
  3         116  
2580 48 100       98 if ($ser == 4) { $self->SetDiag(2015); die "Empty row\n"; }
  3         12  
  3         108  
2581 45 100       74 if ($ser == 5) { $self->SetDiag(2015); return undef; }
  2         17  
  2         8  
2582              
2583 43 100       133 if ($ser <= 2) { # skip & eof
2584 33         52 $ctx->{fld_idx} = 0;
2585 33         81 $c = $self->__get($ctx, $src);
2586 33 100 100     128 if (!defined $c or $ser == 2) { # EOF
2587 4         5 $v_ref = undef;
2588 4         6 $waitingForField = 0;
2589 4 100       8 if ($ser == 2) { return undef; }
  2         8  
2590 2         6 last LOOP;
2591             }
2592             }
2593              
2594 39 100       91 if ($ser == 6) {
2595 10         17 my $cb = $self->{_EMPTROW_CB};
2596 10 50 33     38 unless ($cb && ref $cb eq 'CODE') {
2597 0         0 return undef; # A callback is wanted, but none found
2598             }
2599 10         16 local $_ = $v_ref;
2600 10         24 my $rv = $cb->();
2601             # Result should be a ref to a list.
2602 10 100       42 unless (ref $rv eq 'ARRAY') {
2603 2         9 return undef;
2604             }
2605 8         12 my $n = @$rv;
2606 8 50       14 if ($n <= 0) {
2607 0         0 return 1;
2608             }
2609 8 50 33     19 if ($ctx->{is_bound} && $ctx->{is_bound} < $n) {
2610 0         0 $n = $ctx->{is_bound} - 1;
2611             }
2612 8         28 for (my $i = 0; $i < $n; $i++) {
2613 32         43 my $rvi = $rv->[$i];
2614 32         65 $self->__push_value($ctx, \$rvi, $fields, $fflags, $ctx->{flag}, $fnum);
2615             }
2616 8         29 return 1;
2617             }
2618 29         2165 goto RESTART;
2619             }
2620              
2621 2946 100       5367 if ($waitingForField) {
2622             # ,1,"foo, 3",,bar,
2623             # ^
2624 230 100 100     815 if ($ctx->{blank_is_undef} or $ctx->{empty_is_undef}) {
2625 16         32 $$v_ref = undef;
2626             } else {
2627 214         373 $$v_ref = "";
2628             }
2629 230 100       480 unless ($ctx->{is_bound}) {
2630 229         471 push @$fields, $$v_ref;
2631             }
2632 230 100 66     569 if ($ctx->{keep_meta_info} and $fflags) {
2633 14         25 push @$fflags, $ctx->{flag};
2634             }
2635 230         991 return 1;
2636             }
2637 2716 100       6362 if ($ctx->{flag} & IS_QUOTED) {
    100          
2638             # ,1,"foo\n 3",,bar,
2639             # ^
2640 779         1140 $ctx->{flag} |= IS_BINARY;
2641 779 100       1542 unless ($ctx->{binary}) {
2642 29         135 $self->__error_inside_quotes($ctx, 2021);
2643 29         111 return;
2644             }
2645 750         1165 $$v_ref .= $c;
2646             }
2647             elsif ($ctx->{verbatim}) {
2648             # ,1,foo\n 3,,bar,
2649             # This feature should be deprecated
2650 11         22 $ctx->{flag} |= IS_BINARY;
2651 11 100       22 unless ($ctx->{binary}) {
2652 1         7 $self->__error_inside_field($ctx, 2030);
2653 1         6 return;
2654             }
2655 10 100 100     35 $$v_ref .= $c unless $ctx->{eol} eq $c and $ctx->{useIO};
2656             }
2657             else {
2658             # sep=,
2659             # ^
2660 1926 100 100     5206 if (!$ctx->{recno} and $ctx->{fld_idx} == 1 and $ctx->{useIO} and $hit =~ /^sep=(.{1,16})$/i) {
      100        
      100        
2661 4         11 $ctx->{sep} = $1;
2662 37     37   119338 use bytes;
  37         107  
  37         171  
2663 4         9 my $len = length $ctx->{sep};
2664 4 50       10 if ($len <= 16) {
2665 4 100       10 $ctx->{sep_len} = $len == 1 ? 0 : $len;
2666 4         34 return $self->____parse($ctx, $src, $fields, $fflags);
2667             }
2668             }
2669              
2670             # ,1,"foo\n 3",,bar
2671             # ^
2672 1922         5511 $self->__push_value($ctx, $v_ref, $fields, $fflags, $ctx->{flag}, $fnum);
2673 1922         7693 return 1;
2674             }
2675             }
2676             elsif (defined $c and $c eq "\015" and !$ctx->{verbatim}) {
2677 1033 100       2093 if ($waitingForField) {
2678 113 100       251 if ($ctx->{eol_is_cr}) {
2679             # ,1,"foo\n 3",,bar,\r
2680             # ^
2681 29         45 $c = "\012";
2682 29         1166 goto EOLX;
2683             }
2684              
2685 84         226 my $c2 = $self->__get($ctx, $src);
2686 84 100       210 if (!defined $c2) { # EOF
2687             # ,1,"foo\n 3",,bar,\r
2688             # ^
2689 5         12 $c = undef;
2690 5 50       25 last unless $seenSomething;
2691 5         596 goto RESTART;
2692             }
2693 79 100       214 if ($c2 eq "\012") { # \r is not optional before EOLX!
2694             # ,1,"foo\n 3",,bar,\r\n
2695             # ^
2696 69         94 $c = $c2;
2697 69         2741 goto EOLX;
2698             }
2699              
2700 10 100 66     52 if ($ctx->{useIO} and !$ctx->{eol_len}) {
2701 5 50       18 if ($c2 eq "\012") { # \r followed by an empty line
2702             # ,1,"foo\n 3",,bar,\r\r
2703             # ^
2704 0         0 $self->__set_eol_is_cr($ctx);
2705 0         0 goto EOLX;
2706             }
2707 5         10 $waitingForField = 0;
2708 5 100       24 if ($c2 !~ /[^\x09\x20-\x7E]/) {
2709             # ,1,"foo\n 3",,bar,\r
2710             # baz,4
2711             # ^
2712 2         9 $self->__set_eol_is_cr($ctx);
2713 2         3 $ctx->{used}--;
2714 2         5 $ctx->{has_ahead} = 1;
2715 2 50 66     37 if ($fnum == 1 && $ctx->{flag} == 0 && (!$v_ref or $$v_ref eq '') && $ctx->{skip_empty_rows}) {
      33        
      66        
      33        
2716             ### SkipEmptyRow
2717 1         3 my $ser = $ctx->{skip_empty_rows};
2718 1 50       3 if ($ser == 3) { $self->SetDiag(2015); die "Empty row\n"; }
  0         0  
  0         0  
2719 1 50       4 if ($ser == 4) { $self->SetDiag(2015); die "Empty row\n"; }
  0         0  
  0         0  
2720 1 50       3 if ($ser == 5) { $self->SetDiag(2015); return undef; }
  0         0  
  0         0  
2721              
2722 1 50       2 if ($ser <= 2) { # skip & eof
2723 1         3 $ctx->{fld_idx} = 0;
2724 1         3 $c = $self->__get($ctx, $src);
2725 1 50       6 if (!defined $c) { # EOF
2726 0         0 $v_ref = undef;
2727 0         0 $waitingForField = 0;
2728 0         0 last LOOP;
2729             }
2730             }
2731              
2732 1 50       3 if ($ser == 6) {
2733 0         0 my $cb = $self->{_EMPTROW_CB};
2734 0 0 0     0 unless ($cb && ref $cb eq 'CODE') {
2735 0         0 return undef; # A callback is wanted, but none found
2736             }
2737 0         0 local $_ = $v_ref;
2738 0         0 my $rv = $cb->();
2739             # Result should be a ref to a list.
2740 0 0       0 unless (ref $rv eq 'ARRAY') {
2741 0         0 return undef;
2742             }
2743 0         0 my $n = @$rv;
2744 0 0       0 if ($n <= 0) {
2745 0         0 return 1;
2746             }
2747 0 0 0     0 if ($ctx->{is_bound} && $ctx->{is_bound} < $n) {
2748 0         0 $n = $ctx->{is_bound} - 1;
2749             }
2750 0         0 for (my $i = 0; $i < $n; $i++) {
2751 0         0 my $rvi = $rv->[$i];
2752 0         0 $self->__push_value($ctx, \$rvi, $fields, $fflags, $ctx->{flag}, $fnum);
2753             }
2754 0         0 return 1;
2755             }
2756              
2757 1         2 $$v_ref = $c2;
2758 1         77 goto RESTART;
2759             }
2760 1         8 $self->__push_value($ctx, $v_ref, $fields, $fflags, $ctx->{flag}, $fnum);
2761 1         5 return 1;
2762             }
2763             }
2764              
2765             # ,1,"foo\n 3",,bar,\r\t
2766             # ^
2767 8         15 $ctx->{used}--;
2768 8         32 $self->__error_inside_field($ctx, 2031);
2769 8         33 return;
2770             }
2771 920 100       1703 if ($ctx->{flag} & IS_QUOTED) {
2772             # ,1,"foo\r 3",,bar,\r\t
2773             # ^
2774 593         952 $ctx->{flag} |= IS_BINARY;
2775 593 100       1047 unless ($ctx->{binary}) {
2776 70         210 $self->__error_inside_quotes($ctx, 2022);
2777 70         252 return;
2778             }
2779 523         862 $$v_ref .= $c;
2780             }
2781             else {
2782 327 100       689 if ($ctx->{eol_is_cr}) {
2783             # ,1,"foo\n 3",,bar\r
2784             # ^
2785 181         7436 goto EOLX;
2786             }
2787              
2788 146         384 my $c2 = $self->__get($ctx, $src);
2789 146 100 100     621 if (defined $c2 and $c2 eq "\012") { # \r is not optional before EOLX!
2790             # ,1,"foo\n 3",,bar\r\n
2791             # ^
2792 130         5489 goto EOLX;
2793             }
2794              
2795 16 100 66     85 if ($ctx->{useIO} and !$ctx->{eol_len}) {
2796 11 100 100     97 if ($c2 !~ /[^\x09\x20-\x7E]/
2797             # ,1,"foo\n 3",,bar\r
2798             # baz,4
2799             # ^
2800             or $c2 eq "\015"
2801             # ,1,"foo\n 3",,bar,\r\r
2802             # ^
2803             ) {
2804 5         56 $self->__set_eol_is_cr($ctx);
2805 5         10 $ctx->{used}--;
2806 5         8 $ctx->{has_ahead} = 1;
2807 5 0 33     21 if ($fnum == 1 && $ctx->{flag} == 0 && (!$v_ref or $$v_ref eq '') && $ctx->{skip_empty_rows}) {
      0        
      33        
      0        
2808             ### SKipEmptyRow
2809 0         0 my $ser = $ctx->{skip_empty_rows};
2810 0 0       0 if ($ser == 3) { $self->SetDiag(2015); die "Empty row\n"; }
  0         0  
  0         0  
2811 0 0       0 if ($ser == 4) { $self->SetDiag(2015); die "Empty row\n"; }
  0         0  
  0         0  
2812 0 0       0 if ($ser == 5) { $self->SetDiag(2015); return undef; }
  0         0  
  0         0  
2813              
2814 0 0       0 if ($ser <= 2) { # skip & eof
2815 0         0 $ctx->{fld_idx} = 0;
2816 0         0 $c = $self->__get($ctx, $src);
2817 0 0       0 if (!defined $c) { # EOL
2818 0         0 $v_ref = undef;
2819 0         0 $waitingForField = 0;
2820 0         0 last LOOP;
2821             }
2822             }
2823              
2824 0 0       0 if ($ser == 6) {
2825 0         0 my $cb = $self->{_EMPTROW_CB};
2826 0 0 0     0 unless ($cb && ref $cb eq 'CODE') {
2827 0         0 return undef; # A callback is wanted, but none found
2828             }
2829 0         0 local $_ = $v_ref;
2830 0         0 my $rv = $cb->();
2831             # Result should be a ref to a list.
2832 0 0       0 unless (ref $rv eq 'ARRAY') {
2833 0         0 return undef;
2834             }
2835 0         0 my $n = @$rv;
2836 0 0       0 if ($n <= 0) {
2837 0         0 return 1;
2838             }
2839 0 0 0     0 if ($ctx->{is_bound} && $ctx->{is_bound} < $n) {
2840 0         0 $n = $ctx->{is_bound} - 1;
2841             }
2842 0         0 for (my $i = 0; $i < $n; $i++) {
2843 0         0 my $rvi = $rv->[$i];
2844 0         0 $self->__push_value($ctx, \$rvi, $fields, $fflags, $ctx->{flag}, $fnum);
2845             }
2846 0         0 return 1;
2847             }
2848 0         0 goto RESTART;
2849             }
2850 5         21 $self->__push_value($ctx, $v_ref, $fields, $fflags, $ctx->{flag}, $fnum);
2851 5         21 return 1;
2852             }
2853             }
2854              
2855             # ,1,"foo\n 3",,bar\r\t
2856             # ^
2857 11         38 $self->__error_inside_field($ctx, 2032);
2858 11         47 return;
2859             }
2860             }
2861             else {
2862 32177 50 66     66448 if ($ctx->{eolx} and $c eq $eol) {
2863 0         0 $c = '';
2864 0         0 goto EOLX;
2865             }
2866              
2867 32177 100       48797 if ($waitingForField) {
2868 608 100 100     1660 if (!$spl && $ctx->{comment_str} && $ctx->{tmp} =~ /\A$ctx->{comment_str}/) {
      100        
2869 6         13 $ctx->{used} = $ctx->{size};
2870 6         23 next LOOP;
2871             }
2872 602 100 100     1643 if ($ctx->{allow_whitespace} and $self->__is_whitespace($ctx, $c)) {
2873 231         333 do {
2874 341         635 $c = $self->__get($ctx, $src);
2875 341 100       878 last if !defined $c;
2876             } while $self->__is_whitespace($ctx, $c);
2877 230         15453 goto RESTART;
2878             }
2879 371         524 $waitingForField = 0;
2880 371         25832 goto RESTART;
2881             }
2882 31569 100       53449 if ($ctx->{flag} & IS_QUOTED) {
2883 29469 100 66     91799 if (!defined $c or $c =~ /[^\x09\x20-\x7E]/) {
2884 3297         5586 $ctx->{flag} |= IS_BINARY;
2885 3297 100 100     6208 unless ($ctx->{binary} or $ctx->{utf8}) {
2886 5         21 $self->__error_inside_quotes($ctx, 2026);
2887 5         22 return;
2888             }
2889             }
2890 29464         42920 $$v_ref .= $c;
2891             } else {
2892 2100 100 100     7271 if (!defined $c or $c =~ /[^\x09\x20-\x7E]/) {
2893 450 100 100     1461 last if $ctx->{useIO} && !defined $c;
2894 447         690 $ctx->{flag} |= IS_BINARY;
2895 447 50 66     931 unless ($ctx->{binary} or $ctx->{utf8}) {
2896 9         44 $self->__error_inside_field($ctx, 2037);
2897 9         37 return;
2898             }
2899             }
2900 2088         3319 $$v_ref .= $c;
2901             }
2902             }
2903 49321 100 100     285493 last LOOP if $ctx->{useIO} and $ctx->{verbatim} and $ctx->{used} == $ctx->{size};
      100        
2904             }
2905             }
2906              
2907 423 100       912 if ($waitingForField) {
2908 366 100 66     1436 if ($seenSomething or !$ctx->{useIO}) {
2909             # new field
2910 32 100       87 if (!$v_ref) {
2911 31 50       68 if ($ctx->{is_bound}) {
2912 0         0 $v_ref = $self->__bound_field($ctx, $fnum, 0);
2913             } else {
2914 31         56 $value = '';
2915 31         49 $v_ref = \$value;
2916             }
2917 31         52 $fnum++;
2918 31 50       61 return unless $v_ref;
2919 31         58 $ctx->{flag} = 0;
2920 31         46 $ctx->{fld_idx}++;
2921             }
2922 32 100 100     147 if ($ctx->{blank_is_undef} or $ctx->{empty_is_undef}) {
2923 9         16 $$v_ref = undef;
2924             } else {
2925 23         51 $$v_ref = "";
2926             }
2927 32 50       83 unless ($ctx->{is_bound}) {
2928 32         70 push @$fields, $$v_ref;
2929             }
2930 32 100 66     95 if ($ctx->{keep_meta_info} and $fflags) {
2931 3         16 push @$fflags, $ctx->{flag};
2932             }
2933 32         130 return 1;
2934             }
2935 334         1115 $self->SetDiag(2012);
2936 334         1170 return;
2937             }
2938              
2939 57 100       162 if ($ctx->{flag} & IS_QUOTED) {
2940 14         56 $self->__error_inside_quotes($ctx, 2027);
2941 13         47 return;
2942             }
2943              
2944 43 100 33     130 if ($v_ref) {
    50 33        
2945 41         114 $self->__push_value($ctx, $v_ref, $fields, $fflags, $ctx->{flag}, $fnum);
2946             } elsif ($ctx->{flag} == 0 && $fnum == 1 && $ctx->{skip_empty_rows} == 1) {
2947 2         8 return undef;
2948             }
2949 41         156 return 1;
2950             }
2951              
2952             sub __get_from_src {
2953 6516     6516   11868 my ($self, $ctx, $src) = @_;
2954 6516 100 100     23653 return 1 if defined $ctx->{tmp} and $ctx->{used} <= 0;
2955 4398 50       9500 return 1 if $ctx->{used} < $ctx->{size};
2956 4398 100       10238 return unless $ctx->{useIO};
2957 3033         70866 my $res = $src->getline;
2958 3033 100       90291 if (defined $res) {
    100          
2959 2496 50       5111 if ($ctx->{has_ahead}) {
2960 0         0 $ctx->{tmp} = $self->{_AHEAD};
2961 0 0       0 $ctx->{tmp} .= $ctx->{eol} if $ctx->{eol_len};
2962 0         0 $ctx->{tmp} .= $res;
2963 0         0 $ctx->{has_ahead} = 0;
2964             } else {
2965 2496         4312 $ctx->{tmp} = $res;
2966             }
2967 2496 50       5982 if ($ctx->{size} = length $ctx->{tmp}) {
2968 2496         3652 $ctx->{used} = -1;
2969 2496 100       6723 $ctx->{utf8} = 1 if utf8::is_utf8($ctx->{tmp});
2970 2496         6553 pos($ctx->{tmp}) = 0;
2971 2496         7968 return 1;
2972             }
2973             } elsif (delete $ctx->{has_leftover}) {
2974 147         367 $ctx->{tmp} = $self->{_AHEAD};
2975 147         231 $ctx->{has_ahead} = 0;
2976 147         241 $ctx->{useIO} |= useIO_EOF;
2977 147 50       342 if ($ctx->{size} = length $ctx->{tmp}) {
2978 147         195 $ctx->{used} = -1;
2979 147 50       398 $ctx->{utf8} = 1 if utf8::is_utf8($ctx->{tmp});
2980 147         314 pos($ctx->{tmp}) = 0;
2981 147         442 return 1;
2982             }
2983             }
2984 390 100       1135 $ctx->{tmp} = '' unless defined $ctx->{tmp};
2985 390         722 $ctx->{useIO} |= useIO_EOF;
2986 390         1013 return;
2987             }
2988              
2989             sub __set_eol_is_cr {
2990 8     8   22 my ($self, $ctx) = @_;
2991 8         20 $ctx->{eol} = "\015";
2992 8         20 $ctx->{eol_is_cr} = 1;
2993 8         28 $ctx->{eol_len} = 1;
2994 8         68 %{$self->{_CACHE}} = %$ctx;
  8         111  
2995              
2996 8         38 $self->{eol} = $ctx->{eol};
2997             }
2998              
2999             sub __bound_field {
3000 101     101   191 my ($self, $ctx, $i, $keep) = @_;
3001 101 100       212 if ($i >= $ctx->{is_bound}) {
3002 3         17 $self->SetDiag(3006);
3003 3         13 return;
3004             }
3005 98 50       238 if (ref $ctx->{bound} eq 'ARRAY') {
3006 98         179 my $ref = $ctx->{bound}[$i];
3007 98 50       229 if (ref $ref) {
3008 98 100       192 if ($keep) {
3009 14         29 return $ref;
3010             }
3011 84 100       245 unless (Scalar::Util::readonly($$ref)) {
3012 83         141 $$ref = "";
3013 83         208 return $ref;
3014             }
3015             }
3016             }
3017 1         22 $self->SetDiag(3008);
3018 1         3 return;
3019             }
3020              
3021             sub __get {
3022 17443     17443   30228 my ($self, $ctx, $src) = @_;
3023 17443 50       32612 return unless defined $ctx->{used};
3024 17443 100       32230 if ($ctx->{used} >= $ctx->{size}) {
3025 1365 100       2878 if ($self->__get_from_src($ctx, $src)) {
3026 28         113 return $self->__get($ctx, $src);
3027             }
3028 1337         2689 return;
3029             }
3030 16078         23105 my $pos = pos($ctx->{tmp});
3031 16078 50       108382 if ($ctx->{tmp} =~ /\G($ctx->{_re}|.)/gs) {
3032 16078         32318 my $c = $1;
3033 16078 100       34631 if ($c =~ /[^\x09\012\015\x20-\x7e]/) {
3034 1222         2136 $ctx->{flag} |= IS_BINARY;
3035             }
3036 16078         25289 $ctx->{used} = pos($ctx->{tmp});
3037 16078         45046 return $c;
3038             } else {
3039 0 0       0 if ($self->__get_from_src($ctx, $src)) {
3040 0         0 return $self->__get($ctx, $src);
3041             }
3042 0         0 pos($ctx->{tmp}) = $pos;
3043 0         0 return;
3044             }
3045             }
3046              
3047             sub __error_inside_quotes {
3048 194     194   402 my ($self, $ctx, $error) = @_;
3049 194         531 $self->__parse_error($ctx, $error, $ctx->{used} - 1);
3050             }
3051              
3052             sub __error_inside_field {
3053 84     84   180 my ($self, $ctx, $error) = @_;
3054 84         267 $self->__parse_error($ctx, $error, $ctx->{used} - 1);
3055             }
3056              
3057             sub __parse_error {
3058 299     299   584 my ($self, $ctx, $error, $pos) = @_;
3059 299         560 $self->{_ERROR_POS} = $pos;
3060 299         496 $self->{_ERROR_FLD} = $ctx->{fld_idx};
3061 299 50       784 $self->{_ERROR_INPUT} = $ctx->{tmp} if $ctx->{tmp};
3062 299         813 $self->SetDiag($error);
3063 296         572 return;
3064             }
3065              
3066             sub __is_whitespace {
3067 5064     5064   8594 my ($self, $ctx, $c) = @_;
3068 5064 100       9593 return unless defined $c;
3069             return (
3070             (!defined $ctx->{sep} or $c ne $ctx->{sep}) &&
3071             (!defined $ctx->{quo} or $c ne $ctx->{quo}) &&
3072 4529   33     24967 (!defined $ctx->{escape_char} or $c ne $ctx->{escape_char}) &&
3073             ($c eq " " or $c eq "\t")
3074             );
3075             }
3076              
3077             sub __push_value { # AV_PUSH (part of)
3078 21286     21286   37516 my ($self, $ctx, $v_ref, $fields, $fflags, $flag, $fnum) = @_;
3079 21286 100       38509 utf8::encode($$v_ref) if $ctx->{utf8};
3080 21286 100 66     41431 if ($ctx->{formula} && defined $$v_ref && substr($$v_ref, 0, 1) eq '=') {
      100        
3081 27         67 my $value = $self->_formula($ctx, $$v_ref, $fnum);
3082 25 100       548 push @$fields, defined $value ? $value : undef;
3083 25         35 return;
3084             }
3085 21259 100 66     74149 if (
      66        
      100        
3086             (!defined $$v_ref or $$v_ref eq '') and
3087             ($ctx->{empty_is_undef} or (!($flag & IS_QUOTED) and $ctx->{blank_is_undef}))
3088             ) {
3089 12         17 $$v_ref = undef;
3090             } else {
3091 21247 100 100     47446 if ($ctx->{allow_whitespace} && !($flag & IS_QUOTED)) {
3092 1725         3822 $$v_ref =~ s/[ \t]+$//;
3093             }
3094 21247 100 66     48651 if ($flag & IS_BINARY and $ctx->{decode_utf8} and ($ctx->{utf8} || _is_valid_utf8($$v_ref))) {
      100        
      66        
3095 2171         6049 utf8::decode($$v_ref);
3096             }
3097             }
3098 21259 100       39988 unless ($ctx->{is_bound}) {
3099 21178         45262 push @$fields, $$v_ref;
3100             }
3101 21259 100 66     49049 if ($ctx->{keep_meta_info} and $fflags) {
3102 88         175 push @$fflags, $flag;
3103             }
3104             }
3105              
3106             sub getline {
3107 1621     1621 1 345244 my ($self, $io) = @_;
3108              
3109 1621         2535 my (@fields, @fflags);
3110 1621         4585 my $res = $self->__parse(\@fields, \@fflags, $io, 1);
3111 1619 100       8461 $res ? \@fields : undef;
3112             }
3113              
3114             sub getline_all {
3115 336     336 1 728 my ( $self, $io, $offset, $len ) = @_;
3116              
3117 336         699 my $ctx = $self->_setup_ctx;
3118              
3119 336         517 my $tail = 0;
3120 336         470 my $n = 0;
3121 336   100     1224 $offset ||= 0;
3122              
3123 336 100       640 if ( $offset < 0 ) {
3124 12         23 $tail = -$offset;
3125 12         24 $offset = -1;
3126             }
3127              
3128 336         532 my (@row, @list);
3129 336         975 while ($self->___parse($ctx, \@row, undef, $io, 1)) {
3130 740         1938 $ctx = $self->_setup_ctx;
3131              
3132 740 100       1734 if ($offset > 0) {
3133 20         32 $offset--;
3134 20         41 @row = ();
3135 20         56 next;
3136             }
3137 720 100 100     2500 if ($n++ >= $tail and $tail) {
3138 12         17 shift @list;
3139 12         25 $n--;
3140             }
3141 720 100 100     2340 if (($ctx->{has_hooks} || 0) & HOOK_AFTER_PARSE) {
3142 117 100       323 unless ($self->_hook(after_parse => \@row)) {
3143 63         112 @row = ();
3144 63         174 next;
3145             }
3146             }
3147 657         2115 push @list, [@row];
3148 657         1269 @row = ();
3149              
3150 657 100 100     2435 last if defined $len && $n >= $len and $offset >= 0; # exceeds limit size
      100        
3151             }
3152              
3153 330 100 100     876 if ( defined $len && $n > $len ) {
3154 8         25 @list = splice( @list, 0, $len);
3155             }
3156              
3157 330         2052 return \@list;
3158             }
3159              
3160             sub _is_valid_utf8 {
3161 3749 100   3749   54192 return ( $_[0] =~ /^(?:
3162             [\x00-\x7F]
3163             |[\xC2-\xDF][\x80-\xBF]
3164             |[\xE0][\xA0-\xBF][\x80-\xBF]
3165             |[\xE1-\xEC][\x80-\xBF][\x80-\xBF]
3166             |[\xED][\x80-\x9F][\x80-\xBF]
3167             |[\xEE-\xEF][\x80-\xBF][\x80-\xBF]
3168             |[\xF0][\x90-\xBF][\x80-\xBF][\x80-\xBF]
3169             |[\xF1-\xF3][\x80-\xBF][\x80-\xBF][\x80-\xBF]
3170             |[\xF4][\x80-\x8F][\x80-\xBF][\x80-\xBF]
3171             )+$/x ) ? 1 : 0;
3172             }
3173              
3174             ################################################################################
3175             # methods for errors
3176             ################################################################################
3177              
3178             sub _set_error_diag {
3179 1     1   38 my ( $self, $error, $pos ) = @_;
3180              
3181 1         4 $self->SetDiag($error);
3182              
3183 1 50       4 if (defined $pos) {
3184 0         0 $_[0]->{_ERROR_POS} = $pos;
3185             }
3186              
3187 1         8 return;
3188             }
3189              
3190             sub error_input {
3191 8     8 1 598 my $self = shift;
3192 8 100 66     58 if ($self and ((Scalar::Util::reftype($self) || '') eq 'HASH' or (ref $self) =~ /^Text::CSV/)) {
      66        
3193 4         20 return $self->{_ERROR_INPUT};
3194             }
3195 4         17 return;
3196             }
3197              
3198             sub _sv_diag {
3199 3640     3640   6218 my ($self, $error) = @_;
3200 3640         14992 bless [$error, $ERRORS->{$error}], 'Text::CSV::ErrorDiag';
3201             }
3202              
3203             sub _set_diag {
3204 1700     1700   3278 my ($self, $ctx, $error) = @_;
3205              
3206 1700         3320 $last_error = $self->_sv_diag($error);
3207 1700         3967 $self->{_ERROR_DIAG} = $last_error;
3208 1700 100       4161 if ($error == 0) {
3209 6         17 $self->{_ERROR_POS} = 0;
3210 6         28 $self->{_ERROR_FLD} = 0;
3211 6         15 $self->{_ERROR_INPUT} = undef;
3212 6         10 $ctx->{has_error_input} = 0;
3213             }
3214 1700 100       3378 if ($error == 2012) { # EOF
3215 335         602 $self->{_EOF} = 1;
3216             }
3217 1700 100       3274 if ($ctx->{auto_diag}) {
3218 284         707 $self->error_diag;
3219             }
3220 1697         7456 return $last_error;
3221             }
3222              
3223             sub SetDiag {
3224 3640     3640 1 9599 my ($self, $error, $errstr) = @_;
3225 3640         5096 my $res;
3226 3640 100       7821 if (ref $self) {
3227 1700         3761 my $ctx = $self->_setup_ctx;
3228 1700         4460 $res = $self->_set_diag($ctx, $error);
3229              
3230             } else {
3231 1940         3059 $last_error = $error;
3232 1940         3948 $res = $self->_sv_diag($error);
3233             }
3234 3637 100       8161 if (defined $errstr) {
3235 962         2740 $res->[1] = $errstr;
3236             }
3237 3637         28071 $res;
3238             }
3239              
3240             ################################################################################
3241             package Text::CSV::ErrorDiag;
3242              
3243 37     37   144323 use strict;
  37         94  
  37         3092  
3244             use overload (
3245 37         348 '""' => \&stringify,
3246             '+' => \&numeric,
3247             '-' => \&numeric,
3248             '*' => \&numeric,
3249             '/' => \&numeric,
3250             fallback => 1,
3251 37     37   46365 );
  37         38022  
3252              
3253              
3254             sub numeric {
3255 4414     4414   7500 my ($left, $right) = @_;
3256 4414 50       15180 return ref $left ? $left->[0] : $right->[0];
3257             }
3258              
3259              
3260             sub stringify {
3261 2340     2340   465983 $_[0]->[1];
3262             }
3263             ################################################################################
3264             1;
3265             __END__