gecko-dev/parser/html/nsHtml5String.h

143 lines
3.4 KiB
C++

/* 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 nsHtml5String_h
#define nsHtml5String_h
#include "nsAtom.h"
#include "nsString.h"
namespace mozilla {
class StringBuffer;
}
class nsHtml5TreeBuilder;
/**
* A pass-by-value type that can represent
* * nullptr
* * empty string
* * Non-empty string as exactly-sized (capacity is length) `StringBuffer*`
* * Non-empty string as an nsAtom*
*
* Holding or passing this type is as unsafe as holding or passing
* `StringBuffer*`/`nsAtom*`.
*/
class nsHtml5String final {
private:
static const uintptr_t kKindMask = uintptr_t(3);
static const uintptr_t kPtrMask = ~kKindMask;
enum Kind : uintptr_t {
eNull = 0,
eEmpty = 1,
eStringBuffer = 2,
eAtom = 3,
};
inline Kind GetKind() const { return (Kind)(mBits & kKindMask); }
inline mozilla::StringBuffer* AsStringBuffer() const {
MOZ_ASSERT(GetKind() == eStringBuffer);
return reinterpret_cast<mozilla::StringBuffer*>(mBits & kPtrMask);
}
inline nsAtom* AsAtom() const {
MOZ_ASSERT(GetKind() == eAtom);
return reinterpret_cast<nsAtom*>(mBits & kPtrMask);
}
inline const char16_t* AsPtr() const {
switch (GetKind()) {
case eStringBuffer:
return reinterpret_cast<char16_t*>(AsStringBuffer()->Data());
case eAtom:
return AsAtom()->GetUTF16String();
default:
return nsCharTraits<char16_t>::sEmptyBuffer;
}
}
public:
/**
* Default constructor.
*/
inline nsHtml5String() : nsHtml5String(nullptr) {}
/**
* Constructor from nullptr.
*/
inline MOZ_IMPLICIT nsHtml5String(decltype(nullptr)) : mBits(eNull) {}
inline uint32_t Length() const {
switch (GetKind()) {
case eStringBuffer:
return (AsStringBuffer()->StorageSize() / sizeof(char16_t) - 1);
case eAtom:
return AsAtom()->GetLength();
default:
return 0;
}
}
/**
* False iff the string is logically null
*/
inline MOZ_IMPLICIT operator bool() const { return mBits; }
/**
* Get the underlying nsAtom* or nullptr if this nsHtml5String
* does not hold an atom.
*/
inline nsAtom* MaybeAsAtom() {
if (GetKind() == eAtom) {
return AsAtom();
}
return nullptr;
}
void ToString(nsAString& aString);
void CopyToBuffer(char16_t* aBuffer) const;
bool LowerCaseEqualsASCII(const char* aLowerCaseLiteral) const;
bool EqualsASCII(const char* aLiteral) const;
bool LowerCaseStartsWithASCII(const char* aLowerCaseLiteral) const;
bool Equals(nsHtml5String aOther) const;
nsHtml5String Clone();
void Release();
static nsHtml5String FromBuffer(char16_t* aBuffer, int32_t aLength,
nsHtml5TreeBuilder* aTreeBuilder);
static nsHtml5String FromLiteral(const char* aLiteral);
static nsHtml5String FromString(const nsAString& aString);
static nsHtml5String FromAtom(already_AddRefed<nsAtom> aAtom);
static nsHtml5String EmptyString();
private:
/**
* Constructor from raw bits.
*/
explicit nsHtml5String(uintptr_t aBits) : mBits(aBits) {};
/**
* Zero if null, one if empty, otherwise tagged pointer
* to either nsAtom or nsStringBuffer. The two least-significant
* bits are tag bits.
*/
uintptr_t mBits;
};
#endif // nsHtml5String_h