oj 3.8.1

Sign up to get free protection for your applications and to get access to all the features.
Files changed (156) 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 +1191 -0
  13. data/ext/oj/dump.c +1252 -0
  14. data/ext/oj/dump.h +96 -0
  15. data/ext/oj/dump_compat.c +977 -0
  16. data/ext/oj/dump_leaf.c +252 -0
  17. data/ext/oj/dump_object.c +837 -0
  18. data/ext/oj/dump_strict.c +433 -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 +47 -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 +878 -0
  28. data/ext/oj/object.c +771 -0
  29. data/ext/oj/odd.c +231 -0
  30. data/ext/oj/odd.h +44 -0
  31. data/ext/oj/oj.c +1704 -0
  32. data/ext/oj/oj.h +385 -0
  33. data/ext/oj/parse.c +1086 -0
  34. data/ext/oj/parse.h +111 -0
  35. data/ext/oj/rails.c +1493 -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 +910 -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 +283 -0
  74. data/pages/Rails.md +116 -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/decoding_test.rb +125 -0
  85. data/test/activesupport5/encoding_test.rb +485 -0
  86. data/test/activesupport5/encoding_test_cases.rb +90 -0
  87. data/test/activesupport5/test_helper.rb +50 -0
  88. data/test/activesupport5/time_zone_test_helpers.rb +24 -0
  89. data/test/bar.rb +25 -0
  90. data/test/files.rb +29 -0
  91. data/test/foo.rb +167 -0
  92. data/test/helper.rb +26 -0
  93. data/test/isolated/shared.rb +308 -0
  94. data/test/isolated/test_mimic_after.rb +13 -0
  95. data/test/isolated/test_mimic_alone.rb +12 -0
  96. data/test/isolated/test_mimic_as_json.rb +45 -0
  97. data/test/isolated/test_mimic_before.rb +13 -0
  98. data/test/isolated/test_mimic_define.rb +28 -0
  99. data/test/isolated/test_mimic_rails_after.rb +22 -0
  100. data/test/isolated/test_mimic_rails_before.rb +21 -0
  101. data/test/isolated/test_mimic_redefine.rb +15 -0
  102. data/test/json_gem/json_addition_test.rb +216 -0
  103. data/test/json_gem/json_common_interface_test.rb +148 -0
  104. data/test/json_gem/json_encoding_test.rb +107 -0
  105. data/test/json_gem/json_ext_parser_test.rb +20 -0
  106. data/test/json_gem/json_fixtures_test.rb +35 -0
  107. data/test/json_gem/json_generator_test.rb +383 -0
  108. data/test/json_gem/json_generic_object_test.rb +90 -0
  109. data/test/json_gem/json_parser_test.rb +470 -0
  110. data/test/json_gem/json_string_matching_test.rb +42 -0
  111. data/test/json_gem/test_helper.rb +18 -0
  112. data/test/perf.rb +107 -0
  113. data/test/perf_compat.rb +130 -0
  114. data/test/perf_fast.rb +164 -0
  115. data/test/perf_file.rb +64 -0
  116. data/test/perf_object.rb +138 -0
  117. data/test/perf_saj.rb +109 -0
  118. data/test/perf_scp.rb +151 -0
  119. data/test/perf_simple.rb +287 -0
  120. data/test/perf_strict.rb +145 -0
  121. data/test/perf_wab.rb +131 -0
  122. data/test/sample.rb +54 -0
  123. data/test/sample/change.rb +14 -0
  124. data/test/sample/dir.rb +19 -0
  125. data/test/sample/doc.rb +36 -0
  126. data/test/sample/file.rb +48 -0
  127. data/test/sample/group.rb +16 -0
  128. data/test/sample/hasprops.rb +16 -0
  129. data/test/sample/layer.rb +12 -0
  130. data/test/sample/line.rb +20 -0
  131. data/test/sample/oval.rb +10 -0
  132. data/test/sample/rect.rb +10 -0
  133. data/test/sample/shape.rb +35 -0
  134. data/test/sample/text.rb +20 -0
  135. data/test/sample_json.rb +37 -0
  136. data/test/test_compat.rb +509 -0
  137. data/test/test_custom.rb +503 -0
  138. data/test/test_debian.rb +53 -0
  139. data/test/test_fast.rb +470 -0
  140. data/test/test_file.rb +239 -0
  141. data/test/test_gc.rb +49 -0
  142. data/test/test_hash.rb +29 -0
  143. data/test/test_integer_range.rb +73 -0
  144. data/test/test_null.rb +376 -0
  145. data/test/test_object.rb +1018 -0
  146. data/test/test_saj.rb +186 -0
  147. data/test/test_scp.rb +433 -0
  148. data/test/test_strict.rb +410 -0
  149. data/test/test_various.rb +741 -0
  150. data/test/test_wab.rb +307 -0
  151. data/test/test_writer.rb +380 -0
  152. data/test/tests.rb +24 -0
  153. data/test/tests_mimic.rb +14 -0
  154. data/test/tests_mimic_addition.rb +7 -0
  155. data/test/zoo.rb +13 -0
  156. metadata +359 -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
+ }