Thu, 15 Jan 2015 21:03:48 +0100
Integrate friendly tips from Tor colleagues to make (or not) 4.5 alpha 3;
This includes removal of overloaded (but unused) methods, and addition of
a overlooked call to DataStruct::SetData(nsISupports, uint32_t, bool.)
1 /* -*- Mode: C++; tab-width: 2; indent-tabs-mode: nil; c-basic-offset: 2 -*- */
2 /* This Source Code Form is subject to the terms of the Mozilla Public
3 * License, v. 2.0. If a copy of the MPL was not distributed with this
4 * file, You can obtain one at http://mozilla.org/MPL/2.0/. */
6 /*
7 * A unique per-element set of attributes that is used as an
8 * nsIStyleRule; used to implement presentational attributes.
9 */
11 #include "nsMappedAttributes.h"
12 #include "nsHTMLStyleSheet.h"
13 #include "nsRuleWalker.h"
14 #include "mozilla/HashFunctions.h"
15 #include "mozilla/MemoryReporting.h"
17 using namespace mozilla;
19 nsMappedAttributes::nsMappedAttributes(nsHTMLStyleSheet* aSheet,
20 nsMapRuleToAttributesFunc aMapRuleFunc)
21 : mAttrCount(0),
22 mSheet(aSheet),
23 mRuleMapper(aMapRuleFunc)
24 {
25 }
27 nsMappedAttributes::nsMappedAttributes(const nsMappedAttributes& aCopy)
28 : mAttrCount(aCopy.mAttrCount),
29 mSheet(aCopy.mSheet),
30 mRuleMapper(aCopy.mRuleMapper)
31 {
32 NS_ASSERTION(mBufferSize >= aCopy.mAttrCount, "can't fit attributes");
34 uint32_t i;
35 for (i = 0; i < mAttrCount; ++i) {
36 new (&Attrs()[i]) InternalAttr(aCopy.Attrs()[i]);
37 }
38 }
40 nsMappedAttributes::~nsMappedAttributes()
41 {
42 if (mSheet) {
43 mSheet->DropMappedAttributes(this);
44 }
46 uint32_t i;
47 for (i = 0; i < mAttrCount; ++i) {
48 Attrs()[i].~InternalAttr();
49 }
50 }
53 nsMappedAttributes*
54 nsMappedAttributes::Clone(bool aWillAddAttr)
55 {
56 uint32_t extra = aWillAddAttr ? 1 : 0;
58 // This will call the overridden operator new
59 return new (mAttrCount + extra) nsMappedAttributes(*this);
60 }
62 void* nsMappedAttributes::operator new(size_t aSize, uint32_t aAttrCount) CPP_THROW_NEW
63 {
64 NS_ASSERTION(aAttrCount > 0, "zero-attribute nsMappedAttributes requested");
66 // aSize will include the mAttrs buffer so subtract that.
67 void* newAttrs = ::operator new(aSize - sizeof(void*[1]) +
68 aAttrCount * sizeof(InternalAttr));
70 #ifdef DEBUG
71 static_cast<nsMappedAttributes*>(newAttrs)->mBufferSize = aAttrCount;
72 #endif
74 return newAttrs;
75 }
77 NS_IMPL_ISUPPORTS(nsMappedAttributes,
78 nsIStyleRule)
80 void
81 nsMappedAttributes::SetAndTakeAttr(nsIAtom* aAttrName, nsAttrValue& aValue)
82 {
83 NS_PRECONDITION(aAttrName, "null name");
85 uint32_t i;
86 for (i = 0; i < mAttrCount && !Attrs()[i].mName.IsSmaller(aAttrName); ++i) {
87 if (Attrs()[i].mName.Equals(aAttrName)) {
88 Attrs()[i].mValue.Reset();
89 Attrs()[i].mValue.SwapValueWith(aValue);
90 return;
91 }
92 }
94 NS_ASSERTION(mBufferSize >= mAttrCount + 1, "can't fit attributes");
96 if (mAttrCount != i) {
97 memmove(&Attrs()[i + 1], &Attrs()[i], (mAttrCount - i) * sizeof(InternalAttr));
98 }
100 new (&Attrs()[i].mName) nsAttrName(aAttrName);
101 new (&Attrs()[i].mValue) nsAttrValue();
102 Attrs()[i].mValue.SwapValueWith(aValue);
103 ++mAttrCount;
104 }
106 const nsAttrValue*
107 nsMappedAttributes::GetAttr(nsIAtom* aAttrName) const
108 {
109 NS_PRECONDITION(aAttrName, "null name");
111 for (uint32_t i = 0; i < mAttrCount; ++i) {
112 if (Attrs()[i].mName.Equals(aAttrName)) {
113 return &Attrs()[i].mValue;
114 }
115 }
117 return nullptr;
118 }
120 const nsAttrValue*
121 nsMappedAttributes::GetAttr(const nsAString& aAttrName) const
122 {
123 for (uint32_t i = 0; i < mAttrCount; ++i) {
124 if (Attrs()[i].mName.Atom()->Equals(aAttrName)) {
125 return &Attrs()[i].mValue;
126 }
127 }
129 return nullptr;
130 }
132 bool
133 nsMappedAttributes::Equals(const nsMappedAttributes* aOther) const
134 {
135 if (this == aOther) {
136 return true;
137 }
139 if (mRuleMapper != aOther->mRuleMapper || mAttrCount != aOther->mAttrCount) {
140 return false;
141 }
143 uint32_t i;
144 for (i = 0; i < mAttrCount; ++i) {
145 if (!Attrs()[i].mName.Equals(aOther->Attrs()[i].mName) ||
146 !Attrs()[i].mValue.Equals(aOther->Attrs()[i].mValue)) {
147 return false;
148 }
149 }
151 return true;
152 }
154 uint32_t
155 nsMappedAttributes::HashValue() const
156 {
157 uint32_t hash = HashGeneric(mRuleMapper);
159 uint32_t i;
160 for (i = 0; i < mAttrCount; ++i) {
161 hash = AddToHash(hash,
162 Attrs()[i].mName.HashValue(),
163 Attrs()[i].mValue.HashValue());
164 }
166 return hash;
167 }
169 void
170 nsMappedAttributes::SetStyleSheet(nsHTMLStyleSheet* aSheet)
171 {
172 if (mSheet) {
173 mSheet->DropMappedAttributes(this);
174 }
175 mSheet = aSheet; // not ref counted
176 }
178 /* virtual */ void
179 nsMappedAttributes::MapRuleInfoInto(nsRuleData* aRuleData)
180 {
181 if (mRuleMapper) {
182 (*mRuleMapper)(this, aRuleData);
183 }
184 }
186 #ifdef DEBUG
187 /* virtual */ void
188 nsMappedAttributes::List(FILE* out, int32_t aIndent) const
189 {
190 nsAutoString buffer;
191 uint32_t i;
193 for (i = 0; i < mAttrCount; ++i) {
194 int32_t indent;
195 for (indent = aIndent; indent > 0; --indent)
196 fputs(" ", out);
198 Attrs()[i].mName.GetQualifiedName(buffer);
199 fputs(NS_LossyConvertUTF16toASCII(buffer).get(), out);
201 Attrs()[i].mValue.ToString(buffer);
202 fputs(NS_LossyConvertUTF16toASCII(buffer).get(), out);
203 fputs("\n", out);
204 }
205 }
206 #endif
208 void
209 nsMappedAttributes::RemoveAttrAt(uint32_t aPos, nsAttrValue& aValue)
210 {
211 Attrs()[aPos].mValue.SwapValueWith(aValue);
212 Attrs()[aPos].~InternalAttr();
213 memmove(&Attrs()[aPos], &Attrs()[aPos + 1],
214 (mAttrCount - aPos - 1) * sizeof(InternalAttr));
215 mAttrCount--;
216 }
218 const nsAttrName*
219 nsMappedAttributes::GetExistingAttrNameFromQName(const nsAString& aName) const
220 {
221 uint32_t i;
222 for (i = 0; i < mAttrCount; ++i) {
223 if (Attrs()[i].mName.IsAtom()) {
224 if (Attrs()[i].mName.Atom()->Equals(aName)) {
225 return &Attrs()[i].mName;
226 }
227 }
228 else {
229 if (Attrs()[i].mName.NodeInfo()->QualifiedNameEquals(aName)) {
230 return &Attrs()[i].mName;
231 }
232 }
233 }
235 return nullptr;
236 }
238 int32_t
239 nsMappedAttributes::IndexOfAttr(nsIAtom* aLocalName) const
240 {
241 uint32_t i;
242 for (i = 0; i < mAttrCount; ++i) {
243 if (Attrs()[i].mName.Equals(aLocalName)) {
244 return i;
245 }
246 }
248 return -1;
249 }
251 size_t
252 nsMappedAttributes::SizeOfIncludingThis(MallocSizeOf aMallocSizeOf) const
253 {
254 NS_ASSERTION(mAttrCount == mBufferSize,
255 "mBufferSize and mAttrCount are expected to be the same.");
257 size_t n = aMallocSizeOf(this);
258 for (uint16_t i = 0; i < mAttrCount; ++i) {
259 n += Attrs()[i].mValue.SizeOfExcludingThis(aMallocSizeOf);
260 }
261 return n;
262 }