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