json_pure 2.4.0 → 2.4.1

Sign up to get free protection for your applications and to get access to all the features.
Files changed (46) hide show
  1. checksums.yaml +4 -4
  2. data/CHANGES.md +14 -0
  3. data/VERSION +1 -1
  4. data/json_pure.gemspec +47 -19
  5. data/lib/json/version.rb +1 -1
  6. data/tests/fixtures/fail29.json +1 -0
  7. data/tests/fixtures/fail30.json +1 -0
  8. data/tests/fixtures/fail31.json +1 -0
  9. data/tests/fixtures/fail32.json +1 -0
  10. metadata +16 -48
  11. data/.gitignore +0 -18
  12. data/.travis.yml +0 -23
  13. data/README-json-jruby.md +0 -33
  14. data/Rakefile +0 -334
  15. data/diagrams/.keep +0 -0
  16. data/ext/json/ext/fbuffer/fbuffer.h +0 -187
  17. data/ext/json/ext/generator/depend +0 -1
  18. data/ext/json/ext/generator/extconf.rb +0 -4
  19. data/ext/json/ext/generator/generator.c +0 -1612
  20. data/ext/json/ext/generator/generator.h +0 -174
  21. data/ext/json/ext/parser/depend +0 -1
  22. data/ext/json/ext/parser/extconf.rb +0 -31
  23. data/ext/json/ext/parser/parser.c +0 -2164
  24. data/ext/json/ext/parser/parser.h +0 -92
  25. data/ext/json/ext/parser/parser.rl +0 -924
  26. data/ext/json/extconf.rb +0 -3
  27. data/install.rb +0 -23
  28. data/java/src/json/ext/ByteListTranscoder.java +0 -166
  29. data/java/src/json/ext/Generator.java +0 -447
  30. data/java/src/json/ext/GeneratorMethods.java +0 -231
  31. data/java/src/json/ext/GeneratorService.java +0 -42
  32. data/java/src/json/ext/GeneratorState.java +0 -520
  33. data/java/src/json/ext/OptionsReader.java +0 -113
  34. data/java/src/json/ext/Parser.java +0 -2374
  35. data/java/src/json/ext/Parser.rl +0 -905
  36. data/java/src/json/ext/ParserService.java +0 -34
  37. data/java/src/json/ext/RuntimeInfo.java +0 -116
  38. data/java/src/json/ext/StringDecoder.java +0 -166
  39. data/java/src/json/ext/StringEncoder.java +0 -117
  40. data/java/src/json/ext/Utils.java +0 -88
  41. data/json-java.gemspec +0 -38
  42. data/json.gemspec +0 -140
  43. data/references/rfc7159.txt +0 -899
  44. data/tools/diff.sh +0 -18
  45. data/tools/fuzz.rb +0 -131
  46. data/tools/server.rb +0 -62
