File Coverage

blib/lib/JSON/PP.pm
Criterion Covered Total %
statement 859 972 88.3
branch 474 630 75.2
condition 189 275 68.7
subroutine 131 164 79.8
pod 42 82 51.2
total 1695 2123 79.8


line stmt bran cond sub pod time code
1             package JSON::PP;
2              
3             # JSON-2.0
4              
5 67     67   7553072 use 5.008;
  67         252  
6 67     67   365 use strict;
  67         115  
  67         2105  
7              
8 67     67   320 use Exporter ();
  67         124  
  67         2601  
9 67     67   2675 BEGIN { our @ISA = ('Exporter') }
10              
11 67     67   43415 use overload ();
  67         122716  
  67         2393  
12 67     67   31136 use JSON::PP::Boolean;
  67         190  
  67         2161  
13              
14 67     67   411 use Carp ();
  67         160  
  67         1726  
15 67     67   303 use Scalar::Util qw(blessed reftype refaddr);
  67         106  
  67         8298  
16             #use Devel::Peek;
17              
18             our $VERSION = '4.18';
19              
20             our @EXPORT = qw(encode_json decode_json from_json to_json);
21              
22             # instead of hash-access, i tried index-access for speed.
23             # but this method is not faster than what i expected. so it will be changed.
24              
25 67     67   396 use constant P_ASCII => 0;
  67         134  
  67         6899  
26 67     67   410 use constant P_LATIN1 => 1;
  67         131  
  67         3652  
27 67     67   328 use constant P_UTF8 => 2;
  67         596  
  67         3735  
28 67     67   460 use constant P_INDENT => 3;
  67         321  
  67         3410  
29 67     67   312 use constant P_CANONICAL => 4;
  67         178  
  67         3077  
30 67     67   373 use constant P_SPACE_BEFORE => 5;
  67         138  
  67         3180  
31 67     67   335 use constant P_SPACE_AFTER => 6;
  67         150  
  67         3303  
32 67     67   396 use constant P_ALLOW_NONREF => 7;
  67         142  
  67         3161  
33 67     67   292 use constant P_SHRINK => 8;
  67         114  
  67         3102  
34 67     67   320 use constant P_ALLOW_BLESSED => 9;
  67         120  
  67         3074  
35 67     67   326 use constant P_CONVERT_BLESSED => 10;
  67         185  
  67         3224  
36 67     67   299 use constant P_RELAXED => 11;
  67         118  
  67         3186  
37              
38 67     67   360 use constant P_LOOSE => 12;
  67         155  
  67         2783  
39 67     67   347 use constant P_ALLOW_BIGNUM => 13;
  67         152  
  67         3118  
40 67     67   303 use constant P_ALLOW_BAREKEY => 14;
  67         134  
  67         2972  
41 67     67   408 use constant P_ALLOW_SINGLEQUOTE => 15;
  67         164  
  67         6100  
42 67     67   315 use constant P_ESCAPE_SLASH => 16;
  67         112  
  67         3675  
43 67     67   537 use constant P_AS_NONBLESSED => 17;
  67         271  
  67         3874  
44              
45 67     67   420 use constant P_ALLOW_UNKNOWN => 18;
  67         126  
  67         3182  
46 67     67   348 use constant P_ALLOW_TAGS => 19;
  67         127  
  67         3968  
47              
48 67   50 67   367 use constant USE_B => $ENV{PERL_JSON_PP_USE_B} || 0;
  67         136  
  67         4527  
49 67     67   363 use constant CORE_BOOL => defined &builtin::is_bool;
  67         116  
  67         9202  
50              
51             my $invalid_char_re;
52              
53             BEGIN {
54 67     67   247 $invalid_char_re = "[";
55 67         212 for my $i (0 .. 0x01F, 0x22, 0x5c) { # '/' is ok
56 2278         3674 $invalid_char_re .= quotemeta chr utf8::unicode_to_native($i);
57             }
58              
59 67         5402 $invalid_char_re = qr/$invalid_char_re]/;
60             }
61              
62             BEGIN {
63 67     67   11351 if (USE_B) {
64             require B;
65             }
66             }
67              
68             BEGIN {
69 67     67   502 my @xs_compati_bit_properties = qw(
70             latin1 ascii utf8 indent canonical space_before space_after allow_nonref shrink
71             allow_blessed convert_blessed relaxed allow_unknown
72             allow_tags
73             );
74 67         231 my @pp_bit_properties = qw(
75             allow_singlequote allow_bignum loose
76             allow_barekey escape_slash as_nonblessed
77             );
78              
79 67         182 for my $name (@xs_compati_bit_properties, @pp_bit_properties) {
80 1340         4337 my $property_id = 'P_' . uc($name);
81              
82 1340 50   2 1 213085 eval qq/
  2 50   1 1 707  
  2 50   2 1 7  
  2 50   24653 1 8  
  0 50   1 1 0  
  2 50   1 1 9  
  1 100   3 1 6  
  1 100   0 0 4  
  1 50   12292 1 3  
  0 50   10 1 0  
  1 50   5 1 3  
  2 50   1 1 258  
  2 100   0 0 20  
  2 100   0 0 5  
  0 0   0 0 0  
  2 0   0 0 7  
  24653 100   0 0 123785  
  24653 50   0 0 79021  
  9286 100   0 0 29999  
  15367 50   0 0 47640  
  24653 50   0 0 555686  
  1 50   0 0 664  
  1 50   0 0 4  
  1 50   0 0 4  
  0 0   0 0 0  
  1 0   0 0 3  
  1 0   0 0 2  
  1 0   0 0 3  
  1 0   0 0 4  
  0 0   0 0 0  
  1 0   0 0 115  
  3 0   309 0 4541  
  3 0   6 1 9  
  2 0   2 1 7  
  1 0   0 1 3  
  3 0   14 1 7  
  0 0   21504 1 0  
  0 0   7 1 0  
  0 0   6 1 0  
  0 0   18511 1 0  
  0 0       0  
  12292 0       40021  
  12292 0       31807  
  12292 100       32991  
  0 50       0  
  12292 100       112088  
  10 50       257  
  10 50       25  
  10 0       28  
  0 0       0  
  10 50       177  
  5 50       28  
  5 50       16  
  5 50       17  
  0 50       0  
  5 100       54  
  1 50       7  
  1 100       3  
  1 100       5  
  0 50       0  
  1         4  
  0         0  
  0         0  
  0         0  
  0         0  
  0         0  
  0         0  
  0         0  
  0         0  
  0         0  
  0         0  
  0         0  
  0         0  
  0         0  
  0         0  
  0         0  
  0         0  
  0         0  
  0         0  
  0         0  
  309         1486  
  6         675  
  6         11  
  4         8  
  2         4  
  6         78  
  2         15  
  2         8  
  2         8  
  0         0  
  2         54  
  0         0  
  0         0  
  0         0  
  0         0  
  0         0  
  14         42  
  14         25  
  14         34  
  0         0  
  14         22  
  21504         70171  
  21504         53134  
  21504         74869  
  0         0  
  21504         93421  
  7         93  
  7         16  
  4         8  
  3         5  
  7         12  
  6         14  
  6         10  
  4         9  
  2         4  
  6         69  
  18511         70757  
  18511         51962  
  18511         47547  
  0         0  
  18511         360612  
83             sub $name {
84             my \$enable = defined \$_[1] ? \$_[1] : 1;
85              
86             if (\$enable) {
87             \$_[0]->{PROPS}->[$property_id] = 1;
88             }
89             else {
90             \$_[0]->{PROPS}->[$property_id] = 0;
91             }
92              
93             \$_[0];
94             }
95              
96             sub get_$name {
97             \$_[0]->{PROPS}->[$property_id] ? 1 : '';
98             }
99             /;
100             }
101              
102             }
103              
104              
105              
106             # Functions
107              
108             my $JSON; # cache
109              
110             sub encode_json ($) { # encode
111 191   33 191 1 14484 ($JSON ||= __PACKAGE__->new->utf8)->encode(@_);
112             }
113              
114              
115             sub decode_json ($) { # decode
116 6273   66 6273 1 8205100 ($JSON ||= __PACKAGE__->new->utf8)->decode(@_);
117             }
118              
119             # Obsoleted
120              
121             sub to_json($) {
122 0     0 0 0 Carp::croak ("JSON::PP::to_json has been renamed to encode_json.");
123             }
124              
125              
126             sub from_json($) {
127 0     0 0 0 Carp::croak ("JSON::PP::from_json has been renamed to decode_json.");
128             }
129              
130              
131             # Methods
132              
133             sub new {
134 43220     43220 1 5352343 my $class = shift;
135 43220         197521 my $self = {
136             max_depth => 512,
137             max_size => 0,
138             indent_length => 3,
139             };
140              
141 43220         145947 $self->{PROPS}[P_ALLOW_NONREF] = 1;
142              
143 43220         1629681 bless $self, $class;
144             }
145              
146              
147             sub encode {
148 25148     25148 1 199322 return $_[0]->PP_encode_json($_[1]);
149             }
150              
151              
152             sub decode {
153 25019     25019 1 167695 return $_[0]->PP_decode_json($_[1], 0x00000000);
154             }
155              
156              
157             sub decode_prefix {
158 8     8 1 705 return $_[0]->PP_decode_json($_[1], 0x00000001);
159             }
160              
161              
162             # accessor
163              
164              
165             # pretty printing
166              
167             sub pretty {
168 5     5 1 2863 my ($self, $v) = @_;
169 5 50       32 my $enable = defined $v ? $v : 1;
170              
171 5 100       10 if ($enable) { # indent_length(3) for JSON::XS compatibility
172 3         77 $self->indent(1)->space_before(1)->space_after(1);
173             }
174             else {
175 2         42 $self->indent(0)->space_before(0)->space_after(0);
176             }
177              
178 5         12 $self;
179             }
180              
181             # etc
182              
183             sub max_depth {
184 5 50   5 1 24 my $max = defined $_[1] ? $_[1] : 0x80000000;
185 5         17 $_[0]->{max_depth} = $max;
186 5         46 $_[0];
187             }
188              
189              
190 383     383 0 849 sub get_max_depth { $_[0]->{max_depth}; }
191              
192              
193             sub max_size {
194 3 50   3 1 13 my $max = defined $_[1] ? $_[1] : 0;
195 3         10 $_[0]->{max_size} = $max;
196 3         11 $_[0];
197             }
198              
199              
200 383     383 0 808 sub get_max_size { $_[0]->{max_size}; }
201              
202             sub boolean_values {
203 6     6 1 2640 my $self = shift;
204 6 100       17 if (@_) {
205 4         62 my ($false, $true) = @_;
206 4         11 $self->{false} = $false;
207 4         11 $self->{true} = $true;
208 4         91 if (CORE_BOOL) {
209 67     67   144741 BEGIN { CORE_BOOL and warnings->unimport(qw(experimental::builtin)) }
210 4 100 66     31 if (builtin::is_bool($true) && builtin::is_bool($false) && $true && !$false) {
      100        
      66        
211 1         3 $self->{core_bools} = !!1;
212             }
213             else {
214 3         7 delete $self->{core_bools};
215             }
216             }
217             } else {
218 2         4 delete $self->{false};
219 2         4 delete $self->{true};
220 2         4 delete $self->{core_bools};
221             }
222 6         43 return $self;
223             }
224              
225             sub core_bools {
226 1     1 1 3 my $self = shift;
227 1 50       4 my $core_bools = defined $_[0] ? $_[0] : 1;
228 1 50       4 if ($core_bools) {
229 1         2 $self->{true} = !!1;
230 1         3 $self->{false} = !!0;
231 1         4 $self->{core_bools} = !!1;
232             }
233             else {
234 0         0 $self->{true} = $JSON::PP::true;
235 0         0 $self->{false} = $JSON::PP::false;
236 0         0 $self->{core_bools} = !!0;
237             }
238 1         2 return $self;
239             }
240              
241             sub get_core_bools {
242 4     4 0 18 my $self = shift;
243 4         30 return !!$self->{core_bools};
244             }
245              
246             sub unblessed_bool {
247 0     0 0 0 my $self = shift;
248 0         0 return $self->core_bools(@_);
249             }
250              
251             sub get_unblessed_bool {
252 0     0 0 0 my $self = shift;
253 0         0 return $self->get_core_bools(@_);
254             }
255              
256             sub get_boolean_values {
257 5     5 0 3601 my $self = shift;
258 5 50 66     25 if (exists $self->{true} and exists $self->{false}) {
259 3         10 return @$self{qw/false true/};
260             }
261 2         8 return;
262             }
263              
264             sub filter_json_object {
265 3 100 66 3 1 16 if (defined $_[1] and ref $_[1] eq 'CODE') {
266 2         6 $_[0]->{cb_object} = $_[1];
267             } else {
268 1         4 delete $_[0]->{cb_object};
269             }
270 3 50 66     10 $_[0]->{F_HOOK} = ($_[0]->{cb_object} or $_[0]->{cb_sk_object}) ? 1 : 0;
271 3         5 $_[0];
272             }
273              
274             sub filter_json_single_key_object {
275 4 50 33 4 1 18 if (@_ == 1 or @_ > 3) {
276 0         0 Carp::croak("Usage: JSON::PP::filter_json_single_key_object(self, key, callback = undef)");
277             }
278 4 100 66     25 if (defined $_[2] and ref $_[2] eq 'CODE') {
279 3         7 $_[0]->{cb_sk_object}->{$_[1]} = $_[2];
280             } else {
281 1         7 delete $_[0]->{cb_sk_object}->{$_[1]};
282 1 50       2 delete $_[0]->{cb_sk_object} unless %{$_[0]->{cb_sk_object} || {}};
  1 50       6  
283             }
284 4 50 33     11 $_[0]->{F_HOOK} = ($_[0]->{cb_object} or $_[0]->{cb_sk_object}) ? 1 : 0;
285 4         6 $_[0];
286             }
287              
288             sub indent_length {
289 0 0 0 0 1 0 if (!defined $_[1] or $_[1] > 15 or $_[1] < 0) {
      0        
290 0         0 Carp::carp "The acceptable range of indent_length() is 0 to 15.";
291             }
292             else {
293 0         0 $_[0]->{indent_length} = $_[1];
294             }
295 0         0 $_[0];
296             }
297              
298             sub get_indent_length {
299 0     0 0 0 $_[0]->{indent_length};
300             }
301              
302             sub sort_by {
303 3 50   3 1 2129 $_[0]->{sort_by} = defined $_[1] ? $_[1] : 1;
304 3         13 $_[0];
305             }
306              
307             sub allow_bigint {
308 0     0 0 0 Carp::carp("allow_bigint() is obsoleted. use allow_bignum() instead.");
309 0         0 $_[0]->allow_bignum;
310             }
311              
312             ###############################
313              
314             ###
315             ### Perl => JSON
316             ###
317              
318              
319             { # Convert
320              
321             sub PP_encode_json {
322 25148     25148 0 50513 my $self = shift;
323 25148         44489 my $obj = shift;
324              
325 25148         66380 $self->{indent_count} = 0;
326 25148         76880 $self->{depth} = 0;
327              
328 25148         48106 my $props = $self->{PROPS};
329              
330 25148 100   589   91974 $self->{keysort} = $self->{PROPS}[P_CANONICAL] ? sub { $a cmp $b } : undef;
  589         1343  
331              
332 25148 100       99470 if ($self->{sort_by}) {
333             $self->{keysort} = ref($self->{sort_by}) eq 'CODE' ? $self->{sort_by}
334             : $self->{sort_by} =~ /\D+/ ? $self->{sort_by}
335 3 100   21   42 : sub { $a cmp $b };
  21 100       41  
336             }
337              
338 25148 50 66     79496 encode_error("hash- or arrayref expected (not a simple scalar, use allow_nonref to allow this)")
339             if(!ref $obj and !$props->[ P_ALLOW_NONREF ]);
340              
341 25148         86562 my $str = $self->object_to_json($obj);
342              
343 25130 100       77708 $str .= "\n" if ( $self->{PROPS}[P_INDENT] ); # JSON::XS 2.26 compatible
344              
345 25130         114327 return $str;
346             }
347              
348              
349             sub object_to_json {
350 25504     25504 0 63670 my ($self, $obj) = @_;
351 25504         63521 my $type = ref($obj);
352              
353 25504 100       94175 if($type eq 'HASH'){
    100          
    100          
354 346         748 return $self->hash_to_json($obj);
355             }
356             elsif($type eq 'ARRAY'){
357 25017         96483 return $self->array_to_json($obj);
358             }
359             elsif ($type) { # blessed object?
360 57 100       120 if (blessed($obj)) {
361              
362 37 100       303 return $self->value_to_json($obj) if ( $obj->isa('JSON::PP::Boolean') );
363              
364 17 100 100     92 if ( $self->{PROPS}[P_ALLOW_TAGS] and $obj->can('FREEZE') ) {
365 1   33     5 my $obj_class = ref $obj || $obj;
366 1         3 $obj = bless $obj, $obj_class;
367 1         6 my @results = $obj->FREEZE('JSON');
368 1 50 33     4757 if ( @results and ref $results[0] ) {
369 0 0       0 if ( refaddr( $obj ) eq refaddr( $results[0] ) ) {
370 0         0 encode_error( sprintf(
371             "%s::FREEZE method returned same object as was passed instead of a new one",
372             ref $obj
373             ) );
374             }
375             }
376 1         11 return '("'.$obj_class.'")['.join(',', @results).']';
377             }
378              
379 16 100 100     113 if ( $self->{PROPS}[P_CONVERT_BLESSED] and $obj->can('TO_JSON') ) {
380 8         30 my $result = $obj->TO_JSON();
381 8 100 66     2066 if ( defined $result and ref( $result ) ) {
382 2 100       11 if ( refaddr( $obj ) eq refaddr( $result ) ) {
383 1         7 encode_error( sprintf(
384             "%s::TO_JSON method returned same object as was passed instead of a new one",
385             ref $obj
386             ) );
387             }
388             }
389              
390 7         53 return $self->object_to_json( $result );
391             }
392              
393 8 100 66     26 return "$obj" if ( $self->{PROPS}[P_ALLOW_BIGNUM] and _is_bignum($obj) );
394              
395 5 100       8 if ($self->{PROPS}[P_ALLOW_BLESSED]) {
396 3 50       6 return $self->blessed_to_json($obj) if ($self->{PROPS}[P_AS_NONBLESSED]); # will be removed.
397 3         6 return 'null';
398             }
399 2         11 encode_error( sprintf("encountered object '%s', but neither allow_blessed, convert_blessed nor allow_tags settings are enabled (or TO_JSON/FREEZE method missing)", $obj)
400             );
401             }
402             else {
403 20         63 return $self->value_to_json($obj);
404             }
405             }
406             else{
407 84         242 return $self->value_to_json($obj);
408             }
409             }
410              
411              
412             sub hash_to_json {
413 346     346 0 526 my ($self, $obj) = @_;
414 346         413 my @res;
415              
416             encode_error("json text or perl structure exceeds maximum nesting level (max_depth set too low?)")
417 346 100       884 if (++$self->{depth} > $self->{max_depth});
418              
419 345 100       854 my ($pre, $post) = $self->{PROPS}[P_INDENT] ? $self->_up_indent() : ('', '');
420 345 100       885 my $del = ($self->{PROPS}[P_SPACE_BEFORE] ? ' ' : '') . ':' . ($self->{PROPS}[P_SPACE_AFTER] ? ' ' : '');
    100          
421              
422 345         779 for my $k ( $self->__sort( $obj ) ) {
423             push @res, $self->string_to_json( $k )
424             . $del
425 744 100       1545 . ( ref $obj->{$k} ? $self->object_to_json( $obj->{$k} ) : $self->value_to_json( $obj->{$k} ) );
426             }
427              
428 343         698 --$self->{depth};
429 343 100       649 $self->_down_indent() if ($self->{PROPS}[P_INDENT]);
430              
431 343 100       818 return '{}' unless @res;
432 333         1758 return '{' . $pre . join( ",$pre", @res ) . $post . '}';
433             }
434              
435              
436             sub array_to_json {
437 25017     25017 0 59430 my ($self, $obj) = @_;
438 25017         43571 my @res;
439              
440             encode_error("json text or perl structure exceeds maximum nesting level (max_depth set too low?)")
441 25017 100       96928 if (++$self->{depth} > $self->{max_depth});
442              
443 25016 100       94709 my ($pre, $post) = $self->{PROPS}[P_INDENT] ? $self->_up_indent() : ('', '');
444              
445 25016         66247 for my $v (@$obj){
446 25800 100       115978 push @res, ref($v) ? $self->object_to_json($v) : $self->value_to_json($v);
447             }
448              
449 25002         58008 --$self->{depth};
450 25002 100       65854 $self->_down_indent() if ($self->{PROPS}[P_INDENT]);
451              
452 25002 100       68073 return '[]' unless @res;
453 24989 50 66     146048 my $space = $pre eq '' && $self->{PROPS}[P_SPACE_AFTER] ? ' ' : '';
454 24989         230947 return '[' . $pre . join( ",$space$pre", @res ) . $post . ']';
455             }
456              
457             sub _looks_like_number {
458 26233     26233   47592 my $value = shift;
459 26233         42068 if (USE_B) {
460             my $b_obj = B::svref_2object(\$value);
461             my $flags = $b_obj->FLAGS;
462             return 1 if $flags & ( B::SVp_IOK() | B::SVp_NOK() ) and !( $flags & B::SVp_POK() );
463             return;
464             } else {
465 67     67   663 no warnings 'numeric';
  67         418  
  67         15330  
466             # if the utf8 flag is on, it almost certainly started as a string
467 26233 100       129361 return if utf8::is_utf8($value);
468             # detect numbers
469             # string & "" -> ""
470             # number & "" -> 0 (with warning)
471             # nan and inf can detect as numbers, so check with * 0
472 13746 100       75290 return unless length((my $dummy = "") & $value);
473 817 100       1909 return unless 0 + $value eq $value;
474 816 50       2487 return 1 if $value * 0 == 0;
475 0         0 return -1; # inf/nan
476             }
477             }
478              
479             sub value_to_json {
480 26319     26319 0 61222 my ($self, $value) = @_;
481              
482 26319 100       71594 return 'null' if(!defined $value);
483              
484 26275         56879 my $type = ref($value);
485              
486 26275 100 66     63739 if (!$type) {
    100          
487 67     67   91528 BEGIN { CORE_BOOL and warnings->unimport('experimental::builtin') }
488 26235 100       92598 if (CORE_BOOL && builtin::is_bool($value)) {
    100          
489 2 100       10 return $value ? 'true' : 'false';
490             }
491             elsif (_looks_like_number($value)) {
492 816         2420 return $value;
493             }
494 25417         96652 return $self->string_to_json($value);
495             }
496             elsif( blessed($value) and $value->isa('JSON::PP::Boolean') ){
497 20 100       153 return $$value == 1 ? 'true' : 'false';
498             }
499             else {
500 20 50       72 if ((overload::StrVal($value) =~ /=(\w+)/)[0]) {
501 0         0 return $self->value_to_json("$value");
502             }
503              
504 20 100 100     190 if ($type eq 'SCALAR' and defined $$value) {
505             return $$value eq '1' ? 'true'
506             : $$value eq '0' ? 'false'
507 7 100       67 : $self->{PROPS}->[ P_ALLOW_UNKNOWN ] ? 'null'
    100          
    100          
508             : encode_error("cannot encode reference to scalar");
509             }
510              
511 13 100       29 if ( $self->{PROPS}->[ P_ALLOW_UNKNOWN ] ) {
512 4         12 return 'null';
513             }
514             else {
515 9 100 100     40 if ( $type eq 'SCALAR' or $type eq 'REF' ) {
516 6         11 encode_error("cannot encode reference to scalar");
517             }
518             else {
519 3         23 encode_error("encountered $value, but JSON can only represent references to arrays or hashes");
520             }
521             }
522              
523             }
524             }
525              
526              
527             my %esc = (
528             "\n" => '\n',
529             "\r" => '\r',
530             "\t" => '\t',
531             "\f" => '\f',
532             "\b" => '\b',
533             "\"" => '\"',
534             "\\" => '\\\\',
535             "\'" => '\\\'',
536             );
537              
538              
539             sub string_to_json {
540 26161     26161 0 73636 my ($self, $arg) = @_;
541              
542 26161         579091 $arg =~ s/(["\\\n\r\t\f\b])/$esc{$1}/g;
543 26161 100       88575 $arg =~ s/\//\\\//g if ($self->{PROPS}[P_ESCAPE_SLASH]);
544              
545             # On ASCII platforms, matches [\x00-\x08\x0b\x0e-\x1f]
546 26161         163875 $arg =~ s/([^\n\t\c?[:^cntrl:][:^ascii:]])/'\\u00' . unpack('H2', $1)/eg;
  578676         1697915  
547              
548 26161 100       93922 if ($self->{PROPS}[P_ASCII]) {
549 12297         43880 $arg = _encode_ascii($arg);
550             }
551              
552 26161 100       287436 if ($self->{PROPS}[P_LATIN1]) {
553 2         8 $arg = _encode_latin1($arg);
554             }
555              
556 26161 100       78061 if ($self->{PROPS}[P_UTF8]) {
557 12551         53009 utf8::encode($arg);
558             }
559              
560 26161         335540 return '"' . $arg . '"';
561             }
562              
563              
564             sub blessed_to_json {
565 0   0 0 0 0 my $reftype = reftype($_[1]) || '';
566 0 0       0 if ($reftype eq 'HASH') {
    0          
567 0         0 return $_[0]->hash_to_json($_[1]);
568             }
569             elsif ($reftype eq 'ARRAY') {
570 0         0 return $_[0]->array_to_json($_[1]);
571             }
572             else {
573 0         0 return 'null';
574             }
575             }
576              
577              
578             sub encode_error {
579 18     18 0 32 my $error = shift;
580 18         3596 Carp::croak "$error";
581             }
582              
583              
584             sub __sort {
585 345     345   458 my $self = shift;
586 345         546 my $keysort = $self->{keysort};
587 345 100       598 defined $keysort ? (sort $keysort (keys %{$_[0]})) : keys %{$_[0]};
  222         1281  
  123         594  
588             }
589              
590              
591             sub _up_indent {
592 9     9   23 my $self = shift;
593 9         17 my $space = ' ' x $self->{indent_length};
594              
595 9         16 my ($pre,$post) = ('','');
596              
597 9         14 $post = "\n" . $space x $self->{indent_count};
598              
599 9         10 $self->{indent_count}++;
600              
601 9         13 $pre = "\n" . $space x $self->{indent_count};
602              
603 9         22 return ($pre,$post);
604             }
605              
606              
607 9     9   11 sub _down_indent { $_[0]->{indent_count}--; }
608              
609             } # Convert
610              
611              
612             sub _encode_ascii {
613             join('',
614             map {
615 12297 100   12297   409541 chr($_) =~ /[[:ascii:]]/ ?
  6259537 100       17673637  
616             chr($_) :
617             $_ <= 65535 ?
618             sprintf('\u%04x', $_) : sprintf('\u%x\u%x', _encode_surrogates($_));
619             } unpack('U*', $_[0])
620             );
621             }
622              
623              
624             sub _encode_latin1 {
625             join('',
626             map {
627 2 50   2   11 $_ <= 255 ?
  22 100       78  
628             chr($_) :
629             $_ <= 65535 ?
630             sprintf('\u%04x', $_) : sprintf('\u%x\u%x', _encode_surrogates($_));
631             } unpack('U*', $_[0])
632             );
633             }
634              
635              
636             sub _encode_surrogates { # from perlunicode
637 1127975     1127975   1492078 my $uni = $_[0] - 0x10000;
638 1127975         3257529 return ($uni / 0x400 + 0xD800, $uni % 0x400 + 0xDC00);
639             }
640              
641              
642             sub _is_bignum {
643 3 100   3   26 $_[0]->isa('Math::BigInt') or $_[0]->isa('Math::BigFloat');
644             }
645              
646              
647              
648             #
649             # JSON => Perl
650             #
651              
652             my $max_intsize;
653              
654             BEGIN {
655 67     67   3287 my $checkint = 1111;
656 67         434 for my $d (5..64) {
657 1139         1710 $checkint .= 1;
658 1139         47964 my $int = eval qq| $checkint |;
659 1139 100       7431 if ($int =~ /[eE]/) {
660 67         2105 $max_intsize = $d - 1;
661 67         41440 last;
662             }
663             }
664             }
665              
666             { # PARSE
667              
668             my %escapes = ( # by Jeremy Muhlich
669             b => "\b",
670             t => "\t",
671             n => "\n",
672             f => "\f",
673             r => "\r",
674             '\\' => '\\',
675             '"' => '"',
676             '/' => '/',
677             );
678              
679             sub _detect_utf_encoding {
680 12477     12477   26856 my $text = shift;
681 12477         54881 my @octets = unpack('C4', $text);
682 12477 100       40999 return 'unknown' unless defined $octets[3];
683 12457 0 100     77759 return ( $octets[0] and $octets[1]) ? 'UTF-8'
    50 66        
    50 33        
    100          
    100          
684             : (!$octets[0] and $octets[1]) ? 'UTF-16BE'
685             : (!$octets[0] and !$octets[1]) ? 'UTF-32BE'
686             : ( $octets[2] ) ? 'UTF-16LE'
687             : (!$octets[2] ) ? 'UTF-32LE'
688             : 'unknown';
689             }
690              
691             sub PP_decode_json {
692 25336     25336 0 84605 my ($self, $text, $want_offset) = @_;
693              
694 25336         135107 @$self{qw/at ch depth/} = (0, '', 0);
695              
696 25336 100 100     168897 if ( !defined $text or ref $text ) {
697 4         19 $self->_decode_error("malformed JSON string, neither array, object, number, string or atom");
698             }
699              
700 25332         57952 my $props = $self->{PROPS};
701              
702 25332 100       80700 if ( $self->{PROPS}[P_UTF8] ) {
703 12477         39107 my $encoding = _detect_utf_encoding($text);
704 12477 100 100     57606 if ($encoding ne 'UTF-8' and $encoding ne 'unknown') {
705 3         26 require Encode;
706 3         23 Encode::from_to($text, $encoding, 'utf-8');
707             } else {
708 12474 100       59134 utf8::downgrade( $text, 1 ) or Carp::croak("Wide character in subroutine entry");
709             }
710             }
711             else {
712 12855         60597 utf8::encode( $text );
713             }
714              
715 25331         73171 $self->{len} = length $text;
716 25331         74546 $self->{text} = $text;
717              
718 25331 100       85021 if ($self->{max_size} > 1) {
719 67     67   30005 use bytes;
  67         24055  
  67         2004  
720 2         5 my $bytes = length $text;
721             $self->_decode_error(
722             sprintf("attempted decode of JSON text of %s bytes size, but max_size is set to %s"
723             , $bytes, $self->{max_size}), 1
724 2 100       23 ) if ($bytes > $self->{max_size});
725             }
726              
727 25330         88820 $self->_white(); # remove head white space
728              
729 25330 100       67156 $self->_decode_error("malformed JSON string, neither array, object, number, string or atom") unless defined $self->{ch}; # Is there a first character for JSON structure?
730              
731 25328         71571 my $result = $self->_value();
732              
733 25251 100 100     127801 if ( !$props->[ P_ALLOW_NONREF ] and !ref $result ) {
734 5         25 $self->_decode_error(
735             'JSON text must be an object or array (but found number, string, true, false or null,'
736             . ' use allow_nonref to allow this)', 1);
737             }
738              
739 25246 50       78954 Carp::croak('something wrong.') if $self->{len} < $self->{at}; # we won't arrive here.
740              
741 25246 100       77736 my $consumed = defined $self->{ch} ? $self->{at} - 1 : $self->{at}; # consumed JSON text length
742              
743 25246         67283 $self->_white(); # remove tail white space
744              
745 25246 100       57392 return ( $result, $consumed ) if $want_offset; # all right if decode_prefix
746              
747 24942 100       68319 $self->_decode_error("garbage after JSON object") if defined $self->{ch};
748              
749 24930         316734 $result;
750             }
751              
752              
753             sub _next_chr {
754 36800656     36800656   47669822 my $self = shift;
755 36800656 100       68194586 return $self->{ch} = undef if($self->{at} >= $self->{len});
756 36775519         84616609 $self->{ch} = substr($self->{text}, $self->{at}++, 1);
757             }
758              
759              
760             sub _value {
761 56178     56178   86172 my $self = shift;
762 56178         123834 $self->_white();
763 56178         95430 my $ch = $self->{ch};
764 56178 50       118772 return if(!defined $ch);
765 56178 100       129088 return $self->_object() if($ch eq '{');
766 53917 100       163286 return $self->_array() if($ch eq '[');
767 27601 100       63885 return $self->_tag() if($ch eq '(');
768 27600 100 66     113144 return $self->_string() if($ch eq '"' or ($self->{PROPS}[P_ALLOW_SINGLEQUOTE] and $ch eq "'"));
      100        
769 1039 100 100     4812 return $self->_number() if($ch =~ /[0-9]/ or $ch eq '-');
770 93         298 return $self->_word();
771             }
772              
773             sub _string {
774 30301     30301   54829 my $self = shift;
775 30301         57297 my $utf16;
776             my $is_utf8;
777              
778 30301         47563 my $utf8_len = 0;
779              
780 30301         50620 my $s = ''; # basically UTF8 flag on
781              
782 30301         55202 my $ch = $self->{ch};
783 30301 100 66     87428 if($ch eq '"' or ($self->{PROPS}[P_ALLOW_SINGLEQUOTE] and $ch eq "'")){
      100        
784 30296         48873 my $boundChar = $ch;
785              
786 30296         61607 OUTER: while( defined($ch = $self->_next_chr()) ){
787              
788 10760450 100       22130511 if($ch eq $boundChar){
    100          
789 30280         75822 $self->_next_chr();
790              
791 30280 100       71612 if ($utf16) {
792 1         4 $self->_decode_error("missing low surrogate character in surrogate pair");
793             }
794              
795 30279 100       203700 utf8::decode($s) if($is_utf8);
796              
797 30279         195019 return $s;
798             }
799             elsif($ch eq '\\'){
800 5300299         8827403 $ch = $self->_next_chr();
801 5300299 100       11570972 if(exists $escapes{$ch}){
    100          
802 152492         340981 $s .= $escapes{$ch};
803             }
804             elsif($ch eq 'u'){ # UNICODE handling
805 5147803         6933668 my $u = '';
806              
807 5147803         9081807 for(1..4){
808 20591212         31597893 $ch = $self->_next_chr();
809 20591212 50       50522940 last OUTER if($ch !~ /[0-9a-fA-F]/);
810 20591212         31088531 $u .= $ch;
811             }
812              
813             # U+D800 - U+DBFF
814 5147803 100       13579609 if ($u =~ /^[dD][89abAB][0-9a-fA-F]{2}/) { # UTF-16 high surrogate?
    100          
815 1127978         2311489 $utf16 = $u;
816             }
817             # U+DC00 - U+DFFF
818             elsif ($u =~ /^[dD][c-fC-F][0-9a-fA-F]{2}/) { # UTF-16 low surrogate?
819 1127977 100       2190322 unless (defined $utf16) {
820 1         4 $self->_decode_error("missing high surrogate character in surrogate pair");
821             }
822 1127976         1511694 $is_utf8 = 1;
823 1127976   50     2048715 $s .= _decode_surrogates($utf16, $u) || next;
824 1127976         2569762 $utf16 = undef;
825             }
826             else {
827 2891848 100       5237469 if (defined $utf16) {
828 1         6 $self->_decode_error("surrogate pair expected");
829             }
830              
831 2891847         4319599 my $hex = hex( $u );
832 2891847 50       5989542 if ( chr $u =~ /[[:^ascii:]]/ ) {
833 2891847         3764650 $is_utf8 = 1;
834 2891847   50     4974501 $s .= _decode_unicode($u) || next;
835             }
836             else {
837 0         0 $s .= chr $hex;
838             }
839             }
840              
841             }
842             else{
843 4 50       10 unless ($self->{PROPS}[P_LOOSE]) {
844 4         11 $self->{at} -= 2;
845 4         13 $self->_decode_error('illegal backslash escape sequence in string');
846             }
847 0         0 $s .= $ch;
848             }
849             }
850             else{
851              
852 5429871 100       12401100 if ( $ch =~ /[[:^ascii:]]/ ) {
853 3441000 100       6498529 unless( $ch = $self->_is_valid_utf8($ch, \$utf8_len) ) {
854 5         28 $self->{at} -= 1;
855 5         19 $self->_decode_error("malformed UTF-8 character in JSON string");
856             }
857             else {
858 3440995         5503009 $self->{at} += $utf8_len - 1;
859             }
860              
861 3440995         4840653 $is_utf8 = 1;
862             }
863              
864 5429866 50       10211591 if (!$self->{PROPS}[P_LOOSE]) {
865 5429866 100       18122145 if ($ch =~ $invalid_char_re) { # '/' ok
866 4 50 33     16 if (!$self->{PROPS}[P_RELAXED] or $ch ne "\t") {
867 4         8 $self->{at}--;
868 4         25 $self->_decode_error(sprintf "invalid character 0x%X"
869             . " encountered while parsing JSON string",
870             ord $ch);
871             }
872             }
873             }
874              
875 5429862         10675786 $s .= $ch;
876             }
877             }
878             }
879              
880 6         31 $self->_decode_error("unexpected end of string while parsing JSON string");
881             }
882              
883              
884             sub _white {
885 171150     171150   243693 my $self = shift;
886 171150         288847 my $ch = $self->{ch};
887 171150         355896 while( defined $ch ){
888 200701 100 100     937481 if($ch eq '' or $ch =~ /\A[ \t\r\n]\z/){
    50 66        
889 54670         112860 $ch = $self->_next_chr();
890             }
891             elsif($self->{PROPS}[P_RELAXED] and $ch eq '/'){
892 0         0 $ch = $self->_next_chr();
893 0 0 0     0 if(defined $ch and $ch eq '/'){
    0 0        
894 0   0     0 1 while(defined($ch = $self->_next_chr()) and $ch ne "\n" and $ch ne "\r");
      0        
895             }
896             elsif(defined $ch and $ch eq '*'){
897 0         0 $ch = $self->_next_chr();
898 0         0 while(1){
899 0 0       0 if(defined $ch){
900 0 0       0 if($ch eq '*'){
901 0 0 0     0 if(defined($ch = $self->_next_chr()) and $ch eq '/'){
902 0         0 $ch = $self->_next_chr();
903 0         0 last;
904             }
905             }
906             else{
907 0         0 $ch = $self->_next_chr();
908             }
909             }
910             else{
911 0         0 $self->_decode_error("Unterminated comment");
912             }
913             }
914 0         0 next;
915             }
916             else{
917 0         0 $self->{at}--;
918 0         0 $self->_decode_error("malformed JSON string, neither array, object, number, string or atom");
919             }
920             }
921             else{
922 146031 100 100     357215 if ($self->{PROPS}[P_RELAXED] and $ch eq '#') { # correctly?
923 9         27 pos($self->{text}) = $self->{at};
924 9         30 $self->{text} =~ /\G([^\n]*(?:\r\n|\r|\n|$))/g;
925 9         16 $self->{at} = pos($self->{text});
926 9         13 $ch = $self->_next_chr;
927 9         16 next;
928             }
929              
930 146022         257500 last;
931             }
932             }
933             }
934              
935              
936             sub _array {
937 26316     26316   44170 my $self = shift;
938 26316   50     103535 my $a = $_[0] || []; # you can use this code to use another array ref object.
939              
940             $self->_decode_error('json text or perl structure exceeds maximum nesting level (max_depth set too low?)')
941 26316 100       95556 if (++$self->{depth} > $self->{max_depth});
942              
943 26313         70476 $self->_next_chr();
944 26313         65018 $self->_white();
945              
946 26313         50935 my $ch = $self->{ch};
947 26313 100 66     105287 if(defined $ch and $ch eq ']'){
948 23         44 --$self->{depth};
949 23         64 $self->_next_chr();
950 23         76 return $a;
951             }
952             else {
953 26290         64098 while(defined($ch)){
954 27114         77374 push @$a, $self->_value();
955              
956 26547         110469 $self->_white();
957              
958 26547         58096 $ch = $self->{ch};
959 26547 100       72345 if (!defined $ch) {
960 3         6 last;
961             }
962              
963 26544 100       72715 if($ch eq ']'){
964 25715         56870 --$self->{depth};
965 25715         68991 $self->_next_chr();
966 25715         83619 return $a;
967             }
968              
969 829 100       1631 if($ch ne ','){
970 3         8 last;
971             }
972              
973 826         1715 $self->_next_chr();
974 826         1656 $self->_white();
975              
976 826         1183 $ch = $self->{ch};
977 826 100 100     2479 if ($self->{PROPS}[P_RELAXED] and $ch eq ']') {
978 2         5 --$self->{depth};
979 2         6 $self->_next_chr();
980 2         7 return $a;
981             }
982              
983             }
984             }
985              
986 6 100 66     28 $self->{at}-- if defined $ch and $ch ne '';
987 6         35 $self->_decode_error(", or ] expected while parsing array");
988             }
989              
990             sub _tag {
991 1     1   4 my $self = shift;
992 1 50       4 $self->_decode_error('malformed JSON string, neither array, object, number, string or atom') unless $self->{PROPS}[P_ALLOW_TAGS];
993              
994 1         4 $self->_next_chr();
995 1         3 $self->_white();
996              
997 1         4 my $tag = $self->_value();
998 1 50       4 return unless defined $tag;
999 1 50       4 $self->_decode_error('malformed JSON string, (tag) must be a string') if ref $tag;
1000              
1001 1         4 $self->_white();
1002              
1003 1         2 my $ch = $self->{ch};
1004 1 50 33     8 if (!defined $ch or $ch ne ')') {
1005 0         0 $self->_decode_error(') expected after tag');
1006             }
1007              
1008 1         4 $self->_next_chr();
1009 1         3 $self->_white();
1010              
1011 1         4 my $val = $self->_value();
1012 1 50       4 return unless defined $val;
1013 1 50       6 $self->_decode_error('malformed JSON string, tag value must be an array') unless ref $val eq 'ARRAY';
1014              
1015 1 50       3 if (!eval { $tag->can('THAW') }) {
  1         13  
1016 0 0       0 $self->_decode_error('cannot decode perl-object (package does not exist)') if $@;
1017 0         0 $self->_decode_error('cannot decode perl-object (package does not have a THAW method)');
1018             }
1019 1         23 $tag->THAW('JSON', @$val);
1020             }
1021              
1022             sub _object {
1023 2261     2261   3672 my $self = shift;
1024 2261   50     7951 my $o = $_[0] || {}; # you can use this code to use another hash ref object.
1025 2261         3606 my $k;
1026              
1027             $self->_decode_error('json text or perl structure exceeds maximum nesting level (max_depth set too low?)')
1028 2261 50       6178 if (++$self->{depth} > $self->{max_depth});
1029 2261         6670 $self->_next_chr();
1030 2261         18383 $self->_white();
1031              
1032 2261         4412 my $ch = $self->{ch};
1033 2261 100 66     7874 if(defined $ch and $ch eq '}'){
1034 9         20 --$self->{depth};
1035 9         32 $self->_next_chr();
1036 9 100       30 if ($self->{F_HOOK}) {
1037 1         5 return $self->__json_object_hook($o);
1038             }
1039 8         28 return $o;
1040             }
1041             else {
1042 2252         4748 while (defined $ch) {
1043 3742 100 66     12982 $k = ($self->{PROPS}[P_ALLOW_BAREKEY] and $ch ne '"' and $ch ne "'") ? $self->_bareKey() : $self->_string();
1044 3737         18023 $self->_white();
1045              
1046 3737         6153 $ch = $self->{ch};
1047 3737 100 100     20787 if(!defined $ch or $ch ne ':'){
1048 3         6 $self->{at}--;
1049 3         11 $self->_decode_error("':' expected");
1050             }
1051              
1052 3734         8800 $self->_next_chr();
1053 3734         8957 $o->{$k} = $self->_value();
1054 3217         8034 $self->_white();
1055              
1056 3217         5186 $ch = $self->{ch};
1057 3217 100       6457 last if (!defined $ch);
1058              
1059 3215 100       6263 if($ch eq '}'){
1060 1718         2720 --$self->{depth};
1061 1718         4005 $self->_next_chr();
1062 1718 100       3561 if ($self->{F_HOOK}) {
1063 8         17 return $self->__json_object_hook($o);
1064             }
1065 1710         6240 return $o;
1066             }
1067              
1068 1497 100       3150 if($ch ne ','){
1069 5         12 last;
1070             }
1071              
1072 1492         3359 $self->_next_chr();
1073 1492         3139 $self->_white();
1074              
1075 1492         2398 $ch = $self->{ch};
1076 1492 100 66     4925 if ($self->{PROPS}[P_RELAXED] and $ch eq '}') {
1077 1         3 --$self->{depth};
1078 1         4 $self->_next_chr();
1079 1 50       3 if ($self->{F_HOOK}) {
1080 0         0 return $self->__json_object_hook($o);
1081             }
1082 1         3 return $o;
1083             }
1084              
1085             }
1086              
1087             }
1088              
1089 8 100 66     47 $self->{at}-- if defined $ch and $ch ne '';
1090 8         48 $self->_decode_error(", or } expected while parsing object/hash");
1091             }
1092              
1093              
1094             sub _bareKey { # doesn't strictly follow Standard ECMA-262 3rd Edition
1095 2     2   6 my $self = shift;
1096 2         4 my $key;
1097 2         8 my $ch = $self->{ch};
1098 2         12 while($ch =~ /[\$\w[:^ascii:]]/){
1099 6         9 $key .= $ch;
1100 6         14 $ch = $self->_next_chr();
1101             }
1102 2         6 return $key;
1103             }
1104              
1105              
1106             sub _word {
1107 93     93   147 my $self = shift;
1108 93         262 my $word = substr($self->{text},$self->{at}-1,4);
1109              
1110 93 100       419 if($word eq 'true'){
    100          
    100          
1111 14         28 $self->{at} += 3;
1112 14         42 $self->_next_chr;
1113 14 100       120 return defined $self->{true} ? $self->{true} : $JSON::PP::true;
1114             }
1115             elsif($word eq 'null'){
1116 44         72 $self->{at} += 3;
1117 44         90 $self->_next_chr;
1118 44         158 return undef;
1119             }
1120             elsif($word eq 'fals'){
1121 11         24 $self->{at} += 3;
1122 11 50       41 if(substr($self->{text},$self->{at},1) eq 'e'){
1123 11         23 $self->{at}++;
1124 11         30 $self->_next_chr;
1125 11 100       49 return defined $self->{false} ? $self->{false} : $JSON::PP::false;
1126             }
1127             }
1128              
1129 24         44 $self->{at}--; # for decode_error report
1130              
1131 24 100       103 $self->_decode_error("'null' expected") if ($word =~ /^n/);
1132 23 100       65 $self->_decode_error("'true' expected") if ($word =~ /^t/);
1133 22 50       59 $self->_decode_error("'false' expected") if ($word =~ /^f/);
1134 22         80 $self->_decode_error("malformed JSON string, neither array, object, number, string or atom");
1135             }
1136              
1137              
1138             sub _number {
1139 946     946   1374 my $self = shift;
1140 946         1300 my $n = '';
1141 946         1999 my $v;
1142             my $is_dec;
1143 946         0 my $is_exp;
1144              
1145 946         1493 my $ch = $self->{ch};
1146 946 100       1893 if($ch eq '-'){
1147 41         139 $n = '-';
1148 41         91 $ch = $self->_next_chr;
1149 41 100 66     261 if (!defined $ch or $ch !~ /\d/) {
1150 1         3 $self->_decode_error("malformed number (no digits after initial minus)");
1151             }
1152             }
1153              
1154             # According to RFC4627, hex or oct digits are invalid.
1155 945 100       1787 if($ch eq '0'){
1156 113         360 my $peek = substr($self->{text},$self->{at},1);
1157 113 100       452 if($peek =~ /^[0-9a-dfA-DF]/){ # e may be valid (exponential)
1158 5         25 $self->_decode_error("malformed number (leading zero must not be followed by another digit)");
1159             }
1160 108         285 $n .= $ch;
1161 108         373 $ch = $self->_next_chr;
1162             }
1163              
1164 940   100     4194 while(defined $ch and $ch =~ /\d/){
1165 1038         1558 $n .= $ch;
1166 1038         1752 $ch = $self->_next_chr;
1167             }
1168              
1169 940 100 100     3080 if(defined $ch and $ch eq '.'){
1170 49         86 $n .= '.';
1171 49         72 $is_dec = 1;
1172              
1173 49         137 $ch = $self->_next_chr;
1174 49 100 66     294 if (!defined $ch or $ch !~ /\d/) {
1175 1         3 $self->_decode_error("malformed number (no digits after decimal point)");
1176             }
1177             else {
1178 48         134 $n .= $ch;
1179             }
1180              
1181 48   100     118 while(defined($ch = $self->_next_chr) and $ch =~ /\d/){
1182 97         222 $n .= $ch;
1183             }
1184             }
1185              
1186 939 100 100     5333 if(defined $ch and ($ch eq 'e' or $ch eq 'E')){
      100        
1187 58         91 $n .= $ch;
1188 58         164 $is_exp = 1;
1189 58         167 $ch = $self->_next_chr;
1190              
1191 58 100 100     353 if(defined($ch) and ($ch eq '+' or $ch eq '-')){
    100 100        
      100        
1192 38         58 $n .= $ch;
1193 38         87 $ch = $self->_next_chr;
1194 38 100 66     165 if (!defined $ch or $ch =~ /\D/) {
1195 2         8 $self->_decode_error("malformed number (no digits after exp sign)");
1196             }
1197 36         59 $n .= $ch;
1198             }
1199             elsif(defined($ch) and $ch =~ /\d/){
1200 18         37 $n .= $ch;
1201             }
1202             else {
1203 2         8 $self->_decode_error("malformed number (no digits after exp sign)");
1204             }
1205              
1206 54   100     103 while(defined($ch = $self->_next_chr) and $ch =~ /\d/){
1207 33         104 $n .= $ch;
1208             }
1209              
1210             }
1211              
1212 935         1470 $v .= $n;
1213              
1214 935 100 100     2735 if ($is_dec or $is_exp) {
1215 70 100       175 if ($self->{PROPS}[P_ALLOW_BIGNUM]) {
1216 1         1593 require Math::BigFloat;
1217 1         52247 return Math::BigFloat->new($v);
1218             }
1219             } else {
1220 865 100       2887 if (length $v > $max_intsize) {
1221 1 50       9 if ($self->{PROPS}[P_ALLOW_BIGNUM]) { # from Adam Sussman
1222 1         15 require Math::BigInt;
1223 1         7 return Math::BigInt->new($v);
1224             }
1225             else {
1226 0         0 return "$v";
1227             }
1228             }
1229             }
1230              
1231 933 100       3846 return $is_dec ? $v/1.0 : 0+$v;
1232             }
1233              
1234             # Compute how many bytes are in the longest legal official Unicode
1235             # character
1236             my $max_unicode_length = do {
1237 67     67   283108 no warnings 'utf8';
  67         133  
  67         80122  
1238             chr 0x10FFFF;
1239             };
1240             utf8::encode($max_unicode_length);
1241             $max_unicode_length = length $max_unicode_length;
1242              
1243             sub _is_valid_utf8 {
1244 3441000     3441000   6167123 my ($self, $ch, $utf8_len_r) = @_;
1245              
1246             # Returns undef (setting $utf8_len to 0) unless the next bytes in $text
1247             # comprise a well-formed UTF-8 encoded character, in which case,
1248             # return those bytes, setting $utf8_len to their count.
1249              
1250 3441000         6927828 my $start_point = substr($self->{text}, $self->{at} - 1);
1251              
1252             # Look no further than the maximum number of bytes in a single
1253             # character
1254 3441000         4717677 my $limit = $max_unicode_length;
1255 3441000 100       6309712 $limit = length($start_point) if $limit > length($start_point);
1256              
1257             # Find the number of bytes comprising the first character in $text
1258             # (without having to know the details of its internal representation).
1259             # This loop will iterate just once on well-formed input.
1260 3441000         5988451 while ($limit > 0) { # Until we succeed or exhaust the input
1261 4681125         6707579 my $copy = substr($start_point, 0, $limit);
1262              
1263             # decode() will return true if all bytes are valid; false
1264             # if any aren't.
1265 4681125 100       10169385 if (utf8::decode($copy)) {
1266              
1267             # Is valid: get the first character, convert back to bytes,
1268             # and return those bytes.
1269 3440995         6970396 $copy = substr($copy, 0, 1);
1270 3440995         6999249 utf8::encode($copy);
1271 3440995         4640917 $$utf8_len_r = length $copy;
1272 3440995         9258877 return substr($start_point, 0, $$utf8_len_r);
1273             }
1274              
1275             # If it didn't work, it could be that there is a full legal character
1276             # followed by a partial or malformed one. Narrow the window and
1277             # try again.
1278 1240130         2244173 $limit--;
1279             }
1280              
1281             # Failed to find a legal UTF-8 character.
1282 5         13 $$utf8_len_r = 0;
1283 5         20 return;
1284             }
1285              
1286              
1287             sub _decode_error {
1288 101     101   292 my $self = shift;
1289 101         290 my $error = shift;
1290 101         273 my $no_rep = shift;
1291 101 100       460 my $str = defined $self->{text} ? substr($self->{text}, $self->{at}) : '';
1292 101         250 my $mess = '';
1293 101         249 my $type = 'U*';
1294              
1295 101         586 for my $c ( unpack( $type, $str ) ) { # emulate pv_uni_display() ?
1296 411         890 my $chr_c = chr($c);
1297 411 50       1567 $mess .= $chr_c eq '\\' ? '\\\\'
    50          
    50          
    50          
    50          
    100          
    100          
1298             : $chr_c =~ /[[:print:]]/ ? $chr_c
1299             : $chr_c eq '\a' ? '\a'
1300             : $chr_c eq '\t' ? '\t'
1301             : $chr_c eq '\n' ? '\n'
1302             : $chr_c eq '\r' ? '\r'
1303             : $chr_c eq '\f' ? '\f'
1304             : sprintf('\x{%x}', $c)
1305             ;
1306 411 100       1064 if ( length $mess >= 20 ) {
1307 10         26 $mess .= '...';
1308 10         22 last;
1309             }
1310             }
1311              
1312 101 100       363 unless ( length $mess ) {
1313 33         67 $mess = '(end of string)';
1314             }
1315              
1316             Carp::croak (
1317 101 100       60879 $no_rep ? "$error" : "$error, at character offset $self->{at} (before \"$mess\")"
1318             );
1319              
1320             }
1321              
1322              
1323             sub __json_object_hook {
1324 9     9   9 my $self = shift;
1325 9         11 my $o = $_[0];
1326 9         9 my @ks = keys %{$o};
  9         20  
1327              
1328 9 100 66     61 if ( $self->{cb_sk_object} and @ks == 1 and exists $self->{cb_sk_object}{ $ks[0] } and ref $self->{cb_sk_object}{ $ks[0] } ) {
      100        
      66        
1329 4         11 my @val = $self->{cb_sk_object}{ $ks[0] }->( $o->{$ks[0]} );
1330 4 100       14 if (@val == 0) {
    50          
1331 1         3 return $o;
1332             }
1333             elsif (@val == 1) {
1334 3         29 return $val[0];
1335             }
1336             else {
1337 0         0 Carp::croak("filter_json_single_key_object callbacks must not return more than one scalar");
1338             }
1339             }
1340              
1341 5 100       16 my @val = $self->{cb_object}->($o) if ($self->{cb_object});
1342 5 100       16 if (@val == 0) {
    50          
1343 3         13 return $o;
1344             }
1345             elsif (@val == 1) {
1346 2         8 return $val[0];
1347             }
1348             else {
1349 0         0 Carp::croak("filter_json_object callbacks must not return more than one scalar");
1350             }
1351             }
1352              
1353             } # PARSE
1354              
1355              
1356             sub _decode_surrogates { # from perlunicode
1357 1127976     1127976   2330124 my $uni = 0x10000 + (hex($_[0]) - 0xD800) * 0x400 + (hex($_[1]) - 0xDC00);
1358 1127976         2636873 my $un = pack('U*', $uni);
1359 1127976         2564717 utf8::encode( $un );
1360 1127976         2682113 return $un;
1361             }
1362              
1363              
1364             sub _decode_unicode {
1365 2891847     2891847   6633521 my $un = pack('U', hex shift);
1366 2891847         6330231 utf8::encode( $un );
1367 2891847         9149367 return $un;
1368             }
1369              
1370             sub incr_parse {
1371 744     744 1 55527 local $Carp::CarpLevel = 1;
1372 744   66     2761 ( $_[0]->{_incr_parser} ||= JSON::PP::IncrParser->new )->incr_parse( @_ );
1373             }
1374              
1375              
1376             sub incr_skip {
1377 2   33 2 1 1462 ( $_[0]->{_incr_parser} ||= JSON::PP::IncrParser->new )->incr_skip;
1378             }
1379              
1380              
1381             sub incr_reset {
1382 0   0 0 1 0 ( $_[0]->{_incr_parser} ||= JSON::PP::IncrParser->new )->incr_reset;
1383             }
1384              
1385             sub incr_text : lvalue {
1386 304   33 304 1 45605 $_[0]->{_incr_parser} ||= JSON::PP::IncrParser->new;
1387              
1388 304 50       711 if ( $_[0]->{_incr_parser}->{incr_pos} ) {
1389 0         0 Carp::croak("incr_text cannot be called when the incremental parser already started parsing");
1390             }
1391 304         2044 $_[0]->{_incr_parser}->{incr_text};
1392             }
1393              
1394              
1395             ###############################
1396             # Utilities
1397             #
1398              
1399             # shamelessly copied and modified from JSON::XS code.
1400              
1401             $JSON::PP::true = do { bless \(my $dummy = 1), "JSON::PP::Boolean" };
1402             $JSON::PP::false = do { bless \(my $dummy = 0), "JSON::PP::Boolean" };
1403              
1404             sub is_bool {
1405 11 100   11 1 1735 if (blessed $_[0]) {
1406             return (
1407 2   33     25 $_[0]->isa("JSON::PP::Boolean")
1408             or $_[0]->isa("Types::Serialiser::BooleanBase")
1409             or $_[0]->isa("JSON::XS::Boolean")
1410             );
1411             }
1412             elsif (CORE_BOOL) {
1413 67     67   10591 BEGIN { CORE_BOOL and warnings->unimport('experimental::builtin') }
1414 9         49 return builtin::is_bool($_[0]);
1415             }
1416 0         0 return !!0;
1417             }
1418              
1419 3     3 1 3456 sub true { $JSON::PP::true }
1420 3     3 1 15 sub false { $JSON::PP::false }
1421 0     0 1 0 sub null { undef; }
1422              
1423             ###############################
1424              
1425             package JSON::PP::IncrParser;
1426              
1427 67     67   538 use strict;
  67         125  
  67         2113  
1428              
1429 67     67   416 use constant INCR_M_WS => 0; # initial whitespace skipping
  67         139  
  67         5663  
1430 67     67   379 use constant INCR_M_STR => 1; # inside string
  67         199  
  67         3950  
1431 67     67   357 use constant INCR_M_BS => 2; # inside backslash
  67         126  
  67         3331  
1432 67     67   325 use constant INCR_M_JSON => 3; # outside anything, count nesting
  67         174  
  67         3201  
1433 67     67   360 use constant INCR_M_C0 => 4;
  67         156  
  67         3372  
1434 67     67   394 use constant INCR_M_C1 => 5;
  67         152  
  67         3337  
1435 67     67   343 use constant INCR_M_TFN => 6;
  67         149  
  67         4687  
1436 67     67   942 use constant INCR_M_NUM => 7;
  67         421  
  67         23905  
1437              
1438             our $VERSION = '1.01';
1439              
1440             sub new {
1441 57     57   97 my ( $class ) = @_;
1442              
1443 57         515 bless {
1444             incr_nest => 0,
1445             incr_text => undef,
1446             incr_pos => 0,
1447             incr_mode => 0,
1448             }, $class;
1449             }
1450              
1451              
1452             sub incr_parse {
1453 744     744   1479 my ( $self, $coder, $text ) = @_;
1454              
1455 744 100       1637 $self->{incr_text} = '' unless ( defined $self->{incr_text} );
1456              
1457 744 100       1338 if ( defined $text ) {
1458 402         1107 $self->{incr_text} .= $text;
1459             }
1460              
1461 744 100       2213 if ( defined wantarray ) {
1462 383         999 my $max_size = $coder->get_max_size;
1463 383         678 my $p = $self->{incr_pos};
1464 383         496 my @ret;
1465             {
1466 383         518 do {
  383         479  
1467 394 100 100     1661 unless ( $self->{incr_nest} <= 0 and $self->{incr_mode} == INCR_M_JSON ) {
1468 393         1039 $self->_incr_parse( $coder );
1469              
1470 392 100 100     830 if ( $max_size and $self->{incr_pos} > $max_size ) {
1471 1         180 Carp::croak("attempted decode of JSON text of $self->{incr_pos} bytes size, but max_size is set to $max_size");
1472             }
1473 391 100 100     1350 unless ( $self->{incr_nest} <= 0 and $self->{incr_mode} == INCR_M_JSON ) {
1474             # as an optimisation, do not accumulate white space in the incr buffer
1475 83 100 100     385 if ( $self->{incr_mode} == INCR_M_WS and $self->{incr_pos} ) {
1476 7         12 $self->{incr_pos} = 0;
1477 7         14 $self->{incr_text} = '';
1478             }
1479 83         182 last;
1480             }
1481             }
1482              
1483 309 100       10596 unless ( $coder->get_utf8 ) {
1484 301         888 utf8::decode( $self->{incr_text} );
1485             }
1486              
1487 309         876 my ($obj, $offset) = $coder->PP_decode_json( $self->{incr_text}, 0x00000001 );
1488 298         548 push @ret, $obj;
1489 67     67   524 use bytes;
  67         204  
  67         470  
1490 298   50     793 $self->{incr_text} = substr( $self->{incr_text}, $offset || 0 );
1491 298         423 $self->{incr_pos} = 0;
1492 298         422 $self->{incr_nest} = 0;
1493 298         366 $self->{incr_mode} = 0;
1494 298 100       613 last unless wantarray;
1495             } while ( wantarray );
1496             }
1497              
1498 370 100       603 if ( wantarray ) {
1499 7         54 return @ret;
1500             }
1501             else { # in scalar context
1502 363 100       1684 return defined $ret[0] ? $ret[0] : undef;
1503             }
1504             }
1505             }
1506              
1507              
1508             sub _incr_parse {
1509 393     393   703 my ($self, $coder) = @_;
1510 393         997 my $text = $self->{incr_text};
1511 393         689 my $len = length $text;
1512 393         603 my $p = $self->{incr_pos};
1513              
1514             INCR_PARSE:
1515 393         817 while ( $len > $p ) {
1516 3084         4540 my $s = substr( $text, $p, 1 );
1517 3084 50       5626 last INCR_PARSE unless defined $s;
1518 3084         3969 my $mode = $self->{incr_mode};
1519              
1520 3084 100 100     12272 if ( $mode == INCR_M_WS ) {
    50          
    100          
    100          
    100          
    100          
    50          
1521 335         637 while ( $len > $p ) {
1522 594         887 $s = substr( $text, $p, 1 );
1523 594 50       894 last INCR_PARSE unless defined $s;
1524 594 100       1053 if ( ord($s) > ord " " ) {
1525 328 100       625 if ( $s eq '#' ) {
1526 6         7 $self->{incr_mode} = INCR_M_C0;
1527 6         12 redo INCR_PARSE;
1528             } else {
1529 322         725 $self->{incr_mode} = INCR_M_JSON;
1530 322         728 redo INCR_PARSE;
1531             }
1532             }
1533 266         421 $p++;
1534             }
1535             } elsif ( $mode == INCR_M_BS ) {
1536 0         0 $p++;
1537 0         0 $self->{incr_mode} = INCR_M_STR;
1538 0         0 redo INCR_PARSE;
1539             } elsif ( $mode == INCR_M_C0 or $mode == INCR_M_C1 ) {
1540 9         15 while ( $len > $p ) {
1541 45         43 $s = substr( $text, $p, 1 );
1542 45 50       56 last INCR_PARSE unless defined $s;
1543 45 100       50 if ( $s eq "\n" ) {
1544 9 100       17 $self->{incr_mode} = $self->{incr_mode} == INCR_M_C0 ? INCR_M_WS : INCR_M_JSON;
1545 9         11 last;
1546             }
1547 36         42 $p++;
1548             }
1549 9         16 next;
1550             } elsif ( $mode == INCR_M_TFN ) {
1551 36 50 66     87 last INCR_PARSE if $p >= $len && $self->{incr_nest};
1552 35         66 while ( $len > $p ) {
1553 140         226 $s = substr( $text, $p++, 1 );
1554 140 100 66     529 next if defined $s and $s =~ /[rueals]/;
1555 35         50 last;
1556             }
1557 35         49 $p--;
1558 35         49 $self->{incr_mode} = INCR_M_JSON;
1559              
1560 35 50       66 last INCR_PARSE unless $self->{incr_nest};
1561 35         53 redo INCR_PARSE;
1562             } elsif ( $mode == INCR_M_NUM ) {
1563 399 100 100     880 last INCR_PARSE if $p >= $len && $self->{incr_nest};
1564 396         642 while ( $len > $p ) {
1565 482         709 $s = substr( $text, $p++, 1 );
1566 482 100 66     1668 next if defined $s and $s =~ /[0-9eE.+\-]/;
1567 389         479 last;
1568             }
1569 396         462 $p--;
1570 396         498 $self->{incr_mode} = INCR_M_JSON;
1571              
1572 396 100       691 last INCR_PARSE unless $self->{incr_nest};
1573 378         522 redo INCR_PARSE;
1574             } elsif ( $mode == INCR_M_STR ) {
1575 805         1427 while ( $len > $p ) {
1576 84413         116047 $s = substr( $text, $p, 1 );
1577 84413 50       136845 last INCR_PARSE unless defined $s;
1578 84413 100       160842 if ( $s eq '"' ) {
    100          
1579 780         913 $p++;
1580 780         1139 $self->{incr_mode} = INCR_M_JSON;
1581              
1582 780 100       1431 last INCR_PARSE unless $self->{incr_nest};
1583 760         1255 redo INCR_PARSE;
1584             }
1585             elsif ( $s eq '\\' ) {
1586 508         542 $p++;
1587 508 50       903 if ( !defined substr($text, $p, 1) ) {
1588 0         0 $self->{incr_mode} = INCR_M_BS;
1589 0         0 last INCR_PARSE;
1590             }
1591             }
1592 83633         135734 $p++;
1593             }
1594             } elsif ( $mode == INCR_M_JSON ) {
1595 1500         2558 while ( $len > $p ) {
1596 3614         5315 $s = substr( $text, $p++, 1 );
1597 3614 50 66     22011 if ( $s eq "\x00" ) {
    100 100        
    100 100        
    100 100        
    100          
    100          
    100          
    100          
1598 0         0 $p--;
1599 0         0 last INCR_PARSE;
1600             } elsif ( $s =~ /^[\t\n\r ]$/) {
1601 724 50       1286 if ( !$self->{incr_nest} ) {
1602 0         0 $p--; # do not eat the whitespace, let the next round do it
1603 0         0 last INCR_PARSE;
1604             }
1605 724         1217 next;
1606             } elsif ( $s eq 't' or $s eq 'f' or $s eq 'n' ) {
1607 36         54 $self->{incr_mode} = INCR_M_TFN;
1608 36         55 redo INCR_PARSE;
1609             } elsif ( $s =~ /^[0-9\-]$/ ) {
1610 398         563 $self->{incr_mode} = INCR_M_NUM;
1611 398         688 redo INCR_PARSE;
1612             } elsif ( $s eq '"' ) {
1613 783         1155 $self->{incr_mode} = INCR_M_STR;
1614 783         1156 redo INCR_PARSE;
1615             } elsif ( $s eq '[' or $s eq '{' ) {
1616 383 100       1125 if ( ++$self->{incr_nest} > $coder->get_max_depth ) {
1617 1         175 Carp::croak('json text or perl structure exceeds maximum nesting level (max_depth set too low?)');
1618             }
1619 382         747 next;
1620             } elsif ( $s eq ']' or $s eq '}' ) {
1621 369 100       789 if ( --$self->{incr_nest} <= 0 ) {
1622 270         454 last INCR_PARSE;
1623             }
1624             } elsif ( $s eq '#' ) {
1625 3         4 $self->{incr_mode} = INCR_M_C1;
1626 3         5 redo INCR_PARSE;
1627             }
1628             }
1629             }
1630             }
1631              
1632 392         630 $self->{incr_pos} = $p;
1633 392 100       1105 $self->{incr_parsing} = $p ? 1 : 0; # for backward compatibility
1634             }
1635              
1636              
1637             sub incr_text {
1638 0 0   0   0 if ( $_[0]->{incr_pos} ) {
1639 0         0 Carp::croak("incr_text cannot be called when the incremental parser already started parsing");
1640             }
1641 0         0 $_[0]->{incr_text};
1642             }
1643              
1644              
1645             sub incr_skip {
1646 2     2   4 my $self = shift;
1647 2         7 $self->{incr_text} = substr( $self->{incr_text}, $self->{incr_pos} );
1648 2         4 $self->{incr_pos} = 0;
1649 2         3 $self->{incr_mode} = 0;
1650 2         4 $self->{incr_nest} = 0;
1651             }
1652              
1653              
1654             sub incr_reset {
1655 0     0     my $self = shift;
1656 0           $self->{incr_text} = undef;
1657 0           $self->{incr_pos} = 0;
1658 0           $self->{incr_mode} = 0;
1659 0           $self->{incr_nest} = 0;
1660             }
1661              
1662             ###############################
1663              
1664              
1665             1;
1666             __END__