oj 3.13.17 → 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.
Files changed (156) hide show
  1. checksums.yaml +4 -4
  2. data/CHANGELOG.md +77 -0
  3. data/README.md +4 -2
  4. data/ext/oj/buf.h +7 -6
  5. data/ext/oj/cache.c +29 -26
  6. data/ext/oj/cache.h +3 -2
  7. data/ext/oj/cache8.c +10 -9
  8. data/ext/oj/circarray.c +7 -5
  9. data/ext/oj/circarray.h +2 -2
  10. data/ext/oj/code.c +5 -12
  11. data/ext/oj/code.h +2 -2
  12. data/ext/oj/compat.c +20 -60
  13. data/ext/oj/custom.c +44 -96
  14. data/ext/oj/debug.c +3 -9
  15. data/ext/oj/dump.c +69 -39
  16. data/ext/oj/dump.h +1 -4
  17. data/ext/oj/dump_compat.c +557 -592
  18. data/ext/oj/dump_leaf.c +3 -5
  19. data/ext/oj/dump_object.c +42 -48
  20. data/ext/oj/dump_strict.c +10 -22
  21. data/ext/oj/encoder.c +1 -1
  22. data/ext/oj/err.c +2 -13
  23. data/ext/oj/err.h +9 -12
  24. data/ext/oj/extconf.rb +16 -6
  25. data/ext/oj/fast.c +76 -106
  26. data/ext/oj/intern.c +63 -51
  27. data/ext/oj/intern.h +3 -7
  28. data/ext/oj/mem.c +318 -0
  29. data/ext/oj/mem.h +53 -0
  30. data/ext/oj/mimic_json.c +43 -30
  31. data/ext/oj/object.c +61 -70
  32. data/ext/oj/odd.c +8 -6
  33. data/ext/oj/odd.h +4 -4
  34. data/ext/oj/oj.c +243 -205
  35. data/ext/oj/oj.h +82 -78
  36. data/ext/oj/parse.c +123 -188
  37. data/ext/oj/parse.h +23 -24
  38. data/ext/oj/parser.c +103 -63
  39. data/ext/oj/parser.h +19 -9
  40. data/ext/oj/rails.c +68 -92
  41. data/ext/oj/reader.c +10 -15
  42. data/ext/oj/reader.h +4 -2
  43. data/ext/oj/resolve.c +3 -4
  44. data/ext/oj/rxclass.c +6 -5
  45. data/ext/oj/rxclass.h +1 -1
  46. data/ext/oj/saj.c +10 -9
  47. data/ext/oj/saj2.c +74 -92
  48. data/ext/oj/saj2.h +23 -0
  49. data/ext/oj/scp.c +3 -14
  50. data/ext/oj/sparse.c +22 -70
  51. data/ext/oj/stream_writer.c +43 -35
  52. data/ext/oj/strict.c +20 -52
  53. data/ext/oj/string_writer.c +60 -34
  54. data/ext/oj/trace.h +31 -4
  55. data/ext/oj/usual.c +125 -150
  56. data/ext/oj/usual.h +69 -0
  57. data/ext/oj/util.h +1 -1
  58. data/ext/oj/val_stack.c +14 -3
  59. data/ext/oj/val_stack.h +8 -7
  60. data/ext/oj/wab.c +25 -57
  61. data/lib/oj/active_support_helper.rb +1 -3
  62. data/lib/oj/bag.rb +7 -1
  63. data/lib/oj/easy_hash.rb +4 -5
  64. data/lib/oj/error.rb +0 -1
  65. data/lib/oj/json.rb +162 -150
  66. data/lib/oj/mimic.rb +6 -2
  67. data/lib/oj/state.rb +9 -6
  68. data/lib/oj/version.rb +1 -2
  69. data/lib/oj.rb +2 -0
  70. data/pages/Compatibility.md +1 -1
  71. data/pages/InstallOptions.md +20 -0
  72. data/pages/Options.md +10 -0
  73. data/test/_test_active.rb +8 -9
  74. data/test/_test_active_mimic.rb +7 -8
  75. data/test/_test_mimic_rails.rb +17 -20
  76. data/test/activerecord/result_test.rb +5 -6
  77. data/test/files.rb +15 -15
  78. data/test/foo.rb +9 -72
  79. data/test/helper.rb +11 -8
  80. data/test/isolated/shared.rb +3 -2
  81. data/test/json_gem/json_addition_test.rb +2 -2
  82. data/test/json_gem/json_common_interface_test.rb +8 -6
  83. data/test/json_gem/json_encoding_test.rb +0 -0
  84. data/test/json_gem/json_ext_parser_test.rb +1 -0
  85. data/test/json_gem/json_fixtures_test.rb +3 -2
  86. data/test/json_gem/json_generator_test.rb +53 -37
  87. data/test/json_gem/json_generic_object_test.rb +11 -11
  88. data/test/json_gem/json_parser_test.rb +47 -47
  89. data/test/json_gem/json_string_matching_test.rb +9 -9
  90. data/test/json_gem/test_helper.rb +7 -3
  91. data/test/mem.rb +13 -12
  92. data/test/perf.rb +21 -26
  93. data/test/perf_compat.rb +31 -33
  94. data/test/perf_dump.rb +28 -28
  95. data/test/perf_fast.rb +80 -82
  96. data/test/perf_file.rb +27 -29
  97. data/test/perf_object.rb +65 -69
  98. data/test/perf_once.rb +12 -11
  99. data/test/perf_parser.rb +42 -48
  100. data/test/perf_saj.rb +46 -54
  101. data/test/perf_scp.rb +57 -69
  102. data/test/perf_simple.rb +41 -39
  103. data/test/perf_strict.rb +68 -70
  104. data/test/perf_wab.rb +67 -69
  105. data/test/prec.rb +5 -5
  106. data/test/sample/change.rb +0 -1
  107. data/test/sample/dir.rb +0 -1
  108. data/test/sample/doc.rb +0 -1
  109. data/test/sample/file.rb +0 -1
  110. data/test/sample/group.rb +0 -1
  111. data/test/sample/hasprops.rb +0 -1
  112. data/test/sample/layer.rb +0 -1
  113. data/test/sample/rect.rb +0 -1
  114. data/test/sample/shape.rb +0 -1
  115. data/test/sample/text.rb +0 -1
  116. data/test/sample.rb +16 -16
  117. data/test/sample_json.rb +8 -8
  118. data/test/test_compat.rb +80 -53
  119. data/test/test_custom.rb +73 -51
  120. data/test/test_debian.rb +7 -10
  121. data/test/test_fast.rb +86 -90
  122. data/test/test_file.rb +28 -35
  123. data/test/test_gc.rb +16 -5
  124. data/test/test_generate.rb +5 -5
  125. data/test/test_hash.rb +4 -4
  126. data/test/test_integer_range.rb +9 -9
  127. data/test/test_null.rb +20 -20
  128. data/test/test_object.rb +94 -96
  129. data/test/test_parser.rb +6 -22
  130. data/test/test_parser_debug.rb +27 -0
  131. data/test/test_parser_saj.rb +61 -22
  132. data/test/test_parser_usual.rb +16 -6
  133. data/test/test_rails.rb +2 -2
  134. data/test/test_saj.rb +10 -8
  135. data/test/test_scp.rb +37 -39
  136. data/test/test_strict.rb +40 -32
  137. data/test/test_various.rb +148 -100
  138. data/test/test_wab.rb +48 -44
  139. data/test/test_writer.rb +47 -47
  140. data/test/tests.rb +13 -4
  141. data/test/tests_mimic.rb +12 -3
  142. data/test/tests_mimic_addition.rb +12 -3
  143. metadata +36 -27
  144. data/test/activesupport4/decoding_test.rb +0 -108
  145. data/test/activesupport4/encoding_test.rb +0 -531
  146. data/test/activesupport4/test_helper.rb +0 -41
  147. data/test/activesupport5/abstract_unit.rb +0 -45
  148. data/test/activesupport5/decoding_test.rb +0 -133
  149. data/test/activesupport5/encoding_test.rb +0 -500
  150. data/test/activesupport5/encoding_test_cases.rb +0 -98
  151. data/test/activesupport5/test_helper.rb +0 -72
  152. data/test/activesupport5/time_zone_test_helpers.rb +0 -39
  153. data/test/bar.rb +0 -11
  154. data/test/baz.rb +0 -16
  155. data/test/bug.rb +0 -16
  156. data/test/zoo.rb +0 -13
