oj 3.10.7

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 (167) hide show
  1. checksums.yaml +7 -0
  2. data/LICENSE +21 -0
  3. data/README.md +104 -0
  4. data/ext/oj/buf.h +103 -0
  5. data/ext/oj/cache8.c +107 -0
  6. data/ext/oj/cache8.h +48 -0
  7. data/ext/oj/circarray.c +68 -0
  8. data/ext/oj/circarray.h +23 -0
  9. data/ext/oj/code.c +235 -0
  10. data/ext/oj/code.h +42 -0
  11. data/ext/oj/compat.c +299 -0
  12. data/ext/oj/custom.c +1218 -0
  13. data/ext/oj/dump.c +1249 -0
  14. data/ext/oj/dump.h +96 -0
  15. data/ext/oj/dump_compat.c +975 -0
  16. data/ext/oj/dump_leaf.c +252 -0
  17. data/ext/oj/dump_object.c +844 -0
  18. data/ext/oj/dump_strict.c +434 -0
  19. data/ext/oj/encode.h +45 -0
  20. data/ext/oj/err.c +57 -0
  21. data/ext/oj/err.h +70 -0
  22. data/ext/oj/extconf.rb +53 -0
  23. data/ext/oj/fast.c +1771 -0
  24. data/ext/oj/hash.c +163 -0
  25. data/ext/oj/hash.h +46 -0
  26. data/ext/oj/hash_test.c +512 -0
  27. data/ext/oj/mimic_json.c +890 -0
  28. data/ext/oj/object.c +775 -0
  29. data/ext/oj/odd.c +231 -0
  30. data/ext/oj/odd.h +44 -0
  31. data/ext/oj/oj.c +1723 -0
  32. data/ext/oj/oj.h +387 -0
  33. data/ext/oj/parse.c +1134 -0
  34. data/ext/oj/parse.h +112 -0
  35. data/ext/oj/rails.c +1528 -0
  36. data/ext/oj/rails.h +21 -0
  37. data/ext/oj/reader.c +231 -0
  38. data/ext/oj/reader.h +151 -0
  39. data/ext/oj/resolve.c +102 -0
  40. data/ext/oj/resolve.h +14 -0
  41. data/ext/oj/rxclass.c +147 -0
  42. data/ext/oj/rxclass.h +27 -0
  43. data/ext/oj/saj.c +714 -0
  44. data/ext/oj/scp.c +224 -0
  45. data/ext/oj/sparse.c +924 -0
  46. data/ext/oj/stream_writer.c +363 -0
  47. data/ext/oj/strict.c +212 -0
  48. data/ext/oj/string_writer.c +534 -0
  49. data/ext/oj/trace.c +79 -0
  50. data/ext/oj/trace.h +28 -0
  51. data/ext/oj/util.c +136 -0
  52. data/ext/oj/util.h +19 -0
  53. data/ext/oj/val_stack.c +118 -0
  54. data/ext/oj/val_stack.h +185 -0
  55. data/ext/oj/wab.c +631 -0
  56. data/lib/oj.rb +21 -0
  57. data/lib/oj/active_support_helper.rb +41 -0
  58. data/lib/oj/bag.rb +88 -0
  59. data/lib/oj/easy_hash.rb +52 -0
  60. data/lib/oj/error.rb +22 -0
  61. data/lib/oj/json.rb +176 -0
  62. data/lib/oj/mimic.rb +267 -0
  63. data/lib/oj/saj.rb +66 -0
  64. data/lib/oj/schandler.rb +142 -0
  65. data/lib/oj/state.rb +131 -0
  66. data/lib/oj/version.rb +5 -0
  67. data/pages/Advanced.md +22 -0
  68. data/pages/Compatibility.md +25 -0
  69. data/pages/Custom.md +23 -0
  70. data/pages/Encoding.md +65 -0
  71. data/pages/JsonGem.md +79 -0
  72. data/pages/Modes.md +155 -0
  73. data/pages/Options.md +287 -0
  74. data/pages/Rails.md +155 -0
  75. data/pages/Security.md +20 -0
  76. data/pages/WAB.md +13 -0
  77. data/test/_test_active.rb +76 -0
  78. data/test/_test_active_mimic.rb +96 -0
  79. data/test/_test_mimic_rails.rb +126 -0
  80. data/test/activerecord/result_test.rb +27 -0
  81. data/test/activesupport4/decoding_test.rb +108 -0
  82. data/test/activesupport4/encoding_test.rb +531 -0
  83. data/test/activesupport4/test_helper.rb +41 -0
  84. data/test/activesupport5/abstract_unit.rb +45 -0
  85. data/test/activesupport5/decoding_test.rb +133 -0
  86. data/test/activesupport5/encoding_test.rb +500 -0
  87. data/test/activesupport5/encoding_test_cases.rb +98 -0
  88. data/test/activesupport5/test_helper.rb +72 -0
  89. data/test/activesupport5/time_zone_test_helpers.rb +39 -0
  90. data/test/activesupport6/abstract_unit.rb +44 -0
  91. data/test/activesupport6/decoding_test.rb +133 -0
  92. data/test/activesupport6/encoding_test.rb +507 -0
  93. data/test/activesupport6/encoding_test_cases.rb +98 -0
  94. data/test/activesupport6/test_common.rb +17 -0
  95. data/test/activesupport6/test_helper.rb +163 -0
  96. data/test/activesupport6/time_zone_test_helpers.rb +39 -0
  97. data/test/bar.rb +35 -0
  98. data/test/baz.rb +16 -0
  99. data/test/files.rb +29 -0
  100. data/test/foo.rb +52 -0
  101. data/test/helper.rb +26 -0
  102. data/test/isolated/shared.rb +308 -0
  103. data/test/isolated/test_mimic_after.rb +13 -0
  104. data/test/isolated/test_mimic_alone.rb +12 -0
  105. data/test/isolated/test_mimic_as_json.rb +45 -0
  106. data/test/isolated/test_mimic_before.rb +13 -0
  107. data/test/isolated/test_mimic_define.rb +28 -0
  108. data/test/isolated/test_mimic_rails_after.rb +22 -0
  109. data/test/isolated/test_mimic_rails_before.rb +21 -0
  110. data/test/isolated/test_mimic_redefine.rb +15 -0
  111. data/test/json_gem/json_addition_test.rb +216 -0
  112. data/test/json_gem/json_common_interface_test.rb +148 -0
  113. data/test/json_gem/json_encoding_test.rb +107 -0
  114. data/test/json_gem/json_ext_parser_test.rb +20 -0
  115. data/test/json_gem/json_fixtures_test.rb +35 -0
  116. data/test/json_gem/json_generator_test.rb +383 -0
  117. data/test/json_gem/json_generic_object_test.rb +90 -0
  118. data/test/json_gem/json_parser_test.rb +470 -0
  119. data/test/json_gem/json_string_matching_test.rb +42 -0
  120. data/test/json_gem/test_helper.rb +18 -0
  121. data/test/perf.rb +107 -0
  122. data/test/perf_compat.rb +130 -0
  123. data/test/perf_fast.rb +164 -0
  124. data/test/perf_file.rb +64 -0
  125. data/test/perf_object.rb +138 -0
  126. data/test/perf_saj.rb +109 -0
  127. data/test/perf_scp.rb +151 -0
  128. data/test/perf_simple.rb +287 -0
  129. data/test/perf_strict.rb +145 -0
  130. data/test/perf_wab.rb +131 -0
  131. data/test/prec.rb +23 -0
  132. data/test/sample.rb +54 -0
  133. data/test/sample/change.rb +14 -0
  134. data/test/sample/dir.rb +19 -0
  135. data/test/sample/doc.rb +36 -0
  136. data/test/sample/file.rb +48 -0
  137. data/test/sample/group.rb +16 -0
  138. data/test/sample/hasprops.rb +16 -0
  139. data/test/sample/layer.rb +12 -0
  140. data/test/sample/line.rb +20 -0
  141. data/test/sample/oval.rb +10 -0
  142. data/test/sample/rect.rb +10 -0
  143. data/test/sample/shape.rb +35 -0
  144. data/test/sample/text.rb +20 -0
  145. data/test/sample_json.rb +37 -0
  146. data/test/test_compat.rb +502 -0
  147. data/test/test_custom.rb +527 -0
  148. data/test/test_debian.rb +53 -0
  149. data/test/test_fast.rb +470 -0
  150. data/test/test_file.rb +239 -0
  151. data/test/test_gc.rb +49 -0
  152. data/test/test_hash.rb +29 -0
  153. data/test/test_integer_range.rb +72 -0
  154. data/test/test_null.rb +376 -0
  155. data/test/test_object.rb +1027 -0
  156. data/test/test_rails.rb +26 -0
  157. data/test/test_saj.rb +186 -0
  158. data/test/test_scp.rb +433 -0
  159. data/test/test_strict.rb +433 -0
  160. data/test/test_various.rb +719 -0
  161. data/test/test_wab.rb +307 -0
  162. data/test/test_writer.rb +380 -0
  163. data/test/tests.rb +25 -0
  164. data/test/tests_mimic.rb +14 -0
  165. data/test/tests_mimic_addition.rb +7 -0
  166. data/test/zoo.rb +13 -0
  167. metadata +381 -0
