]>
Commit | Line | Data |
---|---|---|
bbc27441 | 1 | /* |
b8ae064d | 2 | * Copyright (C) 1996-2023 The Squid Software Foundation and contributors |
bbc27441 AJ |
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" |
8095d0c8 | 13 | #include "acl/Gadgets.h" |
aa3b39af | 14 | #include "cache_cf.h" |
6f58d7d7 | 15 | #include "MemBuf.h" |
aa3b39af | 16 | #include "sbuf/SBuf.h" |
25aa6c9a | 17 | #include "sbuf/Stream.h" |
6f58d7d7 | 18 | |
6f58d7d7 AR |
19 | char const * |
20 | Acl::AllOf::typeString() const | |
21 | { | |
22 | return "all-of"; | |
23 | } | |
24 | ||
8966008b | 25 | SBufList |
6f58d7d7 AR |
26 | Acl::AllOf::dump() const |
27 | { | |
8966008b | 28 | return empty() ? SBufList() : nodes.front()->dump(); |
6f58d7d7 AR |
29 | } |
30 | ||
31 | int | |
32 | Acl::AllOf::doMatch(ACLChecklist *checklist, Nodes::const_iterator start) const | |
33 | { | |
34 | assert(start == nodes.begin()); // we only have one node | |
35 | ||
36 | // avoid dereferencing invalid start | |
37 | if (empty()) | |
38 | return 1; // not 0 because in math empty product equals identity | |
39 | ||
40 | if (checklist->matchChild(this, start, *start)) | |
41 | return 1; // match | |
42 | ||
43 | return checklist->keepMatching() ? 0 : -1; | |
44 | } | |
45 | ||
46 | // called once per "acl name all-of name1 name2 ...." line | |
47 | void | |
48 | Acl::AllOf::parse() | |
49 | { | |
aee3523a | 50 | Acl::InnerNode *whole = nullptr; |
922513e5 | 51 | Acl::Node *oldNode = empty() ? nullptr : nodes.front(); |
6f58d7d7 AR |
52 | |
53 | // optimization: this logic reduces subtree hight (number of tree levels) | |
54 | if (Acl::OrNode *oldWhole = dynamic_cast<Acl::OrNode*>(oldNode)) { | |
55 | // this acl saw multiple lines before; add another one to the old node | |
56 | whole = oldWhole; | |
57 | } else if (oldNode) { | |
58 | // this acl saw a single line before; create a new OR inner node | |
59 | ||
6f58d7d7 | 60 | Acl::OrNode *newWhole = new Acl::OrNode; |
25aa6c9a | 61 | newWhole->context(ToSBuf('(', name, " lines)"), oldNode->cfgline); |
6f58d7d7 AR |
62 | newWhole->add(oldNode); // old (i.e. first) line |
63 | nodes.front() = whole = newWhole; | |
8095d0c8 | 64 | aclRegister(newWhole); |
6f58d7d7 AR |
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 | ||
6f58d7d7 | 73 | Acl::AndNode *line = new AndNode; |
25aa6c9a | 74 | line->context(ToSBuf('(', name, " line #", lineId, ')'), config_input_line); |
6f58d7d7 AR |
75 | line->lineParse(); |
76 | ||
77 | whole->add(line); | |
78 | } | |
f53969cc | 79 |