data/ext/oj/oj.c CHANGED
@@ -14,6 +14,7 @@
14
14
  #include "dump.h"
15
15
  #include "encode.h"
16
16
  #include "intern.h"
17
+ #include "mem.h"
17
18
  #include "odd.h"
18
19
  #include "parse.h"
19
20
  #include "rails.h"
@@ -21,7 +22,7 @@
21
22
  typedef struct _yesNoOpt {
22
23
  VALUE sym;
23
24
  char *attr;
24
- } * YesNoOpt;
25
+ } *YesNoOpt;
25
26
 
26
27
  void Init_oj();
27
28
 
@@ -49,6 +50,7 @@ ID oj_json_create_id;
49
50
  ID oj_length_id;
50
51
  ID oj_new_id;
51
52
  ID oj_parse_id;
53
+ ID oj_plus_id;
52
54
  ID oj_pos_id;
53
55
  ID oj_raw_json_id;
54
56
  ID oj_read_id;
@@ -119,6 +121,7 @@ static VALUE escape_mode_sym;
119
121
  static VALUE integer_range_sym;
120
122
  static VALUE fast_sym;
121
123
  static VALUE float_prec_sym;
124
+ static VALUE float_format_sym;
122
125
  static VALUE float_sym;
123
126
  static VALUE huge_sym;
124
127
  static VALUE ignore_sym;
@@ -131,6 +134,7 @@ static VALUE newline_sym;
131
134
  static VALUE nilnil_sym;
132
135
  static VALUE null_sym;
133
136
  static VALUE object_sym;
137
+ static VALUE omit_null_byte_sym;
134
138
  static VALUE omit_nil_sym;
135
139
  static VALUE rails_sym;
136
140
  static VALUE raise_sym;
@@ -152,8 +156,8 @@ static VALUE word_sym;
152
156
  static VALUE xmlschema_sym;
153
157
  static VALUE xss_safe_sym;
154
158
 
155
- rb_encoding *oj_utf8_encoding = 0;
156
- int oj_utf8_encoding_index = 0;
159
+ rb_encoding *oj_utf8_encoding = 0;
160
+ int oj_utf8_encoding_index = 0;
157
161
 
158
162
  #ifdef HAVE_PTHREAD_MUTEX_INIT
159
163
  pthread_mutex_t oj_cache_mutex;
@@ -218,6 +222,7 @@ struct _options oj_default_options = {
218
222
  0, // array_size
219
223
  AutoNan, // nan_dump
220
224
  false, // omit_nil
225
+ false, // omit_null_byte
221
226
  MAX_DEPTH, // max_depth
222
227
  },
223
228
  {
@@ -226,76 +231,89 @@ struct _options oj_default_options = {
226
231
  NULL, // tail
227
232
  {'\0'}, // err
228
233
  },
229
- NULL, // ignore
234
+ NULL,
230
235
  };
231
236
 
