oj 3.10.6 → 3.12.1

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 +176 -181
  11. data/ext/oj/custom.c +800 -864
  12. data/ext/oj/dump.c +774 -776
  13. data/ext/oj/dump.h +50 -55
  14. data/ext/oj/dump_compat.c +2 -4
  15. data/ext/oj/dump_leaf.c +118 -162
  16. data/ext/oj/dump_object.c +610 -632
  17. data/ext/oj/dump_strict.c +319 -331
  18. data/ext/oj/encode.h +4 -33
  19. data/ext/oj/err.c +40 -29
  20. data/ext/oj/err.h +25 -44
  21. data/ext/oj/extconf.rb +2 -1
  22. data/ext/oj/fast.c +1054 -1081
  23. data/ext/oj/hash.c +102 -97
  24. data/ext/oj/hash.h +10 -35
  25. data/ext/oj/hash_test.c +451 -472
  26. data/ext/oj/mimic_json.c +415 -402
  27. data/ext/oj/object.c +588 -532
  28. data/ext/oj/odd.c +124 -132
  29. data/ext/oj/odd.h +28 -29
  30. data/ext/oj/oj.c +1186 -906
  31. data/ext/oj/oj.h +289 -298
  32. data/ext/oj/parse.c +946 -870
  33. data/ext/oj/parse.h +81 -79
  34. data/ext/oj/rails.c +837 -842
  35. data/ext/oj/rails.h +8 -11
  36. data/ext/oj/reader.c +139 -147
  37. data/ext/oj/reader.h +68 -84
  38. data/ext/oj/resolve.c +44 -47
  39. data/ext/oj/resolve.h +4 -6
  40. data/ext/oj/rxclass.c +69 -73
  41. data/ext/oj/rxclass.h +13 -14
  42. data/ext/oj/saj.c +453 -484
  43. data/ext/oj/scp.c +88 -113
  44. data/ext/oj/sparse.c +783 -714
  45. data/ext/oj/stream_writer.c +123 -157
  46. data/ext/oj/strict.c +133 -106
  47. data/ext/oj/string_writer.c +199 -247
  48. data/ext/oj/trace.c +34 -41
  49. data/ext/oj/trace.h +15 -15
  50. data/ext/oj/util.c +104 -104
  51. data/ext/oj/util.h +4 -3
  52. data/ext/oj/val_stack.c +48 -76
  53. data/ext/oj/val_stack.h +80 -115
  54. data/ext/oj/wab.c +321 -325
  55. data/lib/oj.rb +0 -8
  56. data/lib/oj/bag.rb +1 -0
  57. data/lib/oj/easy_hash.rb +5 -4
  58. data/lib/oj/mimic.rb +47 -13
  59. data/lib/oj/version.rb +1 -1
  60. data/pages/Modes.md +1 -0
  61. data/pages/Options.md +23 -11
  62. data/test/activerecord/result_test.rb +7 -2
  63. data/test/foo.rb +8 -40
  64. data/test/helper.rb +10 -0
  65. data/test/json_gem/json_common_interface_test.rb +8 -3
  66. data/test/json_gem/json_generator_test.rb +15 -3
  67. data/test/json_gem/test_helper.rb +8 -0
  68. data/test/perf.rb +1 -1
  69. data/test/perf_scp.rb +11 -10
  70. data/test/perf_strict.rb +17 -23
  71. data/test/prec.rb +23 -0
  72. data/test/sample_json.rb +1 -1
  73. data/test/test_compat.rb +16 -3
  74. data/test/test_custom.rb +11 -0
  75. data/test/test_fast.rb +32 -2
  76. data/test/test_generate.rb +21 -0
  77. data/test/test_hash.rb +10 -0
  78. data/test/test_rails.rb +9 -0
  79. data/test/test_scp.rb +1 -1
  80. data/test/test_various.rb +4 -2
  81. metadata +89 -85
data/ext/oj/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
  }