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 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
- (http://www.ietf.org/rfc/rfc4627.txt). Starting from version 1.0.0 on there
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
- (http://www.cs.queensu.ca/~thurston/ragel).
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 (http://www.prototypejs.org) works.
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://json.rubyforge.org"
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://json.rubyforge.org"
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 = 'i386-mswin32'
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 = 'i386-mswin32'
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.0
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, i_array_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 88 "parser.rl"
68
+ #line 91 "parser.rl"
66
69
 
67
70
 
68
71
 
69
- #line 70 "parser.c"
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 121 "parser.rl"
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 94 "parser.c"
96
+ #line 97 "parser.c"
94
97
  {
95
98
  cs = JSON_object_start;
96
99
  }
97
100
 
98
- #line 136 "parser.rl"
101
+ #line 141 "parser.rl"
99
102
 
100
- #line 101 "parser.c"
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 107 "parser.rl"
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 139 "parser.c"
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 96 "parser.rl"
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 222 "parser.c"
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 112 "parser.rl"
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 318 "parser.c"
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 137 "parser.rl"
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 435 "parser.c"
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 235 "parser.rl"
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 451 "parser.c"
455
+ #line 456 "parser.c"
451
456
  {
452
457
  cs = JSON_value_start;
453
458
  }
454
459
 
455
- #line 242 "parser.rl"
460
+ #line 247 "parser.rl"
456
461
 
457
- #line 458 "parser.c"
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 183 "parser.rl"
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 188 "parser.rl"
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 206 "parser.rl"
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 214 "parser.rl"
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 176 "parser.rl"
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 169 "parser.rl"
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 163 "parser.rl"
554
+ #line 168 "parser.rl"
550
555
  {
551
556
  *result = Qfalse;
552
557
  }
553
558
  goto st21;
554
559
  tr25:
555
- #line 160 "parser.rl"
560
+ #line 165 "parser.rl"
556
561
  {
557
562
  *result = Qnil;
558
563
  }
559
564
  goto st21;
560
565
  tr28:
561
- #line 166 "parser.rl"
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 222 "parser.rl"
575
+ #line 227 "parser.rl"
571
576
  { p--; {p++; cs = 21; goto _out;} }
572
- #line 573 "parser.c"
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 243 "parser.rl"
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 744 "parser.c"
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 259 "parser.rl"
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 760 "parser.c"
764
+ #line 765 "parser.c"
760
765
  {
761
766
  cs = JSON_integer_start;
762
767
  }
763
768
 
764
- #line 266 "parser.rl"
769
+ #line 271 "parser.rl"
765
770
  json->memo = p;
766
771
 
767
- #line 768 "parser.c"
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 256 "parser.rl"
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 809 "parser.c"
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 268 "parser.rl"
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 840 "parser.c"
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 290 "parser.rl"
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 856 "parser.c"
860
+ #line 861 "parser.c"
856
861
  {
857
862
  cs = JSON_float_start;
858
863
  }
859
864
 
860
- #line 297 "parser.rl"
865
+ #line 302 "parser.rl"
861
866
  json->memo = p;
862
867
 
863
- #line 864 "parser.c"
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 284 "parser.rl"
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 929 "parser.c"
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 299 "parser.rl"
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 1003 "parser.c"
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 335 "parser.rl"
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 1025 "parser.c"
1029
+ #line 1030 "parser.c"
1025
1030
  {
1026
1031
  cs = JSON_array_start;
1027
1032
  }
1028
1033
 
1029
- #line 348 "parser.rl"
1034
+ #line 353 "parser.rl"
1030
1035
 
1031
- #line 1032 "parser.c"
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 316 "parser.rl"
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 1087 "parser.c"
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 327 "parser.rl"
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 1194 "parser.c"
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 349 "parser.rl"
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 1316 "parser.c"
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 433 "parser.rl"
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 1333 "parser.c"
1337
+ #line 1338 "parser.c"
1333
1338
  {
1334
1339
  cs = JSON_string_start;
1335
1340
  }
1336
1341
 
1337
- #line 441 "parser.rl"
1342
+ #line 446 "parser.rl"
1338
1343
  json->memo = p;
1339
1344
 
1340
- #line 1341 "parser.c"
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 419 "parser.rl"
1370
+ #line 424 "parser.rl"
1366
1371
  {
1367
- *result = json_string_unescape(json->memo + 1, p);
1368
- if (NIL_P(*result)) {
1369
- p--;
1370
- {p++; cs = 8; goto _out;}
1371
- } else {
1372
- FORCE_UTF8(*result);
1373
- {p = (( p + 1))-1;}
1374
- }
1375
- }
1376
- #line 430 "parser.rl"
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 1384 "parser.c"
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 443 "parser.rl"
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 1471 "parser.c"
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 477 "parser.rl"
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 1651 "parser.c"
1668
+ #line 1669 "parser.c"
1651
1669
  {
1652
1670
  cs = JSON_start;
1653
1671
  }
1654
1672
 
1655
- #line 648 "parser.rl"
1673
+ #line 666 "parser.rl"
1656
1674
  p = json->source;
1657
1675
  pe = p + json->len;
1658
1676
 
1659
- #line 1660 "parser.c"
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 466 "parser.rl"
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 459 "parser.rl"
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 1737 "parser.c"
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 651 "parser.rl"
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, i_array_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
- *result = json_string_unescape(json->memo + 1, p);
421
- if (NIL_P(*result)) {
422
- fhold;
423
- fbreak;
424
- } else {
425
- FORCE_UTF8(*result);
426
- fexec p + 1;
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
@@ -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
- 'json_class' => self.class.name,
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
- 'json_class' => self.class.name,
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
- 'json_class' => self.class.name,
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
- 'json_class' => self.class.name,
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
- 'json_class' => klass,
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
- 'json_class' => self.class.name,
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
- 'json_class' => self.class.name,
143
+ JSON.create_id => self.class.name,
131
144
  'o' => options,
132
145
  's' => source,
133
146
  }.to_json
@@ -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 == 'json_class'
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
- 'json_class' => self.class.name
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
@@ -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
@@ -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)
@@ -1,6 +1,6 @@
1
1
  module JSON
2
2
  # JSON version
3
- VERSION = '1.2.0'
3
+ VERSION = '1.2.1'
4
4
  VERSION_ARRAY = VERSION.split(/\./).map { |x| x.to_i } # :nodoc:
5
5
  VERSION_MAJOR = VERSION_ARRAY[0] # :nodoc:
6
6
  VERSION_MINOR = VERSION_ARRAY[1] # :nodoc:
@@ -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.0
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: 2009-11-08 00:00:00 +01:00
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://json.rubyforge.org
142
+ homepage: http://flori.github.com/json
143
143
  licenses: []
144
144
 
145
145
  post_install_message: