scout 5.6.7 → 5.6.8.pre

Sign up to get free protection for your applications and to get access to all the features.
Files changed (125) hide show
  1. data/CHANGELOG.markdown +4 -0
  2. data/lib/scout/version.rb +1 -1
  3. data/vendor/json_pure/.gitignore +12 -0
  4. data/vendor/json_pure/.travis.yml +20 -0
  5. data/vendor/json_pure/CHANGES +120 -0
  6. data/vendor/json_pure/COPYING-json-jruby +57 -0
  7. data/vendor/json_pure/Gemfile +11 -0
  8. data/vendor/json_pure/README-json-jruby.markdown +33 -0
  9. data/vendor/json_pure/{README → README.rdoc} +7 -7
  10. data/vendor/json_pure/Rakefile +305 -185
  11. data/vendor/json_pure/VERSION +1 -1
  12. data/vendor/json_pure/diagrams/.keep +0 -0
  13. data/vendor/json_pure/ext/json/ext/fbuffer/fbuffer.h +181 -0
  14. data/vendor/json_pure/ext/json/ext/generator/depend +1 -0
  15. data/vendor/json_pure/ext/json/ext/generator/extconf.rb +4 -6
  16. data/vendor/json_pure/ext/json/ext/generator/generator.c +463 -369
  17. data/vendor/json_pure/ext/json/ext/generator/generator.h +44 -66
  18. data/vendor/json_pure/ext/json/ext/parser/depend +1 -0
  19. data/vendor/json_pure/ext/json/ext/parser/extconf.rb +3 -5
  20. data/vendor/json_pure/ext/json/ext/parser/parser.c +580 -311
  21. data/vendor/json_pure/ext/json/ext/parser/parser.h +14 -8
  22. data/vendor/json_pure/ext/json/ext/parser/parser.rl +242 -107
  23. data/vendor/json_pure/install.rb +8 -11
  24. data/vendor/json_pure/java/src/json/ext/ByteListTranscoder.java +167 -0
  25. data/vendor/json_pure/java/src/json/ext/Generator.java +444 -0
  26. data/vendor/json_pure/java/src/json/ext/GeneratorMethods.java +232 -0
  27. data/vendor/json_pure/java/src/json/ext/GeneratorService.java +43 -0
  28. data/vendor/json_pure/java/src/json/ext/GeneratorState.java +543 -0
  29. data/vendor/json_pure/java/src/json/ext/OptionsReader.java +114 -0
  30. data/vendor/json_pure/java/src/json/ext/Parser.java +2644 -0
  31. data/vendor/json_pure/java/src/json/ext/Parser.rl +968 -0
  32. data/vendor/json_pure/java/src/json/ext/ParserService.java +35 -0
  33. data/vendor/json_pure/java/src/json/ext/RuntimeInfo.java +121 -0
  34. data/vendor/json_pure/java/src/json/ext/StringDecoder.java +167 -0
  35. data/vendor/json_pure/java/src/json/ext/StringEncoder.java +106 -0
  36. data/vendor/json_pure/java/src/json/ext/Utils.java +89 -0
  37. data/vendor/json_pure/json-java.gemspec +23 -0
  38. data/vendor/json_pure/json.gemspec +37 -0
  39. data/vendor/json_pure/json_pure.gemspec +39 -0
  40. data/vendor/json_pure/lib/json.rb +52 -0
  41. data/vendor/json_pure/lib/json/add/bigdecimal.rb +28 -0
  42. data/vendor/json_pure/lib/json/add/complex.rb +22 -0
  43. data/vendor/json_pure/lib/json/add/core.rb +9 -146
  44. data/vendor/json_pure/lib/json/add/date.rb +34 -0
  45. data/vendor/json_pure/lib/json/add/date_time.rb +50 -0
  46. data/vendor/json_pure/lib/json/add/exception.rb +31 -0
  47. data/vendor/json_pure/lib/json/add/ostruct.rb +31 -0
  48. data/vendor/json_pure/lib/json/add/range.rb +29 -0
  49. data/vendor/json_pure/lib/json/add/rational.rb +22 -0
  50. data/vendor/json_pure/lib/json/add/regexp.rb +30 -0
  51. data/vendor/json_pure/lib/json/add/struct.rb +30 -0
  52. data/vendor/json_pure/lib/json/add/symbol.rb +25 -0
  53. data/vendor/json_pure/lib/json/add/time.rb +38 -0
  54. data/vendor/json_pure/lib/json/common.rb +157 -67
  55. data/vendor/json_pure/lib/json/ext.rb +8 -2
  56. data/vendor/json_pure/lib/json/ext/.keep +0 -0
  57. data/vendor/json_pure/lib/json/generic_object.rb +70 -0
  58. data/vendor/json_pure/lib/json/pure.rb +8 -64
  59. data/vendor/json_pure/lib/json/pure/generator.rb +183 -113
  60. data/vendor/json_pure/lib/json/pure/parser.rb +118 -66
  61. data/vendor/json_pure/lib/json/version.rb +1 -1
  62. data/vendor/json_pure/tests/fixtures/fail18.json +1 -1
  63. data/vendor/json_pure/tests/setup_variant.rb +11 -0
  64. data/vendor/json_pure/tests/test_json.rb +233 -28
  65. data/vendor/json_pure/tests/test_json_addition.rb +68 -34
  66. data/vendor/json_pure/tests/test_json_encoding.rb +11 -14
  67. data/vendor/json_pure/tests/test_json_fixtures.rb +11 -10
  68. data/vendor/json_pure/tests/test_json_generate.rb +207 -7
  69. data/vendor/json_pure/tests/test_json_generic_object.rb +75 -0
  70. data/vendor/json_pure/tests/test_json_string_matching.rb +39 -0
  71. data/vendor/json_pure/tests/test_json_unicode.rb +3 -7
  72. data/vendor/json_pure/tools/fuzz.rb +1 -1
  73. data/vendor/json_pure/tools/server.rb +1 -0
  74. metadata +87 -94
  75. data/vendor/json_pure/benchmarks/data-p4-3GHz-ruby18/GeneratorBenchmarkComparison.log +0 -52
  76. data/vendor/json_pure/benchmarks/data-p4-3GHz-ruby18/GeneratorBenchmarkExt#generator_fast-autocorrelation.dat +0 -1000
  77. data/vendor/json_pure/benchmarks/data-p4-3GHz-ruby18/GeneratorBenchmarkExt#generator_fast.dat +0 -1001
  78. data/vendor/json_pure/benchmarks/data-p4-3GHz-ruby18/GeneratorBenchmarkExt#generator_pretty-autocorrelation.dat +0 -900
  79. data/vendor/json_pure/benchmarks/data-p4-3GHz-ruby18/GeneratorBenchmarkExt#generator_pretty.dat +0 -901
  80. data/vendor/json_pure/benchmarks/data-p4-3GHz-ruby18/GeneratorBenchmarkExt#generator_safe-autocorrelation.dat +0 -1000
  81. data/vendor/json_pure/benchmarks/data-p4-3GHz-ruby18/GeneratorBenchmarkExt#generator_safe.dat +0 -1001
  82. data/vendor/json_pure/benchmarks/data-p4-3GHz-ruby18/GeneratorBenchmarkExt.log +0 -261
  83. data/vendor/json_pure/benchmarks/data-p4-3GHz-ruby18/GeneratorBenchmarkPure#generator_fast-autocorrelation.dat +0 -1000
  84. data/vendor/json_pure/benchmarks/data-p4-3GHz-ruby18/GeneratorBenchmarkPure#generator_fast.dat +0 -1001
  85. data/vendor/json_pure/benchmarks/data-p4-3GHz-ruby18/GeneratorBenchmarkPure#generator_pretty-autocorrelation.dat +0 -1000
  86. data/vendor/json_pure/benchmarks/data-p4-3GHz-ruby18/GeneratorBenchmarkPure#generator_pretty.dat +0 -1001
  87. data/vendor/json_pure/benchmarks/data-p4-3GHz-ruby18/GeneratorBenchmarkPure#generator_safe-autocorrelation.dat +0 -1000
  88. data/vendor/json_pure/benchmarks/data-p4-3GHz-ruby18/GeneratorBenchmarkPure#generator_safe.dat +0 -1001
  89. data/vendor/json_pure/benchmarks/data-p4-3GHz-ruby18/GeneratorBenchmarkPure.log +0 -262
  90. data/vendor/json_pure/benchmarks/data-p4-3GHz-ruby18/GeneratorBenchmarkRails#generator-autocorrelation.dat +0 -1000
  91. data/vendor/json_pure/benchmarks/data-p4-3GHz-ruby18/GeneratorBenchmarkRails#generator.dat +0 -1001
  92. data/vendor/json_pure/benchmarks/data-p4-3GHz-ruby18/GeneratorBenchmarkRails.log +0 -82
  93. data/vendor/json_pure/benchmarks/data-p4-3GHz-ruby18/ParserBenchmarkComparison.log +0 -34
  94. data/vendor/json_pure/benchmarks/data-p4-3GHz-ruby18/ParserBenchmarkExt#parser-autocorrelation.dat +0 -900
  95. data/vendor/json_pure/benchmarks/data-p4-3GHz-ruby18/ParserBenchmarkExt#parser.dat +0 -901
  96. data/vendor/json_pure/benchmarks/data-p4-3GHz-ruby18/ParserBenchmarkExt.log +0 -81
  97. data/vendor/json_pure/benchmarks/data-p4-3GHz-ruby18/ParserBenchmarkPure#parser-autocorrelation.dat +0 -1000
  98. data/vendor/json_pure/benchmarks/data-p4-3GHz-ruby18/ParserBenchmarkPure#parser.dat +0 -1001
  99. data/vendor/json_pure/benchmarks/data-p4-3GHz-ruby18/ParserBenchmarkPure.log +0 -82
  100. data/vendor/json_pure/benchmarks/data-p4-3GHz-ruby18/ParserBenchmarkRails#parser-autocorrelation.dat +0 -1000
  101. data/vendor/json_pure/benchmarks/data-p4-3GHz-ruby18/ParserBenchmarkRails#parser.dat +0 -1001
  102. data/vendor/json_pure/benchmarks/data-p4-3GHz-ruby18/ParserBenchmarkRails.log +0 -82
  103. data/vendor/json_pure/benchmarks/data-p4-3GHz-ruby18/ParserBenchmarkYAML#parser-autocorrelation.dat +0 -1000
  104. data/vendor/json_pure/benchmarks/data-p4-3GHz-ruby18/ParserBenchmarkYAML#parser.dat +0 -1001
  105. data/vendor/json_pure/benchmarks/data-p4-3GHz-ruby18/ParserBenchmarkYAML.log +0 -82
  106. data/vendor/json_pure/benchmarks/generator2_benchmark.rb +0 -222
  107. data/vendor/json_pure/benchmarks/generator_benchmark.rb +0 -224
  108. data/vendor/json_pure/benchmarks/ohai.json +0 -1216
  109. data/vendor/json_pure/benchmarks/ohai.ruby +0 -1
  110. data/vendor/json_pure/benchmarks/parser2_benchmark.rb +0 -251
  111. data/vendor/json_pure/benchmarks/parser_benchmark.rb +0 -259
  112. data/vendor/json_pure/bin/edit_json.rb +0 -9
  113. data/vendor/json_pure/bin/prettify_json.rb +0 -75
  114. data/vendor/json_pure/lib/json/Array.xpm +0 -21
  115. data/vendor/json_pure/lib/json/FalseClass.xpm +0 -21
  116. data/vendor/json_pure/lib/json/Hash.xpm +0 -21
  117. data/vendor/json_pure/lib/json/Key.xpm +0 -73
  118. data/vendor/json_pure/lib/json/NilClass.xpm +0 -21
  119. data/vendor/json_pure/lib/json/Numeric.xpm +0 -28
  120. data/vendor/json_pure/lib/json/String.xpm +0 -96
  121. data/vendor/json_pure/lib/json/TrueClass.xpm +0 -21
  122. data/vendor/json_pure/lib/json/add/rails.rb +0 -58
  123. data/vendor/json_pure/lib/json/editor.rb +0 -1371
  124. data/vendor/json_pure/lib/json/json.xpm +0 -1499
  125. data/vendor/json_pure/tests/test_json_rails.rb +0 -144
