oj 2.18.5 → 3.0.0

Sign up to get free protection for your applications and to get access to all the features.
Files changed (111) hide show
  1. checksums.yaml +4 -4
  2. data/README.md +33 -226
  3. data/ext/oj/circarray.c +0 -25
  4. data/ext/oj/circarray.h +0 -25
  5. data/ext/oj/code.c +227 -0
  6. data/ext/oj/code.h +40 -0
  7. data/ext/oj/compat.c +126 -38
  8. data/ext/oj/custom.c +1097 -0
  9. data/ext/oj/dump.c +658 -2376
  10. data/ext/oj/dump.h +92 -0
  11. data/ext/oj/dump_compat.c +937 -0
  12. data/ext/oj/dump_leaf.c +254 -0
  13. data/ext/oj/dump_object.c +810 -0
  14. data/ext/oj/dump_rails.c +329 -0
  15. data/ext/oj/dump_strict.c +416 -0
  16. data/ext/oj/err.c +0 -25
  17. data/ext/oj/err.h +8 -2
  18. data/ext/oj/fast.c +24 -24
  19. data/ext/oj/mimic_json.c +817 -0
  20. data/ext/oj/mimic_rails.c +806 -0
  21. data/ext/oj/mimic_rails.h +17 -0
  22. data/ext/oj/object.c +18 -72
  23. data/ext/oj/odd.c +0 -25
  24. data/ext/oj/odd.h +2 -27
  25. data/ext/oj/oj.c +655 -1503
  26. data/ext/oj/oj.h +93 -40
  27. data/ext/oj/parse.c +99 -46
  28. data/ext/oj/parse.h +12 -26
  29. data/ext/oj/reader.c +1 -25
  30. data/ext/oj/reader.h +3 -25
  31. data/ext/oj/resolve.c +9 -11
  32. data/ext/oj/resolve.h +2 -2
  33. data/ext/oj/rxclass.c +133 -0
  34. data/ext/oj/rxclass.h +27 -0
  35. data/ext/oj/saj.c +4 -25
  36. data/ext/oj/scp.c +3 -25
  37. data/ext/oj/sparse.c +89 -13
  38. data/ext/oj/stream_writer.c +301 -0
  39. data/ext/oj/strict.c +4 -27
  40. data/ext/oj/string_writer.c +480 -0
  41. data/ext/oj/val_stack.h +6 -2
  42. data/lib/oj.rb +1 -23
  43. data/lib/oj/easy_hash.rb +12 -4
  44. data/lib/oj/json.rb +172 -0
  45. data/lib/oj/mimic.rb +123 -18
  46. data/lib/oj/state.rb +131 -0
  47. data/lib/oj/version.rb +1 -1
  48. data/pages/Advanced.md +22 -0
  49. data/pages/Compatibility.md +25 -0
  50. data/pages/Custom.md +23 -0
  51. data/pages/Encoding.md +65 -0
  52. data/pages/JsonGem.md +79 -0
  53. data/pages/Modes.md +140 -0
  54. data/pages/Options.md +250 -0
  55. data/pages/Rails.md +60 -0
  56. data/pages/Security.md +20 -0
  57. data/test/activesupport4/decoding_test.rb +105 -0
  58. data/test/activesupport4/encoding_test.rb +531 -0
  59. data/test/activesupport4/test_helper.rb +41 -0
  60. data/test/activesupport5/decoding_test.rb +125 -0
  61. data/test/activesupport5/encoding_test.rb +483 -0
  62. data/test/activesupport5/encoding_test_cases.rb +90 -0
  63. data/test/activesupport5/test_helper.rb +50 -0
  64. data/test/activesupport5/time_zone_test_helpers.rb +24 -0
  65. data/test/json_gem/json_addition_test.rb +216 -0
  66. data/test/json_gem/json_common_interface_test.rb +143 -0
  67. data/test/json_gem/json_encoding_test.rb +109 -0
  68. data/test/json_gem/json_ext_parser_test.rb +20 -0
  69. data/test/json_gem/json_fixtures_test.rb +35 -0
  70. data/test/json_gem/json_generator_test.rb +383 -0
  71. data/test/json_gem/json_generic_object_test.rb +90 -0
  72. data/test/json_gem/json_parser_test.rb +470 -0
  73. data/test/json_gem/json_string_matching_test.rb +42 -0
  74. data/test/json_gem/test_helper.rb +18 -0
  75. data/test/perf_compat.rb +30 -28
  76. data/test/perf_object.rb +1 -1
  77. data/test/perf_strict.rb +18 -1
  78. data/test/sample.rb +0 -1
  79. data/test/test_compat.rb +169 -93
  80. data/test/test_custom.rb +355 -0
  81. data/test/test_file.rb +0 -8
  82. data/test/test_null.rb +376 -0
  83. data/test/test_object.rb +268 -3
  84. data/test/test_scp.rb +22 -1
  85. data/test/test_strict.rb +160 -4
  86. data/test/test_various.rb +52 -620
  87. data/test/tests.rb +14 -0
  88. data/test/tests_mimic.rb +14 -0
  89. data/test/tests_mimic_addition.rb +7 -0
  90. metadata +89 -47
  91. data/test/activesupport_datetime_test.rb +0 -23
  92. data/test/bug.rb +0 -51
  93. data/test/bug2.rb +0 -10
  94. data/test/bug3.rb +0 -46
  95. data/test/bug_fast.rb +0 -32
  96. data/test/bug_load.rb +0 -24
  97. data/test/crash.rb +0 -111
  98. data/test/curl/curl_oj.rb +0 -46
  99. data/test/curl/get_oj.rb +0 -24
  100. data/test/curl/just_curl.rb +0 -31
  101. data/test/curl/just_oj.rb +0 -51
  102. data/test/example.rb +0 -11
  103. data/test/foo.rb +0 -24
  104. data/test/io.rb +0 -48
  105. data/test/isolated/test_mimic_rails_datetime.rb +0 -27
  106. data/test/mod.rb +0 -16
  107. data/test/rails.rb +0 -50
  108. data/test/russian.rb +0 -18
  109. data/test/struct.rb +0 -29
  110. data/test/test_serializer.rb +0 -59
  111. data/test/write_timebars.rb +0 -31
