oj 3.15.0 → 3.16.3
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 +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
|
}
|