ovsdb-data: New functions for predicting serialized length of data.
authorBen Pfaff <blp@nicira.com>
Wed, 27 Mar 2013 16:32:56 +0000 (09:32 -0700)
committerBen Pfaff <blp@nicira.com>
Wed, 3 Apr 2013 02:21:27 +0000 (19:21 -0700)
These will be used for the first time in an upcoming commit.

Signed-off-by: Ben Pfaff <blp@nicira.com>
lib/ovsdb-data.c
lib/ovsdb-data.h
tests/test-ovsdb.c

index 0afd03a..7ec7694 100644 (file)
@@ -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)
 {
index 2e31cc5..ece1672 100644 (file)
@@ -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 *,
index 81b5f9f..658259e 100644 (file)
@@ -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);
     }