json 1.4.6 → 1.5.0

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.

Files changed (48) hide show
  1. data/CHANGES +6 -0
  2. data/COPYING-json-jruby +57 -0
  3. data/README-json-jruby.markdown +33 -0
  4. data/Rakefile +224 -119
  5. data/VERSION +1 -1
  6. data/benchmarks/generator2_benchmark.rb +1 -1
  7. data/benchmarks/generator_benchmark.rb +1 -1
  8. data/ext/json/ext/generator/generator.c +20 -20
  9. data/ext/json/ext/generator/generator.h +7 -7
  10. data/ext/json/ext/parser/extconf.rb +1 -0
  11. data/ext/json/ext/parser/parser.c +122 -88
  12. data/ext/json/ext/parser/parser.h +7 -0
  13. data/ext/json/ext/parser/parser.rl +54 -20
  14. data/java/lib/bytelist-1.0.6.jar +0 -0
  15. data/java/lib/jcodings.jar +0 -0
  16. data/java/src/json/ext/ByteListTranscoder.java +167 -0
  17. data/java/src/json/ext/Generator.java +441 -0
  18. data/java/src/json/ext/GeneratorMethods.java +231 -0
  19. data/java/src/json/ext/GeneratorService.java +42 -0
  20. data/java/src/json/ext/GeneratorState.java +473 -0
  21. data/java/src/json/ext/OptionsReader.java +119 -0
  22. data/java/src/json/ext/Parser.java +2295 -0
  23. data/java/src/json/ext/Parser.rl +825 -0
  24. data/java/src/json/ext/ParserService.java +34 -0
  25. data/java/src/json/ext/RuntimeInfo.java +119 -0
  26. data/java/src/json/ext/StringDecoder.java +166 -0
  27. data/java/src/json/ext/StringEncoder.java +106 -0
  28. data/java/src/json/ext/Utils.java +89 -0
  29. data/json-java.gemspec +20 -0
  30. data/lib/json/add/core.rb +1 -2
  31. data/lib/json/add/rails.rb +4 -54
  32. data/lib/json/common.rb +36 -8
  33. data/lib/json/editor.rb +1 -3
  34. data/lib/json/ext.rb +2 -2
  35. data/lib/json/pure.rb +2 -64
  36. data/lib/json/pure/generator.rb +10 -8
  37. data/lib/json/pure/parser.rb +23 -12
  38. data/lib/json/version.rb +1 -1
  39. data/tests/setup_variant.rb +11 -0
  40. data/tests/test_json.rb +1 -5
  41. data/tests/test_json_addition.rb +14 -9
  42. data/tests/test_json_encoding.rb +9 -12
  43. data/tests/test_json_fixtures.rb +9 -8
  44. data/tests/test_json_generate.rb +3 -5
  45. data/tests/test_json_string_matching.rb +40 -0
  46. data/tests/test_json_unicode.rb +1 -5
  47. metadata +51 -13
  48. data/tests/test_json_rails.rb +0 -144
data/VERSION CHANGED
@@ -1 +1 @@
1
- 1.4.6
1
+ 1.5.0
@@ -138,7 +138,7 @@ class Generator2BenchmarkRails < Bullshit::RepeatCase
138
138
  histogram yes
139
139
 
140
140
  def benchmark_generator
141
- @result = @big.to_json
141
+ @result = ActiveSupport::JSON.encode @big
142
142
  end
143
143
 
144
144
  alias reset_benchmark_generator generic_reset_method
@@ -140,7 +140,7 @@ class GeneratorBenchmarkRails < Bullshit::RepeatCase
140
140
  histogram yes
141
141
 
142
142
  def benchmark_generator
143
- @result = @big.to_json
143
+ @result = ActiveSupport::JSON.encode @big
144
144
  end
145
145
 
146
146
  alias reset_benchmark_generator generic_reset_method
