JSON-2.90/0000755000175000017500000000000012234431435010706 5ustar reonreonJSON-2.90/META.yml0000664000175000017500000000114312234431435012160 0ustar reonreon--- abstract: 'JSON (JavaScript Object Notation) encoder/decoder' author: - 'Makamaka Hannyaharamitu, Emakamaka[at]cpan.orgE' build_requires: ExtUtils::MakeMaker: 0 configure_requires: ExtUtils::MakeMaker: 0 dynamic_config: 1 generated_by: 'ExtUtils::MakeMaker version 6.62, CPAN::Meta::Converter version 2.130880' license: perl meta-spec: url: http://module-build.sourceforge.net/META-spec-v1.4.html version: 1.4 name: JSON no_index: directory: - t - inc recommends: JSON::XS: 2.34 requires: Test::More: 0 resources: repository: https://github.com/makamaka/JSON version: 2.90 JSON-2.90/MANIFEST0000644000175000017500000000251112234431436012037 0ustar reonreonChanges eg/bench_decode.pl eg/bench_encode.pl lib/JSON.pm lib/JSON/backportPP.pm lib/JSON/backportPP/Boolean.pm lib/JSON/backportPP/Compat5005.pm lib/JSON/backportPP/Compat5006.pm Makefile.PL MANIFEST META.yml Module meta-data (added by MakeMaker) README t/00_load.t t/00_pod.t t/01_utf8.t t/02_error.t t/03_types.t t/06_pc_pretty.t t/07_pc_esc.t t/08_pc_base.t t/09_pc_extra_number.t t/10_pc_keysort.t t/11_pc_expo.t t/12_blessed.t t/13_limit.t t/14_latin1.t t/15_prefix.t t/16_tied.t t/17_relaxed.t t/18_json_checker.t t/19_incr.t t/20_unknown.t t/21_evans_bugrep.t t/22_comment_at_eof.t t/99_binary.t t/_unicode_handling.pm t/e00_func.t t/e01_property.t t/e02_bool.t t/e03_bool2.t t/e04_sortby.t t/e05_esc_slash.t t/e06_allow_barekey.t t/e07_allow_singlequote.t t/e08_decode.t t/e09_encode.t t/e10_bignum.t t/e11_conv_blessed_univ.t t/e12_upgrade.t t/e13_overloaded_eq.t t/e14_decode_prefix.t t/e15_tie_ixhash.t t/e16_incr_parse_fixed.t t/e90_misc.t t/x00_load.t t/x02_error.t t/x12_blessed.t t/x16_tied.t t/x17_strange_overload.t t/xe01_property.t t/xe02_bool.t t/xe03_bool2.t t/xe04support_by_pp.t t/xe05_indent_length.t t/xe08_decode.t t/xe10_bignum.t t/xe11_conv_blessed_univ.t t/xe12_boolean.t t/xe19_xs_and_suportbypp.t t/xe20_croak_message.t t/xe21_is_pp.t META.json Module JSON meta-data (added by MakeMaker) JSON-2.90/t/0000755000175000017500000000000012234431435011151 5ustar reonreonJSON-2.90/t/01_utf8.t0000644000175000017500000000211411651666007012531 0ustar reonreon# copied over from JSON::XS and modified to use JSON use strict; use Test::More; BEGIN { plan tests => 9 }; BEGIN { $ENV{PERL_JSON_BACKEND} = "JSON::backportPP"; } BEGIN { use lib qw(t); use _unicode_handling; } use utf8; use JSON; ok (JSON->new->allow_nonref (1)->utf8 (1)->encode ("ü") eq "\"\xc3\xbc\""); ok (JSON->new->allow_nonref (1)->encode ("ü") eq "\"ü\""); SKIP: { skip "UNICODE handling is disabale.", 7 unless $JSON::can_handle_UTF16_and_utf8; ok (JSON->new->allow_nonref (1)->ascii (1)->utf8 (1)->encode (chr 0x8000) eq '"\u8000"'); ok (JSON->new->allow_nonref (1)->ascii (1)->utf8 (1)->pretty (1)->encode (chr 0x10402) eq "\"\\ud801\\udc02\"\n"); eval { JSON->new->allow_nonref (1)->utf8 (1)->decode ('"ü"') }; ok $@ =~ /malformed UTF-8/; ok (JSON->new->allow_nonref (1)->decode ('"ü"') eq "ü"); ok (JSON->new->allow_nonref (1)->decode ('"\u00fc"') eq "ü"); ok (JSON->new->allow_nonref (1)->decode ('"\ud801\udc02' . "\x{10204}\"") eq "\x{10402}\x{10204}"); ok (JSON->new->allow_nonref (1)->decode ('"\"\n\\\\\r\t\f\b"') eq "\"\012\\\015\011\014\010"); } JSON-2.90/t/08_pc_base.t0000644000175000017500000000413511651666007013253 0ustar reonreonuse Test::More; # copied over from JSON::PC and modified to use JSON # copied over from JSON::XS and modified to use JSON use strict; BEGIN { plan tests => 20 }; BEGIN { $ENV{PERL_JSON_BACKEND} = "JSON::backportPP"; } use JSON; my ($js,$obj); my $pc = new JSON; $js = q|{}|; $obj = $pc->decode($js); $js = $pc->encode($obj); is($js,'{}', '{}'); $js = q|[]|; $obj = $pc->decode($js); $js = $pc->encode($obj); is($js,'[]', '[]'); $js = q|{"foo":"bar"}|; $obj = $pc->decode($js); is($obj->{foo},'bar'); $js = $pc->encode($obj); is($js,'{"foo":"bar"}', '{"foo":"bar"}'); $js = q|{"foo":""}|; $obj = $pc->decode($js); $js = $pc->encode($obj); is($js,'{"foo":""}', '{"foo":""}'); $js = q|{"foo":" "}|; $obj = $pc->decode($js); $js = $pc->encode($obj); is($js,'{"foo":" "}' ,'{"foo":" "}'); $js = q|{"foo":"0"}|; $obj = $pc->decode($js); $js = $pc->encode($obj); is($js,'{"foo":"0"}',q|{"foo":"0"} - autoencode (default)|); $js = q|{"foo":"0 0"}|; $obj = $pc->decode($js); $js = $pc->encode($obj); is($js,'{"foo":"0 0"}','{"foo":"0 0"}'); $js = q|[1,2,3]|; $obj = $pc->decode($js); is($obj->[1],2); $js = $pc->encode($obj); is($js,'[1,2,3]'); $js = q|{"foo":{"bar":"hoge"}}|; $obj = $pc->decode($js); is($obj->{foo}->{bar},'hoge'); $js = $pc->encode($obj); is($js,q|{"foo":{"bar":"hoge"}}|); $js = q|[{"foo":[1,2,3]},-0.12,{"a":"b"}]|; $obj = $pc->decode($js); $js = $pc->encode($obj); is($js,q|[{"foo":[1,2,3]},-0.12,{"a":"b"}]|); $obj = ["\x01"]; is($js = $pc->encode($obj),'["\\u0001"]'); $obj = $pc->decode($js); is($obj->[0],"\x01"); $obj = ["\e"]; is($js = $pc->encode($obj),'["\\u001b"]'); $obj = $pc->decode($js); is($obj->[0],"\e"); $js = '{"id":"}'; eval q{ $pc->decode($js) }; like($@, qr/unexpected end/i); $obj = { foo => sub { "bar" } }; eval q{ $js = $pc->encode($obj) }; like($@, qr/JSON can only/i, 'invalid value (coderef)'); #$obj = { foo => bless {}, "Hoge" }; #eval q{ $js = $pc->encode($obj) }; #like($@, qr/JSON can only/i, 'invalid value (blessd object)'); $obj = { foo => \$js }; eval q{ $js = $pc->encode($obj) }; like($@, qr/cannot encode reference/i, 'invalid value (ref)'); JSON-2.90/t/e06_allow_barekey.t0000644000175000017500000000056311651666007014643 0ustar reonreon use Test::More; use strict; BEGIN { plan tests => 2 }; BEGIN { $ENV{PERL_JSON_BACKEND} = "JSON::backportPP"; } use JSON; ######################### my $json = JSON->new->allow_nonref; eval q| $json->decode('{foo:"bar"}') |; ok($@); # in XS and PP, the error message differs. $json->allow_barekey; is($json->decode('{foo:"bar"}')->{foo}, 'bar'); JSON-2.90/t/e16_incr_parse_fixed.t0000644000175000017500000000072711651666007015332 0ustar reonreon#!/usr/bin/perl BEGIN { $ENV{ PERL_JSON_BACKEND } = $ARGV[0] || 'JSON::backportPP'; } use strict; use Test::More tests => 4; use JSON; my $json = JSON->new->allow_nonref(); my @vs = $json->incr_parse('"a\"bc'); ok( not scalar(@vs) ); @vs = $json->incr_parse('"'); is( $vs[0], "a\"bc" ); $json = JSON->new; @vs = $json->incr_parse('"a\"bc'); ok( not scalar(@vs) ); @vs = eval { $json->incr_parse('"') }; ok($@ =~ qr/JSON text must be an object or array/); JSON-2.90/t/xe10_bignum.t0000644000175000017500000000144311651666007013465 0ustar reonreon use strict; use Test::More; BEGIN { plan tests => 6 }; BEGIN { $ENV{PERL_JSON_BACKEND} = 1; } use JSON -support_by_pp; eval q| require Math::BigInt |; SKIP: { skip "can't use JSON::XS.", 6, unless( JSON->backend->is_xs ); skip "Can't load Math::BigInt.", 6 if ($@); my $json = new JSON; print $json->backend, "\n"; $json->allow_nonref->allow_bignum(1); $json->convert_blessed->allow_blessed; my $num = $json->decode(q|100000000000000000000000000000000000000|); isa_ok($num, 'Math::BigInt'); is($num, '100000000000000000000000000000000000000'); is($json->encode($num), '100000000000000000000000000000000000000'); $num = $json->decode(q|2.0000000000000000001|); isa_ok($num, 'Math::BigFloat'); is($num, '2.0000000000000000001'); is($json->encode($num), '2.0000000000000000001'); } JSON-2.90/t/03_types.t0000644000175000017500000000430311651666007013013 0ustar reonreon# copied over from JSON::XS and modified to use JSON use strict; use Test::More; BEGIN { plan tests => 76 }; BEGIN { $ENV{PERL_JSON_BACKEND} = "JSON::backportPP"; } use JSON; ok (!defined JSON->new->allow_nonref (1)->decode ('null')); ok (JSON->new->allow_nonref (1)->decode ('true') == 1); ok (JSON->new->allow_nonref (1)->decode ('false') == 0); my $true = JSON->new->allow_nonref (1)->decode ('true'); ok ($true eq 1); ok (JSON::is_bool $true); my $false = JSON->new->allow_nonref (1)->decode ('false'); ok ($false == !$true); ok (JSON::is_bool $false); ok (++$false == 1); ok (!JSON::is_bool $false); ok (JSON->new->allow_nonref (1)->decode ('5') == 5); ok (JSON->new->allow_nonref (1)->decode ('-5') == -5); ok (JSON->new->allow_nonref (1)->decode ('5e1') == 50); ok (JSON->new->allow_nonref (1)->decode ('-333e+0') == -333); ok (JSON->new->allow_nonref (1)->decode ('2.5') == 2.5); ok (JSON->new->allow_nonref (1)->decode ('""') eq ""); ok ('[1,2,3,4]' eq encode_json decode_json ('[1,2, 3,4]')); ok ('[{},[],[],{}]' eq encode_json decode_json ('[{},[], [ ] ,{ }]')); ok ('[{"1":[5]}]' eq encode_json [{1 => [5]}]); ok ('{"1":2,"3":4}' eq JSON->new->canonical (1)->encode (decode_json '{ "1" : 2, "3" : 4 }')); ok ('{"1":2,"3":1.2}' eq JSON->new->canonical (1)->encode (decode_json '{ "1" : 2, "3" : 1.2 }')); ok ('[true]' eq encode_json [JSON::true]); ok ('[false]' eq encode_json [JSON::false]); ok ('[true]' eq encode_json [\1]); ok ('[false]' eq encode_json [\0]); ok ('[null]' eq encode_json [undef]); ok ('[true]' eq encode_json [JSON::true]); ok ('[false]' eq encode_json [JSON::false]); for my $v (1, 2, 3, 5, -1, -2, -3, -4, 100, 1000, 10000, -999, -88, -7, 7, 88, 999, -1e5, 1e6, 1e7, 1e8) { ok ($v == ((decode_json "[$v]")->[0])); ok ($v == ((decode_json encode_json [$v])->[0])); } ok (30123 == ((decode_json encode_json [30123])->[0])); ok (32123 == ((decode_json encode_json [32123])->[0])); ok (32456 == ((decode_json encode_json [32456])->[0])); ok (32789 == ((decode_json encode_json [32789])->[0])); ok (32767 == ((decode_json encode_json [32767])->[0])); ok (32768 == ((decode_json encode_json [32768])->[0])); my @sparse; @sparse[0,3] = (1, 4); ok ("[1,null,null,4]" eq encode_json \@sparse); JSON-2.90/t/11_pc_expo.t0000644000175000017500000000206211651666007013303 0ustar reonreon# copied over from JSON::PC and modified to use JSON # copied over from JSON::XS and modified to use JSON use Test::More; use strict; BEGIN { plan tests => 8 }; BEGIN { $ENV{PERL_JSON_BACKEND} = "JSON::backportPP"; } use JSON; ######################### my ($js,$obj); my $pc = new JSON; $js = q|[-12.34]|; $obj = $pc->decode($js); is($obj->[0], -12.34, 'digit -12.34'); $js = $pc->encode($obj); is($js,'[-12.34]', 'digit -12.34'); $js = q|[-1.234e5]|; $obj = $pc->decode($js); is($obj->[0], -123400, 'digit -1.234e5'); $js = $pc->encode($obj); is($js,'[-123400]', 'digit -1.234e5'); $js = q|[1.23E-4]|; $obj = $pc->decode($js); is($obj->[0], 0.000123, 'digit 1.23E-4'); $js = $pc->encode($obj); if ( $js =~ /\[1/ ) { # for 5.6.2 on Darwin 8.10.0 like($js, qr/[1.23[eE]-04]/, 'digit 1.23E-4'); } else { is($js,'[0.000123]', 'digit 1.23E-4'); } $js = q|[1.01e+67]|; # 30 -> 67 ... patched by H.Merijn Brand $obj = $pc->decode($js); is($obj->[0], 1.01e+67, 'digit 1.01e+67'); $js = $pc->encode($obj); like($js,qr/\[1.01[Ee]\+0?67\]/, 'digit 1.01e+67'); JSON-2.90/t/e05_esc_slash.t0000644000175000017500000000044611651666007013766 0ustar reonreon use Test::More; use strict; BEGIN { plan tests => 2 }; BEGIN { $ENV{PERL_JSON_BACKEND} = "JSON::backportPP"; } use JSON; ######################### my $json = JSON->new->allow_nonref; my $js = '/'; is($json->encode($js), '"/"'); is($json->escape_slash->encode($js), '"\/"'); JSON-2.90/t/09_pc_extra_number.t0000644000175000017500000000135111651666007015032 0ustar reonreon# copied over from JSON::PC and modified to use JSON # copied over from JSON::XS and modified to use JSON use Test::More; use strict; BEGIN { plan tests => 6 }; BEGIN { $ENV{PERL_JSON_BACKEND} = "JSON::backportPP"; } use JSON; ######################### my ($js,$obj); my $pc = new JSON; $js = '{"foo":0}'; $obj = $pc->decode($js); is($obj->{foo}, 0, "normal 0"); $js = '{"foo":0.1}'; $obj = $pc->decode($js); is($obj->{foo}, 0.1, "normal 0.1"); $js = '{"foo":10}'; $obj = $pc->decode($js); is($obj->{foo}, 10, "normal 10"); $js = '{"foo":-10}'; $obj = $pc->decode($js); is($obj->{foo}, -10, "normal -10"); $js = '{"foo":0, "bar":0.1}'; $obj = $pc->decode($js); is($obj->{foo},0, "normal 0"); is($obj->{bar},0.1,"normal 0.1"); JSON-2.90/t/20_unknown.t0000644000175000017500000000205211651666007013344 0ustar reonreon#!/usr/bin/perl -w use strict; use Test::More; BEGIN { plan tests => 10 }; BEGIN { $ENV{PERL_JSON_BACKEND} = "JSON::backportPP"; } use strict; use JSON; my $json = JSON->new; eval q| $json->encode( [ sub {} ] ) |; ok( $@ =~ /encountered CODE/, $@ ); eval q| $json->encode( [ \-1 ] ) |; ok( $@ =~ /cannot encode reference to scalar/, $@ ); eval q| $json->encode( [ \undef ] ) |; ok( $@ =~ /cannot encode reference to scalar/, $@ ); eval q| $json->encode( [ \{} ] ) |; ok( $@ =~ /cannot encode reference to scalar/, $@ ); $json->allow_unknown; is( $json->encode( [ sub {} ] ), '[null]' ); is( $json->encode( [ \-1 ] ), '[null]' ); is( $json->encode( [ \undef ] ), '[null]' ); is( $json->encode( [ \{} ] ), '[null]' ); SKIP: { skip "this test is for Perl 5.8 or later", 2 if( $] < 5.008 ); $json->allow_unknown(0); my $fh; open( $fh, '>hoge.txt' ) or die $!; eval q| $json->encode( [ $fh ] ) |; ok( $@ =~ /encountered GLOB/, $@ ); $json->allow_unknown(1); is( $json->encode( [ $fh ] ), '[null]' ); close $fh; unlink('hoge.txt'); } JSON-2.90/t/xe19_xs_and_suportbypp.t0000644000175000017500000000114311651666007015775 0ustar reonreon#! perl # https://rt.cpan.org/Public/Bug/Display.html?id=52847 use strict; use Test::More; BEGIN { plan tests => 2 }; BEGIN { $ENV{PERL_JSON_BACKEND} = 1; } use JSON -support_by_pp; SKIP: { skip "can't use JSON::XS.", 2, unless( JSON->backend->is_xs ); my $json = JSON->new->allow_barekey; for (1..2) { is_deeply( test($json, q!{foo:"foo"}! ), {foo=>'foo'} ); JSON->new->allow_singlequote(0); } } sub test { my ($coder, $str) = @_; my $rv; return $rv if eval { $rv = $coder->decode($str); 1 }; chomp( my $e = $@ ); return "died with \"$e\""; }; JSON-2.90/t/19_incr.t0000644000175000017500000001177012127467462012622 0ustar reonreon#!/usr/bin/perl -w # copied over from JSON::XS and modified to use JSON use strict; use Test::More; BEGIN { plan tests => 697 }; BEGIN { $ENV{PERL_JSON_BACKEND} = "JSON::backportPP"; } use JSON; if ( $] >= 5.006 ) { eval <<'TEST' or die "Failed to eval test code for version $]: $@"; sub splitter { my ($coder, $text) = @_; $coder->canonical(1) if $] >= 5.017009; for (0 .. length $text) { my $a = substr $text, 0, $_; my $b = substr $text, $_; $coder->incr_parse ($a); $coder->incr_parse ($b); my $data = $coder->incr_parse; ok ($data); is ($coder->encode ($data), $coder->encode ($coder->decode ($text)), "data"); ok ($coder->incr_text =~ /^\s*$/, "tailws"); } } splitter +JSON->new , ' ["x\\"","\\u1000\\\\n\\nx",1,{"\\\\" :5 , "": "x"}]'; splitter +JSON->new , '[ "x\\"","\\u1000\\\\n\\nx" , 1,{"\\\\ " :5 , "": " x"} ] '; splitter +JSON->new->allow_nonref, '"test"'; splitter +JSON->new->allow_nonref, ' "5" '; { my $text = '[5],{"":1} , [ 1,2, 3], {"3":null}'; my $coder = new JSON; for (0 .. length $text) { my $a = substr $text, 0, $_; my $b = substr $text, $_; $coder->incr_parse ($a); $coder->incr_parse ($b); my $j1 = $coder->incr_parse; ok ($coder->incr_text =~ s/^\s*,//, "cskip1"); my $j2 = $coder->incr_parse; ok ($coder->incr_text =~ s/^\s*,//, "cskip2"); my $j3 = $coder->incr_parse; ok ($coder->incr_text =~ s/^\s*,//, "cskip3"); my $j4 = $coder->incr_parse; ok ($coder->incr_text !~ s/^\s*,//, "cskip4"); my $j5 = $coder->incr_parse; ok ($coder->incr_text !~ s/^\s*,//, "cskip5"); ok ('[5]' eq encode_json $j1, "cjson1"); ok ('{"":1}' eq encode_json $j2, "cjson2"); ok ('[1,2,3]' eq encode_json $j3, "cjson3"); ok ('{"3":null}' eq encode_json $j4, "cjson4"); ok (!defined $j5, "cjson5"); } } { my $text = '[x][5]'; my $coder = new JSON; $coder->incr_parse ($text); ok (!eval { $coder->incr_parse }, "sparse1"); ok (!eval { $coder->incr_parse }, "sparse2"); $coder->incr_skip; ok ('[5]' eq $coder->encode (scalar $coder->incr_parse), "sparse3"); } TEST } else { eval <<'TEST' or die "Failed to eval test code for version $]: $@"; my $incr_text; sub splitter { my ($coder, $text) = @_; for (0 .. length $text) { my $a = substr $text, 0, $_; my $b = substr $text, $_; $coder->incr_parse ($a); $coder->incr_parse ($b); my $data = $coder->incr_parse; ok ($data); ok ($coder->encode ($data) eq $coder->encode ($coder->decode ($text)), "data"); ok (($incr_text = $coder->incr_text) =~ /^\s*$/, "tailws"); } } splitter +JSON->new , ' ["x\\"","\\u1000\\\\n\\nx",1,{"\\\\" :5 , "": "x"}]'; splitter +JSON->new , '[ "x\\"","\\u1000\\\\n\\nx" , 1,{"\\\\ " :5 , "": " x"} ] '; splitter +JSON->new->allow_nonref, '"test"'; splitter +JSON->new->allow_nonref, ' "5" '; { my $text = '[5],{"":1} , [ 1,2, 3], {"3":null}'; my $coder = new JSON; for (0 .. length $text) { my $a = substr $text, 0, $_; my $b = substr $text, $_; $coder->incr_parse ($a); $coder->incr_parse ($b); my $j1 = $coder->incr_parse; ok ( $coder->incr_text( ($incr_text = $coder->incr_text) =~ s/^\s*,// and $incr_text ), "cskip1"); my $j2 = $coder->incr_parse; ok ( $coder->incr_text( ($incr_text = $coder->incr_text) =~ s/^\s*,// and $incr_text ), "cskip2"); my $j3 = $coder->incr_parse; ok ( $coder->incr_text( ($incr_text = $coder->incr_text) =~ s/^\s*,// and $incr_text ), "cskip3"); my $j4 = $coder->incr_parse; ok (($incr_text = $coder->incr_text) !~ s/^\s*,//, "cskip4"); my $j5 = $coder->incr_parse; ok (($incr_text = $coder->incr_text) !~ s/^\s*,//, "cskip5"); ok ('[5]' eq encode_json $j1, "cjson1"); ok ('{"":1}' eq encode_json $j2, "cjson2"); ok ('[1,2,3]' eq encode_json $j3, "cjson3"); ok ('{"3":null}' eq encode_json $j4, "cjson4"); ok (!defined $j5, "cjson5"); } } { my $text = '[x][5]'; my $coder = new JSON; $coder->incr_parse ($text); ok (!eval { $coder->incr_parse }, "sparse1"); ok (!eval { $coder->incr_parse }, "sparse2"); $coder->incr_skip; ok ('[5]' eq $coder->encode (scalar $coder->incr_parse), "sparse3"); } TEST } # for 5.005 { my $coder = JSON->new->max_size (5); ok (!$coder->incr_parse ("[ "), "incsize1"); eval q{ !$coder->incr_parse ("] ") }; ok ($@ =~ /6 bytes/, "incsize2 $@"); } { my $coder = JSON->new->max_depth (3); ok (!$coder->incr_parse ("[[["), "incdepth1"); eval q{ !$coder->incr_parse (" [] ") }; ok ($@ =~ /maximum nesting/, "incdepth2 $@"); } { my $coder = JSON->new; my $res = eval { $coder->incr_parse("]") }; my $e = $@; # test more clobbers $@, we need it twice ok(!$res, "unbalanced bracket" ); ok($e, "got error"); like( $e, qr/malformed/, "malformed json string error" ); $coder->incr_skip; is_deeply(eval { $coder->incr_parse("[42]") }, [42], "valid data after incr_skip"); } JSON-2.90/t/16_tied.t0000644000175000017500000000060411651666007012600 0ustar reonreon# copied over from JSON::XS and modified to use JSON use strict; use Test::More; BEGIN { plan tests => 2 }; BEGIN { $ENV{PERL_JSON_BACKEND} = "JSON::backportPP"; } use JSON; use Tie::Hash; use Tie::Array; my $js = JSON->new; tie my %h, 'Tie::StdHash'; %h = (a => 1); ok ($js->encode (\%h) eq '{"a":1}'); tie my @a, 'Tie::StdArray'; @a = (1, 2); ok ($js->encode (\@a) eq '[1,2]'); JSON-2.90/t/xe05_indent_length.t0000644000175000017500000000234211651666007015031 0ustar reonreonuse strict; use Test::More; BEGIN { plan tests => 7 }; BEGIN { $ENV{PERL_JSON_BACKEND} = 1; } use JSON -support_by_pp; SKIP: { skip "can't use JSON::XS.", 7, unless( JSON->backend->is_xs ); my $json = new JSON; is($json->indent_length(2)->encode([1,{foo => 'bar'}, "1", "/"]), qq|[1,{"foo":"bar"},"1","/"]|); is($json->indent->encode([1,{foo => 'bar'}, "1", "/"]), qq|[ 1, { "foo":"bar" }, "1", "/" ] |); is($json->escape_slash(1)->pretty->indent_length(2)->encode([1,{foo => 'bar'}, "1", "/"]), qq|[ 1, { "foo" : "bar" }, "1", "\\/" ] |); is($json->escape_slash(1)->pretty->indent_length(3)->encode([1,{foo => 'bar'}, "1", "/"]), qq|[ 1, { "foo" : "bar" }, "1", "\\/" ] |); is($json->escape_slash(1)->pretty->indent_length(15)->encode([1,{foo => 'bar'}, "1", "/"]), qq|[ 1, { "foo" : "bar" }, "1", "\\/" ] |); is($json->indent_length(0)->encode([1,{foo => 'bar'}, "1", "/"]), qq|[ 1, { "foo" : "bar" }, "1", "\\/" ] |); is($json->indent(0)->space_before(0)->space_after(0)->escape_slash(0) ->encode([1,{foo => 'bar'}, "1", "/"]), qq|[1,{"foo":"bar"},"1","/"]|); } JSON-2.90/t/21_evans_bugrep.t0000644000175000017500000000157511651666007014337 0ustar reonreonuse strict; use Test::More; BEGIN { plan tests => 6 }; BEGIN { $ENV{PERL_JSON_BACKEND} = "JSON::backportPP"; } BEGIN { use lib qw(t); use _unicode_handling; } use JSON; print JSON->backend, "\t", JSON->backend->VERSION, "\n"; my $data = ["\x{3042}\x{3044}\x{3046}\x{3048}\x{304a}", "\x{304b}\x{304d}\x{304f}\x{3051}\x{3053}"]; my $j = new JSON; my $js = $j->encode($data); $j = undef; my @parts = (substr($js, 0, int(length($js) / 2)), substr($js, int(length($js) / 2))); $j = JSON->new; my $object = $j->incr_parse($parts[0]); ok( !defined $object ); eval { $j->incr_text; }; like( $@, qr/incr_text can not be called when the incremental parser already started parsing/ ); $object = $j->incr_parse($parts[1]); ok( defined $object ); is( $object->[0], $data->[0] ); is( $object->[1], $data->[1] ); eval { $j->incr_text; }; ok( !$@ ); JSON-2.90/t/17_relaxed.t0000644000175000017500000000130711651666007013301 0ustar reonreon# copied over from JSON::XS and modified to use JSON use Test::More; use strict; BEGIN { plan tests => 8 }; BEGIN { $ENV{PERL_JSON_BACKEND} = "JSON::backportPP"; } BEGIN { use lib qw(t); use _unicode_handling; } use utf8; use JSON; my $json = JSON->new->relaxed; ok ('[1,2,3]' eq encode_json $json->decode (' [1,2, 3]')); ok ('[1,2,4]' eq encode_json $json->decode ('[1,2, 4 , ]')); ok (!eval { $json->decode ('[1,2, 3,4,,]') }); ok (!eval { $json->decode ('[,1]') }); ok ('{"1":2}' eq encode_json $json->decode (' {"1":2}')); ok ('{"1":2}' eq encode_json $json->decode ('{"1":2,}')); ok (!eval { $json->decode ('{,}') }); ok ('[1,2]' eq encode_json $json->decode ("[1#,2\n ,2,# ] \n\t]")); JSON-2.90/t/e10_bignum.t0000644000175000017500000000155411651666007013300 0ustar reonreon use strict; use Test::More; BEGIN { plan tests => 6 }; BEGIN { $ENV{PERL_JSON_BACKEND} = "JSON::backportPP"; } use JSON -support_by_pp; eval q| require Math::BigInt |; SKIP: { skip "Can't load Math::BigInt.", 6 if ($@); my $v = Math::BigInt->VERSION; $v =~ s/_.+$// if $v; my $fix = !$v ? '+' : $v < 1.6 ? '+' : ''; my $json = new JSON; $json->allow_nonref->allow_bignum(1); $json->convert_blessed->allow_blessed; my $num = $json->decode(q|100000000000000000000000000000000000000|); isa_ok($num, 'Math::BigInt'); is("$num", $fix . '100000000000000000000000000000000000000'); is($json->encode($num), $fix . '100000000000000000000000000000000000000'); $num = $json->decode(q|2.0000000000000000001|); isa_ok($num, 'Math::BigFloat'); is("$num", '2.0000000000000000001'); is($json->encode($num), '2.0000000000000000001'); } JSON-2.90/t/xe03_bool2.t0000644000175000017500000000212612234431225013210 0ustar reonreonuse Test::More; BEGIN { plan tests => 16 }; BEGIN { $ENV{PERL_JSON_BACKEND} = 1; } use JSON; SKIP: { skip "can't use JSON::XS.", 16, unless( JSON->backend->is_xs ); is(to_json([JSON::true]), q|[true]|); is(to_json([JSON::false]), q|[false]|); is(to_json([JSON::null]), q|[null]|); my $jsontext = q|[true,false,null]|; my $obj = from_json($jsontext); isa_ok($obj->[0], 'JSON::PP::Boolean'); isa_ok($obj->[1], 'JSON::PP::Boolean'); ok(!defined $obj->[2], 'null is undef'); ok($obj->[0] == 1); ok($obj->[0] != 0); ok($obj->[1] == 0); ok($obj->[1] != 1); #ok($obj->[0] eq 'true', 'eq true'); #ok($obj->[0] ne 'false', 'ne false'); #ok($obj->[1] eq 'false', 'eq false'); #ok($obj->[1] ne 'true', 'ne true'); ok($obj->[0] eq $obj->[0]); ok($obj->[0] ne $obj->[1]); #ok(JSON::true eq 'true'); #ok(JSON::true ne 'false'); #ok(JSON::true ne 'null'); #ok(JSON::false eq 'false'); #ok(JSON::false ne 'true'); #ok(JSON::false ne 'null'); ok(!defined JSON::null); is(from_json('[true]' )->[0], JSON::true); is(from_json('[false]')->[0], JSON::false); is(from_json('[null]' )->[0], JSON::null); } JSON-2.90/t/x16_tied.t0000644000175000017500000000061411651666007012771 0ustar reonreonuse strict; use Test::More; BEGIN { plan tests => 2 }; BEGIN { $ENV{PERL_JSON_BACKEND} = 1; } use JSON; use Tie::Hash; use Tie::Array; SKIP: { skip "can't use JSON::XS.", 2, unless( JSON->backend->is_xs ); my $js = JSON->new; tie my %h, 'Tie::StdHash'; %h = (a => 1); ok ($js->encode (\%h) eq '{"a":1}'); tie my @a, 'Tie::StdArray'; @a = (1, 2); ok ($js->encode (\@a) eq '[1,2]'); } JSON-2.90/t/e14_decode_prefix.t0000644000175000017500000000146111651666007014620 0ustar reonreon#!/usr/bin/perl use strict; use Test::More tests => 8; BEGIN { $ENV{ PERL_JSON_BACKEND } = "JSON::backportPP"; } use JSON; my $json = JSON->new; my $complete_text = qq/{"foo":"bar"}/; my $garbaged_text = qq/{"foo":"bar"}\n/; my $garbaged_text2 = qq/{"foo":"bar"}\n\n/; my $garbaged_text3 = qq/{"foo":"bar"}\n----/; is( ( $json->decode_prefix( $complete_text ) ) [1], 13 ); is( ( $json->decode_prefix( $garbaged_text ) ) [1], 13 ); is( ( $json->decode_prefix( $garbaged_text2 ) ) [1], 13 ); is( ( $json->decode_prefix( $garbaged_text3 ) ) [1], 13 ); eval { $json->decode( "\n" ) }; ok( $@ =~ /malformed JSON/ ); eval { $json->decode('null') }; ok $@ =~ /allow_nonref/; eval { $json->decode_prefix( "\n" ) }; ok( $@ =~ /malformed JSON/ ); eval { $json->decode_prefix('null') }; ok $@ =~ /allow_nonref/; JSON-2.90/t/99_binary.t0000644000175000017500000000314711750163317013153 0ustar reonreon# copied over from JSON::XS and modified to use JSON use Test::More; use strict; BEGIN { plan tests => 2432 }; BEGIN { $ENV{PERL_JSON_BACKEND} = "JSON::backportPP"; } BEGIN { use lib qw(t); use _unicode_handling; } use JSON; SKIP: { skip "UNICODE handling is disabale.", 2432 unless $JSON::can_handle_UTF16_and_utf8; sub test($) { my $js; $js = JSON->new->allow_nonref(0)->utf8->ascii->shrink->encode ([$_[0]]); ok ($_[0] eq ((decode_json $js)->[0])); $js = JSON->new->allow_nonref(0)->utf8->ascii->encode ([$_[0]]); ok ($_[0] eq (JSON->new->utf8->shrink->decode($js))->[0]); $js = JSON->new->allow_nonref(0)->utf8->shrink->encode ([$_[0]]); ok ($_[0] eq ((decode_json $js)->[0])); $js = JSON->new->allow_nonref(1)->utf8->encode ([$_[0]]); ok ($_[0] eq (JSON->new->utf8->shrink->decode($js))->[0]); $js = JSON->new->allow_nonref(1)->ascii->encode ([$_[0]]); ok ($_[0] eq JSON->new->decode ($js)->[0]); $js = JSON->new->allow_nonref(0)->ascii->encode ([$_[0]]); ok ($_[0] eq JSON->new->shrink->decode ($js)->[0]); $js = JSON->new->allow_nonref(1)->shrink->encode ([$_[0]]); ok ($_[0] eq JSON->new->decode ($js)->[0]); $js = JSON->new->allow_nonref(0)->encode ([$_[0]]); ok ($_[0] eq JSON->new->shrink->decode ($js)->[0]); } srand 0; # doesn't help too much, but its at least more deterministic #for (1..768) { for (1..64, 125..129, 255..257, 512, 704, 736, 768) { test join "", map chr ($_ & 255), 0..$_; test join "", map chr rand 255, 0..$_; test join "", map chr ($_ * 97 & ~0x4000), 0..$_; test join "", map chr (rand (2**20) & ~0x800), 0..$_; } } JSON-2.90/t/e12_upgrade.t0000644000175000017500000000111411651666007013440 0ustar reonreonuse strict; use Test::More; BEGIN { plan tests => 3 }; BEGIN { $ENV{PERL_JSON_BACKEND} = "JSON::backportPP"; } use JSON; BEGIN { use lib qw(t); use _unicode_handling; } my $json = JSON->new->allow_nonref->utf8; my $str = '\\u00c8'; my $value = $json->decode( '"\\u00c8"' ); #use Devel::Peek; #Dump( $value ); is( $value, chr 0xc8 ); SKIP: { skip "UNICODE handling is disabale.", 1 unless $JSON::can_handle_UTF16_and_utf8; ok( utf8::is_utf8( $value ) ); } eval { $json->decode( '"' . chr(0xc8) . '"' ) }; ok( $@ =~ /malformed UTF-8 character in JSON string/ ); JSON-2.90/t/12_blessed.t0000644000175000017500000000273511651666007013277 0ustar reonreon# copied over from JSON::XS and modified to use JSON use strict; use Test::More; BEGIN { plan tests => 16 }; BEGIN { $ENV{PERL_JSON_BACKEND} = "JSON::backportPP"; } use JSON; my $o1 = bless { a => 3 }, "XX"; my $o2 = bless \(my $dummy = 1), "YY"; sub XX::TO_JSON { {'__',""} } my $js = JSON->new; eval { $js->encode ($o1) }; ok ($@ =~ /allow_blessed/); eval { $js->encode ($o2) }; ok ($@ =~ /allow_blessed/); $js->allow_blessed; ok ($js->encode ($o1) eq "null"); ok ($js->encode ($o2) eq "null"); $js->convert_blessed; ok ($js->encode ($o1) eq '{"__":""}'); ok ($js->encode ($o2) eq "null"); $js->filter_json_object (sub { 5 }); $js->filter_json_single_key_object (a => sub { shift }); $js->filter_json_single_key_object (b => sub { 7 }); ok ("ARRAY" eq ref $js->decode ("[]")); ok (5 eq join ":", @{ $js->decode ('[{}]') }); ok (6 eq join ":", @{ $js->decode ('[{"a":6}]') }); ok (5 eq join ":", @{ $js->decode ('[{"a":4,"b":7}]') }); $js->filter_json_object; ok (7 == $js->decode ('[{"a":4,"b":7}]')->[0]{b}); ok (3 eq join ":", @{ $js->decode ('[{"a":3}]') }); $js->filter_json_object (sub { }); ok (7 == $js->decode ('[{"a":4,"b":7}]')->[0]{b}); ok (9 eq join ":", @{ $js->decode ('[{"a":9}]') }); $js->filter_json_single_key_object ("a"); ok (4 == $js->decode ('[{"a":4}]')->[0]{a}); #$js->filter_json_single_key_object (a => sub {}); $js->filter_json_single_key_object (a => sub { return; }); # sub {} is not suitable for Perl 5.6 ok (4 == $js->decode ('[{"a":4}]')->[0]{a}); JSON-2.90/t/xe02_bool.t0000644000175000017500000000123712234431225013127 0ustar reonreon#!/usr/bin/perl -w use strict; use Test::More; use strict; BEGIN { plan tests => 8 }; BEGIN { $ENV{PERL_JSON_BACKEND} = 1; } use JSON; SKIP: { skip "can't use JSON::XS.", 8, unless( JSON->backend->is_xs ); my $json = new JSON; is($json->encode([!1]), '[""]'); is($json->encode([!!2]), '["1"]'); is($json->encode([ 'a' eq 'b' ]), '[""]'); is($json->encode([ 'a' eq 'a' ]), '["1"]'); is($json->encode([ ('a' eq 'b') + 1 ]), '[1]'); is($json->encode([ ('a' eq 'a') + 1 ]), '[2]'); # discard overload hack for JSON::XS 3.0 boolean class #ok(JSON::true eq 'true'); #ok(JSON::true eq '1'); ok(JSON::true == 1); isa_ok(JSON::true, 'JSON::PP::Boolean'); } JSON-2.90/t/02_error.t0000644000175000017500000000467611651666007013014 0ustar reonreon# copied over from JSON::XS and modified to use JSON use strict; use Test::More; BEGIN { plan tests => 31 }; BEGIN { $ENV{PERL_JSON_BACKEND} = "JSON::backportPP"; } BEGIN { use lib qw(t); use _unicode_handling; } use utf8; use JSON; eval { JSON->new->encode ([\-1]) }; ok $@ =~ /cannot encode reference/; eval { JSON->new->encode ([\undef]) }; ok $@ =~ /cannot encode reference/; eval { JSON->new->encode ([\2]) }; ok $@ =~ /cannot encode reference/; eval { JSON->new->encode ([\{}]) }; ok $@ =~ /cannot encode reference/; eval { JSON->new->encode ([\[]]) }; ok $@ =~ /cannot encode reference/; eval { JSON->new->encode ([\\1]) }; ok $@ =~ /cannot encode reference/; eval { JSON->new->allow_nonref (1)->decode ('"\u1234\udc00"') }; ok $@ =~ /missing high /; eval { JSON->new->allow_nonref->decode ('"\ud800"') }; ok $@ =~ /missing low /; eval { JSON->new->allow_nonref (1)->decode ('"\ud800\u1234"') }; ok $@ =~ /surrogate pair /; eval { JSON->new->decode ('null') }; ok $@ =~ /allow_nonref/; eval { JSON->new->allow_nonref (1)->decode ('+0') }; ok $@ =~ /malformed/; eval { JSON->new->allow_nonref->decode ('.2') }; ok $@ =~ /malformed/; eval { JSON->new->allow_nonref (1)->decode ('bare') }; ok $@ =~ /malformed/; eval { JSON->new->allow_nonref->decode ('naughty') }; ok $@ =~ /null/; eval { JSON->new->allow_nonref (1)->decode ('01') }; ok $@ =~ /leading zero/; eval { JSON->new->allow_nonref->decode ('00') }; ok $@ =~ /leading zero/; eval { JSON->new->allow_nonref (1)->decode ('-0.') }; ok $@ =~ /decimal point/; eval { JSON->new->allow_nonref->decode ('-0e') }; ok $@ =~ /exp sign/; eval { JSON->new->allow_nonref (1)->decode ('-e+1') }; ok $@ =~ /initial minus/; eval { JSON->new->allow_nonref->decode ("\"\n\"") }; ok $@ =~ /invalid character/; eval { JSON->new->allow_nonref (1)->decode ("\"\x01\"") }; ok $@ =~ /invalid character/; eval { JSON->new->decode ('[5') }; ok $@ =~ /parsing array/; eval { JSON->new->decode ('{"5"') }; ok $@ =~ /':' expected/; eval { JSON->new->decode ('{"5":null') }; ok $@ =~ /parsing object/; eval { JSON->new->decode (undef) }; ok $@ =~ /malformed/; eval { JSON->new->decode (\5) }; ok !!$@; # Can't coerce readonly eval { JSON->new->decode ([]) }; ok $@ =~ /malformed/; eval { JSON->new->decode (\*STDERR) }; ok $@ =~ /malformed/; eval { JSON->new->decode (*STDERR) }; ok !!$@; # cannot coerce GLOB eval { decode_json ("\"\xa0") }; ok $@ =~ /malformed.*character/; eval { decode_json ("\"\xa0\"") }; ok $@ =~ /malformed.*character/; JSON-2.90/t/e09_encode.t0000644000175000017500000000151211651666007013256 0ustar reonreon# # decode on Perl 5.005, 5.6, 5.8 or later # use strict; use Test::More; BEGIN { plan tests => 7 }; BEGIN { $ENV{PERL_JSON_BACKEND} = "JSON::backportPP"; } use JSON; BEGIN { use lib qw(t); use _unicode_handling; } no utf8; my $json = JSON->new->allow_nonref; is($json->encode("ü"), q|"ü"|); # as is $json->ascii; is($json->encode("\xfc"), q|"\u00fc"|); # latin1 is($json->encode("\xc3\xbc"), q|"\u00c3\u00bc"|); # utf8 is($json->encode("ü"), q|"\u00c3\u00bc"|); # utf8 is($json->encode('あ'), q|"\u00e3\u0081\u0082"|); if ($] >= 5.006) { is($json->encode(chr hex 3042 ), q|"\u3042"|); is($json->encode(chr hex 12345 ), q|"\ud808\udf45"|); } else { is($json->encode(chr hex 3042 ), $json->encode(chr 66)); is($json->encode(chr hex 12345 ), $json->encode(chr 69)); } JSON-2.90/t/00_pod.t0000644000175000017500000000023111651666007012422 0ustar reonreonuse strict; $^W = 1; use Test::More; eval "use Test::Pod 1.00"; plan skip_all => "Test::Pod 1.00 required for testing POD" if $@; all_pod_files_ok (); JSON-2.90/t/13_limit.t0000644000175000017500000000154011651666007012766 0ustar reonreonuse strict; use Test::More; BEGIN { plan tests => 11 }; BEGIN { $ENV{PERL_JSON_BACKEND} = "JSON::backportPP"; } use JSON; my $def = 512; my $js = JSON->new; { local $^W = undef; # avoid for warning 'Deep recursion on subroutin' ok (!eval { $js->decode (("[" x ($def + 1)) . ("]" x ($def + 1))) }); ok (ref $js->decode (("[" x $def) . ("]" x $def))); ok (ref $js->decode (("{\"\":" x ($def - 1)) . "[]" . ("}" x ($def - 1)))); ok (!eval { $js->decode (("{\"\":" x $def) . "[]" . ("}" x $def)) }); ok (ref $js->max_depth (32)->decode (("[" x 32) . ("]" x 32))); ok ($js->max_depth(1)->encode ([])); ok (!eval { $js->encode ([[]]), 1 }); ok ($js->max_depth(2)->encode ([{}])); ok (!eval { $js->encode ([[{}]]), 1 }); ok (eval { ref $js->max_size (8)->decode ("[ ]") }); eval { $js->max_size (8)->decode ("[ ]") }; ok ($@ =~ /max_size/); } JSON-2.90/t/x02_error.t0000644000175000017500000000525111651666007013172 0ustar reonreonuse strict; use Test::More; BEGIN { plan tests => 31 }; BEGIN { $ENV{PERL_JSON_BACKEND} = 1; } local $^W; BEGIN { use lib qw(t); use _unicode_handling; } use utf8; use JSON; SKIP: { skip "can't use JSON::XS.", 31, unless( JSON->backend->is_xs ); eval { JSON->new->encode ([\-1]) }; ok $@ =~ /cannot encode reference/; eval { JSON->new->encode ([\undef]) }; ok $@ =~ /cannot encode reference/; eval { JSON->new->encode ([\2]) }; ok $@ =~ /cannot encode reference/; eval { JSON->new->encode ([\{}]) }; ok $@ =~ /cannot encode reference/; eval { JSON->new->encode ([\[]]) }; ok $@ =~ /cannot encode reference/; eval { JSON->new->encode ([\\1]) }; ok $@ =~ /cannot encode reference/; eval { JSON->new->allow_nonref (1)->decode ('"\u1234\udc00"') }; ok $@ =~ /missing high /; eval { JSON->new->allow_nonref->decode ('"\ud800"') }; ok $@ =~ /missing low /; eval { JSON->new->allow_nonref (1)->decode ('"\ud800\u1234"') }; ok $@ =~ /surrogate pair /; eval { JSON->new->decode ('null') }; ok $@ =~ /allow_nonref/; eval { JSON->new->allow_nonref (1)->decode ('+0') }; ok $@ =~ /malformed/; eval { JSON->new->allow_nonref->decode ('.2') }; ok $@ =~ /malformed/; eval { JSON->new->allow_nonref (1)->decode ('bare') }; ok $@ =~ /malformed/; eval { JSON->new->allow_nonref->decode ('naughty') }; ok $@ =~ /null/; eval { JSON->new->allow_nonref (1)->decode ('01') }; ok $@ =~ /leading zero/; eval { JSON->new->allow_nonref->decode ('00') }; ok $@ =~ /leading zero/; eval { JSON->new->allow_nonref (1)->decode ('-0.') }; ok $@ =~ /decimal point/; eval { JSON->new->allow_nonref->decode ('-0e') }; ok $@ =~ /exp sign/; eval { JSON->new->allow_nonref (1)->decode ('-e+1') }; ok $@ =~ /initial minus/; eval { JSON->new->allow_nonref->decode ("\"\n\"") }; ok $@ =~ /invalid character/; eval { JSON->new->allow_nonref (1)->decode ("\"\x01\"") }; ok $@ =~ /invalid character/; eval { JSON->new->decode ('[5') }; ok $@ =~ /parsing array/; eval { JSON->new->decode ('{"5"') }; ok $@ =~ /':' expected/; eval { JSON->new->decode ('{"5":null') }; ok $@ =~ /parsing object/; eval { JSON->new->decode (undef) }; ok $@ =~ /malformed/; eval { JSON->new->decode (\5) }; ok !!$@; # Can't coerce readonly eval { JSON->new->decode ([]) }; ok $@ =~ /malformed/; eval { JSON->new->decode (\*STDERR) }; ok $@ =~ /malformed/; eval { JSON->new->decode (*STDERR) }; ok !!$@; # cannot coerce GLOB # differences between JSON::XS and JSON::PP eval { decode_json ("\"\xa0") }; ok $@ =~ /malformed.*character/; eval { decode_json ("\"\xa0\"") }; ok $@ =~ /malformed.*character/; #eval { decode_json ("\"\xa0") }; ok $@ =~ /JSON text must be an object or array/; #eval { decode_json ("\"\xa0\"") }; ok $@ =~ /JSON text must be an object or array/; } JSON-2.90/t/00_load.t0000644000175000017500000000050411651666007012562 0ustar reonreonuse Test::More; use strict; BEGIN { plan tests => 5 }; BEGIN { $ENV{PERL_JSON_BACKEND} = "JSON::backportPP"; } BEGIN { use_ok('JSON'); } ok( exists $INC{ 'JSON/backportPP.pm' }, 'load backportPP' ); ok( ! exists $INC{ 'JSON/PP.pm' }, q/didn't load PP/ ); is( JSON->backend, 'JSON::PP' ); ok( JSON->backend->is_pp ); JSON-2.90/t/e00_func.t0000644000175000017500000000046511651666007012751 0ustar reonreon use Test::More; use strict; BEGIN { plan tests => 2 }; BEGIN { $ENV{PERL_JSON_BACKEND} = "JSON::backportPP"; } use JSON; ######################### my $json = JSON->new; my $js = 'abc'; is(to_json($js, {allow_nonref => 1}), '"abc"'); is(from_json('"abc"', {allow_nonref => 1}), 'abc'); JSON-2.90/t/22_comment_at_eof.t0000644000175000017500000000257111651666007014634 0ustar reonreon# the oritinal test case was provided by IKEGAMI@cpan.org use strict; use Test::More tests => 13; BEGIN { $ENV{PERL_JSON_BACKEND} = "JSON::backportPP"; } use JSON; use Data::Dumper qw( Dumper ); sub decoder { my ($str) = @_; my $json = JSON->new->relaxed; $json->incr_parse($_[0]); my $rv; if (!eval { $rv = $json->incr_parse(); 1 }) { $rv = "died with $@"; } local $Data::Dumper::Useqq = 1; local $Data::Dumper::Terse = 1; local $Data::Dumper::Indent = 0; return Dumper($rv); } is( decoder( "[]" ), '[]', 'array baseline' ); is( decoder( " []" ), '[]', 'space ignored before array' ); is( decoder( "\n[]" ), '[]', 'newline ignored before array' ); is( decoder( "# foo\n[]" ), '[]', 'comment ignored before array' ); is( decoder( "# fo[o\n[]"), '[]', 'comment ignored before array' ); is( decoder( "# fo]o\n[]"), '[]', 'comment ignored before array' ); is( decoder( "[# fo]o\n]"), '[]', 'comment ignored inside array' ); is( decoder( "" ), 'undef', 'eof baseline' ); is( decoder( " " ), 'undef', 'space ignored before eof' ); is( decoder( "\n" ), 'undef', 'newline ignored before eof' ); is( decoder( "#,foo\n" ), 'undef', 'comment ignored before eof' ); is( decoder( "# []o\n" ), 'undef', 'comment ignored before eof' ); is( decoder( qq/#\n[#foo\n"#\\n"#\n]/), '["#\n"]', 'array and string in multiple lines' ); JSON-2.90/t/e90_misc.t0000644000175000017500000000070411651666007012756 0ustar reonreon#!/usr/bin/perl use strict; use Test::More tests => 4; BEGIN { $ENV{ PERL_JSON_BACKEND } = $ARGV[0] || 'JSON::backportPP'; } use JSON; # reported by https://rt.cpan.org/Public/Bug/Display.html?id=68359 eval { JSON->to_json( 5, { allow_nonref => 1 } ) }; ok($@); is( q{"5"}, JSON::to_json( "5", { allow_nonref => 1 } ) ); is( q{5}, JSON::to_json( 5, { allow_nonref => 1 } ) ); is( q{"JSON"}, JSON::to_json( 'JSON', { allow_nonref => 1 } ) ); JSON-2.90/t/06_pc_pretty.t0000644000175000017500000000243111651666007013663 0ustar reonreon#! perl # copied over from JSON::PC and modified to use JSON # copied over from JSON::XS and modified to use JSON use strict; use Test::More; BEGIN { plan tests => 9 }; BEGIN { $ENV{PERL_JSON_BACKEND} = "JSON::backportPP"; } use JSON; my ($js,$obj,$json); my $pc = new JSON; $obj = {foo => "bar"}; $js = $pc->encode($obj); is($js,q|{"foo":"bar"}|); $obj = [10, "hoge", {foo => "bar"}]; $pc->pretty (1); $js = $pc->encode($obj); is($js,q|[ 10, "hoge", { "foo" : "bar" } ] |); $obj = { foo => [ {a=>"b"}, 0, 1, 2 ] }; $pc->pretty(0); $js = $pc->encode($obj); is($js,q|{"foo":[{"a":"b"},0,1,2]}|); $obj = { foo => [ {a=>"b"}, 0, 1, 2 ] }; $pc->pretty(1); $js = $pc->encode($obj); is($js,q|{ "foo" : [ { "a" : "b" }, 0, 1, 2 ] } |); $obj = { foo => [ {a=>"b"}, 0, 1, 2 ] }; $pc->pretty(0); $js = $pc->encode($obj); is($js,q|{"foo":[{"a":"b"},0,1,2]}|); $obj = {foo => "bar"}; $pc->indent(3); # original -- $pc->indent(1); is($pc->encode($obj), qq|{\n "foo":"bar"\n}\n|, "nospace"); $pc->space_after(1); is($pc->encode($obj), qq|{\n "foo": "bar"\n}\n|, "after"); $pc->space_before(1); is($pc->encode($obj), qq|{\n "foo" : "bar"\n}\n|, "both"); $pc->space_after(0); is($pc->encode($obj), qq|{\n "foo" :"bar"\n}\n|, "before"); JSON-2.90/t/18_json_checker.t0000644000175000017500000000747511651666007014327 0ustar reonreon#! perl # use the testsuite from http://www.json.org/JSON_checker/ # except for fail18.json, as we do not support a depth of 20 (but 16 and 32). # copied over from JSON::XS and modified to use JSON use strict; #no warnings; local $^W = undef; use Test::More; BEGIN { plan tests => 39 }; BEGIN { $ENV{PERL_JSON_BACKEND} = "JSON::backportPP"; } use JSON; my $json = JSON->new->utf8->max_depth(32)->canonical; binmode DATA; my $num = 1; for (;;) { $/ = "\n# "; chomp (my $test = ) or last; $/ = "\n"; my $name = ; if (my $perl = eval { $json->decode ($test) }) { ok ($name =~ /^pass/, $name); #print $json->encode ($perl), "\n"; is ($json->encode ($json->decode ($json->encode ($perl))), $json->encode ($perl)); } else { ok ($name =~ /^fail/, "$name ($@)"); } } __DATA__ "A JSON payload should be an object or array, not a string." # fail1.json {"Extra value after close": true} "misplaced quoted value" # fail10.json {"Illegal expression": 1 + 2} # fail11.json {"Illegal invocation": alert()} # fail12.json {"Numbers cannot have leading zeroes": 013} # fail13.json {"Numbers cannot be hex": 0x14} # fail14.json ["Illegal backslash escape: \x15"] # fail15.json [\naked] # fail16.json ["Illegal backslash escape: \017"] # fail17.json [[[[[[[[[[[[[[[[[[[[[[[[[[[[[[[[["Too deep"]]]]]]]]]]]]]]]]]]]]]]]]]]]]]]]]] # fail18.json {"Missing colon" null} # fail19.json ["Unclosed array" # fail2.json {"Double colon":: null} # fail20.json {"Comma instead of colon", null} # fail21.json ["Colon instead of comma": false] # fail22.json ["Bad value", truth] # fail23.json ['single quote'] # fail24.json [" tab character in string "] # fail25.json ["tab\ character\ in\ string\ "] # fail26.json ["line break"] # fail27.json ["line\ break"] # fail28.json [0e] # fail29.json {unquoted_key: "keys must be quoted"} # fail3.json [0e+] # fail30.json [0e+-1] # fail31.json {"Comma instead if closing brace": true, # fail32.json ["mismatch"} # fail33.json ["extra comma",] # fail4.json ["double extra comma",,] # fail5.json [ , "<-- missing value"] # fail6.json ["Comma after the close"], # fail7.json ["Extra close"]] # fail8.json {"Extra comma": true,} # fail9.json [ "JSON Test Pattern pass1", {"object with 1 member":["array with 1 element"]}, {}, [], -42, true, false, null, { "integer": 1234567890, "real": -9876.543210, "e": 0.123456789e-12, "E": 1.234567890E+34, "": 23456789012E66, "zero": 0, "one": 1, "space": " ", "quote": "\"", "backslash": "\\", "controls": "\b\f\n\r\t", "slash": "/ & \/", "alpha": "abcdefghijklmnopqrstuvwyz", "ALPHA": "ABCDEFGHIJKLMNOPQRSTUVWYZ", "digit": "0123456789", "0123456789": "digit", "special": "`1~!@#$%^&*()_+-={':[,]}|;.?", "hex": "\u0123\u4567\u89AB\uCDEF\uabcd\uef4A", "true": true, "false": false, "null": null, "array":[ ], "object":{ }, "address": "50 St. James Street", "url": "http://www.JSON.org/", "comment": "// /* */": " ", " s p a c e d " :[1,2 , 3 , 4 , 5 , 6 ,7 ],"compact":[1,2,3,4,5,6,7], "jsontext": "{\"object with 1 member\":[\"array with 1 element\"]}", "quotes": "" \u0022 %22 0x22 034 "", "\/\\\"\uCAFE\uBABE\uAB98\uFCDE\ubcda\uef4A\b\f\n\r\t`1~!@#$%^&*()_+-=[]{}|;:',./<>?" : "A key can be any string" }, 0.5 ,98.6 , 99.44 , 1066, 1e1, 0.1e1, 1e-1, 1e00,2e+00,2e-00 ,"rosebud"] # pass1.json [[[[[[[[[[[[[[[[[[["Not too deep"]]]]]]]]]]]]]]]]]]] # pass2.json { "JSON Test Pattern pass3": { "The outermost value": "must be an object or array.", "In this test": "It is an object." } } # pass3.json JSON-2.90/t/e07_allow_singlequote.t0000644000175000017500000000075711651666007015566 0ustar reonreon use Test::More; use strict; BEGIN { plan tests => 4 }; BEGIN { $ENV{PERL_JSON_BACKEND} = "JSON::backportPP"; } use JSON; ######################### my $json = JSON->new->allow_nonref; eval q| $json->decode("{'foo':'bar'}") |; ok($@); # in XS and PP, the error message differs. $json->allow_singlequote; is($json->decode(q|{'foo':"bar"}|)->{foo}, 'bar'); is($json->decode(q|{'foo':'bar'}|)->{foo}, 'bar'); is($json->allow_barekey->decode(q|{foo:'bar'}|)->{foo}, 'bar'); JSON-2.90/t/x00_load.t0000644000175000017500000000045312234431225012743 0ustar reonreon use strict; use Test::More; BEGIN { plan tests => 1 }; BEGIN { $ENV{PERL_JSON_BACKEND} = 1; } use JSON; SKIP: { skip "can't use JSON::XS.", 1, unless( JSON->backend->is_xs ); diag("load JSON::XS v." . JSON->backend->VERSION ); ok(1, "load JSON::XS v." . JSON->backend->VERSION ); } JSON-2.90/t/e11_conv_blessed_univ.t0000644000175000017500000000124111651666007015520 0ustar reonreon use strict; use Test::More; BEGIN { plan tests => 3 }; BEGIN { $ENV{PERL_JSON_BACKEND} = "JSON::backportPP"; } use JSON -convert_blessed_universally; my $obj = Test->new( [ 1, 2, {foo => 'bar'} ] ); $obj->[3] = Test2->new( { a => 'b' } ); my $json = JSON->new->allow_blessed->convert_blessed; is( $json->encode( $obj ), '[1,2,{"foo":"bar"},"hoge"]' ); $json->convert_blessed(0); is( $json->encode( $obj ), 'null' ); $json->allow_blessed(0)->convert_blessed(1); is( $json->encode( $obj ), '[1,2,{"foo":"bar"},"hoge"]' ); package Test; sub new { bless $_[1], $_[0]; } package Test2; sub new { bless $_[1], $_[0]; } sub TO_JSON { "hoge"; } JSON-2.90/t/_unicode_handling.pm0000644000175000017500000000076111651666007015153 0ustar reonreon#package utf8; package _unicode_handling; # this is a dummy pragma for 5.005. if ($] < 5.006) { $INC{'utf8.pm'} = './utf8.pm'; eval q| sub utf8::import { } sub utf8::unimport { } |; $JSON::can_handle_UTF16_and_utf8 = 0; } else { $JSON::can_handle_UTF16_and_utf8 = 1; if ($] > 5.007 and $] < 5.008003) { # $JSON::can_handle_UTF16_and_utf8 = 0; } } 1; JSON-2.90/t/x12_blessed.t0000644000175000017500000000260211651666007013460 0ustar reonreonuse strict; use Test::More; BEGIN { plan tests => 16 }; BEGIN { $ENV{PERL_JSON_BACKEND} = 1; } use JSON; SKIP: { skip "can't use JSON::XS.", 16, unless( JSON->backend->is_xs ); my $o1 = bless { a => 3 }, "XX"; my $o2 = bless \(my $dummy = 1), "YY"; sub XX::TO_JSON { {'__',""} } my $js = JSON->new; eval { $js->encode ($o1) }; ok ($@ =~ /allow_blessed/); eval { $js->encode ($o2) }; ok ($@ =~ /allow_blessed/); $js->allow_blessed; ok ($js->encode ($o1) eq "null"); ok ($js->encode ($o2) eq "null"); $js->convert_blessed; ok ($js->encode ($o1) eq '{"__":""}'); ok ($js->encode ($o2) eq "null"); $js->filter_json_object (sub { 5 }); $js->filter_json_single_key_object (a => sub { shift }); $js->filter_json_single_key_object (b => sub { 7 }); ok ("ARRAY" eq ref $js->decode ("[]")); ok (5 eq join ":", @{ $js->decode ('[{}]') }); ok (6 eq join ":", @{ $js->decode ('[{"a":6}]') }); ok (5 eq join ":", @{ $js->decode ('[{"a":4,"b":7}]') }); $js->filter_json_object; ok (7 == $js->decode ('[{"a":4,"b":7}]')->[0]{b}); ok (3 eq join ":", @{ $js->decode ('[{"a":3}]') }); $js->filter_json_object (sub { }); ok (7 == $js->decode ('[{"a":4,"b":7}]')->[0]{b}); ok (9 eq join ":", @{ $js->decode ('[{"a":9}]') }); $js->filter_json_single_key_object ("a"); ok (4 == $js->decode ('[{"a":4}]')->[0]{a}); $js->filter_json_single_key_object (a => sub {}); ok (4 == $js->decode ('[{"a":4}]')->[0]{a}); } JSON-2.90/t/xe08_decode.t0000644000175000017500000000151611651666007013437 0ustar reonreon# # decode on Perl 5.005, 5.6, 5.8 or later # use strict; use Test::More; BEGIN { plan tests => 6 }; BEGIN { $ENV{PERL_JSON_BACKEND} = 1; } use JSON; BEGIN { use lib qw(t); use _unicode_handling; } no utf8; SKIP: { skip "can't use JSON::XS.", 6, unless( JSON->backend->is_xs ); my $json = JSON->new->allow_nonref; is($json->decode(q|"ü"|), "ü"); # utf8 is($json->decode(q|"\u00fc"|), "\xfc"); # latin1 is($json->decode(q|"\u00c3\u00bc"|), "\xc3\xbc"); # utf8 my $str = 'あ'; # Japanese 'a' in utf8 is($json->decode(q|"\u00e3\u0081\u0082"|), $str); utf8::decode($str); # usually UTF-8 flagged on, but no-op for 5.005. is($json->decode(q|"\u3042"|), $str); my $utf8 = $json->decode(q|"\ud808\udf45"|); # chr 12345 utf8::encode($utf8); # UTf-8 flaged off is($utf8, "\xf0\x92\x8d\x85"); } JSON-2.90/t/xe11_conv_blessed_univ.t0000644000175000017500000000133511651666007015714 0ustar reonreon use strict; use Test::More; BEGIN { plan tests => 3 }; BEGIN { $ENV{PERL_JSON_BACKEND} = 1; } use JSON -convert_blessed_universally; SKIP: { skip "can't use JSON::XS.", 3, unless( JSON->backend->is_xs ); my $obj = Test->new( [ 1, 2, {foo => 'bar'} ] ); $obj->[3] = Test2->new( { a => 'b' } ); my $json = JSON->new->allow_blessed->convert_blessed; is( $json->encode( $obj ), '[1,2,{"foo":"bar"},"hoge"]' ); $json->convert_blessed(0); is( $json->encode( $obj ), 'null' ); $json->allow_blessed(0)->convert_blessed(1); is( $json->encode( $obj ), '[1,2,{"foo":"bar"},"hoge"]' ); } package Test; sub new { bless $_[1], $_[0]; } package Test2; sub new { bless $_[1], $_[0]; } sub TO_JSON { "hoge"; } JSON-2.90/t/xe04support_by_pp.t0000644000175000017500000000064511651666007014760 0ustar reonreonuse strict; use Test::More; BEGIN { plan tests => 3 }; BEGIN { $ENV{PERL_JSON_BACKEND} = 1; } use JSON -support_by_pp; SKIP: { skip "can't use JSON::XS.", 3, unless( JSON->backend->is_xs ); my $json = new JSON; is($json->escape_slash(0)->allow_nonref->encode("/"), '"/"'); is($json->escape_slash(1)->allow_nonref->encode("/"), '"\/"'); is($json->escape_slash(0)->allow_nonref->encode("/"), '"/"'); } __END__ JSON-2.90/t/xe01_property.t0000644000175000017500000000245711651666007014076 0ustar reonreon use Test::More; use strict; BEGIN { plan tests => 90 }; BEGIN { $ENV{PERL_JSON_BACKEND} = 1; } use JSON; SKIP: { skip "can't use JSON::XS.", 90, unless( JSON->backend->is_xs ); my @simples = qw/ascii latin1 utf8 indent canonical space_before space_after allow_nonref shrink allow_blessed convert_blessed relaxed /; my $json = new JSON; for my $name (@simples) { my $method = 'get_' . $name; ok(! $json->$method(), $method . ' default'); $json->$name(); ok($json->$method(), $method . ' set true'); $json->$name(0); ok(! $json->$method(), $method . ' set false'); $json->$name(); ok($json->$method(), $method . ' set true again'); } ok($json->get_max_depth == 512, 'get_max_depth default'); $json->max_depth(7); ok($json->get_max_depth == 7, 'get_max_depth set 7 => 7'); $json->max_depth(); ok($json->get_max_depth != 0, 'get_max_depth no arg'); ok($json->get_max_size == 0, 'get_max_size default'); $json->max_size(7); ok($json->get_max_size == 7, 'get_max_size set 7 => 7'); $json->max_size(); ok($json->get_max_size == 0, 'get_max_size no arg'); for my $name (@simples) { $json->$name(); ok($json->property($name), $name); $json->$name(0); ok(! $json->property($name), $name); $json->$name(); ok($json->property($name), $name); } } JSON-2.90/t/e08_decode.t0000644000175000017500000000142111651666007013242 0ustar reonreon# # decode on Perl 5.005, 5.6, 5.8 or later # use strict; use Test::More; BEGIN { plan tests => 6 }; BEGIN { $ENV{PERL_JSON_BACKEND} = "JSON::backportPP"; } use JSON; BEGIN { use lib qw(t); use _unicode_handling; } no utf8; my $json = JSON->new->allow_nonref; is($json->decode(q|"ü"|), "ü"); # utf8 is($json->decode(q|"\u00fc"|), "\xfc"); # latin1 is($json->decode(q|"\u00c3\u00bc"|), "\xc3\xbc"); # utf8 my $str = 'あ'; # Japanese 'a' in utf8 is($json->decode(q|"\u00e3\u0081\u0082"|), $str); utf8::decode($str); # usually UTF-8 flagged on, but no-op for 5.005. is($json->decode(q|"\u3042"|), $str); my $utf8 = $json->decode(q|"\ud808\udf45"|); # chr 12345 utf8::encode($utf8); # UTf-8 flaged off is($utf8, "\xf0\x92\x8d\x85"); JSON-2.90/t/x17_strange_overload.t0000644000175000017500000000074212234431225015373 0ustar reonreonuse strict; use Test::More; BEGIN { plan tests => 2 }; BEGIN { $ENV{PERL_JSON_BACKEND} = 1; } SKIP: { skip "for JSON::XS 3.x. cimpatible. Please see to Changes.", 2; eval q{ use JSON::XS; use JSON (); }; skip "can't use JSON::XS.", 2, if $@; skip "JSON::XS version < " . JSON->require_xs_version, 2 if JSON::XS->VERSION < JSON->require_xs_version; is("" . JSON::XS::true(), 'true'); is("" . JSON::true(), 'true'); } JSON-2.90/t/e02_bool.t0000644000175000017500000000121312234431225012731 0ustar reonreon#!/usr/bin/perl -w use strict; use Test::More; use strict; BEGIN { plan tests => 8 }; BEGIN { $ENV{PERL_JSON_BACKEND} = "JSON::backportPP"; } use JSON; my $json = new JSON; is($json->encode([!1]), '[""]'); is($json->encode([!!2]), '["1"]'); is($json->encode([ 'a' eq 'b' ]), '[""]'); is($json->encode([ 'a' eq 'a' ]), '["1"]'); is($json->encode([ ('a' eq 'b') + 1 ]), '[1]'); is($json->encode([ ('a' eq 'a') + 1 ]), '[2]'); # discard overload hack for JSON::XS 3.0 boolean class #ok(JSON::true eq 'true'); #ok(JSON::true eq '1'); ok(JSON::true == 1); isa_ok(JSON::true, 'JSON::PP::Boolean'); #isa_ok(JSON::true, 'JSON::Boolean'); JSON-2.90/t/xe20_croak_message.t0000644000175000017500000000061211651666007015005 0ustar reonreon#! perl # https://rt.cpan.org/Public/Bug/Display.html?id=61708 use strict; use Test::More; BEGIN { plan tests => 1 }; BEGIN { $ENV{PERL_JSON_BACKEND} = 1; } use JSON; # currently it can't pass with -support_by_pp; SKIP: { skip "can't use JSON::XS.", 1, unless( JSON->backend->is_xs ); my $json = JSON->new; eval q{ $json->encode( undef ) }; like( $@, qr/line 1\./ ); } JSON-2.90/t/14_latin1.t0000644000175000017500000000121111651666007013034 0ustar reonreon# copied over from JSON::XS and modified to use JSON use Test::More; use strict; BEGIN { plan tests => 4 }; BEGIN { $ENV{PERL_JSON_BACKEND} = "JSON::backportPP"; } BEGIN { use lib qw(t); use _unicode_handling; } use JSON; SKIP: { skip "UNICODE handling is disabale.", 4 unless $JSON::can_handle_UTF16_and_utf8; my $xs = JSON->new->latin1->allow_nonref; ok $xs->encode ("\x{12}\x{89} ") eq "\"\\u0012\x{89} \""; ok $xs->encode ("\x{12}\x{89}\x{abc}") eq "\"\\u0012\x{89}\\u0abc\""; ok $xs->decode ("\"\\u0012\x{89}\"" ) eq "\x{12}\x{89}"; ok $xs->decode ("\"\\u0012\x{89}\\u0abc\"") eq "\x{12}\x{89}\x{abc}"; } JSON-2.90/t/xe12_boolean.t0000644000175000017500000000114312234431225013610 0ustar reonreon use strict; use Test::More; BEGIN { plan tests => 4 }; BEGIN { $ENV{PERL_JSON_BACKEND} = 1; } use JSON -support_by_pp; BEGIN { use lib qw(t); use _unicode_handling; } SKIP: { skip "can't use JSON::XS.", 4, unless( JSON->backend->is_xs ); my $json = new JSON; my $bool = $json->allow_nonref->decode('true'); # it's normal isa_ok( $bool, 'JSON::PP::Boolean' ); is( $json->encode([ JSON::true ]), '[true]' ); # make XS non support flag enable! $bool = $json->allow_singlequote->decode('true'); isa_ok( $bool, 'JSON::PP::Boolean' ); is( $json->encode([ JSON::true ]), '[true]' ); } __END__ JSON-2.90/t/07_pc_esc.t0000644000175000017500000000415611651666007013115 0ustar reonreon# # このファイルのエンコーディングはUTF-8 # # copied over from JSON::PC and modified to use JSON # copied over from JSON::XS and modified to use JSON use Test::More; use strict; BEGIN { plan tests => 17 }; BEGIN { $ENV{PERL_JSON_BACKEND} = "JSON::backportPP"; } BEGIN { use lib qw(t); use _unicode_handling; } use utf8; use JSON; ######################### my ($js,$obj,$str); my $pc = new JSON; $obj = {test => qq|abc"def|}; $str = $pc->encode($obj); is($str,q|{"test":"abc\"def"}|); $obj = {qq|te"st| => qq|abc"def|}; $str = $pc->encode($obj); is($str,q|{"te\"st":"abc\"def"}|); $obj = {test => qq|abc/def|}; # / => \/ $str = $pc->encode($obj); # but since version 0.99 is($str,q|{"test":"abc/def"}|); # this handling is deleted. $obj = $pc->decode($str); is($obj->{test},q|abc/def|); $obj = {test => q|abc\def|}; $str = $pc->encode($obj); is($str,q|{"test":"abc\\\\def"}|); $obj = {test => "abc\bdef"}; $str = $pc->encode($obj); is($str,q|{"test":"abc\bdef"}|); $obj = {test => "abc\fdef"}; $str = $pc->encode($obj); is($str,q|{"test":"abc\fdef"}|); $obj = {test => "abc\ndef"}; $str = $pc->encode($obj); is($str,q|{"test":"abc\ndef"}|); $obj = {test => "abc\rdef"}; $str = $pc->encode($obj); is($str,q|{"test":"abc\rdef"}|); $obj = {test => "abc-def"}; $str = $pc->encode($obj); is($str,q|{"test":"abc-def"}|); $obj = {test => "abc(def"}; $str = $pc->encode($obj); is($str,q|{"test":"abc(def"}|); $obj = {test => "abc\\def"}; $str = $pc->encode($obj); is($str,q|{"test":"abc\\\\def"}|); $obj = {test => "あいうえお"}; $str = $pc->encode($obj); is($str,q|{"test":"あいうえお"}|); $obj = {"あいうえお" => "かきくけこ"}; $str = $pc->encode($obj); is($str,q|{"あいうえお":"かきくけこ"}|); $obj = $pc->decode(q|{"id":"abc\ndef"}|); is($obj->{id},"abc\ndef",q|{"id":"abc\ndef"}|); $obj = $pc->decode(q|{"id":"abc\\\ndef"}|); is($obj->{id},"abc\\ndef",q|{"id":"abc\\\ndef"}|); $obj = $pc->decode(q|{"id":"abc\\\\\ndef"}|); is($obj->{id},"abc\\\ndef",q|{"id":"abc\\\\\ndef"}|); JSON-2.90/t/e04_sortby.t0000644000175000017500000000126111651666007013337 0ustar reonreon use Test::More; use strict; BEGIN { plan tests => 3 }; BEGIN { $ENV{PERL_JSON_BACKEND} = "JSON::backportPP"; } use JSON; ######################### my ($js,$obj); my $pc = JSON->new; $obj = {a=>1, b=>2, c=>3, d=>4, e=>5, f=>6, g=>7, h=>8, i=>9}; $js = $pc->sort_by(1)->encode($obj); is($js, q|{"a":1,"b":2,"c":3,"d":4,"e":5,"f":6,"g":7,"h":8,"i":9}|); $js = $pc->sort_by(sub { $JSON::PP::a cmp $JSON::PP::b })->encode($obj); is($js, q|{"a":1,"b":2,"c":3,"d":4,"e":5,"f":6,"g":7,"h":8,"i":9}|); $js = $pc->sort_by('hoge')->encode($obj); is($js, q|{"a":1,"b":2,"c":3,"d":4,"e":5,"f":6,"g":7,"h":8,"i":9}|); sub JSON::PP::hoge { $JSON::PP::a cmp $JSON::PP::b } JSON-2.90/t/e01_property.t0000644000175000017500000000275111651666007013703 0ustar reonreon use Test::More; use strict; BEGIN { plan tests => 90 }; BEGIN { $ENV{PERL_JSON_BACKEND} = "JSON::backportPP"; } BEGIN { use lib qw(t); use _unicode_handling; } use JSON; my @simples = qw/utf8 indent canonical space_before space_after allow_nonref shrink allow_blessed convert_blessed relaxed /; if ($JSON::can_handle_UTF16_and_utf8) { unshift @simples, 'ascii'; unshift @simples, 'latin1'; } SKIP: { skip "UNICODE handling is disabale.", 14 unless $JSON::can_handle_UTF16_and_utf8; } my $json = new JSON; for my $name (@simples) { my $method = 'get_' . $name; ok(! $json->$method(), $method . ' default'); $json->$name(); ok($json->$method(), $method . ' set true'); $json->$name(0); ok(! $json->$method(), $method . ' set false'); $json->$name(); ok($json->$method(), $method . ' set true again'); } ok($json->get_max_depth == 512, 'get_max_depth default'); $json->max_depth(7); ok($json->get_max_depth == 7, 'get_max_depth set 7 => 7'); $json->max_depth(); ok($json->get_max_depth != 0, 'get_max_depth no arg'); ok($json->get_max_size == 0, 'get_max_size default'); $json->max_size(7); ok($json->get_max_size == 7, 'get_max_size set 7 => 7'); $json->max_size(); ok($json->get_max_size == 0, 'get_max_size no arg'); for my $name (@simples) { $json->$name(); ok($json->property($name), $name); $json->$name(0); ok(! $json->property($name), $name); $json->$name(); ok($json->property($name), $name); } JSON-2.90/t/e15_tie_ixhash.t0000644000175000017500000000130211651666007014140 0ustar reonreon use strict; use Test::More; BEGIN { plan tests => 2 }; BEGIN { $ENV{PERL_JSON_BACKEND} = "JSON::backportPP"; } use JSON; # from https://rt.cpan.org/Ticket/Display.html?id=25162 SKIP: { eval {require Tie::IxHash}; skip "Can't load Tie::IxHash.", 2 if ($@); my %columns; tie %columns, 'Tie::IxHash'; %columns = ( id => 'int', 1 => 'a', 2 => 'b', 3 => 'c', 4 => 'd', 5 => 'e', ); my $js = to_json(\%columns); is( $js, q/{"id":"int","1":"a","2":"b","3":"c","4":"d","5":"e"}/ ); $js = to_json(\%columns, {pretty => 1}); is( $js, <<'STR' ); { "id" : "int", "1" : "a", "2" : "b", "3" : "c", "4" : "d", "5" : "e" } STR } JSON-2.90/t/e03_bool2.t0000644000175000017500000000220512234431225013016 0ustar reonreonuse Test::More; BEGIN { plan tests => 16 }; BEGIN { $ENV{PERL_JSON_BACKEND} = "JSON::backportPP"; } use JSON; is(to_json([JSON::true]), q|[true]|); is(to_json([JSON::false]), q|[false]|); is(to_json([JSON::null]), q|[null]|); my $jsontext = q|[true,false,null]|; my $obj = from_json($jsontext); #push @JSON::backportPP::Boolean::ISA, 'JSON::Boolean'; isa_ok($obj->[0], 'JSON::PP::Boolean'); isa_ok($obj->[1], 'JSON::PP::Boolean'); ok(!defined $obj->[2], 'null is undef'); ok($obj->[0] == 1); ok($obj->[0] != 0); ok($obj->[1] == 0); ok($obj->[1] != 1); # discard overload hack for JSON::XS 3.0 boolean class #ok($obj->[0] eq 'true', 'eq true'); #ok($obj->[0] ne 'false', 'ne false'); #ok($obj->[1] eq 'false', 'eq false'); #ok($obj->[1] ne 'true', 'ne true'); ok($obj->[0] eq $obj->[0]); ok($obj->[0] ne $obj->[1]); #ok(JSON::true eq 'true'); #ok(JSON::true ne 'false'); #ok(JSON::true ne 'null'); #ok(JSON::false eq 'false'); #ok(JSON::false ne 'true'); #ok(JSON::false ne 'null'); ok(!defined JSON::null); is(from_json('[true]' )->[0], JSON::true); is(from_json('[false]')->[0], JSON::false); is(from_json('[null]' )->[0], JSON::null); JSON-2.90/t/xe21_is_pp.t0000644000175000017500000000112712153776166013325 0ustar reonreon#!/usr/bin/perl -w use strict; use Test::More; BEGIN { plan tests => 5 }; BEGIN { $ENV{PERL_JSON_BACKEND} = 1; } use JSON; my $json = JSON->new(); ok( $json->backend, 'backend is ' . $json->backend ); if ( $json->backend->is_xs ) { ok (!JSON->is_pp(), 'JSON->is_pp()'); ok ( JSON->is_xs(), 'JSON->is_xs()'); ok (!$json->is_pp(), '$json->is_pp()'); ok ( $json->is_xs(), '$json->is_xs()'); } else { ok ( JSON->is_pp(), 'JSON->is_pp()'); ok (!JSON->is_xs(), 'JSON->is_xs()'); ok ( $json->is_pp(), '$json->is_pp()'); ok (!$json->is_xs(), '$json->is_xs()'); } JSON-2.90/t/e13_overloaded_eq.t0000644000175000017500000000167311651666007014635 0ustar reonreon#!/usr/bin/perl use strict; use Test::More tests => 4; BEGIN { $ENV{ PERL_JSON_BACKEND } = "JSON::backportPP"; } use JSON; my $json = JSON->new->convert_blessed; my $obj = OverloadedObject->new( 'foo' ); ok( $obj eq 'foo' ); is( $json->encode( [ $obj ] ), q{["foo"]} ); # rt.cpan.org #64783 my $foo = bless {}, 'Foo'; my $bar = bless {}, 'Bar'; eval q{ $json->encode( $foo ) }; ok($@); eval q{ $json->encode( $bar ) }; ok(!$@); package Foo; use strict; use overload ( 'eq' => sub { 0 }, '""' => sub { $_[0] }, fallback => 1, ); sub TO_JSON { return $_[0]; } package Bar; use strict; use overload ( 'eq' => sub { 0 }, '""' => sub { $_[0] }, fallback => 1, ); sub TO_JSON { return overload::StrVal($_[0]); } package OverloadedObject; use overload 'eq' => sub { $_[0]->{v} eq $_[1] }, '""' => sub { $_[0]->{v} }, fallback => 1; sub new { bless { v => $_[1] }, $_[0]; } sub TO_JSON { "$_[0]"; } JSON-2.90/t/15_prefix.t0000644000175000017500000000071411651666007013151 0ustar reonreon# copied over from JSON::XS and modified to use JSON BEGIN { $| = 1; print "1..4\n"; } BEGIN { $ENV{PERL_JSON_BACKEND} = "JSON::backportPP"; } use JSON; my $xs = JSON->new->allow_nonref; eval { $xs->decode ("[] ") }; print $@ ? "not " : "", "ok 1\n"; eval { $xs->decode ("[] x") }; print $@ ? "" : "not ", "ok 2\n"; print 2 == ($xs->decode_prefix ("[][]"))[1] ? "" : "not ", "ok 3\n"; print 3 == ($xs->decode_prefix ("[1] t"))[1] ? "" : "not ", "ok 4\n"; JSON-2.90/t/10_pc_keysort.t0000644000175000017500000000072211651666007014030 0ustar reonreon# copied over from JSON::PC and modified to use JSON # copied over from JSON::XS and modified to use JSON use Test::More; use strict; BEGIN { plan tests => 1 }; BEGIN { $ENV{PERL_JSON_BACKEND} = "JSON::backportPP"; } use JSON; ######################### my ($js,$obj); my $pc = JSON->new->canonical(1); $obj = {a=>1, b=>2, c=>3, d=>4, e=>5, f=>6, g=>7, h=>8, i=>9}; $js = $pc->encode($obj); is($js, q|{"a":1,"b":2,"c":3,"d":4,"e":5,"f":6,"g":7,"h":8,"i":9}|); JSON-2.90/Changes0000644000175000017500000003207512234431225012205 0ustar reonreonRevision history for Perl extension JSON. ## JSON version 2.9 ##################################################### CAUTION!!! INCOMPATIBLE CHANGE JSON.pm had patched JSON::XS::Boolean and JSON::PP::Boolean internally on loading time for making these modules inherit JSON::Boolean. But since JSON::XS v3.0 it use Types::Serialiser as boolean class. Then now JSON.pm breaks boolean classe overload features and -support_by_pp if JSON::XS v3.0 or later is installed. JSON::true and JSON::false returned JSON::Boolean objects. For workaround, they return JSON::PP::Boolean objects in this version. isa_ok(JSON::true, 'JSON::PP::Boolean'); And it discards a feature: ok(JSON::true eq 'true'); In other word, JSON::PP::Boolean overload numeric only. ok( JSON::true == 1 ); ########################################################################## 2.90 Wed Oct 30 19:48:43 2013 **** Please see to the headline in this file. **** - workaround for JSON::XS version 3.0 or later installed case. * the objects returned by JSON::true/false are JSON::PP::Boolean. * they do not overload 'eq'. - changed test cases for this patch. t/e02_bool.t t/e03_bool2.t t/x17_strange_overload.t t/xe02_bool.t t/xe03_bool2.t t/xe12_boolean.t **** Please see to the headline in this file. **** 2.61 Thu Oct 17 19:38:55 2013 - fixed return/or in _incr_parse reported and patched by MAUKE, sprout and rjbs https://rt.cpan.org/Public/Bug/Display.html?id=86948 2.60 - $json->is_xs, $json->is_pp was completely broken. pointed by rt#75867 and emceelam 2.59 Wed Jun 5 14:35:54 2013 - PUREPERL_ONLY support was not supported... and finally remove all PP options from Makefile.PL. - recommend JSON::XS instead of conditionally requiring it patched by miyagaw ( for example, $ cpanm --with-recommends JSON) - Hide more packages from PAUSE (and other stuff) patched by miyagawa 2.58 Thu May 23 09:04:37 2013 - support PUREPERL_ONLY install option. (rt#84876) (PERL_ONLY and NO_XS are not yet removed) - stop installing JSON::XS automatically on Perl 5.18 2.57 - t/x17_strage_overload.t didn't work correctly. 2.56 Sat Apr 6 09:58:32 2013 - fixed t/x17_strage_overload.t (rt#84451 by Ricardo Signes) 2.55 - update JSON::BackportPP version 2.54 Fri Apr 5 16:15:08 2013 - fixed t/19_incr.t on perl >= 5.17.10 (wyant, rt#84154) pathced by mbeijen and modified with demerphq's patch - Fixed some spelling (by briandfoy) - fixed sppeling (by Perlover) - enhanced documents (Thanks to Justin Hunter and Olof Johansson) - changed backend module loading for overloaded object behavior (reported by tokuhirom) 2.53 Sun May 22 16:11:05 2011 - made Makefile.PL skipping a installing XS question when set $ENV{PERL_ONLY} or $ENV{NO_XS} (rt#66820) 2.52 Sun May 22 15:05:49 2011 - fixed to_json (pointed and patched by mmcleric in rt#68359) - backport JSON::PP 2.27200 * fixed incr_parse docodeing string more correctly (rt#68032 by LCONS) 2.51 Tue Mar 8 16:03:34 2011 - import JSON::PP 2.27105 as BackportPP - fixed documentations (pointed by Britton Kerin and rt#64738) 2.50 Mon Dec 20 14:56:42 2010 [JSON] - stable release 2.49_01 Sat Nov 27 22:03:17 2010 [JSON] - JSON::PP is split away JSON distributino for perl 5.14 - JSON::backportPP is included in instead. 2.27 Sun Oct 31 20:32:46 2010 [JSON::PP] - Some optimizations (gfx) [JSON::PP::5005] - added missing B module varibales (makamaka) 2.26 Tue Sep 28 17:41:37 2010 [JSON::PP] - cleaned up code and enhanced sort option efficiency in encode. 2.25 Tue Sep 28 16:47:08 2010 [JSON] - JSON::Backend::XS::Supportable always executed a needless process with JSON::XS backend. This made encode/decode a bit slower. 2.24 Mon Sep 27 10:56:24 2010 [JSON::PP] - tweaked code. - optimized code in hash object encoding. 2.23 Sun Sep 26 22:08:12 2010 [JSON::PP] - modified tied object handling in encode. it made encoding speed faster. pointed by https://rt.cpan.org/Ticket/Display.html?id=61604 - modified t/e10_bignum.t for avoiding a warning in using Math::BigInt dev version 2.22 Wed Aug 25 12:46:13 2010 [JSON] - added JSON::XS installing feature in Makefile.PL with cpan or cpanm (some points suggested by gfx) - check that to_json and from_json are not called as methods (CHORNY) [JSON::PP] - modified for -Duse64bitall -Duselongdouble compiled perl. 11_pc_expo.t too. (these are patched by H.Merijn Brand) 2.21 Mon Apr 5 14:56:52 2010 [JSON] - enhanced 'HOW DO I DECODE A DATA FROM OUTER AND ENCODE TO OUTER' - renamed eg/bench_pp_xs.pl to eg/bench_decode.pl - added eg/bench_encode.pl 2.20 Fri Apr 2 12:50:08 2010 [JSON] - added eg/bench_pp_xs.pl for benchmark sample - updated 'INCREMENTAL PARSING' section [JSON::PP] - decode_prefix() didn't count a consumed text length properly. - enhanced XS compatibilty in the case of decoding a white space garbaged text. 2.19 Tue Mar 30 13:40:24 2010 [JSON] - fixed typo (rt#53535 by Angel Abad) - added a recommendation refering to (en|de)code_json to pod (suggested by tokuhirom) - added 'HOW DO I DECODE A DATA FROM OUTER AND ENCODE TO OUTER' to pod. 2.18 Tue Mar 23 15:18:10 2010 [JSON] - updated document (compatible with JSON::XS 2.29) [JSON::PP] - fixed encode an overloaded 'eq' object bug (reported by Alexey A. Kiritchun) - enhanced an error message compatible to JSON::XS 2.17 Thu Jan 7 12:23:13 2010 [JSON] - fixed a problem caused by JSON::XS backend and support_by_pp option (rt#52842, rt#52847 by ikegami) [JSON::PP] - made compatible with JSON::XS 2.27 - patched decode for incr_parse (rt#52820 by ikegami) - relaxed option caused an infinite loop in some condition. 2.16 Fri Oct 16 15:07:37 2009 [JSON][JSON::PP] - made compatible with JSON::XS 2.26 *indent adds a final newline - corrected copyrights in JSON::PP58. 2.15 Tue Jun 2 16:36:42 2009 [JSON] - made compatible with JSON::XS 2.24 - corrected copyrights in some modules. [JSON::PP] - modified incr_parse, pointed by Martin J. Evans (rt#46439) - deleted a meaningless code 2.14 Tue Feb 24 11:20:24 2009 [JSON] - the compatible XS version was miswritten in document. 2.13 Sat Feb 21 17:01:05 2009 [JSON::PP] - decode() didn't upgrade unicode escaped charcters \u0080-\u00ff. this problem was pointed by rt#43424 (Mika Raento) [JSON::PP::56] - fixed utf8::encode/decode emulators bugs. - defined a missing B module constant in Perl 5.6.0. (reported by Clinton Pierce) [JSON::PP::5005] - _decode_unicode() returned a 0x80-0xff value as UTF8 encoded byte. [JSON] - added a refference to JSON::XS's document "JSON and ECMAscript". - fixed a typo in the document (pointed by Jim Cromie). 2.12 Wed Jul 16 11:14:35 2008 [JSON] - made compatible with JSON::XS 2.22 [JSON::PP] - fixed the incremental parser in negative nest level (pointed and patched by Yuval Kogman) 2.11 Tue Jun 17 14:30:01 2008 [JSON::PP] - fixed the decoding process which checks number. regarded number like chars in Unicode (ex. U+FF11) as [\d]. - enhanced error messages compatible to JSON::XS. 2.10 Tue Jun 3 18:42:11 2008 [JSON] - made compatible with JSON::XS 2.21 * updated the document. - added an item pointed by rt#32361 to the doc. [JSON::PP] [JSON::PP58] [JSON::PP56] [JSON::PP5005] - made compatible with JSON::XS 2.21 * added incr_reset - removed useless codes. 2.09 Sun Apr 20 20:45:33 2008 [JSON] - made compatible with JSON::XS 2.2 - changed pod section totally. [JSON::PP] 2.20001 - made compatible witg JSON::XS 2.2 * lifted the log2 rounding restriction of max_depth and max_size. * incremental json parsing (EXPERIMENTAL). * allow_unknown/get_allow_unknown methods. - the version format was changed. X.YYZZZ => X.YY is the same as JSON::XS. ZZZ is the PP own version. - changed pod section totally. 2.08 Sat Apr 12 22:49:39 2008 [JSON] - fixed JSON::Boolean inheritance mechanism. If the backend is XS with support_by_pp mode and using PP only support method, JSON::Boolean did not work correctly. Thanks to hg[at]apteryx's point. [JSON::PP] 2.07 - Now split into JSON::PP58 for Perl 5.8 and lator. - enhanced an error message compatible to JSON::XS did not croak when TO_JSON method returns same object as passed. [JSON::PP58] - modified for Perls post 5.8.0 that don't have utf8::is_utf8. Thanks to Andreas Koenig. 2.07 Sat Feb 16 15:52:29 2008 [JSON] - experimentally added -convert_blessed_universally to define UNIVERSAL::TO_JSON subroutine. use JSON -convert_blessed_universally; $json->convert_blessed->encode( $blessed ); - and as_nonbleesed is obsoleted (not yet removed). OK? - fixed t/04_pretty.t. 2.06 Fri Feb 8 16:21:59 2008 [JSON::PP] 2.06 - enhanced the XS compatibility for pretty-printing and the indent handling was broken! 2.05 Tue Feb 5 13:57:19 2008 [JSON::PP] 2.05 - enhanced some XS compatibilities for de/encode. - now decode_error can dump high (>127) chars. - enhanced the XS combatilbity of the decoding error. - fixed the utf8 checker while decoding (is_valid_utf8). - implemented utf8::downgrade in JSON::PP56. - enhanced utf8::encode in JSON::PP56. - made utf8::downgrade return a true in JSON::PP5005. 2.04 Sat Jan 5 16:10:01 2008 [JSON] - fixed a document typo pointed by kawasaki@annocpan - make DATA handle closed for error mssages in support_by_pp mode. - switched JSON::Backend::XS::Supportable wrapper de/encode to changing symbolic tables for croak messages and speed. - fixed support_by_pp setting [JSON::PP] 2.04 - enhanced the error message compatiblity to XS. 2.03 Fri Jan 4 14:10:58 2008 [JSON] - fixed the description - Transition ways from 1.xx to 2.xx. $JSON::ConvBlessed compat => $json->allow_blessed->as_nonbleesed - support_by_pp supports 'as_nonbleesed' (experimental) - clean up the code for saving memory [JSON::PP] 2.03 - Now the allo_bignum flag also affects the encoding process. encode() can convert Math::BigInt/Float objects into JSON numbers - added as_nonblessed option (experimental) - cleaned up internal function names (renamed camel case names) 2.02 Wed Dec 26 11:08:19 2007 [JSON] - Now support_by_pp allows to use indent_length() [JSON::PP] 2.02 - added get_indent_length 2.01 Thu Dec 20 11:30:59 2007 [JSON] - made the object methods - jsonToObj and objToJson available for a while with warnings. 2.00 Wed Dec 19 11:48:04 2007 [JSON] - new version! - modified Makefile.PL for broken Perls (when PERL_DL_NONLAZY = 1). [JSON::PP] 2.0104 - clean up the document. - use 'subs' instead of CORE::GLOBAL for fixing join() in 5.8.0 - 5.8.2 - enhanced decoding error messages for JSON::XS compatibility. - jsonToObj and objToJson warn. 1.99_05 Fri Dec 14 18:30:43 2007 [JSON] - added a description about the Unicode handling to document. [JSON::PP] (2.0103) - Now the JSON::PP56 unicode handling does not require Unicode::String. - Now JSON::PP5005 can de/enocde properly within the Perl 5.005 world. - decode() always utf8::decode()ed to strings. - decode() returned a big integer as string though the integer is smaller than it is so. - a bad know how - added the join() wrapper for Perl 5.8.0 - 5.8.2 bug. - JSON::PP56 encode() did not handle Unicode properly. - added a section about the unicode handling on Perls to JSON::PP doc. 1.99_04 Mon Dec 10 14:28:15 2007 [JSON] - modified the tests and source for Perl 5.005 [JSON::PP] (2.0102) - modified some prototypes in JSON::PP5005. 1.99_03 Mon Dec 10 11:43:02 2007 [JSON] - modified tests and document. in Perl5.8.2 or earlier, decoding with utf8 is broken because of a Perl side problem. (join() had a bug.) - modified Makefile.PL for Perl 5.005. in the version, 'require JSON' is fail.... [JSON::PP] (2.0102) - modified string decode function. - enhanced error messages for compatibility to JSON::XS. - enhanced utf8::decode emulator and unpack emulator in JSON::PP56. 1.99_02 Sun Dec 9 05:06:19 2007 [JSON::PP] (2.0101) - decoding with utf8 was broken in Perl 5.10 as the behaviour of unpack was changed. - added a fake in JSON::PP5005 (bytes.pm) - added the missing file JONS::PP::Boolean.pm 1.99_01 Sat Dec 8 12:01:43 2007 [JSON] - released as version 2.0 this module is incompatible to 1.xx, so check the document. [JSON::PP] (2.01 from 0.97) - updated JSON::PP for compatible to JSON::XS 2.01 - renamed from_json and to_json to decode_json and encode_json - added get_* to JSON::PP - deleted property() from JSON::PP - deleted strict() and added loose() - deleted disable_UTF8() and self_encode() - renamed singlequote to allow_singlequote - renamed allow_bigint to allow_bignum - max_depth and max_size round up their arguments. - added indent_length and sort_by ## JSON version 1.xx 1.15 Wed Nov 14 14:52:31 2007 - 1.xx final version. 0.09 Sat Apr 9 15:27:47 2005 - original version; created by h2xs 1.22 with options -XA -b 5.5.3 -n JSON JSON-2.90/lib/0000755000175000017500000000000012234431435011454 5ustar reonreonJSON-2.90/lib/JSON/0000755000175000017500000000000012234431435012225 5ustar reonreonJSON-2.90/lib/JSON/backportPP/0000755000175000017500000000000012234431435014272 5ustar reonreonJSON-2.90/lib/JSON/backportPP/Boolean.pm0000644000175000017500000000066112127460043016210 0ustar reonreon=head1 NAME JSON::PP::Boolean - dummy module providing JSON::PP::Boolean =head1 SYNOPSIS # do not "use" yourself =head1 DESCRIPTION This module exists only to provide overload resolution for Storable and similar modules. See L for more info about this class. =cut use JSON::backportPP (); use strict; 1; =head1 AUTHOR This idea is from L written by Marc Lehmann =cut JSON-2.90/lib/JSON/backportPP/Compat5006.pm0000644000175000017500000000736512127460043016377 0ustar reonreonpackage # This is JSON::backportPP JSON::backportPP56; use 5.006; use strict; my @properties; $JSON::PP56::VERSION = '1.08'; BEGIN { sub utf8::is_utf8 { my $len = length $_[0]; # char length { use bytes; # byte length; return $len != length $_[0]; # if !=, UTF8-flagged on. } } sub utf8::upgrade { ; # noop; } sub utf8::downgrade ($;$) { return 1 unless ( utf8::is_utf8( $_[0] ) ); if ( _is_valid_utf8( $_[0] ) ) { my $downgrade; for my $c ( unpack( "U*", $_[0] ) ) { if ( $c < 256 ) { $downgrade .= pack("C", $c); } else { $downgrade .= pack("U", $c); } } $_[0] = $downgrade; return 1; } else { Carp::croak("Wide character in subroutine entry") unless ( $_[1] ); 0; } } sub utf8::encode ($) { # UTF8 flag off if ( utf8::is_utf8( $_[0] ) ) { $_[0] = pack( "C*", unpack( "C*", $_[0] ) ); } else { $_[0] = pack( "U*", unpack( "C*", $_[0] ) ); $_[0] = pack( "C*", unpack( "C*", $_[0] ) ); } } sub utf8::decode ($) { # UTF8 flag on if ( _is_valid_utf8( $_[0] ) ) { utf8::downgrade( $_[0] ); $_[0] = pack( "U*", unpack( "U*", $_[0] ) ); } } *JSON::PP::JSON_PP_encode_ascii = \&_encode_ascii; *JSON::PP::JSON_PP_encode_latin1 = \&_encode_latin1; *JSON::PP::JSON_PP_decode_surrogates = \&JSON::PP::_decode_surrogates; *JSON::PP::JSON_PP_decode_unicode = \&JSON::PP::_decode_unicode; unless ( defined &B::SVp_NOK ) { # missing in B module. eval q{ sub B::SVp_NOK () { 0x02000000; } }; } } sub _encode_ascii { join('', map { $_ <= 127 ? chr($_) : $_ <= 65535 ? sprintf('\u%04x', $_) : sprintf('\u%x\u%x', JSON::PP::_encode_surrogates($_)); } _unpack_emu($_[0]) ); } sub _encode_latin1 { join('', map { $_ <= 255 ? chr($_) : $_ <= 65535 ? sprintf('\u%04x', $_) : sprintf('\u%x\u%x', JSON::PP::_encode_surrogates($_)); } _unpack_emu($_[0]) ); } sub _unpack_emu { # for Perl 5.6 unpack warnings return !utf8::is_utf8($_[0]) ? unpack('C*', $_[0]) : _is_valid_utf8($_[0]) ? unpack('U*', $_[0]) : unpack('C*', $_[0]); } sub _is_valid_utf8 { my $str = $_[0]; my $is_utf8; while ($str =~ /(?: ( [\x00-\x7F] |[\xC2-\xDF][\x80-\xBF] |[\xE0][\xA0-\xBF][\x80-\xBF] |[\xE1-\xEC][\x80-\xBF][\x80-\xBF] |[\xED][\x80-\x9F][\x80-\xBF] |[\xEE-\xEF][\x80-\xBF][\x80-\xBF] |[\xF0][\x90-\xBF][\x80-\xBF][\x80-\xBF] |[\xF1-\xF3][\x80-\xBF][\x80-\xBF][\x80-\xBF] |[\xF4][\x80-\x8F][\x80-\xBF][\x80-\xBF] ) | (.) )/xg) { if (defined $1) { $is_utf8 = 1 if (!defined $is_utf8); } else { $is_utf8 = 0 if (!defined $is_utf8); if ($is_utf8) { # eventually, not utf8 return; } } } return $is_utf8; } 1; __END__ =pod =head1 NAME JSON::PP56 - Helper module in using JSON::PP in Perl 5.6 =head1 DESCRIPTION JSON::PP calls internally. =head1 AUTHOR Makamaka Hannyaharamitu, Emakamaka[at]cpan.orgE =head1 COPYRIGHT AND LICENSE Copyright 2007-2012 by Makamaka Hannyaharamitu This library is free software; you can redistribute it and/or modify it under the same terms as Perl itself. =cut JSON-2.90/lib/JSON/backportPP/Compat5005.pm0000644000175000017500000000536512127460043016374 0ustar reonreonpackage # This is JSON::backportPP JSON::backportPP5005; use 5.005; use strict; my @properties; $JSON::PP5005::VERSION = '1.10'; BEGIN { sub utf8::is_utf8 { 0; # It is considered that UTF8 flag off for Perl 5.005. } sub utf8::upgrade { } sub utf8::downgrade { 1; # must always return true. } sub utf8::encode { } sub utf8::decode { } *JSON::PP::JSON_PP_encode_ascii = \&_encode_ascii; *JSON::PP::JSON_PP_encode_latin1 = \&_encode_latin1; *JSON::PP::JSON_PP_decode_surrogates = \&_decode_surrogates; *JSON::PP::JSON_PP_decode_unicode = \&_decode_unicode; # missing in B module. sub B::SVp_IOK () { 0x01000000; } sub B::SVp_NOK () { 0x02000000; } sub B::SVp_POK () { 0x04000000; } $INC{'bytes.pm'} = 1; # dummy } sub _encode_ascii { join('', map { $_ <= 127 ? chr($_) : sprintf('\u%04x', $_) } unpack('C*', $_[0]) ); } sub _encode_latin1 { join('', map { chr($_) } unpack('C*', $_[0]) ); } sub _decode_surrogates { # from http://homepage1.nifty.com/nomenclator/unicode/ucs_utf.htm my $uni = 0x10000 + (hex($_[0]) - 0xD800) * 0x400 + (hex($_[1]) - 0xDC00); # from perlunicode my $bit = unpack('B32', pack('N', $uni)); if ( $bit =~ /^00000000000(...)(......)(......)(......)$/ ) { my ($w, $x, $y, $z) = ($1, $2, $3, $4); return pack('B*', sprintf('11110%s10%s10%s10%s', $w, $x, $y, $z)); } else { Carp::croak("Invalid surrogate pair"); } } sub _decode_unicode { my ($u) = @_; my ($utf8bit); if ( $u =~ /^00([89a-f][0-9a-f])$/i ) { # 0x80-0xff return pack( 'H2', $1 ); } my $bit = unpack("B*", pack("H*", $u)); if ( $bit =~ /^00000(.....)(......)$/ ) { $utf8bit = sprintf('110%s10%s', $1, $2); } elsif ( $bit =~ /^(....)(......)(......)$/ ) { $utf8bit = sprintf('1110%s10%s10%s', $1, $2, $3); } else { Carp::croak("Invalid escaped unicode"); } return pack('B*', $utf8bit); } sub JSON::PP::incr_text { $_[0]->{_incr_parser} ||= JSON::PP::IncrParser->new; if ( $_[0]->{_incr_parser}->{incr_parsing} ) { Carp::croak("incr_text can not be called when the incremental parser already started parsing"); } $_[0]->{_incr_parser}->{incr_text} = $_[1] if ( @_ > 1 ); $_[0]->{_incr_parser}->{incr_text}; } 1; __END__ =pod =head1 NAME JSON::PP5005 - Helper module in using JSON::PP in Perl 5.005 =head1 DESCRIPTION JSON::PP calls internally. =head1 AUTHOR Makamaka Hannyaharamitu, Emakamaka[at]cpan.orgE =head1 COPYRIGHT AND LICENSE Copyright 2007-2012 by Makamaka Hannyaharamitu This library is free software; you can redistribute it and/or modify it under the same terms as Perl itself. =cut JSON-2.90/lib/JSON/backportPP.pm0000644000175000017500000024031412234431225014631 0ustar reonreonpackage # This is JSON::backportPP JSON::PP; # JSON-2.0 use 5.005; use strict; use base qw(Exporter); use overload (); use Carp (); use B (); #use Devel::Peek; use vars qw($VERSION); $VERSION = '2.27204'; @JSON::PP::EXPORT = qw(encode_json decode_json from_json to_json); # instead of hash-access, i tried index-access for speed. # but this method is not faster than what i expected. so it will be changed. use constant P_ASCII => 0; use constant P_LATIN1 => 1; use constant P_UTF8 => 2; use constant P_INDENT => 3; use constant P_CANONICAL => 4; use constant P_SPACE_BEFORE => 5; use constant P_SPACE_AFTER => 6; use constant P_ALLOW_NONREF => 7; use constant P_SHRINK => 8; use constant P_ALLOW_BLESSED => 9; use constant P_CONVERT_BLESSED => 10; use constant P_RELAXED => 11; use constant P_LOOSE => 12; use constant P_ALLOW_BIGNUM => 13; use constant P_ALLOW_BAREKEY => 14; use constant P_ALLOW_SINGLEQUOTE => 15; use constant P_ESCAPE_SLASH => 16; use constant P_AS_NONBLESSED => 17; use constant P_ALLOW_UNKNOWN => 18; use constant OLD_PERL => $] < 5.008 ? 1 : 0; BEGIN { my @xs_compati_bit_properties = qw( latin1 ascii utf8 indent canonical space_before space_after allow_nonref shrink allow_blessed convert_blessed relaxed allow_unknown ); my @pp_bit_properties = qw( allow_singlequote allow_bignum loose allow_barekey escape_slash as_nonblessed ); # Perl version check, Unicode handling is enable? # Helper module sets @JSON::PP::_properties. if ($] < 5.008 ) { my $helper = $] >= 5.006 ? 'JSON::backportPP::Compat5006' : 'JSON::backportPP::Compat5005'; eval qq| require $helper |; if ($@) { Carp::croak $@; } } for my $name (@xs_compati_bit_properties, @pp_bit_properties) { my $flag_name = 'P_' . uc($name); eval qq/ sub $name { my \$enable = defined \$_[1] ? \$_[1] : 1; if (\$enable) { \$_[0]->{PROPS}->[$flag_name] = 1; } else { \$_[0]->{PROPS}->[$flag_name] = 0; } \$_[0]; } sub get_$name { \$_[0]->{PROPS}->[$flag_name] ? 1 : ''; } /; } } # Functions my %encode_allow_method = map {($_ => 1)} qw/utf8 pretty allow_nonref latin1 self_encode escape_slash allow_blessed convert_blessed indent indent_length allow_bignum as_nonblessed /; my %decode_allow_method = map {($_ => 1)} qw/utf8 allow_nonref loose allow_singlequote allow_bignum allow_barekey max_size relaxed/; my $JSON; # cache sub encode_json ($) { # encode ($JSON ||= __PACKAGE__->new->utf8)->encode(@_); } sub decode_json { # decode ($JSON ||= __PACKAGE__->new->utf8)->decode(@_); } # Obsoleted sub to_json($) { Carp::croak ("JSON::PP::to_json has been renamed to encode_json."); } sub from_json($) { Carp::croak ("JSON::PP::from_json has been renamed to decode_json."); } # Methods sub new { my $class = shift; my $self = { max_depth => 512, max_size => 0, indent => 0, FLAGS => 0, fallback => sub { encode_error('Invalid value. JSON can only reference.') }, indent_length => 3, }; bless $self, $class; } sub encode { return $_[0]->PP_encode_json($_[1]); } sub decode { return $_[0]->PP_decode_json($_[1], 0x00000000); } sub decode_prefix { return $_[0]->PP_decode_json($_[1], 0x00000001); } # accessor # pretty printing sub pretty { my ($self, $v) = @_; my $enable = defined $v ? $v : 1; if ($enable) { # indent_length(3) for JSON::XS compatibility $self->indent(1)->indent_length(3)->space_before(1)->space_after(1); } else { $self->indent(0)->space_before(0)->space_after(0); } $self; } # etc sub max_depth { my $max = defined $_[1] ? $_[1] : 0x80000000; $_[0]->{max_depth} = $max; $_[0]; } sub get_max_depth { $_[0]->{max_depth}; } sub max_size { my $max = defined $_[1] ? $_[1] : 0; $_[0]->{max_size} = $max; $_[0]; } sub get_max_size { $_[0]->{max_size}; } sub filter_json_object { $_[0]->{cb_object} = defined $_[1] ? $_[1] : 0; $_[0]->{F_HOOK} = ($_[0]->{cb_object} or $_[0]->{cb_sk_object}) ? 1 : 0; $_[0]; } sub filter_json_single_key_object { if (@_ > 1) { $_[0]->{cb_sk_object}->{$_[1]} = $_[2]; } $_[0]->{F_HOOK} = ($_[0]->{cb_object} or $_[0]->{cb_sk_object}) ? 1 : 0; $_[0]; } sub indent_length { if (!defined $_[1] or $_[1] > 15 or $_[1] < 0) { Carp::carp "The acceptable range of indent_length() is 0 to 15."; } else { $_[0]->{indent_length} = $_[1]; } $_[0]; } sub get_indent_length { $_[0]->{indent_length}; } sub sort_by { $_[0]->{sort_by} = defined $_[1] ? $_[1] : 1; $_[0]; } sub allow_bigint { Carp::carp("allow_bigint() is obsoleted. use allow_bignum() insted."); } ############################### ### ### Perl => JSON ### { # Convert my $max_depth; my $indent; my $ascii; my $latin1; my $utf8; my $space_before; my $space_after; my $canonical; my $allow_blessed; my $convert_blessed; my $indent_length; my $escape_slash; my $bignum; my $as_nonblessed; my $depth; my $indent_count; my $keysort; sub PP_encode_json { my $self = shift; my $obj = shift; $indent_count = 0; $depth = 0; my $idx = $self->{PROPS}; ($ascii, $latin1, $utf8, $indent, $canonical, $space_before, $space_after, $allow_blessed, $convert_blessed, $escape_slash, $bignum, $as_nonblessed) = @{$idx}[P_ASCII .. P_SPACE_AFTER, P_ALLOW_BLESSED, P_CONVERT_BLESSED, P_ESCAPE_SLASH, P_ALLOW_BIGNUM, P_AS_NONBLESSED]; ($max_depth, $indent_length) = @{$self}{qw/max_depth indent_length/}; $keysort = $canonical ? sub { $a cmp $b } : undef; if ($self->{sort_by}) { $keysort = ref($self->{sort_by}) eq 'CODE' ? $self->{sort_by} : $self->{sort_by} =~ /\D+/ ? $self->{sort_by} : sub { $a cmp $b }; } encode_error("hash- or arrayref expected (not a simple scalar, use allow_nonref to allow this)") if(!ref $obj and !$idx->[ P_ALLOW_NONREF ]); my $str = $self->object_to_json($obj); $str .= "\n" if ( $indent ); # JSON::XS 2.26 compatible unless ($ascii or $latin1 or $utf8) { utf8::upgrade($str); } if ($idx->[ P_SHRINK ]) { utf8::downgrade($str, 1); } return $str; } sub object_to_json { my ($self, $obj) = @_; my $type = ref($obj); if($type eq 'HASH'){ return $self->hash_to_json($obj); } elsif($type eq 'ARRAY'){ return $self->array_to_json($obj); } elsif ($type) { # blessed object? if (blessed($obj)) { return $self->value_to_json($obj) if ( $obj->isa('JSON::PP::Boolean') ); if ( $convert_blessed and $obj->can('TO_JSON') ) { my $result = $obj->TO_JSON(); if ( defined $result and ref( $result ) ) { if ( refaddr( $obj ) eq refaddr( $result ) ) { encode_error( sprintf( "%s::TO_JSON method returned same object as was passed instead of a new one", ref $obj ) ); } } return $self->object_to_json( $result ); } return "$obj" if ( $bignum and _is_bignum($obj) ); return $self->blessed_to_json($obj) if ($allow_blessed and $as_nonblessed); # will be removed. encode_error( sprintf("encountered object '%s', but neither allow_blessed " . "nor convert_blessed settings are enabled", $obj) ) unless ($allow_blessed); return 'null'; } else { return $self->value_to_json($obj); } } else{ return $self->value_to_json($obj); } } sub hash_to_json { my ($self, $obj) = @_; my @res; encode_error("json text or perl structure exceeds maximum nesting level (max_depth set too low?)") if (++$depth > $max_depth); my ($pre, $post) = $indent ? $self->_up_indent() : ('', ''); my $del = ($space_before ? ' ' : '') . ':' . ($space_after ? ' ' : ''); for my $k ( _sort( $obj ) ) { if ( OLD_PERL ) { utf8::decode($k) } # key for Perl 5.6 / be optimized push @res, string_to_json( $self, $k ) . $del . ( $self->object_to_json( $obj->{$k} ) || $self->value_to_json( $obj->{$k} ) ); } --$depth; $self->_down_indent() if ($indent); return '{' . ( @res ? $pre : '' ) . ( @res ? join( ",$pre", @res ) . $post : '' ) . '}'; } sub array_to_json { my ($self, $obj) = @_; my @res; encode_error("json text or perl structure exceeds maximum nesting level (max_depth set too low?)") if (++$depth > $max_depth); my ($pre, $post) = $indent ? $self->_up_indent() : ('', ''); for my $v (@$obj){ push @res, $self->object_to_json($v) || $self->value_to_json($v); } --$depth; $self->_down_indent() if ($indent); return '[' . ( @res ? $pre : '' ) . ( @res ? join( ",$pre", @res ) . $post : '' ) . ']'; } sub value_to_json { my ($self, $value) = @_; return 'null' if(!defined $value); my $b_obj = B::svref_2object(\$value); # for round trip problem my $flags = $b_obj->FLAGS; return $value # as is if $flags & ( B::SVp_IOK | B::SVp_NOK ) and !( $flags & B::SVp_POK ); # SvTYPE is IV or NV? my $type = ref($value); if(!$type){ return string_to_json($self, $value); } elsif( blessed($value) and $value->isa('JSON::PP::Boolean') ){ return $$value == 1 ? 'true' : 'false'; } elsif ($type) { if ((overload::StrVal($value) =~ /=(\w+)/)[0]) { return $self->value_to_json("$value"); } if ($type eq 'SCALAR' and defined $$value) { return $$value eq '1' ? 'true' : $$value eq '0' ? 'false' : $self->{PROPS}->[ P_ALLOW_UNKNOWN ] ? 'null' : encode_error("cannot encode reference to scalar"); } if ( $self->{PROPS}->[ P_ALLOW_UNKNOWN ] ) { return 'null'; } else { if ( $type eq 'SCALAR' or $type eq 'REF' ) { encode_error("cannot encode reference to scalar"); } else { encode_error("encountered $value, but JSON can only represent references to arrays or hashes"); } } } else { return $self->{fallback}->($value) if ($self->{fallback} and ref($self->{fallback}) eq 'CODE'); return 'null'; } } my %esc = ( "\n" => '\n', "\r" => '\r', "\t" => '\t', "\f" => '\f', "\b" => '\b', "\"" => '\"', "\\" => '\\\\', "\'" => '\\\'', ); sub string_to_json { my ($self, $arg) = @_; $arg =~ s/([\x22\x5c\n\r\t\f\b])/$esc{$1}/g; $arg =~ s/\//\\\//g if ($escape_slash); $arg =~ s/([\x00-\x08\x0b\x0e-\x1f])/'\\u00' . unpack('H2', $1)/eg; if ($ascii) { $arg = JSON_PP_encode_ascii($arg); } if ($latin1) { $arg = JSON_PP_encode_latin1($arg); } if ($utf8) { utf8::encode($arg); } return '"' . $arg . '"'; } sub blessed_to_json { my $reftype = reftype($_[1]) || ''; if ($reftype eq 'HASH') { return $_[0]->hash_to_json($_[1]); } elsif ($reftype eq 'ARRAY') { return $_[0]->array_to_json($_[1]); } else { return 'null'; } } sub encode_error { my $error = shift; Carp::croak "$error"; } sub _sort { defined $keysort ? (sort $keysort (keys %{$_[0]})) : keys %{$_[0]}; } sub _up_indent { my $self = shift; my $space = ' ' x $indent_length; my ($pre,$post) = ('',''); $post = "\n" . $space x $indent_count; $indent_count++; $pre = "\n" . $space x $indent_count; return ($pre,$post); } sub _down_indent { $indent_count--; } sub PP_encode_box { { depth => $depth, indent_count => $indent_count, }; } } # Convert sub _encode_ascii { join('', map { $_ <= 127 ? chr($_) : $_ <= 65535 ? sprintf('\u%04x', $_) : sprintf('\u%x\u%x', _encode_surrogates($_)); } unpack('U*', $_[0]) ); } sub _encode_latin1 { join('', map { $_ <= 255 ? chr($_) : $_ <= 65535 ? sprintf('\u%04x', $_) : sprintf('\u%x\u%x', _encode_surrogates($_)); } unpack('U*', $_[0]) ); } sub _encode_surrogates { # from perlunicode my $uni = $_[0] - 0x10000; return ($uni / 0x400 + 0xD800, $uni % 0x400 + 0xDC00); } sub _is_bignum { $_[0]->isa('Math::BigInt') or $_[0]->isa('Math::BigFloat'); } # # JSON => Perl # my $max_intsize; BEGIN { my $checkint = 1111; for my $d (5..64) { $checkint .= 1; my $int = eval qq| $checkint |; if ($int =~ /[eE]/) { $max_intsize = $d - 1; last; } } } { # PARSE my %escapes = ( # by Jeremy Muhlich b => "\x8", t => "\x9", n => "\xA", f => "\xC", r => "\xD", '\\' => '\\', '"' => '"', '/' => '/', ); my $text; # json data my $at; # offset my $ch; # 1chracter my $len; # text length (changed according to UTF8 or NON UTF8) # INTERNAL my $depth; # nest counter my $encoding; # json text encoding my $is_valid_utf8; # temp variable my $utf8_len; # utf8 byte length # FLAGS my $utf8; # must be utf8 my $max_depth; # max nest number of objects and arrays my $max_size; my $relaxed; my $cb_object; my $cb_sk_object; my $F_HOOK; my $allow_bigint; # using Math::BigInt my $singlequote; # loosely quoting my $loose; # my $allow_barekey; # bareKey # $opt flag # 0x00000001 .... decode_prefix # 0x10000000 .... incr_parse sub PP_decode_json { my ($self, $opt); # $opt is an effective flag during this decode_json. ($self, $text, $opt) = @_; ($at, $ch, $depth) = (0, '', 0); if ( !defined $text or ref $text ) { decode_error("malformed JSON string, neither array, object, number, string or atom"); } my $idx = $self->{PROPS}; ($utf8, $relaxed, $loose, $allow_bigint, $allow_barekey, $singlequote) = @{$idx}[P_UTF8, P_RELAXED, P_LOOSE .. P_ALLOW_SINGLEQUOTE]; if ( $utf8 ) { utf8::downgrade( $text, 1 ) or Carp::croak("Wide character in subroutine entry"); } else { utf8::upgrade( $text ); } $len = length $text; ($max_depth, $max_size, $cb_object, $cb_sk_object, $F_HOOK) = @{$self}{qw/max_depth max_size cb_object cb_sk_object F_HOOK/}; if ($max_size > 1) { use bytes; my $bytes = length $text; decode_error( sprintf("attempted decode of JSON text of %s bytes size, but max_size is set to %s" , $bytes, $max_size), 1 ) if ($bytes > $max_size); } # Currently no effect # should use regexp my @octets = unpack('C4', $text); $encoding = ( $octets[0] and $octets[1]) ? 'UTF-8' : (!$octets[0] and $octets[1]) ? 'UTF-16BE' : (!$octets[0] and !$octets[1]) ? 'UTF-32BE' : ( $octets[2] ) ? 'UTF-16LE' : (!$octets[2] ) ? 'UTF-32LE' : 'unknown'; white(); # remove head white space my $valid_start = defined $ch; # Is there a first character for JSON structure? my $result = value(); return undef if ( !$result && ( $opt & 0x10000000 ) ); # for incr_parse decode_error("malformed JSON string, neither array, object, number, string or atom") unless $valid_start; if ( !$idx->[ P_ALLOW_NONREF ] and !ref $result ) { decode_error( 'JSON text must be an object or array (but found number, string, true, false or null,' . ' use allow_nonref to allow this)', 1); } Carp::croak('something wrong.') if $len < $at; # we won't arrive here. my $consumed = defined $ch ? $at - 1 : $at; # consumed JSON text length white(); # remove tail white space if ( $ch ) { return ( $result, $consumed ) if ($opt & 0x00000001); # all right if decode_prefix decode_error("garbage after JSON object"); } ( $opt & 0x00000001 ) ? ( $result, $consumed ) : $result; } sub next_chr { return $ch = undef if($at >= $len); $ch = substr($text, $at++, 1); } sub value { white(); return if(!defined $ch); return object() if($ch eq '{'); return array() if($ch eq '['); return string() if($ch eq '"' or ($singlequote and $ch eq "'")); return number() if($ch =~ /[0-9]/ or $ch eq '-'); return word(); } sub string { my ($i, $s, $t, $u); my $utf16; my $is_utf8; ($is_valid_utf8, $utf8_len) = ('', 0); $s = ''; # basically UTF8 flag on if($ch eq '"' or ($singlequote and $ch eq "'")){ my $boundChar = $ch; OUTER: while( defined(next_chr()) ){ if($ch eq $boundChar){ next_chr(); if ($utf16) { decode_error("missing low surrogate character in surrogate pair"); } utf8::decode($s) if($is_utf8); return $s; } elsif($ch eq '\\'){ next_chr(); if(exists $escapes{$ch}){ $s .= $escapes{$ch}; } elsif($ch eq 'u'){ # UNICODE handling my $u = ''; for(1..4){ $ch = next_chr(); last OUTER if($ch !~ /[0-9a-fA-F]/); $u .= $ch; } # U+D800 - U+DBFF if ($u =~ /^[dD][89abAB][0-9a-fA-F]{2}/) { # UTF-16 high surrogate? $utf16 = $u; } # U+DC00 - U+DFFF elsif ($u =~ /^[dD][c-fC-F][0-9a-fA-F]{2}/) { # UTF-16 low surrogate? unless (defined $utf16) { decode_error("missing high surrogate character in surrogate pair"); } $is_utf8 = 1; $s .= JSON_PP_decode_surrogates($utf16, $u) || next; $utf16 = undef; } else { if (defined $utf16) { decode_error("surrogate pair expected"); } if ( ( my $hex = hex( $u ) ) > 127 ) { $is_utf8 = 1; $s .= JSON_PP_decode_unicode($u) || next; } else { $s .= chr $hex; } } } else{ unless ($loose) { $at -= 2; decode_error('illegal backslash escape sequence in string'); } $s .= $ch; } } else{ if ( ord $ch > 127 ) { if ( $utf8 ) { unless( $ch = is_valid_utf8($ch) ) { $at -= 1; decode_error("malformed UTF-8 character in JSON string"); } else { $at += $utf8_len - 1; } } else { utf8::encode( $ch ); } $is_utf8 = 1; } if (!$loose) { if ($ch =~ /[\x00-\x1f\x22\x5c]/) { # '/' ok $at--; decode_error('invalid character encountered while parsing JSON string'); } } $s .= $ch; } } } decode_error("unexpected end of string while parsing JSON string"); } sub white { while( defined $ch ){ if($ch le ' '){ next_chr(); } elsif($ch eq '/'){ next_chr(); if(defined $ch and $ch eq '/'){ 1 while(defined(next_chr()) and $ch ne "\n" and $ch ne "\r"); } elsif(defined $ch and $ch eq '*'){ next_chr(); while(1){ if(defined $ch){ if($ch eq '*'){ if(defined(next_chr()) and $ch eq '/'){ next_chr(); last; } } else{ next_chr(); } } else{ decode_error("Unterminated comment"); } } next; } else{ $at--; decode_error("malformed JSON string, neither array, object, number, string or atom"); } } else{ if ($relaxed and $ch eq '#') { # correctly? pos($text) = $at; $text =~ /\G([^\n]*(?:\r\n|\r|\n|$))/g; $at = pos($text); next_chr; next; } last; } } } sub array { my $a = $_[0] || []; # you can use this code to use another array ref object. decode_error('json text or perl structure exceeds maximum nesting level (max_depth set too low?)') if (++$depth > $max_depth); next_chr(); white(); if(defined $ch and $ch eq ']'){ --$depth; next_chr(); return $a; } else { while(defined($ch)){ push @$a, value(); white(); if (!defined $ch) { last; } if($ch eq ']'){ --$depth; next_chr(); return $a; } if($ch ne ','){ last; } next_chr(); white(); if ($relaxed and $ch eq ']') { --$depth; next_chr(); return $a; } } } decode_error(", or ] expected while parsing array"); } sub object { my $o = $_[0] || {}; # you can use this code to use another hash ref object. my $k; decode_error('json text or perl structure exceeds maximum nesting level (max_depth set too low?)') if (++$depth > $max_depth); next_chr(); white(); if(defined $ch and $ch eq '}'){ --$depth; next_chr(); if ($F_HOOK) { return _json_object_hook($o); } return $o; } else { while (defined $ch) { $k = ($allow_barekey and $ch ne '"' and $ch ne "'") ? bareKey() : string(); white(); if(!defined $ch or $ch ne ':'){ $at--; decode_error("':' expected"); } next_chr(); $o->{$k} = value(); white(); last if (!defined $ch); if($ch eq '}'){ --$depth; next_chr(); if ($F_HOOK) { return _json_object_hook($o); } return $o; } if($ch ne ','){ last; } next_chr(); white(); if ($relaxed and $ch eq '}') { --$depth; next_chr(); if ($F_HOOK) { return _json_object_hook($o); } return $o; } } } $at--; decode_error(", or } expected while parsing object/hash"); } sub bareKey { # doesn't strictly follow Standard ECMA-262 3rd Edition my $key; while($ch =~ /[^\x00-\x23\x25-\x2F\x3A-\x40\x5B-\x5E\x60\x7B-\x7F]/){ $key .= $ch; next_chr(); } return $key; } sub word { my $word = substr($text,$at-1,4); if($word eq 'true'){ $at += 3; next_chr; return $JSON::PP::true; } elsif($word eq 'null'){ $at += 3; next_chr; return undef; } elsif($word eq 'fals'){ $at += 3; if(substr($text,$at,1) eq 'e'){ $at++; next_chr; return $JSON::PP::false; } } $at--; # for decode_error report decode_error("'null' expected") if ($word =~ /^n/); decode_error("'true' expected") if ($word =~ /^t/); decode_error("'false' expected") if ($word =~ /^f/); decode_error("malformed JSON string, neither array, object, number, string or atom"); } sub number { my $n = ''; my $v; # According to RFC4627, hex or oct digits are invalid. if($ch eq '0'){ my $peek = substr($text,$at,1); my $hex = $peek =~ /[xX]/; # 0 or 1 if($hex){ decode_error("malformed number (leading zero must not be followed by another digit)"); ($n) = ( substr($text, $at+1) =~ /^([0-9a-fA-F]+)/); } else{ # oct ($n) = ( substr($text, $at) =~ /^([0-7]+)/); if (defined $n and length $n > 1) { decode_error("malformed number (leading zero must not be followed by another digit)"); } } if(defined $n and length($n)){ if (!$hex and length($n) == 1) { decode_error("malformed number (leading zero must not be followed by another digit)"); } $at += length($n) + $hex; next_chr; return $hex ? hex($n) : oct($n); } } if($ch eq '-'){ $n = '-'; next_chr; if (!defined $ch or $ch !~ /\d/) { decode_error("malformed number (no digits after initial minus)"); } } while(defined $ch and $ch =~ /\d/){ $n .= $ch; next_chr; } if(defined $ch and $ch eq '.'){ $n .= '.'; next_chr; if (!defined $ch or $ch !~ /\d/) { decode_error("malformed number (no digits after decimal point)"); } else { $n .= $ch; } while(defined(next_chr) and $ch =~ /\d/){ $n .= $ch; } } if(defined $ch and ($ch eq 'e' or $ch eq 'E')){ $n .= $ch; next_chr; if(defined($ch) and ($ch eq '+' or $ch eq '-')){ $n .= $ch; next_chr; if (!defined $ch or $ch =~ /\D/) { decode_error("malformed number (no digits after exp sign)"); } $n .= $ch; } elsif(defined($ch) and $ch =~ /\d/){ $n .= $ch; } else { decode_error("malformed number (no digits after exp sign)"); } while(defined(next_chr) and $ch =~ /\d/){ $n .= $ch; } } $v .= $n; if ($v !~ /[.eE]/ and length $v > $max_intsize) { if ($allow_bigint) { # from Adam Sussman require Math::BigInt; return Math::BigInt->new($v); } else { return "$v"; } } elsif ($allow_bigint) { require Math::BigFloat; return Math::BigFloat->new($v); } return 0+$v; } sub is_valid_utf8 { $utf8_len = $_[0] =~ /[\x00-\x7F]/ ? 1 : $_[0] =~ /[\xC2-\xDF]/ ? 2 : $_[0] =~ /[\xE0-\xEF]/ ? 3 : $_[0] =~ /[\xF0-\xF4]/ ? 4 : 0 ; return unless $utf8_len; my $is_valid_utf8 = substr($text, $at - 1, $utf8_len); return ( $is_valid_utf8 =~ /^(?: [\x00-\x7F] |[\xC2-\xDF][\x80-\xBF] |[\xE0][\xA0-\xBF][\x80-\xBF] |[\xE1-\xEC][\x80-\xBF][\x80-\xBF] |[\xED][\x80-\x9F][\x80-\xBF] |[\xEE-\xEF][\x80-\xBF][\x80-\xBF] |[\xF0][\x90-\xBF][\x80-\xBF][\x80-\xBF] |[\xF1-\xF3][\x80-\xBF][\x80-\xBF][\x80-\xBF] |[\xF4][\x80-\x8F][\x80-\xBF][\x80-\xBF] )$/x ) ? $is_valid_utf8 : ''; } sub decode_error { my $error = shift; my $no_rep = shift; my $str = defined $text ? substr($text, $at) : ''; my $mess = ''; my $type = $] >= 5.008 ? 'U*' : $] < 5.006 ? 'C*' : utf8::is_utf8( $str ) ? 'U*' # 5.6 : 'C*' ; for my $c ( unpack( $type, $str ) ) { # emulate pv_uni_display() ? $mess .= $c == 0x07 ? '\a' : $c == 0x09 ? '\t' : $c == 0x0a ? '\n' : $c == 0x0d ? '\r' : $c == 0x0c ? '\f' : $c < 0x20 ? sprintf('\x{%x}', $c) : $c == 0x5c ? '\\\\' : $c < 0x80 ? chr($c) : sprintf('\x{%x}', $c) ; if ( length $mess >= 20 ) { $mess .= '...'; last; } } unless ( length $mess ) { $mess = '(end of string)'; } Carp::croak ( $no_rep ? "$error" : "$error, at character offset $at (before \"$mess\")" ); } sub _json_object_hook { my $o = $_[0]; my @ks = keys %{$o}; if ( $cb_sk_object and @ks == 1 and exists $cb_sk_object->{ $ks[0] } and ref $cb_sk_object->{ $ks[0] } ) { my @val = $cb_sk_object->{ $ks[0] }->( $o->{$ks[0]} ); if (@val == 1) { return $val[0]; } } my @val = $cb_object->($o) if ($cb_object); if (@val == 0 or @val > 1) { return $o; } else { return $val[0]; } } sub PP_decode_box { { text => $text, at => $at, ch => $ch, len => $len, depth => $depth, encoding => $encoding, is_valid_utf8 => $is_valid_utf8, }; } } # PARSE sub _decode_surrogates { # from perlunicode my $uni = 0x10000 + (hex($_[0]) - 0xD800) * 0x400 + (hex($_[1]) - 0xDC00); my $un = pack('U*', $uni); utf8::encode( $un ); return $un; } sub _decode_unicode { my $un = pack('U', hex shift); utf8::encode( $un ); return $un; } # # Setup for various Perl versions (the code from JSON::PP58) # BEGIN { unless ( defined &utf8::is_utf8 ) { require Encode; *utf8::is_utf8 = *Encode::is_utf8; } if ( $] >= 5.008 ) { *JSON::PP::JSON_PP_encode_ascii = \&_encode_ascii; *JSON::PP::JSON_PP_encode_latin1 = \&_encode_latin1; *JSON::PP::JSON_PP_decode_surrogates = \&_decode_surrogates; *JSON::PP::JSON_PP_decode_unicode = \&_decode_unicode; } if ($] >= 5.008 and $] < 5.008003) { # join() in 5.8.0 - 5.8.2 is broken. package # hide from PAUSE JSON::PP; require subs; subs->import('join'); eval q| sub join { return '' if (@_ < 2); my $j = shift; my $str = shift; for (@_) { $str .= $j . $_; } return $str; } |; } sub JSON::PP::incr_parse { local $Carp::CarpLevel = 1; ( $_[0]->{_incr_parser} ||= JSON::PP::IncrParser->new )->incr_parse( @_ ); } sub JSON::PP::incr_skip { ( $_[0]->{_incr_parser} ||= JSON::PP::IncrParser->new )->incr_skip; } sub JSON::PP::incr_reset { ( $_[0]->{_incr_parser} ||= JSON::PP::IncrParser->new )->incr_reset; } eval q{ sub JSON::PP::incr_text : lvalue { $_[0]->{_incr_parser} ||= JSON::PP::IncrParser->new; if ( $_[0]->{_incr_parser}->{incr_parsing} ) { Carp::croak("incr_text can not be called when the incremental parser already started parsing"); } $_[0]->{_incr_parser}->{incr_text}; } } if ( $] >= 5.006 ); } # Setup for various Perl versions (the code from JSON::PP58) ############################### # Utilities # BEGIN { eval 'require Scalar::Util'; unless($@){ *JSON::PP::blessed = \&Scalar::Util::blessed; *JSON::PP::reftype = \&Scalar::Util::reftype; *JSON::PP::refaddr = \&Scalar::Util::refaddr; } else{ # This code is from Scalar::Util. # warn $@; eval 'sub UNIVERSAL::a_sub_not_likely_to_be_here { ref($_[0]) }'; *JSON::PP::blessed = sub { local($@, $SIG{__DIE__}, $SIG{__WARN__}); ref($_[0]) ? eval { $_[0]->a_sub_not_likely_to_be_here } : undef; }; my %tmap = qw( B::NULL SCALAR B::HV HASH B::AV ARRAY B::CV CODE B::IO IO B::GV GLOB B::REGEXP REGEXP ); *JSON::PP::reftype = sub { my $r = shift; return undef unless length(ref($r)); my $t = ref(B::svref_2object($r)); return exists $tmap{$t} ? $tmap{$t} : length(ref($$r)) ? 'REF' : 'SCALAR'; }; *JSON::PP::refaddr = sub { return undef unless length(ref($_[0])); my $addr; if(defined(my $pkg = blessed($_[0]))) { $addr .= bless $_[0], 'Scalar::Util::Fake'; bless $_[0], $pkg; } else { $addr .= $_[0] } $addr =~ /0x(\w+)/; local $^W; #no warnings 'portable'; hex($1); } } } # shamelessly copied and modified from JSON::XS code. unless ( $INC{'JSON/PP.pm'} ) { eval q| package JSON::PP::Boolean; use overload ( "0+" => sub { ${$_[0]} }, "++" => sub { $_[0] = ${$_[0]} + 1 }, "--" => sub { $_[0] = ${$_[0]} - 1 }, fallback => 1, ); |; } $JSON::PP::true = do { bless \(my $dummy = 1), "JSON::PP::Boolean" }; $JSON::PP::false = do { bless \(my $dummy = 0), "JSON::PP::Boolean" }; sub is_bool { defined $_[0] and UNIVERSAL::isa($_[0], "JSON::PP::Boolean"); } sub true { $JSON::PP::true } sub false { $JSON::PP::false } sub null { undef; } ############################### ############################### package # hide from PAUSE JSON::PP::IncrParser; use strict; use constant INCR_M_WS => 0; # initial whitespace skipping use constant INCR_M_STR => 1; # inside string use constant INCR_M_BS => 2; # inside backslash use constant INCR_M_JSON => 3; # outside anything, count nesting use constant INCR_M_C0 => 4; use constant INCR_M_C1 => 5; use vars qw($VERSION); $VERSION = '1.01'; my $unpack_format = $] < 5.006 ? 'C*' : 'U*'; sub new { my ( $class ) = @_; bless { incr_nest => 0, incr_text => undef, incr_parsing => 0, incr_p => 0, }, $class; } sub incr_parse { my ( $self, $coder, $text ) = @_; $self->{incr_text} = '' unless ( defined $self->{incr_text} ); if ( defined $text ) { if ( utf8::is_utf8( $text ) and !utf8::is_utf8( $self->{incr_text} ) ) { utf8::upgrade( $self->{incr_text} ) ; utf8::decode( $self->{incr_text} ) ; } $self->{incr_text} .= $text; } my $max_size = $coder->get_max_size; if ( defined wantarray ) { $self->{incr_mode} = INCR_M_WS unless defined $self->{incr_mode}; if ( wantarray ) { my @ret; $self->{incr_parsing} = 1; do { push @ret, $self->_incr_parse( $coder, $self->{incr_text} ); unless ( !$self->{incr_nest} and $self->{incr_mode} == INCR_M_JSON ) { $self->{incr_mode} = INCR_M_WS if $self->{incr_mode} != INCR_M_STR; } } until ( length $self->{incr_text} >= $self->{incr_p} ); $self->{incr_parsing} = 0; return @ret; } else { # in scalar context $self->{incr_parsing} = 1; my $obj = $self->_incr_parse( $coder, $self->{incr_text} ); $self->{incr_parsing} = 0 if defined $obj; # pointed by Martin J. Evans return $obj ? $obj : undef; # $obj is an empty string, parsing was completed. } } } sub _incr_parse { my ( $self, $coder, $text, $skip ) = @_; my $p = $self->{incr_p}; my $restore = $p; my @obj; my $len = length $text; if ( $self->{incr_mode} == INCR_M_WS ) { while ( $len > $p ) { my $s = substr( $text, $p, 1 ); $p++ and next if ( 0x20 >= unpack($unpack_format, $s) ); $self->{incr_mode} = INCR_M_JSON; last; } } while ( $len > $p ) { my $s = substr( $text, $p++, 1 ); if ( $s eq '"' ) { if (substr( $text, $p - 2, 1 ) eq '\\' ) { next; } if ( $self->{incr_mode} != INCR_M_STR ) { $self->{incr_mode} = INCR_M_STR; } else { $self->{incr_mode} = INCR_M_JSON; unless ( $self->{incr_nest} ) { last; } } } if ( $self->{incr_mode} == INCR_M_JSON ) { if ( $s eq '[' or $s eq '{' ) { if ( ++$self->{incr_nest} > $coder->get_max_depth ) { Carp::croak('json text or perl structure exceeds maximum nesting level (max_depth set too low?)'); } } elsif ( $s eq ']' or $s eq '}' ) { last if ( --$self->{incr_nest} <= 0 ); } elsif ( $s eq '#' ) { while ( $len > $p ) { last if substr( $text, $p++, 1 ) eq "\n"; } } } } $self->{incr_p} = $p; return if ( $self->{incr_mode} == INCR_M_STR and not $self->{incr_nest} ); return if ( $self->{incr_mode} == INCR_M_JSON and $self->{incr_nest} > 0 ); return '' unless ( length substr( $self->{incr_text}, 0, $p ) ); local $Carp::CarpLevel = 2; $self->{incr_p} = $restore; $self->{incr_c} = $p; my ( $obj, $tail ) = $coder->PP_decode_json( substr( $self->{incr_text}, 0, $p ), 0x10000001 ); $self->{incr_text} = substr( $self->{incr_text}, $p ); $self->{incr_p} = 0; return $obj || ''; } sub incr_text { if ( $_[0]->{incr_parsing} ) { Carp::croak("incr_text can not be called when the incremental parser already started parsing"); } $_[0]->{incr_text}; } sub incr_skip { my $self = shift; $self->{incr_text} = substr( $self->{incr_text}, $self->{incr_c} ); $self->{incr_p} = 0; } sub incr_reset { my $self = shift; $self->{incr_text} = undef; $self->{incr_p} = 0; $self->{incr_mode} = 0; $self->{incr_nest} = 0; $self->{incr_parsing} = 0; } ############################### 1; __END__ =pod =head1 NAME JSON::PP - JSON::XS compatible pure-Perl module. =head1 SYNOPSIS use JSON::PP; # exported functions, they croak on error # and expect/generate UTF-8 $utf8_encoded_json_text = encode_json $perl_hash_or_arrayref; $perl_hash_or_arrayref = decode_json $utf8_encoded_json_text; # OO-interface $coder = JSON::PP->new->ascii->pretty->allow_nonref; $json_text = $json->encode( $perl_scalar ); $perl_scalar = $json->decode( $json_text ); $pretty_printed = $json->pretty->encode( $perl_scalar ); # pretty-printing # Note that JSON version 2.0 and above will automatically use # JSON::XS or JSON::PP, so you should be able to just: use JSON; =head1 VERSION 2.27200 L 2.27 (~2.30) compatible. =head1 DESCRIPTION This module is L compatible pure Perl module. (Perl 5.8 or later is recommended) JSON::XS is the fastest and most proper JSON module on CPAN. It is written by Marc Lehmann in C, so must be compiled and installed in the used environment. JSON::PP is a pure-Perl module and has compatibility to JSON::XS. =head2 FEATURES =over =item * correct unicode handling This module knows how to handle Unicode (depending on Perl version). See to L and L. =item * round-trip integrity When you serialise a perl data structure using only data types supported by JSON and Perl, the deserialised data structure is identical on the Perl level. (e.g. the string "2.0" doesn't suddenly become "2" just because it looks like a number). There I minor exceptions to this, read the MAPPING section below to learn about those. =item * strict checking of JSON correctness There is no guessing, no generating of illegal JSON texts by default, and only JSON is accepted as input by default (the latter is a security feature). But when some options are set, loose checking features are available. =back =head1 FUNCTIONAL INTERFACE Some documents are copied and modified from L. =head2 encode_json $json_text = encode_json $perl_scalar Converts the given Perl data structure to a UTF-8 encoded, binary string. This function call is functionally identical to: $json_text = JSON::PP->new->utf8->encode($perl_scalar) =head2 decode_json $perl_scalar = decode_json $json_text The opposite of C: expects an UTF-8 (binary) string and tries to parse that as an UTF-8 encoded JSON text, returning the resulting reference. This function call is functionally identical to: $perl_scalar = JSON::PP->new->utf8->decode($json_text) =head2 JSON::PP::is_bool $is_boolean = JSON::PP::is_bool($scalar) Returns true if the passed scalar represents either JSON::PP::true or JSON::PP::false, two constants that act like C<1> and C<0> respectively and are also used to represent JSON C and C in Perl strings. =head2 JSON::PP::true Returns JSON true value which is blessed object. It C JSON::PP::Boolean object. =head2 JSON::PP::false Returns JSON false value which is blessed object. It C JSON::PP::Boolean object. =head2 JSON::PP::null Returns C. See L, below, for more information on how JSON values are mapped to Perl. =head1 HOW DO I DECODE A DATA FROM OUTER AND ENCODE TO OUTER This section supposes that your perl version is 5.8 or later. If you know a JSON text from an outer world - a network, a file content, and so on, is encoded in UTF-8, you should use C or C module object with C enable. And the decoded result will contain UNICODE characters. # from network my $json = JSON::PP->new->utf8; my $json_text = CGI->new->param( 'json_data' ); my $perl_scalar = $json->decode( $json_text ); # from file content local $/; open( my $fh, '<', 'json.data' ); $json_text = <$fh>; $perl_scalar = decode_json( $json_text ); If an outer data is not encoded in UTF-8, firstly you should C it. use Encode; local $/; open( my $fh, '<', 'json.data' ); my $encoding = 'cp932'; my $unicode_json_text = decode( $encoding, <$fh> ); # UNICODE # or you can write the below code. # # open( my $fh, "<:encoding($encoding)", 'json.data' ); # $unicode_json_text = <$fh>; In this case, C<$unicode_json_text> is of course UNICODE string. So you B use C nor C module object with C enable. Instead of them, you use C module object with C disable. $perl_scalar = $json->utf8(0)->decode( $unicode_json_text ); Or C and C: $perl_scalar = decode_json( encode( 'utf8', $unicode_json_text ) ); # this way is not efficient. And now, you want to convert your C<$perl_scalar> into JSON data and send it to an outer world - a network or a file content, and so on. Your data usually contains UNICODE strings and you want the converted data to be encoded in UTF-8, you should use C or C module object with C enable. print encode_json( $perl_scalar ); # to a network? file? or display? # or print $json->utf8->encode( $perl_scalar ); If C<$perl_scalar> does not contain UNICODE but C<$encoding>-encoded strings for some reason, then its characters are regarded as B for perl (because it does not concern with your $encoding). You B use C nor C module object with C enable. Instead of them, you use C module object with C disable. Note that the resulted text is a UNICODE string but no problem to print it. # $perl_scalar contains $encoding encoded string values $unicode_json_text = $json->utf8(0)->encode( $perl_scalar ); # $unicode_json_text consists of characters less than 0x100 print $unicode_json_text; Or C all string values and C: $perl_scalar->{ foo } = decode( $encoding, $perl_scalar->{ foo } ); # ... do it to each string values, then encode_json $json_text = encode_json( $perl_scalar ); This method is a proper way but probably not efficient. See to L, L. =head1 METHODS Basically, check to L or L. =head2 new $json = JSON::PP->new Returns a new JSON::PP object that can be used to de/encode JSON strings. All boolean flags described below are by default I. The mutators for flags all return the JSON object again and thus calls can be chained: my $json = JSON::PP->new->utf8->space_after->encode({a => [1,2]}) => {"a": [1, 2]} =head2 ascii $json = $json->ascii([$enable]) $enabled = $json->get_ascii If $enable is true (or missing), then the encode method will not generate characters outside the code range 0..127. Any Unicode characters outside that range will be escaped using either a single \uXXXX or a double \uHHHH\uLLLLL escape sequence, as per RFC4627. (See to L). In Perl 5.005, there is no character having high value (more than 255). See to L. If $enable is false, then the encode method will not escape Unicode characters unless required by the JSON syntax or other flags. This results in a faster and more compact format. JSON::PP->new->ascii(1)->encode([chr 0x10401]) => ["\ud801\udc01"] =head2 latin1 $json = $json->latin1([$enable]) $enabled = $json->get_latin1 If $enable is true (or missing), then the encode method will encode the resulting JSON text as latin1 (or iso-8859-1), escaping any characters outside the code range 0..255. If $enable is false, then the encode method will not escape Unicode characters unless required by the JSON syntax or other flags. JSON::XS->new->latin1->encode (["\x{89}\x{abc}"] => ["\x{89}\\u0abc"] # (perl syntax, U+abc escaped, U+89 not) See to L. =head2 utf8 $json = $json->utf8([$enable]) $enabled = $json->get_utf8 If $enable is true (or missing), then the encode method will encode the JSON result into UTF-8, as required by many protocols, while the decode method expects to be handled an UTF-8-encoded string. Please note that UTF-8-encoded strings do not contain any characters outside the range 0..255, they are thus useful for bytewise/binary I/O. (In Perl 5.005, any character outside the range 0..255 does not exist. See to L.) In future versions, enabling this option might enable autodetection of the UTF-16 and UTF-32 encoding families, as described in RFC4627. If $enable is false, then the encode method will return the JSON string as a (non-encoded) Unicode string, while decode expects thus a Unicode string. Any decoding or encoding (e.g. to UTF-8 or UTF-16) needs to be done yourself, e.g. using the Encode module. Example, output UTF-16BE-encoded JSON: use Encode; $jsontext = encode "UTF-16BE", JSON::PP->new->encode ($object); Example, decode UTF-32LE-encoded JSON: use Encode; $object = JSON::PP->new->decode (decode "UTF-32LE", $jsontext); =head2 pretty $json = $json->pretty([$enable]) This enables (or disables) all of the C, C and C flags in one call to generate the most readable (or most compact) form possible. Equivalent to: $json->indent->space_before->space_after =head2 indent $json = $json->indent([$enable]) $enabled = $json->get_indent The default indent space length is three. You can use C to change the length. =head2 space_before $json = $json->space_before([$enable]) $enabled = $json->get_space_before If C<$enable> is true (or missing), then the C method will add an extra optional space before the C<:> separating keys from values in JSON objects. If C<$enable> is false, then the C method will not add any extra space at those places. This setting has no effect when decoding JSON texts. Example, space_before enabled, space_after and indent disabled: {"key" :"value"} =head2 space_after $json = $json->space_after([$enable]) $enabled = $json->get_space_after If C<$enable> is true (or missing), then the C method will add an extra optional space after the C<:> separating keys from values in JSON objects and extra whitespace after the C<,> separating key-value pairs and array members. If C<$enable> is false, then the C method will not add any extra space at those places. This setting has no effect when decoding JSON texts. Example, space_before and indent disabled, space_after enabled: {"key": "value"} =head2 relaxed $json = $json->relaxed([$enable]) $enabled = $json->get_relaxed If C<$enable> is true (or missing), then C will accept some extensions to normal JSON syntax (see below). C will not be affected in anyway. I. I suggest only to use this option to parse application-specific files written by humans (configuration files, resource files etc.) If C<$enable> is false (the default), then C will only accept valid JSON texts. Currently accepted extensions are: =over 4 =item * list items can have an end-comma JSON I array elements and key-value pairs with commas. This can be annoying if you write JSON texts manually and want to be able to quickly append elements, so this extension accepts comma at the end of such items not just between them: [ 1, 2, <- this comma not normally allowed ] { "k1": "v1", "k2": "v2", <- this comma not normally allowed } =item * shell-style '#'-comments Whenever JSON allows whitespace, shell-style comments are additionally allowed. They are terminated by the first carriage-return or line-feed character, after which more white-space and comments are allowed. [ 1, # this comment not allowed in JSON # neither this one... ] =back =head2 canonical $json = $json->canonical([$enable]) $enabled = $json->get_canonical If C<$enable> is true (or missing), then the C method will output JSON objects by sorting their keys. This is adding a comparatively high overhead. If C<$enable> is false, then the C method will output key-value pairs in the order Perl stores them (which will likely change between runs of the same script). This option is useful if you want the same data structure to be encoded as the same JSON text (given the same overall settings). If it is disabled, the same hash might be encoded differently even if contains the same data, as key-value pairs have no inherent ordering in Perl. This setting has no effect when decoding JSON texts. If you want your own sorting routine, you can give a code reference or a subroutine name to C. See to C. =head2 allow_nonref $json = $json->allow_nonref([$enable]) $enabled = $json->get_allow_nonref If C<$enable> is true (or missing), then the C method can convert a non-reference into its corresponding string, number or null JSON value, which is an extension to RFC4627. Likewise, C will accept those JSON values instead of croaking. If C<$enable> is false, then the C method will croak if it isn't passed an arrayref or hashref, as JSON texts must either be an object or array. Likewise, C will croak if given something that is not a JSON object or array. JSON::PP->new->allow_nonref->encode ("Hello, World!") => "Hello, World!" =head2 allow_unknown $json = $json->allow_unknown ([$enable]) $enabled = $json->get_allow_unknown If $enable is true (or missing), then "encode" will *not* throw an exception when it encounters values it cannot represent in JSON (for example, filehandles) but instead will encode a JSON "null" value. Note that blessed objects are not included here and are handled separately by c. If $enable is false (the default), then "encode" will throw an exception when it encounters anything it cannot encode as JSON. This option does not affect "decode" in any way, and it is recommended to leave it off unless you know your communications partner. =head2 allow_blessed $json = $json->allow_blessed([$enable]) $enabled = $json->get_allow_blessed If C<$enable> is true (or missing), then the C method will not barf when it encounters a blessed reference. Instead, the value of the B option will decide whether C (C disabled or no C method found) or a representation of the object (C enabled and C method found) is being encoded. Has no effect on C. If C<$enable> is false (the default), then C will throw an exception when it encounters a blessed object. =head2 convert_blessed $json = $json->convert_blessed([$enable]) $enabled = $json->get_convert_blessed If C<$enable> is true (or missing), then C, upon encountering a blessed object, will check for the availability of the C method on the object's class. If found, it will be called in scalar context and the resulting scalar will be encoded instead of the object. If no C method is found, the value of C will decide what to do. The C method may safely call die if it wants. If C returns other blessed objects, those will be handled in the same way. C must take care of not causing an endless recursion cycle (== crash) in this case. The name of C was chosen because other methods called by the Perl core (== not by the user of the object) are usually in upper case letters and to avoid collisions with the C function or method. This setting does not yet influence C in any way. If C<$enable> is false, then the C setting will decide what to do when a blessed object is found. =head2 filter_json_object $json = $json->filter_json_object([$coderef]) When C<$coderef> is specified, it will be called from C each time it decodes a JSON object. The only argument passed to the coderef is a reference to the newly-created hash. If the code references returns a single scalar (which need not be a reference), this value (i.e. a copy of that scalar to avoid aliasing) is inserted into the deserialised data structure. If it returns an empty list (NOTE: I C, which is a valid scalar), the original deserialised hash will be inserted. This setting can slow down decoding considerably. When C<$coderef> is omitted or undefined, any existing callback will be removed and C will not change the deserialised hash in any way. Example, convert all JSON objects into the integer 5: my $js = JSON::PP->new->filter_json_object (sub { 5 }); # returns [5] $js->decode ('[{}]'); # the given subroutine takes a hash reference. # throw an exception because allow_nonref is not enabled # so a lone 5 is not allowed. $js->decode ('{"a":1, "b":2}'); =head2 filter_json_single_key_object $json = $json->filter_json_single_key_object($key [=> $coderef]) Works remotely similar to C, but is only called for JSON objects having a single key named C<$key>. This C<$coderef> is called before the one specified via C, if any. It gets passed the single value in the JSON object. If it returns a single value, it will be inserted into the data structure. If it returns nothing (not even C but the empty list), the callback from C will be called next, as if no single-key callback were specified. If C<$coderef> is omitted or undefined, the corresponding callback will be disabled. There can only ever be one callback for a given key. As this callback gets called less often then the C one, decoding speed will not usually suffer as much. Therefore, single-key objects make excellent targets to serialise Perl objects into, especially as single-key JSON objects are as close to the type-tagged value concept as JSON gets (it's basically an ID/VALUE tuple). Of course, JSON does not support this in any way, so you need to make sure your data never looks like a serialised Perl hash. Typical names for the single object key are C<__class_whatever__>, or C<$__dollars_are_rarely_used__$> or C<}ugly_brace_placement>, or even things like C<__class_md5sum(classname)__>, to reduce the risk of clashing with real hashes. Example, decode JSON objects of the form C<< { "__widget__" => } >> into the corresponding C<< $WIDGET{} >> object: # return whatever is in $WIDGET{5}: JSON::PP ->new ->filter_json_single_key_object (__widget__ => sub { $WIDGET{ $_[0] } }) ->decode ('{"__widget__": 5') # this can be used with a TO_JSON method in some "widget" class # for serialisation to json: sub WidgetBase::TO_JSON { my ($self) = @_; unless ($self->{id}) { $self->{id} = ..get..some..id..; $WIDGET{$self->{id}} = $self; } { __widget__ => $self->{id} } } =head2 shrink $json = $json->shrink([$enable]) $enabled = $json->get_shrink In JSON::XS, this flag resizes strings generated by either C or C to their minimum size possible. It will also try to downgrade any strings to octet-form if possible. In JSON::PP, it is noop about resizing strings but tries C to the returned string by C. See to L. See to L =head2 max_depth $json = $json->max_depth([$maximum_nesting_depth]) $max_depth = $json->get_max_depth Sets the maximum nesting level (default C<512>) accepted while encoding or decoding. If a higher nesting level is detected in JSON text or a Perl data structure, then the encoder and decoder will stop and croak at that point. Nesting level is defined by number of hash- or arrayrefs that the encoder needs to traverse to reach a given point or the number of C<{> or C<[> characters without their matching closing parenthesis crossed to reach a given character in a string. If no argument is given, the highest possible setting will be used, which is rarely useful. See L for more info on why this is useful. When a large value (100 or more) was set and it de/encodes a deep nested object/text, it may raise a warning 'Deep recursion on subroutine' at the perl runtime phase. =head2 max_size $json = $json->max_size([$maximum_string_size]) $max_size = $json->get_max_size Set the maximum length a JSON text may have (in bytes) where decoding is being attempted. The default is C<0>, meaning no limit. When C is called on a string that is longer then this many bytes, it will not attempt to decode the string but throw an exception. This setting has no effect on C (yet). If no argument is given, the limit check will be deactivated (same as when C<0> is specified). See L for more info on why this is useful. =head2 encode $json_text = $json->encode($perl_scalar) Converts the given Perl data structure (a simple scalar or a reference to a hash or array) to its JSON representation. Simple scalars will be converted into JSON string or number sequences, while references to arrays become JSON arrays and references to hashes become JSON objects. Undefined Perl values (e.g. C) become JSON C values. References to the integers C<0> and C<1> are converted into C and C. =head2 decode $perl_scalar = $json->decode($json_text) The opposite of C: expects a JSON text and tries to parse it, returning the resulting simple scalar or reference. Croaks on error. JSON numbers and strings become simple Perl scalars. JSON arrays become Perl arrayrefs and JSON objects become Perl hashrefs. C becomes C<1> (C), C becomes C<0> (C) and C becomes C. =head2 decode_prefix ($perl_scalar, $characters) = $json->decode_prefix($json_text) This works like the C method, but instead of raising an exception when there is trailing garbage after the first JSON object, it will silently stop parsing there and return the number of characters consumed so far. JSON->new->decode_prefix ("[1] the tail") => ([], 3) =head1 INCREMENTAL PARSING Most of this section are copied and modified from L. In some cases, there is the need for incremental parsing of JSON texts. This module does allow you to parse a JSON stream incrementally. It does so by accumulating text until it has a full JSON object, which it then can decode. This process is similar to using C to see if a full JSON object is available, but is much more efficient (and can be implemented with a minimum of method calls). This module will only attempt to parse the JSON text once it is sure it has enough text to get a decisive result, using a very simple but truly incremental parser. This means that it sometimes won't stop as early as the full parser, for example, it doesn't detect parenthesis mismatches. The only thing it guarantees is that it starts decoding as soon as a syntactically valid JSON text has been seen. This means you need to set resource limits (e.g. C) to ensure the parser will stop parsing in the presence if syntax errors. The following methods implement this incremental parser. =head2 incr_parse $json->incr_parse( [$string] ) # void context $obj_or_undef = $json->incr_parse( [$string] ) # scalar context @obj_or_empty = $json->incr_parse( [$string] ) # list context This is the central parsing function. It can both append new text and extract objects from the stream accumulated so far (both of these functions are optional). If C<$string> is given, then this string is appended to the already existing JSON fragment stored in the C<$json> object. After that, if the function is called in void context, it will simply return without doing anything further. This can be used to add more text in as many chunks as you want. If the method is called in scalar context, then it will try to extract exactly I JSON object. If that is successful, it will return this object, otherwise it will return C. If there is a parse error, this method will croak just as C would do (one can then use C to skip the erroneous part). This is the most common way of using the method. And finally, in list context, it will try to extract as many objects from the stream as it can find and return them, or the empty list otherwise. For this to work, there must be no separators between the JSON objects or arrays, instead they must be concatenated back-to-back. If an error occurs, an exception will be raised as in the scalar context case. Note that in this case, any previously-parsed JSON texts will be lost. Example: Parse some JSON arrays/objects in a given string and return them. my @objs = JSON->new->incr_parse ("[5][7][1,2]"); =head2 incr_text $lvalue_string = $json->incr_text This method returns the currently stored JSON fragment as an lvalue, that is, you can manipulate it. This I works when a preceding call to C in I successfully returned an object. Under all other circumstances you must not call this function (I mean it. although in simple tests it might actually work, it I fail under real world conditions). As a special exception, you can also call this method before having parsed anything. This function is useful in two cases: a) finding the trailing text after a JSON object or b) parsing multiple JSON objects separated by non-JSON text (such as commas). $json->incr_text =~ s/\s*,\s*//; In Perl 5.005, C attribute is not available. You must write codes like the below: $string = $json->incr_text; $string =~ s/\s*,\s*//; $json->incr_text( $string ); =head2 incr_skip $json->incr_skip This will reset the state of the incremental parser and will remove the parsed text from the input buffer. This is useful after C died, in which case the input buffer and incremental parser state is left unchanged, to skip the text parsed so far and to reset the parse state. =head2 incr_reset $json->incr_reset This completely resets the incremental parser, that is, after this call, it will be as if the parser had never parsed anything. This is useful if you want to repeatedly parse JSON objects and want to ignore any trailing data, which means you have to reset the parser after each successful decode. See to L for examples. =head1 JSON::PP OWN METHODS =head2 allow_singlequote $json = $json->allow_singlequote([$enable]) If C<$enable> is true (or missing), then C will accept JSON strings quoted by single quotations that are invalid JSON format. $json->allow_singlequote->decode({"foo":'bar'}); $json->allow_singlequote->decode({'foo':"bar"}); $json->allow_singlequote->decode({'foo':'bar'}); As same as the C option, this option may be used to parse application-specific files written by humans. =head2 allow_barekey $json = $json->allow_barekey([$enable]) If C<$enable> is true (or missing), then C will accept bare keys of JSON object that are invalid JSON format. As same as the C option, this option may be used to parse application-specific files written by humans. $json->allow_barekey->decode('{foo:"bar"}'); =head2 allow_bignum $json = $json->allow_bignum([$enable]) If C<$enable> is true (or missing), then C will convert the big integer Perl cannot handle as integer into a L object and convert a floating number (any) into a L. On the contrary, C converts C objects and C objects into JSON numbers with C enable. $json->allow_nonref->allow_blessed->allow_bignum; $bigfloat = $json->decode('2.000000000000000000000000001'); print $json->encode($bigfloat); # => 2.000000000000000000000000001 See to L about the normal conversion of JSON number. =head2 loose $json = $json->loose([$enable]) The unescaped [\x00-\x1f\x22\x2f\x5c] strings are invalid in JSON strings and the module doesn't allow to C to these (except for \x2f). If C<$enable> is true (or missing), then C will accept these unescaped strings. $json->loose->decode(qq|["abc def"]|); See L. =head2 escape_slash $json = $json->escape_slash([$enable]) According to JSON Grammar, I (U+002F) is escaped. But default JSON::PP (as same as JSON::XS) encodes strings without escaping slash. If C<$enable> is true (or missing), then C will escape slashes. =head2 indent_length $json = $json->indent_length($length) JSON::XS indent space length is 3 and cannot be changed. JSON::PP set the indent space length with the given $length. The default is 3. The acceptable range is 0 to 15. =head2 sort_by $json = $json->sort_by($function_name) $json = $json->sort_by($subroutine_ref) If $function_name or $subroutine_ref are set, its sort routine are used in encoding JSON objects. $js = $pc->sort_by(sub { $JSON::PP::a cmp $JSON::PP::b })->encode($obj); # is($js, q|{"a":1,"b":2,"c":3,"d":4,"e":5,"f":6,"g":7,"h":8,"i":9}|); $js = $pc->sort_by('own_sort')->encode($obj); # is($js, q|{"a":1,"b":2,"c":3,"d":4,"e":5,"f":6,"g":7,"h":8,"i":9}|); sub JSON::PP::own_sort { $JSON::PP::a cmp $JSON::PP::b } As the sorting routine runs in the JSON::PP scope, the given subroutine name and the special variables C<$a>, C<$b> will begin 'JSON::PP::'. If $integer is set, then the effect is same as C on. =head1 INTERNAL For developers. =over =item PP_encode_box Returns { depth => $depth, indent_count => $indent_count, } =item PP_decode_box Returns { text => $text, at => $at, ch => $ch, len => $len, depth => $depth, encoding => $encoding, is_valid_utf8 => $is_valid_utf8, }; =back =head1 MAPPING This section is copied from JSON::XS and modified to C. JSON::XS and JSON::PP mapping mechanisms are almost equivalent. See to L. =head2 JSON -> PERL =over 4 =item object A JSON object becomes a reference to a hash in Perl. No ordering of object keys is preserved (JSON does not preserver object key ordering itself). =item array A JSON array becomes a reference to an array in Perl. =item string A JSON string becomes a string scalar in Perl - Unicode codepoints in JSON are represented by the same codepoints in the Perl string, so no manual decoding is necessary. =item number A JSON number becomes either an integer, numeric (floating point) or string scalar in perl, depending on its range and any fractional parts. On the Perl level, there is no difference between those as Perl handles all the conversion details, but an integer may take slightly less memory and might represent more values exactly than floating point numbers. If the number consists of digits only, C will try to represent it as an integer value. If that fails, it will try to represent it as a numeric (floating point) value if that is possible without loss of precision. Otherwise it will preserve the number as a string value (in which case you lose roundtripping ability, as the JSON number will be re-encoded to a JSON string). Numbers containing a fractional or exponential part will always be represented as numeric (floating point) values, possibly at a loss of precision (in which case you might lose perfect roundtripping ability, but the JSON number will still be re-encoded as a JSON number). Note that precision is not accuracy - binary floating point values cannot represent most decimal fractions exactly, and when converting from and to floating point, C only guarantees precision up to but not including the least significant bit. When C is enable, the big integers and the numeric can be optionally converted into L and L objects. =item true, false These JSON atoms become C and C, respectively. They are overloaded to act almost exactly like the numbers C<1> and C<0>. You can check whether a scalar is a JSON boolean by using the C function. print JSON::PP::true . "\n"; => true print JSON::PP::true + 1; => 1 ok(JSON::true eq '1'); ok(JSON::true == 1); C will install these missing overloading features to the backend modules. =item null A JSON null atom becomes C in Perl. C returns C. =back =head2 PERL -> JSON The mapping from Perl to JSON is slightly more difficult, as Perl is a truly typeless language, so we can only guess which JSON type is meant by a Perl value. =over 4 =item hash references Perl hash references become JSON objects. As there is no inherent ordering in hash keys (or JSON objects), they will usually be encoded in a pseudo-random order that can change between runs of the same program but stays generally the same within a single run of a program. C optionally sort the hash keys (determined by the I flag), so the same data structure will serialise to the same JSON text (given same settings and version of JSON::XS), but this incurs a runtime overhead and is only rarely useful, e.g. when you want to compare some JSON text against another for equality. =item array references Perl array references become JSON arrays. =item other references Other unblessed references are generally not allowed and will cause an exception to be thrown, except for references to the integers C<0> and C<1>, which get turned into C and C atoms in JSON. You can also use C and C to improve readability. to_json [\0,JSON::PP::true] # yields [false,true] =item JSON::PP::true, JSON::PP::false, JSON::PP::null These special values become JSON true and JSON false values, respectively. You can also use C<\1> and C<\0> directly if you want. JSON::PP::null returns C. =item blessed objects Blessed objects are not directly representable in JSON. See the C and C methods on various options on how to deal with this: basically, you can choose between throwing an exception, encoding the reference as if it weren't blessed, or provide your own serialiser method. See to L. =item simple scalars Simple Perl scalars (any scalar that is not a reference) are the most difficult objects to encode: JSON::XS and JSON::PP will encode undefined scalars as JSON C values, scalars that have last been used in a string context before encoding as JSON strings, and anything else as number value: # dump as number encode_json [2] # yields [2] encode_json [-3.0e17] # yields [-3e+17] my $value = 5; encode_json [$value] # yields [5] # used as string, so dump as string print $value; encode_json [$value] # yields ["5"] # undef becomes null encode_json [undef] # yields [null] You can force the type to be a string by stringifying it: my $x = 3.1; # some variable containing a number "$x"; # stringified $x .= ""; # another, more awkward way to stringify print $x; # perl does it for you, too, quite often You can force the type to be a number by numifying it: my $x = "3"; # some variable containing a string $x += 0; # numify it, ensuring it will be dumped as a number $x *= 1; # same thing, the choice is yours. You can not currently force the type in other, less obscure, ways. Note that numerical precision has the same meaning as under Perl (so binary to decimal conversion follows the same rules as in Perl, which can differ to other languages). Also, your perl interpreter might expose extensions to the floating point numbers of your platform, such as infinities or NaN's - these cannot be represented in JSON, and it is an error to pass those in. =item Big Number When C is enable, C converts C objects and C objects into JSON numbers. =back =head1 UNICODE HANDLING ON PERLS If you do not know about Unicode on Perl well, please check L. =head2 Perl 5.8 and later Perl can handle Unicode and the JSON::PP de/encode methods also work properly. $json->allow_nonref->encode(chr hex 3042); $json->allow_nonref->encode(chr hex 12345); Returns C<"\u3042"> and C<"\ud808\udf45"> respectively. $json->allow_nonref->decode('"\u3042"'); $json->allow_nonref->decode('"\ud808\udf45"'); Returns UTF-8 encoded strings with UTF8 flag, regarded as C and C. Note that the versions from Perl 5.8.0 to 5.8.2, Perl built-in C was broken, so JSON::PP wraps the C with a subroutine. Thus JSON::PP works slow in the versions. =head2 Perl 5.6 Perl can handle Unicode and the JSON::PP de/encode methods also work. =head2 Perl 5.005 Perl 5.005 is a byte semantics world -- all strings are sequences of bytes. That means the unicode handling is not available. In encoding, $json->allow_nonref->encode(chr hex 3042); # hex 3042 is 12354. $json->allow_nonref->encode(chr hex 12345); # hex 12345 is 74565. Returns C and C, as C takes a value more than 255, it treats as C<$value % 256>, so the above codes are equivalent to : $json->allow_nonref->encode(chr 66); $json->allow_nonref->encode(chr 69); In decoding, $json->decode('"\u00e3\u0081\u0082"'); The returned is a byte sequence C<0xE3 0x81 0x82> for UTF-8 encoded japanese character (C). And if it is represented in Unicode code point, C. Next, $json->decode('"\u3042"'); We ordinary expect the returned value is a Unicode character C. But here is 5.005 world. This is C<0xE3 0x81 0x82>. $json->decode('"\ud808\udf45"'); This is not a character C but bytes - C<0xf0 0x92 0x8d 0x85>. =head1 TODO =over =item speed =item memory saving =back =head1 SEE ALSO Most of the document are copied and modified from JSON::XS doc. L RFC4627 (L) =head1 AUTHOR Makamaka Hannyaharamitu, Emakamaka[at]cpan.orgE =head1 COPYRIGHT AND LICENSE Copyright 2007-2012 by Makamaka Hannyaharamitu This library is free software; you can redistribute it and/or modify it under the same terms as Perl itself. =cut JSON-2.90/lib/JSON.pm0000644000175000017500000021154012234431225012563 0ustar reonreonpackage JSON; use strict; use Carp (); use base qw(Exporter); @JSON::EXPORT = qw(from_json to_json jsonToObj objToJson encode_json decode_json); BEGIN { $JSON::VERSION = '2.90'; $JSON::DEBUG = 0 unless (defined $JSON::DEBUG); $JSON::DEBUG = $ENV{ PERL_JSON_DEBUG } if exists $ENV{ PERL_JSON_DEBUG }; } my $Module_XS = 'JSON::XS'; my $Module_PP = 'JSON::PP'; my $Module_bp = 'JSON::backportPP'; # included in JSON distribution my $PP_Version = '2.27203'; my $XS_Version = '2.34'; # XS and PP common methods my @PublicMethods = qw/ ascii latin1 utf8 pretty indent space_before space_after relaxed canonical allow_nonref allow_blessed convert_blessed filter_json_object filter_json_single_key_object shrink max_depth max_size encode decode decode_prefix allow_unknown /; my @Properties = qw/ ascii latin1 utf8 indent space_before space_after relaxed canonical allow_nonref allow_blessed convert_blessed shrink max_depth max_size allow_unknown /; my @XSOnlyMethods = qw/allow_tags/; # Currently nothing my @PPOnlyMethods = qw/ indent_length sort_by allow_singlequote allow_bignum loose allow_barekey escape_slash as_nonblessed /; # JSON::PP specific # used in _load_xs and _load_pp ($INSTALL_ONLY is not used currently) my $_INSTALL_DONT_DIE = 1; # When _load_xs fails to load XS, don't die. my $_INSTALL_ONLY = 2; # Don't call _set_methods() my $_ALLOW_UNSUPPORTED = 0; my $_UNIV_CONV_BLESSED = 0; my $_USSING_bpPP = 0; # Check the environment variable to decide worker module. unless ($JSON::Backend) { $JSON::DEBUG and Carp::carp("Check used worker module..."); my $backend = exists $ENV{PERL_JSON_BACKEND} ? $ENV{PERL_JSON_BACKEND} : 1; if ($backend eq '1' or $backend =~ /JSON::XS\s*,\s*JSON::PP/) { _load_xs($_INSTALL_DONT_DIE) or _load_pp(); } elsif ($backend eq '0' or $backend eq 'JSON::PP') { _load_pp(); } elsif ($backend eq '2' or $backend eq 'JSON::XS') { _load_xs(); } elsif ($backend eq 'JSON::backportPP') { $_USSING_bpPP = 1; _load_pp(); } else { Carp::croak "The value of environmental variable 'PERL_JSON_BACKEND' is invalid."; } } sub import { my $pkg = shift; my @what_to_export; my $no_export; for my $tag (@_) { if ($tag eq '-support_by_pp') { if (!$_ALLOW_UNSUPPORTED++) { JSON::Backend::XS ->support_by_pp(@PPOnlyMethods) if ($JSON::Backend eq $Module_XS); } next; } elsif ($tag eq '-no_export') { $no_export++, next; } elsif ( $tag eq '-convert_blessed_universally' ) { eval q| require B; *UNIVERSAL::TO_JSON = sub { my $b_obj = B::svref_2object( $_[0] ); return $b_obj->isa('B::HV') ? { %{ $_[0] } } : $b_obj->isa('B::AV') ? [ @{ $_[0] } ] : undef ; } | if ( !$_UNIV_CONV_BLESSED++ ); next; } push @what_to_export, $tag; } return if ($no_export); __PACKAGE__->export_to_level(1, $pkg, @what_to_export); } # OBSOLETED sub jsonToObj { my $alternative = 'from_json'; if (defined $_[0] and UNIVERSAL::isa($_[0], 'JSON')) { shift @_; $alternative = 'decode'; } Carp::carp "'jsonToObj' will be obsoleted. Please use '$alternative' instead."; return JSON::from_json(@_); }; sub objToJson { my $alternative = 'to_json'; if (defined $_[0] and UNIVERSAL::isa($_[0], 'JSON')) { shift @_; $alternative = 'encode'; } Carp::carp "'objToJson' will be obsoleted. Please use '$alternative' instead."; JSON::to_json(@_); }; # INTERFACES sub to_json ($@) { if ( ref($_[0]) eq 'JSON' or (@_ > 2 and $_[0] eq 'JSON') ) { Carp::croak "to_json should not be called as a method."; } my $json = JSON->new; if (@_ == 2 and ref $_[1] eq 'HASH') { my $opt = $_[1]; for my $method (keys %$opt) { $json->$method( $opt->{$method} ); } } $json->encode($_[0]); } sub from_json ($@) { if ( ref($_[0]) eq 'JSON' or $_[0] eq 'JSON' ) { Carp::croak "from_json should not be called as a method."; } my $json = JSON->new; if (@_ == 2 and ref $_[1] eq 'HASH') { my $opt = $_[1]; for my $method (keys %$opt) { $json->$method( $opt->{$method} ); } } return $json->decode( $_[0] ); } sub true { $JSON::true } sub false { $JSON::false } sub null { undef; } sub require_xs_version { $XS_Version; } sub backend { my $proto = shift; $JSON::Backend; } #*module = *backend; sub is_xs { return $_[0]->backend eq $Module_XS; } sub is_pp { return not $_[0]->is_xs; } sub pureperl_only_methods { @PPOnlyMethods; } sub property { my ($self, $name, $value) = @_; if (@_ == 1) { my %props; for $name (@Properties) { my $method = 'get_' . $name; if ($name eq 'max_size') { my $value = $self->$method(); $props{$name} = $value == 1 ? 0 : $value; next; } $props{$name} = $self->$method(); } return \%props; } elsif (@_ > 3) { Carp::croak('property() can take only the option within 2 arguments.'); } elsif (@_ == 2) { if ( my $method = $self->can('get_' . $name) ) { if ($name eq 'max_size') { my $value = $self->$method(); return $value == 1 ? 0 : $value; } $self->$method(); } } else { $self->$name($value); } } # INTERNAL sub _load_xs { my $opt = shift; $JSON::DEBUG and Carp::carp "Load $Module_XS."; # if called after install module, overload is disable.... why? JSON::Boolean::_overrride_overload($Module_XS); JSON::Boolean::_overrride_overload($Module_PP); eval qq| use $Module_XS $XS_Version (); |; if ($@) { if (defined $opt and $opt & $_INSTALL_DONT_DIE) { $JSON::DEBUG and Carp::carp "Can't load $Module_XS...($@)"; return 0; } Carp::croak $@; } unless (defined $opt and $opt & $_INSTALL_ONLY) { _set_module( $JSON::Backend = $Module_XS ); my $data = join("", ); # this code is from Jcode 2.xx. close(DATA); eval $data; JSON::Backend::XS->init; } return 1; }; sub _load_pp { my $opt = shift; my $backend = $_USSING_bpPP ? $Module_bp : $Module_PP; $JSON::DEBUG and Carp::carp "Load $backend."; # if called after install module, overload is disable.... why? JSON::Boolean::_overrride_overload($Module_XS); JSON::Boolean::_overrride_overload($backend); if ( $_USSING_bpPP ) { eval qq| require $backend |; } else { eval qq| use $backend $PP_Version () |; } if ($@) { if ( $backend eq $Module_PP ) { $JSON::DEBUG and Carp::carp "Can't load $Module_PP ($@), so try to load $Module_bp"; $_USSING_bpPP++; $backend = $Module_bp; JSON::Boolean::_overrride_overload($backend); local $^W; # if PP installed but invalid version, backportPP redefines methods. eval qq| require $Module_bp |; } Carp::croak $@ if $@; } unless (defined $opt and $opt & $_INSTALL_ONLY) { _set_module( $JSON::Backend = $Module_PP ); # even if backportPP, set $Backend with 'JSON::PP' JSON::Backend::PP->init; } }; sub _set_module { return if defined $JSON::true; my $module = shift; local $^W; no strict qw(refs); $JSON::true = ${"$module\::true"}; $JSON::false = ${"$module\::false"}; push @JSON::ISA, $module; if ( JSON->is_xs and JSON->backend->VERSION < 3 ) { eval 'package JSON::PP::Boolean'; push @{"$module\::Boolean::ISA"}, qw(JSON::PP::Boolean); } *{"JSON::is_bool"} = \&{"$module\::is_bool"}; for my $method ($module eq $Module_XS ? @PPOnlyMethods : @XSOnlyMethods) { *{"JSON::$method"} = sub { Carp::carp("$method is not supported in $module."); $_[0]; }; } return 1; } # # JSON Boolean # package JSON::Boolean; my %Installed; sub _overrride_overload { return; # this function is currently disable. return if ($Installed{ $_[0] }++); my $boolean = $_[0] . '::Boolean'; eval sprintf(q| package %s; use overload ( '""' => sub { ${$_[0]} == 1 ? 'true' : 'false' }, 'eq' => sub { my ($obj, $op) = ref ($_[0]) ? ($_[0], $_[1]) : ($_[1], $_[0]); if ($op eq 'true' or $op eq 'false') { return "$obj" eq 'true' ? 'true' eq $op : 'false' eq $op; } else { return $obj ? 1 == $op : 0 == $op; } }, ); |, $boolean); if ($@) { Carp::croak $@; } if ( exists $INC{'JSON/XS.pm'} and $boolean eq 'JSON::XS::Boolean' ) { local $^W; my $true = do { bless \(my $dummy = 1), $boolean }; my $false = do { bless \(my $dummy = 0), $boolean }; *JSON::XS::true = sub () { $true }; *JSON::XS::false = sub () { $false }; } elsif ( exists $INC{'JSON/PP.pm'} and $boolean eq 'JSON::PP::Boolean' ) { local $^W; my $true = do { bless \(my $dummy = 1), $boolean }; my $false = do { bless \(my $dummy = 0), $boolean }; *JSON::PP::true = sub { $true }; *JSON::PP::false = sub { $false }; } return 1; } # # Helper classes for Backend Module (PP) # package JSON::Backend::PP; sub init { local $^W; no strict qw(refs); # this routine may be called after JSON::Backend::XS init was called. *{"JSON::decode_json"} = \&{"JSON::PP::decode_json"}; *{"JSON::encode_json"} = \&{"JSON::PP::encode_json"}; *{"JSON::PP::is_xs"} = sub { 0 }; *{"JSON::PP::is_pp"} = sub { 1 }; return 1; } # # To save memory, the below lines are read only when XS backend is used. # package JSON; 1; __DATA__ # # Helper classes for Backend Module (XS) # package JSON::Backend::XS; use constant INDENT_LENGTH_FLAG => 15 << 12; use constant UNSUPPORTED_ENCODE_FLAG => { ESCAPE_SLASH => 0x00000010, ALLOW_BIGNUM => 0x00000020, AS_NONBLESSED => 0x00000040, EXPANDED => 0x10000000, # for developer's }; use constant UNSUPPORTED_DECODE_FLAG => { LOOSE => 0x00000001, ALLOW_BIGNUM => 0x00000002, ALLOW_BAREKEY => 0x00000004, ALLOW_SINGLEQUOTE => 0x00000008, EXPANDED => 0x20000000, # for developer's }; sub init { local $^W; no strict qw(refs); *{"JSON::decode_json"} = \&{"JSON::XS::decode_json"}; *{"JSON::encode_json"} = \&{"JSON::XS::encode_json"}; *{"JSON::XS::is_xs"} = sub { 1 }; *{"JSON::XS::is_pp"} = sub { 0 }; return 1; } sub support_by_pp { my ($class, @methods) = @_; local $^W; no strict qw(refs); my $JSON_XS_encode_orignal = \&JSON::XS::encode; my $JSON_XS_decode_orignal = \&JSON::XS::decode; my $JSON_XS_incr_parse_orignal = \&JSON::XS::incr_parse; *JSON::XS::decode = \&JSON::Backend::XS::Supportable::_decode; *JSON::XS::encode = \&JSON::Backend::XS::Supportable::_encode; *JSON::XS::incr_parse = \&JSON::Backend::XS::Supportable::_incr_parse; *{JSON::XS::_original_decode} = $JSON_XS_decode_orignal; *{JSON::XS::_original_encode} = $JSON_XS_encode_orignal; *{JSON::XS::_original_incr_parse} = $JSON_XS_incr_parse_orignal; push @JSON::Backend::XS::Supportable::ISA, 'JSON'; my $pkg = 'JSON::Backend::XS::Supportable'; *{JSON::new} = sub { my $proto = JSON::XS->new; $$proto = 0; bless $proto, $pkg; }; for my $method (@methods) { my $flag = uc($method); my $type |= (UNSUPPORTED_ENCODE_FLAG->{$flag} || 0); $type |= (UNSUPPORTED_DECODE_FLAG->{$flag} || 0); next unless($type); $pkg->_make_unsupported_method($method => $type); } # push @{"JSON::XS::Boolean::ISA"}, qw(JSON::PP::Boolean); # push @{"JSON::PP::Boolean::ISA"}, qw(JSON::Boolean); $JSON::DEBUG and Carp::carp("set -support_by_pp mode."); return 1; } # # Helper classes for XS # package JSON::Backend::XS::Supportable; $Carp::Internal{'JSON::Backend::XS::Supportable'} = 1; sub _make_unsupported_method { my ($pkg, $method, $type) = @_; local $^W; no strict qw(refs); *{"$pkg\::$method"} = sub { local $^W; if (defined $_[1] ? $_[1] : 1) { ${$_[0]} |= $type; } else { ${$_[0]} &= ~$type; } $_[0]; }; *{"$pkg\::get_$method"} = sub { ${$_[0]} & $type ? 1 : ''; }; } sub _set_for_pp { JSON::_load_pp( $_INSTALL_ONLY ); my $type = shift; my $pp = JSON::PP->new; my $prop = $_[0]->property; for my $name (keys %$prop) { $pp->$name( $prop->{$name} ? $prop->{$name} : 0 ); } my $unsupported = $type eq 'encode' ? JSON::Backend::XS::UNSUPPORTED_ENCODE_FLAG : JSON::Backend::XS::UNSUPPORTED_DECODE_FLAG; my $flags = ${$_[0]} || 0; for my $name (keys %$unsupported) { next if ($name eq 'EXPANDED'); # for developer's my $enable = ($flags & $unsupported->{$name}) ? 1 : 0; my $method = lc $name; $pp->$method($enable); } $pp->indent_length( $_[0]->get_indent_length ); return $pp; } sub _encode { # using with PP encode if (${$_[0]}) { _set_for_pp('encode' => @_)->encode($_[1]); } else { $_[0]->_original_encode( $_[1] ); } } sub _decode { # if unsupported-flag is set, use PP if (${$_[0]}) { _set_for_pp('decode' => @_)->decode($_[1]); } else { $_[0]->_original_decode( $_[1] ); } } sub decode_prefix { # if unsupported-flag is set, use PP _set_for_pp('decode' => @_)->decode_prefix($_[1]); } sub _incr_parse { if (${$_[0]}) { _set_for_pp('decode' => @_)->incr_parse($_[1]); } else { $_[0]->_original_incr_parse( $_[1] ); } } sub get_indent_length { ${$_[0]} << 4 >> 16; } sub indent_length { my $length = $_[1]; if (!defined $length or $length > 15 or $length < 0) { Carp::carp "The acceptable range of indent_length() is 0 to 15."; } else { local $^W; $length <<= 12; ${$_[0]} &= ~ JSON::Backend::XS::INDENT_LENGTH_FLAG; ${$_[0]} |= $length; *JSON::XS::encode = \&JSON::Backend::XS::Supportable::_encode; } $_[0]; } 1; __END__ =head1 NAME JSON - JSON (JavaScript Object Notation) encoder/decoder =head1 SYNOPSIS use JSON; # imports encode_json, decode_json, to_json and from_json. # simple and fast interfaces (expect/generate UTF-8) $utf8_encoded_json_text = encode_json $perl_hash_or_arrayref; $perl_hash_or_arrayref = decode_json $utf8_encoded_json_text; # OO-interface $json = JSON->new->allow_nonref; $json_text = $json->encode( $perl_scalar ); $perl_scalar = $json->decode( $json_text ); $pretty_printed = $json->pretty->encode( $perl_scalar ); # pretty-printing # If you want to use PP only support features, call with '-support_by_pp' # When XS unsupported feature is enable, using PP (de|en)code instead of XS ones. use JSON -support_by_pp; # option-acceptable interfaces (expect/generate UNICODE by default) $json_text = to_json( $perl_scalar, { ascii => 1, pretty => 1 } ); $perl_scalar = from_json( $json_text, { utf8 => 1 } ); # Between (en|de)code_json and (to|from)_json, if you want to write # a code which communicates to an outer world (encoded in UTF-8), # recommend to use (en|de)code_json. =head1 VERSION 2.90 This version is compatible with JSON::XS B<2.34> and later. (Not yet compatble to JSON::XS B<3.0x>.) =head1 NOTE JSON::PP was earlier included in the C distribution, but has since Perl 5.14 been a core module. For this reason, L was removed from the JSON distribution and can now be found also in the Perl5 repository at =over =item * L =back (The newest JSON::PP version still exists in CPAN.) Instead, the C distribution will include JSON::backportPP for backwards computability. JSON.pm should thus work as it did before. =head1 DESCRIPTION *************************** CAUTION ************************************** * * * INCOMPATIBLE CHANGE (JSON::XS version 2.90) * * * * JSON.pm had patched JSON::XS::Boolean and JSON::PP::Boolean internally * * on loading time for making these modules inherit JSON::Boolean. * * But since JSON::XS v3.0 it use Types::Serialiser as boolean class. * * Then now JSON.pm breaks boolean classe overload features and * * -support_by_pp if JSON::XS v3.0 or later is installed. * * * * JSON::true and JSON::false returned JSON::Boolean objects. * * For workaround, they return JSON::PP::Boolean objects in this version. * * * * isa_ok(JSON::true, 'JSON::PP::Boolean'); * * * * And it discards a feature: * * * * ok(JSON::true eq 'true'); * * * * In other word, JSON::PP::Boolean overload numeric only. * * * * ok( JSON::true == 1 ); * * * ************************************************************************** ************************** CAUTION ******************************** * This is 'JSON module version 2' and there are many differences * * to version 1.xx * * Please check your applications using old version. * * See to 'INCOMPATIBLE CHANGES TO OLD VERSION' * ******************************************************************* JSON (JavaScript Object Notation) is a simple data format. See to L and C(L). This module converts Perl data structures to JSON and vice versa using either L or L. JSON::XS is the fastest and most proper JSON module on CPAN which must be compiled and installed in your environment. JSON::PP is a pure-Perl module which is bundled in this distribution and has a strong compatibility to JSON::XS. This module try to use JSON::XS by default and fail to it, use JSON::PP instead. So its features completely depend on JSON::XS or JSON::PP. See to L. To distinguish the module name 'JSON' and the format type JSON, the former is quoted by CEE (its results vary with your using media), and the latter is left just as it is. Module name : C Format type : JSON =head2 FEATURES =over =item * correct unicode handling This module (i.e. backend modules) knows how to handle Unicode, documents how and when it does so, and even documents what "correct" means. Even though there are limitations, this feature is available since Perl version 5.6. JSON::XS requires Perl 5.8.2 (but works correctly in 5.8.8 or later), so in older versions C should call JSON::PP as the backend which can be used since Perl 5.005. With Perl 5.8.x JSON::PP works, but from 5.8.0 to 5.8.2, because of a Perl side problem, JSON::PP works slower in the versions. And in 5.005, the Unicode handling is not available. See to L for more information. See also to L and L. =item * round-trip integrity When you serialise a perl data structure using only data types supported by JSON and Perl, the deserialised data structure is identical on the Perl level. (e.g. the string "2.0" doesn't suddenly become "2" just because it looks like a number). There I minor exceptions to this, read the L section below to learn about those. =item * strict checking of JSON correctness There is no guessing, no generating of illegal JSON texts by default, and only JSON is accepted as input by default (the latter is a security feature). See to L and L. =item * fast This module returns a JSON::XS object itself if available. Compared to other JSON modules and other serialisers such as Storable, JSON::XS usually compares favorably in terms of speed, too. If not available, C returns a JSON::PP object instead of JSON::XS and it is very slow as pure-Perl. =item * simple to use This module has both a simple functional interface as well as an object oriented interface interface. =item * reasonably versatile output formats You can choose between the most compact guaranteed-single-line format possible (nice for simple line-based protocols), a pure-ASCII format (for when your transport is not 8-bit clean, still supports the whole Unicode range), or a pretty-printed format (for when you want to read that stuff). Or you can combine those features in whatever way you like. =back =head1 FUNCTIONAL INTERFACE Some documents are copied and modified from L. C and C are additional functions. =head2 encode_json $json_text = encode_json $perl_scalar Converts the given Perl data structure to a UTF-8 encoded, binary string. This function call is functionally identical to: $json_text = JSON->new->utf8->encode($perl_scalar) =head2 decode_json $perl_scalar = decode_json $json_text The opposite of C: expects an UTF-8 (binary) string and tries to parse that as an UTF-8 encoded JSON text, returning the resulting reference. This function call is functionally identical to: $perl_scalar = JSON->new->utf8->decode($json_text) =head2 to_json $json_text = to_json($perl_scalar) Converts the given Perl data structure to a json string. This function call is functionally identical to: $json_text = JSON->new->encode($perl_scalar) Takes a hash reference as the second. $json_text = to_json($perl_scalar, $flag_hashref) So, $json_text = to_json($perl_scalar, {utf8 => 1, pretty => 1}) equivalent to: $json_text = JSON->new->utf8(1)->pretty(1)->encode($perl_scalar) If you want to write a modern perl code which communicates to outer world, you should use C (supposed that JSON data are encoded in UTF-8). =head2 from_json $perl_scalar = from_json($json_text) The opposite of C: expects a json string and tries to parse it, returning the resulting reference. This function call is functionally identical to: $perl_scalar = JSON->decode($json_text) Takes a hash reference as the second. $perl_scalar = from_json($json_text, $flag_hashref) So, $perl_scalar = from_json($json_text, {utf8 => 1}) equivalent to: $perl_scalar = JSON->new->utf8(1)->decode($json_text) If you want to write a modern perl code which communicates to outer world, you should use C (supposed that JSON data are encoded in UTF-8). =head2 JSON::is_bool $is_boolean = JSON::is_bool($scalar) Returns true if the passed scalar represents either JSON::true or JSON::false, two constants that act like C<1> and C<0> respectively and are also used to represent JSON C and C in Perl strings. =head2 JSON::true Returns JSON true value which is blessed object. It C JSON::Boolean object. =head2 JSON::false Returns JSON false value which is blessed object. It C JSON::Boolean object. =head2 JSON::null Returns C. See L, below, for more information on how JSON values are mapped to Perl. =head1 HOW DO I DECODE A DATA FROM OUTER AND ENCODE TO OUTER This section supposes that your perl version is 5.8 or later. If you know a JSON text from an outer world - a network, a file content, and so on, is encoded in UTF-8, you should use C or C module object with C enable. And the decoded result will contain UNICODE characters. # from network my $json = JSON->new->utf8; my $json_text = CGI->new->param( 'json_data' ); my $perl_scalar = $json->decode( $json_text ); # from file content local $/; open( my $fh, '<', 'json.data' ); $json_text = <$fh>; $perl_scalar = decode_json( $json_text ); If an outer data is not encoded in UTF-8, firstly you should C it. use Encode; local $/; open( my $fh, '<', 'json.data' ); my $encoding = 'cp932'; my $unicode_json_text = decode( $encoding, <$fh> ); # UNICODE # or you can write the below code. # # open( my $fh, "<:encoding($encoding)", 'json.data' ); # $unicode_json_text = <$fh>; In this case, C<$unicode_json_text> is of course UNICODE string. So you B use C nor C module object with C enable. Instead of them, you use C module object with C disable or C. $perl_scalar = $json->utf8(0)->decode( $unicode_json_text ); # or $perl_scalar = from_json( $unicode_json_text ); Or C and C: $perl_scalar = decode_json( encode( 'utf8', $unicode_json_text ) ); # this way is not efficient. And now, you want to convert your C<$perl_scalar> into JSON data and send it to an outer world - a network or a file content, and so on. Your data usually contains UNICODE strings and you want the converted data to be encoded in UTF-8, you should use C or C module object with C enable. print encode_json( $perl_scalar ); # to a network? file? or display? # or print $json->utf8->encode( $perl_scalar ); If C<$perl_scalar> does not contain UNICODE but C<$encoding>-encoded strings for some reason, then its characters are regarded as B for perl (because it does not concern with your $encoding). You B use C nor C module object with C enable. Instead of them, you use C module object with C disable or C. Note that the resulted text is a UNICODE string but no problem to print it. # $perl_scalar contains $encoding encoded string values $unicode_json_text = $json->utf8(0)->encode( $perl_scalar ); # or $unicode_json_text = to_json( $perl_scalar ); # $unicode_json_text consists of characters less than 0x100 print $unicode_json_text; Or C all string values and C: $perl_scalar->{ foo } = decode( $encoding, $perl_scalar->{ foo } ); # ... do it to each string values, then encode_json $json_text = encode_json( $perl_scalar ); This method is a proper way but probably not efficient. See to L, L. =head1 COMMON OBJECT-ORIENTED INTERFACE =head2 new $json = JSON->new Returns a new C object inherited from either JSON::XS or JSON::PP that can be used to de/encode JSON strings. All boolean flags described below are by default I. The mutators for flags all return the JSON object again and thus calls can be chained: my $json = JSON->new->utf8->space_after->encode({a => [1,2]}) => {"a": [1, 2]} =head2 ascii $json = $json->ascii([$enable]) $enabled = $json->get_ascii If $enable is true (or missing), then the encode method will not generate characters outside the code range 0..127. Any Unicode characters outside that range will be escaped using either a single \uXXXX or a double \uHHHH\uLLLLL escape sequence, as per RFC4627. If $enable is false, then the encode method will not escape Unicode characters unless required by the JSON syntax or other flags. This results in a faster and more compact format. This feature depends on the used Perl version and environment. See to L if the backend is PP. JSON->new->ascii(1)->encode([chr 0x10401]) => ["\ud801\udc01"] =head2 latin1 $json = $json->latin1([$enable]) $enabled = $json->get_latin1 If $enable is true (or missing), then the encode method will encode the resulting JSON text as latin1 (or iso-8859-1), escaping any characters outside the code range 0..255. If $enable is false, then the encode method will not escape Unicode characters unless required by the JSON syntax or other flags. JSON->new->latin1->encode (["\x{89}\x{abc}"] => ["\x{89}\\u0abc"] # (perl syntax, U+abc escaped, U+89 not) =head2 utf8 $json = $json->utf8([$enable]) $enabled = $json->get_utf8 If $enable is true (or missing), then the encode method will encode the JSON result into UTF-8, as required by many protocols, while the decode method expects to be handled an UTF-8-encoded string. Please note that UTF-8-encoded strings do not contain any characters outside the range 0..255, they are thus useful for bytewise/binary I/O. In future versions, enabling this option might enable autodetection of the UTF-16 and UTF-32 encoding families, as described in RFC4627. If $enable is false, then the encode method will return the JSON string as a (non-encoded) Unicode string, while decode expects thus a Unicode string. Any decoding or encoding (e.g. to UTF-8 or UTF-16) needs to be done yourself, e.g. using the Encode module. Example, output UTF-16BE-encoded JSON: use Encode; $jsontext = encode "UTF-16BE", JSON::XS->new->encode ($object); Example, decode UTF-32LE-encoded JSON: use Encode; $object = JSON::XS->new->decode (decode "UTF-32LE", $jsontext); See to L if the backend is PP. =head2 pretty $json = $json->pretty([$enable]) This enables (or disables) all of the C, C and C (and in the future possibly more) flags in one call to generate the most readable (or most compact) form possible. Equivalent to: $json->indent->space_before->space_after The indent space length is three and JSON::XS cannot change the indent space length. =head2 indent $json = $json->indent([$enable]) $enabled = $json->get_indent If C<$enable> is true (or missing), then the C method will use a multiline format as output, putting every array member or object/hash key-value pair into its own line, identifying them properly. If C<$enable> is false, no newlines or indenting will be produced, and the resulting JSON text is guaranteed not to contain any C. This setting has no effect when decoding JSON texts. The indent space length is three. With JSON::PP, you can also access C to change indent space length. =head2 space_before $json = $json->space_before([$enable]) $enabled = $json->get_space_before If C<$enable> is true (or missing), then the C method will add an extra optional space before the C<:> separating keys from values in JSON objects. If C<$enable> is false, then the C method will not add any extra space at those places. This setting has no effect when decoding JSON texts. Example, space_before enabled, space_after and indent disabled: {"key" :"value"} =head2 space_after $json = $json->space_after([$enable]) $enabled = $json->get_space_after If C<$enable> is true (or missing), then the C method will add an extra optional space after the C<:> separating keys from values in JSON objects and extra whitespace after the C<,> separating key-value pairs and array members. If C<$enable> is false, then the C method will not add any extra space at those places. This setting has no effect when decoding JSON texts. Example, space_before and indent disabled, space_after enabled: {"key": "value"} =head2 relaxed $json = $json->relaxed([$enable]) $enabled = $json->get_relaxed If C<$enable> is true (or missing), then C will accept some extensions to normal JSON syntax (see below). C will not be affected in anyway. I. I suggest only to use this option to parse application-specific files written by humans (configuration files, resource files etc.) If C<$enable> is false (the default), then C will only accept valid JSON texts. Currently accepted extensions are: =over 4 =item * list items can have an end-comma JSON I array elements and key-value pairs with commas. This can be annoying if you write JSON texts manually and want to be able to quickly append elements, so this extension accepts comma at the end of such items not just between them: [ 1, 2, <- this comma not normally allowed ] { "k1": "v1", "k2": "v2", <- this comma not normally allowed } =item * shell-style '#'-comments Whenever JSON allows whitespace, shell-style comments are additionally allowed. They are terminated by the first carriage-return or line-feed character, after which more white-space and comments are allowed. [ 1, # this comment not allowed in JSON # neither this one... ] =back =head2 canonical $json = $json->canonical([$enable]) $enabled = $json->get_canonical If C<$enable> is true (or missing), then the C method will output JSON objects by sorting their keys. This is adding a comparatively high overhead. If C<$enable> is false, then the C method will output key-value pairs in the order Perl stores them (which will likely change between runs of the same script). This option is useful if you want the same data structure to be encoded as the same JSON text (given the same overall settings). If it is disabled, the same hash might be encoded differently even if contains the same data, as key-value pairs have no inherent ordering in Perl. This setting has no effect when decoding JSON texts. =head2 allow_nonref $json = $json->allow_nonref([$enable]) $enabled = $json->get_allow_nonref If C<$enable> is true (or missing), then the C method can convert a non-reference into its corresponding string, number or null JSON value, which is an extension to RFC4627. Likewise, C will accept those JSON values instead of croaking. If C<$enable> is false, then the C method will croak if it isn't passed an arrayref or hashref, as JSON texts must either be an object or array. Likewise, C will croak if given something that is not a JSON object or array. JSON->new->allow_nonref->encode ("Hello, World!") => "Hello, World!" =head2 allow_unknown $json = $json->allow_unknown ([$enable]) $enabled = $json->get_allow_unknown If $enable is true (or missing), then "encode" will *not* throw an exception when it encounters values it cannot represent in JSON (for example, filehandles) but instead will encode a JSON "null" value. Note that blessed objects are not included here and are handled separately by c. If $enable is false (the default), then "encode" will throw an exception when it encounters anything it cannot encode as JSON. This option does not affect "decode" in any way, and it is recommended to leave it off unless you know your communications partner. =head2 allow_blessed $json = $json->allow_blessed([$enable]) $enabled = $json->get_allow_blessed If C<$enable> is true (or missing), then the C method will not barf when it encounters a blessed reference. Instead, the value of the B option will decide whether C (C disabled or no C method found) or a representation of the object (C enabled and C method found) is being encoded. Has no effect on C. If C<$enable> is false (the default), then C will throw an exception when it encounters a blessed object. =head2 convert_blessed $json = $json->convert_blessed([$enable]) $enabled = $json->get_convert_blessed If C<$enable> is true (or missing), then C, upon encountering a blessed object, will check for the availability of the C method on the object's class. If found, it will be called in scalar context and the resulting scalar will be encoded instead of the object. If no C method is found, the value of C will decide what to do. The C method may safely call die if it wants. If C returns other blessed objects, those will be handled in the same way. C must take care of not causing an endless recursion cycle (== crash) in this case. The name of C was chosen because other methods called by the Perl core (== not by the user of the object) are usually in upper case letters and to avoid collisions with the C function or method. This setting does not yet influence C in any way. If C<$enable> is false, then the C setting will decide what to do when a blessed object is found. =over =item convert_blessed_universally mode If use C with C<-convert_blessed_universally>, the C subroutine is defined as the below code: *UNIVERSAL::TO_JSON = sub { my $b_obj = B::svref_2object( $_[0] ); return $b_obj->isa('B::HV') ? { %{ $_[0] } } : $b_obj->isa('B::AV') ? [ @{ $_[0] } ] : undef ; } This will cause that C method converts simple blessed objects into JSON objects as non-blessed object. JSON -convert_blessed_universally; $json->allow_blessed->convert_blessed->encode( $blessed_object ) This feature is experimental and may be removed in the future. =back =head2 filter_json_object $json = $json->filter_json_object([$coderef]) When C<$coderef> is specified, it will be called from C each time it decodes a JSON object. The only argument passed to the coderef is a reference to the newly-created hash. If the code references returns a single scalar (which need not be a reference), this value (i.e. a copy of that scalar to avoid aliasing) is inserted into the deserialised data structure. If it returns an empty list (NOTE: I C, which is a valid scalar), the original deserialised hash will be inserted. This setting can slow down decoding considerably. When C<$coderef> is omitted or undefined, any existing callback will be removed and C will not change the deserialised hash in any way. Example, convert all JSON objects into the integer 5: my $js = JSON->new->filter_json_object (sub { 5 }); # returns [5] $js->decode ('[{}]'); # the given subroutine takes a hash reference. # throw an exception because allow_nonref is not enabled # so a lone 5 is not allowed. $js->decode ('{"a":1, "b":2}'); =head2 filter_json_single_key_object $json = $json->filter_json_single_key_object($key [=> $coderef]) Works remotely similar to C, but is only called for JSON objects having a single key named C<$key>. This C<$coderef> is called before the one specified via C, if any. It gets passed the single value in the JSON object. If it returns a single value, it will be inserted into the data structure. If it returns nothing (not even C but the empty list), the callback from C will be called next, as if no single-key callback were specified. If C<$coderef> is omitted or undefined, the corresponding callback will be disabled. There can only ever be one callback for a given key. As this callback gets called less often then the C one, decoding speed will not usually suffer as much. Therefore, single-key objects make excellent targets to serialise Perl objects into, especially as single-key JSON objects are as close to the type-tagged value concept as JSON gets (it's basically an ID/VALUE tuple). Of course, JSON does not support this in any way, so you need to make sure your data never looks like a serialised Perl hash. Typical names for the single object key are C<__class_whatever__>, or C<$__dollars_are_rarely_used__$> or C<}ugly_brace_placement>, or even things like C<__class_md5sum(classname)__>, to reduce the risk of clashing with real hashes. Example, decode JSON objects of the form C<< { "__widget__" => } >> into the corresponding C<< $WIDGET{} >> object: # return whatever is in $WIDGET{5}: JSON ->new ->filter_json_single_key_object (__widget__ => sub { $WIDGET{ $_[0] } }) ->decode ('{"__widget__": 5') # this can be used with a TO_JSON method in some "widget" class # for serialisation to json: sub WidgetBase::TO_JSON { my ($self) = @_; unless ($self->{id}) { $self->{id} = ..get..some..id..; $WIDGET{$self->{id}} = $self; } { __widget__ => $self->{id} } } =head2 shrink $json = $json->shrink([$enable]) $enabled = $json->get_shrink With JSON::XS, this flag resizes strings generated by either C or C to their minimum size possible. This can save memory when your JSON texts are either very very long or you have many short strings. It will also try to downgrade any strings to octet-form if possible: perl stores strings internally either in an encoding called UTF-X or in octet-form. The latter cannot store everything but uses less space in general (and some buggy Perl or C code might even rely on that internal representation being used). With JSON::PP, it is noop about resizing strings but tries C to the returned string by C. See to L. See to L and L. =head2 max_depth $json = $json->max_depth([$maximum_nesting_depth]) $max_depth = $json->get_max_depth Sets the maximum nesting level (default C<512>) accepted while encoding or decoding. If a higher nesting level is detected in JSON text or a Perl data structure, then the encoder and decoder will stop and croak at that point. Nesting level is defined by number of hash- or arrayrefs that the encoder needs to traverse to reach a given point or the number of C<{> or C<[> characters without their matching closing parenthesis crossed to reach a given character in a string. If no argument is given, the highest possible setting will be used, which is rarely useful. Note that nesting is implemented by recursion in C. The default value has been chosen to be as large as typical operating systems allow without crashing. (JSON::XS) With JSON::PP as the backend, when a large value (100 or more) was set and it de/encodes a deep nested object/text, it may raise a warning 'Deep recursion on subroutine' at the perl runtime phase. See L for more info on why this is useful. =head2 max_size $json = $json->max_size([$maximum_string_size]) $max_size = $json->get_max_size Set the maximum length a JSON text may have (in bytes) where decoding is being attempted. The default is C<0>, meaning no limit. When C is called on a string that is longer then this many bytes, it will not attempt to decode the string but throw an exception. This setting has no effect on C (yet). If no argument is given, the limit check will be deactivated (same as when C<0> is specified). See L, below, for more info on why this is useful. =head2 encode $json_text = $json->encode($perl_scalar) Converts the given Perl data structure (a simple scalar or a reference to a hash or array) to its JSON representation. Simple scalars will be converted into JSON string or number sequences, while references to arrays become JSON arrays and references to hashes become JSON objects. Undefined Perl values (e.g. C) become JSON C values. References to the integers C<0> and C<1> are converted into C and C. =head2 decode $perl_scalar = $json->decode($json_text) The opposite of C: expects a JSON text and tries to parse it, returning the resulting simple scalar or reference. Croaks on error. JSON numbers and strings become simple Perl scalars. JSON arrays become Perl arrayrefs and JSON objects become Perl hashrefs. C becomes C<1> (C), C becomes C<0> (C) and C becomes C. =head2 decode_prefix ($perl_scalar, $characters) = $json->decode_prefix($json_text) This works like the C method, but instead of raising an exception when there is trailing garbage after the first JSON object, it will silently stop parsing there and return the number of characters consumed so far. JSON->new->decode_prefix ("[1] the tail") => ([], 3) See to L =head2 property $boolean = $json->property($property_name) Returns a boolean value about above some properties. The available properties are C, C, C, C,C, C, C, C, C, C, C, C, C, C and C. $boolean = $json->property('utf8'); => 0 $json->utf8; $boolean = $json->property('utf8'); => 1 Sets the property with a given boolean value. $json = $json->property($property_name => $boolean); With no argument, it returns all the above properties as a hash reference. $flag_hashref = $json->property(); =head1 INCREMENTAL PARSING Most of this section are copied and modified from L. In some cases, there is the need for incremental parsing of JSON texts. This module does allow you to parse a JSON stream incrementally. It does so by accumulating text until it has a full JSON object, which it then can decode. This process is similar to using C to see if a full JSON object is available, but is much more efficient (and can be implemented with a minimum of method calls). The backend module will only attempt to parse the JSON text once it is sure it has enough text to get a decisive result, using a very simple but truly incremental parser. This means that it sometimes won't stop as early as the full parser, for example, it doesn't detect parenthesis mismatches. The only thing it guarantees is that it starts decoding as soon as a syntactically valid JSON text has been seen. This means you need to set resource limits (e.g. C) to ensure the parser will stop parsing in the presence if syntax errors. The following methods implement this incremental parser. =head2 incr_parse $json->incr_parse( [$string] ) # void context $obj_or_undef = $json->incr_parse( [$string] ) # scalar context @obj_or_empty = $json->incr_parse( [$string] ) # list context This is the central parsing function. It can both append new text and extract objects from the stream accumulated so far (both of these functions are optional). If C<$string> is given, then this string is appended to the already existing JSON fragment stored in the C<$json> object. After that, if the function is called in void context, it will simply return without doing anything further. This can be used to add more text in as many chunks as you want. If the method is called in scalar context, then it will try to extract exactly I JSON object. If that is successful, it will return this object, otherwise it will return C. If there is a parse error, this method will croak just as C would do (one can then use C to skip the erroneous part). This is the most common way of using the method. And finally, in list context, it will try to extract as many objects from the stream as it can find and return them, or the empty list otherwise. For this to work, there must be no separators between the JSON objects or arrays, instead they must be concatenated back-to-back. If an error occurs, an exception will be raised as in the scalar context case. Note that in this case, any previously-parsed JSON texts will be lost. Example: Parse some JSON arrays/objects in a given string and return them. my @objs = JSON->new->incr_parse ("[5][7][1,2]"); =head2 incr_text $lvalue_string = $json->incr_text This method returns the currently stored JSON fragment as an lvalue, that is, you can manipulate it. This I works when a preceding call to C in I successfully returned an object. Under all other circumstances you must not call this function (I mean it. although in simple tests it might actually work, it I fail under real world conditions). As a special exception, you can also call this method before having parsed anything. This function is useful in two cases: a) finding the trailing text after a JSON object or b) parsing multiple JSON objects separated by non-JSON text (such as commas). $json->incr_text =~ s/\s*,\s*//; In Perl 5.005, C attribute is not available. You must write codes like the below: $string = $json->incr_text; $string =~ s/\s*,\s*//; $json->incr_text( $string ); =head2 incr_skip $json->incr_skip This will reset the state of the incremental parser and will remove the parsed text from the input buffer. This is useful after C died, in which case the input buffer and incremental parser state is left unchanged, to skip the text parsed so far and to reset the parse state. =head2 incr_reset $json->incr_reset This completely resets the incremental parser, that is, after this call, it will be as if the parser had never parsed anything. This is useful if you want to repeatedly parse JSON objects and want to ignore any trailing data, which means you have to reset the parser after each successful decode. See to L for examples. =head1 JSON::PP SUPPORT METHODS The below methods are JSON::PP own methods, so when C works with JSON::PP (i.e. the created object is a JSON::PP object), available. See to L in detail. If you use C with additional C<-support_by_pp>, some methods are available even with JSON::XS. See to L. BEING { $ENV{PERL_JSON_BACKEND} = 'JSON::XS' } use JSON -support_by_pp; my $json = JSON->new; $json->allow_nonref->escape_slash->encode("/"); # functional interfaces too. print to_json(["/"], {escape_slash => 1}); print from_json('["foo"]', {utf8 => 1}); If you do not want to all functions but C<-support_by_pp>, use C<-no_export>. use JSON -support_by_pp, -no_export; # functional interfaces are not exported. =head2 allow_singlequote $json = $json->allow_singlequote([$enable]) If C<$enable> is true (or missing), then C will accept any JSON strings quoted by single quotations that are invalid JSON format. $json->allow_singlequote->decode({"foo":'bar'}); $json->allow_singlequote->decode({'foo':"bar"}); $json->allow_singlequote->decode({'foo':'bar'}); As same as the C option, this option may be used to parse application-specific files written by humans. =head2 allow_barekey $json = $json->allow_barekey([$enable]) If C<$enable> is true (or missing), then C will accept bare keys of JSON object that are invalid JSON format. As same as the C option, this option may be used to parse application-specific files written by humans. $json->allow_barekey->decode('{foo:"bar"}'); =head2 allow_bignum $json = $json->allow_bignum([$enable]) If C<$enable> is true (or missing), then C will convert the big integer Perl cannot handle as integer into a L object and convert a floating number (any) into a L. On the contrary, C converts C objects and C objects into JSON numbers with C enable. $json->allow_nonref->allow_blessed->allow_bignum; $bigfloat = $json->decode('2.000000000000000000000000001'); print $json->encode($bigfloat); # => 2.000000000000000000000000001 See to L about the conversion of JSON number. =head2 loose $json = $json->loose([$enable]) The unescaped [\x00-\x1f\x22\x2f\x5c] strings are invalid in JSON strings and the module doesn't allow to C to these (except for \x2f). If C<$enable> is true (or missing), then C will accept these unescaped strings. $json->loose->decode(qq|["abc def"]|); See to L. =head2 escape_slash $json = $json->escape_slash([$enable]) According to JSON Grammar, I (U+002F) is escaped. But by default JSON backend modules encode strings without escaping slash. If C<$enable> is true (or missing), then C will escape slashes. =head2 indent_length $json = $json->indent_length($length) With JSON::XS, The indent space length is 3 and cannot be changed. With JSON::PP, it sets the indent space length with the given $length. The default is 3. The acceptable range is 0 to 15. =head2 sort_by $json = $json->sort_by($function_name) $json = $json->sort_by($subroutine_ref) If $function_name or $subroutine_ref are set, its sort routine are used. $js = $pc->sort_by(sub { $JSON::PP::a cmp $JSON::PP::b })->encode($obj); # is($js, q|{"a":1,"b":2,"c":3,"d":4,"e":5,"f":6,"g":7,"h":8,"i":9}|); $js = $pc->sort_by('own_sort')->encode($obj); # is($js, q|{"a":1,"b":2,"c":3,"d":4,"e":5,"f":6,"g":7,"h":8,"i":9}|); sub JSON::PP::own_sort { $JSON::PP::a cmp $JSON::PP::b } As the sorting routine runs in the JSON::PP scope, the given subroutine name and the special variables C<$a>, C<$b> will begin with 'JSON::PP::'. If $integer is set, then the effect is same as C on. See to L. =head1 MAPPING This section is copied from JSON::XS and modified to C. JSON::XS and JSON::PP mapping mechanisms are almost equivalent. See to L. =head2 JSON -> PERL =over 4 =item object A JSON object becomes a reference to a hash in Perl. No ordering of object keys is preserved (JSON does not preserver object key ordering itself). =item array A JSON array becomes a reference to an array in Perl. =item string A JSON string becomes a string scalar in Perl - Unicode codepoints in JSON are represented by the same codepoints in the Perl string, so no manual decoding is necessary. =item number A JSON number becomes either an integer, numeric (floating point) or string scalar in perl, depending on its range and any fractional parts. On the Perl level, there is no difference between those as Perl handles all the conversion details, but an integer may take slightly less memory and might represent more values exactly than floating point numbers. If the number consists of digits only, C will try to represent it as an integer value. If that fails, it will try to represent it as a numeric (floating point) value if that is possible without loss of precision. Otherwise it will preserve the number as a string value (in which case you lose roundtripping ability, as the JSON number will be re-encoded to a JSON string). Numbers containing a fractional or exponential part will always be represented as numeric (floating point) values, possibly at a loss of precision (in which case you might lose perfect roundtripping ability, but the JSON number will still be re-encoded as a JSON number). Note that precision is not accuracy - binary floating point values cannot represent most decimal fractions exactly, and when converting from and to floating point, C only guarantees precision up to but not including the least significant bit. If the backend is JSON::PP and C is enable, the big integers and the numeric can be optionally converted into L and L objects. =item true, false These JSON atoms become C and C, respectively. They are overloaded to act almost exactly like the numbers C<1> and C<0>. You can check whether a scalar is a JSON boolean by using the C function. print JSON::true + 1; => 1 ok(JSON::true eq '1'); ok(JSON::true == 1); C will install these missing overloading features to the backend modules. =item null A JSON null atom becomes C in Perl. C returns C. =back =head2 PERL -> JSON The mapping from Perl to JSON is slightly more difficult, as Perl is a truly typeless language, so we can only guess which JSON type is meant by a Perl value. =over 4 =item hash references Perl hash references become JSON objects. As there is no inherent ordering in hash keys (or JSON objects), they will usually be encoded in a pseudo-random order that can change between runs of the same program but stays generally the same within a single run of a program. C optionally sort the hash keys (determined by the I flag), so the same data structure will serialise to the same JSON text (given same settings and version of JSON::XS), but this incurs a runtime overhead and is only rarely useful, e.g. when you want to compare some JSON text against another for equality. In future, the ordered object feature will be added to JSON::PP using C mechanism. =item array references Perl array references become JSON arrays. =item other references Other unblessed references are generally not allowed and will cause an exception to be thrown, except for references to the integers C<0> and C<1>, which get turned into C and C atoms in JSON. You can also use C and C to improve readability. to_json [\0,JSON::true] # yields [false,true] =item JSON::true, JSON::false, JSON::null These special values become JSON true and JSON false values, respectively. You can also use C<\1> and C<\0> directly if you want. JSON::null returns C. =item blessed objects Blessed objects are not directly representable in JSON. See the C and C methods on various options on how to deal with this: basically, you can choose between throwing an exception, encoding the reference as if it weren't blessed, or provide your own serialiser method. With C mode, C converts blessed hash references or blessed array references (contains other blessed references) into JSON members and arrays. use JSON -convert_blessed_universally; JSON->new->allow_blessed->convert_blessed->encode( $blessed_object ); See to L. =item simple scalars Simple Perl scalars (any scalar that is not a reference) are the most difficult objects to encode: JSON::XS and JSON::PP will encode undefined scalars as JSON C values, scalars that have last been used in a string context before encoding as JSON strings, and anything else as number value: # dump as number encode_json [2] # yields [2] encode_json [-3.0e17] # yields [-3e+17] my $value = 5; encode_json [$value] # yields [5] # used as string, so dump as string print $value; encode_json [$value] # yields ["5"] # undef becomes null encode_json [undef] # yields [null] You can force the type to be a string by stringifying it: my $x = 3.1; # some variable containing a number "$x"; # stringified $x .= ""; # another, more awkward way to stringify print $x; # perl does it for you, too, quite often You can force the type to be a number by numifying it: my $x = "3"; # some variable containing a string $x += 0; # numify it, ensuring it will be dumped as a number $x *= 1; # same thing, the choice is yours. You can not currently force the type in other, less obscure, ways. Note that numerical precision has the same meaning as under Perl (so binary to decimal conversion follows the same rules as in Perl, which can differ to other languages). Also, your perl interpreter might expose extensions to the floating point numbers of your platform, such as infinities or NaN's - these cannot be represented in JSON, and it is an error to pass those in. =item Big Number If the backend is JSON::PP and C is enable, C converts C objects and C objects into JSON numbers. =back =head1 JSON and ECMAscript See to L. =head1 JSON and YAML JSON is not a subset of YAML. See to L. =head1 BACKEND MODULE DECISION When you use C, C tries to C JSON::XS. If this call failed, it will C JSON::PP. The required JSON::XS version is I<2.2> or later. The C constructor method returns an object inherited from the backend module, and JSON::XS object is a blessed scalar reference while JSON::PP is a blessed hash reference. So, your program should not depend on the backend module, especially returned objects should not be modified. my $json = JSON->new; # XS or PP? $json->{stash} = 'this is xs object'; # this code may raise an error! To check the backend module, there are some methods - C, C and C. JSON->backend; # 'JSON::XS' or 'JSON::PP' JSON->backend->is_pp: # 0 or 1 JSON->backend->is_xs: # 1 or 0 $json->is_xs; # 1 or 0 $json->is_pp; # 0 or 1 If you set an environment variable C, the calling action will be changed. =over =item PERL_JSON_BACKEND = 0 or PERL_JSON_BACKEND = 'JSON::PP' Always use JSON::PP =item PERL_JSON_BACKEND == 1 or PERL_JSON_BACKEND = 'JSON::XS,JSON::PP' (The default) Use compiled JSON::XS if it is properly compiled & installed, otherwise use JSON::PP. =item PERL_JSON_BACKEND == 2 or PERL_JSON_BACKEND = 'JSON::XS' Always use compiled JSON::XS, die if it isn't properly compiled & installed. =item PERL_JSON_BACKEND = 'JSON::backportPP' Always use JSON::backportPP. JSON::backportPP is JSON::PP back port module. C includes JSON::backportPP instead of JSON::PP. =back These ideas come from L mechanism. example: BEGIN { $ENV{PERL_JSON_BACKEND} = 'JSON::PP' } use JSON; # always uses JSON::PP In future, it may be able to specify another module. =head1 USE PP FEATURES EVEN THOUGH XS BACKEND Many methods are available with either JSON::XS or JSON::PP and when the backend module is JSON::XS, if any JSON::PP specific (i.e. JSON::XS unsupported) method is called, it will C and be noop. But If you C C passing the optional string C<-support_by_pp>, it makes a part of those unsupported methods available. This feature is achieved by using JSON::PP in C. BEGIN { $ENV{PERL_JSON_BACKEND} = 2 } # with JSON::XS use JSON -support_by_pp; my $json = JSON->new; $json->allow_nonref->escape_slash->encode("/"); At this time, the returned object is a C object (re-blessed XS object), and by checking JSON::XS unsupported flags in de/encoding, can support some unsupported methods - C, C, C, C, C and C. When any unsupported methods are not enable, C will be used as is. The switch is achieved by changing the symbolic tables. C<-support_by_pp> is effective only when the backend module is JSON::XS and it makes the de/encoding speed down a bit. See to L. =head1 INCOMPATIBLE CHANGES TO OLD VERSION There are big incompatibility between new version (2.00) and old (1.xx). If you use old C 1.xx in your code, please check it. See to L =over =item jsonToObj and objToJson are obsoleted. Non Perl-style name C and C are obsoleted (but not yet deleted from the source). If you use these functions in your code, please replace them with C and C. =item Global variables are no longer available. C class variables - C<$JSON::AUTOCONVERT>, C<$JSON::BareKey>, etc... - are not available any longer. Instead, various features can be used through object methods. =item Package JSON::Converter and JSON::Parser are deleted. Now C bundles with JSON::PP which can handle JSON more properly than them. =item Package JSON::NotString is deleted. There was C class which represents JSON value C, C, C and numbers. It was deleted and replaced by C. C represents C and C. C does not represent C. C returns C. C makes L and L is-a relation to L. =item function JSON::Number is obsoleted. C is now needless because JSON::XS and JSON::PP have round-trip integrity. =item JSONRPC modules are deleted. Perl implementation of JSON-RPC protocol - C, C and C are deleted in this distribution. Instead of them, there is L which supports JSON-RPC protocol version 1.1. =back =head2 Transition ways from 1.xx to 2.xx. You should set C mode firstly, because it is always successful for the below codes even with JSON::XS. use JSON -support_by_pp; =over =item Exported jsonToObj (simple) from_json($json_text); =item Exported objToJson (simple) to_json($perl_scalar); =item Exported jsonToObj (advanced) $flags = {allow_barekey => 1, allow_singlequote => 1}; from_json($json_text, $flags); equivalent to: $JSON::BareKey = 1; $JSON::QuotApos = 1; jsonToObj($json_text); =item Exported objToJson (advanced) $flags = {allow_blessed => 1, allow_barekey => 1}; to_json($perl_scalar, $flags); equivalent to: $JSON::BareKey = 1; objToJson($perl_scalar); =item jsonToObj as object method $json->decode($json_text); =item objToJson as object method $json->encode($perl_scalar); =item new method with parameters The C method in 2.x takes any parameters no longer. You can set parameters instead; $json = JSON->new->pretty; =item $JSON::Pretty, $JSON::Indent, $JSON::Delimiter If C is enable, that means C<$JSON::Pretty> flag set. And C<$JSON::Delimiter> was substituted by C and C. In conclusion: $json->indent->space_before->space_after; Equivalent to: $json->pretty; To change indent length, use C. (Only with JSON::PP, if C<-support_by_pp> is not used.) $json->pretty->indent_length(2)->encode($perl_scalar); =item $JSON::BareKey (Only with JSON::PP, if C<-support_by_pp> is not used.) $json->allow_barekey->decode($json_text) =item $JSON::ConvBlessed use C<-convert_blessed_universally>. See to L. =item $JSON::QuotApos (Only with JSON::PP, if C<-support_by_pp> is not used.) $json->allow_singlequote->decode($json_text) =item $JSON::SingleQuote Disable. C does not make such a invalid JSON string any longer. =item $JSON::KeySort $json->canonical->encode($perl_scalar) This is the ascii sort. If you want to use with your own sort routine, check the C method. (Only with JSON::PP, even if C<-support_by_pp> is used currently.) $json->sort_by($sort_routine_ref)->encode($perl_scalar) $json->sort_by(sub { $JSON::PP::a <=> $JSON::PP::b })->encode($perl_scalar) Can't access C<$a> and C<$b> but C<$JSON::PP::a> and C<$JSON::PP::b>. =item $JSON::SkipInvalid $json->allow_unknown =item $JSON::AUTOCONVERT Needless. C backend modules have the round-trip integrity. =item $JSON::UTF8 Needless because C (JSON::XS/JSON::PP) sets the UTF8 flag on properly. # With UTF8-flagged strings $json->allow_nonref; $str = chr(1000); # UTF8-flagged $json_text = $json->utf8(0)->encode($str); utf8::is_utf8($json_text); # true $json_text = $json->utf8(1)->encode($str); utf8::is_utf8($json_text); # false $str = '"' . chr(1000) . '"'; # UTF8-flagged $perl_scalar = $json->utf8(0)->decode($str); utf8::is_utf8($perl_scalar); # true $perl_scalar = $json->utf8(1)->decode($str); # died because of 'Wide character in subroutine' See to L. =item $JSON::UnMapping Disable. See to L. =item $JSON::SelfConvert This option was deleted. Instead of it, if a given blessed object has the C method, C will be executed with C. $json->convert_blessed->encode($blessed_hashref_or_arrayref) # if need, call allow_blessed Note that it was C in old version, but now not C but C. =back =head1 TODO =over =item example programs =back =head1 THREADS No test with JSON::PP. If with JSON::XS, See to L. =head1 BUGS Please report bugs relevant to C to Emakamaka[at]cpan.orgE. =head1 SEE ALSO Most of the document is copied and modified from JSON::XS doc. L, L C(L) =head1 AUTHOR Makamaka Hannyaharamitu, Emakamaka[at]cpan.orgE JSON::XS was written by Marc Lehmann The release of this new version owes to the courtesy of Marc Lehmann. =head1 COPYRIGHT AND LICENSE Copyright 2005-2013 by Makamaka Hannyaharamitu This library is free software; you can redistribute it and/or modify it under the same terms as Perl itself. =cut JSON-2.90/eg/0000755000175000017500000000000012234431435011301 5ustar reonreonJSON-2.90/eg/bench_decode.pl0000644000175000017500000000224411651666007014231 0ustar reonreon#!/usr/bin/perl use strict; use warnings; use Benchmark qw( cmpthese timethese ); our $VERSION = '1.00'; my $wanttime = $ARGV[1] || 5; use JSON qw( -support_by_pp -no_export ); # for JSON::PP::Boolean inheritance use JSON::PP (); use JSON::XS (); use utf8; my $pp = JSON::PP->new->utf8; my $xs = JSON::XS->new->utf8; local $/; my $json = <>; my $perl = JSON::XS::decode_json $json; my $result; printf( "JSON::PP %s\n", JSON::PP->VERSION ); printf( "JSON::XS %s\n", JSON::XS->VERSION ); print "-----------------------------------\n"; print "->decode()\n"; print "-----------------------------------\n"; $result = timethese( -$wanttime, { 'JSON::PP' => sub { $pp->decode( $json ) }, 'JSON::XS' => sub { $xs->decode( $json ) }, }, 'none' ); cmpthese( $result ); print "-----------------------------------\n"; __END__ =pod =head1 SYNOPSYS bench_decode.pl json-file # or bench_decode.pl json-file minimum-time =head1 DESCRIPTION L and L decoding benchmark. =head1 AUTHOR makamaka =head1 LISENCE This library is free software; you can redistribute it and/or modify it under the same terms as Perl itself. =cut JSON-2.90/eg/bench_encode.pl0000644000175000017500000000302711651666007014243 0ustar reonreon#!/usr/bin/perl use strict; use warnings; use Benchmark qw( cmpthese timethese ); our $VERSION = '1.00'; my $wanttime = $ARGV[1] || 5; use JSON qw( -support_by_pp -no_export ); # for JSON::PP::Boolean inheritance use JSON::PP (); use JSON::XS (); use utf8; my $pp = JSON::PP->new->utf8; my $xs = JSON::XS->new->utf8; local $/; my $json = <>; my $perl = JSON::XS::decode_json $json; my $result; printf( "JSON::PP %s\n", JSON::PP->VERSION ); printf( "JSON::XS %s\n", JSON::XS->VERSION ); print "-----------------------------------\n"; print "->encode()\n"; print "-----------------------------------\n"; $result = timethese( -$wanttime, { 'JSON::PP' => sub { $pp->encode( $perl ) }, 'JSON::XS' => sub { $xs->encode( $perl ) }, }, 'none' ); cmpthese( $result ); print "-----------------------------------\n"; print "->pretty->canonical->encode()\n"; print "-----------------------------------\n"; $pp->pretty->canonical; $xs->pretty->canonical; $result = timethese( -$wanttime, { 'JSON::PP' => sub { $pp->encode( $perl ) }, 'JSON::XS' => sub { $xs->encode( $perl ) }, }, 'none' ); cmpthese( $result ); print "-----------------------------------\n"; __END__ =pod =head1 SYNOPSYS bench_encode.pl json-file # or bench_encode.pl json-file minimum-time =head1 DESCRIPTION L and L encoding benchmark. =head1 AUTHOR makamaka =head1 LISENCE This library is free software; you can redistribute it and/or modify it under the same terms as Perl itself. =cut JSON-2.90/Makefile.PL0000644000175000017500000000756212234431225012667 0ustar reonreonrequire 5.00503; use strict; use ExtUtils::MakeMaker; use lib qw( ./lib ); $| = 1; eval q| require JSON |; # B module can't install? I'm not careful for such a problem. # Leave us alone today? if ($@) { print "We try to look up lib/JSON.pm, but in vain. B module can't install?\n"; print "Set the environmental variable 'PERL_DL_NONLAZY' with 0.\n"; print "And see to ExtUtils::MM_Unix.\n"; print "perl says : $@"; print "We do not make Makefile by requiring Perl version 7.0.\n"; require 7.0000; } my $version = JSON->VERSION; my $message; print < 'JSON', 'VERSION_FROM' => 'lib/JSON.pm', # finds $VERSION 'PREREQ_PM' => { 'Test::More' => 0, }, ($] >= 5.005 ? ## Add these new keywords supported since 5.005 (ABSTRACT_FROM => 'lib/JSON.pm', # retrieve abstract from module AUTHOR => 'Makamaka Hannyaharamitu, Emakamaka[at]cpan.orgE') : ()), ( $ExtUtils::MakeMaker::VERSION >= 6.3002 ? ('LICENSE' => 'perl', ) : () ), ( $ExtUtils::MakeMaker::VERSION >= 6.46 ? ( 'META_MERGE' => { resources => { repository => 'https://github.com/makamaka/JSON', }, recommends => { 'JSON::XS' => JSON->require_xs_version, }, } ) : () ), ); if ($] < 5.006) { # I saw to http://d.hatena.ne.jp/asakusabashi/20051231/p1 open(IN, "Makefile"); open(OUT,">Makefile.tmp") || die; while() { s/PERL_DL_NONLAZY=1//g; print OUT; } close(OUT); close(IN); rename("Makefile.tmp" => "Makefile"); } JSON-2.90/META.json0000664000175000017500000000210212234431435012324 0ustar reonreon{ "abstract" : "JSON (JavaScript Object Notation) encoder/decoder", "author" : [ "Makamaka Hannyaharamitu, Emakamaka[at]cpan.orgE" ], "dynamic_config" : 1, "generated_by" : "ExtUtils::MakeMaker version 6.62, CPAN::Meta::Converter version 2.130880", "license" : [ "perl_5" ], "meta-spec" : { "url" : "http://search.cpan.org/perldoc?CPAN::Meta::Spec", "version" : "2" }, "name" : "JSON", "no_index" : { "directory" : [ "t", "inc" ] }, "prereqs" : { "build" : { "requires" : { "ExtUtils::MakeMaker" : "0" } }, "configure" : { "requires" : { "ExtUtils::MakeMaker" : "0" } }, "runtime" : { "recommends" : { "JSON::XS" : "2.34" }, "requires" : { "Test::More" : "0" } } }, "release_status" : "stable", "resources" : { "repository" : { "url" : "https://github.com/makamaka/JSON" } }, "version" : "2.90" } JSON-2.90/README0000644000175000017500000016501112234431225011567 0ustar reonreonJSON version 2.58 ================= "JSON::PP" was earlier included in the "JSON" distribution, but has since Perl 5.14 been a core module. For this reason, "JSON::PP" was removed from the "JSON" distribution and can now be found also in the Perl5 repository at http://perl5.git.perl.org/perl.git (The newest "JSON::PP" version still exists in CPAN.) Instead, the "JSON" distribution will include "JSON::backportPP" for backwards computability. JSON.pm should thus work as it did before. ================= INSTALLATION To install this module type the following: perl Makefile.PL make make test make install if you use cpanm, can install JSON::XS at once. cpanm --with-recommends JSON NAME JSON - JSON (JavaScript Object Notation) encoder/decoder SYNOPSIS use JSON; # imports encode_json, decode_json, to_json and from_json. # simple and fast interfaces (expect/generate UTF-8) $utf8_encoded_json_text = encode_json $perl_hash_or_arrayref; $perl_hash_or_arrayref = decode_json $utf8_encoded_json_text; # OO-interface $json = JSON->new->allow_nonref; $json_text = $json->encode( $perl_scalar ); $perl_scalar = $json->decode( $json_text ); $pretty_printed = $json->pretty->encode( $perl_scalar ); # pretty-printing # If you want to use PP only support features, call with '-support_by_pp' # When XS unsupported feature is enable, using PP (de|en)code instead of XS ones. use JSON -support_by_pp; # option-acceptable interfaces (expect/generate UNICODE by default) $json_text = to_json( $perl_scalar, { ascii => 1, pretty => 1 } ); $perl_scalar = from_json( $json_text, { utf8 => 1 } ); # Between (en|de)code_json and (to|from)_json, if you want to write # a code which communicates to an outer world (encoded in UTF-8), # recommend to use (en|de)code_json. VERSION 2.90 This version is compatible with JSON::XS 2.34 and later. (Not yet compatble to JSON::XS B<3.0x>.) NOTE JSON::PP was earlier included in the "JSON" distribution, but has since Perl 5.14 been a core module. For this reason, JSON::PP was removed from the JSON distribution and can now be found also in the Perl5 repository at * (The newest JSON::PP version still exists in CPAN.) Instead, the "JSON" distribution will include JSON::backportPP for backwards computability. JSON.pm should thus work as it did before. DESCRIPTION *************************** CAUTION ************************************** * * * INCOMPATIBLE CHANGE (JSON::XS version 2.90) * * * * JSON.pm had patched JSON::XS::Boolean and JSON::PP::Boolean internally * * on loading time for making these modules inherit JSON::Boolean. * * But since JSON::XS v3.0 it use Types::Serialiser as boolean class. * * Then now JSON.pm breaks boolean classe overload features and * * -support_by_pp if JSON::XS v3.0 or later is installed. * * * * JSON::true and JSON::false returned JSON::Boolean objects. * * For workaround, they return JSON::PP::Boolean objects in this version. * * * * isa_ok(JSON::true, 'JSON::PP::Boolean'); * * * * And it discards a feature: * * * * ok(JSON::true eq 'true'); * * * * In other word, JSON::PP::Boolean overload numeric only. * * * * ok( JSON::true == 1 ); * * * ************************************************************************** ************************** CAUTION ******************************** * This is 'JSON module version 2' and there are many differences * * to version 1.xx * * Please check your applications using old version. * * See to 'INCOMPATIBLE CHANGES TO OLD VERSION' * ******************************************************************* JSON (JavaScript Object Notation) is a simple data format. See to and "RFC4627"(). This module converts Perl data structures to JSON and vice versa using either JSON::XS or JSON::PP. JSON::XS is the fastest and most proper JSON module on CPAN which must be compiled and installed in your environment. JSON::PP is a pure-Perl module which is bundled in this distribution and has a strong compatibility to JSON::XS. This module try to use JSON::XS by default and fail to it, use JSON::PP instead. So its features completely depend on JSON::XS or JSON::PP. See to "BACKEND MODULE DECISION". To distinguish the module name 'JSON' and the format type JSON, the former is quoted by C<> (its results vary with your using media), and the latter is left just as it is. Module name : "JSON" Format type : JSON FEATURES * correct unicode handling This module (i.e. backend modules) knows how to handle Unicode, documents how and when it does so, and even documents what "correct" means. Even though there are limitations, this feature is available since Perl version 5.6. JSON::XS requires Perl 5.8.2 (but works correctly in 5.8.8 or later), so in older versions "JSON" should call JSON::PP as the backend which can be used since Perl 5.005. With Perl 5.8.x JSON::PP works, but from 5.8.0 to 5.8.2, because of a Perl side problem, JSON::PP works slower in the versions. And in 5.005, the Unicode handling is not available. See to "UNICODE HANDLING ON PERLS" in JSON::PP for more information. See also to "A FEW NOTES ON UNICODE AND PERL" in JSON::XS and "ENCODING/CODESET_FLAG_NOTES" in JSON::XS. * round-trip integrity When you serialise a perl data structure using only data types supported by JSON and Perl, the deserialised data structure is identical on the Perl level. (e.g. the string "2.0" doesn't suddenly become "2" just because it looks like a number). There *are* minor exceptions to this, read the "MAPPING" section below to learn about those. * strict checking of JSON correctness There is no guessing, no generating of illegal JSON texts by default, and only JSON is accepted as input by default (the latter is a security feature). See to "FEATURES" in JSON::XS and "FEATURES" in JSON::PP. * fast This module returns a JSON::XS object itself if available. Compared to other JSON modules and other serialisers such as Storable, JSON::XS usually compares favorably in terms of speed, too. If not available, "JSON" returns a JSON::PP object instead of JSON::XS and it is very slow as pure-Perl. * simple to use This module has both a simple functional interface as well as an object oriented interface interface. * reasonably versatile output formats You can choose between the most compact guaranteed-single-line format possible (nice for simple line-based protocols), a pure-ASCII format (for when your transport is not 8-bit clean, still supports the whole Unicode range), or a pretty-printed format (for when you want to read that stuff). Or you can combine those features in whatever way you like. FUNCTIONAL INTERFACE Some documents are copied and modified from "FUNCTIONAL INTERFACE" in JSON::XS. "to_json" and "from_json" are additional functions. encode_json $json_text = encode_json $perl_scalar Converts the given Perl data structure to a UTF-8 encoded, binary string. This function call is functionally identical to: $json_text = JSON->new->utf8->encode($perl_scalar) decode_json $perl_scalar = decode_json $json_text The opposite of "encode_json": expects an UTF-8 (binary) string and tries to parse that as an UTF-8 encoded JSON text, returning the resulting reference. This function call is functionally identical to: $perl_scalar = JSON->new->utf8->decode($json_text) to_json $json_text = to_json($perl_scalar) Converts the given Perl data structure to a json string. This function call is functionally identical to: $json_text = JSON->new->encode($perl_scalar) Takes a hash reference as the second. $json_text = to_json($perl_scalar, $flag_hashref) So, $json_text = to_json($perl_scalar, {utf8 => 1, pretty => 1}) equivalent to: $json_text = JSON->new->utf8(1)->pretty(1)->encode($perl_scalar) If you want to write a modern perl code which communicates to outer world, you should use "encode_json" (supposed that JSON data are encoded in UTF-8). from_json $perl_scalar = from_json($json_text) The opposite of "to_json": expects a json string and tries to parse it, returning the resulting reference. This function call is functionally identical to: $perl_scalar = JSON->decode($json_text) Takes a hash reference as the second. $perl_scalar = from_json($json_text, $flag_hashref) So, $perl_scalar = from_json($json_text, {utf8 => 1}) equivalent to: $perl_scalar = JSON->new->utf8(1)->decode($json_text) If you want to write a modern perl code which communicates to outer world, you should use "decode_json" (supposed that JSON data are encoded in UTF-8). JSON::is_bool $is_boolean = JSON::is_bool($scalar) Returns true if the passed scalar represents either JSON::true or JSON::false, two constants that act like 1 and 0 respectively and are also used to represent JSON "true" and "false" in Perl strings. JSON::true Returns JSON true value which is blessed object. It "isa" JSON::Boolean object. JSON::false Returns JSON false value which is blessed object. It "isa" JSON::Boolean object. JSON::null Returns "undef". See MAPPING, below, for more information on how JSON values are mapped to Perl. HOW DO I DECODE A DATA FROM OUTER AND ENCODE TO OUTER This section supposes that your perl version is 5.8 or later. If you know a JSON text from an outer world - a network, a file content, and so on, is encoded in UTF-8, you should use "decode_json" or "JSON" module object with "utf8" enable. And the decoded result will contain UNICODE characters. # from network my $json = JSON->new->utf8; my $json_text = CGI->new->param( 'json_data' ); my $perl_scalar = $json->decode( $json_text ); # from file content local $/; open( my $fh, '<', 'json.data' ); $json_text = <$fh>; $perl_scalar = decode_json( $json_text ); If an outer data is not encoded in UTF-8, firstly you should "decode" it. use Encode; local $/; open( my $fh, '<', 'json.data' ); my $encoding = 'cp932'; my $unicode_json_text = decode( $encoding, <$fh> ); # UNICODE # or you can write the below code. # # open( my $fh, "<:encoding($encoding)", 'json.data' ); # $unicode_json_text = <$fh>; In this case, $unicode_json_text is of course UNICODE string. So you cannot use "decode_json" nor "JSON" module object with "utf8" enable. Instead of them, you use "JSON" module object with "utf8" disable or "from_json". $perl_scalar = $json->utf8(0)->decode( $unicode_json_text ); # or $perl_scalar = from_json( $unicode_json_text ); Or "encode 'utf8'" and "decode_json": $perl_scalar = decode_json( encode( 'utf8', $unicode_json_text ) ); # this way is not efficient. And now, you want to convert your $perl_scalar into JSON data and send it to an outer world - a network or a file content, and so on. Your data usually contains UNICODE strings and you want the converted data to be encoded in UTF-8, you should use "encode_json" or "JSON" module object with "utf8" enable. print encode_json( $perl_scalar ); # to a network? file? or display? # or print $json->utf8->encode( $perl_scalar ); If $perl_scalar does not contain UNICODE but $encoding-encoded strings for some reason, then its characters are regarded as latin1 for perl (because it does not concern with your $encoding). You cannot use "encode_json" nor "JSON" module object with "utf8" enable. Instead of them, you use "JSON" module object with "utf8" disable or "to_json". Note that the resulted text is a UNICODE string but no problem to print it. # $perl_scalar contains $encoding encoded string values $unicode_json_text = $json->utf8(0)->encode( $perl_scalar ); # or $unicode_json_text = to_json( $perl_scalar ); # $unicode_json_text consists of characters less than 0x100 print $unicode_json_text; Or "decode $encoding" all string values and "encode_json": $perl_scalar->{ foo } = decode( $encoding, $perl_scalar->{ foo } ); # ... do it to each string values, then encode_json $json_text = encode_json( $perl_scalar ); This method is a proper way but probably not efficient. See to Encode, perluniintro. COMMON OBJECT-ORIENTED INTERFACE new $json = JSON->new Returns a new "JSON" object inherited from either JSON::XS or JSON::PP that can be used to de/encode JSON strings. All boolean flags described below are by default *disabled*. The mutators for flags all return the JSON object again and thus calls can be chained: my $json = JSON->new->utf8->space_after->encode({a => [1,2]}) => {"a": [1, 2]} ascii $json = $json->ascii([$enable]) $enabled = $json->get_ascii If $enable is true (or missing), then the encode method will not generate characters outside the code range 0..127. Any Unicode characters outside that range will be escaped using either a single \uXXXX or a double \uHHHH\uLLLLL escape sequence, as per RFC4627. If $enable is false, then the encode method will not escape Unicode characters unless required by the JSON syntax or other flags. This results in a faster and more compact format. This feature depends on the used Perl version and environment. See to "UNICODE HANDLING ON PERLS" in JSON::PP if the backend is PP. JSON->new->ascii(1)->encode([chr 0x10401]) => ["\ud801\udc01"] latin1 $json = $json->latin1([$enable]) $enabled = $json->get_latin1 If $enable is true (or missing), then the encode method will encode the resulting JSON text as latin1 (or iso-8859-1), escaping any characters outside the code range 0..255. If $enable is false, then the encode method will not escape Unicode characters unless required by the JSON syntax or other flags. JSON->new->latin1->encode (["\x{89}\x{abc}"] => ["\x{89}\\u0abc"] # (perl syntax, U+abc escaped, U+89 not) utf8 $json = $json->utf8([$enable]) $enabled = $json->get_utf8 If $enable is true (or missing), then the encode method will encode the JSON result into UTF-8, as required by many protocols, while the decode method expects to be handled an UTF-8-encoded string. Please note that UTF-8-encoded strings do not contain any characters outside the range 0..255, they are thus useful for bytewise/binary I/O. In future versions, enabling this option might enable autodetection of the UTF-16 and UTF-32 encoding families, as described in RFC4627. If $enable is false, then the encode method will return the JSON string as a (non-encoded) Unicode string, while decode expects thus a Unicode string. Any decoding or encoding (e.g. to UTF-8 or UTF-16) needs to be done yourself, e.g. using the Encode module. Example, output UTF-16BE-encoded JSON: use Encode; $jsontext = encode "UTF-16BE", JSON::XS->new->encode ($object); Example, decode UTF-32LE-encoded JSON: use Encode; $object = JSON::XS->new->decode (decode "UTF-32LE", $jsontext); See to "UNICODE HANDLING ON PERLS" in JSON::PP if the backend is PP. pretty $json = $json->pretty([$enable]) This enables (or disables) all of the "indent", "space_before" and "space_after" (and in the future possibly more) flags in one call to generate the most readable (or most compact) form possible. Equivalent to: $json->indent->space_before->space_after The indent space length is three and JSON::XS cannot change the indent space length. indent $json = $json->indent([$enable]) $enabled = $json->get_indent If $enable is true (or missing), then the "encode" method will use a multiline format as output, putting every array member or object/hash key-value pair into its own line, identifying them properly. If $enable is false, no newlines or indenting will be produced, and the resulting JSON text is guaranteed not to contain any "newlines". This setting has no effect when decoding JSON texts. The indent space length is three. With JSON::PP, you can also access "indent_length" to change indent space length. space_before $json = $json->space_before([$enable]) $enabled = $json->get_space_before If $enable is true (or missing), then the "encode" method will add an extra optional space before the ":" separating keys from values in JSON objects. If $enable is false, then the "encode" method will not add any extra space at those places. This setting has no effect when decoding JSON texts. Example, space_before enabled, space_after and indent disabled: {"key" :"value"} space_after $json = $json->space_after([$enable]) $enabled = $json->get_space_after If $enable is true (or missing), then the "encode" method will add an extra optional space after the ":" separating keys from values in JSON objects and extra whitespace after the "," separating key-value pairs and array members. If $enable is false, then the "encode" method will not add any extra space at those places. This setting has no effect when decoding JSON texts. Example, space_before and indent disabled, space_after enabled: {"key": "value"} relaxed $json = $json->relaxed([$enable]) $enabled = $json->get_relaxed If $enable is true (or missing), then "decode" will accept some extensions to normal JSON syntax (see below). "encode" will not be affected in anyway. *Be aware that this option makes you accept invalid JSON texts as if they were valid!*. I suggest only to use this option to parse application-specific files written by humans (configuration files, resource files etc.) If $enable is false (the default), then "decode" will only accept valid JSON texts. Currently accepted extensions are: * list items can have an end-comma JSON *separates* array elements and key-value pairs with commas. This can be annoying if you write JSON texts manually and want to be able to quickly append elements, so this extension accepts comma at the end of such items not just between them: [ 1, 2, <- this comma not normally allowed ] { "k1": "v1", "k2": "v2", <- this comma not normally allowed } * shell-style '#'-comments Whenever JSON allows whitespace, shell-style comments are additionally allowed. They are terminated by the first carriage-return or line-feed character, after which more white-space and comments are allowed. [ 1, # this comment not allowed in JSON # neither this one... ] canonical $json = $json->canonical([$enable]) $enabled = $json->get_canonical If $enable is true (or missing), then the "encode" method will output JSON objects by sorting their keys. This is adding a comparatively high overhead. If $enable is false, then the "encode" method will output key-value pairs in the order Perl stores them (which will likely change between runs of the same script). This option is useful if you want the same data structure to be encoded as the same JSON text (given the same overall settings). If it is disabled, the same hash might be encoded differently even if contains the same data, as key-value pairs have no inherent ordering in Perl. This setting has no effect when decoding JSON texts. allow_nonref $json = $json->allow_nonref([$enable]) $enabled = $json->get_allow_nonref If $enable is true (or missing), then the "encode" method can convert a non-reference into its corresponding string, number or null JSON value, which is an extension to RFC4627. Likewise, "decode" will accept those JSON values instead of croaking. If $enable is false, then the "encode" method will croak if it isn't passed an arrayref or hashref, as JSON texts must either be an object or array. Likewise, "decode" will croak if given something that is not a JSON object or array. JSON->new->allow_nonref->encode ("Hello, World!") => "Hello, World!" allow_unknown $json = $json->allow_unknown ([$enable]) $enabled = $json->get_allow_unknown If $enable is true (or missing), then "encode" will *not* throw an exception when it encounters values it cannot represent in JSON (for example, filehandles) but instead will encode a JSON "null" value. Note that blessed objects are not included here and are handled separately by c. If $enable is false (the default), then "encode" will throw an exception when it encounters anything it cannot encode as JSON. This option does not affect "decode" in any way, and it is recommended to leave it off unless you know your communications partner. allow_blessed $json = $json->allow_blessed([$enable]) $enabled = $json->get_allow_blessed If $enable is true (or missing), then the "encode" method will not barf when it encounters a blessed reference. Instead, the value of the convert_blessed option will decide whether "null" ("convert_blessed" disabled or no "TO_JSON" method found) or a representation of the object ("convert_blessed" enabled and "TO_JSON" method found) is being encoded. Has no effect on "decode". If $enable is false (the default), then "encode" will throw an exception when it encounters a blessed object. convert_blessed $json = $json->convert_blessed([$enable]) $enabled = $json->get_convert_blessed If $enable is true (or missing), then "encode", upon encountering a blessed object, will check for the availability of the "TO_JSON" method on the object's class. If found, it will be called in scalar context and the resulting scalar will be encoded instead of the object. If no "TO_JSON" method is found, the value of "allow_blessed" will decide what to do. The "TO_JSON" method may safely call die if it wants. If "TO_JSON" returns other blessed objects, those will be handled in the same way. "TO_JSON" must take care of not causing an endless recursion cycle (== crash) in this case. The name of "TO_JSON" was chosen because other methods called by the Perl core (== not by the user of the object) are usually in upper case letters and to avoid collisions with the "to_json" function or method. This setting does not yet influence "decode" in any way. If $enable is false, then the "allow_blessed" setting will decide what to do when a blessed object is found. convert_blessed_universally mode If use "JSON" with "-convert_blessed_universally", the "UNIVERSAL::TO_JSON" subroutine is defined as the below code: *UNIVERSAL::TO_JSON = sub { my $b_obj = B::svref_2object( $_[0] ); return $b_obj->isa('B::HV') ? { %{ $_[0] } } : $b_obj->isa('B::AV') ? [ @{ $_[0] } ] : undef ; } This will cause that "encode" method converts simple blessed objects into JSON objects as non-blessed object. JSON -convert_blessed_universally; $json->allow_blessed->convert_blessed->encode( $blessed_object ) This feature is experimental and may be removed in the future. filter_json_object $json = $json->filter_json_object([$coderef]) When $coderef is specified, it will be called from "decode" each time it decodes a JSON object. The only argument passed to the coderef is a reference to the newly-created hash. If the code references returns a single scalar (which need not be a reference), this value (i.e. a copy of that scalar to avoid aliasing) is inserted into the deserialised data structure. If it returns an empty list (NOTE: *not* "undef", which is a valid scalar), the original deserialised hash will be inserted. This setting can slow down decoding considerably. When $coderef is omitted or undefined, any existing callback will be removed and "decode" will not change the deserialised hash in any way. Example, convert all JSON objects into the integer 5: my $js = JSON->new->filter_json_object (sub { 5 }); # returns [5] $js->decode ('[{}]'); # the given subroutine takes a hash reference. # throw an exception because allow_nonref is not enabled # so a lone 5 is not allowed. $js->decode ('{"a":1, "b":2}'); filter_json_single_key_object $json = $json->filter_json_single_key_object($key [=> $coderef]) Works remotely similar to "filter_json_object", but is only called for JSON objects having a single key named $key. This $coderef is called before the one specified via "filter_json_object", if any. It gets passed the single value in the JSON object. If it returns a single value, it will be inserted into the data structure. If it returns nothing (not even "undef" but the empty list), the callback from "filter_json_object" will be called next, as if no single-key callback were specified. If $coderef is omitted or undefined, the corresponding callback will be disabled. There can only ever be one callback for a given key. As this callback gets called less often then the "filter_json_object" one, decoding speed will not usually suffer as much. Therefore, single-key objects make excellent targets to serialise Perl objects into, especially as single-key JSON objects are as close to the type-tagged value concept as JSON gets (it's basically an ID/VALUE tuple). Of course, JSON does not support this in any way, so you need to make sure your data never looks like a serialised Perl hash. Typical names for the single object key are "__class_whatever__", or "$__dollars_are_rarely_used__$" or "}ugly_brace_placement", or even things like "__class_md5sum(classname)__", to reduce the risk of clashing with real hashes. Example, decode JSON objects of the form "{ "__widget__" => }" into the corresponding $WIDGET{} object: # return whatever is in $WIDGET{5}: JSON ->new ->filter_json_single_key_object (__widget__ => sub { $WIDGET{ $_[0] } }) ->decode ('{"__widget__": 5') # this can be used with a TO_JSON method in some "widget" class # for serialisation to json: sub WidgetBase::TO_JSON { my ($self) = @_; unless ($self->{id}) { $self->{id} = ..get..some..id..; $WIDGET{$self->{id}} = $self; } { __widget__ => $self->{id} } } shrink $json = $json->shrink([$enable]) $enabled = $json->get_shrink With JSON::XS, this flag resizes strings generated by either "encode" or "decode" to their minimum size possible. This can save memory when your JSON texts are either very very long or you have many short strings. It will also try to downgrade any strings to octet-form if possible: perl stores strings internally either in an encoding called UTF-X or in octet-form. The latter cannot store everything but uses less space in general (and some buggy Perl or C code might even rely on that internal representation being used). With JSON::PP, it is noop about resizing strings but tries "utf8::downgrade" to the returned string by "encode". See to utf8. See to "OBJECT-ORIENTED INTERFACE" in JSON::XS and "METHODS" in JSON::PP. max_depth $json = $json->max_depth([$maximum_nesting_depth]) $max_depth = $json->get_max_depth Sets the maximum nesting level (default 512) accepted while encoding or decoding. If a higher nesting level is detected in JSON text or a Perl data structure, then the encoder and decoder will stop and croak at that point. Nesting level is defined by number of hash- or arrayrefs that the encoder needs to traverse to reach a given point or the number of "{" or "[" characters without their matching closing parenthesis crossed to reach a given character in a string. If no argument is given, the highest possible setting will be used, which is rarely useful. Note that nesting is implemented by recursion in C. The default value has been chosen to be as large as typical operating systems allow without crashing. (JSON::XS) With JSON::PP as the backend, when a large value (100 or more) was set and it de/encodes a deep nested object/text, it may raise a warning 'Deep recursion on subroutine' at the perl runtime phase. See "SECURITY CONSIDERATIONS" in JSON::XS for more info on why this is useful. max_size $json = $json->max_size([$maximum_string_size]) $max_size = $json->get_max_size Set the maximum length a JSON text may have (in bytes) where decoding is being attempted. The default is 0, meaning no limit. When "decode" is called on a string that is longer then this many bytes, it will not attempt to decode the string but throw an exception. This setting has no effect on "encode" (yet). If no argument is given, the limit check will be deactivated (same as when 0 is specified). See "SECURITY CONSIDERATIONS" in JSON::XS, below, for more info on why this is useful. encode $json_text = $json->encode($perl_scalar) Converts the given Perl data structure (a simple scalar or a reference to a hash or array) to its JSON representation. Simple scalars will be converted into JSON string or number sequences, while references to arrays become JSON arrays and references to hashes become JSON objects. Undefined Perl values (e.g. "undef") become JSON "null" values. References to the integers 0 and 1 are converted into "true" and "false". decode $perl_scalar = $json->decode($json_text) The opposite of "encode": expects a JSON text and tries to parse it, returning the resulting simple scalar or reference. Croaks on error. JSON numbers and strings become simple Perl scalars. JSON arrays become Perl arrayrefs and JSON objects become Perl hashrefs. "true" becomes 1 ("JSON::true"), "false" becomes 0 ("JSON::false") and "null" becomes "undef". decode_prefix ($perl_scalar, $characters) = $json->decode_prefix($json_text) This works like the "decode" method, but instead of raising an exception when there is trailing garbage after the first JSON object, it will silently stop parsing there and return the number of characters consumed so far. JSON->new->decode_prefix ("[1] the tail") => ([], 3) See to "OBJECT-ORIENTED INTERFACE" in JSON::XS property $boolean = $json->property($property_name) Returns a boolean value about above some properties. The available properties are "ascii", "latin1", "utf8", "indent","space_before", "space_after", "relaxed", "canonical", "allow_nonref", "allow_unknown", "allow_blessed", "convert_blessed", "shrink", "max_depth" and "max_size". $boolean = $json->property('utf8'); => 0 $json->utf8; $boolean = $json->property('utf8'); => 1 Sets the property with a given boolean value. $json = $json->property($property_name => $boolean); With no argument, it returns all the above properties as a hash reference. $flag_hashref = $json->property(); INCREMENTAL PARSING Most of this section are copied and modified from "INCREMENTAL PARSING" in JSON::XS. In some cases, there is the need for incremental parsing of JSON texts. This module does allow you to parse a JSON stream incrementally. It does so by accumulating text until it has a full JSON object, which it then can decode. This process is similar to using "decode_prefix" to see if a full JSON object is available, but is much more efficient (and can be implemented with a minimum of method calls). The backend module will only attempt to parse the JSON text once it is sure it has enough text to get a decisive result, using a very simple but truly incremental parser. This means that it sometimes won't stop as early as the full parser, for example, it doesn't detect parenthesis mismatches. The only thing it guarantees is that it starts decoding as soon as a syntactically valid JSON text has been seen. This means you need to set resource limits (e.g. "max_size") to ensure the parser will stop parsing in the presence if syntax errors. The following methods implement this incremental parser. incr_parse $json->incr_parse( [$string] ) # void context $obj_or_undef = $json->incr_parse( [$string] ) # scalar context @obj_or_empty = $json->incr_parse( [$string] ) # list context This is the central parsing function. It can both append new text and extract objects from the stream accumulated so far (both of these functions are optional). If $string is given, then this string is appended to the already existing JSON fragment stored in the $json object. After that, if the function is called in void context, it will simply return without doing anything further. This can be used to add more text in as many chunks as you want. If the method is called in scalar context, then it will try to extract exactly *one* JSON object. If that is successful, it will return this object, otherwise it will return "undef". If there is a parse error, this method will croak just as "decode" would do (one can then use "incr_skip" to skip the erroneous part). This is the most common way of using the method. And finally, in list context, it will try to extract as many objects from the stream as it can find and return them, or the empty list otherwise. For this to work, there must be no separators between the JSON objects or arrays, instead they must be concatenated back-to-back. If an error occurs, an exception will be raised as in the scalar context case. Note that in this case, any previously-parsed JSON texts will be lost. Example: Parse some JSON arrays/objects in a given string and return them. my @objs = JSON->new->incr_parse ("[5][7][1,2]"); incr_text $lvalue_string = $json->incr_text This method returns the currently stored JSON fragment as an lvalue, that is, you can manipulate it. This *only* works when a preceding call to "incr_parse" in *scalar context* successfully returned an object. Under all other circumstances you must not call this function (I mean it. although in simple tests it might actually work, it *will* fail under real world conditions). As a special exception, you can also call this method before having parsed anything. This function is useful in two cases: a) finding the trailing text after a JSON object or b) parsing multiple JSON objects separated by non-JSON text (such as commas). $json->incr_text =~ s/\s*,\s*//; In Perl 5.005, "lvalue" attribute is not available. You must write codes like the below: $string = $json->incr_text; $string =~ s/\s*,\s*//; $json->incr_text( $string ); incr_skip $json->incr_skip This will reset the state of the incremental parser and will remove the parsed text from the input buffer. This is useful after "incr_parse" died, in which case the input buffer and incremental parser state is left unchanged, to skip the text parsed so far and to reset the parse state. incr_reset $json->incr_reset This completely resets the incremental parser, that is, after this call, it will be as if the parser had never parsed anything. This is useful if you want to repeatedly parse JSON objects and want to ignore any trailing data, which means you have to reset the parser after each successful decode. See to "INCREMENTAL PARSING" in JSON::XS for examples. JSON::PP SUPPORT METHODS The below methods are JSON::PP own methods, so when "JSON" works with JSON::PP (i.e. the created object is a JSON::PP object), available. See to "JSON::PP OWN METHODS" in JSON::PP in detail. If you use "JSON" with additional "-support_by_pp", some methods are available even with JSON::XS. See to "USE PP FEATURES EVEN THOUGH XS BACKEND". BEING { $ENV{PERL_JSON_BACKEND} = 'JSON::XS' } use JSON -support_by_pp; my $json = JSON->new; $json->allow_nonref->escape_slash->encode("/"); # functional interfaces too. print to_json(["/"], {escape_slash => 1}); print from_json('["foo"]', {utf8 => 1}); If you do not want to all functions but "-support_by_pp", use "-no_export". use JSON -support_by_pp, -no_export; # functional interfaces are not exported. allow_singlequote $json = $json->allow_singlequote([$enable]) If $enable is true (or missing), then "decode" will accept any JSON strings quoted by single quotations that are invalid JSON format. $json->allow_singlequote->decode({"foo":'bar'}); $json->allow_singlequote->decode({'foo':"bar"}); $json->allow_singlequote->decode({'foo':'bar'}); As same as the "relaxed" option, this option may be used to parse application-specific files written by humans. allow_barekey $json = $json->allow_barekey([$enable]) If $enable is true (or missing), then "decode" will accept bare keys of JSON object that are invalid JSON format. As same as the "relaxed" option, this option may be used to parse application-specific files written by humans. $json->allow_barekey->decode('{foo:"bar"}'); allow_bignum $json = $json->allow_bignum([$enable]) If $enable is true (or missing), then "decode" will convert the big integer Perl cannot handle as integer into a Math::BigInt object and convert a floating number (any) into a Math::BigFloat. On the contrary, "encode" converts "Math::BigInt" objects and "Math::BigFloat" objects into JSON numbers with "allow_blessed" enable. $json->allow_nonref->allow_blessed->allow_bignum; $bigfloat = $json->decode('2.000000000000000000000000001'); print $json->encode($bigfloat); # => 2.000000000000000000000000001 See to MAPPING about the conversion of JSON number. loose $json = $json->loose([$enable]) The unescaped [\x00-\x1f\x22\x2f\x5c] strings are invalid in JSON strings and the module doesn't allow to "decode" to these (except for \x2f). If $enable is true (or missing), then "decode" will accept these unescaped strings. $json->loose->decode(qq|["abc def"]|); See to "JSON::PP OWN METHODS" in JSON::PP. escape_slash $json = $json->escape_slash([$enable]) According to JSON Grammar, *slash* (U+002F) is escaped. But by default JSON backend modules encode strings without escaping slash. If $enable is true (or missing), then "encode" will escape slashes. indent_length $json = $json->indent_length($length) With JSON::XS, The indent space length is 3 and cannot be changed. With JSON::PP, it sets the indent space length with the given $length. The default is 3. The acceptable range is 0 to 15. sort_by $json = $json->sort_by($function_name) $json = $json->sort_by($subroutine_ref) If $function_name or $subroutine_ref are set, its sort routine are used. $js = $pc->sort_by(sub { $JSON::PP::a cmp $JSON::PP::b })->encode($obj); # is($js, q|{"a":1,"b":2,"c":3,"d":4,"e":5,"f":6,"g":7,"h":8,"i":9}|); $js = $pc->sort_by('own_sort')->encode($obj); # is($js, q|{"a":1,"b":2,"c":3,"d":4,"e":5,"f":6,"g":7,"h":8,"i":9}|); sub JSON::PP::own_sort { $JSON::PP::a cmp $JSON::PP::b } As the sorting routine runs in the JSON::PP scope, the given subroutine name and the special variables $a, $b will begin with 'JSON::PP::'. If $integer is set, then the effect is same as "canonical" on. See to "JSON::PP OWN METHODS" in JSON::PP. MAPPING This section is copied from JSON::XS and modified to "JSON". JSON::XS and JSON::PP mapping mechanisms are almost equivalent. See to "MAPPING" in JSON::XS. JSON -> PERL object A JSON object becomes a reference to a hash in Perl. No ordering of object keys is preserved (JSON does not preserver object key ordering itself). array A JSON array becomes a reference to an array in Perl. string A JSON string becomes a string scalar in Perl - Unicode codepoints in JSON are represented by the same codepoints in the Perl string, so no manual decoding is necessary. number A JSON number becomes either an integer, numeric (floating point) or string scalar in perl, depending on its range and any fractional parts. On the Perl level, there is no difference between those as Perl handles all the conversion details, but an integer may take slightly less memory and might represent more values exactly than floating point numbers. If the number consists of digits only, "JSON" will try to represent it as an integer value. If that fails, it will try to represent it as a numeric (floating point) value if that is possible without loss of precision. Otherwise it will preserve the number as a string value (in which case you lose roundtripping ability, as the JSON number will be re-encoded to a JSON string). Numbers containing a fractional or exponential part will always be represented as numeric (floating point) values, possibly at a loss of precision (in which case you might lose perfect roundtripping ability, but the JSON number will still be re-encoded as a JSON number). Note that precision is not accuracy - binary floating point values cannot represent most decimal fractions exactly, and when converting from and to floating point, "JSON" only guarantees precision up to but not including the least significant bit. If the backend is JSON::PP and "allow_bignum" is enable, the big integers and the numeric can be optionally converted into Math::BigInt and Math::BigFloat objects. true, false These JSON atoms become "JSON::true" and "JSON::false", respectively. They are overloaded to act almost exactly like the numbers 1 and 0. You can check whether a scalar is a JSON boolean by using the "JSON::is_bool" function. print JSON::true + 1; => 1 ok(JSON::true eq '1'); ok(JSON::true == 1); "JSON" will install these missing overloading features to the backend modules. null A JSON null atom becomes "undef" in Perl. "JSON::null" returns "undef". PERL -> JSON The mapping from Perl to JSON is slightly more difficult, as Perl is a truly typeless language, so we can only guess which JSON type is meant by a Perl value. hash references Perl hash references become JSON objects. As there is no inherent ordering in hash keys (or JSON objects), they will usually be encoded in a pseudo-random order that can change between runs of the same program but stays generally the same within a single run of a program. "JSON" optionally sort the hash keys (determined by the *canonical* flag), so the same data structure will serialise to the same JSON text (given same settings and version of JSON::XS), but this incurs a runtime overhead and is only rarely useful, e.g. when you want to compare some JSON text against another for equality. In future, the ordered object feature will be added to JSON::PP using "tie" mechanism. array references Perl array references become JSON arrays. other references Other unblessed references are generally not allowed and will cause an exception to be thrown, except for references to the integers 0 and 1, which get turned into "false" and "true" atoms in JSON. You can also use "JSON::false" and "JSON::true" to improve readability. to_json [\0,JSON::true] # yields [false,true] JSON::true, JSON::false, JSON::null These special values become JSON true and JSON false values, respectively. You can also use "\1" and "\0" directly if you want. JSON::null returns "undef". blessed objects Blessed objects are not directly representable in JSON. See the "allow_blessed" and "convert_blessed" methods on various options on how to deal with this: basically, you can choose between throwing an exception, encoding the reference as if it weren't blessed, or provide your own serialiser method. With "convert_blessed_universally" mode, "encode" converts blessed hash references or blessed array references (contains other blessed references) into JSON members and arrays. use JSON -convert_blessed_universally; JSON->new->allow_blessed->convert_blessed->encode( $blessed_object ); See to convert_blessed. simple scalars Simple Perl scalars (any scalar that is not a reference) are the most difficult objects to encode: JSON::XS and JSON::PP will encode undefined scalars as JSON "null" values, scalars that have last been used in a string context before encoding as JSON strings, and anything else as number value: # dump as number encode_json [2] # yields [2] encode_json [-3.0e17] # yields [-3e+17] my $value = 5; encode_json [$value] # yields [5] # used as string, so dump as string print $value; encode_json [$value] # yields ["5"] # undef becomes null encode_json [undef] # yields [null] You can force the type to be a string by stringifying it: my $x = 3.1; # some variable containing a number "$x"; # stringified $x .= ""; # another, more awkward way to stringify print $x; # perl does it for you, too, quite often You can force the type to be a number by numifying it: my $x = "3"; # some variable containing a string $x += 0; # numify it, ensuring it will be dumped as a number $x *= 1; # same thing, the choice is yours. You can not currently force the type in other, less obscure, ways. Note that numerical precision has the same meaning as under Perl (so binary to decimal conversion follows the same rules as in Perl, which can differ to other languages). Also, your perl interpreter might expose extensions to the floating point numbers of your platform, such as infinities or NaN's - these cannot be represented in JSON, and it is an error to pass those in. Big Number If the backend is JSON::PP and "allow_bignum" is enable, "encode" converts "Math::BigInt" objects and "Math::BigFloat" objects into JSON numbers. JSON and ECMAscript See to "JSON and ECMAscript" in JSON::XS. JSON and YAML JSON is not a subset of YAML. See to "JSON and YAML" in JSON::XS. BACKEND MODULE DECISION When you use "JSON", "JSON" tries to "use" JSON::XS. If this call failed, it will "uses" JSON::PP. The required JSON::XS version is *2.2* or later. The "JSON" constructor method returns an object inherited from the backend module, and JSON::XS object is a blessed scalar reference while JSON::PP is a blessed hash reference. So, your program should not depend on the backend module, especially returned objects should not be modified. my $json = JSON->new; # XS or PP? $json->{stash} = 'this is xs object'; # this code may raise an error! To check the backend module, there are some methods - "backend", "is_pp" and "is_xs". JSON->backend; # 'JSON::XS' or 'JSON::PP' JSON->backend->is_pp: # 0 or 1 JSON->backend->is_xs: # 1 or 0 $json->is_xs; # 1 or 0 $json->is_pp; # 0 or 1 If you set an environment variable "PERL_JSON_BACKEND", the calling action will be changed. PERL_JSON_BACKEND = 0 or PERL_JSON_BACKEND = 'JSON::PP' Always use JSON::PP PERL_JSON_BACKEND == 1 or PERL_JSON_BACKEND = 'JSON::XS,JSON::PP' (The default) Use compiled JSON::XS if it is properly compiled & installed, otherwise use JSON::PP. PERL_JSON_BACKEND == 2 or PERL_JSON_BACKEND = 'JSON::XS' Always use compiled JSON::XS, die if it isn't properly compiled & installed. PERL_JSON_BACKEND = 'JSON::backportPP' Always use JSON::backportPP. JSON::backportPP is JSON::PP back port module. "JSON" includes JSON::backportPP instead of JSON::PP. These ideas come from DBI::PurePerl mechanism. example: BEGIN { $ENV{PERL_JSON_BACKEND} = 'JSON::PP' } use JSON; # always uses JSON::PP In future, it may be able to specify another module. USE PP FEATURES EVEN THOUGH XS BACKEND Many methods are available with either JSON::XS or JSON::PP and when the backend module is JSON::XS, if any JSON::PP specific (i.e. JSON::XS unsupported) method is called, it will "warn" and be noop. But If you "use" "JSON" passing the optional string "-support_by_pp", it makes a part of those unsupported methods available. This feature is achieved by using JSON::PP in "de/encode". BEGIN { $ENV{PERL_JSON_BACKEND} = 2 } # with JSON::XS use JSON -support_by_pp; my $json = JSON->new; $json->allow_nonref->escape_slash->encode("/"); At this time, the returned object is a "JSON::Backend::XS::Supportable" object (re-blessed XS object), and by checking JSON::XS unsupported flags in de/encoding, can support some unsupported methods - "loose", "allow_bignum", "allow_barekey", "allow_singlequote", "escape_slash" and "indent_length". When any unsupported methods are not enable, "XS de/encode" will be used as is. The switch is achieved by changing the symbolic tables. "-support_by_pp" is effective only when the backend module is JSON::XS and it makes the de/encoding speed down a bit. See to "JSON::PP SUPPORT METHODS". INCOMPATIBLE CHANGES TO OLD VERSION There are big incompatibility between new version (2.00) and old (1.xx). If you use old "JSON" 1.xx in your code, please check it. See to "Transition ways from 1.xx to 2.xx." jsonToObj and objToJson are obsoleted. Non Perl-style name "jsonToObj" and "objToJson" are obsoleted (but not yet deleted from the source). If you use these functions in your code, please replace them with "from_json" and "to_json". Global variables are no longer available. "JSON" class variables - $JSON::AUTOCONVERT, $JSON::BareKey, etc... - are not available any longer. Instead, various features can be used through object methods. Package JSON::Converter and JSON::Parser are deleted. Now "JSON" bundles with JSON::PP which can handle JSON more properly than them. Package JSON::NotString is deleted. There was "JSON::NotString" class which represents JSON value "true", "false", "null" and numbers. It was deleted and replaced by "JSON::Boolean". "JSON::Boolean" represents "true" and "false". "JSON::Boolean" does not represent "null". "JSON::null" returns "undef". "JSON" makes JSON::XS::Boolean and JSON::PP::Boolean is-a relation to JSON::Boolean. function JSON::Number is obsoleted. "JSON::Number" is now needless because JSON::XS and JSON::PP have round-trip integrity. JSONRPC modules are deleted. Perl implementation of JSON-RPC protocol - "JSONRPC ", "JSONRPC::Transport::HTTP" and "Apache::JSONRPC " are deleted in this distribution. Instead of them, there is JSON::RPC which supports JSON-RPC protocol version 1.1. Transition ways from 1.xx to 2.xx. You should set "suport_by_pp" mode firstly, because it is always successful for the below codes even with JSON::XS. use JSON -support_by_pp; Exported jsonToObj (simple) from_json($json_text); Exported objToJson (simple) to_json($perl_scalar); Exported jsonToObj (advanced) $flags = {allow_barekey => 1, allow_singlequote => 1}; from_json($json_text, $flags); equivalent to: $JSON::BareKey = 1; $JSON::QuotApos = 1; jsonToObj($json_text); Exported objToJson (advanced) $flags = {allow_blessed => 1, allow_barekey => 1}; to_json($perl_scalar, $flags); equivalent to: $JSON::BareKey = 1; objToJson($perl_scalar); jsonToObj as object method $json->decode($json_text); objToJson as object method $json->encode($perl_scalar); new method with parameters The "new" method in 2.x takes any parameters no longer. You can set parameters instead; $json = JSON->new->pretty; $JSON::Pretty, $JSON::Indent, $JSON::Delimiter If "indent" is enable, that means $JSON::Pretty flag set. And $JSON::Delimiter was substituted by "space_before" and "space_after". In conclusion: $json->indent->space_before->space_after; Equivalent to: $json->pretty; To change indent length, use "indent_length". (Only with JSON::PP, if "-support_by_pp" is not used.) $json->pretty->indent_length(2)->encode($perl_scalar); $JSON::BareKey (Only with JSON::PP, if "-support_by_pp" is not used.) $json->allow_barekey->decode($json_text) $JSON::ConvBlessed use "-convert_blessed_universally". See to convert_blessed. $JSON::QuotApos (Only with JSON::PP, if "-support_by_pp" is not used.) $json->allow_singlequote->decode($json_text) $JSON::SingleQuote Disable. "JSON" does not make such a invalid JSON string any longer. $JSON::KeySort $json->canonical->encode($perl_scalar) This is the ascii sort. If you want to use with your own sort routine, check the "sort_by" method. (Only with JSON::PP, even if "-support_by_pp" is used currently.) $json->sort_by($sort_routine_ref)->encode($perl_scalar) $json->sort_by(sub { $JSON::PP::a <=> $JSON::PP::b })->encode($perl_scalar) Can't access $a and $b but $JSON::PP::a and $JSON::PP::b. $JSON::SkipInvalid $json->allow_unknown $JSON::AUTOCONVERT Needless. "JSON" backend modules have the round-trip integrity. $JSON::UTF8 Needless because "JSON" (JSON::XS/JSON::PP) sets the UTF8 flag on properly. # With UTF8-flagged strings $json->allow_nonref; $str = chr(1000); # UTF8-flagged $json_text = $json->utf8(0)->encode($str); utf8::is_utf8($json_text); # true $json_text = $json->utf8(1)->encode($str); utf8::is_utf8($json_text); # false $str = '"' . chr(1000) . '"'; # UTF8-flagged $perl_scalar = $json->utf8(0)->decode($str); utf8::is_utf8($perl_scalar); # true $perl_scalar = $json->utf8(1)->decode($str); # died because of 'Wide character in subroutine' See to "A FEW NOTES ON UNICODE AND PERL" in JSON::XS. $JSON::UnMapping Disable. See to MAPPING. $JSON::SelfConvert This option was deleted. Instead of it, if a given blessed object has the "TO_JSON" method, "TO_JSON" will be executed with "convert_blessed". $json->convert_blessed->encode($blessed_hashref_or_arrayref) # if need, call allow_blessed Note that it was "toJson" in old version, but now not "toJson" but "TO_JSON". TODO example programs THREADS No test with JSON::PP. If with JSON::XS, See to "THREADS" in JSON::XS. BUGS Please report bugs relevant to "JSON" to . SEE ALSO Most of the document is copied and modified from JSON::XS doc. JSON::XS, JSON::PP "RFC4627"() AUTHOR Makamaka Hannyaharamitu, JSON::XS was written by Marc Lehmann The release of this new version owes to the courtesy of Marc Lehmann. COPYRIGHT AND LICENSE Copyright 2005-2013 by Makamaka Hannyaharamitu This library is free software; you can redistribute it and/or modify it under the same terms as Perl itself.