summaryrefslogtreecommitdiff
diff options
context:
space:
mode:
-rw-r--r--xs_json.h108
-rw-r--r--xs_version.h2
2 files changed, 53 insertions, 57 deletions
diff --git a/xs_json.h b/xs_json.h
index 2a7766e..1b6e61c 100644
--- a/xs_json.h
+++ b/xs_json.h
@@ -4,9 +4,10 @@
4 4
5#define _XS_JSON_H 5#define _XS_JSON_H
6 6
7xs_str *xs_json_dumps_pp(const xs_val *data, int indent);
8int xs_json_dump_pp(const xs_val *data, int indent, FILE *f); 7int xs_json_dump_pp(const xs_val *data, int indent, FILE *f);
8xs_str *xs_json_dumps_pp(const xs_val *data, int indent);
9#define xs_json_dumps(data) xs_json_dumps_pp(data, 0) 9#define xs_json_dumps(data) xs_json_dumps_pp(data, 0)
10#define xs_json_dump(data, f) xs_json_dumps_pp(data, 0, f)
10xs_val *xs_json_loads(const xs_str *json); 11xs_val *xs_json_loads(const xs_str *json);
11xs_val *xs_json_load(FILE *f); 12xs_val *xs_json_load(FILE *f);
12 13
@@ -17,63 +18,55 @@ xs_val *xs_json_load(FILE *f);
17 18
18/** JSON dumps **/ 19/** JSON dumps **/
19 20
20static xs_str *_xs_json_dumps_str(xs_str *s, const char *data) 21static void _xs_json_dump_str(const char *data, FILE *f)
21/* dumps a string in JSON format */ 22/* dumps a string in JSON format */
22{ 23{
23 unsigned char c; 24 unsigned char c;
24 s = xs_str_cat(s, "\""); 25 fputs("\"", f);
25 26
26 while ((c = *data)) { 27 while ((c = *data)) {
27 if (c == '\n') 28 if (c == '\n')
28 s = xs_str_cat(s, "\\n"); 29 fputs("\\n", f);
29 else 30 else
30 if (c == '\r') 31 if (c == '\r')
31 s = xs_str_cat(s, "\\r"); 32 fputs("\\r", f);
32 else 33 else
33 if (c == '\t') 34 if (c == '\t')
34 s = xs_str_cat(s, "\\t"); 35 fputs("\\t", f);
35 else 36 else
36 if (c == '\\') 37 if (c == '\\')
37 s = xs_str_cat(s, "\\\\"); 38 fputs("\\\\", f);
38 else 39 else
39 if (c == '"') 40 if (c == '"')
40 s = xs_str_cat(s, "\\\""); 41 fputs("\\\"", f);
41 else 42 else
42 if (c < 32) { 43 if (c < 32)
43 char tmp[10]; 44 fprintf(f, "\\u%04x", (unsigned int) c);
44
45 snprintf(tmp, sizeof(tmp), "\\u%04x", (unsigned int) c);
46 s = xs_str_cat(s, tmp);
47 }
48 else 45 else
49 s = xs_append_m(s, data, 1); 46 fputc(c, f);
50 47
51 data++; 48 data++;
52 } 49 }
53 50
54 s = xs_str_cat(s, "\""); 51 fputs("\"", f);
55
56 return s;
57} 52}
58 53
59 54
60static xs_str *_xs_json_indent(xs_str *s, int level, int indent) 55static void _xs_json_indent(int level, int indent, FILE *f)
61/* adds indentation */ 56/* adds indentation */
62{ 57{
63 if (indent) { 58 if (indent) {
64 int n; 59 int n;
65 60
66 s = xs_str_cat(s, "\n"); 61 fputc('\n', f);
67 62
68 for (n = 0; n < level * indent; n++) 63 for (n = 0; n < level * indent; n++)
69 s = xs_str_cat(s, " "); 64 fputc(' ', f);
70 } 65 }
71
72 return s;
73} 66}
74 67
75 68
76static xs_str *_xs_json_dumps(xs_str *s, const xs_val *s_data, int level, int indent) 69static void _xs_json_dump(const xs_val *s_data, int level, int indent, FILE *f)
77/* dumps partial data as JSON */ 70/* dumps partial data as JSON */
78{ 71{
79 int c = 0; 72 int c = 0;
@@ -82,85 +75,87 @@ static xs_str *_xs_json_dumps(xs_str *s, const xs_val *s_data, int level, int in
82 75
83 switch (xs_type(data)) { 76 switch (xs_type(data)) {
84 case XSTYPE_NULL: 77 case XSTYPE_NULL:
85 s = xs_str_cat(s, "null"); 78 fputs("null", f);
86 break; 79 break;
87 80
88 case XSTYPE_TRUE: 81 case XSTYPE_TRUE:
89 s = xs_str_cat(s, "true"); 82 fputs("true", f);
90 break; 83 break;
91 84
92 case XSTYPE_FALSE: 85 case XSTYPE_FALSE:
93 s = xs_str_cat(s, "false"); 86 fputs("false", f);
94 break; 87 break;
95 88
96 case XSTYPE_NUMBER: 89 case XSTYPE_NUMBER:
97 s = xs_str_cat(s, xs_number_str(data)); 90 fputs(xs_number_str(data), f);
98 break; 91 break;
99 92
100 case XSTYPE_LIST: 93 case XSTYPE_LIST:
101 s = xs_str_cat(s, "["); 94 fputc('[', f);
102 95
103 while (xs_list_iter(&data, &v)) { 96 while (xs_list_iter(&data, &v)) {
104 if (c != 0) 97 if (c != 0)
105 s = xs_str_cat(s, ","); 98 fputc(',', f);
106 99
107 s = _xs_json_indent(s, level + 1, indent); 100 _xs_json_indent(level + 1, indent, f);
108 s = _xs_json_dumps(s, v, level + 1, indent); 101 _xs_json_dump(v, level + 1, indent, f);
109 102
110 c++; 103 c++;
111 } 104 }
112 105
113 s = _xs_json_indent(s, level, indent); 106 _xs_json_indent(level, indent, f);
114 s = xs_str_cat(s, "]"); 107 fputc(']', f);
115 108
116 break; 109 break;
117 110
118 case XSTYPE_DICT: 111 case XSTYPE_DICT:
119 s = xs_str_cat(s, "{"); 112 fputc('{', f);
120 113
121 xs_str *k; 114 xs_str *k;
122 while (xs_dict_iter(&data, &k, &v)) { 115 while (xs_dict_iter(&data, &k, &v)) {
123 if (c != 0) 116 if (c != 0)
124 s = xs_str_cat(s, ","); 117 fputc(',', f);
125 118
126 s = _xs_json_indent(s, level + 1, indent); 119 _xs_json_indent(level + 1, indent, f);
127 120
128 s = _xs_json_dumps_str(s, k); 121 _xs_json_dump_str(k, f);
129 s = xs_str_cat(s, ":"); 122 fputc(':', f);
130 123
131 if (indent) 124 if (indent)
132 s = xs_str_cat(s, " "); 125 fputc(' ', f);
133 126
134 s = _xs_json_dumps(s, v, level + 1, indent); 127 _xs_json_dump(v, level + 1, indent, f);
135 128
136 c++; 129 c++;
137 } 130 }
138 131
139 s = _xs_json_indent(s, level, indent); 132 _xs_json_indent(level, indent, f);
140 s = xs_str_cat(s, "}"); 133 fputc('}', f);
141 break; 134 break;
142 135
143 case XSTYPE_STRING: 136 case XSTYPE_STRING:
144 s = _xs_json_dumps_str(s, data); 137 _xs_json_dump_str(data, f);
145 break; 138 break;
146 139
147 default: 140 default:
148 break; 141 break;
149 } 142 }
150
151 return s;
152} 143}
153 144
154 145
155xs_str *xs_json_dumps_pp(const xs_val *data, int indent) 146xs_str *xs_json_dumps_pp(const xs_val *data, int indent)
156/* dumps a piece of data as JSON */ 147/* dumps data as a JSON string */
157{ 148{
158 xstype t = xs_type(data);
159 xs_str *s = NULL; 149 xs_str *s = NULL;
150 size_t sz;
151 FILE *f;
160 152
161 if (t == XSTYPE_LIST || t == XSTYPE_DICT) { 153 if ((f = open_memstream(&s, &sz)) != NULL) {
162 s = xs_str_new(NULL); 154 int r = xs_json_dump_pp(data, indent, f);
163 s = _xs_json_dumps(s, data, 0, indent); 155 fclose(f);
156
157 if (!r)
158 s = xs_free(s);
164 } 159 }
165 160
166 return s; 161 return s;
@@ -170,13 +165,14 @@ xs_str *xs_json_dumps_pp(const xs_val *data, int indent)
170int xs_json_dump_pp(const xs_val *data, int indent, FILE *f) 165int xs_json_dump_pp(const xs_val *data, int indent, FILE *f)
171/* dumps data into a file as JSON */ 166/* dumps data into a file as JSON */
172{ 167{
173 xs *j = xs_json_dumps_pp(data, indent); 168 xstype t = xs_type(data);
174 169
175 if (j == NULL) 170 if (t == XSTYPE_LIST || t == XSTYPE_DICT) {
176 return 0; 171 _xs_json_dump(data, 0, indent, f);
172 return 1;
173 }
177 174
178 fwrite(j, strlen(j), 1, f); 175 return 0;
179 return 1;
180} 176}
181 177
182 178
diff --git a/xs_version.h b/xs_version.h
index 6f137ea..7086cd4 100644
--- a/xs_version.h
+++ b/xs_version.h
@@ -1 +1 @@
/* 5ad148b1c1dbbf7b4550c9fcd13d96ac6def2d21 */ /* 7ee8d1e20f4adc0a1cddd64b290efee94e055f32 */