oj 3.10.6 → 3.12.1

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 (81) hide show
  1. checksums.yaml +4 -4
  2. data/README.md +6 -1
  3. data/ext/oj/buf.h +36 -68
  4. data/ext/oj/cache8.c +59 -62
  5. data/ext/oj/cache8.h +9 -36
  6. data/ext/oj/circarray.c +36 -42
  7. data/ext/oj/circarray.h +12 -13
  8. data/ext/oj/code.c +172 -179
  9. data/ext/oj/code.h +22 -24
  10. data/ext/oj/compat.c +176 -181
  11. data/ext/oj/custom.c +800 -864
  12. data/ext/oj/dump.c +774 -776
  13. data/ext/oj/dump.h +50 -55
  14. data/ext/oj/dump_compat.c +2 -4
  15. data/ext/oj/dump_leaf.c +118 -162
  16. data/ext/oj/dump_object.c +610 -632
  17. data/ext/oj/dump_strict.c +319 -331
  18. data/ext/oj/encode.h +4 -33
  19. data/ext/oj/err.c +40 -29
  20. data/ext/oj/err.h +25 -44
  21. data/ext/oj/extconf.rb +2 -1
  22. data/ext/oj/fast.c +1054 -1081
  23. data/ext/oj/hash.c +102 -97
  24. data/ext/oj/hash.h +10 -35
  25. data/ext/oj/hash_test.c +451 -472
  26. data/ext/oj/mimic_json.c +415 -402
  27. data/ext/oj/object.c +588 -532
  28. data/ext/oj/odd.c +124 -132
  29. data/ext/oj/odd.h +28 -29
  30. data/ext/oj/oj.c +1186 -906
  31. data/ext/oj/oj.h +289 -298
  32. data/ext/oj/parse.c +946 -870
  33. data/ext/oj/parse.h +81 -79
  34. data/ext/oj/rails.c +837 -842
  35. data/ext/oj/rails.h +8 -11
  36. data/ext/oj/reader.c +139 -147
  37. data/ext/oj/reader.h +68 -84
  38. data/ext/oj/resolve.c +44 -47
  39. data/ext/oj/resolve.h +4 -6
  40. data/ext/oj/rxclass.c +69 -73
  41. data/ext/oj/rxclass.h +13 -14
  42. data/ext/oj/saj.c +453 -484
  43. data/ext/oj/scp.c +88 -113
  44. data/ext/oj/sparse.c +783 -714
  45. data/ext/oj/stream_writer.c +123 -157
  46. data/ext/oj/strict.c +133 -106
  47. data/ext/oj/string_writer.c +199 -247
  48. data/ext/oj/trace.c +34 -41
  49. data/ext/oj/trace.h +15 -15
  50. data/ext/oj/util.c +104 -104
  51. data/ext/oj/util.h +4 -3
  52. data/ext/oj/val_stack.c +48 -76
  53. data/ext/oj/val_stack.h +80 -115
  54. data/ext/oj/wab.c +321 -325
  55. data/lib/oj.rb +0 -8
  56. data/lib/oj/bag.rb +1 -0
  57. data/lib/oj/easy_hash.rb +5 -4
  58. data/lib/oj/mimic.rb +47 -13
  59. data/lib/oj/version.rb +1 -1
  60. data/pages/Modes.md +1 -0
  61. data/pages/Options.md +23 -11
  62. data/test/activerecord/result_test.rb +7 -2
  63. data/test/foo.rb +8 -40
  64. data/test/helper.rb +10 -0
  65. data/test/json_gem/json_common_interface_test.rb +8 -3
  66. data/test/json_gem/json_generator_test.rb +15 -3
  67. data/test/json_gem/test_helper.rb +8 -0
  68. data/test/perf.rb +1 -1
  69. data/test/perf_scp.rb +11 -10
  70. data/test/perf_strict.rb +17 -23
  71. data/test/prec.rb +23 -0
  72. data/test/sample_json.rb +1 -1
  73. data/test/test_compat.rb +16 -3
  74. data/test/test_custom.rb +11 -0
  75. data/test/test_fast.rb +32 -2
  76. data/test/test_generate.rb +21 -0
  77. data/test/test_hash.rb +10 -0
  78. data/test/test_rails.rb +9 -0
  79. data/test/test_scp.rb +1 -1
  80. data/test/test_various.rb +4 -2
  81. metadata +89 -85
data/ext/oj/mimic_json.c CHANGED
@@ -1,27 +1,25 @@
1
- /* mimic_json.c
2
- * Copyright (c) 2012, 2017, Peter Ohler
3
- * All rights reserved.
4
- */
1
+ // Copyright (c) 2012, 2017 Peter Ohler. All rights reserved.
2
+ // Licensed under the MIT License. See LICENSE file in the project root for license details.
5
3
 
6
- #include "oj.h"
7
- #include "encode.h"
8
4
  #include "dump.h"
5
+ #include "encode.h"
6
+ #include "oj.h"
9
7
  #include "parse.h"
10
8
 
11
- static VALUE symbolize_names_sym = Qundef;
9
+ static VALUE symbolize_names_sym = Qundef;
12
10
 
13
- extern const char oj_json_class[];
11
+ extern const char oj_json_class[];
14
12
 
15
- VALUE oj_array_nl_sym;
16
- VALUE oj_ascii_only_sym;
17
- VALUE oj_json_generator_error_class;
18
- VALUE oj_json_parser_error_class;
19
- VALUE oj_max_nesting_sym;
20
- VALUE oj_object_nl_sym;
21
- VALUE oj_space_before_sym;
22
- VALUE oj_space_sym;
13
+ VALUE oj_array_nl_sym;
14
+ VALUE oj_ascii_only_sym;
15
+ VALUE oj_json_generator_error_class;
16
+ VALUE oj_json_parser_error_class;
17
+ VALUE oj_max_nesting_sym;
18
+ VALUE oj_object_nl_sym;
19
+ VALUE oj_space_before_sym;
20
+ VALUE oj_space_sym;
23
21
 
24
- static VALUE state_class;
22
+ static VALUE state_class = Qundef;
25
23
 
26
24
  // mimic JSON documentation
27
25
 
@@ -56,14 +54,14 @@ static VALUE state_class;
56
54
 
57
55
  VALUE
