| line |
stmt |
bran |
cond |
sub |
pod |
time |
code |
|
1
|
|
|
|
|
|
|
package JSON::YY; |
|
2
|
|
|
|
|
|
|
|
|
3
|
14
|
|
|
14
|
|
1354828
|
use strict; |
|
|
14
|
|
|
|
|
22
|
|
|
|
14
|
|
|
|
|
456
|
|
|
4
|
14
|
|
|
14
|
|
54
|
use warnings; |
|
|
14
|
|
|
|
|
22
|
|
|
|
14
|
|
|
|
|
747
|
|
|
5
|
14
|
|
|
14
|
|
92
|
use Carp; |
|
|
14
|
|
|
|
|
20
|
|
|
|
14
|
|
|
|
|
4888
|
|
|
6
|
|
|
|
|
|
|
|
|
7
|
|
|
|
|
|
|
our $VERSION = '0.02'; |
|
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
|
|
478
|
my $class = shift; |
|
38
|
21
|
|
|
|
|
34
|
my @exports; |
|
39
|
|
|
|
|
|
|
my @flags; |
|
40
|
21
|
|
|
|
|
29
|
my $want_doc = 0; |
|
41
|
21
|
|
|
|
|
51
|
for my $arg (@_) { |
|
42
|
33
|
100
|
|
|
|
120
|
if ($arg eq ':doc') { |
|
|
|
100
|
|
|
|
|
|
|
43
|
9
|
|
|
|
|
43
|
$want_doc = 1; |
|
44
|
|
|
|
|
|
|
} elsif ($arg =~ /^-(.+)/) { |
|
45
|
2
|
|
|
|
|
11
|
push @flags, $1; |
|
46
|
|
|
|
|
|
|
} else { |
|
47
|
22
|
|
|
|
|
83
|
push @exports, $arg; |
|
48
|
|
|
|
|
|
|
} |
|
49
|
|
|
|
|
|
|
} |
|
50
|
21
|
|
|
|
|
94
|
my $caller = caller; |
|
51
|
21
|
100
|
|
|
|
97
|
if ($want_doc) { |
|
52
|
14
|
|
|
14
|
|
104
|
no strict 'refs'; |
|
|
14
|
|
|
|
|
26
|
|
|
|
14
|
|
|
|
|
1822
|
|
|
53
|
9
|
|
|
|
|
19
|
for my $kw (@DOC_KEYWORDS) { |
|
54
|
360
|
|
|
|
|
424
|
*{"${caller}::${kw}"} = \&{"_xs_${kw}"}; |
|
|
360
|
|
|
|
|
973
|
|
|
|
360
|
|
|
|
|
549
|
|
|
55
|
|
|
|
|
|
|
} |
|
56
|
|
|
|
|
|
|
} |
|
57
|
21
|
100
|
|
|
|
45
|
if (@flags) { |
|
58
|
1
|
|
|
|
|
3
|
my $coder = $class->new; |
|
59
|
1
|
|
|
|
|
2
|
for my $f (@flags) { |
|
60
|
2
|
50
|
|
|
|
4
|
my $setter = $SETTERS{$f} |
|
61
|
|
|
|
|
|
|
or Carp::croak("unknown flag: -$f"); |
|
62
|
2
|
|
|
|
|
5
|
$coder->$setter(1); |
|
63
|
|
|
|
|
|
|
} |
|
64
|
14
|
|
|
14
|
|
68
|
no strict 'refs'; |
|
|
14
|
|
|
|
|
22
|
|
|
|
14
|
|
|
|
|
1488
|
|
|
65
|
1
|
|
|
1
|
|
3
|
*{"${caller}::encode_json"} = sub { $coder->encode($_[0]) }; |
|
|
1
|
|
|
|
|
4
|
|
|
|
1
|
|
|
|
|
155048
|
|
|
66
|
1
|
|
|
1
|
|
3
|
*{"${caller}::decode_json"} = sub { $coder->decode($_[0]) }; |
|
|
1
|
|
|
|
|
2
|
|
|
|
1
|
|
|
|
|
851
|
|
|
67
|
|
|
|
|
|
|
} |
|
68
|
21
|
100
|
|
|
|
125401
|
if (@exports) { |
|
69
|
14
|
|
|
14
|
|
88
|
no strict 'refs'; |
|
|
14
|
|
|
|
|
45
|
|
|
|
14
|
|
|
|
|
5201
|
|
|
70
|
11
|
|
|
|
|
14
|
for my $e (@exports) { |
|
71
|
|
|
|
|
|
|
Carp::croak("'$e' is not exported by JSON::YY") |
|
72
|
22
|
50
|
|
|
|
32
|
unless grep { $_ eq $e } @EXPORT_OK; |
|
|
66
|
|
|
|
|
170
|
|
|
73
|
22
|
|
|
|
|
21
|
*{"${caller}::$e"} = \&{$e}; |
|
|
22
|
|
|
|
|
84192
|
|
|
|
22
|
|
|
|
|
52
|
|
|
74
|
|
|
|
|
|
|
} |
|
75
|
|
|
|
|
|
|
} |
|
76
|
|
|
|
|
|
|
} |
|
77
|
|
|
|
|
|
|
|
|
78
|
|
|
|
|
|
|
# chaining setters |
|
79
|
10
|
|
50
|
10
|
1
|
52
|
sub utf8 { $_[0]->_set_utf8($_[1] // 1); $_[0] } |
|
|
10
|
|
|
|
|
26
|
|
|
80
|
3
|
|
50
|
3
|
1
|
17
|
sub pretty { $_[0]->_set_pretty($_[1] // 1); $_[0] } |
|
|
3
|
|
|
|
|
46
|
|
|
81
|
0
|
|
0
|
0
|
1
|
0
|
sub canonical { $_[0]->_set_canonical($_[1] // 1); $_[0] } |
|
|
0
|
|
|
|
|
0
|
|
|
82
|
2
|
|
100
|
2
|
1
|
8
|
sub allow_nonref { $_[0]->_set_allow_nonref($_[1] // 1); $_[0] } |
|
|
2
|
|
|
|
|
3
|
|
|
83
|
0
|
|
0
|
0
|
1
|
0
|
sub allow_unknown { $_[0]->_set_allow_unknown($_[1] // 1); $_[0] } |
|
|
0
|
|
|
|
|
0
|
|
|
84
|
1
|
|
50
|
1
|
1
|
6
|
sub allow_blessed { $_[0]->_set_allow_blessed($_[1] // 1); $_[0] } |
|
|
1
|
|
|
|
|
2
|
|
|
85
|
1
|
|
50
|
1
|
1
|
6
|
sub convert_blessed { $_[0]->_set_convert_blessed($_[1] // 1); $_[0] } |
|
|
1
|
|
|
|
|
2
|
|
|
86
|
2
|
|
50
|
2
|
1
|
13
|
sub max_depth { $_[0]->_set_max_depth($_[1] // 512); $_[0] } |
|
|
2
|
|
|
|
|
4
|
|
|
87
|
|
|
|
|
|
|
|
|
88
|
|
|
|
|
|
|
# wrap XS new to accept keyword args |
|
89
|
|
|
|
|
|
|
{ |
|
90
|
|
|
|
|
|
|
my $orig_new = JSON::YY->can('new'); |
|
91
|
14
|
|
|
14
|
|
76
|
no warnings 'redefine'; |
|
|
14
|
|
|
|
|
23
|
|
|
|
14
|
|
|
|
|
3681
|
|
|
92
|
|
|
|
|
|
|
*new = sub { |
|
93
|
16
|
|
|
16
|
|
636701
|
my ($class, %args) = @_; |
|
94
|
16
|
|
|
|
|
168
|
my $self = $orig_new->($class); |
|
95
|
16
|
|
|
|
|
47
|
for my $k (keys %args) { |
|
96
|
8
|
50
|
|
|
|
28
|
my $setter = $SETTERS{$k} |
|
97
|
|
|
|
|
|
|
or Carp::croak("unknown option: $k"); |
|
98
|
8
|
|
|
|
|
28
|
$self->$setter($args{$k}); |
|
99
|
|
|
|
|
|
|
} |
|
100
|
16
|
|
|
|
|
62
|
$self; |
|
101
|
|
|
|
|
|
|
}; |
|
102
|
|
|
|
|
|
|
} |
|
103
|
|
|
|
|
|
|
|
|
104
|
|
|
|
|
|
|
# Doc overloading: stringify to JSON, boolean always true, eq/ne deep compare |
|
105
|
|
|
|
|
|
|
package JSON::YY::Doc; |
|
106
|
|
|
|
|
|
|
use overload |
|
107
|
2
|
|
|
2
|
|
173171
|
'""' => sub { JSON::YY::_doc_stringify($_[0]) }, |
|
108
|
1
|
|
|
1
|
|
77
|
'bool' => sub { 1 }, |
|
109
|
1
|
|
|
1
|
|
7
|
'eq' => sub { JSON::YY::_doc_eq($_[0], $_[1]) }, |
|
110
|
1
|
|
|
1
|
|
6
|
'ne' => sub { !JSON::YY::_doc_eq($_[0], $_[1]) }, |
|
111
|
14
|
|
|
14
|
|
6576
|
fallback => 1; |
|
|
14
|
|
|
|
|
16967
|
|
|
|
14
|
|
|
|
|
174
|
|
|
112
|
|
|
|
|
|
|
|
|
113
|
|
|
|
|
|
|
package JSON::YY; |
|
114
|
|
|
|
|
|
|
1; |
|
115
|
|
|
|
|
|
|
|
|
116
|
|
|
|
|
|
|
__END__ |