зеркало из https://github.com/mozilla/gecko-dev.git
226 строки
5.7 KiB
C++
226 строки
5.7 KiB
C++
/* This Source Code Form is subject to the terms of the Mozilla Public
|
|
* License, v. 2.0. If a copy of the MPL was not distributed with this
|
|
* file, You can obtain one at http://mozilla.org/MPL/2.0/. */
|
|
|
|
#include "nsHtml5String.h"
|
|
#include "nsCharTraits.h"
|
|
#include "nsUTF8Utils.h"
|
|
#include "nsHtml5TreeBuilder.h"
|
|
|
|
nsHtml5String::nsHtml5String(already_AddRefed<nsStringBuffer> aBuffer,
|
|
uint32_t aLength)
|
|
: mBuffer(aBuffer.take())
|
|
, mLength(aLength)
|
|
{
|
|
if (mBuffer) {
|
|
MOZ_ASSERT(aLength);
|
|
} else {
|
|
MOZ_ASSERT(!aLength || aLength == UINT32_MAX);
|
|
}
|
|
}
|
|
|
|
void
|
|
nsHtml5String::ToString(nsAString& aString)
|
|
{
|
|
if (mBuffer) {
|
|
mBuffer->ToString(mLength, aString);
|
|
} else {
|
|
aString.Truncate();
|
|
if (mLength) {
|
|
aString.SetIsVoid(true);
|
|
}
|
|
}
|
|
}
|
|
|
|
void
|
|
nsHtml5String::CopyToBuffer(char16_t* aBuffer)
|
|
{
|
|
if (mBuffer) {
|
|
memcpy(aBuffer, mBuffer->Data(), mLength * sizeof(char16_t));
|
|
}
|
|
}
|
|
|
|
bool
|
|
nsHtml5String::LowerCaseEqualsASCII(const char* aLowerCaseLiteral)
|
|
{
|
|
if (!mBuffer) {
|
|
if (mLength) {
|
|
// This string is null
|
|
return false;
|
|
}
|
|
// this string is empty
|
|
return !(*aLowerCaseLiteral);
|
|
}
|
|
return !nsCharTraits<char16_t>::compareLowerCaseToASCIINullTerminated(
|
|
reinterpret_cast<char16_t*>(mBuffer->Data()), Length(), aLowerCaseLiteral);
|
|
}
|
|
|
|
bool
|
|
nsHtml5String::EqualsASCII(const char* aLiteral)
|
|
{
|
|
if (!mBuffer) {
|
|
if (mLength) {
|
|
// This string is null
|
|
return false;
|
|
}
|
|
// this string is empty
|
|
return !(*aLiteral);
|
|
}
|
|
return !nsCharTraits<char16_t>::compareASCIINullTerminated(
|
|
reinterpret_cast<char16_t*>(mBuffer->Data()), Length(), aLiteral);
|
|
}
|
|
|
|
bool
|
|
nsHtml5String::LowerCaseStartsWithASCII(const char* aLowerCaseLiteral)
|
|
{
|
|
if (!mBuffer) {
|
|
if (mLength) {
|
|
// This string is null
|
|
return false;
|
|
}
|
|
// this string is empty
|
|
return !(*aLowerCaseLiteral);
|
|
}
|
|
const char* litPtr = aLowerCaseLiteral;
|
|
const char16_t* strPtr = reinterpret_cast<char16_t*>(mBuffer->Data());
|
|
const char16_t* end = strPtr + Length();
|
|
char16_t litChar;
|
|
while ((litChar = *litPtr) && (strPtr != end)) {
|
|
MOZ_ASSERT(!(litChar >= 'A' && litChar <= 'Z'),
|
|
"Literal isn't in lower case.");
|
|
char16_t strChar = *strPtr;
|
|
if (strChar >= 'A' && strChar <= 'Z') {
|
|
strChar += 0x20;
|
|
}
|
|
if (litChar != strChar) {
|
|
return false;
|
|
}
|
|
++litPtr;
|
|
++strPtr;
|
|
}
|
|
return true;
|
|
}
|
|
|
|
bool
|
|
nsHtml5String::Equals(nsHtml5String aOther)
|
|
{
|
|
MOZ_ASSERT(operator bool());
|
|
MOZ_ASSERT(aOther);
|
|
if (mLength != aOther.mLength) {
|
|
return false;
|
|
}
|
|
if (!mBuffer) {
|
|
return true;
|
|
}
|
|
MOZ_ASSERT(aOther.mBuffer);
|
|
return !memcmp(
|
|
mBuffer->Data(), aOther.mBuffer->Data(), Length() * sizeof(char16_t));
|
|
}
|
|
|
|
nsHtml5String
|
|
nsHtml5String::Clone()
|
|
{
|
|
MOZ_ASSERT(operator bool());
|
|
RefPtr<nsStringBuffer> ref(mBuffer);
|
|
return nsHtml5String(ref.forget(), mLength);
|
|
}
|
|
|
|
void
|
|
nsHtml5String::Release()
|
|
{
|
|
if (mBuffer) {
|
|
mBuffer->Release();
|
|
mBuffer = nullptr;
|
|
}
|
|
mLength = UINT32_MAX;
|
|
}
|
|
|
|
// static
|
|
nsHtml5String
|
|
nsHtml5String::FromBuffer(char16_t* aBuffer,
|
|
int32_t aLength,
|
|
nsHtml5TreeBuilder* aTreeBuilder)
|
|
{
|
|
if (!aLength) {
|
|
return nsHtml5String(nullptr, 0U);
|
|
}
|
|
// Work with nsStringBuffer directly to make sure that storage is actually
|
|
// nsStringBuffer and to make sure the allocation strategy matches
|
|
// nsAttrValue::GetStringBuffer, so that it doesn't need to reallocate and
|
|
// copy.
|
|
RefPtr<nsStringBuffer> buffer(
|
|
nsStringBuffer::Alloc((aLength + 1) * sizeof(char16_t)));
|
|
if (!buffer) {
|
|
if (!aTreeBuilder) {
|
|
MOZ_CRASH("Out of memory.");
|
|
}
|
|
aTreeBuilder->MarkAsBroken(NS_ERROR_OUT_OF_MEMORY);
|
|
buffer = nsStringBuffer::Alloc(2 * sizeof(char16_t));
|
|
if (!buffer) {
|
|
MOZ_CRASH(
|
|
"Out of memory so badly that couldn't even allocate placeholder.");
|
|
}
|
|
char16_t* data = reinterpret_cast<char16_t*>(buffer->Data());
|
|
data[0] = 0xFFFD;
|
|
data[1] = 0;
|
|
return nsHtml5String(buffer.forget(), 1);
|
|
}
|
|
char16_t* data = reinterpret_cast<char16_t*>(buffer->Data());
|
|
memcpy(data, aBuffer, aLength * sizeof(char16_t));
|
|
data[aLength] = 0;
|
|
return nsHtml5String(buffer.forget(), aLength);
|
|
}
|
|
|
|
// static
|
|
nsHtml5String
|
|
nsHtml5String::FromLiteral(const char* aLiteral)
|
|
{
|
|
size_t length = std::strlen(aLiteral);
|
|
if (!length) {
|
|
return nsHtml5String(nullptr, 0U);
|
|
}
|
|
// Work with nsStringBuffer directly to make sure that storage is actually
|
|
// nsStringBuffer and to make sure the allocation strategy matches
|
|
// nsAttrValue::GetStringBuffer, so that it doesn't need to reallocate and
|
|
// copy.
|
|
RefPtr<nsStringBuffer> buffer(
|
|
nsStringBuffer::Alloc((length + 1) * sizeof(char16_t)));
|
|
if (!buffer) {
|
|
MOZ_CRASH("Out of memory.");
|
|
}
|
|
char16_t* data = reinterpret_cast<char16_t*>(buffer->Data());
|
|
LossyConvertEncoding8to16 converter(data);
|
|
converter.write(aLiteral, length);
|
|
data[length] = 0;
|
|
return nsHtml5String(buffer.forget(), length);
|
|
}
|
|
|
|
// static
|
|
nsHtml5String
|
|
nsHtml5String::FromString(const nsAString& aString)
|
|
{
|
|
auto length = aString.Length();
|
|
if (!length) {
|
|
return nsHtml5String(nullptr, 0U);
|
|
}
|
|
RefPtr<nsStringBuffer> buffer = nsStringBuffer::FromString(aString);
|
|
if (buffer) {
|
|
return nsHtml5String(buffer.forget(), length);
|
|
}
|
|
buffer = nsStringBuffer::Alloc((length + 1) * sizeof(char16_t));
|
|
if (!buffer) {
|
|
MOZ_CRASH("Out of memory.");
|
|
}
|
|
char16_t* data = reinterpret_cast<char16_t*>(buffer->Data());
|
|
memcpy(data, aString.BeginReading(), length * sizeof(char16_t));
|
|
data[length] = 0;
|
|
return nsHtml5String(buffer.forget(), length);
|
|
}
|
|
|
|
// static
|
|
nsHtml5String
|
|
nsHtml5String::EmptyString()
|
|
{
|
|
return nsHtml5String(nullptr, 0U);
|
|
}
|