Coverage Report

Created: 2018-09-25 14:53

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