58
56
  oj_get_json_err_class(const char *err_classname) {
59
- volatile VALUE json_module;
60
- volatile VALUE clas;
61
- volatile VALUE json_error_class;
57
+ volatile VALUE json_module;
58
+ volatile VALUE clas;
59
+ volatile VALUE json_error_class;
62
60
 
63
61
  if (rb_const_defined_at(rb_cObject, rb_intern("JSON"))) {
64
- json_module = rb_const_get_at(rb_cObject, rb_intern("JSON"));
62
+ json_module = rb_const_get_at(rb_cObject, rb_intern("JSON"));
65
63
  } else {
66
- json_module = rb_define_module("JSON");
64
+ json_module = rb_define_module("JSON");
67
65
  }
68
66
  if (rb_const_defined_at(json_module, rb_intern("JSONError"))) {
69
67
  json_error_class = rb_const_get(json_module, rb_intern("JSONError"));
@@ -71,113 +69,121 @@ oj_get_json_err_class(const char *err_classname) {
71
69
  json_error_class = rb_define_class_under(json_module, "JSONError", rb_eStandardError);
72
70
  }
73
71
  if (0 == strcmp(err_classname, "JSONError")) {
74
- clas = json_error_class;
72
+ clas = json_error_class;
75
73
  } else {
76
- if (rb_const_defined_at(json_module, rb_intern(err_classname))) {
77
- clas = rb_const_get(json_module, rb_intern(err_classname));
78
- } else {
79
- clas = rb_define_class_under(json_module, err_classname, json_error_class);
80
- }
74
+ if (rb_const_defined_at(json_module, rb_intern(err_classname))) {
75
+ clas = rb_const_get(json_module, rb_intern(err_classname));
76
+ } else {
77
+ clas = rb_define_class_under(json_module, err_classname, json_error_class);
78
+ }
81
79
  }
82
80
  return clas;
83
81
  }
84
82
 
85
- void
86
- oj_parse_mimic_dump_options(VALUE ropts, Options copts) {
87
- VALUE v;
88
- size_t len;
83
+ void oj_parse_mimic_dump_options(VALUE ropts, Options copts) {
84
+ VALUE v;
85
+ size_t len;
89
86
 
90
87
  if (T_HASH != rb_type(ropts)) {
91
- if (rb_respond_to(ropts, oj_to_hash_id)) {
92
- ropts = rb_funcall(ropts, oj_to_hash_id, 0);
93
- } else if (rb_respond_to(ropts, oj_to_h_id)) {
94
- ropts = rb_funcall(ropts, oj_to_h_id, 0);
95
- } else if (Qnil == ropts) {
96
- return;
97
- } else {
98
- rb_raise(rb_eArgError, "options must be a hash.");
99
- }
88
+ if (rb_respond_to(ropts, oj_to_hash_id)) {
89
+ ropts = rb_funcall(ropts, oj_to_hash_id, 0);
90
+ } else if (rb_respond_to(ropts, oj_to_h_id)) {
91
+ ropts = rb_funcall(ropts, oj_to_h_id, 0);
92
+ } else if (Qnil == ropts) {
93
+ return;
94
+ } else {
95
+ rb_raise(rb_eArgError, "options must be a hash.");
96
+ }
100
97
  }
101
98
  v = rb_hash_lookup(ropts, oj_max_nesting_sym);
102
99
  if (Qtrue == v) {
103
- copts->dump_opts.max_depth = 100;
100
+ copts->dump_opts.max_depth = 100;
104
101
  } else if (Qfalse == v || Qnil == v) {
105
- copts->dump_opts.max_depth = MAX_DEPTH;
102
+ copts->dump_opts.max_depth = MAX_DEPTH;
106
103
  } else if (T_FIXNUM == rb_type(v)) {
107
- copts->dump_opts.max_depth = NUM2INT(v);
108
- if (0 >= copts->dump_opts.max_depth) {
109
- copts->dump_opts.max_depth = MAX_DEPTH;
110
- }
104
+ copts->dump_opts.max_depth = NUM2INT(v);
105
+ if (0 >= copts->dump_opts.max_depth) {
106
+ copts->dump_opts.max_depth = MAX_DEPTH;
107
+ }
111
108
  }
112
109
  if (Qnil != (v = rb_hash_lookup(ropts, oj_allow_nan_sym))) {
113
- if (Qtrue == v) {
114
- copts->dump_opts.nan_dump = WordNan;
115
- } else {
116
- copts->dump_opts.nan_dump = RaiseNan;
117
- }
110
+ if (Qtrue == v) {
111
+ copts->dump_opts.nan_dump = WordNan;
112
+ } else {
113
+ copts->dump_opts.nan_dump = RaiseNan;
114
+ }
118
115
  }
119
116
  if (Qnil != (v = rb_hash_lookup(ropts, oj_indent_sym))) {
120
- rb_check_type(v, T_STRING);
121
- if (sizeof(copts->dump_opts.indent_str) <= (len = RSTRING_LEN(v))) {
122
- rb_raise(rb_eArgError, "indent string is limited to %lu characters.", (unsigned long)sizeof(copts->dump_opts.indent_str));
123
- }
124
- strcpy(copts->dump_opts.indent_str, StringValuePtr(v));
125
- copts->dump_opts.indent_size = (uint8_t)len;
126
- copts->dump_opts.use = true;
117
+ rb_check_type(v, T_STRING);
118
+ if (sizeof(copts->dump_opts.indent_str) <= (len = RSTRING_LEN(v))) {
119
+ rb_raise(rb_eArgError,
120
+ "indent string is limited to %lu characters.",
121
+ (unsigned long)sizeof(copts->dump_opts.indent_str));
122
+ }
123
+ strcpy(copts->dump_opts.indent_str, StringValuePtr(v));
124
+ copts->dump_opts.indent_size = (uint8_t)len;
125
+ copts->dump_opts.use = true;
127
126
  }
128
127
  if (Qnil != (v = rb_hash_lookup(ropts, oj_space_sym))) {
129
- rb_check_type(v, T_STRING);
130
- if (sizeof(copts->dump_opts.after_sep) <= (len = RSTRING_LEN(v))) {
131
- rb_raise(rb_eArgError, "space string is limited to %lu characters.", (unsigned long)sizeof(copts->dump_opts.after_sep));
132
- }
133
- strcpy(copts->dump_opts.after_sep, StringValuePtr(v));
134
- copts->dump_opts.after_size = (uint8_t)len;
135
- copts->dump_opts.use = true;
128
+ rb_check_type(v, T_STRING);
129
+ if (sizeof(copts->dump_opts.after_sep) <= (len = RSTRING_LEN(v))) {
130
+ rb_raise(rb_eArgError,
131
+ "space string is limited to %lu characters.",
132
+ (unsigned long)sizeof(copts->dump_opts.after_sep));
133
+ }
134
+ strcpy(copts->dump_opts.after_sep, StringValuePtr(v));
135
+ copts->dump_opts.after_size = (uint8_t)len;
136
+ copts->dump_opts.use = true;
136
137
  }
137
138
  if (Qnil != (v = rb_hash_lookup(ropts, oj_space_before_sym))) {
138
- rb_check_type(v, T_STRING);
139
- if (sizeof(copts->dump_opts.before_sep) <= (len = RSTRING_LEN(v))) {
140
- rb_raise(rb_eArgError, "space_before string is limited to %lu characters.", (unsigned long)sizeof(copts->dump_opts.before_sep));
141
- }
142
- strcpy(copts->dump_opts.before_sep, StringValuePtr(v));
143
- copts->dump_opts.before_size = (uint8_t)len;
144
- copts->dump_opts.use = true;
139
+ rb_check_type(v, T_STRING);
140
+ if (sizeof(copts->dump_opts.before_sep) <= (len = RSTRING_LEN(v))) {
141
+ rb_raise(rb_eArgError,
142
+ "space_before string is limited to %lu characters.",
143
+ (unsigned long)sizeof(copts->dump_opts.before_sep));
144
+ }
145
+ strcpy(copts->dump_opts.before_sep, StringValuePtr(v));
146
+ copts->dump_opts.before_size = (uint8_t)len;
147
+ copts->dump_opts.use = true;
145
148
  }
146
149
  if (Qnil != (v = rb_hash_lookup(ropts, oj_object_nl_sym))) {
147
- rb_check_type(v, T_STRING);
148
- if (sizeof(copts->dump_opts.hash_nl) <= (len = RSTRING_LEN(v))) {
149
- rb_raise(rb_eArgError, "object_nl string is limited to %lu characters.", (unsigned long)sizeof(copts->dump_opts.hash_nl));
150
- }
151
- strcpy(copts->dump_opts.hash_nl, StringValuePtr(v));
152
- copts->dump_opts.hash_size = (uint8_t)len;
153
- copts->dump_opts.use = true;
150
+ rb_check_type(v, T_STRING);
151
+ if (sizeof(copts->dump_opts.hash_nl) <= (len = RSTRING_LEN(v))) {
152
+ rb_raise(rb_eArgError,
153
+ "object_nl string is limited to %lu characters.",
154
+ (unsigned long)sizeof(copts->dump_opts.hash_nl));
155
+ }
156
+ strcpy(copts->dump_opts.hash_nl, StringValuePtr(v));
157
+ copts->dump_opts.hash_size = (uint8_t)len;
158
+ copts->dump_opts.use = true;
154
159
  }
155
160
  if (Qnil != (v = rb_hash_lookup(ropts, oj_array_nl_sym))) {
156
- rb_check_type(v, T_STRING);
157
- if (sizeof(copts->dump_opts.array_nl) <= (len = RSTRING_LEN(v))) {
158
- rb_raise(rb_eArgError, "array_nl string is limited to %lu characters.", (unsigned long)sizeof(copts->dump_opts.array_nl));
159
- }
160
- strcpy(copts->dump_opts.array_nl, StringValuePtr(v));
161
- copts->dump_opts.array_size = (uint8_t)len;
162
- copts->dump_opts.use = true;
161
+ rb_check_type(v, T_STRING);
162
+ if (sizeof(copts->dump_opts.array_nl) <= (len = RSTRING_LEN(v))) {
163
+ rb_raise(rb_eArgError,
164
+ "array_nl string is limited to %lu characters.",
165
+ (unsigned long)sizeof(copts->dump_opts.array_nl));
166
+ }
167
+ strcpy(copts->dump_opts.array_nl, StringValuePtr(v));
168
+ copts->dump_opts.array_size = (uint8_t)len;
169
+ copts->dump_opts.use = true;
163
170
  }
164
171
  if (Qnil != (v = rb_hash_lookup(ropts, oj_quirks_mode_sym))) {
165
- copts->quirks_mode = (Qtrue == v) ? Yes : No;
172
+ copts->quirks_mode = (Qtrue == v) ? Yes : No;
166
173
  }
167
174
  if (Qnil != (v = rb_hash_lookup(ropts, oj_ascii_only_sym))) {
168
- // generate seems to assume anything except nil and false are true.
169
- if (Qfalse == v) {
170
- copts->escape_mode = JXEsc;
171
- } else {
172
- copts->escape_mode = ASCIIEsc;
173
- }
175
+ // generate seems to assume anything except nil and false are true.
176
+ if (Qfalse == v) {
177
+ copts->escape_mode = JXEsc;
178
+ } else {
179
+ copts->escape_mode = ASCIIEsc;
180
+ }
174
181
  }
175
182
  }
176
183
 
177
- static int
178
- mimic_limit_arg(VALUE a) {
184
+ static int mimic_limit_arg(VALUE a) {
179
185
  if (Qnil == a || T_FIXNUM != rb_type(a)) {
180
- return -1;
186
+ return -1;
181
187
  }
182
188
  return NUM2INT(a);
183
189
  }
@@ -193,44 +199,43 @@ mimic_limit_arg(VALUE a) {
193
199
  *
194
200
  * Returns [_String_] a JSON string.
195
201
  */
196
- static VALUE
197
- mimic_dump(int argc, VALUE *argv, VALUE self) {
198
- char buf[4096];
199
- struct _out out;
200
- struct _options copts = oj_default_options;
201
- VALUE rstr;
202
- VALUE active_hack[1];
202
+ static VALUE mimic_dump(int argc, VALUE *argv, VALUE self) {
203
+ char buf[4096];
204
+ struct _out out;
205
+ struct _options copts = oj_default_options;
206
+ VALUE rstr;
207
+ VALUE active_hack[1];
203
208
 
204
209
  copts.str_rx.head = NULL;
205
210
  copts.str_rx.tail = NULL;
206
- out.buf = buf;
207
- out.end = buf + sizeof(buf) - 10;
208
- out.allocated = false;
209
- out.caller = CALLER_DUMP;
211
+ out.buf = buf;
212
+ out.end = buf + sizeof(buf) - 10;
213
+ out.allocated = false;
214
+ out.caller = CALLER_DUMP;
210
215
  copts.escape_mode = JXEsc;
211
- copts.mode = CompatMode;
216
+ copts.mode = CompatMode;
212
217
 
213
218
  /* seems like this is not correct
214
219
  if (No == copts.nilnil && Qnil == *argv) {
215
- rb_raise(rb_eTypeError, "nil not allowed.");
220
+ rb_raise(rb_eTypeError, "nil not allowed.");
216
221
  }
217
222
  */
218
- copts.dump_opts.max_depth = MAX_DEPTH; // when using dump there is no limit
219
- out.omit_nil = copts.dump_opts.omit_nil;
223
+ copts.dump_opts.max_depth = MAX_DEPTH; // when using dump there is no limit
224
+ out.omit_nil = copts.dump_opts.omit_nil;
220
225
 
221
226
  if (2 <= argc) {
222
- int limit;
223
-
224
- // The json gem take a more liberal approach to optional
225
- // arguments. Expected are (obj, anIO=nil, limit=nil) yet the io
226
- // argument can be left off completely and the 2nd argument is then
227
- // the limit.
228
- if (0 <= (limit = mimic_limit_arg(argv[1]))) {
229
- copts.dump_opts.max_depth = limit;
230
- }
231
- if (3 <= argc && 0 <= (limit = mimic_limit_arg(argv[2]))) {
232
- copts.dump_opts.max_depth = limit;
233
- }
227
+ int limit;
228
+
229
+ // The json gem take a more liberal approach to optional
230
+ // arguments. Expected are (obj, anIO=nil, limit=nil) yet the io
231
+ // argument can be left off completely and the 2nd argument is then
232
+ // the limit.
233
+ if (0 <= (limit = mimic_limit_arg(argv[1]))) {
234
+ copts.dump_opts.max_depth = limit;
235
+ }
236
+ if (3 <= argc && 0 <= (limit = mimic_limit_arg(argv[2]))) {
237
+ copts.dump_opts.max_depth = limit;
238
+ }
234
239
  }
235
240
  // ActiveSupport in active_support/core_ext/object/json.rb check the
236
241
  // optional argument type to to_json and it the argument is a
@@ -242,53 +247,48 @@ mimic_dump(int argc, VALUE *argv, VALUE self) {
242
247
  oj_dump_obj_to_json_using_params(*argv, &copts, &out, 1, active_hack);
243
248
 
244
249
  if (0 == out.buf) {
245
- rb_raise(rb_eNoMemError, "Not enough memory.");
250
+ rb_raise(rb_eNoMemError, "Not enough memory.");
246
251
  }
247
252
  rstr = rb_str_new2(out.buf);
248
253
  rstr = oj_encode(rstr);
249
254
  if (2 <= argc && Qnil != argv[1] && rb_respond_to(argv[1], oj_write_id)) {
250
- VALUE io = argv[1];
251
- VALUE args[1];
255
+ VALUE io = argv[1];
256
+ VALUE args[1];
252
257
 
253
- *args = rstr;
254
- rb_funcall2(io, oj_write_id, 1, args);
255
- rstr = io;
258
+ *args = rstr;
259
+ rb_funcall2(io, oj_write_id, 1, args);
260
+ rstr = io;
256
261
  }
257
262
  if (out.allocated) {
258
- xfree(out.buf);
263
+ xfree(out.buf);
259
264
  }
260
265
  return rstr;
261
266
  }
262
267
 
263
268
  // This is the signature for the hash_foreach callback also.
264
- static int
265
- mimic_walk(VALUE key, VALUE obj, VALUE proc) {
269
+ static int mimic_walk(VALUE key, VALUE obj, VALUE proc) {
266
270
  switch (rb_type(obj)) {
267
- case T_HASH:
268
- rb_hash_foreach(obj, mimic_walk, proc);
269
- break;
270
- case T_ARRAY:
271
- {
272
- size_t cnt = RARRAY_LEN(obj);
273
- size_t i;
274
-
275
- for (i = 0; i < cnt; i++) {
276
- mimic_walk(Qnil, rb_ary_entry(obj, i), proc);
277
- }
278
- break;
279
- }
280
- default:
281
- break;
271
+ case T_HASH: rb_hash_foreach(obj, mimic_walk, proc); break;
272
+ case T_ARRAY: {
273
+ size_t cnt = RARRAY_LEN(obj);
274
+ size_t i;
275
+
276
+ for (i = 0; i < cnt; i++) {
277
+ mimic_walk(Qnil, rb_ary_entry(obj, i), proc);
278
+ }
279
+ break;
280
+ }
281
+ default: break;
282
282
  }
283
283
  if (Qnil == proc) {
284
- if (rb_block_given_p()) {
285
- rb_yield(obj);
286
- }
284
+ if (rb_block_given_p()) {
285
+ rb_yield(obj);
286
+ }
287
287
  } else {
288
- VALUE args[1];
288
+ VALUE args[1];
289
289
 
290
- *args = obj;
291
- rb_proc_call_with_block(proc, 1, args, Qnil);
290
+ *args = obj;
291
+ rb_proc_call_with_block(proc, 1, args, Qnil);
292
292
  }
293
293
  return ST_CONTINUE;
294
294
  }
@@ -318,20 +318,19 @@ mimic_walk(VALUE key, VALUE obj, VALUE proc) {
318
318
  *
319
319
  * Returns [_Object_] the decode Object.
320
320
  */
321
- static VALUE
322
- mimic_load(int argc, VALUE *argv, VALUE self) {
323
- VALUE obj;
324
- VALUE p = Qnil;
321
+ static VALUE mimic_load(int argc, VALUE *argv, VALUE self) {
322
+ VALUE obj;
323
+ VALUE p = Qnil;
325
324
 
326
325
  obj = oj_compat_load(argc, argv, self);
327
326
  if (2 <= argc) {
328
- if (rb_cProc == rb_obj_class(argv[1])) {
329
- p = argv[1];
330
- } else if (3 <= argc) {
331
- if (rb_cProc == rb_obj_class(argv[2])) {
332
- p = argv[2];
333
- }
334
- }
327
+ if (rb_cProc == rb_obj_class(argv[1])) {
328
+ p = argv[1];
329
+ } else if (3 <= argc) {
330
+ if (rb_cProc == rb_obj_class(argv[2])) {
331
+ p = argv[2];
332
+ }
333
+ }
335
334
  }
336
335
  mimic_walk(Qnil, obj, p);
337
336
 
@@ -349,54 +348,60 @@ mimic_load(int argc, VALUE *argv, VALUE self) {
349
348
  *
350
349
  * Returns [_Object_]
351
350
  */
352
- static VALUE
353
- mimic_dump_load(int argc, VALUE *argv, VALUE self) {
351
+ static VALUE mimic_dump_load(int argc, VALUE *argv, VALUE self) {
354
352
  if (1 > argc) {
355
- rb_raise(rb_eArgError, "wrong number of arguments (0 for 1)");
353
+ rb_raise(rb_eArgError, "wrong number of arguments (0 for 1)");
356
354
  } else if (T_STRING == rb_type(*argv)) {
357
- return mimic_load(argc, argv, self);
355
+ return mimic_load(argc, argv, self);
358
356
  } else {
359
- return mimic_dump(argc, argv, self);
357
+ return mimic_dump(argc, argv, self);
360
358
  }
361
359
  return Qnil;
362
360
  }
363
361
 
364
- static VALUE
365
- mimic_generate_core(int argc, VALUE *argv, Options copts) {
366
- char buf[4096];
367
- struct _out out;
368
- VALUE rstr;
362
+ static VALUE mimic_generate_core(int argc, VALUE *argv, Options copts) {
363
+ char buf[4096];
364
+ struct _out out;
365
+ VALUE rstr;
369
366
 
370
- // TBD
371
367
  memset(buf, 0, sizeof(buf));
372
368
 
373
- out.buf = buf;
374
- out.end = buf + sizeof(buf) - 10;
369
+ out.buf = buf;
370
+ out.end = buf + sizeof(buf) - 10;
375
371
  out.allocated = false;
376
- out.omit_nil = copts->dump_opts.omit_nil;
377
- out.caller = CALLER_GENERATE;
372
+ out.omit_nil = copts->dump_opts.omit_nil;
373
+ out.caller = CALLER_GENERATE;
378
374
  // For obj.to_json or generate nan is not allowed but if called from dump
379
375
  // it is.
380
376
  copts->dump_opts.nan_dump = RaiseNan;
381
- copts->mode = CompatMode;
382
- copts->to_json = Yes;
377
+ copts->mode = CompatMode;
378
+ copts->to_json = Yes;
383
379
  if (2 == argc && Qnil != argv[1]) {
384
- oj_parse_mimic_dump_options(argv[1], copts);
380
+ oj_parse_mimic_dump_options(argv[1], copts);
385
381
  }
386
382
  /* seems like this is not correct
387
383
  if (No == copts->nilnil && Qnil == *argv) {
388
- rb_raise(rb_eTypeError, "nil not allowed.");
384
+ rb_raise(rb_eTypeError, "nil not allowed.");
389
385
  }
390
386
  */
391
- oj_dump_obj_to_json_using_params(*argv, copts, &out, argc - 1, argv + 1);
387
+ if (1 < argc) {
388
+ oj_dump_obj_to_json_using_params(*argv, copts, &out, argc - 1, argv + 1);
389
+ } else {
390
+ VALUE active_hack[1];
392
391
 
392
+ if (Qundef == state_class) {
393
+ oj_define_mimic_json(0, NULL, Qnil);
394
+ }
395
+ active_hack[0] = rb_funcall(state_class, oj_new_id, 0);
396
+ oj_dump_obj_to_json_using_params(*argv, copts, &out, 1, active_hack);
397
+ }
393
398
  if (0 == out.buf) {
394
- rb_raise(rb_eNoMemError, "Not enough memory.");
399
+ rb_raise(rb_eNoMemError, "Not enough memory.");
395
400
  }
396
401
  rstr = rb_str_new2(out.buf);
397
402
  rstr = oj_encode(rstr);
398
403
  if (out.allocated) {
399
- xfree(out.buf);
404
+ xfree(out.buf);
400
405
  }
401
406
  return rstr;
402
407
  }
@@ -421,13 +426,14 @@ mimic_generate_core(int argc, VALUE *argv, Options copts) {
421
426
  * - *:space_before* [_String_] String placed before a : delimiter
422
427
  * - *:object_nl* [_String_] String placed after a JSON object
423
428
  * - *:array_nl* [_String_] String placed after a JSON array
424
- * - *:ascii_only* [_Boolean_] if not nil or false then use only ascii characters in the output. Note JSON.generate does support this even if it is not documented.
429
+ * - *:ascii_only* [_Boolean_] if not nil or false then use only ascii characters in the output.
430
+ * Note JSON.generate does support this even if it is not documented.
425
431
  *
426
432
  * Returns [_String_] generated JSON.
427
433
  */
428
434
  VALUE
429
435
  oj_mimic_generate(int argc, VALUE *argv, VALUE self) {
430
- struct _options copts = oj_default_options;
436
+ struct _options copts = oj_default_options;
431
437
 
432
438
  copts.str_rx.head = NULL;
433
439
  copts.str_rx.tail = NULL;
@@ -445,33 +451,36 @@ oj_mimic_generate(int argc, VALUE *argv, VALUE self) {
445
451
  */
446
452
  VALUE
447
453
  oj_mimic_pretty_generate(int argc, VALUE *argv, VALUE self) {
448
- struct _options copts = oj_default_options;
449
- VALUE rargs[2];
450
- volatile VALUE h;
454
+ struct _options copts = oj_default_options;
455
+ VALUE rargs[2];
456
+ volatile VALUE h;
451
457
 
452
458
  // Some (all?) json gem to_json methods need a State instance and not just
453
459
  // a Hash. I haven't dug deep enough to find out why but using a State
454
460
  // instance and not a Hash gives the desired behavior.
455
461
  *rargs = *argv;
456
462
  if (1 == argc) {
457
- h = rb_hash_new();
463
+ h = rb_hash_new();
458
464
  } else {
459
- h = argv[1];
465
+ h = argv[1];
460
466
  }
461
467
  if (Qfalse == rb_funcall(h, oj_has_key_id, 1, oj_indent_sym)) {
462
- rb_hash_aset(h, oj_indent_sym, rb_str_new2(" "));
468
+ rb_hash_aset(h, oj_indent_sym, rb_str_new2(" "));
463
469
  }
464
470
  if (Qfalse == rb_funcall(h, oj_has_key_id, 1, oj_space_before_sym)) {
465
- rb_hash_aset(h, oj_space_before_sym, rb_str_new2(""));
471
+ rb_hash_aset(h, oj_space_before_sym, rb_str_new2(""));
466
472
  }
467
473
  if (Qfalse == rb_funcall(h, oj_has_key_id, 1, oj_space_sym)) {
468
- rb_hash_aset(h, oj_space_sym, rb_str_new2(" "));
474
+ rb_hash_aset(h, oj_space_sym, rb_str_new2(" "));
469
475
  }
470
476
  if (Qfalse == rb_funcall(h, oj_has_key_id, 1, oj_object_nl_sym)) {
471
- rb_hash_aset(h, oj_object_nl_sym, rb_str_new2("\n"));
477
+ rb_hash_aset(h, oj_object_nl_sym, rb_str_new2("\n"));
472
478
  }
473
479
  if (Qfalse == rb_funcall(h, oj_has_key_id, 1, oj_array_nl_sym)) {
474
- rb_hash_aset(h, oj_array_nl_sym, rb_str_new2("\n"));
480
+ rb_hash_aset(h, oj_array_nl_sym, rb_str_new2("\n"));
481
+ }
482
+ if (Qundef == state_class) {
483
+ oj_define_mimic_json(0, NULL, Qnil);
475
484
  }
476
485
  rargs[1] = rb_funcall(state_class, oj_new_id, 1, h);
477
486
 
@@ -487,101 +496,105 @@ oj_mimic_pretty_generate(int argc, VALUE *argv, VALUE self) {
487
496
  copts.dump_opts.hash_size = (uint8_t)strlen(copts.dump_opts.hash_nl);
488
497
  strcpy(copts.dump_opts.array_nl, "\n");
489
498
  copts.dump_opts.array_size = (uint8_t)strlen(copts.dump_opts.array_nl);
490
- copts.dump_opts.use = true;
499
+ copts.dump_opts.use = true;
491
500
 
492
501
  return mimic_generate_core(2, rargs, &copts);
493
502
  }
494
503
 
495
- static VALUE
496
- mimic_parse_core(int argc, VALUE *argv, VALUE self, bool bang) {
497
- struct _parseInfo pi;
498
- VALUE ropts;
499
- VALUE args[1];
504
+ static VALUE mimic_parse_core(int argc, VALUE *argv, VALUE self, bool bang) {
505
+ struct _parseInfo pi;
506
+ VALUE ropts;
507
+ VALUE args[1];
500
508
 
501
509
  rb_scan_args(argc, argv, "11", NULL, &ropts);
502
510
  parse_info_init(&pi);
503
511
  oj_set_compat_callbacks(&pi);
504
512
 
505
513
  pi.err_class = oj_json_parser_error_class;
506
- //pi.err_class = Qnil;
514
+ // pi.err_class = Qnil;
507
515
 
508
- pi.options = oj_default_options;
509
- pi.options.auto_define = No;
510
- pi.options.quirks_mode = Yes;
516
+ pi.options = oj_default_options;
517
+ pi.options.auto_define = No;
518
+ pi.options.quirks_mode = Yes;
511
519
  pi.options.allow_invalid = No;
512
- pi.options.empty_string = No;
513
- pi.options.create_ok = No;
514
- pi.options.allow_nan = (bang ? Yes : No);
515
- pi.options.nilnil = No;
516
- pi.options.bigdec_load = FloatDec;
517
- pi.options.mode = CompatMode;
518
- pi.max_depth = 100;
520
+ pi.options.empty_string = No;
521
+ pi.options.create_ok = No;
522
+ pi.options.allow_nan = (bang ? Yes : No);
523
+ pi.options.nilnil = No;
524
+ pi.options.bigdec_load = RubyDec;
525
+ pi.options.mode = CompatMode;
526
+ pi.max_depth = 100;
519
527
 
520
528
  if (Qnil != ropts) {
521
- VALUE v;
522
-
523
- if (T_HASH != rb_type(ropts)) {
524
- rb_raise(rb_eArgError, "options must be a hash.");
525
- }
526
- if (Qundef == symbolize_names_sym) {
527
- symbolize_names_sym = ID2SYM(rb_intern("symbolize_names")); rb_gc_register_address(&symbolize_names_sym);
528
- }
529
- if (Qnil != (v = rb_hash_lookup(ropts, symbolize_names_sym))) {
530
- pi.options.sym_key = (Qtrue == v) ? Yes : No;
531
- }
532
- if (Qnil != (v = rb_hash_lookup(ropts, oj_quirks_mode_sym))) {
533
- pi.options.quirks_mode = (Qtrue == v) ? Yes : No;
534
- }
535
- if (Qnil != (v = rb_hash_lookup(ropts, oj_create_additions_sym))) {
536
- pi.options.create_ok = (Qtrue == v) ? Yes : No;
537
- }
538
- if (Qnil != (v = rb_hash_lookup(ropts, oj_allow_nan_sym))) {
539
- pi.options.allow_nan = (Qtrue == v) ? Yes : No;
540
- }
541
-
542
- if (Qtrue == rb_funcall(ropts, oj_has_key_id, 1, oj_hash_class_sym)) {
543
- if (Qnil == (v = rb_hash_lookup(ropts, oj_hash_class_sym))) {
544
- pi.options.hash_class = Qnil;
545
- } else {
546
- rb_check_type(v, T_CLASS);
547
- pi.options.hash_class = v;
548
- }
549
- }
550
- if (Qtrue == rb_funcall(ropts, oj_has_key_id, 1, oj_object_class_sym)) {
551
- if (Qnil == (v = rb_hash_lookup(ropts, oj_object_class_sym))) {
552
- pi.options.hash_class = Qnil;
553
- } else {
554
- rb_check_type(v, T_CLASS);
555
- pi.options.hash_class = v;
556
- }
557
- }
558
- if (Qtrue == rb_funcall(ropts, oj_has_key_id, 1, oj_array_class_sym)) {
559
- if (Qnil == (v = rb_hash_lookup(ropts, oj_array_class_sym))) {
560
- pi.options.array_class = Qnil;
561
- } else {
562
- rb_check_type(v, T_CLASS);
563
- pi.options.array_class = v;
564
- }
565
- }
566
- v = rb_hash_lookup(ropts, oj_max_nesting_sym);
567
- if (Qtrue == v) {
568
- pi.max_depth = 100;
569
- } else if (Qfalse == v || Qnil == v) {
570
- pi.max_depth = 0;
571
- } else if (T_FIXNUM == rb_type(v)) {
572
- pi.max_depth = NUM2INT(v);
573
- }
574
- oj_parse_opt_match_string(&pi.options.str_rx, ropts);
575
- if (Yes == pi.options.create_ok && Yes == pi.options.sym_key) {
576
- rb_raise(rb_eArgError, ":symbolize_names and :create_additions can not both be true.");
577
- }
529
+ VALUE v;
530
+
531
+ if (T_HASH != rb_type(ropts)) {
532
+ rb_raise(rb_eArgError, "options must be a hash.");
533
+ }
534
+ if (Qundef == symbolize_names_sym) {
535
+ symbolize_names_sym = ID2SYM(rb_intern("symbolize_names"));
536
+ rb_gc_register_address(&symbolize_names_sym);
537
+ }
538
+ if (Qnil != (v = rb_hash_lookup(ropts, symbolize_names_sym))) {
539
+ pi.options.sym_key = (Qtrue == v) ? Yes : No;
540
+ }
541
+ if (Qnil != (v = rb_hash_lookup(ropts, oj_quirks_mode_sym))) {
542
+ pi.options.quirks_mode = (Qtrue == v) ? Yes : No;
543
+ }
544
+ if (Qnil != (v = rb_hash_lookup(ropts, oj_create_additions_sym))) {
545
+ pi.options.create_ok = (Qtrue == v) ? Yes : No;
546
+ }
547
+ if (Qnil != (v = rb_hash_lookup(ropts, oj_allow_nan_sym))) {
548
+ pi.options.allow_nan = (Qtrue == v) ? Yes : No;
549
+ }
550
+
551
+ if (Qtrue == rb_funcall(ropts, oj_has_key_id, 1, oj_hash_class_sym)) {
552
+ if (Qnil == (v = rb_hash_lookup(ropts, oj_hash_class_sym))) {
553
+ pi.options.hash_class = Qnil;
554
+ } else {
555
+ rb_check_type(v, T_CLASS);
556
+ pi.options.hash_class = v;
557
+ }
558
+ }
559
+ if (Qtrue == rb_funcall(ropts, oj_has_key_id, 1, oj_object_class_sym)) {
560
+ if (Qnil == (v = rb_hash_lookup(ropts, oj_object_class_sym))) {
561
+ pi.options.hash_class = Qnil;
562
+ } else {
563
+ rb_check_type(v, T_CLASS);
564
+ pi.options.hash_class = v;
565
+ }
566
+ }
567
+ if (Qtrue == rb_funcall(ropts, oj_has_key_id, 1, oj_array_class_sym)) {
568
+ if (Qnil == (v = rb_hash_lookup(ropts, oj_array_class_sym))) {
569
+ pi.options.array_class = Qnil;
570
+ } else {
571
+ rb_check_type(v, T_CLASS);
572
+ pi.options.array_class = v;
573
+ }
574
+ }
575
+ if (Qtrue == rb_funcall(ropts, oj_has_key_id, 1, oj_decimal_class_sym)) {
576
+ pi.options.compat_bigdec = (oj_bigdecimal_class ==
577
+ rb_hash_lookup(ropts, oj_decimal_class_sym));
578
+ }
579
+ v = rb_hash_lookup(ropts, oj_max_nesting_sym);
580
+ if (Qtrue == v) {
581
+ pi.max_depth = 100;
582
+ } else if (Qfalse == v || Qnil == v) {
583
+ pi.max_depth = 0;
584
+ } else if (T_FIXNUM == rb_type(v)) {
585
+ pi.max_depth = NUM2INT(v);
586
+ }
587
+ oj_parse_opt_match_string(&pi.options.str_rx, ropts);
588
+ if (Yes == pi.options.create_ok && Yes == pi.options.sym_key) {
589
+ rb_raise(rb_eArgError, ":symbolize_names and :create_additions can not both be true.");
590
+ }
578
591
  }
579
592
  *args = *argv;
580
593
 
581
594
  if (T_STRING == rb_type(*args)) {
582
- return oj_pi_parse(1, args, &pi, 0, 0, false);
595
+ return oj_pi_parse(1, args, &pi, 0, 0, false);
583
596
  } else {
584
- return oj_pi_sparse(1, args, &pi, 0);
597
+ return oj_pi_sparse(1, args, &pi, 0);
585
598
  }
586
599
  }
587
600
 
@@ -594,8 +607,10 @@ mimic_parse_core(int argc, VALUE *argv, VALUE self, bool bang) {
594
607
  *
595
608
  * - *source* [_String_|IO] source to parse
596
609
  * - *opts* [_Hash_] options
597
- * - *:symbolize* [Boolean] _names flag indicating JSON object keys should be Symbols instead of Strings
598
- * - *:create_additions* [Boolean] flag indicating a key matching +create_id+ in a JSON object should trigger the creation of Ruby Object
610
+ * - *:symbolize* [Boolean] _names flag indicating JSON object keys should be Symbols instead of
611
+ * Strings
612
+ * - *:create_additions* [Boolean] flag indicating a key matching +create_id+ in a JSON object
613
+ * should trigger the creation of Ruby Object
599
614
  *
600
615
  * Returns [Object]
601
616
  * @see create_id=
@@ -611,8 +626,7 @@ oj_mimic_parse(int argc, VALUE *argv, VALUE self) {
611
626
  * Same as parse().
612
627
  * @see parse
613
628
  */
614
- static VALUE
615
- mimic_parse_bang(int argc, VALUE *argv, VALUE self) {
629
+ static VALUE mimic_parse_bang(int argc, VALUE *argv, VALUE self) {
616
630
  return mimic_parse_core(argc, argv, self, true);
617
631
  }
618
632
 
@@ -624,8 +638,7 @@ mimic_parse_bang(int argc, VALUE *argv, VALUE self) {
624
638
  * - *obj* [_Hash_|Array] object to walk
625
639
  * - *proc* [_Proc_] to yield to on each element
626
640
  */
627
- static VALUE
628
- mimic_recurse_proc(VALUE self, VALUE obj) {
641
+ static VALUE mimic_recurse_proc(VALUE self, VALUE obj) {
629
642
  rb_need_block();
630
643
  mimic_walk(Qnil, obj, Qnil);
631
644
 
@@ -642,23 +655,22 @@ mimic_recurse_proc(VALUE self, VALUE obj) {
642
655
  *
643
656
  * Returns [_String_] the id.
644
657
  */
645
- static VALUE
646
- mimic_set_create_id(VALUE self, VALUE id) {
658
+ static VALUE mimic_set_create_id(VALUE self, VALUE id) {
647
659
  Check_Type(id, T_STRING);
648
660
 
649
661
  if (NULL != oj_default_options.create_id) {
650
- if (oj_json_class != oj_default_options.create_id) {
651
- xfree((char*)oj_default_options.create_id);
652
- }
653
- oj_default_options.create_id = NULL;
654
- oj_default_options.create_id_len = 0;
662
+ if (oj_json_class != oj_default_options.create_id) {
663
+ xfree((char *)oj_default_options.create_id);
664
+ }
665
+ oj_default_options.create_id = NULL;
666
+ oj_default_options.create_id_len = 0;
655
667
  }
656
668
  if (Qnil != id) {
657
- size_t len = RSTRING_LEN(id) + 1;
669
+ size_t len = RSTRING_LEN(id) + 1;
658
670
 
659
- oj_default_options.create_id = ALLOC_N(char, len);
660
- strcpy((char*)oj_default_options.create_id, StringValuePtr(id));
661
- oj_default_options.create_id_len = len - 1;
671
+ oj_default_options.create_id = ALLOC_N(char, len);
672
+ strcpy((char *)oj_default_options.create_id, StringValuePtr(id));
673
+ oj_default_options.create_id_len = len - 1;
662
674
  }
663
675
  return id;
664
676
  }
@@ -668,101 +680,102 @@ mimic_set_create_id(VALUE self, VALUE id) {
668
680
  *
669
681
  * Returns [_String_] the create_id.
670
682
  */
671
- static VALUE
672
- mimic_create_id(VALUE self) {
683
+ static VALUE mimic_create_id(VALUE self) {
673
684
  if (NULL != oj_default_options.create_id) {
674
- return oj_encode(rb_str_new_cstr(oj_default_options.create_id));
685
+ return oj_encode(rb_str_new_cstr(oj_default_options.create_id));
675
686
  }
676
687
  return rb_str_new_cstr(oj_json_class);
677
688
  }
678
689
 
679
- static struct _options mimic_object_to_json_options = {
680
- 0, // indent
681
- No, // circular
682
- No, // auto_define
683
- No, // sym_key
684
- JXEsc, // escape_mode
685
- CompatMode, // mode
686
- No, // class_cache
687
- RubyTime, // time_format
688
- No, // bigdec_as_num
689
- FloatDec, // bigdec_load
690
- No, // to_hash
691
- No, // to_json
692
- No, // as_json
693
- No, // raw_json
694
- No, // nilnil
695
- No, // empty_string
696
- Yes, // allow_gc
697
- Yes, // quirks_mode
698
- No, // allow_invalid
699
- No, // create_ok
700
- No, // allow_nan
701
- No, // trace
702
- No, // safe
703
- false, // sec_prec_set
704
- No, // ignore_under
705
- 0, // int_range_min
706
- 0, // int_range_max
707
- oj_json_class,// create_id
708
- 10, // create_id_len
709
- 3, // sec_prec
710
- 16, // float_prec
711
- "%0.16g", // float_fmt
712
- Qnil, // hash_class
713
- Qnil, // array_class
714
- { // dump_opts
715
- false, //use
716
- "", // indent
717
- "", // before_sep
718
- "", // after_sep
719
- "", // hash_nl
720
- "", // array_nl
721
- 0, // indent_size
722
- 0, // before_size
723
- 0, // after_size
724
- 0, // hash_size
725
- 0, // array_size
726
- RaiseNan,// nan_dump
727
- false, // omit_nil
728
- 100, // max_depth
729
- },
730
- { // str_rx
731
- NULL, // head
732
- NULL, // tail
733
- { '\0' }, // err
734
- }
735
- };
736
-
737
- static VALUE
738
- mimic_object_to_json(int argc, VALUE *argv, VALUE self) {
739
- char buf[4096];
740
- struct _out out;
741
- VALUE rstr;
742
- struct _options copts = oj_default_options;
690
+ static struct _options mimic_object_to_json_options = {0, // indent
691
+ No, // circular
692
+ No, // auto_define
693
+ No, // sym_key
694
+ JXEsc, // escape_mode
695
+ CompatMode, // mode
696
+ No, // class_cache
697
+ RubyTime, // time_format
698
+ No, // bigdec_as_num
699
+ RubyDec, // bigdec_load
700
+ false, // compat_bigdec
701
+ No, // to_hash
702
+ No, // to_json
703
+ No, // as_json
704
+ No, // raw_json
705
+ No, // nilnil
706
+ No, // empty_string
707
+ Yes, // allow_gc
708
+ Yes, // quirks_mode
709
+ No, // allow_invalid
710
+ No, // create_ok
711
+ No, // allow_nan
712
+ No, // trace
713
+ No, // safe
714
+ false, // sec_prec_set
715
+ No, // ignore_under
716
+ Yes, // cache_keys
717
+ 3, // cache_str
718
+ 0, // int_range_min
719
+ 0, // int_range_max
720
+ oj_json_class, // create_id
721
+ 10, // create_id_len
722
+ 3, // sec_prec
723
+ 0, // float_prec
724
+ "%0.16g", // float_fmt
725
+ Qnil, // hash_class
726
+ Qnil, // array_class
727
+ {
728
+ // dump_opts
729
+ false, // use
730
+ "", // indent
731
+ "", // before_sep
732
+ "", // after_sep
733
+ "", // hash_nl
734
+ "", // array_nl
735
+ 0, // indent_size
736
+ 0, // before_size
737
+ 0, // after_size
738
+ 0, // hash_size
739
+ 0, // array_size
740
+ RaiseNan, // nan_dump
741
+ false, // omit_nil
742
+ 100, // max_depth
743
+ },
744
+ {
745
+ // str_rx
746
+ NULL, // head
747
+ NULL, // tail
748
+ {'\0'}, // err
749
+ }};
750
+
751
+ static VALUE mimic_object_to_json(int argc, VALUE *argv, VALUE self) {
752
+ char buf[4096];
753
+ struct _out out;
754
+ VALUE rstr;
755
+ struct _options copts = oj_default_options;
743
756
 
744
757
  copts.str_rx.head = NULL;
745
758
  copts.str_rx.tail = NULL;
746
- out.buf = buf;
747
- out.end = buf + sizeof(buf) - 10;
748
- out.allocated = false;
749
- out.omit_nil = copts.dump_opts.omit_nil;
750
- copts.mode = CompatMode;
751
- copts.to_json = No;
759
+ out.buf = buf;
760
+ out.end = buf + sizeof(buf) - 10;
761
+ out.allocated = false;
762
+ out.omit_nil = copts.dump_opts.omit_nil;
763
+ copts.mode = CompatMode;
764
+ copts.to_json = No;
752
765
  if (1 <= argc && Qnil != argv[0]) {
753
- oj_parse_mimic_dump_options(argv[0], &copts);
766
+ oj_parse_mimic_dump_options(argv[0], &copts);
754
767
  }
755
768
  // To be strict the mimic_object_to_json_options should be used but people
756
769
  // seem to prefer the option of changing that.
757
- //oj_dump_obj_to_json(self, &mimic_object_to_json_options, &out);
770
+ // oj_dump_obj_to_json(self, &mimic_object_to_json_options, &out);
758
771
  oj_dump_obj_to_json_using_params(self, &copts, &out, argc, argv);
759
- if (0 == out.buf) {
760
- rb_raise(rb_eNoMemError, "Not enough memory.");
772
+ if (NULL == out.buf) {
773
+ rb_raise(rb_eNoMemError, "Not enough memory.");
761
774
  }
762
775
  rstr = rb_str_new2(out.buf);
763
776
  rstr = oj_encode(rstr);
764
777
  if (out.allocated) {
765
- xfree(out.buf);
778
+ xfree(out.buf);
766
779
  }
767
780
  return rstr;
768
781
  }
@@ -772,16 +785,14 @@ mimic_object_to_json(int argc, VALUE *argv, VALUE self) {
772
785
  *
773
786
  * Returns [_JSON::State_] the JSON::State class.
774
787
  */
775
- static VALUE
776
- mimic_state(VALUE self) {
788
+ static VALUE mimic_state(VALUE self) {
777
789
  return state_class;
778
790
  }
779
791
 
780
- void
781
- oj_mimic_json_methods(VALUE json) {
782
- VALUE json_error;
783
- VALUE generator;
784
- VALUE ext;
792
+ void oj_mimic_json_methods(VALUE json) {
793
+ VALUE json_error;
794
+ VALUE generator;
795
+ VALUE ext;
785
796
 
786
797
  rb_define_module_function(json, "create_id=", mimic_set_create_id, 1);
787
798
  rb_define_module_function(json, "create_id", mimic_create_id, 0);
@@ -813,36 +824,38 @@ oj_mimic_json_methods(VALUE json) {
813
824
  if (rb_const_defined_at(json, rb_intern("ParserError"))) {
814
825
  oj_json_parser_error_class = rb_const_get(json, rb_intern("ParserError"));
815
826
  } else {
816
- oj_json_parser_error_class = rb_define_class_under(json, "ParserError", json_error);
827
+ oj_json_parser_error_class = rb_define_class_under(json, "ParserError", json_error);
817
828
  }
818
829
  if (rb_const_defined_at(json, rb_intern("GeneratorError"))) {
819
830
  oj_json_generator_error_class = rb_const_get(json, rb_intern("GeneratorError"));
820
831
  } else {
821
- oj_json_generator_error_class = rb_define_class_under(json, "GeneratorError", json_error);
832
+ oj_json_generator_error_class = rb_define_class_under(json, "GeneratorError", json_error);
822
833
  }
823
834
  if (rb_const_defined_at(json, rb_intern("NestingError"))) {
824
835
  rb_const_get(json, rb_intern("NestingError"));
825
836
  } else {
826
- rb_define_class_under(json, "NestingError", json_error);
837
+ rb_define_class_under(json, "NestingError", json_error);
827
838
  }
828
839
 
829
840
  if (rb_const_defined_at(json, rb_intern("Ext"))) {
830
- ext = rb_const_get_at(json, rb_intern("Ext"));
831
- } else {
832
- ext = rb_define_module_under(json, "Ext");
841
+ ext = rb_const_get_at(json, rb_intern("Ext"));
842
+ } else {
843
+ ext = rb_define_module_under(json, "Ext");
833
844
  }
834
845
  if (rb_const_defined_at(ext, rb_intern("Generator"))) {
835
- generator = rb_const_get_at(ext, rb_intern("Generator"));
836
- } else {
837
- generator = rb_define_module_under(ext, "Generator");
846
+ generator = rb_const_get_at(ext, rb_intern("Generator"));
847
+ } else {
848
+ generator = rb_define_module_under(ext, "Generator");
838
849
  }
839
850
  if (!rb_const_defined_at(generator, rb_intern("State"))) {
840
- rb_require("oj/state");
851
+ rb_require("oj/state");
841
852
  }
842
853
  // Pull in the JSON::State mimic file.
843
854
  state_class = rb_const_get_at(generator, rb_intern("State"));
855
+ rb_gc_register_mark_object(state_class);
844
856
 
845
- symbolize_names_sym = ID2SYM(rb_intern("symbolize_names")); rb_gc_register_address(&symbolize_names_sym);
857
+ symbolize_names_sym = ID2SYM(rb_intern("symbolize_names"));
858
+ rb_gc_register_address(&symbolize_names_sym);
846
859
  }
847
860
 
848
861
  /* Document-module: JSON
@@ -851,31 +864,31 @@ oj_mimic_json_methods(VALUE json) {
851
864
  */
852
865
  VALUE
853
866
  oj_define_mimic_json(int argc, VALUE *argv, VALUE self) {
854
- VALUE dummy;
855
- VALUE verbose;
856
- VALUE json;
867
+ VALUE dummy;
868
+ VALUE verbose;
869
+ VALUE json;
857
870
 
858
871
  // Either set the paths to indicate JSON has been loaded or replaces the
859
872
  // methods if it has been loaded.
860
873
  if (rb_const_defined_at(rb_cObject, rb_intern("JSON"))) {
861
- json = rb_const_get_at(rb_cObject, rb_intern("JSON"));
874
+ json = rb_const_get_at(rb_cObject, rb_intern("JSON"));
862
875
  } else {
863
- json = rb_define_module("JSON");
876
+ json = rb_define_module("JSON");
864
877
  }
865
878
  verbose = rb_gv_get("$VERBOSE");
866
879
  rb_gv_set("$VERBOSE", Qfalse);
867
880
  rb_define_module_function(rb_cObject, "JSON", mimic_dump_load, -1);
868
881
  dummy = rb_gv_get("$LOADED_FEATURES");
869
882
  if (rb_type(dummy) == T_ARRAY) {
870
- rb_ary_push(dummy, rb_str_new2("json"));
871
- if (0 < argc) {
872
- VALUE mimic_args[1];
883
+ rb_ary_push(dummy, rb_str_new2("json"));
884
+ if (0 < argc) {
885
+ VALUE mimic_args[1];
873
886
 
874
- *mimic_args = *argv;
875
- rb_funcall2(Oj, rb_intern("mimic_loaded"), 1, mimic_args);
876
- } else {
877
- rb_funcall2(Oj, rb_intern("mimic_loaded"), 0, 0);
878
- }
887
+ *mimic_args = *argv;
888
+ rb_funcall2(Oj, rb_intern("mimic_loaded"), 1, mimic_args);
889
+ } else {
890
+ rb_funcall2(Oj, rb_intern("mimic_loaded"), 0, 0);
891
+ }
879
892
  }
880
893
  oj_mimic_json_methods(json);
881
894
 
@@ -883,7 +896,7 @@ oj_define_mimic_json(int argc, VALUE *argv, VALUE self) {
883
896
 
884
897
  rb_gv_set("$VERBOSE", verbose);
885
898
 
886
- oj_default_options = mimic_object_to_json_options;
899
+ oj_default_options = mimic_object_to_json_options;
887
900
  oj_default_options.to_json = Yes;
888
901
 
889
902
  return json;