Line data Source code
1 : /* -*- Mode: C++; tab-width: 8; indent-tabs-mode: nil; c-basic-offset: 2 -*- */
2 : /* vim: set ts=8 sts=2 et sw=2 tw=80: */
3 : /* This Source Code Form is subject to the terms of the Mozilla Public
4 : * License, v. 2.0. If a copy of the MPL was not distributed with this
5 : * file, You can obtain one at http://mozilla.org/MPL/2.0/. */
6 :
7 : #ifndef nsAttrValueInlines_h__
8 : #define nsAttrValueInlines_h__
9 :
10 : #include <stdint.h>
11 :
12 : #include "nsAttrValue.h"
13 : #include "mozilla/Attributes.h"
14 :
15 : struct MiscContainer;
16 :
17 : struct MiscContainer final
18 : {
19 : typedef nsAttrValue::ValueType ValueType;
20 :
21 : ValueType mType;
22 : // mStringBits points to either nsIAtom* or nsStringBuffer* and is used when
23 : // mType isn't eCSSDeclaration.
24 : // Note eStringBase and eAtomBase is used also to handle the type of
25 : // mStringBits.
26 : uintptr_t mStringBits;
27 : union {
28 : struct {
29 : union {
30 : int32_t mInteger;
31 : nscolor mColor;
32 : uint32_t mEnumValue;
33 : int32_t mPercent;
34 : mozilla::DeclarationBlock* mCSSDeclaration;
35 : mozilla::css::URLValue* mURL;
36 : mozilla::css::ImageValue* mImage;
37 : nsAttrValue::AtomArray* mAtomArray;
38 : nsIntMargin* mIntMargin;
39 : const nsSVGAngle* mSVGAngle;
40 : const nsSVGIntegerPair* mSVGIntegerPair;
41 : const nsSVGLength2* mSVGLength;
42 : const mozilla::SVGLengthList* mSVGLengthList;
43 : const mozilla::SVGNumberList* mSVGNumberList;
44 : const nsSVGNumberPair* mSVGNumberPair;
45 : const mozilla::SVGPathData* mSVGPathData;
46 : const mozilla::SVGPointList* mSVGPointList;
47 : const mozilla::SVGAnimatedPreserveAspectRatio* mSVGPreserveAspectRatio;
48 : const mozilla::SVGStringList* mSVGStringList;
49 : const mozilla::SVGTransformList* mSVGTransformList;
50 : const nsSVGViewBox* mSVGViewBox;
51 : };
52 : uint32_t mRefCount : 31;
53 : uint32_t mCached : 1;
54 : } mValue;
55 : double mDoubleValue;
56 : };
57 :
58 766 : MiscContainer()
59 766 : : mType(nsAttrValue::eColor),
60 766 : mStringBits(0)
61 : {
62 766 : MOZ_COUNT_CTOR(MiscContainer);
63 766 : mValue.mColor = 0;
64 766 : mValue.mRefCount = 0;
65 766 : mValue.mCached = 0;
66 766 : }
67 :
68 : protected:
69 : // Only nsAttrValue should be able to delete us.
70 : friend class nsAttrValue;
71 :
72 263 : ~MiscContainer()
73 263 : {
74 263 : if (IsRefCounted()) {
75 10 : MOZ_ASSERT(mValue.mRefCount == 0);
76 10 : MOZ_ASSERT(!mValue.mCached);
77 : }
78 263 : MOZ_COUNT_DTOR(MiscContainer);
79 263 : }
80 :
81 : public:
82 : bool GetString(nsAString& aString) const;
83 :
84 1579 : inline bool IsRefCounted() const
85 : {
86 : // Nothing stops us from refcounting (and sharing) other types of
87 : // MiscContainer (except eDoubleValue types) but there's no compelling
88 : // reason to.
89 1579 : return mType == nsAttrValue::eCSSDeclaration;
90 : }
91 :
92 26 : inline int32_t AddRef() {
93 26 : MOZ_ASSERT(IsRefCounted());
94 26 : return ++mValue.mRefCount;
95 : }
96 :
97 10 : inline int32_t Release() {
98 10 : MOZ_ASSERT(IsRefCounted());
99 10 : return --mValue.mRefCount;
100 : }
101 :
102 : void Cache();
103 : void Evict();
104 : };
105 :
106 : /**
107 : * Implementation of inline methods
108 : */
109 :
110 : inline int32_t
111 0 : nsAttrValue::GetIntegerValue() const
112 : {
113 0 : NS_PRECONDITION(Type() == eInteger, "wrong type");
114 0 : return (BaseType() == eIntegerBase)
115 0 : ? GetIntInternal()
116 0 : : GetMiscContainer()->mValue.mInteger;
117 : }
118 :
119 : inline int16_t
120 36 : nsAttrValue::GetEnumValue() const
121 : {
122 36 : NS_PRECONDITION(Type() == eEnum, "wrong type");
123 : // We don't need to worry about sign extension here since we're
124 : // returning an int16_t which will cut away the top bits.
125 : return static_cast<int16_t>((
126 36 : (BaseType() == eIntegerBase)
127 36 : ? static_cast<uint32_t>(GetIntInternal())
128 0 : : GetMiscContainer()->mValue.mEnumValue)
129 72 : >> NS_ATTRVALUE_ENUMTABLEINDEX_BITS);
130 : }
131 :
132 : inline float
133 0 : nsAttrValue::GetPercentValue() const
134 : {
135 0 : NS_PRECONDITION(Type() == ePercent, "wrong type");
136 0 : return ((BaseType() == eIntegerBase)
137 0 : ? GetIntInternal()
138 0 : : GetMiscContainer()->mValue.mPercent)
139 0 : / 100.0f;
140 : }
141 :
142 : inline nsAttrValue::AtomArray*
143 9625 : nsAttrValue::GetAtomArrayValue() const
144 : {
145 9625 : NS_PRECONDITION(Type() == eAtomArray, "wrong type");
146 9625 : return GetMiscContainer()->mValue.mAtomArray;
147 : }
148 :
149 : inline mozilla::DeclarationBlock*
150 45 : nsAttrValue::GetCSSDeclarationValue() const
151 : {
152 45 : NS_PRECONDITION(Type() == eCSSDeclaration, "wrong type");
153 45 : return GetMiscContainer()->mValue.mCSSDeclaration;
154 : }
155 :
156 : inline mozilla::css::URLValue*
157 : nsAttrValue::GetURLValue() const
158 : {
159 : NS_PRECONDITION(Type() == eURL, "wrong type");
160 : return GetMiscContainer()->mValue.mURL;
161 : }
162 :
163 : inline mozilla::css::ImageValue*
164 0 : nsAttrValue::GetImageValue() const
165 : {
166 0 : NS_PRECONDITION(Type() == eImage, "wrong type");
167 0 : return GetMiscContainer()->mValue.mImage;
168 : }
169 :
170 : inline double
171 0 : nsAttrValue::GetDoubleValue() const
172 : {
173 0 : NS_PRECONDITION(Type() == eDoubleValue, "wrong type");
174 0 : return GetMiscContainer()->mDoubleValue;
175 : }
176 :
177 : inline bool
178 0 : nsAttrValue::GetIntMarginValue(nsIntMargin& aMargin) const
179 : {
180 0 : NS_PRECONDITION(Type() == eIntMarginValue, "wrong type");
181 0 : nsIntMargin* m = GetMiscContainer()->mValue.mIntMargin;
182 0 : if (!m)
183 0 : return false;
184 0 : aMargin = *m;
185 0 : return true;
186 : }
187 :
188 : inline bool
189 380 : nsAttrValue::IsSVGType(ValueType aType) const
190 : {
191 380 : return aType >= eSVGTypesBegin && aType <= eSVGTypesEnd;
192 : }
193 :
194 : inline bool
195 2380 : nsAttrValue::StoresOwnData() const
196 : {
197 2380 : if (BaseType() != eOtherBase) {
198 2370 : return true;
199 : }
200 10 : ValueType t = Type();
201 10 : return t != eCSSDeclaration && !IsSVGType(t);
202 : }
203 :
204 : inline void
205 15221 : nsAttrValue::SetPtrValueAndType(void* aValue, ValueBaseType aType)
206 : {
207 15221 : NS_ASSERTION(!(NS_PTR_TO_INT32(aValue) & ~NS_ATTRVALUE_POINTERVALUE_MASK),
208 : "pointer not properly aligned, this will crash");
209 15221 : mBits = reinterpret_cast<intptr_t>(aValue) | aType;
210 15221 : }
211 :
212 : inline void
213 29035 : nsAttrValue::ResetIfSet()
214 : {
215 29035 : if (mBits) {
216 3240 : Reset();
217 : }
218 29035 : }
219 :
220 : inline MiscContainer*
221 32699 : nsAttrValue::GetMiscContainer() const
222 : {
223 32699 : NS_ASSERTION(BaseType() == eOtherBase, "wrong type");
224 32699 : return static_cast<MiscContainer*>(GetPtr());
225 : }
226 :
227 : inline int32_t
228 128 : nsAttrValue::GetIntInternal() const
229 : {
230 128 : NS_ASSERTION(BaseType() == eIntegerBase,
231 : "getting integer from non-integer");
232 : // Make sure we get a signed value.
233 : // Lets hope the optimizer optimizes this into a shift. Unfortunatly signed
234 : // bitshift right is implementaion dependant.
235 128 : return static_cast<int32_t>(mBits & ~NS_ATTRVALUE_INTEGERTYPE_MASK) /
236 128 : NS_ATTRVALUE_INTEGERTYPE_MULTIPLIER;
237 : }
238 :
239 : #endif
|