@@ -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). */
@@ -99,6 +99,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 *);
@@ -119,7 +121,8 @@ void json_object_put_uuid(struct json *, const char *name,
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 *);
@@ -226,30 +226,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);
}
}
@@ -257,46 +271,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;
@@ -381,11 +395,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 *
@@ -417,7 +438,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
@@ -429,7 +450,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:
@@ -479,26 +500,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 *
@@ -509,7 +531,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));
@@ -555,16 +577,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
@@ -585,13 +624,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;
}
@@ -604,7 +643,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);
@@ -649,16 +688,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;
}
}
@@ -682,7 +721,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));
@@ -1605,7 +1644,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 *);
@@ -1668,7 +1707,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:
@@ -1760,10 +1799,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++;
@@ -1772,15 +1811,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);
}
}
@@ -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);
@@ -1585,21 +1587,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;
@@ -1626,7 +1628,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);
@@ -1634,12 +1636,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);
@@ -1648,7 +1650,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;
}
@@ -1661,8 +1664,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;
}
@@ -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;
}
@@ -1276,9 +1276,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;
@@ -1290,7 +1290,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 "
@@ -1309,7 +1309,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;
@@ -2862,11 +2862,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);
@@ -2882,9 +2882,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;
@@ -3318,7 +3320,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));
@@ -3388,7 +3390,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");
@@ -3903,21 +3905,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;
@@ -3929,18 +3931,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;
}
@@ -3955,7 +3957,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;
@@ -3963,16 +3965,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;
@@ -4019,14 +4021,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
@@ -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);
@@ -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 "
@@ -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);
@@ -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);
@@ -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 <db-name>", 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 <id>",
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) {
@@ -1183,11 +1184,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);
@@ -1431,23 +1432,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 "
@@ -1493,20 +1496,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");
@@ -1532,7 +1535,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) {
@@ -1546,13 +1549,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;
}
@@ -1583,7 +1587,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");
@@ -1661,24 +1666,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,
@@ -1686,7 +1691,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,
@@ -1697,7 +1702,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) {
@@ -1714,11 +1719,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;
}
@@ -1769,16 +1773,16 @@ error:
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);
@@ -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);
@@ -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, "<result> is not array");
}
- if (result->array.n != 3) {
+ if (json_array_size(result) != 3) {
ovs_error(0, "<result> 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;
@@ -1520,9 +1521,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
@@ -1530,9 +1531,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
@@ -1540,10 +1541,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
@@ -1759,7 +1761,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;
@@ -1769,7 +1771,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);
@@ -1783,15 +1785,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++) {
@@ -1810,7 +1814,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);
@@ -1820,7 +1824,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);
@@ -1911,13 +1915,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
@@ -1929,9 +1933,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);
}
}
@@ -2025,7 +2029,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));
@@ -2036,7 +2040,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
@@ -2047,13 +2051,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));
@@ -2092,8 +2097,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");
}
@@ -3032,16 +3032,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);
@@ -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);
}
}
@@ -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);
@@ -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 *);
@@ -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);
@@ -878,14 +880,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;
@@ -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);
@@ -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);
@@ -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;
@@ -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);
@@ -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);
@@ -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:
@@ -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 {
@@ -788,11 +787,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);
@@ -932,13 +931,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);
}
@@ -1034,10 +1033,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);
@@ -1047,11 +1046,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);
@@ -1123,11 +1122,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);
@@ -1207,11 +1206,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);
@@ -1221,11 +1220,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);
@@ -1333,13 +1332,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",
@@ -1355,11 +1354,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);
@@ -1435,7 +1434,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;
@@ -1446,7 +1445,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. */
@@ -1479,12 +1478,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++) {
@@ -1646,11 +1645,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);
@@ -1885,10 +1884,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);
@@ -2395,8 +2394,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;
@@ -2422,10 +2421,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;
@@ -2728,25 +2728,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")) {
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 <i.maximets@ovn.org> --- 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(-)