140 lines
3.8 KiB
C
140 lines
3.8 KiB
C
#include <errno.h>
|
|
#include "adb.h"
|
|
#include "apk_print.h"
|
|
|
|
static int adb_walk_genadb_schema(struct adb_walk *d, uint32_t schema_id)
|
|
{
|
|
struct adb_walk_genadb *dt = container_of(d, struct adb_walk_genadb, d);
|
|
const struct adb_db_schema *s;
|
|
|
|
dt->db.schema = schema_id;
|
|
for (s = d->schemas; s->magic; s++)
|
|
if (s->magic == schema_id) break;
|
|
if (!s) return -APKE_ADB_SCHEMA;
|
|
|
|
adb_wo_init(&dt->objs[0], &dt->vals[0], s->root, &dt->db);
|
|
dt->num_vals += s->root->num_fields;
|
|
if (dt->num_vals >= ARRAY_SIZE(dt->vals)) return -APKE_ADB_LIMIT;
|
|
dt->nest = 0;
|
|
|
|
return 0;
|
|
}
|
|
|
|
static int adb_walk_genadb_comment(struct adb_walk *d, apk_blob_t comment)
|
|
{
|
|
return 0;
|
|
}
|
|
|
|
static int adb_walk_genadb_start_object(struct adb_walk *d)
|
|
{
|
|
struct adb_walk_genadb *dt = container_of(d, struct adb_walk_genadb, d);
|
|
|
|
if (!dt->db.schema) return -APKE_ADB_SCHEMA;
|
|
if (dt->nest >= ARRAY_SIZE(dt->objs)) return -APKE_ADB_LIMIT;
|
|
|
|
if (dt->curkey[dt->nest] == 0 &&
|
|
dt->objs[dt->nest].schema->kind == ADB_KIND_OBJECT)
|
|
return -APKE_ADB_SCHEMA;
|
|
|
|
dt->nest++;
|
|
adb_wo_init_val(
|
|
&dt->objs[dt->nest], &dt->vals[dt->num_vals],
|
|
&dt->objs[dt->nest-1], dt->curkey[dt->nest-1]);
|
|
|
|
if (*adb_ro_kind(&dt->objs[dt->nest-1], dt->curkey[dt->nest-1]) == ADB_KIND_ADB) {
|
|
struct adb_adb_schema *schema = container_of(&dt->objs[dt->nest-1].schema->kind, struct adb_adb_schema, kind);
|
|
if (dt->nestdb >= ARRAY_SIZE(dt->idb)) return -APKE_ADB_LIMIT;
|
|
adb_reset(&dt->idb[dt->nestdb]);
|
|
dt->idb[dt->nestdb].schema = schema->schema_id;
|
|
dt->objs[dt->nest].db = &dt->idb[dt->nestdb];
|
|
dt->nestdb++;
|
|
}
|
|
|
|
dt->num_vals += dt->objs[dt->nest].schema->num_fields;
|
|
if (dt->num_vals >= ARRAY_SIZE(dt->vals)) return -APKE_ADB_LIMIT;
|
|
|
|
return 0;
|
|
}
|
|
|
|
static int adb_walk_genadb_start_array(struct adb_walk *d, unsigned int num)
|
|
{
|
|
return adb_walk_genadb_start_object(d);
|
|
}
|
|
|
|
static int adb_walk_genadb_end(struct adb_walk *d)
|
|
{
|
|
struct adb_walk_genadb *dt = container_of(d, struct adb_walk_genadb, d);
|
|
adb_val_t val;
|
|
|
|
val = adb_w_obj(&dt->objs[dt->nest]);
|
|
if (ADB_IS_ERROR(val))
|
|
return -ADB_VAL_VALUE(val);
|
|
|
|
dt->curkey[dt->nest] = 0;
|
|
dt->num_vals -= dt->objs[dt->nest].schema->num_fields;
|
|
|
|
if (dt->nest == 0) {
|
|
dt->stored_object = val;
|
|
return 0;
|
|
}
|
|
|
|
dt->nest--;
|
|
|
|
if (*adb_ro_kind(&dt->objs[dt->nest], dt->curkey[dt->nest]) == ADB_KIND_ADB) {
|
|
dt->nestdb--;
|
|
adb_w_root(&dt->idb[dt->nestdb], val);
|
|
val = adb_w_adb(&dt->db, &dt->idb[dt->nestdb]);
|
|
}
|
|
|
|
if (dt->curkey[dt->nest] == 0) {
|
|
adb_wa_append(&dt->objs[dt->nest], val);
|
|
} else {
|
|
adb_wo_val(&dt->objs[dt->nest], dt->curkey[dt->nest], val);
|
|
dt->curkey[dt->nest] = 0;
|
|
}
|
|
|
|
return 0;
|
|
}
|
|
|
|
static int adb_walk_genadb_key(struct adb_walk *d, apk_blob_t key)
|
|
{
|
|
struct adb_walk_genadb *dt = container_of(d, struct adb_walk_genadb, d);
|
|
uint8_t kind = dt->objs[dt->nest].schema->kind;
|
|
|
|
if (kind != ADB_KIND_OBJECT && kind != ADB_KIND_ADB)
|
|
return -APKE_ADB_SCHEMA;
|
|
|
|
dt->curkey[dt->nest] = adb_s_field_by_name_blob(dt->objs[dt->nest].schema, key);
|
|
if (dt->curkey[dt->nest] == 0)
|
|
return -APKE_ADB_SCHEMA;
|
|
|
|
return 0;
|
|
}
|
|
|
|
static int adb_walk_genadb_scalar(struct adb_walk *d, apk_blob_t scalar, int multiline)
|
|
{
|
|
struct adb_walk_genadb *dt = container_of(d, struct adb_walk_genadb, d);
|
|
|
|
if (dt->objs[dt->nest].schema->kind == ADB_KIND_ARRAY) {
|
|
adb_wa_append_fromstring(&dt->objs[dt->nest], scalar);
|
|
} else {
|
|
if (dt->curkey[dt->nest] == 0)
|
|
adb_wo_fromstring(&dt->objs[dt->nest], scalar);
|
|
else
|
|
adb_wo_val_fromstring(&dt->objs[dt->nest], dt->curkey[dt->nest], scalar);
|
|
}
|
|
dt->curkey[dt->nest] = 0;
|
|
|
|
return 0;
|
|
}
|
|
|
|
const struct adb_walk_ops adb_walk_genadb_ops = {
|
|
.schema = adb_walk_genadb_schema,
|
|
.comment = adb_walk_genadb_comment,
|
|
.start_array = adb_walk_genadb_start_array,
|
|
.start_object = adb_walk_genadb_start_object,
|
|
.end = adb_walk_genadb_end,
|
|
.key = adb_walk_genadb_key,
|
|
.scalar = adb_walk_genadb_scalar,
|
|
};
|