@@ -1,231 +0,0 @@
1
- /*
2
- * This code is copyrighted work by Daniel Luz <dev at mernen dot com>.
3
- *
4
- * Distributed under the Ruby license: https://www.ruby-lang.org/en/about/license.txt
5
- */
6
- package json.ext;
7
-
8
- import java.lang.ref.WeakReference;
9
- import org.jruby.Ruby;
10
- import org.jruby.RubyArray;
11
- import org.jruby.RubyBoolean;
12
- import org.jruby.RubyFixnum;
13
- import org.jruby.RubyFloat;
14
- import org.jruby.RubyHash;
15
- import org.jruby.RubyInteger;
16
- import org.jruby.RubyModule;
17
- import org.jruby.RubyNumeric;
18
- import org.jruby.RubyString;
19
- import org.jruby.anno.JRubyMethod;
20
- import org.jruby.runtime.ThreadContext;
21
- import org.jruby.runtime.builtin.IRubyObject;
22
- import org.jruby.util.ByteList;
23
-
24
- /**
25
- * A class that populates the
26
- * <code>Json::Ext::Generator::GeneratorMethods</code> module.
27
- *
28
- * @author mernen
29
- */
30
- class GeneratorMethods {
31
- /**
32
- * Populates the given module with all modules and their methods
33
- * @param info
34
- * @param generatorMethodsModule The module to populate
35
- * (normally <code>JSON::Generator::GeneratorMethods</code>)
36
- */
37
- static void populate(RuntimeInfo info, RubyModule module) {
38
- defineMethods(module, "Array", RbArray.class);
39
- defineMethods(module, "FalseClass", RbFalse.class);
40
- defineMethods(module, "Float", RbFloat.class);
41
- defineMethods(module, "Hash", RbHash.class);
42
- defineMethods(module, "Integer", RbInteger.class);
43
- defineMethods(module, "NilClass", RbNil.class);
44
- defineMethods(module, "Object", RbObject.class);
45
- defineMethods(module, "String", RbString.class);
46
- defineMethods(module, "TrueClass", RbTrue.class);
47
-
48
- info.stringExtendModule = new WeakReference<RubyModule>(module.defineModuleUnder("String")
49
- .defineModuleUnder("Extend"));
50
- info.stringExtendModule.get().defineAnnotatedMethods(StringExtend.class);
51
- }
52
-
53
- /**
54
- * Convenience method for defining methods on a submodule.
55
- * @param parentModule
56
- * @param submoduleName
57
- * @param klass
58
- */
59
- private static void defineMethods(RubyModule parentModule,
60
- String submoduleName, Class klass) {
61
- RubyModule submodule = parentModule.defineModuleUnder(submoduleName);
62
- submodule.defineAnnotatedMethods(klass);
63
- }
64
-
65
-
66
- public static class RbHash {
67
- @JRubyMethod(rest=true)
68
- public static IRubyObject to_json(ThreadContext context,
69
- IRubyObject vSelf, IRubyObject[] args) {
70
- return Generator.generateJson(context, (RubyHash)vSelf,
71
- Generator.HASH_HANDLER, args);
72
- }
73
- }
74
-
75
- public static class RbArray {
76
- @JRubyMethod(rest=true)
77
- public static IRubyObject to_json(ThreadContext context,
78
- IRubyObject vSelf, IRubyObject[] args) {
79
- return Generator.generateJson(context, (RubyArray)vSelf,
80
- Generator.ARRAY_HANDLER, args);
81
- }
82
- }
83
-
84
- public static class RbInteger {
85
- @JRubyMethod(rest=true)
86
- public static IRubyObject to_json(ThreadContext context,
87
- IRubyObject vSelf, IRubyObject[] args) {
88
- return Generator.generateJson(context, vSelf, args);
89
- }
90
- }
91
-
92
- public static class RbFloat {
93
- @JRubyMethod(rest=true)
94
- public static IRubyObject to_json(ThreadContext context,
95
- IRubyObject vSelf, IRubyObject[] args) {
96
- return Generator.generateJson(context, (RubyFloat)vSelf,
97
- Generator.FLOAT_HANDLER, args);
98
- }
99
- }
100
-
101
- public static class RbString {
102
- @JRubyMethod(rest=true)
103
- public static IRubyObject to_json(ThreadContext context,
104
- IRubyObject vSelf, IRubyObject[] args) {
105
- return Generator.generateJson(context, (RubyString)vSelf,
106
- Generator.STRING_HANDLER, args);
107
- }
108
-
109
- /**
110
- * <code>{@link RubyString String}#to_json_raw(*)</code>
111
- *
112
- * <p>This method creates a JSON text from the result of a call to
113
- * {@link #to_json_raw_object} of this String.
114
- */
115
- @JRubyMethod(rest=true)
116
- public static IRubyObject to_json_raw(ThreadContext context,
117
- IRubyObject vSelf, IRubyObject[] args) {
118
- RubyHash obj = toJsonRawObject(context, Utils.ensureString(vSelf));
119
- return Generator.generateJson(context, obj,
120
- Generator.HASH_HANDLER, args);
121
- }
122
-
123
- /**
124
- * <code>{@link RubyString String}#to_json_raw_object(*)</code>
125
- *
126
- * <p>This method creates a raw object Hash, that can be nested into
127
- * other data structures and will be unparsed as a raw string. This
128
- * method should be used if you want to convert raw strings to JSON
129
- * instead of UTF-8 strings, e.g. binary data.
130
- */
131
- @JRubyMethod(rest=true)
132
- public static IRubyObject to_json_raw_object(ThreadContext context,
133
- IRubyObject vSelf, IRubyObject[] args) {
134
- return toJsonRawObject(context, Utils.ensureString(vSelf));
135
- }
136
-
137
- private static RubyHash toJsonRawObject(ThreadContext context,
138
- RubyString self) {
139
- Ruby runtime = context.getRuntime();
140
- RubyHash result = RubyHash.newHash(runtime);
141
-
142
- IRubyObject createId = RuntimeInfo.forRuntime(runtime)
143
- .jsonModule.get().callMethod(context, "create_id");
144
- result.op_aset(context, createId, self.getMetaClass().to_s());
145
-
146
- ByteList bl = self.getByteList();
147
- byte[] uBytes = bl.unsafeBytes();
148
- RubyArray array = runtime.newArray(bl.length());
149
- for (int i = bl.begin(), t = bl.begin() + bl.length(); i < t; i++) {
150
- array.store(i, runtime.newFixnum(uBytes[i] & 0xff));
151
- }
152
-
153
- result.op_aset(context, runtime.newString("raw"), array);
154
- return result;
155
- }
156
-
157
- @JRubyMethod(required=1, module=true)
158
- public static IRubyObject included(ThreadContext context,
159
- IRubyObject vSelf, IRubyObject module) {
160
- RuntimeInfo info = RuntimeInfo.forRuntime(context.getRuntime());
161
- return module.callMethod(context, "extend", info.stringExtendModule.get());
162
- }
163
- }
164
-
165
- public static class StringExtend {
166
- /**
167
- * <code>{@link RubyString String}#json_create(o)</code>
168
- *
169
- * <p>Raw Strings are JSON Objects (the raw bytes are stored in an
170
- * array for the key "raw"). The Ruby String can be created by this
171
- * module method.
172
- */
173
- @JRubyMethod(required=1)
174
- public static IRubyObject json_create(ThreadContext context,
175
- IRubyObject vSelf, IRubyObject vHash) {
176
- Ruby runtime = context.getRuntime();
177
- RubyHash o = vHash.convertToHash();
178
- IRubyObject rawData = o.fastARef(runtime.newString("raw"));
179
- if (rawData == null) {
180
- throw runtime.newArgumentError("\"raw\" value not defined "
181
- + "for encoded String");
182
- }
183
- RubyArray ary = Utils.ensureArray(rawData);
184
- byte[] bytes = new byte[ary.getLength()];
185
- for (int i = 0, t = ary.getLength(); i < t; i++) {
186
- IRubyObject element = ary.eltInternal(i);
187
- if (element instanceof RubyFixnum) {
188
- bytes[i] = (byte)RubyNumeric.fix2long(element);
189
- } else {
190
- throw runtime.newTypeError(element, runtime.getFixnum());
191
- }
192
- }
193
- return runtime.newString(new ByteList(bytes, false));
194
- }
195
- }
196
-
197
- public static class RbTrue {
198
- @JRubyMethod(rest=true)
199
- public static IRubyObject to_json(ThreadContext context,
200
- IRubyObject vSelf, IRubyObject[] args) {
201
- return Generator.generateJson(context, (RubyBoolean)vSelf,
202
- Generator.TRUE_HANDLER, args);
203
- }
204
- }
205
-
206
- public static class RbFalse {
207
- @JRubyMethod(rest=true)
208
- public static IRubyObject to_json(ThreadContext context,
209
- IRubyObject vSelf, IRubyObject[] args) {
210
- return Generator.generateJson(context, (RubyBoolean)vSelf,
211
- Generator.FALSE_HANDLER, args);
212
- }
213
- }
214
-
215
- public static class RbNil {
216
- @JRubyMethod(rest=true)
217
- public static IRubyObject to_json(ThreadContext context,
218
- IRubyObject vSelf, IRubyObject[] args) {
219
- return Generator.generateJson(context, vSelf,
220
- Generator.NIL_HANDLER, args);
221
- }
222
- }
223
-
224
- public static class RbObject {
225
- @JRubyMethod(rest=true)
226
- public static IRubyObject to_json(ThreadContext context,
227
- IRubyObject self, IRubyObject[] args) {
228
- return RbString.to_json(context, self.asString(), args);
229
- }
230
- }
231
- }
@@ -1,42 +0,0 @@
1
- /*
2
- * This code is copyrighted work by Daniel Luz <dev at mernen dot com>.
3
- *
4
- * Distributed under the Ruby license: https://www.ruby-lang.org/en/about/license.txt
5
- */
6
- package json.ext;
7
-
8
- import java.io.IOException;
9
- import java.lang.ref.WeakReference;
10
-
11
- import org.jruby.Ruby;
12
- import org.jruby.RubyClass;
13
- import org.jruby.RubyModule;
14
- import org.jruby.runtime.load.BasicLibraryService;
15
-
16
- /**
17
- * The service invoked by JRuby's {@link org.jruby.runtime.load.LoadService LoadService}.
18
- * Defines the <code>JSON::Ext::Generator</code> module.
19
- * @author mernen
20
- */
21
- public class GeneratorService implements BasicLibraryService {
22
- public boolean basicLoad(Ruby runtime) throws IOException {
23
- runtime.getLoadService().require("json/common");
24
- RuntimeInfo info = RuntimeInfo.initRuntime(runtime);
25
-
26
- info.jsonModule = new WeakReference<RubyModule>(runtime.defineModule("JSON"));
27
- RubyModule jsonExtModule = info.jsonModule.get().defineModuleUnder("Ext");
28
- RubyModule generatorModule = jsonExtModule.defineModuleUnder("Generator");
29
-
30
- RubyClass stateClass =
31
- generatorModule.defineClassUnder("State", runtime.getObject(),
32
- GeneratorState.ALLOCATOR);
33
- stateClass.defineAnnotatedMethods(GeneratorState.class);
34
- info.generatorStateClass = new WeakReference<RubyClass>(stateClass);
35
-
36
- RubyModule generatorMethods =
37
- generatorModule.defineModuleUnder("GeneratorMethods");
38
- GeneratorMethods.populate(info, generatorMethods);
39
-
40
- return true;
41
- }
42
- }
@@ -1,520 +0,0 @@
1
- /*
2
- * This code is copyrighted work by Daniel Luz <dev at mernen dot com>.
3
- *
4
- * Distributed under the Ruby license: https://www.ruby-lang.org/en/about/license.txt
5
- */
6
- package json.ext;
7
-
8
- import org.jruby.Ruby;
9
- import org.jruby.RubyBoolean;
10
- import org.jruby.RubyClass;
11
- import org.jruby.RubyHash;
12
- import org.jruby.RubyInteger;
13
- import org.jruby.RubyNumeric;
14
- import org.jruby.RubyObject;
15
- import org.jruby.RubyString;
16
- import org.jruby.anno.JRubyMethod;
17
- import org.jruby.runtime.Block;
18
- import org.jruby.runtime.ObjectAllocator;
19
- import org.jruby.runtime.ThreadContext;
20
- import org.jruby.runtime.Visibility;
21
- import org.jruby.runtime.builtin.IRubyObject;
22
- import org.jruby.util.ByteList;
23
-
24
- /**
25
- * The <code>JSON::Ext::Generator::State</code> class.
26
- *
27
- * <p>This class is used to create State instances, that are use to hold data
28
- * while generating a JSON text from a a Ruby data structure.
29
- *
30
- * @author mernen
31
- */
32
- public class GeneratorState extends RubyObject {
33
- /**
34
- * The indenting unit string. Will be repeated several times for larger
35
- * indenting levels.
36
- */
37
- private ByteList indent = ByteList.EMPTY_BYTELIST;
38
- /**
39
- * The spacing to be added after a semicolon on a JSON object.
40
- * @see #spaceBefore
41
- */
42
- private ByteList space = ByteList.EMPTY_BYTELIST;
43
- /**
44
- * The spacing to be added before a semicolon on a JSON object.
45
- * @see #space
46
- */
47
- private ByteList spaceBefore = ByteList.EMPTY_BYTELIST;
48
- /**
49
- * Any suffix to be added after the comma for each element on a JSON object.
50
- * It is assumed to be a newline, if set.
51
- */
52
- private ByteList objectNl = ByteList.EMPTY_BYTELIST;
53
- /**
54
- * Any suffix to be added after the comma for each element on a JSON Array.
55
- * It is assumed to be a newline, if set.
56
- */
57
- private ByteList arrayNl = ByteList.EMPTY_BYTELIST;
58
-
59
- /**
60
- * The maximum level of nesting of structures allowed.
61
- * <code>0</code> means disabled.
62
- */
63
- private int maxNesting = DEFAULT_MAX_NESTING;
64
- static final int DEFAULT_MAX_NESTING = 100;
65
- /**
66
- * Whether special float values (<code>NaN</code>, <code>Infinity</code>,
67
- * <code>-Infinity</code>) are accepted.
68
- * If set to <code>false</code>, an exception will be thrown upon
69
- * encountering one.
70
- */
71
- private boolean allowNaN = DEFAULT_ALLOW_NAN;
72
- static final boolean DEFAULT_ALLOW_NAN = false;
73
- /**
74
- * If set to <code>true</code> all JSON documents generated do not contain
75
- * any other characters than ASCII characters.
76
- */
77
- private boolean asciiOnly = DEFAULT_ASCII_ONLY;
78
- static final boolean DEFAULT_ASCII_ONLY = false;
79
- /**
80
- * If set to <code>true</code> all JSON values generated might not be
81
- * RFC-conform JSON documents.
82
- */
83
- private boolean quirksMode = DEFAULT_QUIRKS_MODE;
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;
91
- /**
92
- * The initial buffer length of this state. (This isn't really used on all
93
- * non-C implementations.)
94
- */
95
- private int bufferInitialLength = DEFAULT_BUFFER_INITIAL_LENGTH;
96
- static final int DEFAULT_BUFFER_INITIAL_LENGTH = 1024;
97
-
98
- /**
99
- * The current depth (inside a #to_json call)
100
- */
101
- private int depth = 0;
102
-
103
- static final ObjectAllocator ALLOCATOR = new ObjectAllocator() {
104
- public IRubyObject allocate(Ruby runtime, RubyClass klazz) {
105
- return new GeneratorState(runtime, klazz);
106
- }
107
- };
108
-
109
- public GeneratorState(Ruby runtime, RubyClass metaClass) {
110
- super(runtime, metaClass);
111
- }
112
-
113
- /**
114
- * <code>State.from_state(opts)</code>
115
- *
116
- * <p>Creates a State object from <code>opts</code>, which ought to be
117
- * {@link RubyHash Hash} to create a new <code>State</code> instance
118
- * configured by <codes>opts</code>, something else to create an
119
- * unconfigured instance. If <code>opts</code> is a <code>State</code>
120
- * object, it is just returned.
121
- * @param clazzParam The receiver of the method call
122
- * ({@link RubyClass} <code>State</code>)
123
- * @param opts The object to use as a base for the new <code>State</code>
124
- * @param block The block passed to the method
125
- * @return A <code>GeneratorState</code> as determined above
126
- */
127
- @JRubyMethod(meta=true)
128
- public static IRubyObject from_state(ThreadContext context,
129
- IRubyObject klass, IRubyObject opts) {
130
- return fromState(context, opts);
131
- }
132
-
133
- static GeneratorState fromState(ThreadContext context, IRubyObject opts) {
134
- return fromState(context, RuntimeInfo.forRuntime(context.getRuntime()), opts);
135
- }
136
-
137
- static GeneratorState fromState(ThreadContext context, RuntimeInfo info,
138
- IRubyObject opts) {
139
- RubyClass klass = info.generatorStateClass.get();
140
- if (opts != null) {
141
- // if the given parameter is a Generator::State, return itself
142
- if (klass.isInstance(opts)) return (GeneratorState)opts;
143
-
144
- // if the given parameter is a Hash, pass it to the instantiator
145
- if (context.getRuntime().getHash().isInstance(opts)) {
146
- return (GeneratorState)klass.newInstance(context,
147
- new IRubyObject[] {opts}, Block.NULL_BLOCK);
148
- }
149
- }
150
-
151
- // for other values, return the safe prototype
152
- return (GeneratorState)info.getSafeStatePrototype(context).dup();
153
- }
154
-
155
- /**
156
- * <code>State#initialize(opts = {})</code>
157
- *
158
- * Instantiates a new <code>State</code> object, configured by <code>opts</code>.
159
- *
160
- * <code>opts</code> can have the following keys:
161
- *
162
- * <dl>
163
- * <dt><code>:indent</code>
164
- * <dd>a {@link RubyString String} used to indent levels (default: <code>""</code>)
165
- * <dt><code>:space</code>
166
- * <dd>a String that is put after a <code>':'</code> or <code>','</code>
167
- * delimiter (default: <code>""</code>)
168
- * <dt><code>:space_before</code>
169
- * <dd>a String that is put before a <code>":"</code> pair delimiter
170
- * (default: <code>""</code>)
171
- * <dt><code>:object_nl</code>
172
- * <dd>a String that is put at the end of a JSON object (default: <code>""</code>)
173
- * <dt><code>:array_nl</code>
174
- * <dd>a String that is put at the end of a JSON array (default: <code>""</code>)
175
- * <dt><code>:allow_nan</code>
176
- * <dd><code>true</code> if <code>NaN</code>, <code>Infinity</code>, and
177
- * <code>-Infinity</code> should be generated, otherwise an exception is
178
- * thrown if these values are encountered.
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>)
183
- */
184
- @JRubyMethod(optional=1, visibility=Visibility.PRIVATE)
185
- public IRubyObject initialize(ThreadContext context, IRubyObject[] args) {
186
- configure(context, args.length > 0 ? args[0] : null);
187
- return this;
188
- }
189
-
190
- @JRubyMethod
191
- public IRubyObject initialize_copy(ThreadContext context, IRubyObject vOrig) {
192
- Ruby runtime = context.getRuntime();
193
- if (!(vOrig instanceof GeneratorState)) {
194
- throw runtime.newTypeError(vOrig, getType());
195
- }
196
- GeneratorState orig = (GeneratorState)vOrig;
197
- this.indent = orig.indent;
198
- this.space = orig.space;
199
- this.spaceBefore = orig.spaceBefore;
200
- this.objectNl = orig.objectNl;
201
- this.arrayNl = orig.arrayNl;
202
- this.maxNesting = orig.maxNesting;
203
- this.allowNaN = orig.allowNaN;
204
- this.asciiOnly = orig.asciiOnly;
205
- this.quirksMode = orig.quirksMode;
206
- this.escapeSlash = orig.escapeSlash;
207
- this.bufferInitialLength = orig.bufferInitialLength;
208
- this.depth = orig.depth;
209
- return this;
210
- }
211
-
212
- /**
213
- * Generates a valid JSON document from object <code>obj</code> and returns
214
- * the result. If no valid JSON document can be created this method raises
215
- * a GeneratorError exception.
216
- */
217
- @JRubyMethod
218
- public IRubyObject generate(ThreadContext context, IRubyObject obj) {
219
- RubyString result = Generator.generateJson(context, obj, this);
220
- RuntimeInfo info = RuntimeInfo.forRuntime(context.getRuntime());
221
- result.force_encoding(context, info.utf8.get());
222
- return result;
223
- }
224
-
225
- private static boolean matchClosingBrace(ByteList bl, int pos, int len,
226
- int brace) {
227
- for (int endPos = len - 1; endPos > pos; endPos--) {
228
- int b = bl.get(endPos);
229
- if (Character.isWhitespace(b)) continue;
230
- return b == brace;
231
- }
232
- return false;
233
- }
234
-
235
- @JRubyMethod(name="[]", required=1)
236
- public IRubyObject op_aref(ThreadContext context, IRubyObject vName) {
237
- String name = vName.asJavaString();
238
- if (getMetaClass().isMethodBound(name, true)) {
239
- return send(context, vName, Block.NULL_BLOCK);
240
- } else {
241
- IRubyObject value = getInstanceVariables().getInstanceVariable("@" + name);
242
- return value == null ? context.nil : value;
243
- }
244
- }
245
-
246
- @JRubyMethod(name="[]=", required=2)
247
- public IRubyObject op_aset(ThreadContext context, IRubyObject vName, IRubyObject value) {
248
- String name = vName.asJavaString();
249
- String nameWriter = name + "=";
250
- if (getMetaClass().isMethodBound(nameWriter, true)) {
251
- return send(context, context.getRuntime().newString(nameWriter), value, Block.NULL_BLOCK);
252
- } else {
253
- getInstanceVariables().setInstanceVariable("@" + name, value);
254
- }
255
- return context.getRuntime().getNil();
256
- }
257
-
258
- public ByteList getIndent() {
259
- return indent;
260
- }
261
-
262
- @JRubyMethod(name="indent")
263
- public RubyString indent_get(ThreadContext context) {
264
- return context.getRuntime().newString(indent);
265
- }
266
-
267
- @JRubyMethod(name="indent=")
268
- public IRubyObject indent_set(ThreadContext context, IRubyObject indent) {
269
- this.indent = prepareByteList(context, indent);
270
- return indent;
271
- }
272
-
273
- public ByteList getSpace() {
274
- return space;
275
- }
276
-
277
- @JRubyMethod(name="space")
278
- public RubyString space_get(ThreadContext context) {
279
- return context.getRuntime().newString(space);
280
- }
281
-
282
- @JRubyMethod(name="space=")
283
- public IRubyObject space_set(ThreadContext context, IRubyObject space) {
284
- this.space = prepareByteList(context, space);
285
- return space;
286
- }
287
-
288
- public ByteList getSpaceBefore() {
289
- return spaceBefore;
290
- }
291
-
292
- @JRubyMethod(name="space_before")
293
- public RubyString space_before_get(ThreadContext context) {
294
- return context.getRuntime().newString(spaceBefore);
295
- }
296
-
297
- @JRubyMethod(name="space_before=")
298
- public IRubyObject space_before_set(ThreadContext context,
299
- IRubyObject spaceBefore) {
300
- this.spaceBefore = prepareByteList(context, spaceBefore);
301
- return spaceBefore;
302
- }
303
-
304
- public ByteList getObjectNl() {
305
- return objectNl;
306
- }
307
-
308
- @JRubyMethod(name="object_nl")
309
- public RubyString object_nl_get(ThreadContext context) {
310
- return context.getRuntime().newString(objectNl);
311
- }
312
-
313
- @JRubyMethod(name="object_nl=")
314
- public IRubyObject object_nl_set(ThreadContext context,
315
- IRubyObject objectNl) {
316
- this.objectNl = prepareByteList(context, objectNl);
317
- return objectNl;
318
- }
319
-
320
- public ByteList getArrayNl() {
321
- return arrayNl;
322
- }
323
-
324
- @JRubyMethod(name="array_nl")
325
- public RubyString array_nl_get(ThreadContext context) {
326
- return context.getRuntime().newString(arrayNl);
327
- }
328
-
329
- @JRubyMethod(name="array_nl=")
330
- public IRubyObject array_nl_set(ThreadContext context,
331
- IRubyObject arrayNl) {
332
- this.arrayNl = prepareByteList(context, arrayNl);
333
- return arrayNl;
334
- }
335
-
336
- @JRubyMethod(name="check_circular?")
337
- public RubyBoolean check_circular_p(ThreadContext context) {
338
- return context.getRuntime().newBoolean(maxNesting != 0);
339
- }
340
-
341
- /**
342
- * Returns the maximum level of nesting configured for this state.
343
- */
344
- public int getMaxNesting() {
345
- return maxNesting;
346
- }
347
-
348
- @JRubyMethod(name="max_nesting")
349
- public RubyInteger max_nesting_get(ThreadContext context) {
350
- return context.getRuntime().newFixnum(maxNesting);
351
- }
352
-
353
- @JRubyMethod(name="max_nesting=")
354
- public IRubyObject max_nesting_set(IRubyObject max_nesting) {
355
- maxNesting = RubyNumeric.fix2int(max_nesting);
356
- return max_nesting;
357
- }
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
-
377
- public boolean allowNaN() {
378
- return allowNaN;
379
- }
380
-
381
- @JRubyMethod(name="allow_nan?")
382
- public RubyBoolean allow_nan_p(ThreadContext context) {
383
- return context.getRuntime().newBoolean(allowNaN);
384
- }
385
-
386
- public boolean asciiOnly() {
387
- return asciiOnly;
388
- }
389
-
390
- @JRubyMethod(name="ascii_only?")
391
- public RubyBoolean ascii_only_p(ThreadContext context) {
392
- return context.getRuntime().newBoolean(asciiOnly);
393
- }
394
-
395
- @JRubyMethod(name="buffer_initial_length")
396
- public RubyInteger buffer_initial_length_get(ThreadContext context) {
397
- return context.getRuntime().newFixnum(bufferInitialLength);
398
- }
399
-
400
- @JRubyMethod(name="buffer_initial_length=")
401
- public IRubyObject buffer_initial_length_set(IRubyObject buffer_initial_length) {
402
- int newLength = RubyNumeric.fix2int(buffer_initial_length);
403
- if (newLength > 0) bufferInitialLength = newLength;
404
- return buffer_initial_length;
405
- }
406
-
407
- public int getDepth() {
408
- return depth;
409
- }
410
-
411
- @JRubyMethod(name="depth")
412
- public RubyInteger depth_get(ThreadContext context) {
413
- return context.getRuntime().newFixnum(depth);
414
- }
415
-
416
- @JRubyMethod(name="depth=")
417
- public IRubyObject depth_set(IRubyObject vDepth) {
418
- depth = RubyNumeric.fix2int(vDepth);
419
- return vDepth;
420
- }
421
-
422
- private ByteList prepareByteList(ThreadContext context, IRubyObject value) {
423
- RubyString str = value.convertToString();
424
- RuntimeInfo info = RuntimeInfo.forRuntime(context.getRuntime());
425
- if (str.encoding(context) != info.utf8.get()) {
426
- str = (RubyString)str.encode(context, info.utf8.get());
427
- }
428
- return str.getByteList().dup();
429
- }
430
-
431
- /**
432
- * <code>State#configure(opts)</code>
433
- *
434
- * <p>Configures this State instance with the {@link RubyHash Hash}
435
- * <code>opts</code>, and returns itself.
436
- * @param vOpts The options hash
437
- * @return The receiver
438
- */
439
- @JRubyMethod(alias = "merge")
440
- public IRubyObject configure(ThreadContext context, IRubyObject vOpts) {
441
- OptionsReader opts = new OptionsReader(context, vOpts);
442
-
443
- ByteList indent = opts.getString("indent");
444
- if (indent != null) this.indent = indent;
445
-
446
- ByteList space = opts.getString("space");
447
- if (space != null) this.space = space;
448
-
449
- ByteList spaceBefore = opts.getString("space_before");
450
- if (spaceBefore != null) this.spaceBefore = spaceBefore;
451
-
452
- ByteList arrayNl = opts.getString("array_nl");
453
- if (arrayNl != null) this.arrayNl = arrayNl;
454
-
455
- ByteList objectNl = opts.getString("object_nl");
456
- if (objectNl != null) this.objectNl = objectNl;
457
-
458
- maxNesting = opts.getInt("max_nesting", DEFAULT_MAX_NESTING);
459
- allowNaN = opts.getBool("allow_nan", DEFAULT_ALLOW_NAN);
460
- asciiOnly = opts.getBool("ascii_only", DEFAULT_ASCII_ONLY);
461
- escapeSlash = opts.getBool("escape_slash", DEFAULT_ESCAPE_SLASH);
462
- bufferInitialLength = opts.getInt("buffer_initial_length", DEFAULT_BUFFER_INITIAL_LENGTH);
463
-
464
- depth = opts.getInt("depth", 0);
465
-
466
- return this;
467
- }
468
-
469
- /**
470
- * <code>State#to_h()</code>
471
- *
472
- * <p>Returns the configuration instance variables as a hash, that can be
473
- * passed to the configure method.
474
- * @return the hash
475
- */
476
- @JRubyMethod(alias = "to_hash")
477
- public RubyHash to_h(ThreadContext context) {
478
- Ruby runtime = context.getRuntime();
479
- RubyHash result = RubyHash.newHash(runtime);
480
-
481
- result.op_aset(context, runtime.newSymbol("indent"), indent_get(context));
482
- result.op_aset(context, runtime.newSymbol("space"), space_get(context));
483
- result.op_aset(context, runtime.newSymbol("space_before"), space_before_get(context));
484
- result.op_aset(context, runtime.newSymbol("object_nl"), object_nl_get(context));
485
- result.op_aset(context, runtime.newSymbol("array_nl"), array_nl_get(context));
486
- result.op_aset(context, runtime.newSymbol("allow_nan"), allow_nan_p(context));
487
- result.op_aset(context, runtime.newSymbol("ascii_only"), ascii_only_p(context));
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));
490
- result.op_aset(context, runtime.newSymbol("depth"), depth_get(context));
491
- result.op_aset(context, runtime.newSymbol("buffer_initial_length"), buffer_initial_length_get(context));
492
- for (String name: getInstanceVariableNameList()) {
493
- result.op_aset(context, runtime.newSymbol(name.substring(1)), getInstanceVariables().getInstanceVariable(name));
494
- }
495
- return result;
496
- }
497
-
498
- public int increaseDepth() {
499
- depth++;
500
- checkMaxNesting();
501
- return depth;
502
- }
503
-
504
- public int decreaseDepth() {
505
- return --depth;
506
- }
507
-
508
- /**
509
- * Checks if the current depth is allowed as per this state's options.
510
- * @param context
511
- * @param depth The corrent depth
512
- */
513
- private void checkMaxNesting() {
514
- if (maxNesting != 0 && depth > maxNesting) {
515
- depth--;
516
- throw Utils.newException(getRuntime().getCurrentContext(),
517
- Utils.M_NESTING_ERROR, "nesting of " + depth + " is too deep");
518
- }
519
- }
520
- }