oj 3.10.6 → 3.12.0

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 +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/dump.c CHANGED
@@ -1,7 +1,7 @@
1
- /* dump.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.
3
+
4
+ #include "dump.h"
5
5
 
6
6
  #include <errno.h>
7
7
  #include <math.h>
@@ -11,32 +11,31 @@
11
11
  #include <string.h>
12
12
  #include <unistd.h>
13
13
 
14
- #include "oj.h"
15
14
  #include "cache8.h"
16
- #include "dump.h"
17
15
  #include "odd.h"
16
+ #include "oj.h"
18
17
  #include "trace.h"
19
18
  #include "util.h"
20
19
 
21
20
  // Workaround in case INFINITY is not defined in math.h or if the OS is CentOS
22
- #define OJ_INFINITY (1.0/0.0)
21
+ #define OJ_INFINITY (1.0 / 0.0)
23
22
 
24
23
  #define MAX_DEPTH 1000
25
24
 
26
- static const char inf_val[] = INF_VAL;
27
- static const char ninf_val[] = NINF_VAL;
28
- static const char nan_val[] = NAN_VAL;
25
+ static const char inf_val[] = INF_VAL;
26
+ static const char ninf_val[] = NINF_VAL;
27
+ static const char nan_val[] = NAN_VAL;
29
28
 
30
- typedef unsigned long ulong;
29
+ typedef unsigned long ulong;
31
30
 
32
- static size_t hibit_friendly_size(const uint8_t *str, size_t len);
33
- static size_t xss_friendly_size(const uint8_t *str, size_t len);
34
- static size_t ascii_friendly_size(const uint8_t *str, size_t len);
31
+ static size_t hibit_friendly_size(const uint8_t *str, size_t len);
32
+ static size_t xss_friendly_size(const uint8_t *str, size_t len);
33
+ static size_t ascii_friendly_size(const uint8_t *str, size_t len);
35
34
 
36
- static const char hex_chars[17] = "0123456789abcdef";
35
+ static const char hex_chars[17] = "0123456789abcdef";
37
36
 
38
37
  // JSON standard except newlines are no escaped
39
- static char newline_friendly_chars[256] = "\
38
+ static char newline_friendly_chars[256] = "\
40
39
  66666666221622666666666666666666\
41
40
  11211111111111111111111111111111\
42
41
  11111111111111111111111111112111\
@@ -47,7 +46,7 @@ static char newline_friendly_chars[256] = "\
47
46
  11111111111111111111111111111111";
48
47
 
49
48
  // JSON standard
50
- static char hibit_friendly_chars[256] = "\
49
+ static char hibit_friendly_chars[256] = "\
51
50
  66666666222622666666666666666666\
52
51
  11211111111111111111111111111111\
53
52
  11111111111111111111111111112111\
@@ -59,7 +58,7 @@ static char hibit_friendly_chars[256] = "\
59
58
 
60
59
  // High bit set characters are always encoded as unicode. Worse case is 3
61
60
  // bytes per character in the output. That makes this conservative.
62
- static char ascii_friendly_chars[256] = "\
61
+ static char ascii_friendly_chars[256] = "\
63
62
  66666666222622666666666666666666\
64
63
  11211111111111111111111111111111\
65
64
  11111111111111111111111111112111\
@@ -70,7 +69,7 @@ static char ascii_friendly_chars[256] = "\
70
69
  33333333333333333333333333333333";
71
70
 
72
71
  // XSS safe mode
73
- static char xss_friendly_chars[256] = "\
72
+ static char xss_friendly_chars[256] = "\
74
73
  66666666222622666666666666666666\
75
74
  11211161111111121111111111116161\
76
75
  11111111111111111111111111112111\
@@ -81,7 +80,7 @@ static char xss_friendly_chars[256] = "\
81
80
  33333333333333333333333333333333";
82
81
 
83
82
  // JSON XSS combo
84
- static char hixss_friendly_chars[256] = "\
83
+ static char hixss_friendly_chars[256] = "\
85
84
  66666666222622666666666666666666\
86
85
  11211111111111111111111111111111\
87
86
  11111111111111111111111111112111\
@@ -92,7 +91,7 @@ static char hixss_friendly_chars[256] = "\
92
91
  11611111111111111111111111111111";
93
92
 
94
93
  // Rails XSS combo
95
- static char rails_xss_friendly_chars[256] = "\
94
+ static char rails_xss_friendly_chars[256] = "\
96
95
  66666666222622666666666666666666\
97
96
  11211161111111111111111111116161\
98
97
  11111111111111111111111111112111\
@@ -103,7 +102,7 @@ static char rails_xss_friendly_chars[256] = "\
103
102
  11611111111111111111111111111111";
104
103
 
105
104
  // Rails HTML non-escape
106
- static char rails_friendly_chars[256] = "\
105
+ static char rails_friendly_chars[256] = "\
107
106
  66666666222622666666666666666666\
108
107
  11211111111111111111111111111111\
109
108
  11111111111111111111111111112111\
@@ -113,245 +112,235 @@ static char rails_friendly_chars[256] = "\
113
112
  11111111111111111111111111111111\
114
113
  11111111111111111111111111111111";
115
114
 
116
- static void
117
- raise_strict(VALUE obj) {
118
- rb_raise(rb_eTypeError, "Failed to dump %s Object to JSON in strict mode.", rb_class2name(rb_obj_class(obj)));
115
+ static void raise_strict(VALUE obj) {
116
+ rb_raise(rb_eTypeError,
117
+ "Failed to dump %s Object to JSON in strict mode.",
118
+ rb_class2name(rb_obj_class(obj)));
119
119
  }
120
120
 
121
- inline static size_t
122
- newline_friendly_size(const uint8_t *str, size_t len) {
123
- size_t size = 0;
124
- size_t i = len;
121
+ inline static size_t newline_friendly_size(const uint8_t *str, size_t len) {
122
+ size_t size = 0;
123
+ size_t i = len;
125
124
 
126
125
  for (; 0 < i; str++, i--) {
127
- size += newline_friendly_chars[*str];
126
+ size += newline_friendly_chars[*str];
128
127
  }
129
128
  return size - len * (size_t)'0';
130
129
  }
131
130
 
132
- inline static size_t
133
- hibit_friendly_size(const uint8_t *str, size_t len) {
134
- size_t size = 0;
135
- size_t i = len;
131
+ inline static size_t hibit_friendly_size(const uint8_t *str, size_t len) {
132
+ size_t size = 0;
133
+ size_t i = len;
136
134
 
137
135
  for (; 0 < i; str++, i--) {
138
- size += hibit_friendly_chars[*str];
136
+ size += hibit_friendly_chars[*str];
139
137
  }
140
138
  return size - len * (size_t)'0';
141
139
  }
142
140
 
143
- inline static size_t
144
- ascii_friendly_size(const uint8_t *str, size_t len) {
145
- size_t size = 0;
146
- size_t i = len;
141
+ inline static size_t ascii_friendly_size(const uint8_t *str, size_t len) {
142
+ size_t size = 0;
143
+ size_t i = len;
147
144
 
148
145
  for (; 0 < i; str++, i--) {
149
- size += ascii_friendly_chars[*str];
146
+ size += ascii_friendly_chars[*str];
150
147
  }
151
148
  return size - len * (size_t)'0';
152
149
  }
153
150
 
154
- inline static size_t
155
- xss_friendly_size(const uint8_t *str, size_t len) {
156
- size_t size = 0;
157
- size_t i = len;
151
+ inline static size_t xss_friendly_size(const uint8_t *str, size_t len) {
152
+ size_t size = 0;
153
+ size_t i = len;
158
154
 
159
155
  for (; 0 < i; str++, i--) {
160
- size += xss_friendly_chars[*str];
156
+ size += xss_friendly_chars[*str];
161
157
  }
162
158
  return size - len * (size_t)'0';
163
159
  }
164
160
 
165
- inline static size_t
166
- hixss_friendly_size(const uint8_t *str, size_t len) {
167
- size_t size = 0;
168
- size_t i = len;
169
- bool check = false;
161
+ inline static size_t hixss_friendly_size(const uint8_t *str, size_t len) {
162
+ size_t size = 0;
163
+ size_t i = len;
164
+ bool check = false;
170
165
 
171
166
  for (; 0 < i; str++, i--) {
172
- size += hixss_friendly_chars[*str];
173
- if (0 != (0x80 & *str)) {
174
- check = true;
175
- }
167
+ size += hixss_friendly_chars[*str];
168
+ if (0 != (0x80 & *str)) {
169
+ check = true;
170
+ }
176
171
  }
177
172
  return size - len * (size_t)'0' + check;
178
173
  }
179
174
 
180
- inline static size_t
181
- rails_xss_friendly_size(const uint8_t *str, size_t len) {
182
- size_t size = 0;
183
- size_t i = len;
175
+ inline static long rails_xss_friendly_size(const uint8_t *str, size_t len) {
176
+ long size = 0;
177
+ size_t i = len;
178
+ uint8_t hi = 0;
184
179
 
185
180
  for (; 0 < i; str++, i--) {
186
- size += rails_xss_friendly_chars[*str];
181
+ size += rails_xss_friendly_chars[*str];
182
+ hi |= *str & 0x80;
187
183
  }
188
- return size - len * (size_t)'0';
184
+ if (0 == hi) {
185
+ return size - len * (size_t)'0';
186
+ }
187
+ return -(size - len * (size_t)'0');
189
188
  }
190
189
 
191
- inline static size_t
192
- rails_friendly_size(const uint8_t *str, size_t len) {
193
- size_t size = 0;
194
- size_t i = len;
190
+ inline static size_t rails_friendly_size(const uint8_t *str, size_t len) {
191
+ size_t size = 0;
192
+ size_t i = len;
195
193
 
196
194
  for (; 0 < i; str++, i--) {
197
- size += rails_friendly_chars[*str];
195
+ size += rails_friendly_chars[*str];
198
196
  }
199
197
  return size - len * (size_t)'0';
200
198
  }
201
199
 
202
- const char*
203
- oj_nan_str(VALUE obj, int opt, int mode, bool plus, int *lenp) {
204
- const char *str = NULL;
200
+ const char *oj_nan_str(VALUE obj, int opt, int mode, bool plus, int *lenp) {
201
+ const char *str = NULL;
205
202
 
206
203
  if (AutoNan == opt) {
207
- switch (mode) {
208
- case CompatMode: opt = WordNan; break;
209
- case StrictMode: opt = RaiseNan; break;
210
- default: break;
211
- }
204
+ switch (mode) {
205
+ case CompatMode: opt = WordNan; break;
206
+ case StrictMode: opt = RaiseNan; break;
207
+ default: break;
208
+ }
212
209
  }
213
210
  switch (opt) {
214
- case RaiseNan:
215
- raise_strict(obj);
216
- break;
211
+ case RaiseNan: raise_strict(obj); break;
217
212
  case WordNan:
218
- if (plus) {
219
- str = "Infinity";
220
- *lenp = 8;
221
- } else {
222
- str = "-Infinity";
223
- *lenp = 9;
224
- }
225
- break;
213
+ if (plus) {
214
+ str = "Infinity";
215
+ *lenp = 8;
216
+ } else {
217
+ str = "-Infinity";
218
+ *lenp = 9;
219
+ }
220
+ break;
226
221
  case NullNan:
227
- str = "null";
228
- *lenp = 4;
229
- break;
222
+ str = "null";
223
+ *lenp = 4;
224
+ break;
230
225
  case HugeNan:
231
226
  default:
232
- if (plus) {
233
- str = inf_val;
234
- *lenp = sizeof(inf_val) - 1;
235
- } else {
236
- str = ninf_val;
237
- *lenp = sizeof(ninf_val) - 1;
238
- }
239
- break;
227
+ if (plus) {
228
+ str = inf_val;
229
+ *lenp = sizeof(inf_val) - 1;
230
+ } else {
231
+ str = ninf_val;
232
+ *lenp = sizeof(ninf_val) - 1;
233
+ }
234
+ break;
240
235
  }
241
236
  return str;
242
237
  }
243
238
 
244
- inline static void
245
- dump_hex(uint8_t c, Out out) {
246
- uint8_t d = (c >> 4) & 0x0F;
239
+ inline static void dump_hex(uint8_t c, Out out) {
240
+ uint8_t d = (c >> 4) & 0x0F;
247
241
 
248
242
  *out->cur++ = hex_chars[d];
249
- d = c & 0x0F;
243
+ d = c & 0x0F;
250
244
  *out->cur++ = hex_chars[d];
251
245
  }
252
246
 
253
- static void
254
- raise_invalid_unicode(const char *str, int len, int pos) {
255
- char buf[len + 1];
256
- char c;
257
- char code[32];
258
- char *cp = code;
259
- int i;
260
- uint8_t d;
247
+ static void raise_invalid_unicode(const char *str, int len, int pos) {
248
+ char c;
249
+ char code[32];
250
+ char * cp = code;
251
+ int i;
252
+ uint8_t d;
261
253
 
262
254
  *cp++ = '[';
263
255
  for (i = pos; i < len && i - pos < 5; i++) {
264
- c = str[i];
265
- d = (c >> 4) & 0x0F;
266
- *cp++ = hex_chars[d];
267
- d = c & 0x0F;
268
- *cp++ = hex_chars[d];
269
- *cp++ = ' ';
256
+ c = str[i];
257
+ d = (c >> 4) & 0x0F;
258
+ *cp++ = hex_chars[d];
259
+ d = c & 0x0F;
260
+ *cp++ = hex_chars[d];
261
+ *cp++ = ' ';
270
262
  }
271
263
  cp--;
272
264
  *cp++ = ']';
273
- *cp = '\0';
274
- strncpy(buf, str, len);
275
- rb_raise(oj_json_generator_error_class, "Invalid Unicode %s at %d in '%s'", code, pos, buf);
265
+ *cp = '\0';
266
+ rb_raise(oj_json_generator_error_class, "Invalid Unicode %s at %d", code, pos);
276
267
  }
277
268
 
278
- static const char*
279
- dump_unicode(const char *str, const char *end, Out out, const char *orig) {
280
- uint32_t code = 0;
281
- uint8_t b = *(uint8_t*)str;
282
- int i, cnt;
269
+ static const char *dump_unicode(const char *str, const char *end, Out out, const char *orig) {
270
+ uint32_t code = 0;
271
+ uint8_t b = *(uint8_t *)str;
272
+ int i, cnt;
283
273
 
284
274
  if (0xC0 == (0xE0 & b)) {
285
- cnt = 1;
286
- code = b & 0x0000001F;
275
+ cnt = 1;
276
+ code = b & 0x0000001F;
287
277
  } else if (0xE0 == (0xF0 & b)) {
288
- cnt = 2;
289
- code = b & 0x0000000F;
278
+ cnt = 2;
279
+ code = b & 0x0000000F;
290
280
  } else if (0xF0 == (0xF8 & b)) {
291
- cnt = 3;
292
- code = b & 0x00000007;
281
+ cnt = 3;
282
+ code = b & 0x00000007;
293
283
  } else if (0xF8 == (0xFC & b)) {
294
- cnt = 4;
295
- code = b & 0x00000003;
284
+ cnt = 4;
285
+ code = b & 0x00000003;
296
286
  } else if (0xFC == (0xFE & b)) {
297
- cnt = 5;
298
- code = b & 0x00000001;
287
+ cnt = 5;
288
+ code = b & 0x00000001;
299
289
  } else {
300
- cnt = 0;
301
- raise_invalid_unicode(orig, (int)(end - orig), (int)(str - orig));
290
+ cnt = 0;
291
+ raise_invalid_unicode(orig, (int)(end - orig), (int)(str - orig));
302
292
  }
303
293
  str++;
304
294
  for (; 0 < cnt; cnt--, str++) {
305
- b = *(uint8_t*)str;
306
- if (end <= str || 0x80 != (0xC0 & b)) {
307
- raise_invalid_unicode(orig, (int)(end - orig), (int)(str - orig));
308
- }
309
- code = (code << 6) | (b & 0x0000003F);
295
+ b = *(uint8_t *)str;
296
+ if (end <= str || 0x80 != (0xC0 & b)) {
297
+ raise_invalid_unicode(orig, (int)(end - orig), (int)(str - orig));
298
+ }
299
+ code = (code << 6) | (b & 0x0000003F);
310
300
  }
311
301
  if (0x0000FFFF < code) {
312
- uint32_t c1;
313
-
314
- code -= 0x00010000;
315
- c1 = ((code >> 10) & 0x000003FF) + 0x0000D800;
316
- code = (code & 0x000003FF) + 0x0000DC00;
317
- *out->cur++ = '\\';
318
- *out->cur++ = 'u';
319
- for (i = 3; 0 <= i; i--) {
320
- *out->cur++ = hex_chars[(uint8_t)(c1 >> (i * 4)) & 0x0F];
321
- }
302
+ uint32_t c1;
303
+
304
+ code -= 0x00010000;
305
+ c1 = ((code >> 10) & 0x000003FF) + 0x0000D800;
306
+ code = (code & 0x000003FF) + 0x0000DC00;
307
+ *out->cur++ = '\\';
308
+ *out->cur++ = 'u';
309
+ for (i = 3; 0 <= i; i--) {
310
+ *out->cur++ = hex_chars[(uint8_t)(c1 >> (i * 4)) & 0x0F];
311
+ }
322
312
  }
323
313
  *out->cur++ = '\\';
324
314
  *out->cur++ = 'u';
325
315
  for (i = 3; 0 <= i; i--) {
326
- *out->cur++ = hex_chars[(uint8_t)(code >> (i * 4)) & 0x0F];
316
+ *out->cur++ = hex_chars[(uint8_t)(code >> (i * 4)) & 0x0F];
327
317
  }
328
318
  return str - 1;
329
319
  }
330
320
 
331
- static const char*
332
- check_unicode(const char *str, const char *end, const char *orig) {
333
- uint8_t b = *(uint8_t*)str;
334
- int cnt = 0;
321
+ static const char *check_unicode(const char *str, const char *end, const char *orig) {
322
+ uint8_t b = *(uint8_t *)str;
323
+ int cnt = 0;
335
324
 
336
325
  if (0xC0 == (0xE0 & b)) {
337
- cnt = 1;
326
+ cnt = 1;
338
327
  } else if (0xE0 == (0xF0 & b)) {
339
- cnt = 2;
328
+ cnt = 2;
340
329
  } else if (0xF0 == (0xF8 & b)) {
341
- cnt = 3;
330
+ cnt = 3;
342
331
  } else if (0xF8 == (0xFC & b)) {
343
- cnt = 4;
332
+ cnt = 4;
344
333
  } else if (0xFC == (0xFE & b)) {
345
- cnt = 5;
334
+ cnt = 5;
346
335
  } else {
347
- raise_invalid_unicode(orig, (int)(end - orig), (int)(str - orig));
336
+ raise_invalid_unicode(orig, (int)(end - orig), (int)(str - orig));
348
337
  }
349
338
  str++;
350
339
  for (; 0 < cnt; cnt--, str++) {
351
- b = *(uint8_t*)str;
352
- if (end <= str || 0x80 != (0xC0 & b)) {
353
- raise_invalid_unicode(orig, (int)(end - orig), (int)(str - orig));
354
- }
340
+ b = *(uint8_t *)str;
341
+ if (end <= str || 0x80 != (0xC0 & b)) {
342
+ raise_invalid_unicode(orig, (int)(end - orig), (int)(str - orig));
343
+ }
355
344
  }
356
345
  return str;
357
346
  }
@@ -359,120 +348,118 @@ check_unicode(const char *str, const char *end, const char *orig) {
359
348
  // Returns 0 if not using circular references, -1 if no further writing is
360
349
  // needed (duplicate), and a positive value if the object was added to the
361
350
  // cache.
362
- long
363
- oj_check_circular(VALUE obj, Out out) {
364
- slot_t id = 0;
365
- slot_t *slot;
351
+ long oj_check_circular(VALUE obj, Out out) {
352
+ slot_t id = 0;
353
+ slot_t *slot;
366
354
 
367
355
  if (Yes == out->opts->circular) {
368
- if (0 == (id = oj_cache8_get(out->circ_cache, obj, &slot))) {
369
- out->circ_cnt++;
370
- id = out->circ_cnt;
371
- *slot = id;
372
- } else {
373
- if (ObjectMode == out->opts->mode) {
374
- assure_size(out, 18);
375
- *out->cur++ = '"';
376
- *out->cur++ = '^';
377
- *out->cur++ = 'r';
378
- dump_ulong(id, out);
379
- *out->cur++ = '"';
380
- }
381
- return -1;
382
- }
356
+ if (0 == (id = oj_cache8_get(out->circ_cache, obj, &slot))) {
357
+ out->circ_cnt++;
358
+ id = out->circ_cnt;
359
+ *slot = id;
360
+ } else {
361
+ if (ObjectMode == out->opts->mode) {
362
+ assure_size(out, 18);
363
+ *out->cur++ = '"';
364
+ *out->cur++ = '^';
365
+ *out->cur++ = 'r';
366
+ dump_ulong(id, out);
367
+ *out->cur++ = '"';
368
+ }
369
+ return -1;
370
+ }
383
371
  }
384
372
  return (long)id;
385
373
  }
386
374
 
387
- void
388
- oj_dump_time(VALUE obj, Out out, int withZone) {
389
- char buf[64];
390
- char *b = buf + sizeof(buf) - 1;
391
- long size;
392
- char *dot;
393
- int neg = 0;
394
- long one = 1000000000;
395
- long long sec;
396
- long long nsec;
375
+ void oj_dump_time(VALUE obj, Out out, int withZone) {
376
+ char buf[64];
377
+ char * b = buf + sizeof(buf) - 1;
378
+ long size;
379
+ char * dot;
380
+ int neg = 0;
381
+ long one = 1000000000;
382
+ long long sec;
383
+ long long nsec;
397
384
 
398
385
  #ifdef HAVE_RB_TIME_TIMESPEC
399
386
  // rb_time_timespec as well as rb_time_timeeval have a bug that causes an
400
387
  // exception to be raised if a time is before 1970 on 32 bit systems so
401
388
  // check the timespec size and use the ruby calls if a 32 bit system.
402
389
  if (16 <= sizeof(struct timespec)) {
403
- struct timespec ts = rb_time_timespec(obj);
390
+ struct timespec ts = rb_time_timespec(obj);
404
391
 
405
- sec = (long long)ts.tv_sec;
406
- nsec = ts.tv_nsec;
392
+ sec = (long long)ts.tv_sec;
393
+ nsec = ts.tv_nsec;
407
394
  } else {
408
- sec = rb_num2ll(rb_funcall2(obj, oj_tv_sec_id, 0, 0));
409
- nsec = rb_num2ll(rb_funcall2(obj, oj_tv_nsec_id, 0, 0));
395
+ sec = rb_num2ll(rb_funcall2(obj, oj_tv_sec_id, 0, 0));
396
+ nsec = rb_num2ll(rb_funcall2(obj, oj_tv_nsec_id, 0, 0));
410
397
  }
411
398
  #else
412
- sec = rb_num2ll(rb_funcall2(obj, oj_tv_sec_id, 0, 0));
399
+ sec = rb_num2ll(rb_funcall2(obj, oj_tv_sec_id, 0, 0));
413
400
  nsec = rb_num2ll(rb_funcall2(obj, oj_tv_nsec_id, 0, 0));
414
401
  #endif
415
402
 
416
403
  *b-- = '\0';
417
404
  if (withZone) {
418
- long tzsecs = NUM2LONG(rb_funcall2(obj, oj_utc_offset_id, 0, 0));
419
- int zneg = (0 > tzsecs);
420
-
421
- if (0 == tzsecs && rb_funcall2(obj, oj_utcq_id, 0, 0)) {
422
- tzsecs = 86400;
423
- }
424
- if (zneg) {
425
- tzsecs = -tzsecs;
426
- }
427
- if (0 == tzsecs) {
428
- *b-- = '0';
429
- } else {
430
- for (; 0 < tzsecs; b--, tzsecs /= 10) {
431
- *b = '0' + (tzsecs % 10);
432
- }
433
- if (zneg) {
434
- *b-- = '-';
435
- }
436
- }
437
- *b-- = 'e';
405
+ long tzsecs = NUM2LONG(rb_funcall2(obj, oj_utc_offset_id, 0, 0));
406
+ int zneg = (0 > tzsecs);
407
+
408
+ if (0 == tzsecs && rb_funcall2(obj, oj_utcq_id, 0, 0)) {
409
+ tzsecs = 86400;
410
+ }
411
+ if (zneg) {
412
+ tzsecs = -tzsecs;
413
+ }
414
+ if (0 == tzsecs) {
415
+ *b-- = '0';
416
+ } else {
417
+ for (; 0 < tzsecs; b--, tzsecs /= 10) {
418
+ *b = '0' + (tzsecs % 10);
419
+ }
420
+ if (zneg) {
421
+ *b-- = '-';
422
+ }
423
+ }
424
+ *b-- = 'e';
438
425
  }
439
426
  if (0 > sec) {
440
- neg = 1;
441
- sec = -sec;
442
- if (0 < nsec) {
443
- nsec = 1000000000 - nsec;
444
- sec--;
445
- }
427
+ neg = 1;
428
+ sec = -sec;
429
+ if (0 < nsec) {
430
+ nsec = 1000000000 - nsec;
431
+ sec--;
432
+ }
446
433
  }
447
434
  dot = b - 9;
448
435
  if (0 < out->opts->sec_prec) {
449
- if (9 > out->opts->sec_prec) {
450
- int i;
451
-
452
- for (i = 9 - out->opts->sec_prec; 0 < i; i--) {
453
- dot++;
454
- nsec = (nsec + 5) / 10;
455
- one /= 10;
456
- }
457
- }
458
- if (one <= nsec) {
459
- nsec -= one;
460
- sec++;
461
- }
462
- for (; dot < b; b--, nsec /= 10) {
463
- *b = '0' + (nsec % 10);
464
- }
465
- *b-- = '.';
436
+ if (9 > out->opts->sec_prec) {
437
+ int i;
438
+
439
+ for (i = 9 - out->opts->sec_prec; 0 < i; i--) {
440
+ dot++;
441
+ nsec = (nsec + 5) / 10;
442
+ one /= 10;
443
+ }
444
+ }
445
+ if (one <= nsec) {
446
+ nsec -= one;
447
+ sec++;
448
+ }
449
+ for (; dot < b; b--, nsec /= 10) {
450
+ *b = '0' + (nsec % 10);
451
+ }
452
+ *b-- = '.';
466
453
  }
467
454
  if (0 == sec) {
468
- *b-- = '0';
455
+ *b-- = '0';
469
456
  } else {
470
- for (; 0 < sec; b--, sec /= 10) {
471
- *b = '0' + (sec % 10);
472
- }
457
+ for (; 0 < sec; b--, sec /= 10) {
458
+ *b = '0' + (sec % 10);
459
+ }
473
460
  }
474
461
  if (neg) {
475
- *b-- = '-';
462
+ *b-- = '-';
476
463
  }
477
464
  b++;
478
465
  size = sizeof(buf) - (b - buf) - 1;
@@ -482,768 +469,779 @@ oj_dump_time(VALUE obj, Out out, int withZone) {
482
469
  *out->cur = '\0';
483
470
  }
484
471
 
485
- void
486
- oj_dump_ruby_time(VALUE obj, Out out) {
487
- volatile VALUE rstr = rb_funcall(obj, oj_to_s_id, 0);
472
+ void oj_dump_ruby_time(VALUE obj, Out out) {
473
+ volatile VALUE rstr = rb_funcall(obj, oj_to_s_id, 0);
488
474
 
489
- oj_dump_cstr(rb_string_value_ptr((VALUE*)&rstr), (int)RSTRING_LEN(rstr), 0, 0, out);
475
+ oj_dump_cstr(rb_string_value_ptr((VALUE *)&rstr), (int)RSTRING_LEN(rstr), 0, 0, out);
490
476
  }
491
477
 
492
- void
493
- oj_dump_xml_time(VALUE obj, Out out) {
494
- char buf[64];
495
- struct _timeInfo ti;
496
- long one = 1000000000;
497
- int64_t sec;
498
- long long nsec;
499
- long tzsecs = NUM2LONG(rb_funcall2(obj, oj_utc_offset_id, 0, 0));
500
- int tzhour, tzmin;
501
- char tzsign = '+';
478
+ void oj_dump_xml_time(VALUE obj, Out out) {
479
+ char buf[64];
480
+ struct _timeInfo ti;
481
+ long one = 1000000000;
482
+ int64_t sec;
483
+ long long nsec;
484
+ long tzsecs = NUM2LONG(rb_funcall2(obj, oj_utc_offset_id, 0, 0));
485
+ int tzhour, tzmin;
486
+ char tzsign = '+';
502
487
 
503
488
  #ifdef HAVE_RB_TIME_TIMESPEC
504
489
  if (16 <= sizeof(struct timespec)) {
505
- struct timespec ts = rb_time_timespec(obj);
490
+ struct timespec ts = rb_time_timespec(obj);
506
491
 
507
- sec = ts.tv_sec;
508
- nsec = ts.tv_nsec;
492
+ sec = ts.tv_sec;
493
+ nsec = ts.tv_nsec;
509
494
  } else {
510
- sec = rb_num2ll(rb_funcall2(obj, oj_tv_sec_id, 0, 0));
511
- nsec = rb_num2ll(rb_funcall2(obj, oj_tv_nsec_id, 0, 0));
495
+ sec = rb_num2ll(rb_funcall2(obj, oj_tv_sec_id, 0, 0));
496
+ nsec = rb_num2ll(rb_funcall2(obj, oj_tv_nsec_id, 0, 0));
512
497
  }
513
498
  #else
514
- sec = rb_num2ll(rb_funcall2(obj, oj_tv_sec_id, 0, 0));
499
+ sec = rb_num2ll(rb_funcall2(obj, oj_tv_sec_id, 0, 0));
515
500
  nsec = rb_num2ll(rb_funcall2(obj, oj_tv_nsec_id, 0, 0));
516
501
  #endif
517
502
 
518
503
  assure_size(out, 36);
519
504
  if (9 > out->opts->sec_prec) {
520
- int i;
521
-
522
- // This is pretty lame but to be compatible with rails and active
523
- // support rounding is not done but instead a floor is done when
524
- // second precision is 3 just to be like rails. sigh.
525
- if (3 == out->opts->sec_prec) {
526
- nsec /= 1000000;
527
- one = 1000;
528
- } else {
529
- for (i = 9 - out->opts->sec_prec; 0 < i; i--) {
530
- nsec = (nsec + 5) / 10;
531
- one /= 10;
532
- }
533
- if (one <= nsec) {
534
- nsec -= one;
535
- sec++;
536
- }
537
- }
505
+ int i;
506
+
507
+ // This is pretty lame but to be compatible with rails and active
508
+ // support rounding is not done but instead a floor is done when
509
+ // second precision is 3 just to be like rails. sigh.
510
+ if (3 == out->opts->sec_prec) {
511
+ nsec /= 1000000;
512
+ one = 1000;
513
+ } else {
514
+ for (i = 9 - out->opts->sec_prec; 0 < i; i--) {
515
+ nsec = (nsec + 5) / 10;
516
+ one /= 10;
517
+ }
518
+ if (one <= nsec) {
519
+ nsec -= one;
520
+ sec++;
521
+ }
522
+ }
538
523
  }
539
524
  // 2012-01-05T23:58:07.123456000+09:00
540
- //tm = localtime(&sec);
525
+ // tm = localtime(&sec);
541
526
  sec += tzsecs;
542
527
  sec_as_time((int64_t)sec, &ti);
543
528
  if (0 > tzsecs) {
544
529
  tzsign = '-';
545
530
  tzhour = (int)(tzsecs / -3600);
546
- tzmin = (int)(tzsecs / -60) - (tzhour * 60);
531
+ tzmin = (int)(tzsecs / -60) - (tzhour * 60);
547
532
  } else {
548
533
  tzhour = (int)(tzsecs / 3600);
549
- tzmin = (int)(tzsecs / 60) - (tzhour * 60);
534
+ tzmin = (int)(tzsecs / 60) - (tzhour * 60);
550
535
  }
551
536
  if ((0 == nsec && !out->opts->sec_prec_set) || 0 == out->opts->sec_prec) {
552
- if (0 == tzsecs && rb_funcall2(obj, oj_utcq_id, 0, 0)) {
553
- sprintf(buf, "%04d-%02d-%02dT%02d:%02d:%02dZ", ti.year, ti.mon, ti.day, ti.hour, ti.min, ti.sec);
554
- oj_dump_cstr(buf, 20, 0, 0, out);
555
- } else {
556
- sprintf(buf, "%04d-%02d-%02dT%02d:%02d:%02d%c%02d:%02d", ti.year, ti.mon, ti.day, ti.hour, ti.min, ti.sec,
557
- tzsign, tzhour, tzmin);
558
- oj_dump_cstr(buf, 25, 0, 0, out);
559
- }
537
+ if (0 == tzsecs && rb_funcall2(obj, oj_utcq_id, 0, 0)) {
538
+ sprintf(buf,
539
+ "%04d-%02d-%02dT%02d:%02d:%02dZ",
540
+ ti.year,
541
+ ti.mon,
542
+ ti.day,
543
+ ti.hour,
544
+ ti.min,
545
+ ti.sec);
546
+ oj_dump_cstr(buf, 20, 0, 0, out);
547
+ } else {
548
+ sprintf(buf,
549
+ "%04d-%02d-%02dT%02d:%02d:%02d%c%02d:%02d",
550
+ ti.year,
551
+ ti.mon,
552
+ ti.day,
553
+ ti.hour,
554
+ ti.min,
555
+ ti.sec,
556
+ tzsign,
557
+ tzhour,
558
+ tzmin);
559
+ oj_dump_cstr(buf, 25, 0, 0, out);
560
+ }
560
561
  } else if (0 == tzsecs && rb_funcall2(obj, oj_utcq_id, 0, 0)) {
561
- char format[64] = "%04d-%02d-%02dT%02d:%02d:%02d.%09ldZ";
562
- int len = 30;
563
-
564
- if (9 > out->opts->sec_prec) {
565
- format[32] = '0' + out->opts->sec_prec;
566
- len -= 9 - out->opts->sec_prec;
567
- }
568
- sprintf(buf, format, ti.year, ti.mon, ti.day, ti.hour, ti.min, ti.sec, (long)nsec);
569
- oj_dump_cstr(buf, len, 0, 0, out);
562
+ char format[64] = "%04d-%02d-%02dT%02d:%02d:%02d.%09ldZ";
563
+ int len = 30;
564
+
565
+ if (9 > out->opts->sec_prec) {
566
+ format[32] = '0' + out->opts->sec_prec;
567
+ len -= 9 - out->opts->sec_prec;
568
+ }
569
+ sprintf(buf, format, ti.year, ti.mon, ti.day, ti.hour, ti.min, ti.sec, (long)nsec);
570
+ oj_dump_cstr(buf, len, 0, 0, out);
570
571
  } else {
571
- char format[64] = "%04d-%02d-%02dT%02d:%02d:%02d.%09ld%c%02d:%02d";
572
- int len = 35;
573
-
574
- if (9 > out->opts->sec_prec) {
575
- format[32] = '0' + out->opts->sec_prec;
576
- len -= 9 - out->opts->sec_prec;
577
- }
578
- sprintf(buf, format, ti.year, ti.mon, ti.day, ti.hour, ti.min, ti.sec, (long)nsec, tzsign, tzhour, tzmin);
579
- oj_dump_cstr(buf, len, 0, 0, out);
572
+ char format[64] = "%04d-%02d-%02dT%02d:%02d:%02d.%09ld%c%02d:%02d";
573
+ int len = 35;
574
+
575
+ if (9 > out->opts->sec_prec) {
576
+ format[32] = '0' + out->opts->sec_prec;
577
+ len -= 9 - out->opts->sec_prec;
578
+ }
579
+ sprintf(buf,
580
+ format,
581
+ ti.year,
582
+ ti.mon,
583
+ ti.day,
584
+ ti.hour,
585
+ ti.min,
586
+ ti.sec,
587
+ (long)nsec,
588
+ tzsign,
589
+ tzhour,
590
+ tzmin);
591
+ oj_dump_cstr(buf, len, 0, 0, out);
580
592
  }
581
593
  }
582
594
 
583
- void
584
- oj_dump_obj_to_json(VALUE obj, Options copts, Out out) {
595
+ void oj_dump_obj_to_json(VALUE obj, Options copts, Out out) {
585
596
  oj_dump_obj_to_json_using_params(obj, copts, out, 0, 0);
586
597
  }
587
598
 
588
- void
589
- oj_dump_obj_to_json_using_params(VALUE obj, Options copts, Out out, int argc, VALUE *argv) {
599
+ void oj_dump_obj_to_json_using_params(VALUE obj, Options copts, Out out, int argc, VALUE *argv) {
590
600
  if (0 == out->buf) {
591
- out->buf = ALLOC_N(char, 4096);
592
- out->end = out->buf + 4095 - BUFFER_EXTRA; // 1 less than end plus extra for possible errors
593
- out->allocated = true;
601
+ out->buf = ALLOC_N(char, 4096);
602
+ // 1 less than end plus extra for possible errors
603
+ out->end = out->buf + 4095 - BUFFER_EXTRA;
604
+ out->allocated = true;
594
605
  }
595
- out->cur = out->buf;
606
+ out->cur = out->buf;
596
607
  out->circ_cnt = 0;
597
- out->opts = copts;
608
+ out->opts = copts;
598
609
  out->hash_cnt = 0;
599
- out->indent = copts->indent;
600
- out->argc = argc;
601
- out->argv = argv;
602
- out->ropts = NULL;
610
+ out->indent = copts->indent;
611
+ out->argc = argc;
612
+ out->argv = argv;
613
+ out->ropts = NULL;
603
614
  if (Yes == copts->circular) {
604
- oj_cache8_new(&out->circ_cache);
615
+ oj_cache8_new(&out->circ_cache);
605
616
  }
606
617
  switch (copts->mode) {
607
- case StrictMode: oj_dump_strict_val(obj, 0, out); break;
608
- case NullMode: oj_dump_null_val(obj, 0, out); break;
609
- case ObjectMode: oj_dump_obj_val(obj, 0, out); break;
610
- case CompatMode: oj_dump_compat_val(obj, 0, out, Yes == copts->to_json); break;
611
- case RailsMode: oj_dump_rails_val(obj, 0, out); break;
612
- case CustomMode: oj_dump_custom_val(obj, 0, out, true); break;
613
- case WabMode: oj_dump_wab_val(obj, 0, out); break;
614
- default: oj_dump_custom_val(obj, 0, out, true); break;
618
+ case StrictMode: oj_dump_strict_val(obj, 0, out); break;
619
+ case NullMode: oj_dump_null_val(obj, 0, out); break;
620
+ case ObjectMode: oj_dump_obj_val(obj, 0, out); break;
621
+ case CompatMode: oj_dump_compat_val(obj, 0, out, Yes == copts->to_json); break;
622
+ case RailsMode: oj_dump_rails_val(obj, 0, out); break;
623
+ case CustomMode: oj_dump_custom_val(obj, 0, out, true); break;
624
+ case WabMode: oj_dump_wab_val(obj, 0, out); break;
625
+ default: oj_dump_custom_val(obj, 0, out, true); break;
615
626
  }
616
627
  if (0 < out->indent) {
617
- switch (*(out->cur - 1)) {
618
- case ']':
619
- case '}':
620
- assure_size(out, 1);
621
- *out->cur++ = '\n';
622
- default:
623
- break;
624
- }
628
+ switch (*(out->cur - 1)) {
629
+ case ']':
630
+ case '}': assure_size(out, 1); *out->cur++ = '\n';
631
+ default: break;
632
+ }
625
633
  }
626
634
  *out->cur = '\0';
627
635
  if (Yes == copts->circular) {
628
- oj_cache8_delete(out->circ_cache);
636
+ oj_cache8_delete(out->circ_cache);
629
637
  }
630
638
  }
631
639
 
632
- void
633
- oj_write_obj_to_file(VALUE obj, const char *path, Options copts) {
634
- char buf[4096];
640
+ void oj_write_obj_to_file(VALUE obj, const char *path, Options copts) {
641
+ char buf[4096];
635
642
  struct _out out;
636
- size_t size;
637
- FILE *f;
638
- int ok;
643
+ size_t size;
644
+ FILE * f;
645
+ int ok;
639
646
 
640
- out.buf = buf;
641
- out.end = buf + sizeof(buf) - BUFFER_EXTRA;
647
+ out.buf = buf;
648
+ out.end = buf + sizeof(buf) - BUFFER_EXTRA;
642
649
  out.allocated = false;
643
- out.omit_nil = copts->dump_opts.omit_nil;
650
+ out.omit_nil = copts->dump_opts.omit_nil;
644
651
  oj_dump_obj_to_json(obj, copts, &out);
645
652
  size = out.cur - out.buf;
646
653
  if (0 == (f = fopen(path, "w"))) {
647
- if (out.allocated) {
648
- xfree(out.buf);
649
- }
650
- rb_raise(rb_eIOError, "%s", strerror(errno));
654
+ if (out.allocated) {
655
+ xfree(out.buf);
656
+ }
657
+ rb_raise(rb_eIOError, "%s", strerror(errno));
651
658
  }
652
659
  ok = (size == fwrite(out.buf, 1, size, f));
653
660
  if (out.allocated) {
654
- xfree(out.buf);
661
+ xfree(out.buf);
655
662
  }
656
663
  fclose(f);
657
664
  if (!ok) {
658
- int err = ferror(f);
665
+ int err = ferror(f);
659
666
 
660
- rb_raise(rb_eIOError, "Write failed. [%d:%s]", err, strerror(err));
667
+ rb_raise(rb_eIOError, "Write failed. [%d:%s]", err, strerror(err));
661
668
  }
662
669
  }
663
670
 
664
- void
665
- oj_write_obj_to_stream(VALUE obj, VALUE stream, Options copts) {
666
- char buf[4096];
671
+ void oj_write_obj_to_stream(VALUE obj, VALUE stream, Options copts) {
672
+ char buf[4096];
667
673
  struct _out out;
668
- ssize_t size;
669
- VALUE clas = rb_obj_class(stream);
674
+ ssize_t size;
675
+ VALUE clas = rb_obj_class(stream);
670
676
  #if !IS_WINDOWS
671
- int fd;
672
- VALUE s;
677
+ int fd;
678
+ VALUE s;
673
679
  #endif
674
680
 
675
- out.buf = buf;
676
- out.end = buf + sizeof(buf) - BUFFER_EXTRA;
681
+ out.buf = buf;
682
+ out.end = buf + sizeof(buf) - BUFFER_EXTRA;
677
683
  out.allocated = false;
678
- out.omit_nil = copts->dump_opts.omit_nil;
684
+ out.omit_nil = copts->dump_opts.omit_nil;
679
685
  oj_dump_obj_to_json(obj, copts, &out);
680
686
  size = out.cur - out.buf;
681
687
  if (oj_stringio_class == clas) {
682
- rb_funcall(stream, oj_write_id, 1, rb_str_new(out.buf, size));
688
+ rb_funcall(stream, oj_write_id, 1, rb_str_new(out.buf, size));
683
689
  #if !IS_WINDOWS
684
690
  } else if (rb_respond_to(stream, oj_fileno_id) &&
685
- Qnil != (s = rb_funcall(stream, oj_fileno_id, 0)) &&
686
- 0 != (fd = FIX2INT(s))) {
687
- if (size != write(fd, out.buf, size)) {
688
- if (out.allocated) {
689
- xfree(out.buf);
690
- }
691
- rb_raise(rb_eIOError, "Write failed. [%d:%s]", errno, strerror(errno));
692
- }
691
+ Qnil != (s = rb_funcall(stream, oj_fileno_id, 0)) && 0 != (fd = FIX2INT(s))) {
692
+ if (size != write(fd, out.buf, size)) {
693
+ if (out.allocated) {
694
+ xfree(out.buf);
695
+ }
696
+ rb_raise(rb_eIOError, "Write failed. [%d:%s]", errno, strerror(errno));
697
+ }
693
698
  #endif
694
699
  } else if (rb_respond_to(stream, oj_write_id)) {
695
- rb_funcall(stream, oj_write_id, 1, rb_str_new(out.buf, size));
700
+ rb_funcall(stream, oj_write_id, 1, rb_str_new(out.buf, size));
696
701
  } else {
697
- if (out.allocated) {
698
- xfree(out.buf);
699
- }
700
- rb_raise(rb_eArgError, "to_stream() expected an IO Object.");
702
+ if (out.allocated) {
703
+ xfree(out.buf);
704
+ }
705
+ rb_raise(rb_eArgError, "to_stream() expected an IO Object.");
701
706
  }
702
707
  if (out.allocated) {
703
- xfree(out.buf);
708
+ xfree(out.buf);
704
709
  }
705
710
  }
706
711
 
707
- void
708
- oj_dump_str(VALUE obj, int depth, Out out, bool as_ok) {
709
- rb_encoding *enc = rb_to_encoding(rb_obj_encoding(obj));
712
+ void oj_dump_str(VALUE obj, int depth, Out out, bool as_ok) {
713
+ rb_encoding *enc = rb_to_encoding(rb_obj_encoding(obj));
710
714
 
711
715
  if (rb_utf8_encoding() != enc) {
712
- obj = rb_str_conv_enc(obj, enc, rb_utf8_encoding());
716
+ obj = rb_str_conv_enc(obj, enc, rb_utf8_encoding());
713
717
  }
714
- oj_dump_cstr(rb_string_value_ptr((VALUE*)&obj), (int)RSTRING_LEN(obj), 0, 0, out);
718
+ oj_dump_cstr(rb_string_value_ptr((VALUE *)&obj), (int)RSTRING_LEN(obj), 0, 0, out);
715
719
  }
716
720
 
717
- void
718
- oj_dump_sym(VALUE obj, int depth, Out out, bool as_ok) {
721
+ void oj_dump_sym(VALUE obj, int depth, Out out, bool as_ok) {
719
722
  // This causes a memory leak in 2.5.1. Maybe in other versions as well.
720
- //const char *sym = rb_id2name(SYM2ID(obj));
723
+ // const char *sym = rb_id2name(SYM2ID(obj));
721
724
 
722
- volatile VALUE s = rb_sym_to_s(obj);
725
+ volatile VALUE s = rb_sym_to_s(obj);
723
726
 
724
- oj_dump_cstr(rb_string_value_ptr((VALUE*)&s), (int)RSTRING_LEN(s), 0, 0, out);
727
+ oj_dump_cstr(rb_string_value_ptr((VALUE *)&s), (int)RSTRING_LEN(s), 0, 0, out);
725
728
  }
726
729
 
727
- static void
728
- debug_raise(const char *orig, size_t cnt, int line) {
729
- char buf[1024];
730
- char *b = buf;
731
- const char *s = orig;
732
- const char *s_end = s + cnt;
730
+ static void debug_raise(const char *orig, size_t cnt, int line) {
731
+ char buf[1024];
732
+ char * b = buf;
733
+ const char *s = orig;
734
+ const char *s_end = s + cnt;
733
735
 
734
736
  if (32 < s_end - s) {
735
- s_end = s + 32;
737
+ s_end = s + 32;
736
738
  }
737
739
  for (; s < s_end; s++) {
738
- b += sprintf(b, " %02x", *s);
740
+ b += sprintf(b, " %02x", *s);
739
741
  }
740
742
  *b = '\0';
741
743
  rb_raise(oj_json_generator_error_class, "Partial character in string. %s @ %d", buf, line);
742
744
  }
743
745
 
744
- void
745
- oj_dump_raw_json(VALUE obj, int depth, Out out) {
746
+ void oj_dump_raw_json(VALUE obj, int depth, Out out) {
746
747
  if (oj_string_writer_class == rb_obj_class(obj)) {
747
- StrWriter sw = (StrWriter)DATA_PTR(obj);
748
- size_t len = sw->out.cur - sw->out.buf;
748
+ StrWriter sw = (StrWriter)DATA_PTR(obj);
749
+ size_t len = sw->out.cur - sw->out.buf;
749
750
 
750
- if (0 < len) {
751
- len--;
752
- }
753
- oj_dump_raw(sw->out.buf, len, out);
751
+ if (0 < len) {
752
+ len--;
753
+ }
754
+ oj_dump_raw(sw->out.buf, len, out);
754
755
  } else {
755
- volatile VALUE jv;
756
-
757
- if (Yes == out->opts->trace) {
758
- oj_trace("raw_json", obj, __FILE__, __LINE__, depth + 1, TraceRubyIn);
759
- }
760
- jv = rb_funcall(obj, oj_raw_json_id, 2, RB_INT2NUM(depth), RB_INT2NUM(out->indent));
761
- if (Yes == out->opts->trace) {
762
- oj_trace("raw_json", obj, __FILE__, __LINE__, depth + 1, TraceRubyOut);
763
- }
764
- oj_dump_raw(rb_string_value_ptr((VALUE*)&jv), (size_t)RSTRING_LEN(jv), out);
756
+ volatile VALUE jv;
757
+
758
+ if (Yes == out->opts->trace) {
759
+ oj_trace("raw_json", obj, __FILE__, __LINE__, depth + 1, TraceRubyIn);
760
+ }
761
+ jv = rb_funcall(obj, oj_raw_json_id, 2, RB_INT2NUM(depth), RB_INT2NUM(out->indent));
762
+ if (Yes == out->opts->trace) {
763
+ oj_trace("raw_json", obj, __FILE__, __LINE__, depth + 1, TraceRubyOut);
764
+ }
765
+ oj_dump_raw(rb_string_value_ptr((VALUE *)&jv), (size_t)RSTRING_LEN(jv), out);
765
766
  }
766
767
  }
767
768
 
768
- void
769
- oj_dump_cstr(const char *str, size_t cnt, bool is_sym, bool escape1, Out out) {
770
- size_t size;
771
- char *cmap;
772
- const char *orig = str;
769
+ void oj_dump_cstr(const char *str, size_t cnt, bool is_sym, bool escape1, Out out) {
770
+ size_t size;
771
+ char * cmap;
772
+ const char *orig = str;
773
+ bool has_hi = false;
773
774
 
774
775
  switch (out->opts->escape_mode) {
775
776
  case NLEsc:
776
- cmap = newline_friendly_chars;
777
- size = newline_friendly_size((uint8_t*)str, cnt);
778
- break;
777
+ cmap = newline_friendly_chars;
778
+ size = newline_friendly_size((uint8_t *)str, cnt);
779
+ break;
779
780
  case ASCIIEsc:
780
- cmap = ascii_friendly_chars;
781
- size = ascii_friendly_size((uint8_t*)str, cnt);
782
- break;
781
+ cmap = ascii_friendly_chars;
782
+ size = ascii_friendly_size((uint8_t *)str, cnt);
783
+ break;
783
784
  case XSSEsc:
784
- cmap = xss_friendly_chars;
785
- size = xss_friendly_size((uint8_t*)str, cnt);
786
- break;
785
+ cmap = xss_friendly_chars;
786
+ size = xss_friendly_size((uint8_t *)str, cnt);
787
+ break;
787
788
  case JXEsc:
788
- cmap = hixss_friendly_chars;
789
- size = hixss_friendly_size((uint8_t*)str, cnt);
790
- break;
791
- case RailsXEsc:
792
- cmap = rails_xss_friendly_chars;
793
- size = rails_xss_friendly_size((uint8_t*)str, cnt);
794
- break;
789
+ cmap = hixss_friendly_chars;
790
+ size = hixss_friendly_size((uint8_t *)str, cnt);
791
+ break;
792
+ case RailsXEsc: {
793
+ long sz;
794
+
795
+ cmap = rails_xss_friendly_chars;
796
+ sz = rails_xss_friendly_size((uint8_t *)str, cnt);
797
+ if (sz < 0) {
798
+ has_hi = true;
799
+ size = (size_t)-sz;
800
+ } else {
801
+ size = (size_t)sz;
802
+ }
803
+ break;
804
+ }
795
805
  case RailsEsc:
796
- cmap = rails_friendly_chars;
797
- size = rails_friendly_size((uint8_t*)str, cnt);
798
- break;
806
+ cmap = rails_friendly_chars;
807
+ size = rails_friendly_size((uint8_t *)str, cnt);
808
+ break;
799
809
  case JSONEsc:
800
- default:
801
- cmap = hibit_friendly_chars;
802
- size = hibit_friendly_size((uint8_t*)str, cnt);
810
+ default: cmap = hibit_friendly_chars; size = hibit_friendly_size((uint8_t *)str, cnt);
803
811
  }
804
812
  assure_size(out, size + BUFFER_EXTRA);
805
813
  *out->cur++ = '"';
806
814
 
807
815
  if (escape1) {
808
- *out->cur++ = '\\';
809
- *out->cur++ = 'u';
810
- *out->cur++ = '0';
811
- *out->cur++ = '0';
812
- dump_hex((uint8_t)*str, out);
813
- cnt--;
814
- size--;
815
- str++;
816
- is_sym = 0; // just to make sure
816
+ *out->cur++ = '\\';
817
+ *out->cur++ = 'u';
818
+ *out->cur++ = '0';
819
+ *out->cur++ = '0';
820
+ dump_hex((uint8_t)*str, out);
821
+ cnt--;
822
+ size--;
823
+ str++;
824
+ is_sym = 0; // just to make sure
817
825
  }
818
- if (cnt == size) {
819
- if (is_sym) {
820
- *out->cur++ = ':';
821
- }
822
- for (; '\0' != *str; str++) {
823
- *out->cur++ = *str;
824
- }
825
- *out->cur++ = '"';
826
+ if (cnt == size && !has_hi) {
827
+ if (is_sym) {
828
+ *out->cur++ = ':';
829
+ }
830
+ for (; '\0' != *str; str++) {
831
+ *out->cur++ = *str;
832
+ }
833
+ *out->cur++ = '"';
826
834
  } else {
827
- const char *end = str + cnt;
828
- const char *check_start = str;
829
-
830
- if (is_sym) {
831
- *out->cur++ = ':';
832
- }
833
- for (; str < end; str++) {
834
- switch (cmap[(uint8_t)*str]) {
835
- case '1':
836
- if ((JXEsc == out->opts->escape_mode || RailsXEsc == out->opts->escape_mode) && check_start <= str) {
837
- if (0 != (0x80 & (uint8_t)*str)) {
838
- if (0xC0 == (0xC0 & (uint8_t)*str)) {
839
- check_start = check_unicode(str, end, orig);
840
- } else {
841
- raise_invalid_unicode(orig, (int)(end - orig), (int)(str - orig));
842
- }
843
- }
844
- }
845
- *out->cur++ = *str;
846
- break;
847
- case '2':
848
- *out->cur++ = '\\';
849
- switch (*str) {
850
- case '\\': *out->cur++ = '\\'; break;
851
- case '\b': *out->cur++ = 'b'; break;
852
- case '\t': *out->cur++ = 't'; break;
853
- case '\n': *out->cur++ = 'n'; break;
854
- case '\f': *out->cur++ = 'f'; break;
855
- case '\r': *out->cur++ = 'r'; break;
856
- default: *out->cur++ = *str; break;
857
- }
858
- break;
859
- case '3': // Unicode
860
- if (0xe2 == (uint8_t)*str && (JXEsc == out->opts->escape_mode || RailsXEsc == out->opts->escape_mode) && 2 <= end - str) {
861
- if (0x80 == (uint8_t)str[1] && (0xa8 == (uint8_t)str[2] || 0xa9 == (uint8_t)str[2])) {
862
- str = dump_unicode(str, end, out, orig);
863
- } else {
864
- check_start = check_unicode(str, end, orig);
865
- *out->cur++ = *str;
866
- }
867
- break;
868
- }
869
- str = dump_unicode(str, end, out, orig);
870
- break;
871
- case '6': // control characters
872
- if (*(uint8_t*)str < 0x80) {
873
- *out->cur++ = '\\';
874
- *out->cur++ = 'u';
875
- *out->cur++ = '0';
876
- *out->cur++ = '0';
877
- dump_hex((uint8_t)*str, out);
878
- } else {
879
- if (0xe2 == (uint8_t)*str && (JXEsc == out->opts->escape_mode || RailsXEsc == out->opts->escape_mode) && 2 <= end - str) {
880
- if (0x80 == (uint8_t)str[1] && (0xa8 == (uint8_t)str[2] || 0xa9 == (uint8_t)str[2])) {
881
- str = dump_unicode(str, end, out, orig);
882
- } else {
883
- check_start = check_unicode(str, end, orig);
884
- *out->cur++ = *str;
885
- }
886
- break;
887
- }
888
- str = dump_unicode(str, end, out, orig);
889
- }
890
- break;
891
- default:
892
- break; // ignore, should never happen if the table is correct
893
- }
894
- }
895
- *out->cur++ = '"';
835
+ const char *end = str + cnt;
836
+ const char *check_start = str;
837
+
838
+ if (is_sym) {
839
+ *out->cur++ = ':';
840
+ }
841
+ for (; str < end; str++) {
842
+ switch (cmap[(uint8_t)*str]) {
843
+ case '1':
844
+ if ((JXEsc == out->opts->escape_mode || RailsXEsc == out->opts->escape_mode) &&
845
+ check_start <= str) {
846
+ if (0 != (0x80 & (uint8_t)*str)) {
847
+ if (0xC0 == (0xC0 & (uint8_t)*str)) {
848
+ check_start = check_unicode(str, end, orig);
849
+ } else {
850
+ raise_invalid_unicode(orig, (int)(end - orig), (int)(str - orig));
851
+ }
852
+ }
853
+ }
854
+ *out->cur++ = *str;
855
+ break;
856
+ case '2':
857
+ *out->cur++ = '\\';
858
+ switch (*str) {
859
+ case '\\': *out->cur++ = '\\'; break;
860
+ case '\b': *out->cur++ = 'b'; break;
861
+ case '\t': *out->cur++ = 't'; break;
862
+ case '\n': *out->cur++ = 'n'; break;
863
+ case '\f': *out->cur++ = 'f'; break;
864
+ case '\r': *out->cur++ = 'r'; break;
865
+ default: *out->cur++ = *str; break;
866
+ }
867
+ break;
868
+ case '3': // Unicode
869
+ if (0xe2 == (uint8_t)*str &&
870
+ (JXEsc == out->opts->escape_mode || RailsXEsc == out->opts->escape_mode) &&
871
+ 2 <= end - str) {
872
+ if (0x80 == (uint8_t)str[1] &&
873
+ (0xa8 == (uint8_t)str[2] || 0xa9 == (uint8_t)str[2])) {
874
+ str = dump_unicode(str, end, out, orig);
875
+ } else {
876
+ check_start = check_unicode(str, end, orig);
877
+ *out->cur++ = *str;
878
+ }
879
+ break;
880
+ }
881
+ str = dump_unicode(str, end, out, orig);
882
+ break;
883
+ case '6': // control characters
884
+ if (*(uint8_t *)str < 0x80) {
885
+ *out->cur++ = '\\';
886
+ *out->cur++ = 'u';
887
+ *out->cur++ = '0';
888
+ *out->cur++ = '0';
889
+ dump_hex((uint8_t)*str, out);
890
+ } else {
891
+ if (0xe2 == (uint8_t)*str &&
892
+ (JXEsc == out->opts->escape_mode || RailsXEsc == out->opts->escape_mode) &&
893
+ 2 <= end - str) {
894
+ if (0x80 == (uint8_t)str[1] &&
895
+ (0xa8 == (uint8_t)str[2] || 0xa9 == (uint8_t)str[2])) {
896
+ str = dump_unicode(str, end, out, orig);
897
+ } else {
898
+ check_start = check_unicode(str, end, orig);
899
+ *out->cur++ = *str;
900
+ }
901
+ break;
902
+ }
903
+ str = dump_unicode(str, end, out, orig);
904
+ }
905
+ break;
906
+ default: break; // ignore, should never happen if the table is correct
907
+ }
908
+ }
909
+ *out->cur++ = '"';
896
910
  }
897
- if ((JXEsc == out->opts->escape_mode || RailsXEsc == out->opts->escape_mode) && 0 < str - orig && 0 != (0x80 & *(str - 1))) {
898
- uint8_t c = (uint8_t)*(str - 1);
899
- int i;
900
- int scnt = (int)(str - orig);
901
-
902
- // Last utf-8 characters must be 0x10xxxxxx. The start must be
903
- // 0x110xxxxx for 2 characters, 0x1110xxxx for 3, and 0x11110xxx for
904
- // 4.
905
- if (0 != (0x40 & c)) {
906
- debug_raise(orig, cnt, __LINE__);
907
- }
908
- for (i = 1; i < (int)scnt && i < 4; i++) {
909
- c = str[-1 - i];
910
- if (0x80 != (0xC0 & c)) {
911
- switch (i) {
912
- case 1:
913
- if (0xC0 != (0xE0 & c)) {
914
- debug_raise(orig, cnt, __LINE__);
915
- }
916
- break;
917
- case 2:
918
- if (0xE0 != (0xF0 & c)) {
919
- debug_raise(orig, cnt, __LINE__);
920
- }
921
- break;
922
- case 3:
923
- if (0xF0 != (0xF8 & c)) {
924
- debug_raise(orig, cnt, __LINE__);
925
- }
926
- break;
927
- default: // can't get here
928
- break;
929
- }
930
- break;
931
- }
932
- }
933
- if (i == (int)scnt || 4 <= i) {
934
- debug_raise(orig, cnt, __LINE__);
935
- }
911
+ if ((JXEsc == out->opts->escape_mode || RailsXEsc == out->opts->escape_mode) &&
912
+ 0 < str - orig && 0 != (0x80 & *(str - 1))) {
913
+ uint8_t c = (uint8_t) * (str - 1);
914
+ int i;
915
+ int scnt = (int)(str - orig);
916
+
917
+ // Last utf-8 characters must be 0x10xxxxxx. The start must be
918
+ // 0x110xxxxx for 2 characters, 0x1110xxxx for 3, and 0x11110xxx for
919
+ // 4.
920
+ if (0 != (0x40 & c)) {
921
+ debug_raise(orig, cnt, __LINE__);
922
+ }
923
+ for (i = 1; i < (int)scnt && i < 4; i++) {
924
+ c = str[-1 - i];
925
+ if (0x80 != (0xC0 & c)) {
926
+ switch (i) {
927
+ case 1:
928
+ if (0xC0 != (0xE0 & c)) {
929
+ debug_raise(orig, cnt, __LINE__);
930
+ }
931
+ break;
932
+ case 2:
933
+ if (0xE0 != (0xF0 & c)) {
934
+ debug_raise(orig, cnt, __LINE__);
935
+ }
936
+ break;
937
+ case 3:
938
+ if (0xF0 != (0xF8 & c)) {
939
+ debug_raise(orig, cnt, __LINE__);
940
+ }
941
+ break;
942
+ default: // can't get here
943
+ break;
944
+ }
945
+ break;
946
+ }
947
+ }
948
+ if (i == (int)scnt || 4 <= i) {
949
+ debug_raise(orig, cnt, __LINE__);
950
+ }
936
951
  }
937
952
  *out->cur = '\0';
938
953
  }
939
954
 
940
- void
941
- oj_dump_class(VALUE obj, int depth, Out out, bool as_ok) {
942
- const char *s = rb_class2name(obj);
955
+ void oj_dump_class(VALUE obj, int depth, Out out, bool as_ok) {
956
+ const char *s = rb_class2name(obj);
943
957
 
944
958
  oj_dump_cstr(s, strlen(s), 0, 0, out);
945
959
  }
946
960
 
947
- void
948
- oj_dump_obj_to_s(VALUE obj, Out out) {
949
- volatile VALUE rstr = rb_funcall(obj, oj_to_s_id, 0);
961
+ void oj_dump_obj_to_s(VALUE obj, Out out) {
962
+ volatile VALUE rstr = rb_funcall(obj, oj_to_s_id, 0);
950
963
 
951
- oj_dump_cstr(rb_string_value_ptr((VALUE*)&rstr), (int)RSTRING_LEN(rstr), 0, 0, out);
964
+ oj_dump_cstr(rb_string_value_ptr((VALUE *)&rstr), (int)RSTRING_LEN(rstr), 0, 0, out);
952
965
  }
953
966
 
954
- void
955
- oj_dump_raw(const char *str, size_t cnt, Out out) {
967
+ void oj_dump_raw(const char *str, size_t cnt, Out out) {
956
968
  assure_size(out, cnt + 10);
957
969
  memcpy(out->cur, str, cnt);
958
970
  out->cur += cnt;
959
971
  *out->cur = '\0';
960
972
  }
961
973
 
962
- void
963
- oj_grow_out(Out out, size_t len) {
964
- size_t size = out->end - out->buf;
965
- long pos = out->cur - out->buf;
966
- char *buf = out->buf;
974
+ void oj_grow_out(Out out, size_t len) {
975
+ size_t size = out->end - out->buf;
976
+ long pos = out->cur - out->buf;
977
+ char * buf = out->buf;
967
978
 
968
979
  size *= 2;
969
980
  if (size <= len * 2 + pos) {
970
- size += len;
981
+ size += len;
971
982
  }
972
983
  if (out->allocated) {
973
- REALLOC_N(buf, char, (size + BUFFER_EXTRA));
984
+ REALLOC_N(buf, char, (size + BUFFER_EXTRA));
974
985
  } else {
975
- buf = ALLOC_N(char, (size + BUFFER_EXTRA));
976
- out->allocated = true;
977
- memcpy(buf, out->buf, out->end - out->buf + BUFFER_EXTRA);
986
+ buf = ALLOC_N(char, (size + BUFFER_EXTRA));
987
+ out->allocated = true;
988
+ memcpy(buf, out->buf, out->end - out->buf + BUFFER_EXTRA);
978
989
  }
979
990
  if (0 == buf) {
980
- rb_raise(rb_eNoMemError, "Failed to create string. [%d:%s]", ENOSPC, strerror(ENOSPC));
991
+ rb_raise(rb_eNoMemError, "Failed to create string. [%d:%s]", ENOSPC, strerror(ENOSPC));
981
992
  }
982
993
  out->buf = buf;
983
994
  out->end = buf + size;
984
995
  out->cur = out->buf + pos;
985
996
  }
986
997
 
987
- void
988
- oj_dump_nil(VALUE obj, int depth, Out out, bool as_ok) {
998
+ void oj_dump_nil(VALUE obj, int depth, Out out, bool as_ok) {
989
999
  assure_size(out, 4);
990
1000
  *out->cur++ = 'n';
991
1001
  *out->cur++ = 'u';
992
1002
  *out->cur++ = 'l';
993
1003
  *out->cur++ = 'l';
994
- *out->cur = '\0';
1004
+ *out->cur = '\0';
995
1005
  }
996
1006
 
997
- void
998
- oj_dump_true(VALUE obj, int depth, Out out, bool as_ok) {
1007
+ void oj_dump_true(VALUE obj, int depth, Out out, bool as_ok) {
999
1008
  assure_size(out, 4);
1000
1009
  *out->cur++ = 't';
1001
1010
  *out->cur++ = 'r';
1002
1011
  *out->cur++ = 'u';
1003
1012
  *out->cur++ = 'e';
1004
- *out->cur = '\0';
1013
+ *out->cur = '\0';
1005
1014
  }
1006
1015
 
1007
- void
1008
- oj_dump_false(VALUE obj, int depth, Out out, bool as_ok) {
1016
+ void oj_dump_false(VALUE obj, int depth, Out out, bool as_ok) {
1009
1017
  assure_size(out, 5);
1010
1018
  *out->cur++ = 'f';
1011
1019
  *out->cur++ = 'a';
1012
1020
  *out->cur++ = 'l';
1013
1021
  *out->cur++ = 's';
1014
1022
  *out->cur++ = 'e';
1015
- *out->cur = '\0';
1023
+ *out->cur = '\0';
1016
1024
  }
1017
1025
 
1018
- void
1019
- oj_dump_fixnum(VALUE obj, int depth, Out out, bool as_ok) {
1020
- char buf[32];
1021
- char *b = buf + sizeof(buf) - 1;
1022
- long long num = rb_num2ll(obj);
1023
- int neg = 0;
1024
- bool dump_as_string = false;
1026
+ void oj_dump_fixnum(VALUE obj, int depth, Out out, bool as_ok) {
1027
+ char buf[32];
1028
+ char * b = buf + sizeof(buf) - 1;
1029
+ long long num = rb_num2ll(obj);
1030
+ int neg = 0;
1031
+ bool dump_as_string = false;
1025
1032
 
1026
1033
  if (out->opts->int_range_max != 0 && out->opts->int_range_min != 0 &&
1027
- (out->opts->int_range_max < num || out->opts->int_range_min > num)) {
1028
- dump_as_string = true;
1034
+ (out->opts->int_range_max < num || out->opts->int_range_min > num)) {
1035
+ dump_as_string = true;
1029
1036
  }
1030
1037
  if (0 > num) {
1031
- neg = 1;
1032
- num = -num;
1038
+ neg = 1;
1039
+ num = -num;
1033
1040
  }
1034
1041
  *b-- = '\0';
1035
1042
 
1036
1043
  if (dump_as_string) {
1037
- *b-- = '"';
1044
+ *b-- = '"';
1038
1045
  }
1039
1046
  if (0 < num) {
1040
- for (; 0 < num; num /= 10, b--) {
1041
- *b = (num % 10) + '0';
1042
- }
1043
- if (neg) {
1044
- *b = '-';
1045
- } else {
1046
- b++;
1047
- }
1047
+ for (; 0 < num; num /= 10, b--) {
1048
+ *b = (num % 10) + '0';
1049
+ }
1050
+ if (neg) {
1051
+ *b = '-';
1052
+ } else {
1053
+ b++;
1054
+ }
1048
1055
  } else {
1049
- *b = '0';
1056
+ *b = '0';
1050
1057
  }
1051
1058
  if (dump_as_string) {
1052
- *--b = '"';
1059
+ *--b = '"';
1053
1060
  }
1054
1061
  assure_size(out, (sizeof(buf) - (b - buf)));
1055
1062
  for (; '\0' != *b; b++) {
1056
- *out->cur++ = *b;
1063
+ *out->cur++ = *b;
1057
1064
  }
1058
1065
  *out->cur = '\0';
1059
1066
  }
1060
1067
 
1061
- void
1062
- oj_dump_bignum(VALUE obj, int depth, Out out, bool as_ok) {
1063
- volatile VALUE rs = rb_big2str(obj, 10);
1064
- int cnt = (int)RSTRING_LEN(rs);
1065
- bool dump_as_string = false;
1068
+ void oj_dump_bignum(VALUE obj, int depth, Out out, bool as_ok) {
1069
+ volatile VALUE rs = rb_big2str(obj, 10);
1070
+ int cnt = (int)RSTRING_LEN(rs);
1071
+ bool dump_as_string = false;
1066
1072
 
1067
- if (out->opts->int_range_max != 0 || out->opts->int_range_min != 0) { // Bignum cannot be inside of Fixnum range
1068
- dump_as_string = true;
1069
- assure_size(out, cnt + 2);
1070
- *out->cur++ = '"';
1073
+ if (out->opts->int_range_max != 0 ||
1074
+ out->opts->int_range_min != 0) { // Bignum cannot be inside of Fixnum range
1075
+ dump_as_string = true;
1076
+ assure_size(out, cnt + 2);
1077
+ *out->cur++ = '"';
1071
1078
  } else {
1072
- assure_size(out, cnt);
1079
+ assure_size(out, cnt);
1073
1080
  }
1074
- memcpy(out->cur, rb_string_value_ptr((VALUE*)&rs), cnt);
1081
+ memcpy(out->cur, rb_string_value_ptr((VALUE *)&rs), cnt);
1075
1082
  out->cur += cnt;
1076
1083
  if (dump_as_string) {
1077
- *out->cur++ = '"';
1084
+ *out->cur++ = '"';
1078
1085
  }
1079
1086
  *out->cur = '\0';
1080
1087
  }
1081
1088
 
1082
1089
  // Removed dependencies on math due to problems with CentOS 5.4.
1083
- void
1084
- oj_dump_float(VALUE obj, int depth, Out out, bool as_ok) {
1085
- char buf[64];
1086
- char *b;
1087
- double d = rb_num2dbl(obj);
1088
- int cnt = 0;
1090
+ void oj_dump_float(VALUE obj, int depth, Out out, bool as_ok) {
1091
+ char buf[64];
1092
+ char * b;
1093
+ double d = rb_num2dbl(obj);
1094
+ int cnt = 0;
1089
1095
 
1090
1096
  if (0.0 == d) {
1091
- b = buf;
1092
- *b++ = '0';
1093
- *b++ = '.';
1094
- *b++ = '0';
1095
- *b++ = '\0';
1096
- cnt = 3;
1097
+ b = buf;
1098
+ *b++ = '0';
1099
+ *b++ = '.';
1100
+ *b++ = '0';
1101
+ *b++ = '\0';
1102
+ cnt = 3;
1097
1103
  } else if (OJ_INFINITY == d) {
1098
- if (ObjectMode == out->opts->mode) {
1099
- strcpy(buf, inf_val);
1100
- cnt = sizeof(inf_val) - 1;
1101
- } else {
1102
- NanDump nd = out->opts->dump_opts.nan_dump;
1103
-
1104
- if (AutoNan == nd) {
1105
- switch (out->opts->mode) {
1106
- case CompatMode: nd = WordNan; break;
1107
- case StrictMode: nd = RaiseNan; break;
1108
- case NullMode: nd = NullNan; break;
1109
- case CustomMode: nd = NullNan; break;
1110
- default: break;
1111
- }
1112
- }
1113
- switch (nd) {
1114
- case RaiseNan:
1115
- raise_strict(obj);
1116
- break;
1117
- case WordNan:
1118
- strcpy(buf, "Infinity");
1119
- cnt = 8;
1120
- break;
1121
- case NullNan:
1122
- strcpy(buf, "null");
1123
- cnt = 4;
1124
- break;
1125
- case HugeNan:
1126
- default:
1127
- strcpy(buf, inf_val);
1128
- cnt = sizeof(inf_val) - 1;
1129
- break;
1130
- }
1131
- }
1104
+ if (ObjectMode == out->opts->mode) {
1105
+ strcpy(buf, inf_val);
1106
+ cnt = sizeof(inf_val) - 1;
1107
+ } else {
1108
+ NanDump nd = out->opts->dump_opts.nan_dump;
1109
+
1110
+ if (AutoNan == nd) {
1111
+ switch (out->opts->mode) {
1112
+ case CompatMode: nd = WordNan; break;
1113
+ case StrictMode: nd = RaiseNan; break;
1114
+ case NullMode: nd = NullNan; break;
1115
+ case CustomMode: nd = NullNan; break;
1116
+ default: break;
1117
+ }
1118
+ }
1119
+ switch (nd) {
1120
+ case RaiseNan: raise_strict(obj); break;
1121
+ case WordNan:
1122
+ strcpy(buf, "Infinity");
1123
+ cnt = 8;
1124
+ break;
1125
+ case NullNan:
1126
+ strcpy(buf, "null");
1127
+ cnt = 4;
1128
+ break;
1129
+ case HugeNan:
1130
+ default:
1131
+ strcpy(buf, inf_val);
1132
+ cnt = sizeof(inf_val) - 1;
1133
+ break;
1134
+ }
1135
+ }
1132
1136
  } else if (-OJ_INFINITY == d) {
1133
- if (ObjectMode == out->opts->mode) {
1134
- strcpy(buf, ninf_val);
1135
- cnt = sizeof(ninf_val) - 1;
1136
- } else {
1137
- NanDump nd = out->opts->dump_opts.nan_dump;
1138
-
1139
- if (AutoNan == nd) {
1140
- switch (out->opts->mode) {
1141
- case CompatMode: nd = WordNan; break;
1142
- case StrictMode: nd = RaiseNan; break;
1143
- case NullMode: nd = NullNan; break;
1144
- default: break;
1145
- }
1146
- }
1147
- switch (nd) {
1148
- case RaiseNan:
1149
- raise_strict(obj);
1150
- break;
1151
- case WordNan:
1152
- strcpy(buf, "-Infinity");
1153
- cnt = 9;
1154
- break;
1155
- case NullNan:
1156
- strcpy(buf, "null");
1157
- cnt = 4;
1158
- break;
1159
- case HugeNan:
1160
- default:
1161
- strcpy(buf, ninf_val);
1162
- cnt = sizeof(ninf_val) - 1;
1163
- break;
1164
- }
1165
- }
1137
+ if (ObjectMode == out->opts->mode) {
1138
+ strcpy(buf, ninf_val);
1139
+ cnt = sizeof(ninf_val) - 1;
1140
+ } else {
1141
+ NanDump nd = out->opts->dump_opts.nan_dump;
1142
+
1143
+ if (AutoNan == nd) {
1144
+ switch (out->opts->mode) {
1145
+ case CompatMode: nd = WordNan; break;
1146
+ case StrictMode: nd = RaiseNan; break;
1147
+ case NullMode: nd = NullNan; break;
1148
+ default: break;
1149
+ }
1150
+ }
1151
+ switch (nd) {
1152
+ case RaiseNan: raise_strict(obj); break;
1153
+ case WordNan:
1154
+ strcpy(buf, "-Infinity");
1155
+ cnt = 9;
1156
+ break;
1157
+ case NullNan:
1158
+ strcpy(buf, "null");
1159
+ cnt = 4;
1160
+ break;
1161
+ case HugeNan:
1162
+ default:
1163
+ strcpy(buf, ninf_val);
1164
+ cnt = sizeof(ninf_val) - 1;
1165
+ break;
1166
+ }
1167
+ }
1166
1168
  } else if (isnan(d)) {
1167
- if (ObjectMode == out->opts->mode) {
1168
- strcpy(buf, nan_val);
1169
- cnt = sizeof(ninf_val) - 1;
1170
- } else {
1171
- NanDump nd = out->opts->dump_opts.nan_dump;
1172
-
1173
- if (AutoNan == nd) {
1174
- switch (out->opts->mode) {
1175
- case ObjectMode: nd = HugeNan; break;
1176
- case StrictMode: nd = RaiseNan; break;
1177
- case NullMode: nd = NullNan; break;
1178
- default: break;
1179
- }
1180
- }
1181
- switch (nd) {
1182
- case RaiseNan:
1183
- raise_strict(obj);
1184
- break;
1185
- case WordNan:
1186
- strcpy(buf, "NaN");
1187
- cnt = 3;
1188
- break;
1189
- case NullNan:
1190
- strcpy(buf, "null");
1191
- cnt = 4;
1192
- break;
1193
- case HugeNan:
1194
- default:
1195
- strcpy(buf, nan_val);
1196
- cnt = sizeof(nan_val) - 1;
1197
- break;
1198
- }
1199
- }
1169
+ if (ObjectMode == out->opts->mode) {
1170
+ strcpy(buf, nan_val);
1171
+ cnt = sizeof(ninf_val) - 1;
1172
+ } else {
1173
+ NanDump nd = out->opts->dump_opts.nan_dump;
1174
+
1175
+ if (AutoNan == nd) {
1176
+ switch (out->opts->mode) {
1177
+ case ObjectMode: nd = HugeNan; break;
1178
+ case StrictMode: nd = RaiseNan; break;
1179
+ case NullMode: nd = NullNan; break;
1180
+ default: break;
1181
+ }
1182
+ }
1183
+ switch (nd) {
1184
+ case RaiseNan: raise_strict(obj); break;
1185
+ case WordNan:
1186
+ strcpy(buf, "NaN");
1187
+ cnt = 3;
1188
+ break;
1189
+ case NullNan:
1190
+ strcpy(buf, "null");
1191
+ cnt = 4;
1192
+ break;
1193
+ case HugeNan:
1194
+ default:
1195
+ strcpy(buf, nan_val);
1196
+ cnt = sizeof(nan_val) - 1;
1197
+ break;
1198
+ }
1199
+ }
1200
1200
  } else if (d == (double)(long long int)d) {
1201
- cnt = snprintf(buf, sizeof(buf), "%.1f", d);
1201
+ cnt = snprintf(buf, sizeof(buf), "%.1f", d);
1202
1202
  } else if (0 == out->opts->float_prec) {
1203
- volatile VALUE rstr = rb_funcall(obj, oj_to_s_id, 0);
1204
-
1205
- cnt = (int)RSTRING_LEN(rstr);
1206
- if ((int)sizeof(buf) <= cnt) {
1207
- cnt = sizeof(buf) - 1;
1208
- }
1209
- strncpy(buf, rb_string_value_ptr((VALUE*)&rstr), cnt);
1210
- buf[cnt] = '\0';
1203
+ volatile VALUE rstr = rb_funcall(obj, oj_to_s_id, 0);
1204
+
1205
+ cnt = (int)RSTRING_LEN(rstr);
1206
+ if ((int)sizeof(buf) <= cnt) {
1207
+ cnt = sizeof(buf) - 1;
1208
+ }
1209
+ strncpy(buf, rb_string_value_ptr((VALUE *)&rstr), cnt);
1210
+ buf[cnt] = '\0';
1211
1211
  } else {
1212
- cnt = oj_dump_float_printf(buf, sizeof(buf), obj, d, out->opts->float_fmt);
1212
+ cnt = oj_dump_float_printf(buf, sizeof(buf), obj, d, out->opts->float_fmt);
1213
1213
  }
1214
1214
  assure_size(out, cnt);
1215
1215
  for (b = buf; '\0' != *b; b++) {
1216
- *out->cur++ = *b;
1216
+ *out->cur++ = *b;
1217
1217
  }
1218
1218
  *out->cur = '\0';
1219
1219
  }
1220
1220
 
1221
- int
1222
- oj_dump_float_printf(char *buf, size_t blen, VALUE obj, double d, const char *format) {
1223
- int cnt = snprintf(buf, blen, format, d);
1221
+ int oj_dump_float_printf(char *buf, size_t blen, VALUE obj, double d, const char *format) {
1222
+ int cnt = snprintf(buf, blen, format, d);
1224
1223
 
1225
1224
  // Round off issues at 16 significant digits so check for obvious ones of
1226
1225
  // 0001 and 9999.
1227
1226
  if (17 <= cnt && (0 == strcmp("0001", buf + cnt - 4) || 0 == strcmp("9999", buf + cnt - 4))) {
1228
- volatile VALUE rstr = rb_funcall(obj, oj_to_s_id, 0);
1227
+ volatile VALUE rstr = rb_funcall(obj, oj_to_s_id, 0);
1229
1228
 
1230
- strcpy(buf, rb_string_value_ptr((VALUE*)&rstr));
1231
- cnt = (int)RSTRING_LEN(rstr);
1229
+ strcpy(buf, rb_string_value_ptr((VALUE *)&rstr));
1230
+ cnt = (int)RSTRING_LEN(rstr);
1232
1231
  }
1233
1232
  return cnt;
1234
1233
  }
1235
1234
 
1236
- bool
1237
- oj_dump_ignore(Options opts, VALUE obj) {
1235
+ bool oj_dump_ignore(Options opts, VALUE obj) {
1238
1236
  if (NULL != opts->ignore && (ObjectMode == opts->mode || CustomMode == opts->mode)) {
1239
- VALUE *vp = opts->ignore;
1240
- VALUE clas = rb_obj_class(obj);
1241
-
1242
- for (; Qnil != *vp; vp++) {
1243
- if (clas == *vp) {
1244
- return true;
1245
- }
1246
- }
1237
+ VALUE *vp = opts->ignore;
1238
+ VALUE clas = rb_obj_class(obj);
1239
+
1240
+ for (; Qnil != *vp; vp++) {
1241
+ if (clas == *vp) {
1242
+ return true;
1243
+ }
1244
+ }
1247
1245
  }
1248
1246
  return false;
1249
1247
  }