json_pure 1.4.6 → 1.5.0

Sign up to get free protection for your applications and to get access to all the features.
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