DXR is a code search and navigation tool aimed at making sense of large projects. It supports full-text and regex searches as well as structural queries.

Implementation

Mercurial (409f3966645a)

VCS Links

Line Code
1 2 3 4 5 6 7 8 9 10 11 12 13 14 15 16 17 18 19 20 21 22 23 24 25 26 27 28 29 30 31 32 33 34 35 36 37 38 39 40 41 42 43 44 45 46 47 48 49 50 51 52 53 54 55 56 57 58 59 60 61 62 63 64 65 66 67 68 69 70 71 72 73 74 75 76 77 78 79 80 81 82 83 84 85 86 87 88 89 90 91 92 93 94 95 96 97 98 99 100 101 102 103 104 105 106 107 108 109 110 111 112 113 114 115 116 117 118 119 120 121 122 123 124 125 126 127 128 129 130 131 132 133 134 135 136 137 138 139 140 141 142 143 144 145 146 147 148 149 150 151 152 153 154
/* 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 nullptr;
    }
  }

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