line |
stmt |
bran |
cond |
sub |
pod |
time |
code |
1
|
|
|
|
|
|
|
package Cpanel::JSON::XS::Type; |
2
|
|
|
|
|
|
|
|
3
|
|
|
|
|
|
|
=pod |
4
|
|
|
|
|
|
|
|
5
|
|
|
|
|
|
|
=head1 NAME |
6
|
|
|
|
|
|
|
|
7
|
|
|
|
|
|
|
Cpanel::JSON::XS::Type - Type support for JSON encode |
8
|
|
|
|
|
|
|
|
9
|
|
|
|
|
|
|
=head1 SYNOPSIS |
10
|
|
|
|
|
|
|
|
11
|
|
|
|
|
|
|
use Cpanel::JSON::XS; |
12
|
|
|
|
|
|
|
use Cpanel::JSON::XS::Type; |
13
|
|
|
|
|
|
|
|
14
|
|
|
|
|
|
|
|
15
|
|
|
|
|
|
|
encode_json([10, "10", 10.25], [JSON_TYPE_INT, JSON_TYPE_INT, JSON_TYPE_STRING]); |
16
|
|
|
|
|
|
|
# '[10,10,"10.25"]' |
17
|
|
|
|
|
|
|
|
18
|
|
|
|
|
|
|
encode_json([10, "10", 10.25], json_type_arrayof(JSON_TYPE_INT)); |
19
|
|
|
|
|
|
|
# '[10,10,10]' |
20
|
|
|
|
|
|
|
|
21
|
|
|
|
|
|
|
encode_json(1, JSON_TYPE_BOOL); |
22
|
|
|
|
|
|
|
# 'true' |
23
|
|
|
|
|
|
|
|
24
|
|
|
|
|
|
|
my $perl_struct = { key1 => 1, key2 => "2", key3 => 1 }; |
25
|
|
|
|
|
|
|
my $type_spec = { key1 => JSON_TYPE_STRING, key2 => JSON_TYPE_INT, key3 => JSON_TYPE_BOOL }; |
26
|
|
|
|
|
|
|
my $json_string = encode_json($perl_struct, $type_spec); |
27
|
|
|
|
|
|
|
# '{"key1":"1","key2":2,"key3":true}' |
28
|
|
|
|
|
|
|
|
29
|
|
|
|
|
|
|
my $perl_struct = { key1 => "value1", key2 => "value2", key3 => 0, key4 => 1, key5 => "string", key6 => "string2" }; |
30
|
|
|
|
|
|
|
my $type_spec = json_type_hashof(JSON_TYPE_STRING); |
31
|
|
|
|
|
|
|
my $json_string = encode_json($perl_struct, $type_spec); |
32
|
|
|
|
|
|
|
# '{"key1":"value1","key2":"value2","key3":"0","key4":"1","key5":"string","key6":"string2"}' |
33
|
|
|
|
|
|
|
|
34
|
|
|
|
|
|
|
my $perl_struct = { key1 => { key2 => [ 10, "10", 10.6 ] }, key3 => "10.5" }; |
35
|
|
|
|
|
|
|
my $type_spec = { key1 => json_type_anyof(JSON_TYPE_FLOAT, json_type_hashof(json_type_arrayof(JSON_TYPE_INT))), key3 => JSON_TYPE_FLOAT }; |
36
|
|
|
|
|
|
|
my $json_string = encode_json($perl_struct, $type_spec); |
37
|
|
|
|
|
|
|
# '{"key1":{"key2":[10,10,10]},"key3":10.5}' |
38
|
|
|
|
|
|
|
|
39
|
|
|
|
|
|
|
|
40
|
|
|
|
|
|
|
my $value = decode_json('false', 1, my $type); |
41
|
|
|
|
|
|
|
# $value is 0 and $type is JSON_TYPE_BOOL |
42
|
|
|
|
|
|
|
|
43
|
|
|
|
|
|
|
my $value = decode_json('0', 1, my $type); |
44
|
|
|
|
|
|
|
# $value is 0 and $type is JSON_TYPE_INT |
45
|
|
|
|
|
|
|
|
46
|
|
|
|
|
|
|
my $value = decode_json('"0"', 1, my $type); |
47
|
|
|
|
|
|
|
# $value is 0 and $type is JSON_TYPE_STRING |
48
|
|
|
|
|
|
|
|
49
|
|
|
|
|
|
|
my $json_string = '{"key1":{"key2":[10,"10",10.6]},"key3":"10.5"}'; |
50
|
|
|
|
|
|
|
my $perl_struct = decode_json($json_string, 0, my $type_spec); |
51
|
|
|
|
|
|
|
# $perl_struct is { key1 => { key2 => [ 10, 10, 10.6 ] }, key3 => 10.5 } |
52
|
|
|
|
|
|
|
# $type_spec is { key1 => { key2 => [ JSON_TYPE_INT, JSON_TYPE_STRING, JSON_TYPE_FLOAT ] }, key3 => JSON_TYPE_STRING } |
53
|
|
|
|
|
|
|
|
54
|
|
|
|
|
|
|
=head1 DESCRIPTION |
55
|
|
|
|
|
|
|
|
56
|
|
|
|
|
|
|
This module provides stable JSON type support for the |
57
|
|
|
|
|
|
|
L encoder which doesn't depend on |
58
|
|
|
|
|
|
|
any internal perl scalar flags or characteristics. Also it provides |
59
|
|
|
|
|
|
|
real JSON types for L decoder. |
60
|
|
|
|
|
|
|
|
61
|
|
|
|
|
|
|
In most cases perl structures passed to |
62
|
|
|
|
|
|
|
L come from other functions |
63
|
|
|
|
|
|
|
or from other modules and caller of Cpanel::JSON::XS module does not |
64
|
|
|
|
|
|
|
have control of internals or they are subject of change. So it is not |
65
|
|
|
|
|
|
|
easy to support enforcing types as described in the |
66
|
|
|
|
|
|
|
L section. |
67
|
|
|
|
|
|
|
|
68
|
|
|
|
|
|
|
For services based on JSON contents it is sometimes needed to correctly |
69
|
|
|
|
|
|
|
process and enforce JSON types. |
70
|
|
|
|
|
|
|
|
71
|
|
|
|
|
|
|
The function L takes optional |
72
|
|
|
|
|
|
|
third scalar parameter and fills it with specification of json types. |
73
|
|
|
|
|
|
|
|
74
|
|
|
|
|
|
|
The function L takes a perl |
75
|
|
|
|
|
|
|
structure as its input and optionally also a json type specification in |
76
|
|
|
|
|
|
|
the second parameter. |
77
|
|
|
|
|
|
|
|
78
|
|
|
|
|
|
|
If the specification is not provided (or is undef) internal perl |
79
|
|
|
|
|
|
|
scalar flags are used for the resulting JSON type. The internal flags |
80
|
|
|
|
|
|
|
can be changed by perl itself, but also by external modules. Which |
81
|
|
|
|
|
|
|
means that types in resulting JSON string aren't stable. Specially it |
82
|
|
|
|
|
|
|
does not work reliable for dual vars and scalars which were used in |
83
|
|
|
|
|
|
|
both numeric and string operations. See L
|
84
|
|
|
|
|
|
|
scalars|Cpanel::JSON::XS/simple scalars>. |
85
|
|
|
|
|
|
|
|
86
|
|
|
|
|
|
|
To enforce that specification is always provided use C. |
87
|
|
|
|
|
|
|
In this case when C is called without second argument (or is |
88
|
|
|
|
|
|
|
undef) then it croaks. It applies recursively for all sub-structures. |
89
|
|
|
|
|
|
|
|
90
|
|
|
|
|
|
|
=head2 JSON type specification for scalars: |
91
|
|
|
|
|
|
|
|
92
|
|
|
|
|
|
|
=over 4 |
93
|
|
|
|
|
|
|
|
94
|
|
|
|
|
|
|
=item JSON_TYPE_BOOL |
95
|
|
|
|
|
|
|
|
96
|
|
|
|
|
|
|
It enforces JSON boolean in resulting JSON, i.e. either C or |
97
|
|
|
|
|
|
|
C. For determining whether the scalar passed to the encoder |
98
|
|
|
|
|
|
|
is true, standard perl boolean logic is used. |
99
|
|
|
|
|
|
|
|
100
|
|
|
|
|
|
|
=item JSON_TYPE_INT |
101
|
|
|
|
|
|
|
|
102
|
|
|
|
|
|
|
It enforces JSON number without fraction part in the resulting JSON. |
103
|
|
|
|
|
|
|
Equivalent of perl function L is used for conversion. |
104
|
|
|
|
|
|
|
|
105
|
|
|
|
|
|
|
=item JSON_TYPE_FLOAT |
106
|
|
|
|
|
|
|
|
107
|
|
|
|
|
|
|
It enforces JSON number with fraction part in the resulting JSON. |
108
|
|
|
|
|
|
|
Equivalent of perl operation C<+0> is used for conversion. |
109
|
|
|
|
|
|
|
|
110
|
|
|
|
|
|
|
=item JSON_TYPE_STRING |
111
|
|
|
|
|
|
|
|
112
|
|
|
|
|
|
|
It enforces JSON string type in the resulting JSON. |
113
|
|
|
|
|
|
|
|
114
|
|
|
|
|
|
|
=item JSON_TYPE_NULL |
115
|
|
|
|
|
|
|
|
116
|
|
|
|
|
|
|
It represents JSON C value. Makes sense only when passing |
117
|
|
|
|
|
|
|
perl's C value. |
118
|
|
|
|
|
|
|
|
119
|
|
|
|
|
|
|
=back |
120
|
|
|
|
|
|
|
|
121
|
|
|
|
|
|
|
For each type, there also exists a type with the suffix C<_OR_NULL> |
122
|
|
|
|
|
|
|
which encodes perl's C into JSON C. Without type with |
123
|
|
|
|
|
|
|
suffix C<_OR_NULL> perl's C is converted to specific type |
124
|
|
|
|
|
|
|
according to above rules. |
125
|
|
|
|
|
|
|
|
126
|
|
|
|
|
|
|
=head2 JSON type specification for arrays: |
127
|
|
|
|
|
|
|
|
128
|
|
|
|
|
|
|
=over 4 |
129
|
|
|
|
|
|
|
|
130
|
|
|
|
|
|
|
=item [...] |
131
|
|
|
|
|
|
|
|
132
|
|
|
|
|
|
|
The array must contain the same number of elements as in the perl |
133
|
|
|
|
|
|
|
array passed for encoding. Each element of the array describes the |
134
|
|
|
|
|
|
|
JSON type which is enforced for the corresponding element of the |
135
|
|
|
|
|
|
|
perl array. |
136
|
|
|
|
|
|
|
|
137
|
|
|
|
|
|
|
=item json_type_arrayof |
138
|
|
|
|
|
|
|
|
139
|
|
|
|
|
|
|
This function takes a JSON type specification as its argument which |
140
|
|
|
|
|
|
|
is enforced for every element of the passed perl array. |
141
|
|
|
|
|
|
|
|
142
|
|
|
|
|
|
|
=back |
143
|
|
|
|
|
|
|
|
144
|
|
|
|
|
|
|
=head2 JSON type specification for hashes: |
145
|
|
|
|
|
|
|
|
146
|
|
|
|
|
|
|
=over 4 |
147
|
|
|
|
|
|
|
|
148
|
|
|
|
|
|
|
=item {...} |
149
|
|
|
|
|
|
|
|
150
|
|
|
|
|
|
|
Each hash value for corresponding key describes the JSON type |
151
|
|
|
|
|
|
|
specification for values of passed perl hash structure. Keys in hash |
152
|
|
|
|
|
|
|
which are not present in passed perl hash structure are simple |
153
|
|
|
|
|
|
|
ignored and not used. |
154
|
|
|
|
|
|
|
|
155
|
|
|
|
|
|
|
=item json_type_hashof |
156
|
|
|
|
|
|
|
|
157
|
|
|
|
|
|
|
This function takes a JSON type specification as its argument which |
158
|
|
|
|
|
|
|
is enforced for every value of passed perl hash structure. |
159
|
|
|
|
|
|
|
|
160
|
|
|
|
|
|
|
=back |
161
|
|
|
|
|
|
|
|
162
|
|
|
|
|
|
|
=head2 JSON type specification for alternatives: |
163
|
|
|
|
|
|
|
|
164
|
|
|
|
|
|
|
=over 4 |
165
|
|
|
|
|
|
|
|
166
|
|
|
|
|
|
|
=item json_type_anyof |
167
|
|
|
|
|
|
|
|
168
|
|
|
|
|
|
|
This function takes a list of JSON type alternative specifications |
169
|
|
|
|
|
|
|
(maximally one scalar, one array, and one hash) as its input and the |
170
|
|
|
|
|
|
|
JSON encoder chooses one that matches. |
171
|
|
|
|
|
|
|
|
172
|
|
|
|
|
|
|
=item json_type_null_or_anyof |
173
|
|
|
|
|
|
|
|
174
|
|
|
|
|
|
|
Like L|/json_type_anyof>, but scalar can be only |
175
|
|
|
|
|
|
|
perl's C. |
176
|
|
|
|
|
|
|
|
177
|
|
|
|
|
|
|
=back |
178
|
|
|
|
|
|
|
|
179
|
|
|
|
|
|
|
=head2 Recursive specifications |
180
|
|
|
|
|
|
|
|
181
|
|
|
|
|
|
|
=over 4 |
182
|
|
|
|
|
|
|
|
183
|
|
|
|
|
|
|
=item json_type_weaken |
184
|
|
|
|
|
|
|
|
185
|
|
|
|
|
|
|
This function can be used as an argument for L, |
186
|
|
|
|
|
|
|
L or L functions to create weak |
187
|
|
|
|
|
|
|
references suitable for complicated recursive structures. It depends |
188
|
|
|
|
|
|
|
on L module. |
189
|
|
|
|
|
|
|
See following example: |
190
|
|
|
|
|
|
|
|
191
|
|
|
|
|
|
|
my $struct = { |
192
|
|
|
|
|
|
|
type => JSON_TYPE_STRING, |
193
|
|
|
|
|
|
|
array => json_type_arrayof(JSON_TYPE_INT), |
194
|
|
|
|
|
|
|
}; |
195
|
|
|
|
|
|
|
$struct->{recursive} = json_type_anyof( |
196
|
|
|
|
|
|
|
json_type_weaken($struct), |
197
|
|
|
|
|
|
|
json_type_arrayof(JSON_TYPE_STRING), |
198
|
|
|
|
|
|
|
); |
199
|
|
|
|
|
|
|
|
200
|
|
|
|
|
|
|
If you want to encode all perl scalars to JSON string types despite |
201
|
|
|
|
|
|
|
how complicated is input perl structure you can define JSON type |
202
|
|
|
|
|
|
|
specification for alternatives recursively. It could be defined as: |
203
|
|
|
|
|
|
|
|
204
|
|
|
|
|
|
|
my $type = json_type_anyof(); |
205
|
|
|
|
|
|
|
$type->[0] = JSON_TYPE_STRING_OR_NULL; |
206
|
|
|
|
|
|
|
$type->[1] = json_type_arrayof(json_type_weaken($type)); |
207
|
|
|
|
|
|
|
$type->[2] = json_type_hashof(json_type_weaken($type)); |
208
|
|
|
|
|
|
|
|
209
|
|
|
|
|
|
|
print encode_json([ 10, "10", { key => 10 } ], $type); |
210
|
|
|
|
|
|
|
# ["10","10",{"key":"10"}] |
211
|
|
|
|
|
|
|
|
212
|
|
|
|
|
|
|
An alternative solution for encoding all scalars to JSON strings is to |
213
|
|
|
|
|
|
|
use C method of L itself: |
214
|
|
|
|
|
|
|
|
215
|
|
|
|
|
|
|
my $json = Cpanel::JSON::XS->new->type_all_string; |
216
|
|
|
|
|
|
|
print $json->encode([ 10, "10", { key => 10 } ]); |
217
|
|
|
|
|
|
|
# ["10","10",{"key":"10"}] |
218
|
|
|
|
|
|
|
|
219
|
|
|
|
|
|
|
=back |
220
|
|
|
|
|
|
|
|
221
|
|
|
|
|
|
|
=head1 AUTHOR |
222
|
|
|
|
|
|
|
|
223
|
|
|
|
|
|
|
Pali Epali@cpan.orgE |
224
|
|
|
|
|
|
|
|
225
|
|
|
|
|
|
|
=head1 COPYRIGHT & LICENSE |
226
|
|
|
|
|
|
|
|
227
|
|
|
|
|
|
|
Copyright (c) 2017, GoodData Corporation. All rights reserved. |
228
|
|
|
|
|
|
|
|
229
|
|
|
|
|
|
|
This module is available under the same licences as perl, the Artistic |
230
|
|
|
|
|
|
|
license and the GPL. |
231
|
|
|
|
|
|
|
|
232
|
|
|
|
|
|
|
=cut |
233
|
|
|
|
|
|
|
|
234
|
2
|
|
|
2
|
|
893
|
use strict; |
|
2
|
|
|
|
|
4
|
|
|
2
|
|
|
|
|
47
|
|
235
|
2
|
|
|
2
|
|
9
|
use warnings; |
|
2
|
|
|
|
|
4
|
|
|
2
|
|
|
|
|
157
|
|
236
|
|
|
|
|
|
|
|
237
|
|
|
|
|
|
|
BEGIN { |
238
|
2
|
50
|
|
2
|
|
6
|
if (eval { require Scalar::Util }) { |
|
2
|
|
|
|
|
12
|
|
239
|
2
|
|
|
|
|
197
|
Scalar::Util->import('weaken'); |
240
|
|
|
|
|
|
|
} else { |
241
|
0
|
|
|
|
|
0
|
*weaken = sub($) { die 'Scalar::Util is required for weaken' }; |
|
0
|
|
|
|
|
0
|
|
242
|
|
|
|
|
|
|
} |
243
|
|
|
|
|
|
|
} |
244
|
|
|
|
|
|
|
|
245
|
|
|
|
|
|
|
# This exports needed XS constants to perl |
246
|
2
|
|
|
2
|
|
12
|
use Cpanel::JSON::XS (); |
|
2
|
|
|
|
|
2
|
|
|
2
|
|
|
|
|
44
|
|
247
|
|
|
|
|
|
|
|
248
|
2
|
|
|
2
|
|
13
|
use Exporter; |
|
2
|
|
|
|
|
3
|
|
|
2
|
|
|
|
|
200
|
|
249
|
|
|
|
|
|
|
our @ISA = qw(Exporter); |
250
|
|
|
|
|
|
|
our @EXPORT = our @EXPORT_OK = qw( |
251
|
|
|
|
|
|
|
json_type_arrayof |
252
|
|
|
|
|
|
|
json_type_hashof |
253
|
|
|
|
|
|
|
json_type_anyof |
254
|
|
|
|
|
|
|
json_type_null_or_anyof |
255
|
|
|
|
|
|
|
json_type_weaken |
256
|
|
|
|
|
|
|
JSON_TYPE_NULL |
257
|
|
|
|
|
|
|
JSON_TYPE_BOOL |
258
|
|
|
|
|
|
|
JSON_TYPE_INT |
259
|
|
|
|
|
|
|
JSON_TYPE_FLOAT |
260
|
|
|
|
|
|
|
JSON_TYPE_STRING |
261
|
|
|
|
|
|
|
JSON_TYPE_BOOL_OR_NULL |
262
|
|
|
|
|
|
|
JSON_TYPE_INT_OR_NULL |
263
|
|
|
|
|
|
|
JSON_TYPE_FLOAT_OR_NULL |
264
|
|
|
|
|
|
|
JSON_TYPE_STRING_OR_NULL |
265
|
|
|
|
|
|
|
JSON_TYPE_ARRAYOF_CLASS |
266
|
|
|
|
|
|
|
JSON_TYPE_HASHOF_CLASS |
267
|
|
|
|
|
|
|
JSON_TYPE_ANYOF_CLASS |
268
|
|
|
|
|
|
|
); |
269
|
|
|
|
|
|
|
|
270
|
2
|
|
|
2
|
|
10
|
use constant JSON_TYPE_WEAKEN_CLASS => 'Cpanel::JSON::XS::Type::Weaken'; |
|
2
|
|
|
|
|
4
|
|
|
2
|
|
|
|
|
1016
|
|
271
|
|
|
|
|
|
|
|
272
|
|
|
|
|
|
|
sub json_type_anyof { |
273
|
86
|
|
|
86
|
1
|
39492
|
my ($scalar, $array, $hash); |
274
|
86
|
|
|
|
|
0
|
my ($scalar_weaken, $array_weaken, $hash_weaken); |
275
|
86
|
|
|
|
|
139
|
foreach (@_) { |
276
|
156
|
|
|
|
|
183
|
my $type = $_; |
277
|
156
|
|
|
|
|
203
|
my $ref = ref($_); |
278
|
156
|
|
|
|
|
166
|
my $weaken; |
279
|
156
|
100
|
|
|
|
251
|
if ($ref eq JSON_TYPE_WEAKEN_CLASS) { |
280
|
1
|
|
|
|
|
2
|
$type = ${$type}; |
|
1
|
|
|
|
|
3
|
|
281
|
1
|
|
|
|
|
2
|
$ref = ref($type); |
282
|
1
|
|
|
|
|
2
|
$weaken = 1; |
283
|
|
|
|
|
|
|
} |
284
|
156
|
100
|
100
|
|
|
415
|
if ($ref eq '') { |
|
|
100
|
100
|
|
|
|
|
|
|
100
|
|
|
|
|
|
285
|
77
|
100
|
|
|
|
124
|
die 'Only one scalar type can be specified in anyof' if defined $scalar; |
286
|
76
|
|
|
|
|
80
|
$scalar = $type; |
287
|
76
|
|
|
|
|
100
|
$scalar_weaken = $weaken; |
288
|
|
|
|
|
|
|
} elsif ($ref eq 'ARRAY' or $ref eq JSON_TYPE_ARRAYOF_CLASS) { |
289
|
41
|
100
|
|
|
|
81
|
die 'Only one array type can be specified in anyof' if defined $array; |
290
|
38
|
|
|
|
|
43
|
$array = $type; |
291
|
38
|
|
|
|
|
70
|
$array_weaken = $weaken; |
292
|
|
|
|
|
|
|
} elsif ($ref eq 'HASH' or $ref eq JSON_TYPE_HASHOF_CLASS) { |
293
|
37
|
100
|
|
|
|
84
|
die 'Only one hash type can be specified in anyof' if defined $hash; |
294
|
34
|
|
|
|
|
39
|
$hash = $type; |
295
|
34
|
|
|
|
|
53
|
$hash_weaken = $weaken; |
296
|
|
|
|
|
|
|
} else { |
297
|
1
|
|
|
|
|
9
|
die 'Only scalar, array or hash can be specified in anyof'; |
298
|
|
|
|
|
|
|
} |
299
|
|
|
|
|
|
|
} |
300
|
78
|
|
|
|
|
128
|
my $type = [$scalar, $array, $hash]; |
301
|
78
|
50
|
|
|
|
126
|
weaken $type->[0] if $scalar_weaken; |
302
|
78
|
50
|
|
|
|
116
|
weaken $type->[1] if $array_weaken; |
303
|
78
|
100
|
|
|
|
114
|
weaken $type->[2] if $hash_weaken; |
304
|
78
|
|
|
|
|
519
|
return bless $type, JSON_TYPE_ANYOF_CLASS; |
305
|
|
|
|
|
|
|
} |
306
|
|
|
|
|
|
|
|
307
|
|
|
|
|
|
|
sub json_type_null_or_anyof { |
308
|
4
|
|
|
4
|
1
|
10
|
foreach (@_) { |
309
|
4
|
100
|
|
|
|
30
|
die 'Scalar cannot be specified in null_or_anyof' if ref($_) eq ''; |
310
|
|
|
|
|
|
|
} |
311
|
3
|
|
|
|
|
7
|
return json_type_anyof(JSON_TYPE_CAN_BE_NULL, @_); |
312
|
|
|
|
|
|
|
} |
313
|
|
|
|
|
|
|
|
314
|
|
|
|
|
|
|
sub json_type_arrayof { |
315
|
16
|
100
|
|
16
|
1
|
109488
|
die 'Exactly one type must be specified in arrayof' if scalar @_ != 1; |
316
|
15
|
|
|
|
|
24
|
my $type = $_[0]; |
317
|
15
|
100
|
|
|
|
36
|
if (ref($type) eq JSON_TYPE_WEAKEN_CLASS) { |
318
|
1
|
|
|
|
|
2
|
$type = ${$type}; |
|
1
|
|
|
|
|
2
|
|
319
|
1
|
|
|
|
|
3
|
weaken $type; |
320
|
|
|
|
|
|
|
} |
321
|
15
|
|
|
|
|
89
|
return bless \$type, JSON_TYPE_ARRAYOF_CLASS; |
322
|
|
|
|
|
|
|
} |
323
|
|
|
|
|
|
|
|
324
|
|
|
|
|
|
|
sub json_type_hashof { |
325
|
9
|
100
|
|
9
|
1
|
1305
|
die 'Exactly one type must be specified in hashof' if scalar @_ != 1; |
326
|
8
|
|
|
|
|
11
|
my $type = $_[0]; |
327
|
8
|
100
|
|
|
|
14
|
if (ref($type) eq JSON_TYPE_WEAKEN_CLASS) { |
328
|
1
|
|
|
|
|
3
|
$type = ${$type}; |
|
1
|
|
|
|
|
3
|
|
329
|
1
|
|
|
|
|
3
|
weaken $type; |
330
|
|
|
|
|
|
|
} |
331
|
8
|
|
|
|
|
29
|
return bless \$type, JSON_TYPE_HASHOF_CLASS; |
332
|
|
|
|
|
|
|
} |
333
|
|
|
|
|
|
|
|
334
|
|
|
|
|
|
|
sub json_type_weaken { |
335
|
3
|
50
|
|
3
|
1
|
5214
|
die 'Exactly one type must be specified in weaken' if scalar @_ != 1; |
336
|
3
|
50
|
|
|
|
9
|
die 'Scalar cannot be specfied in weaken' if ref($_[0]) eq ''; |
337
|
3
|
|
|
|
|
18
|
return bless \(my $type = $_[0]), JSON_TYPE_WEAKEN_CLASS; |
338
|
|
|
|
|
|
|
} |
339
|
|
|
|
|
|
|
|
340
|
|
|
|
|
|
|
1; |