]>
Commit | Line | Data |
---|---|---|
6f58d7d7 AR |
1 | #include "squid.h" |
2 | #include "acl/AllOf.h" | |
6f58d7d7 | 3 | #include "acl/BoolOps.h" |
602d9612 | 4 | #include "acl/Checklist.h" |
6f58d7d7 AR |
5 | #include "globals.h" |
6 | #include "MemBuf.h" | |
7 | ||
6f58d7d7 AR |
8 | char const * |
9 | Acl::AllOf::typeString() const | |
10 | { | |
11 | return "all-of"; | |
12 | } | |
13 | ||
14 | ACL * | |
15 | Acl::AllOf::clone() const | |
16 | { | |
17 | return new AllOf; | |
18 | } | |
19 | ||
8966008b | 20 | SBufList |
6f58d7d7 AR |
21 | Acl::AllOf::dump() const |
22 | { | |
8966008b | 23 | return empty() ? SBufList() : nodes.front()->dump(); |
6f58d7d7 AR |
24 | } |
25 | ||
26 | int | |
27 | Acl::AllOf::doMatch(ACLChecklist *checklist, Nodes::const_iterator start) const | |
28 | { | |
29 | assert(start == nodes.begin()); // we only have one node | |
30 | ||
31 | // avoid dereferencing invalid start | |
32 | if (empty()) | |
33 | return 1; // not 0 because in math empty product equals identity | |
34 | ||
35 | if (checklist->matchChild(this, start, *start)) | |
36 | return 1; // match | |
37 | ||
38 | return checklist->keepMatching() ? 0 : -1; | |
39 | } | |
40 | ||
41 | // called once per "acl name all-of name1 name2 ...." line | |
42 | void | |
43 | Acl::AllOf::parse() | |
44 | { | |
45 | Acl::InnerNode *whole = NULL; | |
46 | ACL *oldNode = empty() ? NULL : nodes.front(); | |
47 | ||
48 | // optimization: this logic reduces subtree hight (number of tree levels) | |
49 | if (Acl::OrNode *oldWhole = dynamic_cast<Acl::OrNode*>(oldNode)) { | |
50 | // this acl saw multiple lines before; add another one to the old node | |
51 | whole = oldWhole; | |
52 | } else if (oldNode) { | |
53 | // this acl saw a single line before; create a new OR inner node | |
54 | ||
55 | MemBuf wholeCtx; | |
56 | wholeCtx.init(); | |
57 | wholeCtx.Printf("(%s lines)", name); | |
58 | wholeCtx.terminate(); | |
59 | ||
60 | Acl::OrNode *newWhole = new Acl::OrNode; | |
61 | newWhole->context(wholeCtx.content(), oldNode->cfgline); | |
62 | newWhole->add(oldNode); // old (i.e. first) line | |
63 | nodes.front() = whole = newWhole; | |
64 | } else { | |
65 | // this is the first line for this acl; just use it as is | |
66 | whole = this; | |
67 | } | |
68 | ||
69 | assert(whole); | |
70 | const int lineId = whole->childrenCount() + 1; | |
71 | ||
72 | MemBuf lineCtx; | |
73 | lineCtx.init(); | |
74 | lineCtx.Printf("(%s line #%d)", name, lineId); | |
75 | lineCtx.terminate(); | |
e936c41c | 76 | |
6f58d7d7 AR |
77 | Acl::AndNode *line = new AndNode; |
78 | line->context(lineCtx.content(), config_input_line); | |
79 | line->lineParse(); | |
80 | ||
81 | whole->add(line); | |
82 | } |