2 * UCW JSON Library -- Formatter
4 * (c) 2015 Martin Mares <mj@ucw.cz>
6 * This software may be freely distributed and used according to the terms
7 * of the GNU Lesser General Public License.
11 #include <ucw/fastbuf.h>
13 #include <ucw/ff-unicode.h>
14 #include <ucw/unicode.h>
15 #include <ucw-json/json.h>
20 void json_set_output(struct json_context *js, struct fastbuf *fb)
25 static void write_string(struct json_context *js, const char *p)
27 struct fastbuf *fb = js->out_fb;
33 p = utf8_32_get(p, &u);
36 if (u == '"' || u == '\\')
43 // We avoid "\f" nor "\b" and use "\uXXXX" instead
46 case 0x09: bputs(fb, "\\t"); break;
47 case 0x0a: bputs(fb, "\\n"); break;
48 case 0x0d: bputs(fb, "\\r"); break;
50 bprintf(fb, "\\u%04x", u);
53 else if (u >= 0x007f && (js->format_options & JSON_FORMAT_ESCAPE_NONASCII))
56 bprintf(fb, "\\u%04x", u);
57 else if (u < 0x110000)
58 bprintf(fb, "\\u%04x\\u%04x", 0xd800 + ((u - 0x10000) >> 10), 0xdc00 + (u & 0x3ff));
60 bprintf(fb, "\\u%04x", UNI_REPLACEMENT);
68 static void write_number(struct fastbuf *fb, double val)
70 bprintf(fb, "%.*g", DBL_DIG+1, val);
73 static bool want_indent_p(struct json_context *js)
75 return (js->format_options & JSON_FORMAT_INDENT);
78 static void write_space(struct json_context *js)
80 struct fastbuf *fb = js->out_fb;
82 if (want_indent_p(js))
85 for (uint i=0; i < js->out_indent; i++)
92 void json_write_value(struct json_context *js, struct json_node *n)
94 struct fastbuf *fb = js->out_fb;
102 bputs(fb, (n->boolean ? "true" : "false"));
105 write_number(fb, n->number);
108 write_string(js, n->string);
112 if (!GARY_SIZE(n->elements))
118 for (size_t i=0; i < GARY_SIZE(n->elements); i++)
123 json_write_value(js, n->elements[i]);
133 if (!GARY_SIZE(n->pairs))
139 for (size_t i=0; i < GARY_SIZE(n->pairs); i++)
144 struct json_pair *p = &n->pairs[i];
145 write_string(js, p->key);
147 json_write_value(js, p->value);
160 void json_write(struct json_context *js, struct fastbuf *fb, struct json_node *n)
162 json_set_output(js, fb);
163 json_write_value(js, n);