oj 3.10.6 → 3.12.0

Sign up to get free protection for your applications and to get access to all the features.
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 +168 -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 +78 -95
  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 +1178 -905
  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 +317 -328
  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 +45 -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;