/src/mozilla-central/dom/base/nsAttrValue.h
Line | Count | Source (jump to first uncovered line) |
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 | | /* |
8 | | * A struct that represents the value (type and actual data) of an |
9 | | * attribute. |
10 | | */ |
11 | | |
12 | | #ifndef nsAttrValue_h___ |
13 | | #define nsAttrValue_h___ |
14 | | |
15 | | #include <type_traits> |
16 | | |
17 | | #include "nscore.h" |
18 | | #include "nsString.h" |
19 | | #include "nsStringBuffer.h" |
20 | | #include "nsColor.h" |
21 | | #include "nsCaseTreatment.h" |
22 | | #include "nsMargin.h" |
23 | | #include "nsCOMPtr.h" |
24 | | #include "nsStringFwd.h" |
25 | | #include "SVGAttrValueWrapper.h" |
26 | | #include "nsTArrayForwardDeclare.h" |
27 | | #include "nsAtom.h" |
28 | | #include "mozilla/AtomArray.h" |
29 | | #include "mozilla/MemoryReporting.h" |
30 | | #include "mozilla/dom/BindingDeclarations.h" |
31 | | #include "mozilla/EnumTypeTraits.h" |
32 | | |
33 | | class nsIDocument; |
34 | | class nsIURI; |
35 | | class nsStyledElement; |
36 | | struct MiscContainer; |
37 | | |
38 | | namespace mozilla { |
39 | | class DeclarationBlock; |
40 | | } // namespace mozilla |
41 | | |
42 | | #define NS_ATTRVALUE_MAX_STRINGLENGTH_ATOM 12 |
43 | | |
44 | | const uintptr_t NS_ATTRVALUE_BASETYPE_MASK = 3; |
45 | | #define NS_ATTRVALUE_POINTERVALUE_MASK (~NS_ATTRVALUE_BASETYPE_MASK) |
46 | | |
47 | 0 | #define NS_ATTRVALUE_INTEGERTYPE_BITS 4 |
48 | 0 | #define NS_ATTRVALUE_INTEGERTYPE_MASK (uintptr_t((1 << NS_ATTRVALUE_INTEGERTYPE_BITS) - 1)) |
49 | 0 | #define NS_ATTRVALUE_INTEGERTYPE_MULTIPLIER (1 << NS_ATTRVALUE_INTEGERTYPE_BITS) |
50 | | #define NS_ATTRVALUE_INTEGERTYPE_MAXVALUE ((1 << (31 - NS_ATTRVALUE_INTEGERTYPE_BITS)) - 1) |
51 | | #define NS_ATTRVALUE_INTEGERTYPE_MINVALUE (-NS_ATTRVALUE_INTEGERTYPE_MAXVALUE - 1) |
52 | | |
53 | 0 | #define NS_ATTRVALUE_ENUMTABLEINDEX_BITS (32 - 16 - NS_ATTRVALUE_INTEGERTYPE_BITS) |
54 | | #define NS_ATTRVALUE_ENUMTABLE_VALUE_NEEDS_TO_UPPER (1 << (NS_ATTRVALUE_ENUMTABLEINDEX_BITS - 1)) |
55 | | #define NS_ATTRVALUE_ENUMTABLEINDEX_MAXVALUE (NS_ATTRVALUE_ENUMTABLE_VALUE_NEEDS_TO_UPPER - 1) |
56 | | #define NS_ATTRVALUE_ENUMTABLEINDEX_MASK \ |
57 | | (uintptr_t((((1 << NS_ATTRVALUE_ENUMTABLEINDEX_BITS) - 1) &~ NS_ATTRVALUE_ENUMTABLE_VALUE_NEEDS_TO_UPPER))) |
58 | | |
59 | | /** |
60 | | * A class used to construct a nsString from a nsStringBuffer (we might |
61 | | * want to move this to nsString at some point). |
62 | | * |
63 | | * WARNING: Note that nsCheapString doesn't take an explicit length -- it |
64 | | * assumes the string is maximally large, given the nsStringBuffer's storage |
65 | | * size. This means the given string buffer *must* be sized exactly correctly |
66 | | * for the string it contains (including one byte for a null terminator). If |
67 | | * it has any unused storage space, then that will result in bogus characters |
68 | | * at the end of our nsCheapString. |
69 | | */ |
70 | | class nsCheapString : public nsString { |
71 | | public: |
72 | | explicit nsCheapString(nsStringBuffer* aBuf) |
73 | 0 | { |
74 | 0 | if (aBuf) |
75 | 0 | aBuf->ToString(aBuf->StorageSize()/sizeof(char16_t) - 1, *this); |
76 | 0 | } |
77 | | }; |
78 | | |
79 | | class nsAttrValue { |
80 | | friend struct MiscContainer; |
81 | | public: |
82 | | // This has to be the same as in ValueBaseType |
83 | | enum ValueType { |
84 | | eString = 0x00, // 00 |
85 | | // 01 this value indicates a 'misc' struct |
86 | | eAtom = 0x02, // 10 |
87 | | eInteger = 0x03, // 0011 |
88 | | eColor = 0x07, // 0111 |
89 | | eEnum = 0x0B, // 1011 This should eventually die |
90 | | ePercent = 0x0F, // 1111 |
91 | | // Values below here won't matter, they'll be always stored in the 'misc' |
92 | | // struct. |
93 | | eCSSDeclaration = 0x10, |
94 | | eURL, |
95 | | eImage, |
96 | | eAtomArray, |
97 | | eDoubleValue, |
98 | | eIntMarginValue, |
99 | | eSVGAngle, |
100 | | eSVGTypesBegin = eSVGAngle, |
101 | | eSVGIntegerPair, |
102 | | eSVGLength, |
103 | | eSVGLengthList, |
104 | | eSVGNumberList, |
105 | | eSVGNumberPair, |
106 | | eSVGPathData, |
107 | | eSVGPointList, |
108 | | eSVGPreserveAspectRatio, |
109 | | eSVGStringList, |
110 | | eSVGTransformList, |
111 | | eSVGViewBox, |
112 | | eSVGTypesEnd = eSVGViewBox, |
113 | | }; |
114 | | |
115 | | nsAttrValue(); |
116 | | nsAttrValue(const nsAttrValue& aOther); |
117 | | explicit nsAttrValue(const nsAString& aValue); |
118 | | explicit nsAttrValue(nsAtom* aValue); |
119 | | nsAttrValue(already_AddRefed<mozilla::DeclarationBlock> aValue, |
120 | | const nsAString* aSerialized); |
121 | | explicit nsAttrValue(const nsIntMargin& aValue); |
122 | | ~nsAttrValue(); |
123 | | |
124 | | inline const nsAttrValue& operator=(const nsAttrValue& aOther); |
125 | | |
126 | | static nsresult Init(); |
127 | | static void Shutdown(); |
128 | | |
129 | | inline ValueType Type() const; |
130 | | // Returns true when this value is self-contained and does not depend on |
131 | | // the state of its associated element. |
132 | | // Returns false when this value depends on the state of its associated |
133 | | // element and may be invalid if that state has been changed by changes to |
134 | | // that element state outside of attribute setting. |
135 | | inline bool StoresOwnData() const; |
136 | | |
137 | | void Reset(); |
138 | | |
139 | | void SetTo(const nsAttrValue& aOther); |
140 | | void SetTo(const nsAString& aValue); |
141 | | void SetTo(nsAtom* aValue); |
142 | | void SetTo(int16_t aInt); |
143 | | void SetTo(int32_t aInt, const nsAString* aSerialized); |
144 | | void SetTo(double aValue, const nsAString* aSerialized); |
145 | | void SetTo(already_AddRefed<mozilla::DeclarationBlock> aValue, |
146 | | const nsAString* aSerialized); |
147 | | void SetTo(nsIURI* aValue, const nsAString* aSerialized); |
148 | | void SetTo(const nsIntMargin& aValue); |
149 | | void SetTo(const nsSVGAngle& aValue, const nsAString* aSerialized); |
150 | | void SetTo(const nsSVGIntegerPair& aValue, const nsAString* aSerialized); |
151 | | void SetTo(const nsSVGLength2& aValue, const nsAString* aSerialized); |
152 | | void SetTo(const mozilla::SVGLengthList& aValue, |
153 | | const nsAString* aSerialized); |
154 | | void SetTo(const mozilla::SVGNumberList& aValue, |
155 | | const nsAString* aSerialized); |
156 | | void SetTo(const nsSVGNumberPair& aValue, const nsAString* aSerialized); |
157 | | void SetTo(const mozilla::SVGPathData& aValue, const nsAString* aSerialized); |
158 | | void SetTo(const mozilla::SVGPointList& aValue, const nsAString* aSerialized); |
159 | | void SetTo(const mozilla::SVGAnimatedPreserveAspectRatio& aValue, |
160 | | const nsAString* aSerialized); |
161 | | void SetTo(const mozilla::SVGStringList& aValue, |
162 | | const nsAString* aSerialized); |
163 | | void SetTo(const mozilla::SVGTransformList& aValue, |
164 | | const nsAString* aSerialized); |
165 | | void SetTo(const nsSVGViewBox& aValue, const nsAString* aSerialized); |
166 | | |
167 | | /** |
168 | | * Sets this object with the string or atom representation of aValue. |
169 | | * |
170 | | * After calling this method, this object will have type eString unless the |
171 | | * type of aValue is eAtom, in which case this object will also have type |
172 | | * eAtom. |
173 | | */ |
174 | | void SetToSerialized(const nsAttrValue& aValue); |
175 | | |
176 | | void SwapValueWith(nsAttrValue& aOther); |
177 | | |
178 | | void ToString(nsAString& aResult) const; |
179 | | inline void ToString(mozilla::dom::DOMString& aResult) const; |
180 | | |
181 | | /** |
182 | | * Returns the value of this object as an atom. If necessary, the value will |
183 | | * first be serialised using ToString before converting to an atom. |
184 | | */ |
185 | | already_AddRefed<nsAtom> GetAsAtom() const; |
186 | | |
187 | | // Methods to get value. These methods do not convert so only use them |
188 | | // to retrieve the datatype that this nsAttrValue has. |
189 | | inline bool IsEmptyString() const; |
190 | | const nsCheapString GetStringValue() const; |
191 | | inline nsAtom* GetAtomValue() const; |
192 | | inline int32_t GetIntegerValue() const; |
193 | | bool GetColorValue(nscolor& aColor) const; |
194 | | inline int16_t GetEnumValue() const; |
195 | | inline float GetPercentValue() const; |
196 | | inline mozilla::AtomArray* GetAtomArrayValue() const; |
197 | | inline mozilla::DeclarationBlock* GetCSSDeclarationValue() const; |
198 | | inline nsIURI* GetURLValue() const; |
199 | | inline double GetDoubleValue() const; |
200 | | bool GetIntMarginValue(nsIntMargin& aMargin) const; |
201 | | |
202 | | /** |
203 | | * Returns the string corresponding to the stored enum value. |
204 | | * |
205 | | * @param aResult the string representing the enum tag |
206 | | * @param aRealTag wheter we want to have the real tag or the saved one |
207 | | */ |
208 | | void GetEnumString(nsAString& aResult, bool aRealTag) const; |
209 | | |
210 | | // Methods to get access to atoms we may have |
211 | | // Returns the number of atoms we have; 0 if we have none. It's OK |
212 | | // to call this without checking the type first; it handles that. |
213 | | uint32_t GetAtomCount() const; |
214 | | // Returns the atom at aIndex (0-based). Do not call this with |
215 | | // aIndex >= GetAtomCount(). |
216 | | nsAtom* AtomAt(int32_t aIndex) const; |
217 | | |
218 | | uint32_t HashValue() const; |
219 | | bool Equals(const nsAttrValue& aOther) const; |
220 | | // aCaseSensitive == eIgnoreCase means ASCII case-insenstive matching |
221 | | bool Equals(const nsAString& aValue, nsCaseTreatment aCaseSensitive) const; |
222 | | bool Equals(nsAtom* aValue, nsCaseTreatment aCaseSensitive) const; |
223 | | |
224 | | /** |
225 | | * Compares this object with aOther according to their string representation. |
226 | | * |
227 | | * For example, when called on an object with type eInteger and value 4, and |
228 | | * given aOther of type eString and value "4", EqualsAsStrings will return |
229 | | * true (while Equals will return false). |
230 | | */ |
231 | | bool EqualsAsStrings(const nsAttrValue& aOther) const; |
232 | | |
233 | | /** |
234 | | * Returns true if this AttrValue is equal to the given atom, or is an |
235 | | * array which contains the given atom. |
236 | | */ |
237 | | bool Contains(nsAtom* aValue, nsCaseTreatment aCaseSensitive) const; |
238 | | /** |
239 | | * Returns true if this AttrValue is an atom equal to the given |
240 | | * string, or is an array of atoms which contains the given string. |
241 | | * This always does a case-sensitive comparison. |
242 | | */ |
243 | | bool Contains(const nsAString& aValue) const; |
244 | | |
245 | | void ParseAtom(const nsAString& aValue); |
246 | | void ParseAtomArray(const nsAString& aValue); |
247 | | void ParseStringOrAtom(const nsAString& aValue); |
248 | | |
249 | | /** |
250 | | * Structure for a mapping from int (enum) values to strings. When you use |
251 | | * it you generally create an array of them. |
252 | | * Instantiate like this: |
253 | | * EnumTable myTable[] = { |
254 | | * { "string1", 1 }, |
255 | | * { "string2", 2 }, |
256 | | * { nullptr, 0 } |
257 | | * } |
258 | | */ |
259 | | struct EnumTable { |
260 | | // EnumTable can be initialized either with an int16_t value |
261 | | // or a value of an enumeration type that can fit within an int16_t. |
262 | | |
263 | | constexpr EnumTable(const char* aTag, int16_t aValue) |
264 | | : tag(aTag) |
265 | | , value(aValue) |
266 | 0 | { |
267 | 0 | } |
268 | | |
269 | | template<typename T, |
270 | | typename = typename std::enable_if<std::is_enum<T>::value>::type> |
271 | | constexpr EnumTable(const char* aTag, T aValue) |
272 | | : tag(aTag) |
273 | | , value(static_cast<int16_t>(aValue)) |
274 | | { |
275 | | static_assert(mozilla::EnumTypeFitsWithin<T, int16_t>::value, |
276 | | "aValue must be an enum that fits within int16_t"); |
277 | | } |
278 | | |
279 | | /** The string the value maps to */ |
280 | | const char* tag; |
281 | | /** The enum value that maps to this string */ |
282 | | int16_t value; |
283 | | }; |
284 | | |
285 | | /** |
286 | | * Parse into an enum value. |
287 | | * |
288 | | * @param aValue the string to find the value for |
289 | | * @param aTable the enumeration to map with |
290 | | * @param aCaseSensitive specify if the parsing has to be case sensitive |
291 | | * @param aDefaultValue if non-null, this function will always return true. |
292 | | * Failure to parse aValue as one of the values in aTable will just |
293 | | * cause aDefaultValue->value to be stored as the enumeration value. |
294 | | * @return whether the enum value was found or not |
295 | | */ |
296 | | bool ParseEnumValue(const nsAString& aValue, |
297 | | const EnumTable* aTable, |
298 | | bool aCaseSensitive, |
299 | | const EnumTable* aDefaultValue = nullptr); |
300 | | |
301 | | /** |
302 | | * Parse a string into an integer. Can optionally parse percent (n%). |
303 | | * This method explicitly sets a lower bound of zero on the element, |
304 | | * whether it be percent or raw integer. |
305 | | * |
306 | | * @param aString the string to parse |
307 | | * @return whether the value could be parsed |
308 | | * |
309 | | * @see http://www.whatwg.org/html/#rules-for-parsing-dimension-values |
310 | | */ |
311 | | bool ParseSpecialIntValue(const nsAString& aString); |
312 | | |
313 | | |
314 | | /** |
315 | | * Parse a string value into an integer. |
316 | | * |
317 | | * @param aString the string to parse |
318 | | * @return whether the value could be parsed |
319 | | */ |
320 | 0 | bool ParseIntValue(const nsAString& aString) { |
321 | 0 | return ParseIntWithBounds(aString, INT32_MIN, INT32_MAX); |
322 | 0 | } |
323 | | |
324 | | /** |
325 | | * Parse a string value into an integer with minimum value and maximum value. |
326 | | * |
327 | | * @param aString the string to parse |
328 | | * @param aMin the minimum value (if value is less it will be bumped up) |
329 | | * @param aMax the maximum value (if value is greater it will be chopped down) |
330 | | * @return whether the value could be parsed |
331 | | */ |
332 | | bool ParseIntWithBounds(const nsAString& aString, int32_t aMin, |
333 | | int32_t aMax = INT32_MAX); |
334 | | |
335 | | /** |
336 | | * Parse a string value into an integer with a fallback for invalid values. |
337 | | * Also allows clamping to a maximum value to support col/colgroup.span (this |
338 | | * is not per spec right now). |
339 | | * |
340 | | * @param aString the string to parse |
341 | | * @param aDefault the default value |
342 | | * @param aMax the maximum value (if value is greater it will be clamped) |
343 | | */ |
344 | | void ParseIntWithFallback(const nsAString& aString, int32_t aDefault, |
345 | | int32_t aMax = INT32_MAX); |
346 | | |
347 | | /** |
348 | | * Parse a string value into a non-negative integer. |
349 | | * This method follows the rules for parsing non-negative integer from: |
350 | | * http://dev.w3.org/html5/spec/infrastructure.html#rules-for-parsing-non-negative-integers |
351 | | * |
352 | | * @param aString the string to parse |
353 | | * @return whether the value is valid |
354 | | */ |
355 | | bool ParseNonNegativeIntValue(const nsAString& aString); |
356 | | |
357 | | /** |
358 | | * Parse a string value into a clamped non-negative integer. |
359 | | * This method follows the rules for parsing non-negative integer from: |
360 | | * https://html.spec.whatwg.org/multipage/infrastructure.html#clamped-to-the-range |
361 | | * |
362 | | * @param aString the string to parse |
363 | | * @param aDefault value to return for negative or invalid values |
364 | | * @param aMin minimum value |
365 | | * @param aMax maximum value |
366 | | */ |
367 | | void ParseClampedNonNegativeInt(const nsAString& aString, int32_t aDefault, |
368 | | int32_t aMin, int32_t aMax); |
369 | | |
370 | | /** |
371 | | * Parse a string value into a positive integer. |
372 | | * This method follows the rules for parsing non-negative integer from: |
373 | | * http://dev.w3.org/html5/spec/infrastructure.html#rules-for-parsing-non-negative-integers |
374 | | * In addition of these rules, the value has to be greater than zero. |
375 | | * |
376 | | * This is generally used for parsing content attributes which reflecting IDL |
377 | | * attributes are limited to only non-negative numbers greater than zero, see: |
378 | | * http://dev.w3.org/html5/spec/common-dom-interfaces.html#limited-to-only-non-negative-numbers-greater-than-zero |
379 | | * |
380 | | * @param aString the string to parse |
381 | | * @return whether the value was valid |
382 | | */ |
383 | | bool ParsePositiveIntValue(const nsAString& aString); |
384 | | |
385 | | /** |
386 | | * Parse a string into a color. This implements what HTML5 calls the |
387 | | * "rules for parsing a legacy color value". |
388 | | * |
389 | | * @param aString the string to parse |
390 | | * @return whether the value could be parsed |
391 | | */ |
392 | | bool ParseColor(const nsAString& aString); |
393 | | |
394 | | /** |
395 | | * Parse a string value into a double-precision floating point value. |
396 | | * |
397 | | * @param aString the string to parse |
398 | | * @return whether the value could be parsed |
399 | | */ |
400 | | bool ParseDoubleValue(const nsAString& aString); |
401 | | |
402 | | /** |
403 | | * Parse a lazy URI. This just sets up the storage for the URI; it |
404 | | * doesn't actually allocate it. |
405 | | */ |
406 | | bool ParseLazyURIValue(const nsAString& aString); |
407 | | |
408 | | /** |
409 | | * Parse a margin string of format 'top, right, bottom, left' into |
410 | | * an nsIntMargin. |
411 | | * |
412 | | * @param aString the string to parse |
413 | | * @return whether the value could be parsed |
414 | | */ |
415 | | bool ParseIntMarginValue(const nsAString& aString); |
416 | | |
417 | | /** |
418 | | * Parse a string into a CSS style rule. |
419 | | * |
420 | | * @param aString the style attribute value to be parsed. |
421 | | * @param aElement the element the attribute is set on. |
422 | | * @param aMaybeScriptedPrincipal if available, the scripted principal |
423 | | * responsible for this attribute value, as passed to |
424 | | * Element::ParseAttribute. |
425 | | */ |
426 | | bool ParseStyleAttribute(const nsAString& aString, |
427 | | nsIPrincipal* aMaybeScriptedPrincipal, |
428 | | nsStyledElement* aElement); |
429 | | |
430 | | size_t SizeOfExcludingThis(mozilla::MallocSizeOf aMallocSizeOf) const; |
431 | | |
432 | | private: |
433 | | // These have to be the same as in ValueType |
434 | | enum ValueBaseType { |
435 | | eStringBase = eString, // 00 |
436 | | eOtherBase = 0x01, // 01 |
437 | | eAtomBase = eAtom, // 10 |
438 | | eIntegerBase = 0x03 // 11 |
439 | | }; |
440 | | |
441 | | inline ValueBaseType BaseType() const; |
442 | | inline bool IsSVGType(ValueType aType) const; |
443 | | |
444 | | /** |
445 | | * Get the index of an EnumTable in the sEnumTableArray. |
446 | | * If the EnumTable is not in the sEnumTableArray, it is added. |
447 | | * |
448 | | * @param aTable the EnumTable to get the index of. |
449 | | * @return the index of the EnumTable. |
450 | | */ |
451 | | int16_t GetEnumTableIndex(const EnumTable* aTable); |
452 | | |
453 | | inline void SetPtrValueAndType(void* aValue, ValueBaseType aType); |
454 | | void SetIntValueAndType(int32_t aValue, ValueType aType, |
455 | | const nsAString* aStringValue); |
456 | | void SetColorValue(nscolor aColor, const nsAString& aString); |
457 | | void SetMiscAtomOrString(const nsAString* aValue); |
458 | | void ResetMiscAtomOrString(); |
459 | | void SetSVGType(ValueType aType, const void* aValue, |
460 | | const nsAString* aSerialized); |
461 | | inline void ResetIfSet(); |
462 | | |
463 | | inline void* GetPtr() const; |
464 | | inline MiscContainer* GetMiscContainer() const; |
465 | | inline int32_t GetIntInternal() const; |
466 | | |
467 | | // Clears the current MiscContainer. This will return null if there is no |
468 | | // existing container. |
469 | | MiscContainer* ClearMiscContainer(); |
470 | | // Like ClearMiscContainer, except allocates a new container if one does not |
471 | | // exist already. |
472 | | MiscContainer* EnsureEmptyMiscContainer(); |
473 | | bool EnsureEmptyAtomArray(); |
474 | | already_AddRefed<nsStringBuffer> |
475 | | GetStringBuffer(const nsAString& aValue) const; |
476 | | // Given an enum table and a particular entry in that table, return |
477 | | // the actual integer value we should store. |
478 | | int32_t EnumTableEntryToValue(const EnumTable* aEnumTable, |
479 | | const EnumTable* aTableEntry); |
480 | | |
481 | | static MiscContainer* AllocMiscContainer(); |
482 | | static void DeallocMiscContainer(MiscContainer* aCont); |
483 | | |
484 | | static nsTArray<const EnumTable*>* sEnumTableArray; |
485 | | static MiscContainer* sMiscContainerCache; |
486 | | |
487 | | uintptr_t mBits; |
488 | | }; |
489 | | |
490 | | inline const nsAttrValue& |
491 | | nsAttrValue::operator=(const nsAttrValue& aOther) |
492 | 0 | { |
493 | 0 | SetTo(aOther); |
494 | 0 | return *this; |
495 | 0 | } |
496 | | |
497 | | inline nsAttrValue::ValueBaseType |
498 | | nsAttrValue::BaseType() const |
499 | | { |
500 | | return static_cast<ValueBaseType>(mBits & NS_ATTRVALUE_BASETYPE_MASK); |
501 | | } |
502 | | |
503 | | inline void* |
504 | | nsAttrValue::GetPtr() const |
505 | | { |
506 | | NS_ASSERTION(BaseType() != eIntegerBase, |
507 | | "getting pointer from non-pointer"); |
508 | | return reinterpret_cast<void*>(mBits & NS_ATTRVALUE_POINTERVALUE_MASK); |
509 | | } |
510 | | |
511 | | inline bool |
512 | | nsAttrValue::IsEmptyString() const |
513 | 0 | { |
514 | 0 | return !mBits; |
515 | 0 | } |
516 | | |
517 | | #endif |