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(
113 nsStringBuffer::Alloc((aLength
+ 1) * sizeof(char16_t
)));
116 MOZ_CRASH("Out of memory.");
118 aTreeBuilder
->MarkAsBroken(NS_ERROR_OUT_OF_MEMORY
);
119 buffer
= nsStringBuffer::Alloc(2 * sizeof(char16_t
));
122 "Out of memory so badly that couldn't even allocate placeholder.");
124 char16_t
* data
= reinterpret_cast<char16_t
*>(buffer
->Data());
127 return nsHtml5String(reinterpret_cast<uintptr_t>(buffer
.forget().take()) |
130 char16_t
* data
= reinterpret_cast<char16_t
*>(buffer
->Data());
131 memcpy(data
, aBuffer
, aLength
* sizeof(char16_t
));
133 return nsHtml5String(reinterpret_cast<uintptr_t>(buffer
.forget().take()) |
138 nsHtml5String
nsHtml5String::FromLiteral(const char* aLiteral
) {
139 size_t length
= std::strlen(aLiteral
);
141 return nsHtml5String(eEmpty
);
143 // Work with nsStringBuffer directly to make sure that storage is actually
144 // nsStringBuffer and to make sure the allocation strategy matches
145 // nsAttrValue::GetStringBuffer, so that it doesn't need to reallocate and
147 RefPtr
<nsStringBuffer
> buffer(
148 nsStringBuffer::Alloc((length
+ 1) * sizeof(char16_t
)));
150 MOZ_CRASH("Out of memory.");
152 char16_t
* data
= reinterpret_cast<char16_t
*>(buffer
->Data());
153 ConvertAsciitoUtf16(Span(aLiteral
, length
), Span(data
, length
));
155 return nsHtml5String(reinterpret_cast<uintptr_t>(buffer
.forget().take()) |
160 nsHtml5String
nsHtml5String::FromString(const nsAString
& aString
) {
161 auto length
= aString
.Length();
163 return nsHtml5String(eEmpty
);
165 RefPtr
<nsStringBuffer
> buffer
= nsStringBuffer::FromString(aString
);
166 if (buffer
&& (length
== buffer
->StorageSize() / sizeof(char16_t
) - 1)) {
167 return nsHtml5String(reinterpret_cast<uintptr_t>(buffer
.forget().take()) |
170 buffer
= nsStringBuffer::Alloc((length
+ 1) * sizeof(char16_t
));
172 MOZ_CRASH("Out of memory.");
174 char16_t
* data
= reinterpret_cast<char16_t
*>(buffer
->Data());
175 memcpy(data
, aString
.BeginReading(), length
* sizeof(char16_t
));
177 return nsHtml5String(reinterpret_cast<uintptr_t>(buffer
.forget().take()) |
182 nsHtml5String
nsHtml5String::FromAtom(already_AddRefed
<nsAtom
> aAtom
) {
183 return nsHtml5String(reinterpret_cast<uintptr_t>(aAtom
.take()) | eAtom
);
187 nsHtml5String
nsHtml5String::EmptyString() { return nsHtml5String(eEmpty
); }