示例#1
0
文件: hs.c 项目: NetSys/sts
bool
hs_isect_arr (struct hs *res, const struct hs *hs, const array_t *a)
{
  const struct hs_vec *v = &hs->list;
  array_t tmp[ARRAY_BYTES (hs->len) / sizeof (array_t)];
  int pos = -1;

  for (int i = 0; i < v->used; i++) {
    if (!array_isect (v->elems[i], a, hs->len, tmp)) continue;
    pos = i; break;
  }
  if (pos == -1) return false;

  memset (res, 0, sizeof *res);
  res->len = hs->len;
  struct hs_vec *resv = &res->list;
  for (int i = pos; i < v->used; i++) {
    if (i == pos) vec_append (resv, xmemdup (tmp, sizeof tmp), false);
    else {
      array_t *isect = array_isect_a (v->elems[i], a, res->len);
      if (!isect) continue;
      vec_append (resv, isect, false);
    }

    struct hs_vec *diff = &v->diff[i], *resd = &resv->diff[resv->used - 1];
    for (int j = 0; j < diff->used; j++) {
      array_t *isect = array_isect_a (diff->elems[j], a, res->len);
      if (!isect) continue;
      vec_append (resd, isect, true);
    }
  }
  return true;
}
示例#2
0
static uint32_t
arr_find (const array_t *a, const array_t *arrs, int n)
{
    if (!a) return 0;
    int len = ARRAY_BYTES (arr_len);
    array_t *b = bsearch (a, arrs, n, len, arr_cmp);
    assert (b);
    return VALID_OFS + ((uint8_t *)b - (uint8_t *)arrs);
}
示例#3
0
static array_t *
gen_arrs (const struct parse_ntf *ntf, uint32_t *n)
{
    char *buf, *buf2;
    size_t bufsz, buf2sz;
    FILE *f = open_memstream (&buf, &bufsz);

    uint32_t len = ARRAY_BYTES (arr_len);
    int count = 0;
    for (int i = 0; i < ntf->ntfs; i++) {
        const struct parse_tf *tf = ntf->tfs[i];
        for (struct parse_rule *r = tf->rules.head; r; r = r->next) {
            assert (r->match);
            fwrite (r->match, len, 1, f);
            count++;
            if (r->mask) {
                fwrite (r->mask, len, 1, f);
                fwrite (r->rewrite, len, 1, f);
                count += 2;
            }
            for (struct parse_dep *dep = r->deps.head; dep; dep = dep->next) {
                fwrite (dep->match, len, 1, f);
                count++;
            }
        }
    }
    fclose (f);

    printf ("Arrays: %d (%zu)", count, bufsz);
    fflush (stdout);
    assert (count * len == bufsz);

    qsort (buf, count, len, arr_cmp);
    array_t *arrs = (array_t *) buf;
    int count2 = 0, last = -1;

    f = open_memstream (&buf2, &buf2sz);
    for (int i = 0; i < count * (len / sizeof (array_t)); i += len / sizeof (array_t)) {
        if (last != -1 && array_is_eq (&arrs[i], &arrs[last], arr_len)) continue;
        fwrite (&arrs[i], len, 1, f);
        last = i;
        count2++;
    }
    fclose (f);
    free (buf);

    printf (" -> %d (%zu)\n", count2, buf2sz);
    assert (count2 * len == buf2sz);

    *n = count2;
    return (array_t *) buf2;
}
示例#4
0
void
data_gen (const char *name, const struct parse_ntf *ntf, const struct parse_tf *ttf)
{
    FILE *out = fopen (name, "w");
    if (!out) err (1, "Can't open output file %s", name);

    int ntfs = ntf->ntfs + 1;
    char *buf_strs;
    size_t sz_strs;
    FILE *f_strs = open_memstream (&buf_strs, &sz_strs);

    uint32_t narrs;
    arr_len = ntf->tfs[0]->len;
    array_t *arrs = gen_arrs (ntf, &narrs);

    int hdr_size = offsetof (struct file, tf_ofs[ntfs]);
    struct file *hdr = xmalloc (hdr_size);
    memset (hdr, 0, hdr_size);
    hdr->ntfs = ntfs;
    hdr->stages = ntf->stages;
    fwrite (hdr, hdr_size, 1, out);

    for (int i = 0; i < ntfs; i++) {
        hdr->tf_ofs[i] = ftell (out);
        printf ("%" PRIu32 "\n", hdr->tf_ofs[i]);
        if (!i) gen_tf (ttf, out, f_strs, arrs, narrs);
        else gen_tf (ntf->tfs[i - 1], out, f_strs, arrs, narrs);
    }
    fclose (f_strs);

    int len = ARRAY_BYTES (arr_len);
    hdr->arrs_ofs = ftell (out);
    fwrite (&arr_len, sizeof arr_len, 1, out);
    fwrite (&narrs, sizeof narrs, 1, out);
    fwrite (arrs, len, narrs, out);
    free (arrs);

    hdr->strs_ofs = ftell (out);
    fwrite (buf_strs, 1, sz_strs, out);
    free (buf_strs);

    int end = ftell (out);
    rewind (out);
    fwrite (hdr, hdr_size, 1, out);
    free (hdr);

    printf ("Total: %d bytes\n", end);
    fclose (out);
}
示例#5
0
static int
arr_cmp (const void *a, const void *b)
{
    return memcmp (a, b, ARRAY_BYTES (arr_len));
}