File Coverage

blib/lib/Text/CSV_PP.pm
Criterion Covered Total %
statement 1619 1704 95.0
branch 1183 1312 90.1
condition 718 880 81.4
subroutine 120 120 100.0
pod 59 60 98.3
total 3699 4076 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 32     32   71619 use strict;
  32         74  
  32         953  
11 32     32   153 use Exporter ();
  32         58  
  32         694  
12 32     32   165 use vars qw($VERSION @ISA @EXPORT_OK);
  32         80  
  32         1993  
13 32     32   203 use Carp;
  32         67  
  32         12993  
14              
15             $VERSION = '2.01';
16             @ISA = qw(Exporter);
17             @EXPORT_OK = qw(csv);
18              
19 4     4 1 12 sub PV { 0 }
20 10     10 1 1223 sub IV { 1 }
21 8     8 1 30 sub NV { 2 }
22              
23             sub IS_QUOTED () { 0x0001; }
24             sub IS_BINARY () { 0x0002; }
25             sub IS_ERROR () { 0x0004; }
26             sub IS_MISSING () { 0x0010; }
27              
28             sub HOOK_ERROR () { 0x0001; }
29             sub HOOK_AFTER_PARSE () { 0x0002; }
30             sub HOOK_BEFORE_PRINT () { 0x0004; }
31              
32             sub useIO_EOF () { 0x0010; }
33              
34             my $ERRORS = {
35             # Generic errors
36             1000 => "INI - constructor failed",
37             1001 => "INI - sep_char is equal to quote_char or escape_char",
38             1002 => "INI - allow_whitespace with escape_char or quote_char SP or TAB",
39             1003 => "INI - \\r or \\n in main attr not allowed",
40             1004 => "INI - callbacks should be undef or a hashref",
41             1005 => "INI - EOL too long",
42             1006 => "INI - SEP too long",
43             1007 => "INI - QUOTE too long",
44             1008 => "INI - SEP undefined",
45              
46             1010 => "INI - the header is empty",
47             1011 => "INI - the header contains more than one valid separator",
48             1012 => "INI - the header contains an empty field",
49             1013 => "INI - the header contains nun-unique fields",
50             1014 => "INI - header called on undefined stream",
51              
52             # Syntax errors
53             1500 => "PRM - Invalid/unsupported arguments(s)",
54             1501 => "PRM - The key attribute is passed as an unsupported type",
55             1502 => "PRM - The value attribute is passed without the key attribute",
56             1503 => "PRM - The value attribute is passed as an unsupported type",
57              
58             # Parse errors
59             2010 => "ECR - QUO char inside quotes followed by CR not part of EOL",
60             2011 => "ECR - Characters after end of quoted field",
61             2012 => "EOF - End of data in parsing input stream",
62             2013 => "ESP - Specification error for fragments RFC7111",
63             2014 => "ENF - Inconsistent number of fields",
64              
65             # EIQ - Error Inside Quotes
66             2021 => "EIQ - NL char inside quotes, binary off",
67             2022 => "EIQ - CR char inside quotes, binary off",
68             2023 => "EIQ - QUO character not allowed",
69             2024 => "EIQ - EOF cannot be escaped, not even inside quotes",
70             2025 => "EIQ - Loose unescaped escape",
71             2026 => "EIQ - Binary character inside quoted field, binary off",
72             2027 => "EIQ - Quoted field not terminated",
73              
74             # EIF - Error Inside Field
75             2030 => "EIF - NL char inside unquoted verbatim, binary off",
76             2031 => "EIF - CR char is first char of field, not part of EOL",
77             2032 => "EIF - CR char inside unquoted, not part of EOL",
78             2034 => "EIF - Loose unescaped quote",
79             2035 => "EIF - Escaped EOF in unquoted field",
80             2036 => "EIF - ESC error",
81             2037 => "EIF - Binary character in unquoted field, binary off",
82              
83             # Combine errors
84             2110 => "ECB - Binary character in Combine, binary off",
85              
86             # IO errors
87             2200 => "EIO - print to IO failed. See errno",
88              
89             # Hash-Ref errors
90             3001 => "EHR - Unsupported syntax for column_names ()",
91             3002 => "EHR - getline_hr () called before column_names ()",
92             3003 => "EHR - bind_columns () and column_names () fields count mismatch",
93             3004 => "EHR - bind_columns () only accepts refs to scalars",
94             3006 => "EHR - bind_columns () did not pass enough refs for parsed fields",
95             3007 => "EHR - bind_columns needs refs to writable scalars",
96             3008 => "EHR - unexpected error in bound fields",
97             3009 => "EHR - print_hr () called before column_names ()",
98             3010 => "EHR - print_hr () called with invalid arguments",
99              
100             4001 => "PRM - The key does not exist as field in the data",
101              
102             5001 => "PRM - The result does not match the output to append to",
103             5002 => "PRM - Unsupported output",
104              
105             0 => "",
106             };
107              
108             BEGIN {
109 32 50   32   392 if ( $] < 5.006 ) {
    50          
    50          
110 0 0       0 $INC{'bytes.pm'} = 1 unless $INC{'bytes.pm'}; # dummy
111 32     32   245 no strict 'refs';
  32         74  
  32         3317  
112 0         0 *{"utf8::is_utf8"} = sub { 0; };
  0         0  
  0         0  
113 0         0 *{"utf8::decode"} = sub { };
  0         0  
114             }
115             elsif ( $] < 5.008 ) {
116 32     32   221 no strict 'refs';
  32         61  
  32         10246  
117 0         0 *{"utf8::is_utf8"} = sub { 0; };
  0         0  
  0         0  
118 0         0 *{"utf8::decode"} = sub { };
  0         0  
119 0         0 *{"utf8::encode"} = sub { };
  0         0  
120             }
121             elsif ( !defined &utf8::is_utf8 ) {
122 0         0 require Encode;
123 0         0 *utf8::is_utf8 = *Encode::is_utf8;
124             }
125              
126 32         2255 eval q| require Scalar::Util |;
127 32 50       381424 if ( $@ ) {
128 0         0 eval q| require B |;
129 0 0       0 if ( $@ ) {
130 0         0 Carp::croak $@;
131             }
132             else {
133 0         0 my %tmap = qw(
134             B::NULL SCALAR
135             B::HV HASH
136             B::AV ARRAY
137             B::CV CODE
138             B::IO IO
139             B::GV GLOB
140             B::REGEXP REGEXP
141             );
142             *Scalar::Util::reftype = sub (\$) {
143 0         0 my $r = shift;
144 0 0       0 return undef unless length(ref($r));
145 0         0 my $t = ref(B::svref_2object($r));
146             return
147 0 0       0 exists $tmap{$t} ? $tmap{$t}
    0          
148             : length(ref($$r)) ? 'REF'
149             : 'SCALAR';
150 0         0 };
151             *Scalar::Util::readonly = sub (\$) {
152 0         0 my $b = B::svref_2object( $_[0] );
153 0         0 $b->FLAGS & 0x00800000; # SVf_READONLY?
154 0         0 };
155             }
156             }
157             }
158              
159             ################################################################################
160             #
161             # Common pure perl methods, taken almost directly from Text::CSV_XS.
162             # (These should be moved into a common class eventually, so that
163             # both XS and PP don't need to apply the same changes.)
164             #
165             ################################################################################
166              
167             ################################################################################
168             # version
169             ################################################################################
170              
171             sub version {
172 2     2 1 646 return $VERSION;
173             }
174              
175             ################################################################################
176             # new
177             ################################################################################
178              
179             my %def_attr = (
180             eol => '',
181             sep_char => ',',
182             quote_char => '"',
183             escape_char => '"',
184             binary => 0,
185             decode_utf8 => 1,
186             auto_diag => 0,
187             diag_verbose => 0,
188             strict => 0,
189             blank_is_undef => 0,
190             empty_is_undef => 0,
191             allow_whitespace => 0,
192             allow_loose_quotes => 0,
193             allow_loose_escapes => 0,
194             allow_unquoted_escape => 0,
195             always_quote => 0,
196             quote_empty => 0,
197             quote_space => 1,
198             quote_binary => 1,
199             escape_null => 1,
200             keep_meta_info => 0,
201             verbatim => 0,
202             formula => 0,
203             skip_empty_rows => 0,
204             undef_str => undef,
205             comment_str => undef,
206             types => undef,
207             callbacks => undef,
208              
209             _EOF => 0,
210             _RECNO => 0,
211             _STATUS => undef,
212             _FIELDS => undef,
213             _FFLAGS => undef,
214             _STRING => undef,
215             _ERROR_INPUT => undef,
216             _COLUMN_NAMES => undef,
217             _BOUND_COLUMNS => undef,
218             _AHEAD => undef,
219             _FORMULA_CB => undef,
220              
221             ENCODING => undef,
222             );
223              
224             my %attr_alias = (
225             quote_always => "always_quote",
226             verbose_diag => "diag_verbose",
227             quote_null => "escape_null",
228             escape => "escape_char",
229             comment => "comment_str",
230             );
231              
232             my $last_new_error = Text::CSV_PP->SetDiag(0);
233             my $ebcdic = ord("A") == 0xC1; # Faster than $Config{'ebcdic'}
234             my $last_error;
235              
236             # NOT a method: is also used before bless
237             sub _unhealthy_whitespace {
238 15565     15565   27890 my ($self, $aw) = @_;
239 15565 100       46272 $aw or return 0; # no checks needed without allow_whitespace
240              
241 3568         5279 my $quo = $self->{quote};
242 3568 100 100     8905 defined $quo && length ($quo) or $quo = $self->{quote_char};
243 3568         5208 my $esc = $self->{escape_char};
244              
245 3568 100 100     16103 defined $quo && $quo =~ m/^[ \t]/ and return 1002;
246 3326 100 100     12014 defined $esc && $esc =~ m/^[ \t]/ and return 1002;
247              
248 3036         7475 return 0;
249             }
250              
251             sub _check_sanity {
252 12259     12259   17032 my $self = shift;
253              
254 12259         19818 my $eol = $self->{eol};
255 12259         18291 my $sep = $self->{sep};
256 12259 100 100     32025 defined $sep && length ($sep) or $sep = $self->{sep_char};
257 12259         17936 my $quo = $self->{quote};
258 12259 100 100     28251 defined $quo && length ($quo) or $quo = $self->{quote_char};
259 12259         17877 my $esc = $self->{escape_char};
260              
261             # use DP;::diag ("SEP: '", DPeek ($sep),
262             # "', QUO: '", DPeek ($quo),
263             # "', ESC: '", DPeek ($esc),"'");
264              
265             # sep_char should not be undefined
266 12259 100       25037 $sep ne "" or return 1008;
267 12257 100       25228 length ($sep) > 16 and return 1006;
268 12256 100       37511 $sep =~ m/[\r\n]/ and return 1003;
269              
270 12250 100       22823 if (defined $quo) {
271 12239 100       23341 $quo eq $sep and return 1001;
272 12011 100       23685 length ($quo) > 16 and return 1007;
273 12010 100       23364 $quo =~ m/[\r\n]/ and return 1003;
274             }
275 12015 100       22029 if (defined $esc) {
276 11999 100       22383 $esc eq $sep and return 1001;
277 11831 100       22300 $esc =~ m/[\r\n]/ and return 1003;
278             }
279 11841 100       20609 if (defined $eol) {
280 11837 100       21679 length ($eol) > 16 and return 1005;
281             }
282              
283 11840         22809 return _unhealthy_whitespace ($self, $self->{allow_whitespace});
284             }
285              
286             sub known_attributes {
287 3     3 1 663 sort grep !m/^_/ => "sep", "quote", keys %def_attr;
288             }
289              
290             sub new {
291 885     885 1 4314 $last_new_error = Text::CSV_PP->SetDiag(1000,
292             'usage: my $csv = Text::CSV_PP->new ([{ option => value, ... }]);');
293              
294 885         1622 my $proto = shift;
295 885 100 66     3557 my $class = ref $proto || $proto or return;
296 884 100 100     4103 @_ > 0 && ref $_[0] ne "HASH" and return;
297 876   100     2208 my $attr = shift || {};
298             my %attr = map {
299 876 100       3090 my $k = m/^[a-zA-Z]\w+$/ ? lc $_ : $_;
  1975         8306  
300 1975 100       4518 exists $attr_alias{$k} and $k = $attr_alias{$k};
301 1975         5729 ($k => $attr->{$_});
302             } keys %$attr;
303              
304 876         2002 my $sep_aliased = 0;
305 876 100       2162 if (exists $attr{sep}) {
306 7         24 $attr{sep_char} = delete $attr{sep};
307 7         19 $sep_aliased = 1;
308             }
309 876         1398 my $quote_aliased = 0;
310 876 100       1968 if (exists $attr{quote}) {
311 25         60 $attr{quote_char} = delete $attr{quote};
312 25         41 $quote_aliased = 1;
313             }
314             exists $attr{formula_handling} and
315 876 100       1847 $attr{formula} = delete $attr{formula_handling};
316 876         1620 my $attr_formula = delete $attr{formula};
317              
318 876         2319 for (keys %attr) {
319 1937 100 100     7352 if (m/^[a-z]/ && exists $def_attr{$_}) {
320             # uncoverable condition false
321 1930 100 100     7049 defined $attr{$_} && m/_char$/ and utf8::decode ($attr{$_});
322 1930         3322 next;
323             }
324             # croak?
325 7         32 $last_new_error = Text::CSV_PP->SetDiag(1000, "INI - Unknown attribute '$_'");
326 7 100       26 $attr{auto_diag} and error_diag ();
327 7         31 return;
328             }
329 869 100       2163 if ($sep_aliased) {
330 7         56 my @b = unpack "U0C*", $attr{sep_char};
331 7 100       30 if (@b > 1) {
332 6         18 $attr{sep} = $attr{sep_char};
333 6         20 $attr{sep_char} = "\0";
334             }
335             else {
336 1         3 $attr{sep} = undef;
337             }
338             }
339 869 100 100     2217 if ($quote_aliased and defined $attr{quote_char}) {
340 21         92 my @b = unpack "U0C*", $attr{quote_char};
341 21 100       57 if (@b > 1) {
342 7         19 $attr{quote} = $attr{quote_char};
343 7         19 $attr{quote_char} = "\0";
344             }
345             else {
346 14         32 $attr{quote} = undef;
347             }
348             }
349              
350 869         16506 my $self = { %def_attr, %attr };
351 869 100       3537 if (my $ec = _check_sanity ($self)) {
352 35         99 $last_new_error = Text::CSV_PP->SetDiag($ec);
353 35 100       81 $attr{auto_diag} and error_diag ();
354 35         222 return;
355             }
356 834 100 100     2723 if (defined $self->{callbacks} && ref $self->{callbacks} ne "HASH") {
357 6         950 Carp::carp "The 'callbacks' attribute is set but is not a hash: ignored\n";
358 6         198 $self->{callbacks} = undef;
359             }
360              
361 834         2016 $last_new_error = Text::CSV_PP->SetDiag(0);
362 834 100 100     2866 defined $\ && !exists $attr{eol} and $self->{eol} = $\;
363 834         1479 bless $self, $class;
364 834 100       2100 defined $self->{types} and $self->types ($self->{types});
365 834 100       1683 defined $attr_formula and $self->{formula} = _supported_formula($self, $attr_formula);
366 833         3806 $self;
367             }
368              
369             # Keep in sync with XS!
370             my %_cache_id = ( # Only expose what is accessed from within PM
371             quote_char => 0,
372             escape_char => 1,
373             sep_char => 2,
374             sep => 39, # 39 .. 55
375             binary => 3,
376             keep_meta_info => 4,
377             always_quote => 5,
378             allow_loose_quotes => 6,
379             allow_loose_escapes => 7,
380             allow_unquoted_escape => 8,
381             allow_whitespace => 9,
382             blank_is_undef => 10,
383             eol => 11,
384             quote => 15,
385             verbatim => 22,
386             empty_is_undef => 23,
387             auto_diag => 24,
388             diag_verbose => 33,
389             quote_space => 25,
390             quote_empty => 37,
391             quote_binary => 32,
392             escape_null => 31,
393             decode_utf8 => 35,
394             _has_ahead => 30,
395             _has_hooks => 36,
396             _is_bound => 26, # 26 .. 29
397             formula => 38,
398             strict => 42,
399             skip_empty_rows => 43,
400             undef_str => 46,
401             comment_str => 54,
402             types => 62,
403             );
404              
405             my %_hidden_cache_id = qw(
406             sep_len 38
407             eol_len 12
408             eol_is_cr 13
409             quo_len 16
410             has_error_input 34
411             );
412              
413             my %_reverse_cache_id = (
414             map({$_cache_id{$_} => $_} keys %_cache_id),
415             map({$_hidden_cache_id{$_} => $_} keys %_hidden_cache_id),
416             );
417              
418             # A `character'
419             sub _set_attr_C {
420 11083     11083   22976 my ($self, $name, $val, $ec) = @_;
421 11083 100       35306 defined $val and utf8::decode($val);
422 11083         18110 $self->{$name} = $val;
423 11083 100       17667 $ec = _check_sanity ($self) and croak ($self->SetDiag ($ec));
424 10173         26331 $self->_cache_set ($_cache_id{$name}, $val);
425             }
426              
427             # A flag
428             sub _set_attr_X {
429 5644     5644   11285 my ($self, $name, $val) = @_;
430 5644 100       12160 defined $val or $val = 0;
431 5644         10752 $self->{$name} = $val;
432 5644         15696 $self->_cache_set ($_cache_id{$name}, 0 + $val);
433             }
434              
435             # A number
436             sub _set_attr_N {
437 38     38   97 my ($self, $name, $val) = @_;
438 38         92 $self->{$name} = $val;
439 38         158 $self->_cache_set ($_cache_id{$name}, 0 + $val);
440             }
441              
442             # Accessor methods.
443             # It is unwise to change them halfway through a single file!
444             sub quote_char {
445 4836     4836 1 664087 my $self = shift;
446 4836 100       11749 if (@_) {
447 3601         8092 $self->_set_attr_C ("quote_char", shift);
448 3374         7577 $self->_cache_set ($_cache_id{quote}, "");
449             }
450 4609         14500 $self->{quote_char};
451             }
452              
453             sub quote {
454 20     20 1 56 my $self = shift;
455 20 100       64 if (@_) {
456 11         25 my $quote = shift;
457 11 100       31 defined $quote or $quote = "";
458 11         34 utf8::decode ($quote);
459 11         54 my @b = unpack "U0C*", $quote;
460 11 100       37 if (@b > 1) {
461 5 100       22 @b > 16 and croak ($self->SetDiag (1007));
462 4         18 $self->quote_char ("\0");
463             }
464             else {
465 6         17 $self->quote_char ($quote);
466 6         12 $quote = "";
467             }
468 10         21 $self->{quote} = $quote;
469              
470 10         21 my $ec = _check_sanity ($self);
471 10 100       25 $ec and croak ($self->SetDiag ($ec));
472              
473 9         25 $self->_cache_set ($_cache_id{quote}, $quote);
474             }
475 18         59 my $quote = $self->{quote};
476 18 100 100     134 defined $quote && length ($quote) ? $quote : $self->{quote_char};
477             }
478              
479             sub escape_char {
480 4827     4827 1 673532 my $self = shift;
481 4827 100       12097 if (@_) {
482 3595         5788 my $ec = shift;
483 3595         8594 $self->_set_attr_C ("escape_char", $ec);
484 3480 100       6930 $ec or $self->_set_attr_X ("escape_null", 0);
485             }
486 4712         15372 $self->{escape_char};
487             }
488              
489             sub sep_char {
490 5130     5130 1 666010 my $self = shift;
491 5130 100       12450 if (@_) {
492 3887         9250 $self->_set_attr_C ("sep_char", shift);
493 3319         6346 $self->_cache_set ($_cache_id{sep}, "");
494             }
495 4562         14393 $self->{sep_char};
496             }
497              
498             sub sep {
499 334     334 1 3836 my $self = shift;
500 334 100       779 if (@_) {
501 301         559 my $sep = shift;
502 301 100       655 defined $sep or $sep = "";
503 301         1020 utf8::decode ($sep);
504 301         1164 my @b = unpack "U0C*", $sep;
505 301 100       693 if (@b > 1) {
506 13 100       37 @b > 16 and croak ($self->SetDiag (1006));
507 12         37 $self->sep_char ("\0");
508             }
509             else {
510 288         786 $self->sep_char ($sep);
511 285         426 $sep = "";
512             }
513 297         588 $self->{sep} = $sep;
514              
515 297         511 my $ec = _check_sanity ($self);
516 297 100       566 $ec and croak ($self->SetDiag ($ec));
517              
518 296         601 $self->_cache_set ($_cache_id{sep}, $sep);
519             }
520 329         657 my $sep = $self->{sep};
521 329 100 100     1559 defined $sep && length ($sep) ? $sep : $self->{sep_char};
522             }
523              
524             sub eol {
525 157     157 1 3407 my $self = shift;
526 157 100       413 if (@_) {
527 125         265 my $eol = shift;
528 125 100       379 defined $eol or $eol = "";
529 125 100       404 length ($eol) > 16 and croak ($self->SetDiag (1005));
530 124         253 $self->{eol} = $eol;
531 124         311 $self->_cache_set ($_cache_id{eol}, $eol);
532             }
533 156         347 $self->{eol};
534             }
535              
536             sub always_quote {
537 3033     3033 1 680157 my $self = shift;
538 3033 100       9413 @_ and $self->_set_attr_X ("always_quote", shift);
539 3033         8677 $self->{always_quote};
540             }
541              
542             sub quote_space {
543 10     10 1 29 my $self = shift;
544 10 100       44 @_ and $self->_set_attr_X ("quote_space", shift);
545 10         39 $self->{quote_space};
546             }
547              
548             sub quote_empty {
549 5     5 1 15 my $self = shift;
550 5 100       25 @_ and $self->_set_attr_X ("quote_empty", shift);
551 5         23 $self->{quote_empty};
552             }
553              
554             sub escape_null {
555 6     6 1 14 my $self = shift;
556 6 100       23 @_ and $self->_set_attr_X ("escape_null", shift);
557 6         28 $self->{escape_null};
558             }
559              
560 3     3 0 17 sub quote_null { goto &escape_null; }
561              
562             sub quote_binary {
563 7     7 1 22 my $self = shift;
564 7 100       29 @_ and $self->_set_attr_X ("quote_binary", shift);
565 7         24 $self->{quote_binary};
566             }
567              
568             sub binary {
569 21     21 1 3565 my $self = shift;
570 21 100       128 @_ and $self->_set_attr_X ("binary", shift);
571 21         65 $self->{binary};
572             }
573              
574             sub strict {
575 2     2 1 4 my $self = shift;
576 2 100       11 @_ and $self->_set_attr_X ("strict", shift);
577 2         9 $self->{strict};
578             }
579              
580             sub skip_empty_rows {
581 2     2 1 6 my $self = shift;
582 2 100       10 @_ and $self->_set_attr_X ("skip_empty_rows", shift);
583 2         10 $self->{skip_empty_rows};
584             }
585              
586             sub _SetDiagInfo {
587 17     17   44 my ($self, $err, $msg) = @_;
588 17         54 $self->SetDiag ($err);
589 17         46 my $em = $self->error_diag;
590 17 50       41 $em =~ s/^\d+$// and $msg =~ s/^/# /;
591 17 50       35 my $sep = $em =~ m/[;\n]$/ ? "\n\t" : ": ";
592 17         44 join $sep => grep m/\S\S\S/ => $em, $msg;
593             }
594              
595             sub _supported_formula {
596 103     103   176 my ($self, $f) = @_;
597 103 100       196 defined $f or return 5;
598 102 100 66     488 if ($self && $f && ref $f && ref $f eq "CODE") {
      100        
      100        
599 6         11 $self->{_FORMULA_CB} = $f;
600 6         16 return 6;
601             }
602             $f =~ m/^(?: 0 | none )$/xi ? 0 :
603             $f =~ m/^(?: 1 | die )$/xi ? 1 :
604             $f =~ m/^(?: 2 | croak )$/xi ? 2 :
605             $f =~ m/^(?: 3 | diag )$/xi ? 3 :
606             $f =~ m/^(?: 4 | empty | )$/xi ? 4 :
607             $f =~ m/^(?: 5 | undef )$/xi ? 5 :
608 96 100       880 $f =~ m/^(?: 6 | cb )$/xi ? 6 : do {
    100          
    100          
    100          
    100          
    100          
    100          
609 7   50     17 $self ||= "Text::CSV_PP";
610 7         43 croak ($self->_SetDiagInfo (1500, "formula-handling '$f' is not supported"));
611             };
612             }
613              
614             sub formula {
615 44     44 1 3335 my $self = shift;
616 44 100       138 @_ and $self->_set_attr_N ("formula", _supported_formula ($self, shift));
617 38 100       104 $self->{formula} == 6 or $self->{_FORMULA_CB} = undef;
618 38         130 [qw( none die croak diag empty undef cb )]->[_supported_formula ($self, $self->{formula})];
619             }
620             sub formula_handling {
621 7     7 1 15 my $self = shift;
622 7         16 $self->formula (@_);
623             }
624              
625             sub decode_utf8 {
626 2     2 1 6 my $self = shift;
627 2 100       11 @_ and $self->_set_attr_X ("decode_utf8", shift);
628 2         9 $self->{decode_utf8};
629             }
630              
631             sub keep_meta_info {
632 12     12 1 197 my $self = shift;
633 12 100       46 if (@_) {
634 11         21 my $v = shift;
635 11 100 100     66 !defined $v || $v eq "" and $v = 0;
636 11 100       63 $v =~ m/^[0-9]/ or $v = lc $v eq "false" ? 0 : 1; # true/truth = 1
    100          
637 11         56 $self->_set_attr_X ("keep_meta_info", $v);
638             }
639 12         54 $self->{keep_meta_info};
640             }
641              
642             sub allow_loose_quotes {
643 12     12 1 25 my $self = shift;
644 12 100       54 @_ and $self->_set_attr_X ("allow_loose_quotes", shift);
645 12         30 $self->{allow_loose_quotes};
646             }
647              
648             sub allow_loose_escapes {
649 12     12 1 1147 my $self = shift;
650 12 100       62 @_ and $self->_set_attr_X ("allow_loose_escapes", shift);
651 12         35 $self->{allow_loose_escapes};
652             }
653              
654             sub allow_whitespace {
655 4954     4954 1 1868670 my $self = shift;
656 4954 100       14026 if (@_) {
657 3725         5716 my $aw = shift;
658 3725 100       8732 _unhealthy_whitespace ($self, $aw) and
659             croak ($self->SetDiag (1002));
660 3721         9731 $self->_set_attr_X ("allow_whitespace", $aw);
661             }
662 4950         17143 $self->{allow_whitespace};
663             }
664              
665             sub allow_unquoted_escape {
666 4     4 1 10 my $self = shift;
667 4 100       30 @_ and $self->_set_attr_X ("allow_unquoted_escape", shift);
668 4         16 $self->{allow_unquoted_escape};
669             }
670              
671             sub blank_is_undef {
672 3     3 1 10 my $self = shift;
673 3 100       19 @_ and $self->_set_attr_X ("blank_is_undef", shift);
674 3         13 $self->{blank_is_undef};
675             }
676              
677             sub empty_is_undef {
678 2     2 1 7 my $self = shift;
679 2 100       10 @_ and $self->_set_attr_X ("empty_is_undef", shift);
680 2         9 $self->{empty_is_undef};
681             }
682              
683             sub verbatim {
684 9     9 1 5337 my $self = shift;
685 9 100       63 @_ and $self->_set_attr_X ("verbatim", shift);
686 9         34 $self->{verbatim};
687             }
688              
689             sub undef_str {
690 12     12 1 3310 my $self = shift;
691 12 100       37 if (@_) {
692 11         20 my $v = shift;
693 11 100       40 $self->{undef_str} = defined $v ? "$v" : undef;
694 11         34 $self->_cache_set ($_cache_id{undef_str}, $self->{undef_str});
695             }
696 12         48 $self->{undef_str};
697             }
698              
699             sub comment_str {
700 3     3 1 7 my $self = shift;
701 3 100       11 if (@_) {
702 2         4 my $v = shift;
703 2 100       6 $self->{comment_str} = defined $v ? "$v" : undef;
704 2         7 $self->_cache_set ($_cache_id{comment_str}, $self->{comment_str});
705             }
706 3         14 $self->{comment_str};
707             }
708              
709             sub auto_diag {
710 12     12 1 355 my $self = shift;
711 12 100       39 if (@_) {
712 9         19 my $v = shift;
713 9 100 100     49 !defined $v || $v eq "" and $v = 0;
714 9 100       50 $v =~ m/^[0-9]/ or $v = lc $v eq "false" ? 0 : 1; # true/truth = 1
    100          
715 9         25 $self->_set_attr_X ("auto_diag", $v);
716             }
717 12         55 $self->{auto_diag};
718             }
719              
720             sub diag_verbose {
721 10     10 1 634 my $self = shift;
722 10 100       33 if (@_) {
723 8         13 my $v = shift;
724 8 100 100     43 !defined $v || $v eq "" and $v = 0;
725 8 100       78 $v =~ m/^[0-9]/ or $v = lc $v eq "false" ? 0 : 1; # true/truth = 1
    100          
726 8         27 $self->_set_attr_X ("diag_verbose", $v);
727             }
728 10         47 $self->{diag_verbose};
729             }
730              
731             ################################################################################
732             # status
733             ################################################################################
734              
735             sub status {
736 5     5 1 28 $_[0]->{_STATUS};
737             }
738              
739             sub eof {
740 33     33 1 797 $_[0]->{_EOF};
741             }
742              
743             sub types {
744 7     7 1 1618 my $self = shift;
745              
746 7 100       18 if (@_) {
747 2 100       12 if (my $types = shift) {
748 1         3 $self->{'_types'} = join("", map{ chr($_) } @$types);
  3         11  
749 1         2 $self->{'types'} = $types;
750 1         4 $self->_cache_set ($_cache_id{'types'}, $self->{'_types'});
751             }
752             else {
753 1         44 delete $self->{'types'};
754 1         6 delete $self->{'_types'};
755 1         11 $self->_cache_set ($_cache_id{'types'}, undef);
756 1         5 undef;
757             }
758             }
759             else {
760 5         19 $self->{'types'};
761             }
762             }
763              
764             sub callbacks {
765 72     72 1 20475 my $self = shift;
766 72 100       189 if (@_) {
767 42         55 my $cb;
768 42         57 my $hf = 0x00;
769 42 100       101 if (defined $_[0]) {
    100          
770 40 100       73 grep { !defined } @_ and croak ($self->SetDiag (1004));
  71         178  
771 38 100 100     193 $cb = @_ == 1 && ref $_[0] eq "HASH" ? shift
    100          
772             : @_ % 2 == 0 ? { @_ }
773             : croak ($self->SetDiag (1004));
774 33         112 foreach my $cbk (keys %$cb) {
775             # A key cannot be a ref. That would be stored as the *string
776             # 'SCALAR(0x1f3e710)' or 'ARRAY(0x1a5ae18)'
777 35 100 100     273 $cbk =~ m/^[\w.]+$/ && ref $cb->{$cbk} eq "CODE" or
778             croak ($self->SetDiag (1004));
779             }
780 19 100       51 exists $cb->{error} and $hf |= 0x01;
781 19 100       45 exists $cb->{after_parse} and $hf |= 0x02;
782 19 100       33 exists $cb->{before_print} and $hf |= 0x04;
783             }
784             elsif (@_ > 1) {
785             # (undef, whatever)
786 1         5 croak ($self->SetDiag (1004));
787             }
788 20         63 $self->_set_attr_X ("_has_hooks", $hf);
789 20         48 $self->{callbacks} = $cb;
790             }
791 50         152 $self->{callbacks};
792             }
793              
794             ################################################################################
795             # error_diag
796             ################################################################################
797              
798             sub error_diag {
799 1680     1680 1 39920 my $self = shift;
800 1680         4808 my @diag = (0 + $last_new_error, $last_new_error, 0, 0, 0);
801              
802             # Docs state to NEVER use UNIVERSAL::isa, because it will *never* call an
803             # overridden isa method in any class. Well, that is exacly what I want here
804 1680 100 100     15174 if ($self && ref $self && # Not a class method or direct call
      100        
      100        
805             UNIVERSAL::isa ($self, __PACKAGE__) && exists $self->{_ERROR_DIAG}) {
806 1505         3354 $diag[0] = 0 + $self->{_ERROR_DIAG};
807 1505         2759 $diag[1] = $self->{_ERROR_DIAG};
808 1505 100       3447 $diag[2] = 1 + $self->{_ERROR_POS} if exists $self->{_ERROR_POS};
809 1505         2371 $diag[3] = $self->{_RECNO};
810 1505 100       3180 $diag[4] = $self->{_ERROR_FLD} if exists $self->{_ERROR_FLD};
811              
812             $diag[0] && $self->{callbacks} && $self->{callbacks}{error} and
813 1505 100 100     6007 return $self->{callbacks}{error}->(@diag);
      100        
814             }
815              
816 1677         2812 my $context = wantarray;
817              
818 1677 100       3542 unless (defined $context) { # Void context, auto-diag
819 257 100 100     866 if ($diag[0] && $diag[0] != 2012) {
820 16         82 my $msg = "# CSV_PP ERROR: $diag[0] - $diag[1] \@ rec $diag[3] pos $diag[2]\n";
821 16 100       114 $diag[4] and $msg =~ s/$/ field $diag[4]/;
822              
823 16 100 100     100 unless ($self && ref $self) { # auto_diag
824             # called without args in void context
825 4         40 warn $msg;
826 4         30 return;
827             }
828              
829             $self->{diag_verbose} and $self->{_ERROR_INPUT} and
830 12 50 66     56 $msg .= "$self->{_ERROR_INPUT}'\n".
831             (" " x ($diag[2] - 1))."^\n";
832              
833 12         32 my $lvl = $self->{auto_diag};
834 12 100       39 if ($lvl < 2) {
835 9         81 my @c = caller (2);
836 9 50 66     67 if (@c >= 11 && $c[10] && ref $c[10] eq "HASH") {
      33        
837 0         0 my $hints = $c[10];
838             (exists $hints->{autodie} && $hints->{autodie} or
839             exists $hints->{"guard Fatal"} &&
840 0 0 0     0 !exists $hints->{"no Fatal"}) and
      0        
      0        
841             $lvl++;
842             # Future releases of autodie will probably set $^H{autodie}
843             # to "autodie @args", like "autodie :all" or "autodie open"
844             # so we can/should check for "open" or "new"
845             }
846             }
847 12 100       174 $lvl > 1 ? die $msg : warn $msg;
848             }
849 250         608 return;
850             }
851              
852 1420 100       4885 return $context ? @diag : $diag[1];
853             }
854              
855             sub record_number {
856 3     3 1 16 return shift->{_RECNO};
857             }
858              
859             ################################################################################
860             # string
861             ################################################################################
862              
863             *string = \&_string;
864             sub _string {
865 1401 100   1401   383204 defined $_[0]->{_STRING} ? ${ $_[0]->{_STRING} } : undef;
  1400         6267  
866             }
867              
868             ################################################################################
869             # fields
870             ################################################################################
871              
872             *fields = \&_fields;
873             sub _fields {
874 1614 100   1614   27408 ref($_[0]->{_FIELDS}) ? @{$_[0]->{_FIELDS}} : undef;
  1613         10745  
875             }
876              
877             ################################################################################
878             # meta_info
879             ################################################################################
880              
881             sub meta_info {
882 21 100   21 1 712 $_[0]->{_FFLAGS} ? @{ $_[0]->{_FFLAGS} } : undef;
  16         75  
883             }
884              
885             sub is_quoted {
886 29 100   29 1 106 return unless (defined $_[0]->{_FFLAGS});
887 26 100 66     134 return if( $_[1] =~ /\D/ or $_[1] < 0 or $_[1] > $#{ $_[0]->{_FFLAGS} } );
  25   100     85  
888              
889 24 100       105 $_[0]->{_FFLAGS}->[$_[1]] & IS_QUOTED ? 1 : 0;
890             }
891              
892             sub is_binary {
893 11 100   11 1 47 return unless (defined $_[0]->{_FFLAGS});
894 10 100 66     73 return if( $_[1] =~ /\D/ or $_[1] < 0 or $_[1] > $#{ $_[0]->{_FFLAGS} } );
  9   100     37  
895 8 100       55 $_[0]->{_FFLAGS}->[$_[1]] & IS_BINARY ? 1 : 0;
896             }
897              
898             sub is_missing {
899 19     19 1 51 my ($self, $idx, $val) = @_;
900 19 100       72 return unless $self->{keep_meta_info}; # FIXME
901 13 100 100     71 $idx < 0 || !ref $self->{_FFLAGS} and return;
902 11 100       20 $idx >= @{$self->{_FFLAGS}} and return 1;
  11         32  
903 10 100       51 $self->{_FFLAGS}[$idx] & IS_MISSING ? 1 : 0;
904             }
905              
906             ################################################################################
907             # combine
908             ################################################################################
909             *combine = \&_combine;
910             sub _combine {
911 1399     1399   710376 my ($self, @fields) = @_;
912 1399         3449 my $str = "";
913 1399         5904 $self->{_FIELDS} = \@fields;
914 1399   100     8244 $self->{_STATUS} = (@fields > 0) && $self->__combine(\$str, \@fields, 0);
915 1395         3448 $self->{_STRING} = \$str;
916 1395         4389 $self->{_STATUS};
917             }
918              
919             ################################################################################
920             # parse
921             ################################################################################
922             *parse = \&_parse;
923             sub _parse {
924 1953     1953   102572 my ($self, $str) = @_;
925              
926 1953 100       5202 ref $str and croak ($self->SetDiag (1500));
927              
928 1949         3804 my $fields = [];
929 1949         3513 my $fflags = [];
930 1949         4752 $self->{_STRING} = \$str;
931 1949 100 100     8638 if (defined $str && $self->__parse ($fields, $fflags, $str, 0)) {
932 1739         5696 $self->{_FIELDS} = $fields;
933 1739         3794 $self->{_FFLAGS} = $fflags;
934 1739         3372 $self->{_STATUS} = 1;
935             }
936             else {
937 207         452 $self->{_FIELDS} = undef;
938 207         357 $self->{_FFLAGS} = undef;
939 207         369 $self->{_STATUS} = 0;
940             }
941 1946         11458 $self->{_STATUS};
942             }
943              
944             sub column_names {
945 943     943 1 52704 my ( $self, @columns ) = @_;
946              
947 943 100       2507 @columns or return defined $self->{_COLUMN_NAMES} ? @{$self->{_COLUMN_NAMES}} : ();
  270 100       1235  
948 630 100 100     2250 @columns == 1 && ! defined $columns[0] and return $self->{_COLUMN_NAMES} = undef;
949              
950 492 100 100     1697 if ( @columns == 1 && ref $columns[0] eq "ARRAY" ) {
    100          
951 196         293 @columns = @{ $columns[0] };
  196         472  
952             }
953 607 100       2132 elsif ( join "", map { defined $_ ? ref $_ : "" } @columns ) {
954 5         23 croak $self->SetDiag( 3001 );
955             }
956              
957 487 100 100     1349 if ( $self->{_BOUND_COLUMNS} && @columns != @{$self->{_BOUND_COLUMNS}} ) {
  2         10  
958 1         5 croak $self->SetDiag( 3003 );
959             }
960              
961 486 100       738 $self->{_COLUMN_NAMES} = [ map { defined $_ ? $_ : "\cAUNDEF\cA" } @columns ];
  1061         2763  
962 486         830 @{ $self->{_COLUMN_NAMES} };
  486         1230  
963             }
964              
965             sub header {
966 305     305 1 41027 my ($self, $fh, @args) = @_;
967              
968 305 100       765 $fh or croak ($self->SetDiag (1014));
969              
970 304         506 my (@seps, %args);
971 304         614 for (@args) {
972 197 100       462 if (ref $_ eq "ARRAY") {
973 18         50 push @seps, @$_;
974 18         37 next;
975             }
976 179 100       355 if (ref $_ eq "HASH") {
977 178         363 %args = %$_;
978 178         362 next;
979             }
980 1         220 croak (q{usage: $csv->header ($fh, [ seps ], { options })});
981             }
982              
983             defined $args{munge} && !defined $args{munge_column_names} and
984 303 100 66     742 $args{munge_column_names} = $args{munge}; # munge as alias
985 303 100       765 defined $args{detect_bom} or $args{detect_bom} = 1;
986 303 100       742 defined $args{set_column_names} or $args{set_column_names} = 1;
987 303 100       671 defined $args{munge_column_names} or $args{munge_column_names} = "lc";
988              
989             # Reset any previous leftovers
990 303         488 $self->{_RECNO} = 0;
991 303         441 $self->{_AHEAD} = undef;
992 303 100       672 $self->{_COLUMN_NAMES} = undef if $args{set_column_names};
993 303 100       654 $self->{_BOUND_COLUMNS} = undef if $args{set_column_names};
994 303         914 $self->_cache_set($_cache_id{'_has_ahead'}, 0);
995              
996 303 100       665 if (defined $args{sep_set}) {
997 11 100       52 ref $args{sep_set} eq "ARRAY" or
998             croak ($self->_SetDiagInfo (1500, "sep_set should be an array ref"));
999 6         10 @seps = @{$args{sep_set}};
  6         21  
1000             }
1001              
1002 298 50       840 $^O eq "MSWin32" and binmode $fh;
1003 298         4881 my $hdr = <$fh>;
1004             # check if $hdr can be empty here, I don't think so
1005 298 100 66     1792 defined $hdr && $hdr ne "" or croak ($self->SetDiag (1010));
1006              
1007 296         439 my %sep;
1008 296 100       994 @seps or @seps = (",", ";");
1009 296         601 foreach my $sep (@seps) {
1010 688 100       2078 index ($hdr, $sep) >= 0 and $sep{$sep}++;
1011             }
1012              
1013 296 100       661 keys %sep >= 2 and croak ($self->SetDiag (1011));
1014              
1015 295         1065 $self->sep (keys %sep);
1016 295         531 my $enc = "";
1017 295 100       592 if ($args{detect_bom}) { # UTF-7 is not supported
1018 294 100       2724 if ($hdr =~ s/^\x00\x00\xfe\xff//) { $enc = "utf-32be" }
  24 100       50  
    100          
    100          
    100          
    100          
    100          
    100          
    100          
    100          
    100          
1019 24         58 elsif ($hdr =~ s/^\xff\xfe\x00\x00//) { $enc = "utf-32le" }
1020 25         50 elsif ($hdr =~ s/^\xfe\xff//) { $enc = "utf-16be" }
1021 24         54 elsif ($hdr =~ s/^\xff\xfe//) { $enc = "utf-16le" }
1022 48         95 elsif ($hdr =~ s/^\xef\xbb\xbf//) { $enc = "utf-8" }
1023 1         11 elsif ($hdr =~ s/^\xf7\x64\x4c//) { $enc = "utf-1" }
1024 1         3 elsif ($hdr =~ s/^\xdd\x73\x66\x73//) { $enc = "utf-ebcdic" }
1025 1         4 elsif ($hdr =~ s/^\x0e\xfe\xff//) { $enc = "scsu" }
1026 1         6 elsif ($hdr =~ s/^\xfb\xee\x28//) { $enc = "bocu-1" }
1027 1         3 elsif ($hdr =~ s/^\x84\x31\x95\x33//) { $enc = "gb-18030" }
1028 36         76 elsif ($hdr =~ s/^\x{feff}//) { $enc = "" }
1029              
1030 294 100       785 $self->{ENCODING} = $enc ? uc $enc : undef;
1031              
1032 294 100       566 $hdr eq "" and croak ($self->SetDiag (1010));
1033              
1034 288 100       562 if ($enc) {
1035 144 50 33     344 $ebcdic && $enc eq "utf-ebcdic" and $enc = "";
1036 144 100       437 if ($enc =~ m/([13]).le$/) {
1037 48         155 my $l = 0 + $1;
1038 48         75 my $x;
1039 48         115 $hdr .= "\0" x $l;
1040 48         172 read $fh, $x, $l;
1041             }
1042 144 50       289 if ($enc) {
1043 144 100       277 if ($enc ne "utf-8") {
1044 96         537 require Encode;
1045 96         524 $hdr = Encode::decode ($enc, $hdr);
1046             }
1047 144         5855 binmode $fh, ":encoding($enc)";
1048             }
1049             }
1050             }
1051              
1052 289         8928 my ($ahead, $eol);
1053 289 100 66     1528 if ($hdr and $hdr =~ s/\Asep=(\S)([\r\n]+)//i) { # Also look in xs:Parse
1054 1         4 $self->sep ($1);
1055 1 50       5 length $hdr or $hdr = <$fh>;
1056             }
1057              
1058 289 100       1963 if ($hdr =~ s/^([^\r\n]+)([\r\n]+)([^\r\n].+)\z/$1/s) {
1059 142         310 $eol = $2;
1060 142         262 $ahead = $3;
1061             }
1062              
1063 289         570 my $hr = \$hdr; # Will cause croak on perl-5.6.x
1064 289 50       3163 open my $h, "<", $hr or croak ($self->SetDiag (1010));
1065              
1066 289 100       1718 my $row = $self->getline ($h) or croak;
1067 287         893 close $h;
1068              
1069 287 100       744 if ( $args{'munge_column_names'} eq "lc") {
    100          
    100          
1070 268         356 $_ = lc for @{$row};
  268         967  
1071             }
1072             elsif ($args{'munge_column_names'} eq "uc") {
1073 7         25 $_ = uc for @{$row};
  7         36  
1074             }
1075             elsif ($args{'munge_column_names'} eq "db") {
1076 3         6 for (@{$row}) {
  3         9  
1077 7         17 s/\W+/_/g;
1078 7         18 s/^_+//;
1079 7         14 $_ = lc;
1080             }
1081             }
1082              
1083 287 100       669 if ($ahead) { # Must be after getline, which creates the cache
1084 142         488 $self->_cache_set ($_cache_id{_has_ahead}, 1);
1085 142         256 $self->{_AHEAD} = $ahead;
1086 142 100       672 $eol =~ m/^\r([^\n]|\z)/ and $self->eol ($eol);
1087             }
1088              
1089 287         732 my @hdr = @$row;
1090             ref $args{munge_column_names} eq "CODE" and
1091 287 100       686 @hdr = map { $args{munge_column_names}->($_) } @hdr;
  4         18  
1092             ref $args{munge_column_names} eq "HASH" and
1093 287 100       692 @hdr = map { $args{munge_column_names}->{$_} || $_ } @hdr;
  3 100       15  
1094 287         379 my %hdr; $hdr{$_}++ for @hdr;
  287         1013  
1095 287 100       631 exists $hdr{""} and croak ($self->SetDiag (1012));
1096 285 100       667 unless (keys %hdr == @hdr) {
1097             croak ($self->_SetDiagInfo (1013, join ", " =>
1098 1         3 map { "$_ ($hdr{$_})" } grep { $hdr{$_} > 1 } keys %hdr));
  1         18  
  2         7  
1099             }
1100 284 100       1125 $args{set_column_names} and $self->column_names (@hdr);
1101 284 100       2482 wantarray ? @hdr : $self;
1102             }
1103              
1104             sub bind_columns {
1105 27     27 1 7493 my ( $self, @refs ) = @_;
1106              
1107 27 100       113 @refs or return defined $self->{_BOUND_COLUMNS} ? @{$self->{_BOUND_COLUMNS}} : undef;
  2 100       13  
1108 23 100 100     146 @refs == 1 && ! defined $refs[0] and return $self->{_BOUND_COLUMNS} = undef;
1109              
1110 18 100 100     84 if ( $self->{_COLUMN_NAMES} && @refs != @{$self->{_COLUMN_NAMES}} ) {
  3         16  
1111 1         4 croak $self->SetDiag( 3003 );
1112             }
1113              
1114 17 100       221 if ( grep { ref $_ ne "SCALAR" } @refs ) { # why don't use grep?
  74606         107529  
1115 2         9 croak $self->SetDiag( 3004 );
1116             }
1117              
1118 15         103 $self->_set_attr_N("_is_bound", scalar @refs);
1119 15         6036 $self->{_BOUND_COLUMNS} = [ @refs ];
1120 15         1432 @refs;
1121             }
1122              
1123             sub getline_hr {
1124 120     120 1 15731 my ($self, @args, %hr) = @_;
1125 120 100       378 $self->{_COLUMN_NAMES} or croak ($self->SetDiag (3002));
1126 119 100       350 my $fr = $self->getline (@args) or return;
1127 117 100       336 if (ref $self->{_FFLAGS}) { # missing
1128             $self->{_FFLAGS}[$_] = IS_MISSING
1129 5 50       11 for (@$fr ? $#{$fr} + 1 : 0) .. $#{$self->{_COLUMN_NAMES}};
  5         9  
  5         22  
1130             @$fr == 1 && (!defined $fr->[0] || $fr->[0] eq "") and
1131 5 100 50     30 $self->{_FFLAGS}[0] ||= IS_MISSING;
      66        
      100        
1132             }
1133 117         204 @hr{@{$self->{_COLUMN_NAMES}}} = @$fr;
  117         449  
1134 117         682 \%hr;
1135             }
1136              
1137             sub getline_hr_all {
1138 209     209 1 417 my ( $self, $io, @args ) = @_;
1139              
1140 209 100       488 unless ( $self->{_COLUMN_NAMES} ) {
1141 2         8 croak $self->SetDiag( 3002 );
1142             }
1143              
1144 207         288 my @cn = @{$self->{_COLUMN_NAMES}};
  207         477  
1145              
1146 207         305 return [ map { my %h; @h{ @cn } = @$_; \%h } @{ $self->getline_all( $io, @args ) } ];
  304         445  
  304         984  
  304         1350  
  207         550  
1147             }
1148              
1149             sub say {
1150 13     13 1 2790 my ($self, $io, @f) = @_;
1151 13         51 my $eol = $self->eol;
1152 13 100 33     103 $eol eq "" and $self->eol ($\ || $/);
1153             # say ($fh, undef) does not propage actual undef to print ()
1154 13 100 66     89 my $state = $self->print ($io, @f == 1 && !defined $f[0] ? undef : @f);
1155 13         202 $self->eol ($eol);
1156 13         71 return $state;
1157             }
1158              
1159             sub print_hr {
1160 3     3 1 16 my ($self, $io, $hr) = @_;
1161 3 100       16 $self->{_COLUMN_NAMES} or croak($self->SetDiag(3009));
1162 2 100       11 ref $hr eq "HASH" or croak($self->SetDiag(3010));
1163 1         14 $self->print ($io, [ map { $hr->{$_} } $self->column_names ]);
  3         9  
1164             }
1165              
1166             sub fragment {
1167 58     58 1 29756 my ($self, $io, $spec) = @_;
1168              
1169 58         223 my $qd = qr{\s* [0-9]+ \s* }x; # digit
1170 58         151 my $qs = qr{\s* (?: [0-9]+ | \* ) \s*}x; # digit or star
1171 58         436 my $qr = qr{$qd (?: - $qs )?}x; # range
1172 58         331 my $qc = qr{$qr (?: ; $qr )*}x; # list
1173 58 100 100     1366 defined $spec && $spec =~ m{^ \s*
1174             \x23 ? \s* # optional leading #
1175             ( row | col | cell ) \s* =
1176             ( $qc # for row and col
1177             | $qd , $qd (?: - $qs , $qs)? # for cell (ranges)
1178             (?: ; $qd , $qd (?: - $qs , $qs)? )* # and cell (range) lists
1179             ) \s* $}xi or croak ($self->SetDiag (2013));
1180 38         199 my ($type, $range) = (lc $1, $2);
1181              
1182 38         130 my @h = $self->column_names ();
1183              
1184 38         68 my @c;
1185 38 100       92 if ($type eq "cell") {
1186 21         61 my @spec;
1187             my $min_row;
1188 21         40 my $max_row = 0;
1189 21         102 for (split m/\s*;\s*/ => $range) {
1190 37 100       238 my ($tlr, $tlc, $brr, $brc) = (m{
1191             ^ \s* ([0-9]+ ) \s* , \s* ([0-9]+ ) \s*
1192             (?: - \s* ([0-9]+ | \*) \s* , \s* ([0-9]+ | \*) \s* )?
1193             $}x) or croak ($self->SetDiag (2013));
1194 36 100       97 defined $brr or ($brr, $brc) = ($tlr, $tlc);
1195 36 100 100     338 $tlr == 0 || $tlc == 0 ||
      66        
      100        
      100        
      66        
      100        
      100        
1196             ($brr ne "*" && ($brr == 0 || $brr < $tlr)) ||
1197             ($brc ne "*" && ($brc == 0 || $brc < $tlc))
1198             and croak ($self->SetDiag (2013));
1199 28         41 $tlc--;
1200 28 100       49 $brc-- unless $brc eq "*";
1201 28 100       57 defined $min_row or $min_row = $tlr;
1202 28 100       50 $tlr < $min_row and $min_row = $tlr;
1203 28 100 100     85 $brr eq "*" || $brr > $max_row and
1204             $max_row = $brr;
1205 28         94 push @spec, [ $tlr, $tlc, $brr, $brc ];
1206             }
1207 12         22 my $r = 0;
1208 12         34 while (my $row = $self->getline ($io)) {
1209 77 100       256 ++$r < $min_row and next;
1210 33         56 my %row;
1211             my $lc;
1212 33         61 foreach my $s (@spec) {
1213 77         156 my ($tlr, $tlc, $brr, $brc) = @$s;
1214 77 100 100     271 $r < $tlr || ($brr ne "*" && $r > $brr) and next;
      100        
1215 45 100 100     111 !defined $lc || $tlc < $lc and $lc = $tlc;
1216 45 100       82 my $rr = $brc eq "*" ? $#$row : $brc;
1217 45         213 $row{$_} = $row->[$_] for $tlc .. $rr;
1218             }
1219 33         129 push @c, [ @row{sort { $a <=> $b } keys %row } ];
  57         171  
1220 33 100       84 if (@h) {
1221 2         84 my %h; @h{@h} = @{$c[-1]};
  2         5  
  2         11  
1222 2         5 $c[-1] = \%h;
1223             }
1224 33 100 100     175 $max_row ne "*" && $r == $max_row and last;
1225             }
1226 12         86 return \@c;
1227             }
1228              
1229             # row or col
1230 17         54 my @r;
1231 17         34 my $eod = 0;
1232 17         87 for (split m/\s*;\s*/ => $range) {
1233 25 50       153 my ($from, $to) = m/^\s* ([0-9]+) (?: \s* - \s* ([0-9]+ | \* ))? \s* $/x
1234             or croak ($self->SetDiag (2013));
1235 25   100     91 $to ||= $from;
1236 25 100       62 $to eq "*" and ($to, $eod) = ($from, 1);
1237             # $to cannot be <= 0 due to regex and ||=
1238 25 100 100     105 $from <= 0 || $to < $from and croak ($self->SetDiag (2013));
1239 22         82 $r[$_] = 1 for $from .. $to;
1240             }
1241              
1242 14         26 my $r = 0;
1243 14 100       35 $type eq "col" and shift @r;
1244 14   100     145 $_ ||= 0 for @r;
1245 14         51 while (my $row = $self->getline ($io)) {
1246 109         166 $r++;
1247 109 100       258 if ($type eq "row") {
1248 64 100 100     309 if (($r > $#r && $eod) || $r[$r]) {
      100        
1249 20         36 push @c, $row;
1250 20 100       44 if (@h) {
1251 3         7 my %h; @h{@h} = @{$c[-1]};
  3         5  
  3         14  
1252 3         8 $c[-1] = \%h;
1253             }
1254             }
1255 64         225 next;
1256             }
1257 45 100 100     116 push @c, [ map { ($_ > $#r && $eod) || $r[$_] ? $row->[$_] : () } 0..$#$row ];
  405         1499  
1258 45 100       207 if (@h) {
1259 9         14 my %h; @h{@h} = @{$c[-1]};
  9         13  
  9         25  
1260 9         35 $c[-1] = \%h;
1261             }
1262             }
1263              
1264 14         93 return \@c;
1265             }
1266              
1267             my $csv_usage = q{usage: my $aoa = csv (in => $file);};
1268              
1269             sub _csv_attr {
1270 273 100 66 273   1553 my %attr = (@_ == 1 && ref $_[0] eq "HASH" ? %{$_[0]} : @_) or croak;
  4 50       26  
1271              
1272 273         570 $attr{binary} = 1;
1273              
1274 273   100     1315 my $enc = delete $attr{enc} || delete $attr{encoding} || "";
1275 273 100       667 $enc eq "auto" and ($attr{detect_bom}, $enc) = (1, "");
1276 273 50       724 my $stack = $enc =~ s/(:\w.*)// ? $1 : "";
1277 273 100       571 $enc =~ m/^[-\w.]+$/ and $enc = ":encoding($enc)";
1278 273         458 $enc .= $stack;
1279              
1280 273         411 my $fh;
1281 273         376 my $sink = 0;
1282 273         368 my $cls = 0; # If I open a file, I have to close it
1283 273 100 100     1395 my $in = delete $attr{in} || delete $attr{file} or croak $csv_usage;
1284             my $out = exists $attr{out} && !$attr{out} ? \"skip"
1285 270 50 66     1177 : delete $attr{out} || delete $attr{file};
      100        
1286              
1287 270 100 100     988 ref $in eq "CODE" || ref $in eq "ARRAY" and $out ||= \*STDOUT;
      100        
1288              
1289 270 100 66     1115 $in && $out && !ref $in && !ref $out and croak join "\n" =>
      100        
      100        
1290             qq{Cannot use a string for both in and out. Instead use:},
1291             qq{ csv (in => csv (in => "$in"), out => "$out");\n};
1292              
1293 269 100       510 if ($out) {
1294 27 100 100     265 if (ref $out and ("ARRAY" eq ref $out or "HASH" eq ref $out)) {
    100 100        
    100 100        
      100        
      66        
      66        
      66        
1295 5         14 delete $attr{out};
1296 5         9 $sink = 1;
1297             }
1298             elsif ((ref $out and "SCALAR" ne ref $out) or "GLOB" eq ref \$out) {
1299 13         24 $fh = $out;
1300             }
1301             elsif (ref $out and "SCALAR" eq ref $out and defined $$out and $$out eq "skip") {
1302 1         3 delete $attr{out};
1303 1         2 $sink = 1;
1304             }
1305             else {
1306 8 100       21774 open $fh, ">", $out or croak "$out: $!";
1307 7         33 $cls = 1;
1308             }
1309 26 100       68 if ($fh) {
1310 20 100       50 if ($enc) {
1311 1         19 binmode $fh, $enc;
1312 1         87 my $fn = fileno $fh; # This is a workaround for a bug in PerlIO::via::gzip
1313             }
1314 20 100       57 unless (defined $attr{eol}) {
1315 17         32 my @layers = eval { PerlIO::get_layers ($fh) };
  17         123  
1316 17 100       118 $attr{eol} = (grep m/crlf/ => @layers) ? "\n" : "\r\n";
1317             }
1318             }
1319             }
1320              
1321 268 100 100     1593 if ( ref $in eq "CODE" or ref $in eq "ARRAY") {
    100 100        
    100          
1322             # All done
1323             }
1324             elsif (ref $in eq "SCALAR") {
1325             # Strings with code points over 0xFF may not be mapped into in-memory file handles
1326             # "<$enc" does not change that :(
1327 23 50   5   387 open $fh, "<", $in or croak "Cannot open from SCALAR using PerlIO";
  5         47  
  5         13  
  5         38  
1328 23         1985 $cls = 1;
1329             }
1330             elsif (ref $in or "GLOB" eq ref \$in) {
1331 16 50 66     47 if (!ref $in && $] < 5.008005) {
1332 0         0 $fh = \*$in; # uncoverable statement ancient perl version required
1333             }
1334             else {
1335 16         27 $fh = $in;
1336             }
1337             }
1338             else {
1339 210 100       8654 open $fh, "<$enc", $in or croak "$in: $!";
1340 208         18036 $cls = 1;
1341             }
1342 266 50 33     769 $fh || $sink or croak qq{No valid source passed. "in" is required};
1343              
1344 266         535 my $hdrs = delete $attr{headers};
1345 266         412 my $frag = delete $attr{fragment};
1346 266         392 my $key = delete $attr{key};
1347 266         395 my $val = delete $attr{value};
1348             my $kh = delete $attr{keep_headers} ||
1349             delete $attr{keep_column_names} ||
1350 266   100     1235 delete $attr{kh};
1351              
1352             my $cbai = delete $attr{callbacks}{after_in} ||
1353             delete $attr{after_in} ||
1354             delete $attr{callbacks}{after_parse} ||
1355 266   100     1845 delete $attr{after_parse};
1356             my $cbbo = delete $attr{callbacks}{before_out} ||
1357 266   100     793 delete $attr{before_out};
1358             my $cboi = delete $attr{callbacks}{on_in} ||
1359 266   100     710 delete $attr{on_in};
1360              
1361             my $hd_s = delete $attr{sep_set} ||
1362 266   100     715 delete $attr{seps};
1363             my $hd_b = delete $attr{detect_bom} ||
1364 266   100     741 delete $attr{bom};
1365             my $hd_m = delete $attr{munge} ||
1366 266   100     713 delete $attr{munge_column_names};
1367 266         411 my $hd_c = delete $attr{set_column_names};
1368              
1369 266         1041 for ([ quo => "quote" ],
1370             [ esc => "escape" ],
1371             [ escape => "escape_char" ],
1372             ) {
1373 798         1396 my ($f, $t) = @$_;
1374 798 100 100     2015 exists $attr{$f} and !exists $attr{$t} and $attr{$t} = delete $attr{$f};
1375             }
1376              
1377 266         660 my $fltr = delete $attr{filter};
1378             my %fltr = (
1379 10 100 33 10   17 not_blank => sub { @{$_[1]} > 1 or defined $_[1][0] && $_[1][0] ne "" },
  10         42  
1380 10 50   10   14 not_empty => sub { grep { defined && $_ ne "" } @{$_[1]} },
  26         97  
  10         23  
1381 10 50   10   15 filled => sub { grep { defined && m/\S/ } @{$_[1]} },
  26         116  
  10         19  
1382 266         1986 );
1383             defined $fltr && !ref $fltr && exists $fltr{$fltr} and
1384 266 50 100     773 $fltr = { 0 => $fltr{$fltr} };
      66        
1385 266 100       575 ref $fltr eq "CODE" and $fltr = { 0 => $fltr };
1386 266 100       678 ref $fltr eq "HASH" or $fltr = undef;
1387              
1388 266         502 my $form = delete $attr{formula};
1389              
1390 266 100       736 defined $attr{auto_diag} or $attr{auto_diag} = 1;
1391 266 100       581 defined $attr{escape_null} or $attr{escape_null} = 0;
1392 266 50 66     1513 my $csv = delete $attr{csv} || Text::CSV_PP->new (\%attr)
1393             or croak $last_new_error;
1394 266 100       560 defined $form and $csv->formula ($form);
1395              
1396             return {
1397 266         5080 csv => $csv,
1398             attr => { %attr },
1399             fh => $fh,
1400             cls => $cls,
1401             in => $in,
1402             sink => $sink,
1403             out => $out,
1404             enc => $enc,
1405             hdrs => $hdrs,
1406             key => $key,
1407             val => $val,
1408             kh => $kh,
1409             frag => $frag,
1410             fltr => $fltr,
1411             cbai => $cbai,
1412             cbbo => $cbbo,
1413             cboi => $cboi,
1414             hd_s => $hd_s,
1415             hd_b => $hd_b,
1416             hd_m => $hd_m,
1417             hd_c => $hd_c,
1418             };
1419             }
1420              
1421             sub csv {
1422 274 100 66 274 1 54151 @_ && (ref $_[0] eq __PACKAGE__ or ref $_[0] eq 'Text::CSV') and splice @_, 0, 0, "csv";
      100        
1423 274 100       753 @_ or croak $csv_usage;
1424              
1425 273         625 my $c = _csv_attr (@_);
1426              
1427 266         537 my ($csv, $in, $fh, $hdrs) = @{$c}{qw( csv in fh hdrs )};
  266         771  
1428 266         417 my %hdr;
1429 266 100       635 if (ref $hdrs eq "HASH") {
1430 2         8 %hdr = %$hdrs;
1431 2         5 $hdrs = "auto";
1432             }
1433              
1434 266 100 100     702 if ($c->{out} && !$c->{sink}) {
1435 19 100       70 if (ref $in eq "CODE") {
    100          
1436 3         5 my $hdr = 1;
1437 3         12 while (my $row = $in->($csv)) {
1438 7 100       69 if (ref $row eq "ARRAY") {
1439 3         8 $csv->print ($fh, $row);
1440 3         35 next;
1441             }
1442 4 50       10 if (ref $row eq "HASH") {
1443 4 100       9 if ($hdr) {
1444 2 50 100     19 $hdrs ||= [ map { $hdr{$_} || $_ } keys %$row ];
  3         14  
1445 2         10 $csv->print ($fh, $hdrs);
1446 2         26 $hdr = 0;
1447             }
1448 4         8 $csv->print ($fh, [ @{$row}{@$hdrs} ]);
  4         15  
1449             }
1450             }
1451             }
1452             elsif (ref $in->[0] eq "ARRAY") { # aoa
1453 9 50       22 ref $hdrs and $csv->print ($fh, $hdrs);
1454 9         15 for (@{$in}) {
  9         24  
1455 12 100       86 $c->{cboi} and $c->{cboi}->($csv, $_);
1456 12 50       1095 $c->{cbbo} and $c->{cbbo}->($csv, $_);
1457 12         42 $csv->print ($fh, $_);
1458             }
1459             }
1460             else { # aoh
1461 7 100       19 my @hdrs = ref $hdrs ? @{$hdrs} : keys %{$in->[0]};
  1         2  
  6         21  
1462 7 100       19 defined $hdrs or $hdrs = "auto";
1463             ref $hdrs || $hdrs eq "auto" and
1464 7 100 100     34 $csv->print ($fh, [ map { $hdr{$_} || $_ } @hdrs ]);
  8 100       43  
1465 7         110 for (@{$in}) {
  7         18  
1466 9         52 local %_;
1467 9         23 *_ = $_;
1468 9 50       21 $c->{cboi} and $c->{cboi}->($csv, $_);
1469 9 50       20 $c->{cbbo} and $c->{cbbo}->($csv, $_);
1470 9         16 $csv->print ($fh, [ @{$_}{@hdrs} ]);
  9         30  
1471             }
1472             }
1473              
1474 19 100       743 $c->{cls} and close $fh;
1475 19         331 return 1;
1476             }
1477              
1478 247         377 my @row1;
1479 247 100 100     1314 if (defined $c->{hd_s} || defined $c->{hd_b} || defined $c->{hd_m} || defined $c->{hd_c}) {
      100        
      100        
1480 148         199 my %harg;
1481 148 100       272 defined $c->{hd_s} and $harg{set_set} = $c->{hd_s};
1482 148 50       270 defined $c->{hd_d} and $harg{detect_bom} = $c->{hd_b};
1483 148 50       277 defined $c->{hd_m} and $harg{munge_column_names} = $hdrs ? "none" : $c->{hd_m};
    100          
1484 148 50       270 defined $c->{hd_c} and $harg{set_column_names} = $hdrs ? 0 : $c->{hd_c};
    100          
1485 148         390 @row1 = $csv->header ($fh, \%harg);
1486 148         366 my @hdr = $csv->column_names;
1487 148 100 50     724 @hdr and $hdrs ||= \@hdr;
1488             }
1489              
1490 247 100       607 if ($c->{kh}) {
1491 11 100       38 ref $c->{kh} eq "ARRAY" or croak ($csv->SetDiag (1501));
1492 6   100     15 $hdrs ||= "auto";
1493             }
1494              
1495 242         423 my $key = $c->{key};
1496 242 100       487 if ($key) {
1497 27 100 100     143 !ref $key or ref $key eq "ARRAY" && @$key > 1 or croak ($csv->SetDiag (1501));
      100        
1498 20   100     62 $hdrs ||= "auto";
1499             }
1500 235         348 my $val = $c->{val};
1501 235 100       444 if ($val) {
1502 9 100       24 $key or croak ($csv->SetDiag (1502));
1503 8 100 100     44 !ref $val or ref $val eq "ARRAY" && @$val > 0 or croak ($csv->SetDiag (1503));
      100        
1504             }
1505              
1506 231 100 100     557 $c->{fltr} && grep m/\D/ => keys %{$c->{fltr}} and $hdrs ||= "auto";
  16   100     113  
1507 231 100       484 if (defined $hdrs) {
1508 192 100       551 if (!ref $hdrs) {
    100          
1509 41 100       121 if ($hdrs eq "skip") {
    100          
    100          
    50          
1510 1         4 $csv->getline ($fh); # discard;
1511             }
1512             elsif ($hdrs eq "auto") {
1513 38 50       100 my $h = $csv->getline ($fh) or return;
1514 38 100       93 $hdrs = [ map { $hdr{$_} || $_ } @$h ];
  110         453  
1515             }
1516             elsif ($hdrs eq "lc") {
1517 1 50       4 my $h = $csv->getline ($fh) or return;
1518 1   33     4 $hdrs = [ map { lc ($hdr{$_} || $_) } @$h ];
  3         14  
1519             }
1520             elsif ($hdrs eq "uc") {
1521 1 50       4 my $h = $csv->getline ($fh) or return;
1522 1   33     3 $hdrs = [ map { uc ($hdr{$_} || $_) } @$h ];
  3         15  
1523             }
1524             }
1525             elsif (ref $hdrs eq "CODE") {
1526 1 50       7 my $h = $csv->getline ($fh) or return;
1527 1         3 my $cr = $hdrs;
1528 1   33     3 $hdrs = [ map { $cr->($hdr{$_} || $_) } @$h ];
  3         22  
1529             }
1530 192 100 66     498 $c->{kh} and $hdrs and @{$c->{kh}} = @$hdrs;
  6         16  
1531             }
1532              
1533 231 100       456 if ($c->{fltr}) {
1534 16         23 my %f = %{$c->{fltr}};
  16         45  
1535             # convert headers to index
1536 16         27 my @hdr;
1537 16 100       34 if (ref $hdrs) {
1538 7         9 @hdr = @{$hdrs};
  7         19  
1539 7         22 for (0 .. $#hdr) {
1540 21 100       72 exists $f{$hdr[$_]} and $f{$_ + 1} = delete $f{$hdr[$_]};
1541             }
1542             }
1543             $csv->callbacks (after_parse => sub {
1544 114     114   200 my ($CSV, $ROW) = @_; # lexical sub-variables in caps
1545 114         345 foreach my $FLD (sort keys %f) {
1546 115         322 local $_ = $ROW->[$FLD - 1];
1547 115         194 local %_;
1548 115 100       327 @hdr and @_{@hdr} = @$ROW;
1549 115 100       316 $f{$FLD}->($CSV, $ROW) or return \"skip";
1550 52         377 $ROW->[$FLD - 1] = $_;
1551             }
1552 16         88 });
1553             }
1554              
1555 231         356 my $frag = $c->{frag};
1556             my $ref = ref $hdrs
1557             ? # aoh
1558 231 100       572 do {
    100          
1559 191         411 my @h = $csv->column_names ($hdrs);
1560 191         303 my %h; $h{$_}++ for @h;
  191         667  
1561 191 50       397 exists $h{""} and croak ($csv->SetDiag (1012));
1562 191 50       504 unless (keys %h == @h) {
1563             croak ($csv->_SetDiagInfo (1013, join ", " =>
1564 0         0 map { "$_ ($h{$_})" } grep { $h{$_} > 1 } keys %h));
  0         0  
  0         0  
1565             }
1566             $frag ? $csv->fragment ($fh, $frag) :
1567 191 100       599 $key ? do {
    100          
1568 17 100       64 my ($k, $j, @f) = ref $key ? (undef, @$key) : ($key);
1569 17 100       36 if (my @mk = grep { !exists $h{$_} } grep { defined } $k, @f) {
  22         68  
  27         57  
1570 2         12 croak ($csv->_SetDiagInfo (4001, join ", " => @mk));
1571             }
1572             +{ map {
1573 26         43 my $r = $_;
1574 26 100       63 my $K = defined $k ? $r->{$k} : join $j => @{$r}{@f};
  4         12  
1575             ( $K => (
1576             $val
1577             ? ref $val
1578 4         20 ? { map { $_ => $r->{$_} } @$val }
1579 26 100       116 : $r->{$val}
    100          
1580             : $r ));
1581 15         23 } @{$csv->getline_hr_all ($fh)} }
  15         41  
1582             }
1583             : $csv->getline_hr_all ($fh);
1584             }
1585             : # aoa
1586             $frag ? $csv->fragment ($fh, $frag)
1587             : $csv->getline_all ($fh);
1588 229 50       489 if ($ref) {
1589 229 100 66     1074 @row1 && !$c->{hd_c} && !ref $hdrs and unshift @$ref, \@row1;
      100        
1590             }
1591             else {
1592 0         0 Text::CSV_PP->auto_diag;
1593             }
1594 229 100       3145 $c->{cls} and close $fh;
1595 229 100 100     1465 if ($ref and $c->{cbai} || $c->{cboi}) {
      66        
1596             # Default is ARRAYref, but with key =>, you'll get a hashref
1597 22 100       69 foreach my $r (ref $ref eq "ARRAY" ? @{$ref} : values %{$ref}) {
  21         54  
  1         5  
1598 71         5747 local %_;
1599 71 100       177 ref $r eq "HASH" and *_ = $r;
1600 71 100       189 $c->{cbai} and $c->{cbai}->($csv, $r);
1601 71 100       3649 $c->{cboi} and $c->{cboi}->($csv, $r);
1602             }
1603             }
1604              
1605 229 100       1641 if ($c->{sink}) {
1606 6 50       25 my $ro = ref $c->{out} or return;
1607              
1608 6 100 66     25 $ro eq "SCALAR" && ${$c->{out}} eq "skip" and
  1         19  
1609             return;
1610              
1611 5 50       15 $ro eq ref $ref or
1612             croak ($csv->_SetDiagInfo (5001, "Output type mismatch"));
1613              
1614 5 100       15 if ($ro eq "ARRAY") {
1615 4 100 33     6 if (@{$c->{out}} and @$ref and ref $c->{out}[0] eq ref $ref->[0]) {
  4   66     34  
1616 2         4 push @{$c->{out}} => @$ref;
  2         6  
1617 2         38 return $c->{out};
1618             }
1619 2         51 croak ($csv->_SetDiagInfo (5001, "Output type mismatch"));
1620             }
1621              
1622 1 50       6 if ($ro eq "HASH") {
1623 1         3 @{$c->{out}}{keys %{$ref}} = values %{$ref};
  1         3  
  1         4  
  1         3  
1624 1         18 return $c->{out};
1625             }
1626              
1627 0         0 croak ($csv->_SetDiagInfo (5002, "Unsupported output type"));
1628             }
1629              
1630             defined wantarray or
1631             return csv (
1632             in => $ref,
1633             headers => $hdrs,
1634 223 100       492 %{$c->{attr}},
  1         109  
1635             );
1636              
1637 222         4276 return $ref;
1638             }
1639              
1640             # The end of the common pure perl part.
1641              
1642             ################################################################################
1643             #
1644             # The following are methods implemented in XS in Text::CSV_XS or
1645             # helper methods for Text::CSV_PP only
1646             #
1647             ################################################################################
1648              
1649             sub _setup_ctx {
1650 27646     27646   51291 my $self = shift;
1651              
1652 27646         42877 $last_error = undef;
1653              
1654 27646         44600 my $ctx;
1655 27646 100       70188 if ($self->{_CACHE}) {
1656 26871         51242 %$ctx = %{$self->{_CACHE}};
  26871         439690  
1657             } else {
1658 775         2078 $ctx->{sep} = ',';
1659 775 50       1909 if (defined $self->{sep_char}) {
1660 775         1679 $ctx->{sep} = $self->{sep_char};
1661             }
1662 775 100 100     2557 if (defined $self->{sep} and $self->{sep} ne '') {
1663 32     32   23335 use bytes;
  32         511  
  32         202  
1664 5         17 $ctx->{sep} = $self->{sep};
1665 5         15 my $sep_len = length($ctx->{sep});
1666 5 50       22 $ctx->{sep_len} = $sep_len if $sep_len > 1;
1667             }
1668              
1669 775         1576 $ctx->{quo} = '"';
1670 775 50       1772 if (exists $self->{quote_char}) {
1671 775         1411 my $quote_char = $self->{quote_char};
1672 775 100 66     3074 if (defined $quote_char and length $quote_char) {
1673 771         1559 $ctx->{quo} = $quote_char;
1674             } else {
1675 4         21 $ctx->{quo} = "\0";
1676             }
1677             }
1678 775 100 100     2081 if (defined $self->{quote} and $self->{quote} ne '') {
1679 32     32   3571 use bytes;
  32         75  
  32         120  
1680 4         13 $ctx->{quo} = $self->{quote};
1681 4         10 my $quote_len = length($ctx->{quo});
1682 4 50       16 $ctx->{quo_len} = $quote_len if $quote_len > 1;
1683             }
1684              
1685 775         1478 $ctx->{escape_char} = '"';
1686 775 50       1693 if (exists $self->{escape_char}) {
1687 775         1272 my $escape_char = $self->{escape_char};
1688 775 100 100     2656 if (defined $escape_char and length $escape_char) {
1689 767         1551 $ctx->{escape_char} = $escape_char;
1690             } else {
1691 8         21 $ctx->{escape_char} = "\0";
1692             }
1693             }
1694              
1695 775 100       1789 if (defined $self->{eol}) {
1696 771         1274 my $eol = $self->{eol};
1697 771         1222 my $eol_len = length($eol);
1698 771         1290 $ctx->{eol} = $eol;
1699 771         1285 $ctx->{eol_len} = $eol_len;
1700 771 100 100     2261 if ($eol_len == 1 and $eol eq "\015") {
1701 42         111 $ctx->{eol_is_cr} = 1;
1702             }
1703             }
1704              
1705 775         1450 $ctx->{undef_flg} = 0;
1706 775 100       1810 if (defined $self->{undef_str}) {
1707 1         3 $ctx->{undef_str} = $self->{undef_str};
1708 1 50       5 $ctx->{undef_flg} = 3 if utf8::is_utf8($self->{undef_str});
1709             } else {
1710 774         1476 $ctx->{undef_str} = undef;
1711             }
1712 775 50       1827 if (defined $self->{comment_str}) {
1713 0         0 $ctx->{comment_str} = $self->{comment_str};
1714             }
1715              
1716 775 100       1690 if (defined $self->{_types}) {
1717 1         4 $ctx->{types} = $self->{_types};
1718 1         3 $ctx->{types_len} = length($ctx->{types});
1719             }
1720              
1721 775 100       1570 if (defined $self->{_is_bound}) {
1722 4         15 $ctx->{is_bound} = $self->{_is_bound};
1723             }
1724              
1725 775 100       1700 if (defined $self->{callbacks}) {
1726 255         381 my $cb = $self->{callbacks};
1727 255         661 $ctx->{has_hooks} = 0;
1728 255 100 66     615 if (defined $cb->{after_parse} and ref $cb->{after_parse} eq 'CODE') {
1729 9         15 $ctx->{has_hooks} |= HOOK_AFTER_PARSE;
1730             }
1731 255 100 66     598 if (defined $cb->{before_print} and ref $cb->{before_print} eq 'CODE') {
1732 1         3 $ctx->{has_hooks} |= HOOK_BEFORE_PRINT;
1733             }
1734             }
1735              
1736 775         1881 for (qw/
1737             binary decode_utf8 always_quote strict quote_empty
1738             allow_loose_quotes allow_loose_escapes
1739             allow_unquoted_escape allow_whitespace blank_is_undef
1740             empty_is_undef verbatim auto_diag diag_verbose
1741             keep_meta_info formula skip_empty_rows
1742             /) {
1743 13175 50       29758 $ctx->{$_} = defined $self->{$_} ? $self->{$_} : 0;
1744             }
1745 775         1442 for (qw/quote_space escape_null quote_binary/) {
1746 2325 50       5463 $ctx->{$_} = defined $self->{$_} ? $self->{$_} : 1;
1747             }
1748 775 100       1912 if ($ctx->{escape_char} eq "\0") {
1749 8         15 $ctx->{escape_null} = 0;
1750             }
1751              
1752             # FIXME: readonly
1753 775         3916 %{$self->{_CACHE}} = %$ctx;
  775         6536  
1754             }
1755              
1756 27646         99390 $ctx->{utf8} = 0;
1757 27646         47596 $ctx->{size} = 0;
1758 27646         43119 $ctx->{used} = 0;
1759              
1760 27646 100       63586 if ($ctx->{is_bound}) {
1761 89         162 my $bound = $self->{_BOUND_COLUMNS};
1762 89 100 66     377 if ($bound and ref $bound eq 'ARRAY') {
1763 75         168 $ctx->{bound} = $bound;
1764             } else {
1765 14         27 $ctx->{is_bound} = 0;
1766             }
1767             }
1768              
1769 27646         43321 $ctx->{eol_pos} = -1;
1770             $ctx->{eolx} = $ctx->{eol_len}
1771             ? $ctx->{verbatim} || $ctx->{eol_len} >= 2
1772             ? 1
1773 27646 100 100     92218 : $ctx->{eol} =~ /\A[\015\012]/ ? 0 : 1
    100          
    100          
1774             : 0;
1775              
1776 27646 100 66     75648 if ($ctx->{sep_len} and $ctx->{sep_len} > 1 and _is_valid_utf8($ctx->{sep})) {
      100        
1777 14         26 $ctx->{utf8} = 1;
1778             }
1779 27646 50 66     67686 if ($ctx->{quo_len} and $ctx->{quo_len} > 1 and _is_valid_utf8($ctx->{quo})) {
      66        
1780 0         0 $ctx->{utf8} = 1;
1781             }
1782              
1783 27646         56135 $ctx;
1784             }
1785              
1786             sub _cache_set {
1787 23439     23439   40431 my ($self, $idx, $value) = @_;
1788 23439 100       45743 return unless exists $self->{_CACHE};
1789 22589         31282 my $cache = $self->{_CACHE};
1790              
1791 22589         40621 my $key = $_reverse_cache_id{$idx};
1792 22589 100       97656 if (!defined $key) {
    100          
    100          
    100          
    100          
    100          
    100          
    100          
    100          
    100          
1793 1         15 warn (sprintf "Unknown cache index %d ignored\n", $idx);
1794             } elsif ($key eq 'sep_char') {
1795 3122         5280 $cache->{sep} = $value;
1796 3122         5913 $cache->{sep_len} = 0;
1797             }
1798             elsif ($key eq 'quote_char') {
1799 3369         6240 $cache->{quo} = $value;
1800 3369         5491 $cache->{quo_len} = 0;
1801             }
1802             elsif ($key eq '_has_ahead') {
1803 251         428 $cache->{has_ahead} = $value;
1804             }
1805             elsif ($key eq '_has_hooks') {
1806 11         19 $cache->{has_hooks} = $value;
1807             }
1808             elsif ($key eq '_is_bound') {
1809 11         28 $cache->{is_bound} = $value;
1810             }
1811             elsif ($key eq 'sep') {
1812 32     32   26947 use bytes;
  32         106  
  32         838  
1813 3223         7950 my $len = bytes::length($value);
1814 3223 100       17973 $cache->{sep} = $value if $len;
1815 3223 50       7314 $cache->{sep_len} = $len == 1 ? 0 : $len;
1816             }
1817             elsif ($key eq 'quote') {
1818 32     32   2355 use bytes;
  32         60  
  32         233  
1819 3377         8564 my $len = bytes::length($value);
1820 3377 100       13376 $cache->{quo} = $value if $len;
1821 3377 50       7331 $cache->{quo_len} = $len == 1 ? 0 : $len;
1822             }
1823             elsif ($key eq 'eol') {
1824 112 50       232 if (defined($value)) {
1825 112         211 $cache->{eol} = $value;
1826 112         206 $cache->{eol_len} = length($value);
1827             }
1828 112 100       259 $cache->{eol_is_cr} = $value eq "\015" ? 1 : 0;
1829             }
1830             elsif ($key eq 'undef_str') {
1831 11 100       20 if (defined $value) {
1832 9         16 $cache->{undef_str} = $value;
1833 9 100       26 $cache->{undef_flg} = 3 if utf8::is_utf8($value);
1834             } else {
1835 2         6 $cache->{undef_str} = undef;
1836 2         5 $cache->{undef_flg} = 0;
1837             }
1838             }
1839             else {
1840 9101         14411 $cache->{$key} = $value;
1841             }
1842 22589         36575 return 1;
1843             }
1844              
1845             sub _cache_diag {
1846 2     2   5 my $self = shift;
1847 2 100       11 unless (exists $self->{_CACHE}) {
1848 1         17 warn ("CACHE: invalid\n");
1849 1         8 return;
1850             }
1851              
1852 1         3 my $cache = $self->{_CACHE};
1853 1         62 warn ("CACHE:\n");
1854 1         16 $self->__cache_show_char(quote_char => $cache->{quo});
1855 1         8 $self->__cache_show_char(escape_char => $cache->{escape_char});
1856 1         8 $self->__cache_show_char(sep_char => $cache->{sep});
1857 1         7 for (qw/
1858             binary decode_utf8 allow_loose_escapes allow_loose_quotes allow_unquoted_escape
1859             allow_whitespace always_quote quote_empty quote_space
1860             escape_null quote_binary auto_diag diag_verbose formula strict skip_empty_rows
1861             has_error_input blank_is_undef empty_is_undef has_ahead
1862             keep_meta_info verbatim has_hooks eol_is_cr eol_len
1863             /) {
1864 25         120 $self->__cache_show_byte($_ => $cache->{$_});
1865             }
1866 1         11 $self->__cache_show_str(eol => $cache->{eol_len}, $cache->{eol});
1867 1         8 $self->__cache_show_byte(sep_len => $cache->{sep_len});
1868 1 50 33     10 if ($cache->{sep_len} and $cache->{sep_len} > 1) {
1869 1         5 $self->__cache_show_str(sep => $cache->{sep_len}, $cache->{sep});
1870             }
1871 1         8 $self->__cache_show_byte(quo_len => $cache->{quo_len});
1872 1 50 33     10 if ($cache->{quo_len} and $cache->{quo_len} > 1) {
1873 1         4 $self->__cache_show_str(quote => $cache->{quo_len}, $cache->{quo});
1874             }
1875 1 50       25 if ($cache->{types_len}) {
1876 0         0 $self->__cache_show_str(types => $cache->{types_len}, $cache->{types});
1877             } else {
1878 1         6 $self->__cache_show_str(types => 0, "");
1879             }
1880 1 50       8 if ($cache->{bptr}) {
1881 0         0 $self->__cache_show_str(bptr => length($cache->{bptr}), $cache->{bptr});
1882             }
1883 1 50       6 if ($cache->{tmp}) {
1884 1         5 $self->__cache_show_str(tmp => length($cache->{tmp}), $cache->{tmp});
1885             }
1886             }
1887              
1888             sub __cache_show_byte {
1889 27     27   58 my ($self, $key, $value) = @_;
1890 27 100       426 warn (sprintf " %-21s %02x:%3d\n", $key, defined $value ? ord($value) : 0, defined $value ? $value : 0);
    100          
1891             }
1892              
1893             sub __cache_show_char {
1894 3     3   11 my ($self, $key, $value) = @_;
1895 3         5 my $v = $value;
1896 3 50       9 if (defined $value) {
1897 3         12 my @b = unpack "U0C*", $value;
1898 3         15 $v = pack "U*", $b[0];
1899             }
1900 3 50       16 warn (sprintf " %-21s %02x:%s\n", $key, defined $v ? ord($v) : 0, $self->__pretty_str($v, 1));
1901             }
1902              
1903             sub __cache_show_str {
1904 5     5   12 my ($self, $key, $len, $value) = @_;
1905 5         12 warn (sprintf " %-21s %02d:%s\n", $key, $len, $self->__pretty_str($value, $len));
1906             }
1907              
1908             sub __pretty_str { # FIXME
1909 8     8   18 my ($self, $str, $len) = @_;
1910 8 50       15 return '' unless defined $str;
1911 8         19 $str = substr($str, 0, $len);
1912 8         23 $str =~ s/"/\\"/g;
1913 8         16 $str =~ s/([^\x09\x20-\x7e])/sprintf '\\x{%x}', ord($1)/eg;
  0         0  
1914 8         148 qq{"$str"};
1915             }
1916              
1917             sub _hook {
1918 20394     20394   46038 my ($self, $name, $fields) = @_;
1919 20394 100       69040 return 0 unless $self->{callbacks};
1920              
1921 161         269 my $cb = $self->{callbacks}{$name};
1922 161 100 66     579 return 0 unless $cb && ref $cb eq 'CODE';
1923              
1924 125         240 my (@res) = $cb->($self, $fields);
1925 125 50       651 if (@res) {
1926 125 100 66     299 return 0 if ref $res[0] eq 'SCALAR' and ${$res[0]} eq "skip";
  64         302  
1927             }
1928 61         140 scalar @res;
1929             }
1930              
1931             ################################################################################
1932             # methods for combine
1933             ################################################################################
1934              
1935             sub __combine {
1936 21670     21670   49981 my ($self, $dst, $fields, $useIO) = @_;
1937              
1938 21670         57303 my $ctx = $self->_setup_ctx;
1939              
1940 21670         37210 my ($binary, $quot, $sep, $esc, $quote_space) = @{$ctx}{qw/binary quo sep escape_char quote_space/};
  21670         63959  
1941              
1942 21670 100 100     96727 if(!defined $quot or $quot eq "\0"){ $quot = ''; }
  2         5  
1943              
1944 21670         33758 my $re_esc;
1945 21670 100 66     75738 if ($esc ne '' and $esc ne "\0") {
1946 21668 100       42801 if ($quot ne '') {
1947 21666   66     80570 $re_esc = $self->{_re_comb_escape}->{$quot}->{$esc} ||= qr/(\Q$quot\E|\Q$esc\E)/;
1948             } else {
1949 2   33     55 $re_esc = $self->{_re_comb_escape}->{$quot}->{$esc} ||= qr/(\Q$esc\E)/;
1950             }
1951             }
1952              
1953 21670         41805 my $bound = 0;
1954 21670         35625 my $n = @$fields - 1;
1955 21670 100 100     48473 if ($n < 0 and $ctx->{is_bound}) {
1956 5         23 $n = $ctx->{is_bound} - 1;
1957 5         9 $bound = 1;
1958             }
1959              
1960 21670 100 66     59949 my $check_meta = ($ctx->{keep_meta_info} >= 10 and @{$self->{_FFLAGS} || []} >= $n) ? 1 : 0;
1961              
1962 21670         35130 my $must_be_quoted;
1963             my @results;
1964 21670         47591 for(my $i = 0; $i <= $n; $i++) {
1965 53867         66905 my $v_ref;
1966 53867 100       91482 if ($bound) {
1967 14         47 $v_ref = $self->__bound_field($ctx, $i, 1);
1968             } else {
1969 53853 50       104361 if (@$fields > $i) {
1970 53853         86523 $v_ref = \($fields->[$i]);
1971             }
1972             }
1973 53867 50       101635 next unless $v_ref;
1974              
1975 53867         87037 my $value = $$v_ref;
1976              
1977 53867 100       99642 if (!defined $value) {
1978 56 100       121 if ($ctx->{undef_str}) {
1979 8 100       18 if ($ctx->{undef_flg}) {
1980 3         4 $ctx->{utf8} = 1;
1981 3         5 $ctx->{binary} = 1;
1982             }
1983 8         15 push @results, $ctx->{undef_str};
1984             } else {
1985 48         88 push @results, '';
1986             }
1987 56         138 next;
1988             }
1989              
1990 53811 100 100     2505148 if ( substr($value, 0, 1) eq '=' && $ctx->{formula} ) {
1991 10         25 $value = $self->_formula($ctx, $value, $i);
1992 6 100       14 if (!defined $value) {
1993 2         3 push @results, '';
1994 2         6 next;
1995             }
1996             }
1997              
1998 53805 100       105928 $must_be_quoted = $ctx->{always_quote} ? 1 : 0;
1999 53805 100       89603 if ($value eq '') {
2000 1402 100 100     5147 $must_be_quoted++ if $ctx->{quote_empty} or ($check_meta && $self->is_quoted($i));
      100        
2001             }
2002             else {
2003              
2004 52403 100       139841 if (utf8::is_utf8 $value) {
2005 20041         33486 $ctx->{utf8} = 1;
2006 20041         29168 $ctx->{binary} = 1;
2007             }
2008              
2009 52403 100 100     109132 $must_be_quoted++ if $check_meta && $self->is_quoted($i);
2010              
2011 52403 100 100     162492 if (!$must_be_quoted and $quot ne '') {
2012 32     32   45815 use bytes;
  32         77  
  32         175  
2013             $must_be_quoted++ if
2014             ($value =~ /\Q$quot\E/) ||
2015             ($sep ne '' and $sep ne "\0" and $value =~ /\Q$sep\E/) ||
2016             ($esc ne '' and $esc ne "\0" and $value =~ /\Q$esc\E/) ||
2017             ($ctx->{quote_binary} && $value =~ /[\x00-\x1f\x7f-\xa0]/) ||
2018 46761 100 66     900646 ($ctx->{quote_space} && $value =~ /[\x09\x20]/);
      100        
      100        
      66        
      100        
      100        
      100        
      100        
      100        
      100        
2019             }
2020              
2021 52403 100 100     130744 if (!$ctx->{binary} and $value =~ /[^\x09\x20-\x7E]/) {
2022             # an argument contained an invalid character...
2023 7         22 $self->{_ERROR_INPUT} = $value;
2024 7         60 $self->SetDiag(2110);
2025 7         74 return 0;
2026             }
2027              
2028 52396 100       98244 if ($re_esc) {
2029 52394         2570167 $value =~ s/($re_esc)/$esc$1/g;
2030             }
2031 52396 100       124198 if ($ctx->{escape_null}) {
2032 52291         2427604 $value =~ s/\0/${esc}0/g;
2033             }
2034             }
2035              
2036 53798 100       96279 if ($must_be_quoted) {
2037 29446         334973 $value = $quot . $value . $quot;
2038             }
2039 53798         174804 push @results, $value;
2040             }
2041              
2042 21659 100       628166 $$dst = join($sep, @results) . ( defined $ctx->{eol} ? $ctx->{eol} : '' );
2043              
2044 21659         163303 return 1;
2045             }
2046              
2047             sub _formula {
2048 37     37   74 my ($self, $ctx, $value, $i) = @_;
2049              
2050 37 50       81 my $fa = $ctx->{formula} or return;
2051 37 100       63 if ($fa == 1) { die "Formulas are forbidden\n" }
  3         58  
2052 34 100       60 if ($fa == 2) { die "Formulas are forbidden\n" } # XS croak behaves like PP's "die"
  3         53  
2053              
2054 31 100       56 if ($fa == 3) {
2055 6         17 my $rec = '';
2056 6 100       14 if ($ctx->{recno}) {
2057 3         13 $rec = sprintf " in record %lu", $ctx->{recno} + 1;
2058             }
2059 6         21 my $field = '';
2060 6         11 my $column_names = $self->{_COLUMN_NAMES};
2061 6 100 66     24 if (ref $column_names eq 'ARRAY' and @$column_names >= $i - 1) {
2062 1         3 my $column_name = $column_names->[$i - 1];
2063 1 50       9 $field = sprintf " (column: '%.100s')", $column_name if defined $column_name;
2064             }
2065 6         123 warn sprintf("Field %d%s%s contains formula '%s'\n", $i, $field, $rec, $value);
2066 6         80 return $value;
2067             }
2068              
2069 25 100       45 if ($fa == 4) {
2070 5         14 return '';
2071             }
2072 20 100       36 if ($fa == 5) {
2073 5         25 return undef;
2074             }
2075              
2076 15 50       32 if ($fa == 6) {
2077 15 50       35 if (ref $self->{_FORMULA_CB} eq 'CODE') {
2078 15         30 local $_ = $value;
2079 15         39 return $self->{_FORMULA_CB}->();
2080             }
2081             }
2082 0         0 return;
2083             }
2084              
2085             sub print {
2086 20277     20277 1 38296522 my ($self, $io, $fields) = @_;
2087              
2088 20277         143964 require IO::Handle;
2089              
2090 20277 100       164088 if (!defined $fields) {
    100          
2091 5         12 $fields = [];
2092             } elsif(ref($fields) ne 'ARRAY'){
2093 5         589 Carp::croak("Expected fields to be an array ref");
2094             }
2095              
2096 20272         68146 $self->_hook(before_print => $fields);
2097              
2098 20272         33418 my $str = "";
2099 20272 100       55129 $self->__combine(\$str, $fields, 1) or return '';
2100              
2101 20266         95262 local $\ = '';
2102              
2103 20266 100       90666 $io->print( $str ) or $self->_set_error_diag(2200);
2104             }
2105              
2106             ################################################################################
2107             # methods for parse
2108             ################################################################################
2109              
2110              
2111             sub __parse { # cx_xsParse
2112 3464     3464   8186 my ($self, $fields, $fflags, $src, $useIO) = @_;
2113              
2114 3464         8908 my $ctx = $self->_setup_ctx;
2115              
2116 3464         9604 my $state = $self->___parse($ctx, $fields, $fflags, $src, $useIO);
2117 3459 100 100     16334 if ($state and ($ctx->{has_hooks} || 0) & HOOK_AFTER_PARSE) {
      100        
2118 5         19 $self->_hook(after_parse => $fields);
2119             }
2120 3459   100     24414 return $state || !$last_error;
2121             }
2122              
2123             sub ___parse { # cx_c_xsParse
2124 4312     4312   9951 my ($self, $ctx, $fields, $fflags, $src, $useIO) = @_;
2125              
2126 4312 100 100     19340 local $/ = $ctx->{eol} if $ctx->{eolx} or $ctx->{eol_is_cr};
2127              
2128 4312 100       9491 if ($ctx->{useIO} = $useIO) {
2129 2369         21738 require IO::Handle;
2130              
2131 2369         91188 $ctx->{tmp} = undef;
2132 2369 100 66     6158 if ($ctx->{has_ahead} and defined $self->{_AHEAD}) {
2133 175         321 $ctx->{tmp} = $self->{_AHEAD};
2134 175         338 $ctx->{size} = length $ctx->{tmp};
2135 175         311 $ctx->{used} = 0;
2136             }
2137             } else {
2138 1943         3379 $ctx->{tmp} = $src;
2139 1943         3667 $ctx->{size} = length $src;
2140 1943         2827 $ctx->{used} = 0;
2141 1943         4845 $ctx->{utf8} = utf8::is_utf8($src);
2142             }
2143 4312 50       9530 if ($ctx->{has_error_input}) {
2144 0         0 $self->{_ERROR_INPUT} = undef;
2145 0         0 $ctx->{has_error_input} = 0;
2146             }
2147              
2148 4312         10857 my $result = $self->____parse($ctx, $src, $fields, $fflags);
2149 4307         9919 $self->{_RECNO} = ++($ctx->{recno});
2150 4307         7853 $self->{_EOF} = '';
2151              
2152 4307 100       9083 if ($ctx->{strict}) {
2153 15   66     52 $ctx->{strict_n} ||= $ctx->{fld_idx};
2154 15 100       44 if ($ctx->{strict_n} != $ctx->{fld_idx}) {
2155 6 100       20 unless ($ctx->{useIO} & useIO_EOF) {
2156 4         19 $self->__parse_error($ctx, 2014, $ctx->{used});
2157             }
2158 6         13 $result = undef;
2159             }
2160             }
2161              
2162 4307 100       8423 if ($ctx->{useIO}) {
2163 2367 100 66     9456 if (defined $ctx->{tmp} and $ctx->{used} < $ctx->{size} and $ctx->{has_ahead}) {
      100        
2164 37         145 $self->{_AHEAD} = substr($ctx->{tmp}, $ctx->{used}, $ctx->{size} - $ctx->{used});
2165             } else {
2166 2330         3700 $ctx->{has_ahead} = 0;
2167 2330 100       4697 if ($ctx->{useIO} & useIO_EOF) {
2168 501         857 $self->{_EOF} = 1;
2169             }
2170             }
2171 2367         18025 %{$self->{_CACHE}} = %$ctx;
  2367         34501  
2172              
2173 2367 100       9211 if ($fflags) {
2174 1519 100       2933 if ($ctx->{keep_meta_info}) {
2175 11         27 $self->{_FFLAGS} = $fflags;
2176             } else {
2177 1508         2579 undef $fflags;
2178             }
2179             }
2180             } else {
2181 1940         20628 %{$self->{_CACHE}} = %$ctx;
  1940         36655  
2182             }
2183              
2184 4307 100 100     20120 if ($result and $ctx->{types}) {
2185 2         5 my $len = @$fields;
2186 2   66     19 for(my $i = 0; $i <= $len && $i <= $ctx->{types_len}; $i++) {
2187 8         25 my $value = $fields->[$i];
2188 8 100       17 next unless defined $value;
2189 6         14 my $type = ord(substr($ctx->{types}, $i, 1));
2190 6 100       12 if ($type == IV) {
    100          
2191 2         26 $fields->[$i] = int($value);
2192             } elsif ($type == NV) {
2193 2         10 $fields->[$i] = $value + 0.0;
2194             }
2195             }
2196             }
2197              
2198 4307         11791 $result;
2199             }
2200              
2201             sub ____parse { # cx_Parse
2202 4316     4316   9033 my ($self, $ctx, $src, $fields, $fflags) = @_;
2203              
2204 4316         6365 my ($quot, $sep, $esc, $eol) = @{$ctx}{qw/quo sep escape_char eol/};
  4316         12052  
2205              
2206 4316 100 100     17885 utf8::encode($sep) if !$ctx->{utf8} and $ctx->{sep_len};
2207 4316 100 100     14247 utf8::encode($quot) if !$ctx->{utf8} and $ctx->{quo_len};
2208 4316 100 100     15758 utf8::encode($eol) if !$ctx->{utf8} and $ctx->{eol_len};
2209              
2210 4316         6070 my $seenSomething = 0;
2211 4316         5565 my $spl = -1;
2212 4316         5769 my $waitingForField = 1;
2213 4316         6810 my ($value, $v_ref);
2214 4316         7250 $ctx->{fld_idx} = my $fnum = 0;
2215 4316         6429 $ctx->{flag} = 0;
2216              
2217 4316 100       8979 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", " ";
  13999 100       39146  
  14375         26715  
  17264         64829  
2218 4316         67971 $ctx->{_re} = qr/$re_str/;
2219 4316         63730 my $re = qr/$re_str|[^\x09\x20-\x7E]|$/;
2220              
2221             LOOP:
2222 4316         15117 while($self->__get_from_src($ctx, $src)) {
2223 4432         85475 while($ctx->{tmp} =~ /\G(.*?)($re)/gs) {
2224 74182         190566 my ($hit, $c) = ($1, $2);
2225 74182         113957 $ctx->{used} = pos($ctx->{tmp});
2226 74182 100 100     200598 if (!$waitingForField and $c eq '' and $hit ne '' and $ctx->{useIO} and !($ctx->{useIO} & useIO_EOF)) {
      100        
      100        
      100        
2227 147         312 $self->{_AHEAD} = $hit;
2228 147         249 $ctx->{has_ahead} = 1;
2229 147         217 $ctx->{has_leftover} = 1;
2230 147         468 last;
2231             }
2232 74035 100 100     233848 last if $seenSomething and $hit eq '' and $c eq ''; # EOF
      100        
2233              
2234             # new field
2235 73683 100       120872 if (!$v_ref) {
2236 22191 100       37475 if ($ctx->{is_bound}) {
2237 87         264 $v_ref = $self->__bound_field($ctx, $fnum, 0);
2238             } else {
2239 22104         29646 $value = '';
2240 22104         32895 $v_ref = \$value;
2241             }
2242 22191         29903 $fnum++;
2243 22191 100       36766 return unless $v_ref;
2244 22187         29688 $ctx->{flag} = 0;
2245 22187         29464 $ctx->{fld_idx}++;
2246             }
2247              
2248 73679         87342 $seenSomething = 1;
2249 73679         86747 $spl++;
2250              
2251 73679 100 66     202177 if (defined $hit and $hit ne '') {
2252 45237 100       70943 if ($waitingForField) {
2253 9488 50 66     19481 if (!$spl && $ctx->{comment_str} && $ctx->{tmp} =~ /\A\Q$ctx->{comment_str}/) {
      33        
2254 0         0 $ctx->{used} = $ctx->{size};
2255 0         0 next LOOP;
2256             }
2257 9488         11953 $waitingForField = 0;
2258             }
2259 45237 50       92547 if ($hit =~ /[^\x09\x20-\x7E]/) {
2260 0         0 $ctx->{flag} |= IS_BINARY;
2261             }
2262 45237         69440 $$v_ref .= $hit;
2263             }
2264              
2265             RESTART:
2266 74295 100 66     802982 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        
2267 11383 100       24324 if ($waitingForField) {
    100          
2268             # ,1,"foo, 3",,bar,
2269             # ^ ^
2270 1177 100 100     4288 if ($ctx->{blank_is_undef} or $ctx->{empty_is_undef}) {
2271 53         93 $$v_ref = undef;
2272             } else {
2273 1124         1904 $$v_ref = "";
2274             }
2275 1177 50       2543 unless ($ctx->{is_bound}) {
2276 1177         2789 push @$fields, $$v_ref;
2277             }
2278 1177         1787 $v_ref = undef;
2279 1177 100 66     2909 if ($ctx->{keep_meta_info} and $fflags) {
2280 8         20 push @$fflags, $ctx->{flag};
2281             }
2282             } elsif ($ctx->{flag} & IS_QUOTED) {
2283             # ,1,"foo, 3",,bar,
2284             # ^
2285 2186         3616 $$v_ref .= $c;
2286             } else {
2287             # ,1,"foo, 3",,bar,
2288             # ^ ^ ^
2289 8020         21980 $self->__push_value($ctx, $v_ref, $fields, $fflags, $ctx->{flag}, $fnum);
2290 8018         10988 $v_ref = undef;
2291 8018         10619 $waitingForField = 1;
2292             }
2293             }
2294             elsif (defined $c and defined $quot and $quot ne "\0" and $c eq $quot) {
2295 22895 100       40202 if ($waitingForField) {
2296             # ,1,"foo, 3",,bar,\r\n
2297             # ^
2298 10923         16325 $ctx->{flag} |= IS_QUOTED;
2299 10923         13896 $waitingForField = 0;
2300 10923         56764 next;
2301             }
2302 11972 100       23531 if ($ctx->{flag} & IS_QUOTED) {
2303             # ,1,"foo, 3",,bar,\r\n
2304             # ^
2305 11918         15786 my $quoesc = 0;
2306 11918         27334 my $c2 = $self->__get($ctx, $src);
2307              
2308 11918 100       23719 if ($ctx->{allow_whitespace}) {
2309             # , 1 , "foo, 3" , , bar , \r\n
2310             # ^
2311 4290         9988 while($self->__is_whitespace($ctx, $c2)) {
2312 90 100 33     312 if ($ctx->{allow_loose_quotes} and !(defined $esc and $c2 eq $esc)) {
      66        
2313 1         4 $$v_ref .= $c;
2314 1         2 $c = $c2;
2315             }
2316 90         206 $c2 = $self->__get($ctx, $src);
2317             }
2318             }
2319              
2320 11918 100       23423 if (!defined $c2) { # EOF
2321             # ,1,"foo, 3"
2322             # ^
2323 1311         4312 $self->__push_value($ctx, $v_ref, $fields, $fflags, $ctx->{flag}, $fnum);
2324 1311         6330 return 1;
2325             }
2326              
2327 10607 100 33     41866 if (defined $c2 and defined $sep and $c2 eq $sep) {
      66        
2328             # ,1,"foo, 3",,bar,\r\n
2329             # ^
2330 9014         25459 $self->__push_value($ctx, $v_ref, $fields, $fflags, $ctx->{flag}, $fnum);
2331 9014         12661 $v_ref = undef;
2332 9014         11199 $waitingForField = 1;
2333 9014         48502 next;
2334             }
2335 1593 100 100     7932 if (defined $c2 and ($c2 eq "\012" or (defined $eol and $c2 eq $eol))) { # FIXME: EOLX
      66        
2336             # ,1,"foo, 3",,"bar"\n
2337             # ^
2338 311         949 $self->__push_value($ctx, $v_ref, $fields, $fflags, $ctx->{flag}, $fnum);
2339 311         1415 return 1;
2340             }
2341              
2342 1282 100 100     4084 if (defined $esc and $c eq $esc) {
2343 1261         1657 $quoesc = 1;
2344 1261 100 66     3845 if (defined $c2 and $c2 eq '0') {
2345             # ,1,"foo, 3"056",,bar,\r\n
2346             # ^
2347 51         96 $$v_ref .= "\0";
2348 51         243 next;
2349             }
2350 1210 100 33     5115 if (defined $c2 and defined $quot and $c2 eq $quot) {
      66        
2351             # ,1,"foo, 3""56",,bar,\r\n
2352             # ^
2353 1077 100       2293 if ($ctx->{utf8}) {
2354 1         3 $ctx->{flag} |= IS_BINARY;
2355             }
2356 1077         1648 $$v_ref .= $c2;
2357 1077         5519 next;
2358             }
2359 133 100 66     424 if ($ctx->{allow_loose_escapes} and defined $c2 and $c2 ne "\015") {
      100        
2360             # ,1,"foo, 3"56",,bar,\r\n
2361             # ^
2362 4         9 $$v_ref .= $c;
2363 4         56 $c = $c2;
2364 4         354 goto RESTART;
2365             }
2366             }
2367 150 100 66     593 if (defined $c2 and $c2 eq "\015") {
2368 93 50       200 if ($ctx->{eol_is_cr}) {
2369             # ,1,"foo, 3"\r
2370             # ^
2371 0         0 $self->__push_value($ctx, $v_ref, $fields, $fflags, $ctx->{flag}, $fnum);
2372 0         0 return 1;
2373             }
2374              
2375 93         192 my $c3 = $self->__get($ctx, $src);
2376 93 100 100     341 if (defined $c3 and $c3 eq "\012") {
2377             # ,1,"foo, 3"\r\n
2378             # ^
2379 79         229 $self->__push_value($ctx, $v_ref, $fields, $fflags, $ctx->{flag}, $fnum);
2380 79         312 return 1;
2381             }
2382              
2383 14 100 66     94 if ($ctx->{useIO} and !$ctx->{eol_len}) {
2384 1 50       4 if ($c3 eq "\015") { # \r followed by an empty line
2385             # ,1,"foo, 3"\r\r
2386             # ^
2387 0         0 $self->__set_eol_is_cr($ctx);
2388 0         0 goto EOLX;
2389             }
2390 1 50       15 if ($c3 !~ /[^\x09\x20-\x7E]/) {
2391             # ,1,"foo\n 3",,"bar"\r
2392             # baz,4
2393             # ^
2394 1         15 $self->__set_eol_is_cr($ctx);
2395 1         2 $ctx->{used}--;
2396 1         2 $ctx->{has_ahead} = 1;
2397 1         13 $self->__push_value($ctx, $v_ref, $fields, $fflags, $ctx->{flag}, $fnum);
2398 1         6 return 1;
2399             }
2400             }
2401              
2402 13 100       63 $self->__parse_error($ctx, $quoesc ? 2023 : 2010, $ctx->{used} - 2);
2403 13         55 return;
2404             }
2405              
2406 57 100 100     192 if ($ctx->{allow_loose_quotes} and !$quoesc) {
2407             # ,1,"foo, 3"456",,bar,\r\n
2408             # ^
2409 10         19 $$v_ref .= $c;
2410 10         14 $c = $c2;
2411 10         642 goto RESTART;
2412             }
2413             # 1,"foo" ",3
2414             # ^
2415 47 100       122 if ($quoesc) {
2416 39         67 $ctx->{used}--;
2417 39         164 $self->__error_inside_quotes($ctx, 2023);
2418 37         169 return;
2419             }
2420 8         36 $self->__error_inside_quotes($ctx, 2011);
2421 8         37 return;
2422             }
2423             # !waitingForField, !InsideQuotes
2424 54 100       138 if ($ctx->{allow_loose_quotes}) { # 1,foo "boo" d'uh,1
2425 4         7 $ctx->{flag} |= IS_ERROR;
2426 4         5 $$v_ref .= $c;
2427             } else {
2428 50         225 $self->__error_inside_field($ctx, 2034);
2429 50         241 return;
2430             }
2431             }
2432             elsif (defined $c and defined $esc and $esc ne "\0" and $c eq $esc) {
2433             # This means quote_char != escape_char
2434 4655 100       11350 if ($waitingForField) {
    100          
    50          
2435 34         49 $waitingForField = 0;
2436 34 100       111 if ($ctx->{allow_unquoted_escape}) {
2437             # The escape character is the first character of an
2438             # unquoted field
2439             # ... get and store next character
2440 4         18 my $c2 = $self->__get($ctx, $src);
2441 4         12 $$v_ref = "";
2442              
2443 4 100       14 if (!defined $c2) { # EOF
2444 1         3 $ctx->{used}--;
2445 1         6 $self->__error_inside_field($ctx, 2035);
2446 1         5 return;
2447             }
2448 3 100 33     70 if ($c2 eq '0') {
    50 33        
      33        
      0        
      33        
      0        
2449 1         3 $$v_ref .= "\0";
2450             }
2451             elsif (
2452             (defined $quot and $c2 eq $quot) or
2453             (defined $sep and $c2 eq $sep) or
2454             (defined $esc and $c2 eq $esc) or
2455             $ctx->{allow_loose_escapes}
2456             ) {
2457 2 50       12 if ($ctx->{utf8}) {
2458 0         0 $ctx->{flag} |= IS_BINARY;
2459             }
2460 2         8 $$v_ref .= $c2;
2461             } else {
2462 0         0 $self->__parse_inside_quotes($ctx, 2025);
2463 0         0 return;
2464             }
2465             }
2466             }
2467             elsif ($ctx->{flag} & IS_QUOTED) {
2468 4612         10887 my $c2 = $self->__get($ctx, $src);
2469 4612 100       9315 if (!defined $c2) { # EOF
2470 3         9 $ctx->{used}--;
2471 3         15 $self->__error_inside_quotes($ctx, 2024);
2472 3         13 return;
2473             }
2474 4609 100 66     27853 if ($c2 eq '0') {
    100 66        
      100        
      66        
      100        
      66        
2475 2         5 $$v_ref .= "\0";
2476             }
2477             elsif (
2478             (defined $quot and $c2 eq $quot) or
2479             (defined $sep and $c2 eq $sep) or
2480             (defined $esc and $c2 eq $esc) or
2481             $ctx->{allow_loose_escapes}
2482             ) {
2483 4581 50       9901 if ($ctx->{utf8}) {
2484 0         0 $ctx->{flag} |= IS_BINARY;
2485             }
2486 4581         7630 $$v_ref .= $c2;
2487             } else {
2488 26         52 $ctx->{used}--;
2489 26         109 $self->__error_inside_quotes($ctx, 2025);
2490 26         130 return;
2491             }
2492             }
2493             elsif ($v_ref) {
2494 9         31 my $c2 = $self->__get($ctx, $src);
2495 9 100       37 if (!defined $c2) { # EOF
2496 4         11 $ctx->{used}--;
2497 4         14 $self->__error_inside_field($ctx, 2035);
2498 4         15 return;
2499             }
2500 5         13 $$v_ref .= $c2;
2501             }
2502             else {
2503 0         0 $self->__error_inside_field($ctx, 2036);
2504 0         0 return;
2505             }
2506             }
2507             elsif (defined $c and ($c eq "\012" or $c eq '' or (defined $eol and $c eq $eol and $eol ne "\015"))) { # EOL
2508             EOLX:
2509 2736 100 100     7460 if ($fnum == 1 && $ctx->{flag} == 0 && (!$v_ref || $$v_ref eq '') && $ctx->{skip_empty_rows}) {
      66        
      100        
      100        
2510 23         35 $ctx->{fld_idx} = 0;
2511 23         61 $c = $self->__get($ctx, $src);
2512 23 50       75 if (!defined $c) { # EOF
2513 0         0 $v_ref = undef;
2514 0         0 $waitingForField = 0;
2515 0         0 last LOOP;
2516             }
2517 23         1259 goto RESTART;
2518             }
2519              
2520 2713 100       4864 if ($waitingForField) {
2521             # ,1,"foo, 3",,bar,
2522             # ^
2523 211 100 100     805 if ($ctx->{blank_is_undef} or $ctx->{empty_is_undef}) {
2524 16         43 $$v_ref = undef;
2525             } else {
2526 195         369 $$v_ref = "";
2527             }
2528 211 100       464 unless ($ctx->{is_bound}) {
2529 210         450 push @$fields, $$v_ref;
2530             }
2531 211 100 66     588 if ($ctx->{keep_meta_info} and $fflags) {
2532 14         28 push @$fflags, $ctx->{flag};
2533             }
2534 211         923 return 1;
2535             }
2536 2502 100       5894 if ($ctx->{flag} & IS_QUOTED) {
    100          
2537             # ,1,"foo\n 3",,bar,
2538             # ^
2539 767         1172 $ctx->{flag} |= IS_BINARY;
2540 767 100       1492 unless ($ctx->{binary}) {
2541 29         160 $self->__error_inside_quotes($ctx, 2021);
2542 29         155 return;
2543             }
2544 738         1173 $$v_ref .= $c;
2545             }
2546             elsif ($ctx->{verbatim}) {
2547             # ,1,foo\n 3,,bar,
2548             # This feature should be deprecated
2549 11         23 $ctx->{flag} |= IS_BINARY;
2550 11 100       31 unless ($ctx->{binary}) {
2551 1         7 $self->__error_inside_field($ctx, 2030);
2552 1         6 return;
2553             }
2554 10 100 100     51 $$v_ref .= $c unless $ctx->{eol} eq $c and $ctx->{useIO};
2555             }
2556             else {
2557             # sep=,
2558             # ^
2559 1724 100 100     4563 if (!$ctx->{recno} and $ctx->{fld_idx} == 1 and $ctx->{useIO} and $hit =~ /^sep=(.{1,16})$/i) {
      100        
      100        
2560 4         13 $ctx->{sep} = $1;
2561 32     32   98382 use bytes;
  32         77  
  32         180  
2562 4         7 my $len = length $ctx->{sep};
2563 4 50       10 if ($len <= 16) {
2564 4 100       10 $ctx->{sep_len} = $len == 1 ? 0 : $len;
2565 4         36 return $self->____parse($ctx, $src, $fields, $fflags);
2566             }
2567             }
2568              
2569             # ,1,"foo\n 3",,bar
2570             # ^
2571 1720         4982 $self->__push_value($ctx, $v_ref, $fields, $fflags, $ctx->{flag}, $fnum);
2572 1720         7201 return 1;
2573             }
2574             }
2575             elsif (defined $c and $c eq "\015" and !$ctx->{verbatim}) {
2576 1012 100       2101 if ($waitingForField) {
2577 110 100       262 if ($ctx->{eol_is_cr}) {
2578             # ,1,"foo\n 3",,bar,\r
2579             # ^
2580 29         45 $c = "\012";
2581 29         1078 goto EOLX;
2582             }
2583              
2584 81         237 my $c2 = $self->__get($ctx, $src);
2585 81 100       235 if (!defined $c2) { # EOF
2586             # ,1,"foo\n 3",,bar,\r
2587             # ^
2588 5         11 $c = undef;
2589 5 50       17 last unless $seenSomething;
2590 5         618 goto RESTART;
2591             }
2592 76 100       189 if ($c2 eq "\012") { # \r is not optional before EOLX!
2593             # ,1,"foo\n 3",,bar,\r\n
2594             # ^
2595 66         89 $c = $c2;
2596 66         2905 goto EOLX;
2597             }
2598              
2599 10 100 66     45 if ($ctx->{useIO} and !$ctx->{eol_len}) {
2600 5 50       17 if ($c2 eq "\012") { # \r followed by an empty line
2601             # ,1,"foo\n 3",,bar,\r\r
2602             # ^
2603 0         0 $self->__set_eol_is_cr($ctx);
2604 0         0 goto EOLX;
2605             }
2606 5         10 $waitingForField = 0;
2607 5 100       20 if ($c2 !~ /[^\x09\x20-\x7E]/) {
2608             # ,1,"foo\n 3",,bar,\r
2609             # baz,4
2610             # ^
2611 2         10 $self->__set_eol_is_cr($ctx);
2612 2         5 $ctx->{used}--;
2613 2         7 $ctx->{has_ahead} = 1;
2614 2 50 66     64 if ($fnum == 1 && $ctx->{flag} == 0 && (!$v_ref or $$v_ref eq '') && $ctx->{skip_empty_rows}) {
      33        
      66        
      33        
2615 1         3 $ctx->{fld_idx} = 0;
2616 1         5 $c = $self->__get($ctx, $src);
2617 1 50       3 if (!defined $c) { # EOF
2618 0         0 $v_ref = undef;
2619 0         0 $waitingForField = 0;
2620 0         0 last LOOP;
2621             }
2622 1         3 $$v_ref = $c2;
2623 1         68 goto RESTART;
2624             }
2625 1         4 $self->__push_value($ctx, $v_ref, $fields, $fflags, $ctx->{flag}, $fnum);
2626 1         6 return 1;
2627             }
2628             }
2629              
2630             # ,1,"foo\n 3",,bar,\r\t
2631             # ^
2632 8         25 $ctx->{used}--;
2633 8         52 $self->__error_inside_field($ctx, 2031);
2634 8         31 return;
2635             }
2636 902 100       1832 if ($ctx->{flag} & IS_QUOTED) {
2637             # ,1,"foo\r 3",,bar,\r\t
2638             # ^
2639 593         933 $ctx->{flag} |= IS_BINARY;
2640 593 100       1203 unless ($ctx->{binary}) {
2641 70         212 $self->__error_inside_quotes($ctx, 2022);
2642 70         267 return;
2643             }
2644 523         792 $$v_ref .= $c;
2645             }
2646             else {
2647 309 100       631 if ($ctx->{eol_is_cr}) {
2648             # ,1,"foo\n 3",,bar\r
2649             # ^
2650 163         6471 goto EOLX;
2651             }
2652              
2653 146         419 my $c2 = $self->__get($ctx, $src);
2654 146 100 100     561 if (defined $c2 and $c2 eq "\012") { # \r is not optional before EOLX!
2655             # ,1,"foo\n 3",,bar\r\n
2656             # ^
2657 130         4898 goto EOLX;
2658             }
2659              
2660 16 100 66     108 if ($ctx->{useIO} and !$ctx->{eol_len}) {
2661 11 100 100     61 if ($c2 !~ /[^\x09\x20-\x7E]/
2662             # ,1,"foo\n 3",,bar\r
2663             # baz,4
2664             # ^
2665             or $c2 eq "\015"
2666             # ,1,"foo\n 3",,bar,\r\r
2667             # ^
2668             ) {
2669 5         40 $self->__set_eol_is_cr($ctx);
2670 5         8 $ctx->{used}--;
2671 5         11 $ctx->{has_ahead} = 1;
2672 5 0 33     29 if ($fnum == 1 && $ctx->{flag} == 0 && (!$v_ref or $$v_ref eq '') && $ctx->{skip_empty_rows}) {
      0        
      33        
      0        
2673 0         0 $ctx->{fld_idx} = 0;
2674 0         0 $c = $self->__get($ctx, $src);
2675 0 0       0 if (!defined $c) { # EOL
2676 0         0 $v_ref = undef;
2677 0         0 $waitingForField = 0;
2678 0         0 last LOOP;
2679             }
2680 0         0 goto RESTART;
2681             }
2682 5         21 $self->__push_value($ctx, $v_ref, $fields, $fflags, $ctx->{flag}, $fnum);
2683 5         25 return 1;
2684             }
2685             }
2686              
2687             # ,1,"foo\n 3",,bar\r\t
2688             # ^
2689 11         42 $self->__error_inside_field($ctx, 2032);
2690 11         68 return;
2691             }
2692             }
2693             else {
2694 32002 50 66     66949 if ($ctx->{eolx} and $c eq $eol) {
2695 0         0 $c = '';
2696 0         0 goto EOLX;
2697             }
2698              
2699 32002 100       49227 if ($waitingForField) {
2700 574 50 66     1462 if (!$spl && $ctx->{comment_str} && $ctx->{tmp} =~ /\A$ctx->{comment_str}/) {
      33        
2701 0         0 $ctx->{used} = $ctx->{size};
2702 0         0 next LOOP;
2703             }
2704 574 100 100     1570 if ($ctx->{allow_whitespace} and $self->__is_whitespace($ctx, $c)) {
2705 231         330 do {
2706 341         698 $c = $self->__get($ctx, $src);
2707 341 100       947 last if !defined $c;
2708             } while $self->__is_whitespace($ctx, $c);
2709 230         12647 goto RESTART;
2710             }
2711 343         555 $waitingForField = 0;
2712 343         20317 goto RESTART;
2713             }
2714 31428 100       52182 if ($ctx->{flag} & IS_QUOTED) {
2715 29398 100 66     92948 if (!defined $c or $c =~ /[^\x09\x20-\x7E]/) {
2716 3252         5744 $ctx->{flag} |= IS_BINARY;
2717 3252 100 100     6407 unless ($ctx->{binary} or $ctx->{utf8}) {
2718 5         22 $self->__error_inside_quotes($ctx, 2026);
2719 5         45 return;
2720             }
2721             }
2722 29393         44666 $$v_ref .= $c;
2723             } else {
2724 2030 100 100     6940 if (!defined $c or $c =~ /[^\x09\x20-\x7E]/) {
2725 414 100 100     1350 last if $ctx->{useIO} && !defined $c;
2726 411         616 $ctx->{flag} |= IS_BINARY;
2727 411 50 66     817 unless ($ctx->{binary} or $ctx->{utf8}) {
2728 9         50 $self->__error_inside_field($ctx, 2037);
2729 9         42 return;
2730             }
2731             }
2732 2018         3129 $$v_ref .= $c;
2733             }
2734             }
2735 48688 100 100     282614 last LOOP if $ctx->{useIO} and $ctx->{verbatim} and $ctx->{used} == $ctx->{size};
      100        
2736             }
2737             }
2738              
2739 390 100       887 if ($waitingForField) {
2740 335 100 66     1399 if ($seenSomething or !$ctx->{useIO}) {
2741             # new field
2742 32 100       100 if (!$v_ref) {
2743 31 50       124 if ($ctx->{is_bound}) {
2744 0         0 $v_ref = $self->__bound_field($ctx, $fnum, 0);
2745             } else {
2746 31         63 $value = '';
2747 31         56 $v_ref = \$value;
2748             }
2749 31         52 $fnum++;
2750 31 50       84 return unless $v_ref;
2751 31         65 $ctx->{flag} = 0;
2752 31         228 $ctx->{fld_idx}++;
2753             }
2754 32 100 100     283 if ($ctx->{blank_is_undef} or $ctx->{empty_is_undef}) {
2755 9         22 $$v_ref = undef;
2756             } else {
2757 23         59 $$v_ref = "";
2758             }
2759 32 50       90 unless ($ctx->{is_bound}) {
2760 32         87 push @$fields, $$v_ref;
2761             }
2762 32 100 66     122 if ($ctx->{keep_meta_info} and $fflags) {
2763 3         10 push @$fflags, $ctx->{flag};
2764             }
2765 32         164 return 1;
2766             }
2767 303         1108 $self->SetDiag(2012);
2768 303         1023 return;
2769             }
2770              
2771 55 100       201 if ($ctx->{flag} & IS_QUOTED) {
2772 14         88 $self->__error_inside_quotes($ctx, 2027);
2773 13         56 return;
2774             }
2775              
2776 41 50       107 if ($v_ref) {
2777 41         196 $self->__push_value($ctx, $v_ref, $fields, $fflags, $ctx->{flag}, $fnum);
2778             }
2779 41         171 return 1;
2780             }
2781              
2782             sub __get_from_src {
2783 6174     6174   12730 my ($self, $ctx, $src) = @_;
2784 6174 100 100     26396 return 1 if defined $ctx->{tmp} and $ctx->{used} <= 0;
2785 4056 50       9554 return 1 if $ctx->{used} < $ctx->{size};
2786 4056 100       9784 return unless $ctx->{useIO};
2787 2691         65771 my $res = $src->getline;
2788 2691 100       79079 if (defined $res) {
    100          
2789 2187 50       4688 if ($ctx->{has_ahead}) {
2790 0         0 $ctx->{tmp} = $self->{_AHEAD};
2791 0 0       0 $ctx->{tmp} .= $ctx->{eol} if $ctx->{eol_len};
2792 0         0 $ctx->{tmp} .= $res;
2793 0         0 $ctx->{has_ahead} = 0;
2794             } else {
2795 2187         4051 $ctx->{tmp} = $res;
2796             }
2797 2187 50       5399 if ($ctx->{size} = length $ctx->{tmp}) {
2798 2187         3490 $ctx->{used} = -1;
2799 2187 100       5895 $ctx->{utf8} = 1 if utf8::is_utf8($ctx->{tmp});
2800 2187         5944 pos($ctx->{tmp}) = 0;
2801 2187         7278 return 1;
2802             }
2803             } elsif (delete $ctx->{has_leftover}) {
2804 147         382 $ctx->{tmp} = $self->{_AHEAD};
2805 147         221 $ctx->{has_ahead} = 0;
2806 147         232 $ctx->{useIO} |= useIO_EOF;
2807 147 50       350 if ($ctx->{size} = length $ctx->{tmp}) {
2808 147         208 $ctx->{used} = -1;
2809 147 50       384 $ctx->{utf8} = 1 if utf8::is_utf8($ctx->{tmp});
2810 147         338 pos($ctx->{tmp}) = 0;
2811 147         457 return 1;
2812             }
2813             }
2814 357 100       1098 $ctx->{tmp} = '' unless defined $ctx->{tmp};
2815 357         743 $ctx->{useIO} |= useIO_EOF;
2816 357         1000 return;
2817             }
2818              
2819             sub __set_eol_is_cr {
2820 8     8   24 my ($self, $ctx) = @_;
2821 8         20 $ctx->{eol} = "\015";
2822 8         29 $ctx->{eol_is_cr} = 1;
2823 8         15 $ctx->{eol_len} = 1;
2824 8         76 %{$self->{_CACHE}} = %$ctx;
  8         114  
2825              
2826 8         48 $self->{eol} = $ctx->{eol};
2827             }
2828              
2829             sub __bound_field {
2830 101     101   196 my ($self, $ctx, $i, $keep) = @_;
2831 101 100       281 if ($i >= $ctx->{is_bound}) {
2832 3         15 $self->SetDiag(3006);
2833 3         5 return;
2834             }
2835 98 50       241 if (ref $ctx->{bound} eq 'ARRAY') {
2836 98         165 my $ref = $ctx->{bound}[$i];
2837 98 50       195 if (ref $ref) {
2838 98 100       186 if ($keep) {
2839 14         28 return $ref;
2840             }
2841 84 100       239 unless (Scalar::Util::readonly($$ref)) {
2842 83         150 $$ref = "";
2843 83         187 return $ref;
2844             }
2845             }
2846             }
2847 1         6 $self->SetDiag(3008);
2848 1         2 return;
2849             }
2850              
2851             sub __get {
2852 17338     17338   29455 my ($self, $ctx, $src) = @_;
2853 17338 50       32441 return unless defined $ctx->{used};
2854 17338 100       33589 if ($ctx->{used} >= $ctx->{size}) {
2855 1355 100       3610 if ($self->__get_from_src($ctx, $src)) {
2856 20         49 return $self->__get($ctx, $src);
2857             }
2858 1335         2709 return;
2859             }
2860 15983         23522 my $pos = pos($ctx->{tmp});
2861 15983 50       109924 if ($ctx->{tmp} =~ /\G($ctx->{_re}|.)/gs) {
2862 15983         33402 my $c = $1;
2863 15983 100       36610 if ($c =~ /[^\x09\012\015\x20-\x7e]/) {
2864 1222         2195 $ctx->{flag} |= IS_BINARY;
2865             }
2866 15983         26396 $ctx->{used} = pos($ctx->{tmp});
2867 15983         47009 return $c;
2868             } else {
2869 0 0       0 if ($self->__get_from_src($ctx, $src)) {
2870 0         0 return $self->__get($ctx, $src);
2871             }
2872 0         0 pos($ctx->{tmp}) = $pos;
2873 0         0 return;
2874             }
2875             }
2876              
2877             sub __error_inside_quotes {
2878 194     194   439 my ($self, $ctx, $error) = @_;
2879 194         693 $self->__parse_error($ctx, $error, $ctx->{used} - 1);
2880             }
2881              
2882             sub __error_inside_field {
2883 84     84   199 my ($self, $ctx, $error) = @_;
2884 84         322 $self->__parse_error($ctx, $error, $ctx->{used} - 1);
2885             }
2886              
2887             sub __parse_error {
2888 295     295   648 my ($self, $ctx, $error, $pos) = @_;
2889 295         659 $self->{_ERROR_POS} = $pos;
2890 295         625 $self->{_ERROR_FLD} = $ctx->{fld_idx};
2891 295 50       858 $self->{_ERROR_INPUT} = $ctx->{tmp} if $ctx->{tmp};
2892 295         980 $self->SetDiag($error);
2893 292         539 return;
2894             }
2895              
2896             sub __is_whitespace {
2897 5064     5064   8941 my ($self, $ctx, $c) = @_;
2898 5064 100       9800 return unless defined $c;
2899             return (
2900             (!defined $ctx->{sep} or $c ne $ctx->{sep}) &&
2901             (!defined $ctx->{quo} or $c ne $ctx->{quo}) &&
2902 4529   33     25519 (!defined $ctx->{escape_char} or $c ne $ctx->{escape_char}) &&
2903             ($c eq " " or $c eq "\t")
2904             );
2905             }
2906              
2907             sub __push_value { # AV_PUSH (part of)
2908 20503     20503   37691 my ($self, $ctx, $v_ref, $fields, $fflags, $flag, $fnum) = @_;
2909 20503 100       38278 utf8::encode($$v_ref) if $ctx->{utf8};
2910 20503 100 66     40768 if ($ctx->{formula} && $$v_ref && substr($$v_ref, 0, 1) eq '=') {
      100        
2911 27         88 my $value = $self->_formula($ctx, $$v_ref, $fnum);
2912 25 100       511 push @$fields, defined $value ? $value : undef;
2913 25         49 return;
2914             }
2915 20476 100 66     74140 if (
      66        
      100        
2916             (!defined $$v_ref or $$v_ref eq '') and
2917             ($ctx->{empty_is_undef} or (!($flag & IS_QUOTED) and $ctx->{blank_is_undef}))
2918             ) {
2919 12         20 $$v_ref = undef;
2920             } else {
2921 20464 100 100     47644 if ($ctx->{allow_whitespace} && !($flag & IS_QUOTED)) {
2922 1725         3979 $$v_ref =~ s/[ \t]+$//;
2923             }
2924 20464 100 66     48201 if ($flag & IS_BINARY and $ctx->{decode_utf8} and ($ctx->{utf8} || _is_valid_utf8($$v_ref))) {
      100        
      66        
2925 2111         5738 utf8::decode($$v_ref);
2926             }
2927             }
2928 20476 100       39210 unless ($ctx->{is_bound}) {
2929 20395         43061 push @$fields, $$v_ref;
2930             }
2931 20476 100 66     47159 if ($ctx->{keep_meta_info} and $fflags) {
2932 88         187 push @$fflags, $flag;
2933             }
2934             }
2935              
2936             sub getline {
2937 1521     1521 1 317014 my ($self, $io) = @_;
2938              
2939 1521         2481 my (@fields, @fflags);
2940 1521         4380 my $res = $self->__parse(\@fields, \@fflags, $io, 1);
2941 1519 100       7829 $res ? \@fields : undef;
2942             }
2943              
2944             sub getline_all {
2945 271     271 1 588 my ( $self, $io, $offset, $len ) = @_;
2946              
2947 271         551 my $ctx = $self->_setup_ctx;
2948              
2949 271         415 my $tail = 0;
2950 271         364 my $n = 0;
2951 271   100     974 $offset ||= 0;
2952              
2953 271 100       525 if ( $offset < 0 ) {
2954 12         21 $tail = -$offset;
2955 12         20 $offset = -1;
2956             }
2957              
2958 271         422 my (@row, @list);
2959 271         798 while ($self->___parse($ctx, \@row, undef, $io, 1)) {
2960 589         1579 $ctx = $self->_setup_ctx;
2961              
2962 589 100       1425 if ($offset > 0) {
2963 12         21 $offset--;
2964 12         29 @row = ();
2965 12         36 next;
2966             }
2967 577 100 100     1994 if ($n++ >= $tail and $tail) {
2968 12         23 shift @list;
2969 12         24 $n--;
2970             }
2971 577 100 100     1906 if (($ctx->{has_hooks} || 0) & HOOK_AFTER_PARSE) {
2972 117 100       318 unless ($self->_hook(after_parse => \@row)) {
2973 63         118 @row = ();
2974 63         172 next;
2975             }
2976             }
2977 514         1497 push @list, [@row];
2978 514         1033 @row = ();
2979              
2980 514 100 100     1906 last if defined $len && $n >= $len and $offset >= 0; # exceeds limit size
      100        
2981             }
2982              
2983 271 100 100     734 if ( defined $len && $n > $len ) {
2984 8         22 @list = splice( @list, 0, $len);
2985             }
2986              
2987 271         1674 return \@list;
2988             }
2989              
2990             sub _is_valid_utf8 {
2991 3689 100   3689   55925 return ( $_[0] =~ /^(?:
2992             [\x00-\x7F]
2993             |[\xC2-\xDF][\x80-\xBF]
2994             |[\xE0][\xA0-\xBF][\x80-\xBF]
2995             |[\xE1-\xEC][\x80-\xBF][\x80-\xBF]
2996             |[\xED][\x80-\x9F][\x80-\xBF]
2997             |[\xEE-\xEF][\x80-\xBF][\x80-\xBF]
2998             |[\xF0][\x90-\xBF][\x80-\xBF][\x80-\xBF]
2999             |[\xF1-\xF3][\x80-\xBF][\x80-\xBF][\x80-\xBF]
3000             |[\xF4][\x80-\x8F][\x80-\xBF][\x80-\xBF]
3001             )+$/x ) ? 1 : 0;
3002             }
3003              
3004             ################################################################################
3005             # methods for errors
3006             ################################################################################
3007              
3008             sub _set_error_diag {
3009 1     1   48 my ( $self, $error, $pos ) = @_;
3010              
3011 1         19 $self->SetDiag($error);
3012              
3013 1 50       4 if (defined $pos) {
3014 0         0 $_[0]->{_ERROR_POS} = $pos;
3015             }
3016              
3017 1         9 return;
3018             }
3019              
3020             sub error_input {
3021 8     8 1 681 my $self = shift;
3022 8 100 66     72 if ($self and ((Scalar::Util::reftype($self) || '') eq 'HASH' or (ref $self) =~ /^Text::CSV/)) {
      66        
3023 4         23 return $self->{_ERROR_INPUT};
3024             }
3025 4         17 return;
3026             }
3027              
3028             sub _sv_diag {
3029 3445     3445   6343 my ($self, $error) = @_;
3030 3445         14670 bless [$error, $ERRORS->{$error}], 'Text::CSV::ErrorDiag';
3031             }
3032              
3033             sub _set_diag {
3034 1652     1652   3252 my ($self, $ctx, $error) = @_;
3035              
3036 1652         3317 $last_error = $self->_sv_diag($error);
3037 1652         4219 $self->{_ERROR_DIAG} = $last_error;
3038 1652 100       3903 if ($error == 0) {
3039 4         11 $self->{_ERROR_POS} = 0;
3040 4         8 $self->{_ERROR_FLD} = 0;
3041 4         8 $self->{_ERROR_INPUT} = undef;
3042 4         8 $ctx->{has_error_input} = 0;
3043             }
3044 1652 100       3360 if ($error == 2012) { # EOF
3045 304         528 $self->{_EOF} = 1;
3046             }
3047 1652 100       3158 if ($ctx->{auto_diag}) {
3048 250         578 $self->error_diag;
3049             }
3050 1649         7598 return $last_error;
3051             }
3052              
3053             sub SetDiag {
3054 3445     3445 1 9576 my ($self, $error, $errstr) = @_;
3055 3445         4973 my $res;
3056 3445 100       7454 if (ref $self) {
3057 1652         3943 my $ctx = $self->_setup_ctx;
3058 1652         4477 $res = $self->_set_diag($ctx, $error);
3059              
3060             } else {
3061 1793         4042 $res = $self->_sv_diag($error);
3062             }
3063 3442 100       7966 if (defined $errstr) {
3064 892         2647 $res->[1] = $errstr;
3065             }
3066 3442         28681 $res;
3067             }
3068              
3069             ################################################################################
3070             package Text::CSV::ErrorDiag;
3071              
3072 32     32   112879 use strict;
  32         84  
  32         2852  
3073             use overload (
3074 32         295 '""' => \&stringify,
3075             '+' => \&numeric,
3076             '-' => \&numeric,
3077             '*' => \&numeric,
3078             '/' => \&numeric,
3079             fallback => 1,
3080 32     32   42938 );
  32         34119  
3081              
3082              
3083             sub numeric {
3084 4336     4336   8022 my ($left, $right) = @_;
3085 4336 50       15573 return ref $left ? $left->[0] : $right->[0];
3086             }
3087              
3088              
3089             sub stringify {
3090 2315     2315   467971 $_[0]->[1];
3091             }
3092             ################################################################################
3093             1;
3094             __END__