PRInt32 nsAttrAndChildArray::IndexOfAttr(nsIAtom* aLocalName, PRInt32 aNamespaceID) const { PRInt32 idx; if (mImpl && mImpl->mMappedAttrs) { idx = mImpl->mMappedAttrs->IndexOfAttr(aLocalName, aNamespaceID); if (idx >= 0) { return idx; } } PRUint32 i; PRUint32 mapped = MappedAttrCount(); PRUint32 slotCount = AttrSlotCount(); if (aNamespaceID == kNameSpaceID_None) { // This should be the common case so lets make an optimized loop for (i = 0; i < slotCount && AttrSlotIsTaken(i); ++i) { if (ATTRS(mImpl)[i].mName.Equals(aLocalName)) { return i + mapped; } } } else { for (i = 0; i < slotCount && AttrSlotIsTaken(i); ++i) { if (ATTRS(mImpl)[i].mName.Equals(aLocalName, aNamespaceID)) { return i + mapped; } } } return -1; }
const nsAttrValue* nsAttrAndChildArray::GetAttr(nsIAtom* aLocalName, PRInt32 aNamespaceID) const { PRUint32 i, slotCount = AttrSlotCount(); if (aNamespaceID == kNameSpaceID_None) { // This should be the common case so lets make an optimized loop for (i = 0; i < slotCount && AttrSlotIsTaken(i); ++i) { if (ATTRS(mImpl)[i].mName.Equals(aLocalName)) { return &ATTRS(mImpl)[i].mValue; } } if (mImpl && mImpl->mMappedAttrs) { return mImpl->mMappedAttrs->GetAttr(aLocalName); } } else { for (i = 0; i < slotCount && AttrSlotIsTaken(i); ++i) { if (ATTRS(mImpl)[i].mName.Equals(aLocalName, aNamespaceID)) { return &ATTRS(mImpl)[i].mValue; } } } return nsnull; }
nsresult nsAttrAndChildArray::SetAndTakeAttr(nsINodeInfo* aName, nsAttrValue& aValue) { PRInt32 namespaceID = aName->NamespaceID(); nsIAtom* localName = aName->NameAtom(); if (namespaceID == kNameSpaceID_None) { return SetAndTakeAttr(localName, aValue); } PRUint32 i, slotCount = AttrSlotCount(); for (i = 0; i < slotCount && AttrSlotIsTaken(i); ++i) { if (ATTRS(mImpl)[i].mName.Equals(localName, namespaceID)) { ATTRS(mImpl)[i].mName.SetTo(aName); ATTRS(mImpl)[i].mValue.Reset(); ATTRS(mImpl)[i].mValue.SwapValueWith(aValue); return NS_OK; } } NS_ENSURE_TRUE(i < ATTRCHILD_ARRAY_MAX_ATTR_COUNT, NS_ERROR_FAILURE); if (i == slotCount && !AddAttrSlot()) { return NS_ERROR_OUT_OF_MEMORY; } new (&ATTRS(mImpl)[i].mName) nsAttrName(aName); new (&ATTRS(mImpl)[i].mValue) nsAttrValue(); ATTRS(mImpl)[i].mValue.SwapValueWith(aValue); return NS_OK; }
nsresult nsAttrAndChildArray::SetAndTakeAttr(nsIAtom* aLocalName, nsAttrValue& aValue) { PRUint32 i, slotCount = AttrSlotCount(); for (i = 0; i < slotCount && AttrSlotIsTaken(i); ++i) { if (ATTRS(mImpl)[i].mName.Equals(aLocalName)) { ATTRS(mImpl)[i].mValue.Reset(); ATTRS(mImpl)[i].mValue.SwapValueWith(aValue); return NS_OK; } } NS_ENSURE_TRUE(i < ATTRCHILD_ARRAY_MAX_ATTR_COUNT, NS_ERROR_FAILURE); if (i == slotCount && !AddAttrSlot()) { return NS_ERROR_OUT_OF_MEMORY; } new (&ATTRS(mImpl)[i].mName) nsAttrName(aLocalName); new (&ATTRS(mImpl)[i].mValue) nsAttrValue(); ATTRS(mImpl)[i].mValue.SwapValueWith(aValue); return NS_OK; }
const nsAttrValue* nsAttrAndChildArray::GetAttr(const nsAString& aName, nsCaseTreatment aCaseSensitive) const { // Check whether someone is being silly and passing non-lowercase // attr names. if (aCaseSensitive == eIgnoreCase && nsContentUtils::StringContainsASCIIUpper(aName)) { // Try again with a lowercased name, but make sure we can't reenter this // block by passing eCaseSensitive for aCaseSensitive. nsAutoString lowercase; nsContentUtils::ASCIIToLower(aName, lowercase); return GetAttr(lowercase, eCaseMatters); } uint32_t i, slotCount = AttrSlotCount(); for (i = 0; i < slotCount && AttrSlotIsTaken(i); ++i) { if (ATTRS(mImpl)[i].mName.QualifiedNameEquals(aName)) { return &ATTRS(mImpl)[i].mValue; } } if (mImpl && mImpl->mMappedAttrs) { const nsAttrValue* val = mImpl->mMappedAttrs->GetAttr(aName); if (val) { return val; } } return nullptr; }
const nsAttrName* nsAttrAndChildArray::GetExistingAttrNameFromQName(const nsAString& aName) const { PRUint32 i, slotCount = AttrSlotCount(); for (i = 0; i < slotCount && AttrSlotIsTaken(i); ++i) { if (ATTRS(mImpl)[i].mName.QualifiedNameEquals(aName)) { return &ATTRS(mImpl)[i].mName; } } if (mImpl && mImpl->mMappedAttrs) { return mImpl->mMappedAttrs->GetExistingAttrNameFromQName(aName); } return nsnull; }
const nsAttrValue* nsAttrAndChildArray::GetAttr(const nsAString& aLocalName) const { uint32_t i, slotCount = AttrSlotCount(); for (i = 0; i < slotCount && AttrSlotIsTaken(i); ++i) { if (ATTRS(mImpl)[i].mName.Equals(aLocalName)) { return &ATTRS(mImpl)[i].mValue; } } if (mImpl && mImpl->mMappedAttrs) { return mImpl->mMappedAttrs->GetAttr(aLocalName); } return nullptr; }
size_t nsAttrAndChildArray::SizeOfExcludingThis(nsMallocSizeOfFun aMallocSizeOf) const { size_t n = 0; if (mImpl) { // Don't add the size taken by *mMappedAttrs because it's shared. n += aMallocSizeOf(mImpl); PRUint32 slotCount = AttrSlotCount(); for (PRUint32 i = 0; i < slotCount && AttrSlotIsTaken(i); ++i) { nsAttrValue* value = &ATTRS(mImpl)[i].mValue; n += value->SizeOfExcludingThis(aMallocSizeOf); } } return n; }
void nsAttrAndChildArray::Clear() { if (!mImpl) { return; } if (mImpl->mMappedAttrs) { NS_RELEASE(mImpl->mMappedAttrs); } PRUint32 i, slotCount = AttrSlotCount(); for (i = 0; i < slotCount && AttrSlotIsTaken(i); ++i) { ATTRS(mImpl)[i].~InternalAttr(); } nsAutoScriptBlocker scriptBlocker; PRUint32 end = slotCount * ATTRSIZE + ChildCount(); for (i = slotCount * ATTRSIZE; i < end; ++i) { nsIContent* child = static_cast<nsIContent*>(mImpl->mBuffer[i]); // making this false so tree teardown doesn't end up being // O(N*D) (number of nodes times average depth of tree). child->UnbindFromTree(false); // XXX is it better to let the owner do this? // Make sure to unlink our kids from each other, since someone // else could stil be holding references to some of them. // XXXbz We probably can't push this assignment down into the |aNullParent| // case of UnbindFromTree because we still need the assignment in // RemoveChildAt. In particular, ContentRemoved fires between // RemoveChildAt and UnbindFromTree, and in ContentRemoved the sibling // chain needs to be correct. Though maybe we could set the prev and next // to point to each other but keep the kid being removed pointing to them // through ContentRemoved so consumers can find where it used to be in the // list? child->mPreviousSibling = child->mNextSibling = nsnull; NS_RELEASE(child); } SetAttrSlotAndChildCount(0, 0); }
PRInt64 nsAttrAndChildArray::SizeOf() const { PRInt64 size = sizeof(*this); if (mImpl) { // Don't add the size taken by *mMappedAttrs because it's shared. // mBuffer cointains InternalAttr and nsIContent* (even if it's void**) // so, we just have to compute the size of *mBuffer given that this object // doesn't own the children list. size += mImpl->mBufferSize * sizeof(*(mImpl->mBuffer)) + NS_IMPL_EXTRA_SIZE; PRUint32 slotCount = AttrSlotCount(); for (PRUint32 i = 0; i < slotCount && AttrSlotIsTaken(i); ++i) { nsAttrValue* value = &ATTRS(mImpl)[i].mValue; size += value->SizeOf() - sizeof(*value); } } return size; }