#define SPACES_PER_LEVEL 2
struct json_serializer {
- struct ds ds;
+ struct ds *ds;
int depth;
int flags;
};
-static void json_to_ds(const struct json *, struct json_serializer *);
-static void json_object_to_ds(const struct shash *object,
- struct json_serializer *);
-static void json_array_to_ds(const struct json_array *,
- struct json_serializer *);
-static void json_string_to_ds(const char *string, struct ds *);
+static void json_serialize(const struct json *, struct json_serializer *);
+static void json_serialize_object(const struct shash *object,
+ struct json_serializer *);
+static void json_serialize_array(const struct json_array *,
+ struct json_serializer *);
+static void json_serialize_string(const char *, struct ds *);
/* Converts 'json' to a string in JSON format, encoded in UTF-8, and returns
* that string. The caller is responsible for freeing the returned string,
* object, since a bare literal does not satisfy the JSON grammar. */
char *
json_to_string(const struct json *json, int flags)
+{
+ struct ds ds;
+
+ ds_init(&ds);
+ json_to_ds(json, flags, &ds);
+ return ds_steal_cstr(&ds);
+}
+
+/* Same as json_to_string(), but the output is appended to 'ds'. */
+void
+json_to_ds(const struct json *json, int flags, struct ds *ds)
{
struct json_serializer s;
- ds_init(&s.ds);
+
+ s.ds = ds;
s.depth = 0;
s.flags = flags;
- json_to_ds(json, &s);
- return ds_steal_cstr(&s.ds);
+ json_serialize(json, &s);
}
static void
-json_to_ds(const struct json *json, struct json_serializer *s)
+json_serialize(const struct json *json, struct json_serializer *s)
{
- struct ds *ds = &s->ds;
+ struct ds *ds = s->ds;
switch (json->type) {
case JSON_NULL:
break;
case JSON_OBJECT:
- json_object_to_ds(json->u.object, s);
+ json_serialize_object(json->u.object, s);
break;
case JSON_ARRAY:
- json_array_to_ds(&json->u.array, s);
+ json_serialize_array(&json->u.array, s);
break;
case JSON_INTEGER:
break;
case JSON_STRING:
- json_string_to_ds(json->u.string, ds);
+ json_serialize_string(json->u.string, ds);
break;
case JSON_N_TYPES:
indent_line(struct json_serializer *s)
{
if (s->flags & JSSF_PRETTY) {
- ds_put_char(&s->ds, '\n');
- ds_put_char_multiple(&s->ds, ' ', SPACES_PER_LEVEL * s->depth);
+ ds_put_char(s->ds, '\n');
+ ds_put_char_multiple(s->ds, ' ', SPACES_PER_LEVEL * s->depth);
}
}
static void
-json_object_member_to_ds(size_t i, const struct shash_node *node,
- struct json_serializer *s)
+json_serialize_object_member(size_t i, const struct shash_node *node,
+ struct json_serializer *s)
{
- struct ds *ds = &s->ds;
+ struct ds *ds = s->ds;
if (i) {
ds_put_char(ds, ',');
indent_line(s);
}
- json_string_to_ds(node->name, ds);
+ json_serialize_string(node->name, ds);
ds_put_char(ds, ':');
if (s->flags & JSSF_PRETTY) {
ds_put_char(ds, ' ');
}
- json_to_ds(node->data, s);
+ json_serialize(node->data, s);
}
static void
-json_object_to_ds(const struct shash *object, struct json_serializer *s)
+json_serialize_object(const struct shash *object, struct json_serializer *s)
{
- struct ds *ds = &s->ds;
+ struct ds *ds = s->ds;
ds_put_char(ds, '{');
nodes = shash_sort(object);
n = shash_count(object);
for (i = 0; i < n; i++) {
- json_object_member_to_ds(i, nodes[i], s);
+ json_serialize_object_member(i, nodes[i], s);
}
free(nodes);
} else {
i = 0;
SHASH_FOR_EACH (node, object) {
- json_object_member_to_ds(i++, node, s);
+ json_serialize_object_member(i++, node, s);
}
}
}
static void
-json_array_to_ds(const struct json_array *array, struct json_serializer *s)
+json_serialize_array(const struct json_array *array, struct json_serializer *s)
{
- struct ds *ds = &s->ds;
+ struct ds *ds = s->ds;
size_t i;
ds_put_char(ds, '[');
ds_put_char(ds, ',');
indent_line(s);
}
- json_to_ds(array->elems[i], s);
+ json_serialize(array->elems[i], s);
}
}
}
static void
-json_string_to_ds(const char *string, struct ds *ds)
+json_serialize_string(const char *string, struct ds *ds)
{
uint8_t c;
}
if (msg->params) {
ds_put_cstr(&s, ", params=");
- ds_put_and_free_cstr(&s, json_to_string(msg->params, 0));
+ json_to_ds(msg->params, 0, &s);
}
if (msg->result) {
ds_put_cstr(&s, ", result=");
- ds_put_and_free_cstr(&s, json_to_string(msg->result, 0));
+ json_to_ds(msg->result, 0, &s);
}
if (msg->error) {
ds_put_cstr(&s, ", error=");
- ds_put_and_free_cstr(&s, json_to_string(msg->error, 0));
+ json_to_ds(msg->error, 0, &s);
}
if (msg->id) {
ds_put_cstr(&s, ", id=");
- ds_put_and_free_cstr(&s, json_to_string(msg->id, 0));
+ json_to_ds(msg->id, 0, &s);
}
VLOG_DBG("%s: %s %s%s", rpc->name, title,
jsonrpc_msg_type_to_string(msg->type), ds_cstr(&s));