summaryrefslogtreecommitdiffstats
path: root/dom/xul/templates/nsRDFBinding.h
diff options
context:
space:
mode:
Diffstat (limited to 'dom/xul/templates/nsRDFBinding.h')
-rw-r--r--dom/xul/templates/nsRDFBinding.h216
1 files changed, 216 insertions, 0 deletions
diff --git a/dom/xul/templates/nsRDFBinding.h b/dom/xul/templates/nsRDFBinding.h
new file mode 100644
index 000000000..92c8b16ca
--- /dev/null
+++ b/dom/xul/templates/nsRDFBinding.h
@@ -0,0 +1,216 @@
+/* -*- Mode: C++; tab-width: 4; indent-tabs-mode: nil; c-basic-offset: 4 -*- */
+/* This Source Code Form is subject to the terms of the Mozilla Public
+ * License, v. 2.0. If a copy of the MPL was not distributed with this
+ * file, You can obtain one at http://mozilla.org/MPL/2.0/. */
+
+#ifndef nsRDFBinding_h__
+#define nsRDFBinding_h__
+
+#include "nsIAtom.h"
+#include "nsIRDFResource.h"
+#include "nsISupportsImpl.h"
+
+class nsXULTemplateResultRDF;
+class nsBindingValues;
+
+/*
+ * Classes related to storing bindings for RDF handling.
+ */
+
+/*
+ * a <binding> descriptors
+ */
+class RDFBinding {
+
+public:
+
+ nsCOMPtr<nsIAtom> mSubjectVariable;
+ nsCOMPtr<nsIRDFResource> mPredicate;
+ nsCOMPtr<nsIAtom> mTargetVariable;
+
+ // indicates whether a binding is dependant on the result from a
+ // previous binding
+ bool mHasDependency;
+
+ RDFBinding* mNext;
+
+private:
+
+ friend class RDFBindingSet;
+
+ RDFBinding(nsIAtom* aSubjectVariable,
+ nsIRDFResource* aPredicate,
+ nsIAtom* aTargetVariable)
+ : mSubjectVariable(aSubjectVariable),
+ mPredicate(aPredicate),
+ mTargetVariable(aTargetVariable),
+ mHasDependency(false),
+ mNext(nullptr)
+ {
+ MOZ_COUNT_CTOR(RDFBinding);
+ }
+
+ ~RDFBinding()
+ {
+ MOZ_COUNT_DTOR(RDFBinding);
+ }
+};
+
+/*
+ * a collection of <binding> descriptors. This object is refcounted by
+ * nsBindingValues objects and the query processor.
+ */
+class RDFBindingSet final
+{
+private:
+ // Private destructor, to discourage deletion outside of Release():
+ ~RDFBindingSet();
+
+ // the number of bindings
+ int32_t mCount;
+
+ // pointer to the first binding in a linked list
+ RDFBinding* mFirst;
+
+public:
+
+ RDFBindingSet()
+ : mCount(0),
+ mFirst(nullptr)
+ {
+ MOZ_COUNT_CTOR(RDFBindingSet);
+ }
+
+ NS_INLINE_DECL_REFCOUNTING(RDFBindingSet)
+
+ int32_t Count() const { return mCount; }
+
+ /*
+ * Add a binding (aRef -> aPredicate -> aVar) to the set
+ */
+ nsresult
+ AddBinding(nsIAtom* aVar, nsIAtom* aRef, nsIRDFResource* aPredicate);
+
+ /*
+ * Return true if the binding set contains a binding which would cause
+ * the result to need resynchronizing for an RDF triple. The member
+ * variable may be supplied as an optimization since bindings most
+ * commonly use the member variable as the subject. If aMemberVariable
+ * is set, aSubject must be the value of the member variable for the
+ * result. The supplied binding values aBindingValues must be values
+ * using this binding set (that is aBindingValues->GetBindingSet() == this)
+ *
+ * @param aSubject subject of the RDF triple
+ * @param aPredicate predicate of the RDF triple
+ * @param aTarget target of the RDF triple
+ * @param aMemberVariable member variable for the query for the binding
+ * @param aResult result to synchronize
+ * @param aBindingValues the values for the bindings for the result
+ */
+ bool
+ SyncAssignments(nsIRDFResource* aSubject,
+ nsIRDFResource* aPredicate,
+ nsIRDFNode* aTarget,
+ nsIAtom* aMemberVariable,
+ nsXULTemplateResultRDF* aResult,
+ nsBindingValues& aBindingValues);
+
+ /*
+ * The query processor maintains a map of subjects to an array of results.
+ * This is used such that when a new assertion is added to the RDF graph,
+ * the results associated with the subject of that triple may be checked
+ * to see if their bindings have changed. The AddDependencies method adds
+ * these subject dependencies to the map.
+ */
+ void
+ AddDependencies(nsIRDFResource* aSubject,
+ nsXULTemplateResultRDF* aResult);
+
+ /*
+ * Remove the results from the dependencies map when results are deleted.
+ */
+ void
+ RemoveDependencies(nsIRDFResource* aSubject,
+ nsXULTemplateResultRDF* aResult);
+
+ /*
+ * The nsBindingValues classes stores an array of values, one for each
+ * target symbol that could be set by the bindings in the set.
+ * LookupTargetIndex determines the index into the array for a given
+ * target symbol.
+ */
+ int32_t
+ LookupTargetIndex(nsIAtom* aTargetVariable, RDFBinding** aBinding);
+};
+
+/*
+ * A set of values of bindings. This object is used once per result.
+ * This stores a reference to the binding set and an array of node values.
+ * Since the binding set is used once per query and the values are
+ * used once per result, we reduce size by only storing the value array's
+ * length in the binding set. This is possible since the array is always
+ * a fixed length for a particular binding set.
+ *
+ * XXX ndeakin We may want to revisit this later since it makes the code
+ * more complicated.
+ */
+class nsBindingValues
+{
+protected:
+
+ // the binding set
+ RefPtr<RDFBindingSet> mBindings;
+
+ /*
+ * A set of values for variable bindings. To look up a binding value,
+ * scan through the binding set in mBindings for the right target atom.
+ * Its index will correspond to the index in this array. The size of this
+ * array is determined by the RDFBindingSet's Count().
+ */
+ nsCOMPtr<nsIRDFNode>* mValues;
+
+public:
+
+ nsBindingValues()
+ : mBindings(nullptr),
+ mValues(nullptr)
+ {
+ MOZ_COUNT_CTOR(nsBindingValues);
+ }
+
+ ~nsBindingValues();
+
+
+ /**
+ * Clear the binding set, to be called when the nsBindingValues is deleted
+ * or a new binding set is being set.
+ */
+ void ClearBindingSet();
+
+ RDFBindingSet* GetBindingSet() { return mBindings; }
+
+ /**
+ * Set the binding set to use. This needs to be called once a rule matches
+ * since it is then known which bindings will apply.
+ */
+ nsresult SetBindingSet(RDFBindingSet* aBindings);
+
+ nsCOMPtr<nsIRDFNode>* ValuesArray() { return mValues; }
+
+ /*
+ * Retrieve the assignment for a particular variable
+ */
+ void
+ GetAssignmentFor(nsXULTemplateResultRDF* aResult,
+ nsIAtom* aVar,
+ nsIRDFNode** aValue);
+
+ /*
+ * Remove depenedencies the bindings have on particular resources
+ */
+ void
+ RemoveDependencies(nsIRDFResource* aSubject,
+ nsXULTemplateResultRDF* aResult);
+};
+
+#endif // nsRDFBinding_h__