tor-browser

The Tor Browser
git clone https://git.dasho.dev/tor-browser.git
Log | Files | Refs | README | LICENSE

nsHtml5String.cpp (5611B)


      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 #include "nsHtml5String.h"
      6 #include "nsCharTraits.h"
      7 #include "nsHtml5TreeBuilder.h"
      8 #include "mozilla/StringBuffer.h"
      9 
     10 using mozilla::StringBuffer;
     11 
     12 void nsHtml5String::ToString(nsAString& aString) {
     13  switch (GetKind()) {
     14    case eStringBuffer:
     15      return aString.Assign(AsStringBuffer(), Length());
     16    case eAtom:
     17      return AsAtom()->ToString(aString);
     18    case eEmpty:
     19      aString.Truncate();
     20      return;
     21    default:
     22      aString.Truncate();
     23      aString.SetIsVoid(true);
     24      return;
     25  }
     26 }
     27 
     28 void nsHtml5String::CopyToBuffer(char16_t* aBuffer) const {
     29  memcpy(aBuffer, AsPtr(), Length() * sizeof(char16_t));
     30 }
     31 
     32 bool nsHtml5String::LowerCaseEqualsASCII(const char* aLowerCaseLiteral) const {
     33  return !nsCharTraits<char16_t>::compareLowerCaseToASCIINullTerminated(
     34      AsPtr(), Length(), aLowerCaseLiteral);
     35 }
     36 
     37 bool nsHtml5String::EqualsASCII(const char* aLiteral) const {
     38  return !nsCharTraits<char16_t>::compareASCIINullTerminated(AsPtr(), Length(),
     39                                                             aLiteral);
     40 }
     41 
     42 bool nsHtml5String::LowerCaseStartsWithASCII(
     43    const char* aLowerCaseLiteral) const {
     44  const char* litPtr = aLowerCaseLiteral;
     45  const char16_t* strPtr = AsPtr();
     46  const char16_t* end = strPtr + Length();
     47  char16_t litChar;
     48  while ((litChar = *litPtr)) {
     49    MOZ_ASSERT(!(litChar >= 'A' && litChar <= 'Z'),
     50               "Literal isn't in lower case.");
     51    if (strPtr == end) {
     52      return false;
     53    }
     54    char16_t strChar = *strPtr;
     55    if (strChar >= 'A' && strChar <= 'Z') {
     56      strChar += 0x20;
     57    }
     58    if (litChar != strChar) {
     59      return false;
     60    }
     61    ++litPtr;
     62    ++strPtr;
     63  }
     64  return true;
     65 }
     66 
     67 bool nsHtml5String::Equals(nsHtml5String aOther) const {
     68  MOZ_ASSERT(operator bool());
     69  MOZ_ASSERT(aOther);
     70  if (Length() != aOther.Length()) {
     71    return false;
     72  }
     73  return !memcmp(AsPtr(), aOther.AsPtr(), Length() * sizeof(char16_t));
     74 }
     75 
     76 nsHtml5String nsHtml5String::Clone() {
     77  switch (GetKind()) {
     78    case eStringBuffer:
     79      AsStringBuffer()->AddRef();
     80      break;
     81    case eAtom:
     82      AsAtom()->AddRef();
     83      break;
     84    default:
     85      break;
     86  }
     87  return nsHtml5String(mBits);
     88 }
     89 
     90 void nsHtml5String::Release() {
     91  switch (GetKind()) {
     92    case eStringBuffer:
     93      AsStringBuffer()->Release();
     94      break;
     95    case eAtom:
     96      AsAtom()->Release();
     97      break;
     98    default:
     99      break;
    100  }
    101  mBits = eNull;
    102 }
    103 
    104 // static
    105 nsHtml5String nsHtml5String::FromBuffer(char16_t* aBuffer, int32_t aLength,
    106                                        nsHtml5TreeBuilder* aTreeBuilder) {
    107  if (!aLength) {
    108    return nsHtml5String(eEmpty);
    109  }
    110  // Work with StringBuffer directly to make sure that storage is actually
    111  // StringBuffer and to make sure the allocation strategy matches
    112  // nsAttrValue::GetStringBuffer, so that it doesn't need to reallocate and
    113  // copy.
    114  RefPtr<StringBuffer> buffer = StringBuffer::Create(aBuffer, aLength);
    115  if (MOZ_UNLIKELY(!buffer)) {
    116    if (!aTreeBuilder) {
    117      MOZ_CRASH("Out of memory.");
    118    }
    119    aTreeBuilder->MarkAsBroken(NS_ERROR_OUT_OF_MEMORY);
    120    buffer = StringBuffer::Alloc(2 * sizeof(char16_t));
    121    if (!buffer) {
    122      MOZ_CRASH(
    123          "Out of memory so badly that couldn't even allocate placeholder.");
    124    }
    125    char16_t* data = reinterpret_cast<char16_t*>(buffer->Data());
    126    data[0] = 0xFFFD;
    127    data[1] = 0;
    128  }
    129  return nsHtml5String(reinterpret_cast<uintptr_t>(buffer.forget().take()) |
    130                       eStringBuffer);
    131 }
    132 
    133 // static
    134 nsHtml5String nsHtml5String::FromLiteral(const char* aLiteral) {
    135  size_t length = std::strlen(aLiteral);
    136  if (!length) {
    137    return nsHtml5String(eEmpty);
    138  }
    139  // Work with StringBuffer directly to make sure that storage is actually
    140  // StringBuffer and to make sure the allocation strategy matches
    141  // nsAttrValue::GetStringBuffer, so that it doesn't need to reallocate and
    142  // copy.
    143  RefPtr<StringBuffer> buffer(
    144      StringBuffer::Alloc((length + 1) * sizeof(char16_t)));
    145  if (!buffer) {
    146    MOZ_CRASH("Out of memory.");
    147  }
    148  char16_t* data = reinterpret_cast<char16_t*>(buffer->Data());
    149  ConvertAsciitoUtf16(mozilla::Span(aLiteral, length),
    150                      mozilla::Span(data, length));
    151  data[length] = 0;
    152  return nsHtml5String(reinterpret_cast<uintptr_t>(buffer.forget().take()) |
    153                       eStringBuffer);
    154 }
    155 
    156 // static
    157 nsHtml5String nsHtml5String::FromString(const nsAString& aString) {
    158  auto length = aString.Length();
    159  if (!length) {
    160    return nsHtml5String(eEmpty);
    161  }
    162  if (StringBuffer* buffer = aString.GetStringBuffer()) {
    163    if (length == buffer->StorageSize() / sizeof(char16_t) - 1) {
    164      buffer->AddRef();
    165      return nsHtml5String(reinterpret_cast<uintptr_t>(buffer) | eStringBuffer);
    166    }
    167  }
    168  RefPtr<StringBuffer> buffer =
    169      StringBuffer::Alloc((length + 1) * sizeof(char16_t));
    170  if (!buffer) {
    171    MOZ_CRASH("Out of memory.");
    172  }
    173  char16_t* data = reinterpret_cast<char16_t*>(buffer->Data());
    174  memcpy(data, aString.BeginReading(), length * sizeof(char16_t));
    175  data[length] = 0;
    176  return nsHtml5String(reinterpret_cast<uintptr_t>(buffer.forget().take()) |
    177                       eStringBuffer);
    178 }
    179 
    180 // static
    181 nsHtml5String nsHtml5String::FromAtom(already_AddRefed<nsAtom> aAtom) {
    182  return nsHtml5String(reinterpret_cast<uintptr_t>(aAtom.take()) | eAtom);
    183 }
    184 
    185 // static
    186 nsHtml5String nsHtml5String::EmptyString() { return nsHtml5String(eEmpty); }