Filename | /usr/lib/perl5/Text/CSV_XS.pm |
Statements | Executed 23 statements in 3.01ms |
Calls | P | F | Exclusive Time |
Inclusive Time |
Subroutine |
---|---|---|---|---|---|
1 | 1 | 1 | 30µs | 30µs | bootstrap (xsub) | Text::CSV_XS::
1 | 1 | 1 | 17µs | 22µs | BEGIN@26 | Text::CSV_XS::
1 | 1 | 1 | 17µs | 87µs | BEGIN@30 | Text::CSV_XS::
1 | 1 | 1 | 11µs | 53µs | BEGIN@32 | Text::CSV_XS::
1 | 1 | 1 | 9µs | 22µs | BEGIN@27 | Text::CSV_XS::
1 | 1 | 1 | 7µs | 7µs | SetDiag (xsub) | Text::CSV_XS::
1 | 1 | 1 | 6µs | 6µs | BEGIN@29 | Text::CSV_XS::
0 | 0 | 0 | 0s | 0s | IV | Text::CSV_XS::
0 | 0 | 0 | 0s | 0s | NV | Text::CSV_XS::
0 | 0 | 0 | 0s | 0s | PV | Text::CSV_XS::
0 | 0 | 0 | 0s | 0s | _check_sanity | Text::CSV_XS::
0 | 0 | 0 | 0s | 0s | _set_attr_C | Text::CSV_XS::
0 | 0 | 0 | 0s | 0s | _set_attr_N | Text::CSV_XS::
0 | 0 | 0 | 0s | 0s | _set_attr_X | Text::CSV_XS::
0 | 0 | 0 | 0s | 0s | allow_loose_escapes | Text::CSV_XS::
0 | 0 | 0 | 0s | 0s | allow_loose_quotes | Text::CSV_XS::
0 | 0 | 0 | 0s | 0s | allow_whitespace | Text::CSV_XS::
0 | 0 | 0 | 0s | 0s | always_quote | Text::CSV_XS::
0 | 0 | 0 | 0s | 0s | auto_diag | Text::CSV_XS::
0 | 0 | 0 | 0s | 0s | binary | Text::CSV_XS::
0 | 0 | 0 | 0s | 0s | bind_columns | Text::CSV_XS::
0 | 0 | 0 | 0s | 0s | blank_is_undef | Text::CSV_XS::
0 | 0 | 0 | 0s | 0s | column_names | Text::CSV_XS::
0 | 0 | 0 | 0s | 0s | combine | Text::CSV_XS::
0 | 0 | 0 | 0s | 0s | empty_is_undef | Text::CSV_XS::
0 | 0 | 0 | 0s | 0s | eof | Text::CSV_XS::
0 | 0 | 0 | 0s | 0s | eol | Text::CSV_XS::
0 | 0 | 0 | 0s | 0s | error_diag | Text::CSV_XS::
0 | 0 | 0 | 0s | 0s | error_input | Text::CSV_XS::
0 | 0 | 0 | 0s | 0s | escape_char | Text::CSV_XS::
0 | 0 | 0 | 0s | 0s | fields | Text::CSV_XS::
0 | 0 | 0 | 0s | 0s | getline_hr | Text::CSV_XS::
0 | 0 | 0 | 0s | 0s | is_binary | Text::CSV_XS::
0 | 0 | 0 | 0s | 0s | is_quoted | Text::CSV_XS::
0 | 0 | 0 | 0s | 0s | keep_meta_info | Text::CSV_XS::
0 | 0 | 0 | 0s | 0s | meta_info | Text::CSV_XS::
0 | 0 | 0 | 0s | 0s | new | Text::CSV_XS::
0 | 0 | 0 | 0s | 0s | parse | Text::CSV_XS::
0 | 0 | 0 | 0s | 0s | quote_char | Text::CSV_XS::
0 | 0 | 0 | 0s | 0s | quote_null | Text::CSV_XS::
0 | 0 | 0 | 0s | 0s | quote_space | Text::CSV_XS::
0 | 0 | 0 | 0s | 0s | sep_char | Text::CSV_XS::
0 | 0 | 0 | 0s | 0s | status | Text::CSV_XS::
0 | 0 | 0 | 0s | 0s | string | Text::CSV_XS::
0 | 0 | 0 | 0s | 0s | types | Text::CSV_XS::
0 | 0 | 0 | 0s | 0s | verbatim | Text::CSV_XS::
0 | 0 | 0 | 0s | 0s | version | Text::CSV_XS::
Line | State ments |
Time on line |
Calls | Time in subs |
Code |
---|---|---|---|---|---|
1 | package Text::CSV_XS; | ||||
2 | |||||
3 | # Copyright (c) 2007-2010 H.Merijn Brand. All rights reserved. | ||||
4 | # Copyright (c) 1998-2001 Jochen Wiedmann. All rights reserved. | ||||
5 | # Portions Copyright (c) 1997 Alan Citterman. All rights reserved. | ||||
6 | # | ||||
7 | # This program is free software; you can redistribute it and/or | ||||
8 | # modify it under the same terms as Perl itself. | ||||
9 | |||||
10 | ################################################################################ | ||||
11 | # HISTORY | ||||
12 | # | ||||
13 | # Written by: | ||||
14 | # Jochen Wiedmann <joe@ispsoft.de> | ||||
15 | # | ||||
16 | # Based on Text::CSV by: | ||||
17 | # Alan Citterman <alan@mfgrtl.com> | ||||
18 | # | ||||
19 | # Extended and Remodelled by: | ||||
20 | # H.Merijn Brand (h.m.brand@xs4all.nl) | ||||
21 | # | ||||
22 | ############################################################################ | ||||
23 | |||||
24 | 1 | 28µs | require 5.005; | ||
25 | |||||
26 | 3 | 27µs | 2 | 26µs | # spent 22µs (17+4) within Text::CSV_XS::BEGIN@26 which was called:
# once (17µs+4µs) by Text::CSV::BEGIN@1 at line 26 # spent 22µs making 1 call to Text::CSV_XS::BEGIN@26
# spent 4µs making 1 call to strict::import |
27 | 3 | 26µs | 2 | 35µs | # spent 22µs (9+13) within Text::CSV_XS::BEGIN@27 which was called:
# once (9µs+13µs) by Text::CSV::BEGIN@1 at line 27 # spent 22µs making 1 call to Text::CSV_XS::BEGIN@27
# spent 13µs making 1 call to warnings::import |
28 | |||||
29 | 3 | 23µs | 1 | 6µs | # spent 6µs within Text::CSV_XS::BEGIN@29 which was called:
# once (6µs+0s) by Text::CSV::BEGIN@1 at line 29 # spent 6µs making 1 call to Text::CSV_XS::BEGIN@29 |
30 | 3 | 53µs | 2 | 157µs | # spent 87µs (17+70) within Text::CSV_XS::BEGIN@30 which was called:
# once (17µs+70µs) by Text::CSV::BEGIN@1 at line 30 # spent 87µs making 1 call to Text::CSV_XS::BEGIN@30
# spent 70µs making 1 call to Exporter::import |
31 | |||||
32 | 3 | 2.79ms | 2 | 96µs | # spent 53µs (11+43) within Text::CSV_XS::BEGIN@32 which was called:
# once (11µs+43µs) by Text::CSV::BEGIN@1 at line 32 # spent 53µs making 1 call to Text::CSV_XS::BEGIN@32
# spent 43µs making 1 call to vars::import |
33 | 1 | 400ns | $VERSION = "0.73"; | ||
34 | 1 | 10µs | @ISA = qw( DynaLoader ); | ||
35 | 1 | 8µs | 1 | 333µs | bootstrap Text::CSV_XS $VERSION; # spent 333µs making 1 call to DynaLoader::bootstrap |
36 | |||||
37 | sub PV { 0 } | ||||
38 | sub IV { 1 } | ||||
39 | sub NV { 2 } | ||||
40 | |||||
41 | # version | ||||
42 | # | ||||
43 | # class/object method expecting no arguments and returning the version | ||||
44 | # number of Text::CSV. there are no side-effects. | ||||
45 | |||||
46 | sub version | ||||
47 | { | ||||
48 | return $VERSION; | ||||
49 | } # version | ||||
50 | |||||
51 | # new | ||||
52 | # | ||||
53 | # class/object method expecting no arguments and returning a reference to | ||||
54 | # a newly created Text::CSV object. | ||||
55 | |||||
56 | 1 | 16µs | my %def_attr = ( | ||
57 | quote_char => '"', | ||||
58 | escape_char => '"', | ||||
59 | sep_char => ',', | ||||
60 | eol => '', | ||||
61 | always_quote => 0, | ||||
62 | quote_space => 1, | ||||
63 | quote_null => 1, | ||||
64 | binary => 0, | ||||
65 | keep_meta_info => 0, | ||||
66 | allow_loose_quotes => 0, | ||||
67 | allow_loose_escapes => 0, | ||||
68 | allow_whitespace => 0, | ||||
69 | blank_is_undef => 0, | ||||
70 | empty_is_undef => 0, | ||||
71 | verbatim => 0, | ||||
72 | auto_diag => 0, | ||||
73 | types => undef, | ||||
74 | |||||
75 | _EOF => 0, | ||||
76 | _STATUS => undef, | ||||
77 | _FIELDS => undef, | ||||
78 | _FFLAGS => undef, | ||||
79 | _STRING => undef, | ||||
80 | _ERROR_INPUT => undef, | ||||
81 | _COLUMN_NAMES => undef, | ||||
82 | _BOUND_COLUMNS => undef, | ||||
83 | _AHEAD => undef, | ||||
84 | ); | ||||
85 | 1 | 13µs | 1 | 7µs | my $last_new_err = Text::CSV_XS->SetDiag (0); # spent 7µs making 1 call to Text::CSV_XS::SetDiag |
86 | |||||
87 | sub _check_sanity | ||||
88 | { | ||||
89 | my $attr = shift; | ||||
90 | for (qw( sep_char quote_char escape_char )) { | ||||
91 | exists $attr->{$_} && defined $attr->{$_} && $attr->{$_} =~ m/[\r\n]/ and | ||||
92 | return 1003; | ||||
93 | } | ||||
94 | $attr->{allow_whitespace} and | ||||
95 | (defined $attr->{quote_char} && $attr->{quote_char} =~ m/^[ \t]$/) || | ||||
96 | (defined $attr->{escape_char} && $attr->{escape_char} =~ m/^[ \t]$/) and | ||||
97 | return 1002; | ||||
98 | return 0; | ||||
99 | } # _check_sanity | ||||
100 | |||||
101 | sub new | ||||
102 | { | ||||
103 | $last_new_err = SetDiag (undef, 1000, | ||||
104 | "usage: my \$csv = Text::CSV_XS->new ([{ option => value, ... }]);"); | ||||
105 | |||||
106 | my $proto = shift; | ||||
107 | my $class = ref ($proto) || $proto or return; | ||||
108 | @_ > 0 && ref $_[0] ne "HASH" and return; | ||||
109 | my $attr = shift || {}; | ||||
110 | |||||
111 | for (keys %{$attr}) { | ||||
112 | if (m/^[a-z]/ && exists $def_attr{$_}) { | ||||
113 | $] >= 5.008002 && m/_char$/ and utf8::decode ($attr->{$_}); | ||||
114 | next; | ||||
115 | } | ||||
116 | # croak? | ||||
117 | $last_new_err = SetDiag (undef, 1000, "INI - Unknown attribute '$_'"); | ||||
118 | $attr->{auto_diag} and error_diag (); | ||||
119 | return; | ||||
120 | } | ||||
121 | |||||
122 | my $self = {%def_attr, %{$attr}}; | ||||
123 | if (my $ec = _check_sanity ($self)) { | ||||
124 | $last_new_err = SetDiag (undef, $ec); | ||||
125 | $attr->{auto_diag} and error_diag (); | ||||
126 | return; | ||||
127 | } | ||||
128 | |||||
129 | $last_new_err = SetDiag (undef, 0); | ||||
130 | defined $\ && !exists $attr->{eol} and $self->{eol} = $\; | ||||
131 | bless $self, $class; | ||||
132 | defined $self->{types} and $self->types ($self->{types}); | ||||
133 | $self; | ||||
134 | } # new | ||||
135 | |||||
136 | # Keep in sync with XS! | ||||
137 | 1 | 6µs | my %_cache_id = ( # Only expose what is accessed from within PM | ||
138 | quote_char => 0, | ||||
139 | escape_char => 1, | ||||
140 | sep_char => 2, | ||||
141 | binary => 3, | ||||
142 | keep_meta_info => 4, | ||||
143 | always_quote => 5, | ||||
144 | allow_loose_quotes => 6, | ||||
145 | allow_loose_escapes => 7, | ||||
146 | allow_double_quoted => 8, | ||||
147 | allow_whitespace => 9, | ||||
148 | blank_is_undef => 10, | ||||
149 | eol => 11, # 11 .. 18 | ||||
150 | verbatim => 22, | ||||
151 | empty_is_undef => 23, | ||||
152 | auto_diag => 24, | ||||
153 | quote_space => 25, | ||||
154 | quote_null => 31, | ||||
155 | _is_bound => 26, # 26 .. 29 | ||||
156 | ); | ||||
157 | |||||
158 | # A `character' | ||||
159 | sub _set_attr_C | ||||
160 | { | ||||
161 | my ($self, $name, $val, $ec) = @_; | ||||
162 | defined $val or $val = 0; | ||||
163 | $] >= 5.008002 and utf8::decode ($val); | ||||
164 | $self->{$name} = $val; | ||||
165 | $ec = _check_sanity ($self) and | ||||
166 | croak ($self->SetDiag ($ec)); | ||||
167 | $self->_cache_set ($_cache_id{$name}, $val); | ||||
168 | } # _set_attr_C | ||||
169 | |||||
170 | # A flag | ||||
171 | sub _set_attr_X | ||||
172 | { | ||||
173 | my ($self, $name, $val) = @_; | ||||
174 | defined $val or $val = 0; | ||||
175 | $self->{$name} = $val; | ||||
176 | $self->_cache_set ($_cache_id{$name}, 0 + $val); | ||||
177 | } # _set_attr_X | ||||
178 | |||||
179 | # A number | ||||
180 | sub _set_attr_N | ||||
181 | { | ||||
182 | my ($self, $name, $val) = @_; | ||||
183 | $self->{$name} = $val; | ||||
184 | $self->_cache_set ($_cache_id{$name}, 0 + $val); | ||||
185 | } # _set_attr_N | ||||
186 | |||||
187 | # Accessor methods. | ||||
188 | # It is unwise to change them halfway through a single file! | ||||
189 | sub quote_char | ||||
190 | { | ||||
191 | my $self = shift; | ||||
192 | if (@_) { | ||||
193 | my $qc = shift; | ||||
194 | $self->_set_attr_C ("quote_char", $qc); | ||||
195 | } | ||||
196 | $self->{quote_char}; | ||||
197 | } # quote_char | ||||
198 | |||||
199 | sub escape_char | ||||
200 | { | ||||
201 | my $self = shift; | ||||
202 | if (@_) { | ||||
203 | my $ec = shift; | ||||
204 | $self->_set_attr_C ("escape_char", $ec); | ||||
205 | } | ||||
206 | $self->{escape_char}; | ||||
207 | } # escape_char | ||||
208 | |||||
209 | sub sep_char | ||||
210 | { | ||||
211 | my $self = shift; | ||||
212 | @_ and $self->_set_attr_C ("sep_char", shift); | ||||
213 | $self->{sep_char}; | ||||
214 | } # sep_char | ||||
215 | |||||
216 | sub eol | ||||
217 | { | ||||
218 | my $self = shift; | ||||
219 | if (@_) { | ||||
220 | my $eol = shift; | ||||
221 | defined $eol or $eol = ""; | ||||
222 | $self->{eol} = $eol; | ||||
223 | $self->_cache_set ($_cache_id{eol}, $eol); | ||||
224 | } | ||||
225 | $self->{eol}; | ||||
226 | } # eol | ||||
227 | |||||
228 | sub always_quote | ||||
229 | { | ||||
230 | my $self = shift; | ||||
231 | @_ and $self->_set_attr_X ("always_quote", shift); | ||||
232 | $self->{always_quote}; | ||||
233 | } # always_quote | ||||
234 | |||||
235 | sub quote_space | ||||
236 | { | ||||
237 | my $self = shift; | ||||
238 | @_ and $self->_set_attr_X ("quote_space", shift); | ||||
239 | $self->{quote_space}; | ||||
240 | } # quote_space | ||||
241 | |||||
242 | sub quote_null | ||||
243 | { | ||||
244 | my $self = shift; | ||||
245 | @_ and $self->_set_attr_X ("quote_null", shift); | ||||
246 | $self->{quote_null}; | ||||
247 | } # quote_null | ||||
248 | |||||
249 | sub binary | ||||
250 | { | ||||
251 | my $self = shift; | ||||
252 | @_ and $self->_set_attr_X ("binary", shift); | ||||
253 | $self->{binary}; | ||||
254 | } # binary | ||||
255 | |||||
256 | sub keep_meta_info | ||||
257 | { | ||||
258 | my $self = shift; | ||||
259 | @_ and $self->_set_attr_X ("keep_meta_info", shift); | ||||
260 | $self->{keep_meta_info}; | ||||
261 | } # keep_meta_info | ||||
262 | |||||
263 | sub allow_loose_quotes | ||||
264 | { | ||||
265 | my $self = shift; | ||||
266 | @_ and $self->_set_attr_X ("allow_loose_quotes", shift); | ||||
267 | $self->{allow_loose_quotes}; | ||||
268 | } # allow_loose_quotes | ||||
269 | |||||
270 | sub allow_loose_escapes | ||||
271 | { | ||||
272 | my $self = shift; | ||||
273 | @_ and $self->_set_attr_X ("allow_loose_escapes", shift); | ||||
274 | $self->{allow_loose_escapes}; | ||||
275 | } # allow_loose_escapes | ||||
276 | |||||
277 | sub allow_whitespace | ||||
278 | { | ||||
279 | my $self = shift; | ||||
280 | if (@_) { | ||||
281 | my $aw = shift; | ||||
282 | $aw and | ||||
283 | (defined $self->{quote_char} && $self->{quote_char} =~ m/^[ \t]$/) || | ||||
284 | (defined $self->{escape_char} && $self->{escape_char} =~ m/^[ \t]$/) and | ||||
285 | croak ($self->SetDiag (1002)); | ||||
286 | $self->_set_attr_X ("allow_whitespace", $aw); | ||||
287 | } | ||||
288 | $self->{allow_whitespace}; | ||||
289 | } # allow_whitespace | ||||
290 | |||||
291 | sub blank_is_undef | ||||
292 | { | ||||
293 | my $self = shift; | ||||
294 | @_ and $self->_set_attr_X ("blank_is_undef", shift); | ||||
295 | $self->{blank_is_undef}; | ||||
296 | } # blank_is_undef | ||||
297 | |||||
298 | sub empty_is_undef | ||||
299 | { | ||||
300 | my $self = shift; | ||||
301 | @_ and $self->_set_attr_X ("empty_is_undef", shift); | ||||
302 | $self->{empty_is_undef}; | ||||
303 | } # empty_is_undef | ||||
304 | |||||
305 | sub verbatim | ||||
306 | { | ||||
307 | my $self = shift; | ||||
308 | @_ and $self->_set_attr_X ("verbatim", shift); | ||||
309 | $self->{verbatim}; | ||||
310 | } # verbatim | ||||
311 | |||||
312 | sub auto_diag | ||||
313 | { | ||||
314 | my $self = shift; | ||||
315 | @_ and $self->_set_attr_X ("auto_diag", shift); | ||||
316 | $self->{auto_diag}; | ||||
317 | } # auto_diag | ||||
318 | |||||
319 | # status | ||||
320 | # | ||||
321 | # object method returning the success or failure of the most recent | ||||
322 | # combine () or parse (). there are no side-effects. | ||||
323 | |||||
324 | sub status | ||||
325 | { | ||||
326 | my $self = shift; | ||||
327 | return $self->{_STATUS}; | ||||
328 | } # status | ||||
329 | |||||
330 | sub eof | ||||
331 | { | ||||
332 | my $self = shift; | ||||
333 | return $self->{_EOF}; | ||||
334 | } # status | ||||
335 | |||||
336 | # error_input | ||||
337 | # | ||||
338 | # object method returning the first invalid argument to the most recent | ||||
339 | # combine () or parse (). there are no side-effects. | ||||
340 | |||||
341 | sub error_input | ||||
342 | { | ||||
343 | my $self = shift; | ||||
344 | return $self->{_ERROR_INPUT}; | ||||
345 | } # error_input | ||||
346 | |||||
347 | # erro_diag | ||||
348 | # | ||||
349 | # If (and only if) an error occured, this function returns a code that | ||||
350 | # indicates the reason of failure | ||||
351 | |||||
352 | sub error_diag | ||||
353 | { | ||||
354 | my $self = shift; | ||||
355 | my @diag = (0 + $last_new_err, $last_new_err, 0); | ||||
356 | |||||
357 | if ($self && ref $self && # Not a class method or direct call | ||||
358 | $self->isa (__PACKAGE__) && exists $self->{_ERROR_DIAG}) { | ||||
359 | @diag = (0 + $self->{_ERROR_DIAG}, $self->{_ERROR_DIAG}); | ||||
360 | exists $self->{_ERROR_POS} and $diag[2] = 1 + $self->{_ERROR_POS}; | ||||
361 | } | ||||
362 | |||||
363 | my $context = wantarray; | ||||
364 | unless (defined $context) { # Void context, auto-diag | ||||
365 | if ($diag[0] && $diag[0] != 2012) { | ||||
366 | my $msg = "# CSV_XS ERROR: $diag[0] - $diag[1] \@ pos $diag[2]\n"; | ||||
367 | if ($self && ref $self) { # auto_diag | ||||
368 | |||||
369 | my $lvl = $self->{auto_diag}; | ||||
370 | if ($lvl < 2) { | ||||
371 | my @c = caller (2); | ||||
372 | if (@c >= 11 && $c[10] && ref $c[10] eq "HASH") { | ||||
373 | my $hints = $c[10]; | ||||
374 | (exists $hints->{autodie} && $hints->{autodie} or | ||||
375 | exists $hints->{"guard Fatal"} && | ||||
376 | !exists $hints->{"no Fatal"}) and | ||||
377 | $lvl++; | ||||
378 | # Future releases of autodie will probably set $^H{autodie} | ||||
379 | # to "autodie @args", like "autodie :all" or "autodie open" | ||||
380 | # so we can/should check for "open" or "new" | ||||
381 | } | ||||
382 | } | ||||
383 | $lvl > 1 ? die $msg : warn $msg; | ||||
384 | } | ||||
385 | else { # called without args in void context | ||||
386 | warn $msg; | ||||
387 | } | ||||
388 | } | ||||
389 | return; | ||||
390 | } | ||||
391 | return $context ? @diag : $diag[1]; | ||||
392 | } # error_diag | ||||
393 | |||||
394 | # string | ||||
395 | # | ||||
396 | # object method returning the result of the most recent combine () or the | ||||
397 | # input to the most recent parse (), whichever is more recent. there are | ||||
398 | # no side-effects. | ||||
399 | |||||
400 | sub string | ||||
401 | { | ||||
402 | my $self = shift; | ||||
403 | return ref $self->{_STRING} ? ${$self->{_STRING}} : undef; | ||||
404 | } # string | ||||
405 | |||||
406 | # fields | ||||
407 | # | ||||
408 | # object method returning the result of the most recent parse () or the | ||||
409 | # input to the most recent combine (), whichever is more recent. there | ||||
410 | # are no side-effects. | ||||
411 | |||||
412 | sub fields | ||||
413 | { | ||||
414 | my $self = shift; | ||||
415 | return ref $self->{_FIELDS} ? @{$self->{_FIELDS}} : undef; | ||||
416 | } # fields | ||||
417 | |||||
418 | # meta_info | ||||
419 | # | ||||
420 | # object method returning the result of the most recent parse () or the | ||||
421 | # input to the most recent combine (), whichever is more recent. there | ||||
422 | # are no side-effects. meta_info () returns (if available) some of the | ||||
423 | # field's properties | ||||
424 | |||||
425 | sub meta_info | ||||
426 | { | ||||
427 | my $self = shift; | ||||
428 | return ref $self->{_FFLAGS} ? @{$self->{_FFLAGS}} : undef; | ||||
429 | } # meta_info | ||||
430 | |||||
431 | sub is_quoted | ||||
432 | { | ||||
433 | my ($self, $idx, $val) = @_; | ||||
434 | ref $self->{_FFLAGS} && | ||||
435 | $idx >= 0 && $idx < @{$self->{_FFLAGS}} or return; | ||||
436 | $self->{_FFLAGS}[$idx] & 0x0001 ? 1 : 0; | ||||
437 | } # is_quoted | ||||
438 | |||||
439 | sub is_binary | ||||
440 | { | ||||
441 | my ($self, $idx, $val) = @_; | ||||
442 | ref $self->{_FFLAGS} && | ||||
443 | $idx >= 0 && $idx < @{$self->{_FFLAGS}} or return; | ||||
444 | $self->{_FFLAGS}[$idx] & 0x0002 ? 1 : 0; | ||||
445 | } # is_binary | ||||
446 | |||||
447 | # combine | ||||
448 | # | ||||
449 | # object method returning success or failure. the given arguments are | ||||
450 | # combined into a single comma-separated value. failure can be the | ||||
451 | # result of no arguments or an argument containing an invalid character. | ||||
452 | # side-effects include: | ||||
453 | # setting status () | ||||
454 | # setting fields () | ||||
455 | # setting string () | ||||
456 | # setting error_input () | ||||
457 | |||||
458 | sub combine | ||||
459 | { | ||||
460 | my $self = shift; | ||||
461 | my $str = ""; | ||||
462 | $self->{_FIELDS} = \@_; | ||||
463 | $self->{_FFLAGS} = undef; | ||||
464 | $self->{_STATUS} = (@_ > 0) && $self->Combine (\$str, \@_, 0); | ||||
465 | $self->{_STRING} = \$str; | ||||
466 | $self->{_STATUS}; | ||||
467 | } # combine | ||||
468 | |||||
469 | # parse | ||||
470 | # | ||||
471 | # object method returning success or failure. the given argument is | ||||
472 | # expected to be a valid comma-separated value. failure can be the | ||||
473 | # result of no arguments or an argument containing an invalid sequence | ||||
474 | # of characters. side-effects include: | ||||
475 | # setting status () | ||||
476 | # setting fields () | ||||
477 | # setting meta_info () | ||||
478 | # setting string () | ||||
479 | # setting error_input () | ||||
480 | |||||
481 | sub parse | ||||
482 | { | ||||
483 | my ($self, $str) = @_; | ||||
484 | |||||
485 | my $fields = []; | ||||
486 | my $fflags = []; | ||||
487 | $self->{_STRING} = \$str; | ||||
488 | if (defined $str && $self->Parse ($str, $fields, $fflags)) { | ||||
489 | $self->{_ERROR_INPUT} = undef; | ||||
490 | $self->{_FIELDS} = $fields; | ||||
491 | $self->{_FFLAGS} = $fflags; | ||||
492 | $self->{_STATUS} = 1; | ||||
493 | } | ||||
494 | else { | ||||
495 | $self->{_FIELDS} = undef; | ||||
496 | $self->{_FFLAGS} = undef; | ||||
497 | $self->{_STATUS} = 0; | ||||
498 | } | ||||
499 | $self->{_STATUS}; | ||||
500 | } # parse | ||||
501 | |||||
502 | sub column_names | ||||
503 | { | ||||
504 | my ($self, @keys) = @_; | ||||
505 | @keys or | ||||
506 | return defined $self->{_COLUMN_NAMES} ? @{$self->{_COLUMN_NAMES}} : undef; | ||||
507 | |||||
508 | @keys == 1 && ! defined $keys[0] and | ||||
509 | return $self->{_COLUMN_NAMES} = undef; | ||||
510 | |||||
511 | if (@keys == 1 && ref $keys[0] eq "ARRAY") { | ||||
512 | @keys = @{$keys[0]}; | ||||
513 | } | ||||
514 | elsif (join "", map { defined $_ ? ref $_ : "" } @keys) { | ||||
515 | croak ($self->SetDiag (3001)); | ||||
516 | } | ||||
517 | |||||
518 | $self->{_BOUND_COLUMNS} && @keys != @{$self->{_BOUND_COLUMNS}} and | ||||
519 | croak ($self->SetDiag (3003)); | ||||
520 | |||||
521 | $self->{_COLUMN_NAMES} = [ map { defined $_ ? $_ : "\cAUNDEF\cA" } @keys ]; | ||||
522 | @{$self->{_COLUMN_NAMES}}; | ||||
523 | } # column_names | ||||
524 | |||||
525 | sub bind_columns | ||||
526 | { | ||||
527 | my ($self, @refs) = @_; | ||||
528 | @refs or | ||||
529 | return defined $self->{_BOUND_COLUMNS} ? @{$self->{_BOUND_COLUMNS}} : undef; | ||||
530 | |||||
531 | @refs == 1 && ! defined $refs[0] and | ||||
532 | return $self->{_BOUND_COLUMNS} = undef; | ||||
533 | |||||
534 | $self->{_COLUMN_NAMES} && @refs != @{$self->{_COLUMN_NAMES}} and | ||||
535 | croak ($self->SetDiag (3003)); | ||||
536 | |||||
537 | join "", map { ref $_ eq "SCALAR" ? "" : "*" } @refs and | ||||
538 | croak ($self->SetDiag (3004)); | ||||
539 | |||||
540 | $self->_set_attr_N ("_is_bound", scalar @refs); | ||||
541 | $self->{_BOUND_COLUMNS} = [ @refs ]; | ||||
542 | @refs; | ||||
543 | } # bind_columns | ||||
544 | |||||
545 | sub getline_hr | ||||
546 | { | ||||
547 | my ($self, @args, %hr) = @_; | ||||
548 | $self->{_COLUMN_NAMES} or croak ($self->SetDiag (3002)); | ||||
549 | my $fr = $self->getline (@args) or return; | ||||
550 | @hr{@{$self->{_COLUMN_NAMES}}} = @$fr; | ||||
551 | \%hr; | ||||
552 | } # getline_hr | ||||
553 | |||||
554 | sub types | ||||
555 | { | ||||
556 | my $self = shift; | ||||
557 | if (@_) { | ||||
558 | if (my $types = shift) { | ||||
559 | $self->{_types} = join "", map { chr $_ } @{$types}; | ||||
560 | $self->{types} = $types; | ||||
561 | } | ||||
562 | else { | ||||
563 | delete $self->{types}; | ||||
564 | delete $self->{_types}; | ||||
565 | undef; | ||||
566 | } | ||||
567 | } | ||||
568 | else { | ||||
569 | $self->{types}; | ||||
570 | } | ||||
571 | } # types | ||||
572 | |||||
573 | 1 | 14µs | 1; | ||
574 | |||||
575 | __END__ | ||||
# spent 7µs within Text::CSV_XS::SetDiag which was called:
# once (7µs+0s) by Text::CSV::BEGIN@1 at line 85 | |||||
# spent 30µs within Text::CSV_XS::bootstrap which was called:
# once (30µs+0s) by DynaLoader::bootstrap at line 215 of DynaLoader.pm |