content/xul/templates/src/nsRDFBinding.cpp

Sat, 03 Jan 2015 20:18:00 +0100

author
Michael Schloh von Bennewitz <michael@schloh.com>
date
Sat, 03 Jan 2015 20:18:00 +0100
branch
TOR_BUG_3246
changeset 7
129ffea94266
permissions
-rw-r--r--

Conditionally enable double key logic according to:
private browsing mode or privacy.thirdparty.isolate preference and
implement in GetCookieStringCommon and FindCookie where it counts...
With some reservations of how to convince FindCookie users to test
condition and pass a nullptr when disabling double key logic.

michael@0 1 /* -*- Mode: C++; tab-width: 4; indent-tabs-mode: nil; c-basic-offset: 4 -*- */
michael@0 2 /* This Source Code Form is subject to the terms of the Mozilla Public
michael@0 3 * License, v. 2.0. If a copy of the MPL was not distributed with this
michael@0 4 * file, You can obtain one at http://mozilla.org/MPL/2.0/. */
michael@0 5
michael@0 6 #include "nsXULTemplateQueryProcessorRDF.h"
michael@0 7 #include "nsXULTemplateResultRDF.h"
michael@0 8 #include "nsRDFBinding.h"
michael@0 9
michael@0 10 #ifdef DEBUG
michael@0 11 #include "nsXULContentUtils.h"
michael@0 12 #endif
michael@0 13
michael@0 14 RDFBindingSet::~RDFBindingSet()
michael@0 15 {
michael@0 16 while (mFirst) {
michael@0 17 RDFBinding* doomed = mFirst;
michael@0 18 mFirst = mFirst->mNext;
michael@0 19 delete doomed;
michael@0 20 }
michael@0 21
michael@0 22 MOZ_COUNT_DTOR(RDFBindingSet);
michael@0 23 }
michael@0 24
michael@0 25 nsresult
michael@0 26 RDFBindingSet::AddBinding(nsIAtom* aVar, nsIAtom* aRef, nsIRDFResource* aPredicate)
michael@0 27 {
michael@0 28 RDFBinding* newbinding = new RDFBinding(aRef, aPredicate, aVar);
michael@0 29 if (! newbinding)
michael@0 30 return NS_ERROR_OUT_OF_MEMORY;
michael@0 31
michael@0 32 if (mFirst) {
michael@0 33 RDFBinding* binding = mFirst;
michael@0 34
michael@0 35 while (binding) {
michael@0 36 // the binding is dependant on the calculation of a previous binding
michael@0 37 if (binding->mSubjectVariable == aVar)
michael@0 38 newbinding->mHasDependency = true;
michael@0 39
michael@0 40 // if the target variable is already used in a binding, ignore it
michael@0 41 // since it won't be useful for anything
michael@0 42 if (binding->mTargetVariable == aVar) {
michael@0 43 delete newbinding;
michael@0 44 return NS_OK;
michael@0 45 }
michael@0 46
michael@0 47 // add the binding at the end of the list
michael@0 48 if (! binding->mNext) {
michael@0 49 binding->mNext = newbinding;
michael@0 50 break;
michael@0 51 }
michael@0 52
michael@0 53 binding = binding->mNext;
michael@0 54 }
michael@0 55 }
michael@0 56 else {
michael@0 57 mFirst = newbinding;
michael@0 58 }
michael@0 59
michael@0 60 mCount++;
michael@0 61
michael@0 62 return NS_OK;
michael@0 63 }
michael@0 64
michael@0 65 bool
michael@0 66 RDFBindingSet::SyncAssignments(nsIRDFResource* aSubject,
michael@0 67 nsIRDFResource* aPredicate,
michael@0 68 nsIRDFNode* aTarget,
michael@0 69 nsIAtom* aMemberVariable,
michael@0 70 nsXULTemplateResultRDF* aResult,
michael@0 71 nsBindingValues& aBindingValues)
michael@0 72 {
michael@0 73 NS_ASSERTION(aBindingValues.GetBindingSet() == this,
michael@0 74 "nsBindingValues not for this RDFBindingSet");
michael@0 75 NS_PRECONDITION(aResult, "Must have result");
michael@0 76
michael@0 77 bool needSync = false;
michael@0 78 nsCOMPtr<nsIRDFNode>* valuesArray = aBindingValues.ValuesArray();
michael@0 79 if (!valuesArray)
michael@0 80 return false;
michael@0 81
michael@0 82 RDFBinding* binding = mFirst;
michael@0 83 int32_t count = 0;
michael@0 84
michael@0 85 // QI for proper comparisons just to be safe
michael@0 86 nsCOMPtr<nsIRDFNode> subjectnode = do_QueryInterface(aSubject);
michael@0 87
michael@0 88 // iterate through the bindings looking for ones that would match the RDF
michael@0 89 // nodes that were involved in a change
michael@0 90 nsCOMPtr<nsIRDFNode> value;
michael@0 91 while (binding) {
michael@0 92 if (aPredicate == binding->mPredicate) {
michael@0 93 // if the source of the binding is the member variable, optimize
michael@0 94 if (binding->mSubjectVariable == aMemberVariable) {
michael@0 95 valuesArray[count] = aTarget;
michael@0 96 needSync = true;
michael@0 97 }
michael@0 98 else {
michael@0 99 aResult->GetAssignment(binding->mSubjectVariable, getter_AddRefs(value));
michael@0 100 if (value == subjectnode) {
michael@0 101 valuesArray[count] = aTarget;
michael@0 102 needSync = true;
michael@0 103 }
michael@0 104 }
michael@0 105 }
michael@0 106
michael@0 107 binding = binding->mNext;
michael@0 108 count++;
michael@0 109 }
michael@0 110
michael@0 111 return needSync;
michael@0 112 }
michael@0 113
michael@0 114 void
michael@0 115 RDFBindingSet::AddDependencies(nsIRDFResource* aSubject,
michael@0 116 nsXULTemplateResultRDF* aResult)
michael@0 117 {
michael@0 118 NS_PRECONDITION(aResult, "Must have result");
michael@0 119
michael@0 120 // iterate through the bindings and add binding dependencies to the
michael@0 121 // processor
michael@0 122
michael@0 123 nsXULTemplateQueryProcessorRDF* processor = aResult->GetProcessor();
michael@0 124 if (! processor)
michael@0 125 return;
michael@0 126
michael@0 127 nsCOMPtr<nsIRDFNode> value;
michael@0 128
michael@0 129 RDFBinding* binding = mFirst;
michael@0 130 while (binding) {
michael@0 131 aResult->GetAssignment(binding->mSubjectVariable, getter_AddRefs(value));
michael@0 132
michael@0 133 nsCOMPtr<nsIRDFResource> valueres = do_QueryInterface(value);
michael@0 134 if (valueres)
michael@0 135 processor->AddBindingDependency(aResult, valueres);
michael@0 136
michael@0 137 binding = binding->mNext;
michael@0 138 }
michael@0 139 }
michael@0 140
michael@0 141 void
michael@0 142 RDFBindingSet::RemoveDependencies(nsIRDFResource* aSubject,
michael@0 143 nsXULTemplateResultRDF* aResult)
michael@0 144 {
michael@0 145 NS_PRECONDITION(aResult, "Must have result");
michael@0 146
michael@0 147 // iterate through the bindings and remove binding dependencies from the
michael@0 148 // processor
michael@0 149
michael@0 150 nsXULTemplateQueryProcessorRDF* processor = aResult->GetProcessor();
michael@0 151 if (! processor)
michael@0 152 return;
michael@0 153
michael@0 154 nsCOMPtr<nsIRDFNode> value;
michael@0 155
michael@0 156 RDFBinding* binding = mFirst;
michael@0 157 while (binding) {
michael@0 158 aResult->GetAssignment(binding->mSubjectVariable, getter_AddRefs(value));
michael@0 159
michael@0 160 nsCOMPtr<nsIRDFResource> valueres = do_QueryInterface(value);
michael@0 161 if (valueres)
michael@0 162 processor->RemoveBindingDependency(aResult, valueres);
michael@0 163
michael@0 164 binding = binding->mNext;
michael@0 165 }
michael@0 166 }
michael@0 167
michael@0 168 int32_t
michael@0 169 RDFBindingSet::LookupTargetIndex(nsIAtom* aTargetVariable, RDFBinding** aBinding)
michael@0 170 {
michael@0 171 int32_t idx = 0;
michael@0 172 RDFBinding* binding = mFirst;
michael@0 173
michael@0 174 while (binding) {
michael@0 175 if (binding->mTargetVariable == aTargetVariable) {
michael@0 176 *aBinding = binding;
michael@0 177 return idx;
michael@0 178 }
michael@0 179 idx++;
michael@0 180 binding = binding->mNext;
michael@0 181 }
michael@0 182
michael@0 183 return -1;
michael@0 184 }
michael@0 185
michael@0 186 nsBindingValues::~nsBindingValues()
michael@0 187 {
michael@0 188 ClearBindingSet();
michael@0 189 MOZ_COUNT_DTOR(nsBindingValues);
michael@0 190 }
michael@0 191
michael@0 192 void
michael@0 193 nsBindingValues::ClearBindingSet()
michael@0 194 {
michael@0 195 if (mBindings && mValues) {
michael@0 196 delete [] mValues;
michael@0 197 mValues = nullptr;
michael@0 198 }
michael@0 199
michael@0 200 mBindings = nullptr;
michael@0 201 }
michael@0 202
michael@0 203 nsresult
michael@0 204 nsBindingValues::SetBindingSet(RDFBindingSet* aBindings)
michael@0 205 {
michael@0 206 ClearBindingSet();
michael@0 207
michael@0 208 int32_t count = aBindings->Count();
michael@0 209 if (count) {
michael@0 210 mValues = new nsCOMPtr<nsIRDFNode>[count];
michael@0 211 if (!mValues)
michael@0 212 return NS_ERROR_OUT_OF_MEMORY;
michael@0 213
michael@0 214 mBindings = aBindings;
michael@0 215 }
michael@0 216 else {
michael@0 217 mValues = nullptr;
michael@0 218 }
michael@0 219
michael@0 220 return NS_OK;
michael@0 221 }
michael@0 222
michael@0 223 void
michael@0 224 nsBindingValues::GetAssignmentFor(nsXULTemplateResultRDF* aResult,
michael@0 225 nsIAtom* aVar,
michael@0 226 nsIRDFNode** aValue)
michael@0 227 {
michael@0 228 *aValue = nullptr;
michael@0 229
michael@0 230 // assignments are calculated lazily when asked for. The only issue is
michael@0 231 // when a binding has no value in the RDF graph, it will be checked again
michael@0 232 // every time.
michael@0 233
michael@0 234 if (mBindings && mValues) {
michael@0 235 RDFBinding* binding;
michael@0 236 int32_t idx = mBindings->LookupTargetIndex(aVar, &binding);
michael@0 237 if (idx >= 0) {
michael@0 238 *aValue = mValues[idx];
michael@0 239 if (*aValue) {
michael@0 240 NS_ADDREF(*aValue);
michael@0 241 }
michael@0 242 else {
michael@0 243 nsXULTemplateQueryProcessorRDF* processor = aResult->GetProcessor();
michael@0 244 if (! processor)
michael@0 245 return;
michael@0 246
michael@0 247 nsIRDFDataSource* ds = processor->GetDataSource();
michael@0 248 if (! ds)
michael@0 249 return;
michael@0 250
michael@0 251 nsCOMPtr<nsIRDFNode> subjectValue;
michael@0 252 aResult->GetAssignment(binding->mSubjectVariable,
michael@0 253 getter_AddRefs(subjectValue));
michael@0 254 if (subjectValue) {
michael@0 255 nsCOMPtr<nsIRDFResource> subject = do_QueryInterface(subjectValue);
michael@0 256 ds->GetTarget(subject, binding->mPredicate, true, aValue);
michael@0 257 if (*aValue)
michael@0 258 mValues[idx] = *aValue;
michael@0 259 }
michael@0 260 }
michael@0 261 }
michael@0 262 }
michael@0 263 }
michael@0 264
michael@0 265 void
michael@0 266 nsBindingValues::RemoveDependencies(nsIRDFResource* aSubject,
michael@0 267 nsXULTemplateResultRDF* aResult)
michael@0 268 {
michael@0 269 if (mBindings)
michael@0 270 mBindings->RemoveDependencies(aSubject, aResult);
michael@0 271 }

mercurial