@@ -0,0 +1,35 @@
1
+ /*
2
+ * This code is copyrighted work by Daniel Luz <dev at mernen dot com>.
3
+ *
4
+ * Distributed under the Ruby and GPLv2 licenses; see COPYING and GPL files
5
+ * for details.
6
+ */
7
+ package json.ext;
8
+
9
+ import java.io.IOException;
10
+ import java.lang.ref.WeakReference;
11
+
12
+ import org.jruby.Ruby;
13
+ import org.jruby.RubyClass;
14
+ import org.jruby.RubyModule;
15
+ import org.jruby.runtime.load.BasicLibraryService;
16
+
17
+ /**
18
+ * The service invoked by JRuby's {@link org.jruby.runtime.load.LoadService LoadService}.
19
+ * Defines the <code>JSON::Ext::Parser</code> class.
20
+ * @author mernen
21
+ */
22
+ public class ParserService implements BasicLibraryService {
23
+ public boolean basicLoad(Ruby runtime) throws IOException {
24
+ runtime.getLoadService().require("json/common");
25
+ RuntimeInfo info = RuntimeInfo.initRuntime(runtime);
26
+
27
+ info.jsonModule = new WeakReference<RubyModule>(runtime.defineModule("JSON"));
28
+ RubyModule jsonExtModule = info.jsonModule.get().defineModuleUnder("Ext");
29
+ RubyClass parserClass =
30
+ jsonExtModule.defineClassUnder("Parser", runtime.getObject(),
31
+ Parser.ALLOCATOR);
32
+ parserClass.defineAnnotatedMethods(Parser.class);
33
+ return true;
34
+ }
35
+ }
@@ -0,0 +1,121 @@
1
+ /*
2
+ * This code is copyrighted work by Daniel Luz <dev at mernen dot com>.
3
+ *
4
+ * Distributed under the Ruby and GPLv2 licenses; see COPYING and GPL files
5
+ * for details.
6
+ */
7
+ package json.ext;
8
+
9
+ import java.lang.ref.WeakReference;
10
+ import java.util.HashMap;
11
+ import java.util.Map;
12
+ import java.util.WeakHashMap;
13
+ import org.jruby.Ruby;
14
+ import org.jruby.RubyClass;
15
+ import org.jruby.RubyEncoding;
16
+ import org.jruby.RubyModule;
17
+ import org.jruby.runtime.ThreadContext;
18
+ import org.jruby.runtime.builtin.IRubyObject;
19
+
20
+
21
+ final class RuntimeInfo {
22
+ // since the vast majority of cases runs just one runtime,
23
+ // we optimize for that
24
+ private static WeakReference<Ruby> runtime1 = new WeakReference<Ruby>(null);
25
+ private static RuntimeInfo info1;
26
+ // store remaining runtimes here (does not include runtime1)
27
+ private static Map<Ruby, RuntimeInfo> runtimes;
28
+
29
+ // these fields are filled by the service loaders
30
+ // Use WeakReferences so that RuntimeInfo doesn't indirectly hold a hard reference to
31
+ // the Ruby runtime object, which would cause memory leaks in the runtimes map above.
32
+ /** JSON */
33
+ WeakReference<RubyModule> jsonModule;
34
+ /** JSON::Ext::Generator::GeneratorMethods::String::Extend */
35
+ WeakReference<RubyModule> stringExtendModule;
36
+ /** JSON::Ext::Generator::State */
37
+ WeakReference<RubyClass> generatorStateClass;
38
+ /** JSON::SAFE_STATE_PROTOTYPE */
39
+ WeakReference<GeneratorState> safeStatePrototype;
40
+
41
+ final WeakReference<RubyEncoding> utf8;
42
+ final WeakReference<RubyEncoding> ascii8bit;
43
+ // other encodings
44
+ private final Map<String, WeakReference<RubyEncoding>> encodings;
45
+
46
+ private RuntimeInfo(Ruby runtime) {
47
+ RubyClass encodingClass = runtime.getEncoding();
48
+ if (encodingClass == null) { // 1.8 mode
49
+ utf8 = ascii8bit = null;
50
+ encodings = null;
51
+ } else {
52
+ ThreadContext context = runtime.getCurrentContext();
53
+
54
+ utf8 = new WeakReference<RubyEncoding>((RubyEncoding)RubyEncoding.find(context,
55
+ encodingClass, runtime.newString("utf-8")));
56
+ ascii8bit = new WeakReference<RubyEncoding>((RubyEncoding)RubyEncoding.find(context,
57
+ encodingClass, runtime.newString("ascii-8bit")));
58
+ encodings = new HashMap<String, WeakReference<RubyEncoding>>();
59
+ }
60
+ }
61
+
62
+ static RuntimeInfo initRuntime(Ruby runtime) {
63
+ synchronized (RuntimeInfo.class) {
64
+ if (runtime1.get() == runtime) {
65
+ return info1;
66
+ } else if (runtime1.get() == null) {
67
+ runtime1 = new WeakReference<Ruby>(runtime);
68
+ info1 = new RuntimeInfo(runtime);
69
+ return info1;
70
+ } else {
71
+ if (runtimes == null) {
72
+ runtimes = new WeakHashMap<Ruby, RuntimeInfo>(1);
73
+ }
74
+ RuntimeInfo cache = runtimes.get(runtime);
75
+ if (cache == null) {
76
+ cache = new RuntimeInfo(runtime);
77
+ runtimes.put(runtime, cache);
78
+ }
79
+ return cache;
80
+ }
81
+ }
82
+ }
83
+
84
+ public static RuntimeInfo forRuntime(Ruby runtime) {
85
+ synchronized (RuntimeInfo.class) {
86
+ if (runtime1.get() == runtime) return info1;
87
+ RuntimeInfo cache = null;
88
+ if (runtimes != null) cache = runtimes.get(runtime);
89
+ assert cache != null : "Runtime given has not initialized JSON::Ext";
90
+ return cache;
91
+ }
92
+ }
93
+
94
+ public boolean encodingsSupported() {
95
+ return utf8 != null && utf8.get() != null;
96
+ }
97
+
98
+ public RubyEncoding getEncoding(ThreadContext context, String name) {
99
+ synchronized (encodings) {
100
+ WeakReference<RubyEncoding> encoding = encodings.get(name);
101
+ if (encoding == null) {
102
+ Ruby runtime = context.getRuntime();
103
+ encoding = new WeakReference<RubyEncoding>((RubyEncoding)RubyEncoding.find(context,
104
+ runtime.getEncoding(), runtime.newString(name)));
105
+ encodings.put(name, encoding);
106
+ }
107
+ return encoding.get();
108
+ }
109
+ }
110
+
111
+ public GeneratorState getSafeStatePrototype(ThreadContext context) {
112
+ if (safeStatePrototype == null) {
113
+ IRubyObject value = jsonModule.get().getConstant("SAFE_STATE_PROTOTYPE");
114
+ if (!(value instanceof GeneratorState)) {
115
+ throw context.getRuntime().newTypeError(value, generatorStateClass.get());
116
+ }
117
+ safeStatePrototype = new WeakReference<GeneratorState>((GeneratorState)value);
118
+ }
119
+ return safeStatePrototype.get();
120
+ }
121
+ }
@@ -0,0 +1,167 @@
1
+ /*
2
+ * This code is copyrighted work by Daniel Luz <dev at mernen dot com>.
3
+ *
4
+ * Distributed under the Ruby and GPLv2 licenses; see COPYING and GPL files
5
+ * for details.
6
+ */
7
+ package json.ext;
8
+
9
+ import org.jruby.exceptions.RaiseException;
10
+ import org.jruby.runtime.ThreadContext;
11
+ import org.jruby.util.ByteList;
12
+
13
+ /**
14
+ * A decoder that reads a JSON-encoded string from the given sources and
15
+ * returns its decoded form on a new ByteList. Escaped Unicode characters
16
+ * are encoded as UTF-8.
17
+ */
18
+ final class StringDecoder extends ByteListTranscoder {
19
+ /**
20
+ * Stores the offset of the high surrogate when reading a surrogate pair,
21
+ * or -1 when not.
22
+ */
23
+ private int surrogatePairStart = -1;
24
+
25
+ // Array used for writing multi-byte characters into the buffer at once
26
+ private final byte[] aux = new byte[4];
27
+
28
+ StringDecoder(ThreadContext context) {
29
+ super(context);
30
+ }
31
+
32
+ ByteList decode(ByteList src, int start, int end) {
33
+ ByteList out = new ByteList(end - start);
34
+ out.setEncoding(src.getEncoding());
35
+ init(src, start, end, out);
36
+ while (hasNext()) {
37
+ handleChar(readUtf8Char());
38
+ }
39
+ quoteStop(pos);
40
+ return out;
41
+ }
42
+
43
+ private void handleChar(int c) {
44
+ if (c == '\\') {
45
+ quoteStop(charStart);
46
+ handleEscapeSequence();
47
+ } else {
48
+ quoteStart();
49
+ }
50
+ }
51
+
52
+ private void handleEscapeSequence() {
53
+ ensureMin(1);
54
+ switch (readUtf8Char()) {
55
+ case 'b':
56
+ append('\b');
57
+ break;
58
+ case 'f':
59
+ append('\f');
60
+ break;
61
+ case 'n':
62
+ append('\n');
63
+ break;
64
+ case 'r':
65
+ append('\r');
66
+ break;
67
+ case 't':
68
+ append('\t');
69
+ break;
70
+ case 'u':
71
+ ensureMin(4);
72
+ int cp = readHex();
73
+ if (Character.isHighSurrogate((char)cp)) {
74
+ handleLowSurrogate((char)cp);
75
+ } else if (Character.isLowSurrogate((char)cp)) {
76
+ // low surrogate with no high surrogate
77
+ throw invalidUtf8();
78
+ } else {
79
+ writeUtf8Char(cp);
80
+ }
81
+ break;
82
+ default: // '\\', '"', '/'...
83
+ quoteStart();
84
+ }
85
+ }
86
+
87
+ private void handleLowSurrogate(char highSurrogate) {
88
+ surrogatePairStart = charStart;
89
+ ensureMin(1);
90
+ int lowSurrogate = readUtf8Char();
91
+
92
+ if (lowSurrogate == '\\') {
93
+ ensureMin(5);
94
+ if (readUtf8Char() != 'u') throw invalidUtf8();
95
+ lowSurrogate = readHex();
96
+ }
97
+
98
+ if (Character.isLowSurrogate((char)lowSurrogate)) {
99
+ writeUtf8Char(Character.toCodePoint(highSurrogate,
100
+ (char)lowSurrogate));
101
+ surrogatePairStart = -1;
102
+ } else {
103
+ throw invalidUtf8();
104
+ }
105
+ }
106
+
107
+ private void writeUtf8Char(int codePoint) {
108
+ if (codePoint < 0x80) {
109
+ append(codePoint);
110
+ } else if (codePoint < 0x800) {
111
+ aux[0] = (byte)(0xc0 | (codePoint >>> 6));
112
+ aux[1] = tailByte(codePoint & 0x3f);
113
+ append(aux, 0, 2);
114
+ } else if (codePoint < 0x10000) {
115
+ aux[0] = (byte)(0xe0 | (codePoint >>> 12));
116
+ aux[1] = tailByte(codePoint >>> 6);
117
+ aux[2] = tailByte(codePoint);
118
+ append(aux, 0, 3);
119
+ } else {
120
+ aux[0] = (byte)(0xf0 | codePoint >>> 18);
121
+ aux[1] = tailByte(codePoint >>> 12);
122
+ aux[2] = tailByte(codePoint >>> 6);
123
+ aux[3] = tailByte(codePoint);
124
+ append(aux, 0, 4);
125
+ }
126
+ }
127
+
128
+ private byte tailByte(int value) {
129
+ return (byte)(0x80 | (value & 0x3f));
130
+ }
131
+
132
+ /**
133
+ * Reads a 4-digit unsigned hexadecimal number from the source.
134
+ */
135
+ private int readHex() {
136
+ int numberStart = pos;
137
+ int result = 0;
138
+ int length = 4;
139
+ for (int i = 0; i < length; i++) {
140
+ int digit = readUtf8Char();
141
+ int digitValue;
142
+ if (digit >= '0' && digit <= '9') {
143
+ digitValue = digit - '0';
144
+ } else if (digit >= 'a' && digit <= 'f') {
145
+ digitValue = 10 + digit - 'a';
146
+ } else if (digit >= 'A' && digit <= 'F') {
147
+ digitValue = 10 + digit - 'A';
148
+ } else {
149
+ throw new NumberFormatException("Invalid base 16 number "
150
+ + src.subSequence(numberStart, numberStart + length));
151
+ }
152
+ result = result * 16 + digitValue;
153
+ }
154
+ return result;
155
+ }
156
+
157
+ @Override
158
+ protected RaiseException invalidUtf8() {
159
+ ByteList message = new ByteList(
160
+ ByteList.plain("partial character in source, " +
161
+ "but hit end near "));
162
+ int start = surrogatePairStart != -1 ? surrogatePairStart : charStart;
163
+ message.append(src, start, srcEnd - start);
164
+ return Utils.newException(context, Utils.M_PARSER_ERROR,
165
+ context.getRuntime().newString(message));
166
+ }
167
+ }
@@ -0,0 +1,106 @@
1
+ package json.ext;
2
+
3
+ import org.jruby.exceptions.RaiseException;
4
+ import org.jruby.runtime.ThreadContext;
5
+ import org.jruby.util.ByteList;
6
+
7
+ /**
8
+ * An encoder that reads from the given source and outputs its representation
9
+ * to another ByteList. The source string is fully checked for UTF-8 validity,
10
+ * and throws a GeneratorError if any problem is found.
11
+ */
12
+ final class StringEncoder extends ByteListTranscoder {
13
+ private final boolean asciiOnly;
14
+
15
+ // Escaped characters will reuse this array, to avoid new allocations
16
+ // or appending them byte-by-byte
17
+ private final byte[] aux =
18
+ new byte[] {/* First unicode character */
19
+ '\\', 'u', 0, 0, 0, 0,
20
+ /* Second unicode character (for surrogate pairs) */
21
+ '\\', 'u', 0, 0, 0, 0,
22
+ /* "\X" characters */
23
+ '\\', 0};
24
+ // offsets on the array above
25
+ private static final int ESCAPE_UNI1_OFFSET = 0;
26
+ private static final int ESCAPE_UNI2_OFFSET = ESCAPE_UNI1_OFFSET + 6;
27
+ private static final int ESCAPE_CHAR_OFFSET = ESCAPE_UNI2_OFFSET + 6;
28
+ /** Array used for code point decomposition in surrogates */
29
+ private final char[] utf16 = new char[2];
30
+
31
+ private static final byte[] HEX =
32
+ new byte[] {'0', '1', '2', '3', '4', '5', '6', '7',
33
+ '8', '9', 'a', 'b', 'c', 'd', 'e', 'f'};
34
+
35
+ StringEncoder(ThreadContext context, boolean asciiOnly) {
36
+ super(context);
37
+ this.asciiOnly = asciiOnly;
38
+ }
39
+
40
+ void encode(ByteList src, ByteList out) {
41
+ init(src, out);
42
+ append('"');
43
+ while (hasNext()) {
44
+ handleChar(readUtf8Char());
45
+ }
46
+ quoteStop(pos);
47
+ append('"');
48
+ }
49
+
50
+ private void handleChar(int c) {
51
+ switch (c) {
52
+ case '"':
53
+ case '\\':
54
+ escapeChar((char)c);
55
+ break;
56
+ case '\n':
57
+ escapeChar('n');
58
+ break;
59
+ case '\r':
60
+ escapeChar('r');
61
+ break;
62
+ case '\t':
63
+ escapeChar('t');
64
+ break;
65
+ case '\f':
66
+ escapeChar('f');
67
+ break;
68
+ case '\b':
69
+ escapeChar('b');
70
+ break;
71
+ default:
72
+ if (c >= 0x20 && c <= 0x7f ||
73
+ (c >= 0x80 && !asciiOnly)) {
74
+ quoteStart();
75
+ } else {
76
+ quoteStop(charStart);
77
+ escapeUtf8Char(c);
78
+ }
79
+ }
80
+ }
81
+
82
+ private void escapeChar(char c) {
83
+ quoteStop(charStart);
84
+ aux[ESCAPE_CHAR_OFFSET + 1] = (byte)c;
85
+ append(aux, ESCAPE_CHAR_OFFSET, 2);
86
+ }
87
+
88
+ private void escapeUtf8Char(int codePoint) {
89
+ int numChars = Character.toChars(codePoint, utf16, 0);
90
+ escapeCodeUnit(utf16[0], ESCAPE_UNI1_OFFSET + 2);
91
+ if (numChars > 1) escapeCodeUnit(utf16[1], ESCAPE_UNI2_OFFSET + 2);
92
+ append(aux, ESCAPE_UNI1_OFFSET, 6 * numChars);
93
+ }
94
+
95
+ private void escapeCodeUnit(char c, int auxOffset) {
96
+ for (int i = 0; i < 4; i++) {
97
+ aux[auxOffset + i] = HEX[(c >>> (12 - 4 * i)) & 0xf];
98
+ }
99
+ }
100
+
101
+ @Override
102
+ protected RaiseException invalidUtf8() {
103
+ return Utils.newException(context, Utils.M_GENERATOR_ERROR,
104
+ "source sequence is illegal/malformed utf-8");
105
+ }
106
+ }
@@ -0,0 +1,89 @@
1
+ /*
2
+ * This code is copyrighted work by Daniel Luz <dev at mernen dot com>.
3
+ *
4
+ * Distributed under the Ruby and GPLv2 licenses; see COPYING and GPL files
5
+ * for details.
6
+ */
7
+ package json.ext;
8
+
9
+ import org.jruby.Ruby;
10
+ import org.jruby.RubyArray;
11
+ import org.jruby.RubyClass;
12
+ import org.jruby.RubyException;
13
+ import org.jruby.RubyHash;
14
+ import org.jruby.RubyString;
15
+ import org.jruby.exceptions.RaiseException;
16
+ import org.jruby.runtime.Block;
17
+ import org.jruby.runtime.ThreadContext;
18
+ import org.jruby.runtime.builtin.IRubyObject;
19
+ import org.jruby.util.ByteList;
20
+
21
+ /**
22
+ * Library of miscellaneous utility functions
23
+ */
24
+ final class Utils {
25
+ public static final String M_GENERATOR_ERROR = "GeneratorError";
26
+ public static final String M_NESTING_ERROR = "NestingError";
27
+ public static final String M_PARSER_ERROR = "ParserError";
28
+
29
+ private Utils() {
30
+ throw new RuntimeException();
31
+ }
32
+
33
+ /**
34
+ * Safe {@link RubyArray} type-checking.
35
+ * Returns the given object if it is an <code>Array</code>,
36
+ * or throws an exception if not.
37
+ * @param object The object to test
38
+ * @return The given object if it is an <code>Array</code>
39
+ * @throws RaiseException <code>TypeError</code> if the object is not
40
+ * of the expected type
41
+ */
42
+ static RubyArray ensureArray(IRubyObject object) throws RaiseException {
43
+ if (object instanceof RubyArray) return (RubyArray)object;
44
+ Ruby runtime = object.getRuntime();
45
+ throw runtime.newTypeError(object, runtime.getArray());
46
+ }
47
+
48
+ static RubyHash ensureHash(IRubyObject object) throws RaiseException {
49
+ if (object instanceof RubyHash) return (RubyHash)object;
50
+ Ruby runtime = object.getRuntime();
51
+ throw runtime.newTypeError(object, runtime.getHash());
52
+ }
53
+
54
+ static RubyString ensureString(IRubyObject object) throws RaiseException {
55
+ if (object instanceof RubyString) return (RubyString)object;
56
+ Ruby runtime = object.getRuntime();
57
+ throw runtime.newTypeError(object, runtime.getString());
58
+ }
59
+
60
+ static RaiseException newException(ThreadContext context,
61
+ String className, String message) {
62
+ return newException(context, className,
63
+ context.getRuntime().newString(message));
64
+ }
65
+
66
+ static RaiseException newException(ThreadContext context,
67
+ String className, RubyString message) {
68
+ RuntimeInfo info = RuntimeInfo.forRuntime(context.getRuntime());
69
+ RubyClass klazz = info.jsonModule.get().getClass(className);
70
+ RubyException excptn =
71
+ (RubyException)klazz.newInstance(context,
72
+ new IRubyObject[] {message}, Block.NULL_BLOCK);
73
+ return new RaiseException(excptn);
74
+ }
75
+
76
+ static byte[] repeat(ByteList a, int n) {
77
+ return repeat(a.unsafeBytes(), a.begin(), a.length(), n);
78
+ }
79
+
80
+ static byte[] repeat(byte[] a, int begin, int length, int n) {
81
+ if (length == 0) return ByteList.NULL_ARRAY;
82
+ int resultLen = length * n;
83
+ byte[] result = new byte[resultLen];
84
+ for (int pos = 0; pos < resultLen; pos += length) {
85
+ System.arraycopy(a, begin, result, pos, length);
86
+ }
87
+ return result;
88
+ }
89
+ }