static bool port_append_res (struct list_res *res, const struct rule *r, const struct tf *tf, const struct res *in, int32_t ports, bool append, const struct hs *hs, bool inv_remove_deps) { /* Create new result containing headerspace `hs` for each port in `ports`. */ bool used_hs = false; struct hs *new_hs; uint32_t n, x; const uint32_t *a; if (ports > 0) { n = 1; x = ports; a = &x; } else { const struct ports *p = PORTS (tf, ports); n = p->n; a = p->arr; } for (int i = 0; i < n; i++) { if (a[i] == in->port) continue; if (inv_remove_deps) { /* For inversion, also remove dependencies for each input port of the inverted rule. */ new_hs = hs_create (hs->len); hs_copy (new_hs, hs); if (r->deps) deps_diff_inv (new_hs, a[i], DEPS (tf, r->deps), tf); if (!hs_compact_m (new_hs, r->mask ? DATA_ARR (r->mask) : NULL)) { hs_destroy(new_hs); continue; } } else new_hs = (struct hs*) hs; // now *new_hs has the latest hs at this port struct res *tmp; if (! inv_remove_deps) { if (used_hs) tmp = res_extend (in, hs, a[i], append); else { tmp = res_extend (in, NULL, a[i], append); tmp->hs = *hs; used_hs = true; } } else { tmp = res_extend (in, NULL, a[i], append); tmp->hs = *new_hs; } res_rule_add (tmp, tf, r->idx, r); list_append (res, tmp); } return used_hs; }
static struct list_res rule_apply (const struct rule *r, const struct tf *tf, const struct res *in, bool append, uint32_t *app, int *napp) { struct list_res res = {0}; if (!r->out) app_add (r->idx, app, napp); if (!r->out || r->out == in->port) return res; struct hs hs; if (!r->match) hs_copy (&hs, &in->hs); else { if (!hs_isect_arr (&hs, &in->hs, DATA_ARR (r->match))) return res; if (r->deps) deps_diff (&hs, in->port, DEPS (tf, r->deps), tf, app, *napp); if (!hs_compact_m (&hs, r->mask ? DATA_ARR (r->mask) : NULL)) { hs_destroy (&hs); return res; } if (r->mask) hs_rewrite (&hs, DATA_ARR (r->mask), DATA_ARR (r->rewrite)); } bool used_hs = false; uint32_t n, x; const uint32_t *a; if (r->out > 0) { n = 1; x = r->out; a = &x; } else { const struct ports *p = PORTS (tf, r->out); n = p->n; a = p->arr; } for (int i = 0; i < n; i++) { if (a[i] == in->port) continue; struct res *tmp; if (used_hs) tmp = res_extend (in, &hs, a[i], append); else { tmp = res_extend (in, NULL, a[i], append); tmp->hs = hs; used_hs = true; } res_rule_add (tmp, tf, r->idx); list_append (&res, tmp); } if (res.head) app_add (r->idx, app, napp); if (!used_hs) hs_destroy (&hs); return res; }
static struct list_res rule_apply (const struct rule *r, const struct tf *tf, const struct res *in, bool append, uint32_t *app, int *napp) { struct list_res res = {0}; if (!r->out) app_add (r->idx, app, napp); if (!r->out || r->out == in->port) return res; struct hs hs; if (!r->match) hs_copy (&hs, &in->hs); else { if (!hs_isect_arr (&hs, &in->hs, DATA_ARR (r->match))) return res; if (r->deps) deps_diff (&hs, in->port, DEPS (tf, r->deps), tf, app, *napp); if (!hs_compact_m (&hs, r->mask ? DATA_ARR (r->mask) : NULL)) { hs_destroy (&hs); return res; } if (r->mask) hs_rewrite (&hs, DATA_ARR (r->mask), DATA_ARR (r->rewrite)); } bool used_hs = port_append_res (&res, r, tf, in, r->out, append, &hs, false); if (res.head) app_add (r->idx, app, napp); if (!used_hs) hs_destroy (&hs); return res; }
bool hs_compact (struct hs *hs) { return hs_compact_m(hs,NULL); }