json 1.1.0 → 1.1.1
Sign up to get free protection for your applications and to get access to all the features.
Potentially problematic release.
This version of json might be problematic. Click here for more details.
- data/CHANGES +18 -0
- data/Rakefile +5 -5
- data/VERSION +1 -1
- data/benchmarks/benchmark_generator.rb +5 -1
- data/benchmarks/benchmark_parser.rb +5 -1
- data/bin/edit_json.rb +11 -11
- data/ext/json/ext/generator/extconf.rb +2 -2
- data/ext/json/ext/generator/generator.c +185 -50
- data/ext/json/ext/parser/extconf.rb +2 -2
- data/ext/json/ext/parser/parser.c +246 -117
- data/ext/json/ext/parser/parser.rl +54 -6
- data/lib/json.rb +23 -0
- data/lib/json/add/core.rb +119 -0
- data/lib/json/add/rails.rb +52 -0
- data/lib/json/common.rb +174 -23
- data/lib/json/editor.rb +12 -14
- data/lib/json/pure/generator.rb +83 -10
- data/lib/json/pure/parser.rb +15 -1
- data/lib/json/version.rb +1 -1
- data/tests/fixtures/fail18.json +1 -1
- data/tests/test_json.rb +51 -12
- data/tests/test_json_addition.rb +34 -3
- data/tests/test_json_fixtures.rb +2 -2
- data/tests/test_json_generate.rb +21 -2
- data/tests/test_json_unicode.rb +4 -1
- data/tools/fuzz.rb +2 -1
- metadata +6 -3
data/CHANGES
CHANGED
@@ -1,3 +1,21 @@
|
|
1
|
+
2007-07-06 (1.1.1)
|
2
|
+
* Yui NARUSE <naruse@airemix.com> sent some patches to fix tests for Ruby
|
3
|
+
1.9. I applied them and adapted some of them a bit to run both on 1.8 and
|
4
|
+
1.9.
|
5
|
+
* Introduced a JSON.parse! method without depth checking for people who like
|
6
|
+
danger.
|
7
|
+
* Made generate and pretty_generate methods configurable by an options hash.
|
8
|
+
* Added :allow_nan option to parser and generator in order to handle NaN,
|
9
|
+
Infinity, and -Infinity correctly - if requested. Floats, which aren't numbers,
|
10
|
+
aren't valid JSON according to RFC4627, so by default an exception will be
|
11
|
+
raised if any of these symbols are encountered. Thanks to Andrea Censi
|
12
|
+
<andrea.censi@dis.uniroma1.it> for his hint about this.
|
13
|
+
* Fixed some more tests for Ruby 1.9.
|
14
|
+
* Implemented dump/load interface of Marshal as suggested in ruby-core:11405
|
15
|
+
by murphy <murphy@rubychan.de>.
|
16
|
+
* Implemented the max_nesting feature for generate methods, too.
|
17
|
+
* Added some implementations for ruby core's custom objects for
|
18
|
+
serialisation/deserialisation purposes.
|
1
19
|
2007-05-21 (1.1.0)
|
2
20
|
* Implemented max_nesting feature for parser to avoid stack overflows for
|
3
21
|
data from untrusted sources. If you trust the source, you can disable it
|
data/Rakefile
CHANGED
@@ -124,12 +124,12 @@ end
|
|
124
124
|
|
125
125
|
desc "Benchmarking parser (pure)"
|
126
126
|
task :benchmark_parser_pure do
|
127
|
-
ruby '-I lib benchmarks/benchmark_parser.rb'
|
127
|
+
ruby '-I lib benchmarks/benchmark_parser.rb pure'
|
128
128
|
end
|
129
129
|
|
130
130
|
desc "Benchmarking generator (pure)"
|
131
131
|
task :benchmark_generator_pure do
|
132
|
-
ruby '-I lib benchmarks/benchmark_generator.rb'
|
132
|
+
ruby '-I lib benchmarks/benchmark_generator.rb pure'
|
133
133
|
ruby 'benchmarks/benchmark_rails.rb'
|
134
134
|
end
|
135
135
|
|
@@ -138,12 +138,12 @@ task :benchmark_pure => [ :benchmark_parser_pure, :benchmark_generator_pure ]
|
|
138
138
|
|
139
139
|
desc "Benchmarking parser (extension)"
|
140
140
|
task :benchmark_parser_ext => :compile do
|
141
|
-
ruby '-I ext:lib benchmarks/benchmark_parser.rb'
|
141
|
+
ruby '-I ext:lib benchmarks/benchmark_parser.rb ext'
|
142
142
|
end
|
143
143
|
|
144
144
|
desc "Benchmarking generator (extension)"
|
145
145
|
task :benchmark_generator_ext => :compile do
|
146
|
-
ruby '-I ext:lib benchmarks/benchmark_generator.rb'
|
146
|
+
ruby '-I ext:lib benchmarks/benchmark_generator.rb ext'
|
147
147
|
ruby 'benchmarks/benchmark_rails.rb'
|
148
148
|
end
|
149
149
|
|
@@ -164,7 +164,7 @@ end
|
|
164
164
|
|
165
165
|
desc "Create RDOC documentation"
|
166
166
|
task :doc => [ :version, EXT_PARSER_SRC ] do
|
167
|
-
sh "rdoc -m JSON -
|
167
|
+
sh "rdoc -m JSON -S -o doc #{FileList['lib/**/*.rb']} #{EXT_PARSER_SRC} #{EXT_GENERATOR_SRC}"
|
168
168
|
end
|
169
169
|
|
170
170
|
spec_pure = Gem::Specification.new do |s|
|
data/VERSION
CHANGED
@@ -1 +1 @@
|
|
1
|
-
1.1.
|
1
|
+
1.1.1
|
data/bin/edit_json.rb
CHANGED
@@ -1,11 +1,11 @@
|
|
1
|
-
#!/usr/bin/env ruby
|
2
|
-
$KCODE = 'U'
|
3
|
-
require 'json/editor'
|
4
|
-
|
5
|
-
filename, encoding = ARGV
|
6
|
-
JSON::Editor.start(encoding) do |window|
|
7
|
-
if filename
|
8
|
-
window.file_open(filename)
|
9
|
-
end
|
10
|
-
end
|
11
|
-
# vim: set et sw=2 ts=2:
|
1
|
+
#!/usr/bin/env ruby
|
2
|
+
$KCODE = 'U'
|
3
|
+
require 'json/editor'
|
4
|
+
|
5
|
+
filename, encoding = ARGV
|
6
|
+
JSON::Editor.start(encoding) do |window|
|
7
|
+
if filename
|
8
|
+
window.file_open(filename)
|
9
|
+
end
|
10
|
+
end
|
11
|
+
# vim: set et sw=2 ts=2:
|
@@ -4,15 +4,22 @@
|
|
4
4
|
#include "ruby.h"
|
5
5
|
#include "st.h"
|
6
6
|
#include "unicode.h"
|
7
|
+
#include <math.h>
|
8
|
+
|
9
|
+
#define check_max_nesting(state, depth) do { \
|
10
|
+
long current_nesting = 1 + depth; \
|
11
|
+
if (state->max_nesting != 0 && current_nesting > state->max_nesting) \
|
12
|
+
rb_raise(eNestingError, "nesting of %u is too deep", current_nesting); \
|
13
|
+
} while (0);
|
7
14
|
|
8
15
|
static VALUE mJSON, mExt, mGenerator, cState, mGeneratorMethods, mObject,
|
9
16
|
mHash, mArray, mInteger, mFloat, mString, mString_Extend,
|
10
17
|
mTrueClass, mFalseClass, mNilClass, eGeneratorError,
|
11
|
-
eCircularDatastructure;
|
18
|
+
eCircularDatastructure, eNestingError;
|
12
19
|
|
13
20
|
static ID i_to_s, i_to_json, i_new, i_indent, i_space, i_space_before,
|
14
|
-
i_object_nl, i_array_nl, i_check_circular,
|
15
|
-
i_create_id, i_extend;
|
21
|
+
i_object_nl, i_array_nl, i_check_circular, i_max_nesting,
|
22
|
+
i_allow_nan, i_pack, i_unpack, i_create_id, i_extend;
|
16
23
|
|
17
24
|
typedef struct JSON_Generator_StateStruct {
|
18
25
|
VALUE indent;
|
@@ -24,7 +31,9 @@ typedef struct JSON_Generator_StateStruct {
|
|
24
31
|
VALUE seen;
|
25
32
|
VALUE memo;
|
26
33
|
VALUE depth;
|
34
|
+
long max_nesting;
|
27
35
|
int flag;
|
36
|
+
int allow_nan;
|
28
37
|
} JSON_Generator_State;
|
29
38
|
|
30
39
|
#define GET_STATE(self) \
|
@@ -138,6 +147,7 @@ static VALUE mHash_to_json(int argc, VALUE *argv, VALUE self)
|
|
138
147
|
rb_str_buf_cat2(result, "}");
|
139
148
|
} else {
|
140
149
|
GET_STATE(Vstate);
|
150
|
+
check_max_nesting(state, depth);
|
141
151
|
if (state->check_circular) {
|
142
152
|
VALUE self_id = rb_obj_id(self);
|
143
153
|
if (RTEST(rb_hash_aref(state->seen, self_id))) {
|
@@ -162,6 +172,7 @@ inline static VALUE mArray_json_transfrom(VALUE self, VALUE Vstate, VALUE Vdepth
|
|
162
172
|
VALUE delim = rb_str_new2(",");
|
163
173
|
GET_STATE(Vstate);
|
164
174
|
|
175
|
+
check_max_nesting(state, depth);
|
165
176
|
if (state->check_circular) {
|
166
177
|
VALUE self_id = rb_obj_id(self);
|
167
178
|
rb_hash_aset(state->seen, self_id, Qtrue);
|
@@ -170,6 +181,7 @@ inline static VALUE mArray_json_transfrom(VALUE self, VALUE Vstate, VALUE Vdepth
|
|
170
181
|
shift = rb_str_times(state->indent, LONG2FIX(depth + 1));
|
171
182
|
|
172
183
|
rb_str_buf_cat2(result, "[");
|
184
|
+
OBJ_INFECT(result, self);
|
173
185
|
rb_str_buf_append(result, state->array_nl);
|
174
186
|
for (i = 0; i < len; i++) {
|
175
187
|
VALUE element = RARRAY_PTR(self)[i];
|
@@ -190,6 +202,7 @@ inline static VALUE mArray_json_transfrom(VALUE self, VALUE Vstate, VALUE Vdepth
|
|
190
202
|
rb_hash_delete(state->seen, self_id);
|
191
203
|
} else {
|
192
204
|
result = rb_str_buf_new(len);
|
205
|
+
OBJ_INFECT(result, self);
|
193
206
|
if (RSTRING_LEN(state->array_nl)) rb_str_append(delim, state->array_nl);
|
194
207
|
shift = rb_str_times(state->indent, LONG2FIX(depth + 1));
|
195
208
|
|
@@ -228,6 +241,7 @@ static VALUE mArray_to_json(int argc, VALUE *argv, VALUE self) {
|
|
228
241
|
long i, len = RARRAY_LEN(self);
|
229
242
|
result = rb_str_buf_new(2 + 2 * len);
|
230
243
|
rb_str_buf_cat2(result, "[");
|
244
|
+
OBJ_INFECT(result, self);
|
231
245
|
for (i = 0; i < len; i++) {
|
232
246
|
VALUE element = RARRAY_PTR(self)[i];
|
233
247
|
OBJ_INFECT(result, element);
|
@@ -259,7 +273,28 @@ static VALUE mInteger_to_json(int argc, VALUE *argv, VALUE self)
|
|
259
273
|
*/
|
260
274
|
static VALUE mFloat_to_json(int argc, VALUE *argv, VALUE self)
|
261
275
|
{
|
262
|
-
|
276
|
+
JSON_Generator_State *state = NULL;
|
277
|
+
VALUE Vstate, rest, tmp;
|
278
|
+
double value = RFLOAT(self)->value;
|
279
|
+
rb_scan_args(argc, argv, "01*", &Vstate, &rest);
|
280
|
+
if (!NIL_P(Vstate)) Data_Get_Struct(Vstate, JSON_Generator_State, state);
|
281
|
+
if (isinf(value)) {
|
282
|
+
if (!state || state->allow_nan) {
|
283
|
+
return rb_funcall(self, i_to_s, 0);
|
284
|
+
} else {
|
285
|
+
tmp = rb_funcall(self, i_to_s, 0);
|
286
|
+
rb_raise(eGeneratorError, "%s not allowed in JSON", StringValueCStr(tmp));
|
287
|
+
}
|
288
|
+
} else if (isnan(value)) {
|
289
|
+
if (!state || state->allow_nan) {
|
290
|
+
return rb_funcall(self, i_to_s, 0);
|
291
|
+
} else {
|
292
|
+
tmp = rb_funcall(self, i_to_s, 0);
|
293
|
+
rb_raise(eGeneratorError, "%s not allowed in JSON", StringValueCStr(tmp));
|
294
|
+
}
|
295
|
+
} else {
|
296
|
+
return rb_funcall(self, i_to_s, 0);
|
297
|
+
}
|
263
298
|
}
|
264
299
|
|
265
300
|
/*
|
@@ -403,6 +438,92 @@ static VALUE cState_s_allocate(VALUE klass)
|
|
403
438
|
return Data_Wrap_Struct(klass, State_mark, -1, state);
|
404
439
|
}
|
405
440
|
|
441
|
+
/*
|
442
|
+
* call-seq: configure(opts)
|
443
|
+
*
|
444
|
+
* Configure this State instance with the Hash _opts_, and return
|
445
|
+
* itself.
|
446
|
+
*/
|
447
|
+
static inline VALUE cState_configure(VALUE self, VALUE opts)
|
448
|
+
{
|
449
|
+
VALUE tmp;
|
450
|
+
GET_STATE(self);
|
451
|
+
tmp = rb_convert_type(opts, T_HASH, "Hash", "to_hash");
|
452
|
+
if (NIL_P(tmp)) tmp = rb_convert_type(opts, T_HASH, "Hash", "to_h");
|
453
|
+
if (NIL_P(tmp)) {
|
454
|
+
rb_raise(rb_eArgError, "opts has to be hash like or convertable into a hash");
|
455
|
+
}
|
456
|
+
opts = tmp;
|
457
|
+
tmp = rb_hash_aref(opts, ID2SYM(i_indent));
|
458
|
+
if (RTEST(tmp)) {
|
459
|
+
Check_Type(tmp, T_STRING);
|
460
|
+
state->indent = tmp;
|
461
|
+
}
|
462
|
+
tmp = rb_hash_aref(opts, ID2SYM(i_space));
|
463
|
+
if (RTEST(tmp)) {
|
464
|
+
Check_Type(tmp, T_STRING);
|
465
|
+
state->space = tmp;
|
466
|
+
}
|
467
|
+
tmp = rb_hash_aref(opts, ID2SYM(i_space_before));
|
468
|
+
if (RTEST(tmp)) {
|
469
|
+
Check_Type(tmp, T_STRING);
|
470
|
+
state->space_before = tmp;
|
471
|
+
}
|
472
|
+
tmp = rb_hash_aref(opts, ID2SYM(i_array_nl));
|
473
|
+
if (RTEST(tmp)) {
|
474
|
+
Check_Type(tmp, T_STRING);
|
475
|
+
state->array_nl = tmp;
|
476
|
+
}
|
477
|
+
tmp = rb_hash_aref(opts, ID2SYM(i_object_nl));
|
478
|
+
if (RTEST(tmp)) {
|
479
|
+
Check_Type(tmp, T_STRING);
|
480
|
+
state->object_nl = tmp;
|
481
|
+
}
|
482
|
+
tmp = ID2SYM(i_check_circular);
|
483
|
+
if (st_lookup(RHASH(opts)->tbl, tmp, 0)) {
|
484
|
+
tmp = rb_hash_aref(opts, ID2SYM(i_check_circular));
|
485
|
+
state->check_circular = RTEST(tmp);
|
486
|
+
} else {
|
487
|
+
state->check_circular = 1;
|
488
|
+
}
|
489
|
+
tmp = ID2SYM(i_max_nesting);
|
490
|
+
state->max_nesting = 19;
|
491
|
+
if (st_lookup(RHASH(opts)->tbl, tmp, 0)) {
|
492
|
+
VALUE max_nesting = rb_hash_aref(opts, tmp);
|
493
|
+
if (RTEST(max_nesting)) {
|
494
|
+
Check_Type(max_nesting, T_FIXNUM);
|
495
|
+
state->max_nesting = FIX2LONG(max_nesting);
|
496
|
+
} else {
|
497
|
+
state->max_nesting = 0;
|
498
|
+
}
|
499
|
+
}
|
500
|
+
tmp = rb_hash_aref(opts, ID2SYM(i_allow_nan));
|
501
|
+
state->allow_nan = RTEST(tmp);
|
502
|
+
return self;
|
503
|
+
}
|
504
|
+
|
505
|
+
/*
|
506
|
+
* call-seq: to_h
|
507
|
+
*
|
508
|
+
* Returns the configuration instance variables as a hash, that can be
|
509
|
+
* passed to the configure method.
|
510
|
+
*/
|
511
|
+
static VALUE cState_to_h(VALUE self)
|
512
|
+
{
|
513
|
+
VALUE result = rb_hash_new();
|
514
|
+
GET_STATE(self);
|
515
|
+
rb_hash_aset(result, ID2SYM(i_indent), state->indent);
|
516
|
+
rb_hash_aset(result, ID2SYM(i_space), state->space);
|
517
|
+
rb_hash_aset(result, ID2SYM(i_space_before), state->space_before);
|
518
|
+
rb_hash_aset(result, ID2SYM(i_object_nl), state->object_nl);
|
519
|
+
rb_hash_aset(result, ID2SYM(i_array_nl), state->array_nl);
|
520
|
+
rb_hash_aset(result, ID2SYM(i_check_circular), state->check_circular ? Qtrue : Qfalse);
|
521
|
+
rb_hash_aset(result, ID2SYM(i_allow_nan), state->allow_nan ? Qtrue : Qfalse);
|
522
|
+
rb_hash_aset(result, ID2SYM(i_max_nesting), LONG2FIX(state->max_nesting));
|
523
|
+
return result;
|
524
|
+
}
|
525
|
+
|
526
|
+
|
406
527
|
/*
|
407
528
|
* call-seq: new(opts = {})
|
408
529
|
*
|
@@ -417,6 +538,9 @@ static VALUE cState_s_allocate(VALUE klass)
|
|
417
538
|
* * *array_nl*: a string that is put at the end of a JSON array (default: ''),
|
418
539
|
* * *check_circular*: true if checking for circular data structures
|
419
540
|
* should be done, false (the default) otherwise.
|
541
|
+
* * *allow_nan*: true if NaN, Infinity, and -Infinity should be
|
542
|
+
* generated, otherwise an exception is thrown, if these values are
|
543
|
+
* encountered. This options defaults to false.
|
420
544
|
*/
|
421
545
|
static VALUE cState_initialize(int argc, VALUE *argv, VALUE self)
|
422
546
|
{
|
@@ -424,53 +548,17 @@ static VALUE cState_initialize(int argc, VALUE *argv, VALUE self)
|
|
424
548
|
GET_STATE(self);
|
425
549
|
|
426
550
|
rb_scan_args(argc, argv, "01", &opts);
|
551
|
+
state->indent = rb_str_new2("");
|
552
|
+
state->space = rb_str_new2("");
|
553
|
+
state->space_before = rb_str_new2("");
|
554
|
+
state->array_nl = rb_str_new2("");
|
555
|
+
state->object_nl = rb_str_new2("");
|
427
556
|
if (NIL_P(opts)) {
|
428
|
-
state->
|
429
|
-
state->
|
430
|
-
state->
|
431
|
-
state->array_nl = rb_str_new2("");
|
432
|
-
state->object_nl = rb_str_new2("");
|
433
|
-
state->check_circular = 0;
|
557
|
+
state->check_circular = 1;
|
558
|
+
state->allow_nan = 0;
|
559
|
+
state->max_nesting = 19;
|
434
560
|
} else {
|
435
|
-
|
436
|
-
opts = rb_convert_type(opts, T_HASH, "Hash", "to_hash");
|
437
|
-
tmp = rb_hash_aref(opts, ID2SYM(i_indent));
|
438
|
-
if (RTEST(tmp)) {
|
439
|
-
Check_Type(tmp, T_STRING);
|
440
|
-
state->indent = tmp;
|
441
|
-
} else {
|
442
|
-
state->indent = rb_str_new2("");
|
443
|
-
}
|
444
|
-
tmp = rb_hash_aref(opts, ID2SYM(i_space));
|
445
|
-
if (RTEST(tmp)) {
|
446
|
-
Check_Type(tmp, T_STRING);
|
447
|
-
state->space = tmp;
|
448
|
-
} else {
|
449
|
-
state->space = rb_str_new2("");
|
450
|
-
}
|
451
|
-
tmp = rb_hash_aref(opts, ID2SYM(i_space_before));
|
452
|
-
if (RTEST(tmp)) {
|
453
|
-
Check_Type(tmp, T_STRING);
|
454
|
-
state->space_before = tmp;
|
455
|
-
} else {
|
456
|
-
state->space_before = rb_str_new2("");
|
457
|
-
}
|
458
|
-
tmp = rb_hash_aref(opts, ID2SYM(i_array_nl));
|
459
|
-
if (RTEST(tmp)) {
|
460
|
-
Check_Type(tmp, T_STRING);
|
461
|
-
state->array_nl = tmp;
|
462
|
-
} else {
|
463
|
-
state->array_nl = rb_str_new2("");
|
464
|
-
}
|
465
|
-
tmp = rb_hash_aref(opts, ID2SYM(i_object_nl));
|
466
|
-
if (RTEST(tmp)) {
|
467
|
-
Check_Type(tmp, T_STRING);
|
468
|
-
state->object_nl = tmp;
|
469
|
-
} else {
|
470
|
-
state->object_nl = rb_str_new2("");
|
471
|
-
}
|
472
|
-
tmp = rb_hash_aref(opts, ID2SYM(i_check_circular));
|
473
|
-
state->check_circular = RTEST(tmp);
|
561
|
+
cState_configure(self, opts);
|
474
562
|
}
|
475
563
|
state->seen = rb_hash_new();
|
476
564
|
state->memo = Qnil;
|
@@ -616,7 +704,7 @@ static VALUE cState_array_nl_set(VALUE self, VALUE array_nl)
|
|
616
704
|
}
|
617
705
|
|
618
706
|
/*
|
619
|
-
* call-seq: check_circular?
|
707
|
+
* call-seq: check_circular?
|
620
708
|
*
|
621
709
|
* Returns true, if circular data structures should be checked,
|
622
710
|
* otherwise returns false.
|
@@ -627,6 +715,44 @@ static VALUE cState_check_circular_p(VALUE self)
|
|
627
715
|
return state->check_circular ? Qtrue : Qfalse;
|
628
716
|
}
|
629
717
|
|
718
|
+
/*
|
719
|
+
* call-seq: max_nesting
|
720
|
+
*
|
721
|
+
* This integer returns the maximum level of data structure nesting in
|
722
|
+
* the generated JSON, max_nesting = 0 if no maximum is checked.
|
723
|
+
*/
|
724
|
+
static VALUE cState_max_nesting(VALUE self)
|
725
|
+
{
|
726
|
+
GET_STATE(self);
|
727
|
+
return LONG2FIX(state->max_nesting);
|
728
|
+
}
|
729
|
+
|
730
|
+
/*
|
731
|
+
* call-seq: max_nesting=(depth)
|
732
|
+
*
|
733
|
+
* This sets the maximum level of data structure nesting in the generated JSON
|
734
|
+
* to the integer depth, max_nesting = 0 if no maximum should be checked.
|
735
|
+
*/
|
736
|
+
static VALUE cState_max_nesting_set(VALUE self, VALUE depth)
|
737
|
+
{
|
738
|
+
GET_STATE(self);
|
739
|
+
Check_Type(depth, T_FIXNUM);
|
740
|
+
state->max_nesting = FIX2LONG(depth);
|
741
|
+
return Qnil;
|
742
|
+
}
|
743
|
+
|
744
|
+
/*
|
745
|
+
* call-seq: allow_nan?
|
746
|
+
*
|
747
|
+
* Returns true, if NaN, Infinity, and -Infinity should be generated, otherwise
|
748
|
+
* returns false.
|
749
|
+
*/
|
750
|
+
static VALUE cState_allow_nan_p(VALUE self)
|
751
|
+
{
|
752
|
+
GET_STATE(self);
|
753
|
+
return state->allow_nan ? Qtrue : Qfalse;
|
754
|
+
}
|
755
|
+
|
630
756
|
/*
|
631
757
|
* call-seq: seen?(object)
|
632
758
|
*
|
@@ -668,6 +794,7 @@ void Init_generator()
|
|
668
794
|
mGenerator = rb_define_module_under(mExt, "Generator");
|
669
795
|
eGeneratorError = rb_path2class("JSON::GeneratorError");
|
670
796
|
eCircularDatastructure = rb_path2class("JSON::CircularDatastructure");
|
797
|
+
eNestingError = rb_path2class("JSON::NestingError");
|
671
798
|
cState = rb_define_class_under(mGenerator, "State", rb_cObject);
|
672
799
|
rb_define_alloc_func(cState, cState_s_allocate);
|
673
800
|
rb_define_singleton_method(cState, "from_state", cState_from_state_s, 1);
|
@@ -684,9 +811,15 @@ void Init_generator()
|
|
684
811
|
rb_define_method(cState, "array_nl", cState_array_nl, 0);
|
685
812
|
rb_define_method(cState, "array_nl=", cState_array_nl_set, 1);
|
686
813
|
rb_define_method(cState, "check_circular?", cState_check_circular_p, 0);
|
814
|
+
rb_define_method(cState, "max_nesting", cState_max_nesting, 0);
|
815
|
+
rb_define_method(cState, "max_nesting=", cState_max_nesting_set, 1);
|
816
|
+
rb_define_method(cState, "allow_nan?", cState_allow_nan_p, 0);
|
687
817
|
rb_define_method(cState, "seen?", cState_seen_p, 1);
|
688
818
|
rb_define_method(cState, "remember", cState_remember, 1);
|
689
819
|
rb_define_method(cState, "forget", cState_forget, 1);
|
820
|
+
rb_define_method(cState, "configure", cState_configure, 1);
|
821
|
+
rb_define_method(cState, "to_h", cState_to_h, 0);
|
822
|
+
|
690
823
|
mGeneratorMethods = rb_define_module_under(mGenerator, "GeneratorMethods");
|
691
824
|
mObject = rb_define_module_under(mGeneratorMethods, "Object");
|
692
825
|
rb_define_method(mObject, "to_json", mObject_to_json, -1);
|
@@ -721,6 +854,8 @@ void Init_generator()
|
|
721
854
|
i_object_nl = rb_intern("object_nl");
|
722
855
|
i_array_nl = rb_intern("array_nl");
|
723
856
|
i_check_circular = rb_intern("check_circular");
|
857
|
+
i_max_nesting = rb_intern("max_nesting");
|
858
|
+
i_allow_nan = rb_intern("allow_nan");
|
724
859
|
i_pack = rb_intern("pack");
|
725
860
|
i_unpack = rb_intern("unpack");
|
726
861
|
i_create_id = rb_intern("create_id");
|