@@ -0,0 +1,534 @@
1
+ /* strwriter.c
2
+ * Copyright (c) 2012, 2017, Peter Ohler
3
+ * All rights reserved.
4
+ */
5
+
6
+ #include "dump.h"
7
+ #include "encode.h"
8
+
9
+ extern VALUE Oj;
10
+
11
+ bool string_writer_optimized = false;
12
+
13
+ static void
14
+ key_check(StrWriter sw, const char *key) {
15
+ DumpType type = sw->types[sw->depth];
16
+
17
+ if (0 == key && (ObjectNew == type || ObjectType == type)) {
18
+ rb_raise(rb_eStandardError, "Can not push onto an Object without a key.");
19
+ }
20
+ }
21
+
22
+ static void
23
+ push_type(StrWriter sw, DumpType type) {
24
+ if (sw->types_end <= sw->types + sw->depth + 1) {
25
+ size_t size = (sw->types_end - sw->types) * 2;
26
+
27
+ REALLOC_N(sw->types, char, size);
28
+ sw->types_end = sw->types + size;
29
+ }
30
+ sw->depth++;
31
+ sw->types[sw->depth] = type;
32
+ }
33
+
34
+ static void
35
+ maybe_comma(StrWriter sw) {
36
+ switch (sw->types[sw->depth]) {
37
+ case ObjectNew:
38
+ sw->types[sw->depth] = ObjectType;
39
+ break;
40
+ case ArrayNew:
41
+ sw->types[sw->depth] = ArrayType;
42
+ break;
43
+ case ObjectType:
44
+ case ArrayType:
45
+ // Always have a few characters available in the out.buf.
46
+ *sw->out.cur++ = ',';
47
+ break;
48
+ }
49
+ }
50
+
51
+ // Used by stream writer also.
52
+ void
53
+ oj_str_writer_init(StrWriter sw, int buf_size) {
54
+ sw->opts = oj_default_options;
55
+ sw->depth = 0;
56
+ sw->types = ALLOC_N(char, 256);
57
+ sw->types_end = sw->types + 256;
58
+ *sw->types = '\0';
59
+ sw->keyWritten = 0;
60
+
61
+ if (0 == buf_size) {
62
+ buf_size = 4096;
63
+ } else if (buf_size < 1024) {
64
+ buf_size = 1024;
65
+ }
66
+ sw->out.buf = ALLOC_N(char, buf_size);
67
+ sw->out.end = sw->out.buf + buf_size - 10;
68
+ sw->out.allocated = true;
69
+ sw->out.cur = sw->out.buf;
70
+ *sw->out.cur = '\0';
71
+ sw->out.circ_cache = NULL;
72
+ sw->out.circ_cnt = 0;
73
+ sw->out.hash_cnt = 0;
74
+ sw->out.opts = &sw->opts;
75
+ sw->out.indent = sw->opts.indent;
76
+ sw->out.depth = 0;
77
+ sw->out.argc = 0;
78
+ sw->out.argv = NULL;
79
+ sw->out.caller = 0;
80
+ sw->out.ropts = NULL;
81
+ sw->out.omit_nil = oj_default_options.dump_opts.omit_nil;
82
+ }
83
+
84
+ void
85
+ oj_str_writer_push_key(StrWriter sw, const char *key) {
86
+ DumpType type = sw->types[sw->depth];
87
+ long size;
88
+
89
+ if (sw->keyWritten) {
90
+ rb_raise(rb_eStandardError, "Can not push more than one key before pushing a non-key.");
91
+ }
92
+ if (ObjectNew != type && ObjectType != type) {
93
+ rb_raise(rb_eStandardError, "Can only push a key onto an Object.");
94
+ }
95
+ size = sw->depth * sw->out.indent + 3;
96
+ assure_size(&sw->out, size);
97
+ maybe_comma(sw);
98
+ if (0 < sw->depth) {
99
+ fill_indent(&sw->out, sw->depth);
100
+ }
101
+ oj_dump_cstr(key, strlen(key), 0, 0, &sw->out);
102
+ *sw->out.cur++ = ':';
103
+ sw->keyWritten = 1;
104
+ }
105
+
106
+ void
107
+ oj_str_writer_push_object(StrWriter sw, const char *key) {
108
+ if (sw->keyWritten) {
109
+ sw->keyWritten = 0;
110
+ assure_size(&sw->out, 1);
111
+ } else {
112
+ long size;
113
+
114
+ key_check(sw, key);
115
+ size = sw->depth * sw->out.indent + 3;
116
+ assure_size(&sw->out, size);
117
+ maybe_comma(sw);
118
+ if (0 < sw->depth) {
119
+ fill_indent(&sw->out, sw->depth);
120
+ }
121
+ if (0 != key) {
122
+ oj_dump_cstr(key, strlen(key), 0, 0, &sw->out);
123
+ *sw->out.cur++ = ':';
124
+ }
125
+ }
126
+ *sw->out.cur++ = '{';
127
+ push_type(sw, ObjectNew);
128
+ }
129
+
130
+ void
131
+ oj_str_writer_push_array(StrWriter sw, const char *key) {
132
+ if (sw->keyWritten) {
133
+ sw->keyWritten = 0;
134
+ assure_size(&sw->out, 1);
135
+ } else {
136
+ long size;
137
+
138
+ key_check(sw, key);
139
+ size = sw->depth * sw->out.indent + 3;
140
+ assure_size(&sw->out, size);
141
+ maybe_comma(sw);
142
+ if (0 < sw->depth) {
143
+ fill_indent(&sw->out, sw->depth);
144
+ }
145
+ if (0 != key) {
146
+ oj_dump_cstr(key, strlen(key), 0, 0, &sw->out);
147
+ *sw->out.cur++ = ':';
148
+ }
149
+ }
150
+ *sw->out.cur++ = '[';
151
+ push_type(sw, ArrayNew);
152
+ }
153
+
154
+ void
155
+ oj_str_writer_push_value(StrWriter sw, VALUE val, const char *key) {
156
+ Out out = &sw->out;
157
+
158
+ if (sw->keyWritten) {
159
+ sw->keyWritten = 0;
160
+ } else {
161
+ long size;
162
+
163
+ key_check(sw, key);
164
+ size = sw->depth * out->indent + 3;
165
+ assure_size(out, size);
166
+ maybe_comma(sw);
167
+ if (0 < sw->depth) {
168
+ fill_indent(&sw->out, sw->depth);
169
+ }
170
+ if (0 != key) {
171
+ oj_dump_cstr(key, strlen(key), 0, 0, out);
172
+ *out->cur++ = ':';
173
+ }
174
+ }
175
+ switch (out->opts->mode) {
176
+ case StrictMode: oj_dump_strict_val(val, sw->depth, out); break;
177
+ case NullMode: oj_dump_null_val(val, sw->depth, out); break;
178
+ case ObjectMode: oj_dump_obj_val(val, sw->depth, out); break;
179
+ case CompatMode: oj_dump_compat_val(val, sw->depth, out, Yes == out->opts->to_json); break;
180
+ case RailsMode: oj_dump_rails_val(val, sw->depth, out); break;
181
+ case CustomMode: oj_dump_custom_val(val, sw->depth, out, true); break;
182
+ default: oj_dump_custom_val(val, sw->depth, out, true); break;
183
+ }
184
+ }
185
+
186
+ void
187
+ oj_str_writer_push_json(StrWriter sw, const char *json, const char *key) {
188
+ if (sw->keyWritten) {
189
+ sw->keyWritten = 0;
190
+ } else {
191
+ long size;
192
+
193
+ key_check(sw, key);
194
+ size = sw->depth * sw->out.indent + 3;
195
+ assure_size(&sw->out, size);
196
+ maybe_comma(sw);
197
+ if (0 < sw->depth) {
198
+ fill_indent(&sw->out, sw->depth);
199
+ }
200
+ if (0 != key) {
201
+ oj_dump_cstr(key, strlen(key), 0, 0, &sw->out);
202
+ *sw->out.cur++ = ':';
203
+ }
204
+ }
205
+ oj_dump_raw(json, strlen(json), &sw->out);
206
+ }
207
+
208
+ void
209
+ oj_str_writer_pop(StrWriter sw) {
210
+ long size;
211
+ DumpType type = sw->types[sw->depth];
212
+
213
+ if (sw->keyWritten) {
214
+ sw->keyWritten = 0;
215
+ rb_raise(rb_eStandardError, "Can not pop after writing a key but no value.");
216
+ }
217
+ sw->depth--;
218
+ if (0 > sw->depth) {
219
+ rb_raise(rb_eStandardError, "Can not pop with no open array or object.");
220
+ }
221
+ size = sw->depth * sw->out.indent + 2;
222
+ assure_size(&sw->out, size);
223
+ fill_indent(&sw->out, sw->depth);
224
+ switch (type) {
225
+ case ObjectNew:
226
+ case ObjectType:
227
+ *sw->out.cur++ = '}';
228
+ break;
229
+ case ArrayNew:
230
+ case ArrayType:
231
+ *sw->out.cur++ = ']';
232
+ break;
233
+ }
234
+ if (0 == sw->depth && 0 <= sw->out.indent) {
235
+ *sw->out.cur++ = '\n';
236
+ }
237
+ }
238
+
239
+ void
240
+ oj_str_writer_pop_all(StrWriter sw) {
241
+ while (0 < sw->depth) {
242
+ oj_str_writer_pop(sw);
243
+ }
244
+ }
245
+
246
+ static void
247
+ str_writer_free(void *ptr) {
248
+ StrWriter sw;
249
+
250
+ if (0 == ptr) {
251
+ return;
252
+ }
253
+ sw = (StrWriter)ptr;
254
+ xfree(sw->out.buf);
255
+ xfree(sw->types);
256
+ xfree(ptr);
257
+ }
258
+
259
+ /* Document-method: new
260
+ * call-seq: new(io, options)
261
+ *
262
+ * Creates a new StringWriter. Options are supported according the the
263
+ * specified mode or the mode in the default options. Note that if mimic_JSON
264
+ * or Oj.optimize_rails has not been called then the behavior of the modes may
265
+ * not be the same as if they were.
266
+ *
267
+ * In addition to the regular dump options for the various modes a
268
+ * _:buffer_size_ option is available. It should be set to a positive
269
+ * integer. It is considered a hint of how large the initial internal buffer
270
+ * should be.
271
+ *
272
+ * - *io* [_IO_] stream to write to
273
+ * - *options* [_Hash_] formating options
274
+ */
275
+ static VALUE
276
+ str_writer_new(int argc, VALUE *argv, VALUE self) {
277
+ StrWriter sw = ALLOC(struct _strWriter);
278
+
279
+ oj_str_writer_init(sw, 0);
280
+ if (1 == argc) {
281
+ oj_parse_options(argv[0], &sw->opts);
282
+ }
283
+ sw->out.argc = argc - 1;
284
+ sw->out.argv = argv + 1;
285
+ sw->out.indent = sw->opts.indent;
286
+
287
+ return Data_Wrap_Struct(oj_string_writer_class, 0, str_writer_free, sw);
288
+ }
289
+
290
+ /* Document-method: push_key
291
+ * call-seq: push_key(key)
292
+ *
293
+ * Pushes a key onto the JSON document. The key will be used for the next push
294
+ * if currently in a JSON object and ignored otherwise. If a key is provided on
295
+ * the next push then that new key will be ignored.
296
+ * - *key* [_String_] the key pending for the next push
297
+ */
298
+ static VALUE
299
+ str_writer_push_key(VALUE self, VALUE key) {
300
+ StrWriter sw = (StrWriter)DATA_PTR(self);
301
+
302
+ rb_check_type(key, T_STRING);
303
+ oj_str_writer_push_key(sw, StringValuePtr(key));
304
+
305
+ return Qnil;
306
+ }
307
+
308
+ /* Document-method: push_object
309
+ * call-seq: push_object(key=nil)
310
+ *
311
+ * Pushes an object onto the JSON document. Future pushes will be to this object
312
+ * until a pop() is called.
313
+ * - *key* [_String_] the key if adding to an object in the JSON document
314
+ */
315
+ static VALUE
316
+ str_writer_push_object(int argc, VALUE *argv, VALUE self) {
317
+ StrWriter sw = (StrWriter)DATA_PTR(self);
318
+
319
+ switch (argc) {
320
+ case 0:
321
+ oj_str_writer_push_object(sw, 0);
322
+ break;
323
+ case 1:
324
+ if (Qnil == argv[0]) {
325
+ oj_str_writer_push_object(sw, 0);
326
+ } else {
327
+ rb_check_type(argv[0], T_STRING);
328
+ oj_str_writer_push_object(sw, StringValuePtr(argv[0]));
329
+ }
330
+ break;
331
+ default:
332
+ rb_raise(rb_eArgError, "Wrong number of argument to 'push_object'.");
333
+ break;
334
+ }
335
+ if (rb_block_given_p()) {
336
+ rb_yield(Qnil);
337
+ oj_str_writer_pop(sw);
338
+ }
339
+ return Qnil;
340
+ }
341
+
342
+ /* Document-method: push_array
343
+ * call-seq: push_array(key=nil)
344
+ *
345
+ * Pushes an array onto the JSON document. Future pushes will be to this object
346
+ * until a pop() is called.
347
+ * - *key* [_String_] the key if adding to an object in the JSON document
348
+ */
349
+ static VALUE
350
+ str_writer_push_array(int argc, VALUE *argv, VALUE self) {
351
+ StrWriter sw = (StrWriter)DATA_PTR(self);
352
+
353
+ switch (argc) {
354
+ case 0:
355
+ oj_str_writer_push_array(sw, 0);
356
+ break;
357
+ case 1:
358
+ if (Qnil == argv[0]) {
359
+ oj_str_writer_push_array(sw, 0);
360
+ } else {
361
+ rb_check_type(argv[0], T_STRING);
362
+ oj_str_writer_push_array(sw, StringValuePtr(argv[0]));
363
+ }
364
+ break;
365
+ default:
366
+ rb_raise(rb_eArgError, "Wrong number of argument to 'push_object'.");
367
+ break;
368
+ }
369
+ if (rb_block_given_p()) {
370
+ rb_yield(Qnil);
371
+ oj_str_writer_pop(sw);
372
+ }
373
+ return Qnil;
374
+ }
375
+
376
+ /* Document-method: push_value
377
+ * call-seq: push_value(value, key=nil)
378
+ *
379
+ * Pushes a value onto the JSON document.
380
+ * - *value* [_Object_] value to add to the JSON document
381
+ * - *key* [_String_] the key if adding to an object in the JSON document
382
+ */
383
+ static VALUE
384
+ str_writer_push_value(int argc, VALUE *argv, VALUE self) {
385
+ switch (argc) {
386
+ case 1:
387
+ oj_str_writer_push_value((StrWriter)DATA_PTR(self), *argv, 0);
388
+ break;
389
+ case 2:
390
+ if (Qnil == argv[1]) {
391
+ oj_str_writer_push_value((StrWriter)DATA_PTR(self), *argv, 0);
392
+ } else {
393
+ rb_check_type(argv[1], T_STRING);
394
+ oj_str_writer_push_value((StrWriter)DATA_PTR(self), *argv, StringValuePtr(argv[1]));
395
+ }
396
+ break;
397
+ default:
398
+ rb_raise(rb_eArgError, "Wrong number of argument to 'push_value'.");
399
+ break;
400
+ }
401
+ return Qnil;
402
+ }
403
+
404
+ /* Document-method: push_json
405
+ * call-seq: push_json(value, key=nil)
406
+ *
407
+ * Pushes a string onto the JSON document. The String must be a valid JSON
408
+ * encoded string. No additional checking is done to verify the validity of the
409
+ * string.
410
+ * - *value* [_Object_] value to add to the JSON document
411
+ * - *key* [_String_] the key if adding to an object in the JSON document
412
+ */
413
+ static VALUE
414
+ str_writer_push_json(int argc, VALUE *argv, VALUE self) {
415
+ rb_check_type(argv[0], T_STRING);
416
+ switch (argc) {
417
+ case 1:
418
+ oj_str_writer_push_json((StrWriter)DATA_PTR(self), StringValuePtr(*argv), 0);
419
+ break;
420
+ case 2:
421
+ if (Qnil == argv[1]) {
422
+ oj_str_writer_push_json((StrWriter)DATA_PTR(self), StringValuePtr(*argv), 0);
423
+ } else {
424
+ rb_check_type(argv[1], T_STRING);
425
+ oj_str_writer_push_json((StrWriter)DATA_PTR(self), StringValuePtr(*argv), StringValuePtr(argv[1]));
426
+ }
427
+ break;
428
+ default:
429
+ rb_raise(rb_eArgError, "Wrong number of argument to 'push_json'.");
430
+ break;
431
+ }
432
+ return Qnil;
433
+ }
434
+ /* Document-method: pop
435
+ * call-seq: pop()
436
+ *
437
+ * Pops up a level in the JSON document closing the array or object that is
438
+ * currently open.
439
+ */
440
+ static VALUE
441
+ str_writer_pop(VALUE self) {
442
+ oj_str_writer_pop((StrWriter)DATA_PTR(self));
443
+ return Qnil;
444
+ }
445
+
446
+ /* Document-method: pop_all
447
+ * call-seq: pop_all()
448
+ *
449
+ * Pops all level in the JSON document closing all the array or object that is
450
+ * currently open.
451
+ */
452
+ static VALUE
453
+ str_writer_pop_all(VALUE self) {
454
+ oj_str_writer_pop_all((StrWriter)DATA_PTR(self));
455
+
456
+ return Qnil;
457
+ }
458
+
459
+ /* Document-method: reset
460
+ * call-seq: reset()
461
+ *
462
+ * Reset the writer back to the empty state.
463
+ */
464
+ static VALUE
465
+ str_writer_reset(VALUE self) {
466
+ StrWriter sw = (StrWriter)DATA_PTR(self);
467
+
468
+ sw->depth = 0;
469
+ *sw->types = '\0';
470
+ sw->keyWritten = 0;
471
+ sw->out.cur = sw->out.buf;
472
+ *sw->out.cur = '\0';
473
+
474
+ return Qnil;
475
+ }
476
+
477
+ /* Document-method: to_s
478
+ * call-seq: to_s()
479
+ *
480
+ * Returns the JSON document string in what ever state the construction is at.
481
+ *
482
+ * *return* [_String_]
483
+ */
484
+ static VALUE
485
+ str_writer_to_s(VALUE self) {
486
+ StrWriter sw = (StrWriter)DATA_PTR(self);
487
+ VALUE rstr = rb_str_new(sw->out.buf, sw->out.cur - sw->out.buf);
488
+
489
+ return oj_encode(rstr);
490
+ }
491
+
492
+ /* Document-method: as_json
493
+ * call-seq: as_json()
494
+ *
495
+ * Returns the contents of the writer as a JSON element. If called from inside
496
+ * an array or hash by Oj the raw buffer will be used othersize a more
497
+ * inefficient parse of the contents and a return of the result is
498
+ * completed. The parse uses the trict mode.
499
+ *
500
+ * *return* [_Hash_|_Array_|_String_|_Integer_|_Float_|_True_|_False_|_nil|)
501
+ */
502
+ static VALUE
503
+ str_writer_as_json(VALUE self) {
504
+ if (string_writer_optimized) {
505
+ return self;
506
+ }
507
+ return rb_hash_new();
508
+ }
509
+
510
+ /* Document-class: Oj::StringWriter
511
+ *
512
+ * Supports building a JSON document one element at a time. Build the document
513
+ * by pushing values into the document. Pushing an array or an object will
514
+ * create that element in the JSON document and subsequent pushes will add the
515
+ * elements to that array or object until a pop() is called. When complete
516
+ * calling to_s() will return the JSON document. Note tha calling to_s() before
517
+ * construction is complete will return the document in it's current state.
518
+ */
519
+ void
520
+ oj_string_writer_init() {
521
+ oj_string_writer_class = rb_define_class_under(Oj, "StringWriter", rb_cObject);
522
+ rb_define_module_function(oj_string_writer_class, "new", str_writer_new, -1);
523
+ rb_define_method(oj_string_writer_class, "push_key", str_writer_push_key, 1);
524
+ rb_define_method(oj_string_writer_class, "push_object", str_writer_push_object, -1);
525
+ rb_define_method(oj_string_writer_class, "push_array", str_writer_push_array, -1);
526
+ rb_define_method(oj_string_writer_class, "push_value", str_writer_push_value, -1);
527
+ rb_define_method(oj_string_writer_class, "push_json", str_writer_push_json, -1);
528
+ rb_define_method(oj_string_writer_class, "pop", str_writer_pop, 0);
529
+ rb_define_method(oj_string_writer_class, "pop_all", str_writer_pop_all, 0);
530
+ rb_define_method(oj_string_writer_class, "reset", str_writer_reset, 0);
531
+ rb_define_method(oj_string_writer_class, "to_s", str_writer_to_s, 0);
532
+ rb_define_method(oj_string_writer_class, "raw_json", str_writer_to_s, 0);
533
+ rb_define_method(oj_string_writer_class, "as_json", str_writer_as_json, 0);
534
+ }