On Tue, Aug 24, 2021 at 12:00 PM Ilya Maximets <[email protected]> wrote: > > Introducing a new json type JSON_SERIALIZED_OBJECT. It's not an > actual type that can be seen in a json message on a wire, but > internal type that is intended to hold a serialized version of > some other json object. For this reason it's defined after the > JSON_N_TYPES to not confuse parsers and other parts of the code > that relies on compliance with RFC 4627. > > With this JSON type internal users may construct large JSON objects, > parts of which are already serialized. This way, while serializing > the larger object, data from JSON_SERIALIZED_OBJECT can be added > directly to the result, without additional processing. > > This will be used by next commits to add pre-serialized JSON data > to the raft_header structure, that can be converted to a JSON > before writing the file transaction on disk or sending to other > servers. Same technique can also be used to pre-serialize json_cache > for ovsdb monitors, this should allow to not perform serialization > for every client and will save some more memory. > > Since serialized JSON is just a string, reusing the 'json->string' > pointer for it. > > Signed-off-by: Ilya Maximets <[email protected]> > --- > include/openvswitch/json.h | 9 +++++++-- > lib/json.c | 34 ++++++++++++++++++++++++++++++++++ > 2 files changed, 41 insertions(+), 2 deletions(-) > > diff --git a/include/openvswitch/json.h b/include/openvswitch/json.h > index 73b562e03..b8cf49ab6 100644 > --- a/include/openvswitch/json.h > +++ b/include/openvswitch/json.h > @@ -50,7 +50,9 @@ enum json_type { > JSON_INTEGER, /* 123. */ > JSON_REAL, /* 123.456. */ > JSON_STRING, /* "..." */ > - JSON_N_TYPES > + JSON_N_TYPES, > + JSON_SERIALIZED_OBJECT, /* Internal type to hold serialized version of > + * data of other types. */ > }; > > const char *json_type_to_string(enum json_type); > @@ -70,7 +72,7 @@ struct json { > struct json_array array; > long long int integer; > double real; > - char *string; > + char *string; /* JSON_STRING or JSON_SERIALIZED_OBJECT. */ > }; > }; > > @@ -78,6 +80,7 @@ struct json *json_null_create(void); > struct json *json_boolean_create(bool); > struct json *json_string_create(const char *); > struct json *json_string_create_nocopy(char *); > +struct json *json_serialized_object_create(const struct json *); > struct json *json_integer_create(long long int); > struct json *json_real_create(double); > > @@ -99,6 +102,7 @@ void json_object_put_format(struct json *, > OVS_PRINTF_FORMAT(3, 4); > > const char *json_string(const struct json *); > +const char *json_serialized_object(const struct json *); > struct json_array *json_array(const struct json *); > struct shash *json_object(const struct json *); > bool json_boolean(const struct json *); > @@ -125,6 +129,7 @@ struct json *json_parser_finish(struct json_parser *); > void json_parser_abort(struct json_parser *); > > struct json *json_from_string(const char *string); > +struct json *json_from_serialized_object(const struct json *); > struct json *json_from_file(const char *file_name); > struct json *json_from_stream(FILE *stream); > > diff --git a/lib/json.c b/lib/json.c > index 32d25003b..6bb620724 100644 > --- a/lib/json.c > +++ b/lib/json.c > @@ -146,6 +146,7 @@ json_type_to_string(enum json_type type) > case JSON_STRING: > return "string"; > > + case JSON_SERIALIZED_OBJECT: > case JSON_N_TYPES: > default: > return "<invalid>"; > @@ -180,6 +181,14 @@ json_string_create(const char *s) > return json_string_create_nocopy(xstrdup(s)); > } > > +struct json * > +json_serialized_object_create(const struct json *src) > +{ > + struct json *json = json_create(JSON_SERIALIZED_OBJECT); > + json->string = json_to_string(src, JSSF_SORT); > + return json; > +} > + > struct json * > json_array_create_empty(void) > { > @@ -309,6 +318,13 @@ json_string(const struct json *json) > return json->string; > } > > +const char * > +json_serialized_object(const struct json *json) > +{ > + ovs_assert(json->type == JSON_SERIALIZED_OBJECT); > + return json->string; > +} > + > struct json_array * > json_array(const struct json *json) > { > @@ -362,6 +378,7 @@ json_destroy(struct json *json) > break; > > case JSON_STRING: > + case JSON_SERIALIZED_OBJECT: > free(json->string); > break; > > @@ -422,6 +439,9 @@ json_deep_clone(const struct json *json) > case JSON_STRING: > return json_string_create(json->string); > > + case JSON_SERIALIZED_OBJECT: > + return json_serialized_object_create(json); > + > case JSON_NULL: > case JSON_FALSE: > case JSON_TRUE: > @@ -521,6 +541,7 @@ json_hash(const struct json *json, size_t basis) > return json_hash_array(&json->array, basis); > > case JSON_STRING: > + case JSON_SERIALIZED_OBJECT: > return hash_string(json->string, basis); > > case JSON_NULL: > @@ -596,6 +617,7 @@ json_equal(const struct json *a, const struct json *b) > return json_equal_array(&a->array, &b->array); > > case JSON_STRING: > + case JSON_SERIALIZED_OBJECT: > return !strcmp(a->string, b->string); > > case JSON_NULL: > @@ -1072,6 +1094,14 @@ json_from_string(const char *string) > return json_parser_finish(p); > } > > +/* Parses data of JSON_SERIALIZED_OBJECT to the real JSON. */ > +struct json * > +json_from_serialized_object(const struct json *json) > +{ > + ovs_assert(json->type == JSON_SERIALIZED_OBJECT); > + return json_from_string(json->string); > +} > + > /* Reads the file named 'file_name', parses its contents as a JSON object or > * array, and returns a newly allocated 'struct json'. The caller must free > * the returned structure with json_destroy() when it is no longer needed. > @@ -1563,6 +1593,10 @@ json_serialize(const struct json *json, struct json_serializer *s) > json_serialize_string(json->string, ds); > break; > > + case JSON_SERIALIZED_OBJECT: > + ds_put_cstr(ds, json->string); > + break; > + > case JSON_N_TYPES: > default: > OVS_NOT_REACHED(); > -- > 2.31.1 >
Thanks Ilya. Shall we add some test cases for the JSON_SERIALIZD_OBJECT in tests/json.at? Acked-by: Han Zhou <[email protected]> _______________________________________________ dev mailing list [email protected] https://mail.openvswitch.org/mailman/listinfo/ovs-dev
