]> git.evergreen-ils.org Git - Evergreen.git/blob - OpenSRF/src/perlmods/JSON.pm
removing computed regexes and commenting out unused code
[Evergreen.git] / OpenSRF / src / perlmods / JSON.pm
1 package JSON::object_unknown;
2
3 package JSON::number;
4 sub new {
5         my $class = shift;
6         my $x = shift || $class;
7         return bless \$x => __PACKAGE__;
8 }
9 use overload ( '""' => \&toString );
10 use overload ( '0+' => sub { $_[0]->toString } );
11 use overload ( '+' => sub { int($_[0]) + int($_[1]) } );
12 use overload ( '-' => sub { int($_[0]) - int($_[1]) } );
13 use overload ( '*' => sub { int($_[0]) * int($_[1]) } );
14 use overload ( '/' => sub { int($_[0]) / int($_[1]) } );
15 use overload ( '%' => sub { int($_[0]) % int($_[1]) } );
16 use overload ( '**' => sub { int($_[0]) ** int($_[1]) } );
17 use overload ( 'neg' => sub { -int($_[0]) } );
18
19 sub toString { defined($_[1]) ? ${$_[1]} : ${$_[0]} }
20
21 package JSON::bool::true;
22 sub new { return bless {} => __PACKAGE__ }
23 use overload ( '""' => \&toString );
24 use overload ( 'bool' => sub { 1 } );
25 use overload ( '0+' => sub { 1 } );
26
27 sub toString { 'true' }
28
29 package JSON::bool::false;
30 sub new { return bless {} => __PACKAGE__ }
31 use overload ( '""' => \&toString );
32 use overload ( 'bool' => sub { 0 } );
33 use overload ( '0+' => sub { 0 } );
34
35 sub toString { 'false' }
36
37 package JSON;
38 use vars qw/%_class_map/;
39
40 sub register_class_hint {
41         my $class = shift;
42         my %args = @_;
43
44         $_class_map{hints}{$args{hint}} = \%args;
45         $_class_map{classes}{$args{name}} = \%args;
46 }
47 JSON->register_class_hint(
48         name => 'JSON::object_unknown',
49         hint => 'DUNNO',
50         type => 'hash',
51 );
52
53 sub _JSON_regex {
54         my $string = shift;
55
56         $string =~ s/^\s* ( 
57                            {                            | # start object
58                            \[                           | # start array
59                            -?\d+\.?\d*                  | # number literal
60                            "(?:(?:\\[\"])|[^\"])*"      | # string literal
61                            (?:\/\*.+?\*\/)              | # C comment
62                            true                         | # bool true
63                            false                        | # bool false
64                            null                         | # undef()
65                            :                            | # object key-value sep
66                            ,                            | # list sep
67                            \]                           | # array end
68                            }                              # object end
69                         )
70                  \s*//sox;
71         return ($string,$1);
72 }
73
74 sub _json_hint_to_class {
75         my $hint = shift;
76         return $_class_map{hints}{$hint}{name} if (exists $_class_map{hints}{$hint});
77         return 'JSON::object_unknown';
78 }
79
80 sub JSON2perl {
81         my $class = shift;
82         local $_ = shift;
83
84         # Grab strings...
85         my @strings = /"((?:(?:\\[\"])|[^\"])*)"/sog;
86         # Replace with code...
87         s/"(?:(?:\\[\"])|[^\"])*"/ shift(\@strings) /sog;
88
89         s/:/ => /sog;
90
91         if (1) {
92                 # handle class blessings
93                 s/\/\*--\s*S\w*?\s+\S+\s*--\*\// bless(/sog;
94                 s/\/\*--\s*E\w*?\s+(\S+)\s*--\*\// => _json_hint_to_class("$1")) /sog;
95         } else {
96                 #why don't I work?!?!
97                 #my $string = $_;
98                 #for my $hint (values %{$_class_map{hints}}) {
99                 #       $string =~ s/\/\*--\s*S\w*?\s+$$hint{hint_re}\s*--\*\// bless(/sog;
100                 #       $string =~ s/\/\*--\s*E\w*?\s+$$hint{hint_re}\s*--\*\// => "$$hint{name}") /sog;
101                 #}
102                 #$_ = $string;
103                 #s/\/\*--\s*\w+\s+\S+\s*--\*\///sog;
104         }
105
106
107         s/\b(-?\d+\.?\d*)\b/ JSON::number::new($1) /sog;
108
109
110         # Change javascript stuff to perl...
111         s/null/ undef /sog;
112         s/true/ bless( {}, "JSON::bool::true") /sog;
113         s/false/ bless( {}, "JSON::bool::false") /sog;
114
115
116         my $ret;
117         return eval '$ret = '.$_;
118 }
119
120 sub old_JSON2perl {
121         my ($class, $json) = @_;
122
123         if (!defined($json)) {
124                 return undef;
125         }
126
127         #$json =~ s/\/\/.+$//gmo; # remove C++ comments
128         $json =~ s/(?<!\\)\$/\\\$/gmo; # fixup $ for later
129         $json =~ s/(?<!\\)\@/\\\@/gmo; # fixup @ for later
130
131         my @casts;
132         my $casting_depth = 0;
133         my $current_cast;
134         my $element;
135         my $output = '';
136         while (($json,$element) = _JSON_regex($json)) {
137
138                 last unless ($element);
139
140                 if ($element eq 'null') {
141                         $output .= ' undef() ';
142                         next;
143                 } elsif ($element =~ /^\/\*--\s*S\w*?\s+(\w+)\s*--\*\/$/) {
144                         my $hint = $1;
145                         if (exists $_class_map{hints}{$hint}) {
146                                 $casts[$casting_depth] = $hint;
147                                 $output .= ' bless(';
148                         }
149                         next;
150                 } elsif ($element =~ /^\/\*/) {
151                         next;
152                 } elsif ($element =~ /^\d/) {
153                         $output .= "do { JSON::number::new($element) }";
154                         next;
155                 } elsif ($element eq '{' or $element eq '[') {
156                         $casting_depth++;
157                 } elsif ($element eq '}' or $element eq ']') {
158                         $casting_depth--;
159                         my $hint = $casts[$casting_depth];
160                         $casts[$casting_depth] = undef;
161                         if (defined $hint and exists $_class_map{hints}{$hint}) {
162                                 $output .= $element . ',"'. $_class_map{hints}{$hint}{name} . '")';
163                                 next;
164                         }
165                 } elsif ($element eq ':') {
166                         $output .= ' => ';
167                         next;
168                 } elsif ($element eq 'true') {
169                         $output .= 'bless( {}, "JSON::bool::true")';
170                         next;
171                 } elsif ($element eq 'false') {
172                         $output .= 'bless( {}, "JSON::bool::false")';
173                         next;
174                 }
175                 
176                 $output .= $element;
177         }
178
179         return eval $output;
180 }
181
182 sub perl2JSON {
183         my ($class, $perl) = @_;
184
185         my $output = '';
186         if (!defined($perl)) {
187                 $output = 'null';
188         } elsif (ref($perl) and ref($perl) =~ /^JSON/) {
189                 $output .= $perl;
190         } elsif ( ref($perl) && exists($_class_map{classes}{ref($perl)}) ) {
191                 $output .= '/*--S '.$_class_map{classes}{ref($perl)}{hint}.'--*/';
192                 if (lc($_class_map{classes}{ref($perl)}{type}) eq 'hash') {
193                         my %hash =  %$perl;
194                         $output .= perl2JSON(undef,\%hash);
195                 } elsif (lc($_class_map{classes}{ref($perl)}{type}) eq 'array') {
196                         my @array =  @$perl;
197                         $output .= perl2JSON(undef,\@array);
198                 }
199                 $output .= '/*--E '.$_class_map{classes}{ref($perl)}{hint}.'--*/';
200         } elsif (ref($perl) and ref($perl) =~ /HASH/) {
201                 $output .= '{';
202                 my $c = 0;
203                 for my $key (sort keys %$perl) {
204                         $output .= ',' if ($c); 
205                         
206                         $output .= perl2JSON(undef,$key).':'.perl2JSON(undef,$$perl{$key});
207                         $c++;
208                 }
209                 $output .= '}';
210         } elsif (ref($perl) and ref($perl) =~ /ARRAY/) {
211                 $output .= '[';
212                 my $c = 0;
213                 for my $part (@$perl) {
214                         $output .= ',' if ($c); 
215                         
216                         $output .= perl2JSON(undef,$part);
217                         $c++;
218                 }
219                 $output .= ']';
220         } else {
221                 $perl =~ s/\\/\\\\/sgo;
222                 $perl =~ s/"/\\"/sgo;
223                 $perl =~ s/\t/\\t/sgo;
224                 $perl =~ s/\f/\\f/sgo;
225                 $perl =~ s/\r/\\r/sgo;
226                 $perl =~ s/\n/\\n/sgo;
227                 $output = '"'.$perl.'"';
228         }
229
230         return $output;
231 }
232
233 my $depth = 0;
234 sub perl2prettyJSON {
235         my ($class, $perl, $nospace) = @_;
236         $perl ||= $class;
237
238         my $output = '';
239         if (!defined($perl)) {
240                 $output = 'null';
241         } elsif (ref($perl) and ref($perl) =~ /^JSON/) {
242                 $output .= $perl;
243         } elsif ( ref($perl) && exists($_class_map{classes}{ref($perl)}) ) {
244                 $depth++;
245                 $output .= "\n";
246                 $output .= "   "x$depth;
247                 $output .= '/*--S '.$_class_map{classes}{ref($perl)}{hint}."--*/ ";
248                 if (lc($_class_map{classes}{ref($perl)}{type}) eq 'hash') {
249                         my %hash =  %$perl;
250                         $output .= perl2prettyJSON(\%hash,undef,1);
251                 } elsif (lc($_class_map{classes}{ref($perl)}{type}) eq 'array') {
252                         my @array =  @$perl;
253                         $output .= perl2prettyJSON(\@array,undef,1);
254                 }
255                 #$output .= "   "x$depth;
256                 $output .= ' /*--E '.$_class_map{classes}{ref($perl)}{hint}.'--*/';
257                 $depth--;
258         } elsif (ref($perl) and ref($perl) =~ /HASH/) {
259                 #$depth++;
260                 $output .= "   "x$depth unless ($nospace);
261                 $output .= "{\n";
262                 my $c = 0;
263                 $depth++;
264                 for my $key (sort keys %$perl) {
265                         $output .= ",\n" if ($c); 
266                         
267                         $output .= perl2prettyJSON($key)." : ".perl2prettyJSON($$perl{$key}, undef, 1);
268                         $c++;
269                 }
270                 $depth--;
271                 $output .= "\n";
272                 $output .= "   "x$depth;
273                 $output .= '}';
274                 #$depth--;
275         } elsif (ref($perl) and ref($perl) =~ /ARRAY/) {
276                 #$depth++;
277                 $output .= "   "x$depth unless ($nospace);
278                 $output .= "[\n";
279                 my $c = 0;
280                 $depth++;
281                 for my $part (@$perl) {
282                         $output .= ",\n" if ($c); 
283                         
284                         $output .= perl2prettyJSON($part);
285                         $c++;
286                 }
287                 $depth--;
288                 $output .= "\n";
289                 $output .= "   "x$depth;
290                 $output .= "]";
291                 #$depth--;
292         } else {
293                 $perl =~ s/\\/\\\\/sgo;
294                 $perl =~ s/"/\\"/sgo;
295                 $perl =~ s/\t/\\t/sgo;
296                 $perl =~ s/\f/\\f/sgo;
297                 $perl =~ s/\r/\\r/sgo;
298                 $perl =~ s/\n/\\n/sgo;
299                 $output .= "   "x$depth unless($nospace);
300                 $output .= '"'.$perl.'"';
301         }
302
303         return $output;
304 }
305
306 1;