From 182a4490a52514165fbcb4973c8e760667655f8f Mon Sep 17 00:00:00 2001 From: Ilya Maximets Date: Tue, 17 Dec 2024 01:10:01 +0100 Subject: [PATCH] json: Use functions to access json arrays. Internal implementation of JSON array will be changed in the future commits. Add access functions that users can rely on instead of accessing the internals of 'struct json' directly and convert all the users. Structure fields are intentionally renamed to make sure that no code is using the old fields directly. json_array() function is removed, as not needed anymore. Added new functions: json_array_size(), json_array_at(), json_array_set() and json_array_pop(). These are enough to cover all the use cases within OVS. The change is fairly large, however, IMO, it's a much overdue cleanup that we need even without changing the underlying implementation. Signed-off-by: Ilya Maximets --- include/openvswitch/json.h | 9 +- lib/json.c | 179 ++++++++++++++++++++++--------------- lib/ovsdb-cs.c | 49 +++++----- lib/ovsdb-data.c | 26 +++--- lib/ovsdb-idl.c | 57 ++++++------ lib/unixctl.c | 18 ++-- ovsdb/column.c | 11 ++- ovsdb/condition.c | 24 +++-- ovsdb/execution.c | 20 +++-- ovsdb/jsonrpc-server.c | 104 ++++++++++----------- ovsdb/mutation.c | 33 ++++--- ovsdb/ovsdb-client.c | 127 +++++++++++++------------- ovsdb/ovsdb-server.c | 10 ++- ovsdb/ovsdb-tool.c | 30 +++---- ovsdb/raft-private.c | 11 +-- ovsdb/raft-private.h | 3 +- ovsdb/raft-rpc.c | 16 ++-- ovsdb/replication.c | 23 ++--- ovsdb/storage.c | 17 ++-- ovsdb/table.c | 8 +- ovsdb/trigger.c | 4 +- python/ovs/_json.c | 8 +- tests/test-json.c | 12 +-- tests/test-ovsdb.c | 95 ++++++++++---------- 24 files changed, 483 insertions(+), 411 deletions(-) diff --git a/include/openvswitch/json.h b/include/openvswitch/json.h index bd8e8d23546..519289148e1 100644 --- a/include/openvswitch/json.h +++ b/include/openvswitch/json.h @@ -59,8 +59,8 @@ const char *json_type_to_string(enum json_type); /* A JSON array. */ struct json_array { - size_t n, n_allocated; - struct json **elems; + size_t size, allocated; + struct json **elements; }; /* Maximum string length that can be stored inline ('\0' is not included). */ @@ -98,6 +98,8 @@ struct json *json_real_create(double); struct json *json_array_create_empty(void); void json_array_add(struct json *, struct json *element); +void json_array_set(struct json *, size_t index, struct json *element); +struct json *json_array_pop(struct json *); void json_array_trim(struct json *); struct json *json_array_create(struct json **, size_t n); struct json *json_array_create_1(struct json *); @@ -116,7 +118,8 @@ void json_object_put_format(struct json *, const char *json_string(const struct json *); const char *json_serialized_object(const struct json *); -struct json_array *json_array(const struct json *); +size_t json_array_size(const struct json *); +const struct json *json_array_at(const struct json *, size_t index); struct shash *json_object(const struct json *); bool json_boolean(const struct json *); double json_real(const struct json *); diff --git a/lib/json.c b/lib/json.c index dc6f6f87f07..31a33d2a338 100644 --- a/lib/json.c +++ b/lib/json.c @@ -221,30 +221,44 @@ struct json * json_array_create_empty(void) { struct json *json = json_create(JSON_ARRAY); - json->array.elems = NULL; - json->array.n = 0; - json->array.n_allocated = 0; + json->array.elements = NULL; + json->array.size = 0; + json->array.allocated = 0; return json; } void json_array_add(struct json *array_, struct json *element) { - struct json_array *array = json_array(array_); - if (array->n >= array->n_allocated) { - array->elems = x2nrealloc(array->elems, &array->n_allocated, - sizeof *array->elems); + struct json_array *array = &array_->array; + if (array->size >= array->allocated) { + array->elements = x2nrealloc(array->elements, &array->allocated, + sizeof *array->elements); } - array->elems[array->n++] = element; + array->elements[array->size++] = element; +} + +void +json_array_set(struct json *json, size_t index, struct json *element) +{ + ovs_assert(json_array_size(json) > index); + json->array.elements[index] = element; +} + +struct json * +json_array_pop(struct json *json) +{ + return json->array.size ? json->array.elements[--json->array.size] : NULL; } void json_array_trim(struct json *array_) { - struct json_array *array = json_array(array_); - if (array->n < array->n_allocated){ - array->n_allocated = array->n; - array->elems = xrealloc(array->elems, array->n * sizeof *array->elems); + struct json_array *array = &array_->array; + if (array->size < array->allocated) { + array->allocated = array->size; + array->elements = xrealloc(array->elements, + array->size * sizeof *array->elements); } } @@ -252,46 +266,46 @@ struct json * json_array_create(struct json **elements, size_t n) { struct json *json = json_create(JSON_ARRAY); - json->array.elems = elements; - json->array.n = n; - json->array.n_allocated = n; + json->array.elements = elements; + json->array.size = n; + json->array.allocated = n; return json; } struct json * json_array_create_1(struct json *elem0) { - struct json **elems = xmalloc(sizeof *elems); - elems[0] = elem0; - return json_array_create(elems, 1); + struct json **elements = xmalloc(sizeof *elements); + elements[0] = elem0; + return json_array_create(elements, 1); } struct json * json_array_create_2(struct json *elem0, struct json *elem1) { - struct json **elems = xmalloc(2 * sizeof *elems); - elems[0] = elem0; - elems[1] = elem1; - return json_array_create(elems, 2); + struct json **elements = xmalloc(2 * sizeof *elements); + elements[0] = elem0; + elements[1] = elem1; + return json_array_create(elements, 2); } struct json * json_array_create_3(struct json *elem0, struct json *elem1, struct json *elem2) { - struct json **elems = xmalloc(3 * sizeof *elems); - elems[0] = elem0; - elems[1] = elem1; - elems[2] = elem2; - return json_array_create(elems, 3); + struct json **elements = xmalloc(3 * sizeof *elements); + elements[0] = elem0; + elements[1] = elem1; + elements[2] = elem2; + return json_array_create(elements, 3); } bool json_array_contains_string(const struct json *json, const char *str) { - ovs_assert(json->type == JSON_ARRAY); + size_t n = json_array_size(json); - for (size_t i = 0; i < json->array.n; i++) { - const struct json *elem = json->array.elems[i]; + for (size_t i = 0; i < n; i++) { + const struct json *elem = json_array_at(json, i); if (elem->type == JSON_STRING && !strcmp(json_string(elem), str)) { return true; @@ -370,11 +384,18 @@ json_serialized_object(const struct json *json) return json->str_ptr; } -struct json_array * -json_array(const struct json *json) +size_t +json_array_size(const struct json *json) +{ + ovs_assert(json->type == JSON_ARRAY); + return json->array.size; +} + +const struct json * +json_array_at(const struct json *json, size_t index) { ovs_assert(json->type == JSON_ARRAY); - return CONST_CAST(struct json_array *, &json->array); + return (json->array.size > index) ? json->array.elements[index] : NULL; } struct shash * @@ -406,7 +427,7 @@ json_integer(const struct json *json) } static void json_destroy_object(struct shash *object, bool yield); -static void json_destroy_array(struct json_array *array, bool yield); +static void json_destroy_array(struct json *json, bool yield); /* Frees 'json' and everything it points to, recursively. */ void @@ -418,7 +439,7 @@ json_destroy__(struct json *json, bool yield) break; case JSON_ARRAY: - json_destroy_array(&json->array, yield); + json_destroy_array(json, yield); break; case JSON_STRING: @@ -468,26 +489,27 @@ json_destroy_object(struct shash *object, bool yield) } static void -json_destroy_array(struct json_array *array, bool yield) +json_destroy_array(struct json *json, bool yield) { - size_t i; + size_t i, n = json_array_size(json); if (yield) { cooperative_multitasking_yield(); } - for (i = 0; i < array->n; i++) { + for (i = 0; i < n; i++) { if (yield) { - json_destroy_with_yield(array->elems[i]); + json_destroy_with_yield( + CONST_CAST(struct json *, json_array_at(json, i))); } else { - json_destroy(array->elems[i]); + json_destroy(CONST_CAST(struct json *, json_array_at(json, i))); } } - free(array->elems); + free(json->array.elements); } static struct json *json_deep_clone_object(const struct shash *object); -static struct json *json_deep_clone_array(const struct json_array *array); +static struct json *json_deep_clone_array(const struct json *); /* Returns a deep copy of 'json'. */ struct json * @@ -498,7 +520,7 @@ json_deep_clone(const struct json *json) return json_deep_clone_object(json->object); case JSON_ARRAY: - return json_deep_clone_array(&json->array); + return json_deep_clone_array(json); case JSON_STRING: return json_string_create(json_string(json)); @@ -544,16 +566,33 @@ json_deep_clone_object(const struct shash *object) } static struct json * -json_deep_clone_array(const struct json_array *array) -{ - struct json **elems; - size_t i; +json_deep_clone_array(const struct json *json) +{ + struct json **elements; + size_t i, n; + + n = json_array_size(json); + switch (n) { + case 0: + return json_array_create_empty(); + case 1: + return json_array_create_1(json_deep_clone(json_array_at(json, 0))); + case 2: + return json_array_create_2(json_deep_clone(json_array_at(json, 0)), + json_deep_clone(json_array_at(json, 1))); + case 3: + return json_array_create_3(json_deep_clone(json_array_at(json, 0)), + json_deep_clone(json_array_at(json, 1)), + json_deep_clone(json_array_at(json, 2))); + default: + break; + } - elems = xmalloc(array->n * sizeof *elems); - for (i = 0; i < array->n; i++) { - elems[i] = json_deep_clone(array->elems[i]); + elements = xmalloc(n * sizeof *elements); + for (i = 0; i < n; i++) { + elements[i] = json_deep_clone(json_array_at(json, i)); } - return json_array_create(elems, array->n); + return json_array_create(elements, n); } static size_t @@ -574,13 +613,13 @@ json_hash_object(const struct shash *object, size_t basis) } static size_t -json_hash_array(const struct json_array *array, size_t basis) +json_hash_array(const struct json *json, size_t basis) { - size_t i; + size_t i, n = json_array_size(json); - basis = hash_int(array->n, basis); - for (i = 0; i < array->n; i++) { - basis = json_hash(array->elems[i], basis); + basis = hash_int(n, basis); + for (i = 0; i < n; i++) { + basis = json_hash(json_array_at(json, i), basis); } return basis; } @@ -593,7 +632,7 @@ json_hash(const struct json *json, size_t basis) return json_hash_object(json->object, basis); case JSON_ARRAY: - return json_hash_array(&json->array, basis); + return json_hash_array(json, basis); case JSON_STRING: return hash_string(json_string(json), basis); @@ -638,16 +677,16 @@ json_equal_object(const struct shash *a, const struct shash *b) } static bool -json_equal_array(const struct json_array *a, const struct json_array *b) +json_equal_array(const struct json *a, const struct json *b) { - size_t i; + size_t i, n = json_array_size(a); - if (a->n != b->n) { + if (n != json_array_size(b)) { return false; } - for (i = 0; i < a->n; i++) { - if (!json_equal(a->elems[i], b->elems[i])) { + for (i = 0; i < n; i++) { + if (!json_equal(json_array_at(a, i), json_array_at(b, i))) { return false; } } @@ -671,7 +710,7 @@ json_equal(const struct json *a, const struct json *b) return json_equal_object(a->object, b->object); case JSON_ARRAY: - return json_equal_array(&a->array, &b->array); + return json_equal_array(a, b); case JSON_STRING: return !strcmp(json_string(a), json_string(b)); @@ -1594,7 +1633,7 @@ struct json_serializer { 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 *, +static void json_serialize_array(const struct json *, struct json_serializer *); static void json_serialize_string(const char *, struct ds *); @@ -1657,7 +1696,7 @@ json_serialize(const struct json *json, struct json_serializer *s) break; case JSON_ARRAY: - json_serialize_array(&json->array, s); + json_serialize_array(json, s); break; case JSON_INTEGER: @@ -1749,10 +1788,10 @@ json_serialize_object(const struct shash *object, struct json_serializer *s) } static void -json_serialize_array(const struct json_array *array, struct json_serializer *s) +json_serialize_array(const struct json *json, struct json_serializer *s) { + size_t i, n = json_array_size(json); struct ds *ds = s->ds; - size_t i; ds_put_char(ds, '['); s->depth++; @@ -1761,15 +1800,15 @@ json_serialize_array(const struct json_array *array, struct json_serializer *s) cooperative_multitasking_yield(); } - if (array->n > 0) { + if (n > 0) { indent_line(s); - for (i = 0; i < array->n; i++) { + for (i = 0; i < n; i++) { if (i) { ds_put_char(ds, ','); indent_line(s); } - json_serialize(array->elems[i], s); + json_serialize(json_array_at(json, i), s); } } diff --git a/lib/ovsdb-cs.c b/lib/ovsdb-cs.c index f8612cb968d..facad3793b8 100644 --- a/lib/ovsdb-cs.c +++ b/lib/ovsdb-cs.c @@ -843,15 +843,17 @@ static enum condition_type condition_classify(const struct json *condition) { if (condition) { - const struct json_array *a = json_array(condition); - switch (a->n) { + switch (json_array_size(condition)) { case 0: return COND_FALSE; - case 1: - return (a->elems[0]->type == JSON_FALSE ? COND_FALSE - : a->elems[0]->type == JSON_TRUE ? COND_TRUE + case 1: { + const struct json *cond = json_array_at(condition, 0); + + return (cond->type == JSON_FALSE ? COND_FALSE + : cond->type == JSON_TRUE ? COND_TRUE : COND_OTHER); + } default: return COND_OTHER; @@ -1387,9 +1389,9 @@ ovsdb_cs_db_parse_lock_notify(struct ovsdb_cs_db *db, { if (db->lock_name && params->type == JSON_ARRAY - && json_array(params)->n > 0 - && json_array(params)->elems[0]->type == JSON_STRING) { - const char *lock_name = json_string(json_array(params)->elems[0]); + && json_array_size(params) > 0 + && json_array_at(params, 0)->type == JSON_STRING) { + const char *lock_name = json_string(json_array_at(params, 0)); if (!strcmp(db->lock_name, lock_name)) { ovsdb_cs_db_update_has_lock(db, new_has_lock); @@ -1523,12 +1525,12 @@ ovsdb_cs_send_monitor_request(struct ovsdb_cs *cs, struct ovsdb_cs_db *db, ovs_assert(mr->type == JSON_ARRAY); struct json *mr0; - if (json_array(mr)->n == 0) { + if (json_array_size(mr) == 0) { mr0 = json_object_create(); json_object_put(mr0, "columns", json_array_create_empty()); json_array_add(mr, mr0); } else { - mr0 = json_array(mr)->elems[0]; + mr0 = CONST_CAST(struct json *, json_array_at(mr, 0)); } ovs_assert(mr0->type == JSON_OBJECT); @@ -1587,21 +1589,21 @@ ovsdb_cs_db_parse_monitor_reply(struct ovsdb_cs_db *db, const struct json *table_updates; bool clear; if (version == 3) { - if (result->type != JSON_ARRAY || result->array.n != 3 - || (result->array.elems[0]->type != JSON_TRUE && - result->array.elems[0]->type != JSON_FALSE) - || result->array.elems[1]->type != JSON_STRING + if (result->type != JSON_ARRAY || json_array_size(result) != 3 + || (json_array_at(result, 0)->type != JSON_TRUE && + json_array_at(result, 0)->type != JSON_FALSE) + || json_array_at(result, 1)->type != JSON_STRING || !uuid_from_string(&db->last_id, - json_string(result->array.elems[1]))) { + json_string(json_array_at(result, 1)))) { struct ovsdb_error *error = ovsdb_syntax_error( result, NULL, "bad monitor_cond_since reply format"); log_parse_update_error(error); return; } - bool found = json_boolean(result->array.elems[0]); + bool found = json_boolean(json_array_at(result, 0)); clear = !found; - table_updates = result->array.elems[2]; + table_updates = json_array_at(result, 2); } else { clear = true; table_updates = result; @@ -1628,7 +1630,7 @@ ovsdb_cs_db_parse_update_rpc(struct ovsdb_cs_db *db, struct json *params = msg->params; int n = version == 3 ? 3 : 2; - if (params->type != JSON_ARRAY || params->array.n != n) { + if (params->type != JSON_ARRAY || json_array_size(params) != n) { struct ovsdb_error *error = ovsdb_syntax_error( params, NULL, "%s must be an array with %u elements.", msg->method, n); @@ -1636,12 +1638,12 @@ ovsdb_cs_db_parse_update_rpc(struct ovsdb_cs_db *db, return false; } - if (!json_equal(params->array.elems[0], db->monitor_id)) { + if (!json_equal(json_array_at(params, 0), db->monitor_id)) { return false; } if (version == 3) { - const char *last_id = json_string(params->array.elems[1]); + const char *last_id = json_string(json_array_at(params, 1)); if (!uuid_from_string(&db->last_id, last_id)) { struct ovsdb_error *error = ovsdb_syntax_error( params, NULL, "Last-id %s is not in UUID format.", last_id); @@ -1650,7 +1652,8 @@ ovsdb_cs_db_parse_update_rpc(struct ovsdb_cs_db *db, } } - struct json *table_updates = params->array.elems[version == 3 ? 2 : 1]; + const struct json *table_updates = json_array_at(params, + version == 3 ? 2 : 1); ovsdb_cs_db_add_update(db, table_updates, version, false, false); return true; } @@ -1663,8 +1666,8 @@ ovsdb_cs_handle_monitor_canceled(struct ovsdb_cs *cs, if (msg->type != JSONRPC_NOTIFY || strcmp(msg->method, "monitor_canceled") || msg->params->type != JSON_ARRAY - || msg->params->array.n != 1 - || !json_equal(msg->params->array.elems[0], db->monitor_id)) { + || json_array_size(msg->params) != 1 + || !json_equal(json_array_at(msg->params, 0), db->monitor_id)) { return false; } diff --git a/lib/ovsdb-data.c b/lib/ovsdb-data.c index a987bd60d02..745704cfe77 100644 --- a/lib/ovsdb-data.c +++ b/lib/ovsdb-data.c @@ -262,16 +262,16 @@ unwrap_json(const struct json *json, const char *name, enum json_type value_type, const struct json **value) { if (json->type != JSON_ARRAY - || json->array.n != 2 - || json->array.elems[0]->type != JSON_STRING - || (name && strcmp(json_string(json->array.elems[0]), name)) - || json->array.elems[1]->type != value_type) + || json_array_size(json) != 2 + || json_array_at(json, 0)->type != JSON_STRING + || (name && strcmp(json_string(json_array_at(json, 0)), name)) + || json_array_at(json, 1)->type != value_type) { *value = NULL; return ovsdb_syntax_error(json, NULL, "expected [\"%s\", <%s>]", name, json_type_to_string(value_type)); } - *value = json->array.elems[1]; + *value = json_array_at(json, 1); return NULL; } @@ -279,11 +279,11 @@ static struct ovsdb_error * parse_json_pair(const struct json *json, const struct json **elem0, const struct json **elem1) { - if (json->type != JSON_ARRAY || json->array.n != 2) { + if (json->type != JSON_ARRAY || json_array_size(json) != 2) { return ovsdb_syntax_error(json, NULL, "expected 2-element array"); } - *elem0 = json->array.elems[0]; - *elem1 = json->array.elems[1]; + *elem0 = json_array_at(json, 0); + *elem1 = json_array_at(json, 1); return NULL; } @@ -1277,9 +1277,9 @@ ovsdb_datum_from_json__(struct ovsdb_datum *datum, if (ovsdb_type_is_map(type) || (json->type == JSON_ARRAY - && json->array.n > 0 - && json->array.elems[0]->type == JSON_STRING - && !strcmp(json_string(json->array.elems[0]), "set"))) { + && json_array_size(json) > 0 + && json_array_at(json, 0)->type == JSON_STRING + && !strcmp(json_string(json_array_at(json, 0)), "set"))) { bool is_map = ovsdb_type_is_map(type); const char *class = is_map ? "map" : "set"; const struct json *inner; @@ -1291,7 +1291,7 @@ ovsdb_datum_from_json__(struct ovsdb_datum *datum, return error; } - n = inner->array.n; + n = json_array_size(inner); if (n < type->n_min || n > type->n_max) { if (type->n_min == 1 && type->n_max == 1) { return ovsdb_syntax_error(json, NULL, "%s must have exactly " @@ -1310,7 +1310,7 @@ ovsdb_datum_from_json__(struct ovsdb_datum *datum, datum->values = is_map ? xmalloc(n * sizeof *datum->values) : NULL; datum->refcnt = NULL; for (i = 0; i < n; i++) { - const struct json *element = inner->array.elems[i]; + const struct json *element = json_array_at(inner, i); const struct json *key = NULL; const struct json *value = NULL; diff --git a/lib/ovsdb-idl.c b/lib/ovsdb-idl.c index 05880394d20..7c4ad2581c2 100644 --- a/lib/ovsdb-idl.c +++ b/lib/ovsdb-idl.c @@ -2863,11 +2863,11 @@ substitute_uuids(struct json *json, const struct ovsdb_idl_txn *txn) struct uuid uuid; size_t i; - if (json->array.n == 2 - && json->array.elems[0]->type == JSON_STRING - && json->array.elems[1]->type == JSON_STRING - && !strcmp(json_string(json->array.elems[0]), "uuid") - && uuid_from_string(&uuid, json_string(json->array.elems[1]))) { + if (json_array_size(json) == 2 + && json_array_at(json, 0)->type == JSON_STRING + && json_array_at(json, 1)->type == JSON_STRING + && !strcmp(json_string(json_array_at(json, 0)), "uuid") + && uuid_from_string(&uuid, json_string(json_array_at(json, 1)))) { const struct ovsdb_idl_row *row; row = ovsdb_idl_txn_get_row(txn, &uuid); @@ -2883,9 +2883,11 @@ substitute_uuids(struct json *json, const struct ovsdb_idl_txn *txn) } } - for (i = 0; i < json->array.n; i++) { - json->array.elems[i] = substitute_uuids(json->array.elems[i], - txn); + for (i = 0; i < json_array_size(json); i++) { + json_array_set( + json, i, + substitute_uuids( + CONST_CAST(struct json *, json_array_at(json, i)), txn)); } } else if (json->type == JSON_OBJECT) { struct shash_node *node; @@ -3320,7 +3322,7 @@ ovsdb_idl_txn_commit(struct ovsdb_idl_txn *txn) insert = xmalloc(sizeof *insert); insert->dummy = row->uuid; - insert->op_index = operations->array.n - 1; + insert->op_index = json_array_size(operations) - 1; uuid_zero(&insert->real); hmap_insert(&txn->inserted_rows, &insert->hmap_node, uuid_hash(&insert->dummy)); @@ -3390,7 +3392,7 @@ ovsdb_idl_txn_commit(struct ovsdb_idl_txn *txn) /* Add increment. */ if (txn->inc_table && (any_updates || txn->inc_force)) { any_updates = true; - txn->inc_index = operations->array.n - 1; + txn->inc_index = json_array_size(operations) - 1; struct json *op = json_object_create(); json_object_put_string(op, "op", "mutate"); @@ -3905,21 +3907,21 @@ check_json_type(const struct json *json, enum json_type type, const char *name) static bool ovsdb_idl_txn_process_inc_reply(struct ovsdb_idl_txn *txn, - const struct json_array *results) + const struct json *results) { - struct json *count, *rows, *row, *column; + const struct json *count, *rows, *row, *column; struct shash *mutate, *select; - if (txn->inc_index + 2 > results->n) { + if (txn->inc_index + 2 > json_array_size(results)) { VLOG_WARN_RL(&syntax_rl, "reply does not contain enough operations " "for increment (has %"PRIuSIZE", needs %u)", - results->n, txn->inc_index + 2); + json_array_size(results), txn->inc_index + 2); return false; } /* We know that this is a JSON object because the loop in * ovsdb_idl_txn_process_reply() checked. */ - mutate = json_object(results->elems[txn->inc_index]); + mutate = json_object(json_array_at(results, txn->inc_index)); count = shash_find_data(mutate, "count"); if (!check_json_type(count, JSON_INTEGER, "\"mutate\" reply \"count\"")) { return false; @@ -3931,18 +3933,18 @@ ovsdb_idl_txn_process_inc_reply(struct ovsdb_idl_txn *txn, return false; } - select = json_object(results->elems[txn->inc_index + 1]); + select = json_object(json_array_at(results, txn->inc_index + 1)); rows = shash_find_data(select, "rows"); if (!check_json_type(rows, JSON_ARRAY, "\"select\" reply \"rows\"")) { return false; } - if (rows->array.n != 1) { + if (json_array_size(rows) != 1) { VLOG_WARN_RL(&syntax_rl, "\"select\" reply \"rows\" has %"PRIuSIZE" elements " "instead of 1", - rows->array.n); + json_array_size(rows)); return false; } - row = rows->array.elems[0]; + row = json_array_at(rows, 0); if (!check_json_type(row, JSON_OBJECT, "\"select\" reply row")) { return false; } @@ -3957,7 +3959,7 @@ ovsdb_idl_txn_process_inc_reply(struct ovsdb_idl_txn *txn, static bool ovsdb_idl_txn_process_insert_reply(struct ovsdb_idl_txn_insert *insert, - const struct json_array *results) + const struct json *results) { static const struct ovsdb_base_type uuid_type = OVSDB_BASE_UUID_INIT; struct ovsdb_error *error; @@ -3965,16 +3967,16 @@ ovsdb_idl_txn_process_insert_reply(struct ovsdb_idl_txn_insert *insert, union ovsdb_atom uuid; struct shash *reply; - if (insert->op_index >= results->n) { + if (insert->op_index >= json_array_size(results)) { VLOG_WARN_RL(&syntax_rl, "reply does not contain enough operations " "for insert (has %"PRIuSIZE", needs %u)", - results->n, insert->op_index); + json_array_size(results), insert->op_index); return false; } /* We know that this is a JSON object because the loop in * ovsdb_idl_txn_process_reply() checked. */ - reply = json_object(results->elems[insert->op_index]); + reply = json_object(json_array_at(results, insert->op_index)); json_uuid = shash_find_data(reply, "uuid"); if (!check_json_type(json_uuid, JSON_ARRAY, "\"insert\" reply \"uuid\"")) { return false; @@ -4021,14 +4023,15 @@ ovsdb_idl_txn_process_reply(struct ovsdb_idl *idl, status = TXN_ERROR; ovsdb_idl_txn_set_error_json(txn, msg->result); } else { - struct json_array *ops = &msg->result->array; + const struct json *ops = msg->result; int hard_errors = 0; int soft_errors = 0; int lock_errors = 0; - size_t i; + size_t i, n; - for (i = 0; i < ops->n; i++) { - struct json *op = ops->elems[i]; + n = json_array_size(ops); + for (i = 0; i < n; i++) { + const struct json *op = json_array_at(ops, i); if (op->type == JSON_NULL) { /* This isn't an error in itself but indicates that some prior diff --git a/lib/unixctl.c b/lib/unixctl.c index c060e86597d..4fd1509595c 100644 --- a/lib/unixctl.c +++ b/lib/unixctl.c @@ -385,7 +385,7 @@ process_command(struct unixctl_conn *conn, struct jsonrpc_msg *request) char *error = NULL; struct unixctl_command *command; - struct json_array *params; + const struct json *params; COVERAGE_INC(unixctl_received); conn->request_id = json_clone(request->id); @@ -399,30 +399,32 @@ process_command(struct unixctl_conn *conn, struct jsonrpc_msg *request) free(id_s); } - params = json_array(request->params); + params = request->params; command = shash_find_data(&commands, request->method); if (!command) { error = xasprintf("\"%s\" is not a valid command (use " "\"list-commands\" to see a list of valid commands)", request->method); - } else if (params->n < command->min_args) { + } else if (json_array_size(params) < command->min_args) { error = xasprintf("\"%s\" command requires at least %d arguments", request->method, command->min_args); - } else if (params->n > command->max_args) { + } else if (json_array_size(params) > command->max_args) { error = xasprintf("\"%s\" command takes at most %d arguments", request->method, command->max_args); } else { struct svec argv = SVEC_EMPTY_INITIALIZER; - int i; + int i, n = json_array_size(params); svec_add(&argv, request->method); - for (i = 0; i < params->n; i++) { - if (params->elems[i]->type != JSON_STRING) { + for (i = 0; i < n; i++) { + const struct json *elem = json_array_at(params, i); + + if (elem->type != JSON_STRING) { error = xasprintf("\"%s\" command has non-string argument", request->method); break; } - svec_add(&argv, json_string(params->elems[i])); + svec_add(&argv, json_string(elem)); } svec_terminate(&argv); diff --git a/ovsdb/column.c b/ovsdb/column.c index 37cda730c96..f4dc5bea684 100644 --- a/ovsdb/column.c +++ b/ovsdb/column.c @@ -158,22 +158,25 @@ ovsdb_column_set_from_json(const struct json *json, return NULL; } else { struct ovsdb_error *error = NULL; - size_t i; + size_t i, n; if (json->type != JSON_ARRAY) { goto error; } /* XXX this is O(n**2) */ - for (i = 0; i < json->array.n; i++) { + n = json_array_size(json); + for (i = 0; i < n; i++) { const struct ovsdb_column *column; + const struct json *elem; const char *s; - if (json->array.elems[i]->type != JSON_STRING) { + elem = json_array_at(json, i); + if (elem->type != JSON_STRING) { goto error; } - s = json_string(json->array.elems[i]); + s = json_string(elem); column = shash_find_data(&schema->columns, s); if (!column) { error = ovsdb_syntax_error(json, NULL, "%s is not a valid " diff --git a/ovsdb/condition.c b/ovsdb/condition.c index 4911fbf59be..500fce761a4 100644 --- a/ovsdb/condition.c +++ b/ovsdb/condition.c @@ -35,7 +35,6 @@ ovsdb_clause_from_json(const struct ovsdb_table_schema *ts, struct ovsdb_symbol_table *symtab, struct ovsdb_clause *clause) { - const struct json_array *array; struct ovsdb_error *error; const char *function_name; const char *column_name; @@ -57,14 +56,13 @@ ovsdb_clause_from_json(const struct ovsdb_table_schema *ts, } if (json->type != JSON_ARRAY - || json->array.n != 3 - || json->array.elems[0]->type != JSON_STRING - || json->array.elems[1]->type != JSON_STRING) { + || json_array_size(json) != 3 + || json_array_at(json, 0)->type != JSON_STRING + || json_array_at(json, 1)->type != JSON_STRING) { return ovsdb_syntax_error(json, NULL, "Parse error in condition."); } - array = json_array(json); - column_name = json_string(array->elems[0]); + column_name = json_string(json_array_at(json, 0)); clause->column = ovsdb_table_schema_get_column(ts, column_name); if (!clause->column) { return ovsdb_syntax_error(json, "unknown column", @@ -74,7 +72,7 @@ ovsdb_clause_from_json(const struct ovsdb_table_schema *ts, clause->index = clause->column->index; type = clause->column->type; - function_name = json_string(array->elems[1]); + function_name = json_string(json_array_at(json, 1)); error = ovsdb_function_from_string(function_name, &clause->function); if (error) { return error; @@ -127,7 +125,8 @@ ovsdb_clause_from_json(const struct ovsdb_table_schema *ts, case OVSDB_F_FALSE: OVS_NOT_REACHED(); } - return ovsdb_datum_from_json(&clause->arg, &type, array->elems[2], symtab); + return ovsdb_datum_from_json(&clause->arg, &type, + json_array_at(json, 2), symtab); } static void @@ -246,15 +245,14 @@ ovsdb_condition_from_json(const struct ovsdb_table_schema *ts, struct ovsdb_symbol_table *symtab, struct ovsdb_condition *cnd) { - const struct json_array *array = json_array(json); - size_t i; + size_t i, n = json_array_size(json); ovsdb_condition_init(cnd); - cnd->clauses = xmalloc(array->n * sizeof *cnd->clauses); + cnd->clauses = xmalloc(n * sizeof *cnd->clauses); - for (i = 0; i < array->n; i++) { + for (i = 0; i < n; i++) { struct ovsdb_error *error; - error = ovsdb_clause_from_json(ts, array->elems[i], symtab, + error = ovsdb_clause_from_json(ts, json_array_at(json, i), symtab, &cnd->clauses[i]); if (error) { ovsdb_condition_destroy(cnd); diff --git a/ovsdb/execution.c b/ovsdb/execution.c index 756129da456..38cdcd166d6 100644 --- a/ovsdb/execution.c +++ b/ovsdb/execution.c @@ -126,9 +126,9 @@ ovsdb_execute_compose(struct ovsdb *db, const struct ovsdb_session *session, *forwarding_needed = false; } if (params->type != JSON_ARRAY - || !params->array.n - || params->array.elems[0]->type != JSON_STRING - || strcmp(json_string(params->array.elems[0]), db->schema->name)) { + || !json_array_size(params) + || json_array_at(params, 0)->type != JSON_STRING + || strcmp(json_string(json_array_at(params, 0)), db->schema->name)) { if (params->type != JSON_ARRAY) { error = ovsdb_syntax_error(params, NULL, "array expected"); } else { @@ -152,10 +152,10 @@ ovsdb_execute_compose(struct ovsdb *db, const struct ovsdb_session *session, results = NULL; results = json_array_create_empty(); - n_operations = params->array.n - 1; + n_operations = json_array_size(params) - 1; error = NULL; for (i = 1; i <= n_operations; i++) { - struct json *operation = params->array.elems[i]; + const struct json *operation = json_array_at(params, i); struct ovsdb_error *parse_error; struct ovsdb_parser parser; struct json *result; @@ -219,7 +219,7 @@ ovsdb_execute_compose(struct ovsdb *db, const struct ovsdb_session *session, } json_array_add(results, result); } - while (json_array(results)->n < n_operations) { + while (json_array_size(results) < n_operations) { json_array_add(results, json_null_create()); } @@ -745,7 +745,7 @@ ovsdb_execute_wait(struct ovsdb_execution *x, struct ovsdb_parser *parser, struct ovsdb_error *error; struct wait_auxdata aux; long long int timeout_msec = 0; - size_t i; + size_t i, n; timeout = ovsdb_parser_member(parser, "timeout", OP_INTEGER | OP_OPTIONAL); where = ovsdb_parser_member(parser, "where", OP_ARRAY); @@ -786,11 +786,13 @@ ovsdb_execute_wait(struct ovsdb_execution *x, struct ovsdb_parser *parser, if (!error) { /* Parse "rows" into 'expected'. */ ovsdb_row_hash_init(&expected, &columns); - for (i = 0; i < rows->array.n; i++) { + + n = json_array_size(rows); + for (i = 0; i < n; i++) { struct ovsdb_row *row; row = ovsdb_row_create(table); - error = ovsdb_row_from_json(row, rows->array.elems[i], x->symtab, + error = ovsdb_row_from_json(row, json_array_at(rows, i), x->symtab, NULL, false); if (error) { ovsdb_row_destroy(row); diff --git a/ovsdb/jsonrpc-server.c b/ovsdb/jsonrpc-server.c index f5afdc7e595..a47c2c76cea 100644 --- a/ovsdb/jsonrpc-server.c +++ b/ovsdb/jsonrpc-server.c @@ -107,7 +107,7 @@ static struct jsonrpc_msg *ovsdb_jsonrpc_monitor_cond_change( const struct json *request_id); static struct jsonrpc_msg *ovsdb_jsonrpc_monitor_cancel( struct ovsdb_jsonrpc_session *, - struct json_array *params, + const struct json *params, const struct json *request_id); static void ovsdb_jsonrpc_monitor_preremove_db(struct ovsdb_jsonrpc_session *, struct ovsdb *); @@ -887,20 +887,21 @@ ovsdb_jsonrpc_lookup_db(const struct ovsdb_jsonrpc_session *s, const struct jsonrpc_msg *request, struct jsonrpc_msg **replyp) { - struct json_array *params; + const struct json *params; struct ovsdb_error *error; const char *db_name; struct ovsdb *db; - params = json_array(request->params); - if (!params->n || params->elems[0]->type != JSON_STRING) { + params = request->params; + if (!json_array_size(params) + || json_array_at(params, 0)->type != JSON_STRING) { error = ovsdb_syntax_error( request->params, NULL, "%s request params must begin with ", request->method); goto error; } - db_name = json_string(params->elems[0]); + db_name = json_string(json_array_at(params, 0)); db = shash_find_data(&s->up.server->dbs, db_name); if (!db) { error = ovsdb_syntax_error( @@ -932,18 +933,19 @@ static struct ovsdb_error * ovsdb_jsonrpc_session_parse_lock_name(const struct jsonrpc_msg *request, const char **lock_namep) { - const struct json_array *params; + const struct json *params = request->params; + const struct json *elem = json_array_at(params, 0); - params = json_array(request->params); - if (params->n != 1 || params->elems[0]->type != JSON_STRING || - !ovsdb_parser_is_id(json_string(params->elems[0]))) { + if (json_array_size(params) != 1 + || elem->type != JSON_STRING + || !ovsdb_parser_is_id(json_string(elem))) { *lock_namep = NULL; - return ovsdb_syntax_error(request->params, NULL, + return ovsdb_syntax_error(params, NULL, "%s request params must be ", request->method); } - *lock_namep = json_string(params->elems[0]); + *lock_namep = json_string(elem); return NULL; } @@ -1088,14 +1090,14 @@ static struct jsonrpc_msg * ovsdb_jsonrpc_session_set_db_change_aware(struct ovsdb_jsonrpc_session *s, const struct jsonrpc_msg *request) { - const struct json_array *params = json_array(request->params); - if (params->n != 1 - || (params->elems[0]->type != JSON_TRUE && - params->elems[0]->type != JSON_FALSE)) { + const struct json *params = request->params; + if (json_array_size(params) != 1 + || (json_array_at(params, 0)->type != JSON_TRUE && + json_array_at(params, 0)->type != JSON_FALSE)) { return syntax_error_reply(request, "true or false parameter expected"); } - s->db_change_aware = json_boolean(params->elems[0]); + s->db_change_aware = json_boolean(json_array_at(params, 0)); return jsonrpc_create_reply(json_object_create(), request->id); } @@ -1132,8 +1134,7 @@ ovsdb_jsonrpc_session_got_request(struct ovsdb_jsonrpc_session *s, reply = ovsdb_jsonrpc_monitor_cond_change(s, request->params, request->id); } else if (!strcmp(request->method, "monitor_cancel")) { - reply = ovsdb_jsonrpc_monitor_cancel(s, json_array(request->params), - request->id); + reply = ovsdb_jsonrpc_monitor_cancel(s, request->params, request->id); } else if (!strcmp(request->method, "get_schema")) { struct ovsdb *db = ovsdb_jsonrpc_lookup_db(s, request, &reply); if (db && !reply) { @@ -1184,11 +1185,11 @@ ovsdb_jsonrpc_session_got_request(struct ovsdb_jsonrpc_session *s, static void execute_cancel(struct ovsdb_jsonrpc_session *s, struct jsonrpc_msg *request) { - if (json_array(request->params)->n == 1) { + if (json_array_size(request->params) == 1) { struct ovsdb_jsonrpc_trigger *t; - struct json *id; + const struct json *id; - id = request->params->array.elems[0]; + id = json_array_at(request->params, 0); t = ovsdb_jsonrpc_trigger_find(s, id, json_hash(id, 0)); if (t) { ovsdb_jsonrpc_trigger_complete(t); @@ -1432,23 +1433,25 @@ ovsdb_jsonrpc_parse_monitor_request( ovsdb_monitor_table_add_select(dbmon, table, select); if (columns) { - size_t i; + size_t i, n; if (columns->type != JSON_ARRAY) { return ovsdb_syntax_error(columns, NULL, "array of column names expected"); } - for (i = 0; i < columns->array.n; i++) { + n = json_array_size(columns); + for (i = 0; i < n; i++) { + const struct json *elem = json_array_at(columns, i); const struct ovsdb_column *column; const char *s; - if (columns->array.elems[i]->type != JSON_STRING) { + if (elem->type != JSON_STRING) { return ovsdb_syntax_error(columns, NULL, "array of column names expected"); } - s = json_string(columns->array.elems[i]); + s = json_string(elem); column = shash_find_data(&table->schema->columns, s); if (!column) { return ovsdb_syntax_error(columns, NULL, "%s is not a valid " @@ -1494,20 +1497,20 @@ ovsdb_jsonrpc_monitor_create(struct ovsdb_jsonrpc_session *s, struct ovsdb *db, { ovs_assert(db); + const struct json *monitor_id, *monitor_requests; struct ovsdb_jsonrpc_monitor *m = NULL; struct ovsdb_monitor *dbmon = NULL; - struct json *monitor_id, *monitor_requests; struct ovsdb_error *error = NULL; struct shash_node *node; struct json *json; - if ((version == OVSDB_MONITOR_V2 && json_array(params)->n != 3) || - (version == OVSDB_MONITOR_V3 && json_array(params)->n != 4)) { + if ((version == OVSDB_MONITOR_V2 && json_array_size(params) != 3) || + (version == OVSDB_MONITOR_V3 && json_array_size(params) != 4)) { error = ovsdb_syntax_error(params, NULL, "invalid parameters"); goto error; } - monitor_id = params->array.elems[1]; - monitor_requests = params->array.elems[2]; + monitor_id = json_array_at(params, 1); + monitor_requests = json_array_at(params, 2); if (monitor_requests->type != JSON_OBJECT) { error = ovsdb_syntax_error(monitor_requests, NULL, "monitor-requests must be object"); @@ -1533,7 +1536,7 @@ ovsdb_jsonrpc_monitor_create(struct ovsdb_jsonrpc_session *s, struct ovsdb *db, SHASH_FOR_EACH (node, json_object(monitor_requests)) { const struct ovsdb_table *table; const struct json *mr_value; - size_t i; + size_t i, n; table = ovsdb_get_table(m->db, node->name); if (!table) { @@ -1547,13 +1550,14 @@ ovsdb_jsonrpc_monitor_create(struct ovsdb_jsonrpc_session *s, struct ovsdb *db, /* Parse columns. */ mr_value = node->data; if (mr_value->type == JSON_ARRAY) { - const struct json_array *array = &mr_value->array; + n = json_array_size(mr_value); + for (i = 0; i < n; i++) { + const struct json *elem = json_array_at(mr_value, i); - for (i = 0; i < array->n; i++) { error = ovsdb_jsonrpc_parse_monitor_request(m->dbmon, table, m->condition, - array->elems[i]); + elem); if (error) { goto error; } @@ -1584,7 +1588,8 @@ ovsdb_jsonrpc_monitor_create(struct ovsdb_jsonrpc_session *s, struct ovsdb *db, bool initial = false; if (version == OVSDB_MONITOR_V3) { - struct json *last_id = params->array.elems[3]; + const struct json *last_id = json_array_at(params, 3); + if (last_id->type != JSON_STRING) { error = ovsdb_syntax_error(last_id, NULL, "last-txn-id must be string"); @@ -1664,24 +1669,24 @@ ovsdb_jsonrpc_monitor_cond_change(struct ovsdb_jsonrpc_session *s, struct json *params, const struct json *request_id) { - struct ovsdb_error *error; + const struct json *monitor_cond_change_reqs; struct ovsdb_jsonrpc_monitor *m; - struct json *monitor_cond_change_reqs; + struct ovsdb_error *error; struct shash_node *node; - if (json_array(params)->n != 3) { + if (json_array_size(params) != 3) { error = ovsdb_syntax_error(params, NULL, "invalid parameters"); goto error; } - m = ovsdb_jsonrpc_monitor_find(s, params->array.elems[0]); + m = ovsdb_jsonrpc_monitor_find(s, json_array_at(params, 0)); if (!m) { - error = ovsdb_syntax_error(params->array.elems[0], NULL, + error = ovsdb_syntax_error(json_array_at(params, 0), NULL, "unknown monitor session"); goto error; } - const struct json *new_monitor_id = params->array.elems[1]; + const struct json *new_monitor_id = json_array_at(params, 1); bool changing_id = !json_equal(m->monitor_id, new_monitor_id); if (changing_id && ovsdb_jsonrpc_monitor_find(s, new_monitor_id)) { error = ovsdb_syntax_error(new_monitor_id, NULL, @@ -1689,7 +1694,7 @@ ovsdb_jsonrpc_monitor_cond_change(struct ovsdb_jsonrpc_session *s, goto error; } - monitor_cond_change_reqs = params->array.elems[2]; + monitor_cond_change_reqs = json_array_at(params, 2); if (monitor_cond_change_reqs->type != JSON_OBJECT) { error = ovsdb_syntax_error(NULL, NULL, @@ -1700,7 +1705,7 @@ ovsdb_jsonrpc_monitor_cond_change(struct ovsdb_jsonrpc_session *s, SHASH_FOR_EACH (node, json_object(monitor_cond_change_reqs)) { const struct ovsdb_table *table; const struct json *mr_value; - size_t i; + size_t i, n; table = ovsdb_get_table(m->db, node->name); if (!table) { @@ -1717,11 +1722,10 @@ ovsdb_jsonrpc_monitor_cond_change(struct ovsdb_jsonrpc_session *s, mr_value = node->data; if (mr_value->type == JSON_ARRAY) { - const struct json_array *array = &mr_value->array; - - for (i = 0; i < array->n; i++) { + n = json_array_size(mr_value); + for (i = 0; i < n; i++) { error = ovsdb_jsonrpc_parse_monitor_cond_change_request( - m, table, array->elems[i]); + m, table, json_array_at(mr_value, i)); if (error) { goto error; } @@ -1774,16 +1778,16 @@ ovsdb_jsonrpc_monitor_cond_change(struct ovsdb_jsonrpc_session *s, static struct jsonrpc_msg * ovsdb_jsonrpc_monitor_cancel(struct ovsdb_jsonrpc_session *s, - struct json_array *params, + const struct json *params, const struct json *request_id) { - if (params->n != 1) { + if (json_array_size(params) != 1) { return jsonrpc_create_error(json_string_create("invalid parameters"), request_id); } else { struct ovsdb_jsonrpc_monitor *m; - m = ovsdb_jsonrpc_monitor_find(s, params->elems[0]); + m = ovsdb_jsonrpc_monitor_find(s, json_array_at(params, 0)); if (!m) { return jsonrpc_create_error(json_string_create("unknown monitor"), request_id); diff --git a/ovsdb/mutation.c b/ovsdb/mutation.c index 79456001917..f5ca8c88642 100644 --- a/ovsdb/mutation.c +++ b/ovsdb/mutation.c @@ -79,20 +79,18 @@ ovsdb_mutation_from_json(const struct ovsdb_table_schema *ts, struct ovsdb_symbol_table *symtab, struct ovsdb_mutation *m) { - const struct json_array *array; struct ovsdb_error *error; const char *mutator_name; const char *column_name; if (json->type != JSON_ARRAY - || json->array.n != 3 - || json->array.elems[0]->type != JSON_STRING - || json->array.elems[1]->type != JSON_STRING) { + || json_array_size(json) != 3 + || json_array_at(json, 0)->type != JSON_STRING + || json_array_at(json, 1)->type != JSON_STRING) { return ovsdb_syntax_error(json, NULL, "Parse error in mutation."); } - array = json_array(json); - column_name = json_string(array->elems[0]); + column_name = json_string(json_array_at(json, 0)); m->column = ovsdb_table_schema_get_column(ts, column_name); if (!m->column) { return ovsdb_syntax_error(json, "unknown column", @@ -107,7 +105,7 @@ ovsdb_mutation_from_json(const struct ovsdb_table_schema *ts, ovsdb_type_clone(&m->type, &m->column->type); - mutator_name = json_string(array->elems[1]); + mutator_name = json_string(json_array_at(json, 1)); error = ovsdb_mutator_from_string(mutator_name, &m->mutator); if (error) { goto exit; @@ -129,8 +127,8 @@ ovsdb_mutation_from_json(const struct ovsdb_table_schema *ts, } ovsdb_base_type_clear_constraints(&m->type.key); m->type.n_min = m->type.n_max = 1; - error = ovsdb_datum_from_json(&m->arg, &m->type, array->elems[2], - symtab); + error = ovsdb_datum_from_json(&m->arg, &m->type, + json_array_at(json, 2), symtab); break; case OVSDB_M_INSERT: @@ -142,16 +140,16 @@ ovsdb_mutation_from_json(const struct ovsdb_table_schema *ts, if (m->mutator == OVSDB_M_DELETE) { m->type.n_max = UINT_MAX; } - error = ovsdb_datum_from_json(&m->arg, &m->type, array->elems[2], - symtab); + error = ovsdb_datum_from_json(&m->arg, &m->type, + json_array_at(json, 2), symtab); if (error && ovsdb_type_is_map(&m->type) && m->mutator == OVSDB_M_DELETE) { ovsdb_error_destroy(error); ovsdb_base_type_destroy(&m->type.value); m->type.value.enum_ = NULL; m->type.value.type = OVSDB_TYPE_VOID; - error = ovsdb_datum_from_json(&m->arg, &m->type, array->elems[2], - symtab); + error = ovsdb_datum_from_json(&m->arg, &m->type, + json_array_at(json, 2), symtab); } break; @@ -179,14 +177,13 @@ ovsdb_mutation_set_from_json(const struct ovsdb_table_schema *ts, struct ovsdb_symbol_table *symtab, struct ovsdb_mutation_set *set) { - const struct json_array *array = json_array(json); - size_t i; + size_t i, n = json_array_size(json); - set->mutations = xmalloc(array->n * sizeof *set->mutations); + set->mutations = xmalloc(n * sizeof *set->mutations); set->n_mutations = 0; - for (i = 0; i < array->n; i++) { + for (i = 0; i < n; i++) { struct ovsdb_error *error; - error = ovsdb_mutation_from_json(ts, array->elems[i], symtab, + error = ovsdb_mutation_from_json(ts, json_array_at(json, i), symtab, &set->mutations[i]); if (error) { ovsdb_mutation_set_destroy(set); diff --git a/ovsdb/ovsdb-client.c b/ovsdb/ovsdb-client.c index 9c1426b17e9..1639c426af0 100644 --- a/ovsdb/ovsdb-client.c +++ b/ovsdb/ovsdb-client.c @@ -580,7 +580,7 @@ static void fetch_dbs(struct jsonrpc *rpc, struct svec *dbs) { struct jsonrpc_msg *request, *reply; - size_t i; + size_t i, n; request = jsonrpc_create_request("list_dbs", json_array_create_empty(), NULL); @@ -590,8 +590,9 @@ fetch_dbs(struct jsonrpc *rpc, struct svec *dbs) ovs_fatal(0, "list_dbs response is not array"); } - for (i = 0; i < reply->result->array.n; i++) { - const struct json *name = reply->result->array.elems[i]; + n = json_array_size(reply->result); + for (i = 0; i < n; i++) { + const struct json *name = json_array_at(reply->result, i); if (name->type != JSON_STRING) { ovs_fatal(0, "list_dbs response %"PRIuSIZE" is not string", i); @@ -663,14 +664,14 @@ parse_database_info_reply(const struct jsonrpc_msg *reply, const char *server, { const struct json *result = reply->result; if (result->type != JSON_ARRAY - || result->array.n != 1 - || result->array.elems[0]->type != JSON_OBJECT) { + || json_array_size(result) != 1 + || json_array_at(result, 0)->type != JSON_OBJECT) { VLOG_WARN("%s: unexpected reply to _Server request for %s", server, database); return NULL; } - const struct json *op_result = result->array.elems[0]; + const struct json *op_result = json_array_at(result, 0); const struct json *rows = shash_find_data(json_object(op_result), "rows"); if (!rows || rows->type != JSON_ARRAY) { VLOG_WARN("%s: missing \"rows\" member in _Server reply for %s", @@ -678,8 +679,9 @@ parse_database_info_reply(const struct jsonrpc_msg *reply, const char *server, return NULL; } - for (size_t i = 0; i < rows->array.n; i++) { - const struct json *row = rows->array.elems[i]; + size_t n = json_array_size(rows); + for (size_t i = 0; i < n; i++) { + const struct json *row = json_array_at(rows, i); if (row->type != JSON_OBJECT) { VLOG_WARN("%s: bad row in _Server reply for %s", server, database); @@ -868,11 +870,11 @@ do_transact__(int argc, char *argv[], struct json *transaction) { struct jsonrpc_msg *request, *reply; if (transaction->type != JSON_ARRAY - || !transaction->array.n - || transaction->array.elems[0]->type != JSON_STRING) { + || !json_array_size(transaction) + || json_array_at(transaction, 0)->type != JSON_STRING) { ovs_fatal(0, "not a valid OVSDB query"); } - const char *db_name = json_string(transaction->array.elems[0]); + const char *db_name = json_string(json_array_at(transaction, 0)); struct jsonrpc *rpc; char *database = CONST_CAST(char *, db_name); @@ -915,22 +917,21 @@ do_query(struct jsonrpc *rpc OVS_UNUSED, const char *database OVS_UNUSED, struct json *abort_op = json_object_create(); json_object_put_string(abort_op, "op", "abort"); json_array_add(transaction, abort_op); - size_t abort_idx = transaction->array.n - 2; + size_t abort_idx = json_array_size(transaction) - 2; /* Run query. */ struct json *result = do_transact__(argc, argv, transaction); /* If the "abort" operation ended the transaction, remove its result. */ if (result->type == JSON_ARRAY - && result->array.n == abort_idx + 1 - && result->array.elems[abort_idx]->type == JSON_OBJECT) { - struct json *op_result = result->array.elems[abort_idx]; + && json_array_size(result) == abort_idx + 1 + && json_array_at(result, abort_idx)->type == JSON_OBJECT) { + const struct json *op_result = json_array_at(result, abort_idx); struct json *error = shash_find_data(json_object(op_result), "error"); if (error && error->type == JSON_STRING && !strcmp(json_string(error), "aborted")) { - result->array.n--; - json_destroy(op_result); + json_destroy(json_array_pop(result)); } } @@ -946,7 +947,7 @@ struct monitored_table { }; static void -monitor_print_row(struct json *row, const char *type, const char *uuid, +monitor_print_row(const struct json *row, const char *type, const char *uuid, const struct ovsdb_column_set *columns, struct table *t) { size_t i; @@ -1024,7 +1025,7 @@ monitor_print_table(struct json *table_update, } static void -monitor_print(struct json *table_updates, +monitor_print(const struct json *table_updates, const struct monitored_table *mts, size_t n_mts, bool initial) { @@ -1048,7 +1049,7 @@ monitor_print(struct json *table_updates, } static void -monitor2_print_row(struct json *row, const char *type, const char *uuid, +monitor2_print_row(const struct json *row, const char *type, const char *uuid, const struct ovsdb_column_set *columns, struct table *t) { if (!strcmp(type, "delete")) { @@ -1070,8 +1071,8 @@ monitor2_print_row(struct json *row, const char *type, const char *uuid, } static void -monitor2_print_table(struct json *table_update2, - const struct monitored_table *mt, char *caption) +monitor2_print_table(const struct json *table_update2, + const struct monitored_table *mt, char *caption) { const struct ovsdb_table_schema *table = mt->table; const struct ovsdb_column_set *columns = &mt->columns; @@ -1119,7 +1120,7 @@ monitor2_print_table(struct json *table_update2, } static void -monitor2_print(struct json *table_updates2, +monitor2_print(const struct json *table_updates2, const struct monitored_table *mts, size_t n_mts) { size_t i; @@ -1142,28 +1143,28 @@ monitor2_print(struct json *table_updates2, } static void -monitor3_print(struct json *result, +monitor3_print(const struct json *result, const struct monitored_table *mts, size_t n_mts) { if (result->type != JSON_ARRAY) { ovs_error(0, " is not array"); } - if (result->array.n != 3) { + if (json_array_size(result) != 3) { ovs_error(0, " should have 3 elements, but has %"PRIuSIZE".", - result->array.n); + json_array_size(result)); } - bool found = json_boolean(result->array.elems[0]); - const char *last_id = json_string(result->array.elems[1]); + bool found = json_boolean(json_array_at(result, 0)); + const char *last_id = json_string(json_array_at(result, 1)); printf("found: %s, last_id: %s\n", found ? "true" : "false", last_id); - struct json *table_updates2 = result->array.elems[2]; + const struct json *table_updates2 = json_array_at(result, 2); monitor2_print(table_updates2, mts, n_mts); } static void -monitor3_notify_print(const char *last_id, struct json *table_updates2, +monitor3_notify_print(const char *last_id, const struct json *table_updates2, const struct monitored_table *mts, size_t n_mts) { printf("\nlast_id: %s", last_id); @@ -1220,7 +1221,7 @@ parse_monitor_columns(char *arg, const char *server, const char *database, } } - if (columns_json->array.n == 0) { + if (json_array_size(columns_json) == 0) { const struct shash_node **nodes; size_t i, n; @@ -1521,9 +1522,9 @@ do_monitor__(struct jsonrpc *rpc, const char *database, && !strcmp(msg->method, "update")) { struct json *params = msg->params; if (params->type == JSON_ARRAY - && params->array.n == 2 - && params->array.elems[0]->type == JSON_NULL) { - monitor_print(params->array.elems[1], mts, n_mts, false); + && json_array_size(params) == 2 + && json_array_at(params, 0)->type == JSON_NULL) { + monitor_print(json_array_at(params, 1), mts, n_mts, false); fflush(stdout); } } else if (msg->type == JSONRPC_NOTIFY @@ -1531,9 +1532,9 @@ do_monitor__(struct jsonrpc *rpc, const char *database, && !strcmp(msg->method, "update2")) { struct json *params = msg->params; if (params->type == JSON_ARRAY - && params->array.n == 2 - && params->array.elems[0]->type == JSON_NULL) { - monitor2_print(params->array.elems[1], mts, n_mts); + && json_array_size(params) == 2 + && json_array_at(params, 0)->type == JSON_NULL) { + monitor2_print(json_array_at(params, 1), mts, n_mts); fflush(stdout); } } else if (msg->type == JSONRPC_NOTIFY @@ -1541,10 +1542,11 @@ do_monitor__(struct jsonrpc *rpc, const char *database, && !strcmp(msg->method, "update3")) { struct json *params = msg->params; if (params->type == JSON_ARRAY - && params->array.n == 3 - && params->array.elems[0]->type == JSON_NULL) { - monitor3_notify_print(json_string(params->array.elems[1]), - params->array.elems[2], mts, n_mts); + && json_array_size(params) == 3 + && json_array_at(params, 0)->type == JSON_NULL) { + monitor3_notify_print( + json_string(json_array_at(params, 1)), + json_array_at(params, 2), mts, n_mts); fflush(stdout); } } else if (msg->type == JSONRPC_NOTIFY @@ -1760,7 +1762,7 @@ compare_columns(const void *a_, const void *b_) static void dump_table(const char *table_name, const struct shash *cols, - struct json_array *rows) + const struct json *rows) { const struct ovsdb_column **columns; size_t n_columns; @@ -1770,7 +1772,7 @@ dump_table(const char *table_name, const struct shash *cols, struct dump_table_aux aux; struct shash_node *node; struct table t; - size_t x, y; + size_t x, y, n; /* Sort columns by name, for reproducibility. */ columns = xmalloc(shash_count(cols) * sizeof *columns); @@ -1784,15 +1786,17 @@ dump_table(const char *table_name, const struct shash *cols, qsort(columns, n_columns, sizeof *columns, compare_columns); /* Extract data from table. */ - data = xmalloc(rows->n * sizeof *data); - for (y = 0; y < rows->n; y++) { + n = json_array_size(rows); + data = xmalloc(n * sizeof *data); + for (y = 0; y < n; y++) { + const struct json *elem = json_array_at(rows, y); struct shash *row; - if (rows->elems[y]->type != JSON_OBJECT) { + if (elem->type != JSON_OBJECT) { ovs_fatal(0, "row %"PRIuSIZE" in table %s response is not a JSON object: " - "%s", y, table_name, json_to_string(rows->elems[y], 0)); + "%s", y, table_name, json_to_string(elem, 0)); } - row = json_object(rows->elems[y]); + row = json_object(elem); data[y] = xmalloc(n_columns * sizeof **data); for (x = 0; x < n_columns; x++) { @@ -1811,7 +1815,7 @@ dump_table(const char *table_name, const struct shash *cols, aux.data = data; aux.columns = columns; aux.n_columns = n_columns; - sort(rows->n, compare_rows, swap_rows, &aux); + sort(n, compare_rows, swap_rows, &aux); /* Add column headings. */ table_init(&t); @@ -1821,7 +1825,7 @@ dump_table(const char *table_name, const struct shash *cols, } /* Print rows. */ - for (y = 0; y < rows->n; y++) { + for (y = 0; y < n; y++) { table_add_row(&t); for (x = 0; x < n_columns; x++) { struct cell *cell = table_add_cell(&t); @@ -1912,13 +1916,13 @@ do_dump(struct jsonrpc *rpc, const char *database, /* Print database contents. */ if (reply->result->type != JSON_ARRAY - || reply->result->array.n != n_tables) { + || json_array_size(reply->result) != n_tables) { ovs_fatal(0, "reply is not array of %"PRIuSIZE" elements: %s", n_tables, json_to_string(reply->result, 0)); } for (i = 0; i < n_tables; i++) { const struct ovsdb_table_schema *ts = tables[i]->data; - const struct json *op_result = reply->result->array.elems[i]; + const struct json *op_result = json_array_at(reply->result, i); struct json *rows; if (op_result->type != JSON_OBJECT @@ -1930,9 +1934,9 @@ do_dump(struct jsonrpc *rpc, const char *database, } if (argc > 1) { - dump_table(tables[i]->name, &custom_columns, &rows->array); + dump_table(tables[i]->name, &custom_columns, rows); } else { - dump_table(tables[i]->name, &ts->columns, &rows->array); + dump_table(tables[i]->name, &ts->columns, rows); } } @@ -2026,7 +2030,7 @@ do_backup(struct jsonrpc *rpc, const char *database, /* Print database transaction record. */ if (reply->result->type != JSON_ARRAY - || reply->result->array.n != shash_count(&schema->tables)) { + || json_array_size(reply->result) != shash_count(&schema->tables)) { ovs_fatal(0, "reply is not array of %"PRIuSIZE" elements: %s", shash_count(&schema->tables), json_to_string(reply->result, 0)); @@ -2037,7 +2041,7 @@ do_backup(struct jsonrpc *rpc, const char *database, SHASH_FOR_EACH (node, &schema->tables) { const char *table_name = node->name; const struct ovsdb_table_schema *table = node->data; - const struct json *op_result = reply->result->array.elems[i++]; + const struct json *op_result = json_array_at(reply->result, i++); struct json *rows; if (op_result->type != JSON_OBJECT @@ -2048,13 +2052,14 @@ do_backup(struct jsonrpc *rpc, const char *database, table->name, json_to_string(op_result, 0)); } - if (!rows->array.n) { + size_t n = json_array_size(rows); + if (!n) { continue; } struct json *output_rows = json_object_create(); - for (size_t j = 0; j < rows->array.n; j++) { - struct json *row = rows->array.elems[j]; + for (size_t j = 0; j < n; j++) { + const struct json *row = json_array_at(rows, j); if (row->type != JSON_OBJECT) { ovs_fatal(0, "%s table reply row is not an object: %s", table_name, json_to_string(row, 0)); @@ -2093,8 +2098,8 @@ check_transaction_reply(struct jsonrpc_msg *reply) if (reply->result->type != JSON_ARRAY) { ovs_fatal(0, "result is not array"); } - for (size_t i = 0; i < json_array(reply->result)->n; i++) { - struct json *json = json_array(reply->result)->elems[i]; + for (size_t i = 0; i < json_array_size(reply->result); i++) { + const struct json *json = json_array_at(reply->result, i); if (json->type != JSON_OBJECT) { ovs_fatal(0, "result array element is not object"); } diff --git a/ovsdb/ovsdb-server.c b/ovsdb/ovsdb-server.c index fbc7ad5efe3..8d9249aad58 100644 --- a/ovsdb/ovsdb-server.c +++ b/ovsdb/ovsdb-server.c @@ -3033,16 +3033,18 @@ db_config_from_json(const char *name, const struct json *json) sync_exclude = ovsdb_parser_member(&parser, "exclude-tables", OP_ARRAY | OP_OPTIONAL); if (sync_exclude) { - const struct json_array *exclude = json_array(sync_exclude); struct sset set = SSET_INITIALIZER(&set); + size_t n = json_array_size(sync_exclude); - for (size_t i = 0; i < exclude->n; i++) { - if (exclude->elems[i]->type != JSON_STRING) { + for (size_t i = 0; i < n; i++) { + const struct json *exclude = json_array_at(sync_exclude, i); + + if (exclude->type != JSON_STRING) { ovsdb_parser_raise_error(&parser, "'exclude-tables' must contain strings"); break; } - sset_add(&set, json_string(exclude->elems[i])); + sset_add(&set, json_string(exclude)); } conf->ab.sync_exclude = sset_join(&set, ",", ""); sset_destroy(&set); diff --git a/ovsdb/ovsdb-tool.c b/ovsdb/ovsdb-tool.c index 566dc86355d..368e7a5276e 100644 --- a/ovsdb/ovsdb-tool.c +++ b/ovsdb/ovsdb-tool.c @@ -874,12 +874,12 @@ print_data(const char *prefix, const struct json *data, return; } - if (json_array(data)->n != 2) { + if (json_array_size(data) != 2) { printf(" ***invalid data***\n"); return; } - const struct json *schema_json = json_array(data)->elems[0]; + const struct json *schema_json = json_array_at(data, 0); if (schema_json->type != JSON_NULL) { struct ovsdb_schema *schema; @@ -891,7 +891,7 @@ print_data(const char *prefix, const struct json *data, *schemap = schema; } - print_change_record(json_array(data)->elems[1], *schemap, names); + print_change_record(json_array_at(data, 1), *schemap, names); } static void @@ -977,12 +977,11 @@ raft_header_to_standalone_log(const struct raft_header *h, if (h->snap_index) { const struct json *data = raft_entry_get_parsed_data(&h->snap); - if (!data || json_array(data)->n != 2) { + if (!data || json_array_size(data) != 2) { ovs_fatal(0, "Incorrect raft header data array length"); } - struct json_array *pa = json_array(data); - struct json *schema_json = pa->elems[0]; + const struct json *schema_json = json_array_at(data, 0); struct ovsdb_error *error = NULL; if (schema_json->type != JSON_NULL) { @@ -993,7 +992,8 @@ raft_header_to_standalone_log(const struct raft_header *h, } if (!error) { - struct json *data_json = pa->elems[1]; + const struct json *data_json = json_array_at(data, 1); + if (!data_json || data_json->type != JSON_OBJECT) { ovs_fatal(0, "Invalid raft header data"); } @@ -1014,14 +1014,15 @@ raft_record_to_standalone_log(const char *db_file_name, if (!r->entry.data) { return; } - struct json_array *pa = json_array(r->entry.data); + const struct json *pa = r->entry.data; - if (pa->n != 2) { + if (json_array_size(pa) != 2) { ovs_fatal(0, "Incorrect raft record array length"); } - struct json *schema_json = pa->elems[0]; - struct json *data_json = pa->elems[1]; + const struct json *schema_json = json_array_at(pa, 0); + const struct json *data_json = json_array_at(pa, 1); + struct json *new_data = NULL; if (schema_json->type != JSON_NULL) { /* This is a database conversion record. Reset the log and @@ -1041,12 +1042,10 @@ raft_record_to_standalone_log(const char *db_file_name, check_ovsdb_error(ovsdb_convert(old_db, schema, &new_db)); ovsdb_destroy(old_db); - pa->elems[1] = ovsdb_to_txn_json( + new_data = ovsdb_to_txn_json( new_db, "converted by ovsdb-tool", true); ovsdb_destroy(new_db); - - json_destroy(data_json); - data_json = pa->elems[1]; + data_json = new_data; } ovsdb_schema_destroy(schema); @@ -1056,6 +1055,7 @@ raft_record_to_standalone_log(const char *db_file_name, if (data_json->type != JSON_NULL) { check_ovsdb_error(ovsdb_log_write(db_log_data, data_json)); } + json_destroy(new_data); } } diff --git a/ovsdb/raft-private.c b/ovsdb/raft-private.c index e685c8103bc..c880e32acd0 100644 --- a/ovsdb/raft-private.c +++ b/ovsdb/raft-private.c @@ -91,13 +91,14 @@ raft_addresses_from_json(const struct json *json, struct sset *addresses) { sset_init(addresses); - const struct json_array *array = json_array(json); - if (!array->n) { + size_t n = json_array_size(json); + + if (!n) { return ovsdb_syntax_error(json, NULL, "at least one remote address is required"); } - for (size_t i = 0; i < array->n; i++) { - const struct json *address = array->elems[i]; + for (size_t i = 0; i < n; i++) { + const struct json *address = json_array_at(json, i); struct ovsdb_error *error = raft_address_validate_json(address); if (error) { sset_destroy(addresses); @@ -325,7 +326,7 @@ raft_entry_to_json(const struct raft_entry *e) } struct ovsdb_error * OVS_WARN_UNUSED_RESULT -raft_entry_from_json(struct json *json, struct raft_entry *e) +raft_entry_from_json(const struct json *json, struct raft_entry *e) { memset(e, 0, sizeof *e); diff --git a/ovsdb/raft-private.h b/ovsdb/raft-private.h index 48c6df511f3..8bfe8500802 100644 --- a/ovsdb/raft-private.h +++ b/ovsdb/raft-private.h @@ -130,7 +130,8 @@ struct raft_entry { void raft_entry_clone(struct raft_entry *, const struct raft_entry *); void raft_entry_uninit(struct raft_entry *); struct json *raft_entry_to_json(const struct raft_entry *); -struct ovsdb_error *raft_entry_from_json(struct json *, struct raft_entry *) +struct ovsdb_error *raft_entry_from_json(const struct json *, + struct raft_entry *) OVS_WARN_UNUSED_RESULT; bool raft_entry_equals(const struct raft_entry *, const struct raft_entry *); bool raft_entry_has_data(const struct raft_entry *); diff --git a/ovsdb/raft-rpc.c b/ovsdb/raft-rpc.c index 27c3aad99c4..48bcbe7e8d5 100644 --- a/ovsdb/raft-rpc.c +++ b/ovsdb/raft-rpc.c @@ -153,11 +153,13 @@ raft_append_request_from_jsonrpc(struct ovsdb_parser *p, if (!log) { return; } - const struct json_array *entries = json_array(log); - rq->entries = xmalloc(entries->n * sizeof *rq->entries); + + size_t n = json_array_size(log); + + rq->entries = xmalloc(n * sizeof *rq->entries); rq->n_entries = 0; - for (size_t i = 0; i < entries->n; i++) { - struct ovsdb_error *error = raft_entry_from_json(entries->elems[i], + for (size_t i = 0; i < n; i++) { + struct ovsdb_error *error = raft_entry_from_json(json_array_at(log, i), &rq->entries[i]); if (error) { ovsdb_parser_put_error(p, error); @@ -881,14 +883,14 @@ raft_rpc_from_jsonrpc(struct uuid *cidp, const struct uuid *sid, return ovsdb_error(NULL, "unknown method %s", msg->method); } - if (json_array(msg->params)->n != 1) { + if (json_array_size(msg->params) != 1) { return ovsdb_error(NULL, "%s RPC has %"PRIuSIZE" parameters (expected 1)", - msg->method, json_array(msg->params)->n); + msg->method, json_array_size(msg->params)); } struct ovsdb_parser p; - ovsdb_parser_init(&p, json_array(msg->params)->elems[0], + ovsdb_parser_init(&p, json_array_at(msg->params, 0), "raft %s RPC", msg->method); bool is_hello = rpc->type == RAFT_RPC_HELLO_REQUEST; diff --git a/ovsdb/replication.c b/ovsdb/replication.c index 67eab9c42f5..bb21ff7d398 100644 --- a/ovsdb/replication.c +++ b/ovsdb/replication.c @@ -40,11 +40,11 @@ VLOG_DEFINE_THIS_MODULE(replication); static struct uuid server_uuid; -static struct ovsdb_error *process_notification(struct json *, struct ovsdb *); -static struct ovsdb_error *process_table_update(struct json *table_update, - const char *table_name, - struct ovsdb *database, - struct ovsdb_txn *txn); +static struct ovsdb_error *process_notification(const struct json *, + struct ovsdb *); +static struct ovsdb_error *process_table_update( + const struct json *table_update, const char *table_name, + struct ovsdb *database, struct ovsdb_txn *txn); enum ovsdb_replication_state { RPL_S_INIT, @@ -218,13 +218,14 @@ replication_run_db(struct replication_db *rdb) if (msg->type == JSONRPC_NOTIFY && rdb->state != RPL_S_ERR && !strcmp(msg->method, "update")) { if (msg->params->type == JSON_ARRAY - && msg->params->array.n == 2 - && msg->params->array.elems[0]->type == JSON_STRING) { - const char *db_name = json_string(msg->params->array.elems[0]); + && json_array_size(msg->params) == 2 + && json_array_at(msg->params, 0)->type == JSON_STRING) { + const char *db_name = json_string( + json_array_at(msg->params, 0)); if (!strcmp(db_name, rdb->db->name)) { struct ovsdb_error *error; - error = process_notification(msg->params->array.elems[1], + error = process_notification(json_array_at(msg->params, 1), rdb->db); if (error) { ovsdb_error_assert(error); @@ -592,7 +593,7 @@ add_monitored_table(struct ovsdb_table_schema *table, static struct ovsdb_error * -process_notification(struct json *table_updates, struct ovsdb *db) +process_notification(const struct json *table_updates, struct ovsdb *db) { struct ovsdb_error *error = NULL; struct ovsdb_txn *txn; @@ -625,7 +626,7 @@ process_notification(struct json *table_updates, struct ovsdb *db) } static struct ovsdb_error * -process_table_update(struct json *table_update, const char *table_name, +process_table_update(const struct json *table_update, const char *table_name, struct ovsdb *database, struct ovsdb_txn *txn) { struct ovsdb_table *table = ovsdb_get_table(database, table_name); diff --git a/ovsdb/storage.c b/ovsdb/storage.c index c5aec545944..a736bffb67c 100644 --- a/ovsdb/storage.c +++ b/ovsdb/storage.c @@ -264,21 +264,24 @@ ovsdb_storage_read(struct ovsdb_storage *storage, *txnid = UUID_ZERO; } + const struct json *schema_json = NULL; + const struct json *txn_json = NULL; struct json *json; - struct json *schema_json = NULL; - struct json *txn_json = NULL; + if (storage->raft) { json = raft_next_entry(storage->raft, txnid); if (!json) { return NULL; - } else if (json->type != JSON_ARRAY || json->array.n != 2) { + } else if (json->type != JSON_ARRAY || json_array_size(json) != 2) { json_destroy(json); return ovsdb_error(NULL, "invalid commit format"); } - struct json **e = json->array.elems; - schema_json = e[0]->type != JSON_NULL ? e[0] : NULL; - txn_json = e[1]->type != JSON_NULL ? e[1] : NULL; + const struct json *e0 = json_array_at(json, 0); + const struct json *e1 = json_array_at(json, 1); + + schema_json = e0->type != JSON_NULL ? e0 : NULL; + txn_json = e1->type != JSON_NULL ? e1 : NULL; } else if (storage->log) { struct ovsdb_error *error = ovsdb_log_read(storage->log, &json); if (error || !json) { @@ -286,7 +289,7 @@ ovsdb_storage_read(struct ovsdb_storage *storage, } unsigned int n = storage->n_read++; - struct json **jsonp = !n ? &schema_json : &txn_json; + const struct json **jsonp = !n ? &schema_json : &txn_json; *jsonp = json; if (n == 1) { ovsdb_log_mark_base(storage->log); diff --git a/ovsdb/table.c b/ovsdb/table.c index 3e89ddd44a0..589ee5e8c32 100644 --- a/ovsdb/table.c +++ b/ovsdb/table.c @@ -186,14 +186,14 @@ ovsdb_table_schema_from_json(const struct json *json, const char *name, } if (indexes) { - size_t i; + size_t i, n = json_array_size(indexes); - ts->indexes = xmalloc(indexes->array.n * sizeof *ts->indexes); - for (i = 0; i < indexes->array.n; i++) { + ts->indexes = xmalloc(n * sizeof *ts->indexes); + for (i = 0; i < n; i++) { struct ovsdb_column_set *index = &ts->indexes[i]; size_t j; - error = ovsdb_column_set_from_json(indexes->array.elems[i], + error = ovsdb_column_set_from_json(json_array_at(indexes, i), ts, index); if (error) { goto error; diff --git a/ovsdb/trigger.c b/ovsdb/trigger.c index 8c00fec181f..7e3b9a197fc 100644 --- a/ovsdb/trigger.c +++ b/ovsdb/trigger.c @@ -291,14 +291,14 @@ ovsdb_trigger_try(struct ovsdb_trigger *t, long long int now) /* Validate parameters. */ const struct json *params = t->request->params; - if (params->type != JSON_ARRAY || params->array.n != 2) { + if (params->type != JSON_ARRAY || json_array_size(params) != 2) { trigger_convert_error(t, ovsdb_syntax_error(params, NULL, "array expected")); return false; } /* Parse new schema and make a converted copy. */ - const struct json *new_schema_json = params->array.elems[1]; + const struct json *new_schema_json = json_array_at(params, 1); struct ovsdb_schema *new_schema; struct ovsdb_error *error = ovsdb_schema_from_json(new_schema_json, &new_schema); diff --git a/python/ovs/_json.c b/python/ovs/_json.c index 5f4388f80fe..bd9f5fe1988 100644 --- a/python/ovs/_json.c +++ b/python/ovs/_json.c @@ -111,14 +111,14 @@ json_to_python(struct json *json) return dict; } case JSON_ARRAY:{ - size_t i; - PyObject *arr = PyList_New(json->array.n); + size_t i, n = json_array_size(json); + PyObject *arr = PyList_New(n); if (arr == NULL) { return PyErr_NoMemory(); } - for (i = 0; i < json->array.n; i++) { - PyObject *item = json_to_python(json->array.elems[i]); + for (i = 0; i < n; i++) { + PyObject *item = json_to_python(json_array_at(json, i)); if (!item || PyList_SetItem(arr, i, item)) { Py_XDECREF(arr); diff --git a/tests/test-json.c b/tests/test-json.c index e7992e51061..f5b0ad3713a 100644 --- a/tests/test-json.c +++ b/tests/test-json.c @@ -60,7 +60,7 @@ test_json_equal_object(const struct shash *a, const struct shash *b, } static void -test_json_equal_array(const struct json_array *a, const struct json_array *b, +test_json_equal_array(const struct json *a, const struct json *b, bool allow_the_same) { ovs_assert(allow_the_same || a != b); @@ -69,10 +69,12 @@ test_json_equal_array(const struct json_array *a, const struct json_array *b, return; } - ovs_assert(a->n == b->n); + size_t n = json_array_size(a); + ovs_assert(n == json_array_size(b)); - for (size_t i = 0; i < a->n; i++) { - test_json_equal(a->elems[i], b->elems[i], allow_the_same); + for (size_t i = 0; i < n; i++) { + test_json_equal(json_array_at(a, i), json_array_at(b, i), + allow_the_same); } } @@ -96,7 +98,7 @@ test_json_equal(const struct json *a, const struct json *b, return; case JSON_ARRAY: - test_json_equal_array(&a->array, &b->array, allow_the_same); + test_json_equal_array(a, b, allow_the_same); return; case JSON_STRING: diff --git a/tests/test-ovsdb.c b/tests/test-ovsdb.c index 3409386796b..5b41526937b 100644 --- a/tests/test-ovsdb.c +++ b/tests/test-ovsdb.c @@ -273,9 +273,8 @@ parse_json(const char *s) static struct json * unbox_json(struct json *json) { - if (json->type == JSON_ARRAY && json->array.n == 1) { - struct json *inner = json->array.elems[0]; - json->array.elems[0] = NULL; + if (json->type == JSON_ARRAY && json_array_size(json) == 1) { + struct json *inner = json_array_pop(json); json_destroy(json); return inner; } else { @@ -787,11 +786,11 @@ do_sort_atoms(struct ovs_cmdl_context *ctx) } /* Convert JSON atoms to internal representation. */ - n_atoms = json->array.n; + n_atoms = json_array_size(json); atoms = xmalloc(n_atoms * sizeof *atoms); for (i = 0; i < n_atoms; i++) { check_ovsdb_error(ovsdb_atom_from_json(&atoms[i], &base, - json->array.elems[i], NULL)); + json_array_at(json, i), NULL)); } json_destroy(json); @@ -931,13 +930,13 @@ do_compare_rows(struct ovs_cmdl_context *ctx) rows[i] = ovsdb_row_create(table); json = parse_json(ctx->argv[i + 2]); - if (json->type != JSON_ARRAY || json->array.n != 2 - || json->array.elems[0]->type != JSON_STRING) { + if (json->type != JSON_ARRAY || json_array_size(json) != 2 + || json_array_at(json, 0)->type != JSON_STRING) { ovs_fatal(0, "\"%s\" does not have expected form " "[\"name\", {data}]", ctx->argv[i]); } - names[i] = xstrdup(json_string(json->array.elems[0])); - check_ovsdb_error(ovsdb_row_from_json(rows[i], json->array.elems[1], + names[i] = xstrdup(json_string(json_array_at(json, 0))); + check_ovsdb_error(ovsdb_row_from_json(rows[i], json_array_at(json, 1), NULL, NULL, false)); json_destroy(json); } @@ -1033,10 +1032,10 @@ do_evaluate_condition__(struct ovs_cmdl_context *ctx, int mode) if (json->type != JSON_ARRAY) { ovs_fatal(0, "CONDITION argument is not JSON array"); } - n_conditions = json->array.n; + n_conditions = json_array_size(json); conditions = xmalloc(n_conditions * sizeof *conditions); for (i = 0; i < n_conditions; i++) { - check_ovsdb_error(ovsdb_condition_from_json(ts, json->array.elems[i], + check_ovsdb_error(ovsdb_condition_from_json(ts, json_array_at(json, i), NULL, &conditions[i])); } json_destroy(json); @@ -1046,11 +1045,11 @@ do_evaluate_condition__(struct ovs_cmdl_context *ctx, int mode) if (json->type != JSON_ARRAY) { ovs_fatal(0, "ROW argument is not JSON array"); } - n_rows = json->array.n; + n_rows = json_array_size(json); rows = xmalloc(n_rows * sizeof *rows); for (i = 0; i < n_rows; i++) { rows[i] = ovsdb_row_create(table); - check_ovsdb_error(ovsdb_row_from_json(rows[i], json->array.elems[i], + check_ovsdb_error(ovsdb_row_from_json(rows[i], json_array_at(json, i), NULL, NULL, false)); } json_destroy(json); @@ -1122,11 +1121,11 @@ do_compare_conditions(struct ovs_cmdl_context *ctx) if (json->type != JSON_ARRAY) { ovs_fatal(0, "CONDITION argument is not JSON array"); } - n_conditions = json->array.n; + n_conditions = json_array_size(json); conditions = xmalloc(n_conditions * sizeof *conditions); for (i = 0; i < n_conditions; i++) { - check_ovsdb_error(ovsdb_condition_from_json(ts, json->array.elems[i], + check_ovsdb_error(ovsdb_condition_from_json(ts, json_array_at(json, i), NULL, &conditions[i])); } json_destroy(json); @@ -1206,11 +1205,11 @@ do_execute_mutations(struct ovs_cmdl_context *ctx) if (json->type != JSON_ARRAY) { ovs_fatal(0, "MUTATION argument is not JSON array"); } - n_sets = json->array.n; + n_sets = json_array_size(json); sets = xmalloc(n_sets * sizeof *sets); for (i = 0; i < n_sets; i++) { check_ovsdb_error(ovsdb_mutation_set_from_json(ts, - json->array.elems[i], + json_array_at(json, i), NULL, &sets[i])); } json_destroy(json); @@ -1220,11 +1219,11 @@ do_execute_mutations(struct ovs_cmdl_context *ctx) if (json->type != JSON_ARRAY) { ovs_fatal(0, "ROW argument is not JSON array"); } - n_rows = json->array.n; + n_rows = json_array_size(json); rows = xmalloc(n_rows * sizeof *rows); for (i = 0; i < n_rows; i++) { rows[i] = ovsdb_row_create(table); - check_ovsdb_error(ovsdb_row_from_json(rows[i], json->array.elems[i], + check_ovsdb_error(ovsdb_row_from_json(rows[i], json_array_at(json, i), NULL, NULL, false)); } json_destroy(json); @@ -1332,13 +1331,13 @@ do_query(struct ovs_cmdl_context *ctx) if (json->type != JSON_ARRAY) { ovs_fatal(0, "ROW argument is not JSON array"); } - cbdata.n_rows = json->array.n; + cbdata.n_rows = json_array_size(json); cbdata.row_uuids = xmalloc(cbdata.n_rows * sizeof *cbdata.row_uuids); cbdata.counts = xmalloc(cbdata.n_rows * sizeof *cbdata.counts); for (i = 0; i < cbdata.n_rows; i++) { struct ovsdb_row *row = ovsdb_row_create(table); uuid_generate(ovsdb_row_get_uuid_rw(row)); - check_ovsdb_error(ovsdb_row_from_json(row, json->array.elems[i], + check_ovsdb_error(ovsdb_row_from_json(row, json_array_at(json, i), NULL, NULL, false)); if (ovsdb_table_get_row(table, ovsdb_row_get_uuid(row))) { ovs_fatal(0, "duplicate UUID "UUID_FMT" in table", @@ -1354,11 +1353,11 @@ do_query(struct ovs_cmdl_context *ctx) if (json->type != JSON_ARRAY) { ovs_fatal(0, "CONDITION argument is not JSON array"); } - for (i = 0; i < json->array.n; i++) { + for (i = 0; i < json_array_size(json); i++) { struct ovsdb_condition cnd; size_t j; - check_ovsdb_error(ovsdb_condition_from_json(ts, json->array.elems[i], + check_ovsdb_error(ovsdb_condition_from_json(ts, json_array_at(json, i), NULL, &cnd)); memset(cbdata.counts, 0, cbdata.n_rows * sizeof *cbdata.counts); @@ -1434,7 +1433,7 @@ do_query_distinct(struct ovs_cmdl_context *ctx) if (json->type != JSON_ARRAY) { ovs_fatal(0, "ROW argument is not JSON array"); } - n_rows = json->array.n; + n_rows = json_array_size(json); rows = xmalloc(n_rows * sizeof *rows); classes = xmalloc(n_rows * sizeof *classes); n_classes = 0; @@ -1445,7 +1444,7 @@ do_query_distinct(struct ovs_cmdl_context *ctx) /* Parse row. */ row = ovsdb_row_create(table); uuid_generate(ovsdb_row_get_uuid_rw(row)); - check_ovsdb_error(ovsdb_row_from_json(row, json->array.elems[i], + check_ovsdb_error(ovsdb_row_from_json(row, json_array_at(json, i), NULL, NULL, false)); /* Initialize row and find equivalence class. */ @@ -1478,12 +1477,12 @@ do_query_distinct(struct ovs_cmdl_context *ctx) if (json->type != JSON_ARRAY) { ovs_fatal(0, "CONDITION argument is not JSON array"); } - for (i = 0; i < json->array.n; i++) { + for (i = 0; i < json_array_size(json); i++) { struct ovsdb_row_set results; struct ovsdb_condition cnd; size_t j; - check_ovsdb_error(ovsdb_condition_from_json(ts, json->array.elems[i], + check_ovsdb_error(ovsdb_condition_from_json(ts, json_array_at(json, i), NULL, &cnd)); for (j = 0; j < n_classes; j++) { @@ -1645,11 +1644,11 @@ do_trigger(struct ovs_cmdl_context *ctx) for (i = 2; i < ctx->argc; i++) { struct json *params = parse_json(ctx->argv[i]); if (params->type == JSON_ARRAY - && json_array(params)->n == 2 - && json_array(params)->elems[0]->type == JSON_STRING - && !strcmp(json_string(json_array(params)->elems[0]), "advance") - && json_array(params)->elems[1]->type == JSON_INTEGER) { - now += json_integer(json_array(params)->elems[1]); + && json_array_size(params) == 2 + && json_array_at(params, 0)->type == JSON_STRING + && !strcmp(json_string(json_array_at(params, 0)), "advance") + && json_array_at(params, 1)->type == JSON_INTEGER) { + now += json_integer(json_array_at(params, 1)); json_destroy(params); } else { struct test_trigger *t = xmalloc(sizeof *t); @@ -1884,10 +1883,10 @@ do_transact(struct ovs_cmdl_context *ctx) "with at least 1 element", i); } - n_args = command->array.n; + n_args = json_array_size(command); args = xmalloc((n_args + 1) * sizeof *args); for (j = 0; j < n_args; j++) { - struct json *s = command->array.elems[j]; + const struct json *s = json_array_at(command, j); if (s->type != JSON_STRING) { ovs_fatal(0, "transaction %d argument %d must be JSON string", i, j); @@ -2394,8 +2393,8 @@ parse_uuids(const struct json *json, struct ovsdb_symbol_table *symtab, } else if (json->type == JSON_ARRAY) { size_t i; - for (i = 0; i < json->array.n; i++) { - parse_uuids(json->array.elems[i], symtab, n); + for (i = 0; i < json_array_size(json); i++) { + parse_uuids(json_array_at(json, i), symtab, n); } } else if (json->type == JSON_OBJECT) { const struct shash_node *node; @@ -2421,10 +2420,11 @@ substitute_uuids(struct json *json, const struct ovsdb_symbol_table *symtab) json->str_ptr = xasprintf(UUID_FMT, UUID_ARGS(&symbol->uuid)); } } else if (json->type == JSON_ARRAY) { - size_t i; + size_t i, n = json_array_size(json); - for (i = 0; i < json->array.n; i++) { - substitute_uuids(json->array.elems[i], symtab); + for (i = 0; i < n; i++) { + substitute_uuids(CONST_CAST(struct json *, json_array_at(json, i)), + symtab); } } else if (json->type == JSON_OBJECT) { const struct shash_node *node; @@ -2699,25 +2699,26 @@ update_conditions(struct ovsdb_idl *idl, char *commands, int step) } struct ovsdb_idl_condition cond = OVSDB_IDL_CONDITION_INIT(&cond); - for (i = 0; i < json->array.n; i++) { - const struct json *clause = json->array.elems[i]; + for (i = 0; i < json_array_size(json); i++) { + const struct json *clause = json_array_at(json, i); if (clause->type == JSON_TRUE) { ovsdb_idl_condition_add_clause_true(&cond); - } else if (clause->type != JSON_ARRAY || clause->array.n != 3 - || clause->array.elems[0]->type != JSON_STRING - || clause->array.elems[1]->type != JSON_STRING) { + } else if (clause->type != JSON_ARRAY + || json_array_size(clause) != 3 + || json_array_at(clause, 0)->type != JSON_STRING + || json_array_at(clause, 1)->type != JSON_STRING) { ovs_fatal(0, "Error parsing condition"); } else { enum ovsdb_function function; - const char *function_s = json_string(clause->array.elems[1]); + const char *function_s = json_string(json_array_at(clause, 1)); struct ovsdb_error *error = ovsdb_function_from_string( function_s, &function); if (error) { ovs_fatal(0, "unknown clause function %s", function_s); } - const char *column = json_string(clause->array.elems[0]); - const struct json *arg = clause->array.elems[2]; + const char *column = json_string(json_array_at(clause, 0)); + const struct json *arg = json_array_at(clause, 2); if (!strcmp(table_name, "simple")) { parse_simple_json_clause(&cond, function, column, arg); } else if (!strcmp(table_name, "link1")) {