summaryrefslogtreecommitdiff
path: root/src/entry/flag_matcher.cpp
blob: 1c9577b3da7638f064ea6f7ea5ddee93e7ff421b (plain)
1
2
3
4
5
6
7
8
9
10
11
12
13
14
15
16
17
18
19
20
21
22
23
24
25
26
27
28
29
30
31
32
33
34
35
36
37
38
39
40
41
42
43
44
45
46
47
48
49
50
51
52
53
54
55
56
57
58
59
60
61
62
63
64
65
66
67
68
69
70
71
72
73
74
75
#include <malloc.h>
#include <string.h>
#include "flag_matcher.h"

#define RULE_BIT_SIZE_MASK 0x8000000000000000

struct flag_matcher
{
    struct flag_rule  *rule_table;
    uint32_t          number;
};

struct flag_matcher *flag_matcher_new(struct flag_rule *rule, uint32_t n_rule)
{
    if (!rule)
    {
        return NULL;
    }

    if (!n_rule)
    {
        return NULL;
    }

    struct flag_matcher *flag_matcher;

    flag_matcher = (struct flag_matcher *)malloc(sizeof(struct flag_matcher));
    memset(flag_matcher, 0, sizeof(struct flag_matcher));
    flag_matcher->number = n_rule;

    flag_matcher->rule_table = (struct flag_rule *)malloc(sizeof(struct flag_rule) * n_rule);
    memmove(flag_matcher->rule_table, rule, sizeof(struct flag_rule) * n_rule);

    return flag_matcher;
}


void flag_matcher_free(struct flag_matcher *flag_matcher)
{   
    if (!flag_matcher)
    {
        return;
    }

    free(flag_matcher->rule_table);
    free(flag_matcher);
    return;
}


int flag_matcher_match(struct flag_matcher *flag_matcher,  uint64_t flag, struct flag_match *result, uint32_t n_result)
{
    if (!flag_matcher)
    {
        return -1;
    }

    uint32_t result_number = 0;

    for (uint32_t i = 0; i < flag_matcher->number; i ++)
    {
        if (!((flag ^ flag_matcher->rule_table[i].flag) & flag_matcher->rule_table[i].mask))
        {
            result[result_number].flag_rule_id = flag_matcher->rule_table[i].flag_rule_id;
            result[result_number].user_tag = flag_matcher->rule_table[i].user_tag;
            result_number++;
            if (result_number == n_result)
            {
                return result_number;
            }
        }
    }

    return result_number;
}