| line |
stmt |
bran |
cond |
sub |
pod |
time |
code |
|
1
|
|
|
|
|
|
|
package JSON::YY; |
|
2
|
|
|
|
|
|
|
|
|
3
|
14
|
|
|
14
|
|
1188382
|
use strict; |
|
|
14
|
|
|
|
|
19
|
|
|
|
14
|
|
|
|
|
425
|
|
|
4
|
14
|
|
|
14
|
|
53
|
use warnings; |
|
|
14
|
|
|
|
|
20
|
|
|
|
14
|
|
|
|
|
651
|
|
|
5
|
14
|
|
|
14
|
|
56
|
use Carp; |
|
|
14
|
|
|
|
|
19
|
|
|
|
14
|
|
|
|
|
5078
|
|
|
6
|
|
|
|
|
|
|
|
|
7
|
|
|
|
|
|
|
our $VERSION = '0.04'; |
|
8
|
|
|
|
|
|
|
|
|
9
|
|
|
|
|
|
|
require XSLoader; |
|
10
|
|
|
|
|
|
|
XSLoader::load('JSON::YY', $VERSION); |
|
11
|
|
|
|
|
|
|
|
|
12
|
|
|
|
|
|
|
our @EXPORT_OK = qw(encode_json decode_json decode_json_ro); |
|
13
|
|
|
|
|
|
|
|
|
14
|
|
|
|
|
|
|
my @DOC_KEYWORDS = qw(jdoc jget jgetp jset jdel jhas jclone jencode |
|
15
|
|
|
|
|
|
|
jstr jnum jbool jnull jarr jobj jtype jlen jkeys jdecode |
|
16
|
|
|
|
|
|
|
jiter jnext jkey jpatch jmerge jfrom jvals jeq |
|
17
|
|
|
|
|
|
|
jpp jraw jread jwrite jpaths jfind |
|
18
|
|
|
|
|
|
|
jis_obj jis_arr jis_str jis_num jis_int jis_real jis_bool jis_null); |
|
19
|
|
|
|
|
|
|
|
|
20
|
|
|
|
|
|
|
# functional API — fast XS path, always utf8 |
|
21
|
|
|
|
|
|
|
*encode_json = \&_xs_encode_json; |
|
22
|
|
|
|
|
|
|
*decode_json = \&_xs_decode_json; |
|
23
|
|
|
|
|
|
|
*decode_json_ro = \&_xs_decode_json_ro; |
|
24
|
|
|
|
|
|
|
|
|
25
|
|
|
|
|
|
|
my %SETTERS = ( |
|
26
|
|
|
|
|
|
|
utf8 => \&_set_utf8, |
|
27
|
|
|
|
|
|
|
pretty => \&_set_pretty, |
|
28
|
|
|
|
|
|
|
canonical => \&_set_canonical, |
|
29
|
|
|
|
|
|
|
allow_nonref => \&_set_allow_nonref, |
|
30
|
|
|
|
|
|
|
allow_unknown => \&_set_allow_unknown, |
|
31
|
|
|
|
|
|
|
allow_blessed => \&_set_allow_blessed, |
|
32
|
|
|
|
|
|
|
convert_blessed => \&_set_convert_blessed, |
|
33
|
|
|
|
|
|
|
max_depth => \&_set_max_depth, |
|
34
|
|
|
|
|
|
|
); |
|
35
|
|
|
|
|
|
|
|
|
36
|
|
|
|
|
|
|
sub import { |
|
37
|
21
|
|
|
21
|
|
410
|
my $class = shift; |
|
38
|
21
|
|
|
|
|
34
|
my @exports; |
|
39
|
|
|
|
|
|
|
my @flags; |
|
40
|
21
|
|
|
|
|
22
|
my $want_doc = 0; |
|
41
|
21
|
|
|
|
|
45
|
for my $arg (@_) { |
|
42
|
33
|
100
|
|
|
|
94
|
if ($arg eq ':doc') { |
|
|
|
100
|
|
|
|
|
|
|
43
|
9
|
|
|
|
|
15
|
$want_doc = 1; |
|
44
|
|
|
|
|
|
|
} elsif ($arg =~ /^-(.+)/) { |
|
45
|
2
|
|
|
|
|
6
|
push @flags, $1; |
|
46
|
|
|
|
|
|
|
} else { |
|
47
|
22
|
|
|
|
|
53
|
push @exports, $arg; |
|
48
|
|
|
|
|
|
|
} |
|
49
|
|
|
|
|
|
|
} |
|
50
|
21
|
|
|
|
|
37
|
my $caller = caller; |
|
51
|
|
|
|
|
|
|
|
|
52
|
|
|
|
|
|
|
# activate keywords via XS::Parse::Keyword hint keys |
|
53
|
21
|
100
|
|
|
|
60
|
if ($want_doc) { |
|
54
|
9
|
|
|
|
|
507
|
$^H{"JSON::YY/$_"} = 1 for @DOC_KEYWORDS; |
|
55
|
|
|
|
|
|
|
} |
|
56
|
21
|
100
|
|
|
|
95
|
if (@flags) { |
|
57
|
1
|
|
|
|
|
2
|
my $coder = $class->new; |
|
58
|
1
|
|
|
|
|
1
|
for my $f (@flags) { |
|
59
|
2
|
50
|
|
|
|
6
|
my $setter = $SETTERS{$f} |
|
60
|
|
|
|
|
|
|
or Carp::croak("unknown flag: -$f"); |
|
61
|
2
|
|
|
|
|
4
|
$coder->$setter(1); |
|
62
|
|
|
|
|
|
|
} |
|
63
|
14
|
|
|
14
|
|
90
|
no strict 'refs'; |
|
|
14
|
|
|
|
|
27
|
|
|
|
14
|
|
|
|
|
1398
|
|
|
64
|
1
|
|
|
1
|
|
4
|
*{"${caller}::encode_json"} = sub { $coder->encode($_[0]) }; |
|
|
1
|
|
|
|
|
5
|
|
|
|
1
|
|
|
|
|
177230
|
|
|
65
|
1
|
|
|
1
|
|
2
|
*{"${caller}::decode_json"} = sub { $coder->decode($_[0]) }; |
|
|
1
|
|
|
|
|
2
|
|
|
|
1
|
|
|
|
|
941
|
|
|
66
|
|
|
|
|
|
|
} |
|
67
|
21
|
100
|
|
|
|
74013
|
if (@exports) { |
|
68
|
14
|
|
|
14
|
|
62
|
no strict 'refs'; |
|
|
14
|
|
|
|
|
27
|
|
|
|
14
|
|
|
|
|
4372
|
|
|
69
|
11
|
|
|
|
|
16
|
for my $e (@exports) { |
|
70
|
|
|
|
|
|
|
Carp::croak("'$e' is not exported by JSON::YY") |
|
71
|
22
|
50
|
|
|
|
42
|
unless grep { $_ eq $e } @EXPORT_OK; |
|
|
66
|
|
|
|
|
118
|
|
|
72
|
22
|
|
|
|
|
37
|
*{"${caller}::$e"} = \&{$e}; |
|
|
22
|
|
|
|
|
66
|
|
|
|
22
|
|
|
|
|
41
|
|
|
73
|
|
|
|
|
|
|
# also enable keyword for exported functions |
|
74
|
22
|
|
|
|
|
75287
|
$^H{"JSON::YY/$e"} = 1; |
|
75
|
|
|
|
|
|
|
} |
|
76
|
|
|
|
|
|
|
} |
|
77
|
|
|
|
|
|
|
} |
|
78
|
|
|
|
|
|
|
|
|
79
|
|
|
|
|
|
|
# chaining setters |
|
80
|
10
|
|
50
|
10
|
1
|
59
|
sub utf8 { $_[0]->_set_utf8($_[1] // 1); $_[0] } |
|
|
10
|
|
|
|
|
40
|
|
|
81
|
3
|
|
50
|
3
|
1
|
15
|
sub pretty { $_[0]->_set_pretty($_[1] // 1); $_[0] } |
|
|
3
|
|
|
|
|
92
|
|
|
82
|
0
|
|
0
|
0
|
1
|
0
|
sub canonical { $_[0]->_set_canonical($_[1] // 1); $_[0] } |
|
|
0
|
|
|
|
|
0
|
|
|
83
|
2
|
|
100
|
2
|
1
|
9
|
sub allow_nonref { $_[0]->_set_allow_nonref($_[1] // 1); $_[0] } |
|
|
2
|
|
|
|
|
3
|
|
|
84
|
0
|
|
0
|
0
|
1
|
0
|
sub allow_unknown { $_[0]->_set_allow_unknown($_[1] // 1); $_[0] } |
|
|
0
|
|
|
|
|
0
|
|
|
85
|
1
|
|
50
|
1
|
1
|
5
|
sub allow_blessed { $_[0]->_set_allow_blessed($_[1] // 1); $_[0] } |
|
|
1
|
|
|
|
|
2
|
|
|
86
|
1
|
|
50
|
1
|
1
|
6
|
sub convert_blessed { $_[0]->_set_convert_blessed($_[1] // 1); $_[0] } |
|
|
1
|
|
|
|
|
1
|
|
|
87
|
2
|
|
50
|
2
|
1
|
11
|
sub max_depth { $_[0]->_set_max_depth($_[1] // 512); $_[0] } |
|
|
2
|
|
|
|
|
4
|
|
|
88
|
|
|
|
|
|
|
|
|
89
|
|
|
|
|
|
|
# wrap XS new to accept keyword args |
|
90
|
|
|
|
|
|
|
{ |
|
91
|
|
|
|
|
|
|
my $orig_new = JSON::YY->can('new'); |
|
92
|
14
|
|
|
14
|
|
69
|
no warnings 'redefine'; |
|
|
14
|
|
|
|
|
17
|
|
|
|
14
|
|
|
|
|
3061
|
|
|
93
|
|
|
|
|
|
|
*new = sub { |
|
94
|
16
|
|
|
16
|
|
704641
|
my ($class, %args) = @_; |
|
95
|
16
|
|
|
|
|
104
|
my $self = $orig_new->($class); |
|
96
|
16
|
|
|
|
|
55
|
for my $k (keys %args) { |
|
97
|
8
|
50
|
|
|
|
20
|
my $setter = $SETTERS{$k} |
|
98
|
|
|
|
|
|
|
or Carp::croak("unknown option: $k"); |
|
99
|
8
|
|
|
|
|
23
|
$self->$setter($args{$k}); |
|
100
|
|
|
|
|
|
|
} |
|
101
|
16
|
|
|
|
|
56
|
$self; |
|
102
|
|
|
|
|
|
|
}; |
|
103
|
|
|
|
|
|
|
} |
|
104
|
|
|
|
|
|
|
|
|
105
|
|
|
|
|
|
|
# Doc overloading: stringify to JSON, boolean always true, eq/ne deep compare |
|
106
|
|
|
|
|
|
|
package JSON::YY::Doc; |
|
107
|
|
|
|
|
|
|
use overload |
|
108
|
2
|
|
|
2
|
|
172004
|
'""' => sub { JSON::YY::_doc_stringify($_[0]) }, |
|
109
|
1
|
|
|
1
|
|
83
|
'bool' => sub { 1 }, |
|
110
|
1
|
|
|
1
|
|
6
|
'eq' => sub { JSON::YY::_doc_eq($_[0], $_[1]) }, |
|
111
|
1
|
|
|
1
|
|
6
|
'ne' => sub { !JSON::YY::_doc_eq($_[0], $_[1]) }, |
|
112
|
14
|
|
|
14
|
|
6262
|
fallback => 1; |
|
|
14
|
|
|
|
|
16057
|
|
|
|
14
|
|
|
|
|
148
|
|
|
113
|
|
|
|
|
|
|
|
|
114
|
|
|
|
|
|
|
package JSON::YY; |
|
115
|
|
|
|
|
|
|
1; |
|
116
|
|
|
|
|
|
|
|
|
117
|
|
|
|
|
|
|
__END__ |