File Coverage

blib/lib/JSON/DWIW.pm
Criterion Covered Total %
statement 172 288 59.7
branch 62 138 44.9
condition 23 52 44.2
subroutine 27 36 75.0
pod 11 15 73.3
total 295 529 55.7


line stmt bran cond sub pod time code
1             # Creation date: 2007-02-19 16:54:44
2             # Authors: don
3             #
4             # Copyright (c) 2007-2010 Don Owens . All rights reserved.
5             #
6             # This is free software; you can redistribute it and/or modify it under
7             # the Perl Artistic license. You should have received a copy of the
8             # Artistic license with this distribution, in the file named
9             # "Artistic". You may also obtain a copy from
10             # http://regexguy.com/license/Artistic
11             #
12             # This program is distributed in the hope that it will be
13             # useful, but WITHOUT ANY WARRANTY; without even the implied
14             # warranty of MERCHANTABILITY or FITNESS FOR A PARTICULAR
15             # PURPOSE.
16              
17             # $Revision: 1737 $
18              
19             # TODO
20             # * support surrogate pairs as described in http://www.ietf.org/rfc/rfc4627.txt
21             # * check for first surrogate: 0xD800 => 0xDBFF
22             # * check for second surrogate: 0xDC00 => 0xDFFF
23             # * take code point - 0x10000, add lower 10 bits to second surrogate, add upper 10 bits to first
24              
25             =pod
26              
27             =head1 NAME
28              
29             JSON::DWIW - JSON converter that Does What I Want
30              
31             =head1 SYNOPSIS
32              
33             use JSON::DWIW;
34             my $json_obj = JSON::DWIW->new;
35             my $data = $json_obj->from_json($json_str);
36             my $str = $json_obj->to_json($data);
37            
38             my ($data, $error_string) = $json_obj->from_json($json_str);
39            
40             my $data = JSON::DWIW::deserialize($json_str);
41             my $error_str = JSON::DWIW::get_error_string();
42            
43             use JSON::DWIW qw/deserialize_json from_json/
44             my $data = deserialize_json($json_str);
45             my $error_str = JSON::DWIW::get_error_string();
46            
47             my $error_string = $json_obj->get_error_string;
48             my $error_data = $json_obj->get_error_data;
49             my $stats = $json_obj->get_stats;
50            
51             my $data = $json_obj->from_json_file($file)
52             my $ok = $json_obj->to_json_file($data, $file);
53            
54             my $data = JSON::DWIW->from_json($json_str);
55             my $str = JSON::DWIW->to_json($data);
56            
57             my $data = JSON::DWIW->from_json($json_str, \%options);
58             my $str = JSON::DWIW->to_json($data, \%options);
59            
60             my $true_value = JSON::DWIW->true;
61             my $false_value = JSON::DWIW->false;
62             my $data = { var1 => "stuff", var2 => $true_value,
63             var3 => $false_value, };
64             my $str = JSON::DWIW->to_json($data);
65              
66             my $data = JSON::DWIW::deserialize($str, { start_depth => 1,
67             start_depth_handler => $handler });
68              
69              
70             =head1 DESCRIPTION
71              
72             Other JSON modules require setting several parameters before
73             calling the conversion methods to do what I want. This module
74             does things by default that I think should be done when working
75             with JSON in Perl. This module also encodes and decodes faster
76             than L.pm and L in my benchmarks.
77              
78             This means that any piece of data in Perl (assuming it's valid
79             unicode) will get converted to something in JSON instead of
80             throwing an exception. It also means that output will be strict
81             JSON, while accepted input will be flexible, without having to
82             set any options.
83              
84             For a list of changes in recent versions, see the documentation
85             for L.
86              
87             This module can be downloaded from L.
88              
89             =head2 Encoding
90              
91             Perl objects get encoded as their underlying data structure, with
92             the exception of L and L, which will be
93             output as numbers, and L, which will get output
94             as a true or false value (see the true() and false() methods).
95             For example, a blessed hash ref will be represented as an object
96             in JSON, a blessed array will be represented as an array. etc. A
97             reference to a scalar is dereferenced and represented as the
98             scalar itself. Globs, Code refs, etc., get stringified, and
99             undef becomes null.
100              
101             Scalars that have been used as both a string and a number will be
102             output as a string. A reference to a reference is currently
103             output as an empty string, but this may change.
104              
105             You may notice there is a deserialize function, but not a
106             serialize one. The deserialize function was written as a full
107             rewrite (the parsing is in a separate, event-based library now)
108             of from_json (now from_json calls deserialize). In the future,
109             there will be a serialize function that is a rewrite of to_json.
110              
111             =head2 Decoding
112              
113             Input is expected to utf-8. When decoding, null, true, and false
114             become undef, 1, and 0, repectively. Numbers that appear to be
115             too long to be supported natively are converted to L
116             or L objects, if you have them installed.
117             Otherwise, long numbers are turned into strings to prevent data
118             loss.
119              
120             The parser is flexible in what it accepts and handles some
121             things not in the JSON spec:
122              
123             =over 4
124              
125             =item quotes
126              
127             Both single and double quotes are allowed for quoting a string, e.g.,
128              
129             =for pod2rst next-code-block: javascript
130              
131             [ "string1", 'string2' ]
132              
133             =item bare keys
134              
135             Object/hash keys can be bare if they look like an identifier, e.g.,
136              
137             =for pod2rst next-code-block: javascript
138              
139             { var1: "myval1", var2: "myval2" }
140              
141             =item extra commas
142              
143             Extra commas in objects/hashes and arrays are ignored, e.g.,
144              
145             =for pod2rst next-code-block: javascript
146              
147             [1,2,3,,,4,]
148              
149             becomes a 4 element array containing 1, 2, 3, and 4.
150              
151             =item escape sequences
152              
153             Latin1 hexadecimal escape sequences (\xHH) are accepted, as in
154             Javascript. Also, the vertical tab escape \v is recognized (\u000b).
155              
156             =item comments
157              
158             C, C++, and shell-style comments are accepted. That is
159              
160             =for pod2rst next-code-block: c++
161              
162             /* this is a comment */
163             // this is a comment
164              
165             # this is also a comment
166              
167             =back
168              
169             =cut
170              
171 36     36   328778 use strict;
  36         90  
  36         1527  
