oj 3.15.0 → 3.16.3
Sign up to get free protection for your applications and to get access to all the features.
- checksums.yaml +4 -4
- data/CHANGELOG.md +29 -0
- data/ext/oj/cache.c +4 -2
- data/ext/oj/cache.h +3 -2
- data/ext/oj/code.c +3 -10
- data/ext/oj/compat.c +5 -18
- data/ext/oj/custom.c +5 -13
- data/ext/oj/dump.c +30 -22
- data/ext/oj/dump.h +1 -4
- data/ext/oj/dump_compat.c +16 -16
- data/ext/oj/extconf.rb +4 -2
- data/ext/oj/fast.c +10 -12
- data/ext/oj/intern.c +23 -6
- data/ext/oj/mimic_json.c +3 -6
- data/ext/oj/object.c +13 -5
- data/ext/oj/oj.c +155 -132
- data/ext/oj/oj.h +26 -33
- data/ext/oj/parse.c +7 -5
- data/ext/oj/parse.h +16 -14
- data/ext/oj/parser.c +61 -50
- data/ext/oj/parser.h +2 -2
- data/ext/oj/rails.c +23 -7
- data/ext/oj/reader.c +1 -3
- data/ext/oj/saj.c +1 -1
- data/ext/oj/stream_writer.c +35 -15
- data/ext/oj/string_writer.c +50 -17
- data/ext/oj/usual.c +20 -0
- data/ext/oj/usual.h +1 -0
- data/ext/oj/val_stack.c +13 -2
- data/lib/oj/active_support_helper.rb +2 -3
- data/lib/oj/json.rb +159 -149
- data/lib/oj/mimic.rb +3 -1
- data/lib/oj/version.rb +1 -1
- data/test/foo.rb +3 -4
- data/test/json_gem/json_common_interface_test.rb +4 -2
- data/test/json_gem/json_generator_test.rb +7 -1
- data/test/perf_dump.rb +3 -3
- data/test/prec.rb +4 -4
- data/test/test_compat.rb +19 -1
- data/test/test_custom.rb +2 -1
- data/test/test_object.rb +14 -0
- data/test/test_parser_debug.rb +1 -1
- data/test/test_parser_usual.rb +10 -0
- data/test/test_strict.rb +10 -0
- data/test/test_various.rb +6 -0
- metadata +17 -3
data/ext/oj/oj.c
CHANGED
@@ -33,7 +33,6 @@ ID oj_array_append_id;
|
|
33
33
|
ID oj_array_end_id;
|
34
34
|
ID oj_array_start_id;
|
35
35
|
ID oj_as_json_id;
|
36
|
-
ID oj_at_id;
|
37
36
|
ID oj_begin_id;
|
38
37
|
ID oj_bigdecimal_id;
|
39
38
|
ID oj_end_id;
|
@@ -51,6 +50,7 @@ ID oj_json_create_id;
|
|
51
50
|
ID oj_length_id;
|
52
51
|
ID oj_new_id;
|
53
52
|
ID oj_parse_id;
|
53
|
+
ID oj_plus_id;
|
54
54
|
ID oj_pos_id;
|
55
55
|
ID oj_raw_json_id;
|
56
56
|
ID oj_read_id;
|
@@ -91,9 +91,7 @@ VALUE oj_array_class_sym;
|
|
91
91
|
VALUE oj_create_additions_sym;
|
92
92
|
VALUE oj_decimal_class_sym;
|
93
93
|
VALUE oj_hash_class_sym;
|
94
|
-
VALUE oj_in_sym;
|
95
94
|
VALUE oj_indent_sym;
|
96
|
-
VALUE oj_nanosecond_sym;
|
97
95
|
VALUE oj_object_class_sym;
|
98
96
|
VALUE oj_quirks_mode_sym;
|
99
97
|
VALUE oj_safe_sym;
|
@@ -123,6 +121,7 @@ static VALUE escape_mode_sym;
|
|
123
121
|
static VALUE integer_range_sym;
|
124
122
|
static VALUE fast_sym;
|
125
123
|
static VALUE float_prec_sym;
|
124
|
+
static VALUE float_format_sym;
|
126
125
|
static VALUE float_sym;
|
127
126
|
static VALUE huge_sym;
|
128
127
|
static VALUE ignore_sym;
|
@@ -232,77 +231,89 @@ struct _options oj_default_options = {
|
|
232
231
|
NULL, // tail
|
233
232
|
{'\0'}, // err
|
234
233
|
},
|
235
|
-
NULL,
|
234
|
+
NULL,
|
236
235
|
};
|
237
236
|
|
238
237
|
/* Document-method: default_options()
|
239
238
|
* call-seq: default_options()
|
240
239
|
*
|
241
240
|
* Returns the default load and dump options as a Hash. The options are
|
242
|
-
* - *:indent* [_Fixnum_|_String_|_nil_] number of spaces to indent each element
|
243
|
-
*document, zero or nil is no newline between JSON elements,
|
244
|
-
*top level JSON elements in a stream,
|
245
|
-
*
|
246
|
-
*references
|
241
|
+
* - *:indent* [_Fixnum_|_String_|_nil_] number of spaces to indent each element
|
242
|
+
* in an JSON document, zero or nil is no newline between JSON elements,
|
243
|
+
* negative indicates no newline between top level JSON elements in a stream,
|
244
|
+
* a String indicates the string should be used for indentation
|
245
|
+
* - *:circular* [_Boolean_|_nil_] support circular references while dumping as
|
246
|
+
* well as shared references
|
247
247
|
* - *:auto_define* [_Boolean_|_nil_] automatically define classes if they do not exist
|
248
248
|
* - *:symbol_keys* [_Boolean_|_nil_] use symbols instead of strings for hash keys
|
249
|
-
* - *:escape_mode* [_:newline_|_:json_|_:slash_|_:xss_safe_|_:ascii_|_:unicode_xss_|_nil_]
|
250
|
-
*characters to escape
|
251
|
-
* - *:class_cache* [_Boolean_|_nil_] cache classes for faster parsing (if dynamically
|
252
|
-
*classes or reloading classes then don't use this)
|
253
|
-
* - *:mode* [_:object_|_:strict_|_:compat_|_:null_|_:custom_|_:rails_|_:wab_] load and
|
254
|
-
*to use for JSON
|
249
|
+
* - *:escape_mode* [_:newline_|_:json_|_:slash_|_:xss_safe_|_:ascii_|_:unicode_xss_|_nil_]
|
250
|
+
* determines the characters to escape
|
251
|
+
* - *:class_cache* [_Boolean_|_nil_] cache classes for faster parsing (if dynamically
|
252
|
+
* modifying classes or reloading classes then don't use this)
|
253
|
+
* - *:mode* [_:object_|_:strict_|_:compat_|_:null_|_:custom_|_:rails_|_:wab_] load and
|
254
|
+
* dump modes to use for JSON
|
255
255
|
* - *:time_format* [_:unix_|_:unix_zone_|_:xmlschema_|_:ruby_] time format when dumping
|
256
|
-
* - *:bigdecimal_as_decimal* [_Boolean_|_nil_] dump BigDecimal as a decimal number or
|
257
|
-
*
|
258
|
-
*
|
259
|
-
*
|
260
|
-
*
|
261
|
-
*
|
262
|
-
* - *:
|
263
|
-
*
|
264
|
-
* - *:
|
265
|
-
*
|
266
|
-
* - *:
|
267
|
-
*
|
268
|
-
* - *:
|
269
|
-
*
|
256
|
+
* - *:bigdecimal_as_decimal* [_Boolean_|_nil_] dump BigDecimal as a decimal number or
|
257
|
+
* as a String
|
258
|
+
* - *:bigdecimal_load* [_:bigdecimal_|_:float_|_:auto_|_:fast_|_:ruby_] load decimals
|
259
|
+
* as BigDecimal instead of as a Float. :auto pick the most precise for the number
|
260
|
+
* of digits. :float should be the same as ruby. :fast may require rounding but is
|
261
|
+
* must faster.
|
262
|
+
* - *:compat_bigdecimal* [_true_|_false_] load decimals as BigDecimal instead of as
|
263
|
+
* a Float when in compat or rails mode.
|
264
|
+
* - *:create_id* [_String_|_nil_] create id for json compatible object encoding,
|
265
|
+
* default is 'json_class'
|
266
|
+
* - *:create_additions* [_Boolean_|_nil_] if true allow creation of instances using
|
267
|
+
* create_id on load.
|
268
|
+
* - *:second_precision* [_Fixnum_|_nil_] number of digits after the decimal when
|
269
|
+
* dumping the seconds portion of time
|
270
|
+
* - *:float_precision* [_Fixnum_|_nil_] number of digits of precision when dumping
|
271
|
+
* floats, 0 indicates use Ruby
|
272
|
+
* - *:float_format* [_String_] the C printf format string for printing floats.
|
273
|
+
* Default follows the float_precision and will be changed if float_precision is
|
274
|
+
* changed. The string can be no more than 6 bytes.
|
270
275
|
* - *:use_to_json* [_Boolean_|_nil_] call to_json() methods on dump, default is false
|
271
276
|
* - *:use_as_json* [_Boolean_|_nil_] call as_json() methods on dump, default is false
|
272
277
|
* - *:use_raw_json* [_Boolean_|_nil_] call raw_json() methods on dump, default is false
|
273
|
-
* - *:nilnil* [_Boolean_|_nil_] if true a nil input to load will return nil and
|
274
|
-
*Exception
|
278
|
+
* - *:nilnil* [_Boolean_|_nil_] if true a nil input to load will return nil and
|
279
|
+
* not raise an Exception
|
275
280
|
* - *:empty_string* [_Boolean_|_nil_] if true an empty input will not raise an Exception
|
276
281
|
* - *:allow_gc* [_Boolean_|_nil_] allow or prohibit GC during parsing, default is true (allow)
|
277
|
-
* - *:quirks_mode* [_true,_|_false_|_nil_] Allow single JSON values instead of
|
278
|
-
*is true (allow)
|
279
|
-
* - *:allow_invalid_unicode* [_true,_|_false_|_nil_] Allow invalid unicode,
|
280
|
-
*allow)
|
281
|
-
* - *:allow_nan* [_true,_|_false_|_nil_] Allow Nan, Infinity, and -Infinity to
|
282
|
-
*is true (allow)
|
283
|
-
* - *:indent_str* [_String_|_nil_] String to use for indentation, overriding the
|
284
|
-
*not nil
|
285
|
-
* - *:space* [_String_|_nil_] String to use for the space after the colon in JSON
|
286
|
-
*
|
282
|
+
* - *:quirks_mode* [_true,_|_false_|_nil_] Allow single JSON values instead of
|
283
|
+
* documents, default is true (allow)
|
284
|
+
* - *:allow_invalid_unicode* [_true,_|_false_|_nil_] Allow invalid unicode,
|
285
|
+
* default is false (don't allow)
|
286
|
+
* - *:allow_nan* [_true,_|_false_|_nil_] Allow Nan, Infinity, and -Infinity to
|
287
|
+
* be parsed, default is true (allow)
|
288
|
+
* - *:indent_str* [_String_|_nil_] String to use for indentation, overriding the
|
289
|
+
* indent option is not nil
|
290
|
+
* - *:space* [_String_|_nil_] String to use for the space after the colon in JSON
|
291
|
+
* object fields
|
292
|
+
* - *:space_before* [_String_|_nil_] String to use before the colon separator in
|
293
|
+
* JSON object fields
|
287
294
|
* - *:object_nl* [_String_|_nil_] String to use after a JSON object field value
|
288
295
|
* - *:array_nl* [_String_|_nil_] String to use after a JSON array value
|
289
|
-
* - *:nan* [_:null_|_:huge_|_:word_|_:raise_|_:auto_] how to dump Infinity and
|
290
|
-
*null, :huge places a huge number, :word places Infinity
|
291
|
-
*uses default for each mode.
|
292
|
-
* - *:hash_class* [_Class_|_nil_] Class to use instead of Hash on load,
|
293
|
-
*used
|
296
|
+
* - *:nan* [_:null_|_:huge_|_:word_|_:raise_|_:auto_] how to dump Infinity and
|
297
|
+
* NaN. :null places a null, :huge places a huge number, :word places Infinity
|
298
|
+
* or NaN, :raise raises and exception, :auto uses default for each mode.
|
299
|
+
* - *:hash_class* [_Class_|_nil_] Class to use instead of Hash on load,
|
300
|
+
* :object_class can also be used
|
294
301
|
* - *:array_class* [_Class_|_nil_] Class to use instead of Array on load
|
295
|
-
* - *:omit_nil* [_true_|_false_] if true Hash and Object attributes with nil
|
296
|
-
*
|
302
|
+
* - *:omit_nil* [_true_|_false_] if true Hash and Object attributes with nil
|
303
|
+
* values are omitted
|
304
|
+
* - *:omit_null_byte* [_true_|_false_] if true null bytes in strings will be
|
305
|
+
* omitted when dumping
|
297
306
|
* - *:ignore* [_nil_|_Array_] either nil or an Array of classes to ignore when dumping
|
298
|
-
* - *:ignore_under* [_Boolean_] if true then attributes that start with _ are
|
299
|
-
*object or custom mode.
|
307
|
+
* - *:ignore_under* [_Boolean_] if true then attributes that start with _ are
|
308
|
+
* ignored when dumping in object or custom mode.
|
300
309
|
* - *:cache_keys* [_Boolean_] if true then hash keys are cached if less than 35 bytes.
|
301
|
-
* - *:cache_str* [_Fixnum_] maximum string value length to cache (strings less
|
310
|
+
* - *:cache_str* [_Fixnum_] maximum string value length to cache (strings less
|
311
|
+
* than this are cached)
|
302
312
|
* - *:integer_range* [_Range_] Dump integers outside range as strings.
|
303
|
-
* - *:trace* [_true,_|_false_] Trace all load and dump calls, default is false
|
304
|
-
*
|
305
|
-
*
|
313
|
+
* - *:trace* [_true,_|_false_] Trace all load and dump calls, default is false
|
314
|
+
* (trace is off)
|
315
|
+
* - *:safe* [_true,_|_false_] Safe mimic breaks JSON mimic to be safer, default
|
316
|
+
* is false (safe is off)
|
306
317
|
*
|
307
318
|
* Return [_Hash_] all current option settings.
|
308
319
|
*/
|
@@ -378,6 +389,7 @@ static VALUE get_def_opts(VALUE self) {
|
|
378
389
|
oj_safe_sym,
|
379
390
|
(Yes == oj_default_options.safe) ? Qtrue : ((No == oj_default_options.safe) ? Qfalse : Qnil));
|
380
391
|
rb_hash_aset(opts, float_prec_sym, INT2FIX(oj_default_options.float_prec));
|
392
|
+
rb_hash_aset(opts, float_format_sym, rb_str_new_cstr(oj_default_options.float_fmt));
|
381
393
|
rb_hash_aset(opts, cache_str_sym, INT2FIX(oj_default_options.cache_str));
|
382
394
|
rb_hash_aset(
|
383
395
|
opts,
|
@@ -486,68 +498,67 @@ static VALUE get_def_opts(VALUE self) {
|
|
486
498
|
*
|
487
499
|
* Sets the default options for load and dump.
|
488
500
|
* - *opts* [_Hash_] options to change
|
489
|
-
* - *:indent* [_Fixnum_|_String_|_nil_] number of spaces to indent each element
|
490
|
-
*document or the String to use for indentation.
|
501
|
+
* - *:indent* [_Fixnum_|_String_|_nil_] number of spaces to indent each element
|
502
|
+
* in a JSON document or the String to use for indentation.
|
491
503
|
* - :circular [_Boolean_|_nil_] support circular references while dumping.
|
492
504
|
* - *:auto_define* [_Boolean_|_nil_] automatically define classes if they do not exist.
|
493
505
|
* - *:symbol_keys* [_Boolean_|_nil_] convert hash keys to symbols.
|
494
506
|
* - *:class_cache* [_Boolean_|_nil_] cache classes for faster parsing.
|
495
|
-
* - *:escape* [_:newline_|_:json_|_:xss_safe_|_:ascii_|_unicode_xss_|_nil_]
|
496
|
-
*high-bit characters as escaped sequences if :ascii, :json
|
497
|
-
|
498
|
-
*
|
499
|
-
*
|
500
|
-
*
|
501
|
-
*
|
502
|
-
*
|
503
|
-
*
|
504
|
-
*
|
505
|
-
*
|
506
|
-
*
|
507
|
-
*
|
508
|
-
*
|
509
|
-
*Object
|
510
|
-
*
|
511
|
-
*
|
512
|
-
*
|
513
|
-
*
|
514
|
-
*
|
515
|
-
*
|
516
|
-
*
|
507
|
+
* - *:escape* [_:newline_|_:json_|_:xss_safe_|_:ascii_|_unicode_xss_|_nil_]
|
508
|
+
* mode encodes all high-bit characters as escaped sequences if :ascii, :json
|
509
|
+
* is standand UTF-8 JSON encoding, :newline is the same as :json but newlines
|
510
|
+
* are not escaped, :unicode_xss allows unicode but escapes &, <, and >, and
|
511
|
+
* any \u20xx characters along with some others, and :xss_safe escapes &, <,
|
512
|
+
* and >, and some others.
|
513
|
+
* - *:bigdecimal_as_decimal* [_Boolean_|_nil_] dump BigDecimal as a decimal
|
514
|
+
* number or as a String.
|
515
|
+
* - *:bigdecimal_load* [_:bigdecimal_|_:float_|_:auto_|_nil_] load decimals as
|
516
|
+
* BigDecimal instead of as a Float. :auto pick the most precise for the number of digits.
|
517
|
+
* - *:compat_bigdecimal* [_true_|_false_] load decimals as BigDecimal instead
|
518
|
+
* of as a Float in compat mode.
|
519
|
+
* - *:mode* [_:object_|_:strict_|_:compat_|_:null_|_:custom_|_:rails_|_:wab_] load
|
520
|
+
* and dump mode to use for JSON :strict raises an exception when a non-supported
|
521
|
+
* Object is encountered. :compat attempts to extract variable values from an
|
522
|
+
* Object using to_json() or to_hash() then it walks the Object's variables if
|
523
|
+
* neither is found. The :object mode ignores to_hash() and to_json() methods
|
524
|
+
* and encodes variables using code internal to the Oj gem. The :null mode
|
525
|
+
* ignores non-supported Objects and replaces them with a null. The :custom
|
526
|
+
* mode honors all dump options. The :rails more mimics rails and Active behavior.
|
527
|
+
* - *:time_format* [_:unix_|_:xmlschema_|_:ruby_] time format when dumping in :compat
|
528
|
+
* mode :unix decimal number denoting the number of seconds since 1/1/1970,
|
529
|
+
* :unix_zone decimal number denoting the number of seconds since 1/1/1970
|
530
|
+
* plus the utc_offset in the exponent, :xmlschema date-time format taken
|
531
|
+
* from XML Schema as a String, :ruby Time.to_s formatted String.
|
517
532
|
* - *:create_id* [_String_|_nil_] create id for json compatible object encoding
|
518
|
-
* - *:create_additions* [_Boolean_|_nil_] if true allow creation of instances using create_id on
|
519
|
-
*
|
520
|
-
*
|
521
|
-
*
|
522
|
-
*
|
523
|
-
*
|
533
|
+
* - *:create_additions* [_Boolean_|_nil_] if true allow creation of instances using create_id on load.
|
534
|
+
* - *:second_precision* [_Fixnum_|_nil_] number of digits after the decimal
|
535
|
+
* when dumping the seconds portion of time.
|
536
|
+
* - *:float_format* [_String_] the C printf format string for printing floats.
|
537
|
+
* Default follows the float_precision and will be changed if float_precision
|
538
|
+
* is changed. The string can be no more than 6 bytes.
|
539
|
+
* - *:float_precision* [_Fixnum_|_nil_] number of digits of precision when dumping floats, 0 indicates use Ruby.
|
524
540
|
* - *:use_to_json* [_Boolean_|_nil_] call to_json() methods on dump, default is false.
|
525
541
|
* - *:use_as_json* [_Boolean_|_nil_] call as_json() methods on dump, default is false.
|
526
542
|
* - *:use_to_hash* [_Boolean_|_nil_] call to_hash() methods on dump, default is false.
|
527
543
|
* - *:use_raw_json* [_Boolean_|_nil_] call raw_json() methods on dump, default is false.
|
528
|
-
* - *:nilnil* [_Boolean_|_nil_] if true a nil input to load will return nil and not raise an
|
529
|
-
*Exception.
|
544
|
+
* - *:nilnil* [_Boolean_|_nil_] if true a nil input to load will return nil and not raise an Exception.
|
530
545
|
* - *:allow_gc* [_Boolean_|_nil_] allow or prohibit GC during parsing, default is true (allow).
|
531
|
-
* - *:quirks_mode* [_Boolean_|_nil_] allow single JSON values instead of documents, default is
|
532
|
-
*
|
533
|
-
* - *:allow_invalid_unicode* [_Boolean_|_nil_] allow invalid unicode, default is false (don't
|
534
|
-
*allow).
|
546
|
+
* - *:quirks_mode* [_Boolean_|_nil_] allow single JSON values instead of documents, default is true (allow).
|
547
|
+
* - *:allow_invalid_unicode* [_Boolean_|_nil_] allow invalid unicode, default is false (don't allow).
|
535
548
|
* - *:allow_nan* [_Boolean_|_nil_] allow Nan, Infinity, and -Infinity, default is true (allow).
|
536
549
|
* - *:space* [_String_|_nil_] String to use for the space after the colon in JSON object fields.
|
537
|
-
* - *:space_before* [_String_|_nil_] String to use before the colon separator in JSON object
|
538
|
-
*fields.
|
550
|
+
* - *:space_before* [_String_|_nil_] String to use before the colon separator in JSON object fields.
|
539
551
|
* - *:object_nl* [_String_|_nil_] String to use after a JSON object field value.
|
540
552
|
* - *:array_nl* [_String_|_nil_] String to use after a JSON array value
|
541
|
-
* - *:nan* [_:null_|_:huge_|_:word_|_:raise_] how to dump Infinity and NaN in null,
|
542
|
-
*compat mode. :null places a null, :huge places a huge number, :word
|
543
|
-
*raises and exception, :auto uses default for each mode.
|
544
|
-
* - *:hash_class* [_Class_|_nil_] Class to use instead of Hash on load, :object_class can also be
|
545
|
-
*used.
|
553
|
+
* - *:nan* [_:null_|_:huge_|_:word_|_:raise_] how to dump Infinity and NaN in null,
|
554
|
+
* strict, and compat mode. :null places a null, :huge places a huge number, :word
|
555
|
+
* places Infinity or NaN, :raise raises and exception, :auto uses default for each mode.
|
556
|
+
* - *:hash_class* [_Class_|_nil_] Class to use instead of Hash on load, :object_class can also be used.
|
546
557
|
* - *:array_class* [_Class_|_nil_] Class to use instead of Array on load.
|
547
558
|
* - *:omit_nil* [_true_|_false_] if true Hash and Object attributes with nil values are omitted.
|
548
559
|
* - *:ignore* [_nil_|Array] either nil or an Array of classes to ignore when dumping
|
549
|
-
* - *:ignore_under* [_Boolean_] if true then attributes that start with _ are
|
550
|
-
*dumping in object or custom mode.
|
560
|
+
* - *:ignore_under* [_Boolean_] if true then attributes that start with _ are
|
561
|
+
* ignored when dumping in object or custom mode.
|
551
562
|
* - *:cache_keys* [_Boolean_] if true then hash keys are cached
|
552
563
|
* - *:cache_str* [_Fixnum_] maximum string value length to cache (strings less than this are cached)
|
553
564
|
* - *:integer_range* [_Range_] Dump integers outside range as strings.
|
@@ -617,7 +628,6 @@ static int parse_options_cb(VALUE k, VALUE v, VALUE opts) {
|
|
617
628
|
if (set_yesno_options(k, v, copts)) {
|
618
629
|
return ST_CONTINUE;
|
619
630
|
}
|
620
|
-
|
621
631
|
if (oj_indent_sym == k) {
|
622
632
|
switch (rb_type(v)) {
|
623
633
|
case T_NIL:
|
@@ -757,7 +767,6 @@ static int parse_options_cb(VALUE k, VALUE v, VALUE opts) {
|
|
757
767
|
if (Qnil == v) {
|
758
768
|
return ST_CONTINUE;
|
759
769
|
}
|
760
|
-
|
761
770
|
copts->compat_bigdec = (Qtrue == v);
|
762
771
|
} else if (oj_decimal_class_sym == k) {
|
763
772
|
if (rb_cFloat == v) {
|
@@ -949,6 +958,25 @@ static int parse_options_cb(VALUE k, VALUE v, VALUE opts) {
|
|
949
958
|
return ST_CONTINUE;
|
950
959
|
}
|
951
960
|
copts->sym_key = (Qtrue == v) ? Yes : No;
|
961
|
+
|
962
|
+
} else if (oj_max_nesting_sym == k) {
|
963
|
+
if (Qtrue == v) {
|
964
|
+
copts->dump_opts.max_depth = 100;
|
965
|
+
} else if (Qfalse == v || Qnil == v) {
|
966
|
+
copts->dump_opts.max_depth = MAX_DEPTH;
|
967
|
+
} else if (T_FIXNUM == rb_type(v)) {
|
968
|
+
copts->dump_opts.max_depth = NUM2INT(v);
|
969
|
+
if (0 >= copts->dump_opts.max_depth) {
|
970
|
+
copts->dump_opts.max_depth = MAX_DEPTH;
|
971
|
+
}
|
972
|
+
}
|
973
|
+
} else if (float_format_sym == k) {
|
974
|
+
rb_check_type(v, T_STRING);
|
975
|
+
if (6 < (int)RSTRING_LEN(v)) {
|
976
|
+
rb_raise(rb_eArgError, ":float_format must be 6 bytes or less.");
|
977
|
+
}
|
978
|
+
strncpy(copts->float_fmt, RSTRING_PTR(v), (size_t)RSTRING_LEN(v));
|
979
|
+
copts->float_fmt[RSTRING_LEN(v)] = '\0';
|
952
980
|
}
|
953
981
|
return ST_CONTINUE;
|
954
982
|
}
|
@@ -957,7 +985,6 @@ void oj_parse_options(VALUE ropts, Options copts) {
|
|
957
985
|
if (T_HASH != rb_type(ropts)) {
|
958
986
|
return;
|
959
987
|
}
|
960
|
-
|
961
988
|
rb_hash_foreach(ropts, parse_options_cb, (VALUE)copts);
|
962
989
|
oj_parse_opt_match_string(&copts->str_rx, ropts);
|
963
990
|
|
@@ -1294,9 +1321,8 @@ static VALUE dump(int argc, VALUE *argv, VALUE self) {
|
|
1294
1321
|
|
1295
1322
|
oj_out_init(arg.out);
|
1296
1323
|
|
1297
|
-
arg.out->omit_nil
|
1324
|
+
arg.out->omit_nil = copts.dump_opts.omit_nil;
|
1298
1325
|
arg.out->omit_null_byte = copts.dump_opts.omit_null_byte;
|
1299
|
-
arg.out->caller = CALLER_DUMP;
|
1300
1326
|
|
1301
1327
|
return rb_ensure(dump_body, (VALUE)&arg, dump_ensure, (VALUE)&arg);
|
1302
1328
|
}
|
@@ -1308,17 +1334,16 @@ static VALUE dump(int argc, VALUE *argv, VALUE self) {
|
|
1308
1334
|
* will be called. The mode is set to :compat.
|
1309
1335
|
* - *obj* [_Object_] Object to serialize as an JSON document String
|
1310
1336
|
* - *options* [_Hash_]
|
1311
|
-
* - *:max_nesting* [_boolean_] It true nesting is limited to 100.
|
1312
|
-
*
|
1313
|
-
*
|
1314
|
-
*
|
1315
|
-
* - *:
|
1316
|
-
*
|
1317
|
-
* - *:
|
1318
|
-
* nil.
|
1337
|
+
* - *:max_nesting* [_Fixnum_|_boolean_] It true nesting is limited to 100.
|
1338
|
+
* If a Fixnum nesting is set to the provided value. The option to detect
|
1339
|
+
* circular references is available but is not compatible with the json gem.,
|
1340
|
+
* default is false or unlimited.
|
1341
|
+
* - *:allow_nan* [_boolean_] If true non JSON compliant words such as Nan and
|
1342
|
+
* Infinity will be used as appropriate, default is true.
|
1343
|
+
* - *:quirks_mode* [_boolean_] Allow single JSON values instead of documents, default is true (allow).
|
1344
|
+
* - *:indent* [_String_|_nil_] String to use for indentation, overriding the indent option if not nil.
|
1319
1345
|
* - *:space* [_String_|_nil_] String to use for the space after the colon in JSON object fields.
|
1320
|
-
* - *:space_before* [_String_|_nil_] String to use before the colon separator in JSON object
|
1321
|
-
* fields.
|
1346
|
+
* - *:space_before* [_String_|_nil_] String to use before the colon separator in JSON object fields.
|
1322
1347
|
* - *:object_nl* [_String_|_nil_] String to use after a JSON object field value.
|
1323
1348
|
* - *:array_nl* [_String_|_nil_] String to use after a JSON array value.
|
1324
1349
|
* - *:trace* [_Boolean_] If true trace is turned on.
|
@@ -1343,7 +1368,7 @@ static VALUE to_json(int argc, VALUE *argv, VALUE self) {
|
|
1343
1368
|
|
1344
1369
|
oj_out_init(&out);
|
1345
1370
|
|
1346
|
-
out.omit_nil
|
1371
|
+
out.omit_nil = copts.dump_opts.omit_nil;
|
1347
1372
|
out.omit_null_byte = copts.dump_opts.omit_null_byte;
|
1348
1373
|
// For obj.to_json or generate nan is not allowed but if called from dump
|
1349
1374
|
// it is.
|
@@ -1413,10 +1438,10 @@ static VALUE to_stream(int argc, VALUE *argv, VALUE self) {
|
|
1413
1438
|
*
|
1414
1439
|
* - *clas* [_Class__|_Module_] Class or Module to be made special
|
1415
1440
|
* - *create_object* [_Object_] object to call the create method on
|
1416
|
-
* - *create_method* [_Symbol_] method on the clas that will create a new instance
|
1417
|
-
* given all the member values in the order specified.
|
1418
|
-
* - *members* [_Symbol__|_String_] methods used to get the member values from
|
1419
|
-
* clas.
|
1441
|
+
* - *create_method* [_Symbol_] method on the clas that will create a new instance
|
1442
|
+
* of the clas when given all the member values in the order specified.
|
1443
|
+
* - *members* [_Symbol__|_String_] methods used to get the member values from
|
1444
|
+
* instances of the clas.
|
1420
1445
|
*/
|
1421
1446
|
static VALUE register_odd(int argc, VALUE *argv, VALUE self) {
|
1422
1447
|
if (3 > argc) {
|
@@ -1449,10 +1474,10 @@ static VALUE register_odd(int argc, VALUE *argv, VALUE self) {
|
|
1449
1474
|
*
|
1450
1475
|
* - *clas* [_Class_|_Module_] Class or Module to be made special
|
1451
1476
|
* - *create_object* [_Object_] object to call the create method on
|
1452
|
-
* - *create_method* [_Symbol_] method on the clas that will create a new instance
|
1453
|
-
*given all the member values in the order specified.
|
1454
|
-
* - *dump_method* [_Symbol_|_String_] method to call on the object being
|
1455
|
-
*raw JSON.
|
1477
|
+
* - *create_method* [_Symbol_] method on the clas that will create a new instance
|
1478
|
+
* of the clas when given all the member values in the order specified.
|
1479
|
+
* - *dump_method* [_Symbol_|_String_] method to call on the object being
|
1480
|
+
* serialized to generate the raw JSON.
|
1456
1481
|
*/
|
1457
1482
|
static VALUE register_odd_raw(int argc, VALUE *argv, VALUE self) {
|
1458
1483
|
if (3 > argc) {
|
@@ -1678,8 +1703,8 @@ extern VALUE oj_define_mimic_json(int argc, VALUE *argv, VALUE self);
|
|
1678
1703
|
* - *:space_before* [_String_] String placed before a : delimiter
|
1679
1704
|
* - *:object_nl* [_String_] String placed after a JSON object
|
1680
1705
|
* - *:array_nl* [_String_] String placed after a JSON array
|
1681
|
-
* - *:ascii_only* [_Boolean_] if not nil or false then use only ascii characters
|
1682
|
-
* Note JSON.generate does support this even if it is not documented.
|
1706
|
+
* - *:ascii_only* [_Boolean_] if not nil or false then use only ascii characters
|
1707
|
+
* in the output. Note JSON.generate does support this even if it is not documented.
|
1683
1708
|
*
|
1684
1709
|
* Returns [_String_]generated JSON.
|
1685
1710
|
*/
|
@@ -1736,8 +1761,8 @@ static VALUE mem_report(VALUE self) {
|
|
1736
1761
|
* global and options to methods allow additional behavior modifications. The
|
1737
1762
|
* modes are:
|
1738
1763
|
*
|
1739
|
-
* - *:strict* mode will only allow the 7 basic JSON types to be serialized.
|
1740
|
-
* will raise an Exception.
|
1764
|
+
* - *:strict* mode will only allow the 7 basic JSON types to be serialized.
|
1765
|
+
* Any other Object will raise an Exception.
|
1741
1766
|
*
|
1742
1767
|
* - *:null* mode is similar to the :strict mode except any Object that is not
|
1743
1768
|
* one of the JSON base types is replaced by a JSON null.
|
@@ -1821,7 +1846,6 @@ void Init_oj(void) {
|
|
1821
1846
|
oj_array_end_id = rb_intern("array_end");
|
1822
1847
|
oj_array_start_id = rb_intern("array_start");
|
1823
1848
|
oj_as_json_id = rb_intern("as_json");
|
1824
|
-
oj_at_id = rb_intern("at");
|
1825
1849
|
oj_begin_id = rb_intern("begin");
|
1826
1850
|
oj_bigdecimal_id = rb_intern("BigDecimal");
|
1827
1851
|
oj_end_id = rb_intern("end");
|
@@ -1839,6 +1863,7 @@ void Init_oj(void) {
|
|
1839
1863
|
oj_length_id = rb_intern("length");
|
1840
1864
|
oj_new_id = rb_intern("new");
|
1841
1865
|
oj_parse_id = rb_intern("parse");
|
1866
|
+
oj_plus_id = rb_intern("+");
|
1842
1867
|
oj_pos_id = rb_intern("pos");
|
1843
1868
|
oj_raw_json_id = rb_intern("raw_json");
|
1844
1869
|
oj_read_id = rb_intern("read");
|
@@ -1929,6 +1954,8 @@ void Init_oj(void) {
|
|
1929
1954
|
rb_gc_register_address(&integer_range_sym);
|
1930
1955
|
fast_sym = ID2SYM(rb_intern("fast"));
|
1931
1956
|
rb_gc_register_address(&fast_sym);
|
1957
|
+
float_format_sym = ID2SYM(rb_intern("float_format"));
|
1958
|
+
rb_gc_register_address(&float_format_sym);
|
1932
1959
|
float_prec_sym = ID2SYM(rb_intern("float_precision"));
|
1933
1960
|
rb_gc_register_address(&float_prec_sym);
|
1934
1961
|
float_sym = ID2SYM(rb_intern("float"));
|
@@ -1969,14 +1996,10 @@ void Init_oj(void) {
|
|
1969
1996
|
rb_gc_register_address(&oj_decimal_class_sym);
|
1970
1997
|
oj_hash_class_sym = ID2SYM(rb_intern("hash_class"));
|
1971
1998
|
rb_gc_register_address(&oj_hash_class_sym);
|
1972
|
-
oj_in_sym = ID2SYM(rb_intern("in"));
|
1973
|
-
rb_gc_register_address(&oj_in_sym);
|
1974
1999
|
oj_indent_sym = ID2SYM(rb_intern("indent"));
|
1975
2000
|
rb_gc_register_address(&oj_indent_sym);
|
1976
2001
|
oj_max_nesting_sym = ID2SYM(rb_intern("max_nesting"));
|
1977
2002
|
rb_gc_register_address(&oj_max_nesting_sym);
|
1978
|
-
oj_nanosecond_sym = ID2SYM(rb_intern("nanosecond"));
|
1979
|
-
rb_gc_register_address(&oj_nanosecond_sym);
|
1980
2003
|
oj_object_class_sym = ID2SYM(rb_intern("object_class"));
|
1981
2004
|
rb_gc_register_address(&oj_object_class_sym);
|
1982
2005
|
oj_object_nl_sym = ID2SYM(rb_intern("object_nl"));
|
data/ext/oj/oj.h
CHANGED
@@ -103,13 +103,6 @@ typedef enum {
|
|
103
103
|
FILE_IO = 'f',
|
104
104
|
} StreamWriterType;
|
105
105
|
|
106
|
-
typedef enum {
|
107
|
-
CALLER_DUMP = 'd',
|
108
|
-
CALLER_TO_JSON = 't',
|
109
|
-
CALLER_GENERATE = 'g',
|
110
|
-
// Add the fast versions if necessary. Maybe unparse as well if needed.
|
111
|
-
} DumpCaller;
|
112
|
-
|
113
106
|
typedef struct _dumpOpts {
|
114
107
|
bool use;
|
115
108
|
char indent_str[16];
|
@@ -188,23 +181,22 @@ typedef struct _rOptTable {
|
|
188
181
|
} *ROptTable;
|
189
182
|
|
190
183
|
typedef struct _out {
|
191
|
-
char
|
192
|
-
char
|
193
|
-
char
|
194
|
-
char
|
195
|
-
Cache8
|
196
|
-
slot_t
|
197
|
-
int
|
198
|
-
int
|
199
|
-
Options
|
200
|
-
uint32_t
|
201
|
-
bool
|
202
|
-
bool
|
203
|
-
bool
|
204
|
-
int
|
205
|
-
VALUE
|
206
|
-
|
207
|
-
ROptTable ropts;
|
184
|
+
char stack_buffer[4096];
|
185
|
+
char *buf;
|
186
|
+
char *end;
|
187
|
+
char *cur;
|
188
|
+
Cache8 circ_cache;
|
189
|
+
slot_t circ_cnt;
|
190
|
+
int indent;
|
191
|
+
int depth; // used by dump_hash
|
192
|
+
Options opts;
|
193
|
+
uint32_t hash_cnt;
|
194
|
+
bool allocated;
|
195
|
+
bool omit_nil;
|
196
|
+
bool omit_null_byte;
|
197
|
+
int argc;
|
198
|
+
VALUE *argv;
|
199
|
+
ROptTable ropts;
|
208
200
|
} *Out;
|
209
201
|
|
210
202
|
typedef struct _strWriter {
|
@@ -262,12 +254,15 @@ extern VALUE oj_custom_parse_cstr(int argc, VALUE *argv, char *json, size_t len)
|
|
262
254
|
extern bool oj_hash_has_key(VALUE hash, VALUE key);
|
263
255
|
extern void oj_parse_options(VALUE ropts, Options copts);
|
264
256
|
|
265
|
-
extern void
|
266
|
-
extern void
|
267
|
-
extern void
|
268
|
-
extern void
|
269
|
-
extern void
|
270
|
-
extern void
|
257
|
+
extern void oj_dump_obj_to_json(VALUE obj, Options copts, Out out);
|
258
|
+
extern void oj_dump_obj_to_json_using_params(VALUE obj, Options copts, Out out, int argc, VALUE *argv);
|
259
|
+
extern void oj_write_obj_to_file(VALUE obj, const char *path, Options copts);
|
260
|
+
extern void oj_write_obj_to_stream(VALUE obj, VALUE stream, Options copts);
|
261
|
+
extern void oj_dump_leaf_to_json(Leaf leaf, Options copts, Out out);
|
262
|
+
extern void oj_write_leaf_to_file(Leaf leaf, const char *path, Options copts);
|
263
|
+
extern char *oj_longlong_to_string(long long num, bool negative, char *buf);
|
264
|
+
|
265
|
+
extern StrWriter oj_str_writer_unwrap(VALUE writer);
|
271
266
|
|
272
267
|
extern void oj_str_writer_push_key(StrWriter sw, const char *key);
|
273
268
|
extern void oj_str_writer_push_object(StrWriter sw, const char *key);
|
@@ -318,9 +313,7 @@ extern VALUE oj_ascii_only_sym;
|
|
318
313
|
extern VALUE oj_create_additions_sym;
|
319
314
|
extern VALUE oj_decimal_class_sym;
|
320
315
|
extern VALUE oj_hash_class_sym;
|
321
|
-
extern VALUE oj_in_sym;
|
322
316
|
extern VALUE oj_indent_sym;
|
323
|
-
extern VALUE oj_nanosecond_sym;
|
324
317
|
extern VALUE oj_max_nesting_sym;
|
325
318
|
extern VALUE oj_object_class_sym;
|
326
319
|
extern VALUE oj_object_nl_sym;
|
@@ -338,7 +331,6 @@ extern ID oj_array_append_id;
|
|
338
331
|
extern ID oj_array_end_id;
|
339
332
|
extern ID oj_array_start_id;
|
340
333
|
extern ID oj_as_json_id;
|
341
|
-
extern ID oj_at_id;
|
342
334
|
extern ID oj_begin_id;
|
343
335
|
extern ID oj_bigdecimal_id;
|
344
336
|
extern ID oj_end_id;
|
@@ -356,6 +348,7 @@ extern ID oj_json_create_id;
|
|
356
348
|
extern ID oj_length_id;
|
357
349
|
extern ID oj_new_id;
|
358
350
|
extern ID oj_parse_id;
|
351
|
+
extern ID oj_plus_id;
|
359
352
|
extern ID oj_pos_id;
|
360
353
|
extern ID oj_read_id;
|
361
354
|
extern ID oj_readpartial_id;
|
data/ext/oj/parse.c
CHANGED
@@ -426,6 +426,7 @@ static void read_num(ParseInfo pi) {
|
|
426
426
|
struct _numInfo ni;
|
427
427
|
Val parent = stack_peek(&pi->stack);
|
428
428
|
|
429
|
+
ni.pi = pi;
|
429
430
|
ni.str = pi->cur;
|
430
431
|
ni.i = 0;
|
431
432
|
ni.num = 0;
|
@@ -709,10 +710,7 @@ void oj_parse2(ParseInfo pi) {
|
|
709
710
|
case '[': array_start(pi); break;
|
710
711
|
case ']': array_end(pi); break;
|
711
712
|
case ',': comma(pi); break;
|
712
|
-
case '"':
|
713
|
-
read_str(pi);
|
714
|
-
break;
|
715
|
-
// case '+':
|
713
|
+
case '"': read_str(pi); break;
|
716
714
|
case '+':
|
717
715
|
if (CompatMode == pi->options.mode) {
|
718
716
|
oj_set_error_at(pi, oj_parse_error_class, __FILE__, __LINE__, "unexpected character");
|
@@ -877,7 +875,11 @@ oj_num_as_value(NumInfo ni) {
|
|
877
875
|
double d = strtod(ni->str, &end);
|
878
876
|
|
879
877
|
if ((long)ni->len != (long)(end - ni->str)) {
|
880
|
-
|
878
|
+
if (Qnil == ni->pi->err_class) {
|
879
|
+
rb_raise(oj_parse_error_class, "Invalid float");
|
880
|
+
} else {
|
881
|
+
rb_raise(ni->pi->err_class, "Invalid float");
|
882
|
+
}
|
881
883
|
}
|
882
884
|
rnum = rb_float_new(d);
|
883
885
|
}
|