232
237
  /* Document-method: default_options()
233
238
  * call-seq: default_options()
234
239
  *
235
240
  * Returns the default load and dump options as a Hash. The options are
236
- * - *:indent* [_Fixnum_|_String_|_nil_] number of spaces to indent each element in an JSON
237
- *document, zero or nil is no newline between JSON elements, negative indicates no newline between
238
- *top level JSON elements in a stream, a String indicates the string should be used for indentation
239
- * - *:circular* [_Boolean_|_nil_] support circular references while dumping as well as shared
240
- *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
241
247
  * - *:auto_define* [_Boolean_|_nil_] automatically define classes if they do not exist
242
248
  * - *:symbol_keys* [_Boolean_|_nil_] use symbols instead of strings for hash keys
243
- * - *:escape_mode* [_:newline_|_:json_|_:xss_safe_|_:ascii_|_unicode_xss_|_nil_] determines the
244
- *characters to escape
245
- * - *:class_cache* [_Boolean_|_nil_] cache classes for faster parsing (if dynamically modifying
246
- *classes or reloading classes then don't use this)
247
- * - *:mode* [_:object_|_:strict_|_:compat_|_:null_|_:custom_|_:rails_|_:wab_] load and dump modes
248
- *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
249
255
  * - *:time_format* [_:unix_|_:unix_zone_|_:xmlschema_|_:ruby_] time format when dumping
250
- * - *:bigdecimal_as_decimal* [_Boolean_|_nil_] dump BigDecimal as a decimal number or as a String
251
- * - *:bigdecimal_load* [_:bigdecimal_|_:float_|_:auto_|_:fast_] load decimals as BigDecimal instead
252
- *of as a Float. :auto pick the most precise for the number of digits. :float should be the same as
253
- *ruby. :fast may require rounding but is must faster.
254
- * - *:compat_bigdecimal* [_true_|_false_] load decimals as BigDecimal instead of as a Float when in
255
- *compat or rails mode.
256
- * - *:create_id* [_String_|_nil_] create id for json compatible object encoding, default is
257
- *'json_class'
258
- * - *:create_additions* [_Boolean_|_nil_] if true allow creation of instances using create_id on
259
- *load.
260
- * - *:second_precision* [_Fixnum_|_nil_] number of digits after the decimal when dumping the
261
- *seconds portion of time
262
- * - *:float_precision* [_Fixnum_|_nil_] number of digits of precision when dumping floats, 0
263
- *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.
264
275
  * - *:use_to_json* [_Boolean_|_nil_] call to_json() methods on dump, default is false
265
276
  * - *:use_as_json* [_Boolean_|_nil_] call as_json() methods on dump, default is false
266
277
  * - *:use_raw_json* [_Boolean_|_nil_] call raw_json() methods on dump, default is false
267
- * - *:nilnil* [_Boolean_|_nil_] if true a nil input to load will return nil and not raise an
268
- *Exception
278
+ * - *:nilnil* [_Boolean_|_nil_] if true a nil input to load will return nil and
279
+ * not raise an Exception
269
280
  * - *:empty_string* [_Boolean_|_nil_] if true an empty input will not raise an Exception
270
281
  * - *:allow_gc* [_Boolean_|_nil_] allow or prohibit GC during parsing, default is true (allow)
271
- * - *:quirks_mode* [_true,_|_false_|_nil_] Allow single JSON values instead of documents, default
272
- *is true (allow)
273
- * - *:allow_invalid_unicode* [_true,_|_false_|_nil_] Allow invalid unicode, default is false (don't
274
- *allow)
275
- * - *:allow_nan* [_true,_|_false_|_nil_] Allow Nan, Infinity, and -Infinity to be parsed, default
276
- *is true (allow)
277
- * - *:indent_str* [_String_|_nil_] String to use for indentation, overriding the indent option is
278
- *not nil
279
- * - *:space* [_String_|_nil_] String to use for the space after the colon in JSON object fields
280
- * - *: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
281
294
  * - *:object_nl* [_String_|_nil_] String to use after a JSON object field value
282
295
  * - *:array_nl* [_String_|_nil_] String to use after a JSON array value
283
- * - *:nan* [_:null_|_:huge_|_:word_|_:raise_|_:auto_] how to dump Infinity and NaN. :null places a
284
- *null, :huge places a huge number, :word places Infinity or NaN, :raise raises and exception, :auto
285
- *uses default for each mode.
286
- * - *:hash_class* [_Class_|_nil_] Class to use instead of Hash on load, :object_class can also be
287
- *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
288
301
  * - *:array_class* [_Class_|_nil_] Class to use instead of Array on load
289
- * - *:omit_nil* [_true_|_false_] if true Hash and Object attributes with nil values are omitted
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
290
306
  * - *:ignore* [_nil_|_Array_] either nil or an Array of classes to ignore when dumping
291
- * - *:ignore_under* [_Boolean_] if true then attributes that start with _ are ignored when dumping in
292
- *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.
293
309
  * - *:cache_keys* [_Boolean_] if true then hash keys are cached if less than 35 bytes.
294
- * - *: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)
295
312
  * - *:integer_range* [_Range_] Dump integers outside range as strings.
296
- * - *:trace* [_true,_|_false_] Trace all load and dump calls, default is false (trace is off)
297
- * - *:safe* [_true,_|_false_] Safe mimic breaks JSON mimic to be safer, default is false (safe is
298
- *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)
299
317
  *
300
318
  * Return [_Hash_] all current option settings.
301
319
  */
@@ -371,6 +389,7 @@ static VALUE get_def_opts(VALUE self) {
371
389
  oj_safe_sym,
372
390
  (Yes == oj_default_options.safe) ? Qtrue : ((No == oj_default_options.safe) ? Qfalse : Qnil));
373
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));
374
393
  rb_hash_aset(opts, cache_str_sym, INT2FIX(oj_default_options.cache_str));
