From: Ben Pfaff Date: Wed, 27 Mar 2013 16:32:56 +0000 (-0700) Subject: ovsdb-data: New functions for predicting serialized length of data. X-Git-Tag: sliver-openvswitch-1.10.90-1~10^2~10 X-Git-Url: http://git.onelab.eu/?p=sliver-openvswitch.git;a=commitdiff_plain;h=0ea7bec76d804a2c4efccd3dbdaa3e30cf536a5c ovsdb-data: New functions for predicting serialized length of data. These will be used for the first time in an upcoming commit. Signed-off-by: Ben Pfaff --- diff --git a/lib/ovsdb-data.c b/lib/ovsdb-data.c index 0afd03a29..7ec769479 100644 --- a/lib/ovsdb-data.c +++ b/lib/ovsdb-data.c @@ -1,4 +1,4 @@ -/* Copyright (c) 2009, 2010, 2011, 2012 Nicira, Inc. +/* Copyright (c) 2009, 2010, 2011, 2012, 2013 Nicira, Inc. * * Licensed under the Apache License, Version 2.0 (the "License"); * you may not use this file except in compliance with the License. @@ -466,6 +466,47 @@ ovsdb_atom_to_json(const union ovsdb_atom *atom, enum ovsdb_atomic_type type) } } +/* Returns strlen(json_to_string(ovsdb_atom_to_json(atom, type), 0)). */ +size_t +ovsdb_atom_json_length(const union ovsdb_atom *atom, + enum ovsdb_atomic_type type) +{ + struct json json; + + switch (type) { + case OVSDB_TYPE_VOID: + NOT_REACHED(); + + case OVSDB_TYPE_INTEGER: + json.type = JSON_INTEGER; + json.u.integer = atom->integer; + break; + + case OVSDB_TYPE_REAL: + json.type = JSON_REAL; + json.u.real = atom->real; + break; + + case OVSDB_TYPE_BOOLEAN: + json.type = atom->boolean ? JSON_TRUE : JSON_FALSE; + break; + + case OVSDB_TYPE_STRING: + json.type = JSON_STRING; + json.u.string = atom->string; + break; + + case OVSDB_TYPE_UUID: + return strlen("[\"uuid\",\"00000000-0000-0000-0000-000000000000\"]"); + + case OVSDB_N_TYPES: + default: + NOT_REACHED(); + } + + return json_serialized_length(&json); +} + static char * ovsdb_atom_from_string__(union ovsdb_atom *atom, const struct ovsdb_base_type *base, const char *s, @@ -1307,6 +1348,56 @@ ovsdb_datum_to_json(const struct ovsdb_datum *datum, } } +/* Returns strlen(json_to_string(ovsdb_datum_to_json(datum, type), 0)). */ +size_t +ovsdb_datum_json_length(const struct ovsdb_datum *datum, + const struct ovsdb_type *type) +{ + if (ovsdb_type_is_map(type)) { + size_t length; + + /* ["map",[...]]. */ + length = 10; + if (datum->n > 0) { + size_t i; + + /* Commas between pairs in the inner [...] */ + length += datum->n - 1; + + /* [,] in each pair. */ + length += datum->n * 3; + + /* Data. */ + for (i = 0; i < datum->n; i++) { + length += ovsdb_atom_json_length(&datum->keys[i], + type->key.type); + length += ovsdb_atom_json_length(&datum->values[i], + type->value.type); + } + } + return length; + } else if (datum->n == 1) { + return ovsdb_atom_json_length(&datum->keys[0], type->key.type); + } else { + size_t length; + size_t i; + + /* ["set",[...]]. */ + length = 10; + if (datum->n > 0) { + /* Commas between elements in the inner [...]. */ + length += datum->n - 1; + + /* Data. */ + for (i = 0; i < datum->n; i++) { + length += ovsdb_atom_json_length(&datum->keys[i], + type->key.type); + } + } + return length; + } +} + static const char * skip_spaces(const char *p) { diff --git a/lib/ovsdb-data.h b/lib/ovsdb-data.h index 2e31cc5b9..ece167226 100644 --- a/lib/ovsdb-data.h +++ b/lib/ovsdb-data.h @@ -1,4 +1,4 @@ -/* Copyright (c) 2009, 2010, 2011, 2012 Nicira, Inc. +/* Copyright (c) 2009, 2010, 2011, 2012, 2013 Nicira, Inc. * * Licensed under the Apache License, Version 2.0 (the "License"); * you may not use this file except in compliance with the License. @@ -88,6 +88,8 @@ struct ovsdb_error *ovsdb_atom_from_json(union ovsdb_atom *, WARN_UNUSED_RESULT; struct json *ovsdb_atom_to_json(const union ovsdb_atom *, enum ovsdb_atomic_type); +size_t ovsdb_atom_json_length(const union ovsdb_atom *, + enum ovsdb_atomic_type); char *ovsdb_atom_from_string(union ovsdb_atom *, const struct ovsdb_base_type *, const char *, @@ -163,6 +165,8 @@ struct ovsdb_error *ovsdb_datum_from_json(struct ovsdb_datum *, WARN_UNUSED_RESULT; struct json *ovsdb_datum_to_json(const struct ovsdb_datum *, const struct ovsdb_type *); +size_t ovsdb_datum_json_length(const struct ovsdb_datum *, + const struct ovsdb_type *); char *ovsdb_datum_from_string(struct ovsdb_datum *, const struct ovsdb_type *, const char *, diff --git a/tests/test-ovsdb.c b/tests/test-ovsdb.c index 81b5f9fb1..658259e8f 100644 --- a/tests/test-ovsdb.c +++ b/tests/test-ovsdb.c @@ -218,13 +218,16 @@ unbox_json(struct json *json) } } -static void +static size_t print_and_free_json(struct json *json) { char *string = json_to_string(json, JSSF_SORT); + size_t length = strlen(string); json_destroy(json); puts(string); free(string); + + return length; } static void @@ -442,7 +445,10 @@ do_parse_atoms(int argc, char *argv[]) if (error) { print_and_free_ovsdb_error(error); } else { - print_and_free_json(ovsdb_atom_to_json(&atom, base.type)); + size_t length; + + length = print_and_free_json(ovsdb_atom_to_json(&atom, base.type)); + ovs_assert(length == ovsdb_atom_json_length(&atom, base.type)); ovsdb_atom_destroy(&atom, base.type); } } @@ -494,12 +500,14 @@ do_parse_data__(int argc, char *argv[], for (i = 2; i < argc; i++) { struct ovsdb_datum datum; + size_t length; json = unbox_json(parse_json(argv[i])); check_ovsdb_error(parse(&datum, &type, json, NULL)); json_destroy(json); - print_and_free_json(ovsdb_datum_to_json(&datum, &type)); + length = print_and_free_json(ovsdb_datum_to_json(&datum, &type)); + ovs_assert(length == ovsdb_datum_json_length(&datum, &type)); ovsdb_datum_destroy(&datum, &type); }