]> git.ipfire.org Git - thirdparty/squid.git/commitdiff
Adding forgotten src/acl/BoolOps.{cc,h}
authorAlex Rousskov <rousskov@measurement-factory.com>
Mon, 13 May 2013 22:51:02 +0000 (16:51 -0600)
committerAlex Rousskov <rousskov@measurement-factory.com>
Mon, 13 May 2013 22:51:02 +0000 (16:51 -0600)
src/acl/BoolOps.cc [new file with mode: 0644]
src/acl/BoolOps.h [new file with mode: 0644]

diff --git a/src/acl/BoolOps.cc b/src/acl/BoolOps.cc
new file mode 100644 (file)
index 0000000..7e48fc0
--- /dev/null
@@ -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 (file)
index 0000000..b8a9a69
--- /dev/null
@@ -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 */