2 #include <lunaix/mm/valloc.h>
4 #define key_mkwr(key) \
5 (struct dtspec_key*)(key)
6 #define call_op(dtn, ops, name) \
7 ((ops)->name ? (ops)->name(dtn) : NULL)
10 dtspec_create(struct dtn* node, struct dtp_val* map,
11 const struct dtspec_create_ops* ops)
14 struct dtspec_map* spec;
15 struct dtspec_mapent* ent;
16 struct dtp_val val = {}, *field;
19 assert(ops->child_keysz);
20 assert(ops->parent_keysz);
22 keysz = ops->child_keysz(node);
23 spec = vzalloc(sizeof(*spec));
25 field = call_op(node, ops, get_mask);
27 dtp_speckey(key_mkwr(&spec->mask), field);
30 field = call_op(node, ops, get_passthru);
32 dtp_speckey(key_mkwr(&spec->pass_thru), field);
35 llist_init_head(&spec->ents);
38 while (dtpi_has_next(&it))
40 ent = vzalloc(sizeof(*ent));
42 dtpi_next_val(&it, &val, keysz);
43 dtp_speckey(key_mkwr(&ent->child_spec), &val);
45 ent->parent = dtpi_next_hnd(&it);
46 p_keysz = ops->parent_keysz(ent->parent);
48 dtpi_next_val(&it, &val, p_keysz);
49 dtp_speckey(key_mkwr(&ent->parent_spec), &val);
51 changeling_ref(dt_mobj(ent->parent));
52 llist_append(&spec->ents, &ent->ents);
59 __try_match(struct dtspec_key* given, struct dtspec_key* against)
61 for (unsigned int i = 0; i < given->size; i++)
63 if (given->val[i] != against->val[i])
71 dtspec_lookup(struct dtspec_map* map, struct dtspec_key* key)
73 struct dtspec_mapent *pos, *n;
74 struct dtspec_key scratch = {};
76 dtspec_cpykey(&scratch, key);
77 dtspec_applymask(map, &scratch);
79 llist_for_each(pos, n, &map->ents, ents)
81 if (__try_match(&scratch, &pos->child_spec))
83 dtspec_freekey(&scratch);
88 dtspec_freekey(&scratch);
93 dtspec_applymask(struct dtspec_map* map, struct dtspec_key* key)
95 for (unsigned int i = 0; i < map->mask.size; i++)
97 key->val[i] &= map->mask.val[i];
102 dtspec_free(struct dtspec_map* map)
104 struct dtspec_mapent *pos, *n;
106 llist_for_each(pos, n, &map->ents, ents)
108 changeling_unref(dt_mobj(pos->parent));
116 dtspec_cpykey(struct dtspec_key* dest, struct dtspec_key* src)
118 if (dtspec_nullkey(src)) {
122 int sz = sizeof(int) * src->size;
124 dest->val = valloc(sz);
125 dest->size = src->size;
126 memcpy(dest->val, src->val, sz);
130 dtspec_freekey(struct dtspec_key* key)
132 if (dtspec_nullkey(key)) {