json 1.2.0 → 1.2.1
Sign up to get free protection for your applications and to get access to all the features.
Potentially problematic release.
This version of json might be problematic. Click here for more details.
- data/CHANGES +3 -0
- data/README +3 -3
- data/Rakefile +4 -4
- data/VERSION +1 -1
- data/benchmarks/parser_benchmark.rb +14 -0
- data/ext/json/ext/parser/parser.c +103 -84
- data/ext/json/ext/parser/parser.rl +29 -10
- data/lib/json/add/core.rb +20 -7
- data/lib/json/add/rails.rb +2 -2
- data/lib/json/common.rb +5 -0
- data/lib/json/pure/parser.rb +5 -1
- data/lib/json/version.rb +1 -1
- data/tests/test_json.rb +7 -0
- metadata +3 -3
data/CHANGES
CHANGED
@@ -1,3 +1,6 @@
|
|
1
|
+
2009-11-25 (1.2.1)
|
2
|
+
* added :symbolize_names option to Parser, which returns symbols instead of
|
3
|
+
strings in object names/keys.
|
1
4
|
2009-10-01 (1.2.0)
|
2
5
|
* fast_generate now raises an exeception for nan and infinite floats.
|
3
6
|
* On Ruby 1.8 json supports parsing of UTF-8, UTF-16BE, UTF-16LE, UTF-32BE,
|
data/README
CHANGED
@@ -3,7 +3,7 @@
|
|
3
3
|
=== Description
|
4
4
|
|
5
5
|
This is a implementation of the JSON specification according to RFC 4627
|
6
|
-
|
6
|
+
http://www.ietf.org/rfc/rfc4627.txt . Starting from version 1.0.0 on there
|
7
7
|
will be two variants available:
|
8
8
|
|
9
9
|
* A pure ruby variant, that relies on the iconv and the stringscan
|
@@ -11,7 +11,7 @@ will be two variants available:
|
|
11
11
|
* The quite a bit faster C extension variant, which is in parts implemented
|
12
12
|
in C and comes with its own unicode conversion functions and a parser
|
13
13
|
generated by the ragel state machine compiler
|
14
|
-
|
14
|
+
http://www.cs.queensu.ca/~thurston/ragel .
|
15
15
|
|
16
16
|
Both variants of the JSON generator escape all non-ASCII and control characters
|
17
17
|
with \uXXXX escape sequences, and support UTF-16 surrogate pairs in order to be
|
@@ -224,7 +224,7 @@ the pp library's pp methods.
|
|
224
224
|
|
225
225
|
The script tools/server.rb contains a small example if you want to test, how
|
226
226
|
receiving a JSON object from a webrick server in your browser with the
|
227
|
-
javasript prototype library
|
227
|
+
javasript prototype library http://www.prototypejs.org works.
|
228
228
|
|
229
229
|
=== Speed Comparisons
|
230
230
|
|
data/Rakefile
CHANGED
@@ -197,7 +197,7 @@ if defined?(Gem) and defined?(Rake::GemPackageTask) and defined?(Rake::Extension
|
|
197
197
|
|
198
198
|
s.author = "Florian Frank"
|
199
199
|
s.email = "flori@ping.de"
|
200
|
-
s.homepage = "http://
|
200
|
+
s.homepage = "http://flori.github.com/#{PKG_NAME}"
|
201
201
|
s.rubyforge_project = "json"
|
202
202
|
end
|
203
203
|
|
@@ -232,7 +232,7 @@ if defined?(Gem) and defined?(Rake::GemPackageTask) and defined?(Rake::Extension
|
|
232
232
|
|
233
233
|
s.author = "Florian Frank"
|
234
234
|
s.email = "flori@ping.de"
|
235
|
-
s.homepage = "http://
|
235
|
+
s.homepage = "http://flori.github.com/#{PKG_NAME}"
|
236
236
|
s.rubyforge_project = "json"
|
237
237
|
end
|
238
238
|
|
@@ -245,7 +245,7 @@ if defined?(Gem) and defined?(Rake::GemPackageTask) and defined?(Rake::Extension
|
|
245
245
|
ext.name = 'parser'
|
246
246
|
ext.gem_spec = spec_ext
|
247
247
|
ext.cross_compile = true
|
248
|
-
ext.cross_platform =
|
248
|
+
ext.cross_platform = %w[i386-mswin32 i386-mingw32]
|
249
249
|
ext.ext_dir = 'ext/json/ext/parser'
|
250
250
|
ext.lib_dir = 'lib/json/ext'
|
251
251
|
end
|
@@ -254,7 +254,7 @@ if defined?(Gem) and defined?(Rake::GemPackageTask) and defined?(Rake::Extension
|
|
254
254
|
ext.name = 'generator'
|
255
255
|
ext.gem_spec = spec_ext
|
256
256
|
ext.cross_compile = true
|
257
|
-
ext.cross_platform =
|
257
|
+
ext.cross_platform = %w[i386-mswin32 i386-mingw32]
|
258
258
|
ext.ext_dir = 'ext/json/ext/generator'
|
259
259
|
ext.lib_dir = 'lib/json/ext'
|
260
260
|
end
|
data/VERSION
CHANGED
@@ -1 +1 @@
|
|
1
|
-
1.2.
|
1
|
+
1.2.1
|
@@ -62,6 +62,12 @@ class ParserBenchmarkExt < Bullshit::RepeatCase
|
|
62
62
|
end
|
63
63
|
|
64
64
|
alias reset_parser generic_reset_method
|
65
|
+
|
66
|
+
def benchmark_parser_symbolic
|
67
|
+
@result = JSON.parse(@json, :symbolize_names => true)
|
68
|
+
end
|
69
|
+
|
70
|
+
alias reset_parser_symbolc generic_reset_method
|
65
71
|
end
|
66
72
|
|
67
73
|
class ParserBenchmarkPure < Bullshit::RepeatCase
|
@@ -92,6 +98,12 @@ class ParserBenchmarkPure < Bullshit::RepeatCase
|
|
92
98
|
end
|
93
99
|
|
94
100
|
alias reset_parser generic_reset_method
|
101
|
+
|
102
|
+
def benchmark_parser_symbolic
|
103
|
+
@result = JSON.parse(@json, :symbolize_names => true)
|
104
|
+
end
|
105
|
+
|
106
|
+
alias reset_parser_symbolc generic_reset_method
|
95
107
|
end
|
96
108
|
|
97
109
|
class ParserBenchmarkYAML < Bullshit::RepeatCase
|
@@ -189,7 +201,9 @@ if $0 == __FILE__
|
|
189
201
|
output_filename File.join(File.dirname(__FILE__), 'data', 'ParserBenchmarkComparison.log')
|
190
202
|
|
191
203
|
benchmark ParserBenchmarkExt, :parser, :load => yes
|
204
|
+
benchmark ParserBenchmarkExt, :parser_symbolic, :load => yes
|
192
205
|
benchmark ParserBenchmarkPure, :parser, :load => yes
|
206
|
+
benchmark ParserBenchmarkPure, :parser_symbolic, :load => yes
|
193
207
|
benchmark ParserBenchmarkYAML, :parser, :load => yes
|
194
208
|
benchmark ParserBenchmarkRails, :parser, :load => yes
|
195
209
|
end
|
@@ -33,7 +33,8 @@ static VALUE mJSON, mExt, cParser, eParserError, eNestingError;
|
|
33
33
|
static VALUE CNaN, CInfinity, CMinusInfinity;
|
34
34
|
|
35
35
|
static ID i_json_creatable_p, i_json_create, i_create_id, i_create_additions,
|
36
|
-
i_chr, i_max_nesting, i_allow_nan, i_object_class,
|
36
|
+
i_chr, i_max_nesting, i_allow_nan, i_symbolize_names, i_object_class,
|
37
|
+
i_array_class;
|
37
38
|
|
38
39
|
#define MinusInfinity "-Infinity"
|
39
40
|
|
@@ -46,6 +47,8 @@ typedef struct JSON_ParserStruct {
|
|
46
47
|
int max_nesting;
|
47
48
|
int current_nesting;
|
48
49
|
int allow_nan;
|
50
|
+
int parsing_name;
|
51
|
+
int symbolize_names;
|
49
52
|
VALUE object_class;
|
50
53
|
VALUE array_class;
|
51
54
|
} JSON_Parser;
|
@@ -62,11 +65,11 @@ static char *JSON_parse_float(JSON_Parser *json, char *p, char *pe, VALUE *resul
|
|
62
65
|
Data_Get_Struct(self, JSON_Parser, json);
|
63
66
|
|
64
67
|
|
65
|
-
#line
|
68
|
+
#line 91 "parser.rl"
|
66
69
|
|
67
70
|
|
68
71
|
|
69
|
-
#line
|
72
|
+
#line 73 "parser.c"
|
70
73
|
static const int JSON_object_start = 1;
|
71
74
|
static const int JSON_object_first_final = 27;
|
72
75
|
static const int JSON_object_error = 0;
|
@@ -74,7 +77,7 @@ static const int JSON_object_error = 0;
|
|
74
77
|
static const int JSON_object_en_main = 1;
|
75
78
|
|
76
79
|
|
77
|
-
#line
|
80
|
+
#line 126 "parser.rl"
|
78
81
|
|
79
82
|
|
80
83
|
static char *JSON_parse_object(JSON_Parser *json, char *p, char *pe, VALUE *result)
|
@@ -90,14 +93,14 @@ static char *JSON_parse_object(JSON_Parser *json, char *p, char *pe, VALUE *resu
|
|
90
93
|
*result = NIL_P(object_class) ? rb_hash_new() : rb_class_new_instance(0, 0, object_class);
|
91
94
|
|
92
95
|
|
93
|
-
#line
|
96
|
+
#line 97 "parser.c"
|
94
97
|
{
|
95
98
|
cs = JSON_object_start;
|
96
99
|
}
|
97
100
|
|
98
|
-
#line
|
101
|
+
#line 141 "parser.rl"
|
99
102
|
|
100
|
-
#line
|
103
|
+
#line 104 "parser.c"
|
101
104
|
{
|
102
105
|
if ( p == pe )
|
103
106
|
goto _test_eof;
|
@@ -125,9 +128,11 @@ case 2:
|
|
125
128
|
goto st2;
|
126
129
|
goto st0;
|
127
130
|
tr2:
|
128
|
-
#line
|
131
|
+
#line 110 "parser.rl"
|
129
132
|
{
|
133
|
+
json->parsing_name = 1;
|
130
134
|
char *np = JSON_parse_string(json, p, pe, &last_name);
|
135
|
+
json->parsing_name = 0;
|
131
136
|
if (np == NULL) { p--; {p++; cs = 3; goto _out;} } else {p = (( np))-1;}
|
132
137
|
}
|
133
138
|
goto st3;
|
@@ -135,7 +140,7 @@ st3:
|
|
135
140
|
if ( ++p == pe )
|
136
141
|
goto _test_eof3;
|
137
142
|
case 3:
|
138
|
-
#line
|
143
|
+
#line 144 "parser.c"
|
139
144
|
switch( (*p) ) {
|
140
145
|
case 13: goto st3;
|
141
146
|
case 32: goto st3;
|
@@ -202,7 +207,7 @@ case 8:
|
|
202
207
|
goto st8;
|
203
208
|
goto st0;
|
204
209
|
tr11:
|
205
|
-
#line
|
210
|
+
#line 99 "parser.rl"
|
206
211
|
{
|
207
212
|
VALUE v = Qnil;
|
208
213
|
char *np = JSON_parse_value(json, p, pe, &v);
|
@@ -218,7 +223,7 @@ st9:
|
|
218
223
|
if ( ++p == pe )
|
219
224
|
goto _test_eof9;
|
220
225
|
case 9:
|
221
|
-
#line
|
226
|
+
#line 227 "parser.c"
|
222
227
|
switch( (*p) ) {
|
223
228
|
case 13: goto st9;
|
224
229
|
case 32: goto st9;
|
@@ -307,14 +312,14 @@ case 18:
|
|
307
312
|
goto st9;
|
308
313
|
goto st18;
|
309
314
|
tr4:
|
310
|
-
#line
|
315
|
+
#line 117 "parser.rl"
|
311
316
|
{ p--; {p++; cs = 27; goto _out;} }
|
312
317
|
goto st27;
|
313
318
|
st27:
|
314
319
|
if ( ++p == pe )
|
315
320
|
goto _test_eof27;
|
316
321
|
case 27:
|
317
|
-
#line
|
322
|
+
#line 323 "parser.c"
|
318
323
|
goto st0;
|
319
324
|
st19:
|
320
325
|
if ( ++p == pe )
|
@@ -412,7 +417,7 @@ case 26:
|
|
412
417
|
_out: {}
|
413
418
|
}
|
414
419
|
|
415
|
-
#line
|
420
|
+
#line 142 "parser.rl"
|
416
421
|
|
417
422
|
if (cs >= JSON_object_first_final) {
|
418
423
|
if (RTEST(json->create_id)) {
|
@@ -431,7 +436,7 @@ case 26:
|
|
431
436
|
}
|
432
437
|
|
433
438
|
|
434
|
-
#line
|
439
|
+
#line 440 "parser.c"
|
435
440
|
static const int JSON_value_start = 1;
|
436
441
|
static const int JSON_value_first_final = 21;
|
437
442
|
static const int JSON_value_error = 0;
|
@@ -439,7 +444,7 @@ static const int JSON_value_error = 0;
|
|
439
444
|
static const int JSON_value_en_main = 1;
|
440
445
|
|
441
446
|
|
442
|
-
#line
|
447
|
+
#line 240 "parser.rl"
|
443
448
|
|
444
449
|
|
445
450
|
static char *JSON_parse_value(JSON_Parser *json, char *p, char *pe, VALUE *result)
|
@@ -447,14 +452,14 @@ static char *JSON_parse_value(JSON_Parser *json, char *p, char *pe, VALUE *resul
|
|
447
452
|
int cs = EVIL;
|
448
453
|
|
449
454
|
|
450
|
-
#line
|
455
|
+
#line 456 "parser.c"
|
451
456
|
{
|
452
457
|
cs = JSON_value_start;
|
453
458
|
}
|
454
459
|
|
455
|
-
#line
|
460
|
+
#line 247 "parser.rl"
|
456
461
|
|
457
|
-
#line
|
462
|
+
#line 463 "parser.c"
|
458
463
|
{
|
459
464
|
if ( p == pe )
|
460
465
|
goto _test_eof;
|
@@ -479,14 +484,14 @@ st0:
|
|
479
484
|
cs = 0;
|
480
485
|
goto _out;
|
481
486
|
tr0:
|
482
|
-
#line
|
487
|
+
#line 188 "parser.rl"
|
483
488
|
{
|
484
489
|
char *np = JSON_parse_string(json, p, pe, result);
|
485
490
|
if (np == NULL) { p--; {p++; cs = 21; goto _out;} } else {p = (( np))-1;}
|
486
491
|
}
|
487
492
|
goto st21;
|
488
493
|
tr2:
|
489
|
-
#line
|
494
|
+
#line 193 "parser.rl"
|
490
495
|
{
|
491
496
|
char *np;
|
492
497
|
if(pe > p + 9 && !strncmp(MinusInfinity, p, 9)) {
|
@@ -506,7 +511,7 @@ tr2:
|
|
506
511
|
}
|
507
512
|
goto st21;
|
508
513
|
tr5:
|
509
|
-
#line
|
514
|
+
#line 211 "parser.rl"
|
510
515
|
{
|
511
516
|
char *np;
|
512
517
|
json->current_nesting++;
|
@@ -516,7 +521,7 @@ tr5:
|
|
516
521
|
}
|
517
522
|
goto st21;
|
518
523
|
tr9:
|
519
|
-
#line
|
524
|
+
#line 219 "parser.rl"
|
520
525
|
{
|
521
526
|
char *np;
|
522
527
|
json->current_nesting++;
|
@@ -526,7 +531,7 @@ tr9:
|
|
526
531
|
}
|
527
532
|
goto st21;
|
528
533
|
tr16:
|
529
|
-
#line
|
534
|
+
#line 181 "parser.rl"
|
530
535
|
{
|
531
536
|
if (json->allow_nan) {
|
532
537
|
*result = CInfinity;
|
@@ -536,7 +541,7 @@ tr16:
|
|
536
541
|
}
|
537
542
|
goto st21;
|
538
543
|
tr18:
|
539
|
-
#line
|
544
|
+
#line 174 "parser.rl"
|
540
545
|
{
|
541
546
|
if (json->allow_nan) {
|
542
547
|
*result = CNaN;
|
@@ -546,19 +551,19 @@ tr18:
|
|
546
551
|
}
|
547
552
|
goto st21;
|
548
553
|
tr22:
|
549
|
-
#line
|
554
|
+
#line 168 "parser.rl"
|
550
555
|
{
|
551
556
|
*result = Qfalse;
|
552
557
|
}
|
553
558
|
goto st21;
|
554
559
|
tr25:
|
555
|
-
#line
|
560
|
+
#line 165 "parser.rl"
|
556
561
|
{
|
557
562
|
*result = Qnil;
|
558
563
|
}
|
559
564
|
goto st21;
|
560
565
|
tr28:
|
561
|
-
#line
|
566
|
+
#line 171 "parser.rl"
|
562
567
|
{
|
563
568
|
*result = Qtrue;
|
564
569
|
}
|
@@ -567,9 +572,9 @@ st21:
|
|
567
572
|
if ( ++p == pe )
|
568
573
|
goto _test_eof21;
|
569
574
|
case 21:
|
570
|
-
#line
|
575
|
+
#line 227 "parser.rl"
|
571
576
|
{ p--; {p++; cs = 21; goto _out;} }
|
572
|
-
#line
|
577
|
+
#line 578 "parser.c"
|
573
578
|
goto st0;
|
574
579
|
st2:
|
575
580
|
if ( ++p == pe )
|
@@ -730,7 +735,7 @@ case 20:
|
|
730
735
|
_out: {}
|
731
736
|
}
|
732
737
|
|
733
|
-
#line
|
738
|
+
#line 248 "parser.rl"
|
734
739
|
|
735
740
|
if (cs >= JSON_value_first_final) {
|
736
741
|
return p;
|
@@ -740,7 +745,7 @@ case 20:
|
|
740
745
|
}
|
741
746
|
|
742
747
|
|
743
|
-
#line
|
748
|
+
#line 749 "parser.c"
|
744
749
|
static const int JSON_integer_start = 1;
|
745
750
|
static const int JSON_integer_first_final = 5;
|
746
751
|
static const int JSON_integer_error = 0;
|
@@ -748,7 +753,7 @@ static const int JSON_integer_error = 0;
|
|
748
753
|
static const int JSON_integer_en_main = 1;
|
749
754
|
|
750
755
|
|
751
|
-
#line
|
756
|
+
#line 264 "parser.rl"
|
752
757
|
|
753
758
|
|
754
759
|
static char *JSON_parse_integer(JSON_Parser *json, char *p, char *pe, VALUE *result)
|
@@ -756,15 +761,15 @@ static char *JSON_parse_integer(JSON_Parser *json, char *p, char *pe, VALUE *res
|
|
756
761
|
int cs = EVIL;
|
757
762
|
|
758
763
|
|
759
|
-
#line
|
764
|
+
#line 765 "parser.c"
|
760
765
|
{
|
761
766
|
cs = JSON_integer_start;
|
762
767
|
}
|
763
768
|
|
764
|
-
#line
|
769
|
+
#line 271 "parser.rl"
|
765
770
|
json->memo = p;
|
766
771
|
|
767
|
-
#line
|
772
|
+
#line 773 "parser.c"
|
768
773
|
{
|
769
774
|
if ( p == pe )
|
770
775
|
goto _test_eof;
|
@@ -798,14 +803,14 @@ case 3:
|
|
798
803
|
goto st0;
|
799
804
|
goto tr4;
|
800
805
|
tr4:
|
801
|
-
#line
|
806
|
+
#line 261 "parser.rl"
|
802
807
|
{ p--; {p++; cs = 5; goto _out;} }
|
803
808
|
goto st5;
|
804
809
|
st5:
|
805
810
|
if ( ++p == pe )
|
806
811
|
goto _test_eof5;
|
807
812
|
case 5:
|
808
|
-
#line
|
813
|
+
#line 814 "parser.c"
|
809
814
|
goto st0;
|
810
815
|
st4:
|
811
816
|
if ( ++p == pe )
|
@@ -824,7 +829,7 @@ case 4:
|
|
824
829
|
_out: {}
|
825
830
|
}
|
826
831
|
|
827
|
-
#line
|
832
|
+
#line 273 "parser.rl"
|
828
833
|
|
829
834
|
if (cs >= JSON_integer_first_final) {
|
830
835
|
long len = p - json->memo;
|
@@ -836,7 +841,7 @@ case 4:
|
|
836
841
|
}
|
837
842
|
|
838
843
|
|
839
|
-
#line
|
844
|
+
#line 845 "parser.c"
|
840
845
|
static const int JSON_float_start = 1;
|
841
846
|
static const int JSON_float_first_final = 10;
|
842
847
|
static const int JSON_float_error = 0;
|
@@ -844,7 +849,7 @@ static const int JSON_float_error = 0;
|
|
844
849
|
static const int JSON_float_en_main = 1;
|
845
850
|
|
846
851
|
|
847
|
-
#line
|
852
|
+
#line 295 "parser.rl"
|
848
853
|
|
849
854
|
|
850
855
|
static char *JSON_parse_float(JSON_Parser *json, char *p, char *pe, VALUE *result)
|
@@ -852,15 +857,15 @@ static char *JSON_parse_float(JSON_Parser *json, char *p, char *pe, VALUE *resul
|
|
852
857
|
int cs = EVIL;
|
853
858
|
|
854
859
|
|
855
|
-
#line
|
860
|
+
#line 861 "parser.c"
|
856
861
|
{
|
857
862
|
cs = JSON_float_start;
|
858
863
|
}
|
859
864
|
|
860
|
-
#line
|
865
|
+
#line 302 "parser.rl"
|
861
866
|
json->memo = p;
|
862
867
|
|
863
|
-
#line
|
868
|
+
#line 869 "parser.c"
|
864
869
|
{
|
865
870
|
if ( p == pe )
|
866
871
|
goto _test_eof;
|
@@ -918,14 +923,14 @@ case 5:
|
|
918
923
|
goto st0;
|
919
924
|
goto tr7;
|
920
925
|
tr7:
|
921
|
-
#line
|
926
|
+
#line 289 "parser.rl"
|
922
927
|
{ p--; {p++; cs = 10; goto _out;} }
|
923
928
|
goto st10;
|
924
929
|
st10:
|
925
930
|
if ( ++p == pe )
|
926
931
|
goto _test_eof10;
|
927
932
|
case 10:
|
928
|
-
#line
|
933
|
+
#line 934 "parser.c"
|
929
934
|
goto st0;
|
930
935
|
st6:
|
931
936
|
if ( ++p == pe )
|
@@ -986,7 +991,7 @@ case 9:
|
|
986
991
|
_out: {}
|
987
992
|
}
|
988
993
|
|
989
|
-
#line
|
994
|
+
#line 304 "parser.rl"
|
990
995
|
|
991
996
|
if (cs >= JSON_float_first_final) {
|
992
997
|
long len = p - json->memo;
|
@@ -999,7 +1004,7 @@ case 9:
|
|
999
1004
|
|
1000
1005
|
|
1001
1006
|
|
1002
|
-
#line
|
1007
|
+
#line 1008 "parser.c"
|
1003
1008
|
static const int JSON_array_start = 1;
|
1004
1009
|
static const int JSON_array_first_final = 17;
|
1005
1010
|
static const int JSON_array_error = 0;
|
@@ -1007,7 +1012,7 @@ static const int JSON_array_error = 0;
|
|
1007
1012
|
static const int JSON_array_en_main = 1;
|
1008
1013
|
|
1009
1014
|
|
1010
|
-
#line
|
1015
|
+
#line 340 "parser.rl"
|
1011
1016
|
|
1012
1017
|
|
1013
1018
|
static char *JSON_parse_array(JSON_Parser *json, char *p, char *pe, VALUE *result)
|
@@ -1021,14 +1026,14 @@ static char *JSON_parse_array(JSON_Parser *json, char *p, char *pe, VALUE *resul
|
|
1021
1026
|
*result = NIL_P(array_class) ? rb_ary_new() : rb_class_new_instance(0, 0, array_class);
|
1022
1027
|
|
1023
1028
|
|
1024
|
-
#line
|
1029
|
+
#line 1030 "parser.c"
|
1025
1030
|
{
|
1026
1031
|
cs = JSON_array_start;
|
1027
1032
|
}
|
1028
1033
|
|
1029
|
-
#line
|
1034
|
+
#line 353 "parser.rl"
|
1030
1035
|
|
1031
|
-
#line
|
1036
|
+
#line 1037 "parser.c"
|
1032
1037
|
{
|
1033
1038
|
if ( p == pe )
|
1034
1039
|
goto _test_eof;
|
@@ -1067,7 +1072,7 @@ case 2:
|
|
1067
1072
|
goto st2;
|
1068
1073
|
goto st0;
|
1069
1074
|
tr2:
|
1070
|
-
#line
|
1075
|
+
#line 321 "parser.rl"
|
1071
1076
|
{
|
1072
1077
|
VALUE v = Qnil;
|
1073
1078
|
char *np = JSON_parse_value(json, p, pe, &v);
|
@@ -1083,7 +1088,7 @@ st3:
|
|
1083
1088
|
if ( ++p == pe )
|
1084
1089
|
goto _test_eof3;
|
1085
1090
|
case 3:
|
1086
|
-
#line
|
1091
|
+
#line 1092 "parser.c"
|
1087
1092
|
switch( (*p) ) {
|
1088
1093
|
case 13: goto st3;
|
1089
1094
|
case 32: goto st3;
|
@@ -1183,14 +1188,14 @@ case 12:
|
|
1183
1188
|
goto st3;
|
1184
1189
|
goto st12;
|
1185
1190
|
tr4:
|
1186
|
-
#line
|
1191
|
+
#line 332 "parser.rl"
|
1187
1192
|
{ p--; {p++; cs = 17; goto _out;} }
|
1188
1193
|
goto st17;
|
1189
1194
|
st17:
|
1190
1195
|
if ( ++p == pe )
|
1191
1196
|
goto _test_eof17;
|
1192
1197
|
case 17:
|
1193
|
-
#line
|
1198
|
+
#line 1199 "parser.c"
|
1194
1199
|
goto st0;
|
1195
1200
|
st13:
|
1196
1201
|
if ( ++p == pe )
|
@@ -1246,7 +1251,7 @@ case 16:
|
|
1246
1251
|
_out: {}
|
1247
1252
|
}
|
1248
1253
|
|
1249
|
-
#line
|
1254
|
+
#line 354 "parser.rl"
|
1250
1255
|
|
1251
1256
|
if(cs >= JSON_array_first_final) {
|
1252
1257
|
return p + 1;
|
@@ -1312,7 +1317,7 @@ static VALUE json_string_unescape(char *p, char *pe)
|
|
1312
1317
|
}
|
1313
1318
|
|
1314
1319
|
|
1315
|
-
#line
|
1320
|
+
#line 1321 "parser.c"
|
1316
1321
|
static const int JSON_string_start = 1;
|
1317
1322
|
static const int JSON_string_first_final = 8;
|
1318
1323
|
static const int JSON_string_error = 0;
|
@@ -1320,7 +1325,7 @@ static const int JSON_string_error = 0;
|
|
1320
1325
|
static const int JSON_string_en_main = 1;
|
1321
1326
|
|
1322
1327
|
|
1323
|
-
#line
|
1328
|
+
#line 438 "parser.rl"
|
1324
1329
|
|
1325
1330
|
|
1326
1331
|
static char *JSON_parse_string(JSON_Parser *json, char *p, char *pe, VALUE *result)
|
@@ -1329,15 +1334,15 @@ static char *JSON_parse_string(JSON_Parser *json, char *p, char *pe, VALUE *resu
|
|
1329
1334
|
|
1330
1335
|
*result = rb_str_new("", 0);
|
1331
1336
|
|
1332
|
-
#line
|
1337
|
+
#line 1338 "parser.c"
|
1333
1338
|
{
|
1334
1339
|
cs = JSON_string_start;
|
1335
1340
|
}
|
1336
1341
|
|
1337
|
-
#line
|
1342
|
+
#line 446 "parser.rl"
|
1338
1343
|
json->memo = p;
|
1339
1344
|
|
1340
|
-
#line
|
1345
|
+
#line 1346 "parser.c"
|
1341
1346
|
{
|
1342
1347
|
if ( p == pe )
|
1343
1348
|
goto _test_eof;
|
@@ -1362,25 +1367,25 @@ case 2:
|
|
1362
1367
|
goto st0;
|
1363
1368
|
goto st2;
|
1364
1369
|
tr2:
|
1365
|
-
#line
|
1370
|
+
#line 424 "parser.rl"
|
1366
1371
|
{
|
1367
|
-
|
1368
|
-
|
1369
|
-
|
1370
|
-
|
1371
|
-
|
1372
|
-
|
1373
|
-
|
1374
|
-
|
1375
|
-
|
1376
|
-
#line
|
1372
|
+
*result = json_string_unescape(json->memo + 1, p);
|
1373
|
+
if (NIL_P(*result)) {
|
1374
|
+
p--;
|
1375
|
+
{p++; cs = 8; goto _out;}
|
1376
|
+
} else {
|
1377
|
+
FORCE_UTF8(*result);
|
1378
|
+
{p = (( p + 1))-1;}
|
1379
|
+
}
|
1380
|
+
}
|
1381
|
+
#line 435 "parser.rl"
|
1377
1382
|
{ p--; {p++; cs = 8; goto _out;} }
|
1378
1383
|
goto st8;
|
1379
1384
|
st8:
|
1380
1385
|
if ( ++p == pe )
|
1381
1386
|
goto _test_eof8;
|
1382
1387
|
case 8:
|
1383
|
-
#line
|
1388
|
+
#line 1389 "parser.c"
|
1384
1389
|
goto st0;
|
1385
1390
|
st3:
|
1386
1391
|
if ( ++p == pe )
|
@@ -1456,8 +1461,11 @@ case 7:
|
|
1456
1461
|
_out: {}
|
1457
1462
|
}
|
1458
1463
|
|
1459
|
-
#line
|
1464
|
+
#line 448 "parser.rl"
|
1460
1465
|
|
1466
|
+
if (json->symbolize_names && json->parsing_name) {
|
1467
|
+
*result = rb_str_intern(*result);
|
1468
|
+
}
|
1461
1469
|
if (cs >= JSON_string_first_final) {
|
1462
1470
|
return p + 1;
|
1463
1471
|
} else {
|
@@ -1467,7 +1475,7 @@ case 7:
|
|
1467
1475
|
|
1468
1476
|
|
1469
1477
|
|
1470
|
-
#line
|
1478
|
+
#line 1479 "parser.c"
|
1471
1479
|
static const int JSON_start = 1;
|
1472
1480
|
static const int JSON_first_final = 10;
|
1473
1481
|
static const int JSON_error = 0;
|
@@ -1475,7 +1483,7 @@ static const int JSON_error = 0;
|
|
1475
1483
|
static const int JSON_en_main = 1;
|
1476
1484
|
|
1477
1485
|
|
1478
|
-
#line
|
1486
|
+
#line 485 "parser.rl"
|
1479
1487
|
|
1480
1488
|
|
1481
1489
|
/*
|
@@ -1555,6 +1563,9 @@ inline static VALUE convert_encoding(VALUE source)
|
|
1555
1563
|
* * *allow_nan*: If set to true, allow NaN, Infinity and -Infinity in
|
1556
1564
|
* defiance of RFC 4627 to be parsed by the Parser. This option defaults to
|
1557
1565
|
* false.
|
1566
|
+
* * *symbolize_names*: If set to true, returns symbols for the names
|
1567
|
+
* (keys) in a JSON object. Otherwise strings are returned, which is also
|
1568
|
+
* the default.
|
1558
1569
|
* * *create_additions*: If set to false, the Parser doesn't create
|
1559
1570
|
* additions even if a matchin class and create_id was found. This option
|
1560
1571
|
* defaults to true.
|
@@ -1595,6 +1606,13 @@ static VALUE cParser_initialize(int argc, VALUE *argv, VALUE self)
|
|
1595
1606
|
} else {
|
1596
1607
|
json->allow_nan = 0;
|
1597
1608
|
}
|
1609
|
+
tmp = ID2SYM(i_symbolize_names);
|
1610
|
+
if (st_lookup(RHASH_TBL(opts), tmp, 0)) {
|
1611
|
+
VALUE symbolize_names = rb_hash_aref(opts, tmp);
|
1612
|
+
json->symbolize_names = RTEST(symbolize_names) ? 1 : 0;
|
1613
|
+
} else {
|
1614
|
+
json->symbolize_names = 0;
|
1615
|
+
}
|
1598
1616
|
tmp = ID2SYM(i_create_additions);
|
1599
1617
|
if (st_lookup(RHASH_TBL(opts), tmp, 0)) {
|
1600
1618
|
VALUE create_additions = rb_hash_aref(opts, tmp);
|
@@ -1647,16 +1665,16 @@ static VALUE cParser_parse(VALUE self)
|
|
1647
1665
|
GET_STRUCT;
|
1648
1666
|
|
1649
1667
|
|
1650
|
-
#line
|
1668
|
+
#line 1669 "parser.c"
|
1651
1669
|
{
|
1652
1670
|
cs = JSON_start;
|
1653
1671
|
}
|
1654
1672
|
|
1655
|
-
#line
|
1673
|
+
#line 666 "parser.rl"
|
1656
1674
|
p = json->source;
|
1657
1675
|
pe = p + json->len;
|
1658
1676
|
|
1659
|
-
#line
|
1677
|
+
#line 1678 "parser.c"
|
1660
1678
|
{
|
1661
1679
|
if ( p == pe )
|
1662
1680
|
goto _test_eof;
|
@@ -1712,7 +1730,7 @@ case 5:
|
|
1712
1730
|
goto st1;
|
1713
1731
|
goto st5;
|
1714
1732
|
tr3:
|
1715
|
-
#line
|
1733
|
+
#line 474 "parser.rl"
|
1716
1734
|
{
|
1717
1735
|
char *np;
|
1718
1736
|
json->current_nesting = 1;
|
@@ -1721,7 +1739,7 @@ tr3:
|
|
1721
1739
|
}
|
1722
1740
|
goto st10;
|
1723
1741
|
tr4:
|
1724
|
-
#line
|
1742
|
+
#line 467 "parser.rl"
|
1725
1743
|
{
|
1726
1744
|
char *np;
|
1727
1745
|
json->current_nesting = 1;
|
@@ -1733,7 +1751,7 @@ st10:
|
|
1733
1751
|
if ( ++p == pe )
|
1734
1752
|
goto _test_eof10;
|
1735
1753
|
case 10:
|
1736
|
-
#line
|
1754
|
+
#line 1755 "parser.c"
|
1737
1755
|
switch( (*p) ) {
|
1738
1756
|
case 13: goto st10;
|
1739
1757
|
case 32: goto st10;
|
@@ -1790,7 +1808,7 @@ case 9:
|
|
1790
1808
|
_out: {}
|
1791
1809
|
}
|
1792
1810
|
|
1793
|
-
#line
|
1811
|
+
#line 669 "parser.rl"
|
1794
1812
|
|
1795
1813
|
if (cs >= JSON_first_final && p == pe) {
|
1796
1814
|
return result;
|
@@ -1861,6 +1879,7 @@ void Init_parser()
|
|
1861
1879
|
i_chr = rb_intern("chr");
|
1862
1880
|
i_max_nesting = rb_intern("max_nesting");
|
1863
1881
|
i_allow_nan = rb_intern("allow_nan");
|
1882
|
+
i_symbolize_names = rb_intern("symbolize_names");
|
1864
1883
|
i_object_class = rb_intern("object_class");
|
1865
1884
|
i_array_class = rb_intern("array_class");
|
1866
1885
|
#ifdef HAVE_RUBY_ENCODING_H
|
@@ -31,7 +31,8 @@ static VALUE mJSON, mExt, cParser, eParserError, eNestingError;
|
|
31
31
|
static VALUE CNaN, CInfinity, CMinusInfinity;
|
32
32
|
|
33
33
|
static ID i_json_creatable_p, i_json_create, i_create_id, i_create_additions,
|
34
|
-
i_chr, i_max_nesting, i_allow_nan, i_object_class,
|
34
|
+
i_chr, i_max_nesting, i_allow_nan, i_symbolize_names, i_object_class,
|
35
|
+
i_array_class;
|
35
36
|
|
36
37
|
#define MinusInfinity "-Infinity"
|
37
38
|
|
@@ -44,6 +45,8 @@ typedef struct JSON_ParserStruct {
|
|
44
45
|
int max_nesting;
|
45
46
|
int current_nesting;
|
46
47
|
int allow_nan;
|
48
|
+
int parsing_name;
|
49
|
+
int symbolize_names;
|
47
50
|
VALUE object_class;
|
48
51
|
VALUE array_class;
|
49
52
|
} JSON_Parser;
|
@@ -105,7 +108,9 @@ static char *JSON_parse_float(JSON_Parser *json, char *p, char *pe, VALUE *resul
|
|
105
108
|
}
|
106
109
|
|
107
110
|
action parse_name {
|
111
|
+
json->parsing_name = 1;
|
108
112
|
char *np = JSON_parse_string(json, fpc, pe, &last_name);
|
113
|
+
json->parsing_name = 0;
|
109
114
|
if (np == NULL) { fhold; fbreak; } else fexec np;
|
110
115
|
}
|
111
116
|
|
@@ -417,15 +422,15 @@ static VALUE json_string_unescape(char *p, char *pe)
|
|
417
422
|
write data;
|
418
423
|
|
419
424
|
action parse_string {
|
420
|
-
|
421
|
-
|
422
|
-
|
423
|
-
|
424
|
-
|
425
|
-
|
426
|
-
|
427
|
-
|
428
|
-
|
425
|
+
*result = json_string_unescape(json->memo + 1, p);
|
426
|
+
if (NIL_P(*result)) {
|
427
|
+
fhold;
|
428
|
+
fbreak;
|
429
|
+
} else {
|
430
|
+
FORCE_UTF8(*result);
|
431
|
+
fexec p + 1;
|
432
|
+
}
|
433
|
+
}
|
429
434
|
|
430
435
|
action exit { fhold; fbreak; }
|
431
436
|
|
@@ -441,6 +446,9 @@ static char *JSON_parse_string(JSON_Parser *json, char *p, char *pe, VALUE *resu
|
|
441
446
|
json->memo = p;
|
442
447
|
%% write exec;
|
443
448
|
|
449
|
+
if (json->symbolize_names && json->parsing_name) {
|
450
|
+
*result = rb_str_intern(*result);
|
451
|
+
}
|
444
452
|
if (cs >= JSON_string_first_final) {
|
445
453
|
return p + 1;
|
446
454
|
} else {
|
@@ -553,6 +561,9 @@ inline static VALUE convert_encoding(VALUE source)
|
|
553
561
|
* * *allow_nan*: If set to true, allow NaN, Infinity and -Infinity in
|
554
562
|
* defiance of RFC 4627 to be parsed by the Parser. This option defaults to
|
555
563
|
* false.
|
564
|
+
* * *symbolize_names*: If set to true, returns symbols for the names
|
565
|
+
* (keys) in a JSON object. Otherwise strings are returned, which is also
|
566
|
+
* the default.
|
556
567
|
* * *create_additions*: If set to false, the Parser doesn't create
|
557
568
|
* additions even if a matchin class and create_id was found. This option
|
558
569
|
* defaults to true.
|
@@ -593,6 +604,13 @@ static VALUE cParser_initialize(int argc, VALUE *argv, VALUE self)
|
|
593
604
|
} else {
|
594
605
|
json->allow_nan = 0;
|
595
606
|
}
|
607
|
+
tmp = ID2SYM(i_symbolize_names);
|
608
|
+
if (st_lookup(RHASH_TBL(opts), tmp, 0)) {
|
609
|
+
VALUE symbolize_names = rb_hash_aref(opts, tmp);
|
610
|
+
json->symbolize_names = RTEST(symbolize_names) ? 1 : 0;
|
611
|
+
} else {
|
612
|
+
json->symbolize_names = 0;
|
613
|
+
}
|
596
614
|
tmp = ID2SYM(i_create_additions);
|
597
615
|
if (st_lookup(RHASH_TBL(opts), tmp, 0)) {
|
598
616
|
VALUE create_additions = rb_hash_aref(opts, tmp);
|
@@ -718,6 +736,7 @@ void Init_parser()
|
|
718
736
|
i_chr = rb_intern("chr");
|
719
737
|
i_max_nesting = rb_intern("max_nesting");
|
720
738
|
i_allow_nan = rb_intern("allow_nan");
|
739
|
+
i_symbolize_names = rb_intern("symbolize_names");
|
721
740
|
i_object_class = rb_intern("object_class");
|
722
741
|
i_array_class = rb_intern("array_class");
|
723
742
|
#ifdef HAVE_RUBY_ENCODING_H
|
data/lib/json/add/core.rb
CHANGED
@@ -7,6 +7,19 @@ unless Object.const_defined?(:JSON) and ::JSON.const_defined?(:JSON_LOADED) and
|
|
7
7
|
end
|
8
8
|
require 'date'
|
9
9
|
|
10
|
+
class Symbol
|
11
|
+
def to_json(*a)
|
12
|
+
{
|
13
|
+
JSON.create_id => self.class.name,
|
14
|
+
's' => to_s,
|
15
|
+
}.to_json(*a)
|
16
|
+
end
|
17
|
+
|
18
|
+
def self.json_create(o)
|
19
|
+
o['s'].to_sym
|
20
|
+
end
|
21
|
+
end
|
22
|
+
|
10
23
|
class Time
|
11
24
|
def self.json_create(object)
|
12
25
|
if usec = object.delete('u') # used to be tv_usec -> tv_nsec
|
@@ -21,7 +34,7 @@ class Time
|
|
21
34
|
|
22
35
|
def to_json(*args)
|
23
36
|
{
|
24
|
-
|
37
|
+
JSON.create_id => self.class.name,
|
25
38
|
's' => tv_sec,
|
26
39
|
'n' => respond_to?(:tv_nsec) ? tv_nsec : tv_usec * 1000
|
27
40
|
}.to_json(*args)
|
@@ -37,7 +50,7 @@ class Date
|
|
37
50
|
|
38
51
|
def to_json(*args)
|
39
52
|
{
|
40
|
-
|
53
|
+
JSON.create_id => self.class.name,
|
41
54
|
'y' => year,
|
42
55
|
'm' => month,
|
43
56
|
'd' => day,
|
@@ -63,7 +76,7 @@ class DateTime
|
|
63
76
|
|
64
77
|
def to_json(*args)
|
65
78
|
{
|
66
|
-
|
79
|
+
JSON.create_id => self.class.name,
|
67
80
|
'y' => year,
|
68
81
|
'm' => month,
|
69
82
|
'd' => day,
|
@@ -83,7 +96,7 @@ class Range
|
|
83
96
|
|
84
97
|
def to_json(*args)
|
85
98
|
{
|
86
|
-
|
99
|
+
JSON.create_id => self.class.name,
|
87
100
|
'a' => [ first, last, exclude_end? ]
|
88
101
|
}.to_json(*args)
|
89
102
|
end
|
@@ -98,7 +111,7 @@ class Struct
|
|
98
111
|
klass = self.class.name
|
99
112
|
klass.to_s.empty? and raise JSON::JSONError, "Only named structs are supported!"
|
100
113
|
{
|
101
|
-
|
114
|
+
JSON.create_id => klass,
|
102
115
|
'v' => values,
|
103
116
|
}.to_json(*args)
|
104
117
|
end
|
@@ -113,7 +126,7 @@ class Exception
|
|
113
126
|
|
114
127
|
def to_json(*args)
|
115
128
|
{
|
116
|
-
|
129
|
+
JSON.create_id => self.class.name,
|
117
130
|
'm' => message,
|
118
131
|
'b' => backtrace,
|
119
132
|
}.to_json(*args)
|
@@ -127,7 +140,7 @@ class Regexp
|
|
127
140
|
|
128
141
|
def to_json(*)
|
129
142
|
{
|
130
|
-
|
143
|
+
JSON.create_id => self.class.name,
|
131
144
|
'o' => options,
|
132
145
|
's' => source,
|
133
146
|
}.to_json
|
data/lib/json/add/rails.rb
CHANGED
@@ -10,7 +10,7 @@ class Object
|
|
10
10
|
def self.json_create(object)
|
11
11
|
obj = new
|
12
12
|
for key, value in object
|
13
|
-
next if key ==
|
13
|
+
next if key == JSON.create_id
|
14
14
|
instance_variable_set "@#{key}", value
|
15
15
|
end
|
16
16
|
obj
|
@@ -18,7 +18,7 @@ class Object
|
|
18
18
|
|
19
19
|
def to_json(*a)
|
20
20
|
result = {
|
21
|
-
|
21
|
+
JSON.create_id => self.class.name
|
22
22
|
}
|
23
23
|
instance_variables.inject(result) do |r, name|
|
24
24
|
r[name[1..-1]] = instance_variable_get name
|
data/lib/json/common.rb
CHANGED
@@ -116,9 +116,14 @@ module JSON
|
|
116
116
|
# * *allow_nan*: If set to true, allow NaN, Infinity and -Infinity in
|
117
117
|
# defiance of RFC 4627 to be parsed by the Parser. This option defaults
|
118
118
|
# to false.
|
119
|
+
# * *symbolize_names*: If set to true, returns symbols for the names
|
120
|
+
# (keys) in a JSON object. Otherwise strings are returned, which is also
|
121
|
+
# the default.
|
119
122
|
# * *create_additions*: If set to false, the Parser doesn't create
|
120
123
|
# additions even if a matchin class and create_id was found. This option
|
121
124
|
# defaults to true.
|
125
|
+
# * *object_class*: Defaults to Hash
|
126
|
+
# * *array_class*: Defaults to Array
|
122
127
|
def parse(source, opts = {})
|
123
128
|
JSON.parser.new(source, opts).parse
|
124
129
|
end
|
data/lib/json/pure/parser.rb
CHANGED
@@ -60,6 +60,9 @@ module JSON
|
|
60
60
|
# * *allow_nan*: If set to true, allow NaN, Infinity and -Infinity in
|
61
61
|
# defiance of RFC 4627 to be parsed by the Parser. This option defaults
|
62
62
|
# to false.
|
63
|
+
# * *symbolize_names*: If set to true, returns symbols for the names
|
64
|
+
# (keys) in a JSON object. Otherwise strings are returned, which is also
|
65
|
+
# the default.
|
63
66
|
# * *create_additions*: If set to false, the Parser doesn't create
|
64
67
|
# additions even if a matchin class and create_id was found. This option
|
65
68
|
# defaults to true.
|
@@ -109,6 +112,7 @@ module JSON
|
|
109
112
|
@max_nesting = 0
|
110
113
|
end
|
111
114
|
@allow_nan = !!opts[:allow_nan]
|
115
|
+
@symbolize_names = !!opts[:symbolize_names]
|
112
116
|
ca = true
|
113
117
|
ca = opts[:create_additions] if opts.key?(:create_additions)
|
114
118
|
@create_id = ca ? JSON.create_id : nil
|
@@ -267,7 +271,7 @@ module JSON
|
|
267
271
|
end
|
268
272
|
skip(IGNORE)
|
269
273
|
unless (value = parse_value).equal? UNPARSED
|
270
|
-
result[string] = value
|
274
|
+
result[@symbolize_names ? string.to_sym : string] = value
|
271
275
|
delim = false
|
272
276
|
skip(IGNORE)
|
273
277
|
if scan(COLLECTION_DELIMITER)
|
data/lib/json/version.rb
CHANGED
data/tests/test_json.rb
CHANGED
@@ -302,6 +302,13 @@ EOT
|
|
302
302
|
assert_equal too_deep, ok
|
303
303
|
end
|
304
304
|
|
305
|
+
def test_symbolize_names
|
306
|
+
assert_equal({ "foo" => "bar", "baz" => "quux" },
|
307
|
+
JSON.parse('{"foo":"bar", "baz":"quux"}'))
|
308
|
+
assert_equal({ :foo => "bar", :baz => "quux" },
|
309
|
+
JSON.parse('{"foo":"bar", "baz":"quux"}', :symbolize_names => true))
|
310
|
+
end
|
311
|
+
|
305
312
|
def test_load_dump
|
306
313
|
too_deep = '[[[[[[[[[[[[[[[[[[[[]]]]]]]]]]]]]]]]]]]]'
|
307
314
|
assert_equal too_deep, JSON.dump(eval(too_deep))
|
metadata
CHANGED
@@ -1,7 +1,7 @@
|
|
1
1
|
--- !ruby/object:Gem::Specification
|
2
2
|
name: json
|
3
3
|
version: !ruby/object:Gem::Version
|
4
|
-
version: 1.2.
|
4
|
+
version: 1.2.1
|
5
5
|
platform: ruby
|
6
6
|
authors:
|
7
7
|
- Florian Frank
|
@@ -9,7 +9,7 @@ autorequire:
|
|
9
9
|
bindir: bin
|
10
10
|
cert_chain: []
|
11
11
|
|
12
|
-
date:
|
12
|
+
date: 2010-02-26 00:00:00 +01:00
|
13
13
|
default_executable: edit_json.rb
|
14
14
|
dependencies: []
|
15
15
|
|
@@ -139,7 +139,7 @@ files:
|
|
139
139
|
- COPYING
|
140
140
|
- install.rb
|
141
141
|
has_rdoc: true
|
142
|
-
homepage: http://
|
142
|
+
homepage: http://flori.github.com/json
|
143
143
|
licenses: []
|
144
144
|
|
145
145
|
post_install_message:
|