From 36d802ae1fd61d5ae3bfa1b114b8f3a911d987e5 Mon Sep 17 00:00:00 2001 From: Ben Pfaff Date: Fri, 22 Jan 2010 14:57:18 -0800 Subject: [PATCH] json: New function json_to_ds(). Some upcoming code wants to serialize JSON into a "struct ds" dynamic string buffer, so expose an interface to do this. This commit doesn't change much, but it renames some functions internal to json.c to make the naming more consistent. Also, make jsonrpc_log_msg() use this new function, since it is a more straightforward way to do what it wants. --- lib/json.c | 71 +++++++++++++++++++++++++++++---------------------- lib/json.h | 5 +++- lib/jsonrpc.c | 8 +++--- 3 files changed, 49 insertions(+), 35 deletions(-) diff --git a/lib/json.c b/lib/json.c index a7039ba5..0339a368 100644 --- a/lib/json.c +++ b/lib/json.c @@ -1428,17 +1428,17 @@ json_error(struct json_parser *p, const char *format, ...) #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, @@ -1456,19 +1456,30 @@ static void json_string_to_ds(const char *string, struct ds *); * 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: @@ -1484,11 +1495,11 @@ json_to_ds(const struct json *json, struct json_serializer *s) 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: @@ -1500,7 +1511,7 @@ json_to_ds(const struct json *json, struct json_serializer *s) break; case JSON_STRING: - json_string_to_ds(json->u.string, ds); + json_serialize_string(json->u.string, ds); break; case JSON_N_TYPES: @@ -1513,34 +1524,34 @@ static void 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, '{'); @@ -1554,7 +1565,7 @@ json_object_to_ds(const struct shash *object, struct json_serializer *s) 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 { @@ -1563,7 +1574,7 @@ json_object_to_ds(const struct shash *object, struct json_serializer *s) i = 0; SHASH_FOR_EACH (node, object) { - json_object_member_to_ds(i++, node, s); + json_serialize_object_member(i++, node, s); } } @@ -1572,9 +1583,9 @@ json_object_to_ds(const struct shash *object, struct json_serializer *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, '['); @@ -1588,7 +1599,7 @@ json_array_to_ds(const struct json_array *array, struct json_serializer *s) ds_put_char(ds, ','); indent_line(s); } - json_to_ds(array->elems[i], s); + json_serialize(array->elems[i], s); } } @@ -1597,7 +1608,7 @@ json_array_to_ds(const struct json_array *array, struct json_serializer *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; diff --git a/lib/json.h b/lib/json.h index 6aa9c49f..41257b0d 100644 --- a/lib/json.h +++ b/lib/json.h @@ -1,5 +1,5 @@ /* - * Copyright (c) 2009 Nicira Networks. + * Copyright (c) 2009, 2010 Nicira Networks. * * Licensed under the Apache License, Version 2.0 (the "License"); * you may not use this file except in compliance with the License. @@ -32,6 +32,8 @@ #include "shash.h" +struct ds; + /* Type of a JSON value. */ enum json_type { JSON_NULL, /* null */ @@ -120,6 +122,7 @@ enum { JSSF_SORT = 1 << 1 /* Object members in sorted order, if true. */ }; char *json_to_string(const struct json *, int flags); +void json_to_ds(const struct json *, int flags, struct ds *); /* JSON string formatting operations. */ diff --git a/lib/jsonrpc.c b/lib/jsonrpc.c index 562a2870..5c7dfca9 100644 --- a/lib/jsonrpc.c +++ b/lib/jsonrpc.c @@ -152,19 +152,19 @@ jsonrpc_log_msg(const struct jsonrpc *rpc, const char *title, } 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)); -- 2.30.2