diff options
Diffstat (limited to 'dom/base/nsAttrValueInlines.h')
-rw-r--r-- | dom/base/nsAttrValueInlines.h | 239 |
1 files changed, 239 insertions, 0 deletions
diff --git a/dom/base/nsAttrValueInlines.h b/dom/base/nsAttrValueInlines.h new file mode 100644 index 000000000..d2749d486 --- /dev/null +++ b/dom/base/nsAttrValueInlines.h @@ -0,0 +1,239 @@ +/* -*- Mode: C++; tab-width: 8; indent-tabs-mode: nil; c-basic-offset: 2 -*- */ +/* vim: set ts=8 sts=2 et sw=2 tw=80: */ +/* 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 nsAttrValueInlines_h__ +#define nsAttrValueInlines_h__ + +#include <stdint.h> + +#include "nsAttrValue.h" +#include "mozilla/Attributes.h" + +struct MiscContainer; + +struct MiscContainer final +{ + typedef nsAttrValue::ValueType ValueType; + + ValueType mType; + // mStringBits points to either nsIAtom* or nsStringBuffer* and is used when + // mType isn't eCSSDeclaration. + // Note eStringBase and eAtomBase is used also to handle the type of + // mStringBits. + uintptr_t mStringBits; + union { + struct { + union { + int32_t mInteger; + nscolor mColor; + uint32_t mEnumValue; + int32_t mPercent; + mozilla::DeclarationBlock* mCSSDeclaration; + mozilla::css::URLValue* mURL; + mozilla::css::ImageValue* mImage; + nsAttrValue::AtomArray* mAtomArray; + nsIntMargin* mIntMargin; + const nsSVGAngle* mSVGAngle; + const nsSVGIntegerPair* mSVGIntegerPair; + const nsSVGLength2* mSVGLength; + const mozilla::SVGLengthList* mSVGLengthList; + const mozilla::SVGNumberList* mSVGNumberList; + const nsSVGNumberPair* mSVGNumberPair; + const mozilla::SVGPathData* mSVGPathData; + const mozilla::SVGPointList* mSVGPointList; + const mozilla::SVGAnimatedPreserveAspectRatio* mSVGPreserveAspectRatio; + const mozilla::SVGStringList* mSVGStringList; + const mozilla::SVGTransformList* mSVGTransformList; + const nsSVGViewBox* mSVGViewBox; + }; + uint32_t mRefCount : 31; + uint32_t mCached : 1; + } mValue; + double mDoubleValue; + }; + + MiscContainer() + : mType(nsAttrValue::eColor), + mStringBits(0) + { + MOZ_COUNT_CTOR(MiscContainer); + mValue.mColor = 0; + mValue.mRefCount = 0; + mValue.mCached = 0; + } + +protected: + // Only nsAttrValue should be able to delete us. + friend class nsAttrValue; + + ~MiscContainer() + { + if (IsRefCounted()) { + MOZ_ASSERT(mValue.mRefCount == 0); + MOZ_ASSERT(!mValue.mCached); + } + MOZ_COUNT_DTOR(MiscContainer); + } + +public: + bool GetString(nsAString& aString) const; + + inline bool IsRefCounted() const + { + // Nothing stops us from refcounting (and sharing) other types of + // MiscContainer (except eDoubleValue types) but there's no compelling + // reason to. + return mType == nsAttrValue::eCSSDeclaration; + } + + inline int32_t AddRef() { + MOZ_ASSERT(IsRefCounted()); + return ++mValue.mRefCount; + } + + inline int32_t Release() { + MOZ_ASSERT(IsRefCounted()); + return --mValue.mRefCount; + } + + void Cache(); + void Evict(); +}; + +/** + * Implementation of inline methods + */ + +inline int32_t +nsAttrValue::GetIntegerValue() const +{ + NS_PRECONDITION(Type() == eInteger, "wrong type"); + return (BaseType() == eIntegerBase) + ? GetIntInternal() + : GetMiscContainer()->mValue.mInteger; +} + +inline int16_t +nsAttrValue::GetEnumValue() const +{ + NS_PRECONDITION(Type() == eEnum, "wrong type"); + // We don't need to worry about sign extension here since we're + // returning an int16_t which will cut away the top bits. + return static_cast<int16_t>(( + (BaseType() == eIntegerBase) + ? static_cast<uint32_t>(GetIntInternal()) + : GetMiscContainer()->mValue.mEnumValue) + >> NS_ATTRVALUE_ENUMTABLEINDEX_BITS); +} + +inline float +nsAttrValue::GetPercentValue() const +{ + NS_PRECONDITION(Type() == ePercent, "wrong type"); + return ((BaseType() == eIntegerBase) + ? GetIntInternal() + : GetMiscContainer()->mValue.mPercent) + / 100.0f; +} + +inline nsAttrValue::AtomArray* +nsAttrValue::GetAtomArrayValue() const +{ + NS_PRECONDITION(Type() == eAtomArray, "wrong type"); + return GetMiscContainer()->mValue.mAtomArray; +} + +inline mozilla::DeclarationBlock* +nsAttrValue::GetCSSDeclarationValue() const +{ + NS_PRECONDITION(Type() == eCSSDeclaration, "wrong type"); + return GetMiscContainer()->mValue.mCSSDeclaration; +} + +inline mozilla::css::URLValue* +nsAttrValue::GetURLValue() const +{ + NS_PRECONDITION(Type() == eURL, "wrong type"); + return GetMiscContainer()->mValue.mURL; +} + +inline mozilla::css::ImageValue* +nsAttrValue::GetImageValue() const +{ + NS_PRECONDITION(Type() == eImage, "wrong type"); + return GetMiscContainer()->mValue.mImage; +} + +inline double +nsAttrValue::GetDoubleValue() const +{ + NS_PRECONDITION(Type() == eDoubleValue, "wrong type"); + return GetMiscContainer()->mDoubleValue; +} + +inline bool +nsAttrValue::GetIntMarginValue(nsIntMargin& aMargin) const +{ + NS_PRECONDITION(Type() == eIntMarginValue, "wrong type"); + nsIntMargin* m = GetMiscContainer()->mValue.mIntMargin; + if (!m) + return false; + aMargin = *m; + return true; +} + +inline bool +nsAttrValue::IsSVGType(ValueType aType) const +{ + return aType >= eSVGTypesBegin && aType <= eSVGTypesEnd; +} + +inline bool +nsAttrValue::StoresOwnData() const +{ + if (BaseType() != eOtherBase) { + return true; + } + ValueType t = Type(); + return t != eCSSDeclaration && !IsSVGType(t); +} + +inline void +nsAttrValue::SetPtrValueAndType(void* aValue, ValueBaseType aType) +{ + NS_ASSERTION(!(NS_PTR_TO_INT32(aValue) & ~NS_ATTRVALUE_POINTERVALUE_MASK), + "pointer not properly aligned, this will crash"); + mBits = reinterpret_cast<intptr_t>(aValue) | aType; +} + +inline void +nsAttrValue::ResetIfSet() +{ + if (mBits) { + Reset(); + } +} + +inline MiscContainer* +nsAttrValue::GetMiscContainer() const +{ + NS_ASSERTION(BaseType() == eOtherBase, "wrong type"); + return static_cast<MiscContainer*>(GetPtr()); +} + +inline int32_t +nsAttrValue::GetIntInternal() const +{ + NS_ASSERTION(BaseType() == eIntegerBase, + "getting integer from non-integer"); + // Make sure we get a signed value. + // Lets hope the optimizer optimizes this into a shift. Unfortunatly signed + // bitshift right is implementaion dependant. + return static_cast<int32_t>(mBits & ~NS_ATTRVALUE_INTEGERTYPE_MASK) / + NS_ATTRVALUE_INTEGERTYPE_MULTIPLIER; +} + +#endif |