yaji 0.2.3-x86-mingw32

Sign up to get free protection for your applications and to get access to all the features.
@@ -0,0 +1,80 @@
1
+ /*
2
+ * Copyright 2010, Lloyd Hilaiel.
3
+ *
4
+ * Redistribution and use in source and binary forms, with or without
5
+ * modification, are permitted provided that the following conditions are
6
+ * met:
7
+ *
8
+ * 1. Redistributions of source code must retain the above copyright
9
+ * notice, this list of conditions and the following disclaimer.
10
+ *
11
+ * 2. Redistributions in binary form must reproduce the above copyright
12
+ * notice, this list of conditions and the following disclaimer in
13
+ * the documentation and/or other materials provided with the
14
+ * distribution.
15
+ *
16
+ * 3. Neither the name of Lloyd Hilaiel nor the names of its
17
+ * contributors may be used to endorse or promote products derived
18
+ * from this software without specific prior written permission.
19
+ *
20
+ * THIS SOFTWARE IS PROVIDED BY THE AUTHOR ``AS IS'' AND ANY EXPRESS OR
21
+ * IMPLIED WARRANTIES, INCLUDING, BUT NOT LIMITED TO, THE IMPLIED
22
+ * WARRANTIES OF MERCHANTABILITY AND FITNESS FOR A PARTICULAR PURPOSE ARE
23
+ * DISCLAIMED. IN NO EVENT SHALL THE AUTHOR BE LIABLE FOR ANY DIRECT,
24
+ * INDIRECT, INCIDENTAL, SPECIAL, EXEMPLARY, OR CONSEQUENTIAL DAMAGES
25
+ * (INCLUDING, BUT NOT LIMITED TO, PROCUREMENT OF SUBSTITUTE GOODS OR
26
+ * SERVICES; LOSS OF USE, DATA, OR PROFITS; OR BUSINESS INTERRUPTION)
27
+ * HOWEVER CAUSED AND ON ANY THEORY OF LIABILITY, WHETHER IN CONTRACT,
28
+ * STRICT LIABILITY, OR TORT (INCLUDING NEGLIGENCE OR OTHERWISE) ARISING
29
+ * IN ANY WAY OUT OF THE USE OF THIS SOFTWARE, EVEN IF ADVISED OF THE
30
+ * POSSIBILITY OF SUCH DAMAGE.
31
+ */
32
+
33
+ #ifndef __YAJL_BUF_H__
34
+ #define __YAJL_BUF_H__
35
+
36
+ #include "api/yajl_common.h"
37
+ #include "yajl_alloc.h"
38
+
39
+ /*
40
+ * Implementation/performance notes. If this were moved to a header
41
+ * only implementation using #define's where possible we might be
42
+ * able to sqeeze a little performance out of the guy by killing function
43
+ * call overhead. YMMV.
44
+ */
45
+
46
+ /**
47
+ * yajl_buf is a buffer with exponential growth. the buffer ensures that
48
+ * you are always null padded.
49
+ */
50
+ typedef struct yajl_buf_t * yajl_buf;
51
+
52
+ /* allocate a new buffer */
53
+ YAJL_API
54
+ yajl_buf yajl_buf_alloc(yajl_alloc_funcs * alloc);
55
+
56
+ /* free the buffer */
57
+ YAJL_API
58
+ void yajl_buf_free(yajl_buf buf);
59
+
60
+ /* append a number of bytes to the buffer */
61
+ YAJL_API
62
+ void yajl_buf_append(yajl_buf buf, const void * data, unsigned int len);
63
+
64
+ /* empty the buffer */
65
+ YAJL_API
66
+ void yajl_buf_clear(yajl_buf buf);
67
+
68
+ /* get a pointer to the beginning of the buffer */
69
+ YAJL_API
70
+ const unsigned char * yajl_buf_data(yajl_buf buf);
71
+
72
+ /* get the length of the buffer */
73
+ YAJL_API
74
+ unsigned int yajl_buf_len(yajl_buf buf);
75
+
76
+ /* truncate the buffer */
77
+ YAJL_API
78
+ void yajl_buf_truncate(yajl_buf buf, unsigned int len);
79
+
80
+ #endif
@@ -0,0 +1,85 @@
1
+ /*
2
+ * Copyright 2010, Lloyd Hilaiel.
3
+ *
4
+ * Redistribution and use in source and binary forms, with or without
5
+ * modification, are permitted provided that the following conditions are
6
+ * met:
7
+ *
8
+ * 1. Redistributions of source code must retain the above copyright
9
+ * notice, this list of conditions and the following disclaimer.
10
+ *
11
+ * 2. Redistributions in binary form must reproduce the above copyright
12
+ * notice, this list of conditions and the following disclaimer in
13
+ * the documentation and/or other materials provided with the
14
+ * distribution.
15
+ *
16
+ * 3. Neither the name of Lloyd Hilaiel nor the names of its
17
+ * contributors may be used to endorse or promote products derived
18
+ * from this software without specific prior written permission.
19
+ *
20
+ * THIS SOFTWARE IS PROVIDED BY THE AUTHOR ``AS IS'' AND ANY EXPRESS OR
21
+ * IMPLIED WARRANTIES, INCLUDING, BUT NOT LIMITED TO, THE IMPLIED
22
+ * WARRANTIES OF MERCHANTABILITY AND FITNESS FOR A PARTICULAR PURPOSE ARE
23
+ * DISCLAIMED. IN NO EVENT SHALL THE AUTHOR BE LIABLE FOR ANY DIRECT,
24
+ * INDIRECT, INCIDENTAL, SPECIAL, EXEMPLARY, OR CONSEQUENTIAL DAMAGES
25
+ * (INCLUDING, BUT NOT LIMITED TO, PROCUREMENT OF SUBSTITUTE GOODS OR
26
+ * SERVICES; LOSS OF USE, DATA, OR PROFITS; OR BUSINESS INTERRUPTION)
27
+ * HOWEVER CAUSED AND ON ANY THEORY OF LIABILITY, WHETHER IN CONTRACT,
28
+ * STRICT LIABILITY, OR TORT (INCLUDING NEGLIGENCE OR OTHERWISE) ARISING
29
+ * IN ANY WAY OUT OF THE USE OF THIS SOFTWARE, EVEN IF ADVISED OF THE
30
+ * POSSIBILITY OF SUCH DAMAGE.
31
+ */
32
+
33
+ /*
34
+ * A header only implementation of a simple stack of bytes, used in YAJL
35
+ * to maintain parse state.
36
+ */
37
+
38
+ #ifndef __YAJL_BYTESTACK_H__
39
+ #define __YAJL_BYTESTACK_H__
40
+
41
+ #include "api/yajl_common.h"
42
+
43
+ #define YAJL_BS_INC 128
44
+
45
+ typedef struct yajl_bytestack_t
46
+ {
47
+ unsigned char * stack;
48
+ unsigned int size;
49
+ unsigned int used;
50
+ yajl_alloc_funcs * yaf;
51
+ } yajl_bytestack;
52
+
53
+ /* initialize a bytestack */
54
+ #define yajl_bs_init(obs, _yaf) { \
55
+ (obs).stack = NULL; \
56
+ (obs).size = 0; \
57
+ (obs).used = 0; \
58
+ (obs).yaf = (_yaf); \
59
+ } \
60
+
61
+
62
+ /* initialize a bytestack */
63
+ #define yajl_bs_free(obs) \
64
+ if ((obs).stack) (obs).yaf->free((obs).yaf->ctx, (obs).stack);
65
+
66
+ #define yajl_bs_current(obs) \
67
+ (assert((obs).used > 0), (obs).stack[(obs).used - 1])
68
+
69
+ #define yajl_bs_push(obs, byte) { \
70
+ if (((obs).size - (obs).used) == 0) { \
71
+ (obs).size += YAJL_BS_INC; \
72
+ (obs).stack = (obs).yaf->realloc((obs).yaf->ctx,\
73
+ (void *) (obs).stack, (obs).size);\
74
+ } \
75
+ (obs).stack[((obs).used)++] = (byte); \
76
+ }
77
+
78
+ /* removes the top item of the stack, returns nothing */
79
+ #define yajl_bs_pop(obs) { ((obs).used)--; }
80
+
81
+ #define yajl_bs_set(obs, byte) \
82
+ (obs).stack[((obs).used) - 1] = (byte);
83
+
84
+
85
+ #endif
@@ -0,0 +1,195 @@
1
+ /*
2
+ * Copyright 2010, Lloyd Hilaiel.
3
+ *
4
+ * Redistribution and use in source and binary forms, with or without
5
+ * modification, are permitted provided that the following conditions are
6
+ * met:
7
+ *
8
+ * 1. Redistributions of source code must retain the above copyright
9
+ * notice, this list of conditions and the following disclaimer.
10
+ *
11
+ * 2. Redistributions in binary form must reproduce the above copyright
12
+ * notice, this list of conditions and the following disclaimer in
13
+ * the documentation and/or other materials provided with the
14
+ * distribution.
15
+ *
16
+ * 3. Neither the name of Lloyd Hilaiel nor the names of its
17
+ * contributors may be used to endorse or promote products derived
18
+ * from this software without specific prior written permission.
19
+ *
20
+ * THIS SOFTWARE IS PROVIDED BY THE AUTHOR ``AS IS'' AND ANY EXPRESS OR
21
+ * IMPLIED WARRANTIES, INCLUDING, BUT NOT LIMITED TO, THE IMPLIED
22
+ * WARRANTIES OF MERCHANTABILITY AND FITNESS FOR A PARTICULAR PURPOSE ARE
23
+ * DISCLAIMED. IN NO EVENT SHALL THE AUTHOR BE LIABLE FOR ANY DIRECT,
24
+ * INDIRECT, INCIDENTAL, SPECIAL, EXEMPLARY, OR CONSEQUENTIAL DAMAGES
25
+ * (INCLUDING, BUT NOT LIMITED TO, PROCUREMENT OF SUBSTITUTE GOODS OR
26
+ * SERVICES; LOSS OF USE, DATA, OR PROFITS; OR BUSINESS INTERRUPTION)
27
+ * HOWEVER CAUSED AND ON ANY THEORY OF LIABILITY, WHETHER IN CONTRACT,
28
+ * STRICT LIABILITY, OR TORT (INCLUDING NEGLIGENCE OR OTHERWISE) ARISING
29
+ * IN ANY WAY OUT OF THE USE OF THIS SOFTWARE, EVEN IF ADVISED OF THE
30
+ * POSSIBILITY OF SUCH DAMAGE.
31
+ */
32
+
33
+ #include "yajl_encode.h"
34
+
35
+ #include <assert.h>
36
+ #include <stdlib.h>
37
+ #include <string.h>
38
+ #include <stdio.h>
39
+
40
+ static void CharToHex(unsigned char c, char * hexBuf)
41
+ {
42
+ const char * hexchar = "0123456789ABCDEF";
43
+ hexBuf[0] = hexchar[c >> 4];
44
+ hexBuf[1] = hexchar[c & 0x0F];
45
+ }
46
+
47
+ void
48
+ yajl_string_encode(yajl_buf buf, const unsigned char * str,
49
+ unsigned int len)
50
+ {
51
+ yajl_string_encode2((const yajl_print_t) &yajl_buf_append, buf, str, len);
52
+ }
53
+
54
+ void
55
+ yajl_string_encode2(const yajl_print_t print,
56
+ void * ctx,
57
+ const unsigned char * str,
58
+ unsigned int len)
59
+ {
60
+ unsigned int beg = 0;
61
+ unsigned int end = 0;
62
+ char hexBuf[7];
63
+ hexBuf[0] = '\\'; hexBuf[1] = 'u'; hexBuf[2] = '0'; hexBuf[3] = '0';
64
+ hexBuf[6] = 0;
65
+
66
+ while (end < len) {
67
+ const char * escaped = NULL;
68
+ switch (str[end]) {
69
+ case '\r': escaped = "\\r"; break;
70
+ case '\n': escaped = "\\n"; break;
71
+ case '\\': escaped = "\\\\"; break;
72
+ /* case '/': escaped = "\\/"; break; */
73
+ case '"': escaped = "\\\""; break;
74
+ case '\f': escaped = "\\f"; break;
75
+ case '\b': escaped = "\\b"; break;
76
+ case '\t': escaped = "\\t"; break;
77
+ default:
78
+ if ((unsigned char) str[end] < 32) {
79
+ CharToHex(str[end], hexBuf + 4);
80
+ escaped = hexBuf;
81
+ }
82
+ break;
83
+ }
84
+ if (escaped != NULL) {
85
+ print(ctx, (const char *) (str + beg), end - beg);
86
+ print(ctx, escaped, (unsigned int)strlen(escaped));
87
+ beg = ++end;
88
+ } else {
89
+ ++end;
90
+ }
91
+ }
92
+ print(ctx, (const char *) (str + beg), end - beg);
93
+ }
94
+
95
+ static void hexToDigit(unsigned int * val, const unsigned char * hex)
96
+ {
97
+ unsigned int i;
98
+ for (i=0;i<4;i++) {
99
+ unsigned char c = hex[i];
100
+ if (c >= 'A') c = (c & ~0x20) - 7;
101
+ c -= '0';
102
+ assert(!(c & 0xF0));
103
+ *val = (*val << 4) | c;
104
+ }
105
+ }
106
+
107
+ static void Utf32toUtf8(unsigned int codepoint, char * utf8Buf)
108
+ {
109
+ if (codepoint < 0x80) {
110
+ utf8Buf[0] = (char) codepoint;
111
+ utf8Buf[1] = 0;
112
+ } else if (codepoint < 0x0800) {
113
+ utf8Buf[0] = (char) ((codepoint >> 6) | 0xC0);
114
+ utf8Buf[1] = (char) ((codepoint & 0x3F) | 0x80);
115
+ utf8Buf[2] = 0;
116
+ } else if (codepoint < 0x10000) {
117
+ utf8Buf[0] = (char) ((codepoint >> 12) | 0xE0);
118
+ utf8Buf[1] = (char) (((codepoint >> 6) & 0x3F) | 0x80);
119
+ utf8Buf[2] = (char) ((codepoint & 0x3F) | 0x80);
120
+ utf8Buf[3] = 0;
121
+ } else if (codepoint < 0x200000) {
122
+ utf8Buf[0] =(char)((codepoint >> 18) | 0xF0);
123
+ utf8Buf[1] =(char)(((codepoint >> 12) & 0x3F) | 0x80);
124
+ utf8Buf[2] =(char)(((codepoint >> 6) & 0x3F) | 0x80);
125
+ utf8Buf[3] =(char)((codepoint & 0x3F) | 0x80);
126
+ utf8Buf[4] = 0;
127
+ } else {
128
+ utf8Buf[0] = '?';
129
+ utf8Buf[1] = 0;
130
+ }
131
+ }
132
+
133
+ void yajl_string_decode(yajl_buf buf, const unsigned char * str,
134
+ unsigned int len)
135
+ {
136
+ unsigned int beg = 0;
137
+ unsigned int end = 0;
138
+
139
+ while (end < len) {
140
+ if (str[end] == '\\') {
141
+ char utf8Buf[5];
142
+ const char * unescaped = "?";
143
+ yajl_buf_append(buf, str + beg, end - beg);
144
+ switch (str[++end]) {
145
+ case 'r': unescaped = "\r"; break;
146
+ case 'n': unescaped = "\n"; break;
147
+ case '\\': unescaped = "\\"; break;
148
+ case '/': unescaped = "/"; break;
149
+ case '"': unescaped = "\""; break;
150
+ case 'f': unescaped = "\f"; break;
151
+ case 'b': unescaped = "\b"; break;
152
+ case 't': unescaped = "\t"; break;
153
+ case 'u': {
154
+ unsigned int codepoint = 0;
155
+ hexToDigit(&codepoint, str + ++end);
156
+ end+=3;
157
+ /* check if this is a surrogate */
158
+ if ((codepoint & 0xFC00) == 0xD800) {
159
+ end++;
160
+ if (str[end] == '\\' && str[end + 1] == 'u') {
161
+ unsigned int surrogate = 0;
162
+ hexToDigit(&surrogate, str + end + 2);
163
+ codepoint =
164
+ (((codepoint & 0x3F) << 10) |
165
+ ((((codepoint >> 6) & 0xF) + 1) << 16) |
166
+ (surrogate & 0x3FF));
167
+ end += 5;
168
+ } else {
169
+ unescaped = "?";
170
+ break;
171
+ }
172
+ }
173
+
174
+ Utf32toUtf8(codepoint, utf8Buf);
175
+ unescaped = utf8Buf;
176
+
177
+ if (codepoint == 0) {
178
+ yajl_buf_append(buf, unescaped, 1);
179
+ beg = ++end;
180
+ continue;
181
+ }
182
+
183
+ break;
184
+ }
185
+ default:
186
+ assert("this should never happen" == NULL);
187
+ }
188
+ yajl_buf_append(buf, unescaped, (unsigned int)strlen(unescaped));
189
+ beg = ++end;
190
+ } else {
191
+ end++;
192
+ }
193
+ }
194
+ yajl_buf_append(buf, str + beg, end - beg);
195
+ }
@@ -0,0 +1,53 @@
1
+ /*
2
+ * Copyright 2010, Lloyd Hilaiel.
3
+ *
4
+ * Redistribution and use in source and binary forms, with or without
5
+ * modification, are permitted provided that the following conditions are
6
+ * met:
7
+ *
8
+ * 1. Redistributions of source code must retain the above copyright
9
+ * notice, this list of conditions and the following disclaimer.
10
+ *
11
+ * 2. Redistributions in binary form must reproduce the above copyright
12
+ * notice, this list of conditions and the following disclaimer in
13
+ * the documentation and/or other materials provided with the
14
+ * distribution.
15
+ *
16
+ * 3. Neither the name of Lloyd Hilaiel nor the names of its
17
+ * contributors may be used to endorse or promote products derived
18
+ * from this software without specific prior written permission.
19
+ *
20
+ * THIS SOFTWARE IS PROVIDED BY THE AUTHOR ``AS IS'' AND ANY EXPRESS OR
21
+ * IMPLIED WARRANTIES, INCLUDING, BUT NOT LIMITED TO, THE IMPLIED
22
+ * WARRANTIES OF MERCHANTABILITY AND FITNESS FOR A PARTICULAR PURPOSE ARE
23
+ * DISCLAIMED. IN NO EVENT SHALL THE AUTHOR BE LIABLE FOR ANY DIRECT,
24
+ * INDIRECT, INCIDENTAL, SPECIAL, EXEMPLARY, OR CONSEQUENTIAL DAMAGES
25
+ * (INCLUDING, BUT NOT LIMITED TO, PROCUREMENT OF SUBSTITUTE GOODS OR
26
+ * SERVICES; LOSS OF USE, DATA, OR PROFITS; OR BUSINESS INTERRUPTION)
27
+ * HOWEVER CAUSED AND ON ANY THEORY OF LIABILITY, WHETHER IN CONTRACT,
28
+ * STRICT LIABILITY, OR TORT (INCLUDING NEGLIGENCE OR OTHERWISE) ARISING
29
+ * IN ANY WAY OUT OF THE USE OF THIS SOFTWARE, EVEN IF ADVISED OF THE
30
+ * POSSIBILITY OF SUCH DAMAGE.
31
+ */
32
+
33
+ #ifndef __YAJL_ENCODE_H__
34
+ #define __YAJL_ENCODE_H__
35
+
36
+ #include "yajl_buf.h"
37
+ #include "api/yajl_gen.h"
38
+
39
+ YAJL_API
40
+ void yajl_string_encode2(const yajl_print_t printer,
41
+ void * ctx,
42
+ const unsigned char * str,
43
+ unsigned int length);
44
+
45
+ YAJL_API
46
+ void yajl_string_encode(yajl_buf buf, const unsigned char * str,
47
+ unsigned int length);
48
+
49
+ YAJL_API
50
+ void yajl_string_decode(yajl_buf buf, const unsigned char * str,
51
+ unsigned int length);
52
+
53
+ #endif
@@ -0,0 +1,347 @@
1
+ /*
2
+ * Copyright 2010, Lloyd Hilaiel.
3
+ *
4
+ * Redistribution and use in source and binary forms, with or without
5
+ * modification, are permitted provided that the following conditions are
6
+ * met:
7
+ *
8
+ * 1. Redistributions of source code must retain the above copyright
9
+ * notice, this list of conditions and the following disclaimer.
10
+ *
11
+ * 2. Redistributions in binary form must reproduce the above copyright
12
+ * notice, this list of conditions and the following disclaimer in
13
+ * the documentation and/or other materials provided with the
14
+ * distribution.
15
+ *
16
+ * 3. Neither the name of Lloyd Hilaiel nor the names of its
17
+ * contributors may be used to endorse or promote products derived
18
+ * from this software without specific prior written permission.
19
+ *
20
+ * THIS SOFTWARE IS PROVIDED BY THE AUTHOR ``AS IS'' AND ANY EXPRESS OR
21
+ * IMPLIED WARRANTIES, INCLUDING, BUT NOT LIMITED TO, THE IMPLIED
22
+ * WARRANTIES OF MERCHANTABILITY AND FITNESS FOR A PARTICULAR PURPOSE ARE
23
+ * DISCLAIMED. IN NO EVENT SHALL THE AUTHOR BE LIABLE FOR ANY DIRECT,
24
+ * INDIRECT, INCIDENTAL, SPECIAL, EXEMPLARY, OR CONSEQUENTIAL DAMAGES
25
+ * (INCLUDING, BUT NOT LIMITED TO, PROCUREMENT OF SUBSTITUTE GOODS OR
26
+ * SERVICES; LOSS OF USE, DATA, OR PROFITS; OR BUSINESS INTERRUPTION)
27
+ * HOWEVER CAUSED AND ON ANY THEORY OF LIABILITY, WHETHER IN CONTRACT,
28
+ * STRICT LIABILITY, OR TORT (INCLUDING NEGLIGENCE OR OTHERWISE) ARISING
29
+ * IN ANY WAY OUT OF THE USE OF THIS SOFTWARE, EVEN IF ADVISED OF THE
30
+ * POSSIBILITY OF SUCH DAMAGE.
31
+ */
32
+
33
+ #include "api/yajl_gen.h"
34
+ #include "yajl_buf.h"
35
+ #include "yajl_encode.h"
36
+
37
+ #include <stdlib.h>
38
+ #include <string.h>
39
+ #include <stdio.h>
40
+ #include <math.h>
41
+
42
+ typedef enum {
43
+ yajl_gen_start,
44
+ yajl_gen_map_start,
45
+ yajl_gen_map_key,
46
+ yajl_gen_map_val,
47
+ yajl_gen_array_start,
48
+ yajl_gen_in_array,
49
+ yajl_gen_complete,
50
+ yajl_gen_error
51
+ } yajl_gen_state;
52
+
53
+ struct yajl_gen_t
54
+ {
55
+ unsigned int depth;
56
+ unsigned int pretty;
57
+ const char * indentString;
58
+ yajl_gen_state state[YAJL_MAX_DEPTH];
59
+ yajl_print_t print;
60
+ void * ctx; /* yajl_buf */
61
+ /* memory allocation routines */
62
+ yajl_alloc_funcs alloc;
63
+ };
64
+
65
+ yajl_gen
66
+ yajl_gen_alloc(const yajl_gen_config * config,
67
+ const yajl_alloc_funcs * afs)
68
+ {
69
+ return yajl_gen_alloc2(NULL, config, afs, NULL);
70
+ }
71
+
72
+ yajl_gen
73
+ yajl_gen_alloc2(const yajl_print_t callback,
74
+ const yajl_gen_config * config,
75
+ const yajl_alloc_funcs * afs,
76
+ void * ctx)
77
+ {
78
+ yajl_gen g = NULL;
79
+ yajl_alloc_funcs afsBuffer;
80
+
81
+ /* first order of business is to set up memory allocation routines */
82
+ if (afs != NULL) {
83
+ if (afs->malloc == NULL || afs->realloc == NULL || afs->free == NULL)
84
+ {
85
+ return NULL;
86
+ }
87
+ } else {
88
+ yajl_set_default_alloc_funcs(&afsBuffer);
89
+ afs = &afsBuffer;
90
+ }
91
+
92
+ g = (yajl_gen) YA_MALLOC(afs, sizeof(struct yajl_gen_t));
93
+ if (!g) return NULL;
94
+
95
+ memset((void *) g, 0, sizeof(struct yajl_gen_t));
96
+ /* copy in pointers to allocation routines */
97
+ memcpy((void *) &(g->alloc), (void *) afs, sizeof(yajl_alloc_funcs));
98
+
99
+ if (config) {
100
+ const char *indent = config->indentString;
101
+ g->pretty = config->beautify;
102
+ g->indentString = config->indentString;
103
+ if (indent) {
104
+ for (; *indent; indent++) {
105
+ if (*indent != '\n'
106
+ && *indent != '\v'
107
+ && *indent != '\f'
108
+ && *indent != '\t'
109
+ && *indent != '\r'
110
+ && *indent != ' ') {
111
+ g->indentString = NULL;
112
+ break;
113
+ }
114
+ }
115
+ }
116
+ if (!g->indentString) {
117
+ g->indentString = " ";
118
+ }
119
+ }
120
+
121
+ if (callback) {
122
+ g->print = callback;
123
+ g->ctx = ctx;
124
+ } else {
125
+ g->print = (yajl_print_t)&yajl_buf_append;
126
+ g->ctx = yajl_buf_alloc(&(g->alloc));
127
+ }
128
+
129
+ return g;
130
+ }
131
+
132
+ void
133
+ yajl_gen_free(yajl_gen g)
134
+ {
135
+ if (g->print == (yajl_print_t)&yajl_buf_append) yajl_buf_free((yajl_buf)g->ctx);
136
+ YA_FREE(&(g->alloc), g);
137
+ }
138
+
139
+ #define INSERT_SEP \
140
+ if (g->state[g->depth] == yajl_gen_map_key || \
141
+ g->state[g->depth] == yajl_gen_in_array) { \
142
+ g->print(g->ctx, ",", 1); \
143
+ if (g->pretty) g->print(g->ctx, "\n", 1); \
144
+ } else if (g->state[g->depth] == yajl_gen_map_val) { \
145
+ g->print(g->ctx, ":", 1); \
146
+ if (g->pretty) g->print(g->ctx, " ", 1); \
147
+ }
148
+
149
+ #define INSERT_WHITESPACE \
150
+ if (g->pretty) { \
151
+ if (g->state[g->depth] != yajl_gen_map_val) { \
152
+ unsigned int _i; \
153
+ for (_i=0;_i<g->depth;_i++) \
154
+ g->print(g->ctx, \
155
+ g->indentString, \
156
+ (unsigned int)strlen(g->indentString)); \
157
+ } \
158
+ }
159
+
160
+ #define ENSURE_NOT_KEY \
161
+ if (g->state[g->depth] == yajl_gen_map_key || \
162
+ g->state[g->depth] == yajl_gen_map_start) { \
163
+ return yajl_gen_keys_must_be_strings; \
164
+ } \
165
+
166
+ /* check that we're not complete, or in error state. in a valid state
167
+ * to be generating */
168
+ #define ENSURE_VALID_STATE \
169
+ if (g->state[g->depth] == yajl_gen_error) { \
170
+ return yajl_gen_in_error_state;\
171
+ } else if (g->state[g->depth] == yajl_gen_complete) { \
172
+ return yajl_gen_generation_complete; \
173
+ }
174
+
175
+ #define INCREMENT_DEPTH \
176
+ if (++(g->depth) >= YAJL_MAX_DEPTH) return yajl_max_depth_exceeded;
177
+
178
+ #define DECREMENT_DEPTH \
179
+ if (--(g->depth) >= YAJL_MAX_DEPTH) return yajl_gen_error;
180
+
181
+ #define APPENDED_ATOM \
182
+ switch (g->state[g->depth]) { \
183
+ case yajl_gen_start: \
184
+ g->state[g->depth] = yajl_gen_complete; \
185
+ break; \
186
+ case yajl_gen_map_start: \
187
+ case yajl_gen_map_key: \
188
+ g->state[g->depth] = yajl_gen_map_val; \
189
+ break; \
190
+ case yajl_gen_array_start: \
191
+ g->state[g->depth] = yajl_gen_in_array; \
192
+ break; \
193
+ case yajl_gen_map_val: \
194
+ g->state[g->depth] = yajl_gen_map_key; \
195
+ break; \
196
+ default: \
197
+ break; \
198
+ } \
199
+
200
+ #define FINAL_NEWLINE \
201
+ if (g->pretty && g->state[g->depth] == yajl_gen_complete) \
202
+ g->print(g->ctx, "\n", 1);
203
+
204
+ yajl_gen_status
205
+ yajl_gen_integer(yajl_gen g, long int number)
206
+ {
207
+ char i[32];
208
+ ENSURE_VALID_STATE; ENSURE_NOT_KEY; INSERT_SEP; INSERT_WHITESPACE;
209
+ sprintf(i, "%ld", number);
210
+ g->print(g->ctx, i, (unsigned int)strlen(i));
211
+ APPENDED_ATOM;
212
+ FINAL_NEWLINE;
213
+ return yajl_gen_status_ok;
214
+ }
215
+
216
+ #ifdef WIN32
217
+ #include <float.h>
218
+ #define isnan _isnan
219
+ #define isinf !_finite
220
+ #endif
221
+
222
+ yajl_gen_status
223
+ yajl_gen_double(yajl_gen g, double number)
224
+ {
225
+ char i[32];
226
+ ENSURE_VALID_STATE; ENSURE_NOT_KEY;
227
+ if (isnan(number) || isinf(number)) return yajl_gen_invalid_number;
228
+ INSERT_SEP; INSERT_WHITESPACE;
229
+ sprintf(i, "%.20g", number);
230
+ g->print(g->ctx, i, (unsigned int)strlen(i));
231
+ APPENDED_ATOM;
232
+ FINAL_NEWLINE;
233
+ return yajl_gen_status_ok;
234
+ }
235
+
236
+ yajl_gen_status
237
+ yajl_gen_number(yajl_gen g, const char * s, unsigned int l)
238
+ {
239
+ ENSURE_VALID_STATE; ENSURE_NOT_KEY; INSERT_SEP; INSERT_WHITESPACE;
240
+ g->print(g->ctx, s, l);
241
+ APPENDED_ATOM;
242
+ FINAL_NEWLINE;
243
+ return yajl_gen_status_ok;
244
+ }
245
+
246
+ yajl_gen_status
247
+ yajl_gen_string(yajl_gen g, const unsigned char * str,
248
+ unsigned int len)
249
+ {
250
+ ENSURE_VALID_STATE; INSERT_SEP; INSERT_WHITESPACE;
251
+ g->print(g->ctx, "\"", 1);
252
+ yajl_string_encode2(g->print, g->ctx, str, len);
253
+ g->print(g->ctx, "\"", 1);
254
+ APPENDED_ATOM;
255
+ FINAL_NEWLINE;
256
+ return yajl_gen_status_ok;
257
+ }
258
+
259
+ yajl_gen_status
260
+ yajl_gen_null(yajl_gen g)
261
+ {
262
+ ENSURE_VALID_STATE; ENSURE_NOT_KEY; INSERT_SEP; INSERT_WHITESPACE;
263
+ g->print(g->ctx, "null", strlen("null"));
264
+ APPENDED_ATOM;
265
+ FINAL_NEWLINE;
266
+ return yajl_gen_status_ok;
267
+ }
268
+
269
+ yajl_gen_status
270
+ yajl_gen_bool(yajl_gen g, int boolean)
271
+ {
272
+ const char * val = boolean ? "true" : "false";
273
+
274
+ ENSURE_VALID_STATE; ENSURE_NOT_KEY; INSERT_SEP; INSERT_WHITESPACE;
275
+ g->print(g->ctx, val, (unsigned int)strlen(val));
276
+ APPENDED_ATOM;
277
+ FINAL_NEWLINE;
278
+ return yajl_gen_status_ok;
279
+ }
280
+
281
+ yajl_gen_status
282
+ yajl_gen_map_open(yajl_gen g)
283
+ {
284
+ ENSURE_VALID_STATE; ENSURE_NOT_KEY; INSERT_SEP; INSERT_WHITESPACE;
285
+ INCREMENT_DEPTH;
286
+
287
+ g->state[g->depth] = yajl_gen_map_start;
288
+ g->print(g->ctx, "{", 1);
289
+ if (g->pretty) g->print(g->ctx, "\n", 1);
290
+ FINAL_NEWLINE;
291
+ return yajl_gen_status_ok;
292
+ }
293
+
294
+ yajl_gen_status
295
+ yajl_gen_map_close(yajl_gen g)
296
+ {
297
+ ENSURE_VALID_STATE;
298
+ DECREMENT_DEPTH;
299
+
300
+ if (g->pretty) g->print(g->ctx, "\n", 1);
301
+ APPENDED_ATOM;
302
+ INSERT_WHITESPACE;
303
+ g->print(g->ctx, "}", 1);
304
+ FINAL_NEWLINE;
305
+ return yajl_gen_status_ok;
306
+ }
307
+
308
+ yajl_gen_status
309
+ yajl_gen_array_open(yajl_gen g)
310
+ {
311
+ ENSURE_VALID_STATE; ENSURE_NOT_KEY; INSERT_SEP; INSERT_WHITESPACE;
312
+ INCREMENT_DEPTH;
313
+ g->state[g->depth] = yajl_gen_array_start;
314
+ g->print(g->ctx, "[", 1);
315
+ if (g->pretty) g->print(g->ctx, "\n", 1);
316
+ FINAL_NEWLINE;
317
+ return yajl_gen_status_ok;
318
+ }
319
+
320
+ yajl_gen_status
321
+ yajl_gen_array_close(yajl_gen g)
322
+ {
323
+ ENSURE_VALID_STATE;
324
+ DECREMENT_DEPTH;
325
+ if (g->pretty) g->print(g->ctx, "\n", 1);
326
+ APPENDED_ATOM;
327
+ INSERT_WHITESPACE;
328
+ g->print(g->ctx, "]", 1);
329
+ FINAL_NEWLINE;
330
+ return yajl_gen_status_ok;
331
+ }
332
+
333
+ yajl_gen_status
334
+ yajl_gen_get_buf(yajl_gen g, const unsigned char ** buf,
335
+ unsigned int * len)
336
+ {
337
+ if (g->print != (yajl_print_t)&yajl_buf_append) return yajl_gen_no_buf;
338
+ *buf = yajl_buf_data((yajl_buf)g->ctx);
339
+ *len = yajl_buf_len((yajl_buf)g->ctx);
340
+ return yajl_gen_status_ok;
341
+ }
342
+
343
+ void
344
+ yajl_gen_clear(yajl_gen g)
345
+ {
346
+ if (g->print == (yajl_print_t)&yajl_buf_append) yajl_buf_clear((yajl_buf)g->ctx);
347
+ }