PRBool nsAttrValue::Equals(const nsAttrValue& aOther) const { if (BaseType() != aOther.BaseType()) { return PR_FALSE; } switch(BaseType()) { case eStringBase: { return GetStringValue().Equals(aOther.GetStringValue()); } case eOtherBase: { break; } case eAtomBase: case eIntegerBase: { return mBits == aOther.mBits; } } MiscContainer* thisCont = GetMiscContainer(); MiscContainer* otherCont = aOther.GetMiscContainer(); if (thisCont->mType != otherCont->mType) { return PR_FALSE; } PRBool needsStringComparison = PR_FALSE; switch (thisCont->mType) { case eInteger: { if (thisCont->mInteger == otherCont->mInteger) { needsStringComparison = PR_TRUE; } break; } case eEnum: { if (thisCont->mEnumValue == otherCont->mEnumValue) { needsStringComparison = PR_TRUE; } break; } case ePercent: { if (thisCont->mPercent == otherCont->mPercent) { needsStringComparison = PR_TRUE; } break; } case eColor: { if (thisCont->mColor == otherCont->mColor) { needsStringComparison = PR_TRUE; } break; } case eCSSStyleRule: { return thisCont->mCSSStyleRule == otherCont->mCSSStyleRule; } case eAtomArray: { // For classlists we could be insensitive to order, however // classlists are never mapped attributes so they are never compared. if (!(*thisCont->mAtomArray == *otherCont->mAtomArray)) { return PR_FALSE; } needsStringComparison = PR_TRUE; break; } case eSVGValue: { return thisCont->mSVGValue == otherCont->mSVGValue; } case eDoubleValue: { return thisCont->mDoubleValue == otherCont->mDoubleValue; } case eIntMarginValue: { return thisCont->mIntMargin == otherCont->mIntMargin; } default: { NS_NOTREACHED("unknown type stored in MiscContainer"); return PR_FALSE; } } if (needsStringComparison) { if (thisCont->mStringBits == otherCont->mStringBits) { return PR_TRUE; } if ((static_cast<ValueBaseType>(thisCont->mStringBits & NS_ATTRVALUE_BASETYPE_MASK) == eStringBase) && (static_cast<ValueBaseType>(otherCont->mStringBits & NS_ATTRVALUE_BASETYPE_MASK) == eStringBase)) { return nsCheapString(reinterpret_cast<nsStringBuffer*>(thisCont->mStringBits)).Equals( nsCheapString(reinterpret_cast<nsStringBuffer*>(otherCont->mStringBits))); } } return PR_FALSE; }
void nsAttrValue::SetTo(const nsAttrValue& aOther) { switch (aOther.BaseType()) { case eStringBase: { ResetIfSet(); nsStringBuffer* str = static_cast<nsStringBuffer*>(aOther.GetPtr()); if (str) { str->AddRef(); SetPtrValueAndType(str, eStringBase); } #ifdef TAINTED if(aOther.isTainted()==1){ mTainted=1; mJSStr=aOther.mJSStr; } #endif return; } case eOtherBase: { break; } case eAtomBase: { ResetIfSet(); nsIAtom* atom = aOther.GetAtomValue(); NS_ADDREF(atom); SetPtrValueAndType(atom, eAtomBase); return; } case eIntegerBase: { ResetIfSet(); mBits = aOther.mBits; return; } } MiscContainer* otherCont = aOther.GetMiscContainer(); if (!EnsureEmptyMiscContainer()) { return; } MiscContainer* cont = GetMiscContainer(); switch (otherCont->mType) { case eInteger: { cont->mInteger = otherCont->mInteger; break; } case eEnum: { cont->mEnumValue = otherCont->mEnumValue; break; } case ePercent: { cont->mPercent = otherCont->mPercent; break; } case eColor: { cont->mColor = otherCont->mColor; break; } case eCSSStyleRule: { NS_ADDREF(cont->mCSSStyleRule = otherCont->mCSSStyleRule); break; } case eAtomArray: { if (!EnsureEmptyAtomArray() || !GetAtomArrayValue()->AppendElements(*otherCont->mAtomArray)) { Reset(); return; } break; } case eSVGValue: { NS_ADDREF(cont->mSVGValue = otherCont->mSVGValue); break; } case eDoubleValue: { cont->mDoubleValue = otherCont->mDoubleValue; break; } case eIntMarginValue: { if (otherCont->mIntMargin) cont->mIntMargin = new nsIntMargin(*otherCont->mIntMargin); break; } default: { NS_NOTREACHED("unknown type stored in MiscContainer"); break; } } void* otherPtr = MISC_STR_PTR(otherCont); if (otherPtr) { if (static_cast<ValueBaseType>(otherCont->mStringBits & NS_ATTRVALUE_BASETYPE_MASK) == eStringBase) { static_cast<nsStringBuffer*>(otherPtr)->AddRef(); } else { static_cast<nsIAtom*>(otherPtr)->AddRef(); } cont->mStringBits = otherCont->mStringBits; } // Note, set mType after switch-case, otherwise EnsureEmptyAtomArray doesn't // work correctly. cont->mType = otherCont->mType; }
bool nsAttrValue::Equals(const nsAttrValue& aOther) const { if (BaseType() != aOther.BaseType()) { return false; } switch(BaseType()) { case eStringBase: { return GetStringValue().Equals(aOther.GetStringValue()); } case eOtherBase: { break; } case eAtomBase: case eIntegerBase: { return mBits == aOther.mBits; } } MiscContainer* thisCont = GetMiscContainer(); MiscContainer* otherCont = aOther.GetMiscContainer(); if (thisCont == otherCont) { return true; } if (thisCont->mType != otherCont->mType) { return false; } bool needsStringComparison = false; switch (thisCont->mType) { case eInteger: { if (thisCont->mValue.mInteger == otherCont->mValue.mInteger) { needsStringComparison = true; } break; } case eEnum: { if (thisCont->mValue.mEnumValue == otherCont->mValue.mEnumValue) { needsStringComparison = true; } break; } case ePercent: { if (thisCont->mValue.mPercent == otherCont->mValue.mPercent) { needsStringComparison = true; } break; } case eColor: { if (thisCont->mValue.mColor == otherCont->mValue.mColor) { needsStringComparison = true; } break; } case eCSSStyleRule: { return thisCont->mValue.mCSSStyleRule == otherCont->mValue.mCSSStyleRule; } case eURL: { return thisCont->mValue.mURL == otherCont->mValue.mURL; } case eImage: { return thisCont->mValue.mImage == otherCont->mValue.mImage; } case eAtomArray: { // For classlists we could be insensitive to order, however // classlists are never mapped attributes so they are never compared. if (!(*thisCont->mValue.mAtomArray == *otherCont->mValue.mAtomArray)) { return false; } needsStringComparison = true; break; } case eDoubleValue: { return thisCont->mDoubleValue == otherCont->mDoubleValue; } case eIntMarginValue: { return thisCont->mValue.mIntMargin == otherCont->mValue.mIntMargin; } default: { if (IsSVGType(thisCont->mType)) { // Currently this method is never called for nsAttrValue objects that // point to SVG data types. // If that changes then we probably want to add methods to the // corresponding SVG types to compare their base values. // As a shortcut, however, we can begin by comparing the pointers. MOZ_ASSERT(false, "Comparing nsAttrValues that point to SVG data"); return false; } NS_NOTREACHED("unknown type stored in MiscContainer"); return false; } } if (needsStringComparison) { if (thisCont->mStringBits == otherCont->mStringBits) { return true; } if ((static_cast<ValueBaseType>(thisCont->mStringBits & NS_ATTRVALUE_BASETYPE_MASK) == eStringBase) && (static_cast<ValueBaseType>(otherCont->mStringBits & NS_ATTRVALUE_BASETYPE_MASK) == eStringBase)) { return nsCheapString(reinterpret_cast<nsStringBuffer*>(thisCont->mStringBits)).Equals( nsCheapString(reinterpret_cast<nsStringBuffer*>(otherCont->mStringBits))); } } return false; }
void nsAttrValue::SetTo(const nsAttrValue& aOther) { if (this == &aOther) { return; } switch (aOther.BaseType()) { case eStringBase: { ResetIfSet(); nsStringBuffer* str = static_cast<nsStringBuffer*>(aOther.GetPtr()); if (str) { str->AddRef(); SetPtrValueAndType(str, eStringBase); } return; } case eOtherBase: { break; } case eAtomBase: { ResetIfSet(); nsIAtom* atom = aOther.GetAtomValue(); NS_ADDREF(atom); SetPtrValueAndType(atom, eAtomBase); return; } case eIntegerBase: { ResetIfSet(); mBits = aOther.mBits; return; } } MiscContainer* otherCont = aOther.GetMiscContainer(); if (otherCont->IsRefCounted()) { delete ClearMiscContainer(); NS_ADDREF(otherCont); SetPtrValueAndType(otherCont, eOtherBase); return; } MiscContainer* cont = EnsureEmptyMiscContainer(); switch (otherCont->mType) { case eInteger: { cont->mValue.mInteger = otherCont->mValue.mInteger; break; } case eEnum: { cont->mValue.mEnumValue = otherCont->mValue.mEnumValue; break; } case ePercent: { cont->mValue.mPercent = otherCont->mValue.mPercent; break; } case eColor: { cont->mValue.mColor = otherCont->mValue.mColor; break; } case eCSSStyleRule: { MOZ_CRASH("These should be refcounted!"); } case eURL: { NS_ADDREF(cont->mValue.mURL = otherCont->mValue.mURL); break; } case eImage: { NS_ADDREF(cont->mValue.mImage = otherCont->mValue.mImage); break; } case eAtomArray: { if (!EnsureEmptyAtomArray() || !GetAtomArrayValue()->AppendElements(*otherCont->mValue.mAtomArray)) { Reset(); return; } break; } case eDoubleValue: { cont->mDoubleValue = otherCont->mDoubleValue; break; } case eIntMarginValue: { if (otherCont->mValue.mIntMargin) cont->mValue.mIntMargin = new nsIntMargin(*otherCont->mValue.mIntMargin); break; } default: { if (IsSVGType(otherCont->mType)) { // All SVG types are just pointers to classes and will therefore have // the same size so it doesn't really matter which one we assign cont->mValue.mSVGAngle = otherCont->mValue.mSVGAngle; } else { NS_NOTREACHED("unknown type stored in MiscContainer"); } break; } } void* otherPtr = MISC_STR_PTR(otherCont); if (otherPtr) { if (static_cast<ValueBaseType>(otherCont->mStringBits & NS_ATTRVALUE_BASETYPE_MASK) == eStringBase) { static_cast<nsStringBuffer*>(otherPtr)->AddRef(); } else { static_cast<nsIAtom*>(otherPtr)->AddRef(); } cont->mStringBits = otherCont->mStringBits; } // Note, set mType after switch-case, otherwise EnsureEmptyAtomArray doesn't // work correctly. cont->mType = otherCont->mType; }
PRBool nsAttrValue::Equals(const nsAttrValue& aOther) const { if (BaseType() != aOther.BaseType()) { return PR_FALSE; } switch(BaseType()) { case eStringBase: { return GetStringValue().Equals(aOther.GetStringValue()); } case eOtherBase: { break; } case eAtomBase: case eIntegerBase: { return mBits == aOther.mBits; } } MiscContainer* thisCont = GetMiscContainer(); MiscContainer* otherCont = aOther.GetMiscContainer(); if (thisCont->mType != otherCont->mType) { return PR_FALSE; } switch (thisCont->mType) { case eColor: { return thisCont->mColor == otherCont->mColor; } case eCSSStyleRule: { return thisCont->mCSSStyleRule == otherCont->mCSSStyleRule; } case eAtomArray: { // For classlists we could be insensitive to order, however // classlists are never mapped attributes so they are never compared. PRInt32 count = thisCont->mAtomArray->Count(); if (count != otherCont->mAtomArray->Count()) { return PR_FALSE; } PRInt32 i; for (i = 0; i < count; ++i) { if (thisCont->mAtomArray->ObjectAt(i) != otherCont->mAtomArray->ObjectAt(i)) { return PR_FALSE; } } return PR_TRUE; } #ifdef MOZ_SVG case eSVGValue: { return thisCont->mSVGValue == otherCont->mSVGValue; } #endif default: { NS_NOTREACHED("unknown type stored in MiscContainer"); return PR_FALSE; } } }
void nsAttrValue::SetTo(const nsAttrValue& aOther) { switch (aOther.BaseType()) { case eStringBase: { ResetIfSet(); nsStringBuffer* str = static_cast<nsStringBuffer*>(aOther.GetPtr()); if (str) { str->AddRef(); SetPtrValueAndType(str, eStringBase); } return; } case eOtherBase: { break; } case eAtomBase: { ResetIfSet(); nsIAtom* atom = aOther.GetAtomValue(); NS_ADDREF(atom); SetPtrValueAndType(atom, eAtomBase); return; } case eIntegerBase: { ResetIfSet(); mBits = aOther.mBits; return; } } MiscContainer* otherCont = aOther.GetMiscContainer(); switch (otherCont->mType) { case eColor: { if (EnsureEmptyMiscContainer()) { MiscContainer* cont = GetMiscContainer(); cont->mColor = otherCont->mColor; cont->mType = eColor; } break; } case eCSSStyleRule: { SetTo(otherCont->mCSSStyleRule); break; } case eAtomArray: { if (!EnsureEmptyAtomArray() || !GetAtomArrayValue()->AppendObjects(*otherCont->mAtomArray)) { Reset(); } break; } #ifdef MOZ_SVG case eSVGValue: { SetTo(otherCont->mSVGValue); } #endif default: { NS_NOTREACHED("unknown type stored in MiscContainer"); break; } } }