]> git.ipfire.org Git - thirdparty/squid.git/blame - src/acl/AllOf.cc
Major ACL handling update, including the following changes:
[thirdparty/squid.git] / src / acl / AllOf.cc
CommitLineData
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
9char const *
10Acl::AllOf::typeString() const
11{
12 return "all-of";
13}
14
15ACL *
16Acl::AllOf::clone() const
17{
18 return new AllOf;
19}
20
21wordlist*
22Acl::AllOf::dump() const
23{
24 return empty() ? NULL : nodes.front()->dump();
25}
26
27int
28Acl::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
43void
44Acl::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}