vcpe/srcs/libs/json/json_schema/subschemalogic.c

117 lines
3.6 KiB
C

#include "jsoncdaccord.h"
#include "internal.h"
#include "optional.h"
enum subschematype {
JDAC_ALLOF = 0,
JDAC_ANYOF,
JDAC_ONEOF
};
// shall return valid or invalid based on subschema type
int _jdac_test_subschema_array(json_object *jobj, json_object *jsubschema_array, enum subschematype type) {
if (jsubschema_array == NULL) {
return JDAC_ERR_VALID;
}
// MUST be a non-empty array
if (!json_object_is_type(jsubschema_array, json_type_array)) {
return JDAC_ERR_SCHEMA_ERROR;
}
int arraylen = (int)json_object_array_length(jsubschema_array);
if (arraylen == 0) {
return JDAC_ERR_SCHEMA_ERROR;
}
int number_of_valid_schemas = 0;
for (int i = 0; i < arraylen; i++) {
json_object *jsubschema = json_object_array_get_idx(jsubschema_array, i);
if (!json_object_is_type(jsubschema, json_type_object) && !json_object_is_type(jsubschema, json_type_boolean)) {
return JDAC_ERR_SCHEMA_ERROR;
}
int err = _jdac_validate_instance(jobj, jsubschema);
if (err == JDAC_ERR_VALID) {
number_of_valid_schemas++;
} else if (err == JDAC_ERR_SCHEMA_ERROR) {
return JDAC_ERR_SCHEMA_ERROR;
} else {
// continue
}
}
if (type == JDAC_ALLOF) {
if (number_of_valid_schemas == arraylen) {
return JDAC_ERR_VALID;
}
} else if (type == JDAC_ANYOF) {
if (number_of_valid_schemas > 0) {
return JDAC_ERR_VALID;
}
} else if (type == JDAC_ONEOF) {
if (number_of_valid_schemas == 1) {
return JDAC_ERR_VALID;
}
}
return JDAC_ERR_INVALID_SUBSCHEMALOGIC;
}
int _jdac_check_subschemalogic(json_object *jobj, json_object *jschema) {
int err;
json_object *jarray;
jarray = json_object_object_get(jschema, "allOf");
err = _jdac_test_subschema_array(jobj, jarray, JDAC_ALLOF);
if (err) {
return JDAC_ERR_INVALID_SUBSCHEMALOGIC;
}
jarray = json_object_object_get(jschema, "anyOf");
err = _jdac_test_subschema_array(jobj, jarray, JDAC_ANYOF);
if (err) {
return JDAC_ERR_INVALID_SUBSCHEMALOGIC;
}
jarray = json_object_object_get(jschema, "oneOf");
err = _jdac_test_subschema_array(jobj, jarray, JDAC_ONEOF);
if (err) {
return JDAC_ERR_INVALID_SUBSCHEMALOGIC;
}
json_object *jnot = json_object_object_get(jschema, "not");
if (jnot) {
// "not" is special, and MUST be a json object
if (json_object_is_type(jnot, json_type_object) || json_object_is_type(jnot, json_type_boolean)) {
err = _jdac_validate_instance(jobj, jnot);
if (err == JDAC_ERR_VALID) {
return JDAC_ERR_INVALID_SUBSCHEMALOGIC;
} else if (err == JDAC_ERR_SCHEMA_ERROR) {
return JDAC_ERR_SCHEMA_ERROR;
} else {
return JDAC_ERR_VALID;
}
} else {
return JDAC_ERR_SCHEMA_ERROR;
}
}
json_object *if_schema = json_object_object_get(jschema, "if");
json_object *then_schema = json_object_object_get(jschema, "then");
json_object *else_schema = json_object_object_get(jschema, "else");
if (if_schema) {
err = _jdac_validate_instance(jobj, if_schema);
if (err == JDAC_ERR_VALID && then_schema) {
err = _jdac_validate_instance(jobj, then_schema);
return err;
} else if (err != JDAC_ERR_VALID && else_schema) {
err = _jdac_validate_instance(jobj, else_schema);
return err;
}
}
return JDAC_ERR_VALID;
}