oj 3.7.12

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