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/. */
5 #include "nsHtml5String.h"
6 #include "nsCharTraits.h"
7 #include "nsHtml5TreeBuilder.h"
8 #include "mozilla/StringBuffer.h"
10 using mozilla::StringBuffer
;
12 void nsHtml5String::ToString(nsAString
& aString
) {
15 return aString
.Assign(AsStringBuffer(), Length());
17 return AsAtom()->ToString(aString
);
23 aString
.SetIsVoid(true);
28 void nsHtml5String::CopyToBuffer(char16_t
* aBuffer
) const {
29 memcpy(aBuffer
, AsPtr(), Length() * sizeof(char16_t
));
32 bool nsHtml5String::LowerCaseEqualsASCII(const char* aLowerCaseLiteral
) const {
33 return !nsCharTraits
<char16_t
>::compareLowerCaseToASCIINullTerminated(
34 AsPtr(), Length(), aLowerCaseLiteral
);
37 bool nsHtml5String::EqualsASCII(const char* aLiteral
) const {
38 return !nsCharTraits
<char16_t
>::compareASCIINullTerminated(AsPtr(), Length(),
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();
48 while ((litChar
= *litPtr
)) {
49 MOZ_ASSERT(!(litChar
>= 'A' && litChar
<= 'Z'),
50 "Literal isn't in lower case.");
54 char16_t strChar
= *strPtr
;
55 if (strChar
>= 'A' && strChar
<= 'Z') {
58 if (litChar
!= strChar
) {
67 bool nsHtml5String::Equals(nsHtml5String aOther
) const {
68 MOZ_ASSERT(operator bool());
70 if (Length() != aOther
.Length()) {
73 return !memcmp(AsPtr(), aOther
.AsPtr(), Length() * sizeof(char16_t
));
76 nsHtml5String
nsHtml5String::Clone() {
79 AsStringBuffer()->AddRef();
87 return nsHtml5String(mBits
);
90 void nsHtml5String::Release() {
93 AsStringBuffer()->Release();
105 nsHtml5String
nsHtml5String::FromBuffer(char16_t
* aBuffer
, int32_t aLength
,
106 nsHtml5TreeBuilder
* aTreeBuilder
) {
108 return nsHtml5String(eEmpty
);
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
114 RefPtr
<StringBuffer
> buffer
= StringBuffer::Create(aBuffer
, aLength
);
115 if (MOZ_UNLIKELY(!buffer
)) {
117 MOZ_CRASH("Out of memory.");
119 aTreeBuilder
->MarkAsBroken(NS_ERROR_OUT_OF_MEMORY
);
120 buffer
= StringBuffer::Alloc(2 * sizeof(char16_t
));
123 "Out of memory so badly that couldn't even allocate placeholder.");
125 char16_t
* data
= reinterpret_cast<char16_t
*>(buffer
->Data());
129 return nsHtml5String(reinterpret_cast<uintptr_t>(buffer
.forget().take()) |
134 nsHtml5String
nsHtml5String::FromLiteral(const char* aLiteral
) {
135 size_t length
= std::strlen(aLiteral
);
137 return nsHtml5String(eEmpty
);
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
143 RefPtr
<StringBuffer
> buffer(
144 StringBuffer::Alloc((length
+ 1) * sizeof(char16_t
)));
146 MOZ_CRASH("Out of memory.");
148 char16_t
* data
= reinterpret_cast<char16_t
*>(buffer
->Data());
149 ConvertAsciitoUtf16(mozilla::Span(aLiteral
, length
),
150 mozilla::Span(data
, length
));
152 return nsHtml5String(reinterpret_cast<uintptr_t>(buffer
.forget().take()) |
157 nsHtml5String
nsHtml5String::FromString(const nsAString
& aString
) {
158 auto length
= aString
.Length();
160 return nsHtml5String(eEmpty
);
162 if (StringBuffer
* buffer
= aString
.GetStringBuffer()) {
163 if (length
== buffer
->StorageSize() / sizeof(char16_t
) - 1) {
165 return nsHtml5String(reinterpret_cast<uintptr_t>(buffer
) | eStringBuffer
);
168 RefPtr
<StringBuffer
> buffer
=
169 StringBuffer::Alloc((length
+ 1) * sizeof(char16_t
));
171 MOZ_CRASH("Out of memory.");
173 char16_t
* data
= reinterpret_cast<char16_t
*>(buffer
->Data());
174 memcpy(data
, aString
.BeginReading(), length
* sizeof(char16_t
));
176 return nsHtml5String(reinterpret_cast<uintptr_t>(buffer
.forget().take()) |
181 nsHtml5String
nsHtml5String::FromAtom(already_AddRefed
<nsAtom
> aAtom
) {
182 return nsHtml5String(reinterpret_cast<uintptr_t>(aAtom
.take()) | eAtom
);
186 nsHtml5String
nsHtml5String::EmptyString() { return nsHtml5String(eEmpty
); }