@@ -1,31 +1,6 @@
1
1
  /* strict.c
2
2
  * Copyright (c) 2012, Peter Ohler
3
3
  * All rights reserved.
4
- *
5
- * Redistribution and use in source and binary forms, with or without
6
- * modification, are permitted provided that the following conditions are met:
7
- *
8
- * - Redistributions of source code must retain the above copyright notice, this
9
- * list of conditions and the following disclaimer.
10
- *
11
- * - Redistributions in binary form must reproduce the above copyright notice,
12
- * this list of conditions and the following disclaimer in the documentation
13
- * and/or other materials provided with the distribution.
14
- *
15
- * - Neither the name of Peter Ohler nor the names of its contributors may be
16
- * used to endorse or promote products derived from this software without
17
- * specific prior written permission.
18
- *
19
- * THIS SOFTWARE IS PROVIDED BY THE COPYRIGHT HOLDERS AND CONTRIBUTORS "AS IS"
20
- * AND ANY EXPRESS OR IMPLIED WARRANTIES, INCLUDING, BUT NOT LIMITED TO, THE
21
- * IMPLIED WARRANTIES OF MERCHANTABILITY AND FITNESS FOR A PARTICULAR PURPOSE ARE
22
- * DISCLAIMED. IN NO EVENT SHALL THE COPYRIGHT HOLDER OR CONTRIBUTORS BE LIABLE
23
- * FOR ANY DIRECT, INDIRECT, INCIDENTAL, SPECIAL, EXEMPLARY, OR CONSEQUENTIAL
24
- * DAMAGES (INCLUDING, BUT NOT LIMITED TO, PROCUREMENT OF SUBSTITUTE GOODS OR
25
- * SERVICES; LOSS OF USE, DATA, OR PROFITS; OR BUSINESS INTERRUPTION) HOWEVER
26
- * CAUSED AND ON ANY THEORY OF LIABILITY, WHETHER IN CONTRACT, STRICT LIABILITY,
27
- * OR TORT (INCLUDING NEGLIGENCE OR OTHERWISE) ARISING IN ANY WAY OUT OF THE USE
28
- * OF THIS SOFTWARE, EVEN IF ADVISED OF THE POSSIBILITY OF SUCH DAMAGE.
29
4
  */
30
5
 
31
6
  #include <stdlib.h>
