File Coverage

blib/lib/Text/CSV_PP.pm
Criterion Covered Total %
statement 1630 1717 94.9
branch 1191 1318 90.3
condition 740 898 82.2
subroutine 120 127 94.4
pod 66 67 98.5
total 3747 4127 90.7


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 34     34   55762 use strict;
  34         59  
  34         914  
11 34     34   140 use Exporter ();
  34         49  
  34         673  
12 34     34   131 use vars qw($VERSION @ISA @EXPORT_OK %EXPORT_TAGS);
  34         46  
  34         2144  
13 34     34   193 use Carp;
  34         73  
  34         16150  
14              
15             $VERSION = '2.02';
16             @ISA = qw(Exporter);
17              
18 4     4 1 13 sub PV { 0 }
19 10     10 1 1383 sub IV { 1 }
20 8     8 1 27 sub NV { 2 }
21              
22 0     0 1 0 sub CSV_TYPE_PV { PV }
23 0     0 1 0 sub CSV_TYPE_IV { IV }
24 0     0 1 0 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 0     0 1 0 sub CSV_FLAGS_IS_QUOTED { IS_QUOTED }
32 0     0 1 0 sub CSV_FLAGS_IS_BINARY { IS_BINARY }
33 0     0 1 0 sub CSV_FLAGS_ERROR_IN_FIELD { IS_ERROR }
34 0     0 1 0 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              
87             # EIQ - Error Inside Quotes
88             2021 => "EIQ - NL char inside quotes, binary off",
89             2022 => "EIQ - CR char inside quotes, binary off",
90             2023 => "EIQ - QUO character not allowed",
91             2024 => "EIQ - EOF cannot be escaped, not even inside quotes",
92             2025 => "EIQ - Loose unescaped escape",
93             2026 => "EIQ - Binary character inside quoted field, binary off",
94             2027 => "EIQ - Quoted field not terminated",
95              
96             # EIF - Error Inside Field
97             2030 => "EIF - NL char inside unquoted verbatim, binary off",
98             2031 => "EIF - CR char is first char of field, not part of EOL",
99             2032 => "EIF - CR char inside unquoted, not part of EOL",
100             2034 => "EIF - Loose unescaped quote",
101             2035 => "EIF - Escaped EOF in unquoted field",
102             2036 => "EIF - ESC error",
103             2037 => "EIF - Binary character in unquoted field, binary off",
104              
105             # Combine errors
106             2110 => "ECB - Binary character in Combine, binary off",
107              
108             # IO errors
109             2200 => "EIO - print to IO failed. See errno",
110              
111             # Hash-Ref errors
112             3001 => "EHR - Unsupported syntax for column_names ()",
113             3002 => "EHR - getline_hr () called before column_names ()",
114             3003 => "EHR - bind_columns () and column_names () fields count mismatch",
115             3004 => "EHR - bind_columns () only accepts refs to scalars",
116             3006 => "EHR - bind_columns () did not pass enough refs for parsed fields",
117             3007 => "EHR - bind_columns needs refs to writable scalars",
118             3008 => "EHR - unexpected error in bound fields",
119             3009 => "EHR - print_hr () called before column_names ()",
120             3010 => "EHR - print_hr () called with invalid arguments",
121              
122             4001 => "PRM - The key does not exist as field in the data",
123              
124             5001 => "PRM - The result does not match the output to append to",
125             5002 => "PRM - Unsupported output",
126              
127             0 => "",
128             };
129              
130             BEGIN {
131 34 50   34   311 if ( $] < 5.006 ) {
    50          
    50          
132 0 0       0 $INC{'bytes.pm'} = 1 unless $INC{'bytes.pm'}; # dummy
133 34     34   235 no strict 'refs';
  34         58  
  34         2470  
134 0         0 *{"utf8::is_utf8"} = sub { 0; };
  0         0  
  0         0  
135 0         0 *{"utf8::decode"} = sub { };
  0         0  
136             }
137             elsif ( $] < 5.008 ) {
138 34     34   188 no strict 'refs';
  34         49  
  34         9253  
139 0         0 *{"utf8::is_utf8"} = sub { 0; };
  0         0  
  0         0  
140 0         0 *{"utf8::decode"} = sub { };
  0         0  
141 0         0 *{"utf8::encode"} = sub { };
  0         0  
142             }
143             elsif ( !defined &utf8::is_utf8 ) {
144 0         0 require Encode;
145 0         0 *utf8::is_utf8 = *Encode::is_utf8;
146             }
147              
148 34         1853 eval q| require Scalar::Util |;
149 34 50       332606 if ( $@ ) {
150 0         0 eval q| require B |;
151 0 0       0 if ( $@ ) {
152 0         0 Carp::croak $@;
153             }
154             else {
155 0         0 my %tmap = qw(
156             B::NULL SCALAR
157             B::HV HASH
158             B::AV ARRAY
159             B::CV CODE
160             B::IO IO
161             B::GV GLOB
162             B::REGEXP REGEXP
163             );
164             *Scalar::Util::reftype = sub (\$) {
165 0         0 my $r = shift;
166 0 0       0 return undef unless length(ref($r));
167 0         0 my $t = ref(B::svref_2object($r));
168             return
169 0 0       0 exists $tmap{$t} ? $tmap{$t}
    0          
170             : length(ref($$r)) ? 'REF'
171             : 'SCALAR';
172 0         0 };
173             *Scalar::Util::readonly = sub (\$) {
174 0         0 my $b = B::svref_2object( $_[0] );
175 0         0 $b->FLAGS & 0x00800000; # SVf_READONLY?
176 0         0 };
177             }
178             }
179             }
180              
181             ################################################################################
182             #
183             # Common pure perl methods, taken almost directly from Text::CSV_XS.
184             # (These should be moved into a common class eventually, so that
185             # both XS and PP don't need to apply the same changes.)
186             #
187             ################################################################################
188              
189             ################################################################################
190             # version
191             ################################################################################
192              
193             sub version {
194 2     2 1 482 return $VERSION;
195             }
196              
197             ################################################################################
198             # new
199             ################################################################################
200              
201             my %def_attr = (
202             eol => '',
203             sep_char => ',',
204             quote_char => '"',
205             escape_char => '"',
206             binary => 0,
207             decode_utf8 => 1,
208             auto_diag => 0,
209             diag_verbose => 0,
210             strict => 0,
211             blank_is_undef => 0,
212             empty_is_undef => 0,
213             allow_whitespace => 0,
214             allow_loose_quotes => 0,
215             allow_loose_escapes => 0,
216             allow_unquoted_escape => 0,
217             always_quote => 0,
218             quote_empty => 0,
219             quote_space => 1,
220             quote_binary => 1,
221             escape_null => 1,
222             keep_meta_info => 0,
223             verbatim => 0,
224             formula => 0,
225             skip_empty_rows => 0,
226             undef_str => undef,
227             comment_str => undef,
228             types => undef,
229             callbacks => undef,
230              
231             _EOF => 0,
232             _RECNO => 0,
233             _STATUS => undef,
234             _FIELDS => undef,
235             _FFLAGS => undef,
236             _STRING => undef,
237             _ERROR_INPUT => undef,
238             _COLUMN_NAMES => undef,
239             _BOUND_COLUMNS => undef,
240             _AHEAD => undef,
241             _FORMULA_CB => undef,
242              
243             ENCODING => undef,
244             );
245              
246             my %attr_alias = (
247             quote_always => "always_quote",
248             verbose_diag => "diag_verbose",
249             quote_null => "escape_null",
250             escape => "escape_char",
251             comment => "comment_str",
252             );
253              
254             my $last_new_error = Text::CSV_PP->SetDiag(0);
255             my $ebcdic = ord("A") == 0xC1; # Faster than $Config{'ebcdic'}
256             my @internal_kh;
257             my $last_error;
258              
259             # NOT a method: is also used before bless
260             sub _unhealthy_whitespace {
261 15592     15592   21310 my ($self, $aw) = @_;
262 15592 100       36084 $aw or return 0; # no checks needed without allow_whitespace
263              
264 3568         4339 my $quo = $self->{quote};
265 3568 100 100     6735 defined $quo && length ($quo) or $quo = $self->{quote_char};
266 3568         4097 my $esc = $self->{escape_char};
267              
268 3568 100 100     13070 defined $quo && $quo =~ m/^[ \t]/ and return 1002;
269 3326 100 100     8974 defined $esc && $esc =~ m/^[ \t]/ and return 1002;
270              
271 3036         6025 return 0;
272             }
273              
274             sub _check_sanity {
275 12286     12286   15156 my $self = shift;
276              
277 12286         15393 my $eol = $self->{eol};
278 12286         14613 my $sep = $self->{sep};
279 12286 100 100     24337 defined $sep && length ($sep) or $sep = $self->{sep_char};
280 12286         14948 my $quo = $self->{quote};
281 12286 100 100     22736 defined $quo && length ($quo) or $quo = $self->{quote_char};
282 12286         14688 my $esc = $self->{escape_char};
283              
284             # use DP;::diag ("SEP: '", DPeek ($sep),
285             # "', QUO: '", DPeek ($quo),
286             # "', ESC: '", DPeek ($esc),"'");
287              
288             # sep_char should not be undefined
289 12286 100       19263 $sep ne "" or return 1008;
290 12284 100       19366 length ($sep) > 16 and return 1006;
291 12283 100       26421 $sep =~ m/[\r\n]/ and return 1003;
292              
293 12277 100       18608 if (defined $quo) {
294 12266 100       16846 $quo eq $sep and return 1001;
295 12038 100       17498 length ($quo) > 16 and return 1007;
296 12037 100       17867 $quo =~ m/[\r\n]/ and return 1003;
297             }
298 12042 100       17013 if (defined $esc) {
299 12026 100       16343 $esc eq $sep and return 1001;
300 11858 100       17677 $esc =~ m/[\r\n]/ and return 1003;
301             }
302 11868 100       15509 if (defined $eol) {
303 11864 100       16799 length ($eol) > 16 and return 1005;
304             }
305              
306 11867         17515 return _unhealthy_whitespace ($self, $self->{allow_whitespace});
307             }
308              
309             sub known_attributes {
310 3     3 1 519 sort grep !m/^_/ => "sep", "quote", keys %def_attr;
311             }
312              
313             sub new {
314 910     910 1 2269 $last_new_error = Text::CSV_PP->SetDiag(1000,
315             'usage: my $csv = Text::CSV_PP->new ([{ option => value, ... }]);');
316              
317 910         1360 my $proto = shift;
318 910 100 66     2856 my $class = ref $proto || $proto or return;
319 909 100 100     3224 @_ > 0 && ref $_[0] ne "HASH" and return;
320 901   100     1801 my $attr = shift || {};
321             my %attr = map {
322 901 100       2429 my $k = m/^[a-zA-Z]\w+$/ ? lc $_ : $_;
  2038         6654  
323 2038 100       3500 exists $attr_alias{$k} and $k = $attr_alias{$k};
324 2038         4665 ($k => $attr->{$_});
325             } keys %$attr;
326              
327 901         1537 my $sep_aliased = 0;
328 901 100       1611 if (exists $attr{sep}) {
329 7         16 $attr{sep_char} = delete $attr{sep};
330 7         23 $sep_aliased = 1;
331             }
332 901         1057 my $quote_aliased = 0;
333 901 100       1459 if (exists $attr{quote}) {
334 25         45 $attr{quote_char} = delete $attr{quote};
335 25         38 $quote_aliased = 1;
336             }
337             exists $attr{formula_handling} and
338 901 100       1375 $attr{formula} = delete $attr{formula_handling};
339 901         1094 my $attr_formula = delete $attr{formula};
340              
341 901         1891 for (keys %attr) {
342 2002 100 100     5947 if (m/^[a-z]/ && exists $def_attr{$_}) {
343             # uncoverable condition false
344 1995 100 100     5607 defined $attr{$_} && m/_char$/ and utf8::decode ($attr{$_});
345 1995         2730 next;
346             }
347             # croak?
348 7         27 $last_new_error = Text::CSV_PP->SetDiag(1000, "INI - Unknown attribute '$_'");
349 7 100       20 $attr{auto_diag} and error_diag ();
350 7         25 return;
351             }
352 894 100       1585 if ($sep_aliased) {
353 7         35 my @b = unpack "U0C*", $attr{sep_char};
354 7 100       19 if (@b > 1) {
355 6         13 $attr{sep} = $attr{sep_char};
356 6         12 $attr{sep_char} = "\0";
357             }
358             else {
359 1         2 $attr{sep} = undef;
360             }
361             }
362 894 100 100     1709 if ($quote_aliased and defined $attr{quote_char}) {
363 21         65 my @b = unpack "U0C*", $attr{quote_char};
364 21 100       41 if (@b > 1) {
365 7         15 $attr{quote} = $attr{quote_char};
366 7         14 $attr{quote_char} = "\0";
367             }
368             else {
369 14         25 $attr{quote} = undef;
370             }
371             }
372              
373 894         12741 my $self = { %def_attr, %attr };
374 894 100       2793 if (my $ec = _check_sanity ($self)) {
375 35         97 $last_new_error = Text::CSV_PP->SetDiag($ec);
376 35 100       64 $attr{auto_diag} and error_diag ();
377 35         191 return;
378             }
379 859 100 100     2169 if (defined $self->{callbacks} && ref $self->{callbacks} ne "HASH") {
380 6         695 Carp::carp "The 'callbacks' attribute is set but is not a hash: ignored\n";
381 6         156 $self->{callbacks} = undef;
382             }
383              
384 859         1549 $last_new_error = Text::CSV_PP->SetDiag(0);
385 859 100 100     2202 defined $\ && !exists $attr{eol} and $self->{eol} = $\;
386 859         1205 bless $self, $class;
387 859 100       1753 defined $self->{types} and $self->types ($self->{types});
388 859 100       1439 defined $attr_formula and $self->{formula} = _supported_formula($self, $attr_formula);
389 858         3058 $self;
390             }
391              
392             # Keep in sync with XS!
393             my %_cache_id = ( # Only expose what is accessed from within PM
394             quote_char => 0,
395             escape_char => 1,
396             sep_char => 2,
397             sep => 39, # 39 .. 55
398             binary => 3,
399             keep_meta_info => 4,
400             always_quote => 5,
401             allow_loose_quotes => 6,
402             allow_loose_escapes => 7,
403             allow_unquoted_escape => 8,
404             allow_whitespace => 9,
405             blank_is_undef => 10,
406             eol => 11,
407             quote => 15,
408             verbatim => 22,
409             empty_is_undef => 23,
410             auto_diag => 24,
411             diag_verbose => 33,
412             quote_space => 25,
413             quote_empty => 37,
414             quote_binary => 32,
415             escape_null => 31,
416             decode_utf8 => 35,
417             _has_ahead => 30,
418             _has_hooks => 36,
419             _is_bound => 26, # 26 .. 29
420             formula => 38,
421             strict => 42,
422             skip_empty_rows => 43,
423             undef_str => 46,
424             comment_str => 54,
425             types => 62,
426             );
427              
428             my %_hidden_cache_id = qw(
429             sep_len 38
430             eol_len 12
431             eol_is_cr 13
432             quo_len 16
433             has_error_input 34
434             );
435              
436             my %_reverse_cache_id = (
437             map({$_cache_id{$_} => $_} keys %_cache_id),
438             map({$_hidden_cache_id{$_} => $_} keys %_hidden_cache_id),
439             );
440              
441             # A `character'
442             sub _set_attr_C {
443 11084     11084   19266 my ($self, $name, $val, $ec) = @_;
444 11084 100       27970 defined $val and utf8::decode($val);
445 11084         14166 $self->{$name} = $val;
446 11084 100       14867 $ec = _check_sanity ($self) and croak ($self->SetDiag ($ec));
447 10174         19444 $self->_cache_set ($_cache_id{$name}, $val);
448             }
449              
450             # A flag
451             sub _set_attr_X {
452 5645     5645   8408 my ($self, $name, $val) = @_;
453 5645 100       8877 defined $val or $val = 0;
454 5645         7673 $self->{$name} = $val;
455 5645         11819 $self->_cache_set ($_cache_id{$name}, 0 + $val);
456             }
457              
458             # A number
459             sub _set_attr_N {
460 38     38   81 my ($self, $name, $val) = @_;
461 38         71 $self->{$name} = $val;
462 38         125 $self->_cache_set ($_cache_id{$name}, 0 + $val);
463             }
464              
465             # Accessor methods.
466             # It is unwise to change them halfway through a single file!
467             sub quote_char {
468 4836     4836 1 592370 my $self = shift;
469 4836 100       9621 if (@_) {
470 3601         6851 $self->_set_attr_C ("quote_char", shift);
471 3374         5283 $self->_cache_set ($_cache_id{quote}, "");
472             }
473 4609         11486 $self->{quote_char};
474             }
475              
476             sub quote {
477 20     20 1 37 my $self = shift;
478 20 100       51 if (@_) {
479 11         13 my $quote = shift;
480 11 100       42 defined $quote or $quote = "";
481 11         29 utf8::decode ($quote);
482 11         40 my @b = unpack "U0C*", $quote;
483 11 100       25 if (@b > 1) {
484 5 100       13 @b > 16 and croak ($self->SetDiag (1007));
485 4         15 $self->quote_char ("\0");
486             }
487             else {
488 6         13 $self->quote_char ($quote);
489 6         9 $quote = "";
490             }
491 10         15 $self->{quote} = $quote;
492              
493 10         17 my $ec = _check_sanity ($self);
494 10 100       31 $ec and croak ($self->SetDiag ($ec));
495              
496 9         15 $self->_cache_set ($_cache_id{quote}, $quote);
497             }
498 18         27 my $quote = $self->{quote};
499 18 100 100     102 defined $quote && length ($quote) ? $quote : $self->{quote_char};
500             }
501              
502             sub escape_char {
503 4827     4827 1 596480 my $self = shift;
504 4827 100       8792 if (@_) {
505 3595         4920 my $ec = shift;
506 3595         7086 $self->_set_attr_C ("escape_char", $ec);
507 3480 100       5624 $ec or $self->_set_attr_X ("escape_null", 0);
508             }
509 4712         11708 $self->{escape_char};
510             }
511              
512             sub sep_char {
513 5131     5131 1 593490 my $self = shift;
514 5131 100       10216 if (@_) {
515 3888         7906 $self->_set_attr_C ("sep_char", shift);
516 3320         5434 $self->_cache_set ($_cache_id{sep}, "");
517             }
518 4563         11428 $self->{sep_char};
519             }
520              
521             sub sep {
522 335     335 1 2901 my $self = shift;
523 335 100       627 if (@_) {
524 302         410 my $sep = shift;
525 302 100       483 defined $sep or $sep = "";
526 302         821 utf8::decode ($sep);
527 302         881 my @b = unpack "U0C*", $sep;
528 302 100       586 if (@b > 1) {
529 13 100       31 @b > 16 and croak ($self->SetDiag (1006));
530 12         26 $self->sep_char ("\0");
531             }
532             else {
533 289         653 $self->sep_char ($sep);
534 286         356 $sep = "";
535             }
536 298         450 $self->{sep} = $sep;
537              
538 298         383 my $ec = _check_sanity ($self);
539 298 100       459 $ec and croak ($self->SetDiag ($ec));
540              
541 297         430 $self->_cache_set ($_cache_id{sep}, $sep);
542             }
543 330         455 my $sep = $self->{sep};
544 330 100 100     1146 defined $sep && length ($sep) ? $sep : $self->{sep_char};
545             }
546              
547             sub eol {
548 157     157 1 2723 my $self = shift;
549 157 100       305 if (@_) {
550 125         182 my $eol = shift;
551 125 100       216 defined $eol or $eol = "";
552 125 100       261 length ($eol) > 16 and croak ($self->SetDiag (1005));
553 124         197 $self->{eol} = $eol;
554 124         257 $self->_cache_set ($_cache_id{eol}, $eol);
555             }
556 156         272 $self->{eol};
557             }
558              
559             sub always_quote {
560 3033     3033 1 604192 my $self = shift;
561 3033 100       7231 @_ and $self->_set_attr_X ("always_quote", shift);
562 3033         7166 $self->{always_quote};
563             }
564              
565             sub quote_space {
566 10     10 1 27 my $self = shift;
567 10 100       33 @_ and $self->_set_attr_X ("quote_space", shift);
568 10         41 $self->{quote_space};
569             }
570              
571             sub quote_empty {
572 5     5 1 11 my $self = shift;
573 5 100       18 @_ and $self->_set_attr_X ("quote_empty", shift);
574 5         20 $self->{quote_empty};
575             }
576              
577             sub escape_null {
578 6     6 1 9 my $self = shift;
579 6 100       17 @_ and $self->_set_attr_X ("escape_null", shift);
580 6         19 $self->{escape_null};
581             }
582              
583 3     3 0 10 sub quote_null { goto &escape_null; }
584              
585             sub quote_binary {
586 7     7 1 20 my $self = shift;
587 7 100       25 @_ and $self->_set_attr_X ("quote_binary", shift);
588 7         19 $self->{quote_binary};
589             }
590              
591             sub binary {
592 21     21 1 2269 my $self = shift;
593 21 100       88 @_ and $self->_set_attr_X ("binary", shift);
594 21         51 $self->{binary};
595             }
596              
597             sub strict {
598 2     2 1 5 my $self = shift;
599 2 100       6 @_ and $self->_set_attr_X ("strict", shift);
600 2         7 $self->{strict};
601             }
602              
603             sub skip_empty_rows {
604 2     2 1 2 my $self = shift;
605 2 100       8 @_ and $self->_set_attr_X ("skip_empty_rows", shift);
606 2         6 $self->{skip_empty_rows};
607             }
608              
609             sub _SetDiagInfo {
610 17     17   30 my ($self, $err, $msg) = @_;
611 17         44 $self->SetDiag ($err);
612 17         34 my $em = $self->error_diag;
613 17 50       35 $em =~ s/^\d+$// and $msg =~ s/^/# /;
614 17 50       33 my $sep = $em =~ m/[;\n]$/ ? "\n\t" : ": ";
615 17         31 join $sep => grep m/\S\S\S/ => $em, $msg;
616             }
617              
618             sub _supported_formula {
619 103     103   145 my ($self, $f) = @_;
620 103 100       151 defined $f or return 5;
621 102 100 66     432 if ($self && $f && ref $f && ref $f eq "CODE") {
      100        
      100        
622 6         9 $self->{_FORMULA_CB} = $f;
623 6         15 return 6;
624             }
625             $f =~ m/^(?: 0 | none )$/xi ? 0 :
626             $f =~ m/^(?: 1 | die )$/xi ? 1 :
627             $f =~ m/^(?: 2 | croak )$/xi ? 2 :
628             $f =~ m/^(?: 3 | diag )$/xi ? 3 :
629             $f =~ m/^(?: 4 | empty | )$/xi ? 4 :
630             $f =~ m/^(?: 5 | undef )$/xi ? 5 :
631 96 100       707 $f =~ m/^(?: 6 | cb )$/xi ? 6 : do {
    100          
    100          
    100          
    100          
    100          
    100          
632 7   50     12 $self ||= "Text::CSV_PP";
633 7         30 croak ($self->_SetDiagInfo (1500, "formula-handling '$f' is not supported"));
634             };
635             }
636              
637             sub formula {
638 44     44 1 3108 my $self = shift;
639 44 100       122 @_ and $self->_set_attr_N ("formula", _supported_formula ($self, shift));
640 38 100       85 $self->{formula} == 6 or $self->{_FORMULA_CB} = undef;
641 38         98 [qw( none die croak diag empty undef cb )]->[_supported_formula ($self, $self->{formula})];
642             }
643             sub formula_handling {
644 7     7 1 11 my $self = shift;
645 7         15 $self->formula (@_);
646             }
647              
648             sub decode_utf8 {
649 2     2 1 4 my $self = shift;
650 2 100       7 @_ and $self->_set_attr_X ("decode_utf8", shift);
651 2         6 $self->{decode_utf8};
652             }
653              
654             sub keep_meta_info {
655 12     12 1 188 my $self = shift;
656 12 100       34 if (@_) {
657 11         18 my $v = shift;
658 11 100 100     48 !defined $v || $v eq "" and $v = 0;
659 11 100       50 $v =~ m/^[0-9]/ or $v = lc $v eq "false" ? 0 : 1; # true/truth = 1
    100          
660 11         31 $self->_set_attr_X ("keep_meta_info", $v);
661             }
662 12         47 $self->{keep_meta_info};
663             }
664              
665             sub allow_loose_quotes {
666 12     12 1 20 my $self = shift;
667 12 100       53 @_ and $self->_set_attr_X ("allow_loose_quotes", shift);
668 12         22 $self->{allow_loose_quotes};
669             }
670              
671             sub allow_loose_escapes {
672 12     12 1 1181 my $self = shift;
673 12 100       51 @_ and $self->_set_attr_X ("allow_loose_escapes", shift);
674 12         25 $self->{allow_loose_escapes};
675             }
676              
677             sub allow_whitespace {
678 4954     4954 1 1715964 my $self = shift;
679 4954 100       10571 if (@_) {
680 3725         4386 my $aw = shift;
681 3725 100       6152 _unhealthy_whitespace ($self, $aw) and
682             croak ($self->SetDiag (1002));
683 3721         7318 $self->_set_attr_X ("allow_whitespace", $aw);
684             }
685 4950         12840 $self->{allow_whitespace};
686             }
687              
688             sub allow_unquoted_escape {
689 4     4 1 9 my $self = shift;
690 4 100       18 @_ and $self->_set_attr_X ("allow_unquoted_escape", shift);
691 4         35 $self->{allow_unquoted_escape};
692             }
693              
694             sub blank_is_undef {
695 3     3 1 5 my $self = shift;
696 3 100       13 @_ and $self->_set_attr_X ("blank_is_undef", shift);
697 3         9 $self->{blank_is_undef};
698             }
699              
700             sub empty_is_undef {
701 2     2 1 4 my $self = shift;
702 2 100       7 @_ and $self->_set_attr_X ("empty_is_undef", shift);
703 2         6 $self->{empty_is_undef};
704             }
705              
706             sub verbatim {
707 9     9 1 4342 my $self = shift;
708 9 100       30 @_ and $self->_set_attr_X ("verbatim", shift);
709 9         23 $self->{verbatim};
710             }
711              
712             sub undef_str {
713 12     12 1 2657 my $self = shift;
714 12 100       27 if (@_) {
715 11         17 my $v = shift;
716 11 100       38 $self->{undef_str} = defined $v ? "$v" : undef;
717 11         31 $self->_cache_set ($_cache_id{undef_str}, $self->{undef_str});
718             }
719 12         35 $self->{undef_str};
720             }
721              
722             sub comment_str {
723 15     15 1 62 my $self = shift;
724 15 100       32 if (@_) {
725 14         19 my $v = shift;
726 14 100       44 $self->{comment_str} = defined $v ? "$v" : undef;
727 14         36 $self->_cache_set ($_cache_id{comment_str}, $self->{comment_str});
728             }
729 15         32 $self->{comment_str};
730             }
731              
732             sub auto_diag {
733 12     12 1 424 my $self = shift;
734 12 100       31 if (@_) {
735 9         13 my $v = shift;
736 9 100 100     61 !defined $v || $v eq "" and $v = 0;
737 9 100       40 $v =~ m/^[0-9]/ or $v = lc $v eq "false" ? 0 : 1; # true/truth = 1
    100          
738 9         22 $self->_set_attr_X ("auto_diag", $v);
739             }
740 12         49 $self->{auto_diag};
741             }
742              
743             sub diag_verbose {
744 10     10 1 450 my $self = shift;
745 10 100       23 if (@_) {
746 8         12 my $v = shift;
747 8 100 100     34 !defined $v || $v eq "" and $v = 0;
748 8 100       47 $v =~ m/^[0-9]/ or $v = lc $v eq "false" ? 0 : 1; # true/truth = 1
    100          
749 8         21 $self->_set_attr_X ("diag_verbose", $v);
750             }
751 10         34 $self->{diag_verbose};
752             }
753              
754             ################################################################################
755             # status
756             ################################################################################
757              
758             sub status {
759 5     5 1 16 $_[0]->{_STATUS};
760             }
761              
762             sub eof {
763 33     33 1 626 $_[0]->{_EOF};
764             }
765              
766             sub types {
767 7     7 1 1611 my $self = shift;
768              
769 7 100       16 if (@_) {
770 2 100       7 if (my $types = shift) {
771 1         2 $self->{'_types'} = join("", map{ chr($_) } @$types);
  3         9  
772 1         3 $self->{'types'} = $types;
773 1         3 $self->_cache_set ($_cache_id{'types'}, $self->{'_types'});
774             }
775             else {
776 1         3 delete $self->{'types'};
777 1         2 delete $self->{'_types'};
778 1         8 $self->_cache_set ($_cache_id{'types'}, undef);
779 1         4 undef;
780             }
781             }
782             else {
783 5         21 $self->{'types'};
784             }
785             }
786              
787             sub callbacks {
788 73     73 1 16785 my $self = shift;
789 73 100       155 if (@_) {
790 43         45 my $cb;
791 43         44 my $hf = 0x00;
792 43 100       83 if (defined $_[0]) {
    100          
793 41 100       51 grep { !defined } @_ and croak ($self->SetDiag (1004));
  73         159  
794 39 100 100     159 $cb = @_ == 1 && ref $_[0] eq "HASH" ? shift
    100          
795             : @_ % 2 == 0 ? { @_ }
796             : croak ($self->SetDiag (1004));
797 34         83 foreach my $cbk (keys %$cb) {
798             # A key cannot be a ref. That would be stored as the *string
799             # 'SCALAR(0x1f3e710)' or 'ARRAY(0x1a5ae18)'
800 36 100 100     223 $cbk =~ m/^[\w.]+$/ && ref $cb->{$cbk} eq "CODE" or
801             croak ($self->SetDiag (1004));
802             }
803 20 100       49 exists $cb->{error} and $hf |= 0x01;
804 20 100       38 exists $cb->{after_parse} and $hf |= 0x02;
805 20 100       31 exists $cb->{before_print} and $hf |= 0x04;
806             }
807             elsif (@_ > 1) {
808             # (undef, whatever)
809 1         3 croak ($self->SetDiag (1004));
810             }
811 21         54 $self->_set_attr_X ("_has_hooks", $hf);
812 21         41 $self->{callbacks} = $cb;
813             }
814 51         117 $self->{callbacks};
815             }
816              
817             ################################################################################
818             # error_diag
819             ################################################################################
820              
821             sub error_diag {
822 1692     1692 1 32654 my $self = shift;
823 1692         3916 my @diag = (0 + $last_new_error, $last_new_error, 0, 0, 0);
824              
825             # Docs state to NEVER use UNIVERSAL::isa, because it will *never* call an
826             # overridden isa method in any class. Well, that is exacly what I want here
827 1692 100 100     11803 if ($self && ref $self && # Not a class method or direct call
      100        
      100        
828             UNIVERSAL::isa ($self, __PACKAGE__) && exists $self->{_ERROR_DIAG}) {
829 1517         2653 $diag[0] = 0 + $self->{_ERROR_DIAG};
830 1517         2488 $diag[1] = $self->{_ERROR_DIAG};
831 1517 100       2718 $diag[2] = 1 + $self->{_ERROR_POS} if exists $self->{_ERROR_POS};
832 1517         1958 $diag[3] = $self->{_RECNO};
833 1517 100       2371 $diag[4] = $self->{_ERROR_FLD} if exists $self->{_ERROR_FLD};
834              
835             $diag[0] && $self->{callbacks} && $self->{callbacks}{error} and
836 1517 100 100     4548 return $self->{callbacks}{error}->(@diag);
      100        
837             }
838              
839 1683         2246 my $context = wantarray;
840              
841 1683 100       2696 unless (defined $context) { # Void context, auto-diag
842 263 100 100     675 if ($diag[0] && $diag[0] != 2012) {
843 16         44 my $msg = "# CSV_PP ERROR: $diag[0] - $diag[1] \@ rec $diag[3] pos $diag[2]\n";
844 16 100       76 $diag[4] and $msg =~ s/$/ field $diag[4]/;
845              
846 16 100 100     59 unless ($self && ref $self) { # auto_diag
847             # called without args in void context
848 4         35 warn $msg;
849 4         24 return;
850             }
851              
852             $self->{diag_verbose} and $self->{_ERROR_INPUT} and
853 12 50 66     37 $msg .= "$self->{_ERROR_INPUT}'\n".
854             (" " x ($diag[2] - 1))."^\n";
855              
856 12         32 my $lvl = $self->{auto_diag};
857 12 100       24 if ($lvl < 2) {
858 9         55 my @c = caller (2);
859 9 50 66     61 if (@c >= 11 && $c[10] && ref $c[10] eq "HASH") {
      33        
860 0         0 my $hints = $c[10];
861             (exists $hints->{autodie} && $hints->{autodie} or
862             exists $hints->{"guard Fatal"} &&
863 0 0 0     0 !exists $hints->{"no Fatal"}) and
      0        
      0        
864             $lvl++;
865             # Future releases of autodie will probably set $^H{autodie}
866             # to "autodie @args", like "autodie :all" or "autodie open"
867             # so we can/should check for "open" or "new"
868             }
869             }
870 12 100       118 $lvl > 1 ? die $msg : warn $msg;
871             }
872 256         508 return;
873             }
874              
875 1420 100       3747 return $context ? @diag : $diag[1];
876             }
877              
878             sub record_number {
879 3     3 1 11 return shift->{_RECNO};
880             }
881              
882             ################################################################################
883             # string
884             ################################################################################
885              
886             *string = \&_string;
887             sub _string {
888 1401 100   1401   359000 defined $_[0]->{_STRING} ? ${ $_[0]->{_STRING} } : undef;
  1400         4826  
889             }
890              
891             ################################################################################
892             # fields
893             ################################################################################
894              
895             *fields = \&_fields;
896             sub _fields {
897 1614 100   1614   20124 ref($_[0]->{_FIELDS}) ? @{$_[0]->{_FIELDS}} : undef;
  1613         8141  
898             }
899              
900             ################################################################################
901             # meta_info
902             ################################################################################
903              
904             sub meta_info {
905 21 100   21 1 552 $_[0]->{_FFLAGS} ? @{ $_[0]->{_FFLAGS} } : undef;
  16         55  
906             }
907              
908             sub is_quoted {
909 29 100   29 1 80 return unless (defined $_[0]->{_FFLAGS});
910 26 100 66     106 return if( $_[1] =~ /\D/ or $_[1] < 0 or $_[1] > $#{ $_[0]->{_FFLAGS} } );
  25   100     71  
911              
912 24 100       88 $_[0]->{_FFLAGS}->[$_[1]] & IS_QUOTED ? 1 : 0;
913             }
914              
915             sub is_binary {
916 11 100   11 1 41 return unless (defined $_[0]->{_FFLAGS});
917 10 100 66     71 return if( $_[1] =~ /\D/ or $_[1] < 0 or $_[1] > $#{ $_[0]->{_FFLAGS} } );
  9   100     41  
918 8 100       51 $_[0]->{_FFLAGS}->[$_[1]] & IS_BINARY ? 1 : 0;
919             }
920              
921             sub is_missing {
922 19     19 1 36 my ($self, $idx, $val) = @_;
923 19 100       57 return unless $self->{keep_meta_info}; # FIXME
924 13 100 100     58 $idx < 0 || !ref $self->{_FFLAGS} and return;
925 11 100       13 $idx >= @{$self->{_FFLAGS}} and return 1;
  11         52  
926 10 100       50 $self->{_FFLAGS}[$idx] & IS_MISSING ? 1 : 0;
927             }
928              
929             ################################################################################
930             # combine
931             ################################################################################
932             *combine = \&_combine;
933             sub _combine {
934 1399     1399   626951 my ($self, @fields) = @_;
935 1399         2400 my $str = "";
936 1399         4426 $self->{_FIELDS} = \@fields;
937 1399   100     5392 $self->{_STATUS} = (@fields > 0) && $self->__combine(\$str, \@fields, 0);
938 1395         2795 $self->{_STRING} = \$str;
939 1395         3552 $self->{_STATUS};
940             }
941              
942             ################################################################################
943             # parse
944             ################################################################################
945             *parse = \&_parse;
946             sub _parse {
947 1953     1953   83121 my ($self, $str) = @_;
948              
949 1953 100       3904 ref $str and croak ($self->SetDiag (1500));
950              
951 1949         2891 my $fields = [];
952 1949         2508 my $fflags = [];
953 1949         3469 $self->{_STRING} = \$str;
954 1949 100 100     5946 if (defined $str && $self->__parse ($fields, $fflags, $str, 0)) {
955 1739         4488 $self->{_FIELDS} = $fields;
956 1739         2708 $self->{_FFLAGS} = $fflags;
957 1739         2476 $self->{_STATUS} = 1;
958             }
959             else {
960 207         325 $self->{_FIELDS} = undef;
961 207         265 $self->{_FFLAGS} = undef;
962 207         277 $self->{_STATUS} = 0;
963             }
964 1946         8035 $self->{_STATUS};
965             }
966              
967             sub column_names {
968 950     950 1 42705 my ( $self, @columns ) = @_;
969              
970 950 100       2322 @columns or return defined $self->{_COLUMN_NAMES} ? @{$self->{_COLUMN_NAMES}} : ();
  271 100       925  
971 636 100 100     1993 @columns == 1 && ! defined $columns[0] and return $self->{_COLUMN_NAMES} = undef;
972              
973 498 100 100     1429 if ( @columns == 1 && ref $columns[0] eq "ARRAY" ) {
    100          
974 201         217 @columns = @{ $columns[0] };
  201         371  
975             }
976 610 100       1567 elsif ( join "", map { defined $_ ? ref $_ : "" } @columns ) {
977 5         15 croak $self->SetDiag( 3001 );
978             }
979              
980 493 100 100     1043 if ( $self->{_BOUND_COLUMNS} && @columns != @{$self->{_BOUND_COLUMNS}} ) {
  2         6  
981 1         3 croak $self->SetDiag( 3003 );
982             }
983              
984 492 100       605 $self->{_COLUMN_NAMES} = [ map { defined $_ ? $_ : "\cAUNDEF\cA" } @columns ];
  1079         2301  
985 492         630 @{ $self->{_COLUMN_NAMES} };
  492         930  
986             }
987              
988             sub header {
989 306     306 1 32813 my ($self, $fh, @args) = @_;
990              
991 306 100       587 $fh or croak ($self->SetDiag (1014));
992              
993 305         375 my (@seps, %args);
994 305         535 for (@args) {
995 198 100       334 if (ref $_ eq "ARRAY") {
996 18         51 push @seps, @$_;
997 18         30 next;
998             }
999 180 100       324 if (ref $_ eq "HASH") {
1000 179         298 %args = %$_;
1001 179         310 next;
1002             }
1003 1         140 croak (q{usage: $csv->header ($fh, [ seps ], { options })});
1004             }
1005              
1006             defined $args{munge} && !defined $args{munge_column_names} and
1007 304 100 66     622 $args{munge_column_names} = $args{munge}; # munge as alias
1008 304 100       695 defined $args{detect_bom} or $args{detect_bom} = 1;
1009 304 100       555 defined $args{set_column_names} or $args{set_column_names} = 1;
1010 304 100       603 defined $args{munge_column_names} or $args{munge_column_names} = "lc";
1011              
1012             # Reset any previous leftovers
1013 304         426 $self->{_RECNO} = 0;
1014 304         360 $self->{_AHEAD} = undef;
1015 304 100       584 $self->{_COLUMN_NAMES} = undef if $args{set_column_names};
1016 304 100       481 $self->{_BOUND_COLUMNS} = undef if $args{set_column_names};
1017 304         801 $self->_cache_set($_cache_id{'_has_ahead'}, 0);
1018              
1019 304 100       494 if (defined $args{sep_set}) {
1020 15 100       39 ref $args{sep_set} eq "ARRAY" or
1021             croak ($self->_SetDiagInfo (1500, "sep_set should be an array ref"));
1022 10         13 @seps = @{$args{sep_set}};
  10         22  
1023             }
1024              
1025 299 50       692 $^O eq "MSWin32" and binmode $fh;
1026 299         4616 my $hdr = <$fh>;
1027             # check if $hdr can be empty here, I don't think so
1028 299 100 66     1432 defined $hdr && $hdr ne "" or croak ($self->SetDiag (1010));
1029              
1030 297         371 my %sep;
1031 297 100       759 @seps or @seps = (",", ";");
1032 297         502 foreach my $sep (@seps) {
1033 690 100       1660 index ($hdr, $sep) >= 0 and $sep{$sep}++;
1034             }
1035              
1036 297 100       516 keys %sep >= 2 and croak ($self->SetDiag (1011));
1037              
1038 296         840 $self->sep (keys %sep);
1039 296         433 my $enc = "";
1040 296 100       554 if ($args{detect_bom}) { # UTF-7 is not supported
1041 295 100       2015 if ($hdr =~ s/^\x00\x00\xfe\xff//) { $enc = "utf-32be" }
  24 100       37  
    100          
    100          
    100          
    100          
    100          
    100          
    100          
    100          
    100          
1042 24         42 elsif ($hdr =~ s/^\xff\xfe\x00\x00//) { $enc = "utf-32le" }
1043 25         51 elsif ($hdr =~ s/^\xfe\xff//) { $enc = "utf-16be" }
1044 24         36 elsif ($hdr =~ s/^\xff\xfe//) { $enc = "utf-16le" }
1045 48         64 elsif ($hdr =~ s/^\xef\xbb\xbf//) { $enc = "utf-8" }
1046 1         2 elsif ($hdr =~ s/^\xf7\x64\x4c//) { $enc = "utf-1" }
1047 1         3 elsif ($hdr =~ s/^\xdd\x73\x66\x73//) { $enc = "utf-ebcdic" }
1048 1         2 elsif ($hdr =~ s/^\x0e\xfe\xff//) { $enc = "scsu" }
1049 1         2 elsif ($hdr =~ s/^\xfb\xee\x28//) { $enc = "bocu-1" }
1050 1         1 elsif ($hdr =~ s/^\x84\x31\x95\x33//) { $enc = "gb-18030" }
1051 36         56 elsif ($hdr =~ s/^\x{feff}//) { $enc = "" }
1052              
1053 295 100       593 $self->{ENCODING} = $enc ? uc $enc : undef;
1054              
1055 295 100       479 $hdr eq "" and croak ($self->SetDiag (1010));
1056              
1057 289 100       453 if ($enc) {
1058 144 50 33     262 $ebcdic && $enc eq "utf-ebcdic" and $enc = "";
1059 144 100       330 if ($enc =~ m/([13]).le$/) {
1060 48         127 my $l = 0 + $1;
1061 48         57 my $x;
1062 48         95 $hdr .= "\0" x $l;
1063 48         135 read $fh, $x, $l;
1064             }
1065 144 50       209 if ($enc) {
1066 144 100       241 if ($enc ne "utf-8") {
1067 96         449 require Encode;
1068 96         446 $hdr = Encode::decode ($enc, $hdr);
1069             }
1070 144         4682 binmode $fh, ":encoding($enc)";
1071             }
1072             }
1073             }
1074              
1075 290         7199 my ($ahead, $eol);
1076 290 100 66     1239 if ($hdr and $hdr =~ s/\Asep=(\S)([\r\n]+)//i) { # Also look in xs:Parse
1077 1         4 $self->sep ($1);
1078 1 50       5 length $hdr or $hdr = <$fh>;
1079             }
1080              
1081 290 100       1587 if ($hdr =~ s/^([^\r\n]+)([\r\n]+)([^\r\n].+)\z/$1/s) {
1082 142         271 $eol = $2;
1083 142         220 $ahead = $3;
1084             }
1085              
1086 290         417 my $hr = \$hdr; # Will cause croak on perl-5.6.x
1087 290 50       2598 open my $h, "<", $hr or croak ($self->SetDiag (1010));
1088              
1089 290 100       1994 my $row = $self->getline ($h) or croak;
1090 288         695 close $h;
1091              
1092 288 100       588 if ( $args{'munge_column_names'} eq "lc") {
    100          
    100          
1093 269         280 $_ = lc for @{$row};
  269         793  
1094             }
1095             elsif ($args{'munge_column_names'} eq "uc") {
1096 7         15 $_ = uc for @{$row};
  7         25  
1097             }
1098             elsif ($args{'munge_column_names'} eq "db") {
1099 3         4 for (@{$row}) {
  3         7  
1100 7         15 s/\W+/_/g;
1101 7         13 s/^_+//;
1102 7         20 $_ = lc;
1103             }
1104             }
1105              
1106 288 100       519 if ($ahead) { # Must be after getline, which creates the cache
1107 142         399 $self->_cache_set ($_cache_id{_has_ahead}, 1);
1108 142         196 $self->{_AHEAD} = $ahead;
1109 142 100       585 $eol =~ m/^\r([^\n]|\z)/ and $self->eol ($eol);
1110             }
1111              
1112 288         557 my @hdr = @$row;
1113             ref $args{munge_column_names} eq "CODE" and
1114 288 100       570 @hdr = map { $args{munge_column_names}->($_) } @hdr;
  4         15  
1115             ref $args{munge_column_names} eq "HASH" and
1116 288 100       485 @hdr = map { $args{munge_column_names}->{$_} || $_ } @hdr;
  3 100       11  
1117 288         330 my %hdr; $hdr{$_}++ for @hdr;
  288         796  
1118 288 100       509 exists $hdr{""} and croak ($self->SetDiag (1012));
1119 286 100       545 unless (keys %hdr == @hdr) {
1120             croak ($self->_SetDiagInfo (1013, join ", " =>
1121 1         4 map { "$_ ($hdr{$_})" } grep { $hdr{$_} > 1 } keys %hdr));
  1         11  
  2         5  
1122             }
1123 285 100       835 $args{set_column_names} and $self->column_names (@hdr);
1124 285 100       1955 wantarray ? @hdr : $self;
1125             }
1126              
1127             sub bind_columns {
1128 27     27 1 5900 my ( $self, @refs ) = @_;
1129              
1130 27 100       90 @refs or return defined $self->{_BOUND_COLUMNS} ? @{$self->{_BOUND_COLUMNS}} : undef;
  2 100       13  
1131 23 100 100     109 @refs == 1 && ! defined $refs[0] and return $self->{_BOUND_COLUMNS} = undef;
1132              
1133 18 100 100     70 if ( $self->{_COLUMN_NAMES} && @refs != @{$self->{_COLUMN_NAMES}} ) {
  3         12  
1134 1         4 croak $self->SetDiag( 3003 );
1135             }
1136              
1137 17 100       156 if ( grep { ref $_ ne "SCALAR" } @refs ) { # why don't use grep?
  74606         86206  
1138 2         5 croak $self->SetDiag( 3004 );
1139             }
1140              
1141 15         91 $self->_set_attr_N("_is_bound", scalar @refs);
1142 15         4645 $self->{_BOUND_COLUMNS} = [ @refs ];
1143 15         1172 @refs;
1144             }
1145              
1146             sub getline_hr {
1147 120     120 1 13234 my ($self, @args, %hr) = @_;
1148 120 100       366 $self->{_COLUMN_NAMES} or croak ($self->SetDiag (3002));
1149 119 100       268 my $fr = $self->getline (@args) or return;
1150 117 100       230 if (ref $self->{_FFLAGS}) { # missing
1151             $self->{_FFLAGS}[$_] = IS_MISSING
1152 5 50       11 for (@$fr ? $#{$fr} + 1 : 0) .. $#{$self->{_COLUMN_NAMES}};
  5         7  
  5         16  
1153             @$fr == 1 && (!defined $fr->[0] || $fr->[0] eq "") and
1154 5 100 50     26 $self->{_FFLAGS}[0] ||= IS_MISSING;
      66        
      100        
1155             }
1156 117         170 @hr{@{$self->{_COLUMN_NAMES}}} = @$fr;
  117         387  
1157 117         500 \%hr;
1158             }
1159              
1160             sub getline_hr_all {
1161 214     214 1 346 my ( $self, $io, @args ) = @_;
1162              
1163 214 100       393 unless ( $self->{_COLUMN_NAMES} ) {
1164 2         5 croak $self->SetDiag( 3002 );
1165             }
1166              
1167 212         223 my @cn = @{$self->{_COLUMN_NAMES}};
  212         390  
1168              
1169 212         264 return [ map { my %h; @h{ @cn } = @$_; \%h } @{ $self->getline_all( $io, @args ) } ];
  313         350  
  313         847  
  313         1067  
  212         407  
1170             }
1171              
1172             sub say {
1173 13     13 1 1700 my ($self, $io, @f) = @_;
1174 13         30 my $eol = $self->eol;
1175 13 100 33     65 $eol eq "" and $self->eol ($\ || $/);
1176             # say ($fh, undef) does not propage actual undef to print ()
1177 13 100 66     58 my $state = $self->print ($io, @f == 1 && !defined $f[0] ? undef : @f);
1178 13         145 $self->eol ($eol);
1179 13         65 return $state;
1180             }
1181              
1182             sub print_hr {
1183 3     3 1 9 my ($self, $io, $hr) = @_;
1184 3 100       12 $self->{_COLUMN_NAMES} or croak($self->SetDiag(3009));
1185 2 100       9 ref $hr eq "HASH" or croak($self->SetDiag(3010));
1186 1         3 $self->print ($io, [ map { $hr->{$_} } $self->column_names ]);
  3         7  
1187             }
1188              
1189             sub fragment {
1190 58     58 1 27504 my ($self, $io, $spec) = @_;
1191              
1192 58         180 my $qd = qr{\s* [0-9]+ \s* }x; # digit
1193 58         116 my $qs = qr{\s* (?: [0-9]+ | \* ) \s*}x; # digit or star
1194 58         301 my $qr = qr{$qd (?: - $qs )?}x; # range
1195 58         252 my $qc = qr{$qr (?: ; $qr )*}x; # list
1196 58 100 100     1054 defined $spec && $spec =~ m{^ \s*
1197             \x23 ? \s* # optional leading #
1198             ( row | col | cell ) \s* =
1199             ( $qc # for row and col
1200             | $qd , $qd (?: - $qs , $qs)? # for cell (ranges)
1201             (?: ; $qd , $qd (?: - $qs , $qs)? )* # and cell (range) lists
1202             ) \s* $}xi or croak ($self->SetDiag (2013));
1203 38         151 my ($type, $range) = (lc $1, $2);
1204              
1205 38         92 my @h = $self->column_names ();
1206              
1207 38         54 my @c;
1208 38 100       74 if ($type eq "cell") {
1209 21         29 my @spec;
1210             my $min_row;
1211 21         28 my $max_row = 0;
1212 21         88 for (split m/\s*;\s*/ => $range) {
1213 37 100       195 my ($tlr, $tlc, $brr, $brc) = (m{
1214             ^ \s* ([0-9]+ ) \s* , \s* ([0-9]+ ) \s*
1215             (?: - \s* ([0-9]+ | \*) \s* , \s* ([0-9]+ | \*) \s* )?
1216             $}x) or croak ($self->SetDiag (2013));
1217 36 100       79 defined $brr or ($brr, $brc) = ($tlr, $tlc);
1218 36 100 100     266 $tlr == 0 || $tlc == 0 ||
      66        
      100        
      100        
      66        
      100        
      100        
1219             ($brr ne "*" && ($brr == 0 || $brr < $tlr)) ||
1220             ($brc ne "*" && ($brc == 0 || $brc < $tlc))
1221             and croak ($self->SetDiag (2013));
1222 28         33 $tlc--;
1223 28 100       49 $brc-- unless $brc eq "*";
1224 28 100       42 defined $min_row or $min_row = $tlr;
1225 28 100       58 $tlr < $min_row and $min_row = $tlr;
1226 28 100 100     73 $brr eq "*" || $brr > $max_row and
1227             $max_row = $brr;
1228 28         74 push @spec, [ $tlr, $tlc, $brr, $brc ];
1229             }
1230 12         17 my $r = 0;
1231 12         28 while (my $row = $self->getline ($io)) {
1232 77 100       206 ++$r < $min_row and next;
1233 33         53 my %row;
1234             my $lc;
1235 33         52 foreach my $s (@spec) {
1236 77         124 my ($tlr, $tlc, $brr, $brc) = @$s;
1237 77 100 100     229 $r < $tlr || ($brr ne "*" && $r > $brr) and next;
      100        
1238 45 100 100     94 !defined $lc || $tlc < $lc and $lc = $tlc;
1239 45 100       74 my $rr = $brc eq "*" ? $#$row : $brc;
1240 45         184 $row{$_} = $row->[$_] for $tlc .. $rr;
1241             }
1242 33         108 push @c, [ @row{sort { $a <=> $b } keys %row } ];
  62         153  
1243 33 100       70 if (@h) {
1244 2         3 my %h; @h{@h} = @{$c[-1]};
  2         2  
  2         7  
1245 2         4 $c[-1] = \%h;
1246             }
1247 33 100 100     149 $max_row ne "*" && $r == $max_row and last;
1248             }
1249 12         68 return \@c;
1250             }
1251              
1252             # row or col
1253 17         21 my @r;
1254 17         23 my $eod = 0;
1255 17         58 for (split m/\s*;\s*/ => $range) {
1256 25 50       130 my ($from, $to) = m/^\s* ([0-9]+) (?: \s* - \s* ([0-9]+ | \* ))? \s* $/x
1257             or croak ($self->SetDiag (2013));
1258 25   100     80 $to ||= $from;
1259 25 100       45 $to eq "*" and ($to, $eod) = ($from, 1);
1260             # $to cannot be <= 0 due to regex and ||=
1261 25 100 100     79 $from <= 0 || $to < $from and croak ($self->SetDiag (2013));
1262 22         69 $r[$_] = 1 for $from .. $to;
1263             }
1264              
1265 14         21 my $r = 0;
1266 14 100       27 $type eq "col" and shift @r;
1267 14   100     117 $_ ||= 0 for @r;
1268 14         39 while (my $row = $self->getline ($io)) {
1269 109         126 $r++;
1270 109 100       196 if ($type eq "row") {
1271 64 100 100     230 if (($r > $#r && $eod) || $r[$r]) {
      100        
1272 20         32 push @c, $row;
1273 20 100       43 if (@h) {
1274 3         6 my %h; @h{@h} = @{$c[-1]};
  3         4  
  3         14  
1275 3         5 $c[-1] = \%h;
1276             }
1277             }
1278 64         185 next;
1279             }
1280 45 100 100     90 push @c, [ map { ($_ > $#r && $eod) || $r[$_] ? $row->[$_] : () } 0..$#$row ];
  405         1216  
1281 45 100       154 if (@h) {
1282 9         11 my %h; @h{@h} = @{$c[-1]};
  9         10  
  9         26  
1283 9         29 $c[-1] = \%h;
1284             }
1285             }
1286              
1287 14         81 return \@c;
1288             }
1289              
1290             my $csv_usage = q{usage: my $aoa = csv (in => $file);};
1291              
1292             sub _csv_attr {
1293 284 100 66 284   1176 my %attr = (@_ == 1 && ref $_[0] eq "HASH" ? %{$_[0]} : @_) or croak;
  4 50       17  
1294              
1295 284         469 $attr{binary} = 1;
1296              
1297 284   100     963 my $enc = delete $attr{enc} || delete $attr{encoding} || "";
1298 284 100       487 $enc eq "auto" and ($attr{detect_bom}, $enc) = (1, "");
1299 284 50       542 my $stack = $enc =~ s/(:\w.*)// ? $1 : "";
1300 284 100       490 $enc =~ m/^[-\w.]+$/ and $enc = ":encoding($enc)";
1301 284         335 $enc .= $stack;
1302              
1303 284         313 my $fh;
1304 284         319 my $sink = 0;
1305 284         328 my $cls = 0; # If I open a file, I have to close it
1306 284 100 100     1112 my $in = delete $attr{in} || delete $attr{file} or croak $csv_usage;
1307             my $out = exists $attr{out} && !$attr{out} ? \"skip"
1308 281 50 66     992 : delete $attr{out} || delete $attr{file};
      100        
1309              
1310 281 100 100     835 ref $in eq "CODE" || ref $in eq "ARRAY" and $out ||= \*STDOUT;
      100        
1311              
1312 281 100 66     925 $in && $out && !ref $in && !ref $out and croak join "\n" =>
      100        
      100        
1313             qq{Cannot use a string for both in and out. Instead use:},
1314             qq{ csv (in => csv (in => "$in"), out => "$out");\n};
1315              
1316 280 100       542 if ($out) {
1317 32 100 100     223 if (ref $out and ("ARRAY" eq ref $out or "HASH" eq ref $out)) {
    100 100        
    100 100        
      100        
      66        
      100        
      100        
1318 5         5 delete $attr{out};
1319 5         9 $sink = 1;
1320             }
1321             elsif ((ref $out and "SCALAR" ne ref $out) or "GLOB" eq ref \$out) {
1322 14         22 $fh = $out;
1323             }
1324             elsif (ref $out and "SCALAR" eq ref $out and defined $$out and $$out eq "skip") {
1325 1         3 delete $attr{out};
1326 1         2 $sink = 1;
1327             }
1328             else {
1329 12 100       20982 open $fh, ">", $out or croak "$out: $!";
1330 11         30 $cls = 1;
1331             }
1332 31 100       53 if ($fh) {
1333 25 100       43 if ($enc) {
1334 1         8 binmode $fh, $enc;
1335 1         49 my $fn = fileno $fh; # This is a workaround for a bug in PerlIO::via::gzip
1336             }
1337 25 100       51 unless (defined $attr{eol}) {
1338 18         25 my @layers = eval { PerlIO::get_layers ($fh) };
  18         94  
1339 18 100       92 $attr{eol} = (grep m/crlf/ => @layers) ? "\n" : "\r\n";
1340             }
1341             }
1342             }
1343              
1344 279 100 100     1132 if ( ref $in eq "CODE" or ref $in eq "ARRAY") {
    100 100        
    100          
1345             # All done
1346             }
1347             elsif (ref $in eq "SCALAR") {
1348             # Strings with code points over 0xFF may not be mapped into in-memory file handles
1349             # "<$enc" does not change that :(
1350 23 50   6   247 open $fh, "<", $in or croak "Cannot open from SCALAR using PerlIO";
  6         31  
  6         10  
  6         39  
1351 23         1226 $cls = 1;
1352             }
1353             elsif (ref $in or "GLOB" eq ref \$in) {
1354 16 50 66     42 if (!ref $in && $] < 5.008005) {
1355 0         0 $fh = \*$in; # uncoverable statement ancient perl version required
1356             }
1357             else {
1358 16         22 $fh = $in;
1359             }
1360             }
1361             else {
1362 216 100       7053 open $fh, "<$enc", $in or croak "$in: $!";
1363 214         14208 $cls = 1;
1364             }
1365 277 50 33     634 $fh || $sink or croak qq{No valid source passed. "in" is required};
1366              
1367 277         445 my $hdrs = delete $attr{headers};
1368 277         340 my $frag = delete $attr{fragment};
1369 277         349 my $key = delete $attr{key};
1370 277         318 my $val = delete $attr{value};
1371             my $kh = delete $attr{keep_headers} ||
1372             delete $attr{keep_column_names} ||
1373 277   100     1027 delete $attr{kh};
1374              
1375             my $cbai = delete $attr{callbacks}{after_in} ||
1376             delete $attr{after_in} ||
1377             delete $attr{callbacks}{after_parse} ||
1378 277   100     1516 delete $attr{after_parse};
1379             my $cbbo = delete $attr{callbacks}{before_out} ||
1380 277   100     761 delete $attr{before_out};
1381             my $cboi = delete $attr{callbacks}{on_in} ||
1382 277   100     610 delete $attr{on_in};
1383              
1384             my $hd_s = delete $attr{sep_set} ||
1385 277   100     612 delete $attr{seps};
1386             my $hd_b = delete $attr{detect_bom} ||
1387 277   100     569 delete $attr{bom};
1388             my $hd_m = delete $attr{munge} ||
1389 277   100     570 delete $attr{munge_column_names};
1390 277         322 my $hd_c = delete $attr{set_column_names};
1391              
1392 277         826 for ([ quo => "quote" ],
1393             [ esc => "escape" ],
1394             [ escape => "escape_char" ],
1395             ) {
1396 831         1137 my ($f, $t) = @$_;
1397 831 100 100     1657 exists $attr{$f} and !exists $attr{$t} and $attr{$t} = delete $attr{$f};
1398             }
1399              
1400 277         492 my $fltr = delete $attr{filter};
1401             my %fltr = (
1402 10 100 33 10   12 not_blank => sub { @{$_[1]} > 1 or defined $_[1][0] && $_[1][0] ne "" },
  10         34  
1403 10 50   10   11 not_empty => sub { grep { defined && $_ ne "" } @{$_[1]} },
  26         77  
  10         17  
1404 10 50   10   11 filled => sub { grep { defined && m/\S/ } @{$_[1]} },
  26         90  
  10         17  
1405 277         1676 );
1406             defined $fltr && !ref $fltr && exists $fltr{$fltr} and
1407 277 50 100     607 $fltr = { 0 => $fltr{$fltr} };
      66        
1408 277 100       486 ref $fltr eq "CODE" and $fltr = { 0 => $fltr };
1409 277 100       495 ref $fltr eq "HASH" or $fltr = undef;
1410              
1411 277         319 my $form = delete $attr{formula};
1412              
1413 277 100       546 defined $attr{auto_diag} or $attr{auto_diag} = 1;
1414 277 100       535 defined $attr{escape_null} or $attr{escape_null} = 0;
1415 277 50 66     1169 my $csv = delete $attr{csv} || Text::CSV_PP->new (\%attr)
1416             or croak $last_new_error;
1417 277 100       459 defined $form and $csv->formula ($form);
1418              
1419 277 100 100     561 $kh && !ref $kh && $kh =~ m/^(?:1|yes|true|internal|auto)$/i and
      100        
1420             $kh = \@internal_kh;
1421              
1422             return {
1423 277         4046 csv => $csv,
1424             attr => { %attr },
1425             fh => $fh,
1426             cls => $cls,
1427             in => $in,
1428             sink => $sink,
1429             out => $out,
1430             enc => $enc,
1431             hdrs => $hdrs,
1432             key => $key,
1433             val => $val,
1434             kh => $kh,
1435             frag => $frag,
1436             fltr => $fltr,
1437             cbai => $cbai,
1438             cbbo => $cbbo,
1439             cboi => $cboi,
1440             hd_s => $hd_s,
1441             hd_b => $hd_b,
1442             hd_m => $hd_m,
1443             hd_c => $hd_c,
1444             };
1445             }
1446              
1447             sub csv {
1448 285 50 33 285 1 1086 @_ && (ref $_[0] eq __PACKAGE__ or ref $_[0] eq 'Text::CSV') and splice @_, 0, 0, "csv";
      66        
1449 285 100       553 @_ or croak $csv_usage;
1450              
1451 284         497 my $c = _csv_attr (@_);
1452              
1453 277         474 my ($csv, $in, $fh, $hdrs) = @{$c}{qw( csv in fh hdrs )};
  277         621  
1454 277         334 my %hdr;
1455 277 100       492 if (ref $hdrs eq "HASH") {
1456 2         5 %hdr = %$hdrs;
1457 2         4 $hdrs = "auto";
1458             }
1459              
1460 277 100 100     631 if ($c->{out} && !$c->{sink}) {
1461             !$hdrs && ref $c->{'kh'} && $c->{'kh'} == \@internal_kh and
1462 24 100 100     74 $hdrs = $c->{'kh'};
      66        
1463              
1464 24 100 100     53 if (ref $in eq "CODE") {
    100          
1465 3         4 my $hdr = 1;
1466 3         8 while (my $row = $in->($csv)) {
1467 7 100       50 if (ref $row eq "ARRAY") {
1468 3         7 $csv->print ($fh, $row);
1469 3         42 next;
1470             }
1471 4 50       8 if (ref $row eq "HASH") {
1472 4 100       8 if ($hdr) {
1473 2 50 100     7 $hdrs ||= [ map { $hdr{$_} || $_ } keys %$row ];
  3         11  
1474 2         7 $csv->print ($fh, $hdrs);
1475 2         21 $hdr = 0;
1476             }
1477 4         7 $csv->print ($fh, [ @{$row}{@$hdrs} ]);
  4         10  
1478             }
1479             }
1480             }
1481 21         68 elsif (@{$in} == 0 or ref $in->[0] eq "ARRAY") { # aoa
1482 10 50       21 ref $hdrs and $csv->print ($fh, $hdrs);
1483 10         12 for (@{$in}) {
  10         19  
1484 12 100       53 $c->{cboi} and $c->{cboi}->($csv, $_);
1485 12 50       868 $c->{cbbo} and $c->{cbbo}->($csv, $_);
1486 12         24 $csv->print ($fh, $_);
1487             }
1488             }
1489             else { # aoh
1490 11 100       22 my @hdrs = ref $hdrs ? @{$hdrs} : keys %{$in->[0]};
  5         11  
  6         15  
1491 11 100       22 defined $hdrs or $hdrs = "auto";
1492             ref $hdrs || $hdrs eq "auto" and @hdrs and
1493 11 100 100     47 $csv->print ($fh, [ map { $hdr{$_} || $_ } @hdrs ]);
  20 100 66     69  
1494 11         105 for (@{$in}) {
  11         23  
1495 17         69 local %_;
1496 17         30 *_ = $_;
1497 17 50       31 $c->{cboi} and $c->{cboi}->($csv, $_);
1498 17 50       24 $c->{cbbo} and $c->{cbbo}->($csv, $_);
1499 17         22 $csv->print ($fh, [ @{$_}{@hdrs} ]);
  17         45  
1500             }
1501             }
1502              
1503 24 100       618 $c->{cls} and close $fh;
1504 24         300 return 1;
1505             }
1506              
1507 253         288 my @row1;
1508 253 100 100     1014 if (defined $c->{hd_s} || defined $c->{hd_b} || defined $c->{hd_m} || defined $c->{hd_c}) {
      100        
      100        
1509 149         163 my %harg;
1510 149 100       229 defined $c->{hd_s} and $harg{sep_set} = $c->{hd_s};
1511 149 50       218 defined $c->{hd_d} and $harg{detect_bom} = $c->{hd_b};
1512 149 50       220 defined $c->{hd_m} and $harg{munge_column_names} = $hdrs ? "none" : $c->{hd_m};
    100          
1513 149 50       233 defined $c->{hd_c} and $harg{set_column_names} = $hdrs ? 0 : $c->{hd_c};
    100          
1514 149         300 @row1 = $csv->header ($fh, \%harg);
1515 149         296 my @hdr = $csv->column_names;
1516 149 100 50     575 @hdr and $hdrs ||= \@hdr;
1517             }
1518              
1519 253 100       447 if ($c->{kh}) {
1520 15         22 @internal_kh = ();
1521 15 100       33 ref $c->{kh} eq "ARRAY" or croak ($csv->SetDiag (1501));
1522 10   100     22 $hdrs ||= "auto";
1523             }
1524              
1525 248         309 my $key = $c->{key};
1526 248 100       366 if ($key) {
1527 27 100 100     102 !ref $key or ref $key eq "ARRAY" && @$key > 1 or croak ($csv->SetDiag (1501));
      100        
1528 20   100     48 $hdrs ||= "auto";
1529             }
1530 241         292 my $val = $c->{val};
1531 241 100       347 if ($val) {
1532 9 100       18 $key or croak ($csv->SetDiag (1502));
1533 8 100 100     34 !ref $val or ref $val eq "ARRAY" && @$val > 0 or croak ($csv->SetDiag (1503));
      100        
1534             }
1535              
1536 237 100 100     440 $c->{fltr} && grep m/\D/ => keys %{$c->{fltr}} and $hdrs ||= "auto";
  16   100     90  
1537 237 100       401 if (defined $hdrs) {
1538 197 100       429 if (!ref $hdrs) {
    100          
1539 45 100       95 if ($hdrs eq "skip") {
    100          
    100          
    50          
1540 1         3 $csv->getline ($fh); # discard;
1541             }
1542             elsif ($hdrs eq "auto") {
1543 42 50       86 my $h = $csv->getline ($fh) or return;
1544 42 100       74 $hdrs = [ map { $hdr{$_} || $_ } @$h ];
  122         378  
1545             }
1546             elsif ($hdrs eq "lc") {
1547 1 50       3 my $h = $csv->getline ($fh) or return;
1548 1   33     4 $hdrs = [ map { lc ($hdr{$_} || $_) } @$h ];
  3         12  
1549             }
1550             elsif ($hdrs eq "uc") {
1551 1 50       2 my $h = $csv->getline ($fh) or return;
1552 1   33     3 $hdrs = [ map { uc ($hdr{$_} || $_) } @$h ];
  3         13  
1553             }
1554             }
1555             elsif (ref $hdrs eq "CODE") {
1556 1 50       2 my $h = $csv->getline ($fh) or return;
1557 1         1 my $cr = $hdrs;
1558 1   33     3 $hdrs = [ map { $cr->($hdr{$_} || $_) } @$h ];
  3         14  
1559             }
1560 197 100 66     431 $c->{kh} and $hdrs and @{$c->{kh}} = @$hdrs;
  10         23  
1561             }
1562              
1563 237 100       389 if ($c->{fltr}) {
1564 16         19 my %f = %{$c->{fltr}};
  16         40  
1565             # convert headers to index
1566 16         19 my @hdr;
1567 16 100       33 if (ref $hdrs) {
1568 7         8 @hdr = @{$hdrs};
  7         14  
1569 7         19 for (0 .. $#hdr) {
1570 21 100       46 exists $f{$hdr[$_]} and $f{$_ + 1} = delete $f{$hdr[$_]};
1571             }
1572             }
1573             $csv->callbacks (after_parse => sub {
1574 114     114   143 my ($CSV, $ROW) = @_; # lexical sub-variables in caps
1575 114         268 foreach my $FLD (sort keys %f) {
1576 115         254 local $_ = $ROW->[$FLD - 1];
1577 115         144 local %_;
1578 115 100       274 @hdr and @_{@hdr} = @$ROW;
1579 115 100       250 $f{$FLD}->($CSV, $ROW) or return \"skip";
1580 52         312 $ROW->[$FLD - 1] = $_;
1581             }
1582 16         68 });
1583             }
1584              
1585 237         297 my $frag = $c->{frag};
1586             my $ref = ref $hdrs
1587             ? # aoh
1588 237 100       450 do {
    100          
1589 196         377 my @h = $csv->column_names ($hdrs);
1590 196         245 my %h; $h{$_}++ for @h;
  196         550  
1591 196 50       352 exists $h{""} and croak ($csv->SetDiag (1012));
1592 196 50       365 unless (keys %h == @h) {
1593             croak ($csv->_SetDiagInfo (1013, join ", " =>
1594 0         0 map { "$_ ($h{$_})" } grep { $h{$_} > 1 } keys %h));
  0         0  
  0         0  
1595             }
1596             $frag ? $csv->fragment ($fh, $frag) :
1597 196 100       468 $key ? do {
    100          
1598 17 100       46 my ($k, $j, @f) = ref $key ? (undef, @$key) : ($key);
1599 17 100       29 if (my @mk = grep { !exists $h{$_} } grep { defined } $k, @f) {
  22         52  
  27         56  
1600 2         8 croak ($csv->_SetDiagInfo (4001, join ", " => @mk));
1601             }
1602             +{ map {
1603 26         35 my $r = $_;
1604 26 100       47 my $K = defined $k ? $r->{$k} : join $j => @{$r}{@f};
  4         9  
1605             ( $K => (
1606             $val
1607             ? ref $val
1608 4         16 ? { map { $_ => $r->{$_} } @$val }
1609 26 100       94 : $r->{$val}
    100          
1610             : $r ));
1611 15         20 } @{$csv->getline_hr_all ($fh)} }
  15         30  
1612             }
1613             : $csv->getline_hr_all ($fh);
1614             }
1615             : # aoa
1616             $frag ? $csv->fragment ($fh, $frag)
1617             : $csv->getline_all ($fh);
1618 235 50       398 if ($ref) {
1619 235 100 66     839 @row1 && !$c->{hd_c} && !ref $hdrs and unshift @$ref, \@row1;
      100        
1620             }
1621             else {
1622 0         0 Text::CSV_PP->auto_diag;
1623             }
1624 235 100       2665 $c->{cls} and close $fh;
1625 235 100 100     1226 if ($ref and $c->{cbai} || $c->{cboi}) {
      66        
1626             # Default is ARRAYref, but with key =>, you'll get a hashref
1627 22 100       52 foreach my $r (ref $ref eq "ARRAY" ? @{$ref} : values %{$ref}) {
  21         43  
  1         4  
1628 71         4584 local %_;
1629 71 100       189 ref $r eq "HASH" and *_ = $r;
1630 71 100       153 $c->{cbai} and $c->{cbai}->($csv, $r);
1631 71 100       2794 $c->{cboi} and $c->{cboi}->($csv, $r);
1632             }
1633             }
1634              
1635 235 100       1233 if ($c->{sink}) {
1636 6 50       20 my $ro = ref $c->{out} or return;
1637              
1638 6 100 66     19 $ro eq "SCALAR" && ${$c->{out}} eq "skip" and
  1         14  
1639             return;
1640              
1641 5 50       9 $ro eq ref $ref or
1642             croak ($csv->_SetDiagInfo (5001, "Output type mismatch"));
1643              
1644 5 100       9 if ($ro eq "ARRAY") {
1645 4 100 33     6 if (@{$c->{out}} and @$ref and ref $c->{out}[0] eq ref $ref->[0]) {
  4   66     22  
1646 2         3 push @{$c->{out}} => @$ref;
  2         6  
1647 2         27 return $c->{out};
1648             }
1649 2         5 croak ($csv->_SetDiagInfo (5001, "Output type mismatch"));
1650             }
1651              
1652 1 50       4 if ($ro eq "HASH") {
1653 1         2 @{$c->{out}}{keys %{$ref}} = values %{$ref};
  1         3  
  1         2  
  1         2  
1654 1         13 return $c->{out};
1655             }
1656              
1657 0         0 croak ($csv->_SetDiagInfo (5002, "Unsupported output type"));
1658             }
1659              
1660             defined wantarray or
1661             return csv (
1662             in => $ref,
1663             headers => $hdrs,
1664 229 100       431 %{$c->{attr}},
  1         11  
1665             );
1666              
1667 228         3510 return $ref;
1668             }
1669              
1670             # The end of the common pure perl part.
1671              
1672             ################################################################################
1673             #
1674             # The following are methods implemented in XS in Text::CSV_XS or
1675             # helper methods for Text::CSV_PP only
1676             #
1677             ################################################################################
1678              
1679             sub _setup_ctx {
1680 27765     27765   49297 my $self = shift;
1681              
1682 27765         37718 $last_error = undef;
1683              
1684 27765         39759 my $ctx;
1685 27765 100       67065 if ($self->{_CACHE}) {
1686 26966         34938 %$ctx = %{$self->{_CACHE}};
  26966         400958  
1687             } else {
1688 799         1564 $ctx->{sep} = ',';
1689 799 50       1495 if (defined $self->{sep_char}) {
1690 799         1227 $ctx->{sep} = $self->{sep_char};
1691             }
1692 799 100 100     1888 if (defined $self->{sep} and $self->{sep} ne '') {
1693 34     34   17741 use bytes;
  34         436  
  34         185  
1694 5         11 $ctx->{sep} = $self->{sep};
1695 5         9 my $sep_len = length($ctx->{sep});
1696 5 50       13 $ctx->{sep_len} = $sep_len if $sep_len > 1;
1697             }
1698              
1699 799         1164 $ctx->{quo} = '"';
1700 799 50       1351 if (exists $self->{quote_char}) {
1701 799         1090 my $quote_char = $self->{quote_char};
1702 799 100 66     2349 if (defined $quote_char and length $quote_char) {
1703 795         1193 $ctx->{quo} = $quote_char;
1704             } else {
1705 4         9 $ctx->{quo} = "\0";
1706             }
1707             }
1708 799 100 100     1710 if (defined $self->{quote} and $self->{quote} ne '') {
1709 34     34   3462 use bytes;
  34         74  
  34         97  
1710 4         8 $ctx->{quo} = $self->{quote};
1711 4         5 my $quote_len = length($ctx->{quo});
1712 4 50       10 $ctx->{quo_len} = $quote_len if $quote_len > 1;
1713             }
1714              
1715 799         1269 $ctx->{escape_char} = '"';
1716 799 50       1266 if (exists $self->{escape_char}) {
1717 799         1038 my $escape_char = $self->{escape_char};
1718 799 100 100     2032 if (defined $escape_char and length $escape_char) {
1719 791         1151 $ctx->{escape_char} = $escape_char;
1720             } else {
1721 8         15 $ctx->{escape_char} = "\0";
1722             }
1723             }
1724              
1725 799 100       1296 if (defined $self->{eol}) {
1726 795         967 my $eol = $self->{eol};
1727 795         913 my $eol_len = length($eol);
1728 795         1060 $ctx->{eol} = $eol;
1729 795         1113 $ctx->{eol_len} = $eol_len;
1730 795 100 100     1734 if ($eol_len == 1 and $eol eq "\015") {
1731 42         68 $ctx->{eol_is_cr} = 1;
1732             }
1733             }
1734              
1735 799         1119 $ctx->{undef_flg} = 0;
1736 799 100       1302 if (defined $self->{undef_str}) {
1737 1         3 $ctx->{undef_str} = $self->{undef_str};
1738 1 50       3 $ctx->{undef_flg} = 3 if utf8::is_utf8($self->{undef_str});
1739             } else {
1740 798         1112 $ctx->{undef_str} = undef;
1741             }
1742 799 100       1467 if (defined $self->{comment_str}) {
1743 12         27 $ctx->{comment_str} = $self->{comment_str};
1744             }
1745              
1746 799 100       1310 if (defined $self->{_types}) {
1747 1         3 $ctx->{types} = $self->{_types};
1748 1         3 $ctx->{types_len} = length($ctx->{types});
1749             }
1750              
1751 799 100       1228 if (defined $self->{_is_bound}) {
1752 4         15 $ctx->{is_bound} = $self->{_is_bound};
1753             }
1754              
1755 799 100       1338 if (defined $self->{callbacks}) {
1756 265         325 my $cb = $self->{callbacks};
1757 265         496 $ctx->{has_hooks} = 0;
1758 265 100 66     490 if (defined $cb->{after_parse} and ref $cb->{after_parse} eq 'CODE') {
1759 9         13 $ctx->{has_hooks} |= HOOK_AFTER_PARSE;
1760             }
1761 265 100 66     488 if (defined $cb->{before_print} and ref $cb->{before_print} eq 'CODE') {
1762 1         2 $ctx->{has_hooks} |= HOOK_BEFORE_PRINT;
1763             }
1764             }
1765              
1766 799         1504 for (qw/
1767             binary decode_utf8 always_quote strict quote_empty
1768             allow_loose_quotes allow_loose_escapes
1769             allow_unquoted_escape allow_whitespace blank_is_undef
1770             empty_is_undef verbatim auto_diag diag_verbose
1771             keep_meta_info formula skip_empty_rows
1772             /) {
1773 13583 50       24322 $ctx->{$_} = defined $self->{$_} ? $self->{$_} : 0;
1774             }
1775 799         1068 for (qw/quote_space escape_null quote_binary/) {
1776 2397 50       4378 $ctx->{$_} = defined $self->{$_} ? $self->{$_} : 1;
1777             }
1778 799 100       1548 if ($ctx->{escape_char} eq "\0") {
1779 8         16 $ctx->{escape_null} = 0;
1780             }
1781              
1782             # FIXME: readonly
1783 799         3256 %{$self->{_CACHE}} = %$ctx;
  799         5196  
1784             }
1785              
1786 27765         75824 $ctx->{utf8} = 0;
1787 27765         45110 $ctx->{size} = 0;
1788 27765         37239 $ctx->{used} = 0;
1789              
1790 27765 100       61522 if ($ctx->{is_bound}) {
1791 89         111 my $bound = $self->{_BOUND_COLUMNS};
1792 89 100 66     331 if ($bound and ref $bound eq 'ARRAY') {
1793 75         146 $ctx->{bound} = $bound;
1794             } else {
1795 14         20 $ctx->{is_bound} = 0;
1796             }
1797             }
1798              
1799 27765         45756 $ctx->{eol_pos} = -1;
1800             $ctx->{eolx} = $ctx->{eol_len}
1801             ? $ctx->{verbatim} || $ctx->{eol_len} >= 2
1802             ? 1
1803 27765 100 100     80714 : $ctx->{eol} =~ /\A[\015\012]/ ? 0 : 1
    100          
    100          
1804             : 0;
1805              
1806 27765 100 66     61851 if ($ctx->{sep_len} and $ctx->{sep_len} > 1 and _is_valid_utf8($ctx->{sep})) {
      100        
1807 14         23 $ctx->{utf8} = 1;
1808             }
1809 27765 50 66     52998 if ($ctx->{quo_len} and $ctx->{quo_len} > 1 and _is_valid_utf8($ctx->{quo})) {
      66        
1810 0         0 $ctx->{utf8} = 1;
1811             }
1812              
1813 27765         46380 $ctx;
1814             }
1815              
1816             sub _cache_set {
1817 23456     23456   32921 my ($self, $idx, $value) = @_;
1818 23456 100       34767 return unless exists $self->{_CACHE};
1819 22589         25583 my $cache = $self->{_CACHE};
1820              
1821 22589         32189 my $key = $_reverse_cache_id{$idx};
1822 22589 100       73495 if (!defined $key) {
    100          
    100          
    100          
    100          
    100          
    100          
    100          
    100          
    100          
1823 1         10 warn (sprintf "Unknown cache index %d ignored\n", $idx);
1824             } elsif ($key eq 'sep_char') {
1825 3122         4371 $cache->{sep} = $value;
1826 3122         4176 $cache->{sep_len} = 0;
1827             }
1828             elsif ($key eq 'quote_char') {
1829 3369         4517 $cache->{quo} = $value;
1830 3369         4693 $cache->{quo_len} = 0;
1831             }
1832             elsif ($key eq '_has_ahead') {
1833 251         366 $cache->{has_ahead} = $value;
1834             }
1835             elsif ($key eq '_has_hooks') {
1836 11         18 $cache->{has_hooks} = $value;
1837             }
1838             elsif ($key eq '_is_bound') {
1839 11         26 $cache->{is_bound} = $value;
1840             }
1841             elsif ($key eq 'sep') {
1842 34     34   23062 use bytes;
  34         70  
  34         239  
1843 3223         6315 my $len = bytes::length($value);
1844 3223 100       14201 $cache->{sep} = $value if $len;
1845 3223 50       6202 $cache->{sep_len} = $len == 1 ? 0 : $len;
1846             }
1847             elsif ($key eq 'quote') {
1848 34     34   2311 use bytes;
  34         55  
  34         116  
1849 3377         6782 my $len = bytes::length($value);
1850 3377 100       10463 $cache->{quo} = $value if $len;
1851 3377 50       5935 $cache->{quo_len} = $len == 1 ? 0 : $len;
1852             }
1853             elsif ($key eq 'eol') {
1854 112 50       179 if (defined($value)) {
1855 112         170 $cache->{eol} = $value;
1856 112         155 $cache->{eol_len} = length($value);
1857             }
1858 112 100       251 $cache->{eol_is_cr} = $value eq "\015" ? 1 : 0;
1859             }
1860             elsif ($key eq 'undef_str') {
1861 11 100       17 if (defined $value) {
1862 9         12 $cache->{undef_str} = $value;
1863 9 100       22 $cache->{undef_flg} = 3 if utf8::is_utf8($value);
1864             } else {
1865 2         4 $cache->{undef_str} = undef;
1866 2         3 $cache->{undef_flg} = 0;
1867             }
1868             }
1869             else {
1870 9101         12672 $cache->{$key} = $value;
1871             }
1872 22589         29993 return 1;
1873             }
1874              
1875             sub _cache_diag {
1876 2     2   4 my $self = shift;
1877 2 100       8 unless (exists $self->{_CACHE}) {
1878 1         8 warn ("CACHE: invalid\n");
1879 1         6 return;
1880             }
1881              
1882 1         2 my $cache = $self->{_CACHE};
1883 1         54 warn ("CACHE:\n");
1884 1         12 $self->__cache_show_char(quote_char => $cache->{quo});
1885 1         6 $self->__cache_show_char(escape_char => $cache->{escape_char});
1886 1         6 $self->__cache_show_char(sep_char => $cache->{sep});
1887 1         5 for (qw/
1888             binary decode_utf8 allow_loose_escapes allow_loose_quotes allow_unquoted_escape
1889             allow_whitespace always_quote quote_empty quote_space
1890             escape_null quote_binary auto_diag diag_verbose formula strict skip_empty_rows
1891             has_error_input blank_is_undef empty_is_undef has_ahead
1892             keep_meta_info verbatim has_hooks eol_is_cr eol_len
1893             /) {
1894 25         78 $self->__cache_show_byte($_ => $cache->{$_});
1895             }
1896 1         16 $self->__cache_show_str(eol => $cache->{eol_len}, $cache->{eol});
1897 1         6 $self->__cache_show_byte(sep_len => $cache->{sep_len});
1898 1 50 33     8 if ($cache->{sep_len} and $cache->{sep_len} > 1) {
1899 1         10 $self->__cache_show_str(sep => $cache->{sep_len}, $cache->{sep});
1900             }
1901 1         5 $self->__cache_show_byte(quo_len => $cache->{quo_len});
1902 1 50 33     7 if ($cache->{quo_len} and $cache->{quo_len} > 1) {
1903 1         9 $self->__cache_show_str(quote => $cache->{quo_len}, $cache->{quo});
1904             }
1905 1 50       10 if ($cache->{types_len}) {
1906 0         0 $self->__cache_show_str(types => $cache->{types_len}, $cache->{types});
1907             } else {
1908 1         3 $self->__cache_show_str(types => 0, "");
1909             }
1910 1 50       7 if ($cache->{bptr}) {
1911 0         0 $self->__cache_show_str(bptr => length($cache->{bptr}), $cache->{bptr});
1912             }
1913 1 50       4 if ($cache->{tmp}) {
1914 1         3 $self->__cache_show_str(tmp => length($cache->{tmp}), $cache->{tmp});
1915             }
1916             }
1917              
1918             sub __cache_show_byte {
1919 27     27   47 my ($self, $key, $value) = @_;
1920 27 100       319 warn (sprintf " %-21s %02x:%3d\n", $key, defined $value ? ord($value) : 0, defined $value ? $value : 0);
    100          
1921             }
1922              
1923             sub __cache_show_char {
1924 3     3   8 my ($self, $key, $value) = @_;
1925 3         4 my $v = $value;
1926 3 50       8 if (defined $value) {
1927 3         8 my @b = unpack "U0C*", $value;
1928 3         11 $v = pack "U*", $b[0];
1929             }
1930 3 50       13 warn (sprintf " %-21s %02x:%s\n", $key, defined $v ? ord($v) : 0, $self->__pretty_str($v, 1));
1931             }
1932              
1933             sub __cache_show_str {
1934 5     5   15 my ($self, $key, $len, $value) = @_;
1935 5         9 warn (sprintf " %-21s %02d:%s\n", $key, $len, $self->__pretty_str($value, $len));
1936             }
1937              
1938             sub __pretty_str { # FIXME
1939 8     8   12 my ($self, $str, $len) = @_;
1940 8 50       13 return '' unless defined $str;
1941 8         16 $str = substr($str, 0, $len);
1942 8         17 $str =~ s/"/\\"/g;
1943 8         13 $str =~ s/([^\x09\x20-\x7e])/sprintf '\\x{%x}', ord($1)/eg;
  0         0  
1944 8         120 qq{"$str"};
1945             }
1946              
1947             sub _hook {
1948 20406     20406   36497 my ($self, $name, $fields) = @_;
1949 20406 100       59314 return 0 unless $self->{callbacks};
1950              
1951 173         271 my $cb = $self->{callbacks}{$name};
1952 173 100 66     480 return 0 unless $cb && ref $cb eq 'CODE';
1953              
1954 125         233 my (@res) = $cb->($self, $fields);
1955 125 50       511 if (@res) {
1956 125 100 66     257 return 0 if ref $res[0] eq 'SCALAR' and ${$res[0]} eq "skip";
  64         210  
1957             }
1958 61         124 scalar @res;
1959             }
1960              
1961             ################################################################################
1962             # methods for combine
1963             ################################################################################
1964              
1965             sub __combine {
1966 21682     21682   49396 my ($self, $dst, $fields, $useIO) = @_;
1967              
1968 21682         57692 my $ctx = $self->_setup_ctx;
1969              
1970 21682         36292 my ($binary, $quot, $sep, $esc, $quote_space) = @{$ctx}{qw/binary quo sep escape_char quote_space/};
  21682         60651  
1971              
1972 21682 100 100     91131 if(!defined $quot or $quot eq "\0"){ $quot = ''; }
  2         5  
1973              
1974 21682         28030 my $re_esc;
1975 21682 100 66     70782 if ($esc ne '' and $esc ne "\0") {
1976 21680 100       37229 if ($quot ne '') {
1977 21678   66     74578 $re_esc = $self->{_re_comb_escape}->{$quot}->{$esc} ||= qr/(\Q$quot\E|\Q$esc\E)/;
1978             } else {
1979 2   33     34 $re_esc = $self->{_re_comb_escape}->{$quot}->{$esc} ||= qr/(\Q$esc\E)/;
1980             }
1981             }
1982              
1983 21682         32825 my $bound = 0;
1984 21682         32452 my $n = @$fields - 1;
1985 21682 100 100     46514 if ($n < 0 and $ctx->{is_bound}) {
1986 5         7 $n = $ctx->{is_bound} - 1;
1987 5         9 $bound = 1;
1988             }
1989              
1990 21682 100 66     61341 my $check_meta = ($ctx->{keep_meta_info} >= 10 and @{$self->{_FFLAGS} || []} >= $n) ? 1 : 0;
1991              
1992 21682         30022 my $must_be_quoted;
1993             my @results;
1994 21682         48137 for(my $i = 0; $i <= $n; $i++) {
1995 53903         58051 my $v_ref;
1996 53903 100       74627 if ($bound) {
1997 14         35 $v_ref = $self->__bound_field($ctx, $i, 1);
1998             } else {
1999 53889 50       81745 if (@$fields > $i) {
2000 53889         74458 $v_ref = \($fields->[$i]);
2001             }
2002             }
2003 53903 50       83492 next unless $v_ref;
2004              
2005 53903         67987 my $value = $$v_ref;
2006              
2007 53903 100       85653 if (!defined $value) {
2008 56 100       81 if ($ctx->{undef_str}) {
2009 8 100       15 if ($ctx->{undef_flg}) {
2010 3         4 $ctx->{utf8} = 1;
2011 3         3 $ctx->{binary} = 1;
2012             }
2013 8         13 push @results, $ctx->{undef_str};
2014             } else {
2015 48         66 push @results, '';
2016             }
2017 56         107 next;
2018             }
2019              
2020 53847 100 100     2054863 if ( substr($value, 0, 1) eq '=' && $ctx->{formula} ) {
2021 10         18 $value = $self->_formula($ctx, $value, $i);
2022 6 100       14 if (!defined $value) {
2023 2         3 push @results, '';
2024 2         4 next;
2025             }
2026             }
2027              
2028 53841 100       90801 $must_be_quoted = $ctx->{always_quote} ? 1 : 0;
2029 53841 100       76539 if ($value eq '') {
2030 1406 100 100     3843 $must_be_quoted++ if $ctx->{quote_empty} or ($check_meta && $self->is_quoted($i));
      100        
2031             }
2032             else {
2033              
2034 52435 100       108751 if (utf8::is_utf8 $value) {
2035 20041         31701 $ctx->{utf8} = 1;
2036 20041         24187 $ctx->{binary} = 1;
2037             }
2038              
2039 52435 100 100     100572 $must_be_quoted++ if $check_meta && $self->is_quoted($i);
2040              
2041 52435 100 100     143469 if (!$must_be_quoted and $quot ne '') {
2042 34     34   39111 use bytes;
  34         68  
  34         123  
2043             $must_be_quoted++ if
2044             ($value =~ /\Q$quot\E/) ||
2045             ($sep ne '' and $sep ne "\0" and $value =~ /\Q$sep\E/) ||
2046             ($esc ne '' and $esc ne "\0" and $value =~ /\Q$esc\E/) ||
2047             ($ctx->{quote_binary} && $value =~ /[\x00-\x1f\x7f-\xa0]/) ||
2048 46793 100 66     798757 ($ctx->{quote_space} && $value =~ /[\x09\x20]/);
      100        
      100        
      66        
      100        
      100        
      100        
      100        
      100        
      100        
2049             }
2050              
2051 52435 100 100     110546 if (!$ctx->{binary} and $value =~ /[^\x09\x20-\x7E]/) {
2052             # an argument contained an invalid character...
2053 7         15 $self->{_ERROR_INPUT} = $value;
2054 7         84 $self->SetDiag(2110);
2055 7         58 return 0;
2056             }
2057              
2058 52428 100       84419 if ($re_esc) {
2059 52426         2097207 $value =~ s/($re_esc)/$esc$1/g;
2060             }
2061 52428 100       105323 if ($ctx->{escape_null}) {
2062 52291         1991113 $value =~ s/\0/${esc}0/g;
2063             }
2064             }
2065              
2066 53834 100       80840 if ($must_be_quoted) {
2067 29446         284039 $value = $quot . $value . $quot;
2068             }
2069 53834         145864 push @results, $value;
2070             }
2071              
2072 21671 100       545500 $$dst = join($sep, @results) . ( defined $ctx->{eol} ? $ctx->{eol} : '' );
2073              
2074 21671         138169 return 1;
2075             }
2076              
2077             sub _formula {
2078 37     37   60 my ($self, $ctx, $value, $i) = @_;
2079              
2080 37 50       70 my $fa = $ctx->{formula} or return;
2081 37 100       55 if ($fa == 1) { die "Formulas are forbidden\n" }
  3         43  
2082 34 100       52 if ($fa == 2) { die "Formulas are forbidden\n" } # XS croak behaves like PP's "die"
  3         77  
2083              
2084 31 100       74 if ($fa == 3) {
2085 6         24 my $rec = '';
2086 6 100       13 if ($ctx->{recno}) {
2087 3         10 $rec = sprintf " in record %lu", $ctx->{recno} + 1;
2088             }
2089 6         7 my $field = '';
2090 6         7 my $column_names = $self->{_COLUMN_NAMES};
2091 6 100 66     18 if (ref $column_names eq 'ARRAY' and @$column_names >= $i - 1) {
2092 1         3 my $column_name = $column_names->[$i - 1];
2093 1 50       5 $field = sprintf " (column: '%.100s')", $column_name if defined $column_name;
2094             }
2095 6         53 warn sprintf("Field %d%s%s contains formula '%s'\n", $i, $field, $rec, $value);
2096 6         35 return $value;
2097             }
2098              
2099 25 100       38 if ($fa == 4) {
2100 5         10 return '';
2101             }
2102 20 100       34 if ($fa == 5) {
2103 5         11 return undef;
2104             }
2105              
2106 15 50       21 if ($fa == 6) {
2107 15 50       32 if (ref $self->{_FORMULA_CB} eq 'CODE') {
2108 15         22 local $_ = $value;
2109 15         28 return $self->{_FORMULA_CB}->();
2110             }
2111             }
2112 0         0 return;
2113             }
2114              
2115             sub print {
2116 20289     20289 1 31835458 my ($self, $io, $fields) = @_;
2117              
2118 20289         140001 require IO::Handle;
2119              
2120 20289 100       140557 if (!defined $fields) {
    100          
2121 5         9 $fields = [];
2122             } elsif(ref($fields) ne 'ARRAY'){
2123 5         423 Carp::croak("Expected fields to be an array ref");
2124             }
2125              
2126 20284         57924 $self->_hook(before_print => $fields);
2127              
2128 20284         32391 my $str = "";
2129 20284 100       57091 $self->__combine(\$str, $fields, 1) or return '';
2130              
2131 20278         82348 local $\ = '';
2132              
2133 20278 100       69429 $io->print( $str ) or $self->_set_error_diag(2200);
2134             }
2135              
2136             ################################################################################
2137             # methods for parse
2138             ################################################################################
2139              
2140              
2141             sub __parse { # cx_xsParse
2142 3529     3529   6198 my ($self, $fields, $fflags, $src, $useIO) = @_;
2143              
2144 3529         6549 my $ctx = $self->_setup_ctx;
2145              
2146 3529         7302 my $state = $self->___parse($ctx, $fields, $fflags, $src, $useIO);
2147 3524 100 100     12972 if ($state and ($ctx->{has_hooks} || 0) & HOOK_AFTER_PARSE) {
      100        
2148 5         15 $self->_hook(after_parse => $fields);
2149             }
2150 3524   100     18682 return $state || !$last_error;
2151             }
2152              
2153             sub ___parse { # cx_c_xsParse
2154 4405     4405   7711 my ($self, $ctx, $fields, $fflags, $src, $useIO) = @_;
2155              
2156 4405 100 100     15190 local $/ = $ctx->{eol} if $ctx->{eolx} or $ctx->{eol_is_cr};
2157              
2158 4405 100       7557 if ($ctx->{useIO} = $useIO) {
2159 2462         18624 require IO::Handle;
2160              
2161 2462         83924 $ctx->{tmp} = undef;
2162 2462 100 66     4815 if ($ctx->{has_ahead} and defined $self->{_AHEAD}) {
2163 175         268 $ctx->{tmp} = $self->{_AHEAD};
2164 175         267 $ctx->{size} = length $ctx->{tmp};
2165 175         210 $ctx->{used} = 0;
2166             }
2167             } else {
2168 1943         2551 $ctx->{tmp} = $src;
2169 1943         3013 $ctx->{size} = length $src;
2170 1943         2611 $ctx->{used} = 0;
2171 1943         3911 $ctx->{utf8} = utf8::is_utf8($src);
2172             }
2173 4405 50       7361 if ($ctx->{has_error_input}) {
2174 0         0 $self->{_ERROR_INPUT} = undef;
2175 0         0 $ctx->{has_error_input} = 0;
2176             }
2177              
2178 4405         8436 my $result = $self->____parse($ctx, $src, $fields, $fflags);
2179 4400         7451 $self->{_RECNO} = ++($ctx->{recno});
2180 4400         6416 $self->{_EOF} = '';
2181              
2182 4400 100       7730 if ($ctx->{strict}) {
2183 27   66     66 $ctx->{strict_n} ||= $ctx->{fld_idx};
2184 27 100       44 if ($ctx->{strict_n} != $ctx->{fld_idx}) {
2185 12 100       37 unless ($ctx->{useIO} & useIO_EOF) {
2186 8         22 $self->__parse_error($ctx, 2014, $ctx->{used});
2187             }
2188 12 100       27 if ($last_error) {
2189 8         10 $result = undef;
2190             }
2191             }
2192             }
2193              
2194 4400 100       6586 if ($ctx->{useIO}) {
2195 2460 100 66     7866 if (defined $ctx->{tmp} and $ctx->{used} < $ctx->{size} and $ctx->{has_ahead}) {
      100        
2196 37         100 $self->{_AHEAD} = substr($ctx->{tmp}, $ctx->{used}, $ctx->{size} - $ctx->{used});
2197             } else {
2198 2423         3001 $ctx->{has_ahead} = 0;
2199 2423 100       4071 if ($ctx->{useIO} & useIO_EOF) {
2200 509         717 $self->{_EOF} = 1;
2201             }
2202             }
2203 2460         15463 %{$self->{_CACHE}} = %$ctx;
  2460         28545  
2204              
2205 2460 100       7900 if ($fflags) {
2206 1584 100       2563 if ($ctx->{keep_meta_info}) {
2207 11         25 $self->{_FFLAGS} = $fflags;
2208             } else {
2209 1573         2196 undef $fflags;
2210             }
2211             }
2212             } else {
2213 1940         15128 %{$self->{_CACHE}} = %$ctx;
  1940         27450  
2214             }
2215              
2216 4400 100 100     15950 if ($result and $ctx->{types}) {
2217 2         3 my $len = @$fields;
2218 2   66     8 for(my $i = 0; $i <= $len && $i <= $ctx->{types_len}; $i++) {
2219 8         19 my $value = $fields->[$i];
2220 8 100       13 next unless defined $value;
2221 6         12 my $type = ord(substr($ctx->{types}, $i, 1));
2222 6 100       7 if ($type == IV) {
    100          
2223 2         21 $fields->[$i] = int($value);
2224             } elsif ($type == NV) {
2225 2         8 $fields->[$i] = $value + 0.0;
2226             }
2227             }
2228             }
2229              
2230 4400         9250 $result;
2231             }
2232              
2233             sub ____parse { # cx_Parse
2234 4409     4409   6910 my ($self, $ctx, $src, $fields, $fflags) = @_;
2235              
2236 4409         5281 my ($quot, $sep, $esc, $eol) = @{$ctx}{qw/quo sep escape_char eol/};
  4409         9873  
2237              
2238 4409 100 100     14213 utf8::encode($sep) if !$ctx->{utf8} and $ctx->{sep_len};
2239 4409 100 100     11582 utf8::encode($quot) if !$ctx->{utf8} and $ctx->{quo_len};
2240 4409 100 100     12760 utf8::encode($eol) if !$ctx->{utf8} and $ctx->{eol_len};
2241              
2242 4409         4949 my $seenSomething = 0;
2243 4409         4585 my $spl = -1;
2244 4409         4806 my $waitingForField = 1;
2245 4409         5062 my ($value, $v_ref);
2246 4409         5549 $ctx->{fld_idx} = my $fnum = 0;
2247 4409         5655 $ctx->{flag} = 0;
2248              
2249 4409 100       7215 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", " ";
  14278 100       32010  
  14654         22204  
  17636         50505  
2250 4409         52539 $ctx->{_re} = qr/$re_str/;
2251 4409         49925 my $re = qr/$re_str|[^\x09\x20-\x7E]|$/;
2252              
2253             LOOP:
2254 4409         12098 while($self->__get_from_src($ctx, $src)) {
2255 4553         68875 while($ctx->{tmp} =~ /\G(.*?)($re)/gs) {
2256 74500         152004 my ($hit, $c) = ($1, $2);
2257 74500         89648 $ctx->{used} = pos($ctx->{tmp});
2258 74500 100 100     160306 if (!$waitingForField and $c eq '' and $hit ne '' and $ctx->{useIO} and !($ctx->{useIO} & useIO_EOF)) {
      100        
      100        
      100        
2259 147         278 $self->{_AHEAD} = $hit;
2260 147         204 $ctx->{has_ahead} = 1;
2261 147         232 $ctx->{has_leftover} = 1;
2262 147         476 last;
2263             }
2264 74353 100 100     182808 last if $seenSomething and $hit eq '' and $c eq ''; # EOF
      100        
2265              
2266             # new field
2267 73989 100       100976 if (!$v_ref) {
2268 22384 100       29980 if ($ctx->{is_bound}) {
2269 87         219 $v_ref = $self->__bound_field($ctx, $fnum, 0);
2270             } else {
2271 22297         27152 $value = '';
2272 22297         27673 $v_ref = \$value;
2273             }
2274 22384         23922 $fnum++;
2275 22384 100       30875 return unless $v_ref;
2276 22380         24601 $ctx->{flag} = 0;
2277 22380         25299 $ctx->{fld_idx}++;
2278             }
2279              
2280 73985         75697 $seenSomething = 1;
2281 73985         70341 $spl++;
2282              
2283 73985 100 66     158550 if (defined $hit and $hit ne '') {
2284 45447 100       59758 if ($waitingForField) {
2285 9657 100 100     16219 if (!$spl && $ctx->{comment_str} && $ctx->{tmp} =~ /\A\Q$ctx->{comment_str}/) {
      100        
2286 18         29 $ctx->{used} = $ctx->{size};
2287 18         54 next LOOP;
2288             }
2289 9639         9989 $waitingForField = 0;
2290             }
2291 45429 50       73752 if ($hit =~ /[^\x09\x20-\x7E]/) {
2292 0         0 $ctx->{flag} |= IS_BINARY;
2293             }
2294 45429         55899 $$v_ref .= $hit;
2295             }
2296              
2297             RESTART:
2298 74605 100 66     619004 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        
2299 11488 100       19769 if ($waitingForField) {
    100          
2300             # ,1,"foo, 3",,bar,
2301             # ^ ^
2302 1174 100 100     3285 if ($ctx->{blank_is_undef} or $ctx->{empty_is_undef}) {
2303 53         62 $$v_ref = undef;
2304             } else {
2305 1121         1540 $$v_ref = "";
2306             }
2307 1174 50       1851 unless ($ctx->{is_bound}) {
2308 1174         2249 push @$fields, $$v_ref;
2309             }
2310 1174         1437 $v_ref = undef;
2311 1174 100 66     2413 if ($ctx->{keep_meta_info} and $fflags) {
2312 8         14 push @$fflags, $ctx->{flag};
2313             }
2314             } elsif ($ctx->{flag} & IS_QUOTED) {
2315             # ,1,"foo, 3",,bar,
2316             # ^
2317 2186         2799 $$v_ref .= $c;
2318             } else {
2319             # ,1,"foo, 3",,bar,
2320             # ^ ^ ^
2321 8128         17930 $self->__push_value($ctx, $v_ref, $fields, $fflags, $ctx->{flag}, $fnum);
2322 8126         8480 $v_ref = undef;
2323 8126         8693 $waitingForField = 1;
2324             }
2325             }
2326             elsif (defined $c and defined $quot and $quot ne "\0" and $c eq $quot) {
2327 22919 100       30946 if ($waitingForField) {
2328             # ,1,"foo, 3",,bar,\r\n
2329             # ^
2330 10935         13152 $ctx->{flag} |= IS_QUOTED;
2331 10935         11182 $waitingForField = 0;
2332 10935         46496 next;
2333             }
2334 11984 100       18701 if ($ctx->{flag} & IS_QUOTED) {
2335             # ,1,"foo, 3",,bar,\r\n
2336             # ^
2337 11930         12684 my $quoesc = 0;
2338 11930         21693 my $c2 = $self->__get($ctx, $src);
2339              
2340 11930 100       20129 if ($ctx->{allow_whitespace}) {
2341             # , 1 , "foo, 3" , , bar , \r\n
2342             # ^
2343 4290         7569 while($self->__is_whitespace($ctx, $c2)) {
2344 90 100 33     202 if ($ctx->{allow_loose_quotes} and !(defined $esc and $c2 eq $esc)) {
      66        
2345 1         2 $$v_ref .= $c;
2346 1         1 $c = $c2;
2347             }
2348 90         145 $c2 = $self->__get($ctx, $src);
2349             }
2350             }
2351              
2352 11930 100       17614 if (!defined $c2) { # EOF
2353             # ,1,"foo, 3"
2354             # ^
2355 1311         2934 $self->__push_value($ctx, $v_ref, $fields, $fflags, $ctx->{flag}, $fnum);
2356 1311         4799 return 1;
2357             }
2358              
2359 10619 100 33     33459 if (defined $c2 and defined $sep and $c2 eq $sep) {
      66        
2360             # ,1,"foo, 3",,bar,\r\n
2361             # ^
2362 9017         19033 $self->__push_value($ctx, $v_ref, $fields, $fflags, $ctx->{flag}, $fnum);
2363 9017         9652 $v_ref = undef;
2364 9017         9231 $waitingForField = 1;
2365 9017         40691 next;
2366             }
2367 1602 100 100     6140 if (defined $c2 and ($c2 eq "\012" or (defined $eol and $c2 eq $eol))) { # FIXME: EOLX
      66        
2368             # ,1,"foo, 3",,"bar"\n
2369             # ^
2370 323         768 $self->__push_value($ctx, $v_ref, $fields, $fflags, $ctx->{flag}, $fnum);
2371 323         1039 return 1;
2372             }
2373              
2374 1279 100 100     3095 if (defined $esc and $c eq $esc) {
2375 1258         1393 $quoesc = 1;
2376 1258 100 66     2885 if (defined $c2 and $c2 eq '0') {
2377             # ,1,"foo, 3"056",,bar,\r\n
2378             # ^
2379 51         62 $$v_ref .= "\0";
2380 51         195 next;
2381             }
2382 1207 100 33     3954 if (defined $c2 and defined $quot and $c2 eq $quot) {
      66        
2383             # ,1,"foo, 3""56",,bar,\r\n
2384             # ^
2385 1077 100       1680 if ($ctx->{utf8}) {
2386 1         3 $ctx->{flag} |= IS_BINARY;
2387             }
2388 1077         1318 $$v_ref .= $c2;
2389 1077         4436 next;
2390             }
2391 130 100 66     319 if ($ctx->{allow_loose_escapes} and defined $c2 and $c2 ne "\015") {
      100        
2392             # ,1,"foo, 3"56",,bar,\r\n
2393             # ^
2394 4         7 $$v_ref .= $c;
2395 4         6 $c = $c2;
2396 4         270 goto RESTART;
2397             }
2398             }
2399 147 100 66     401 if (defined $c2 and $c2 eq "\015") {
2400 90 50       156 if ($ctx->{eol_is_cr}) {
2401             # ,1,"foo, 3"\r
2402             # ^
2403 0         0 $self->__push_value($ctx, $v_ref, $fields, $fflags, $ctx->{flag}, $fnum);
2404 0         0 return 1;
2405             }
2406              
2407 90         151 my $c3 = $self->__get($ctx, $src);
2408 90 100 100     270 if (defined $c3 and $c3 eq "\012") {
2409             # ,1,"foo, 3"\r\n
2410             # ^
2411 76         203 $self->__push_value($ctx, $v_ref, $fields, $fflags, $ctx->{flag}, $fnum);
2412 76         270 return 1;
2413             }
2414              
2415 14 100 66     47 if ($ctx->{useIO} and !$ctx->{eol_len}) {
2416 1 50       4 if ($c3 eq "\015") { # \r followed by an empty line
2417             # ,1,"foo, 3"\r\r
2418             # ^
2419 0         0 $self->__set_eol_is_cr($ctx);
2420 0         0 goto EOLX;
2421             }
2422 1 50       4 if ($c3 !~ /[^\x09\x20-\x7E]/) {
2423             # ,1,"foo\n 3",,"bar"\r
2424             # baz,4
2425             # ^
2426 1         11 $self->__set_eol_is_cr($ctx);
2427 1         2 $ctx->{used}--;
2428 1         2 $ctx->{has_ahead} = 1;
2429 1         5 $self->__push_value($ctx, $v_ref, $fields, $fflags, $ctx->{flag}, $fnum);
2430 1         4 return 1;
2431             }
2432             }
2433              
2434 13 100       39 $self->__parse_error($ctx, $quoesc ? 2023 : 2010, $ctx->{used} - 2);
2435 13         41 return;
2436             }
2437              
2438 57 100 100     163 if ($ctx->{allow_loose_quotes} and !$quoesc) {
2439             # ,1,"foo, 3"456",,bar,\r\n
2440             # ^
2441 10         16 $$v_ref .= $c;
2442 10         13 $c = $c2;
2443 10         565 goto RESTART;
2444             }
2445             # 1,"foo" ",3
2446             # ^
2447 47 100       77 if ($quoesc) {
2448 39         57 $ctx->{used}--;
2449 39         121 $self->__error_inside_quotes($ctx, 2023);
2450 37         129 return;
2451             }
2452 8         24 $self->__error_inside_quotes($ctx, 2011);
2453 8         26 return;
2454             }
2455             # !waitingForField, !InsideQuotes
2456 54 100       116 if ($ctx->{allow_loose_quotes}) { # 1,foo "boo" d'uh,1
2457 4         5 $ctx->{flag} |= IS_ERROR;
2458 4         6 $$v_ref .= $c;
2459             } else {
2460 50         168 $self->__error_inside_field($ctx, 2034);
2461 50         171 return;
2462             }
2463             }
2464             elsif (defined $c and defined $esc and $esc ne "\0" and $c eq $esc) {
2465             # This means quote_char != escape_char
2466 4655 100       9351 if ($waitingForField) {
    100          
    50          
2467 34         41 $waitingForField = 0;
2468 34 100       70 if ($ctx->{allow_unquoted_escape}) {
2469             # The escape character is the first character of an
2470             # unquoted field
2471             # ... get and store next character
2472 4         20 my $c2 = $self->__get($ctx, $src);
2473 4         8 $$v_ref = "";
2474              
2475 4 100       11 if (!defined $c2) { # EOF
2476 1         2 $ctx->{used}--;
2477 1         6 $self->__error_inside_field($ctx, 2035);
2478 1         3 return;
2479             }
2480 3 100 33     27 if ($c2 eq '0') {
    50 33        
      33        
      0        
      33        
      0        
2481 1         2 $$v_ref .= "\0";
2482             }
2483             elsif (
2484             (defined $quot and $c2 eq $quot) or
2485             (defined $sep and $c2 eq $sep) or
2486             (defined $esc and $c2 eq $esc) or
2487             $ctx->{allow_loose_escapes}
2488             ) {
2489 2 50       6 if ($ctx->{utf8}) {
2490 0         0 $ctx->{flag} |= IS_BINARY;
2491             }
2492 2         4 $$v_ref .= $c2;
2493             } else {
2494 0         0 $self->__parse_inside_quotes($ctx, 2025);
2495 0         0 return;
2496             }
2497             }
2498             }
2499             elsif ($ctx->{flag} & IS_QUOTED) {
2500 4612         9351 my $c2 = $self->__get($ctx, $src);
2501 4612 100       7524 if (!defined $c2) { # EOF
2502 3         8 $ctx->{used}--;
2503 3         9 $self->__error_inside_quotes($ctx, 2024);
2504 3         10 return;
2505             }
2506 4609 100 66     21235 if ($c2 eq '0') {
    100 66        
      100        
      66        
      100        
      66        
2507 2         4 $$v_ref .= "\0";
2508             }
2509             elsif (
2510             (defined $quot and $c2 eq $quot) or
2511             (defined $sep and $c2 eq $sep) or
2512             (defined $esc and $c2 eq $esc) or
2513             $ctx->{allow_loose_escapes}
2514             ) {
2515 4581 50       7070 if ($ctx->{utf8}) {
2516 0         0 $ctx->{flag} |= IS_BINARY;
2517             }
2518 4581         6281 $$v_ref .= $c2;
2519             } else {
2520 26         39 $ctx->{used}--;
2521 26         72 $self->__error_inside_quotes($ctx, 2025);
2522 26         88 return;
2523             }
2524             }
2525             elsif ($v_ref) {
2526 9         20 my $c2 = $self->__get($ctx, $src);
2527 9 100       17 if (!defined $c2) { # EOF
2528 4         6 $ctx->{used}--;
2529 4         20 $self->__error_inside_field($ctx, 2035);
2530 4         13 return;
2531             }
2532 5         8 $$v_ref .= $c2;
2533             }
2534             else {
2535 0         0 $self->__error_inside_field($ctx, 2036);
2536 0         0 return;
2537             }
2538             }
2539             elsif (defined $c and ($c eq "\012" or $c eq '' or (defined $eol and $c eq $eol and $eol ne "\015"))) { # EOL
2540             EOLX:
2541 2824 100 100     5942 if ($fnum == 1 && $ctx->{flag} == 0 && (!$v_ref || $$v_ref eq '') && $ctx->{skip_empty_rows}) {
      66        
      100        
      100        
2542 23         28 $ctx->{fld_idx} = 0;
2543 23         44 $c = $self->__get($ctx, $src);
2544 23 50       42 if (!defined $c) { # EOF
2545 0         0 $v_ref = undef;
2546 0         0 $waitingForField = 0;
2547 0         0 last LOOP;
2548             }
2549 23         1010 goto RESTART;
2550             }
2551              
2552 2801 100       4072 if ($waitingForField) {
2553             # ,1,"foo, 3",,bar,
2554             # ^
2555 222 100 100     676 if ($ctx->{blank_is_undef} or $ctx->{empty_is_undef}) {
2556 16         23 $$v_ref = undef;
2557             } else {
2558 206         301 $$v_ref = "";
2559             }
2560 222 100       395 unless ($ctx->{is_bound}) {
2561 221         415 push @$fields, $$v_ref;
2562             }
2563 222 100 66     435 if ($ctx->{keep_meta_info} and $fflags) {
2564 14         21 push @$fflags, $ctx->{flag};
2565             }
2566 222         740 return 1;
2567             }
2568 2579 100       4779 if ($ctx->{flag} & IS_QUOTED) {
    100          
2569             # ,1,"foo\n 3",,bar,
2570             # ^
2571 779         1052 $ctx->{flag} |= IS_BINARY;
2572 779 100       1130 unless ($ctx->{binary}) {
2573 29         110 $self->__error_inside_quotes($ctx, 2021);
2574 29         97 return;
2575             }
2576 750         954 $$v_ref .= $c;
2577             }
2578             elsif ($ctx->{verbatim}) {
2579             # ,1,foo\n 3,,bar,
2580             # This feature should be deprecated
2581 11         13 $ctx->{flag} |= IS_BINARY;
2582 11 100       20 unless ($ctx->{binary}) {
2583 1         6 $self->__error_inside_field($ctx, 2030);
2584 1         4 return;
2585             }
2586 10 100 100     30 $$v_ref .= $c unless $ctx->{eol} eq $c and $ctx->{useIO};
2587             }
2588             else {
2589             # sep=,
2590             # ^
2591 1789 100 100     3730 if (!$ctx->{recno} and $ctx->{fld_idx} == 1 and $ctx->{useIO} and $hit =~ /^sep=(.{1,16})$/i) {
      100        
      100        
2592 4         13 $ctx->{sep} = $1;
2593 34     34   86116 use bytes;
  34         93  
  34         139  
2594 4         6 my $len = length $ctx->{sep};
2595 4 50       10 if ($len <= 16) {
2596 4 100       12 $ctx->{sep_len} = $len == 1 ? 0 : $len;
2597 4         38 return $self->____parse($ctx, $src, $fields, $fflags);
2598             }
2599             }
2600              
2601             # ,1,"foo\n 3",,bar
2602             # ^
2603 1785         4081 $self->__push_value($ctx, $v_ref, $fields, $fflags, $ctx->{flag}, $fnum);
2604 1785         5931 return 1;
2605             }
2606             }
2607             elsif (defined $c and $c eq "\015" and !$ctx->{verbatim}) {
2608 1015 100       1623 if ($waitingForField) {
2609 113 100       221 if ($ctx->{eol_is_cr}) {
2610             # ,1,"foo\n 3",,bar,\r
2611             # ^
2612 29         36 $c = "\012";
2613 29         831 goto EOLX;
2614             }
2615              
2616 84         195 my $c2 = $self->__get($ctx, $src);
2617 84 100       177 if (!defined $c2) { # EOF
2618             # ,1,"foo\n 3",,bar,\r
2619             # ^
2620 5         6 $c = undef;
2621 5 50       16 last unless $seenSomething;
2622 5         312 goto RESTART;
2623             }
2624 79 100       181 if ($c2 eq "\012") { # \r is not optional before EOLX!
2625             # ,1,"foo\n 3",,bar,\r\n
2626             # ^
2627 69         101 $c = $c2;
2628 69         1972 goto EOLX;
2629             }
2630              
2631 10 100 66     48 if ($ctx->{useIO} and !$ctx->{eol_len}) {
2632 5 50       11 if ($c2 eq "\012") { # \r followed by an empty line
2633             # ,1,"foo\n 3",,bar,\r\r
2634             # ^
2635 0         0 $self->__set_eol_is_cr($ctx);
2636 0         0 goto EOLX;
2637             }
2638 5         7 $waitingForField = 0;
2639 5 100       16 if ($c2 !~ /[^\x09\x20-\x7E]/) {
2640             # ,1,"foo\n 3",,bar,\r
2641             # baz,4
2642             # ^
2643 2         6 $self->__set_eol_is_cr($ctx);
2644 2         2 $ctx->{used}--;
2645 2         4 $ctx->{has_ahead} = 1;
2646 2 50 66     13 if ($fnum == 1 && $ctx->{flag} == 0 && (!$v_ref or $$v_ref eq '') && $ctx->{skip_empty_rows}) {
      33        
      66        
      33        
2647 1         2 $ctx->{fld_idx} = 0;
2648 1         3 $c = $self->__get($ctx, $src);
2649 1 50       2 if (!defined $c) { # EOF
2650 0         0 $v_ref = undef;
2651 0         0 $waitingForField = 0;
2652 0         0 last LOOP;
2653             }
2654 1         2 $$v_ref = $c2;
2655 1         49 goto RESTART;
2656             }
2657 1         3 $self->__push_value($ctx, $v_ref, $fields, $fflags, $ctx->{flag}, $fnum);
2658 1         5 return 1;
2659             }
2660             }
2661              
2662             # ,1,"foo\n 3",,bar,\r\t
2663             # ^
2664 8         9 $ctx->{used}--;
2665 8         27 $self->__error_inside_field($ctx, 2031);
2666 8         27 return;
2667             }
2668 902 100       1385 if ($ctx->{flag} & IS_QUOTED) {
2669             # ,1,"foo\r 3",,bar,\r\t
2670             # ^
2671 593         684 $ctx->{flag} |= IS_BINARY;
2672 593 100       878 unless ($ctx->{binary}) {
2673 70         168 $self->__error_inside_quotes($ctx, 2022);
2674 70         211 return;
2675             }
2676 523         661 $$v_ref .= $c;
2677             }
2678             else {
2679 309 100       544 if ($ctx->{eol_is_cr}) {
2680             # ,1,"foo\n 3",,bar\r
2681             # ^
2682 163         4723 goto EOLX;
2683             }
2684              
2685 146         327 my $c2 = $self->__get($ctx, $src);
2686 146 100 100     465 if (defined $c2 and $c2 eq "\012") { # \r is not optional before EOLX!
2687             # ,1,"foo\n 3",,bar\r\n
2688             # ^
2689 130         3760 goto EOLX;
2690             }
2691              
2692 16 100 66     63 if ($ctx->{useIO} and !$ctx->{eol_len}) {
2693 11 100 100     60 if ($c2 !~ /[^\x09\x20-\x7E]/
2694             # ,1,"foo\n 3",,bar\r
2695             # baz,4
2696             # ^
2697             or $c2 eq "\015"
2698             # ,1,"foo\n 3",,bar,\r\r
2699             # ^
2700             ) {
2701 5         31 $self->__set_eol_is_cr($ctx);
2702 5         6 $ctx->{used}--;
2703 5         10 $ctx->{has_ahead} = 1;
2704 5 0 33     14 if ($fnum == 1 && $ctx->{flag} == 0 && (!$v_ref or $$v_ref eq '') && $ctx->{skip_empty_rows}) {
      0        
      33        
      0        
2705 0         0 $ctx->{fld_idx} = 0;
2706 0         0 $c = $self->__get($ctx, $src);
2707 0 0       0 if (!defined $c) { # EOL
2708 0         0 $v_ref = undef;
2709 0         0 $waitingForField = 0;
2710 0         0 last LOOP;
2711             }
2712 0         0 goto RESTART;
2713             }
2714 5         16 $self->__push_value($ctx, $v_ref, $fields, $fflags, $ctx->{flag}, $fnum);
2715 5         19 return 1;
2716             }
2717             }
2718              
2719             # ,1,"foo\n 3",,bar\r\t
2720             # ^
2721 11         29 $self->__error_inside_field($ctx, 2032);
2722 11         35 return;
2723             }
2724             }
2725             else {
2726 32095 50 66     54921 if ($ctx->{eolx} and $c eq $eol) {
2727 0         0 $c = '';
2728 0         0 goto EOLX;
2729             }
2730              
2731 32095 100       42351 if ($waitingForField) {
2732 602 100 100     1331 if (!$spl && $ctx->{comment_str} && $ctx->{tmp} =~ /\A$ctx->{comment_str}/) {
      100        
2733 6         10 $ctx->{used} = $ctx->{size};
2734 6         33 next LOOP;
2735             }
2736 596 100 100     1422 if ($ctx->{allow_whitespace} and $self->__is_whitespace($ctx, $c)) {
2737 231         290 do {
2738 341         534 $c = $self->__get($ctx, $src);
2739 341 100       744 last if !defined $c;
2740             } while $self->__is_whitespace($ctx, $c);
2741 230         10657 goto RESTART;
2742             }
2743 365         472 $waitingForField = 0;
2744 365         16846 goto RESTART;
2745             }
2746 31493 100       43880 if ($ctx->{flag} & IS_QUOTED) {
2747 29407 100 66     76782 if (!defined $c or $c =~ /[^\x09\x20-\x7E]/) {
2748 3261         4292 $ctx->{flag} |= IS_BINARY;
2749 3261 100 100     4884 unless ($ctx->{binary} or $ctx->{utf8}) {
2750 5         18 $self->__error_inside_quotes($ctx, 2026);
2751 5         19 return;
2752             }
2753             }
2754 29402         35787 $$v_ref .= $c;
2755             } else {
2756 2086 100 100     5763 if (!defined $c or $c =~ /[^\x09\x20-\x7E]/) {
2757 450 100 100     1223 last if $ctx->{useIO} && !defined $c;
2758 447         627 $ctx->{flag} |= IS_BINARY;
2759 447 50 66     730 unless ($ctx->{binary} or $ctx->{utf8}) {
2760 9         48 $self->__error_inside_field($ctx, 2037);
2761 9         34 return;
2762             }
2763             }
2764 2074         2734 $$v_ref .= $c;
2765             }
2766             }
2767 48870 100 100     235890 last LOOP if $ctx->{useIO} and $ctx->{verbatim} and $ctx->{used} == $ctx->{size};
      100        
2768             }
2769             }
2770              
2771 398 100       682 if ($waitingForField) {
2772 343 100 66     1255 if ($seenSomething or !$ctx->{useIO}) {
2773             # new field
2774 32 100       127 if (!$v_ref) {
2775 31 50       65 if ($ctx->{is_bound}) {
2776 0         0 $v_ref = $self->__bound_field($ctx, $fnum, 0);
2777             } else {
2778 31         45 $value = '';
2779 31         45 $v_ref = \$value;
2780             }
2781 31         36 $fnum++;
2782 31 50       50 return unless $v_ref;
2783 31         41 $ctx->{flag} = 0;
2784 31         40 $ctx->{fld_idx}++;
2785             }
2786 32 100 100     106 if ($ctx->{blank_is_undef} or $ctx->{empty_is_undef}) {
2787 9         11 $$v_ref = undef;
2788             } else {
2789 23         37 $$v_ref = "";
2790             }
2791 32 50       60 unless ($ctx->{is_bound}) {
2792 32         53 push @$fields, $$v_ref;
2793             }
2794 32 100 66     90 if ($ctx->{keep_meta_info} and $fflags) {
2795 3         5 push @$fflags, $ctx->{flag};
2796             }
2797 32         142 return 1;
2798             }
2799 311         895 $self->SetDiag(2012);
2800 311         897 return;
2801             }
2802              
2803 55 100       120 if ($ctx->{flag} & IS_QUOTED) {
2804 14         59 $self->__error_inside_quotes($ctx, 2027);
2805 13         38 return;
2806             }
2807              
2808 41 50       90 if ($v_ref) {
2809 41         93 $self->__push_value($ctx, $v_ref, $fields, $fflags, $ctx->{flag}, $fnum);
2810             }
2811 41         131 return 1;
2812             }
2813              
2814             sub __get_from_src {
2815 6303     6303   10032 my ($self, $ctx, $src) = @_;
2816 6303 100 100     19654 return 1 if defined $ctx->{tmp} and $ctx->{used} <= 0;
2817 4185 50       8049 return 1 if $ctx->{used} < $ctx->{size};
2818 4185 100       8409 return unless $ctx->{useIO};
2819 2820         54133 my $res = $src->getline;
2820 2820 100       69058 if (defined $res) {
    100          
2821 2308 50       3990 if ($ctx->{has_ahead}) {
2822 0         0 $ctx->{tmp} = $self->{_AHEAD};
2823 0 0       0 $ctx->{tmp} .= $ctx->{eol} if $ctx->{eol_len};
2824 0         0 $ctx->{tmp} .= $res;
2825 0         0 $ctx->{has_ahead} = 0;
2826             } else {
2827 2308         3393 $ctx->{tmp} = $res;
2828             }
2829 2308 50       4725 if ($ctx->{size} = length $ctx->{tmp}) {
2830 2308         2844 $ctx->{used} = -1;
2831 2308 100       5124 $ctx->{utf8} = 1 if utf8::is_utf8($ctx->{tmp});
2832 2308         4876 pos($ctx->{tmp}) = 0;
2833 2308         6237 return 1;
2834             }
2835             } elsif (delete $ctx->{has_leftover}) {
2836 147         345 $ctx->{tmp} = $self->{_AHEAD};
2837 147         197 $ctx->{has_ahead} = 0;
2838 147         206 $ctx->{useIO} |= useIO_EOF;
2839 147 50       254 if ($ctx->{size} = length $ctx->{tmp}) {
2840 147         187 $ctx->{used} = -1;
2841 147 50       323 $ctx->{utf8} = 1 if utf8::is_utf8($ctx->{tmp});
2842 147         252 pos($ctx->{tmp}) = 0;
2843 147         365 return 1;
2844             }
2845             }
2846 365 100       838 $ctx->{tmp} = '' unless defined $ctx->{tmp};
2847 365         550 $ctx->{useIO} |= useIO_EOF;
2848 365         760 return;
2849             }
2850              
2851             sub __set_eol_is_cr {
2852 8     8   21 my ($self, $ctx) = @_;
2853 8         16 $ctx->{eol} = "\015";
2854 8         14 $ctx->{eol_is_cr} = 1;
2855 8         13 $ctx->{eol_len} = 1;
2856 8         44 %{$self->{_CACHE}} = %$ctx;
  8         130  
2857              
2858 8         34 $self->{eol} = $ctx->{eol};
2859             }
2860              
2861             sub __bound_field {
2862 101     101   497 my ($self, $ctx, $i, $keep) = @_;
2863 101 100       183 if ($i >= $ctx->{is_bound}) {
2864 3         15 $self->SetDiag(3006);
2865 3         5 return;
2866             }
2867 98 50       193 if (ref $ctx->{bound} eq 'ARRAY') {
2868 98         146 my $ref = $ctx->{bound}[$i];
2869 98 50       161 if (ref $ref) {
2870 98 100       156 if ($keep) {
2871 14         23 return $ref;
2872             }
2873 84 100       188 unless (Scalar::Util::readonly($$ref)) {
2874 83         122 $$ref = "";
2875 83         130 return $ref;
2876             }
2877             }
2878             }
2879 1         5 $self->SetDiag(3008);
2880 1         3 return;
2881             }
2882              
2883             sub __get {
2884 17350     17350   24044 my ($self, $ctx, $src) = @_;
2885 17350 50       25975 return unless defined $ctx->{used};
2886 17350 100       25783 if ($ctx->{used} >= $ctx->{size}) {
2887 1355 100       2520 if ($self->__get_from_src($ctx, $src)) {
2888 20         60 return $self->__get($ctx, $src);
2889             }
2890 1335         2117 return;
2891             }
2892 15995         19154 my $pos = pos($ctx->{tmp});
2893 15995 50       88130 if ($ctx->{tmp} =~ /\G($ctx->{_re}|.)/gs) {
2894 15995         25621 my $c = $1;
2895 15995 100       28941 if ($c =~ /[^\x09\012\015\x20-\x7e]/) {
2896 1222         1659 $ctx->{flag} |= IS_BINARY;
2897             }
2898 15995         20151 $ctx->{used} = pos($ctx->{tmp});
2899 15995         35879 return $c;
2900             } else {
2901 0 0       0 if ($self->__get_from_src($ctx, $src)) {
2902 0         0 return $self->__get($ctx, $src);
2903             }
2904 0         0 pos($ctx->{tmp}) = $pos;
2905 0         0 return;
2906             }
2907             }
2908              
2909             sub __error_inside_quotes {
2910 194     194   307 my ($self, $ctx, $error) = @_;
2911 194         572 $self->__parse_error($ctx, $error, $ctx->{used} - 1);
2912             }
2913              
2914             sub __error_inside_field {
2915 84     84   146 my ($self, $ctx, $error) = @_;
2916 84         231 $self->__parse_error($ctx, $error, $ctx->{used} - 1);
2917             }
2918              
2919             sub __parse_error {
2920 299     299   460 my ($self, $ctx, $error, $pos) = @_;
2921 299         471 $self->{_ERROR_POS} = $pos;
2922 299         434 $self->{_ERROR_FLD} = $ctx->{fld_idx};
2923 299 50       612 $self->{_ERROR_INPUT} = $ctx->{tmp} if $ctx->{tmp};
2924 299         622 $self->SetDiag($error);
2925 296         463 return;
2926             }
2927              
2928             sub __is_whitespace {
2929 5064     5064   7015 my ($self, $ctx, $c) = @_;
2930 5064 100       8143 return unless defined $c;
2931             return (
2932             (!defined $ctx->{sep} or $c ne $ctx->{sep}) &&
2933             (!defined $ctx->{quo} or $c ne $ctx->{quo}) &&
2934 4529   33     19638 (!defined $ctx->{escape_char} or $c ne $ctx->{escape_char}) &&
2935             ($c eq " " or $c eq "\t")
2936             );
2937             }
2938              
2939             sub __push_value { # AV_PUSH (part of)
2940 20688     20688   29510 my ($self, $ctx, $v_ref, $fields, $fflags, $flag, $fnum) = @_;
2941 20688 100       30213 utf8::encode($$v_ref) if $ctx->{utf8};
2942 20688 100 66     32609 if ($ctx->{formula} && $$v_ref && substr($$v_ref, 0, 1) eq '=') {
      100        
2943 27         53 my $value = $self->_formula($ctx, $$v_ref, $fnum);
2944 25 100       401 push @$fields, defined $value ? $value : undef;
2945 25         31 return;
2946             }
2947 20661 100 66     59276 if (
      66        
      100        
2948             (!defined $$v_ref or $$v_ref eq '') and
2949             ($ctx->{empty_is_undef} or (!($flag & IS_QUOTED) and $ctx->{blank_is_undef}))
2950             ) {
2951 12         18 $$v_ref = undef;
2952             } else {
2953 20649 100 100     39658 if ($ctx->{allow_whitespace} && !($flag & IS_QUOTED)) {
2954 1725         3059 $$v_ref =~ s/[ \t]+$//;
2955             }
2956 20649 100 66     39027 if ($flag & IS_BINARY and $ctx->{decode_utf8} and ($ctx->{utf8} || _is_valid_utf8($$v_ref))) {
      100        
      66        
2957 2135         4659 utf8::decode($$v_ref);
2958             }
2959             }
2960 20661 100       31685 unless ($ctx->{is_bound}) {
2961 20580         35268 push @$fields, $$v_ref;
2962             }
2963 20661 100 66     38050 if ($ctx->{keep_meta_info} and $fflags) {
2964 88         150 push @$fflags, $flag;
2965             }
2966             }
2967              
2968             sub getline {
2969 1586     1586 1 266227 my ($self, $io) = @_;
2970              
2971 1586         2040 my (@fields, @fflags);
2972 1586         3676 my $res = $self->__parse(\@fields, \@fflags, $io, 1);
2973 1584 100       6637 $res ? \@fields : undef;
2974             }
2975              
2976             sub getline_all {
2977 279     279 1 463 my ( $self, $io, $offset, $len ) = @_;
2978              
2979 279         468 my $ctx = $self->_setup_ctx;
2980              
2981 279         352 my $tail = 0;
2982 279         305 my $n = 0;
2983 279   100     871 $offset ||= 0;
2984              
2985 279 100       435 if ( $offset < 0 ) {
2986 12         16 $tail = -$offset;
2987 12         16 $offset = -1;
2988             }
2989              
2990 279         336 my (@row, @list);
2991 279         624 while ($self->___parse($ctx, \@row, undef, $io, 1)) {
2992 609         1274 $ctx = $self->_setup_ctx;
2993              
2994 609 100       1164 if ($offset > 0) {
2995 12         15 $offset--;
2996 12         21 @row = ();
2997 12         29 next;
2998             }
2999 597 100 100     1677 if ($n++ >= $tail and $tail) {
3000 12         14 shift @list;
3001 12         23 $n--;
3002             }
3003 597 100 100     1582 if (($ctx->{has_hooks} || 0) & HOOK_AFTER_PARSE) {
3004 117 100       239 unless ($self->_hook(after_parse => \@row)) {
3005 63         92 @row = ();
3006 63         140 next;
3007             }
3008             }
3009 534         1281 push @list, [@row];
3010 534         809 @row = ();
3011              
3012 534 100 100     1573 last if defined $len && $n >= $len and $offset >= 0; # exceeds limit size
      100        
3013             }
3014              
3015 279 100 100     598 if ( defined $len && $n > $len ) {
3016 8         20 @list = splice( @list, 0, $len);
3017             }
3018              
3019 279         1411 return \@list;
3020             }
3021              
3022             sub _is_valid_utf8 {
3023 3713 100   3713   44523 return ( $_[0] =~ /^(?:
3024             [\x00-\x7F]
3025             |[\xC2-\xDF][\x80-\xBF]
3026             |[\xE0][\xA0-\xBF][\x80-\xBF]
3027             |[\xE1-\xEC][\x80-\xBF][\x80-\xBF]
3028             |[\xED][\x80-\x9F][\x80-\xBF]
3029             |[\xEE-\xEF][\x80-\xBF][\x80-\xBF]
3030             |[\xF0][\x90-\xBF][\x80-\xBF][\x80-\xBF]
3031             |[\xF1-\xF3][\x80-\xBF][\x80-\xBF][\x80-\xBF]
3032             |[\xF4][\x80-\x8F][\x80-\xBF][\x80-\xBF]
3033             )+$/x ) ? 1 : 0;
3034             }
3035              
3036             ################################################################################
3037             # methods for errors
3038             ################################################################################
3039              
3040             sub _set_error_diag {
3041 1     1   59 my ( $self, $error, $pos ) = @_;
3042              
3043 1         4 $self->SetDiag($error);
3044              
3045 1 50       4 if (defined $pos) {
3046 0         0 $_[0]->{_ERROR_POS} = $pos;
3047             }
3048              
3049 1         7 return;
3050             }
3051              
3052             sub error_input {
3053 8     8 1 486 my $self = shift;
3054 8 100 66     50 if ($self and ((Scalar::Util::reftype($self) || '') eq 'HASH' or (ref $self) =~ /^Text::CSV/)) {
      66        
3055 4         16 return $self->{_ERROR_INPUT};
3056             }
3057 4         14 return;
3058             }
3059              
3060             sub _sv_diag {
3061 3513     3513   4930 my ($self, $error) = @_;
3062 3513         11524 bless [$error, $ERRORS->{$error}], 'Text::CSV::ErrorDiag';
3063             }
3064              
3065             sub _set_diag {
3066 1666     1666   2544 my ($self, $ctx, $error) = @_;
3067              
3068 1666         2797 $last_error = $self->_sv_diag($error);
3069 1666         3333 $self->{_ERROR_DIAG} = $last_error;
3070 1666 100       2977 if ($error == 0) {
3071 6         8 $self->{_ERROR_POS} = 0;
3072 6         9 $self->{_ERROR_FLD} = 0;
3073 6         7 $self->{_ERROR_INPUT} = undef;
3074 6         11 $ctx->{has_error_input} = 0;
3075             }
3076 1666 100       2607 if ($error == 2012) { # EOF
3077 312         441 $self->{_EOF} = 1;
3078             }
3079 1666 100       2711 if ($ctx->{auto_diag}) {
3080 262         504 $self->error_diag;
3081             }
3082 1663         5991 return $last_error;
3083             }
3084              
3085             sub SetDiag {
3086 3513     3513 1 7501 my ($self, $error, $errstr) = @_;
3087 3513         3992 my $res;
3088 3513 100       5723 if (ref $self) {
3089 1666         3037 my $ctx = $self->_setup_ctx;
3090 1666         3370 $res = $self->_set_diag($ctx, $error);
3091              
3092             } else {
3093 1847         2241 $last_error = $error;
3094 1847         3088 $res = $self->_sv_diag($error);
3095             }
3096 3510 100       6237 if (defined $errstr) {
3097 917         2103 $res->[1] = $errstr;
3098             }
3099 3510         23041 $res;
3100             }
3101              
3102             ################################################################################
3103             package Text::CSV::ErrorDiag;
3104              
3105 34     34   95799 use strict;
  34         84  
  34         2374  
3106             use overload (
3107 34         277 '""' => \&stringify,
3108             '+' => \&numeric,
3109             '-' => \&numeric,
3110             '*' => \&numeric,
3111             '/' => \&numeric,
3112             fallback => 1,
3113 34     34   34783 );
  34         28689  
3114              
3115              
3116             sub numeric {
3117 4360     4360   6096 my ($left, $right) = @_;
3118 4360 50       12318 return ref $left ? $left->[0] : $right->[0];
3119             }
3120              
3121              
3122             sub stringify {
3123 2335     2335   421557 $_[0]->[1];
3124             }
3125             ################################################################################
3126             1;
3127             __END__