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