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.
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, // ignore
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 in an JSON
243
- *document, zero or nil is no newline between JSON elements, negative indicates no newline between
244
- *top level JSON elements in a stream, a String indicates the string should be used for indentation
245
- * - *:circular* [_Boolean_|_nil_] support circular references while dumping as well as shared
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_] determines the
250
- *characters to escape
251
- * - *:class_cache* [_Boolean_|_nil_] cache classes for faster parsing (if dynamically modifying
252
- *classes or reloading classes then don't use this)
253
- * - *:mode* [_:object_|_:strict_|_:compat_|_:null_|_:custom_|_:rails_|_:wab_] load and dump modes
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 as a String
257
- * - *:bigdecimal_load* [_:bigdecimal_|_:float_|_:auto_|_:fast_|_:ruby_] load decimals as BigDecimal instead
258
- *of as a Float. :auto pick the most precise for the number of digits. :float should be the same as
259
- *ruby. :fast may require rounding but is must faster.
260
- * - *:compat_bigdecimal* [_true_|_false_] load decimals as BigDecimal instead of as a Float when in
261
- *compat or rails mode.
262
- * - *:create_id* [_String_|_nil_] create id for json compatible object encoding, default is
263
- *'json_class'
264
- * - *:create_additions* [_Boolean_|_nil_] if true allow creation of instances using create_id on
265
- *load.
266
- * - *:second_precision* [_Fixnum_|_nil_] number of digits after the decimal when dumping the
267
- *seconds portion of time
268
- * - *:float_precision* [_Fixnum_|_nil_] number of digits of precision when dumping floats, 0
269
- *indicates use Ruby
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 not raise an
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 documents, default
278
- *is true (allow)
279
- * - *:allow_invalid_unicode* [_true,_|_false_|_nil_] Allow invalid unicode, default is false (don't
280
- *allow)
281
- * - *:allow_nan* [_true,_|_false_|_nil_] Allow Nan, Infinity, and -Infinity to be parsed, default
282
- *is true (allow)
283
- * - *:indent_str* [_String_|_nil_] String to use for indentation, overriding the indent option is
284
- *not nil
285
- * - *:space* [_String_|_nil_] String to use for the space after the colon in JSON object fields
286
- * - *:space_before* [_String_|_nil_] String to use before the colon separator in JSON object fields
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 NaN. :null places a
290
- *null, :huge places a huge number, :word places Infinity or NaN, :raise raises and exception, :auto
291
- *uses default for each mode.
292
- * - *:hash_class* [_Class_|_nil_] Class to use instead of Hash on load, :object_class can also be
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 values are omitted
296
- * - *:omit_null_byte* [_true_|_false_] if true null bytes in strings will be omitted when dumping
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 ignored when dumping in
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 than this are cached)
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 (trace is off)
304
- * - *:safe* [_true,_|_false_] Safe mimic breaks JSON mimic to be safer, default is false (safe is
305
- *off)
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 in a JSON
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_] mode encodes all
496
- *high-bit characters as escaped sequences if :ascii, :json is standand UTF-8 JSON encoding,
497
- *:newline is the same as :json but newlines are not escaped, :unicode_xss allows unicode but
498
- *escapes &, <, and >, and any \u20xx characters along with some others, and :xss_safe escapes &, <,
499
- *and >, and some others.
500
- * - *:bigdecimal_as_decimal* [_Boolean_|_nil_] dump BigDecimal as a decimal number or as a
501
- *String.
502
- * - *:bigdecimal_load* [_:bigdecimal_|_:float_|_:auto_|_nil_] load decimals as BigDecimal instead
503
- *of as a Float. :auto pick the most precise for the number of digits.
504
- * - *:compat_bigdecimal* [_true_|_false_] load decimals as BigDecimal instead of as a Float in
505
- *compat mode.
506
- * - *:mode* [_:object_|_:strict_|_:compat_|_:null_|_:custom_|_:rails_|_:wab_] load and dump mode
507
- *to use for JSON :strict raises an exception when a non-supported Object is encountered. :compat
508
- *attempts to extract variable values from an Object using to_json() or to_hash() then it walks the
509
- *Object's variables if neither is found. The :object mode ignores to_hash() and to_json() methods
510
- *and encodes variables using code internal to the Oj gem. The :null mode ignores non-supported
511
- *Objects and replaces them with a null. The :custom mode honors all dump options. The :rails more
512
- *mimics rails and Active behavior.
513
- * - *:time_format* [_:unix_|_:xmlschema_|_:ruby_] time format when dumping in :compat mode :unix
514
- *decimal number denoting the number of seconds since 1/1/1970, :unix_zone decimal number denoting
515
- *the number of seconds since 1/1/1970 plus the utc_offset in the exponent, :xmlschema date-time
516
- *format taken from XML Schema as a String, :ruby Time.to_s formatted String.
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
- *load.
520
- * - *:second_precision* [_Fixnum_|_nil_] number of digits after the decimal when dumping the
521
- *seconds portion of time.
522
- * - *:float_precision* [_Fixnum_|_nil_] number of digits of precision when dumping floats, 0
523
- *indicates use Ruby.
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
- *true (allow).
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, strict, and
542
- *compat mode. :null places a null, :huge places a huge number, :word places Infinity or NaN, :raise
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 ignored when
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 = copts.dump_opts.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. The option to detect circular
1312
- * references is available but is not compatible with the json gem., default is false
1313
- * - *:allow_nan* [_boolean_] If true non JSON compliant words such as Nan and Infinity will be
1314
- * used as appropriate, default is true.
1315
- * - *:quirks_mode* [_boolean_] Allow single JSON values instead of documents, default is true
1316
- * (allow).
1317
- * - *:indent* [_String_|_nil_] String to use for indentation, overriding the indent option if not
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 = copts.dump_opts.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 of the clas when
1417
- * given all the member values in the order specified.
1418
- * - *members* [_Symbol__|_String_] methods used to get the member values from instances of the
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 of the clas when
1453
- *given all the member values in the order specified.
1454
- * - *dump_method* [_Symbol_|_String_] method to call on the object being serialized to generate the
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 in the output.
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. Any other Object
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 stack_buffer[4096];
192
- char *buf;
193
- char *end;
194
- char *cur;
195
- Cache8 circ_cache;
196
- slot_t circ_cnt;
197
- int indent;
198
- int depth; // used by dump_hash
199
- Options opts;
200
- uint32_t hash_cnt;
201
- bool allocated;
202
- bool omit_nil;
203
- bool omit_null_byte;
204
- int argc;
205
- VALUE *argv;
206
- DumpCaller caller; // used for the mimic json only
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 oj_dump_obj_to_json(VALUE obj, Options copts, Out out);
266
- extern void oj_dump_obj_to_json_using_params(VALUE obj, Options copts, Out out, int argc, VALUE *argv);
267
- extern void oj_write_obj_to_file(VALUE obj, const char *path, Options copts);
268
- extern void oj_write_obj_to_stream(VALUE obj, VALUE stream, Options copts);
269
- extern void oj_dump_leaf_to_json(Leaf leaf, Options copts, Out out);
270
- extern void oj_write_leaf_to_file(Leaf leaf, const char *path, Options copts);
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
- rb_raise(oj_parse_error_class, "Invalid float");
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
  }