1 : /* -*- Mode: C++; tab-width: 2; indent-tabs-mode: nil; c-basic-offset: 2 -*- */
2 : /* ***** BEGIN LICENSE BLOCK *****
3 : * Version: MPL 1.1/GPL 2.0/LGPL 2.1
4 : *
5 : * The contents of this file are subject to the Mozilla Public License Version
6 : * 1.1 (the "License"); you may not use this file except in compliance with
7 : * the License. You may obtain a copy of the License at
8 : * http://www.mozilla.org/MPL/
9 : *
10 : * Software distributed under the License is distributed on an "AS IS" basis,
11 : * WITHOUT WARRANTY OF ANY KIND, either express or implied. See the License
12 : * for the specific language governing rights and limitations under the
13 : * License.
14 : *
15 : * The Original Code is mozilla.org code.
16 : *
17 : * The Initial Developer of the Original Code is
18 : * IBM Corporation.
19 : * Portions created by the Initial Developer are Copyright (C) 2003
20 : * IBM Corporation. All Rights Reserved.
21 : *
22 : * Contributor(s):
23 : * IBM Corporation
24 : *
25 : * Alternatively, the contents of this file may be used under the terms of
26 : * either the GNU General Public License Version 2 or later (the "GPL"), or
27 : * the GNU Lesser General Public License Version 2.1 or later (the "LGPL"),
28 : * in which case the provisions of the GPL or the LGPL are applicable instead
29 : * of those above. If you wish to allow use of your version of this file only
30 : * under the terms of either the GPL or the LGPL, and not to allow others to
31 : * use your version of this file under the terms of the MPL, indicate your
32 : * decision by deleting the provisions above and replace them with the notice
33 : * and other provisions required by the GPL or the LGPL. If you do not delete
34 : * the provisions above, a recipient may use your version of this file under
35 : * the terms of any one of the MPL, the GPL or the LGPL.
36 : *
37 : * ***** END LICENSE BLOCK ***** */
38 :
39 : /*
40 : * A struct that represents the value (type and actual data) of an
41 : * attribute.
42 : */
43 :
44 : #ifndef nsAttrValue_h___
45 : #define nsAttrValue_h___
46 :
47 : #include "nscore.h"
48 : #include "nsString.h"
49 : #include "nsStringBuffer.h"
50 : #include "nsColor.h"
51 : #include "nsCaseTreatment.h"
52 : #include "nsMargin.h"
53 : #include "nsCOMPtr.h"
54 : #include "SVGAttrValueWrapper.h"
55 :
56 : typedef PRUptrdiff PtrBits;
57 : class nsAString;
58 : class nsIAtom;
59 : class nsIDocument;
60 : template<class E, class A> class nsTArray;
61 : struct nsTArrayDefaultAllocator;
62 :
63 : namespace mozilla {
64 : namespace css {
65 : class StyleRule;
66 : }
67 : }
68 :
69 : #define NS_ATTRVALUE_MAX_STRINGLENGTH_ATOM 12
70 :
71 : #define NS_ATTRVALUE_BASETYPE_MASK (PtrBits(3))
72 : #define NS_ATTRVALUE_POINTERVALUE_MASK (~NS_ATTRVALUE_BASETYPE_MASK)
73 :
74 : #define NS_ATTRVALUE_INTEGERTYPE_BITS 4
75 : #define NS_ATTRVALUE_INTEGERTYPE_MASK (PtrBits((1 << NS_ATTRVALUE_INTEGERTYPE_BITS) - 1))
76 : #define NS_ATTRVALUE_INTEGERTYPE_MULTIPLIER (1 << NS_ATTRVALUE_INTEGERTYPE_BITS)
77 : #define NS_ATTRVALUE_INTEGERTYPE_MAXVALUE ((1 << (31 - NS_ATTRVALUE_INTEGERTYPE_BITS)) - 1)
78 : #define NS_ATTRVALUE_INTEGERTYPE_MINVALUE (-NS_ATTRVALUE_INTEGERTYPE_MAXVALUE - 1)
79 :
80 : #define NS_ATTRVALUE_ENUMTABLEINDEX_BITS (32 - 16 - NS_ATTRVALUE_INTEGERTYPE_BITS)
81 : #define NS_ATTRVALUE_ENUMTABLE_VALUE_NEEDS_TO_UPPER (1 << (NS_ATTRVALUE_ENUMTABLEINDEX_BITS - 1))
82 : #define NS_ATTRVALUE_ENUMTABLEINDEX_MAXVALUE (NS_ATTRVALUE_ENUMTABLE_VALUE_NEEDS_TO_UPPER - 1)
83 : #define NS_ATTRVALUE_ENUMTABLEINDEX_MASK \
84 : (PtrBits((((1 << NS_ATTRVALUE_ENUMTABLEINDEX_BITS) - 1) &~ NS_ATTRVALUE_ENUMTABLE_VALUE_NEEDS_TO_UPPER)))
85 :
86 : /**
87 : * A class used to construct a nsString from a nsStringBuffer (we might
88 : * want to move this to nsString at some point).
89 : */
90 11455 : class nsCheapString : public nsString {
91 : public:
92 11455 : nsCheapString(nsStringBuffer* aBuf)
93 11455 : {
94 11455 : if (aBuf)
95 0 : aBuf->ToString(aBuf->StorageSize()/2 - 1, *this);
96 11455 : }
97 : };
98 :
99 : class nsAttrValue {
100 : public:
101 : typedef nsTArray< nsCOMPtr<nsIAtom> > AtomArray;
102 :
103 : nsAttrValue();
104 : nsAttrValue(const nsAttrValue& aOther);
105 : explicit nsAttrValue(const nsAString& aValue);
106 : explicit nsAttrValue(nsIAtom* aValue);
107 : nsAttrValue(mozilla::css::StyleRule* aValue, const nsAString* aSerialized);
108 : explicit nsAttrValue(const nsIntMargin& aValue);
109 : ~nsAttrValue();
110 :
111 : inline const nsAttrValue& operator=(const nsAttrValue& aOther);
112 :
113 : static nsresult Init();
114 : static void Shutdown();
115 :
116 : // This has to be the same as in ValueBaseType
117 : enum ValueType {
118 : eString = 0x00, // 00
119 : // 01 this value indicates an 'misc' struct
120 : eAtom = 0x02, // 10
121 : eInteger = 0x03, // 0011
122 : eColor = 0x07, // 0111
123 : eEnum = 0x0B, // 1011 This should eventually die
124 : ePercent = 0x0F, // 1111
125 : // Values below here won't matter, they'll be always stored in the 'misc'
126 : // struct.
127 : eCSSStyleRule = 0x10
128 : ,eAtomArray = 0x11
129 : ,eDoubleValue = 0x12
130 : ,eIntMarginValue = 0x13
131 : ,eSVGTypesBegin = 0x14
132 : ,eSVGAngle = eSVGTypesBegin
133 : ,eSVGIntegerPair = 0x15
134 : ,eSVGLength = 0x16
135 : ,eSVGLengthList = 0x17
136 : ,eSVGNumberList = 0x18
137 : ,eSVGNumberPair = 0x19
138 : ,eSVGPathData = 0x20
139 : ,eSVGPointList = 0x21
140 : ,eSVGPreserveAspectRatio = 0x22
141 : ,eSVGStringList = 0x23
142 : ,eSVGTransformList = 0x24
143 : ,eSVGViewBox = 0x25
144 : ,eSVGTypesEnd = 0x34
145 : };
146 :
147 : ValueType Type() const;
148 :
149 : void Reset();
150 :
151 : void SetTo(const nsAttrValue& aOther);
152 : void SetTo(const nsAString& aValue);
153 : void SetTo(nsIAtom* aValue);
154 : void SetTo(PRInt16 aInt);
155 : void SetTo(PRInt32 aInt, const nsAString* aSerialized);
156 : void SetTo(double aValue, const nsAString* aSerialized);
157 : void SetTo(mozilla::css::StyleRule* aValue, const nsAString* aSerialized);
158 : void SetTo(const nsIntMargin& aValue);
159 : void SetTo(const nsSVGAngle& aValue, const nsAString* aSerialized);
160 : void SetTo(const nsSVGIntegerPair& aValue, const nsAString* aSerialized);
161 : void SetTo(const nsSVGLength2& aValue, const nsAString* aSerialized);
162 : void SetTo(const mozilla::SVGLengthList& aValue,
163 : const nsAString* aSerialized);
164 : void SetTo(const mozilla::SVGNumberList& aValue,
165 : const nsAString* aSerialized);
166 : void SetTo(const nsSVGNumberPair& aValue, const nsAString* aSerialized);
167 : void SetTo(const mozilla::SVGPathData& aValue, const nsAString* aSerialized);
168 : void SetTo(const mozilla::SVGPointList& aValue, const nsAString* aSerialized);
169 : void SetTo(const mozilla::SVGAnimatedPreserveAspectRatio& aValue,
170 : const nsAString* aSerialized);
171 : void SetTo(const mozilla::SVGStringList& aValue,
172 : const nsAString* aSerialized);
173 : void SetTo(const mozilla::SVGTransformList& aValue,
174 : const nsAString* aSerialized);
175 : void SetTo(const nsSVGViewBox& aValue, const nsAString* aSerialized);
176 :
177 : /**
178 : * Sets this object with the string or atom representation of aValue.
179 : *
180 : * After calling this method, this object will have type eString unless the
181 : * type of aValue is eAtom, in which case this object will also have type
182 : * eAtom.
183 : */
184 : void SetToSerialized(const nsAttrValue& aValue);
185 :
186 : void SwapValueWith(nsAttrValue& aOther);
187 :
188 : void ToString(nsAString& aResult) const;
189 : /**
190 : * Returns the value of this object as an atom. If necessary, the value will
191 : * first be serialised using ToString before converting to an atom.
192 : */
193 : already_AddRefed<nsIAtom> GetAsAtom() const;
194 :
195 : // Methods to get value. These methods do not convert so only use them
196 : // to retrieve the datatype that this nsAttrValue has.
197 : inline bool IsEmptyString() const;
198 : const nsCheapString GetStringValue() const;
199 : inline nsIAtom* GetAtomValue() const;
200 : inline PRInt32 GetIntegerValue() const;
201 : bool GetColorValue(nscolor& aColor) const;
202 : inline PRInt16 GetEnumValue() const;
203 : inline float GetPercentValue() const;
204 : inline AtomArray* GetAtomArrayValue() const;
205 : inline mozilla::css::StyleRule* GetCSSStyleRuleValue() const;
206 : inline double GetDoubleValue() const;
207 : bool GetIntMarginValue(nsIntMargin& aMargin) const;
208 :
209 : /**
210 : * Returns the string corresponding to the stored enum value.
211 : *
212 : * @param aResult the string representing the enum tag
213 : * @param aRealTag wheter we want to have the real tag or the saved one
214 : */
215 : void GetEnumString(nsAString& aResult, bool aRealTag) const;
216 :
217 : // Methods to get access to atoms we may have
218 : // Returns the number of atoms we have; 0 if we have none. It's OK
219 : // to call this without checking the type first; it handles that.
220 : PRUint32 GetAtomCount() const;
221 : // Returns the atom at aIndex (0-based). Do not call this with
222 : // aIndex >= GetAtomCount().
223 : nsIAtom* AtomAt(PRInt32 aIndex) const;
224 :
225 : PRUint32 HashValue() const;
226 : bool Equals(const nsAttrValue& aOther) const;
227 : bool Equals(const nsAString& aValue, nsCaseTreatment aCaseSensitive) const;
228 : bool Equals(nsIAtom* aValue, nsCaseTreatment aCaseSensitive) const;
229 :
230 : /**
231 : * Compares this object with aOther according to their string representation.
232 : *
233 : * For example, when called on an object with type eInteger and value 4, and
234 : * given aOther of type eString and value "4", EqualsAsStrings will return
235 : * true (while Equals will return false).
236 : */
237 : bool EqualsAsStrings(const nsAttrValue& aOther) const;
238 :
239 : /**
240 : * Returns true if this AttrValue is equal to the given atom, or is an
241 : * array which contains the given atom.
242 : */
243 : bool Contains(nsIAtom* aValue, nsCaseTreatment aCaseSensitive) const;
244 : /**
245 : * Returns true if this AttrValue is an atom equal to the given
246 : * string, or is an array of atoms which contains the given string.
247 : * This always does a case-sensitive comparison.
248 : */
249 : bool Contains(const nsAString& aValue) const;
250 :
251 : void ParseAtom(const nsAString& aValue);
252 : void ParseAtomArray(const nsAString& aValue);
253 : void ParseStringOrAtom(const nsAString& aValue);
254 :
255 : /**
256 : * Structure for a mapping from int (enum) values to strings. When you use
257 : * it you generally create an array of them.
258 : * Instantiate like this:
259 : * EnumTable myTable[] = {
260 : * { "string1", 1 },
261 : * { "string2", 2 },
262 : * { 0 }
263 : * }
264 : */
265 : struct EnumTable {
266 : /** The string the value maps to */
267 : const char* tag;
268 : /** The enum value that maps to this string */
269 : PRInt16 value;
270 : };
271 :
272 : /**
273 : * Parse into an enum value.
274 : *
275 : * @param aValue the string to find the value for
276 : * @param aTable the enumeration to map with
277 : * @param aCaseSensitive specify if the parsing has to be case sensitive
278 : * @param aDefaultValue if non-null, this function will always return true.
279 : * Failure to parse aValue as one of the values in aTable will just
280 : * cause aDefaultValue->value to be stored as the enumeration value.
281 : * @return whether the enum value was found or not
282 : */
283 : bool ParseEnumValue(const nsAString& aValue,
284 : const EnumTable* aTable,
285 : bool aCaseSensitive,
286 : const EnumTable* aDefaultValue = nsnull);
287 :
288 : /**
289 : * Parse a string into an integer. Can optionally parse percent (n%).
290 : * This method explicitly sets a lower bound of zero on the element,
291 : * whether it be percent or raw integer.
292 : *
293 : * @param aString the string to parse
294 : * @return whether the value could be parsed
295 : *
296 : * @see http://www.whatwg.org/html/#rules-for-parsing-dimension-values
297 : */
298 : bool ParseSpecialIntValue(const nsAString& aString);
299 :
300 :
301 : /**
302 : * Parse a string value into an integer.
303 : *
304 : * @param aString the string to parse
305 : * @return whether the value could be parsed
306 : */
307 0 : bool ParseIntValue(const nsAString& aString) {
308 0 : return ParseIntWithBounds(aString, PR_INT32_MIN, PR_INT32_MAX);
309 : }
310 :
311 : /**
312 : * Parse a string value into an integer with minimum value and maximum value.
313 : *
314 : * @param aString the string to parse
315 : * @param aMin the minimum value (if value is less it will be bumped up)
316 : * @param aMax the maximum value (if value is greater it will be chopped down)
317 : * @return whether the value could be parsed
318 : */
319 : bool ParseIntWithBounds(const nsAString& aString, PRInt32 aMin,
320 : PRInt32 aMax = PR_INT32_MAX);
321 :
322 : /**
323 : * Parse a string value into a non-negative integer.
324 : * This method follows the rules for parsing non-negative integer from:
325 : * http://dev.w3.org/html5/spec/infrastructure.html#rules-for-parsing-non-negative-integers
326 : *
327 : * @param aString the string to parse
328 : * @return whether the value is valid
329 : */
330 : bool ParseNonNegativeIntValue(const nsAString& aString);
331 :
332 : /**
333 : * Parse a string value into a positive integer.
334 : * This method follows the rules for parsing non-negative integer from:
335 : * http://dev.w3.org/html5/spec/infrastructure.html#rules-for-parsing-non-negative-integers
336 : * In addition of these rules, the value has to be greater than zero.
337 : *
338 : * This is generally used for parsing content attributes which reflecting IDL
339 : * attributes are limited to only non-negative numbers greater than zero, see:
340 : * http://dev.w3.org/html5/spec/common-dom-interfaces.html#limited-to-only-non-negative-numbers-greater-than-zero
341 : *
342 : * @param aString the string to parse
343 : * @return whether the value was valid
344 : */
345 : bool ParsePositiveIntValue(const nsAString& aString);
346 :
347 : /**
348 : * Parse a string into a color. This implements what HTML5 calls the
349 : * "rules for parsing a legacy color value".
350 : *
351 : * @param aString the string to parse
352 : * @return whether the value could be parsed
353 : */
354 : bool ParseColor(const nsAString& aString);
355 :
356 : /**
357 : * Parse a string value into a double-precision floating point value.
358 : *
359 : * @param aString the string to parse
360 : * @return whether the value could be parsed
361 : */
362 : bool ParseDoubleValue(const nsAString& aString);
363 :
364 : /**
365 : * Parse a lazy URI. This just sets up the storage for the URI; it
366 : * doesn't actually allocate it.
367 : */
368 : bool ParseLazyURIValue(const nsAString& aString);
369 :
370 : /**
371 : * Parse a margin string of format 'top, right, bottom, left' into
372 : * an nsIntMargin.
373 : *
374 : * @param aString the string to parse
375 : * @return whether the value could be parsed
376 : */
377 : bool ParseIntMarginValue(const nsAString& aString);
378 :
379 : size_t SizeOfExcludingThis(nsMallocSizeOfFun aMallocSizeOf) const;
380 :
381 : private:
382 : // These have to be the same as in ValueType
383 : enum ValueBaseType {
384 : eStringBase = eString, // 00
385 : eOtherBase = 0x01, // 01
386 : eAtomBase = eAtom, // 10
387 : eIntegerBase = 0x03 // 11
388 : };
389 :
390 : struct MiscContainer
391 : {
392 : ValueType mType;
393 : // mStringBits points to either nsIAtom* or nsStringBuffer* and is used when
394 : // mType isn't mCSSStyleRule.
395 : // Note eStringBase and eAtomBase is used also to handle the type of
396 : // mStringBits.
397 : PtrBits mStringBits;
398 : union {
399 : PRInt32 mInteger;
400 : nscolor mColor;
401 : PRUint32 mEnumValue;
402 : PRInt32 mPercent;
403 : mozilla::css::StyleRule* mCSSStyleRule;
404 : AtomArray* mAtomArray;
405 : double mDoubleValue;
406 : nsIntMargin* mIntMargin;
407 : const nsSVGAngle* mSVGAngle;
408 : const nsSVGIntegerPair* mSVGIntegerPair;
409 : const nsSVGLength2* mSVGLength;
410 : const mozilla::SVGLengthList* mSVGLengthList;
411 : const mozilla::SVGNumberList* mSVGNumberList;
412 : const nsSVGNumberPair* mSVGNumberPair;
413 : const mozilla::SVGPathData* mSVGPathData;
414 : const mozilla::SVGPointList* mSVGPointList;
415 : const mozilla::SVGAnimatedPreserveAspectRatio* mSVGPreserveAspectRatio;
416 : const mozilla::SVGStringList* mSVGStringList;
417 : const mozilla::SVGTransformList* mSVGTransformList;
418 : const nsSVGViewBox* mSVGViewBox;
419 : };
420 : };
421 :
422 : inline ValueBaseType BaseType() const;
423 : inline bool IsSVGType(ValueType aType) const;
424 :
425 : /**
426 : * Get the index of an EnumTable in the sEnumTableArray.
427 : * If the EnumTable is not in the sEnumTableArray, it is added.
428 : *
429 : * @param aTable the EnumTable to get the index of.
430 : * @return the index of the EnumTable.
431 : */
432 : PRInt16 GetEnumTableIndex(const EnumTable* aTable);
433 :
434 : inline void SetPtrValueAndType(void* aValue, ValueBaseType aType);
435 : void SetIntValueAndType(PRInt32 aValue, ValueType aType,
436 : const nsAString* aStringValue);
437 : void SetColorValue(nscolor aColor, const nsAString& aString);
438 : void SetMiscAtomOrString(const nsAString* aValue);
439 : void ResetMiscAtomOrString();
440 : void SetSVGType(ValueType aType, const void* aValue,
441 : const nsAString* aSerialized);
442 : inline void ResetIfSet();
443 :
444 : inline void* GetPtr() const;
445 : inline MiscContainer* GetMiscContainer() const;
446 : inline PRInt32 GetIntInternal() const;
447 :
448 : bool EnsureEmptyMiscContainer();
449 : bool EnsureEmptyAtomArray();
450 : nsStringBuffer* GetStringBuffer(const nsAString& aValue) const;
451 : // aStrict is set true if stringifying the return value equals with
452 : // aValue.
453 : PRInt32 StringToInteger(const nsAString& aValue,
454 : bool* aStrict,
455 : PRInt32* aErrorCode,
456 : bool aCanBePercent = false,
457 : bool* aIsPercent = nsnull) const;
458 : // Given an enum table and a particular entry in that table, return
459 : // the actual integer value we should store.
460 : PRInt32 EnumTableEntryToValue(const EnumTable* aEnumTable,
461 : const EnumTable* aTableEntry);
462 :
463 : static nsTArray<const EnumTable*, nsTArrayDefaultAllocator>* sEnumTableArray;
464 :
465 : PtrBits mBits;
466 : };
467 :
468 : /**
469 : * Implementation of inline methods
470 : */
471 :
472 : inline const nsAttrValue&
473 0 : nsAttrValue::operator=(const nsAttrValue& aOther)
474 : {
475 0 : SetTo(aOther);
476 0 : return *this;
477 : }
478 :
479 : inline nsIAtom*
480 1684 : nsAttrValue::GetAtomValue() const
481 : {
482 1684 : NS_PRECONDITION(Type() == eAtom, "wrong type");
483 1684 : return reinterpret_cast<nsIAtom*>(GetPtr());
484 : }
485 :
486 : inline PRInt32
487 0 : nsAttrValue::GetIntegerValue() const
488 : {
489 0 : NS_PRECONDITION(Type() == eInteger, "wrong type");
490 0 : return (BaseType() == eIntegerBase)
491 : ? GetIntInternal()
492 0 : : GetMiscContainer()->mInteger;
493 : }
494 :
495 : inline PRInt16
496 0 : nsAttrValue::GetEnumValue() const
497 : {
498 0 : NS_PRECONDITION(Type() == eEnum, "wrong type");
499 : // We don't need to worry about sign extension here since we're
500 : // returning an PRInt16 which will cut away the top bits.
501 : return static_cast<PRInt16>((
502 0 : (BaseType() == eIntegerBase)
503 0 : ? static_cast<PRUint32>(GetIntInternal())
504 0 : : GetMiscContainer()->mEnumValue)
505 0 : >> NS_ATTRVALUE_ENUMTABLEINDEX_BITS);
506 : }
507 :
508 : inline float
509 0 : nsAttrValue::GetPercentValue() const
510 : {
511 0 : NS_PRECONDITION(Type() == ePercent, "wrong type");
512 0 : return ((BaseType() == eIntegerBase)
513 0 : ? GetIntInternal()
514 0 : : GetMiscContainer()->mPercent)
515 0 : / 100.0f;
516 : }
517 :
518 : inline nsAttrValue::AtomArray*
519 0 : nsAttrValue::GetAtomArrayValue() const
520 : {
521 0 : NS_PRECONDITION(Type() == eAtomArray, "wrong type");
522 0 : return GetMiscContainer()->mAtomArray;
523 : }
524 :
525 : inline mozilla::css::StyleRule*
526 0 : nsAttrValue::GetCSSStyleRuleValue() const
527 : {
528 0 : NS_PRECONDITION(Type() == eCSSStyleRule, "wrong type");
529 0 : return GetMiscContainer()->mCSSStyleRule;
530 : }
531 :
532 : inline double
533 0 : nsAttrValue::GetDoubleValue() const
534 : {
535 0 : NS_PRECONDITION(Type() == eDoubleValue, "wrong type");
536 0 : return GetMiscContainer()->mDoubleValue;
537 : }
538 :
539 : inline bool
540 0 : nsAttrValue::GetIntMarginValue(nsIntMargin& aMargin) const
541 : {
542 0 : NS_PRECONDITION(Type() == eIntMarginValue, "wrong type");
543 0 : nsIntMargin* m = GetMiscContainer()->mIntMargin;
544 0 : if (!m)
545 0 : return false;
546 0 : aMargin = *m;
547 0 : return true;
548 : }
549 :
550 : inline nsAttrValue::ValueBaseType
551 112578 : nsAttrValue::BaseType() const
552 : {
553 112578 : return static_cast<ValueBaseType>(mBits & NS_ATTRVALUE_BASETYPE_MASK);
554 : }
555 :
556 : inline bool
557 0 : nsAttrValue::IsSVGType(ValueType aType) const
558 : {
559 0 : return aType >= eSVGTypesBegin && aType <= eSVGTypesEnd;
560 : }
561 :
562 : inline void
563 22850 : nsAttrValue::SetPtrValueAndType(void* aValue, ValueBaseType aType)
564 : {
565 22850 : NS_ASSERTION(!(NS_PTR_TO_INT32(aValue) & ~NS_ATTRVALUE_POINTERVALUE_MASK),
566 : "pointer not properly aligned, this will crash");
567 22850 : mBits = reinterpret_cast<PtrBits>(aValue) | aType;
568 22850 : }
569 :
570 : inline void
571 68717 : nsAttrValue::ResetIfSet()
572 : {
573 68717 : if (mBits) {
574 22846 : Reset();
575 : }
576 68717 : }
577 :
578 : inline void*
579 45638 : nsAttrValue::GetPtr() const
580 : {
581 45638 : NS_ASSERTION(BaseType() != eIntegerBase,
582 : "getting pointer from non-pointer");
583 45638 : return reinterpret_cast<void*>(mBits & NS_ATTRVALUE_POINTERVALUE_MASK);
584 : }
585 :
586 : inline nsAttrValue::MiscContainer*
587 0 : nsAttrValue::GetMiscContainer() const
588 : {
589 0 : NS_ASSERTION(BaseType() == eOtherBase, "wrong type");
590 0 : return static_cast<MiscContainer*>(GetPtr());
591 : }
592 :
593 : inline PRInt32
594 0 : nsAttrValue::GetIntInternal() const
595 : {
596 0 : NS_ASSERTION(BaseType() == eIntegerBase,
597 : "getting integer from non-integer");
598 : // Make sure we get a signed value.
599 : // Lets hope the optimizer optimizes this into a shift. Unfortunatly signed
600 : // bitshift right is implementaion dependant.
601 : return static_cast<PRInt32>(mBits & ~NS_ATTRVALUE_INTEGERTYPE_MASK) /
602 0 : NS_ATTRVALUE_INTEGERTYPE_MULTIPLIER;
603 : }
604 :
605 : inline bool
606 0 : nsAttrValue::IsEmptyString() const
607 : {
608 0 : return !mBits;
609 : }
610 :
611 : #endif
|