json 1.8.3 → 2.3.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.
- checksums.yaml +5 -5
- data/.gitignore +2 -0
- data/.travis.yml +9 -11
- data/{CHANGES → CHANGES.md} +186 -90
- data/Gemfile +10 -6
- data/{COPYING-json-jruby → LICENSE} +5 -6
- data/{README-json-jruby.markdown → README-json-jruby.md} +0 -0
- data/{README.rdoc → README.md} +185 -134
- data/Rakefile +41 -40
- data/VERSION +1 -1
- data/ext/json/ext/fbuffer/fbuffer.h +0 -3
- data/ext/json/ext/generator/generator.c +142 -101
- data/ext/json/ext/generator/generator.h +7 -2
- data/ext/json/ext/parser/extconf.rb +3 -0
- data/ext/json/ext/parser/parser.c +383 -463
- data/ext/json/ext/parser/parser.h +4 -5
- data/ext/json/ext/parser/parser.rl +141 -184
- data/ext/json/extconf.rb +0 -1
- data/java/src/json/ext/ByteListTranscoder.java +1 -2
- data/java/src/json/ext/Generator.java +44 -22
- data/java/src/json/ext/GeneratorMethods.java +1 -2
- data/java/src/json/ext/GeneratorService.java +1 -2
- data/java/src/json/ext/GeneratorState.java +3 -56
- data/java/src/json/ext/OptionsReader.java +2 -3
- data/java/src/json/ext/Parser.java +132 -415
- data/java/src/json/ext/Parser.rl +48 -124
- data/java/src/json/ext/ParserService.java +1 -2
- data/java/src/json/ext/RuntimeInfo.java +1 -6
- data/java/src/json/ext/StringDecoder.java +1 -2
- data/java/src/json/ext/StringEncoder.java +5 -0
- data/java/src/json/ext/Utils.java +1 -2
- data/json-java.gemspec +16 -2
- data/json.gemspec +0 -0
- data/json_pure.gemspec +24 -26
- data/lib/json/add/bigdecimal.rb +3 -2
- data/lib/json/add/complex.rb +4 -3
- data/lib/json/add/core.rb +1 -0
- data/lib/json/add/date.rb +1 -1
- data/lib/json/add/date_time.rb +1 -1
- data/lib/json/add/exception.rb +1 -1
- data/lib/json/add/ostruct.rb +3 -3
- data/lib/json/add/range.rb +1 -1
- data/lib/json/add/rational.rb +3 -2
- data/lib/json/add/regexp.rb +3 -3
- data/lib/json/add/set.rb +29 -0
- data/lib/json/add/struct.rb +1 -1
- data/lib/json/add/symbol.rb +1 -1
- data/lib/json/add/time.rb +1 -1
- data/lib/json/common.rb +26 -54
- data/lib/json/ext.rb +0 -6
- data/lib/json/generic_object.rb +5 -4
- data/lib/json/pure/generator.rb +63 -126
- data/lib/json/pure/parser.rb +41 -81
- data/lib/json/pure.rb +2 -8
- data/lib/json/version.rb +2 -1
- data/lib/json.rb +1 -0
- data/references/rfc7159.txt +899 -0
- data/tests/fixtures/obsolete_fail1.json +1 -0
- data/tests/{test_json_addition.rb → json_addition_test.rb} +32 -25
- data/tests/json_common_interface_test.rb +126 -0
- data/tests/json_encoding_test.rb +107 -0
- data/tests/json_ext_parser_test.rb +15 -0
- data/tests/{test_json_fixtures.rb → json_fixtures_test.rb} +5 -8
- data/tests/{test_json_generate.rb → json_generator_test.rb} +123 -39
- data/tests/{test_json_generic_object.rb → json_generic_object_test.rb} +15 -8
- data/tests/json_parser_test.rb +472 -0
- data/tests/json_string_matching_test.rb +38 -0
- data/tests/{setup_variant.rb → test_helper.rb} +6 -0
- data/tools/diff.sh +18 -0
- data/tools/fuzz.rb +1 -9
- metadata +30 -47
- data/COPYING +0 -58
- data/GPL +0 -340
- data/TODO +0 -1
- data/data/example.json +0 -1
- data/data/index.html +0 -38
- data/data/prototype.js +0 -4184
- data/tests/fixtures/fail1.json +0 -1
- data/tests/test_json.rb +0 -553
- data/tests/test_json_encoding.rb +0 -65
- data/tests/test_json_string_matching.rb +0 -39
- data/tests/test_json_unicode.rb +0 -72
@@ -1,13 +1,13 @@
|
|
1
1
|
/*
|
2
2
|
* This code is copyrighted work by Daniel Luz <dev at mernen dot com>.
|
3
3
|
*
|
4
|
-
* Distributed under the Ruby
|
5
|
-
* for details.
|
4
|
+
* Distributed under the Ruby license: https://www.ruby-lang.org/en/about/license.txt
|
6
5
|
*/
|
7
6
|
package json.ext;
|
8
7
|
|
9
8
|
import org.jruby.Ruby;
|
10
9
|
import org.jruby.RubyArray;
|
10
|
+
import org.jruby.RubyBasicObject;
|
11
11
|
import org.jruby.RubyBignum;
|
12
12
|
import org.jruby.RubyBoolean;
|
13
13
|
import org.jruby.RubyClass;
|
@@ -16,6 +16,7 @@ import org.jruby.RubyFloat;
|
|
16
16
|
import org.jruby.RubyHash;
|
17
17
|
import org.jruby.RubyNumeric;
|
18
18
|
import org.jruby.RubyString;
|
19
|
+
import org.jruby.runtime.ClassIndex;
|
19
20
|
import org.jruby.runtime.ThreadContext;
|
20
21
|
import org.jruby.runtime.builtin.IRubyObject;
|
21
22
|
import org.jruby.util.ByteList;
|
@@ -58,6 +59,19 @@ public final class Generator {
|
|
58
59
|
return handler.generateNew(session, object);
|
59
60
|
}
|
60
61
|
|
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
|
+
|
61
75
|
/**
|
62
76
|
* Returns the best serialization handler for the given object.
|
63
77
|
*/
|
@@ -66,16 +80,24 @@ public final class Generator {
|
|
66
80
|
@SuppressWarnings("unchecked")
|
67
81
|
private static <T extends IRubyObject>
|
68
82
|
Handler<? super T> getHandlerFor(Ruby runtime, T object) {
|
69
|
-
|
70
|
-
|
71
|
-
|
72
|
-
|
73
|
-
|
74
|
-
|
75
|
-
|
76
|
-
|
77
|
-
|
78
|
-
|
83
|
+
switch (((RubyBasicObject) object).getNativeTypeIndex()) {
|
84
|
+
// can not use getNativeClassIndex due 1.7 compatibility
|
85
|
+
case NIL : return (Handler) NIL_HANDLER;
|
86
|
+
case TRUE : return (Handler) TRUE_HANDLER;
|
87
|
+
case FALSE : return (Handler) FALSE_HANDLER;
|
88
|
+
case FLOAT : return (Handler) FLOAT_HANDLER;
|
89
|
+
case FIXNUM : return (Handler) FIXNUM_HANDLER;
|
90
|
+
case BIGNUM : return (Handler) BIGNUM_HANDLER;
|
91
|
+
case STRING :
|
92
|
+
if (((RubyBasicObject) object).getMetaClass() != runtime.getString()) break;
|
93
|
+
return (Handler) STRING_HANDLER;
|
94
|
+
case ARRAY :
|
95
|
+
if (((RubyBasicObject) object).getMetaClass() != runtime.getArray()) break;
|
96
|
+
return (Handler) ARRAY_HANDLER;
|
97
|
+
case HASH :
|
98
|
+
if (((RubyBasicObject) object).getMetaClass() != runtime.getHash()) break;
|
99
|
+
return (Handler) HASH_HANDLER;
|
100
|
+
}
|
79
101
|
return GENERIC_HANDLER;
|
80
102
|
}
|
81
103
|
|
@@ -173,9 +195,7 @@ public final class Generator {
|
|
173
195
|
result = RubyString.newString(session.getRuntime(), buffer);
|
174
196
|
ThreadContext context = session.getContext();
|
175
197
|
RuntimeInfo info = session.getInfo();
|
176
|
-
|
177
|
-
result.force_encoding(context, info.utf8.get());
|
178
|
-
}
|
198
|
+
result.force_encoding(context, info.utf8.get());
|
179
199
|
return result;
|
180
200
|
}
|
181
201
|
|
@@ -382,8 +402,7 @@ public final class Generator {
|
|
382
402
|
RuntimeInfo info = session.getInfo();
|
383
403
|
RubyString src;
|
384
404
|
|
385
|
-
if (info.
|
386
|
-
object.encoding(session.getContext()) != info.utf8.get()) {
|
405
|
+
if (object.encoding(session.getContext()) != info.utf8.get()) {
|
387
406
|
src = (RubyString)object.encode(session.getContext(),
|
388
407
|
info.utf8.get());
|
389
408
|
} else {
|
@@ -428,11 +447,14 @@ public final class Generator {
|
|
428
447
|
new Handler<IRubyObject>() {
|
429
448
|
@Override
|
430
449
|
RubyString generateNew(Session session, IRubyObject object) {
|
431
|
-
|
432
|
-
object.callMethod(session.getContext(), "to_json",
|
433
|
-
|
434
|
-
|
435
|
-
|
450
|
+
if (object.respondsTo("to_json")) {
|
451
|
+
IRubyObject result = object.callMethod(session.getContext(), "to_json",
|
452
|
+
new IRubyObject[] {session.getState()});
|
453
|
+
if (result instanceof RubyString) return (RubyString)result;
|
454
|
+
throw session.getRuntime().newTypeError("to_json must return a String");
|
455
|
+
} else {
|
456
|
+
return OBJECT_HANDLER.generateNew(session, object);
|
457
|
+
}
|
436
458
|
}
|
437
459
|
|
438
460
|
@Override
|
@@ -1,8 +1,7 @@
|
|
1
1
|
/*
|
2
2
|
* This code is copyrighted work by Daniel Luz <dev at mernen dot com>.
|
3
3
|
*
|
4
|
-
* Distributed under the Ruby
|
5
|
-
* for details.
|
4
|
+
* Distributed under the Ruby license: https://www.ruby-lang.org/en/about/license.txt
|
6
5
|
*/
|
7
6
|
package json.ext;
|
8
7
|
|
@@ -1,8 +1,7 @@
|
|
1
1
|
/*
|
2
2
|
* This code is copyrighted work by Daniel Luz <dev at mernen dot com>.
|
3
3
|
*
|
4
|
-
* Distributed under the Ruby
|
5
|
-
* for details.
|
4
|
+
* Distributed under the Ruby license: https://www.ruby-lang.org/en/about/license.txt
|
6
5
|
*/
|
7
6
|
package json.ext;
|
8
7
|
|
@@ -1,8 +1,7 @@
|
|
1
1
|
/*
|
2
2
|
* This code is copyrighted work by Daniel Luz <dev at mernen dot com>.
|
3
3
|
*
|
4
|
-
* Distributed under the Ruby
|
5
|
-
* for details.
|
4
|
+
* Distributed under the Ruby license: https://www.ruby-lang.org/en/about/license.txt
|
6
5
|
*/
|
7
6
|
package json.ext;
|
8
7
|
|
@@ -208,45 +207,11 @@ public class GeneratorState extends RubyObject {
|
|
208
207
|
@JRubyMethod
|
209
208
|
public IRubyObject generate(ThreadContext context, IRubyObject obj) {
|
210
209
|
RubyString result = Generator.generateJson(context, obj, this);
|
211
|
-
if (!quirksMode && !objectOrArrayLiteral(result)) {
|
212
|
-
throw Utils.newException(context, Utils.M_GENERATOR_ERROR,
|
213
|
-
"only generation of JSON objects or arrays allowed");
|
214
|
-
}
|
215
210
|
RuntimeInfo info = RuntimeInfo.forRuntime(context.getRuntime());
|
216
|
-
|
217
|
-
result.force_encoding(context, info.utf8.get());
|
218
|
-
}
|
211
|
+
result.force_encoding(context, info.utf8.get());
|
219
212
|
return result;
|
220
213
|
}
|
221
214
|
|
222
|
-
/**
|
223
|
-
* Ensures the given string is in the form "[...]" or "{...}", being
|
224
|
-
* possibly surrounded by white space.
|
225
|
-
* The string's encoding must be ASCII-compatible.
|
226
|
-
* @param value
|
227
|
-
* @return
|
228
|
-
*/
|
229
|
-
private static boolean objectOrArrayLiteral(RubyString value) {
|
230
|
-
ByteList bl = value.getByteList();
|
231
|
-
int len = bl.length();
|
232
|
-
|
233
|
-
for (int pos = 0; pos < len - 1; pos++) {
|
234
|
-
int b = bl.get(pos);
|
235
|
-
if (Character.isWhitespace(b)) continue;
|
236
|
-
|
237
|
-
// match the opening brace
|
238
|
-
switch (b) {
|
239
|
-
case '[':
|
240
|
-
return matchClosingBrace(bl, pos, len, ']');
|
241
|
-
case '{':
|
242
|
-
return matchClosingBrace(bl, pos, len, '}');
|
243
|
-
default:
|
244
|
-
return false;
|
245
|
-
}
|
246
|
-
}
|
247
|
-
return false;
|
248
|
-
}
|
249
|
-
|
250
215
|
private static boolean matchClosingBrace(ByteList bl, int pos, int len,
|
251
216
|
int brace) {
|
252
217
|
for (int endPos = len - 1; endPos > pos; endPos--) {
|
@@ -399,17 +364,6 @@ public class GeneratorState extends RubyObject {
|
|
399
364
|
return context.getRuntime().newBoolean(asciiOnly);
|
400
365
|
}
|
401
366
|
|
402
|
-
@JRubyMethod(name="quirks_mode")
|
403
|
-
public RubyBoolean quirks_mode_get(ThreadContext context) {
|
404
|
-
return context.getRuntime().newBoolean(quirksMode);
|
405
|
-
}
|
406
|
-
|
407
|
-
@JRubyMethod(name="quirks_mode=")
|
408
|
-
public IRubyObject quirks_mode_set(IRubyObject quirks_mode) {
|
409
|
-
quirksMode = quirks_mode.isTrue();
|
410
|
-
return quirks_mode.getRuntime().newBoolean(quirksMode);
|
411
|
-
}
|
412
|
-
|
413
367
|
@JRubyMethod(name="buffer_initial_length")
|
414
368
|
public RubyInteger buffer_initial_length_get(ThreadContext context) {
|
415
369
|
return context.getRuntime().newFixnum(bufferInitialLength);
|
@@ -422,11 +376,6 @@ public class GeneratorState extends RubyObject {
|
|
422
376
|
return buffer_initial_length;
|
423
377
|
}
|
424
378
|
|
425
|
-
@JRubyMethod(name="quirks_mode?")
|
426
|
-
public RubyBoolean quirks_mode_p(ThreadContext context) {
|
427
|
-
return context.getRuntime().newBoolean(quirksMode);
|
428
|
-
}
|
429
|
-
|
430
379
|
public int getDepth() {
|
431
380
|
return depth;
|
432
381
|
}
|
@@ -445,7 +394,7 @@ public class GeneratorState extends RubyObject {
|
|
445
394
|
private ByteList prepareByteList(ThreadContext context, IRubyObject value) {
|
446
395
|
RubyString str = value.convertToString();
|
447
396
|
RuntimeInfo info = RuntimeInfo.forRuntime(context.getRuntime());
|
448
|
-
if (
|
397
|
+
if (str.encoding(context) != info.utf8.get()) {
|
449
398
|
str = (RubyString)str.encode(context, info.utf8.get());
|
450
399
|
}
|
451
400
|
return str.getByteList().dup();
|
@@ -481,7 +430,6 @@ public class GeneratorState extends RubyObject {
|
|
481
430
|
maxNesting = opts.getInt("max_nesting", DEFAULT_MAX_NESTING);
|
482
431
|
allowNaN = opts.getBool("allow_nan", DEFAULT_ALLOW_NAN);
|
483
432
|
asciiOnly = opts.getBool("ascii_only", DEFAULT_ASCII_ONLY);
|
484
|
-
quirksMode = opts.getBool("quirks_mode", DEFAULT_QUIRKS_MODE);
|
485
433
|
bufferInitialLength = opts.getInt("buffer_initial_length", DEFAULT_BUFFER_INITIAL_LENGTH);
|
486
434
|
|
487
435
|
depth = opts.getInt("depth", 0);
|
@@ -508,7 +456,6 @@ public class GeneratorState extends RubyObject {
|
|
508
456
|
result.op_aset(context, runtime.newSymbol("array_nl"), array_nl_get(context));
|
509
457
|
result.op_aset(context, runtime.newSymbol("allow_nan"), allow_nan_p(context));
|
510
458
|
result.op_aset(context, runtime.newSymbol("ascii_only"), ascii_only_p(context));
|
511
|
-
result.op_aset(context, runtime.newSymbol("quirks_mode"), quirks_mode_p(context));
|
512
459
|
result.op_aset(context, runtime.newSymbol("max_nesting"), max_nesting_get(context));
|
513
460
|
result.op_aset(context, runtime.newSymbol("depth"), depth_get(context));
|
514
461
|
result.op_aset(context, runtime.newSymbol("buffer_initial_length"), buffer_initial_length_get(context));
|
@@ -1,8 +1,7 @@
|
|
1
1
|
/*
|
2
2
|
* This code is copyrighted work by Daniel Luz <dev at mernen dot com>.
|
3
3
|
*
|
4
|
-
* Distributed under the Ruby
|
5
|
-
* for details.
|
4
|
+
* Distributed under the Ruby license: https://www.ruby-lang.org/en/about/license.txt
|
6
5
|
*/
|
7
6
|
package json.ext;
|
8
7
|
|
@@ -85,7 +84,7 @@ final class OptionsReader {
|
|
85
84
|
|
86
85
|
RubyString str = value.convertToString();
|
87
86
|
RuntimeInfo info = getRuntimeInfo();
|
88
|
-
if (
|
87
|
+
if (str.encoding(context) != info.utf8.get()) {
|
89
88
|
str = (RubyString)str.encode(context, info.utf8.get());
|
90
89
|
}
|
91
90
|
return str;
|