375
394
  rb_hash_aset(
376
395
  opts,
@@ -380,6 +399,7 @@ static VALUE get_def_opts(VALUE self) {
380
399
  opts,
381
400
  cache_keys_sym,
382
401
  (Yes == oj_default_options.cache_keys) ? Qtrue : ((No == oj_default_options.cache_keys) ? Qfalse : Qnil));
402
+
383
403
  switch (oj_default_options.mode) {
384
404
  case StrictMode: rb_hash_aset(opts, mode_sym, strict_sym); break;
385
405
  case CompatMode: rb_hash_aset(opts, mode_sym, compat_sym); break;
@@ -455,13 +475,14 @@ static VALUE get_def_opts(VALUE self) {
455
475
  default: rb_hash_aset(opts, nan_sym, auto_sym); break;
456
476
  }
457
477
  rb_hash_aset(opts, omit_nil_sym, oj_default_options.dump_opts.omit_nil ? Qtrue : Qfalse);
478
+ rb_hash_aset(opts, omit_null_byte_sym, oj_default_options.dump_opts.omit_null_byte ? Qtrue : Qfalse);
458
479
  rb_hash_aset(opts, oj_hash_class_sym, oj_default_options.hash_class);
459
480
  rb_hash_aset(opts, oj_array_class_sym, oj_default_options.array_class);
460
481
 
461
482
  if (NULL == oj_default_options.ignore) {
462
483
  rb_hash_aset(opts, ignore_sym, Qnil);
463
484
  } else {
464
- VALUE * vp;
485
+ VALUE *vp;
465
486
  volatile VALUE a = rb_ary_new();
466
487
 
467
488
  for (vp = oj_default_options.ignore; Qnil != *vp; vp++) {
@@ -477,68 +498,67 @@ static VALUE get_def_opts(VALUE self) {
477
498
  *
478
499
  * Sets the default options for load and dump.
479
500
  * - *opts* [_Hash_] options to change
480
- * - *:indent* [_Fixnum_|_String_|_nil_] number of spaces to indent each element in a JSON
481
- *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.
482
503
  * - :circular [_Boolean_|_nil_] support circular references while dumping.
483
504
  * - *:auto_define* [_Boolean_|_nil_] automatically define classes if they do not exist.
484
505
  * - *:symbol_keys* [_Boolean_|_nil_] convert hash keys to symbols.
485
506
  * - *:class_cache* [_Boolean_|_nil_] cache classes for faster parsing.
486
- * - *:escape* [_:newline_|_:json_|_:xss_safe_|_:ascii_|_unicode_xss_|_nil_] mode encodes all
487
- *high-bit characters as escaped sequences if :ascii, :json is standand UTF-8 JSON encoding,
488
- *:newline is the same as :json but newlines are not escaped, :unicode_xss allows unicode but
489
- *escapes &, <, and >, and any \u20xx characters along with some others, and :xss_safe escapes &, <,
490
- *and >, and some others.
491
- * - *:bigdecimal_as_decimal* [_Boolean_|_nil_] dump BigDecimal as a decimal number or as a
492
- *String.
493
- * - *:bigdecimal_load* [_:bigdecimal_|_:float_|_:auto_|_nil_] load decimals as BigDecimal instead
494
- *of as a Float. :auto pick the most precise for the number of digits.
495
- * - *:compat_bigdecimal* [_true_|_false_] load decimals as BigDecimal instead of as a Float in
496
- *compat mode.
497
- * - *:mode* [_:object_|_:strict_|_:compat_|_:null_|_:custom_|_:rails_|_:wab_] load and dump mode
498
- *to use for JSON :strict raises an exception when a non-supported Object is encountered. :compat
499
- *attempts to extract variable values from an Object using to_json() or to_hash() then it walks the
500
- *Object's variables if neither is found. The :object mode ignores to_hash() and to_json() methods
501
- *and encodes variables using code internal to the Oj gem. The :null mode ignores non-supported
502
- *Objects and replaces them with a null. The :custom mode honors all dump options. The :rails more
503
- *mimics rails and Active behavior.
504
- * - *:time_format* [_:unix_|_:xmlschema_|_:ruby_] time format when dumping in :compat mode :unix
505
- *decimal number denoting the number of seconds since 1/1/1970, :unix_zone decimal number denoting
506
- *the number of seconds since 1/1/1970 plus the utc_offset in the exponent, :xmlschema date-time
507
- *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.
508
532
  * - *:create_id* [_String_|_nil_] create id for json compatible object encoding
509
- * - *:create_additions* [_Boolean_|_nil_] if true allow creation of instances using create_id on
510
- *load.
511
- * - *:second_precision* [_Fixnum_|_nil_] number of digits after the decimal when dumping the
512
- *seconds portion of time.
513
- * - *:float_precision* [_Fixnum_|_nil_] number of digits of precision when dumping floats, 0
514
- *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.
515
540
  * - *:use_to_json* [_Boolean_|_nil_] call to_json() methods on dump, default is false.
516
541
  * - *:use_as_json* [_Boolean_|_nil_] call as_json() methods on dump, default is false.
517
542
  * - *:use_to_hash* [_Boolean_|_nil_] call to_hash() methods on dump, default is false.
518
543
  * - *:use_raw_json* [_Boolean_|_nil_] call raw_json() methods on dump, default is false.
519
- * - *:nilnil* [_Boolean_|_nil_] if true a nil input to load will return nil and not raise an
520
- *Exception.
544
+ * - *:nilnil* [_Boolean_|_nil_] if true a nil input to load will return nil and not raise an Exception.
521
545
  * - *:allow_gc* [_Boolean_|_nil_] allow or prohibit GC during parsing, default is true (allow).
522
- * - *:quirks_mode* [_Boolean_|_nil_] allow single JSON values instead of documents, default is
523
- *true (allow).
524
- * - *:allow_invalid_unicode* [_Boolean_|_nil_] allow invalid unicode, default is false (don't
525
- *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).
526
548
  * - *:allow_nan* [_Boolean_|_nil_] allow Nan, Infinity, and -Infinity, default is true (allow).
527
549
  * - *:space* [_String_|_nil_] String to use for the space after the colon in JSON object fields.
528
- * - *:space_before* [_String_|_nil_] String to use before the colon separator in JSON object
529
- *fields.
550
+ * - *:space_before* [_String_|_nil_] String to use before the colon separator in JSON object fields.
530
551
  * - *:object_nl* [_String_|_nil_] String to use after a JSON object field value.
531
552
  * - *:array_nl* [_String_|_nil_] String to use after a JSON array value
532
- * - *:nan* [_:null_|_:huge_|_:word_|_:raise_] how to dump Infinity and NaN in null, strict, and
533
- *compat mode. :null places a null, :huge places a huge number, :word places Infinity or NaN, :raise
534
- *raises and exception, :auto uses default for each mode.
535
- * - *:hash_class* [_Class_|_nil_] Class to use instead of Hash on load, :object_class can also be
536
- *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.
537
557
  * - *:array_class* [_Class_|_nil_] Class to use instead of Array on load.
538
558
  * - *:omit_nil* [_true_|_false_] if true Hash and Object attributes with nil values are omitted.
539
559
  * - *:ignore* [_nil_|Array] either nil or an Array of classes to ignore when dumping
540
- * - *:ignore_under* [_Boolean_] if true then attributes that start with _ are ignored when
541
- *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.
542
562
  * - *:cache_keys* [_Boolean_] if true then hash keys are cached
543
563
  * - *:cache_str* [_Fixnum_] maximum string value length to cache (strings less than this are cached)
544
564
  * - *:integer_range* [_Range_] Dump integers outside range as strings.
@@ -608,7 +628,6 @@ static int parse_options_cb(VALUE k, VALUE v, VALUE opts) {
608
628
  if (set_yesno_options(k, v, copts)) {
609
629
  return ST_CONTINUE;
610
630
  }
611
-
612
631
  if (oj_indent_sym == k) {
613
632
  switch (rb_type(v)) {
614
633
  case T_NIL:
@@ -636,15 +655,9 @@ static int parse_options_cb(VALUE k, VALUE v, VALUE opts) {
636
655
  } else if (float_prec_sym == k) {
637
656
  int n;
638
657
 
639
- #ifdef RUBY_INTEGER_UNIFICATION
640
658
  if (rb_cInteger != rb_obj_class(v)) {
641
659
  rb_raise(rb_eArgError, ":float_precision must be a Integer.");
642
660
  }
643
- #else
644
- if (T_FIXNUM != rb_type(v)) {
645
- rb_raise(rb_eArgError, ":float_precision must be a Fixnum.");
646
- }
647
- #endif
648
661
  n = FIX2INT(v);
649
662
  if (0 >= n) {
650
663
  *copts->float_fmt = '\0';
@@ -659,15 +672,9 @@ static int parse_options_cb(VALUE k, VALUE v, VALUE opts) {
659
672
  } else if (cache_str_sym == k || cache_string_sym == k) {
660
673
  int n;
661
674
 
662
- #ifdef RUBY_INTEGER_UNIFICATION
663
675
  if (rb_cInteger != rb_obj_class(v)) {
664
676
  rb_raise(rb_eArgError, ":cache_str must be a Integer.");
665
677
  }
666
- #else
667
- if (T_FIXNUM != rb_type(v)) {
668
- rb_raise(rb_eArgError, ":cache_str must be a Fixnum.");
669
- }
670
- #endif
671
678
  n = FIX2INT(v);
672
679
  if (0 >= n) {
673
680
  copts->cache_str = 0;
@@ -680,15 +687,9 @@ static int parse_options_cb(VALUE k, VALUE v, VALUE opts) {
680
687
  } else if (sec_prec_sym == k) {
681
688
  int n;
682
689
 
683
- #ifdef RUBY_INTEGER_UNIFICATION
684
690
  if (rb_cInteger != rb_obj_class(v)) {
685
691
  rb_raise(rb_eArgError, ":second_precision must be a Integer.");
686
692
  }
687
- #else
688
- if (T_FIXNUM != rb_type(v)) {
689
- rb_raise(rb_eArgError, ":second_precision must be a Fixnum.");
690
- }
691
- #endif
692
693
  n = NUM2INT(v);
693
694
  if (0 > n) {
694
695
  n = 0;
@@ -766,7 +767,6 @@ static int parse_options_cb(VALUE k, VALUE v, VALUE opts) {
766
767
  if (Qnil == v) {
767
768
  return ST_CONTINUE;
768
769
  }
769
-
770
770
  copts->compat_bigdec = (Qtrue == v);
771
771
  } else if (oj_decimal_class_sym == k) {
772
772
  if (rb_cFloat == v) {
@@ -779,7 +779,7 @@ static int parse_options_cb(VALUE k, VALUE v, VALUE opts) {
779
779
  } else if (create_id_sym == k) {
780
780
  if (Qnil == v) {
781
781
  if (oj_json_class != oj_default_options.create_id && NULL != copts->create_id) {
782
- xfree((char *)oj_default_options.create_id);
782
+ OJ_R_FREE((char *)oj_default_options.create_id);
783
783
  }
784
784
  copts->create_id = NULL;
785
785
  copts->create_id_len = 0;
@@ -788,7 +788,7 @@ static int parse_options_cb(VALUE k, VALUE v, VALUE opts) {
788
788
 
789
789
  len = RSTRING_LEN(v);
790
790
  if (len != copts->create_id_len || 0 != strcmp(copts->create_id, str)) {
791
- copts->create_id = ALLOC_N(char, len + 1);
791
+ copts->create_id = OJ_R_ALLOC_N(char, len + 1);
792
792
  strcpy((char *)copts->create_id, str);
793
793
  copts->create_id_len = len;
794
794
  }
@@ -879,6 +879,17 @@ static int parse_options_cb(VALUE k, VALUE v, VALUE opts) {
879
879
  } else {
880
880
  rb_raise(rb_eArgError, ":omit_nil must be true or false.");
881
881
  }
882
+ } else if (omit_null_byte_sym == k) {
883
+ if (Qnil == v) {
884
+ return ST_CONTINUE;
885
+ }
886
+ if (Qtrue == v) {
887
+ copts->dump_opts.omit_null_byte = true;
888
+ } else if (Qfalse == v) {
889
+ copts->dump_opts.omit_null_byte = false;
890
+ } else {
891
+ rb_raise(rb_eArgError, ":omit_null_byte must be true or false.");
892
+ }
882
893
  } else if (oj_ascii_only_sym == k) {
883
894
  // This is here only for backwards compatibility with the original Oj.
884
895
  if (Qtrue == v) {
@@ -908,7 +919,7 @@ static int parse_options_cb(VALUE k, VALUE v, VALUE opts) {
908
919
  copts->array_class = v;
909
920
  }
910
921
  } else if (ignore_sym == k) {
911
- xfree(copts->ignore);
922
+ OJ_R_FREE(copts->ignore);
912
923
  copts->ignore = NULL;
913
924
  if (Qnil != v) {
914
925
  int cnt;
@@ -918,7 +929,7 @@ static int parse_options_cb(VALUE k, VALUE v, VALUE opts) {
918
929
  if (0 < cnt) {
919
930
  int i;
920
931
 
921
- copts->ignore = ALLOC_N(VALUE, cnt + 1);
932
+ copts->ignore = OJ_R_ALLOC_N(VALUE, cnt + 1);
922
933
  for (i = 0; i < cnt; i++) {
923
934
  copts->ignore[i] = RARRAY_AREF(v, i);
924
935
  }
@@ -929,7 +940,7 @@ static int parse_options_cb(VALUE k, VALUE v, VALUE opts) {
929
940
  if (Qnil == v) {
930
941
  return ST_CONTINUE;
931
942
  }
932
- if (TYPE(v) == T_STRUCT && rb_obj_class(v) == rb_cRange) {
943
+ if (rb_obj_class(v) == rb_cRange) {
933
944
  VALUE min = rb_funcall(v, oj_begin_id, 0);
934
945
  VALUE max = rb_funcall(v, oj_end_id, 0);
935
946
 
@@ -946,7 +957,26 @@ static int parse_options_cb(VALUE k, VALUE v, VALUE opts) {
946
957
  if (Qnil == v) {
947
958
  return ST_CONTINUE;
948
959
  }
949
- copts->sym_key = (Qtrue == v) ? Yes : No;
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';
950
980
  }
951
981
  return ST_CONTINUE;
952
982
  }
@@ -955,7 +985,6 @@ void oj_parse_options(VALUE ropts, Options copts) {
955
985
  if (T_HASH != rb_type(ropts)) {
956
986
  return;
957
987
  }
958
-
959
988
  rb_hash_foreach(ropts, parse_options_cb, (VALUE)copts);
960
989
  oj_parse_opt_match_string(&copts->str_rx, ropts);
961
990
 
@@ -1111,7 +1140,7 @@ static VALUE load(int argc, VALUE *argv, VALUE self) {
1111
1140
  * Returns [_Object_|_Hash_|_Array_|_String_|_Fixnum_|_Float_|_Boolean_|_nil_]
1112
1141
  */
1113
1142
  static VALUE load_file(int argc, VALUE *argv, VALUE self) {
1114
- char * path;
1143
+ char *path;
1115
1144
  int fd;
1116
1145
  Mode mode = oj_default_options.mode;
1117
1146
  struct _parseInfo pi;
@@ -1119,7 +1148,7 @@ static VALUE load_file(int argc, VALUE *argv, VALUE self) {
1119
1148
  if (1 > argc) {
1120
1149
  rb_raise(rb_eArgError, "Wrong number of arguments to load().");
1121
1150
  }
1122
- Check_Type(*argv, T_STRING);
1151
+ path = StringValuePtr(*argv);
1123
1152
  parse_info_init(&pi);
1124
1153
  pi.options = oj_default_options;
1125
1154
  pi.handler = Qnil;
@@ -1150,16 +1179,15 @@ static VALUE load_file(int argc, VALUE *argv, VALUE self) {
1150
1179
  }
1151
1180
  }
1152
1181
  }
1153
- path = StringValuePtr(*argv);
1154
1182
  #ifdef _WIN32
1155
1183
  {
1156
1184
  WCHAR *wide_path;
1157
1185
  wide_path = rb_w32_mbstr_to_wstr(CP_UTF8, path, -1, NULL);
1158
- fd = rb_w32_wopen(wide_path, O_RDONLY);
1159
- free(wide_path);
1186
+ fd = rb_w32_wopen(wide_path, O_RDONLY);
1187
+ OJ_FREE(wide_path);
1160
1188
  }
1161
1189
  #else
1162
- fd = open(path, O_RDONLY);
1190
+ fd = open(path, O_RDONLY);
1163
1191
  #endif
1164
1192
  if (0 == fd) {
1165
1193
  rb_raise(rb_eIOError, "%s", strerror(errno));
@@ -1234,10 +1262,10 @@ static VALUE safe_load(VALUE self, VALUE doc) {
1234
1262
  */
1235
1263
 
1236
1264
  struct dump_arg {
1237
- struct _out * out;
1265
+ struct _out *out;
1238
1266
  struct _options *copts;
1239
1267
  int argc;
1240
- VALUE * argv;
1268
+ VALUE *argv;
1241
1269
  };
1242
1270
 
1243
1271
  static VALUE dump_body(VALUE a) {
@@ -1293,8 +1321,8 @@ static VALUE dump(int argc, VALUE *argv, VALUE self) {
1293
1321
 
1294
1322
  oj_out_init(arg.out);
1295
1323
 
1296
- arg.out->omit_nil = copts.dump_opts.omit_nil;
1297
- arg.out->caller = CALLER_DUMP;
1324
+ arg.out->omit_nil = copts.dump_opts.omit_nil;
1325
+ arg.out->omit_null_byte = copts.dump_opts.omit_null_byte;
1298
1326
 
1299
1327
  return rb_ensure(dump_body, (VALUE)&arg, dump_ensure, (VALUE)&arg);
1300
1328
  }
@@ -1306,17 +1334,16 @@ static VALUE dump(int argc, VALUE *argv, VALUE self) {
1306
1334
  * will be called. The mode is set to :compat.
1307
1335
  * - *obj* [_Object_] Object to serialize as an JSON document String
1308
1336
  * - *options* [_Hash_]
1309
- * - *:max_nesting* [_boolean_] It true nesting is limited to 100. The option to detect circular
1310
- * references is available but is not compatible with the json gem., default is false
1311
- * - *:allow_nan* [_boolean_] If true non JSON compliant words such as Nan and Infinity will be
1312
- * used as appropriate, default is true.
1313
- * - *:quirks_mode* [_boolean_] Allow single JSON values instead of documents, default is true
1314
- * (allow).
1315
- * - *:indent* [_String_|_nil_] String to use for indentation, overriding the indent option if not
1316
- * 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.
1317
1345
  * - *:space* [_String_|_nil_] String to use for the space after the colon in JSON object fields.
1318
- * - *:space_before* [_String_|_nil_] String to use before the colon separator in JSON object
1319
- * fields.
1346
+ * - *:space_before* [_String_|_nil_] String to use before the colon separator in JSON object fields.
1320
1347
  * - *:object_nl* [_String_|_nil_] String to use after a JSON object field value.
1321
1348
  * - *:array_nl* [_String_|_nil_] String to use after a JSON array value.
1322
1349
  * - *:trace* [_Boolean_] If true trace is turned on.
@@ -1341,7 +1368,8 @@ static VALUE to_json(int argc, VALUE *argv, VALUE self) {
1341
1368
 
1342
1369
  oj_out_init(&out);
1343
1370
 
1344
- out.omit_nil = copts.dump_opts.omit_nil;
1371
+ out.omit_nil = copts.dump_opts.omit_nil;
1372
+ out.omit_null_byte = copts.dump_opts.omit_null_byte;
1345
1373
  // For obj.to_json or generate nan is not allowed but if called from dump
1346
1374
  // it is.
1347
1375
  oj_dump_obj_to_json_using_params(*argv, &copts, &out, argc - 1, argv + 1);
@@ -1373,7 +1401,6 @@ static VALUE to_file(int argc, VALUE *argv, VALUE self) {
1373
1401
  if (3 == argc) {
1374
1402
  oj_parse_options(argv[2], &copts);
1375
1403
  }
1376
- Check_Type(*argv, T_STRING);
1377
1404
  oj_write_obj_to_file(argv[1], StringValuePtr(*argv), &copts);
1378
1405
 
1379
1406
  return Qnil;
@@ -1411,10 +1438,10 @@ static VALUE to_stream(int argc, VALUE *argv, VALUE self) {
1411
1438
  *
1412
1439
  * - *clas* [_Class__|_Module_] Class or Module to be made special
1413
1440
  * - *create_object* [_Object_] object to call the create method on
1414
- * - *create_method* [_Symbol_] method on the clas that will create a new instance of the clas when
1415
- * given all the member values in the order specified.
1416
- * - *members* [_Symbol__|_String_] methods used to get the member values from instances of the
1417
- * 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.
1418
1445
  */
1419
1446
  static VALUE register_odd(int argc, VALUE *argv, VALUE self) {
1420
1447
  if (3 > argc) {
@@ -1447,10 +1474,10 @@ static VALUE register_odd(int argc, VALUE *argv, VALUE self) {
1447
1474
  *
1448
1475
  * - *clas* [_Class_|_Module_] Class or Module to be made special
1449
1476
  * - *create_object* [_Object_] object to call the create method on
1450
- * - *create_method* [_Symbol_] method on the clas that will create a new instance of the clas when
1451
- *given all the member values in the order specified.
1452
- * - *dump_method* [_Symbol_|_String_] method to call on the object being serialized to generate the
1453
- *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.
1454
1481
  */
1455
1482
  static VALUE register_odd_raw(int argc, VALUE *argv, VALUE self) {
1456
1483
  if (3 > argc) {
@@ -1676,8 +1703,8 @@ extern VALUE oj_define_mimic_json(int argc, VALUE *argv, VALUE self);
1676
1703
  * - *:space_before* [_String_] String placed before a : delimiter
1677
1704
  * - *:object_nl* [_String_] String placed after a JSON object
1678
1705
  * - *:array_nl* [_String_] String placed after a JSON array
1679
- * - *:ascii_only* [_Boolean_] if not nil or false then use only ascii characters in the output.
1680
- * 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.
1681
1708
  *
1682
1709
  * Returns [_String_]generated JSON.
1683
1710
  */
@@ -1715,12 +1742,15 @@ static VALUE protect_require(VALUE x) {
1715
1742
 
1716
1743
  extern void print_all_odds(const char *label);
1717
1744
 
1718
- static VALUE
1719
- debug_odd(VALUE self, VALUE label) {
1745
+ static VALUE debug_odd(VALUE self, VALUE label) {
1720
1746
  print_all_odds(RSTRING_PTR(label));
1721
1747
  return Qnil;
1722
1748
  }
1723
1749
 
1750
+ static VALUE mem_report(VALUE self) {
1751
+ oj_mem_report();
1752
+ return Qnil;
1753
+ }
1724
1754
 
1725
1755
  /* Document-module: Oj
1726
1756
  *
@@ -1731,8 +1761,8 @@ debug_odd(VALUE self, VALUE label) {
1731
1761
  * global and options to methods allow additional behavior modifications. The
1732
1762
  * modes are:
1733
1763
  *
1734
- * - *:strict* mode will only allow the 7 basic JSON types to be serialized. Any other Object
1735
- * 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.
1736
1766
  *
1737
1767
  * - *:null* mode is similar to the :strict mode except any Object that is not
1738
1768
  * one of the JSON base types is replaced by a JSON null.
@@ -1772,7 +1802,7 @@ void Init_oj(void) {
1772
1802
  rb_protect(protect_require, Qnil, &err);
1773
1803
  rb_require("stringio");
1774
1804
  oj_utf8_encoding_index = rb_enc_find_index("UTF-8");
1775
- oj_utf8_encoding = rb_enc_from_index(oj_utf8_encoding_index);
1805
+ oj_utf8_encoding = rb_enc_from_index(oj_utf8_encoding_index);
1776
1806
 
1777
1807
  // rb_define_module_function(Oj, "hash_test", hash_test, 0);
1778
1808
  rb_define_module_function(Oj, "debug_odd", debug_odd, 1);
@@ -1809,48 +1839,51 @@ void Init_oj(void) {
1809
1839
 
1810
1840
  rb_define_module_function(Oj, "optimize_rails", oj_optimize_rails, 0);
1811
1841
 
1812
- oj_add_value_id = rb_intern("add_value");
1813
- oj_array_append_id = rb_intern("array_append");
1814
- oj_array_end_id = rb_intern("array_end");
1815
- oj_array_start_id = rb_intern("array_start");
1816
- oj_as_json_id = rb_intern("as_json");
1817
- oj_begin_id = rb_intern("begin");
1818
- oj_bigdecimal_id = rb_intern("BigDecimal");
1819
- oj_end_id = rb_intern("end");
1820
- oj_error_id = rb_intern("error");
1821
- oj_exclude_end_id = rb_intern("exclude_end?");
1822
- oj_file_id = rb_intern("file?");
1823
- oj_fileno_id = rb_intern("fileno");
1824
- oj_ftype_id = rb_intern("ftype");
1825
- oj_hash_end_id = rb_intern("hash_end");
1826
- oj_hash_key_id = rb_intern("hash_key");
1827
- oj_hash_set_id = rb_intern("hash_set");
1828
- oj_hash_start_id = rb_intern("hash_start");
1829
- oj_iconv_id = rb_intern("iconv");
1830
- oj_json_create_id = rb_intern("json_create");
1831
- oj_length_id = rb_intern("length");
1832
- oj_new_id = rb_intern("new");
1833
- oj_parse_id = rb_intern("parse");
1834
- oj_pos_id = rb_intern("pos");
1835
- oj_raw_json_id = rb_intern("raw_json");
1836
- oj_read_id = rb_intern("read");
1837
- oj_readpartial_id = rb_intern("readpartial");
1838
- oj_replace_id = rb_intern("replace");
1839
- oj_stat_id = rb_intern("stat");
1840
- oj_string_id = rb_intern("string");
1841
- oj_to_h_id = rb_intern("to_h");
1842
- oj_to_hash_id = rb_intern("to_hash");
1843
- oj_to_json_id = rb_intern("to_json");
1844
- oj_to_s_id = rb_intern("to_s");
1845
- oj_to_sym_id = rb_intern("to_sym");
1846
- oj_to_time_id = rb_intern("to_time");
1847
- oj_tv_nsec_id = rb_intern("tv_nsec");
1848
- oj_tv_sec_id = rb_intern("tv_sec");
1849
- oj_tv_usec_id = rb_intern("tv_usec");
1850
- oj_utc_id = rb_intern("utc");
1851
- oj_utc_offset_id = rb_intern("utc_offset");
1852
- oj_utcq_id = rb_intern("utc?");
1853
- oj_write_id = rb_intern("write");
1842
+ rb_define_module_function(Oj, "mem_report", mem_report, 0);
1843
+
1844
+ oj_add_value_id = rb_intern("add_value");
1845
+ oj_array_append_id = rb_intern("array_append");
1846
+ oj_array_end_id = rb_intern("array_end");
1847
+ oj_array_start_id = rb_intern("array_start");
1848
+ oj_as_json_id = rb_intern("as_json");
1849
+ oj_begin_id = rb_intern("begin");
1850
+ oj_bigdecimal_id = rb_intern("BigDecimal");
1851
+ oj_end_id = rb_intern("end");
1852
+ oj_error_id = rb_intern("error");
1853
+ oj_exclude_end_id = rb_intern("exclude_end?");
1854
+ oj_file_id = rb_intern("file?");
1855
+ oj_fileno_id = rb_intern("fileno");
1856
+ oj_ftype_id = rb_intern("ftype");
1857
+ oj_hash_end_id = rb_intern("hash_end");
1858
+ oj_hash_key_id = rb_intern("hash_key");
1859
+ oj_hash_set_id = rb_intern("hash_set");
1860
+ oj_hash_start_id = rb_intern("hash_start");
1861
+ oj_iconv_id = rb_intern("iconv");
1862
+ oj_json_create_id = rb_intern("json_create");
1863
+ oj_length_id = rb_intern("length");
1864
+ oj_new_id = rb_intern("new");
1865
+ oj_parse_id = rb_intern("parse");
1866
+ oj_plus_id = rb_intern("+");
1867
+ oj_pos_id = rb_intern("pos");
1868
+ oj_raw_json_id = rb_intern("raw_json");
1869
+ oj_read_id = rb_intern("read");
1870
+ oj_readpartial_id = rb_intern("readpartial");
1871
+ oj_replace_id = rb_intern("replace");
1872
+ oj_stat_id = rb_intern("stat");
1873
+ oj_string_id = rb_intern("string");
1874
+ oj_to_h_id = rb_intern("to_h");
1875
+ oj_to_hash_id = rb_intern("to_hash");
1876
+ oj_to_json_id = rb_intern("to_json");
1877
+ oj_to_s_id = rb_intern("to_s");
1878
+ oj_to_sym_id = rb_intern("to_sym");
1879
+ oj_to_time_id = rb_intern("to_time");
1880
+ oj_tv_nsec_id = rb_intern("tv_nsec");
1881
+ oj_tv_sec_id = rb_intern("tv_sec");
1882
+ oj_tv_usec_id = rb_intern("tv_usec");
1883
+ oj_utc_id = rb_intern("utc");
1884
+ oj_utc_offset_id = rb_intern("utc_offset");
1885
+ oj_utcq_id = rb_intern("utc?");
1886
+ oj_write_id = rb_intern("write");
1854
1887
 
1855
1888
  rb_require("oj/bag");
1856
1889
  rb_require("oj/error");
@@ -1921,6 +1954,8 @@ void Init_oj(void) {
1921
1954
  rb_gc_register_address(&integer_range_sym);
1922
1955
  fast_sym = ID2SYM(rb_intern("fast"));
1923
1956
  rb_gc_register_address(&fast_sym);
1957
+ float_format_sym = ID2SYM(rb_intern("float_format"));
1958
+ rb_gc_register_address(&float_format_sym);
1924
1959
  float_prec_sym = ID2SYM(rb_intern("float_precision"));
1925
1960
  rb_gc_register_address(&float_prec_sym);
1926
1961
  float_sym = ID2SYM(rb_intern("float"));
@@ -1973,6 +2008,8 @@ void Init_oj(void) {
1973
2008
  rb_gc_register_address(&oj_quirks_mode_sym);
1974
2009
  oj_safe_sym = ID2SYM(rb_intern("safe"));
1975
2010
  rb_gc_register_address(&oj_safe_sym);
2011
+ omit_null_byte_sym = ID2SYM(rb_intern("omit_null_byte"));
2012
+ rb_gc_register_address(&omit_null_byte_sym);
1976
2013
  oj_space_before_sym = ID2SYM(rb_intern("space_before"));
1977
2014
  rb_gc_register_address(&oj_space_before_sym);
1978
2015
  oj_space_sym = ID2SYM(rb_intern("space"));
@@ -2043,4 +2080,5 @@ void Init_oj(void) {
2043
2080
  oj_init_doc();
2044
2081
 
2045
2082
  oj_parser_init();
2083
+ oj_scanner_init();
2046
2084
  }