summaryrefslogtreecommitdiff
path: root/java/src/json
diff options
context:
space:
mode:
authorHiroshi SHIBATA <hsbt@ruby-lang.org>2020-10-20 21:34:14 +0900
committerGitHub <noreply@github.com>2020-10-20 21:34:14 +0900
commitd76e5fc1d2cedeba29fe7a5292f5d451dea0da57 (patch)
treea7b26f7d3d1debb29000b1de774e3c62a49170cf /java/src/json
parent01e4823ee1b9837d7289ae4eb35c9d74535e0f5e (diff)
parent9bf8aa21b36de3bd90bed85e6c85412426b03d9d (diff)
downloadjson-d76e5fc1d2cedeba29fe7a5292f5d451dea0da57.tar.gz
Merge pull request #447 from Shopify/global-freeze-option
Implement a freeze: parser option
Diffstat (limited to 'java/src/json')
-rw-r--r--java/src/json/ext/Parser.java158
-rw-r--r--java/src/json/ext/Parser.rl16
2 files changed, 99 insertions, 75 deletions
diff --git a/java/src/json/ext/Parser.java b/java/src/json/ext/Parser.java
index 647afca..ef28393 100644
--- a/java/src/json/ext/Parser.java
+++ b/java/src/json/ext/Parser.java
@@ -52,6 +52,7 @@ public class Parser extends RubyObject {
private int maxNesting;
private boolean allowNaN;
private boolean symbolizeNames;
+ private boolean freeze;
private RubyClass objectClass;
private RubyClass arrayClass;
private RubyClass decimalClass;
@@ -160,6 +161,7 @@ public class Parser extends RubyObject {
this.maxNesting = opts.getInt("max_nesting", DEFAULT_MAX_NESTING);
this.allowNaN = opts.getBool("allow_nan", false);
this.symbolizeNames = opts.getBool("symbolize_names", false);
+ this.freeze = opts.getBool("freeze", false);
this.createId = opts.getString("create_id", getCreateId(context));
this.createAdditions = opts.getBool("create_additions", false);
this.objectClass = opts.getClass("object_class", runtime.getHash());
@@ -313,11 +315,11 @@ public class Parser extends RubyObject {
}
-// line 339 "Parser.rl"
+// line 341 "Parser.rl"
-// line 321 "Parser.java"
+// line 323 "Parser.java"
private static byte[] init__JSON_value_actions_0()
{
return new byte [] {
@@ -431,7 +433,7 @@ static final int JSON_value_error = 0;
static final int JSON_value_en_main = 1;
-// line 445 "Parser.rl"
+// line 447 "Parser.rl"
void parseValue(ParserResult res, int p, int pe) {
@@ -439,14 +441,14 @@ static final int JSON_value_en_main = 1;
IRubyObject result = null;
-// line 443 "Parser.java"
+// line 445 "Parser.java"
{
cs = JSON_value_start;
}
-// line 452 "Parser.rl"
+// line 454 "Parser.rl"
-// line 450 "Parser.java"
+// line 452 "Parser.java"
{
int _klen;
int _trans = 0;
@@ -472,13 +474,13 @@ case 1:
while ( _nacts-- > 0 ) {
switch ( _JSON_value_actions[_acts++] ) {
case 9:
-// line 430 "Parser.rl"
+// line 432 "Parser.rl"
{
p--;
{ p += 1; _goto_targ = 5; if (true) continue _goto;}
}
break;
-// line 482 "Parser.java"
+// line 484 "Parser.java"
}
}
@@ -541,25 +543,25 @@ case 1:
switch ( _JSON_value_actions[_acts++] )
{
case 0:
-// line 347 "Parser.rl"
+// line 349 "Parser.rl"
{
result = getRuntime().getNil();
}
break;
case 1:
-// line 350 "Parser.rl"
+// line 352 "Parser.rl"
{
result = getRuntime().getFalse();
}
break;
case 2:
-// line 353 "Parser.rl"
+// line 355 "Parser.rl"
{
result = getRuntime().getTrue();
}
break;
case 3:
-// line 356 "Parser.rl"
+// line 358 "Parser.rl"
{
if (parser.allowNaN) {
result = getConstant(CONST_NAN);
@@ -569,7 +571,7 @@ case 1:
}
break;
case 4:
-// line 363 "Parser.rl"
+// line 365 "Parser.rl"
{
if (parser.allowNaN) {
result = getConstant(CONST_INFINITY);
@@ -579,7 +581,7 @@ case 1:
}
break;
case 5:
-// line 370 "Parser.rl"
+// line 372 "Parser.rl"
{
if (pe > p + 8 &&
absSubSequence(p, p + 9).equals(JSON_MINUS_INFINITY)) {
@@ -608,7 +610,7 @@ case 1:
}
break;
case 6:
-// line 396 "Parser.rl"
+// line 398 "Parser.rl"
{
parseString(res, p, pe);
if (res.result == null) {
@@ -621,7 +623,7 @@ case 1:
}
break;
case 7:
-// line 406 "Parser.rl"
+// line 408 "Parser.rl"
{
currentNesting++;
parseArray(res, p, pe);
@@ -636,7 +638,7 @@ case 1:
}
break;
case 8:
-// line 418 "Parser.rl"
+// line 420 "Parser.rl"
{
currentNesting++;
parseObject(res, p, pe);
@@ -650,7 +652,7 @@ case 1:
}
}
break;
-// line 654 "Parser.java"
+// line 656 "Parser.java"
}
}
}
@@ -670,9 +672,12 @@ case 5:
break; }
}
-// line 453 "Parser.rl"
+// line 455 "Parser.rl"
if (cs >= JSON_value_first_final && result != null) {
+ if (parser.freeze) {
+ result.setFrozen(true);
+ }
res.update(result, p);
} else {
res.update(null, p);
@@ -680,7 +685,7 @@ case 5:
}
-// line 684 "Parser.java"
+// line 689 "Parser.java"
private static byte[] init__JSON_integer_actions_0()
{
return new byte [] {
@@ -779,7 +784,7 @@ static final int JSON_integer_error = 0;
static final int JSON_integer_en_main = 1;
-// line 472 "Parser.rl"
+// line 477 "Parser.rl"
void parseInteger(ParserResult res, int p, int pe) {
@@ -797,15 +802,15 @@ static final int JSON_integer_en_main = 1;
int cs = EVIL;
-// line 801 "Parser.java"
+// line 806 "Parser.java"
{
cs = JSON_integer_start;
}
-// line 489 "Parser.rl"
+// line 494 "Parser.rl"
int memo = p;
-// line 809 "Parser.java"
+// line 814 "Parser.java"
{
int _klen;
int _trans = 0;
@@ -886,13 +891,13 @@ case 1:
switch ( _JSON_integer_actions[_acts++] )
{
case 0:
-// line 466 "Parser.rl"
+// line 471 "Parser.rl"
{
p--;
{ p += 1; _goto_targ = 5; if (true) continue _goto;}
}
break;
-// line 896 "Parser.java"
+// line 901 "Parser.java"
}
}
}
@@ -912,7 +917,7 @@ case 5:
break; }
}
-// line 491 "Parser.rl"
+// line 496 "Parser.rl"
if (cs < JSON_integer_first_final) {
return -1;
@@ -934,7 +939,7 @@ case 5:
}
-// line 938 "Parser.java"
+// line 943 "Parser.java"
private static byte[] init__JSON_float_actions_0()
{
return new byte [] {
@@ -1036,7 +1041,7 @@ static final int JSON_float_error = 0;
static final int JSON_float_en_main = 1;
-// line 526 "Parser.rl"
+// line 531 "Parser.rl"
void parseFloat(ParserResult res, int p, int pe) {
@@ -1056,15 +1061,15 @@ static final int JSON_float_en_main = 1;
int cs = EVIL;
-// line 1060 "Parser.java"
+// line 1065 "Parser.java"
{
cs = JSON_float_start;
}
-// line 545 "Parser.rl"
+// line 550 "Parser.rl"
int memo = p;
-// line 1068 "Parser.java"
+// line 1073 "Parser.java"
{
int _klen;
int _trans = 0;
@@ -1145,13 +1150,13 @@ case 1:
switch ( _JSON_float_actions[_acts++] )
{
case 0:
-// line 517 "Parser.rl"
+// line 522 "Parser.rl"
{
p--;
{ p += 1; _goto_targ = 5; if (true) continue _goto;}
}
break;
-// line 1155 "Parser.java"
+// line 1160 "Parser.java"
}
}
}
@@ -1171,7 +1176,7 @@ case 5:
break; }
}
-// line 547 "Parser.rl"
+// line 552 "Parser.rl"
if (cs < JSON_float_first_final) {
return -1;
@@ -1194,7 +1199,7 @@ case 5:
}
-// line 1198 "Parser.java"
+// line 1203 "Parser.java"
private static byte[] init__JSON_string_actions_0()
{
return new byte [] {
@@ -1296,7 +1301,7 @@ static final int JSON_string_error = 0;
static final int JSON_string_en_main = 1;
-// line 599 "Parser.rl"
+// line 604 "Parser.rl"
void parseString(ParserResult res, int p, int pe) {
@@ -1304,15 +1309,15 @@ static final int JSON_string_en_main = 1;
IRubyObject result = null;
-// line 1308 "Parser.java"
+// line 1313 "Parser.java"
{
cs = JSON_string_start;
}
-// line 606 "Parser.rl"
+// line 611 "Parser.rl"
int memo = p;
-// line 1316 "Parser.java"
+// line 1321 "Parser.java"
{
int _klen;
int _trans = 0;
@@ -1393,7 +1398,7 @@ case 1:
switch ( _JSON_string_actions[_acts++] )
{
case 0:
-// line 574 "Parser.rl"
+// line 579 "Parser.rl"
{
int offset = byteList.begin();
ByteList decoded = decoder.decode(byteList, memo + 1 - offset,
@@ -1408,13 +1413,13 @@ case 1:
}
break;
case 1:
-// line 587 "Parser.rl"
+// line 592 "Parser.rl"
{
p--;
{ p += 1; _goto_targ = 5; if (true) continue _goto;}
}
break;
-// line 1418 "Parser.java"
+// line 1423 "Parser.java"
}
}
}
@@ -1434,7 +1439,7 @@ case 5:
break; }
}
-// line 608 "Parser.rl"
+// line 613 "Parser.rl"
if (parser.createAdditions) {
RubyHash matchString = parser.match_string;
@@ -1463,16 +1468,23 @@ case 5:
if (cs >= JSON_string_first_final && result != null) {
if (result instanceof RubyString) {
- ((RubyString)result).force_encoding(context, info.utf8.get());
+ RubyString string = (RubyString)result;
+ string.force_encoding(context, info.utf8.get());
+ if (parser.freeze) {
+ string.setFrozen(true);
+ string = getRuntime().freezeAndDedupString(string);
+ }
+ res.update(string, p + 1);
+ } else {
+ res.update(result, p + 1);
}
- res.update(result, p + 1);
} else {
res.update(null, p + 1);
}
}
-// line 1476 "Parser.java"
+// line 1488 "Parser.java"
private static byte[] init__JSON_array_actions_0()
{
return new byte [] {
@@ -1585,7 +1597,7 @@ static final int JSON_array_error = 0;
static final int JSON_array_en_main = 1;
-// line 681 "Parser.rl"
+// line 693 "Parser.rl"
void parseArray(ParserResult res, int p, int pe) {
@@ -1605,14 +1617,14 @@ static final int JSON_array_en_main = 1;
}
-// line 1609 "Parser.java"
+// line 1621 "Parser.java"
{
cs = JSON_array_start;
}
-// line 700 "Parser.rl"
+// line 712 "Parser.rl"
-// line 1616 "Parser.java"
+// line 1628 "Parser.java"
{
int _klen;
int _trans = 0;
@@ -1693,7 +1705,7 @@ case 1:
switch ( _JSON_array_actions[_acts++] )
{
case 0:
-// line 650 "Parser.rl"
+// line 662 "Parser.rl"
{
parseValue(res, p, pe);
if (res.result == null) {
@@ -1710,13 +1722,13 @@ case 1:
}
break;
case 1:
-// line 665 "Parser.rl"
+// line 677 "Parser.rl"
{
p--;
{ p += 1; _goto_targ = 5; if (true) continue _goto;}
}
break;
-// line 1720 "Parser.java"
+// line 1732 "Parser.java"
}
}
}
@@ -1736,7 +1748,7 @@ case 5:
break; }
}
-// line 701 "Parser.rl"
+// line 713 "Parser.rl"
if (cs >= JSON_array_first_final) {
res.update(result, p + 1);
@@ -1746,7 +1758,7 @@ case 5:
}
-// line 1750 "Parser.java"
+// line 1762 "Parser.java"
private static byte[] init__JSON_object_actions_0()
{
return new byte [] {
@@ -1869,7 +1881,7 @@ static final int JSON_object_error = 0;
static final int JSON_object_en_main = 1;
-// line 760 "Parser.rl"
+// line 772 "Parser.rl"
void parseObject(ParserResult res, int p, int pe) {
@@ -1894,14 +1906,14 @@ static final int JSON_object_en_main = 1;
}
-// line 1898 "Parser.java"
+// line 1910 "Parser.java"
{
cs = JSON_object_start;
}
-// line 784 "Parser.rl"
+// line 796 "Parser.rl"
-// line 1905 "Parser.java"
+// line 1917 "Parser.java"
{
int _klen;
int _trans = 0;
@@ -1982,7 +1994,7 @@ case 1:
switch ( _JSON_object_actions[_acts++] )
{
case 0:
-// line 715 "Parser.rl"
+// line 727 "Parser.rl"
{
parseValue(res, p, pe);
if (res.result == null) {
@@ -1999,7 +2011,7 @@ case 1:
}
break;
case 1:
-// line 730 "Parser.rl"
+// line 742 "Parser.rl"
{
parseString(res, p, pe);
if (res.result == null) {
@@ -2019,13 +2031,13 @@ case 1:
}
break;
case 2:
-// line 748 "Parser.rl"
+// line 760 "Parser.rl"
{
p--;
{ p += 1; _goto_targ = 5; if (true) continue _goto;}
}
break;
-// line 2029 "Parser.java"
+// line 2041 "Parser.java"
}
}
}
@@ -2045,7 +2057,7 @@ case 5:
break; }
}
-// line 785 "Parser.rl"
+// line 797 "Parser.rl"
if (cs < JSON_object_first_final) {
res.update(null, p + 1);
@@ -2078,7 +2090,7 @@ case 5:
}
-// line 2082 "Parser.java"
+// line 2094 "Parser.java"
private static byte[] init__JSON_actions_0()
{
return new byte [] {
@@ -2181,7 +2193,7 @@ static final int JSON_error = 0;
static final int JSON_en_main = 1;
-// line 836 "Parser.rl"
+// line 848 "Parser.rl"
public IRubyObject parseImplemetation() {
@@ -2191,16 +2203,16 @@ static final int JSON_en_main = 1;
ParserResult res = new ParserResult();
-// line 2195 "Parser.java"
+// line 2207 "Parser.java"
{
cs = JSON_start;
}
-// line 845 "Parser.rl"
+// line 857 "Parser.rl"
p = byteList.begin();
pe = p + byteList.length();
-// line 2204 "Parser.java"
+// line 2216 "Parser.java"
{
int _klen;
int _trans = 0;
@@ -2281,7 +2293,7 @@ case 1:
switch ( _JSON_actions[_acts++] )
{
case 0:
-// line 822 "Parser.rl"
+// line 834 "Parser.rl"
{
parseValue(res, p, pe);
if (res.result == null) {
@@ -2293,7 +2305,7 @@ case 1:
}
}
break;
-// line 2297 "Parser.java"
+// line 2309 "Parser.java"
}
}
}
@@ -2313,7 +2325,7 @@ case 5:
break; }
}
-// line 848 "Parser.rl"
+// line 860 "Parser.rl"
if (cs >= JSON_first_final && p == pe) {
return result;
diff --git a/java/src/json/ext/Parser.rl b/java/src/json/ext/Parser.rl
index c0c72ad..f670bad 100644
--- a/java/src/json/ext/Parser.rl
+++ b/java/src/json/ext/Parser.rl
@@ -50,6 +50,7 @@ public class Parser extends RubyObject {
private int maxNesting;
private boolean allowNaN;
private boolean symbolizeNames;
+ private boolean freeze;
private RubyClass objectClass;
private RubyClass arrayClass;
private RubyClass decimalClass;
@@ -158,6 +159,7 @@ public class Parser extends RubyObject {
this.maxNesting = opts.getInt("max_nesting", DEFAULT_MAX_NESTING);
this.allowNaN = opts.getBool("allow_nan", false);
this.symbolizeNames = opts.getBool("symbolize_names", false);
+ this.freeze = opts.getBool("freeze", false);
this.createId = opts.getString("create_id", getCreateId(context));
this.createAdditions = opts.getBool("create_additions", false);
this.objectClass = opts.getClass("object_class", runtime.getHash());
@@ -452,6 +454,9 @@ public class Parser extends RubyObject {
%% write exec;
if (cs >= JSON_value_first_final && result != null) {
+ if (parser.freeze) {
+ result.setFrozen(true);
+ }
res.update(result, p);
} else {
res.update(null, p);
@@ -633,9 +638,16 @@ public class Parser extends RubyObject {
if (cs >= JSON_string_first_final && result != null) {
if (result instanceof RubyString) {
- ((RubyString)result).force_encoding(context, info.utf8.get());
+ RubyString string = (RubyString)result;
+ string.force_encoding(context, info.utf8.get());
+ if (parser.freeze) {
+ string.setFrozen(true);
+ string = getRuntime().freezeAndDedupString(string);
+ }
+ res.update(string, p + 1);
+ } else {
+ res.update(result, p + 1);
}
- res.update(result, p + 1);
} else {
res.update(null, p + 1);
}