json 2.3.1 → 2.4.0

This diff represents the content of publicly available package versions that have been released to one of the supported registries. The information contained in this diff is provided for informational purposes only and reflects changes between package versions as they appear in their respective public registries.
@@ -37,6 +37,7 @@ typedef struct JSON_ParserStruct {
37
37
  int allow_nan;
38
38
  int parsing_name;
39
39
  int symbolize_names;
40
+ int freeze;
40
41
  VALUE object_class;
41
42
  VALUE array_class;
42
43
  VALUE decimal_class;
@@ -95,7 +95,7 @@ static ID i_json_creatable_p, i_json_create, i_create_id, i_create_additions,
95
95
  i_chr, i_max_nesting, i_allow_nan, i_symbolize_names,
96
96
  i_object_class, i_array_class, i_decimal_class, i_key_p,
97
97
  i_deep_const_get, i_match, i_match_string, i_aset, i_aref,
98
- i_leftshift, i_new, i_BigDecimal;
98
+ i_leftshift, i_new, i_BigDecimal, i_freeze, i_uminus;
99
99
 
100
100
  %%{
101
101
  machine JSON_common;
@@ -290,6 +290,10 @@ static char *JSON_parse_value(JSON_Parser *json, char *p, char *pe, VALUE *resul
290
290
  %% write init;
291
291
  %% write exec;
292
292
 
293
+ if (json->freeze) {
294
+ OBJ_FREEZE(*result);
295
+ }
296
+
293
297
  if (cs >= JSON_value_first_final) {
294
298
  return p;
295
299
  } else {
@@ -573,7 +577,22 @@ static char *JSON_parse_string(JSON_Parser *json, char *p, char *pe, VALUE *resu
573
577
  if (json->symbolize_names && json->parsing_name) {
574
578
  *result = rb_str_intern(*result);
575
579
  } else if (RB_TYPE_P(*result, T_STRING)) {
580
+ # if STR_UMINUS_DEDUPE_FROZEN
581
+ if (json->freeze) {
582
+ // Starting from MRI 2.8 it is preferable to freeze the string
583
+ // before deduplication so that it can be interned directly
584
+ // otherwise it would be duplicated first which is wasteful.
585
+ *result = rb_funcall(rb_str_freeze(*result), i_uminus, 0);
586
+ }
587
+ # elif STR_UMINUS_DEDUPE
588
+ if (json->freeze) {
589
+ // MRI 2.5 and older do not deduplicate strings that are already
590
+ // frozen.
591
+ *result = rb_funcall(*result, i_uminus, 0);
592
+ }
593
+ # else
576
594
  rb_str_resize(*result, RSTRING_LEN(*result));
595
+ # endif
577
596
  }
578
597
  if (cs >= JSON_string_first_final) {
579
598
  return p + 1;
@@ -681,6 +700,12 @@ static VALUE cParser_initialize(int argc, VALUE *argv, VALUE self)
681
700
  } else {
682
701
  json->symbolize_names = 0;
683
702
  }
703
+ tmp = ID2SYM(i_freeze);
704
+ if (option_given_p(opts, tmp)) {
705
+ json->freeze = RTEST(rb_hash_aref(opts, tmp)) ? 1 : 0;
706
+ } else {
707
+ json->freeze = 0;
708
+ }
684
709
  tmp = ID2SYM(i_create_additions);
685
710
  if (option_given_p(opts, tmp)) {
686
711
  json->create_additions = RTEST(rb_hash_aref(opts, tmp));
@@ -886,6 +911,8 @@ void Init_parser(void)
886
911
  i_leftshift = rb_intern("<<");
887
912
  i_new = rb_intern("new");
888
913
  i_BigDecimal = rb_intern("BigDecimal");
914
+ i_freeze = rb_intern("freeze");
915
+ i_uminus = rb_intern("-@");
889
916
  }
890
917
 
891
918
  /*
@@ -1,2 +1,3 @@
1
1
  require 'mkmf'
2
+
2
3
  create_makefile('json')
@@ -10,13 +10,10 @@ import org.jruby.RubyArray;
10
10
  import org.jruby.RubyBasicObject;
11
11
  import org.jruby.RubyBignum;
12
12
  import org.jruby.RubyBoolean;
13
- import org.jruby.RubyClass;
14
13
  import org.jruby.RubyFixnum;
15
14
  import org.jruby.RubyFloat;
16
15
  import org.jruby.RubyHash;
17
- import org.jruby.RubyNumeric;
18
16
  import org.jruby.RubyString;
19
- import org.jruby.runtime.ClassIndex;
20
17
  import org.jruby.runtime.ThreadContext;
21
18
  import org.jruby.runtime.builtin.IRubyObject;
22
19
  import org.jruby.util.ByteList;
@@ -32,8 +29,7 @@ public final class Generator {
32
29
  static <T extends IRubyObject> RubyString
33
30
  generateJson(ThreadContext context, T object,
34
31
  Handler<? super T> handler, IRubyObject[] args) {
35
- Session session = new Session(context, args.length > 0 ? args[0]
36
- : null);
32
+ Session session = new Session(context, args.length > 0 ? args[0] : null);
37
33
  return session.infect(handler.generateNew(session, object));
38
34
  }
39
35
 
@@ -43,7 +39,7 @@ public final class Generator {
43
39
  */
44
40
  static <T extends IRubyObject> RubyString
45
41
  generateJson(ThreadContext context, T object, IRubyObject[] args) {
46
- Handler<? super T> handler = getHandlerFor(context.getRuntime(), object);
42
+ Handler<? super T> handler = getHandlerFor(context.runtime, object);
47
43
  return generateJson(context, object, handler, args);
48
44
  }
49
45
 
@@ -55,33 +51,18 @@ public final class Generator {
55
51
  generateJson(ThreadContext context, T object,
56
52
  GeneratorState config) {
57
53
  Session session = new Session(context, config);
58
- Handler<? super T> handler = getHandlerFor(context.getRuntime(), object);
54
+ Handler<? super T> handler = getHandlerFor(context.runtime, object);
59
55
  return handler.generateNew(session, object);
60
56
  }
61
57
 
62
- // NOTE: drop this once Ruby 1.9.3 support is gone!
63
- private static final int FIXNUM = 1;
64
- private static final int BIGNUM = 2;
65
- private static final int ARRAY = 3;
66
- private static final int STRING = 4;
67
- private static final int NIL = 5;
68
- private static final int TRUE = 6;
69
- private static final int FALSE = 7;
70
- private static final int HASH = 10;
71
- private static final int FLOAT = 11;
72
- // hard-coded due JRuby 1.7 compatibility
73
- // https://github.com/jruby/jruby/blob/1.7.27/core/src/main/java/org/jruby/runtime/ClassIndex.java
74
-
75
58
  /**
76
59
  * Returns the best serialization handler for the given object.
77
60
  */
78
61
  // Java's generics can't handle this satisfactorily, so I'll just leave
79
62
  // the best I could get and ignore the warnings
80
63
  @SuppressWarnings("unchecked")
81
- private static <T extends IRubyObject>
82
- Handler<? super T> getHandlerFor(Ruby runtime, T object) {
83
- switch (((RubyBasicObject) object).getNativeTypeIndex()) {
84
- // can not use getNativeClassIndex due 1.7 compatibility
64
+ private static <T extends IRubyObject> Handler<? super T> getHandlerFor(Ruby runtime, T object) {
65
+ switch (((RubyBasicObject) object).getNativeClassIndex()) {
85
66
  case NIL : return (Handler) NIL_HANDLER;
86
67
  case TRUE : return (Handler) TRUE_HANDLER;
87
68
  case FALSE : return (Handler) FALSE_HANDLER;
@@ -158,7 +139,7 @@ public final class Generator {
158
139
 
159
140
  public StringEncoder getStringEncoder() {
160
141
  if (stringEncoder == null) {
161
- stringEncoder = new StringEncoder(context, getState().asciiOnly());
142
+ stringEncoder = new StringEncoder(context, getState().asciiOnly(), getState().escapeSlash());
162
143
  }
163
144
  return stringEncoder;
164
145
  }
@@ -353,13 +334,13 @@ public final class Generator {
353
334
 
354
335
  buffer.append((byte)'{');
355
336
  buffer.append(objectNl);
356
- object.visitAll(new RubyHash.Visitor() {
357
- private boolean firstPair = true;
358
337
 
338
+ final boolean[] firstPair = new boolean[]{true};
339
+ object.visitAll(new RubyHash.Visitor() {
359
340
  @Override
360
341
  public void visit(IRubyObject key, IRubyObject value) {
361
- if (firstPair) {
362
- firstPair = false;
342
+ if (firstPair[0]) {
343
+ firstPair[0] = false;
363
344
  } else {
364
345
  buffer.append((byte)',');
365
346
  buffer.append(objectNl);
@@ -379,7 +360,7 @@ public final class Generator {
379
360
  }
380
361
  });
381
362
  state.decreaseDepth();
382
- if (objectNl.length() != 0) {
363
+ if (!firstPair[0] && objectNl.length() != 0) {
383
364
  buffer.append(objectNl);
384
365
  buffer.append(Utils.repeat(state.getIndent(), state.getDepth()));
385
366
  }
@@ -82,6 +82,12 @@ public class GeneratorState extends RubyObject {
82
82
  */
83
83
  private boolean quirksMode = DEFAULT_QUIRKS_MODE;
84
84
  static final boolean DEFAULT_QUIRKS_MODE = false;
85
+ /**
86
+ * If set to <code>true</code> the forward slash will be escaped in
87
+ * json output.
88
+ */
89
+ private boolean escapeSlash = DEFAULT_ESCAPE_SLASH;
90
+ static final boolean DEFAULT_ESCAPE_SLASH = false;
85
91
  /**
86
92
  * The initial buffer length of this state. (This isn't really used on all
87
93
  * non-C implementations.)
@@ -171,6 +177,9 @@ public class GeneratorState extends RubyObject {
171
177
  * <code>-Infinity</code> should be generated, otherwise an exception is
172
178
  * thrown if these values are encountered.
173
179
  * This options defaults to <code>false</code>.
180
+ * <dt><code>:escape_slash</code>
181
+ * <dd>set to <code>true</code> if the forward slashes should be escaped
182
+ * in the json output (default: <code>false</code>)
174
183
  */
175
184
  @JRubyMethod(optional=1, visibility=Visibility.PRIVATE)
176
185
  public IRubyObject initialize(ThreadContext context, IRubyObject[] args) {
@@ -194,6 +203,7 @@ public class GeneratorState extends RubyObject {
194
203
  this.allowNaN = orig.allowNaN;
195
204
  this.asciiOnly = orig.asciiOnly;
196
205
  this.quirksMode = orig.quirksMode;
206
+ this.escapeSlash = orig.escapeSlash;
197
207
  this.bufferInitialLength = orig.bufferInitialLength;
198
208
  this.depth = orig.depth;
199
209
  return this;
@@ -346,6 +356,24 @@ public class GeneratorState extends RubyObject {
346
356
  return max_nesting;
347
357
  }
348
358
 
359
+ /**
360
+ * Returns true if forward slashes are escaped in the json output.
361
+ */
362
+ public boolean escapeSlash() {
363
+ return escapeSlash;
364
+ }
365
+
366
+ @JRubyMethod(name="escape_slash")
367
+ public RubyBoolean escape_slash_get(ThreadContext context) {
368
+ return context.getRuntime().newBoolean(escapeSlash);
369
+ }
370
+
371
+ @JRubyMethod(name="escape_slash=")
372
+ public IRubyObject escape_slash_set(IRubyObject escape_slash) {
373
+ escapeSlash = escape_slash.isTrue();
374
+ return escape_slash.getRuntime().newBoolean(escapeSlash);
375
+ }
376
+
349
377
  public boolean allowNaN() {
350
378
  return allowNaN;
351
379
  }
@@ -430,6 +458,7 @@ public class GeneratorState extends RubyObject {
430
458
  maxNesting = opts.getInt("max_nesting", DEFAULT_MAX_NESTING);
431
459
  allowNaN = opts.getBool("allow_nan", DEFAULT_ALLOW_NAN);
432
460
  asciiOnly = opts.getBool("ascii_only", DEFAULT_ASCII_ONLY);
461
+ escapeSlash = opts.getBool("escape_slash", DEFAULT_ESCAPE_SLASH);
433
462
  bufferInitialLength = opts.getInt("buffer_initial_length", DEFAULT_BUFFER_INITIAL_LENGTH);
434
463
 
435
464
  depth = opts.getInt("depth", 0);
@@ -457,6 +486,7 @@ public class GeneratorState extends RubyObject {
457
486
  result.op_aset(context, runtime.newSymbol("allow_nan"), allow_nan_p(context));
458
487
  result.op_aset(context, runtime.newSymbol("ascii_only"), ascii_only_p(context));
459
488
  result.op_aset(context, runtime.newSymbol("max_nesting"), max_nesting_get(context));
489
+ result.op_aset(context, runtime.newSymbol("escape_slash"), escape_slash_get(context));
460
490
  result.op_aset(context, runtime.newSymbol("depth"), depth_get(context));
461
491
  result.op_aset(context, runtime.newSymbol("buffer_initial_length"), buffer_initial_length_get(context));
462
492
  for (String name: getInstanceVariableNameList()) {
@@ -52,6 +52,7 @@ public class Parser extends RubyObject {
52
52
  private int maxNesting;
53
53
  private boolean allowNaN;
54
54
  private boolean symbolizeNames;
55
+ private boolean freeze;
55
56
  private RubyClass objectClass;
56
57
  private RubyClass arrayClass;
57
58
  private RubyClass decimalClass;
@@ -160,6 +161,7 @@ public class Parser extends RubyObject {
160
161
  this.maxNesting = opts.getInt("max_nesting", DEFAULT_MAX_NESTING);
161
162
  this.allowNaN = opts.getBool("allow_nan", false);
162
163
  this.symbolizeNames = opts.getBool("symbolize_names", false);
164
+ this.freeze = opts.getBool("freeze", false);
163
165
  this.createId = opts.getString("create_id", getCreateId(context));
164
166
  this.createAdditions = opts.getBool("create_additions", false);
165
167
  this.objectClass = opts.getClass("object_class", runtime.getHash());
@@ -313,11 +315,11 @@ public class Parser extends RubyObject {
313
315
  }
314
316
 
315
317
 
316
- // line 339 "Parser.rl"
318
+ // line 341 "Parser.rl"
317
319
 
318
320
 
319
321
 
320
- // line 321 "Parser.java"
322
+ // line 323 "Parser.java"
321
323
  private static byte[] init__JSON_value_actions_0()
322
324
  {
323
325
  return new byte [] {
@@ -431,7 +433,7 @@ static final int JSON_value_error = 0;
431
433
  static final int JSON_value_en_main = 1;
432
434
 
433
435
 
434
- // line 445 "Parser.rl"
436
+ // line 447 "Parser.rl"
435
437
 
436
438
 
437
439
  void parseValue(ParserResult res, int p, int pe) {
@@ -439,14 +441,14 @@ static final int JSON_value_en_main = 1;
439
441
  IRubyObject result = null;
440
442
 
441
443
 
442
- // line 443 "Parser.java"
444
+ // line 445 "Parser.java"
443
445
  {
444
446
  cs = JSON_value_start;
445
447
  }
446
448
 
447
- // line 452 "Parser.rl"
449
+ // line 454 "Parser.rl"
448
450
 
449
- // line 450 "Parser.java"
451
+ // line 452 "Parser.java"
450
452
  {
451
453
  int _klen;
452
454
  int _trans = 0;
@@ -472,13 +474,13 @@ case 1:
472
474
  while ( _nacts-- > 0 ) {
473
475
  switch ( _JSON_value_actions[_acts++] ) {
474
476
  case 9:
475
- // line 430 "Parser.rl"
477
+ // line 432 "Parser.rl"
476
478
  {
477
479
  p--;
478
480
  { p += 1; _goto_targ = 5; if (true) continue _goto;}
479
481
  }
480
482
  break;
481
- // line 482 "Parser.java"
483
+ // line 484 "Parser.java"
482
484
  }
483
485
  }
484
486
 
@@ -541,25 +543,25 @@ case 1:
541
543
  switch ( _JSON_value_actions[_acts++] )
542
544
  {
543
545
  case 0:
544
- // line 347 "Parser.rl"
546
+ // line 349 "Parser.rl"
545
547
  {
546
548
  result = getRuntime().getNil();
547
549
  }
548
550
  break;
549
551
  case 1:
550
- // line 350 "Parser.rl"
552
+ // line 352 "Parser.rl"
551
553
  {
552
554
  result = getRuntime().getFalse();
553
555
  }
554
556
  break;
555
557
  case 2:
556
- // line 353 "Parser.rl"
558
+ // line 355 "Parser.rl"
557
559
  {
558
560
  result = getRuntime().getTrue();
559
561
  }
560
562
  break;
561
563
  case 3:
562
- // line 356 "Parser.rl"
564
+ // line 358 "Parser.rl"
563
565
  {
564
566
  if (parser.allowNaN) {
565
567
  result = getConstant(CONST_NAN);
@@ -569,7 +571,7 @@ case 1:
569
571
  }
570
572
  break;
571
573
  case 4:
572
- // line 363 "Parser.rl"
574
+ // line 365 "Parser.rl"
573
575
  {
574
576
  if (parser.allowNaN) {
575
577
  result = getConstant(CONST_INFINITY);
@@ -579,7 +581,7 @@ case 1:
579
581
  }
580
582
  break;
581
583
  case 5:
582
- // line 370 "Parser.rl"
584
+ // line 372 "Parser.rl"
583
585
  {
584
586
  if (pe > p + 8 &&
585
587
  absSubSequence(p, p + 9).equals(JSON_MINUS_INFINITY)) {
@@ -608,7 +610,7 @@ case 1:
608
610
  }
609
611
  break;
610
612
  case 6:
611
- // line 396 "Parser.rl"
613
+ // line 398 "Parser.rl"
612
614
  {
613
615
  parseString(res, p, pe);
614
616
  if (res.result == null) {
@@ -621,7 +623,7 @@ case 1:
621
623
  }
622
624
  break;
623
625
  case 7:
624
- // line 406 "Parser.rl"
626
+ // line 408 "Parser.rl"
625
627
  {
626
628
  currentNesting++;
627
629
  parseArray(res, p, pe);
@@ -636,7 +638,7 @@ case 1:
636
638
  }
637
639
  break;
638
640
  case 8:
639
- // line 418 "Parser.rl"
641
+ // line 420 "Parser.rl"
640
642
  {
641
643
  currentNesting++;
642
644
  parseObject(res, p, pe);
@@ -650,7 +652,7 @@ case 1:
650
652
  }
651
653
  }
652
654
  break;
653
- // line 654 "Parser.java"
655
+ // line 656 "Parser.java"
654
656
  }
655
657
  }
656
658
  }
@@ -670,9 +672,12 @@ case 5:
670
672
  break; }
671
673
  }
672
674
 
673
- // line 453 "Parser.rl"
675
+ // line 455 "Parser.rl"
674
676
 
675
677
  if (cs >= JSON_value_first_final && result != null) {
678
+ if (parser.freeze) {
679
+ result.setFrozen(true);
680
+ }
676
681
  res.update(result, p);
677
682
  } else {
678
683
  res.update(null, p);
@@ -680,7 +685,7 @@ case 5:
680
685
  }
681
686
 
682
687
 
683
- // line 684 "Parser.java"
688
+ // line 689 "Parser.java"
684
689
  private static byte[] init__JSON_integer_actions_0()
685
690
  {
686
691
  return new byte [] {
@@ -779,7 +784,7 @@ static final int JSON_integer_error = 0;
779
784
  static final int JSON_integer_en_main = 1;
780
785
 
781
786
 
782
- // line 472 "Parser.rl"
787
+ // line 477 "Parser.rl"
783
788
 
784
789
 
785
790
  void parseInteger(ParserResult res, int p, int pe) {
@@ -797,15 +802,15 @@ static final int JSON_integer_en_main = 1;
797
802
  int cs = EVIL;
798
803
 
799
804
 
800
- // line 801 "Parser.java"
805
+ // line 806 "Parser.java"
801
806
  {
802
807
  cs = JSON_integer_start;
803
808
  }
804
809
 
805
- // line 489 "Parser.rl"
810
+ // line 494 "Parser.rl"
806
811
  int memo = p;
807
812
 
808
- // line 809 "Parser.java"
813
+ // line 814 "Parser.java"
809
814
  {
810
815
  int _klen;
811
816
  int _trans = 0;
@@ -886,13 +891,13 @@ case 1:
886
891
  switch ( _JSON_integer_actions[_acts++] )
887
892
  {
888
893
  case 0:
889
- // line 466 "Parser.rl"
894
+ // line 471 "Parser.rl"
890
895
  {
891
896
  p--;
892
897
  { p += 1; _goto_targ = 5; if (true) continue _goto;}
893
898
  }
894
899
  break;
895
- // line 896 "Parser.java"
900
+ // line 901 "Parser.java"
896
901
  }
897
902
  }
898
903
  }
@@ -912,7 +917,7 @@ case 5:
912
917
  break; }
913
918
  }
914
919
 
915
- // line 491 "Parser.rl"
920
+ // line 496 "Parser.rl"
916
921
 
917
922
  if (cs < JSON_integer_first_final) {
918
923
  return -1;
@@ -934,7 +939,7 @@ case 5:
934
939
  }
935
940
 
936
941
 
937
- // line 938 "Parser.java"
942
+ // line 943 "Parser.java"
938
943
  private static byte[] init__JSON_float_actions_0()
939
944
  {
940
945
  return new byte [] {
@@ -1036,7 +1041,7 @@ static final int JSON_float_error = 0;
1036
1041
  static final int JSON_float_en_main = 1;
1037
1042
 
1038
1043
 
1039
- // line 526 "Parser.rl"
1044
+ // line 531 "Parser.rl"
1040
1045
 
1041
1046
 
1042
1047
  void parseFloat(ParserResult res, int p, int pe) {
@@ -1056,15 +1061,15 @@ static final int JSON_float_en_main = 1;
1056
1061
  int cs = EVIL;
1057
1062
 
1058
1063
 
1059
- // line 1060 "Parser.java"
1064
+ // line 1065 "Parser.java"
1060
1065
  {
1061
1066
  cs = JSON_float_start;
1062
1067
  }
1063
1068
 
1064
- // line 545 "Parser.rl"
1069
+ // line 550 "Parser.rl"
1065
1070
  int memo = p;
1066
1071
 
1067
- // line 1068 "Parser.java"
1072
+ // line 1073 "Parser.java"
1068
1073
  {
1069
1074
  int _klen;
1070
1075
  int _trans = 0;
@@ -1145,13 +1150,13 @@ case 1:
1145
1150
  switch ( _JSON_float_actions[_acts++] )
1146
1151
  {
1147
1152
  case 0:
1148
- // line 517 "Parser.rl"
1153
+ // line 522 "Parser.rl"
1149
1154
  {
1150
1155
  p--;
1151
1156
  { p += 1; _goto_targ = 5; if (true) continue _goto;}
1152
1157
  }
1153
1158
  break;
1154
- // line 1155 "Parser.java"
1159
+ // line 1160 "Parser.java"
1155
1160
  }
1156
1161
  }
1157
1162
  }
@@ -1171,7 +1176,7 @@ case 5:
1171
1176
  break; }
1172
1177
  }
1173
1178
 
1174
- // line 547 "Parser.rl"
1179
+ // line 552 "Parser.rl"
1175
1180
 
1176
1181
  if (cs < JSON_float_first_final) {
1177
1182
  return -1;
@@ -1194,7 +1199,7 @@ case 5:
1194
1199
  }
1195
1200
 
1196
1201
 
1197
- // line 1198 "Parser.java"
1202
+ // line 1203 "Parser.java"
1198
1203
  private static byte[] init__JSON_string_actions_0()
1199
1204
  {
1200
1205
  return new byte [] {
@@ -1296,7 +1301,7 @@ static final int JSON_string_error = 0;
1296
1301
  static final int JSON_string_en_main = 1;
1297
1302
 
1298
1303
 
1299
- // line 599 "Parser.rl"
1304
+ // line 604 "Parser.rl"
1300
1305
 
1301
1306
 
1302
1307
  void parseString(ParserResult res, int p, int pe) {
@@ -1304,15 +1309,15 @@ static final int JSON_string_en_main = 1;
1304
1309
  IRubyObject result = null;
1305
1310
 
1306
1311
 
1307
- // line 1308 "Parser.java"
1312
+ // line 1313 "Parser.java"
1308
1313
  {
1309
1314
  cs = JSON_string_start;
1310
1315
  }
1311
1316
 
1312
- // line 606 "Parser.rl"
1317
+ // line 611 "Parser.rl"
1313
1318
  int memo = p;
1314
1319
 
1315
- // line 1316 "Parser.java"
1320
+ // line 1321 "Parser.java"
1316
1321
  {
1317
1322
  int _klen;
1318
1323
  int _trans = 0;
@@ -1393,7 +1398,7 @@ case 1:
1393
1398
  switch ( _JSON_string_actions[_acts++] )
1394
1399
  {
1395
1400
  case 0:
1396
- // line 574 "Parser.rl"
1401
+ // line 579 "Parser.rl"
1397
1402
  {
1398
1403
  int offset = byteList.begin();
1399
1404
  ByteList decoded = decoder.decode(byteList, memo + 1 - offset,
@@ -1408,13 +1413,13 @@ case 1:
1408
1413
  }
1409
1414
  break;
1410
1415
  case 1:
1411
- // line 587 "Parser.rl"
1416
+ // line 592 "Parser.rl"
1412
1417
  {
1413
1418
  p--;
1414
1419
  { p += 1; _goto_targ = 5; if (true) continue _goto;}
1415
1420
  }
1416
1421
  break;
1417
- // line 1418 "Parser.java"
1422
+ // line 1423 "Parser.java"
1418
1423
  }
1419
1424
  }
1420
1425
  }
@@ -1434,7 +1439,7 @@ case 5:
1434
1439
  break; }
1435
1440
  }
1436
1441
 
1437
- // line 608 "Parser.rl"
1442
+ // line 613 "Parser.rl"
1438
1443
 
1439
1444
  if (parser.createAdditions) {
1440
1445
  RubyHash matchString = parser.match_string;
@@ -1463,16 +1468,23 @@ case 5:
1463
1468
 
1464
1469
  if (cs >= JSON_string_first_final && result != null) {
1465
1470
  if (result instanceof RubyString) {
1466
- ((RubyString)result).force_encoding(context, info.utf8.get());
1471
+ RubyString string = (RubyString)result;
1472
+ string.force_encoding(context, info.utf8.get());
1473
+ if (parser.freeze) {
1474
+ string.setFrozen(true);
1475
+ string = getRuntime().freezeAndDedupString(string);
1476
+ }
1477
+ res.update(string, p + 1);
1478
+ } else {
1479
+ res.update(result, p + 1);
1467
1480
  }
1468
- res.update(result, p + 1);
1469
1481
  } else {
1470
1482
  res.update(null, p + 1);
1471
1483
  }
1472
1484
  }
1473
1485
 
1474
1486
 
1475
- // line 1476 "Parser.java"
1487
+ // line 1488 "Parser.java"
1476
1488
  private static byte[] init__JSON_array_actions_0()
1477
1489
  {
1478
1490
  return new byte [] {
@@ -1585,7 +1597,7 @@ static final int JSON_array_error = 0;
1585
1597
  static final int JSON_array_en_main = 1;
1586
1598
 
1587
1599
 
1588
- // line 681 "Parser.rl"
1600
+ // line 693 "Parser.rl"
1589
1601
 
1590
1602
 
1591
1603
  void parseArray(ParserResult res, int p, int pe) {
@@ -1605,14 +1617,14 @@ static final int JSON_array_en_main = 1;
1605
1617
  }
1606
1618
 
1607
1619
 
1608
- // line 1609 "Parser.java"
1620
+ // line 1621 "Parser.java"
1609
1621
  {
1610
1622
  cs = JSON_array_start;
1611
1623
  }
1612
1624
 
1613
- // line 700 "Parser.rl"
1625
+ // line 712 "Parser.rl"
1614
1626
 
1615
- // line 1616 "Parser.java"
1627
+ // line 1628 "Parser.java"
1616
1628
  {
1617
1629
  int _klen;
1618
1630
  int _trans = 0;
@@ -1693,7 +1705,7 @@ case 1:
1693
1705
  switch ( _JSON_array_actions[_acts++] )
1694
1706
  {
1695
1707
  case 0:
1696
- // line 650 "Parser.rl"
1708
+ // line 662 "Parser.rl"
1697
1709
  {
1698
1710
  parseValue(res, p, pe);
1699
1711
  if (res.result == null) {
@@ -1710,13 +1722,13 @@ case 1:
1710
1722
  }
1711
1723
  break;
1712
1724
  case 1:
1713
- // line 665 "Parser.rl"
1725
+ // line 677 "Parser.rl"
1714
1726
  {
1715
1727
  p--;
1716
1728
  { p += 1; _goto_targ = 5; if (true) continue _goto;}
1717
1729
  }
1718
1730
  break;
1719
- // line 1720 "Parser.java"
1731
+ // line 1732 "Parser.java"
1720
1732
  }
1721
1733
  }
1722
1734
  }
@@ -1736,7 +1748,7 @@ case 5:
1736
1748
  break; }
1737
1749
  }
1738
1750
 
1739
- // line 701 "Parser.rl"
1751
+ // line 713 "Parser.rl"
1740
1752
 
1741
1753
  if (cs >= JSON_array_first_final) {
1742
1754
  res.update(result, p + 1);
@@ -1746,7 +1758,7 @@ case 5:
1746
1758
  }
1747
1759
 
1748
1760
 
1749
- // line 1750 "Parser.java"
1761
+ // line 1762 "Parser.java"
1750
1762
  private static byte[] init__JSON_object_actions_0()
1751
1763
  {
1752
1764
  return new byte [] {
@@ -1869,7 +1881,7 @@ static final int JSON_object_error = 0;
1869
1881
  static final int JSON_object_en_main = 1;
1870
1882
 
1871
1883
 
1872
- // line 760 "Parser.rl"
1884
+ // line 772 "Parser.rl"
1873
1885
 
1874
1886
 
1875
1887
  void parseObject(ParserResult res, int p, int pe) {
@@ -1894,14 +1906,14 @@ static final int JSON_object_en_main = 1;
1894
1906
  }
1895
1907
 
1896
1908
 
1897
- // line 1898 "Parser.java"
1909
+ // line 1910 "Parser.java"
1898
1910
  {
1899
1911
  cs = JSON_object_start;
1900
1912
  }
1901
1913
 
1902
- // line 784 "Parser.rl"
1914
+ // line 796 "Parser.rl"
1903
1915
 
1904
- // line 1905 "Parser.java"
1916
+ // line 1917 "Parser.java"
1905
1917
  {
1906
1918
  int _klen;
1907
1919
  int _trans = 0;
@@ -1982,7 +1994,7 @@ case 1:
1982
1994
  switch ( _JSON_object_actions[_acts++] )
1983
1995
  {
1984
1996
  case 0:
1985
- // line 715 "Parser.rl"
1997
+ // line 727 "Parser.rl"
1986
1998
  {
1987
1999
  parseValue(res, p, pe);
1988
2000
  if (res.result == null) {
@@ -1999,7 +2011,7 @@ case 1:
1999
2011
  }
2000
2012
  break;
2001
2013
  case 1:
2002
- // line 730 "Parser.rl"
2014
+ // line 742 "Parser.rl"
2003
2015
  {
2004
2016
  parseString(res, p, pe);
2005
2017
  if (res.result == null) {
@@ -2019,13 +2031,13 @@ case 1:
2019
2031
  }
2020
2032
  break;
2021
2033
  case 2:
2022
- // line 748 "Parser.rl"
2034
+ // line 760 "Parser.rl"
2023
2035
  {
2024
2036
  p--;
2025
2037
  { p += 1; _goto_targ = 5; if (true) continue _goto;}
2026
2038
  }
2027
2039
  break;
2028
- // line 2029 "Parser.java"
2040
+ // line 2041 "Parser.java"
2029
2041
  }
2030
2042
  }
2031
2043
  }
@@ -2045,7 +2057,7 @@ case 5:
2045
2057
  break; }
2046
2058
  }
2047
2059
 
2048
- // line 785 "Parser.rl"
2060
+ // line 797 "Parser.rl"
2049
2061
 
2050
2062
  if (cs < JSON_object_first_final) {
2051
2063
  res.update(null, p + 1);
@@ -2078,7 +2090,7 @@ case 5:
2078
2090
  }
2079
2091
 
2080
2092
 
2081
- // line 2082 "Parser.java"
2093
+ // line 2094 "Parser.java"
2082
2094
  private static byte[] init__JSON_actions_0()
2083
2095
  {
2084
2096
  return new byte [] {
@@ -2181,7 +2193,7 @@ static final int JSON_error = 0;
2181
2193
  static final int JSON_en_main = 1;
2182
2194
 
2183
2195
 
2184
- // line 836 "Parser.rl"
2196
+ // line 848 "Parser.rl"
2185
2197
 
2186
2198
 
2187
2199
  public IRubyObject parseImplemetation() {
@@ -2191,16 +2203,16 @@ static final int JSON_en_main = 1;
2191
2203
  ParserResult res = new ParserResult();
2192
2204
 
2193
2205
 
2194
- // line 2195 "Parser.java"
2206
+ // line 2207 "Parser.java"
2195
2207
  {
2196
2208
  cs = JSON_start;
2197
2209
  }
2198
2210
 
2199
- // line 845 "Parser.rl"
2211
+ // line 857 "Parser.rl"
2200
2212
  p = byteList.begin();
2201
2213
  pe = p + byteList.length();
2202
2214
 
2203
- // line 2204 "Parser.java"
2215
+ // line 2216 "Parser.java"
2204
2216
  {
2205
2217
  int _klen;
2206
2218
  int _trans = 0;
@@ -2281,7 +2293,7 @@ case 1:
2281
2293
  switch ( _JSON_actions[_acts++] )
2282
2294
  {
2283
2295
  case 0:
2284
- // line 822 "Parser.rl"
2296
+ // line 834 "Parser.rl"
2285
2297
  {
2286
2298
  parseValue(res, p, pe);
2287
2299
  if (res.result == null) {
@@ -2293,7 +2305,7 @@ case 1:
2293
2305
  }
2294
2306
  }
2295
2307
  break;
2296
- // line 2297 "Parser.java"
2308
+ // line 2309 "Parser.java"
2297
2309
  }
2298
2310
  }
2299
2311
  }
@@ -2313,7 +2325,7 @@ case 5:
2313
2325
  break; }
2314
2326
  }
2315
2327
 
2316
- // line 848 "Parser.rl"
2328
+ // line 860 "Parser.rl"
2317
2329
 
2318
2330
  if (cs >= JSON_first_final && p == pe) {
2319
2331
  return result;