172 36     36   205 use warnings;
  36         70  
  36         1279  
173              
174 36     36   751 use 5.006_00;
  36         127  
  36         1454  
175              
176 36     36   22592 use JSON::DWIW::Boolean;
  36         94  
  36         1418  
177              
178             package JSON::DWIW;
179              
180 36     36   240 use vars qw(@ISA @EXPORT @EXPORT_OK %EXPORT_TAGS);
  36         350  
  36         3418  
181              
182             # work around utf-8 weirdness in Perl < 5.8
183 36     36   54369 use utf8;
  36         358  
  36         415  
184              
185             require Exporter;
186             require DynaLoader;
187             @ISA = qw(DynaLoader);
188              
189             @EXPORT = ( );
190             @EXPORT_OK = ();
191             %EXPORT_TAGS = (all => [ 'to_json', 'from_json', 'deserialize_json' ]);
192              
193             Exporter::export_ok_tags('all');
194              
195             # change in POD as well!
196             our $VERSION = '0.47';
197              
198             JSON::DWIW->bootstrap($VERSION);
199              
200              
201             {
202             package JSON::DWIW::Exporter;
203 36     36   5614 use vars qw(@ISA @EXPORT @EXPORT_OK %EXPORT_TAGS);
  36         70  
  36         35435  
204             @ISA = qw(Exporter);
205              
206             *EXPORT = \@JSON::DWIW::EXPORT;
207             *EXPORT_OK = \@JSON::DWIW::EXPORT_OK;
208             *EXPORT_TAGS = \%JSON::DWIW::EXPORT_TAGS;
209              
210             *deserialize_json = \&JSON::DWIW::deserialize_json;
211              
212             sub import {
213 36     36   78226 JSON::DWIW::Exporter->export_to_level(2, @_);
214             }
215              
216             sub to_json {
217 0     0   0 return JSON::DWIW->to_json(@_);
218             }
219              
220             sub from_json {
221             # return JSON::DWIW->from_json(@_);
222 1     1   493 return JSON::DWIW::deserialize(@_);
223             }
224             }
225              
226             sub import {
227 36     36   452 JSON::DWIW::Exporter::import(@_);
228             }
229              
230             {
231             # workaround for weird importing bug on some installations
232             local($SIG{__DIE__});
233 36     36   64621 eval qq{
  36     36   935148  
  36         316  
  36         777765  
  36         895555  
  36         254  
234             use Math::BigInt;
235             use Math::BigFloat;
236             };
237             }
238              
239              
240             =pod
241              
242             =head1 METHODS
243              
244             =head2 C
245              
246             Create a new L object.
247              
248             C<%options> is an optional hash of parameters that will change the
249             bahavior of this module when encoding to JSON. You may also
250             pass these options as the second argument to C and
251             C. The following options are supported:
252              
253             =head3 I
254              
255             If set to a true value, keys in hashes will not be quoted when
256             converted to JSON if they look like identifiers. This is valid
257             Javascript in current browsers, but not in JSON.
258              
259             =head3 I
260              
261             If set to a true value, errors found when converting to or from
262             JSON will result in C being called with the error message.
263             The default is to not use exceptions.
264              
265             =head3 I
266              
267             This options indicates what should be done if bad characters are
268             found, e.g., bad utf-8 sequence. The default is to return an
269             error and drop all the output.
270              
271             The following values for bad_char_policy are supported:
272              
273             =head4 I
274              
275             default action, i.e., drop any output built up and return an error
276              
277             =head4 I
278              
279             Convert to a utf-8 char using the value of the byte as a code
280             point. This is basically the same as assuming the bad character
281             is in latin-1 and converting it to utf-8.
282              
283             =head4 I
284              
285             Ignore the error and pass through the raw bytes (invalid JSON)
286              
287             =head3 I
288              
289             If set to a true value, escape all multi-byte characters (e.g.,
290             \u00e9) when converting to JSON.
291              
292             =head3 I
293              
294             Synonym for escape_multi_byte
295              
296             =head3 I
297              
298             Add white space to the output when calling to_json() to make the
299             output easier for humans to read.
300              
301             =head3 I
302              
303             When converting from JSON, return objects for booleans so that
304             "true" and "false" can be maintained when encoding and decoding.
305             If this flag is set, then "true" becomes a L
306             object that evaluates to true in a boolean context, and "false"
307             becomes an object that evaluates to false in a boolean context.
308             These objects are recognized by the to_json() method, so they
309             will be output as "true" or "false" instead of "1" or "0".
310              
311             =head3 I
312              
313             Don't escape solidus characters ("/") in strings. The output is
314             still legal JSON with this option turned on.
315              
316             =head3 I
317              
318             Only do required escaping in strings (solidus and quote). Tabs,
319             newlines, backspaces, etc., will not be escaped with this
320             optioned turned on (but the output will still be valid JSON).
321              
322             =head3 I
323              
324             Set to a true value to sort hash keys (alphabetically) when converting to JSON.
325              
326             =head3 I
327              
328             A subroutine reference to call when parsing a number. The
329             subroutine will be provided one string that is the number being
330             parsed. The return value from the subroutine will be used to
331             populate the return data instead of converting to a number.
332              
333             E.g.,
334              
335             my $json = '{ "a": 6.3e-10 }';
336             my $cb = sub { my ($val) = @_; return "I got the number '$val'"; };
337            
338             my $data = JSON::DWIW::deserialize($json, { parse_number => $cb });
339              
340             =head3 I
341              
342             A subroutine reference to call when parsing a constant (true,
343             false, or null). The subroutine will be provided one string that
344             is the constant being parsed. The return value from the
345             subroutine will be used to populate the return data instead of
346             converting to a boolean or undef. See the "parse_number" option.
347              
348             =head3 I
349              
350             Depth at which C should be called. See L.
351              
352             =head3 I
353              
354             A reference to a subroutine to called when parsing and at level
355             I in the data structure. When specified along with I, the
356             parser does not return the entire data structure. Instead, it
357             calls I for each element in the array when
358             the parser is at level I. This is useful for
359             parsing a very large array without loading all the data into
360             memory (especially when using C).
361              
362             E.g., with I set to 1 and I set to C<$handler>:
363              
364             my $str = '[ { "foo": "bar", "cat": 1 }, { "concat": 1, "lambda" : [ "one", 2, 3 ] } ]';
365            
366             my $foo = { foo => [ ] };
367             my $handler = sub { push @{$foo->{foo}}, $_[0]; return 1; };
368            
369             my $data = JSON::DWIW::deserialize($str, { start_depth => 1,
370             start_depth_handler => $handler });
371             print STDERR Data::Dumper->Dump([ $foo ], [ 'foo' ]) . "\n";
372             print STDERR Data::Dumper->Dump([ $data ], [ 'leftover_data' ]) . "\n";
373              
374             # Output
375             $foo = {
376             'foo' => [
377             {
378             'cat' => 1,
379             'foo' => 'bar'
380             },
381             {
382             'lambda' => [
383             'one',
384             2,
385             3
386             ],
387             'concat' => 1
388             }
389             ]
390             };
391              
392              
393             $leftover_data = [];
394              
395             =cut
396              
397             sub new {
398 100     100 1 3137 my $proto = shift;
399              
400 100   66     615 my $self = bless {}, ref($proto) || $proto;
401 100         165 my $params = shift;
402            
403 100 100       336 return $self unless $params;
404              
405 19 50 33     139 unless (defined($params) and UNIVERSAL::isa($params, 'HASH')) {
406 0         0 return $self;
407             }
408              
409 19         52 foreach my $field (qw/bare_keys use_exceptions bad_char_policy dump_vars pretty
410             escape_multi_byte convert_bool detect_circular_refs
411             ascii bare_solidus minimal_escaping
412             parse_number parse_constant sort_keys start_depth start_depth_handler/) {
413 304 100       692 if (exists($params->{$field})) {
414 21         93 $self->{$field} = $params->{$field};
415             }
416             }
417              
418 19         59 return $self;
419             }
420              
421             =pod
422              
423             =head2 C
424              
425             Returns the JSON representation of $data (arbitrary
426             datastructure). See http://www.json.org/ for details.
427              
428             Called in list context, this method returns a list whose first
429             element is the encoded JSON string and the second element is an
430             error message, if any. If $error_msg is defined, there was a
431             problem converting to JSON. You may also pass a second argument
432             to to_json() that is a reference to a hash of options -- see
433             new().
434              
435             my $json_str = JSON::DWIW->to_json($data);
436            
437             my ($json_str, $error_msg) = JSON::DWIW->to_json($data);
438            
439             my $json_str = JSON::DWIW->to_json($data, { use_exceptions => 1 });
440              
441             Aliases: toJson, toJSON, objToJson
442              
443             =cut
444              
445             sub to_json {
446 50     50 1 28437 my $proto = shift;
447 50         77 my $data;
448            
449             my $self;
450 50 100       320 if (UNIVERSAL::isa($proto, 'JSON::DWIW')) {
451 49         72 $data = shift;
452 49         78 my $options = shift;
453 49 100       110 if ($options) {
454 10 100 66     64 if (ref($proto) and $proto->isa('HASH')) {
455 3 50       12 if (UNIVERSAL::isa($options, 'HASH')) {
456 3         20 $options = { %$proto, %$options };
457             }
458             }
459              
460 10         47 $self = $proto->new($options, @_);
461             }
462             else {
463 39 100       138 $self = ref($proto) ? $proto : $proto->new(@_);
464             }
465             }
466             else {
467 1         3 $data = $proto;
468 1         4 $self = JSON::DWIW->new(@_);
469             }
470              
471 50         76 my $error_msg;
472             my $error_data;
473 50         81 my $stats_data = { };
474 50         1394 my $str = _xs_to_json($self, $data, \$error_msg, \$error_data, $stats_data);
475              
476 50 50       520 if ($stats_data) {
477 50         87 $JSON::DWIW::Last_Stats = $stats_data;
478 50         387 $self->{last_stats} = $stats_data;
479             }
480              
481 50         86 $JSON::DWIW::LastError = $error_msg;
482 50         98 $self->{last_error} = $error_msg;
483              
484 50         66 $JSON::DWIW::LastErrorData = $error_data;
485 50         77 $self->{last_error_data} = $error_data;
486              
487 50 100 66     176 if (defined($error_msg) and $self->{use_exceptions}) {
488 1         8 die $error_msg;
489             }
490 49 100       304 return wantarray ? ($str, $error_msg) : $str;
491             }
492             {
493 36     36   224 no warnings 'once';
  36         74  
  36         25760  
494            
495             *toJson = \&to_json;
496             *toJSON = \&to_json;
497             *objToJson = \&to_json;
498             }
499              
500             sub serialize {
501 1     1 0 812 my $data = shift;
502 1   50     13 my $options = shift || { };
503              
504 1         3 my $error_msg;
505             my $error_data;
506 1         3 my $stats_data = { };
507 1         43 my $str = _xs_to_json($options, $data, \$error_msg, \$error_data, $stats_data);
508              
509 1 50       9 if ($stats_data) {
510 1         4 $JSON::DWIW::Last_Stats = $stats_data;
511             }
512              
513 1         2 $JSON::DWIW::LastError = $error_msg;
514              
515 1         2 $JSON::DWIW::LastErrorData = $error_data;
516              
517 1         5 return $str;
518             }
519              
520             # total process size in pages
521             sub get_proc_size {
522 0 0   0 0 0 if ($^O eq 'linux') {
523 0         0 my $statm_path = "/proc/$$/statm";
524 0 0       0 if (-e $statm_path) {
525 0 0       0 open(my $in_fh, '<', $statm_path) or return undef;
526 0         0 my $statm = <$in_fh>;
527 0         0 close $in_fh;
528            
529 0         0 my @fields = split /\s+/, $statm;
530            
531 0         0 return $fields[0];
532             }
533             }
534              
535 0         0 return undef;
536             }
537              
538             =pod
539              
540             =head2 C
541              
542             Returns the Perl data structure for the given JSON string. The
543             value for true becomes 1, false becomes 0, and null gets
544             converted to undef.
545              
546             This function should not be called as a method (for performance
547             reasons). Unlike C, it returns a single value, the
548             data structure resulting from the conversion. If the return
549             value is undef, check the result of the C
550             function/method to see if an error is defined.
551              
552             =head2 C
553              
554             Same as deserialize, except that it takes a file as an argument.
555             On Unix, this mmap's the file, so it does not load a big file
556             into memory all at once, and does less buffer copying.
557              
558             =cut
559              
560             =pod
561              
562             =head2 C
563              
564             Similar to C, but expects to be called as a method.
565              
566             Called in list context, this method returns a list whose first
567             element is the data and the second element is the error message,
568             if any. If C<$error_msg> is defined, there was a problem parsing
569             the JSON string, and C<$data> will be undef. You may also pass a
570             second argument to C that is a reference to a hash of
571             options -- see C.
572              
573             my $data = from_json($json_str)
574            
575             my ($data, $error_msg) = from_json($json_str)
576              
577              
578             Aliases: fromJson, fromJSON, jsonToObj
579              
580             =cut
581              
582             sub from_json {
583 60     60 1 21692 my $proto = shift;
584 60         89 my $json;
585             my $self;
586              
587 60 100       287 if (UNIVERSAL::isa($proto, 'JSON::DWIW')) {
588 58         115 $json = shift;
589 58         78 my $options = shift;
590 58 100       124 if ($options) {
591 4 50 33     18 if (ref($proto) and $proto->isa('HASH')) {
592 0 0       0 if (UNIVERSAL::isa($options, 'HASH')) {
593 0         0 $options = { %$proto, %$options };
594             }
595             }
596              
597 4         17 $self = $proto->new($options, @_);
598             }
599             else {
600 54 100       335 $self = ref($proto) ? $proto : $proto->new(@_);
601             }
602             }
603             else {
604 2         4 $json = $proto;
605 2         9 $self = JSON::DWIW->new(@_);
606             }
607              
608 60         77 my $data;
609 60 100       192 if (%$self) {
610 18         663 $data = JSON::DWIW::deserialize($json, $self);
611             }
612             else {
613 42         2313 $data = JSON::DWIW::deserialize($json);
614             }
615              
616 56         397 $self->{last_error} = $JSON::DWIW::LastError;
617 56         100 $self->{last_error_data} = $JSON::DWIW::LastErrorData;
618 56         88 $self->{last_stats} = $JSON::DWIW::Last_Stats;
619              
620 56 50 66     227 if (defined($JSON::DWIW::LastError) and $self->{use_exceptions}) {
621 0         0 die $JSON::DWIW::LastError;
622             }
623              
624 56 100       325 return wantarray ? ($data, $JSON::DWIW::LastError) : $data;
625             }
626              
627             {
628 36     36   616 no warnings 'once';
  36         75  
  36         109771  
629             *jsonToObj = \&from_json;
630             *fromJson = \&from_json;
631             *fromJSON = \&from_json;
632             }
633              
634             =pod
635              
636             =head2 C
637              
638             Similar to C, except that it expects to be
639             called a a method, and it also returns the error, if any, when called
640             in list context.
641              
642             my ($data, $error_msg) = $json->from_json_file($file, \%options)
643              
644             =cut
645             sub from_json_file {
646 22     22 1 4552 my $proto = shift;
647 22         31 my $file;
648             my $self;
649            
650 22 50       94 if (UNIVERSAL::isa($proto, 'JSON::DWIW')) {
651 22         29 $file = shift;
652 22         27 my $options = shift;
653 22 50       36 if ($options) {
654 0 0 0     0 if (ref($proto) and $proto->isa('HASH')) {
655 0 0       0 if (UNIVERSAL::isa($options, 'HASH')) {
656 0         0 $options = { %$proto, %$options };
657             }
658             }
659              
660 0         0 $self = $proto->new($options, @_);
661             }
662             else {
663 22 100       73 $self = ref($proto) ? $proto : $proto->new(@_);
664             }
665             }
666             else {
667 0         0 $file = $proto;
668 0         0 $self = JSON::DWIW->new(@_);
669             }
670              
671 22         24 my $data;
672 22 50       47 if (%$self) {
673 0         0 $data = JSON::DWIW::deserialize_file($file, $self);
674             }
675             else {
676 22         2030 $data = JSON::DWIW::deserialize_file($file);
677             }
678              
679 22         915 $self->{last_error} = $JSON::DWIW::LastError;
680 22         37 $self->{last_error_data} = $JSON::DWIW::LastErrorData;
681 22         28 $self->{last_stats} = $JSON::DWIW::Last_Stats;
682              
683 22 50 66     99 if (defined($JSON::DWIW::LastError) and $self->{use_exceptions}) {
684 0         0 die $JSON::DWIW::LastError;
685             }
686              
687 22 100       144 return wantarray ? ($data, $JSON::DWIW::LastError) : $data;
688             }
689              
690             =pod
691              
692             =head2 C
693              
694             Converts C<$data> to JSON and writes the result to the file C<$file>.
695             Currently, this is simply a convenience routine that converts
696             the data to a JSON string and then writes it to the file.
697              
698             my ($ok, $error) = $json->to_json_file($data, $file, \%options);
699              
700             =cut
701             sub to_json_file {
702 0     0 1 0 my $proto = shift;
703 0         0 my $file;
704             my $data;
705 0         0 my $self;
706            
707 0 0       0 if (UNIVERSAL::isa($proto, 'JSON::DWIW')) {
708 0         0 $data = shift;
709 0         0 $file = shift;
710 0         0 my $options = shift;
711 0 0       0 if ($options) {
712 0 0 0     0 if (ref($proto) and $proto->isa('HASH')) {
713 0 0       0 if (UNIVERSAL::isa($options, 'HASH')) {
714 0         0 $options = { %$proto, %$options };
715             }
716             }
717              
718 0         0 $self = $proto->new($options, @_);
719             }
720             else {
721 0 0       0 $self = ref($proto) ? $proto : $proto->new(@_);
722             }
723             }
724             else {
725 0         0 $data = $proto;
726 0         0 $file = shift;
727 0         0 $self = JSON::DWIW->new(@_);
728             }
729              
730 0         0 my $out_fh;
731 0 0       0 unless (open($out_fh, '>', $file)) {
732 0         0 my $msg = "JSON::DWIW v$VERSION - couldn't open output file $file";
733 0 0       0 if ($self->{use_exceptions}) {
734 0         0 die $msg;
735             } else {
736 0 0       0 return wantarray ? ( undef, $msg ) : undef;
737             }
738             }
739              
740 0 0       0 if ($] >= 5.008) {
741 0         0 binmode($out_fh, 'utf8');
742             }
743              
744 0         0 my $error_msg;
745             my $error_data;
746 0         0 my $stats_data = { };
747 0         0 my $str = _xs_to_json($self, $data, \$error_msg, \$error_data, $stats_data);
748              
749 0 0       0 if ($stats_data) {
750 0         0 $JSON::DWIW::Last_Stats = $stats_data;
751 0         0 $self->{last_stats} = $stats_data;
752             }
753              
754 0         0 $JSON::DWIW::LastError = $error_msg;
755 0         0 $self->{last_error} = $error_msg;
756              
757 0         0 $JSON::DWIW::LastErrorData = $error_data;
758 0         0 $self->{last_error_data} = $error_data;
759              
760              
761 0 0 0     0 if (defined($error_msg) and $self->{use_exceptions}) {
762 0         0 die $error_msg;
763             }
764              
765 0 0       0 if ($error_msg) {
766 0 0       0 return wantarray ? (undef, $error_msg) : undef;
767             }
768              
769 0         0 print $out_fh $str;
770 0         0 close $out_fh;
771              
772 0 0       0 return wantarray ? (1, $error_msg) : 1;
773             }
774              
775             sub parse_mmap_file {
776 0     0 0 0 my $proto = shift;
777 0         0 my $file = shift;
778              
779 0         0 my $error_msg;
780 0         0 my $self = $proto->new;
781              
782 0         0 my $data = _parse_mmap_file($self, $file, \$error_msg);
783 0 0       0 if ($error_msg) {
784 0 0       0 return wantarray ? (undef, $error_msg) : undef;
785             }
786             }
787              
788             =pod
789              
790             =head2 C
791              
792             Returns the error message from the last call, if there was one, e.g.,
793              
794             my $data = JSON::DWIW->from_json($json_str)
795             or die "JSON error: " . JSON::DWIW->get_error_string;
796            
797             my $data = $json_obj->from_json($json_str)
798             or die "JSON error: " . $json_obj->get_error_string;
799              
800              
801             Aliases: get_err_str(), errstr()
802              
803             =cut
804             sub get_error_string {
805 53     53 1 17985 my $self = shift;
806              
807 53 100       142 if (ref($self)) {
808 2         13 return $self->{last_error};
809             }
810            
811 51         183 return $JSON::DWIW::LastError;
812             }
813             *get_err_str = \&get_error_string;
814             *errstr = \&get_error_string;
815              
816             =pod
817              
818             =head2 C
819              
820             Returns the error details from the last call, in a hash ref, e.g.,
821              
822             $error_data = {
823             'byte' => 23,
824             'byte_col' => 23,
825             'col' => 22,
826             'char' => 22,
827             'version' => '0.15a',
828             'line' => 1
829             };
830              
831             This is really only useful when decoding JSON.
832              
833             Aliases: get_error(), error()
834              
835             =cut
836             sub get_error_data {
837 0     0 1 0 my $self = shift;
838              
839 0 0       0 if (ref($self)) {
840 0         0 return $self->{last_error_data};
841             }
842              
843 0         0 return $JSON::DWIW::LastErrorData;
844             }
845             *get_error = \&get_error_data;
846             *error = \&get_error_data;
847              
848             =pod
849              
850             =head2 C
851              
852             Returns statistics from the last method called to encode or
853             decode. E.g., for an encoding (C or C),
854              
855             $stats = {
856             'bytes' => 78,
857             'nulls' => 1,
858             'max_string_bytes' => 5,
859             'max_depth' => 2,
860             'arrays' => 1,
861             'numbers' => 6,
862             'lines' => 1,
863             'max_string_chars' => 5,
864             'strings' => 6,
865             'bools' => 1,
866             'chars' => 78,
867             'hashes' => 1
868             };
869              
870             =cut
871             sub get_stats {
872 11     11 1 5237 my $self = shift;
873 11 50       43 if (ref($self)) {
874 0         0 return $self->{last_stats};
875             }
876              
877 11         34 return $JSON::DWIW::Last_Stats;
878             }
879             *stats = \&get_stats;
880              
881              
882             =pod
883              
884             =head2 C
885              
886             Returns an object that will get output as a true value when encoding to JSON.
887              
888             =cut
889              
890             sub true {
891 1     1 1 184 return JSON::DWIW::Boolean->true;
892             }
893              
894             =pod
895              
896             =head2 C
897              
898             Returns an object that will get output as a false value when encoding to JSON.
899              
900             =cut
901              
902             sub false {
903 1     1 1 174 return JSON::DWIW::Boolean->false;
904             }
905              
906             sub _escape_xml_body {
907 52     52   45 my ($text) = @_;
908 52 50       83 return undef unless defined $text;
909              
910             # FIXME: benchmark this and test fully
911             # $text =~ s/([&<>"'])/$Escape_Map->{$1}/eg;
912             # return $text;
913            
914 52         87 $text =~ s/\&/\&/g;
915 52         53 $text =~ s/
916 52         56 $text =~ s/>/\>/g;
917              
918 52         132 return $text;
919             }
920              
921             sub _escape_xml_attr {
922 0     0   0 my ($text) = @_;
923 0 0       0 return undef unless defined $text;
924              
925             # FIXME: benchmark this and test fully
926             # $text =~ s/([&<>"'])/$Escape_Map->{$1}/eg;
927             # return $text;
928            
929 0         0 $text =~ s/\&/\&/g;
930 0         0 $text =~ s/
931 0         0 $text =~ s/>/\>/g;
932 0         0 $text =~ s/\"/\"/g;
933              
934 0         0 return $text;
935             }
936              
937             sub _to_xml {
938 78     78   98 my ($data, $level, $params, $parent_tag) = @_;
939              
940 78 50       122 return '' unless defined $data;
941            
942 78 100 66     291 $params = { } unless $params and UNIVERSAL::isa($params, 'HASH');
943 78   100     115 $level ||= 0;
944            
945 78         69 my $xml = '';
946              
947 78         77 my $ref = ref($data);
948              
949 78 100       106 unless ($ref) {
950             # string
951 52         66 return _escape_xml_body($data);
952             }
953              
954 26 50       43 my $indent = $params->{pretty} ? (' ' x $level) : '';
955 26 50       36 my $nl = $params->{pretty} ? "\n" : '';
956 26 50 33     54 my $start = ($params->{pretty} and $level) ? "\n" : '';
957 26 50 33     47 my $end = ($params->{pretty} and $level >= 2) ? (' ' x ($level - 1)) : '';
958 26         23 my $first = 1;
959              
960 26 100       46 if ($ref eq 'ARRAY') {
    50          
961 10         19 foreach my $e (@$data) {
962 31         54 $xml .= "$start$indent<$parent_tag>";
963 31         62 $xml .= _to_xml($e, $level + 1, $params, $parent_tag);
964 31         70 $xml .= "$nl$end";
965             }
966             continue {
967 31         50 $first = 0;
968             }
969              
970 10         24 return $xml;
971             }
972             elsif ($ref eq 'HASH') {
973 16         55 foreach my $k (sort keys %$data) {
974 42 100       75 $start = '' unless $first;
975 42         104 (my $tag = $k) =~ s/[^\w-]/_/g;
976 42         78 my $this_ref = ref($data->{$k});
977 42 100 100     107 if ($this_ref and $this_ref eq 'ARRAY') {
978 10         22 $xml .= _to_xml($data->{$k}, $level, $params, $tag);
979 10         14 next;
980             }
981            
982 32         54 $xml .= "$start$indent<$tag>";
983 32         74 $xml .= _to_xml($data->{$k}, $level + 1, $params, $tag);
984 32         71 $xml .= "$nl$end";
985             }
986             continue {
987 42         65 $first = 0;
988             }
989              
990 16         61 return $xml;
991             }
992             else {
993             # make sure objects are stringified, e.g., Math::BigInt
994 0         0 return _escape_xml_body($data . '');
995             }
996              
997 0         0 return $xml;
998             }
999              
1000             sub _data_to_xml {
1001 5     5   7 my ($data, $params) = @_;
1002            
1003 5         10 return _to_xml($data, 0, $params);
1004             }
1005              
1006              
1007             =pod
1008              
1009             =head2 C
1010              
1011             This function (not a method) converts the given JSON to XML.
1012             Hash/object keys become tag names. Arrays that are hash values
1013             are output as multiple tags with the hash key as the tag name.
1014              
1015             Any characters in hash keys not in C<[\w-]> (i.e., letters, numbers,
1016             underscore, or dash), get converted to underscore ("_") when
1017             output as XML tags.
1018              
1019             Valid parameters in C<\%params> are the same as for passing
1020             to C or C, plus the C option, which
1021             will add newlines and indentation to the XML to make it more
1022             human-readable.
1023              
1024             =cut
1025             sub json_to_xml {
1026 5     5 1 1100 my ($json, $params) = @_;
1027              
1028 5         5 my $data;
1029 5 50       10 if ($params) {
1030 0         0 $data = JSON::DWIW::deserialize($json, $params);
1031             }
1032             else {
1033 5         287 $data = JSON::DWIW::deserialize($json);
1034             }
1035              
1036 5         17 my $ref = ref($data);
1037 5 50 33     24 if ($ref and $ref eq 'ARRAY') {
1038 0         0 warn "top level of data must be an object/hash ref in json_to_xml() call";
1039 0         0 return undef;
1040             }
1041              
1042 5         14 return _data_to_xml($data, $params);
1043             }
1044              
1045             sub jsonml_to_xml {
1046 0     0 0   my ($jsonml) = @_;
1047              
1048 0           my $elements = JSON::DWIW::deserialize($jsonml);
1049 0 0         return undef unless defined $elements;
1050              
1051 0           return _jsonml_xml($elements);
1052             }
1053              
1054             sub _jsonml_xml {
1055 0     0     my ($elements) = @_;
1056              
1057 0 0         unless (ref($elements)) {
1058             # string
1059 0           return _escape_xml_body($elements);
1060             }
1061              
1062 0           my $name = $elements->[0];
1063 0           my $attrs = $elements->[1];
1064 0           my $attr_str = '';
1065              
1066 0           my @rest;
1067 0 0 0       if (defined $attrs and UNIVERSAL::isa($attrs, 'HASH')) {
1068 0           my @keys = sort keys %$attrs;
1069 0           my @pairs = map { qq{$_="} . _escape_xml_attr($attrs->{$_}) . qq{"} } @keys;
  0            
1070 0           $attr_str = ' ' . join(' ', @pairs);
1071 0           @rest = @$elements[2 .. $#$elements];
1072             }
1073             else {
1074 0           $attrs = undef;
1075 0           @rest = @$elements[1 .. $#$elements];
1076             }
1077            
1078 0           my $xml = "<$name$attr_str";
1079              
1080 0 0         if (@rest) {
1081 0           $xml .= '>';
1082 0           foreach my $e (@rest) {
1083 0           $xml .= _jsonml_xml($e);
1084             }
1085 0           $xml .= "";
1086             }
1087             else {
1088 0           $xml .= '/>';
1089             }
1090              
1091 0           return $xml;
1092             }
1093              
1094             # used from XS code to sort keys in Perl < 5.8.0 where we don't have
1095             # access to sortsv() from XS
1096             sub _sort_keys {
1097 0     0     return [ sort keys %{ $_[0] } ]
  0            
1098             }
1099              
1100              
1101             =pod
1102              
1103             =head1 Utilities
1104              
1105             Following are some methods I use for debugging and testing.
1106              
1107             =head2 C
1108              
1109             Returns true if the given string is flagged as utf-8.
1110              
1111             =head2 C
1112              
1113             Flags the given string as utf-8.
1114              
1115             =head2 C
1116              
1117             Clears the flag that tells Perl the string is utf-8.
1118              
1119             =head2 C
1120              
1121             Returns true if the given string is valid utf-8 (regardless of the flag).
1122              
1123             =head2 C
1124              
1125             Converts the string to utf-8, assuming it is latin1. This effects $str itself in place, but also returns $str.
1126              
1127             =head2 C
1128              
1129             Returns a utf8 string containing the byte sequence for the given code point.
1130              
1131             =head2 C
1132              
1133             Returns a string representing the byte sequence for $cp encoding in utf-8. E.g.,
1134              
1135             my $hex_bytes = JSON::DWIW->code_point_to_hex_bytes(0xe9);
1136             print "$hex_bytes\n"; # \xc3\xa9
1137              
1138             =head2 C
1139              
1140             Returns a reference to an array of code points from the given string, assuming the string is encoded in utf-8.
1141              
1142             =head2 C
1143              
1144             Dumps the internal structure of the given scalar.
1145              
1146             =head1 BENCHMARKS
1147              
1148             Need new benchmarks here.
1149              
1150             =head1 DEPENDENCIES
1151              
1152             Perl 5.6 or later
1153              
1154             =head1 BUGS/LIMITATIONS
1155              
1156             If you find a bug, please file a tracker request at
1157             L.
1158              
1159             When decoding a JSON string, it is a assumed to be utf-8 encoded.
1160             The module should detect whether the input is utf-8, utf-16, or
1161             utf-32.
1162              
1163             =head1 AUTHOR
1164              
1165             Don Owens
1166              
1167             =head1 ACKNOWLEDGEMENTS
1168              
1169             Thanks to Asher Blum for help with testing.
1170              
1171             Thanks to Nigel Bowden for helping with compilation on Windows.
1172              
1173             Thanks to Robert Peters for discovering and tracking down the source of a number parsing bug.
1174              
1175             Thanks to Mark Phillips for helping with a bug under Solaris on Sparc.
1176              
1177             Thanks to Josh for helping debug [rt.cpan.org #47344].
1178              
1179             =head1 LICENSE AND COPYRIGHT
1180              
1181             Copyright (c) 2007-2010 Don Owens . All rights reserved.
1182              
1183             This is free software; you can redistribute it and/or modify it
1184             under the same terms as Perl itself. See perlartistic.
1185              
1186             This program is distributed in the hope that it will be
1187             useful, but WITHOUT ANY WARRANTY; without even the implied
1188             warranty of MERCHANTABILITY or FITNESS FOR A PARTICULAR
1189             PURPOSE.
1190              
1191             =head1 SEE ALSO
1192              
1193             =over 4
1194              
1195             =item The JSON home page: L
1196              
1197             =item The JSON spec: L
1198              
1199             =item The JSON-RPC spec: L
1200              
1201             =item L
1202              
1203             =item L (included in L)
1204              
1205             =back
1206              
1207             =cut
1208              
1209             1;
1210              
1211             # Local Variables: #
1212             # mode: perl #
1213             # tab-width: 4 #
1214             # indent-tabs-mode: nil #
1215             # cperl-indent-level: 4 #
1216             # perl-indent-level: 4 #
1217             # End: #
1218             # vim:set ai si et sta ts=4 sw=4 sts=4: