summaryrefslogtreecommitdiffstats
path: root/parser/html/nsHtml5String.h
diff options
context:
space:
mode:
Diffstat (limited to 'parser/html/nsHtml5String.h')
-rw-r--r--parser/html/nsHtml5String.h139
1 files changed, 139 insertions, 0 deletions
diff --git a/parser/html/nsHtml5String.h b/parser/html/nsHtml5String.h
new file mode 100644
index 0000000000..f725630f9e
--- /dev/null
+++ b/parser/html/nsHtml5String.h
@@ -0,0 +1,139 @@
+/* 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"
+#include "nsStringBuffer.h"
+
+class nsHtml5TreeBuilder;
+
+/**
+ * A pass-by-value type that can represent
+ * * nullptr
+ * * empty string
+ * * Non-empty string as exactly-sized (capacity is length) `nsStringBuffer*`
+ * * Non-empty string as an nsAtom*
+ *
+ * Holding or passing this type is as unsafe as holding or passing
+ * `nsStringBuffer*`/`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 nsStringBuffer* AsStringBuffer() const {
+ MOZ_ASSERT(GetKind() == eStringBuffer);
+ return reinterpret_cast<nsStringBuffer*>(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