From: Alex Rousskov Date: Mon, 13 May 2013 22:51:02 +0000 (-0600) Subject: Adding forgotten src/acl/BoolOps.{cc,h} X-Git-Tag: SQUID_3_4_0_1~102^2~7 X-Git-Url: http://git.ipfire.org/?a=commitdiff_plain;h=b6095d3e30f9656b88cf2d9f09adde21f27225f3;p=thirdparty%2Fsquid.git Adding forgotten src/acl/BoolOps.{cc,h} --- diff --git a/src/acl/BoolOps.cc b/src/acl/BoolOps.cc new file mode 100644 index 0000000000..7e48fc04d0 --- /dev/null +++ b/src/acl/BoolOps.cc @@ -0,0 +1,139 @@ +#include "squid.h" +#include "acl/BoolOps.h" +#include "acl/Checklist.h" +#include "Debug.h" +#include "wordlist.h" + + +/* Acl::NotNode */ + +Acl::NotNode::NotNode(ACL *acl) +{ + assert(acl); + name[0] = '!'; + strncat(&name[1], acl->name, sizeof(name)-1-1); + add(acl); +} + +void +Acl::NotNode::parse() +{ + // Not implemented: by the time an upper level parser discovers + // an '!' operator, there is nothing left for us to parse. + assert(false); +} + +int +Acl::NotNode::doMatch(ACLChecklist *checklist, Nodes::const_iterator start) const +{ + assert(start == nodes.begin()); // we only have one node + + if (checklist->matchChild(this, start, *start)) + return 0; // converting match into mismatch + + if (!checklist->keepMatching()) + return -1; // suspend on async calls and stop on failures + + return 1; // converting mismatch into match +} + +char const * +Acl::NotNode::typeString() const +{ + return "!"; +} + +ACL * +Acl::NotNode::clone() const +{ + // Not implemented: we are not a named ACL type in squid.conf so nobody + // should try to create a NotNode instance by ACL type name (which is + // what clone() API is for -- it does not really clone anything). + assert(false); + return NULL; +} + +wordlist* +Acl::NotNode::dump() const +{ + wordlist *text = NULL; + wordlistAdd(&text, name); + return text; +} + + +/* Acl::AndNode */ + +char const * +Acl::AndNode::typeString() const +{ + return "and"; +} + +ACL * +Acl::AndNode::clone() const +{ + return new AndNode; +} + +int +Acl::AndNode::doMatch(ACLChecklist *checklist, Nodes::const_iterator start) const +{ + // find the first node that does not match + for (Nodes::const_iterator i = start; i != nodes.end(); ++i) { + if (!checklist->matchChild(this, i, *i)) + return checklist->keepMatching() ? 0 : -1; + } + + // one and not zero on empty because in math empty product equals identity + return 1; // no mismatches found (i.e., all kids matched) +} + +void +Acl::AndNode::parse() +{ + // Not implemented: AndNode cannot be configured directly. See Acl::AllOf. + assert(false); +} + + +/* Acl::OrNode */ + +char const * +Acl::OrNode::typeString() const +{ + return "any-of"; +} + +ACL * +Acl::OrNode::clone() const +{ + return new OrNode; +} + +int +Acl::OrNode::doMatch(ACLChecklist *checklist, Nodes::const_iterator start) const +{ + lastMatch_ = nodes.end(); + + // find the first node that matches, but stop if things go wrong + for (Nodes::const_iterator i = start; i != nodes.end(); ++i) { + if (checklist->matchChild(this, i, *i)) { + lastMatch_ = i; + return 1; + } + + if (!checklist->keepMatching()) + return -1; // suspend on async calls and stop on failures + } + + // zero and not one on empty because in math empty sum equals zero + return 0; // all nodes mismatched +} + +void +Acl::OrNode::parse() +{ + // Not implemented: OrNode cannot be configured directly. See Acl::AnyOf. + assert(false); +} diff --git a/src/acl/BoolOps.h b/src/acl/BoolOps.h new file mode 100644 index 0000000000..b8a9a69c90 --- /dev/null +++ b/src/acl/BoolOps.h @@ -0,0 +1,75 @@ +#ifndef SQUID_ACL_LOGIC_H +#define SQUID_ACL_LOGIC_H + +#include "acl/InnerNode.h" + +/* ACLs defined here are used internally to construct an ACL expression tree. + * They cannot be specified directly in squid.conf because squid.conf ACLs are + * more complex than (and are implemented using) these operator-like classes.*/ + +namespace Acl { + +/// Implements the "not" or "!" operator. +class NotNode: public InnerNode +{ +public: + MEMPROXY_CLASS(NotNode); + + explicit NotNode(ACL *acl); + +private: + /* ACL API */ + virtual char const *typeString() const; + virtual ACL *clone() const; + virtual void parse(); + virtual wordlist *dump() const; + + /* Acl::InnerNode API */ + virtual int doMatch(ACLChecklist *checklist, Nodes::const_iterator start) const; +}; +MEMPROXY_CLASS_INLINE(Acl::NotNode); + + +/// An inner ACL expression tree node representing a boolean conjuction (AND) +/// operator applied to a list of child tree nodes. +/// For example, conditions expressed on a single http_access line are ORed. +class AndNode: public InnerNode +{ +public: + MEMPROXY_CLASS(AndNode); + + /* ACL API */ + virtual char const *typeString() const; + virtual ACL *clone() const; + virtual void parse(); + +private: + virtual int doMatch(ACLChecklist *checklist, Nodes::const_iterator start) const; +}; +MEMPROXY_CLASS_INLINE(Acl::AndNode); + +/// An inner ACL expression tree node representing a boolean disjuction (OR) +/// operator applied to a list of child tree nodes. +/// For example, conditions expressed by multiple http_access lines are ORed. +class OrNode: public InnerNode +{ +public: + MEMPROXY_CLASS(OrNode); + + /* ACL API */ + virtual char const *typeString() const; + virtual ACL *clone() const; + virtual void parse(); + +protected: + mutable Nodes::const_iterator lastMatch_; + +private: + virtual int doMatch(ACLChecklist *checklist, Nodes::const_iterator start) const; +}; +MEMPROXY_CLASS_INLINE(Acl::OrNode); + + +} // namespace Acl + +#endif /* SQUID_ACL_LOGIC_H */