@@ -160,13 +135,14 @@ VALUE
160
135
  oj_strict_parse(int argc, VALUE *argv, VALUE self) {
161
136
  struct _ParseInfo pi;
162
137
 
138
+ parse_info_init(&pi);
163
139
  pi.options = oj_default_options;
164
140
  pi.handler = Qnil;
165
141
  pi.err_class = Qnil;
166
142
  oj_set_strict_callbacks(&pi);
167
143
 
168
144
  if (T_STRING == rb_type(*argv)) {
169
- return oj_pi_parse(argc, argv, &pi, 0, 0, 1);
145
+ return oj_pi_parse(argc, argv, &pi, 0, 0, true);
170
146
  } else {
171
147
  return oj_pi_sparse(argc, argv, &pi, 0);
172
148
  }
@@ -176,10 +152,11 @@ VALUE
176
152
  oj_strict_parse_cstr(int argc, VALUE *argv, char *json, size_t len) {
177
153
  struct _ParseInfo pi;
178
154
 
155
+ parse_info_init(&pi);
179
156
  pi.options = oj_default_options;
180
157
  pi.handler = Qnil;
181
158
  pi.err_class = Qnil;
182
159
  oj_set_strict_callbacks(&pi);
183
160
 
184
- return oj_pi_parse(argc, argv, &pi, json, len, 1);
161
+ return oj_pi_parse(argc, argv, &pi, json, len, true);
185
162
  }
@@ -0,0 +1,480 @@
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) {
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
+ sw->out.buf = ALLOC_N(char, 4096);
60
+ sw->out.end = sw->out.buf + 4086;
61
+ sw->out.allocated = 1;
62
+ sw->out.cur = sw->out.buf;
63
+ *sw->out.cur = '\0';
64
+ sw->out.circ_cnt = 0;
65
+ sw->out.hash_cnt = 0;
66
+ sw->out.opts = &sw->opts;
67
+ sw->out.indent = sw->opts.indent;
68
+ sw->out.depth = 0;
69
+ }
70
+
71
+ void
72
+ oj_str_writer_push_key(StrWriter sw, const char *key) {
73
+ DumpType type = sw->types[sw->depth];
74
+ long size;
75
+
76
+ if (sw->keyWritten) {
77
+ rb_raise(rb_eStandardError, "Can not push more than one key before pushing a non-key.");
78
+ }
79
+ if (ObjectNew != type && ObjectType != type) {
80
+ rb_raise(rb_eStandardError, "Can only push a key onto an Object.");
81
+ }
82
+ size = sw->depth * sw->out.indent + 3;
83
+ assure_size(&sw->out, size);
84
+ maybe_comma(sw);
85
+ if (0 < sw->depth) {
86
+ fill_indent(&sw->out, sw->depth);
87
+ }
88
+ oj_dump_cstr(key, strlen(key), 0, 0, &sw->out);
89
+ *sw->out.cur++ = ':';
90
+ sw->keyWritten = 1;
91
+ }
92
+
93
+ void
94
+ oj_str_writer_push_object(StrWriter sw, const char *key) {
95
+ if (sw->keyWritten) {
96
+ sw->keyWritten = 0;
97
+ assure_size(&sw->out, 1);
98
+ } else {
99
+ long size;
100
+
101
+ key_check(sw, key);
102
+ size = sw->depth * sw->out.indent + 3;
103
+ assure_size(&sw->out, size);
104
+ maybe_comma(sw);
105
+ if (0 < sw->depth) {
106
+ fill_indent(&sw->out, sw->depth);
107
+ }
108
+ if (0 != key) {
109
+ oj_dump_cstr(key, strlen(key), 0, 0, &sw->out);
110
+ *sw->out.cur++ = ':';
111
+ }
112
+ }
113
+ *sw->out.cur++ = '{';
114
+ push_type(sw, ObjectNew);
115
+ }
116
+
117
+ void
118
+ oj_str_writer_push_array(StrWriter sw, const char *key) {
119
+ if (sw->keyWritten) {
120
+ sw->keyWritten = 0;
121
+ assure_size(&sw->out, 1);
122
+ } else {
123
+ long size;
124
+
125
+ key_check(sw, key);
126
+ size = sw->depth * sw->out.indent + 3;
127
+ assure_size(&sw->out, size);
128
+ maybe_comma(sw);
129
+ if (0 < sw->depth) {
130
+ fill_indent(&sw->out, sw->depth);
131
+ }
132
+ if (0 != key) {
133
+ oj_dump_cstr(key, strlen(key), 0, 0, &sw->out);
134
+ *sw->out.cur++ = ':';
135
+ }
136
+ }
137
+ *sw->out.cur++ = '[';
138
+ push_type(sw, ArrayNew);
139
+ }
140
+
141
+ void
142
+ oj_str_writer_push_value(StrWriter sw, VALUE val, const char *key) {
143
+ if (sw->keyWritten) {
144
+ sw->keyWritten = 0;
145
+ } else {
146
+ long size;
147
+
148
+ key_check(sw, key);
149
+ size = sw->depth * sw->out.indent + 3;
150
+ assure_size(&sw->out, size);
151
+ maybe_comma(sw);
152
+ if (0 < sw->depth) {
153
+ fill_indent(&sw->out, sw->depth);
154
+ }
155
+ if (0 != key) {
156
+ oj_dump_cstr(key, strlen(key), 0, 0, &sw->out);
157
+ *sw->out.cur++ = ':';
158
+ }
159
+ }
160
+ oj_dump_comp_val(val, sw->depth, &sw->out, 0, 0, true);
161
+ }
162
+
163
+ void
164
+ oj_str_writer_push_json(StrWriter sw, const char *json, const char *key) {
165
+ if (sw->keyWritten) {
166
+ sw->keyWritten = 0;
167
+ } else {
168
+ long size;
169
+
170
+ key_check(sw, key);
171
+ size = sw->depth * sw->out.indent + 3;
172
+ assure_size(&sw->out, size);
173
+ maybe_comma(sw);
174
+ if (0 < sw->depth) {
175
+ fill_indent(&sw->out, sw->depth);
176
+ }
177
+ if (0 != key) {
178
+ oj_dump_cstr(key, strlen(key), 0, 0, &sw->out);
179
+ *sw->out.cur++ = ':';
180
+ }
181
+ }
182
+ oj_dump_raw(json, strlen(json), &sw->out);
183
+ }
184
+
185
+ void
186
+ oj_str_writer_pop(StrWriter sw) {
187
+ long size;
188
+ DumpType type = sw->types[sw->depth];
189
+
190
+ if (sw->keyWritten) {
191
+ sw->keyWritten = 0;
192
+ rb_raise(rb_eStandardError, "Can not pop after writing a key but no value.");
193
+ }
194
+ sw->depth--;
195
+ if (0 > sw->depth) {
196
+ rb_raise(rb_eStandardError, "Can not pop with no open array or object.");
197
+ }
198
+ size = sw->depth * sw->out.indent + 2;
199
+ assure_size(&sw->out, size);
200
+ fill_indent(&sw->out, sw->depth);
201
+ switch (type) {
202
+ case ObjectNew:
203
+ case ObjectType:
204
+ *sw->out.cur++ = '}';
205
+ break;
206
+ case ArrayNew:
207
+ case ArrayType:
208
+ *sw->out.cur++ = ']';
209
+ break;
210
+ }
211
+ if (0 == sw->depth && 0 <= sw->out.indent) {
212
+ *sw->out.cur++ = '\n';
213
+ }
214
+ }
215
+
216
+ void
217
+ oj_str_writer_pop_all(StrWriter sw) {
218
+ while (0 < sw->depth) {
219
+ oj_str_writer_pop(sw);
220
+ }
221
+ }
222
+
223
+ static void
224
+ str_writer_free(void *ptr) {
225
+ StrWriter sw;
226
+
227
+ if (0 == ptr) {
228
+ return;
229
+ }
230
+ sw = (StrWriter)ptr;
231
+ xfree(sw->out.buf);
232
+ xfree(sw->types);
233
+ xfree(ptr);
234
+ }
235
+
236
+ /* Document-method: new
237
+ * call-seq: new(io, options)
238
+ *
239
+ * Creates a new StringWriter.
240
+ * - *io* [_IO_] stream to write to
241
+ * - *options* [_Hash_] formating options
242
+ */
243
+ static VALUE
244
+ str_writer_new(int argc, VALUE *argv, VALUE self) {
245
+ StrWriter sw = ALLOC(struct _StrWriter);
246
+
247
+ oj_str_writer_init(sw);
248
+ if (1 == argc) {
249
+ oj_parse_options(argv[0], &sw->opts);
250
+ }
251
+ sw->out.indent = sw->opts.indent;
252
+
253
+ return Data_Wrap_Struct(oj_string_writer_class, 0, str_writer_free, sw);
254
+ }
255
+
256
+ /* Document-method: push_key
257
+ * call-seq: push_key(key)
258
+ *
259
+ * Pushes a key onto the JSON document. The key will be used for the next push
260
+ * if currently in a JSON object and ignored otherwise. If a key is provided on
261
+ * the next push then that new key will be ignored.
262
+ * - *key* [_String_] the key pending for the next push
263
+ */
264
+ static VALUE
265
+ str_writer_push_key(VALUE self, VALUE key) {
266
+ StrWriter sw = (StrWriter)DATA_PTR(self);
267
+
268
+ rb_check_type(key, T_STRING);
269
+ oj_str_writer_push_key(sw, StringValuePtr(key));
270
+
271
+ return Qnil;
272
+ }
273
+
274
+ /* Document-method: push_object
275
+ * call-seq: push_object(key=nil)
276
+ *
277
+ * Pushes an object onto the JSON document. Future pushes will be to this object
278
+ * until a pop() is called.
279
+ * - *key* [_String_] the key if adding to an object in the JSON document
280
+ */
281
+ static VALUE
282
+ str_writer_push_object(int argc, VALUE *argv, VALUE self) {
283
+ StrWriter sw = (StrWriter)DATA_PTR(self);
284
+
285
+ switch (argc) {
286
+ case 0:
287
+ oj_str_writer_push_object(sw, 0);
288
+ break;
289
+ case 1:
290
+ if (Qnil == argv[0]) {
291
+ oj_str_writer_push_object(sw, 0);
292
+ } else {
293
+ rb_check_type(argv[0], T_STRING);
294
+ oj_str_writer_push_object(sw, StringValuePtr(argv[0]));
295
+ }
296
+ break;
297
+ default:
298
+ rb_raise(rb_eArgError, "Wrong number of argument to 'push_object'.");
299
+ break;
300
+ }
301
+ if (rb_block_given_p()) {
302
+ rb_yield(Qnil);
303
+ oj_str_writer_pop(sw);
304
+ }
305
+ return Qnil;
306
+ }
307
+
308
+ /* Document-method: push_array
309
+ * call-seq: push_array(key=nil)
310
+ *
311
+ * Pushes an array 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_array(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_array(sw, 0);
322
+ break;
323
+ case 1:
324
+ if (Qnil == argv[0]) {
325
+ oj_str_writer_push_array(sw, 0);
326
+ } else {
327
+ rb_check_type(argv[0], T_STRING);
328
+ oj_str_writer_push_array(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_value
343
+ * call-seq: push_value(value, key=nil)
344
+ *
345
+ * Pushes a value onto the JSON document.
346
+ * - *value* [_Object_] value to add to the JSON document
347
+ * - *key* [_String_] the key if adding to an object in the JSON document
348
+ */
349
+ static VALUE
350
+ str_writer_push_value(int argc, VALUE *argv, VALUE self) {
351
+ switch (argc) {
352
+ case 1:
353
+ oj_str_writer_push_value((StrWriter)DATA_PTR(self), *argv, 0);
354
+ break;
355
+ case 2:
356
+ if (Qnil == argv[1]) {
357
+ oj_str_writer_push_value((StrWriter)DATA_PTR(self), *argv, 0);
358
+ } else {
359
+ rb_check_type(argv[1], T_STRING);
360
+ oj_str_writer_push_value((StrWriter)DATA_PTR(self), *argv, StringValuePtr(argv[1]));
361
+ }
362
+ break;
363
+ default:
364
+ rb_raise(rb_eArgError, "Wrong number of argument to 'push_value'.");
365
+ break;
366
+ }
367
+ return Qnil;
368
+ }
369
+
370
+ /* Document-method: push_json
371
+ * call-seq: push_json(value, key=nil)
372
+ *
373
+ * Pushes a string onto the JSON document. The String must be a valid JSON
374
+ * encoded string. No additional checking is done to verify the validity of the
375
+ * string.
376
+ * - *value* [_Object_] value to add to the JSON document
377
+ * - *key* [_String_] the key if adding to an object in the JSON document
378
+ */
379
+ static VALUE
380
+ str_writer_push_json(int argc, VALUE *argv, VALUE self) {
381
+ rb_check_type(argv[0], T_STRING);
382
+ switch (argc) {
383
+ case 1:
384
+ oj_str_writer_push_json((StrWriter)DATA_PTR(self), StringValuePtr(*argv), 0);
385
+ break;
386
+ case 2:
387
+ if (Qnil == argv[1]) {
388
+ oj_str_writer_push_json((StrWriter)DATA_PTR(self), StringValuePtr(*argv), 0);
389
+ } else {
390
+ rb_check_type(argv[1], T_STRING);
391
+ oj_str_writer_push_json((StrWriter)DATA_PTR(self), StringValuePtr(*argv), StringValuePtr(argv[1]));
392
+ }
393
+ break;
394
+ default:
395
+ rb_raise(rb_eArgError, "Wrong number of argument to 'push_json'.");
396
+ break;
397
+ }
398
+ return Qnil;
399
+ }
400
+ /* Document-method: pop
401
+ * call-seq: pop()
402
+ *
403
+ * Pops up a level in the JSON document closing the array or object that is
404
+ * currently open.
405
+ */
406
+ static VALUE
407
+ str_writer_pop(VALUE self) {
408
+ oj_str_writer_pop((StrWriter)DATA_PTR(self));
409
+ return Qnil;
410
+ }
411
+
412
+ /* Document-method: pop_all
413
+ * call-seq: pop_all()
414
+ *
415
+ * Pops all level in the JSON document closing all the array or object that is
416
+ * currently open.
417
+ */
418
+ static VALUE
419
+ str_writer_pop_all(VALUE self) {
420
+ oj_str_writer_pop_all((StrWriter)DATA_PTR(self));
421
+
422
+ return Qnil;
423
+ }
424
+
425
+ /* Document-method: reset
426
+ * call-seq: reset()
427
+ *
428
+ * Reset the writer back to the empty state.
429
+ */
430
+ static VALUE
431
+ str_writer_reset(VALUE self) {
432
+ StrWriter sw = (StrWriter)DATA_PTR(self);
433
+
434
+ sw->depth = 0;
435
+ *sw->types = '\0';
436
+ sw->keyWritten = 0;
437
+ sw->out.cur = sw->out.buf;
438
+ *sw->out.cur = '\0';
439
+
440
+ return Qnil;
441
+ }
442
+
443
+ /* Document-method: to_s
444
+ * call-seq: to_s()
445
+ *
446
+ * Returns the JSON document string in what ever state the construction is at.
447
+ *
448
+ * *return* [_String_]
449
+ */
450
+ static VALUE
451
+ str_writer_to_s(VALUE self) {
452
+ StrWriter sw = (StrWriter)DATA_PTR(self);
453
+ VALUE rstr = rb_str_new(sw->out.buf, sw->out.cur - sw->out.buf);
454
+
455
+ return oj_encode(rstr);
456
+ }
457
+
458
+ /* Document-class: Oj::StringWriter
459
+ *
460
+ * Supports building a JSON document one element at a time. Build the document
461
+ * by pushing values into the document. Pushing an array or an object will
462
+ * create that element in the JSON document and subsequent pushes will add the
463
+ * elements to that array or object until a pop() is called. When complete
464
+ * calling to_s() will return the JSON document. Note tha calling to_s() before
465
+ * construction is complete will return the document in it's current state.
466
+ */
467
+ void
468
+ oj_string_writer_init() {
469
+ oj_string_writer_class = rb_define_class_under(Oj, "StringWriter", rb_cObject);
470
+ rb_define_module_function(oj_string_writer_class, "new", str_writer_new, -1);
471
+ rb_define_method(oj_string_writer_class, "push_key", str_writer_push_key, 1);
472
+ rb_define_method(oj_string_writer_class, "push_object", str_writer_push_object, -1);
473
+ rb_define_method(oj_string_writer_class, "push_array", str_writer_push_array, -1);
474
+ rb_define_method(oj_string_writer_class, "push_value", str_writer_push_value, -1);
475
+ rb_define_method(oj_string_writer_class, "push_json", str_writer_push_json, -1);
476
+ rb_define_method(oj_string_writer_class, "pop", str_writer_pop, 0);
477
+ rb_define_method(oj_string_writer_class, "pop_all", str_writer_pop_all, 0);
478
+ rb_define_method(oj_string_writer_class, "reset", str_writer_reset, 0);
479
+ rb_define_method(oj_string_writer_class, "to_s", str_writer_to_s, 0);
480
+ }