@@ -74,7 +74,7 @@ static const UTF32 offsetsFromUTF8[6] = { 0x00000000UL, 0x00003080UL, 0x000E2080
74
74
  * If presented with a length > 4, this returns 0. The Unicode
75
75
  * definition of UTF-8 goes up to 4-byte sequences.
76
76
  */
77
- static unsigned char isLegalUTF8(const UTF8 *source, int length)
77
+ static unsigned char isLegalUTF8(const UTF8 *source, unsigned long length)
78
78
  {
79
79
  UTF8 a;
80
80
  const UTF8 *srcptr = source+length;
@@ -223,7 +223,7 @@ static void convert_UTF8_to_JSON_ASCII(FBuffer *buffer, VALUE string)
223
223
  static void convert_UTF8_to_JSON(FBuffer *buffer, VALUE string)
224
224
  {
225
225
  const char *ptr = RSTRING_PTR(string), *p;
226
- int len = RSTRING_LEN(string), start = 0, end = 0;
226
+ unsigned long len = RSTRING_LEN(string), start = 0, end = 0;
227
227
  const char *escape = NULL;
228
228
  int escape_len;
229
229
  unsigned char c;
@@ -284,7 +284,7 @@ static void convert_UTF8_to_JSON(FBuffer *buffer, VALUE string)
284
284
  fbuffer_append(buffer, ptr + start, end - start);
285
285
  }
286
286
 
287
- static char *fstrndup(const char *ptr, int len) {
287
+ static char *fstrndup(const char *ptr, unsigned long len) {
288
288
  char *result;
289
289
  if (len <= 0) return NULL;
290
290
  result = ALLOC_N(char, len);
@@ -302,7 +302,7 @@ static FBuffer *fbuffer_alloc()
302
302
  return fb;
303
303
  }
304
304
 
305
- static FBuffer *fbuffer_alloc_with_length(unsigned int initial_length)
305
+ static FBuffer *fbuffer_alloc_with_length(unsigned long initial_length)
306
306
  {
307
307
  FBuffer *fb;
308
308
  assert(initial_length > 0);
@@ -328,9 +328,9 @@ static void fbuffer_clear(FBuffer *fb)
328
328
  fb->len = 0;
329
329
  }
330
330
 
331
- static void fbuffer_inc_capa(FBuffer *fb, unsigned int requested)
331
+ static void fbuffer_inc_capa(FBuffer *fb, unsigned long requested)
332
332
  {
333
- unsigned int required;
333
+ unsigned long required;
334
334
 
335
335
  if (!fb->ptr) {
336
336
  fb->ptr = ALLOC_N(char, fb->initial_length);
@@ -345,7 +345,7 @@ static void fbuffer_inc_capa(FBuffer *fb, unsigned int requested)
345
345
  }
346
346
  }
347
347
 
348
- static void fbuffer_append(FBuffer *fb, const char *newstr, unsigned int len)
348
+ static void fbuffer_append(FBuffer *fb, const char *newstr, unsigned long len)
349
349
  {
350
350
  if (len > 0) {
351
351
  fbuffer_inc_capa(fb, len);
@@ -370,7 +370,7 @@ static void freverse(char *start, char *end)
370
370
  }
371
371
  }
372
372
 
373
- static int fltoa(long number, char *buf)
373
+ static long fltoa(long number, char *buf)
374
374
  {
375
375
  static char digits[] = "0123456789";
376
376
  long sign = number;
@@ -386,13 +386,13 @@ static int fltoa(long number, char *buf)
386
386
  static void fbuffer_append_long(FBuffer *fb, long number)
387
387
  {
388
388
  char buf[20];
389
- int len = fltoa(number, buf);
389
+ unsigned long len = fltoa(number, buf);
390
390
  fbuffer_append(fb, buf, len);
391
391
  }
392
392
 
393
393
  static FBuffer *fbuffer_dup(FBuffer *fb)
394
394
  {
395
- int len = fb->len;
395
+ unsigned long len = fb->len;
396
396
  FBuffer *result;
397
397
 
398
398
  if (len > 0) {
@@ -628,7 +628,7 @@ static VALUE cState_configure(VALUE self, VALUE opts)
628
628
  opts = tmp;
629
629
  tmp = rb_hash_aref(opts, ID2SYM(i_indent));
630
630
  if (RTEST(tmp)) {
631
- int len;
631
+ unsigned long len;
632
632
  Check_Type(tmp, T_STRING);
633
633
  len = RSTRING_LEN(tmp);
634
634
  state->indent = fstrndup(RSTRING_PTR(tmp), len);
@@ -636,7 +636,7 @@ static VALUE cState_configure(VALUE self, VALUE opts)
636
636
  }
637
637
  tmp = rb_hash_aref(opts, ID2SYM(i_space));
638
638
  if (RTEST(tmp)) {
639
- int len;
639
+ unsigned long len;
640
640
  Check_Type(tmp, T_STRING);
641
641
  len = RSTRING_LEN(tmp);
642
642
  state->space = fstrndup(RSTRING_PTR(tmp), len);
@@ -644,7 +644,7 @@ static VALUE cState_configure(VALUE self, VALUE opts)
644
644
  }
645
645
  tmp = rb_hash_aref(opts, ID2SYM(i_space_before));
646
646
  if (RTEST(tmp)) {
647
- int len;
647
+ unsigned long len;
648
648
  Check_Type(tmp, T_STRING);
649
649
  len = RSTRING_LEN(tmp);
650
650
  state->space_before = fstrndup(RSTRING_PTR(tmp), len);
@@ -652,7 +652,7 @@ static VALUE cState_configure(VALUE self, VALUE opts)
652
652
  }
653
653
  tmp = rb_hash_aref(opts, ID2SYM(i_array_nl));
654
654
  if (RTEST(tmp)) {
655
- int len;
655
+ unsigned long len;
656
656
  Check_Type(tmp, T_STRING);
657
657
  len = RSTRING_LEN(tmp);
658
658
  state->array_nl = fstrndup(RSTRING_PTR(tmp), len);
@@ -660,7 +660,7 @@ static VALUE cState_configure(VALUE self, VALUE opts)
660
660
  }
661
661
  tmp = rb_hash_aref(opts, ID2SYM(i_object_nl));
662
662
  if (RTEST(tmp)) {
663
- int len;
663
+ unsigned long len;
664
664
  Check_Type(tmp, T_STRING);
665
665
  len = RSTRING_LEN(tmp);
666
666
  state->object_nl = fstrndup(RSTRING_PTR(tmp), len);
@@ -1065,7 +1065,7 @@ static VALUE cState_indent(VALUE self)
1065
1065
  */
1066
1066
  static VALUE cState_indent_set(VALUE self, VALUE indent)
1067
1067
  {
1068
- int len;
1068
+ unsigned long len;
1069
1069
  GET_STATE(self);
1070
1070
  Check_Type(indent, T_STRING);
1071
1071
  len = RSTRING_LEN(indent);
@@ -1103,7 +1103,7 @@ static VALUE cState_space(VALUE self)
1103
1103
  */
1104
1104
  static VALUE cState_space_set(VALUE self, VALUE space)
1105
1105
  {
1106
- int len;
1106
+ unsigned long len;
1107
1107
  GET_STATE(self);
1108
1108
  Check_Type(space, T_STRING);
1109
1109
  len = RSTRING_LEN(space);
@@ -1139,7 +1139,7 @@ static VALUE cState_space_before(VALUE self)
1139
1139
  */
1140
1140
  static VALUE cState_space_before_set(VALUE self, VALUE space_before)
1141
1141
  {
1142
- int len;
1142
+ unsigned long len;
1143
1143
  GET_STATE(self);
1144
1144
  Check_Type(space_before, T_STRING);
1145
1145
  len = RSTRING_LEN(space_before);
@@ -1177,7 +1177,7 @@ static VALUE cState_object_nl(VALUE self)
1177
1177
  */
1178
1178
  static VALUE cState_object_nl_set(VALUE self, VALUE object_nl)
1179
1179
  {
1180
- int len;
1180
+ unsigned long len;
1181
1181
  GET_STATE(self);
1182
1182
  Check_Type(object_nl, T_STRING);
1183
1183
  len = RSTRING_LEN(object_nl);
@@ -1212,7 +1212,7 @@ static VALUE cState_array_nl(VALUE self)
1212
1212
  */
1213
1213
  static VALUE cState_array_nl_set(VALUE self, VALUE array_nl)
1214
1214
  {
1215
- int len;
1215
+ unsigned long len;
1216
1216
  GET_STATE(self);
1217
1217
  Check_Type(array_nl, T_STRING);
1218
1218
  len = RSTRING_LEN(array_nl);
@@ -50,10 +50,10 @@
50
50
  /* fbuffer implementation */
51
51
 
52
52
  typedef struct FBufferStruct {
53
- unsigned int initial_length;
53
+ unsigned long initial_length;
54
54
  char *ptr;
55
- unsigned int len;
56
- unsigned int capa;
55
+ unsigned long len;
56
+ unsigned long capa;
57
57
  } FBuffer;
58
58
 
59
59
  #define FBUFFER_INITIAL_LENGTH 4096
@@ -63,13 +63,13 @@ typedef struct FBufferStruct {
63
63
  #define FBUFFER_CAPA(fb) (fb->capa)
64
64
  #define FBUFFER_PAIR(fb) FBUFFER_PTR(fb), FBUFFER_LEN(fb)
65
65
 
66
- static char *fstrndup(const char *ptr, int len);
66
+ static char *fstrndup(const char *ptr, unsigned long len);
67
67
  static FBuffer *fbuffer_alloc();
68
- static FBuffer *fbuffer_alloc_with_length(unsigned initial_length);
68
+ static FBuffer *fbuffer_alloc_with_length(unsigned long initial_length);
69
69
  static void fbuffer_free(FBuffer *fb);
70
70
  static void fbuffer_free_only_buffer(FBuffer *fb);
71
71
  static void fbuffer_clear(FBuffer *fb);
72
- static void fbuffer_append(FBuffer *fb, const char *newstr, unsigned int len);
72
+ static void fbuffer_append(FBuffer *fb, const char *newstr, unsigned long len);
73
73
  static void fbuffer_append_long(FBuffer *fb, long number);
74
74
  static void fbuffer_append_char(FBuffer *fb, char newchr);
75
75
  static FBuffer *fbuffer_dup(FBuffer *fb);
@@ -99,7 +99,7 @@ static const int halfShift = 10; /* used for shifting by 10 bits */
99
99
  static const UTF32 halfBase = 0x0010000UL;
100
100
  static const UTF32 halfMask = 0x3FFUL;
101
101
 
102
- static unsigned char isLegalUTF8(const UTF8 *source, int length);
102
+ static unsigned char isLegalUTF8(const UTF8 *source, unsigned long length);
103
103
  static void unicode_escape(char *buf, UTF16 character);
104
104
  static void unicode_escape_to_buffer(FBuffer *buffer, char buf[6], UTF16 character);
105
105
  static void convert_UTF8_to_JSON_ASCII(FBuffer *buffer, VALUE string);
@@ -12,4 +12,5 @@ if CONFIG['CC'] =~ /gcc/
12
12
  end
13
13
 
14
14
  have_header("re.h")
15
+ have_header("ruby/st.h")
15
16
  create_makefile 'json/ext/parser'
@@ -79,7 +79,7 @@ static VALUE CNaN, CInfinity, CMinusInfinity;
79
79
 
80
80
  static ID i_json_creatable_p, i_json_create, i_create_id, i_create_additions,
81
81
  i_chr, i_max_nesting, i_allow_nan, i_symbolize_names, i_object_class,
82
- i_array_class, i_key_p, i_deep_const_get;
82
+ i_array_class, i_key_p, i_deep_const_get, i_match, i_match_string;
83
83
 
84
84
 
85
85
  #line 108 "parser.rl"
@@ -94,7 +94,7 @@ static const int JSON_object_error = 0;
94
94
  static const int JSON_object_en_main = 1;
95
95
 
96
96
 
97
- #line 143 "parser.rl"
97
+ #line 144 "parser.rl"
98
98
 
99
99
 
100
100
  static char *JSON_parse_object(JSON_Parser *json, char *p, char *pe, VALUE *result)
@@ -115,7 +115,7 @@ static char *JSON_parse_object(JSON_Parser *json, char *p, char *pe, VALUE *resu
115
115
  cs = JSON_object_start;
116
116
  }
117
117
 
118
- #line 158 "parser.rl"
118
+ #line 159 "parser.rl"
119
119
 
120
120
  #line 121 "parser.c"
121
121
  {
@@ -158,7 +158,7 @@ st3:
158
158
  if ( ++p == pe )
159
159
  goto _test_eof3;
160
160
  case 3:
161
- #line 161 "parser.c"
161
+ #line 162 "parser.c"
162
162
  switch( (*p) ) {
163
163
  case 13: goto st3;
164
164
  case 32: goto st3;
@@ -241,7 +241,7 @@ st9:
241
241
  if ( ++p == pe )
242
242
  goto _test_eof9;
243
243
  case 9:
244
- #line 244 "parser.c"
244
+ #line 245 "parser.c"
245
245
  switch( (*p) ) {
246
246
  case 13: goto st9;
247
247
  case 32: goto st9;
@@ -330,14 +330,14 @@ case 18:
330
330
  goto st9;
331
331
  goto st18;
332
332
  tr4:
333
- #line 134 "parser.rl"
333
+ #line 135 "parser.rl"
334
334
  { p--; {p++; cs = 27; goto _out;} }
335
335
  goto st27;
336
336
  st27:
337
337
  if ( ++p == pe )
338
338
  goto _test_eof27;
339
339
  case 27:
340
- #line 340 "parser.c"
340
+ #line 341 "parser.c"
341
341
  goto st0;
342
342
  st19:
343
343
  if ( ++p == pe )
@@ -435,14 +435,14 @@ case 26:
435
435
  _out: {}
436
436
  }
437
437
 
438
- #line 159 "parser.rl"
438
+ #line 160 "parser.rl"
439
439
 
440
440
  if (cs >= JSON_object_first_final) {
441
- if (RTEST(json->create_id)) {
441
+ if (json->create_additions) {
442
442
  VALUE klassname = rb_hash_aref(*result, json->create_id);
443
443
  if (!NIL_P(klassname)) {
444
444
  VALUE klass = rb_funcall(mJSON, i_deep_const_get, 1, klassname);
445
- if RTEST(rb_funcall(klass, i_json_creatable_p, 0)) {
445
+ if (RTEST(rb_funcall(klass, i_json_creatable_p, 0))) {
446
446
  *result = rb_funcall(klass, i_json_create, 1, *result);
447
447
  }
448
448
  }
@@ -454,7 +454,7 @@ case 26:
454
454
  }
455
455
 
456
456
 
457
- #line 457 "parser.c"
457
+ #line 458 "parser.c"
458
458
  static const int JSON_value_start = 1;
459
459
  static const int JSON_value_first_final = 21;
460
460
  static const int JSON_value_error = 0;
@@ -462,7 +462,7 @@ static const int JSON_value_error = 0;
462
462
  static const int JSON_value_en_main = 1;
463
463
 
464
464
 
465
- #line 257 "parser.rl"
465
+ #line 258 "parser.rl"
466
466
 
467
467
 
468
468
  static char *JSON_parse_value(JSON_Parser *json, char *p, char *pe, VALUE *result)
@@ -470,14 +470,14 @@ static char *JSON_parse_value(JSON_Parser *json, char *p, char *pe, VALUE *resul
470
470
  int cs = EVIL;
471
471
 
472
472
 
473
- #line 473 "parser.c"
473
+ #line 474 "parser.c"
474
474
  {
475
475
  cs = JSON_value_start;
476
476
  }
477
477
 
478
- #line 264 "parser.rl"
478
+ #line 265 "parser.rl"
479
479
 
480
- #line 480 "parser.c"
480
+ #line 481 "parser.c"
481
481
  {
482
482
  if ( p == pe )
483
483
  goto _test_eof;
@@ -502,14 +502,14 @@ st0:
502
502
  cs = 0;
503
503
  goto _out;
504
504
  tr0:
505
- #line 205 "parser.rl"
505
+ #line 206 "parser.rl"
506
506
  {
507
507
  char *np = JSON_parse_string(json, p, pe, result);
508
508
  if (np == NULL) { p--; {p++; cs = 21; goto _out;} } else {p = (( np))-1;}
509
509
  }
510
510
  goto st21;
511
511
  tr2:
512
- #line 210 "parser.rl"
512
+ #line 211 "parser.rl"
513
513
  {
514
514
  char *np;
515
515
  if(pe > p + 9 && !strncmp(MinusInfinity, p, 9)) {
@@ -529,7 +529,7 @@ tr2:
529
529
  }
530
530
  goto st21;
531
531
  tr5:
532
- #line 228 "parser.rl"
532
+ #line 229 "parser.rl"
533
533
  {
534
534
  char *np;
535
535
  json->current_nesting++;
@@ -539,7 +539,7 @@ tr5:
539
539
  }
540
540
  goto st21;
541
541
  tr9:
542
- #line 236 "parser.rl"
542
+ #line 237 "parser.rl"
543
543
  {
544
544
  char *np;
545
545
  json->current_nesting++;
@@ -549,7 +549,7 @@ tr9:
549
549
  }
550
550
  goto st21;
551
551
  tr16:
552
- #line 198 "parser.rl"
552
+ #line 199 "parser.rl"
553
553
  {
554
554
  if (json->allow_nan) {
555
555
  *result = CInfinity;
@@ -559,7 +559,7 @@ tr16:
559
559
  }
560
560
  goto st21;
561
561
  tr18:
562
- #line 191 "parser.rl"
562
+ #line 192 "parser.rl"
563
563
  {
564
564
  if (json->allow_nan) {
565
565
  *result = CNaN;
@@ -569,19 +569,19 @@ tr18:
569
569
  }
570
570
  goto st21;
571
571
  tr22:
572
- #line 185 "parser.rl"
572
+ #line 186 "parser.rl"
573
573
  {
574
574
  *result = Qfalse;
575
575
  }
576
576
  goto st21;
577
577
  tr25:
578
- #line 182 "parser.rl"
578
+ #line 183 "parser.rl"
579
579
  {
580
580
  *result = Qnil;
581
581
  }
582
582
  goto st21;
583
583
  tr28:
584
- #line 188 "parser.rl"
584
+ #line 189 "parser.rl"
585
585
  {
586
586
  *result = Qtrue;
587
587
  }
@@ -590,9 +590,9 @@ st21:
590
590
  if ( ++p == pe )
591
591
  goto _test_eof21;
592
592
  case 21:
593
- #line 244 "parser.rl"
593
+ #line 245 "parser.rl"
594
594
  { p--; {p++; cs = 21; goto _out;} }
595
- #line 595 "parser.c"
595
+ #line 596 "parser.c"
596
596
  goto st0;
597
597
  st2:
598
598
  if ( ++p == pe )
@@ -753,7 +753,7 @@ case 20:
753
753
  _out: {}
754
754
  }
755
755
 
756
- #line 265 "parser.rl"
756
+ #line 266 "parser.rl"
757
757
 
758
758
  if (cs >= JSON_value_first_final) {
759
759
  return p;
@@ -763,7 +763,7 @@ case 20:
763
763
  }
764
764
 
765
765
 
766
- #line 766 "parser.c"
766
+ #line 767 "parser.c"
767
767
  static const int JSON_integer_start = 1;
768
768
  static const int JSON_integer_first_final = 5;
769
769
  static const int JSON_integer_error = 0;
@@ -771,7 +771,7 @@ static const int JSON_integer_error = 0;
771
771
  static const int JSON_integer_en_main = 1;
772
772
 
773
773
 
774
- #line 281 "parser.rl"
774
+ #line 282 "parser.rl"
775
775
 
776
776
 
777
777
  static char *JSON_parse_integer(JSON_Parser *json, char *p, char *pe, VALUE *result)
@@ -779,15 +779,15 @@ static char *JSON_parse_integer(JSON_Parser *json, char *p, char *pe, VALUE *res
779
779
  int cs = EVIL;
780
780
 
781
781
 
782
- #line 782 "parser.c"
782
+ #line 783 "parser.c"
783
783
  {
784
784
  cs = JSON_integer_start;
785
785
  }
786
786
 
787
- #line 288 "parser.rl"
787
+ #line 289 "parser.rl"
788
788
  json->memo = p;
789
789
 
790
- #line 790 "parser.c"
790
+ #line 791 "parser.c"
791
791
  {
792
792
  if ( p == pe )
793
793
  goto _test_eof;
@@ -821,14 +821,14 @@ case 3:
821
821
  goto st0;
822
822
  goto tr4;
823
823
  tr4:
824
- #line 278 "parser.rl"
824
+ #line 279 "parser.rl"
825
825
  { p--; {p++; cs = 5; goto _out;} }
826
826
  goto st5;
827
827
  st5:
828
828
  if ( ++p == pe )
829
829
  goto _test_eof5;
830
830
  case 5:
831
- #line 831 "parser.c"
831
+ #line 832 "parser.c"
832
832
  goto st0;
833
833
  st4:
834
834
  if ( ++p == pe )
@@ -847,7 +847,7 @@ case 4:
847
847
  _out: {}
848
848
  }
849
849
 
850
- #line 290 "parser.rl"
850
+ #line 291 "parser.rl"
851
851
 
852
852
  if (cs >= JSON_integer_first_final) {
853
853
  long len = p - json->memo;
@@ -859,7 +859,7 @@ case 4:
859
859
  }
860
860
 
861
861
 
862
- #line 862 "parser.c"
862
+ #line 863 "parser.c"
863
863
  static const int JSON_float_start = 1;
864
864
  static const int JSON_float_first_final = 10;
865
865
  static const int JSON_float_error = 0;
@@ -867,7 +867,7 @@ static const int JSON_float_error = 0;
867
867
  static const int JSON_float_en_main = 1;
868
868
 
869
869
 
870
- #line 312 "parser.rl"
870
+ #line 313 "parser.rl"
871
871
 
872
872
 
873
873
  static char *JSON_parse_float(JSON_Parser *json, char *p, char *pe, VALUE *result)
@@ -875,15 +875,15 @@ static char *JSON_parse_float(JSON_Parser *json, char *p, char *pe, VALUE *resul
875
875
  int cs = EVIL;
876
876
 
877
877
 
878
- #line 878 "parser.c"
878
+ #line 879 "parser.c"
879
879
  {
880
880
  cs = JSON_float_start;
881
881
  }
882
882
 
883
- #line 319 "parser.rl"
883
+ #line 320 "parser.rl"
884
884
  json->memo = p;
885
885
 
886
- #line 886 "parser.c"
886
+ #line 887 "parser.c"
887
887
  {
888
888
  if ( p == pe )
889
889
  goto _test_eof;
@@ -941,14 +941,14 @@ case 5:
941
941
  goto st0;
942
942
  goto tr7;
943
943
  tr7:
944
- #line 306 "parser.rl"
944
+ #line 307 "parser.rl"
945
945
  { p--; {p++; cs = 10; goto _out;} }
946
946
  goto st10;
947
947
  st10:
948
948
  if ( ++p == pe )
949
949
  goto _test_eof10;
950
950
  case 10:
951
- #line 951 "parser.c"
951
+ #line 952 "parser.c"
952
952
  goto st0;
953
953
  st6:
954
954
  if ( ++p == pe )
@@ -1009,7 +1009,7 @@ case 9:
1009
1009
  _out: {}
1010
1010
  }
1011
1011
 
1012
- #line 321 "parser.rl"
1012
+ #line 322 "parser.rl"
1013
1013
 
1014
1014
  if (cs >= JSON_float_first_final) {
1015
1015
  long len = p - json->memo;
@@ -1022,7 +1022,7 @@ case 9:
1022
1022
 
1023
1023
 
1024
1024
 
1025
- #line 1025 "parser.c"
1025
+ #line 1026 "parser.c"
1026
1026
  static const int JSON_array_start = 1;
1027
1027
  static const int JSON_array_first_final = 17;
1028
1028
  static const int JSON_array_error = 0;
@@ -1030,7 +1030,7 @@ static const int JSON_array_error = 0;
1030
1030
  static const int JSON_array_en_main = 1;
1031
1031
 
1032
1032
 
1033
- #line 357 "parser.rl"
1033
+ #line 358 "parser.rl"
1034
1034
 
1035
1035
 
1036
1036
  static char *JSON_parse_array(JSON_Parser *json, char *p, char *pe, VALUE *result)
@@ -1044,14 +1044,14 @@ static char *JSON_parse_array(JSON_Parser *json, char *p, char *pe, VALUE *resul
1044
1044
  *result = NIL_P(array_class) ? rb_ary_new() : rb_class_new_instance(0, 0, array_class);
1045
1045
 
1046
1046
 
1047
- #line 1047 "parser.c"
1047
+ #line 1048 "parser.c"
1048
1048
  {
1049
1049
  cs = JSON_array_start;
1050
1050
  }
1051
1051
 
1052
- #line 370 "parser.rl"
1052
+ #line 371 "parser.rl"
1053
1053
 
1054
- #line 1054 "parser.c"
1054
+ #line 1055 "parser.c"
1055
1055
  {
1056
1056
  if ( p == pe )
1057
1057
  goto _test_eof;
@@ -1090,7 +1090,7 @@ case 2:
1090
1090
  goto st2;
1091
1091
  goto st0;
1092
1092
  tr2:
1093
- #line 338 "parser.rl"
1093
+ #line 339 "parser.rl"
1094
1094
  {
1095
1095
  VALUE v = Qnil;
1096
1096
  char *np = JSON_parse_value(json, p, pe, &v);
@@ -1106,7 +1106,7 @@ st3:
1106
1106
  if ( ++p == pe )
1107
1107
  goto _test_eof3;
1108
1108
  case 3:
1109
- #line 1109 "parser.c"
1109
+ #line 1110 "parser.c"
1110
1110
  switch( (*p) ) {
1111
1111
  case 13: goto st3;
1112
1112
  case 32: goto st3;
@@ -1206,14 +1206,14 @@ case 12:
1206
1206
  goto st3;
1207
1207
  goto st12;
1208
1208
  tr4:
1209
- #line 349 "parser.rl"
1209
+ #line 350 "parser.rl"
1210
1210
  { p--; {p++; cs = 17; goto _out;} }
1211
1211
  goto st17;
1212
1212
  st17:
1213
1213
  if ( ++p == pe )
1214
1214
  goto _test_eof17;
1215
1215
  case 17:
1216
- #line 1216 "parser.c"
1216
+ #line 1217 "parser.c"
1217
1217
  goto st0;
1218
1218
  st13:
1219
1219
  if ( ++p == pe )
@@ -1269,7 +1269,7 @@ case 16:
1269
1269
  _out: {}
1270
1270
  }
1271
1271
 
1272
- #line 371 "parser.rl"
1272
+ #line 372 "parser.rl"
1273
1273
 
1274
1274
  if(cs >= JSON_array_first_final) {
1275
1275
  return p + 1;
@@ -1350,7 +1350,7 @@ static VALUE json_string_unescape(VALUE result, char *string, char *stringEnd)
1350
1350
  }
1351
1351
 
1352
1352
 
1353
- #line 1353 "parser.c"
1353
+ #line 1354 "parser.c"
1354
1354
  static const int JSON_string_start = 1;
1355
1355
  static const int JSON_string_first_final = 8;
1356
1356
  static const int JSON_string_error = 0;
@@ -1358,24 +1358,37 @@ static const int JSON_string_error = 0;
1358
1358
  static const int JSON_string_en_main = 1;
1359
1359
 
1360
1360
 
1361
- #line 470 "parser.rl"
1361
+ #line 471 "parser.rl"
1362
1362
 
1363
1363
 
1364
+ static int
1365
+ match_i(VALUE regexp, VALUE klass, VALUE memo)
1366
+ {
1367
+ if (regexp == Qundef) return ST_STOP;
1368
+ if (RTEST(rb_funcall(klass, i_json_creatable_p, 0)) &&
1369
+ RTEST(rb_funcall(regexp, i_match, 1, rb_ary_entry(memo, 0)))) {
1370
+ rb_ary_push(memo, klass);
1371
+ return ST_STOP;
1372
+ }
1373
+ return ST_CONTINUE;
1374
+ }
1375
+
1364
1376
  static char *JSON_parse_string(JSON_Parser *json, char *p, char *pe, VALUE *result)
1365
1377
  {
1366
1378
  int cs = EVIL;
1379
+ VALUE match_string;
1367
1380
 
1368
1381
  *result = rb_str_buf_new(0);
1369
1382
 
1370
- #line 1370 "parser.c"
1383
+ #line 1384 "parser.c"
1371
1384
  {
1372
1385
  cs = JSON_string_start;
1373
1386
  }
1374
1387
 
1375
- #line 478 "parser.rl"
1388
+ #line 492 "parser.rl"
1376
1389
  json->memo = p;
1377
1390
 
1378
- #line 1378 "parser.c"
1391
+ #line 1392 "parser.c"
1379
1392
  {
1380
1393
  if ( p == pe )
1381
1394
  goto _test_eof;
@@ -1400,25 +1413,25 @@ case 2:
1400
1413
  goto st0;
1401
1414
  goto st2;
1402
1415
  tr2:
1403
- #line 456 "parser.rl"
1416
+ #line 457 "parser.rl"
1404
1417
  {
1405
1418
  *result = json_string_unescape(*result, json->memo + 1, p);
1406
1419
  if (NIL_P(*result)) {
1407
- p--;
1408
- {p++; cs = 8; goto _out;}
1409
- } else {
1410
- FORCE_UTF8(*result);
1411
- {p = (( p + 1))-1;}
1412
- }
1413
- }
1414
- #line 467 "parser.rl"
1420
+ p--;
1421
+ {p++; cs = 8; goto _out;}
1422
+ } else {
1423
+ FORCE_UTF8(*result);
1424
+ {p = (( p + 1))-1;}
1425
+ }
1426
+ }
1427
+ #line 468 "parser.rl"
1415
1428
  { p--; {p++; cs = 8; goto _out;} }
1416
1429
  goto st8;
1417
1430
  st8:
1418
1431
  if ( ++p == pe )
1419
1432
  goto _test_eof8;
1420
1433
  case 8:
1421
- #line 1421 "parser.c"
1434
+ #line 1435 "parser.c"
1422
1435
  goto st0;
1423
1436
  st3:
1424
1437
  if ( ++p == pe )
@@ -1494,7 +1507,18 @@ case 7:
1494
1507
  _out: {}
1495
1508
  }
1496
1509
 
1497
- #line 480 "parser.rl"
1510
+ #line 494 "parser.rl"
1511
+
1512
+ if (json->create_additions && RTEST(match_string = json->match_string)) {
1513
+ VALUE klass;
1514
+ VALUE memo = rb_ary_new2(2);
1515
+ rb_ary_push(memo, *result);
1516
+ rb_hash_foreach(match_string, match_i, memo);
1517
+ klass = rb_ary_entry(memo, 1);
1518
+ if (RTEST(klass)) {
1519
+ *result = rb_funcall(klass, i_json_create, 1, *result);
1520
+ }
1521
+ }
1498
1522
 
1499
1523
  if (json->symbolize_names && json->parsing_name) {
1500
1524
  *result = rb_str_intern(*result);
@@ -1508,7 +1532,7 @@ case 7:
1508
1532
 
1509
1533
 
1510
1534
 
1511
- #line 1511 "parser.c"
1535
+ #line 1536 "parser.c"
1512
1536
  static const int JSON_start = 1;
1513
1537
  static const int JSON_first_final = 10;
1514
1538
  static const int JSON_error = 0;
@@ -1516,7 +1540,7 @@ static const int JSON_error = 0;
1516
1540
  static const int JSON_en_main = 1;
1517
1541
 
1518
1542
 
1519
- #line 517 "parser.rl"
1543
+ #line 542 "parser.rl"
1520
1544
 
1521
1545
 
1522
1546
  /*
@@ -1634,26 +1658,25 @@ static VALUE cParser_initialize(int argc, VALUE *argv, VALUE self)
1634
1658
  }
1635
1659
  tmp = ID2SYM(i_allow_nan);
1636
1660
  if (option_given_p(opts, tmp)) {
1637
- VALUE allow_nan = rb_hash_aref(opts, tmp);
1638
- json->allow_nan = RTEST(allow_nan) ? 1 : 0;
1661
+ json->allow_nan = RTEST(rb_hash_aref(opts, tmp)) ? 1 : 0;
1639
1662
  } else {
1640
1663
  json->allow_nan = 0;
1641
1664
  }
1642
1665
  tmp = ID2SYM(i_symbolize_names);
1643
1666
  if (option_given_p(opts, tmp)) {
1644
- VALUE symbolize_names = rb_hash_aref(opts, tmp);
1645
- json->symbolize_names = RTEST(symbolize_names) ? 1 : 0;
1667
+ json->symbolize_names = RTEST(rb_hash_aref(opts, tmp)) ? 1 : 0;
1646
1668
  } else {
1647
1669
  json->symbolize_names = 0;
1648
1670
  }
1649
1671
  tmp = ID2SYM(i_create_additions);
1650
1672
  if (option_given_p(opts, tmp)) {
1651
- VALUE create_additions = rb_hash_aref(opts, tmp);
1652
- if (RTEST(create_additions)) {
1653
- json->create_id = rb_funcall(mJSON, i_create_id, 0);
1654
- } else {
1655
- json->create_id = Qnil;
1656
- }
1673
+ json->create_additions = RTEST(rb_hash_aref(opts, tmp));
1674
+ } else {
1675
+ json->create_additions = 1;
1676
+ }
1677
+ tmp = ID2SYM(i_create_id);
1678
+ if (option_given_p(opts, tmp)) {
1679
+ json->create_id = rb_hash_aref(opts, tmp);
1657
1680
  } else {
1658
1681
  json->create_id = rb_funcall(mJSON, i_create_id, 0);
1659
1682
  }
@@ -1669,10 +1692,18 @@ static VALUE cParser_initialize(int argc, VALUE *argv, VALUE self)
1669
1692
  } else {
1670
1693
  json->array_class = Qnil;
1671
1694
  }
1695
+ tmp = ID2SYM(i_match_string);
1696
+ if (option_given_p(opts, tmp)) {
1697
+ VALUE match_string = rb_hash_aref(opts, tmp);
1698
+ json->match_string = RTEST(match_string) ? match_string : Qnil;
1699
+ } else {
1700
+ json->match_string = Qnil;
1701
+ }
1672
1702
  }
1673
1703
  } else {
1674
1704
  json->max_nesting = 19;
1675
1705
  json->allow_nan = 0;
1706
+ json->create_additions = 1;
1676
1707
  json->create_id = rb_funcall(mJSON, i_create_id, 0);
1677
1708
  json->object_class = Qnil;
1678
1709
  json->array_class = Qnil;
@@ -1698,16 +1729,16 @@ static VALUE cParser_parse(VALUE self)
1698
1729
  GET_PARSER;
1699
1730
 
1700
1731
 
1701
- #line 1701 "parser.c"
1732
+ #line 1733 "parser.c"
1702
1733
  {
1703
1734
  cs = JSON_start;
1704
1735
  }
1705
1736
 
1706
- #line 698 "parser.rl"
1737
+ #line 730 "parser.rl"
1707
1738
  p = json->source;
1708
1739
  pe = p + json->len;
1709
1740
 
1710
- #line 1710 "parser.c"
1741
+ #line 1742 "parser.c"
1711
1742
  {
1712
1743
  if ( p == pe )
1713
1744
  goto _test_eof;
@@ -1763,7 +1794,7 @@ case 5:
1763
1794
  goto st1;
1764
1795
  goto st5;
1765
1796
  tr3:
1766
- #line 506 "parser.rl"
1797
+ #line 531 "parser.rl"
1767
1798
  {
1768
1799
  char *np;
1769
1800
  json->current_nesting = 1;
@@ -1772,7 +1803,7 @@ tr3:
1772
1803
  }
1773
1804
  goto st10;
1774
1805
  tr4:
1775
- #line 499 "parser.rl"
1806
+ #line 524 "parser.rl"
1776
1807
  {
1777
1808
  char *np;
1778
1809
  json->current_nesting = 1;
@@ -1784,7 +1815,7 @@ st10:
1784
1815
  if ( ++p == pe )
1785
1816
  goto _test_eof10;
1786
1817
  case 10:
1787
- #line 1787 "parser.c"
1818
+ #line 1819 "parser.c"
1788
1819
  switch( (*p) ) {
1789
1820
  case 13: goto st10;
1790
1821
  case 32: goto st10;
@@ -1841,7 +1872,7 @@ case 9:
1841
1872
  _out: {}
1842
1873
  }
1843
1874
 
1844
- #line 701 "parser.rl"
1875
+ #line 733 "parser.rl"
1845
1876
 
1846
1877
  if (cs >= JSON_first_final && p == pe) {
1847
1878
  return result;
@@ -1864,6 +1895,7 @@ static void JSON_mark(JSON_Parser *json)
1864
1895
  rb_gc_mark_maybe(json->create_id);
1865
1896
  rb_gc_mark_maybe(json->object_class);
1866
1897
  rb_gc_mark_maybe(json->array_class);
1898
+ rb_gc_mark_maybe(json->match_string);
1867
1899
  }
1868
1900
 
1869
1901
  static void JSON_free(JSON_Parser *json)
@@ -1916,6 +1948,8 @@ void Init_parser()
1916
1948
  i_symbolize_names = rb_intern("symbolize_names");
1917
1949
  i_object_class = rb_intern("object_class");
1918
1950
  i_array_class = rb_intern("array_class");
1951
+ i_match = rb_intern("match");
1952
+ i_match_string = rb_intern("match_string");
1919
1953
  i_key_p = rb_intern("key?");
1920
1954
  i_deep_const_get = rb_intern("deep_const_get");
1921
1955
  #ifdef HAVE_RUBY_ENCODING_H