json_pure 1.1.0 → 1.1.1
Sign up to get free protection for your applications and to get access to all the features.
- 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");
|