nsHtml5String.h (3457B)
1 /* This Source Code Form is subject to the terms of the Mozilla Public 2 * License, v. 2.0. If a copy of the MPL was not distributed with this 3 * file, You can obtain one at http://mozilla.org/MPL/2.0/. */ 4 5 #ifndef nsHtml5String_h 6 #define nsHtml5String_h 7 8 #include "nsAtom.h" 9 #include "nsString.h" 10 11 namespace mozilla { 12 class StringBuffer; 13 } 14 15 class nsHtml5TreeBuilder; 16 17 /** 18 * A pass-by-value type that can represent 19 * * nullptr 20 * * empty string 21 * * Non-empty string as exactly-sized (capacity is length) `StringBuffer*` 22 * * Non-empty string as an nsAtom* 23 * 24 * Holding or passing this type is as unsafe as holding or passing 25 * `StringBuffer*`/`nsAtom*`. 26 */ 27 class nsHtml5String final { 28 private: 29 static const uintptr_t kKindMask = uintptr_t(3); 30 31 static const uintptr_t kPtrMask = ~kKindMask; 32 33 enum Kind : uintptr_t { 34 eNull = 0, 35 eEmpty = 1, 36 eStringBuffer = 2, 37 eAtom = 3, 38 }; 39 40 inline Kind GetKind() const { return (Kind)(mBits & kKindMask); } 41 42 inline mozilla::StringBuffer* AsStringBuffer() const { 43 MOZ_ASSERT(GetKind() == eStringBuffer); 44 return reinterpret_cast<mozilla::StringBuffer*>(mBits & kPtrMask); 45 } 46 47 inline nsAtom* AsAtom() const { 48 MOZ_ASSERT(GetKind() == eAtom); 49 return reinterpret_cast<nsAtom*>(mBits & kPtrMask); 50 } 51 52 inline const char16_t* AsPtr() const { 53 switch (GetKind()) { 54 case eStringBuffer: 55 return reinterpret_cast<char16_t*>(AsStringBuffer()->Data()); 56 case eAtom: 57 return AsAtom()->GetUTF16String(); 58 default: 59 return nsCharTraits<char16_t>::sEmptyBuffer; 60 } 61 } 62 63 public: 64 /** 65 * Default constructor. 66 */ 67 inline nsHtml5String() : nsHtml5String(nullptr) {} 68 69 /** 70 * Constructor from nullptr. 71 */ 72 inline MOZ_IMPLICIT nsHtml5String(decltype(nullptr)) : mBits(eNull) {} 73 74 inline uint32_t Length() const { 75 switch (GetKind()) { 76 case eStringBuffer: 77 return (AsStringBuffer()->StorageSize() / sizeof(char16_t) - 1); 78 case eAtom: 79 return AsAtom()->GetLength(); 80 default: 81 return 0; 82 } 83 } 84 85 /** 86 * False iff the string is logically null 87 */ 88 inline MOZ_IMPLICIT operator bool() const { return mBits; } 89 90 /** 91 * Get the underlying nsAtom* or nullptr if this nsHtml5String 92 * does not hold an atom. 93 */ 94 inline nsAtom* MaybeAsAtom() { 95 if (GetKind() == eAtom) { 96 return AsAtom(); 97 } 98 return nullptr; 99 } 100 101 void ToString(nsAString& aString); 102 103 void CopyToBuffer(char16_t* aBuffer) const; 104 105 bool LowerCaseEqualsASCII(const char* aLowerCaseLiteral) const; 106 107 bool EqualsASCII(const char* aLiteral) const; 108 109 bool LowerCaseStartsWithASCII(const char* aLowerCaseLiteral) const; 110 111 bool Equals(nsHtml5String aOther) const; 112 113 nsHtml5String Clone(); 114 115 void Release(); 116 117 static nsHtml5String FromBuffer(char16_t* aBuffer, int32_t aLength, 118 nsHtml5TreeBuilder* aTreeBuilder); 119 120 static nsHtml5String FromLiteral(const char* aLiteral); 121 122 static nsHtml5String FromString(const nsAString& aString); 123 124 static nsHtml5String FromAtom(already_AddRefed<nsAtom> aAtom); 125 126 static nsHtml5String EmptyString(); 127 128 private: 129 /** 130 * Constructor from raw bits. 131 */ 132 explicit nsHtml5String(uintptr_t aBits) : mBits(aBits) {}; 133 134 /** 135 * Zero if null, one if empty, otherwise tagged pointer 136 * to either nsAtom or nsStringBuffer. The two least-significant 137 * bits are tag bits. 138 */ 139 uintptr_t mBits; 140 }; 141 142 #endif // nsHtml5String_h