json_pure 2.0.4 → 2.4.0
This diff represents the content of publicly available package versions that have been released to one of the supported registries. The information contained in this diff is provided for informational purposes only and reflects changes between package versions as they appear in their respective public registries.
- checksums.yaml +5 -5
- data/.gitignore +1 -0
- data/.travis.yml +9 -5
- data/CHANGES.md +39 -0
- data/Gemfile +1 -3
- data/LICENSE +56 -0
- data/README.md +54 -21
- data/Rakefile +19 -93
- data/VERSION +1 -1
- data/ext/json/ext/generator/generator.c +214 -45
- data/ext/json/ext/generator/generator.h +5 -2
- data/ext/json/ext/parser/extconf.rb +25 -0
- data/ext/json/ext/parser/parser.c +155 -83
- data/ext/json/ext/parser/parser.h +2 -0
- data/ext/json/ext/parser/parser.rl +79 -7
- data/ext/json/extconf.rb +1 -0
- data/java/src/json/ext/Generator.java +28 -24
- data/java/src/json/ext/GeneratorState.java +30 -0
- data/java/src/json/ext/Parser.java +109 -82
- data/java/src/json/ext/Parser.rl +39 -12
- data/java/src/json/ext/StringEncoder.java +8 -2
- data/json-java.gemspec +22 -22
- data/json.gemspec +0 -0
- data/json_pure.gemspec +9 -14
- data/lib/json.rb +549 -29
- data/lib/json/add/bigdecimal.rb +2 -2
- data/lib/json/add/complex.rb +2 -3
- data/lib/json/add/ostruct.rb +1 -1
- data/lib/json/add/rational.rb +2 -3
- data/lib/json/add/regexp.rb +2 -2
- data/lib/json/add/set.rb +29 -0
- data/lib/json/common.rb +341 -115
- data/lib/json/pure/generator.rb +31 -10
- data/lib/json/pure/parser.rb +35 -5
- data/lib/json/version.rb +1 -1
- data/tests/json_addition_test.rb +6 -0
- data/tests/json_common_interface_test.rb +47 -4
- data/tests/json_encoding_test.rb +2 -2
- data/tests/json_fixtures_test.rb +9 -1
- data/tests/json_generator_test.rb +55 -0
- data/tests/json_parser_test.rb +43 -12
- data/tests/test_helper.rb +3 -7
- metadata +17 -13
- data/data/example.json +0 -1
- data/data/index.html +0 -38
- data/data/prototype.js +0 -4184
data/VERSION
CHANGED
@@ -1 +1 @@
|
|
1
|
-
2.0
|
1
|
+
2.4.0
|
@@ -15,14 +15,14 @@ static VALUE mJSON, mExt, mGenerator, cState, mGeneratorMethods, mObject,
|
|
15
15
|
#endif
|
16
16
|
mFloat, mString, mString_Extend,
|
17
17
|
mTrueClass, mFalseClass, mNilClass, eGeneratorError,
|
18
|
-
eNestingError,
|
18
|
+
eNestingError,
|
19
19
|
i_SAFE_STATE_PROTOTYPE;
|
20
20
|
|
21
21
|
static ID i_to_s, i_to_json, i_new, i_indent, i_space, i_space_before,
|
22
22
|
i_object_nl, i_array_nl, i_max_nesting, i_allow_nan, i_ascii_only,
|
23
23
|
i_pack, i_unpack, i_create_id, i_extend, i_key_p,
|
24
24
|
i_aref, i_send, i_respond_to_p, i_match, i_keys, i_depth,
|
25
|
-
i_buffer_initial_length, i_dup;
|
25
|
+
i_buffer_initial_length, i_dup, i_escape_slash;
|
26
26
|
|
27
27
|
/*
|
28
28
|
* Copyright 2001-2004 Unicode, Inc.
|
@@ -130,7 +130,7 @@ static void unicode_escape_to_buffer(FBuffer *buffer, char buf[6], UTF16
|
|
130
130
|
|
131
131
|
/* Converts string to a JSON string in FBuffer buffer, where all but the ASCII
|
132
132
|
* and control characters are JSON escaped. */
|
133
|
-
static void convert_UTF8_to_JSON_ASCII(FBuffer *buffer, VALUE string)
|
133
|
+
static void convert_UTF8_to_JSON_ASCII(FBuffer *buffer, VALUE string, char escape_slash)
|
134
134
|
{
|
135
135
|
const UTF8 *source = (UTF8 *) RSTRING_PTR(string);
|
136
136
|
const UTF8 *sourceEnd = source + RSTRING_LEN(string);
|
@@ -180,6 +180,11 @@ static void convert_UTF8_to_JSON_ASCII(FBuffer *buffer, VALUE string)
|
|
180
180
|
case '"':
|
181
181
|
fbuffer_append(buffer, "\\\"", 2);
|
182
182
|
break;
|
183
|
+
case '/':
|
184
|
+
if(escape_slash) {
|
185
|
+
fbuffer_append(buffer, "\\/", 2);
|
186
|
+
break;
|
187
|
+
}
|
183
188
|
default:
|
184
189
|
fbuffer_append_char(buffer, (char)ch);
|
185
190
|
break;
|
@@ -229,7 +234,7 @@ static void convert_UTF8_to_JSON_ASCII(FBuffer *buffer, VALUE string)
|
|
229
234
|
* characters required by the JSON standard are JSON escaped. The remaining
|
230
235
|
* characters (should be UTF8) are just passed through and appended to the
|
231
236
|
* result. */
|
232
|
-
static void convert_UTF8_to_JSON(FBuffer *buffer, VALUE string)
|
237
|
+
static void convert_UTF8_to_JSON(FBuffer *buffer, VALUE string, char escape_slash)
|
233
238
|
{
|
234
239
|
const char *ptr = RSTRING_PTR(string), *p;
|
235
240
|
unsigned long len = RSTRING_LEN(string), start = 0, end = 0;
|
@@ -237,6 +242,7 @@ static void convert_UTF8_to_JSON(FBuffer *buffer, VALUE string)
|
|
237
242
|
int escape_len;
|
238
243
|
unsigned char c;
|
239
244
|
char buf[6] = { '\\', 'u' };
|
245
|
+
int ascii_only = rb_enc_str_asciionly_p(string);
|
240
246
|
|
241
247
|
for (start = 0, end = 0; end < len;) {
|
242
248
|
p = ptr + end;
|
@@ -279,16 +285,25 @@ static void convert_UTF8_to_JSON(FBuffer *buffer, VALUE string)
|
|
279
285
|
escape = "\\\"";
|
280
286
|
escape_len = 2;
|
281
287
|
break;
|
288
|
+
case '/':
|
289
|
+
if(escape_slash) {
|
290
|
+
escape = "\\/";
|
291
|
+
escape_len = 2;
|
292
|
+
break;
|
293
|
+
}
|
282
294
|
default:
|
283
295
|
{
|
284
|
-
unsigned short clen =
|
285
|
-
if (
|
286
|
-
|
287
|
-
|
288
|
-
|
289
|
-
|
290
|
-
|
291
|
-
|
296
|
+
unsigned short clen = 1;
|
297
|
+
if (!ascii_only) {
|
298
|
+
clen += trailingBytesForUTF8[c];
|
299
|
+
if (end + clen > len) {
|
300
|
+
rb_raise(rb_path2class("JSON::GeneratorError"),
|
301
|
+
"partial character in source, but hit end");
|
302
|
+
}
|
303
|
+
if (!isLegalUTF8((UTF8 *) p, clen)) {
|
304
|
+
rb_raise(rb_path2class("JSON::GeneratorError"),
|
305
|
+
"source sequence is illegal/malformed utf-8");
|
306
|
+
}
|
292
307
|
}
|
293
308
|
end += clen;
|
294
309
|
}
|
@@ -324,6 +339,76 @@ static char *fstrndup(const char *ptr, unsigned long len) {
|
|
324
339
|
*
|
325
340
|
*/
|
326
341
|
|
342
|
+
/* Explanation of the following: that's the only way to not pollute
|
343
|
+
* standard library's docs with GeneratorMethods::<ClassName> which
|
344
|
+
* are uninformative and take a large place in a list of classes
|
345
|
+
*/
|
346
|
+
|
347
|
+
/*
|
348
|
+
* Document-module: JSON::Ext::Generator::GeneratorMethods
|
349
|
+
* :nodoc:
|
350
|
+
*/
|
351
|
+
|
352
|
+
/*
|
353
|
+
* Document-module: JSON::Ext::Generator::GeneratorMethods::Array
|
354
|
+
* :nodoc:
|
355
|
+
*/
|
356
|
+
|
357
|
+
/*
|
358
|
+
* Document-module: JSON::Ext::Generator::GeneratorMethods::Bignum
|
359
|
+
* :nodoc:
|
360
|
+
*/
|
361
|
+
|
362
|
+
/*
|
363
|
+
* Document-module: JSON::Ext::Generator::GeneratorMethods::FalseClass
|
364
|
+
* :nodoc:
|
365
|
+
*/
|
366
|
+
|
367
|
+
/*
|
368
|
+
* Document-module: JSON::Ext::Generator::GeneratorMethods::Fixnum
|
369
|
+
* :nodoc:
|
370
|
+
*/
|
371
|
+
|
372
|
+
/*
|
373
|
+
* Document-module: JSON::Ext::Generator::GeneratorMethods::Float
|
374
|
+
* :nodoc:
|
375
|
+
*/
|
376
|
+
|
377
|
+
/*
|
378
|
+
* Document-module: JSON::Ext::Generator::GeneratorMethods::Hash
|
379
|
+
* :nodoc:
|
380
|
+
*/
|
381
|
+
|
382
|
+
/*
|
383
|
+
* Document-module: JSON::Ext::Generator::GeneratorMethods::Integer
|
384
|
+
* :nodoc:
|
385
|
+
*/
|
386
|
+
|
387
|
+
/*
|
388
|
+
* Document-module: JSON::Ext::Generator::GeneratorMethods::NilClass
|
389
|
+
* :nodoc:
|
390
|
+
*/
|
391
|
+
|
392
|
+
/*
|
393
|
+
* Document-module: JSON::Ext::Generator::GeneratorMethods::Object
|
394
|
+
* :nodoc:
|
395
|
+
*/
|
396
|
+
|
397
|
+
/*
|
398
|
+
* Document-module: JSON::Ext::Generator::GeneratorMethods::String
|
399
|
+
* :nodoc:
|
400
|
+
*/
|
401
|
+
|
402
|
+
/*
|
403
|
+
* Document-module: JSON::Ext::Generator::GeneratorMethods::String::Extend
|
404
|
+
* :nodoc:
|
405
|
+
*/
|
406
|
+
|
407
|
+
/*
|
408
|
+
* Document-module: JSON::Ext::Generator::GeneratorMethods::TrueClass
|
409
|
+
* :nodoc:
|
410
|
+
*/
|
411
|
+
|
327
412
|
/*
|
328
413
|
* call-seq: to_json(state = nil)
|
329
414
|
*
|
@@ -642,6 +727,8 @@ static VALUE cState_configure(VALUE self, VALUE opts)
|
|
642
727
|
state->allow_nan = RTEST(tmp);
|
643
728
|
tmp = rb_hash_aref(opts, ID2SYM(i_ascii_only));
|
644
729
|
state->ascii_only = RTEST(tmp);
|
730
|
+
tmp = rb_hash_aref(opts, ID2SYM(i_escape_slash));
|
731
|
+
state->escape_slash = RTEST(tmp);
|
645
732
|
return self;
|
646
733
|
}
|
647
734
|
|
@@ -676,6 +763,7 @@ static VALUE cState_to_h(VALUE self)
|
|
676
763
|
rb_hash_aset(result, ID2SYM(i_allow_nan), state->allow_nan ? Qtrue : Qfalse);
|
677
764
|
rb_hash_aset(result, ID2SYM(i_ascii_only), state->ascii_only ? Qtrue : Qfalse);
|
678
765
|
rb_hash_aset(result, ID2SYM(i_max_nesting), LONG2FIX(state->max_nesting));
|
766
|
+
rb_hash_aset(result, ID2SYM(i_escape_slash), state->escape_slash ? Qtrue : Qfalse);
|
679
767
|
rb_hash_aset(result, ID2SYM(i_depth), LONG2FIX(state->depth));
|
680
768
|
rb_hash_aset(result, ID2SYM(i_buffer_initial_length), LONG2FIX(state->buffer_initial_length));
|
681
769
|
return result;
|
@@ -692,7 +780,7 @@ static VALUE cState_aref(VALUE self, VALUE name)
|
|
692
780
|
if (RTEST(rb_funcall(self, i_respond_to_p, 1, name))) {
|
693
781
|
return rb_funcall(self, i_send, 1, name);
|
694
782
|
} else {
|
695
|
-
return
|
783
|
+
return rb_attr_get(self, rb_intern_str(rb_str_concat(rb_str_new2("@"), name)));
|
696
784
|
}
|
697
785
|
}
|
698
786
|
|
@@ -715,43 +803,83 @@ static VALUE cState_aset(VALUE self, VALUE name, VALUE value)
|
|
715
803
|
return Qnil;
|
716
804
|
}
|
717
805
|
|
718
|
-
|
806
|
+
struct hash_foreach_arg {
|
807
|
+
FBuffer *buffer;
|
808
|
+
JSON_Generator_State *state;
|
809
|
+
VALUE Vstate;
|
810
|
+
int iter;
|
811
|
+
};
|
812
|
+
|
813
|
+
static int
|
814
|
+
json_object_i(VALUE key, VALUE val, VALUE _arg)
|
719
815
|
{
|
816
|
+
struct hash_foreach_arg *arg = (struct hash_foreach_arg *)_arg;
|
817
|
+
FBuffer *buffer = arg->buffer;
|
818
|
+
JSON_Generator_State *state = arg->state;
|
819
|
+
VALUE Vstate = arg->Vstate;
|
820
|
+
|
720
821
|
char *object_nl = state->object_nl;
|
721
822
|
long object_nl_len = state->object_nl_len;
|
722
823
|
char *indent = state->indent;
|
723
824
|
long indent_len = state->indent_len;
|
724
|
-
long max_nesting = state->max_nesting;
|
725
825
|
char *delim = FBUFFER_PTR(state->object_delim);
|
726
826
|
long delim_len = FBUFFER_LEN(state->object_delim);
|
727
827
|
char *delim2 = FBUFFER_PTR(state->object_delim2);
|
728
828
|
long delim2_len = FBUFFER_LEN(state->object_delim2);
|
829
|
+
long depth = state->depth;
|
830
|
+
int j;
|
831
|
+
VALUE klass, key_to_s;
|
832
|
+
|
833
|
+
if (arg->iter > 0) fbuffer_append(buffer, delim, delim_len);
|
834
|
+
if (object_nl) {
|
835
|
+
fbuffer_append(buffer, object_nl, object_nl_len);
|
836
|
+
}
|
837
|
+
if (indent) {
|
838
|
+
for (j = 0; j < depth; j++) {
|
839
|
+
fbuffer_append(buffer, indent, indent_len);
|
840
|
+
}
|
841
|
+
}
|
842
|
+
|
843
|
+
klass = CLASS_OF(key);
|
844
|
+
if (klass == rb_cString) {
|
845
|
+
key_to_s = key;
|
846
|
+
} else if (klass == rb_cSymbol) {
|
847
|
+
key_to_s = rb_id2str(SYM2ID(key));
|
848
|
+
} else {
|
849
|
+
key_to_s = rb_funcall(key, i_to_s, 0);
|
850
|
+
}
|
851
|
+
Check_Type(key_to_s, T_STRING);
|
852
|
+
generate_json(buffer, Vstate, state, key_to_s);
|
853
|
+
fbuffer_append(buffer, delim2, delim2_len);
|
854
|
+
generate_json(buffer, Vstate, state, val);
|
855
|
+
|
856
|
+
arg->iter++;
|
857
|
+
return ST_CONTINUE;
|
858
|
+
}
|
859
|
+
|
860
|
+
static void generate_json_object(FBuffer *buffer, VALUE Vstate, JSON_Generator_State *state, VALUE obj)
|
861
|
+
{
|
862
|
+
char *object_nl = state->object_nl;
|
863
|
+
long object_nl_len = state->object_nl_len;
|
864
|
+
char *indent = state->indent;
|
865
|
+
long indent_len = state->indent_len;
|
866
|
+
long max_nesting = state->max_nesting;
|
729
867
|
long depth = ++state->depth;
|
730
|
-
int
|
731
|
-
|
868
|
+
int j;
|
869
|
+
struct hash_foreach_arg arg;
|
870
|
+
|
732
871
|
if (max_nesting != 0 && depth > max_nesting) {
|
733
872
|
fbuffer_free(buffer);
|
734
873
|
rb_raise(eNestingError, "nesting of %ld is too deep", --state->depth);
|
735
874
|
}
|
736
875
|
fbuffer_append_char(buffer, '{');
|
737
|
-
|
738
|
-
|
739
|
-
|
740
|
-
|
741
|
-
|
742
|
-
|
743
|
-
|
744
|
-
for (j = 0; j < depth; j++) {
|
745
|
-
fbuffer_append(buffer, indent, indent_len);
|
746
|
-
}
|
747
|
-
}
|
748
|
-
key = rb_ary_entry(keys, i);
|
749
|
-
key_to_s = rb_funcall(key, i_to_s, 0);
|
750
|
-
Check_Type(key_to_s, T_STRING);
|
751
|
-
generate_json(buffer, Vstate, state, key_to_s);
|
752
|
-
fbuffer_append(buffer, delim2, delim2_len);
|
753
|
-
generate_json(buffer, Vstate, state, rb_hash_aref(obj, key));
|
754
|
-
}
|
876
|
+
|
877
|
+
arg.buffer = buffer;
|
878
|
+
arg.state = state;
|
879
|
+
arg.Vstate = Vstate;
|
880
|
+
arg.iter = 0;
|
881
|
+
rb_hash_foreach(obj, json_object_i, (VALUE)&arg);
|
882
|
+
|
755
883
|
depth = --state->depth;
|
756
884
|
if (object_nl) {
|
757
885
|
fbuffer_append(buffer, object_nl, object_nl_len);
|
@@ -802,16 +930,27 @@ static void generate_json_array(FBuffer *buffer, VALUE Vstate, JSON_Generator_St
|
|
802
930
|
fbuffer_append_char(buffer, ']');
|
803
931
|
}
|
804
932
|
|
933
|
+
#ifdef HAVE_RUBY_ENCODING_H
|
934
|
+
static int enc_utf8_compatible_p(rb_encoding *enc)
|
935
|
+
{
|
936
|
+
if (enc == rb_usascii_encoding()) return 1;
|
937
|
+
if (enc == rb_utf8_encoding()) return 1;
|
938
|
+
return 0;
|
939
|
+
}
|
940
|
+
#endif
|
941
|
+
|
805
942
|
static void generate_json_string(FBuffer *buffer, VALUE Vstate, JSON_Generator_State *state, VALUE obj)
|
806
943
|
{
|
807
944
|
fbuffer_append_char(buffer, '"');
|
808
945
|
#ifdef HAVE_RUBY_ENCODING_H
|
809
|
-
|
946
|
+
if (!enc_utf8_compatible_p(rb_enc_get(obj))) {
|
947
|
+
obj = rb_str_encode(obj, CEncoding_UTF_8, 0, Qnil);
|
948
|
+
}
|
810
949
|
#endif
|
811
950
|
if (state->ascii_only) {
|
812
|
-
convert_UTF8_to_JSON_ASCII(buffer, obj);
|
951
|
+
convert_UTF8_to_JSON_ASCII(buffer, obj, state->escape_slash);
|
813
952
|
} else {
|
814
|
-
convert_UTF8_to_JSON(buffer, obj);
|
953
|
+
convert_UTF8_to_JSON(buffer, obj, state->escape_slash);
|
815
954
|
}
|
816
955
|
fbuffer_append_char(buffer, '"');
|
817
956
|
}
|
@@ -970,6 +1109,8 @@ static VALUE cState_generate(VALUE self, VALUE obj)
|
|
970
1109
|
* * *allow_nan*: true if NaN, Infinity, and -Infinity should be
|
971
1110
|
* generated, otherwise an exception is thrown, if these values are
|
972
1111
|
* encountered. This options defaults to false.
|
1112
|
+
* * *ascii_only*: true if only ASCII characters should be generated. This
|
1113
|
+
* option defaults to false.
|
973
1114
|
* * *buffer_initial_length*: sets the initial length of the generator's
|
974
1115
|
* internal buffer.
|
975
1116
|
*/
|
@@ -1025,10 +1166,8 @@ static VALUE cState_from_state_s(VALUE self, VALUE opts)
|
|
1025
1166
|
} else if (rb_obj_is_kind_of(opts, rb_cHash)) {
|
1026
1167
|
return rb_funcall(self, i_new, 1, opts);
|
1027
1168
|
} else {
|
1028
|
-
|
1029
|
-
|
1030
|
-
}
|
1031
|
-
return rb_funcall(CJSON_SAFE_STATE_PROTOTYPE, i_dup, 0);
|
1169
|
+
VALUE prototype = rb_const_get(mJSON, i_SAFE_STATE_PROTOTYPE);
|
1170
|
+
return rb_funcall(prototype, i_dup, 0);
|
1032
1171
|
}
|
1033
1172
|
}
|
1034
1173
|
|
@@ -1252,6 +1391,31 @@ static VALUE cState_max_nesting_set(VALUE self, VALUE depth)
|
|
1252
1391
|
return state->max_nesting = FIX2LONG(depth);
|
1253
1392
|
}
|
1254
1393
|
|
1394
|
+
/*
|
1395
|
+
* call-seq: escape_slash
|
1396
|
+
*
|
1397
|
+
* If this boolean is true, the forward slashes will be escaped in
|
1398
|
+
* the json output.
|
1399
|
+
*/
|
1400
|
+
static VALUE cState_escape_slash(VALUE self)
|
1401
|
+
{
|
1402
|
+
GET_STATE(self);
|
1403
|
+
return state->escape_slash ? Qtrue : Qfalse;
|
1404
|
+
}
|
1405
|
+
|
1406
|
+
/*
|
1407
|
+
* call-seq: escape_slash=(depth)
|
1408
|
+
*
|
1409
|
+
* This sets whether or not the forward slashes will be escaped in
|
1410
|
+
* the json output.
|
1411
|
+
*/
|
1412
|
+
static VALUE cState_escape_slash_set(VALUE self, VALUE enable)
|
1413
|
+
{
|
1414
|
+
GET_STATE(self);
|
1415
|
+
state->escape_slash = RTEST(enable);
|
1416
|
+
return Qnil;
|
1417
|
+
}
|
1418
|
+
|
1255
1419
|
/*
|
1256
1420
|
* call-seq: allow_nan?
|
1257
1421
|
*
|
@@ -1267,7 +1431,7 @@ static VALUE cState_allow_nan_p(VALUE self)
|
|
1267
1431
|
/*
|
1268
1432
|
* call-seq: ascii_only?
|
1269
1433
|
*
|
1270
|
-
* Returns true, if
|
1434
|
+
* Returns true, if only ASCII characters should be generated. Otherwise
|
1271
1435
|
* returns false.
|
1272
1436
|
*/
|
1273
1437
|
static VALUE cState_ascii_only_p(VALUE self)
|
@@ -1335,6 +1499,7 @@ static VALUE cState_buffer_initial_length_set(VALUE self, VALUE buffer_initial_l
|
|
1335
1499
|
*/
|
1336
1500
|
void Init_generator(void)
|
1337
1501
|
{
|
1502
|
+
#undef rb_intern
|
1338
1503
|
rb_require("json/common");
|
1339
1504
|
|
1340
1505
|
mJSON = rb_define_module("JSON");
|
@@ -1343,6 +1508,8 @@ void Init_generator(void)
|
|
1343
1508
|
|
1344
1509
|
eGeneratorError = rb_path2class("JSON::GeneratorError");
|
1345
1510
|
eNestingError = rb_path2class("JSON::NestingError");
|
1511
|
+
rb_gc_register_mark_object(eGeneratorError);
|
1512
|
+
rb_gc_register_mark_object(eNestingError);
|
1346
1513
|
|
1347
1514
|
cState = rb_define_class_under(mGenerator, "State", rb_cObject);
|
1348
1515
|
rb_define_alloc_func(cState, cState_s_allocate);
|
@@ -1361,6 +1528,9 @@ void Init_generator(void)
|
|
1361
1528
|
rb_define_method(cState, "array_nl=", cState_array_nl_set, 1);
|
1362
1529
|
rb_define_method(cState, "max_nesting", cState_max_nesting, 0);
|
1363
1530
|
rb_define_method(cState, "max_nesting=", cState_max_nesting_set, 1);
|
1531
|
+
rb_define_method(cState, "escape_slash", cState_escape_slash, 0);
|
1532
|
+
rb_define_method(cState, "escape_slash?", cState_escape_slash, 0);
|
1533
|
+
rb_define_method(cState, "escape_slash=", cState_escape_slash_set, 1);
|
1364
1534
|
rb_define_method(cState, "check_circular?", cState_check_circular_p, 0);
|
1365
1535
|
rb_define_method(cState, "allow_nan?", cState_allow_nan_p, 0);
|
1366
1536
|
rb_define_method(cState, "ascii_only?", cState_ascii_only_p, 0);
|
@@ -1408,7 +1578,6 @@ void Init_generator(void)
|
|
1408
1578
|
mNilClass = rb_define_module_under(mGeneratorMethods, "NilClass");
|
1409
1579
|
rb_define_method(mNilClass, "to_json", mNilClass_to_json, -1);
|
1410
1580
|
|
1411
|
-
CRegexp_MULTILINE = rb_const_get(rb_cRegexp, rb_intern("MULTILINE"));
|
1412
1581
|
i_to_s = rb_intern("to_s");
|
1413
1582
|
i_to_json = rb_intern("to_json");
|
1414
1583
|
i_new = rb_intern("new");
|
@@ -1418,6 +1587,7 @@ void Init_generator(void)
|
|
1418
1587
|
i_object_nl = rb_intern("object_nl");
|
1419
1588
|
i_array_nl = rb_intern("array_nl");
|
1420
1589
|
i_max_nesting = rb_intern("max_nesting");
|
1590
|
+
i_escape_slash = rb_intern("escape_slash");
|
1421
1591
|
i_allow_nan = rb_intern("allow_nan");
|
1422
1592
|
i_ascii_only = rb_intern("ascii_only");
|
1423
1593
|
i_depth = rb_intern("depth");
|
@@ -1439,5 +1609,4 @@ void Init_generator(void)
|
|
1439
1609
|
i_encode = rb_intern("encode");
|
1440
1610
|
#endif
|
1441
1611
|
i_SAFE_STATE_PROTOTYPE = rb_intern("SAFE_STATE_PROTOTYPE");
|
1442
|
-
CJSON_SAFE_STATE_PROTOTYPE = Qnil;
|
1443
1612
|
}
|
@@ -49,8 +49,8 @@ static const UTF32 halfMask = 0x3FFUL;
|
|
49
49
|
static unsigned char isLegalUTF8(const UTF8 *source, unsigned long length);
|
50
50
|
static void unicode_escape(char *buf, UTF16 character);
|
51
51
|
static void unicode_escape_to_buffer(FBuffer *buffer, char buf[6], UTF16 character);
|
52
|
-
static void convert_UTF8_to_JSON_ASCII(FBuffer *buffer, VALUE string);
|
53
|
-
static void convert_UTF8_to_JSON(FBuffer *buffer, VALUE string);
|
52
|
+
static void convert_UTF8_to_JSON_ASCII(FBuffer *buffer, VALUE string, char escape_slash);
|
53
|
+
static void convert_UTF8_to_JSON(FBuffer *buffer, VALUE string, char escape_slash);
|
54
54
|
static char *fstrndup(const char *ptr, unsigned long len);
|
55
55
|
|
56
56
|
/* ruby api and some helpers */
|
@@ -72,6 +72,7 @@ typedef struct JSON_Generator_StateStruct {
|
|
72
72
|
long max_nesting;
|
73
73
|
char allow_nan;
|
74
74
|
char ascii_only;
|
75
|
+
char escape_slash;
|
75
76
|
long depth;
|
76
77
|
long buffer_initial_length;
|
77
78
|
} JSON_Generator_State;
|
@@ -150,6 +151,8 @@ static VALUE cState_allow_nan_p(VALUE self);
|
|
150
151
|
static VALUE cState_ascii_only_p(VALUE self);
|
151
152
|
static VALUE cState_depth(VALUE self);
|
152
153
|
static VALUE cState_depth_set(VALUE self, VALUE depth);
|
154
|
+
static VALUE cState_escape_slash(VALUE self);
|
155
|
+
static VALUE cState_escape_slash_set(VALUE self, VALUE depth);
|
153
156
|
static FBuffer *cState_prepare_buffer(VALUE self);
|
154
157
|
#ifndef ZALLOC
|
155
158
|
#define ZALLOC(type) ((type *)ruby_zalloc(sizeof(type)))
|