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 "nsUTF8Utils.h"
10 void nsHtml5String::ToString(nsAString
& aString
) {
13 return AsStringBuffer()->ToString(Length(), aString
);
15 return AsAtom()->ToString(aString
);
21 aString
.SetIsVoid(true);
26 void nsHtml5String::CopyToBuffer(char16_t
* aBuffer
) const {
27 memcpy(aBuffer
, AsPtr(), Length() * sizeof(char16_t
));
30 bool nsHtml5String::LowerCaseEqualsASCII(const char* aLowerCaseLiteral
) const {
31 return !nsCharTraits
<char16_t
>::compareLowerCaseToASCIINullTerminated(
32 AsPtr(), Length(), aLowerCaseLiteral
);
35 bool nsHtml5String::EqualsASCII(const char* aLiteral
) const {
36 return !nsCharTraits
<char16_t
>::compareASCIINullTerminated(AsPtr(), Length(),
40 bool nsHtml5String::LowerCaseStartsWithASCII(
41 const char* aLowerCaseLiteral
) const {
42 const char* litPtr
= aLowerCaseLiteral
;
43 const char16_t
* strPtr
= AsPtr();
44 const char16_t
* end
= strPtr
+ Length();
46 while ((litChar
= *litPtr
)) {
47 MOZ_ASSERT(!(litChar
>= 'A' && litChar
<= 'Z'),
48 "Literal isn't in lower case.");
52 char16_t strChar
= *strPtr
;
53 if (strChar
>= 'A' && strChar
<= 'Z') {
56 if (litChar
!= strChar
) {
65 bool nsHtml5String::Equals(nsHtml5String aOther
) const {
66 MOZ_ASSERT(operator bool());
68 if (Length() != aOther
.Length()) {
71 return !memcmp(AsPtr(), aOther
.AsPtr(), Length() * sizeof(char16_t
));
74 nsHtml5String
nsHtml5String::Clone() {
77 AsStringBuffer()->AddRef();
85 return nsHtml5String(mBits
);
88 void nsHtml5String::Release() {
91 AsStringBuffer()->Release();
103 nsHtml5String
nsHtml5String::FromBuffer(char16_t
* aBuffer
, int32_t aLength
,
104 nsHtml5TreeBuilder
* aTreeBuilder
) {
106 return nsHtml5String(eEmpty
);
108 // Work with nsStringBuffer directly to make sure that storage is actually
109 // nsStringBuffer and to make sure the allocation strategy matches
110 // nsAttrValue::GetStringBuffer, so that it doesn't need to reallocate and
112 RefPtr
<nsStringBuffer
> buffer
= nsStringBuffer::Create(aBuffer
, aLength
);
113 if (MOZ_UNLIKELY(!buffer
)) {
115 MOZ_CRASH("Out of memory.");
117 aTreeBuilder
->MarkAsBroken(NS_ERROR_OUT_OF_MEMORY
);
118 buffer
= nsStringBuffer::Alloc(2 * sizeof(char16_t
));
121 "Out of memory so badly that couldn't even allocate placeholder.");
123 char16_t
* data
= reinterpret_cast<char16_t
*>(buffer
->Data());
127 return nsHtml5String(reinterpret_cast<uintptr_t>(buffer
.forget().take()) |
132 nsHtml5String
nsHtml5String::FromLiteral(const char* aLiteral
) {
133 size_t length
= std::strlen(aLiteral
);
135 return nsHtml5String(eEmpty
);
137 // Work with nsStringBuffer directly to make sure that storage is actually
138 // nsStringBuffer and to make sure the allocation strategy matches
139 // nsAttrValue::GetStringBuffer, so that it doesn't need to reallocate and
141 RefPtr
<nsStringBuffer
> buffer(
142 nsStringBuffer::Alloc((length
+ 1) * sizeof(char16_t
)));
144 MOZ_CRASH("Out of memory.");
146 char16_t
* data
= reinterpret_cast<char16_t
*>(buffer
->Data());
147 ConvertAsciitoUtf16(mozilla::Span(aLiteral
, length
),
148 mozilla::Span(data
, length
));
150 return nsHtml5String(reinterpret_cast<uintptr_t>(buffer
.forget().take()) |
155 nsHtml5String
nsHtml5String::FromString(const nsAString
& aString
) {
156 auto length
= aString
.Length();
158 return nsHtml5String(eEmpty
);
160 RefPtr
<nsStringBuffer
> buffer
= nsStringBuffer::FromString(aString
);
161 if (buffer
&& (length
== buffer
->StorageSize() / sizeof(char16_t
) - 1)) {
162 return nsHtml5String(reinterpret_cast<uintptr_t>(buffer
.forget().take()) |
165 buffer
= nsStringBuffer::Alloc((length
+ 1) * sizeof(char16_t
));
167 MOZ_CRASH("Out of memory.");
169 char16_t
* data
= reinterpret_cast<char16_t
*>(buffer
->Data());
170 memcpy(data
, aString
.BeginReading(), length
* sizeof(char16_t
));
172 return nsHtml5String(reinterpret_cast<uintptr_t>(buffer
.forget().take()) |
177 nsHtml5String
nsHtml5String::FromAtom(already_AddRefed
<nsAtom
> aAtom
) {
178 return nsHtml5String(reinterpret_cast<uintptr_t>(aAtom
.take()) | eAtom
);
182 nsHtml5String
nsHtml5String::EmptyString() { return nsHtml5String(eEmpty
); }