commit 6949d7d
default
·
2023-08-05 19:57:45 +0000 UTC
parent 15f7559
Backport from xs.
2 files changed,
+53,
-57
+52,
-56
1@@ -4,9 +4,10 @@
2
3 #define _XS_JSON_H
4
5-xs_str *xs_json_dumps_pp(const xs_val *data, int indent);
6 int xs_json_dump_pp(const xs_val *data, int indent, FILE *f);
7+xs_str *xs_json_dumps_pp(const xs_val *data, int indent);
8 #define xs_json_dumps(data) xs_json_dumps_pp(data, 0)
9+#define xs_json_dump(data, f) xs_json_dumps_pp(data, 0, f)
10 xs_val *xs_json_loads(const xs_str *json);
11 xs_val *xs_json_load(FILE *f);
12
13@@ -17,63 +18,55 @@ xs_val *xs_json_load(FILE *f);
14
15 /** JSON dumps **/
16
17-static xs_str *_xs_json_dumps_str(xs_str *s, const char *data)
18+static void _xs_json_dump_str(const char *data, FILE *f)
19 /* dumps a string in JSON format */
20 {
21 unsigned char c;
22- s = xs_str_cat(s, "\"");
23+ fputs("\"", f);
24
25 while ((c = *data)) {
26 if (c == '\n')
27- s = xs_str_cat(s, "\\n");
28+ fputs("\\n", f);
29 else
30 if (c == '\r')
31- s = xs_str_cat(s, "\\r");
32+ fputs("\\r", f);
33 else
34 if (c == '\t')
35- s = xs_str_cat(s, "\\t");
36+ fputs("\\t", f);
37 else
38 if (c == '\\')
39- s = xs_str_cat(s, "\\\\");
40+ fputs("\\\\", f);
41 else
42 if (c == '"')
43- s = xs_str_cat(s, "\\\"");
44+ fputs("\\\"", f);
45 else
46- if (c < 32) {
47- char tmp[10];
48-
49- snprintf(tmp, sizeof(tmp), "\\u%04x", (unsigned int) c);
50- s = xs_str_cat(s, tmp);
51- }
52+ if (c < 32)
53+ fprintf(f, "\\u%04x", (unsigned int) c);
54 else
55- s = xs_append_m(s, data, 1);
56+ fputc(c, f);
57
58 data++;
59 }
60
61- s = xs_str_cat(s, "\"");
62-
63- return s;
64+ fputs("\"", f);
65 }
66
67
68-static xs_str *_xs_json_indent(xs_str *s, int level, int indent)
69+static void _xs_json_indent(int level, int indent, FILE *f)
70 /* adds indentation */
71 {
72 if (indent) {
73 int n;
74
75- s = xs_str_cat(s, "\n");
76+ fputc('\n', f);
77
78 for (n = 0; n < level * indent; n++)
79- s = xs_str_cat(s, " ");
80+ fputc(' ', f);
81 }
82-
83- return s;
84 }
85
86
87-static xs_str *_xs_json_dumps(xs_str *s, const xs_val *s_data, int level, int indent)
88+static void _xs_json_dump(const xs_val *s_data, int level, int indent, FILE *f)
89 /* dumps partial data as JSON */
90 {
91 int c = 0;
92@@ -82,85 +75,87 @@ static xs_str *_xs_json_dumps(xs_str *s, const xs_val *s_data, int level, int in
93
94 switch (xs_type(data)) {
95 case XSTYPE_NULL:
96- s = xs_str_cat(s, "null");
97+ fputs("null", f);
98 break;
99
100 case XSTYPE_TRUE:
101- s = xs_str_cat(s, "true");
102+ fputs("true", f);
103 break;
104
105 case XSTYPE_FALSE:
106- s = xs_str_cat(s, "false");
107+ fputs("false", f);
108 break;
109
110 case XSTYPE_NUMBER:
111- s = xs_str_cat(s, xs_number_str(data));
112+ fputs(xs_number_str(data), f);
113 break;
114
115 case XSTYPE_LIST:
116- s = xs_str_cat(s, "[");
117+ fputc('[', f);
118
119 while (xs_list_iter(&data, &v)) {
120 if (c != 0)
121- s = xs_str_cat(s, ",");
122+ fputc(',', f);
123
124- s = _xs_json_indent(s, level + 1, indent);
125- s = _xs_json_dumps(s, v, level + 1, indent);
126+ _xs_json_indent(level + 1, indent, f);
127+ _xs_json_dump(v, level + 1, indent, f);
128
129 c++;
130 }
131
132- s = _xs_json_indent(s, level, indent);
133- s = xs_str_cat(s, "]");
134+ _xs_json_indent(level, indent, f);
135+ fputc(']', f);
136
137 break;
138
139 case XSTYPE_DICT:
140- s = xs_str_cat(s, "{");
141+ fputc('{', f);
142
143 xs_str *k;
144 while (xs_dict_iter(&data, &k, &v)) {
145 if (c != 0)
146- s = xs_str_cat(s, ",");
147+ fputc(',', f);
148
149- s = _xs_json_indent(s, level + 1, indent);
150+ _xs_json_indent(level + 1, indent, f);
151
152- s = _xs_json_dumps_str(s, k);
153- s = xs_str_cat(s, ":");
154+ _xs_json_dump_str(k, f);
155+ fputc(':', f);
156
157 if (indent)
158- s = xs_str_cat(s, " ");
159+ fputc(' ', f);
160
161- s = _xs_json_dumps(s, v, level + 1, indent);
162+ _xs_json_dump(v, level + 1, indent, f);
163
164 c++;
165 }
166
167- s = _xs_json_indent(s, level, indent);
168- s = xs_str_cat(s, "}");
169+ _xs_json_indent(level, indent, f);
170+ fputc('}', f);
171 break;
172
173 case XSTYPE_STRING:
174- s = _xs_json_dumps_str(s, data);
175+ _xs_json_dump_str(data, f);
176 break;
177
178 default:
179 break;
180 }
181-
182- return s;
183 }
184
185
186 xs_str *xs_json_dumps_pp(const xs_val *data, int indent)
187-/* dumps a piece of data as JSON */
188+/* dumps data as a JSON string */
189 {
190- xstype t = xs_type(data);
191 xs_str *s = NULL;
192+ size_t sz;
193+ FILE *f;
194
195- if (t == XSTYPE_LIST || t == XSTYPE_DICT) {
196- s = xs_str_new(NULL);
197- s = _xs_json_dumps(s, data, 0, indent);
198+ if ((f = open_memstream(&s, &sz)) != NULL) {
199+ int r = xs_json_dump_pp(data, indent, f);
200+ fclose(f);
201+
202+ if (!r)
203+ s = xs_free(s);
204 }
205
206 return s;
207@@ -170,13 +165,14 @@ xs_str *xs_json_dumps_pp(const xs_val *data, int indent)
208 int xs_json_dump_pp(const xs_val *data, int indent, FILE *f)
209 /* dumps data into a file as JSON */
210 {
211- xs *j = xs_json_dumps_pp(data, indent);
212+ xstype t = xs_type(data);
213
214- if (j == NULL)
215- return 0;
216+ if (t == XSTYPE_LIST || t == XSTYPE_DICT) {
217+ _xs_json_dump(data, 0, indent, f);
218+ return 1;
219+ }
220
221- fwrite(j, strlen(j), 1, f);
222- return 1;
223+ return 0;
224 }
225
226
+1,
-1
1@@ -1 +1 @@
2-/* 5ad148b1c1dbbf7b4550c9fcd13d96ac6def2d21 */
3+/* 7ee8d1e20f4adc0a1cddd64b290efee94e055f32 */