libyajl2 0.1.4 → 0.1.5

Sign up to get free protection for your applications and to get access to all the features.
@@ -0,0 +1,220 @@
1
+ /*
2
+ * Copyright (c) 2007-2014, Lloyd Hilaiel <me@lloyd.io>
3
+ *
4
+ * Permission to use, copy, modify, and/or distribute this software for any
5
+ * purpose with or without fee is hereby granted, provided that the above
6
+ * copyright notice and this permission notice appear in all copies.
7
+ *
8
+ * THE SOFTWARE IS PROVIDED "AS IS" AND THE AUTHOR DISCLAIMS ALL WARRANTIES
9
+ * WITH REGARD TO THIS SOFTWARE INCLUDING ALL IMPLIED WARRANTIES OF
10
+ * MERCHANTABILITY AND FITNESS. IN NO EVENT SHALL THE AUTHOR BE LIABLE FOR
11
+ * ANY SPECIAL, DIRECT, INDIRECT, OR CONSEQUENTIAL DAMAGES OR ANY DAMAGES
12
+ * WHATSOEVER RESULTING FROM LOSS OF USE, DATA OR PROFITS, WHETHER IN AN
13
+ * ACTION OF CONTRACT, NEGLIGENCE OR OTHER TORTIOUS ACTION, ARISING OUT OF
14
+ * OR IN CONNECTION WITH THE USE OR PERFORMANCE OF THIS SOFTWARE.
15
+ */
16
+
17
+ #include "yajl_encode.h"
18
+
19
+ #include <assert.h>
20
+ #include <stdlib.h>
21
+ #include <string.h>
22
+ #include <stdio.h>
23
+
24
+ static void CharToHex(unsigned char c, char * hexBuf)
25
+ {
26
+ const char * hexchar = "0123456789ABCDEF";
27
+ hexBuf[0] = hexchar[c >> 4];
28
+ hexBuf[1] = hexchar[c & 0x0F];
29
+ }
30
+
31
+ void
32
+ yajl_string_encode(const yajl_print_t print,
33
+ void * ctx,
34
+ const unsigned char * str,
35
+ size_t len,
36
+ int escape_solidus)
37
+ {
38
+ size_t beg = 0;
39
+ size_t end = 0;
40
+ char hexBuf[7];
41
+ hexBuf[0] = '\\'; hexBuf[1] = 'u'; hexBuf[2] = '0'; hexBuf[3] = '0';
42
+ hexBuf[6] = 0;
43
+
44
+ while (end < len) {
45
+ const char * escaped = NULL;
46
+ switch (str[end]) {
47
+ case '\r': escaped = "\\r"; break;
48
+ case '\n': escaped = "\\n"; break;
49
+ case '\\': escaped = "\\\\"; break;
50
+ /* it is not required to escape a solidus in JSON:
51
+ * read sec. 2.5: http://www.ietf.org/rfc/rfc4627.txt
52
+ * specifically, this production from the grammar:
53
+ * unescaped = %x20-21 / %x23-5B / %x5D-10FFFF
54
+ */
55
+ case '/': if (escape_solidus) escaped = "\\/"; break;
56
+ case '"': escaped = "\\\""; break;
57
+ case '\f': escaped = "\\f"; break;
58
+ case '\b': escaped = "\\b"; break;
59
+ case '\t': escaped = "\\t"; break;
60
+ default:
61
+ if ((unsigned char) str[end] < 32) {
62
+ CharToHex(str[end], hexBuf + 4);
63
+ escaped = hexBuf;
64
+ }
65
+ break;
66
+ }
67
+ if (escaped != NULL) {
68
+ print(ctx, (const char *) (str + beg), end - beg);
69
+ print(ctx, escaped, (unsigned int)strlen(escaped));
70
+ beg = ++end;
71
+ } else {
72
+ ++end;
73
+ }
74
+ }
75
+ print(ctx, (const char *) (str + beg), end - beg);
76
+ }
77
+
78
+ static void hexToDigit(unsigned int * val, const unsigned char * hex)
79
+ {
80
+ unsigned int i;
81
+ for (i=0;i<4;i++) {
82
+ unsigned char c = hex[i];
83
+ if (c >= 'A') c = (c & ~0x20) - 7;
84
+ c -= '0';
85
+ assert(!(c & 0xF0));
86
+ *val = (*val << 4) | c;
87
+ }
88
+ }
89
+
90
+ static void Utf32toUtf8(unsigned int codepoint, char * utf8Buf)
91
+ {
92
+ if (codepoint < 0x80) {
93
+ utf8Buf[0] = (char) codepoint;
94
+ utf8Buf[1] = 0;
95
+ } else if (codepoint < 0x0800) {
96
+ utf8Buf[0] = (char) ((codepoint >> 6) | 0xC0);
97
+ utf8Buf[1] = (char) ((codepoint & 0x3F) | 0x80);
98
+ utf8Buf[2] = 0;
99
+ } else if (codepoint < 0x10000) {
100
+ utf8Buf[0] = (char) ((codepoint >> 12) | 0xE0);
101
+ utf8Buf[1] = (char) (((codepoint >> 6) & 0x3F) | 0x80);
102
+ utf8Buf[2] = (char) ((codepoint & 0x3F) | 0x80);
103
+ utf8Buf[3] = 0;
104
+ } else if (codepoint < 0x200000) {
105
+ utf8Buf[0] =(char)((codepoint >> 18) | 0xF0);
106
+ utf8Buf[1] =(char)(((codepoint >> 12) & 0x3F) | 0x80);
107
+ utf8Buf[2] =(char)(((codepoint >> 6) & 0x3F) | 0x80);
108
+ utf8Buf[3] =(char)((codepoint & 0x3F) | 0x80);
109
+ utf8Buf[4] = 0;
110
+ } else {
111
+ utf8Buf[0] = '?';
112
+ utf8Buf[1] = 0;
113
+ }
114
+ }
115
+
116
+ void yajl_string_decode(yajl_buf buf, const unsigned char * str,
117
+ size_t len)
118
+ {
119
+ size_t beg = 0;
120
+ size_t end = 0;
121
+
122
+ while (end < len) {
123
+ if (str[end] == '\\') {
124
+ char utf8Buf[5];
125
+ const char * unescaped = "?";
126
+ yajl_buf_append(buf, str + beg, end - beg);
127
+ switch (str[++end]) {
128
+ case 'r': unescaped = "\r"; break;
129
+ case 'n': unescaped = "\n"; break;
130
+ case '\\': unescaped = "\\"; break;
131
+ case '/': unescaped = "/"; break;
132
+ case '"': unescaped = "\""; break;
133
+ case 'f': unescaped = "\f"; break;
134
+ case 'b': unescaped = "\b"; break;
135
+ case 't': unescaped = "\t"; break;
136
+ case 'u': {
137
+ unsigned int codepoint = 0;
138
+ hexToDigit(&codepoint, str + ++end);
139
+ end+=3;
140
+ /* check if this is a surrogate */
141
+ if ((codepoint & 0xFC00) == 0xD800) {
142
+ end++;
143
+ if (str[end] == '\\' && str[end + 1] == 'u') {
144
+ unsigned int surrogate = 0;
145
+ hexToDigit(&surrogate, str + end + 2);
146
+ codepoint =
147
+ (((codepoint & 0x3F) << 10) |
148
+ ((((codepoint >> 6) & 0xF) + 1) << 16) |
149
+ (surrogate & 0x3FF));
150
+ end += 5;
151
+ } else {
152
+ unescaped = "?";
153
+ break;
154
+ }
155
+ }
156
+
157
+ Utf32toUtf8(codepoint, utf8Buf);
158
+ unescaped = utf8Buf;
159
+
160
+ if (codepoint == 0) {
161
+ yajl_buf_append(buf, unescaped, 1);
162
+ beg = ++end;
163
+ continue;
164
+ }
165
+
166
+ break;
167
+ }
168
+ default:
169
+ assert("this should never happen" == NULL);
170
+ }
171
+ yajl_buf_append(buf, unescaped, (unsigned int)strlen(unescaped));
172
+ beg = ++end;
173
+ } else {
174
+ end++;
175
+ }
176
+ }
177
+ yajl_buf_append(buf, str + beg, end - beg);
178
+ }
179
+
180
+ #define ADV_PTR s++; if (!(len--)) return 0;
181
+
182
+ int yajl_string_validate_utf8(const unsigned char * s, size_t len)
183
+ {
184
+ if (!len) return 1;
185
+ if (!s) return 0;
186
+
187
+ while (len--) {
188
+ /* single byte */
189
+ if (*s <= 0x7f) {
190
+ /* noop */
191
+ }
192
+ /* two byte */
193
+ else if ((*s >> 5) == 0x6) {
194
+ ADV_PTR;
195
+ if (!((*s >> 6) == 0x2)) return 0;
196
+ }
197
+ /* three byte */
198
+ else if ((*s >> 4) == 0x0e) {
199
+ ADV_PTR;
200
+ if (!((*s >> 6) == 0x2)) return 0;
201
+ ADV_PTR;
202
+ if (!((*s >> 6) == 0x2)) return 0;
203
+ }
204
+ /* four byte */
205
+ else if ((*s >> 3) == 0x1e) {
206
+ ADV_PTR;
207
+ if (!((*s >> 6) == 0x2)) return 0;
208
+ ADV_PTR;
209
+ if (!((*s >> 6) == 0x2)) return 0;
210
+ ADV_PTR;
211
+ if (!((*s >> 6) == 0x2)) return 0;
212
+ } else {
213
+ return 0;
214
+ }
215
+
216
+ s++;
217
+ }
218
+
219
+ return 1;
220
+ }
@@ -0,0 +1,34 @@
1
+ /*
2
+ * Copyright (c) 2007-2014, Lloyd Hilaiel <me@lloyd.io>
3
+ *
4
+ * Permission to use, copy, modify, and/or distribute this software for any
5
+ * purpose with or without fee is hereby granted, provided that the above
6
+ * copyright notice and this permission notice appear in all copies.
7
+ *
8
+ * THE SOFTWARE IS PROVIDED "AS IS" AND THE AUTHOR DISCLAIMS ALL WARRANTIES
9
+ * WITH REGARD TO THIS SOFTWARE INCLUDING ALL IMPLIED WARRANTIES OF
10
+ * MERCHANTABILITY AND FITNESS. IN NO EVENT SHALL THE AUTHOR BE LIABLE FOR
11
+ * ANY SPECIAL, DIRECT, INDIRECT, OR CONSEQUENTIAL DAMAGES OR ANY DAMAGES
12
+ * WHATSOEVER RESULTING FROM LOSS OF USE, DATA OR PROFITS, WHETHER IN AN
13
+ * ACTION OF CONTRACT, NEGLIGENCE OR OTHER TORTIOUS ACTION, ARISING OUT OF
14
+ * OR IN CONNECTION WITH THE USE OR PERFORMANCE OF THIS SOFTWARE.
15
+ */
16
+
17
+ #ifndef __YAJL_ENCODE_H__
18
+ #define __YAJL_ENCODE_H__
19
+
20
+ #include "yajl_buf.h"
21
+ #include "api/yajl_gen.h"
22
+
23
+ void yajl_string_encode(const yajl_print_t printer,
24
+ void * ctx,
25
+ const unsigned char * str,
26
+ size_t length,
27
+ int escape_solidus);
28
+
29
+ void yajl_string_decode(yajl_buf buf, const unsigned char * str,
30
+ size_t length);
31
+
32
+ int yajl_string_validate_utf8(const unsigned char * s, size_t len);
33
+
34
+ #endif
@@ -0,0 +1,362 @@
1
+ /*
2
+ * Copyright (c) 2007-2014, Lloyd Hilaiel <me@lloyd.io>
3
+ *
4
+ * Permission to use, copy, modify, and/or distribute this software for any
5
+ * purpose with or without fee is hereby granted, provided that the above
6
+ * copyright notice and this permission notice appear in all copies.
7
+ *
8
+ * THE SOFTWARE IS PROVIDED "AS IS" AND THE AUTHOR DISCLAIMS ALL WARRANTIES
9
+ * WITH REGARD TO THIS SOFTWARE INCLUDING ALL IMPLIED WARRANTIES OF
10
+ * MERCHANTABILITY AND FITNESS. IN NO EVENT SHALL THE AUTHOR BE LIABLE FOR
11
+ * ANY SPECIAL, DIRECT, INDIRECT, OR CONSEQUENTIAL DAMAGES OR ANY DAMAGES
12
+ * WHATSOEVER RESULTING FROM LOSS OF USE, DATA OR PROFITS, WHETHER IN AN
13
+ * ACTION OF CONTRACT, NEGLIGENCE OR OTHER TORTIOUS ACTION, ARISING OUT OF
14
+ * OR IN CONNECTION WITH THE USE OR PERFORMANCE OF THIS SOFTWARE.
15
+ */
16
+
17
+ #include "api/yajl_gen.h"
18
+ #include "yajl_buf.h"
19
+ #include "yajl_encode.h"
20
+
21
+ #include <stdlib.h>
22
+ #include <string.h>
23
+ #include <stdio.h>
24
+ #include <math.h>
25
+ #include <stdarg.h>
26
+
27
+ typedef enum {
28
+ yajl_gen_start,
29
+ yajl_gen_map_start,
30
+ yajl_gen_map_key,
31
+ yajl_gen_map_val,
32
+ yajl_gen_array_start,
33
+ yajl_gen_in_array,
34
+ yajl_gen_complete,
35
+ yajl_gen_error
36
+ } yajl_gen_state;
37
+
38
+ struct yajl_gen_t
39
+ {
40
+ unsigned int flags;
41
+ unsigned int depth;
42
+ const char * indentString;
43
+ yajl_gen_state state[YAJL_MAX_DEPTH];
44
+ yajl_print_t print;
45
+ void * ctx; /* yajl_buf */
46
+ /* memory allocation routines */
47
+ yajl_alloc_funcs alloc;
48
+ };
49
+
50
+ int
51
+ yajl_gen_config(yajl_gen g, yajl_gen_option opt, ...)
52
+ {
53
+ int rv = 1;
54
+ va_list ap;
55
+ va_start(ap, opt);
56
+
57
+ switch(opt) {
58
+ case yajl_gen_beautify:
59
+ case yajl_gen_validate_utf8:
60
+ case yajl_gen_escape_solidus:
61
+ if (va_arg(ap, int)) g->flags |= opt;
62
+ else g->flags &= ~opt;
63
+ break;
64
+ case yajl_gen_indent_string: {
65
+ const char *indent = va_arg(ap, const char *);
66
+ g->indentString = indent;
67
+ for (; *indent; indent++) {
68
+ if (*indent != '\n'
69
+ && *indent != '\v'
70
+ && *indent != '\f'
71
+ && *indent != '\t'
72
+ && *indent != '\r'
73
+ && *indent != ' ')
74
+ {
75
+ g->indentString = NULL;
76
+ rv = 0;
77
+ }
78
+ }
79
+ break;
80
+ }
81
+ case yajl_gen_print_callback:
82
+ yajl_buf_free(g->ctx);
83
+ g->print = va_arg(ap, const yajl_print_t);
84
+ g->ctx = va_arg(ap, void *);
85
+ break;
86
+ default:
87
+ rv = 0;
88
+ }
89
+
90
+ va_end(ap);
91
+
92
+ return rv;
93
+ }
94
+
95
+
96
+
97
+ yajl_gen
98
+ yajl_gen_alloc(const yajl_alloc_funcs * afs)
99
+ {
100
+ yajl_gen g = NULL;
101
+ yajl_alloc_funcs afsBuffer;
102
+
103
+ /* first order of business is to set up memory allocation routines */
104
+ if (afs != NULL) {
105
+ if (afs->malloc == NULL || afs->realloc == NULL || afs->free == NULL)
106
+ {
107
+ return NULL;
108
+ }
109
+ } else {
110
+ yajl_set_default_alloc_funcs(&afsBuffer);
111
+ afs = &afsBuffer;
112
+ }
113
+
114
+ g = (yajl_gen) YA_MALLOC(afs, sizeof(struct yajl_gen_t));
115
+ if (!g) return NULL;
116
+
117
+ memset((void *) g, 0, sizeof(struct yajl_gen_t));
118
+ /* copy in pointers to allocation routines */
119
+ memcpy((void *) &(g->alloc), (void *) afs, sizeof(yajl_alloc_funcs));
120
+
121
+ g->print = (yajl_print_t)&yajl_buf_append;
122
+ g->ctx = yajl_buf_alloc(&(g->alloc));
123
+ g->indentString = " ";
124
+
125
+ return g;
126
+ }
127
+
128
+ void
129
+ yajl_gen_reset(yajl_gen g, const char * sep)
130
+ {
131
+ g->depth = 0;
132
+ memset((void *) &(g->state), 0, sizeof(g->state));
133
+ if (sep != NULL) g->print(g->ctx, sep, strlen(sep));
134
+ }
135
+
136
+ void
137
+ yajl_gen_free(yajl_gen g)
138
+ {
139
+ if (g->print == (yajl_print_t)&yajl_buf_append) yajl_buf_free((yajl_buf)g->ctx);
140
+ YA_FREE(&(g->alloc), g);
141
+ }
142
+
143
+ #define INSERT_SEP \
144
+ if (g->state[g->depth] == yajl_gen_map_key || \
145
+ g->state[g->depth] == yajl_gen_in_array) { \
146
+ g->print(g->ctx, ",", 1); \
147
+ if ((g->flags & yajl_gen_beautify)) g->print(g->ctx, "\n", 1); \
148
+ } else if (g->state[g->depth] == yajl_gen_map_val) { \
149
+ g->print(g->ctx, ":", 1); \
150
+ if ((g->flags & yajl_gen_beautify)) g->print(g->ctx, " ", 1); \
151
+ }
152
+
153
+ #define INSERT_WHITESPACE \
154
+ if ((g->flags & yajl_gen_beautify)) { \
155
+ if (g->state[g->depth] != yajl_gen_map_val) { \
156
+ unsigned int _i; \
157
+ for (_i=0;_i<g->depth;_i++) \
158
+ g->print(g->ctx, \
159
+ g->indentString, \
160
+ (unsigned int)strlen(g->indentString)); \
161
+ } \
162
+ }
163
+
164
+ #define ENSURE_NOT_KEY \
165
+ if (g->state[g->depth] == yajl_gen_map_key || \
166
+ g->state[g->depth] == yajl_gen_map_start) { \
167
+ return yajl_gen_keys_must_be_strings; \
168
+ } \
169
+
170
+ /* check that we're not complete, or in error state. in a valid state
171
+ * to be generating */
172
+ #define ENSURE_VALID_STATE \
173
+ if (g->state[g->depth] == yajl_gen_error) { \
174
+ return yajl_gen_in_error_state;\
175
+ } else if (g->state[g->depth] == yajl_gen_complete) { \
176
+ return yajl_gen_generation_complete; \
177
+ }
178
+
179
+ #define INCREMENT_DEPTH \
180
+ if (++(g->depth) >= YAJL_MAX_DEPTH) return yajl_max_depth_exceeded;
181
+
182
+ #define DECREMENT_DEPTH \
183
+ if (--(g->depth) >= YAJL_MAX_DEPTH) return yajl_gen_generation_complete;
184
+
185
+ #define APPENDED_ATOM \
186
+ switch (g->state[g->depth]) { \
187
+ case yajl_gen_start: \
188
+ g->state[g->depth] = yajl_gen_complete; \
189
+ break; \
190
+ case yajl_gen_map_start: \
191
+ case yajl_gen_map_key: \
192
+ g->state[g->depth] = yajl_gen_map_val; \
193
+ break; \
194
+ case yajl_gen_array_start: \
195
+ g->state[g->depth] = yajl_gen_in_array; \
196
+ break; \
197
+ case yajl_gen_map_val: \
198
+ g->state[g->depth] = yajl_gen_map_key; \
199
+ break; \
200
+ default: \
201
+ break; \
202
+ } \
203
+
204
+ #define FINAL_NEWLINE \
205
+ if ((g->flags & yajl_gen_beautify) && g->state[g->depth] == yajl_gen_complete) \
206
+ g->print(g->ctx, "\n", 1);
207
+
208
+ yajl_gen_status
209
+ yajl_gen_integer(yajl_gen g, long long int number)
210
+ {
211
+ char i[32];
212
+ ENSURE_VALID_STATE; ENSURE_NOT_KEY; INSERT_SEP; INSERT_WHITESPACE;
213
+ sprintf(i, "%lld", number);
214
+ g->print(g->ctx, i, (unsigned int)strlen(i));
215
+ APPENDED_ATOM;
216
+ FINAL_NEWLINE;
217
+ return yajl_gen_status_ok;
218
+ }
219
+
220
+ #if ( defined(_WIN32) || defined(WIN32) ) && !defined(__GCC__)
221
+ #include <float.h>
222
+ #define isnan _isnan
223
+ #define isinf !_finite
224
+ #endif
225
+
226
+ yajl_gen_status
227
+ yajl_gen_double(yajl_gen g, double number)
228
+ {
229
+ char i[32];
230
+ ENSURE_VALID_STATE; ENSURE_NOT_KEY;
231
+ if (isnan(number) || isinf(number)) return yajl_gen_invalid_number;
232
+ INSERT_SEP; INSERT_WHITESPACE;
233
+ sprintf(i, "%.20g", number);
234
+ if (strspn(i, "0123456789-") == strlen(i)) {
235
+ strcat(i, ".0");
236
+ }
237
+ g->print(g->ctx, i, (unsigned int)strlen(i));
238
+ APPENDED_ATOM;
239
+ FINAL_NEWLINE;
240
+ return yajl_gen_status_ok;
241
+ }
242
+
243
+ yajl_gen_status
244
+ yajl_gen_number(yajl_gen g, const char * s, size_t l)
245
+ {
246
+ ENSURE_VALID_STATE; ENSURE_NOT_KEY; INSERT_SEP; INSERT_WHITESPACE;
247
+ g->print(g->ctx, s, l);
248
+ APPENDED_ATOM;
249
+ FINAL_NEWLINE;
250
+ return yajl_gen_status_ok;
251
+ }
252
+
253
+ yajl_gen_status
254
+ yajl_gen_string(yajl_gen g, const unsigned char * str,
255
+ size_t len)
256
+ {
257
+ // if validation is enabled, check that the string is valid utf8
258
+ // XXX: This checking could be done a little faster, in the same pass as
259
+ // the string encoding
260
+ if (g->flags & yajl_gen_validate_utf8) {
261
+ if (!yajl_string_validate_utf8(str, len)) {
262
+ return yajl_gen_invalid_string;
263
+ }
264
+ }
265
+ ENSURE_VALID_STATE; INSERT_SEP; INSERT_WHITESPACE;
266
+ g->print(g->ctx, "\"", 1);
267
+ yajl_string_encode(g->print, g->ctx, str, len, g->flags & yajl_gen_escape_solidus);
268
+ g->print(g->ctx, "\"", 1);
269
+ APPENDED_ATOM;
270
+ FINAL_NEWLINE;
271
+ return yajl_gen_status_ok;
272
+ }
273
+
274
+ yajl_gen_status
275
+ yajl_gen_null(yajl_gen g)
276
+ {
277
+ ENSURE_VALID_STATE; ENSURE_NOT_KEY; INSERT_SEP; INSERT_WHITESPACE;
278
+ g->print(g->ctx, "null", strlen("null"));
279
+ APPENDED_ATOM;
280
+ FINAL_NEWLINE;
281
+ return yajl_gen_status_ok;
282
+ }
283
+
284
+ yajl_gen_status
285
+ yajl_gen_bool(yajl_gen g, int boolean)
286
+ {
287
+ const char * val = boolean ? "true" : "false";
288
+
289
+ ENSURE_VALID_STATE; ENSURE_NOT_KEY; INSERT_SEP; INSERT_WHITESPACE;
290
+ g->print(g->ctx, val, (unsigned int)strlen(val));
291
+ APPENDED_ATOM;
292
+ FINAL_NEWLINE;
293
+ return yajl_gen_status_ok;
294
+ }
295
+
296
+ yajl_gen_status
297
+ yajl_gen_map_open(yajl_gen g)
298
+ {
299
+ ENSURE_VALID_STATE; ENSURE_NOT_KEY; INSERT_SEP; INSERT_WHITESPACE;
300
+ INCREMENT_DEPTH;
301
+
302
+ g->state[g->depth] = yajl_gen_map_start;
303
+ g->print(g->ctx, "{", 1);
304
+ if ((g->flags & yajl_gen_beautify)) g->print(g->ctx, "\n", 1);
305
+ FINAL_NEWLINE;
306
+ return yajl_gen_status_ok;
307
+ }
308
+
309
+ yajl_gen_status
310
+ yajl_gen_map_close(yajl_gen g)
311
+ {
312
+ ENSURE_VALID_STATE;
313
+ DECREMENT_DEPTH;
314
+
315
+ if ((g->flags & yajl_gen_beautify)) g->print(g->ctx, "\n", 1);
316
+ APPENDED_ATOM;
317
+ INSERT_WHITESPACE;
318
+ g->print(g->ctx, "}", 1);
319
+ FINAL_NEWLINE;
320
+ return yajl_gen_status_ok;
321
+ }
322
+
323
+ yajl_gen_status
324
+ yajl_gen_array_open(yajl_gen g)
325
+ {
326
+ ENSURE_VALID_STATE; ENSURE_NOT_KEY; INSERT_SEP; INSERT_WHITESPACE;
327
+ INCREMENT_DEPTH;
328
+ g->state[g->depth] = yajl_gen_array_start;
329
+ g->print(g->ctx, "[", 1);
330
+ if ((g->flags & yajl_gen_beautify)) g->print(g->ctx, "\n", 1);
331
+ FINAL_NEWLINE;
332
+ return yajl_gen_status_ok;
333
+ }
334
+
335
+ yajl_gen_status
336
+ yajl_gen_array_close(yajl_gen g)
337
+ {
338
+ ENSURE_VALID_STATE;
339
+ DECREMENT_DEPTH;
340
+ if ((g->flags & yajl_gen_beautify)) g->print(g->ctx, "\n", 1);
341
+ APPENDED_ATOM;
342
+ INSERT_WHITESPACE;
343
+ g->print(g->ctx, "]", 1);
344
+ FINAL_NEWLINE;
345
+ return yajl_gen_status_ok;
346
+ }
347
+
348
+ yajl_gen_status
349
+ yajl_gen_get_buf(yajl_gen g, const unsigned char ** buf,
350
+ size_t * len)
351
+ {
352
+ if (g->print != (yajl_print_t)&yajl_buf_append) return yajl_gen_no_buf;
353
+ *buf = yajl_buf_data((yajl_buf)g->ctx);
354
+ *len = yajl_buf_len((yajl_buf)g->ctx);
355
+ return yajl_gen_status_ok;
356
+ }
357
+
358
+ void
359
+ yajl_gen_clear(yajl_gen g)
360
+ {
361
+ if (g->print == (yajl_print_t)&yajl_buf_append) yajl_buf_clear((yajl_buf)g->ctx);
362
+ }