forked from mirrors/gecko-dev
Bug 1892257 - Move nsStringBuffer to mfbt. r=nika,xpcom-reviewers,glandium
Inline Create() and Realloc() so that we don't get negative leaks, since were that code end up in mozglue, it wouldn't have access to the logging machinery. Differential Revision: https://phabricator.services.mozilla.com/D209663
This commit is contained in:
parent
d691a9d3db
commit
d55796be17
45 changed files with 293 additions and 316 deletions
|
|
@ -8,7 +8,6 @@
|
||||||
#include "nsString.h"
|
#include "nsString.h"
|
||||||
#include "nsJSPrincipals.h"
|
#include "nsJSPrincipals.h"
|
||||||
#include "nsCOMPtr.h"
|
#include "nsCOMPtr.h"
|
||||||
#include "nsStringBuffer.h"
|
|
||||||
#include "mozilla/BasePrincipal.h"
|
#include "mozilla/BasePrincipal.h"
|
||||||
#include "mozilla/StaticPtr.h"
|
#include "mozilla/StaticPtr.h"
|
||||||
#include "mozilla/dom/StructuredCloneTags.h"
|
#include "mozilla/dom/StructuredCloneTags.h"
|
||||||
|
|
|
||||||
|
|
@ -140,7 +140,7 @@ bool MiscContainer::GetString(nsAString& aString) const {
|
||||||
return false;
|
return false;
|
||||||
}
|
}
|
||||||
if (isString) {
|
if (isString) {
|
||||||
auto* buffer = static_cast<nsStringBuffer*>(ptr);
|
auto* buffer = static_cast<mozilla::StringBuffer*>(ptr);
|
||||||
aString.Assign(buffer, buffer->StorageSize() / sizeof(char16_t) - 1);
|
aString.Assign(buffer, buffer->StorageSize() / sizeof(char16_t) - 1);
|
||||||
} else {
|
} else {
|
||||||
static_cast<nsAtom*>(ptr)->ToString(aString);
|
static_cast<nsAtom*>(ptr)->ToString(aString);
|
||||||
|
|
@ -280,7 +280,7 @@ void nsAttrValue::Shutdown() {
|
||||||
void nsAttrValue::Reset() {
|
void nsAttrValue::Reset() {
|
||||||
switch (BaseType()) {
|
switch (BaseType()) {
|
||||||
case eStringBase: {
|
case eStringBase: {
|
||||||
if (auto* str = static_cast<nsStringBuffer*>(GetPtr())) {
|
if (auto* str = static_cast<mozilla::StringBuffer*>(GetPtr())) {
|
||||||
str->Release();
|
str->Release();
|
||||||
}
|
}
|
||||||
break;
|
break;
|
||||||
|
|
@ -318,7 +318,7 @@ void nsAttrValue::SetTo(const nsAttrValue& aOther) {
|
||||||
switch (aOther.BaseType()) {
|
switch (aOther.BaseType()) {
|
||||||
case eStringBase: {
|
case eStringBase: {
|
||||||
ResetIfSet();
|
ResetIfSet();
|
||||||
if (auto* str = static_cast<nsStringBuffer*>(aOther.GetPtr())) {
|
if (auto* str = static_cast<mozilla::StringBuffer*>(aOther.GetPtr())) {
|
||||||
str->AddRef();
|
str->AddRef();
|
||||||
SetPtrValueAndType(str, eStringBase);
|
SetPtrValueAndType(str, eStringBase);
|
||||||
}
|
}
|
||||||
|
|
@ -395,7 +395,7 @@ void nsAttrValue::SetTo(const nsAttrValue& aOther) {
|
||||||
bool isString;
|
bool isString;
|
||||||
if (void* otherPtr = otherCont->GetStringOrAtomPtr(isString)) {
|
if (void* otherPtr = otherCont->GetStringOrAtomPtr(isString)) {
|
||||||
if (isString) {
|
if (isString) {
|
||||||
static_cast<nsStringBuffer*>(otherPtr)->AddRef();
|
static_cast<mozilla::StringBuffer*>(otherPtr)->AddRef();
|
||||||
} else {
|
} else {
|
||||||
static_cast<nsAtom*>(otherPtr)->AddRef();
|
static_cast<nsAtom*>(otherPtr)->AddRef();
|
||||||
}
|
}
|
||||||
|
|
@ -408,7 +408,7 @@ void nsAttrValue::SetTo(const nsAttrValue& aOther) {
|
||||||
|
|
||||||
void nsAttrValue::SetTo(const nsAString& aValue) {
|
void nsAttrValue::SetTo(const nsAString& aValue) {
|
||||||
ResetIfSet();
|
ResetIfSet();
|
||||||
nsStringBuffer* buf = GetStringBuffer(aValue).take();
|
mozilla::StringBuffer* buf = GetStringBuffer(aValue).take();
|
||||||
if (buf) {
|
if (buf) {
|
||||||
SetPtrValueAndType(buf, eStringBase);
|
SetPtrValueAndType(buf, eStringBase);
|
||||||
}
|
}
|
||||||
|
|
@ -589,7 +589,7 @@ void nsAttrValue::RemoveDuplicatesFromAtomArray() {
|
||||||
if (void* otherPtr = oldCont->GetStringOrAtomPtr(isString)) {
|
if (void* otherPtr = oldCont->GetStringOrAtomPtr(isString)) {
|
||||||
stringBits = oldCont->mStringBits;
|
stringBits = oldCont->mStringBits;
|
||||||
if (isString) {
|
if (isString) {
|
||||||
static_cast<nsStringBuffer*>(otherPtr)->AddRef();
|
static_cast<mozilla::StringBuffer*>(otherPtr)->AddRef();
|
||||||
} else {
|
} else {
|
||||||
static_cast<nsAtom*>(otherPtr)->AddRef();
|
static_cast<nsAtom*>(otherPtr)->AddRef();
|
||||||
}
|
}
|
||||||
|
|
@ -620,7 +620,7 @@ void nsAttrValue::ToString(nsAString& aResult) const {
|
||||||
|
|
||||||
switch (Type()) {
|
switch (Type()) {
|
||||||
case eString: {
|
case eString: {
|
||||||
if (auto* str = static_cast<nsStringBuffer*>(GetPtr())) {
|
if (auto* str = static_cast<mozilla::StringBuffer*>(GetPtr())) {
|
||||||
aResult.Assign(str, str->StorageSize() / sizeof(char16_t) - 1);
|
aResult.Assign(str, str->StorageSize() / sizeof(char16_t) - 1);
|
||||||
} else {
|
} else {
|
||||||
aResult.Truncate();
|
aResult.Truncate();
|
||||||
|
|
@ -770,7 +770,7 @@ already_AddRefed<nsAtom> nsAttrValue::GetAsAtom() const {
|
||||||
const nsCheapString nsAttrValue::GetStringValue() const {
|
const nsCheapString nsAttrValue::GetStringValue() const {
|
||||||
MOZ_ASSERT(Type() == eString, "wrong type");
|
MOZ_ASSERT(Type() == eString, "wrong type");
|
||||||
|
|
||||||
return nsCheapString(static_cast<nsStringBuffer*>(GetPtr()));
|
return nsCheapString(static_cast<mozilla::StringBuffer*>(GetPtr()));
|
||||||
}
|
}
|
||||||
|
|
||||||
bool nsAttrValue::GetColorValue(nscolor& aColor) const {
|
bool nsAttrValue::GetColorValue(nscolor& aColor) const {
|
||||||
|
|
@ -890,7 +890,7 @@ nsAtom* nsAttrValue::AtomAt(int32_t aIndex) const {
|
||||||
uint32_t nsAttrValue::HashValue() const {
|
uint32_t nsAttrValue::HashValue() const {
|
||||||
switch (BaseType()) {
|
switch (BaseType()) {
|
||||||
case eStringBase: {
|
case eStringBase: {
|
||||||
if (auto* str = static_cast<nsStringBuffer*>(GetPtr())) {
|
if (auto* str = static_cast<mozilla::StringBuffer*>(GetPtr())) {
|
||||||
uint32_t len = str->StorageSize() / sizeof(char16_t) - 1;
|
uint32_t len = str->StorageSize() / sizeof(char16_t) - 1;
|
||||||
return HashString(static_cast<char16_t*>(str->Data()), len);
|
return HashString(static_cast<char16_t*>(str->Data()), len);
|
||||||
}
|
}
|
||||||
|
|
@ -1058,9 +1058,9 @@ bool nsAttrValue::Equals(const nsAttrValue& aOther) const {
|
||||||
(static_cast<ValueBaseType>(otherCont->mStringBits &
|
(static_cast<ValueBaseType>(otherCont->mStringBits &
|
||||||
NS_ATTRVALUE_BASETYPE_MASK) ==
|
NS_ATTRVALUE_BASETYPE_MASK) ==
|
||||||
eStringBase)) {
|
eStringBase)) {
|
||||||
return nsCheapString(reinterpret_cast<nsStringBuffer*>(
|
return nsCheapString(reinterpret_cast<mozilla::StringBuffer*>(
|
||||||
static_cast<uintptr_t>(thisCont->mStringBits)))
|
static_cast<uintptr_t>(thisCont->mStringBits)))
|
||||||
.Equals(nsCheapString(reinterpret_cast<nsStringBuffer*>(
|
.Equals(nsCheapString(reinterpret_cast<mozilla::StringBuffer*>(
|
||||||
static_cast<uintptr_t>(otherCont->mStringBits))));
|
static_cast<uintptr_t>(otherCont->mStringBits))));
|
||||||
}
|
}
|
||||||
}
|
}
|
||||||
|
|
@ -1071,7 +1071,7 @@ bool nsAttrValue::Equals(const nsAString& aValue,
|
||||||
nsCaseTreatment aCaseSensitive) const {
|
nsCaseTreatment aCaseSensitive) const {
|
||||||
switch (BaseType()) {
|
switch (BaseType()) {
|
||||||
case eStringBase: {
|
case eStringBase: {
|
||||||
if (auto* str = static_cast<nsStringBuffer*>(GetPtr())) {
|
if (auto* str = static_cast<mozilla::StringBuffer*>(GetPtr())) {
|
||||||
nsDependentString dep(static_cast<char16_t*>(str->Data()),
|
nsDependentString dep(static_cast<char16_t*>(str->Data()),
|
||||||
str->StorageSize() / sizeof(char16_t) - 1);
|
str->StorageSize() / sizeof(char16_t) - 1);
|
||||||
return aCaseSensitive == eCaseMatters
|
return aCaseSensitive == eCaseMatters
|
||||||
|
|
@ -1117,7 +1117,7 @@ bool nsAttrValue::Equals(const nsAtom* aValue,
|
||||||
nsDependentAtomString(atom), nsDependentAtomString(aValue));
|
nsDependentAtomString(atom), nsDependentAtomString(aValue));
|
||||||
}
|
}
|
||||||
case eStringBase: {
|
case eStringBase: {
|
||||||
if (auto* str = static_cast<nsStringBuffer*>(GetPtr())) {
|
if (auto* str = static_cast<mozilla::StringBuffer*>(GetPtr())) {
|
||||||
size_t strLen = str->StorageSize() / sizeof(char16_t) - 1;
|
size_t strLen = str->StorageSize() / sizeof(char16_t) - 1;
|
||||||
if (aValue->GetLength() != strLen) {
|
if (aValue->GetLength() != strLen) {
|
||||||
return false;
|
return false;
|
||||||
|
|
@ -1202,7 +1202,7 @@ bool nsAttrValue::SubstringCheck(const nsAString& aValue,
|
||||||
nsCaseTreatment aCaseSensitive) const {
|
nsCaseTreatment aCaseSensitive) const {
|
||||||
switch (BaseType()) {
|
switch (BaseType()) {
|
||||||
case eStringBase: {
|
case eStringBase: {
|
||||||
if (auto* str = static_cast<nsStringBuffer*>(GetPtr())) {
|
if (auto* str = static_cast<mozilla::StringBuffer*>(GetPtr())) {
|
||||||
return F::Check(static_cast<char16_t*>(str->Data()),
|
return F::Check(static_cast<char16_t*>(str->Data()),
|
||||||
str->StorageSize() / sizeof(char16_t) - 1, aValue,
|
str->StorageSize() / sizeof(char16_t) - 1, aValue,
|
||||||
aCaseSensitive);
|
aCaseSensitive);
|
||||||
|
|
@ -1518,9 +1518,9 @@ nsAtom* nsAttrValue::GetStoredAtom() const {
|
||||||
return nullptr;
|
return nullptr;
|
||||||
}
|
}
|
||||||
|
|
||||||
nsStringBuffer* nsAttrValue::GetStoredStringBuffer() const {
|
mozilla::StringBuffer* nsAttrValue::GetStoredStringBuffer() const {
|
||||||
if (BaseType() == eStringBase) {
|
if (BaseType() == eStringBase) {
|
||||||
return static_cast<nsStringBuffer*>(GetPtr());
|
return static_cast<mozilla::StringBuffer*>(GetPtr());
|
||||||
}
|
}
|
||||||
if (BaseType() == eOtherBase) {
|
if (BaseType() == eOtherBase) {
|
||||||
return GetMiscContainer()->GetStoredStringBuffer();
|
return GetMiscContainer()->GetStoredStringBuffer();
|
||||||
|
|
@ -1829,7 +1829,7 @@ bool nsAttrValue::ParsePositiveIntValue(const nsAString& aString) {
|
||||||
}
|
}
|
||||||
|
|
||||||
void nsAttrValue::SetColorValue(nscolor aColor, const nsAString& aString) {
|
void nsAttrValue::SetColorValue(nscolor aColor, const nsAString& aString) {
|
||||||
nsStringBuffer* buf = GetStringBuffer(aString).take();
|
mozilla::StringBuffer* buf = GetStringBuffer(aString).take();
|
||||||
if (!buf) {
|
if (!buf) {
|
||||||
return;
|
return;
|
||||||
}
|
}
|
||||||
|
|
@ -1988,7 +1988,7 @@ void nsAttrValue::SetMiscAtomOrString(const nsAString* aValue) {
|
||||||
atom->Release();
|
atom->Release();
|
||||||
}
|
}
|
||||||
} else {
|
} else {
|
||||||
nsStringBuffer* buffer = GetStringBuffer(*aValue).take();
|
mozilla::StringBuffer* buffer = GetStringBuffer(*aValue).take();
|
||||||
NS_ENSURE_TRUE_VOID(buffer);
|
NS_ENSURE_TRUE_VOID(buffer);
|
||||||
uintptr_t bits = reinterpret_cast<uintptr_t>(buffer) | eStringBase;
|
uintptr_t bits = reinterpret_cast<uintptr_t>(buffer) | eStringBase;
|
||||||
|
|
||||||
|
|
@ -2009,7 +2009,7 @@ void nsAttrValue::ResetMiscAtomOrString() {
|
||||||
bool isString;
|
bool isString;
|
||||||
if (void* ptr = cont->GetStringOrAtomPtr(isString)) {
|
if (void* ptr = cont->GetStringOrAtomPtr(isString)) {
|
||||||
if (isString) {
|
if (isString) {
|
||||||
static_cast<nsStringBuffer*>(ptr)->Release();
|
static_cast<mozilla::StringBuffer*>(ptr)->Release();
|
||||||
} else {
|
} else {
|
||||||
static_cast<nsAtom*>(ptr)->Release();
|
static_cast<nsAtom*>(ptr)->Release();
|
||||||
}
|
}
|
||||||
|
|
@ -2094,19 +2094,19 @@ MiscContainer* nsAttrValue::EnsureEmptyMiscContainer() {
|
||||||
return cont;
|
return cont;
|
||||||
}
|
}
|
||||||
|
|
||||||
already_AddRefed<nsStringBuffer> nsAttrValue::GetStringBuffer(
|
already_AddRefed<mozilla::StringBuffer> nsAttrValue::GetStringBuffer(
|
||||||
const nsAString& aValue) const {
|
const nsAString& aValue) const {
|
||||||
uint32_t len = aValue.Length();
|
uint32_t len = aValue.Length();
|
||||||
if (!len) {
|
if (!len) {
|
||||||
return nullptr;
|
return nullptr;
|
||||||
}
|
}
|
||||||
if (nsStringBuffer* buf = aValue.GetStringBuffer();
|
if (mozilla::StringBuffer* buf = aValue.GetStringBuffer();
|
||||||
buf && (buf->StorageSize() / sizeof(char16_t) - 1) == len) {
|
buf && (buf->StorageSize() / sizeof(char16_t) - 1) == len) {
|
||||||
// We can only reuse the buffer if it's exactly sized, since we rely on
|
// We can only reuse the buffer if it's exactly sized, since we rely on
|
||||||
// StorageSize() to get the string length in ToString().
|
// StorageSize() to get the string length in ToString().
|
||||||
return do_AddRef(buf);
|
return do_AddRef(buf);
|
||||||
}
|
}
|
||||||
return nsStringBuffer::Create(aValue.Data(), aValue.Length());
|
return mozilla::StringBuffer::Create(aValue.Data(), aValue.Length());
|
||||||
}
|
}
|
||||||
|
|
||||||
size_t nsAttrValue::SizeOfExcludingThis(MallocSizeOf aMallocSizeOf) const {
|
size_t nsAttrValue::SizeOfExcludingThis(MallocSizeOf aMallocSizeOf) const {
|
||||||
|
|
@ -2114,7 +2114,8 @@ size_t nsAttrValue::SizeOfExcludingThis(MallocSizeOf aMallocSizeOf) const {
|
||||||
|
|
||||||
switch (BaseType()) {
|
switch (BaseType()) {
|
||||||
case eStringBase: {
|
case eStringBase: {
|
||||||
nsStringBuffer* str = static_cast<nsStringBuffer*>(GetPtr());
|
mozilla::StringBuffer* str =
|
||||||
|
static_cast<mozilla::StringBuffer*>(GetPtr());
|
||||||
n += str ? str->SizeOfIncludingThisIfUnshared(aMallocSizeOf) : 0;
|
n += str ? str->SizeOfIncludingThisIfUnshared(aMallocSizeOf) : 0;
|
||||||
break;
|
break;
|
||||||
}
|
}
|
||||||
|
|
@ -2134,7 +2135,7 @@ size_t nsAttrValue::SizeOfExcludingThis(MallocSizeOf aMallocSizeOf) const {
|
||||||
|
|
||||||
// We only count the size of the object pointed by otherPtr if it's a
|
// We only count the size of the object pointed by otherPtr if it's a
|
||||||
// string. When it's an atom, it's counted separatly.
|
// string. When it's an atom, it's counted separatly.
|
||||||
if (nsStringBuffer* buf = container->GetStoredStringBuffer()) {
|
if (mozilla::StringBuffer* buf = container->GetStoredStringBuffer()) {
|
||||||
n += buf->SizeOfIncludingThisIfUnshared(aMallocSizeOf);
|
n += buf->SizeOfIncludingThisIfUnshared(aMallocSizeOf);
|
||||||
}
|
}
|
||||||
|
|
||||||
|
|
|
||||||
|
|
@ -16,7 +16,7 @@
|
||||||
|
|
||||||
#include "nscore.h"
|
#include "nscore.h"
|
||||||
#include "nsString.h"
|
#include "nsString.h"
|
||||||
#include "nsStringBuffer.h"
|
#include "mozilla/StringBuffer.h"
|
||||||
#include "nsColor.h"
|
#include "nsColor.h"
|
||||||
#include "nsCaseTreatment.h"
|
#include "nsCaseTreatment.h"
|
||||||
#include "nsMargin.h"
|
#include "nsMargin.h"
|
||||||
|
|
@ -95,19 +95,19 @@ const uintptr_t NS_ATTRVALUE_BASETYPE_MASK = 3;
|
||||||
~NS_ATTRVALUE_ENUMTABLE_VALUE_NEEDS_TO_UPPER)))
|
~NS_ATTRVALUE_ENUMTABLE_VALUE_NEEDS_TO_UPPER)))
|
||||||
|
|
||||||
/**
|
/**
|
||||||
* A class used to construct a nsString from a nsStringBuffer (we might
|
* A class used to construct a nsString from a mozilla::StringBuffer (we might
|
||||||
* want to move this to nsString at some point).
|
* want to move this to nsString at some point).
|
||||||
*
|
*
|
||||||
* WARNING: Note that nsCheapString doesn't take an explicit length -- it
|
* WARNING: Note that nsCheapString doesn't take an explicit length -- it
|
||||||
* assumes the string is maximally large, given the nsStringBuffer's storage
|
* assumes the string is maximally large, given the mozilla::StringBuffer's
|
||||||
* size. This means the given string buffer *must* be sized exactly correctly
|
* storage size. This means the given string buffer *must* be sized exactly
|
||||||
* for the string it contains (including one byte for a null terminator). If
|
* correctly for the string it contains (including one byte for a null
|
||||||
* it has any unused storage space, then that will result in bogus characters
|
* terminator). If it has any unused storage space, then that will result in
|
||||||
* at the end of our nsCheapString.
|
* bogus characters at the end of our nsCheapString.
|
||||||
*/
|
*/
|
||||||
class nsCheapString : public nsString {
|
class nsCheapString : public nsString {
|
||||||
public:
|
public:
|
||||||
explicit nsCheapString(nsStringBuffer* aBuf) {
|
explicit nsCheapString(mozilla::StringBuffer* aBuf) {
|
||||||
if (aBuf) {
|
if (aBuf) {
|
||||||
Assign(aBuf, aBuf->StorageSize() / sizeof(char16_t) - 1);
|
Assign(aBuf, aBuf->StorageSize() / sizeof(char16_t) - 1);
|
||||||
}
|
}
|
||||||
|
|
@ -486,7 +486,7 @@ class nsAttrValue {
|
||||||
size_t SizeOfExcludingThis(mozilla::MallocSizeOf aMallocSizeOf) const;
|
size_t SizeOfExcludingThis(mozilla::MallocSizeOf aMallocSizeOf) const;
|
||||||
|
|
||||||
nsAtom* GetStoredAtom() const;
|
nsAtom* GetStoredAtom() const;
|
||||||
nsStringBuffer* GetStoredStringBuffer() const;
|
mozilla::StringBuffer* GetStoredStringBuffer() const;
|
||||||
|
|
||||||
private:
|
private:
|
||||||
// These have to be the same as in ValueType
|
// These have to be the same as in ValueType
|
||||||
|
|
@ -532,7 +532,7 @@ class nsAttrValue {
|
||||||
// Like ClearMiscContainer, except allocates a new container if one does not
|
// Like ClearMiscContainer, except allocates a new container if one does not
|
||||||
// exist already.
|
// exist already.
|
||||||
MiscContainer* EnsureEmptyMiscContainer();
|
MiscContainer* EnsureEmptyMiscContainer();
|
||||||
already_AddRefed<nsStringBuffer> GetStringBuffer(
|
already_AddRefed<mozilla::StringBuffer> GetStringBuffer(
|
||||||
const nsAString& aValue) const;
|
const nsAString& aValue) const;
|
||||||
// Given an enum table and a particular entry in that table, return
|
// Given an enum table and a particular entry in that table, return
|
||||||
// the actual integer value we should store.
|
// the actual integer value we should store.
|
||||||
|
|
|
||||||
|
|
@ -23,10 +23,9 @@ struct MiscContainer final {
|
||||||
using ValueType = nsAttrValue::ValueType;
|
using ValueType = nsAttrValue::ValueType;
|
||||||
|
|
||||||
ValueType mType;
|
ValueType mType;
|
||||||
// mStringBits points to either nsAtom* or nsStringBuffer* and is used when
|
// mStringBits points to either nsAtom* or mozilla::StringBuffer* and is used
|
||||||
// mType isn't eCSSDeclaration.
|
// when mType isn't eCSSDeclaration. Note eStringBase and eAtomBase is used
|
||||||
// Note eStringBase and eAtomBase is used also to handle the type of
|
// also to handle the type of mStringBits.
|
||||||
// mStringBits.
|
|
||||||
//
|
//
|
||||||
// Note that we use an atomic here so that we can use Compare-And-Swap
|
// Note that we use an atomic here so that we can use Compare-And-Swap
|
||||||
// to cache the serialization during the parallel servo traversal. This case
|
// to cache the serialization during the parallel servo traversal. This case
|
||||||
|
|
@ -102,10 +101,10 @@ struct MiscContainer final {
|
||||||
return isString ? nullptr : static_cast<nsAtom*>(ptr);
|
return isString ? nullptr : static_cast<nsAtom*>(ptr);
|
||||||
}
|
}
|
||||||
|
|
||||||
nsStringBuffer* GetStoredStringBuffer() const {
|
mozilla::StringBuffer* GetStoredStringBuffer() const {
|
||||||
bool isString = false;
|
bool isString = false;
|
||||||
void* ptr = GetStringOrAtomPtr(isString);
|
void* ptr = GetStringOrAtomPtr(isString);
|
||||||
return isString ? static_cast<nsStringBuffer*>(ptr) : nullptr;
|
return isString ? static_cast<mozilla::StringBuffer*>(ptr) : nullptr;
|
||||||
}
|
}
|
||||||
|
|
||||||
void SetStringBitsMainThread(uintptr_t aBits) {
|
void SetStringBitsMainThread(uintptr_t aBits) {
|
||||||
|
|
@ -247,8 +246,7 @@ inline nsAtom* nsAttrValue::GetAtomValue() const {
|
||||||
inline void nsAttrValue::ToString(mozilla::dom::DOMString& aResult) const {
|
inline void nsAttrValue::ToString(mozilla::dom::DOMString& aResult) const {
|
||||||
switch (Type()) {
|
switch (Type()) {
|
||||||
case eString: {
|
case eString: {
|
||||||
nsStringBuffer* str = static_cast<nsStringBuffer*>(GetPtr());
|
if (auto* str = static_cast<mozilla::StringBuffer*>(GetPtr())) {
|
||||||
if (str) {
|
|
||||||
aResult.SetKnownLiveStringBuffer(
|
aResult.SetKnownLiveStringBuffer(
|
||||||
str, str->StorageSize() / sizeof(char16_t) - 1);
|
str, str->StorageSize() / sizeof(char16_t) - 1);
|
||||||
}
|
}
|
||||||
|
|
|
||||||
|
|
@ -369,7 +369,6 @@
|
||||||
#include "nsServiceManagerUtils.h"
|
#include "nsServiceManagerUtils.h"
|
||||||
#include "nsStreamUtils.h"
|
#include "nsStreamUtils.h"
|
||||||
#include "nsString.h"
|
#include "nsString.h"
|
||||||
#include "nsStringBuffer.h"
|
|
||||||
#include "nsStringBundle.h"
|
#include "nsStringBundle.h"
|
||||||
#include "nsStringFlags.h"
|
#include "nsStringFlags.h"
|
||||||
#include "nsStringFwd.h"
|
#include "nsStringFwd.h"
|
||||||
|
|
|
||||||
|
|
@ -142,6 +142,7 @@ class HTMLEditor;
|
||||||
class LazyLogModule;
|
class LazyLogModule;
|
||||||
class LogModule;
|
class LogModule;
|
||||||
class PresShell;
|
class PresShell;
|
||||||
|
class StringBuffer;
|
||||||
class TextEditor;
|
class TextEditor;
|
||||||
class WidgetDragEvent;
|
class WidgetDragEvent;
|
||||||
class WidgetKeyboardEvent;
|
class WidgetKeyboardEvent;
|
||||||
|
|
|
||||||
|
|
@ -106,7 +106,7 @@ nsTextFragment& nsTextFragment::operator=(const nsTextFragment& aOther) {
|
||||||
memcpy(const_cast<char*>(m1b), aOther.m1b, aOther.mState.mLength);
|
memcpy(const_cast<char*>(m1b), aOther.m1b, aOther.mState.mLength);
|
||||||
} else {
|
} else {
|
||||||
// allocate a buffer for a single REPLACEMENT CHARACTER
|
// allocate a buffer for a single REPLACEMENT CHARACTER
|
||||||
m2b = nsStringBuffer::Alloc(sizeof(char16_t) * 2).take();
|
m2b = StringBuffer::Alloc(sizeof(char16_t) * 2).take();
|
||||||
if (!m2b) {
|
if (!m2b) {
|
||||||
MOZ_CRASH("OOM!");
|
MOZ_CRASH("OOM!");
|
||||||
}
|
}
|
||||||
|
|
@ -202,7 +202,7 @@ bool nsTextFragment::SetTo(const char16_t* aBuffer, uint32_t aLength,
|
||||||
uint32_t neededSize = aLength * sizeof(char16_t);
|
uint32_t neededSize = aLength * sizeof(char16_t);
|
||||||
if (!neededSize) {
|
if (!neededSize) {
|
||||||
if (storageSize < AutoStringDefaultStorageSize) {
|
if (storageSize < AutoStringDefaultStorageSize) {
|
||||||
// If we're storing small enough nsStringBuffer, let's preserve it.
|
// If we're storing small enough StringBuffer, let's preserve it.
|
||||||
|
|
||||||
static_cast<char16_t*>(m2b->Data())[0] = char16_t(0);
|
static_cast<char16_t*>(m2b->Data())[0] = char16_t(0);
|
||||||
mState.mLength = 0;
|
mState.mLength = 0;
|
||||||
|
|
@ -212,7 +212,7 @@ bool nsTextFragment::SetTo(const char16_t* aBuffer, uint32_t aLength,
|
||||||
} else if ((neededSize < storageSize) &&
|
} else if ((neededSize < storageSize) &&
|
||||||
((storageSize / 2) <
|
((storageSize / 2) <
|
||||||
(neededSize + AutoStringDefaultStorageSize))) {
|
(neededSize + AutoStringDefaultStorageSize))) {
|
||||||
// Don't try to reuse the existing nsStringBuffer, if it would have
|
// Don't try to reuse the existing StringBuffer, if it would have
|
||||||
// lots of unused space.
|
// lots of unused space.
|
||||||
|
|
||||||
memcpy(m2b->Data(), aBuffer, neededSize);
|
memcpy(m2b->Data(), aBuffer, neededSize);
|
||||||
|
|
@ -296,7 +296,7 @@ bool nsTextFragment::SetTo(const char16_t* aBuffer, uint32_t aLength,
|
||||||
return false;
|
return false;
|
||||||
}
|
}
|
||||||
|
|
||||||
m2b = nsStringBuffer::Alloc(m2bSize.value()).take();
|
m2b = StringBuffer::Alloc(m2bSize.value()).take();
|
||||||
if (!m2b) {
|
if (!m2b) {
|
||||||
return false;
|
return false;
|
||||||
}
|
}
|
||||||
|
|
@ -373,10 +373,10 @@ bool nsTextFragment::Append(const char16_t* aBuffer, uint32_t aLength,
|
||||||
size *= sizeof(char16_t);
|
size *= sizeof(char16_t);
|
||||||
|
|
||||||
// Already a 2-byte string so the result will be too
|
// Already a 2-byte string so the result will be too
|
||||||
nsStringBuffer* buff = nullptr;
|
StringBuffer* buff = nullptr;
|
||||||
nsStringBuffer* bufferToRelease = nullptr;
|
StringBuffer* bufferToRelease = nullptr;
|
||||||
if (m2b->IsReadonly()) {
|
if (m2b->IsReadonly()) {
|
||||||
buff = nsStringBuffer::Alloc(size).take();
|
buff = StringBuffer::Alloc(size).take();
|
||||||
if (!buff) {
|
if (!buff) {
|
||||||
return false;
|
return false;
|
||||||
}
|
}
|
||||||
|
|
@ -384,7 +384,7 @@ bool nsTextFragment::Append(const char16_t* aBuffer, uint32_t aLength,
|
||||||
memcpy(static_cast<char16_t*>(buff->Data()), m2b->Data(),
|
memcpy(static_cast<char16_t*>(buff->Data()), m2b->Data(),
|
||||||
mState.mLength * sizeof(char16_t));
|
mState.mLength * sizeof(char16_t));
|
||||||
} else {
|
} else {
|
||||||
buff = nsStringBuffer::Realloc(m2b, size);
|
buff = StringBuffer::Realloc(m2b, size);
|
||||||
if (!buff) {
|
if (!buff) {
|
||||||
return false;
|
return false;
|
||||||
}
|
}
|
||||||
|
|
@ -418,7 +418,7 @@ bool nsTextFragment::Append(const char16_t* aBuffer, uint32_t aLength,
|
||||||
|
|
||||||
// The old data was 1-byte, but the new is not so we have to expand it
|
// The old data was 1-byte, but the new is not so we have to expand it
|
||||||
// all to 2-byte
|
// all to 2-byte
|
||||||
nsStringBuffer* buff = nsStringBuffer::Alloc(size).take();
|
StringBuffer* buff = StringBuffer::Alloc(size).take();
|
||||||
if (!buff) {
|
if (!buff) {
|
||||||
return false;
|
return false;
|
||||||
}
|
}
|
||||||
|
|
|
||||||
|
|
@ -18,7 +18,7 @@
|
||||||
|
|
||||||
#include "nsCharTraits.h"
|
#include "nsCharTraits.h"
|
||||||
#include "nsString.h"
|
#include "nsString.h"
|
||||||
#include "nsStringBuffer.h"
|
#include "mozilla/StringBuffer.h"
|
||||||
#include "nsReadableUtils.h"
|
#include "nsReadableUtils.h"
|
||||||
#include "nsISupportsImpl.h"
|
#include "nsISupportsImpl.h"
|
||||||
|
|
||||||
|
|
@ -113,7 +113,7 @@ class nsTextFragment final {
|
||||||
}
|
}
|
||||||
ReleaseText();
|
ReleaseText();
|
||||||
if (aForce2b && !aUpdateBidi) {
|
if (aForce2b && !aUpdateBidi) {
|
||||||
if (nsStringBuffer* buffer = aString.GetStringBuffer()) {
|
if (mozilla::StringBuffer* buffer = aString.GetStringBuffer()) {
|
||||||
NS_ADDREF(m2b = buffer);
|
NS_ADDREF(m2b = buffer);
|
||||||
mState.mInHeap = true;
|
mState.mInHeap = true;
|
||||||
mState.mIs2b = true;
|
mState.mIs2b = true;
|
||||||
|
|
@ -296,7 +296,7 @@ class nsTextFragment final {
|
||||||
void UpdateBidiFlag(const char16_t* aBuffer, uint32_t aLength);
|
void UpdateBidiFlag(const char16_t* aBuffer, uint32_t aLength);
|
||||||
|
|
||||||
union {
|
union {
|
||||||
nsStringBuffer* m2b;
|
mozilla::StringBuffer* m2b;
|
||||||
const char* m1b; // This is const since it can point to shared data
|
const char* m1b; // This is const since it can point to shared data
|
||||||
};
|
};
|
||||||
|
|
||||||
|
|
|
||||||
|
|
@ -8,10 +8,10 @@
|
||||||
#define mozilla_dom_DOMString_h
|
#define mozilla_dom_DOMString_h
|
||||||
|
|
||||||
#include "nsString.h"
|
#include "nsString.h"
|
||||||
#include "nsStringBuffer.h"
|
|
||||||
#include "mozilla/Assertions.h"
|
#include "mozilla/Assertions.h"
|
||||||
#include "mozilla/Attributes.h"
|
#include "mozilla/Attributes.h"
|
||||||
#include "mozilla/Maybe.h"
|
#include "mozilla/Maybe.h"
|
||||||
|
#include "mozilla/StringBuffer.h"
|
||||||
#include "nsDOMString.h"
|
#include "nsDOMString.h"
|
||||||
#include "nsAtom.h"
|
#include "nsAtom.h"
|
||||||
|
|
||||||
|
|
@ -36,10 +36,10 @@ namespace mozilla::dom {
|
||||||
* It's only OK to call
|
* It's only OK to call
|
||||||
* SetKnownLiveStringBuffer/SetKnownLiveString/SetKnownLiveAtom if the caller of
|
* SetKnownLiveStringBuffer/SetKnownLiveString/SetKnownLiveAtom if the caller of
|
||||||
* the method in question plans to keep holding a strong ref to the stringbuffer
|
* the method in question plans to keep holding a strong ref to the stringbuffer
|
||||||
* involved, whether it's a raw nsStringBuffer, or stored inside the string or
|
* involved, whether it's a raw mozilla::StringBuffer, or stored inside the
|
||||||
* atom being passed. In the string/atom cases that means the caller must own
|
* string or atom being passed. In the string/atom cases that means the caller
|
||||||
* the string or atom, and not mutate it (in the string case) for the lifetime
|
* must own the string or atom, and not mutate it (in the string case) for the
|
||||||
* of the DOMString.
|
* lifetime of the DOMString.
|
||||||
*
|
*
|
||||||
* The proper way to extract a value is to check IsNull(). If not null, then
|
* The proper way to extract a value is to check IsNull(). If not null, then
|
||||||
* check IsEmpty(). If neither of those is true, check HasStringBuffer(). If
|
* check IsEmpty(). If neither of those is true, check HasStringBuffer(). If
|
||||||
|
|
@ -86,9 +86,9 @@ class MOZ_STACK_CLASS DOMString {
|
||||||
|
|
||||||
// Get the stringbuffer. This can only be called if HasStringBuffer()
|
// Get the stringbuffer. This can only be called if HasStringBuffer()
|
||||||
// returned true. If that's true, it will never return null. Note that
|
// returned true. If that's true, it will never return null. Note that
|
||||||
// constructing a string from this nsStringBuffer with length given by
|
// constructing a string from this mozilla::StringBuffer with length given by
|
||||||
// StringBufferLength() might give you something that is not null-terminated.
|
// StringBufferLength() might give you something that is not null-terminated.
|
||||||
nsStringBuffer* StringBuffer() const {
|
mozilla::StringBuffer* StringBuffer() const {
|
||||||
MOZ_ASSERT(HasStringBuffer(),
|
MOZ_ASSERT(HasStringBuffer(),
|
||||||
"Don't ask for the stringbuffer if we don't have it");
|
"Don't ask for the stringbuffer if we don't have it");
|
||||||
MOZ_ASSERT(mStringBuffer, "We better have a stringbuffer if we claim to");
|
MOZ_ASSERT(mStringBuffer, "We better have a stringbuffer if we claim to");
|
||||||
|
|
@ -103,8 +103,8 @@ class MOZ_STACK_CLASS DOMString {
|
||||||
return mLength;
|
return mLength;
|
||||||
}
|
}
|
||||||
|
|
||||||
// Tell the DOMString to relinquish ownership of its nsStringBuffer to the
|
// Tell the DOMString to relinquish ownership of its mozilla::StringBuffer to
|
||||||
// caller. Can only be called if HasStringBuffer().
|
// the caller. Can only be called if HasStringBuffer().
|
||||||
void RelinquishBufferOwnership() {
|
void RelinquishBufferOwnership() {
|
||||||
MOZ_ASSERT(HasStringBuffer(),
|
MOZ_ASSERT(HasStringBuffer(),
|
||||||
"Don't call this if there is no stringbuffer");
|
"Don't call this if there is no stringbuffer");
|
||||||
|
|
@ -138,10 +138,10 @@ class MOZ_STACK_CLASS DOMString {
|
||||||
return mLength;
|
return mLength;
|
||||||
}
|
}
|
||||||
|
|
||||||
// Initialize the DOMString to a (nsStringBuffer, length) pair. The length
|
// Initialize the DOMString to a (mozilla::StringBuffer, length) pair. The
|
||||||
// does NOT have to be the full length of the (null-terminated) string in the
|
// length does NOT have to be the full length of the (null-terminated) string
|
||||||
// nsStringBuffer.
|
// in the mozilla::StringBuffer.
|
||||||
void SetKnownLiveStringBuffer(nsStringBuffer* aStringBuffer,
|
void SetKnownLiveStringBuffer(mozilla::StringBuffer* aStringBuffer,
|
||||||
uint32_t aLength) {
|
uint32_t aLength) {
|
||||||
MOZ_ASSERT(mState == State::Empty, "We're already set to a value");
|
MOZ_ASSERT(mState == State::Empty, "We're already set to a value");
|
||||||
if (aLength != 0) {
|
if (aLength != 0) {
|
||||||
|
|
@ -151,8 +151,9 @@ class MOZ_STACK_CLASS DOMString {
|
||||||
// else nothing to do
|
// else nothing to do
|
||||||
}
|
}
|
||||||
|
|
||||||
// Like SetKnownLiveStringBuffer, but holds a reference to the nsStringBuffer.
|
// Like SetKnownLiveStringBuffer, but holds a reference to the
|
||||||
void SetStringBuffer(nsStringBuffer* aStringBuffer, uint32_t aLength) {
|
// mozilla::StringBuffer.
|
||||||
|
void SetStringBuffer(mozilla::StringBuffer* aStringBuffer, uint32_t aLength) {
|
||||||
MOZ_ASSERT(mState == State::Empty, "We're already set to a value");
|
MOZ_ASSERT(mState == State::Empty, "We're already set to a value");
|
||||||
if (aLength != 0) {
|
if (aLength != 0) {
|
||||||
SetStringBufferInternal(aStringBuffer, aLength);
|
SetStringBufferInternal(aStringBuffer, aLength);
|
||||||
|
|
@ -169,7 +170,7 @@ class MOZ_STACK_CLASS DOMString {
|
||||||
if (MOZ_UNLIKELY(aString.IsVoid())) {
|
if (MOZ_UNLIKELY(aString.IsVoid())) {
|
||||||
SetNull();
|
SetNull();
|
||||||
} else if (!aString.IsEmpty()) {
|
} else if (!aString.IsEmpty()) {
|
||||||
if (nsStringBuffer* buf = aString.GetStringBuffer()) {
|
if (mozilla::StringBuffer* buf = aString.GetStringBuffer()) {
|
||||||
SetKnownLiveStringBuffer(buf, aString.Length());
|
SetKnownLiveStringBuffer(buf, aString.Length());
|
||||||
} else if (aString.IsLiteral()) {
|
} else if (aString.IsLiteral()) {
|
||||||
SetLiteralInternal(aString.BeginReading(), aString.Length());
|
SetLiteralInternal(aString.BeginReading(), aString.Length());
|
||||||
|
|
@ -228,9 +229,9 @@ class MOZ_STACK_CLASS DOMString {
|
||||||
} else if (IsEmpty()) {
|
} else if (IsEmpty()) {
|
||||||
aString.Truncate();
|
aString.Truncate();
|
||||||
} else if (HasStringBuffer()) {
|
} else if (HasStringBuffer()) {
|
||||||
// Don't share the nsStringBuffer with aString if the result would not
|
// Don't share the mozilla::StringBuffer with aString if the result would
|
||||||
// be null-terminated.
|
// not be null-terminated.
|
||||||
nsStringBuffer* buf = StringBuffer();
|
mozilla::StringBuffer* buf = StringBuffer();
|
||||||
uint32_t len = StringBufferLength();
|
uint32_t len = StringBufferLength();
|
||||||
auto chars = static_cast<char16_t*>(buf->Data());
|
auto chars = static_cast<char16_t*>(buf->Data());
|
||||||
if (chars[len] == '\0') {
|
if (chars[len] == '\0') {
|
||||||
|
|
@ -248,7 +249,7 @@ class MOZ_STACK_CLASS DOMString {
|
||||||
}
|
}
|
||||||
|
|
||||||
private:
|
private:
|
||||||
void SetStringBufferInternal(nsStringBuffer* aStringBuffer,
|
void SetStringBufferInternal(mozilla::StringBuffer* aStringBuffer,
|
||||||
uint32_t aLength) {
|
uint32_t aLength) {
|
||||||
MOZ_ASSERT(mString.isNothing(), "We already have a string?");
|
MOZ_ASSERT(mString.isNothing(), "We already have a string?");
|
||||||
MOZ_ASSERT(mState == State::Empty, "We're already set to a value");
|
MOZ_ASSERT(mState == State::Empty, "We're already set to a value");
|
||||||
|
|
@ -285,8 +286,9 @@ class MOZ_STACK_CLASS DOMString {
|
||||||
Maybe<nsAutoString> mString;
|
Maybe<nsAutoString> mString;
|
||||||
|
|
||||||
union {
|
union {
|
||||||
// The nsStringBuffer in the OwnedStringBuffer/UnownedStringBuffer cases.
|
// The mozilla::StringBuffer in the OwnedStringBuffer/UnownedStringBuffer
|
||||||
nsStringBuffer* MOZ_UNSAFE_REF(
|
// cases.
|
||||||
|
mozilla::StringBuffer* MOZ_UNSAFE_REF(
|
||||||
"The ways in which this can be safe are "
|
"The ways in which this can be safe are "
|
||||||
"documented above and enforced through "
|
"documented above and enforced through "
|
||||||
"assertions") mStringBuffer;
|
"assertions") mStringBuffer;
|
||||||
|
|
|
||||||
|
|
@ -8,7 +8,7 @@
|
||||||
#define mozilla_dom_FakeString_h__
|
#define mozilla_dom_FakeString_h__
|
||||||
|
|
||||||
#include "nsString.h"
|
#include "nsString.h"
|
||||||
#include "nsStringBuffer.h"
|
#include "mozilla/StringBuffer.h"
|
||||||
#include "mozilla/RefPtr.h"
|
#include "mozilla/RefPtr.h"
|
||||||
#include "mozilla/Span.h"
|
#include "mozilla/Span.h"
|
||||||
#include "js/String.h"
|
#include "js/String.h"
|
||||||
|
|
@ -18,7 +18,7 @@ namespace mozilla::dom::binding_detail {
|
||||||
// A struct that has a layout compatible with nsAString, so that
|
// A struct that has a layout compatible with nsAString, so that
|
||||||
// reinterpret-casting a FakeString as a const nsAString is safe, but much
|
// reinterpret-casting a FakeString as a const nsAString is safe, but much
|
||||||
// faster constructor and destructor behavior. FakeString uses inline storage
|
// faster constructor and destructor behavior. FakeString uses inline storage
|
||||||
// for small strings and an nsStringBuffer for longer strings. It can also
|
// for small strings and an StringBuffer for longer strings. It can also
|
||||||
// point to a literal (static-lifetime) string that's compiled into the binary,
|
// point to a literal (static-lifetime) string that's compiled into the binary,
|
||||||
// or point at the buffer of an nsAString whose lifetime is longer than that of
|
// or point at the buffer of an nsAString whose lifetime is longer than that of
|
||||||
// the FakeString.
|
// the FakeString.
|
||||||
|
|
@ -43,7 +43,7 @@ struct FakeString {
|
||||||
~FakeString() {
|
~FakeString() {
|
||||||
if (mDataFlags & DataFlags::REFCOUNTED) {
|
if (mDataFlags & DataFlags::REFCOUNTED) {
|
||||||
MOZ_ASSERT(mDataInitialized);
|
MOZ_ASSERT(mDataInitialized);
|
||||||
nsStringBuffer::FromData(mData)->Release();
|
StringBuffer::FromData(mData)->Release();
|
||||||
}
|
}
|
||||||
}
|
}
|
||||||
|
|
||||||
|
|
@ -51,7 +51,7 @@ struct FakeString {
|
||||||
// depend upon aString's data. aString should outlive this instance of
|
// depend upon aString's data. aString should outlive this instance of
|
||||||
// FakeString.
|
// FakeString.
|
||||||
void ShareOrDependUpon(const AString& aString) {
|
void ShareOrDependUpon(const AString& aString) {
|
||||||
RefPtr<nsStringBuffer> sharedBuffer = aString.GetStringBuffer();
|
RefPtr<StringBuffer> sharedBuffer = aString.GetStringBuffer();
|
||||||
if (!sharedBuffer) {
|
if (!sharedBuffer) {
|
||||||
InitData(aString.BeginReading(), aString.Length());
|
InitData(aString.BeginReading(), aString.Length());
|
||||||
if (!aString.IsTerminated()) {
|
if (!aString.IsTerminated()) {
|
||||||
|
|
@ -102,8 +102,8 @@ struct FakeString {
|
||||||
InitData(mStorage, aLength);
|
InitData(mStorage, aLength);
|
||||||
mDataFlags |= DataFlags::INLINE;
|
mDataFlags |= DataFlags::INLINE;
|
||||||
} else {
|
} else {
|
||||||
RefPtr<nsStringBuffer> buf =
|
RefPtr<StringBuffer> buf =
|
||||||
nsStringBuffer::Alloc((aLength + 1) * sizeof(char_type));
|
StringBuffer::Alloc((aLength + 1) * sizeof(char_type));
|
||||||
if (MOZ_UNLIKELY(!buf)) {
|
if (MOZ_UNLIKELY(!buf)) {
|
||||||
return false;
|
return false;
|
||||||
}
|
}
|
||||||
|
|
@ -124,10 +124,10 @@ struct FakeString {
|
||||||
return true;
|
return true;
|
||||||
}
|
}
|
||||||
|
|
||||||
RefPtr<nsStringBuffer> buffer;
|
RefPtr<StringBuffer> buffer;
|
||||||
if (mDataFlags & DataFlags::REFCOUNTED) {
|
if (mDataFlags & DataFlags::REFCOUNTED) {
|
||||||
// Make sure we'll drop it when we're done.
|
// Make sure we'll drop it when we're done.
|
||||||
buffer = dont_AddRef(nsStringBuffer::FromData(mData));
|
buffer = dont_AddRef(StringBuffer::FromData(mData));
|
||||||
// And make sure we don't release it twice by accident.
|
// And make sure we don't release it twice by accident.
|
||||||
}
|
}
|
||||||
const char_type* oldChars = mData;
|
const char_type* oldChars = mData;
|
||||||
|
|
@ -151,7 +151,7 @@ struct FakeString {
|
||||||
return true;
|
return true;
|
||||||
}
|
}
|
||||||
|
|
||||||
void AssignFromStringBuffer(already_AddRefed<nsStringBuffer> aBuffer,
|
void AssignFromStringBuffer(already_AddRefed<StringBuffer> aBuffer,
|
||||||
size_t aLength) {
|
size_t aLength) {
|
||||||
InitData(static_cast<char_type*>(aBuffer.take()->Data()), aLength);
|
InitData(static_cast<char_type*>(aBuffer.take()->Data()), aLength);
|
||||||
mDataFlags |= DataFlags::REFCOUNTED;
|
mDataFlags |= DataFlags::REFCOUNTED;
|
||||||
|
|
@ -214,7 +214,7 @@ struct FakeString {
|
||||||
bool IsMutable() {
|
bool IsMutable() {
|
||||||
return (mDataFlags & DataFlags::INLINE) ||
|
return (mDataFlags & DataFlags::INLINE) ||
|
||||||
((mDataFlags & DataFlags::REFCOUNTED) &&
|
((mDataFlags & DataFlags::REFCOUNTED) &&
|
||||||
!nsStringBuffer::FromData(mData)->IsReadonly());
|
!StringBuffer::FromData(mData)->IsReadonly());
|
||||||
}
|
}
|
||||||
|
|
||||||
friend class NonNull<AString>;
|
friend class NonNull<AString>;
|
||||||
|
|
@ -257,11 +257,15 @@ struct FakeString {
|
||||||
};
|
};
|
||||||
} // namespace mozilla::dom::binding_detail
|
} // namespace mozilla::dom::binding_detail
|
||||||
|
|
||||||
|
namespace mozilla {
|
||||||
|
|
||||||
template <typename CharT>
|
template <typename CharT>
|
||||||
inline void AssignFromStringBuffer(
|
inline void AssignFromStringBuffer(
|
||||||
nsStringBuffer* aBuffer, size_t aLength,
|
StringBuffer* aBuffer, size_t aLength,
|
||||||
mozilla::dom::binding_detail::FakeString<CharT>& aDest) {
|
dom::binding_detail::FakeString<CharT>& aDest) {
|
||||||
aDest.AssignFromStringBuffer(do_AddRef(aBuffer), aLength);
|
aDest.AssignFromStringBuffer(do_AddRef(aBuffer), aLength);
|
||||||
}
|
}
|
||||||
|
|
||||||
|
} // namespace mozilla
|
||||||
|
|
||||||
#endif /* mozilla_dom_FakeString_h__ */
|
#endif /* mozilla_dom_FakeString_h__ */
|
||||||
|
|
|
||||||
|
|
@ -11,7 +11,7 @@
|
||||||
#include "mozilla/dom/WindowProxyHolder.h"
|
#include "mozilla/dom/WindowProxyHolder.h"
|
||||||
#include "nsAString.h"
|
#include "nsAString.h"
|
||||||
#include "nsContentUtils.h"
|
#include "nsContentUtils.h"
|
||||||
#include "nsStringBuffer.h"
|
#include "mozilla/StringBuffer.h"
|
||||||
#include "xpcpublic.h"
|
#include "xpcpublic.h"
|
||||||
|
|
||||||
namespace mozilla::dom {
|
namespace mozilla::dom {
|
||||||
|
|
@ -23,7 +23,7 @@ bool ToJSValue(JSContext* aCx, const nsAString& aArgument,
|
||||||
|
|
||||||
// XXXkhuey I'd love to use xpc::NonVoidStringToJsval here, but it requires
|
// XXXkhuey I'd love to use xpc::NonVoidStringToJsval here, but it requires
|
||||||
// a non-const nsAString for silly reasons.
|
// a non-const nsAString for silly reasons.
|
||||||
nsStringBuffer* sharedBuffer;
|
mozilla::StringBuffer* sharedBuffer;
|
||||||
if (!XPCStringConvert::ReadableToJSVal(aCx, aArgument, &sharedBuffer,
|
if (!XPCStringConvert::ReadableToJSVal(aCx, aArgument, &sharedBuffer,
|
||||||
aValue)) {
|
aValue)) {
|
||||||
return false;
|
return false;
|
||||||
|
|
|
||||||
|
|
@ -10,7 +10,7 @@
|
||||||
#include "mozilla/dom/TestFunctionsBinding.h"
|
#include "mozilla/dom/TestFunctionsBinding.h"
|
||||||
#include "mozilla/dom/WindowBinding.h"
|
#include "mozilla/dom/WindowBinding.h"
|
||||||
#include "mozilla/dom/WrapperCachedNonISupportsTestInterface.h"
|
#include "mozilla/dom/WrapperCachedNonISupportsTestInterface.h"
|
||||||
#include "nsStringBuffer.h"
|
#include "mozilla/StringBuffer.h"
|
||||||
#include "mozITestInterfaceJS.h"
|
#include "mozITestInterfaceJS.h"
|
||||||
#include "nsComponentManagerUtils.h"
|
#include "nsComponentManagerUtils.h"
|
||||||
#include "nsGlobalWindowInner.h"
|
#include "nsGlobalWindowInner.h"
|
||||||
|
|
@ -66,7 +66,7 @@ void TestFunctions::GetStringDataAsDOMString(const Optional<uint32_t>& aLength,
|
||||||
length = mStringData.Length();
|
length = mStringData.Length();
|
||||||
}
|
}
|
||||||
|
|
||||||
if (nsStringBuffer* buf = mStringData.GetStringBuffer()) {
|
if (StringBuffer* buf = mStringData.GetStringBuffer()) {
|
||||||
aString.SetKnownLiveStringBuffer(buf, length);
|
aString.SetKnownLiveStringBuffer(buf, length);
|
||||||
return;
|
return;
|
||||||
}
|
}
|
||||||
|
|
|
||||||
|
|
@ -1999,13 +1999,13 @@ and exported to `mozilla/dom/BindingDeclarations.h` that is used for
|
||||||
Web IDL `DOMString` return values. It has a conversion operator to
|
Web IDL `DOMString` return values. It has a conversion operator to
|
||||||
`nsString&` so that it can be passed to methods that take that type or
|
`nsString&` so that it can be passed to methods that take that type or
|
||||||
`nsAString&`, but callees that care about performance, have an
|
`nsAString&`, but callees that care about performance, have an
|
||||||
`nsStringBuffer` available, and promise to hold on to the
|
`StringBuffer` available, and promise to hold on to the
|
||||||
`nsStringBuffer` at least until the binding code comes off the stack
|
`StringBuffer` at least until the binding code comes off the stack
|
||||||
can also take a `DOMString` directly for their string return value and
|
can also take a `DOMString` directly for their string return value and
|
||||||
call its `SetStringBuffer` method with the `nsStringBuffer` and its
|
call its `SetStringBuffer` method with the `StringBuffer` and its
|
||||||
length. This allows the binding code to avoid extra reference-counting
|
length. This allows the binding code to avoid extra reference-counting
|
||||||
of the string buffer in many cases, and allows it to take a faster
|
of the string buffer in many cases, and allows it to take a faster
|
||||||
codepath even if it does end up having to addref the `nsStringBuffer`.
|
codepath even if it does end up having to addref the `StringBuffer`.
|
||||||
|
|
||||||
### `GlobalObject`
|
### `GlobalObject`
|
||||||
|
|
||||||
|
|
|
||||||
|
|
@ -1068,8 +1068,8 @@ already_AddRefed<nsITransferable> DataTransfer::GetTransferable(
|
||||||
nsCOMPtr<nsIInputStream> inputStream;
|
nsCOMPtr<nsIInputStream> inputStream;
|
||||||
storageStream->NewInputStream(0, getter_AddRefs(inputStream));
|
storageStream->NewInputStream(0, getter_AddRefs(inputStream));
|
||||||
|
|
||||||
RefPtr<nsStringBuffer> stringBuffer =
|
RefPtr<StringBuffer> stringBuffer =
|
||||||
nsStringBuffer::Alloc(totalCustomLength);
|
StringBuffer::Alloc(totalCustomLength);
|
||||||
|
|
||||||
// Subtract off the null terminator when reading.
|
// Subtract off the null terminator when reading.
|
||||||
totalCustomLength--;
|
totalCustomLength--;
|
||||||
|
|
|
||||||
|
|
@ -652,7 +652,7 @@ void FetchUtil::InitWasmAltDataType() {
|
||||||
MOZ_ASSERT(type.IsEmpty());
|
MOZ_ASSERT(type.IsEmpty());
|
||||||
|
|
||||||
RunOnShutdown([]() {
|
RunOnShutdown([]() {
|
||||||
// Avoid nsStringBuffer leak tests failures.
|
// Avoid StringBuffer leak tests failures.
|
||||||
const_cast<nsCString&>(WasmAltDataType).Truncate();
|
const_cast<nsCString&>(WasmAltDataType).Truncate();
|
||||||
});
|
});
|
||||||
|
|
||||||
|
|
|
||||||
|
|
@ -36,7 +36,7 @@
|
||||||
#include "nsTArray.h"
|
#include "nsTArray.h"
|
||||||
#include "nsIFrame.h"
|
#include "nsIFrame.h"
|
||||||
#include "nsLayoutUtils.h"
|
#include "nsLayoutUtils.h"
|
||||||
#include "nsStringBuffer.h"
|
#include "mozilla/StringBuffer.h"
|
||||||
#include "mozilla/dom/Comment.h"
|
#include "mozilla/dom/Comment.h"
|
||||||
#include "mozilla/dom/Document.h"
|
#include "mozilla/dom/Document.h"
|
||||||
#include "mozilla/dom/DocumentType.h"
|
#include "mozilla/dom/DocumentType.h"
|
||||||
|
|
@ -341,7 +341,7 @@ class nsDocumentEncoder : public nsIDocumentEncoder {
|
||||||
// argument of nsIContentSerializer::Init().
|
// argument of nsIContentSerializer::Init().
|
||||||
bool mNeedsPreformatScanning;
|
bool mNeedsPreformatScanning;
|
||||||
bool mIsCopying; // Set to true only while copying
|
bool mIsCopying; // Set to true only while copying
|
||||||
RefPtr<nsStringBuffer> mCachedBuffer;
|
RefPtr<StringBuffer> mCachedBuffer;
|
||||||
|
|
||||||
class NodeSerializer {
|
class NodeSerializer {
|
||||||
public:
|
public:
|
||||||
|
|
@ -1368,7 +1368,7 @@ nsDocumentEncoder::EncodeToStringWithMaxLength(uint32_t aMaxLength,
|
||||||
nsString output;
|
nsString output;
|
||||||
static const size_t kStringBufferSizeInBytes = 2048;
|
static const size_t kStringBufferSizeInBytes = 2048;
|
||||||
if (!mCachedBuffer) {
|
if (!mCachedBuffer) {
|
||||||
mCachedBuffer = nsStringBuffer::Alloc(kStringBufferSizeInBytes);
|
mCachedBuffer = StringBuffer::Alloc(kStringBufferSizeInBytes);
|
||||||
if (NS_WARN_IF(!mCachedBuffer)) {
|
if (NS_WARN_IF(!mCachedBuffer)) {
|
||||||
return NS_ERROR_OUT_OF_MEMORY;
|
return NS_ERROR_OUT_OF_MEMORY;
|
||||||
}
|
}
|
||||||
|
|
@ -1406,7 +1406,7 @@ nsDocumentEncoder::EncodeToStringWithMaxLength(uint32_t aMaxLength,
|
||||||
bool setOutput = false;
|
bool setOutput = false;
|
||||||
MOZ_ASSERT(!mCachedBuffer);
|
MOZ_ASSERT(!mCachedBuffer);
|
||||||
// Try to cache the buffer.
|
// Try to cache the buffer.
|
||||||
if (nsStringBuffer* outputBuffer = output.GetStringBuffer()) {
|
if (StringBuffer* outputBuffer = output.GetStringBuffer()) {
|
||||||
if (outputBuffer->StorageSize() == kStringBufferSizeInBytes &&
|
if (outputBuffer->StorageSize() == kStringBufferSizeInBytes &&
|
||||||
!outputBuffer->IsReadonly()) {
|
!outputBuffer->IsReadonly()) {
|
||||||
mCachedBuffer = outputBuffer;
|
mCachedBuffer = outputBuffer;
|
||||||
|
|
|
||||||
|
|
@ -83,7 +83,6 @@
|
||||||
#include "nsIWindowWatcher.h"
|
#include "nsIWindowWatcher.h"
|
||||||
#include "nsIConsoleService.h"
|
#include "nsIConsoleService.h"
|
||||||
#include "nsAsyncRedirectVerifyHelper.h"
|
#include "nsAsyncRedirectVerifyHelper.h"
|
||||||
#include "nsStringBuffer.h"
|
|
||||||
#include "nsIFileChannel.h"
|
#include "nsIFileChannel.h"
|
||||||
#include "mozilla/Telemetry.h"
|
#include "mozilla/Telemetry.h"
|
||||||
#include "js/ArrayBuffer.h" // JS::{Create,Release}MappedArrayBufferContents,New{,Mapped}ArrayBufferWithContents
|
#include "js/ArrayBuffer.h" // JS::{Create,Release}MappedArrayBufferContents,New{,Mapped}ArrayBufferWithContents
|
||||||
|
|
|
||||||
|
|
@ -58,7 +58,7 @@ class XMLHttpRequestStringBuffer final {
|
||||||
|
|
||||||
// XXX: Bug 1408793 suggests encapsulating the following sequence within
|
// XXX: Bug 1408793 suggests encapsulating the following sequence within
|
||||||
// DOMString.
|
// DOMString.
|
||||||
if (nsStringBuffer* buf = mData.GetStringBuffer()) {
|
if (StringBuffer* buf = mData.GetStringBuffer()) {
|
||||||
// We have to use SetStringBuffer, because once we release our mutex mData
|
// We have to use SetStringBuffer, because once we release our mutex mData
|
||||||
// can get mutated from some other thread while the DOMString is still
|
// can get mutated from some other thread while the DOMString is still
|
||||||
// alive.
|
// alive.
|
||||||
|
|
|
||||||
|
|
@ -286,10 +286,6 @@ function checkFieldWrite(entry, location, fields)
|
||||||
|
|
||||||
if (/\bThreadLocal<\b/.test(field))
|
if (/\bThreadLocal<\b/.test(field))
|
||||||
return;
|
return;
|
||||||
|
|
||||||
// Debugging check for string corruption.
|
|
||||||
if (field == "nsStringBuffer.mCanary")
|
|
||||||
return;
|
|
||||||
}
|
}
|
||||||
|
|
||||||
var str = "";
|
var str = "";
|
||||||
|
|
@ -539,7 +535,7 @@ function ignoreContents(entry)
|
||||||
|
|
||||||
if (entry.isSafeArgument(2)) {
|
if (entry.isSafeArgument(2)) {
|
||||||
var secondArgWhitelist = [
|
var secondArgWhitelist = [
|
||||||
/nsStringBuffer::ToString/,
|
/StringBuffer::ToString/,
|
||||||
/AppendUTF\d+toUTF\d+/,
|
/AppendUTF\d+toUTF\d+/,
|
||||||
/AppendASCIItoUTF\d+/,
|
/AppendASCIItoUTF\d+/,
|
||||||
];
|
];
|
||||||
|
|
|
||||||
|
|
@ -165,7 +165,7 @@ bool XPCConvert::NativeData2JS(JSContext* cx, MutableHandleValue d,
|
||||||
return true;
|
return true;
|
||||||
}
|
}
|
||||||
|
|
||||||
nsStringBuffer* buf;
|
StringBuffer* buf;
|
||||||
if (!XPCStringConvert::ReadableToJSVal(cx, *p, &buf, d)) {
|
if (!XPCStringConvert::ReadableToJSVal(cx, *p, &buf, d)) {
|
||||||
return false;
|
return false;
|
||||||
}
|
}
|
||||||
|
|
@ -255,7 +255,7 @@ bool XPCConvert::NativeData2JS(JSContext* cx, MutableHandleValue d,
|
||||||
// NOTE: XPCStringConvert::UTF8ToJSVal cannot be used here because
|
// NOTE: XPCStringConvert::UTF8ToJSVal cannot be used here because
|
||||||
// it requires valid UTF-8 sequence.
|
// it requires valid UTF-8 sequence.
|
||||||
if (mozilla::IsAscii(*utf8String)) {
|
if (mozilla::IsAscii(*utf8String)) {
|
||||||
nsStringBuffer* buf;
|
StringBuffer* buf;
|
||||||
if (!XPCStringConvert::Latin1ToJSVal(cx, *utf8String, &buf, d)) {
|
if (!XPCStringConvert::Latin1ToJSVal(cx, *utf8String, &buf, d)) {
|
||||||
return false;
|
return false;
|
||||||
}
|
}
|
||||||
|
|
@ -312,7 +312,7 @@ bool XPCConvert::NativeData2JS(JSContext* cx, MutableHandleValue d,
|
||||||
}
|
}
|
||||||
|
|
||||||
// c-strings (binary blobs) are Latin1 string in JSAPI.
|
// c-strings (binary blobs) are Latin1 string in JSAPI.
|
||||||
nsStringBuffer* buf;
|
StringBuffer* buf;
|
||||||
if (!XPCStringConvert::Latin1ToJSVal(cx, *cString, &buf, d)) {
|
if (!XPCStringConvert::Latin1ToJSVal(cx, *cString, &buf, d)) {
|
||||||
return false;
|
return false;
|
||||||
}
|
}
|
||||||
|
|
|
||||||
|
|
@ -20,11 +20,12 @@
|
||||||
|
|
||||||
#include "nscore.h"
|
#include "nscore.h"
|
||||||
#include "nsString.h"
|
#include "nsString.h"
|
||||||
#include "nsStringBuffer.h"
|
#include "mozilla/StringBuffer.h"
|
||||||
#include "jsapi.h"
|
#include "jsapi.h"
|
||||||
#include "xpcpublic.h"
|
#include "xpcpublic.h"
|
||||||
|
|
||||||
using namespace JS;
|
using namespace JS;
|
||||||
|
using mozilla::StringBuffer;
|
||||||
|
|
||||||
const XPCStringConvert::LiteralExternalString
|
const XPCStringConvert::LiteralExternalString
|
||||||
XPCStringConvert::sLiteralExternalString;
|
XPCStringConvert::sLiteralExternalString;
|
||||||
|
|
@ -55,13 +56,13 @@ size_t XPCStringConvert::LiteralExternalString::sizeOfBuffer(
|
||||||
|
|
||||||
void XPCStringConvert::DOMStringExternalString::finalize(
|
void XPCStringConvert::DOMStringExternalString::finalize(
|
||||||
JS::Latin1Char* aChars) const {
|
JS::Latin1Char* aChars) const {
|
||||||
nsStringBuffer* buf = nsStringBuffer::FromData(aChars);
|
StringBuffer* buf = StringBuffer::FromData(aChars);
|
||||||
buf->Release();
|
buf->Release();
|
||||||
}
|
}
|
||||||
|
|
||||||
void XPCStringConvert::DOMStringExternalString::finalize(
|
void XPCStringConvert::DOMStringExternalString::finalize(
|
||||||
char16_t* aChars) const {
|
char16_t* aChars) const {
|
||||||
nsStringBuffer* buf = nsStringBuffer::FromData(aChars);
|
StringBuffer* buf = StringBuffer::FromData(aChars);
|
||||||
buf->Release();
|
buf->Release();
|
||||||
}
|
}
|
||||||
|
|
||||||
|
|
@ -70,8 +71,8 @@ size_t XPCStringConvert::DOMStringExternalString::sizeOfBuffer(
|
||||||
// We promised the JS engine we would not GC. Enforce that:
|
// We promised the JS engine we would not GC. Enforce that:
|
||||||
JS::AutoCheckCannotGC autoCannotGC;
|
JS::AutoCheckCannotGC autoCannotGC;
|
||||||
|
|
||||||
const nsStringBuffer* buf =
|
const StringBuffer* buf =
|
||||||
nsStringBuffer::FromData(const_cast<JS::Latin1Char*>(aChars));
|
StringBuffer::FromData(const_cast<JS::Latin1Char*>(aChars));
|
||||||
// We want sizeof including this, because the entire string buffer is owned by
|
// We want sizeof including this, because the entire string buffer is owned by
|
||||||
// the external string. But only report here if we're unshared; if we're
|
// the external string. But only report here if we're unshared; if we're
|
||||||
// shared then we don't know who really owns this data.
|
// shared then we don't know who really owns this data.
|
||||||
|
|
@ -83,8 +84,8 @@ size_t XPCStringConvert::DOMStringExternalString::sizeOfBuffer(
|
||||||
// We promised the JS engine we would not GC. Enforce that:
|
// We promised the JS engine we would not GC. Enforce that:
|
||||||
JS::AutoCheckCannotGC autoCannotGC;
|
JS::AutoCheckCannotGC autoCannotGC;
|
||||||
|
|
||||||
const nsStringBuffer* buf =
|
const StringBuffer* buf =
|
||||||
nsStringBuffer::FromData(const_cast<char16_t*>(aChars));
|
StringBuffer::FromData(const_cast<char16_t*>(aChars));
|
||||||
// We want sizeof including this, because the entire string buffer is owned by
|
// We want sizeof including this, because the entire string buffer is owned by
|
||||||
// the external string. But only report here if we're unshared; if we're
|
// the external string. But only report here if we're unshared; if we're
|
||||||
// shared then we don't know who really owns this data.
|
// shared then we don't know who really owns this data.
|
||||||
|
|
@ -94,7 +95,7 @@ size_t XPCStringConvert::DOMStringExternalString::sizeOfBuffer(
|
||||||
// convert a readable to a JSString, copying string data
|
// convert a readable to a JSString, copying string data
|
||||||
// static
|
// static
|
||||||
bool XPCStringConvert::ReadableToJSVal(JSContext* cx, const nsAString& readable,
|
bool XPCStringConvert::ReadableToJSVal(JSContext* cx, const nsAString& readable,
|
||||||
nsStringBuffer** sharedBuffer,
|
StringBuffer** sharedBuffer,
|
||||||
MutableHandleValue vp) {
|
MutableHandleValue vp) {
|
||||||
*sharedBuffer = nullptr;
|
*sharedBuffer = nullptr;
|
||||||
|
|
||||||
|
|
@ -104,7 +105,7 @@ bool XPCStringConvert::ReadableToJSVal(JSContext* cx, const nsAString& readable,
|
||||||
return StringLiteralToJSVal(cx, readable.BeginReading(), length, vp);
|
return StringLiteralToJSVal(cx, readable.BeginReading(), length, vp);
|
||||||
}
|
}
|
||||||
|
|
||||||
if (nsStringBuffer* buf = readable.GetStringBuffer()) {
|
if (StringBuffer* buf = readable.GetStringBuffer()) {
|
||||||
bool shared;
|
bool shared;
|
||||||
if (!UCStringBufferToJSVal(cx, buf, length, vp, &shared)) {
|
if (!UCStringBufferToJSVal(cx, buf, length, vp, &shared)) {
|
||||||
return false;
|
return false;
|
||||||
|
|
@ -125,7 +126,7 @@ bool XPCStringConvert::ReadableToJSVal(JSContext* cx, const nsAString& readable,
|
||||||
}
|
}
|
||||||
|
|
||||||
bool XPCStringConvert::Latin1ToJSVal(JSContext* cx, const nsACString& latin1,
|
bool XPCStringConvert::Latin1ToJSVal(JSContext* cx, const nsACString& latin1,
|
||||||
nsStringBuffer** sharedBuffer,
|
StringBuffer** sharedBuffer,
|
||||||
MutableHandleValue vp) {
|
MutableHandleValue vp) {
|
||||||
*sharedBuffer = nullptr;
|
*sharedBuffer = nullptr;
|
||||||
|
|
||||||
|
|
@ -137,7 +138,7 @@ bool XPCStringConvert::Latin1ToJSVal(JSContext* cx, const nsACString& latin1,
|
||||||
length, vp);
|
length, vp);
|
||||||
}
|
}
|
||||||
|
|
||||||
if (nsStringBuffer* buf = latin1.GetStringBuffer()) {
|
if (StringBuffer* buf = latin1.GetStringBuffer()) {
|
||||||
bool shared;
|
bool shared;
|
||||||
if (!Latin1StringBufferToJSVal(cx, buf, length, vp, &shared)) {
|
if (!Latin1StringBufferToJSVal(cx, buf, length, vp, &shared)) {
|
||||||
return false;
|
return false;
|
||||||
|
|
@ -157,7 +158,7 @@ bool XPCStringConvert::Latin1ToJSVal(JSContext* cx, const nsACString& latin1,
|
||||||
}
|
}
|
||||||
|
|
||||||
bool XPCStringConvert::UTF8ToJSVal(JSContext* cx, const nsACString& utf8,
|
bool XPCStringConvert::UTF8ToJSVal(JSContext* cx, const nsACString& utf8,
|
||||||
nsStringBuffer** sharedBuffer,
|
StringBuffer** sharedBuffer,
|
||||||
MutableHandleValue vp) {
|
MutableHandleValue vp) {
|
||||||
*sharedBuffer = nullptr;
|
*sharedBuffer = nullptr;
|
||||||
|
|
||||||
|
|
@ -168,7 +169,7 @@ bool XPCStringConvert::UTF8ToJSVal(JSContext* cx, const nsACString& utf8,
|
||||||
cx, JS::UTF8Chars(utf8.BeginReading(), length), vp);
|
cx, JS::UTF8Chars(utf8.BeginReading(), length), vp);
|
||||||
}
|
}
|
||||||
|
|
||||||
if (nsStringBuffer* buf = utf8.GetStringBuffer()) {
|
if (StringBuffer* buf = utf8.GetStringBuffer()) {
|
||||||
bool shared;
|
bool shared;
|
||||||
if (!UTF8StringBufferToJSVal(cx, buf, length, vp, &shared)) {
|
if (!UTF8StringBufferToJSVal(cx, buf, length, vp, &shared)) {
|
||||||
return false;
|
return false;
|
||||||
|
|
@ -192,7 +193,7 @@ namespace xpc {
|
||||||
|
|
||||||
bool NonVoidStringToJsval(JSContext* cx, nsAString& str,
|
bool NonVoidStringToJsval(JSContext* cx, nsAString& str,
|
||||||
MutableHandleValue rval) {
|
MutableHandleValue rval) {
|
||||||
nsStringBuffer* sharedBuffer;
|
StringBuffer* sharedBuffer;
|
||||||
if (!XPCStringConvert::ReadableToJSVal(cx, str, &sharedBuffer, rval)) {
|
if (!XPCStringConvert::ReadableToJSVal(cx, str, &sharedBuffer, rval)) {
|
||||||
return false;
|
return false;
|
||||||
}
|
}
|
||||||
|
|
@ -207,7 +208,7 @@ bool NonVoidStringToJsval(JSContext* cx, nsAString& str,
|
||||||
|
|
||||||
bool NonVoidStringToJsval(JSContext* cx, const nsAString& str,
|
bool NonVoidStringToJsval(JSContext* cx, const nsAString& str,
|
||||||
MutableHandleValue rval) {
|
MutableHandleValue rval) {
|
||||||
nsStringBuffer* sharedBuffer;
|
StringBuffer* sharedBuffer;
|
||||||
if (!XPCStringConvert::ReadableToJSVal(cx, str, &sharedBuffer, rval)) {
|
if (!XPCStringConvert::ReadableToJSVal(cx, str, &sharedBuffer, rval)) {
|
||||||
return false;
|
return false;
|
||||||
}
|
}
|
||||||
|
|
@ -221,7 +222,7 @@ bool NonVoidStringToJsval(JSContext* cx, const nsAString& str,
|
||||||
|
|
||||||
bool NonVoidLatin1StringToJsval(JSContext* cx, nsACString& str,
|
bool NonVoidLatin1StringToJsval(JSContext* cx, nsACString& str,
|
||||||
MutableHandleValue rval) {
|
MutableHandleValue rval) {
|
||||||
nsStringBuffer* sharedBuffer;
|
StringBuffer* sharedBuffer;
|
||||||
if (!XPCStringConvert::Latin1ToJSVal(cx, str, &sharedBuffer, rval)) {
|
if (!XPCStringConvert::Latin1ToJSVal(cx, str, &sharedBuffer, rval)) {
|
||||||
return false;
|
return false;
|
||||||
}
|
}
|
||||||
|
|
@ -236,7 +237,7 @@ bool NonVoidLatin1StringToJsval(JSContext* cx, nsACString& str,
|
||||||
|
|
||||||
bool NonVoidLatin1StringToJsval(JSContext* cx, const nsACString& str,
|
bool NonVoidLatin1StringToJsval(JSContext* cx, const nsACString& str,
|
||||||
MutableHandleValue rval) {
|
MutableHandleValue rval) {
|
||||||
nsStringBuffer* sharedBuffer;
|
StringBuffer* sharedBuffer;
|
||||||
if (!XPCStringConvert::Latin1ToJSVal(cx, str, &sharedBuffer, rval)) {
|
if (!XPCStringConvert::Latin1ToJSVal(cx, str, &sharedBuffer, rval)) {
|
||||||
return false;
|
return false;
|
||||||
}
|
}
|
||||||
|
|
@ -250,7 +251,7 @@ bool NonVoidLatin1StringToJsval(JSContext* cx, const nsACString& str,
|
||||||
|
|
||||||
bool NonVoidUTF8StringToJsval(JSContext* cx, nsACString& str,
|
bool NonVoidUTF8StringToJsval(JSContext* cx, nsACString& str,
|
||||||
MutableHandleValue rval) {
|
MutableHandleValue rval) {
|
||||||
nsStringBuffer* sharedBuffer;
|
StringBuffer* sharedBuffer;
|
||||||
if (!XPCStringConvert::UTF8ToJSVal(cx, str, &sharedBuffer, rval)) {
|
if (!XPCStringConvert::UTF8ToJSVal(cx, str, &sharedBuffer, rval)) {
|
||||||
return false;
|
return false;
|
||||||
}
|
}
|
||||||
|
|
@ -265,7 +266,7 @@ bool NonVoidUTF8StringToJsval(JSContext* cx, nsACString& str,
|
||||||
|
|
||||||
bool NonVoidUTF8StringToJsval(JSContext* cx, const nsACString& str,
|
bool NonVoidUTF8StringToJsval(JSContext* cx, const nsACString& str,
|
||||||
MutableHandleValue rval) {
|
MutableHandleValue rval) {
|
||||||
nsStringBuffer* sharedBuffer;
|
StringBuffer* sharedBuffer;
|
||||||
if (!XPCStringConvert::UTF8ToJSVal(cx, str, &sharedBuffer, rval)) {
|
if (!XPCStringConvert::UTF8ToJSVal(cx, str, &sharedBuffer, rval)) {
|
||||||
return false;
|
return false;
|
||||||
}
|
}
|
||||||
|
|
|
||||||
|
|
@ -138,7 +138,6 @@
|
||||||
#include "nsBaseHashtable.h"
|
#include "nsBaseHashtable.h"
|
||||||
#include "nsHashKeys.h"
|
#include "nsHashKeys.h"
|
||||||
#include "nsWrapperCache.h"
|
#include "nsWrapperCache.h"
|
||||||
#include "nsStringBuffer.h"
|
|
||||||
#include "nsDeque.h"
|
#include "nsDeque.h"
|
||||||
|
|
||||||
#include "nsIScriptSecurityManager.h"
|
#include "nsIScriptSecurityManager.h"
|
||||||
|
|
|
||||||
|
|
@ -28,12 +28,12 @@
|
||||||
#include "mozilla/MemoryReporting.h"
|
#include "mozilla/MemoryReporting.h"
|
||||||
#include "mozilla/TextUtils.h"
|
#include "mozilla/TextUtils.h"
|
||||||
#include "mozilla/dom/DOMString.h"
|
#include "mozilla/dom/DOMString.h"
|
||||||
|
#include "mozilla/StringBuffer.h"
|
||||||
#include "mozilla/fallible.h"
|
#include "mozilla/fallible.h"
|
||||||
#include "nsAtom.h"
|
#include "nsAtom.h"
|
||||||
#include "nsCOMPtr.h"
|
#include "nsCOMPtr.h"
|
||||||
#include "nsISupports.h"
|
#include "nsISupports.h"
|
||||||
#include "nsIURI.h"
|
#include "nsIURI.h"
|
||||||
#include "nsStringBuffer.h"
|
|
||||||
#include "nsStringFwd.h"
|
#include "nsStringFwd.h"
|
||||||
#include "nsTArray.h"
|
#include "nsTArray.h"
|
||||||
#include "nsWrapperCache.h"
|
#include "nsWrapperCache.h"
|
||||||
|
|
@ -236,11 +236,11 @@ extern bool xpc_DumpJSStack(bool showArgs, bool showLocals, bool showThisProps);
|
||||||
extern JS::UniqueChars xpc_PrintJSStack(JSContext* cx, bool showArgs,
|
extern JS::UniqueChars xpc_PrintJSStack(JSContext* cx, bool showArgs,
|
||||||
bool showLocals, bool showThisProps);
|
bool showLocals, bool showThisProps);
|
||||||
|
|
||||||
inline void AssignFromStringBuffer(nsStringBuffer* buffer, size_t len,
|
inline void AssignFromStringBuffer(mozilla::StringBuffer* buffer, size_t len,
|
||||||
nsAString& dest) {
|
nsAString& dest) {
|
||||||
dest.Assign(buffer, len);
|
dest.Assign(buffer, len);
|
||||||
}
|
}
|
||||||
inline void AssignFromStringBuffer(nsStringBuffer* buffer, size_t len,
|
inline void AssignFromStringBuffer(mozilla::StringBuffer* buffer, size_t len,
|
||||||
nsACString& dest) {
|
nsACString& dest) {
|
||||||
dest.Assign(buffer, len);
|
dest.Assign(buffer, len);
|
||||||
}
|
}
|
||||||
|
|
@ -252,18 +252,18 @@ class XPCStringConvert {
|
||||||
// get assigned to *sharedBuffer. Otherwise null will be
|
// get assigned to *sharedBuffer. Otherwise null will be
|
||||||
// assigned.
|
// assigned.
|
||||||
static bool ReadableToJSVal(JSContext* cx, const nsAString& readable,
|
static bool ReadableToJSVal(JSContext* cx, const nsAString& readable,
|
||||||
nsStringBuffer** sharedBuffer,
|
mozilla::StringBuffer** sharedBuffer,
|
||||||
JS::MutableHandle<JS::Value> vp);
|
JS::MutableHandle<JS::Value> vp);
|
||||||
static bool Latin1ToJSVal(JSContext* cx, const nsACString& latin1,
|
static bool Latin1ToJSVal(JSContext* cx, const nsACString& latin1,
|
||||||
nsStringBuffer** sharedBuffer,
|
mozilla::StringBuffer** sharedBuffer,
|
||||||
JS::MutableHandle<JS::Value> vp);
|
JS::MutableHandle<JS::Value> vp);
|
||||||
static bool UTF8ToJSVal(JSContext* cx, const nsACString& utf8,
|
static bool UTF8ToJSVal(JSContext* cx, const nsACString& utf8,
|
||||||
nsStringBuffer** sharedBuffer,
|
mozilla::StringBuffer** sharedBuffer,
|
||||||
JS::MutableHandle<JS::Value> vp);
|
JS::MutableHandle<JS::Value> vp);
|
||||||
|
|
||||||
// Convert the given stringbuffer/length pair to a jsval
|
// Convert the given stringbuffer/length pair to a jsval
|
||||||
static MOZ_ALWAYS_INLINE bool UCStringBufferToJSVal(
|
static MOZ_ALWAYS_INLINE bool UCStringBufferToJSVal(
|
||||||
JSContext* cx, nsStringBuffer* buf, uint32_t length,
|
JSContext* cx, mozilla::StringBuffer* buf, uint32_t length,
|
||||||
JS::MutableHandle<JS::Value> rval, bool* sharedBuffer) {
|
JS::MutableHandle<JS::Value> rval, bool* sharedBuffer) {
|
||||||
JSString* str = JS_NewMaybeExternalUCString(
|
JSString* str = JS_NewMaybeExternalUCString(
|
||||||
cx, static_cast<const char16_t*>(buf->Data()), length,
|
cx, static_cast<const char16_t*>(buf->Data()), length,
|
||||||
|
|
@ -276,7 +276,7 @@ class XPCStringConvert {
|
||||||
}
|
}
|
||||||
|
|
||||||
static MOZ_ALWAYS_INLINE bool Latin1StringBufferToJSVal(
|
static MOZ_ALWAYS_INLINE bool Latin1StringBufferToJSVal(
|
||||||
JSContext* cx, nsStringBuffer* buf, uint32_t length,
|
JSContext* cx, mozilla::StringBuffer* buf, uint32_t length,
|
||||||
JS::MutableHandle<JS::Value> rval, bool* sharedBuffer) {
|
JS::MutableHandle<JS::Value> rval, bool* sharedBuffer) {
|
||||||
JSString* str = JS_NewMaybeExternalStringLatin1(
|
JSString* str = JS_NewMaybeExternalStringLatin1(
|
||||||
cx, static_cast<const JS::Latin1Char*>(buf->Data()), length,
|
cx, static_cast<const JS::Latin1Char*>(buf->Data()), length,
|
||||||
|
|
@ -289,7 +289,7 @@ class XPCStringConvert {
|
||||||
}
|
}
|
||||||
|
|
||||||
static MOZ_ALWAYS_INLINE bool UTF8StringBufferToJSVal(
|
static MOZ_ALWAYS_INLINE bool UTF8StringBufferToJSVal(
|
||||||
JSContext* cx, nsStringBuffer* buf, uint32_t length,
|
JSContext* cx, mozilla::StringBuffer* buf, uint32_t length,
|
||||||
JS::MutableHandle<JS::Value> rval, bool* sharedBuffer) {
|
JS::MutableHandle<JS::Value> rval, bool* sharedBuffer) {
|
||||||
JSString* str = JS_NewMaybeExternalStringUTF8(
|
JSString* str = JS_NewMaybeExternalStringUTF8(
|
||||||
cx, {static_cast<const char*>(buf->Data()), length},
|
cx, {static_cast<const char*>(buf->Data()), length},
|
||||||
|
|
@ -387,9 +387,10 @@ class XPCStringConvert {
|
||||||
// the whole buffer; otherwise we have to copy.
|
// the whole buffer; otherwise we have to copy.
|
||||||
if (chars[len] == '\0') {
|
if (chars[len] == '\0') {
|
||||||
// NOTE: No need to worry about SrcCharT vs DestCharT, given
|
// NOTE: No need to worry about SrcCharT vs DestCharT, given
|
||||||
// nsStringBuffer::FromData takes void*.
|
// mozilla::StringBuffer::FromData takes void*.
|
||||||
AssignFromStringBuffer(
|
AssignFromStringBuffer(
|
||||||
nsStringBuffer::FromData(const_cast<DestCharT*>(chars)), len, dest);
|
mozilla::StringBuffer::FromData(const_cast<DestCharT*>(chars)), len,
|
||||||
|
dest);
|
||||||
return true;
|
return true;
|
||||||
}
|
}
|
||||||
} else if (callbacks == &sLiteralExternalString) {
|
} else if (callbacks == &sLiteralExternalString) {
|
||||||
|
|
@ -504,7 +505,7 @@ inline bool NonVoidStringToJsval(JSContext* cx, mozilla::dom::DOMString& str,
|
||||||
|
|
||||||
if (str.HasStringBuffer()) {
|
if (str.HasStringBuffer()) {
|
||||||
uint32_t length = str.StringBufferLength();
|
uint32_t length = str.StringBufferLength();
|
||||||
nsStringBuffer* buf = str.StringBuffer();
|
mozilla::StringBuffer* buf = str.StringBuffer();
|
||||||
bool shared;
|
bool shared;
|
||||||
if (!XPCStringConvert::UCStringBufferToJSVal(cx, buf, length, rval,
|
if (!XPCStringConvert::UCStringBufferToJSVal(cx, buf, length, rval,
|
||||||
&shared)) {
|
&shared)) {
|
||||||
|
|
|
||||||
|
|
@ -17,7 +17,6 @@
|
||||||
#include "mozilla/DbgMacro.h"
|
#include "mozilla/DbgMacro.h"
|
||||||
#include "mozilla/AnimatedPropertyID.h"
|
#include "mozilla/AnimatedPropertyID.h"
|
||||||
#include "nsStringFwd.h"
|
#include "nsStringFwd.h"
|
||||||
#include "nsStringBuffer.h"
|
|
||||||
#include "nsCoord.h"
|
#include "nsCoord.h"
|
||||||
#include "nsColor.h"
|
#include "nsColor.h"
|
||||||
#include "nsCSSPropertyID.h"
|
#include "nsCSSPropertyID.h"
|
||||||
|
|
|
||||||
|
|
@ -4,15 +4,18 @@
|
||||||
* License, v. 2.0. If a copy of the MPL was not distributed with this
|
* 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/. */
|
* file, You can obtain one at http://mozilla.org/MPL/2.0/. */
|
||||||
|
|
||||||
#ifndef nsStringBuffer_h__
|
#ifndef StringBuffer_h__
|
||||||
#define nsStringBuffer_h__
|
#define StringBuffer_h__
|
||||||
|
|
||||||
#include <atomic>
|
#include <atomic>
|
||||||
|
#include <cstring>
|
||||||
#include "mozilla/MemoryReporting.h"
|
#include "mozilla/MemoryReporting.h"
|
||||||
#include "mozilla/Assertions.h"
|
#include "mozilla/Assertions.h"
|
||||||
#include "mozilla/AlreadyAddRefed.h"
|
#include "mozilla/AlreadyAddRefed.h"
|
||||||
#include "mozilla/RefCounted.h"
|
#include "mozilla/RefCounted.h"
|
||||||
|
|
||||||
|
namespace mozilla {
|
||||||
|
|
||||||
/**
|
/**
|
||||||
* This structure precedes the string buffers "we" allocate. It may be the
|
* This structure precedes the string buffers "we" allocate. It may be the
|
||||||
* case that nsTAString::mData does not point to one of these special
|
* case that nsTAString::mData does not point to one of these special
|
||||||
|
|
@ -22,13 +25,13 @@
|
||||||
* tracking. NOTE: A string buffer can be modified only if its reference
|
* tracking. NOTE: A string buffer can be modified only if its reference
|
||||||
* count is 1.
|
* count is 1.
|
||||||
*/
|
*/
|
||||||
class nsStringBuffer {
|
class StringBuffer {
|
||||||
private:
|
private:
|
||||||
std::atomic<uint32_t> mRefCount;
|
std::atomic<uint32_t> mRefCount;
|
||||||
uint32_t mStorageSize;
|
uint32_t mStorageSize;
|
||||||
|
|
||||||
public:
|
public:
|
||||||
MOZ_DECLARE_REFCOUNTED_TYPENAME(nsStringBuffer)
|
MOZ_DECLARE_REFCOUNTED_TYPENAME(StringBuffer)
|
||||||
|
|
||||||
/**
|
/**
|
||||||
* Allocates a new string buffer, with given size in bytes and a
|
* Allocates a new string buffer, with given size in bytes and a
|
||||||
|
|
@ -47,17 +50,17 @@ class nsStringBuffer {
|
||||||
*
|
*
|
||||||
* @return new string buffer or null if out of memory.
|
* @return new string buffer or null if out of memory.
|
||||||
*/
|
*/
|
||||||
static already_AddRefed<nsStringBuffer> Alloc(size_t aSize) {
|
static already_AddRefed<StringBuffer> Alloc(size_t aSize) {
|
||||||
MOZ_ASSERT(aSize != 0, "zero capacity allocation not allowed");
|
MOZ_ASSERT(aSize != 0, "zero capacity allocation not allowed");
|
||||||
MOZ_ASSERT(sizeof(nsStringBuffer) + aSize <= size_t(uint32_t(-1)) &&
|
MOZ_ASSERT(sizeof(StringBuffer) + aSize <= size_t(uint32_t(-1)) &&
|
||||||
sizeof(nsStringBuffer) + aSize > aSize,
|
sizeof(StringBuffer) + aSize > aSize,
|
||||||
"mStorageSize will truncate");
|
"mStorageSize will truncate");
|
||||||
|
|
||||||
auto* hdr = (nsStringBuffer*)malloc(sizeof(nsStringBuffer) + aSize);
|
auto* hdr = (StringBuffer*)malloc(sizeof(StringBuffer) + aSize);
|
||||||
if (hdr) {
|
if (hdr) {
|
||||||
hdr->mRefCount = 1;
|
hdr->mRefCount = 1;
|
||||||
hdr->mStorageSize = aSize;
|
hdr->mStorageSize = aSize;
|
||||||
mozilla::detail::RefCountLogger::logAddRef(hdr, 1);
|
detail::RefCountLogger::logAddRef(hdr, 1);
|
||||||
}
|
}
|
||||||
return already_AddRefed(hdr);
|
return already_AddRefed(hdr);
|
||||||
}
|
}
|
||||||
|
|
@ -68,10 +71,14 @@ class nsStringBuffer {
|
||||||
* Note that this will allocate extra space for the trailing null byte, which
|
* Note that this will allocate extra space for the trailing null byte, which
|
||||||
* this method will add.
|
* this method will add.
|
||||||
*/
|
*/
|
||||||
static already_AddRefed<nsStringBuffer> Create(const char16_t* aData,
|
static already_AddRefed<StringBuffer> Create(const char16_t* aData,
|
||||||
size_t aLength);
|
size_t aLength) {
|
||||||
static already_AddRefed<nsStringBuffer> Create(const char* aData,
|
return DoCreate(aData, aLength);
|
||||||
size_t aLength);
|
}
|
||||||
|
static already_AddRefed<StringBuffer> Create(const char* aData,
|
||||||
|
size_t aLength) {
|
||||||
|
return DoCreate(aData, aLength);
|
||||||
|
}
|
||||||
|
|
||||||
/**
|
/**
|
||||||
* Resizes the given string buffer to the specified storage size. This
|
* Resizes the given string buffer to the specified storage size. This
|
||||||
|
|
@ -84,7 +91,31 @@ class nsStringBuffer {
|
||||||
*
|
*
|
||||||
* @see IsReadonly
|
* @see IsReadonly
|
||||||
*/
|
*/
|
||||||
static nsStringBuffer* Realloc(nsStringBuffer* aBuf, size_t aStorageSize);
|
static StringBuffer* Realloc(StringBuffer* aHdr, size_t aSize) {
|
||||||
|
MOZ_ASSERT(aSize != 0, "zero capacity allocation not allowed");
|
||||||
|
MOZ_ASSERT(sizeof(StringBuffer) + aSize <= size_t(uint32_t(-1)) &&
|
||||||
|
sizeof(StringBuffer) + aSize > aSize,
|
||||||
|
"mStorageSize will truncate");
|
||||||
|
|
||||||
|
// no point in trying to save ourselves if we hit this assertion
|
||||||
|
MOZ_ASSERT(!aHdr->IsReadonly(), "|Realloc| attempted on readonly string");
|
||||||
|
|
||||||
|
// Treat this as a release and addref for refcounting purposes, since we
|
||||||
|
// just asserted that the refcount is 1. If we don't do that, refcount
|
||||||
|
// logging will claim we've leaked all sorts of stuff.
|
||||||
|
{
|
||||||
|
detail::RefCountLogger::ReleaseLogger logger(aHdr);
|
||||||
|
logger.logRelease(0);
|
||||||
|
}
|
||||||
|
|
||||||
|
aHdr = (StringBuffer*)realloc(aHdr, sizeof(StringBuffer) + aSize);
|
||||||
|
if (aHdr) {
|
||||||
|
detail::RefCountLogger::logAddRef(aHdr, 1);
|
||||||
|
aHdr->mStorageSize = aSize;
|
||||||
|
}
|
||||||
|
|
||||||
|
return aHdr;
|
||||||
|
}
|
||||||
|
|
||||||
void AddRef() {
|
void AddRef() {
|
||||||
// Memory synchronization is not required when incrementing a
|
// Memory synchronization is not required when incrementing a
|
||||||
|
|
@ -96,14 +127,14 @@ class nsStringBuffer {
|
||||||
// synchronization is done by the mechanism that transfers the
|
// synchronization is done by the mechanism that transfers the
|
||||||
// pointer between threads.
|
// pointer between threads.
|
||||||
uint32_t count = mRefCount.fetch_add(1, std::memory_order_relaxed) + 1;
|
uint32_t count = mRefCount.fetch_add(1, std::memory_order_relaxed) + 1;
|
||||||
mozilla::detail::RefCountLogger::logAddRef(this, count);
|
detail::RefCountLogger::logAddRef(this, count);
|
||||||
}
|
}
|
||||||
|
|
||||||
void Release() {
|
void Release() {
|
||||||
// Since this may be the last release on this thread, we need release
|
// Since this may be the last release on this thread, we need release
|
||||||
// semantics so that prior writes on this thread are visible to the thread
|
// semantics so that prior writes on this thread are visible to the thread
|
||||||
// that destroys the object when it reads mValue with acquire semantics.
|
// that destroys the object when it reads mValue with acquire semantics.
|
||||||
mozilla::detail::RefCountLogger::ReleaseLogger logger(this);
|
detail::RefCountLogger::ReleaseLogger logger(this);
|
||||||
uint32_t count = mRefCount.fetch_sub(1, std::memory_order_release) - 1;
|
uint32_t count = mRefCount.fetch_sub(1, std::memory_order_release) - 1;
|
||||||
logger.logRelease(count);
|
logger.logRelease(count);
|
||||||
if (count == 0) {
|
if (count == 0) {
|
||||||
|
|
@ -119,10 +150,10 @@ class nsStringBuffer {
|
||||||
/**
|
/**
|
||||||
* This method returns the string buffer corresponding to the given data
|
* This method returns the string buffer corresponding to the given data
|
||||||
* pointer. The data pointer must have been returned previously by a
|
* pointer. The data pointer must have been returned previously by a
|
||||||
* call to the nsStringBuffer::Data method.
|
* call to the StringBuffer::Data method.
|
||||||
*/
|
*/
|
||||||
static nsStringBuffer* FromData(void* aData) {
|
static StringBuffer* FromData(void* aData) {
|
||||||
return reinterpret_cast<nsStringBuffer*>(aData) - 1;
|
return reinterpret_cast<StringBuffer*>(aData) - 1;
|
||||||
}
|
}
|
||||||
|
|
||||||
/**
|
/**
|
||||||
|
|
@ -182,8 +213,9 @@ class nsStringBuffer {
|
||||||
/**
|
/**
|
||||||
* This measures the size only if the StringBuffer is unshared.
|
* This measures the size only if the StringBuffer is unshared.
|
||||||
*/
|
*/
|
||||||
size_t SizeOfIncludingThisIfUnshared(
|
size_t SizeOfIncludingThisIfUnshared(MallocSizeOf aMallocSizeOf) const {
|
||||||
mozilla::MallocSizeOf aMallocSizeOf) const;
|
return IsReadonly() ? 0 : aMallocSizeOf(this);
|
||||||
|
}
|
||||||
|
|
||||||
/**
|
/**
|
||||||
* This measures the size regardless of whether the StringBuffer is
|
* This measures the size regardless of whether the StringBuffer is
|
||||||
|
|
@ -194,8 +226,24 @@ class nsStringBuffer {
|
||||||
* please explain clearly in a comment why it's safe and won't lead to
|
* please explain clearly in a comment why it's safe and won't lead to
|
||||||
* double-counting.
|
* double-counting.
|
||||||
*/
|
*/
|
||||||
size_t SizeOfIncludingThisEvenIfShared(
|
size_t SizeOfIncludingThisEvenIfShared(MallocSizeOf aMallocSizeOf) const {
|
||||||
mozilla::MallocSizeOf aMallocSizeOf) const;
|
return aMallocSizeOf(this);
|
||||||
|
}
|
||||||
|
|
||||||
|
private:
|
||||||
|
template <typename CharT>
|
||||||
|
static already_AddRefed<StringBuffer> DoCreate(const CharT* aData,
|
||||||
|
size_t aLength) {
|
||||||
|
StringBuffer* buffer = Alloc((aLength + 1) * sizeof(CharT)).take();
|
||||||
|
if (MOZ_LIKELY(buffer)) {
|
||||||
|
auto* data = reinterpret_cast<CharT*>(buffer->Data());
|
||||||
|
memcpy(data, aData, aLength * sizeof(CharT));
|
||||||
|
data[aLength] = 0;
|
||||||
|
}
|
||||||
|
return already_AddRefed(buffer);
|
||||||
|
}
|
||||||
};
|
};
|
||||||
|
|
||||||
#endif /* !defined(nsStringBuffer_h__ */
|
} // namespace mozilla
|
||||||
|
|
||||||
|
#endif
|
||||||
|
|
@ -107,6 +107,7 @@ EXPORTS.mozilla = [
|
||||||
"SplayTree.h",
|
"SplayTree.h",
|
||||||
"SPSCQueue.h",
|
"SPSCQueue.h",
|
||||||
"StaticAnalysisFunctions.h",
|
"StaticAnalysisFunctions.h",
|
||||||
|
"StringBuffer.h",
|
||||||
"TaggedAnonymousMemory.h",
|
"TaggedAnonymousMemory.h",
|
||||||
"Tainting.h",
|
"Tainting.h",
|
||||||
"TemplateLib.h",
|
"TemplateLib.h",
|
||||||
|
|
|
||||||
|
|
@ -5,6 +5,9 @@
|
||||||
#include "nsHtml5String.h"
|
#include "nsHtml5String.h"
|
||||||
#include "nsCharTraits.h"
|
#include "nsCharTraits.h"
|
||||||
#include "nsHtml5TreeBuilder.h"
|
#include "nsHtml5TreeBuilder.h"
|
||||||
|
#include "mozilla/StringBuffer.h"
|
||||||
|
|
||||||
|
using mozilla::StringBuffer;
|
||||||
|
|
||||||
void nsHtml5String::ToString(nsAString& aString) {
|
void nsHtml5String::ToString(nsAString& aString) {
|
||||||
switch (GetKind()) {
|
switch (GetKind()) {
|
||||||
|
|
@ -104,17 +107,17 @@ nsHtml5String nsHtml5String::FromBuffer(char16_t* aBuffer, int32_t aLength,
|
||||||
if (!aLength) {
|
if (!aLength) {
|
||||||
return nsHtml5String(eEmpty);
|
return nsHtml5String(eEmpty);
|
||||||
}
|
}
|
||||||
// Work with nsStringBuffer directly to make sure that storage is actually
|
// Work with StringBuffer directly to make sure that storage is actually
|
||||||
// nsStringBuffer and to make sure the allocation strategy matches
|
// StringBuffer and to make sure the allocation strategy matches
|
||||||
// nsAttrValue::GetStringBuffer, so that it doesn't need to reallocate and
|
// nsAttrValue::GetStringBuffer, so that it doesn't need to reallocate and
|
||||||
// copy.
|
// copy.
|
||||||
RefPtr<nsStringBuffer> buffer = nsStringBuffer::Create(aBuffer, aLength);
|
RefPtr<StringBuffer> buffer = StringBuffer::Create(aBuffer, aLength);
|
||||||
if (MOZ_UNLIKELY(!buffer)) {
|
if (MOZ_UNLIKELY(!buffer)) {
|
||||||
if (!aTreeBuilder) {
|
if (!aTreeBuilder) {
|
||||||
MOZ_CRASH("Out of memory.");
|
MOZ_CRASH("Out of memory.");
|
||||||
}
|
}
|
||||||
aTreeBuilder->MarkAsBroken(NS_ERROR_OUT_OF_MEMORY);
|
aTreeBuilder->MarkAsBroken(NS_ERROR_OUT_OF_MEMORY);
|
||||||
buffer = nsStringBuffer::Alloc(2 * sizeof(char16_t));
|
buffer = StringBuffer::Alloc(2 * sizeof(char16_t));
|
||||||
if (!buffer) {
|
if (!buffer) {
|
||||||
MOZ_CRASH(
|
MOZ_CRASH(
|
||||||
"Out of memory so badly that couldn't even allocate placeholder.");
|
"Out of memory so badly that couldn't even allocate placeholder.");
|
||||||
|
|
@ -133,12 +136,12 @@ nsHtml5String nsHtml5String::FromLiteral(const char* aLiteral) {
|
||||||
if (!length) {
|
if (!length) {
|
||||||
return nsHtml5String(eEmpty);
|
return nsHtml5String(eEmpty);
|
||||||
}
|
}
|
||||||
// Work with nsStringBuffer directly to make sure that storage is actually
|
// Work with StringBuffer directly to make sure that storage is actually
|
||||||
// nsStringBuffer and to make sure the allocation strategy matches
|
// StringBuffer and to make sure the allocation strategy matches
|
||||||
// nsAttrValue::GetStringBuffer, so that it doesn't need to reallocate and
|
// nsAttrValue::GetStringBuffer, so that it doesn't need to reallocate and
|
||||||
// copy.
|
// copy.
|
||||||
RefPtr<nsStringBuffer> buffer(
|
RefPtr<StringBuffer> buffer(
|
||||||
nsStringBuffer::Alloc((length + 1) * sizeof(char16_t)));
|
StringBuffer::Alloc((length + 1) * sizeof(char16_t)));
|
||||||
if (!buffer) {
|
if (!buffer) {
|
||||||
MOZ_CRASH("Out of memory.");
|
MOZ_CRASH("Out of memory.");
|
||||||
}
|
}
|
||||||
|
|
@ -156,14 +159,14 @@ nsHtml5String nsHtml5String::FromString(const nsAString& aString) {
|
||||||
if (!length) {
|
if (!length) {
|
||||||
return nsHtml5String(eEmpty);
|
return nsHtml5String(eEmpty);
|
||||||
}
|
}
|
||||||
if (nsStringBuffer* buffer = aString.GetStringBuffer()) {
|
if (StringBuffer* buffer = aString.GetStringBuffer()) {
|
||||||
if (length == buffer->StorageSize() / sizeof(char16_t) - 1) {
|
if (length == buffer->StorageSize() / sizeof(char16_t) - 1) {
|
||||||
buffer->AddRef();
|
buffer->AddRef();
|
||||||
return nsHtml5String(reinterpret_cast<uintptr_t>(buffer) | eStringBuffer);
|
return nsHtml5String(reinterpret_cast<uintptr_t>(buffer) | eStringBuffer);
|
||||||
}
|
}
|
||||||
}
|
}
|
||||||
RefPtr<nsStringBuffer> buffer =
|
RefPtr<StringBuffer> buffer =
|
||||||
nsStringBuffer::Alloc((length + 1) * sizeof(char16_t));
|
StringBuffer::Alloc((length + 1) * sizeof(char16_t));
|
||||||
if (!buffer) {
|
if (!buffer) {
|
||||||
MOZ_CRASH("Out of memory.");
|
MOZ_CRASH("Out of memory.");
|
||||||
}
|
}
|
||||||
|
|
|
||||||
|
|
@ -7,7 +7,10 @@
|
||||||
|
|
||||||
#include "nsAtom.h"
|
#include "nsAtom.h"
|
||||||
#include "nsString.h"
|
#include "nsString.h"
|
||||||
#include "nsStringBuffer.h"
|
|
||||||
|
namespace mozilla {
|
||||||
|
class StringBuffer;
|
||||||
|
}
|
||||||
|
|
||||||
class nsHtml5TreeBuilder;
|
class nsHtml5TreeBuilder;
|
||||||
|
|
||||||
|
|
@ -15,11 +18,11 @@ class nsHtml5TreeBuilder;
|
||||||
* A pass-by-value type that can represent
|
* A pass-by-value type that can represent
|
||||||
* * nullptr
|
* * nullptr
|
||||||
* * empty string
|
* * empty string
|
||||||
* * Non-empty string as exactly-sized (capacity is length) `nsStringBuffer*`
|
* * Non-empty string as exactly-sized (capacity is length) `StringBuffer*`
|
||||||
* * Non-empty string as an nsAtom*
|
* * Non-empty string as an nsAtom*
|
||||||
*
|
*
|
||||||
* Holding or passing this type is as unsafe as holding or passing
|
* Holding or passing this type is as unsafe as holding or passing
|
||||||
* `nsStringBuffer*`/`nsAtom*`.
|
* `StringBuffer*`/`nsAtom*`.
|
||||||
*/
|
*/
|
||||||
class nsHtml5String final {
|
class nsHtml5String final {
|
||||||
private:
|
private:
|
||||||
|
|
@ -36,9 +39,9 @@ class nsHtml5String final {
|
||||||
|
|
||||||
inline Kind GetKind() const { return (Kind)(mBits & kKindMask); }
|
inline Kind GetKind() const { return (Kind)(mBits & kKindMask); }
|
||||||
|
|
||||||
inline nsStringBuffer* AsStringBuffer() const {
|
inline mozilla::StringBuffer* AsStringBuffer() const {
|
||||||
MOZ_ASSERT(GetKind() == eStringBuffer);
|
MOZ_ASSERT(GetKind() == eStringBuffer);
|
||||||
return reinterpret_cast<nsStringBuffer*>(mBits & kPtrMask);
|
return reinterpret_cast<mozilla::StringBuffer*>(mBits & kPtrMask);
|
||||||
}
|
}
|
||||||
|
|
||||||
inline nsAtom* AsAtom() const {
|
inline nsAtom* AsAtom() const {
|
||||||
|
|
|
||||||
|
|
@ -35,7 +35,6 @@
|
||||||
#include "nsNSSComponent.h"
|
#include "nsNSSComponent.h"
|
||||||
#include "nsNetUtil.h"
|
#include "nsNetUtil.h"
|
||||||
#include "nsStreamUtils.h"
|
#include "nsStreamUtils.h"
|
||||||
#include "nsStringBuffer.h"
|
|
||||||
#include "nsThreadUtils.h"
|
#include "nsThreadUtils.h"
|
||||||
|
|
||||||
using namespace mozilla;
|
using namespace mozilla;
|
||||||
|
|
|
||||||
|
|
@ -17,7 +17,6 @@
|
||||||
#include "nsNetUtil.h"
|
#include "nsNetUtil.h"
|
||||||
#include "nsPromiseFlatString.h"
|
#include "nsPromiseFlatString.h"
|
||||||
#include "nsThreadUtils.h"
|
#include "nsThreadUtils.h"
|
||||||
#include "nsStringBuffer.h"
|
|
||||||
#include "cert.h"
|
#include "cert.h"
|
||||||
#include "nspr.h"
|
#include "nspr.h"
|
||||||
#include "pk11pub.h"
|
#include "pk11pub.h"
|
||||||
|
|
|
||||||
|
|
@ -41,7 +41,6 @@
|
||||||
#include "nsDOMMutationObserver.h"
|
#include "nsDOMMutationObserver.h"
|
||||||
#include "nsJSUtils.h"
|
#include "nsJSUtils.h"
|
||||||
#include "nsPIDOMWindow.h"
|
#include "nsPIDOMWindow.h"
|
||||||
#include "nsStringBuffer.h"
|
|
||||||
#include "nsThread.h"
|
#include "nsThread.h"
|
||||||
#include "nsThreadUtils.h"
|
#include "nsThreadUtils.h"
|
||||||
#include "nsWrapperCache.h"
|
#include "nsWrapperCache.h"
|
||||||
|
|
|
||||||
|
|
@ -97,7 +97,6 @@
|
||||||
#include "nsDOMJSUtils.h"
|
#include "nsDOMJSUtils.h"
|
||||||
#include "nsExceptionHandler.h"
|
#include "nsExceptionHandler.h"
|
||||||
#include "nsJSUtils.h"
|
#include "nsJSUtils.h"
|
||||||
#include "nsStringBuffer.h"
|
|
||||||
#include "nsWrapperCache.h"
|
#include "nsWrapperCache.h"
|
||||||
#include "prenv.h"
|
#include "prenv.h"
|
||||||
|
|
||||||
|
|
|
||||||
|
|
@ -353,14 +353,15 @@ static void DumpSerialNumbers(const SerialHash::ConstIterator& aHashEntry,
|
||||||
#endif
|
#endif
|
||||||
|
|
||||||
if (aDumpAsStringBuffer) {
|
if (aDumpAsStringBuffer) {
|
||||||
// This output will be wrong if the nsStringBuffer was used to
|
// This output will be wrong if the StringBuffer was used to
|
||||||
// store a char16_t string.
|
// store a char16_t string.
|
||||||
auto* buffer = static_cast<const nsStringBuffer*>(aHashEntry.Key());
|
auto* buffer = static_cast<const mozilla::StringBuffer*>(aHashEntry.Key());
|
||||||
nsDependentCString bufferString(static_cast<char*>(buffer->Data()));
|
nsDependentCString bufferString(static_cast<char*>(buffer->Data()));
|
||||||
fprintf(outputFile,
|
fprintf(
|
||||||
"Contents of leaked nsStringBuffer with storage size %d as a "
|
outputFile,
|
||||||
"char*: %s\n",
|
"Contents of leaked mozilla::StringBuffer with storage size %d as a "
|
||||||
buffer->StorageSize(), bufferString.get());
|
"char*: %s\n",
|
||||||
|
buffer->StorageSize(), bufferString.get());
|
||||||
}
|
}
|
||||||
|
|
||||||
if (!record->allocationStack.empty()) {
|
if (!record->allocationStack.empty()) {
|
||||||
|
|
@ -449,7 +450,7 @@ nsresult nsTraceRefcnt::DumpStatistics() {
|
||||||
|
|
||||||
if (gSerialNumbers) {
|
if (gSerialNumbers) {
|
||||||
bool onlyLoggingStringBuffers = gTypesToLog && gTypesToLog->Count() == 1 &&
|
bool onlyLoggingStringBuffers = gTypesToLog && gTypesToLog->Count() == 1 &&
|
||||||
gTypesToLog->Contains("nsStringBuffer");
|
gTypesToLog->Contains("StringBuffer");
|
||||||
|
|
||||||
fprintf(gBloatLog, "\nSerial Numbers of Leaked Objects:\n");
|
fprintf(gBloatLog, "\nSerial Numbers of Leaked Objects:\n");
|
||||||
for (auto iter = gSerialNumbers->ConstIter(); !iter.Done(); iter.Next()) {
|
for (auto iter = gSerialNumbers->ConstIter(); !iter.Done(); iter.Next()) {
|
||||||
|
|
|
||||||
|
|
@ -177,7 +177,7 @@ class nsDynamicAtom : public nsAtom {
|
||||||
return count;
|
return count;
|
||||||
}
|
}
|
||||||
|
|
||||||
nsStringBuffer* StringBuffer() const { return mStringBuffer; }
|
mozilla::StringBuffer* StringBuffer() const { return mStringBuffer; }
|
||||||
|
|
||||||
const char16_t* String() const {
|
const char16_t* String() const {
|
||||||
return reinterpret_cast<const char16_t*>(mStringBuffer->Data());
|
return reinterpret_cast<const char16_t*>(mStringBuffer->Data());
|
||||||
|
|
@ -193,7 +193,7 @@ class nsDynamicAtom : public nsAtom {
|
||||||
|
|
||||||
// These shouldn't be used directly, even by friend classes. The
|
// These shouldn't be used directly, even by friend classes. The
|
||||||
// Create()/Destroy() methods use them.
|
// Create()/Destroy() methods use them.
|
||||||
nsDynamicAtom(already_AddRefed<nsStringBuffer>, uint32_t aLength,
|
nsDynamicAtom(already_AddRefed<mozilla::StringBuffer>, uint32_t aLength,
|
||||||
uint32_t aHash, bool aIsAsciiLowercase);
|
uint32_t aHash, bool aIsAsciiLowercase);
|
||||||
~nsDynamicAtom() = default;
|
~nsDynamicAtom() = default;
|
||||||
|
|
||||||
|
|
@ -201,7 +201,7 @@ class nsDynamicAtom : public nsAtom {
|
||||||
static void Destroy(nsDynamicAtom* aAtom);
|
static void Destroy(nsDynamicAtom* aAtom);
|
||||||
|
|
||||||
mozilla::ThreadSafeAutoRefCnt mRefCnt;
|
mozilla::ThreadSafeAutoRefCnt mRefCnt;
|
||||||
RefPtr<nsStringBuffer> mStringBuffer;
|
RefPtr<mozilla::StringBuffer> mStringBuffer;
|
||||||
};
|
};
|
||||||
|
|
||||||
const nsStaticAtom* nsAtom::AsStatic() const {
|
const nsStaticAtom* nsAtom::AsStatic() const {
|
||||||
|
|
|
||||||
|
|
@ -61,7 +61,7 @@ enum class GCKind {
|
||||||
// replaying.
|
// replaying.
|
||||||
Atomic<int32_t, ReleaseAcquire> nsDynamicAtom::gUnusedAtomCount;
|
Atomic<int32_t, ReleaseAcquire> nsDynamicAtom::gUnusedAtomCount;
|
||||||
|
|
||||||
nsDynamicAtom::nsDynamicAtom(already_AddRefed<nsStringBuffer> aBuffer,
|
nsDynamicAtom::nsDynamicAtom(already_AddRefed<mozilla::StringBuffer> aBuffer,
|
||||||
uint32_t aLength, uint32_t aHash,
|
uint32_t aLength, uint32_t aHash,
|
||||||
bool aIsAsciiLowercase)
|
bool aIsAsciiLowercase)
|
||||||
: nsAtom(aLength, /* aIsStatic = */ false, aHash, aIsAsciiLowercase),
|
: nsAtom(aLength, /* aIsStatic = */ false, aHash, aIsAsciiLowercase),
|
||||||
|
|
@ -82,9 +82,9 @@ nsDynamicAtom* nsDynamicAtom::Create(const nsAString& aString, uint32_t aHash) {
|
||||||
// We tack the chars onto the end of the nsDynamicAtom object.
|
// We tack the chars onto the end of the nsDynamicAtom object.
|
||||||
const bool isAsciiLower =
|
const bool isAsciiLower =
|
||||||
::IsAsciiLowercase(aString.Data(), aString.Length());
|
::IsAsciiLowercase(aString.Data(), aString.Length());
|
||||||
RefPtr<nsStringBuffer> buffer = aString.GetStringBuffer();
|
RefPtr<mozilla::StringBuffer> buffer = aString.GetStringBuffer();
|
||||||
if (!buffer) {
|
if (!buffer) {
|
||||||
buffer = nsStringBuffer::Create(aString.Data(), aString.Length());
|
buffer = mozilla::StringBuffer::Create(aString.Data(), aString.Length());
|
||||||
if (MOZ_UNLIKELY(!buffer)) {
|
if (MOZ_UNLIKELY(!buffer)) {
|
||||||
MOZ_CRASH("Out of memory atomizing");
|
MOZ_CRASH("Out of memory atomizing");
|
||||||
}
|
}
|
||||||
|
|
|
||||||
|
|
@ -146,9 +146,9 @@ macro_rules! constant_conversion {
|
||||||
};
|
};
|
||||||
}
|
}
|
||||||
|
|
||||||
/// An intermediate check for avoiding a copy and having an `nsStringBuffer`
|
/// An intermediate check for avoiding a copy and having an `StringBuffer` refcount increment
|
||||||
/// refcount increment instead when both `self` and `other` are `nsACString`s,
|
/// instead when both `self` and `other` are `nsACString`s, `other` is entirely ASCII and all old
|
||||||
/// `other` is entirely ASCII and all old data in `self` is discarded.
|
/// data in `self` is discarded.
|
||||||
///
|
///
|
||||||
/// `$name` is the name of the function to generate
|
/// `$name` is the name of the function to generate
|
||||||
/// `$impl` is the underlying conversion that takes a slice and that is used
|
/// `$impl` is the underlying conversion that takes a slice and that is used
|
||||||
|
|
|
||||||
|
|
@ -18,7 +18,6 @@ EXPORTS += [
|
||||||
"nsPromiseFlatString.h",
|
"nsPromiseFlatString.h",
|
||||||
"nsReadableUtils.h",
|
"nsReadableUtils.h",
|
||||||
"nsString.h",
|
"nsString.h",
|
||||||
"nsStringBuffer.h",
|
|
||||||
"nsStringFlags.h",
|
"nsStringFlags.h",
|
||||||
"nsStringFwd.h",
|
"nsStringFwd.h",
|
||||||
"nsStringIterator.h",
|
"nsStringIterator.h",
|
||||||
|
|
@ -42,7 +41,6 @@ EXPORTS.mozilla += [
|
||||||
UNIFIED_SOURCES += [
|
UNIFIED_SOURCES += [
|
||||||
"nsASCIIMask.cpp",
|
"nsASCIIMask.cpp",
|
||||||
"nsReadableUtils.cpp",
|
"nsReadableUtils.cpp",
|
||||||
"nsStringBuffer.cpp",
|
|
||||||
"nsTDependentString.cpp",
|
"nsTDependentString.cpp",
|
||||||
"nsTDependentSubstring.cpp",
|
"nsTDependentSubstring.cpp",
|
||||||
"nsTextFormatter.cpp",
|
"nsTextFormatter.cpp",
|
||||||
|
|
|
||||||
|
|
@ -197,7 +197,7 @@ inline void LossyAppendUTF16toASCII(mozilla::Span<const char16_t> aSource,
|
||||||
// Latin1 to UTF-8
|
// Latin1 to UTF-8
|
||||||
// Interpret each incoming unsigned byte value as a Unicode scalar value (not
|
// Interpret each incoming unsigned byte value as a Unicode scalar value (not
|
||||||
// windows-1252!).
|
// windows-1252!).
|
||||||
// If the input is ASCII, the heap-allocated nsStringBuffer is shared if
|
// If the input is ASCII, the heap-allocated mozilla::StringBuffer is shared if
|
||||||
// possible.
|
// possible.
|
||||||
|
|
||||||
[[nodiscard]] inline bool CopyLatin1toUTF8(const nsACString& aSource,
|
[[nodiscard]] inline bool CopyLatin1toUTF8(const nsACString& aSource,
|
||||||
|
|
@ -231,7 +231,7 @@ inline void AppendLatin1toUTF8(const nsACString& aSource, nsACString& aDest) {
|
||||||
// points above U+00FF, memory-safely produces garbage in release builds and
|
// points above U+00FF, memory-safely produces garbage in release builds and
|
||||||
// asserts in debug builds. The nature of the garbage may differ
|
// asserts in debug builds. The nature of the garbage may differ
|
||||||
// based on CPU architecture and must not be relied upon.
|
// based on CPU architecture and must not be relied upon.
|
||||||
// If the input is ASCII, the heap-allocated nsStringBuffer is shared if
|
// If the input is ASCII, the heap-allocated mozilla::StringBuffer is shared if
|
||||||
// possible.
|
// possible.
|
||||||
|
|
||||||
[[nodiscard]] inline bool LossyCopyUTF8toLatin1(const nsACString& aSource,
|
[[nodiscard]] inline bool LossyCopyUTF8toLatin1(const nsACString& aSource,
|
||||||
|
|
|
||||||
|
|
@ -1,70 +0,0 @@
|
||||||
/* -*- Mode: C++; tab-width: 8; indent-tabs-mode: nil; c-basic-offset: 2 -*- */
|
|
||||||
/* vim: set ts=8 sts=2 et sw=2 tw=80: */
|
|
||||||
/* 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 "nsStringBuffer.h"
|
|
||||||
|
|
||||||
#include "mozilla/MemoryReporting.h"
|
|
||||||
#include "mozilla/RefPtr.h"
|
|
||||||
|
|
||||||
template <typename CharT>
|
|
||||||
static already_AddRefed<nsStringBuffer> DoCreate(const CharT* aData,
|
|
||||||
size_t aLength) {
|
|
||||||
RefPtr<nsStringBuffer> buffer =
|
|
||||||
nsStringBuffer::Alloc((aLength + 1) * sizeof(CharT));
|
|
||||||
if (MOZ_UNLIKELY(!buffer)) {
|
|
||||||
return nullptr;
|
|
||||||
}
|
|
||||||
auto* data = reinterpret_cast<CharT*>(buffer->Data());
|
|
||||||
memcpy(data, aData, aLength * sizeof(CharT));
|
|
||||||
data[aLength] = 0;
|
|
||||||
return buffer.forget();
|
|
||||||
}
|
|
||||||
|
|
||||||
already_AddRefed<nsStringBuffer> nsStringBuffer::Create(const char* aData,
|
|
||||||
size_t aLength) {
|
|
||||||
return DoCreate(aData, aLength);
|
|
||||||
}
|
|
||||||
|
|
||||||
already_AddRefed<nsStringBuffer> nsStringBuffer::Create(const char16_t* aData,
|
|
||||||
size_t aLength) {
|
|
||||||
return DoCreate(aData, aLength);
|
|
||||||
}
|
|
||||||
|
|
||||||
nsStringBuffer* nsStringBuffer::Realloc(nsStringBuffer* aHdr, size_t aSize) {
|
|
||||||
MOZ_ASSERT(aSize != 0, "zero capacity allocation not allowed");
|
|
||||||
MOZ_ASSERT(sizeof(nsStringBuffer) + aSize <= size_t(uint32_t(-1)) &&
|
|
||||||
sizeof(nsStringBuffer) + aSize > aSize,
|
|
||||||
"mStorageSize will truncate");
|
|
||||||
|
|
||||||
// no point in trying to save ourselves if we hit this assertion
|
|
||||||
MOZ_ASSERT(!aHdr->IsReadonly(), "|Realloc| attempted on readonly string");
|
|
||||||
|
|
||||||
// Treat this as a release and addref for refcounting purposes, since we
|
|
||||||
// just asserted that the refcount is 1. If we don't do that, refcount
|
|
||||||
// logging will claim we've leaked all sorts of stuff.
|
|
||||||
{
|
|
||||||
mozilla::detail::RefCountLogger::ReleaseLogger logger(aHdr);
|
|
||||||
logger.logRelease(0);
|
|
||||||
}
|
|
||||||
|
|
||||||
aHdr = (nsStringBuffer*)realloc(aHdr, sizeof(nsStringBuffer) + aSize);
|
|
||||||
if (aHdr) {
|
|
||||||
mozilla::detail::RefCountLogger::logAddRef(aHdr, 1);
|
|
||||||
aHdr->mStorageSize = aSize;
|
|
||||||
}
|
|
||||||
|
|
||||||
return aHdr;
|
|
||||||
}
|
|
||||||
|
|
||||||
size_t nsStringBuffer::SizeOfIncludingThisIfUnshared(
|
|
||||||
mozilla::MallocSizeOf aMallocSizeOf) const {
|
|
||||||
return IsReadonly() ? 0 : aMallocSizeOf(this);
|
|
||||||
}
|
|
||||||
|
|
||||||
size_t nsStringBuffer::SizeOfIncludingThisEvenIfShared(
|
|
||||||
mozilla::MallocSizeOf aMallocSizeOf) const {
|
|
||||||
return aMallocSizeOf(this);
|
|
||||||
}
|
|
||||||
|
|
@ -14,7 +14,7 @@
|
||||||
#include "mozilla/Char16.h"
|
#include "mozilla/Char16.h"
|
||||||
#include "mozilla/CheckedInt.h"
|
#include "mozilla/CheckedInt.h"
|
||||||
#include "mozilla/fallible.h"
|
#include "mozilla/fallible.h"
|
||||||
#include "nsStringBuffer.h"
|
#include "mozilla/StringBuffer.h"
|
||||||
#include "nsStringFlags.h"
|
#include "nsStringFlags.h"
|
||||||
#include "nsStringFwd.h"
|
#include "nsStringFwd.h"
|
||||||
#include "nsStringIterator.h"
|
#include "nsStringIterator.h"
|
||||||
|
|
@ -74,9 +74,9 @@ class nsTStringLengthStorage {
|
||||||
"nsTString's maximum length, including the trailing null, must fit "
|
"nsTString's maximum length, including the trailing null, must fit "
|
||||||
"within `int32_t`, as callers will cast to `int32_t` occasionally");
|
"within `int32_t`, as callers will cast to `int32_t` occasionally");
|
||||||
static_assert(((CheckedInt<uint32_t>{kMax} + 1) * sizeof(T) +
|
static_assert(((CheckedInt<uint32_t>{kMax} + 1) * sizeof(T) +
|
||||||
sizeof(nsStringBuffer))
|
sizeof(mozilla::StringBuffer))
|
||||||
.isValid(),
|
.isValid(),
|
||||||
"Math required to allocate a nsStringBuffer for a "
|
"Math required to allocate a mozilla::StringBuffer for a "
|
||||||
"maximum-capacity string must not overflow uint32_t");
|
"maximum-capacity string must not overflow uint32_t");
|
||||||
|
|
||||||
// Implicit conversion and assignment from `size_t` which assert that the
|
// Implicit conversion and assignment from `size_t` which assert that the
|
||||||
|
|
|
||||||
|
|
@ -50,7 +50,7 @@ char16_t* const nsCharTraits<char16_t>::sEmptyBuffer =
|
||||||
|
|
||||||
static void ReleaseData(void* aData, nsAString::DataFlags aFlags) {
|
static void ReleaseData(void* aData, nsAString::DataFlags aFlags) {
|
||||||
if (aFlags & nsAString::DataFlags::REFCOUNTED) {
|
if (aFlags & nsAString::DataFlags::REFCOUNTED) {
|
||||||
nsStringBuffer::FromData(aData)->Release();
|
mozilla::StringBuffer::FromData(aData)->Release();
|
||||||
} else if (aFlags & nsAString::DataFlags::OWNED) {
|
} else if (aFlags & nsAString::DataFlags::OWNED) {
|
||||||
// Treat this as destruction of a "StringAdopt" object for leak
|
// Treat this as destruction of a "StringAdopt" object for leak
|
||||||
// tracking purposes.
|
// tracking purposes.
|
||||||
|
|
@ -172,8 +172,8 @@ auto nsTSubstring<T>::StartBulkWriteImpl(size_type aCapacity,
|
||||||
// If |aCapacity > kMaxCapacity|, then our doubling algorithm may not be
|
// If |aCapacity > kMaxCapacity|, then our doubling algorithm may not be
|
||||||
// able to allocate it. Just bail out in cases like that. We don't want
|
// able to allocate it. Just bail out in cases like that. We don't want
|
||||||
// to be allocating 2GB+ strings anyway.
|
// to be allocating 2GB+ strings anyway.
|
||||||
static_assert((sizeof(nsStringBuffer) & 0x1) == 0,
|
static_assert((sizeof(mozilla::StringBuffer) & 0x1) == 0,
|
||||||
"bad size for nsStringBuffer");
|
"bad size for mozilla::StringBuffer");
|
||||||
if (MOZ_UNLIKELY(!this->CheckCapacity(aCapacity))) {
|
if (MOZ_UNLIKELY(!this->CheckCapacity(aCapacity))) {
|
||||||
return mozilla::Err(NS_ERROR_OUT_OF_MEMORY);
|
return mozilla::Err(NS_ERROR_OUT_OF_MEMORY);
|
||||||
}
|
}
|
||||||
|
|
@ -184,10 +184,10 @@ auto nsTSubstring<T>::StartBulkWriteImpl(size_type aCapacity,
|
||||||
// least 1.125, rounding up to the nearest MiB.
|
// least 1.125, rounding up to the nearest MiB.
|
||||||
const size_type slowGrowthThreshold = 8 * 1024 * 1024;
|
const size_type slowGrowthThreshold = 8 * 1024 * 1024;
|
||||||
|
|
||||||
// nsStringBuffer allocates sizeof(nsStringBuffer) + passed size, and
|
// mozilla::StringBuffer allocates sizeof(mozilla::StringBuffer) + passed
|
||||||
// storageSize below wants extra 1 * sizeof(char_type).
|
// size, and storageSize below wants extra 1 * sizeof(char_type).
|
||||||
const size_type neededExtraSpace =
|
const size_type neededExtraSpace =
|
||||||
sizeof(nsStringBuffer) / sizeof(char_type) + 1;
|
sizeof(mozilla::StringBuffer) / sizeof(char_type) + 1;
|
||||||
|
|
||||||
size_type temp;
|
size_type temp;
|
||||||
if (aCapacity >= slowGrowthThreshold) {
|
if (aCapacity >= slowGrowthThreshold) {
|
||||||
|
|
@ -196,8 +196,8 @@ auto nsTSubstring<T>::StartBulkWriteImpl(size_type aCapacity,
|
||||||
temp = XPCOM_MAX(aCapacity, minNewCapacity) + neededExtraSpace;
|
temp = XPCOM_MAX(aCapacity, minNewCapacity) + neededExtraSpace;
|
||||||
|
|
||||||
// Round up to the next multiple of MiB, but ensure the expected
|
// Round up to the next multiple of MiB, but ensure the expected
|
||||||
// capacity doesn't include the extra space required by nsStringBuffer
|
// capacity doesn't include the extra space required by
|
||||||
// and null-termination.
|
// mozilla::StringBuffer and null-termination.
|
||||||
const size_t MiB = 1 << 20;
|
const size_t MiB = 1 << 20;
|
||||||
temp = (MiB * ((temp + MiB - 1) / MiB)) - neededExtraSpace;
|
temp = (MiB * ((temp + MiB - 1) / MiB)) - neededExtraSpace;
|
||||||
} else {
|
} else {
|
||||||
|
|
@ -222,7 +222,8 @@ auto nsTSubstring<T>::StartBulkWriteImpl(size_type aCapacity,
|
||||||
// Since we allocate only by powers of 2 we always fit into a full
|
// Since we allocate only by powers of 2 we always fit into a full
|
||||||
// mozjemalloc bucket, it's not useful to use realloc, which may spend
|
// mozjemalloc bucket, it's not useful to use realloc, which may spend
|
||||||
// time uselessly copying too much.
|
// time uselessly copying too much.
|
||||||
nsStringBuffer* newHdr = nsStringBuffer::Alloc(storageSize).take();
|
mozilla::StringBuffer* newHdr =
|
||||||
|
mozilla::StringBuffer::Alloc(storageSize).take();
|
||||||
if (newHdr) {
|
if (newHdr) {
|
||||||
newData = (char_type*)newHdr->Data();
|
newData = (char_type*)newHdr->Data();
|
||||||
} else if (shrinking) {
|
} else if (shrinking) {
|
||||||
|
|
@ -336,7 +337,7 @@ typename nsTSubstring<T>::size_type nsTSubstring<T>::Capacity() const {
|
||||||
size_type capacity;
|
size_type capacity;
|
||||||
if (this->mDataFlags & DataFlags::REFCOUNTED) {
|
if (this->mDataFlags & DataFlags::REFCOUNTED) {
|
||||||
// if the string is readonly, then we pretend that it has no capacity.
|
// if the string is readonly, then we pretend that it has no capacity.
|
||||||
nsStringBuffer* hdr = nsStringBuffer::FromData(this->mData);
|
mozilla::StringBuffer* hdr = mozilla::StringBuffer::FromData(this->mData);
|
||||||
if (hdr->IsReadonly()) {
|
if (hdr->IsReadonly()) {
|
||||||
capacity = 0;
|
capacity = 0;
|
||||||
} else {
|
} else {
|
||||||
|
|
@ -365,7 +366,7 @@ bool nsTSubstring<T>::EnsureMutable(size_type aNewLen) {
|
||||||
return true;
|
return true;
|
||||||
}
|
}
|
||||||
if ((this->mDataFlags & DataFlags::REFCOUNTED) &&
|
if ((this->mDataFlags & DataFlags::REFCOUNTED) &&
|
||||||
!nsStringBuffer::FromData(this->mData)->IsReadonly()) {
|
!mozilla::StringBuffer::FromData(this->mData)->IsReadonly()) {
|
||||||
return true;
|
return true;
|
||||||
}
|
}
|
||||||
|
|
||||||
|
|
@ -404,9 +405,9 @@ void nsTSubstring<T>::Assign(const char_type* aData, size_type aLength) {
|
||||||
}
|
}
|
||||||
|
|
||||||
template <typename T>
|
template <typename T>
|
||||||
void nsTSubstring<T>::Assign(already_AddRefed<nsStringBuffer> aBuffer,
|
void nsTSubstring<T>::Assign(already_AddRefed<mozilla::StringBuffer> aBuffer,
|
||||||
size_type aLength) {
|
size_type aLength) {
|
||||||
nsStringBuffer* buffer = aBuffer.take();
|
mozilla::StringBuffer* buffer = aBuffer.take();
|
||||||
auto* data = reinterpret_cast<char_type*>(buffer->Data());
|
auto* data = reinterpret_cast<char_type*>(buffer->Data());
|
||||||
MOZ_DIAGNOSTIC_ASSERT(data[aLength] == char_type(0),
|
MOZ_DIAGNOSTIC_ASSERT(data[aLength] == char_type(0),
|
||||||
"data should be null terminated");
|
"data should be null terminated");
|
||||||
|
|
@ -517,7 +518,7 @@ bool nsTSubstring<T>::Assign(const self_type& aStr,
|
||||||
DataFlags::TERMINATED | DataFlags::REFCOUNTED);
|
DataFlags::TERMINATED | DataFlags::REFCOUNTED);
|
||||||
|
|
||||||
// get an owning reference to the this->mData
|
// get an owning reference to the this->mData
|
||||||
nsStringBuffer::FromData(this->mData)->AddRef();
|
mozilla::StringBuffer::FromData(this->mData)->AddRef();
|
||||||
return true;
|
return true;
|
||||||
}
|
}
|
||||||
if (aStr.mDataFlags & DataFlags::LITERAL) {
|
if (aStr.mDataFlags & DataFlags::LITERAL) {
|
||||||
|
|
@ -1236,7 +1237,7 @@ template <typename T>
|
||||||
size_t nsTSubstring<T>::SizeOfExcludingThisIfUnshared(
|
size_t nsTSubstring<T>::SizeOfExcludingThisIfUnshared(
|
||||||
mozilla::MallocSizeOf aMallocSizeOf) const {
|
mozilla::MallocSizeOf aMallocSizeOf) const {
|
||||||
if (this->mDataFlags & DataFlags::REFCOUNTED) {
|
if (this->mDataFlags & DataFlags::REFCOUNTED) {
|
||||||
return nsStringBuffer::FromData(this->mData)
|
return mozilla::StringBuffer::FromData(this->mData)
|
||||||
->SizeOfIncludingThisIfUnshared(aMallocSizeOf);
|
->SizeOfIncludingThisIfUnshared(aMallocSizeOf);
|
||||||
}
|
}
|
||||||
if (this->mDataFlags & DataFlags::OWNED) {
|
if (this->mDataFlags & DataFlags::OWNED) {
|
||||||
|
|
@ -1260,7 +1261,7 @@ size_t nsTSubstring<T>::SizeOfExcludingThisEvenIfShared(
|
||||||
// This is identical to SizeOfExcludingThisIfUnshared except for the
|
// This is identical to SizeOfExcludingThisIfUnshared except for the
|
||||||
// DataFlags::REFCOUNTED case.
|
// DataFlags::REFCOUNTED case.
|
||||||
if (this->mDataFlags & DataFlags::REFCOUNTED) {
|
if (this->mDataFlags & DataFlags::REFCOUNTED) {
|
||||||
return nsStringBuffer::FromData(this->mData)
|
return mozilla::StringBuffer::FromData(this->mData)
|
||||||
->SizeOfIncludingThisEvenIfShared(aMallocSizeOf);
|
->SizeOfIncludingThisEvenIfShared(aMallocSizeOf);
|
||||||
}
|
}
|
||||||
if (this->mDataFlags & DataFlags::OWNED) {
|
if (this->mDataFlags & DataFlags::OWNED) {
|
||||||
|
|
|
||||||
|
|
@ -18,7 +18,6 @@
|
||||||
#include "mozilla/Span.h"
|
#include "mozilla/Span.h"
|
||||||
#include "mozilla/Try.h"
|
#include "mozilla/Try.h"
|
||||||
#include "mozilla/Unused.h"
|
#include "mozilla/Unused.h"
|
||||||
#include "nsStringBuffer.h"
|
|
||||||
|
|
||||||
#include "nsTStringRepr.h"
|
#include "nsTStringRepr.h"
|
||||||
|
|
||||||
|
|
@ -31,7 +30,6 @@
|
||||||
// memory checking. (Limited to avoid quadratic behavior.)
|
// memory checking. (Limited to avoid quadratic behavior.)
|
||||||
const size_t kNsStringBufferMaxPoison = 16;
|
const size_t kNsStringBufferMaxPoison = 16;
|
||||||
|
|
||||||
class nsStringBuffer;
|
|
||||||
template <typename T>
|
template <typename T>
|
||||||
class nsTSubstringSplitter;
|
class nsTSubstringSplitter;
|
||||||
template <typename T>
|
template <typename T>
|
||||||
|
|
@ -283,7 +281,7 @@ class BulkWriteHandle final {
|
||||||
template <typename T>
|
template <typename T>
|
||||||
class nsTSubstring : public mozilla::detail::nsTStringRepr<T> {
|
class nsTSubstring : public mozilla::detail::nsTStringRepr<T> {
|
||||||
friend class mozilla::BulkWriteHandle<T>;
|
friend class mozilla::BulkWriteHandle<T>;
|
||||||
friend class nsStringBuffer;
|
friend class mozilla::StringBuffer;
|
||||||
|
|
||||||
public:
|
public:
|
||||||
typedef nsTSubstring<T> self_type;
|
typedef nsTSubstring<T> self_type;
|
||||||
|
|
@ -419,11 +417,11 @@ class nsTSubstring : public mozilla::detail::nsTStringRepr<T> {
|
||||||
[[nodiscard]] bool NS_FASTCALL Assign(const substring_tuple_type&,
|
[[nodiscard]] bool NS_FASTCALL Assign(const substring_tuple_type&,
|
||||||
const fallible_t&);
|
const fallible_t&);
|
||||||
|
|
||||||
void Assign(nsStringBuffer* aBuffer, size_type aLength) {
|
void Assign(mozilla::StringBuffer* aBuffer, size_type aLength) {
|
||||||
aBuffer->AddRef();
|
aBuffer->AddRef();
|
||||||
Assign(already_AddRefed<nsStringBuffer>(aBuffer), aLength);
|
Assign(already_AddRefed<mozilla::StringBuffer>(aBuffer), aLength);
|
||||||
}
|
}
|
||||||
void NS_FASTCALL Assign(already_AddRefed<nsStringBuffer> aBuffer,
|
void NS_FASTCALL Assign(already_AddRefed<mozilla::StringBuffer> aBuffer,
|
||||||
size_type aLength);
|
size_type aLength);
|
||||||
|
|
||||||
#if defined(MOZ_USE_CHAR16_WRAPPER)
|
#if defined(MOZ_USE_CHAR16_WRAPPER)
|
||||||
|
|
@ -1155,9 +1153,9 @@ class nsTSubstring : public mozilla::detail::nsTStringRepr<T> {
|
||||||
* If the string uses a reference-counted buffer, this method returns a
|
* If the string uses a reference-counted buffer, this method returns a
|
||||||
* pointer to it without incrementing the buffer's refcount.
|
* pointer to it without incrementing the buffer's refcount.
|
||||||
*/
|
*/
|
||||||
nsStringBuffer* GetStringBuffer() const {
|
mozilla::StringBuffer* GetStringBuffer() const {
|
||||||
if (this->mDataFlags & DataFlags::REFCOUNTED) {
|
if (this->mDataFlags & DataFlags::REFCOUNTED) {
|
||||||
return nsStringBuffer::FromData(this->mData);
|
return mozilla::StringBuffer::FromData(this->mData);
|
||||||
}
|
}
|
||||||
return nullptr;
|
return nullptr;
|
||||||
}
|
}
|
||||||
|
|
|
||||||
|
|
@ -8,7 +8,6 @@
|
||||||
#include <stdlib.h>
|
#include <stdlib.h>
|
||||||
#include "nsASCIIMask.h"
|
#include "nsASCIIMask.h"
|
||||||
#include "nsString.h"
|
#include "nsString.h"
|
||||||
#include "nsStringBuffer.h"
|
|
||||||
#include "nsReadableUtils.h"
|
#include "nsReadableUtils.h"
|
||||||
#include "nsCRTGlue.h"
|
#include "nsCRTGlue.h"
|
||||||
#include "mozilla/RefPtr.h"
|
#include "mozilla/RefPtr.h"
|
||||||
|
|
|
||||||
|
|
@ -10,7 +10,7 @@
|
||||||
#include "nsCharSeparatedTokenizer.h"
|
#include "nsCharSeparatedTokenizer.h"
|
||||||
#include "nsPrintfCString.h"
|
#include "nsPrintfCString.h"
|
||||||
#include "nsString.h"
|
#include "nsString.h"
|
||||||
#include "nsStringBuffer.h"
|
#include "mozilla/StringBuffer.h"
|
||||||
#include "nsReadableUtils.h"
|
#include "nsReadableUtils.h"
|
||||||
#include "nsCRTGlue.h"
|
#include "nsCRTGlue.h"
|
||||||
#include "mozilla/RefPtr.h"
|
#include "mozilla/RefPtr.h"
|
||||||
|
|
@ -44,6 +44,7 @@ using mozilla::Maybe;
|
||||||
using mozilla::Nothing;
|
using mozilla::Nothing;
|
||||||
using mozilla::Some;
|
using mozilla::Some;
|
||||||
using mozilla::Span;
|
using mozilla::Span;
|
||||||
|
using mozilla::StringBuffer;
|
||||||
|
|
||||||
#define TestExample1 \
|
#define TestExample1 \
|
||||||
"Sed ut perspiciatis unde omnis iste natus error sit voluptatem " \
|
"Sed ut perspiciatis unde omnis iste natus error sit voluptatem " \
|
||||||
|
|
@ -1172,12 +1173,12 @@ TEST_F(Strings, rfindcharinset) {
|
||||||
TEST_F(Strings, stringbuffer) {
|
TEST_F(Strings, stringbuffer) {
|
||||||
const char kData[] = "hello world";
|
const char kData[] = "hello world";
|
||||||
|
|
||||||
RefPtr<nsStringBuffer> buf;
|
RefPtr<StringBuffer> buf;
|
||||||
|
|
||||||
buf = nsStringBuffer::Alloc(sizeof(kData));
|
buf = StringBuffer::Alloc(sizeof(kData));
|
||||||
EXPECT_TRUE(!!buf);
|
EXPECT_TRUE(!!buf);
|
||||||
|
|
||||||
buf = nsStringBuffer::Alloc(sizeof(kData));
|
buf = StringBuffer::Alloc(sizeof(kData));
|
||||||
EXPECT_TRUE(!!buf);
|
EXPECT_TRUE(!!buf);
|
||||||
char* data = (char*)buf->Data();
|
char* data = (char*)buf->Data();
|
||||||
memcpy(data, kData, sizeof(kData));
|
memcpy(data, kData, sizeof(kData));
|
||||||
|
|
@ -1185,7 +1186,7 @@ TEST_F(Strings, stringbuffer) {
|
||||||
nsCString str;
|
nsCString str;
|
||||||
str.Assign(buf, sizeof(kData) - 1);
|
str.Assign(buf, sizeof(kData) - 1);
|
||||||
|
|
||||||
nsStringBuffer* buf2 = str.GetStringBuffer();
|
StringBuffer* buf2 = str.GetStringBuffer();
|
||||||
EXPECT_EQ(buf, buf2);
|
EXPECT_EQ(buf, buf2);
|
||||||
}
|
}
|
||||||
|
|
||||||
|
|
|
||||||
|
|
@ -9,7 +9,6 @@
|
||||||
#include <stdio.h>
|
#include <stdio.h>
|
||||||
#include <stdlib.h>
|
#include <stdlib.h>
|
||||||
#include "nsString.h"
|
#include "nsString.h"
|
||||||
#include "nsStringBuffer.h"
|
|
||||||
#include "nsReadableUtils.h"
|
#include "nsReadableUtils.h"
|
||||||
#include "UTFStrings.h"
|
#include "UTFStrings.h"
|
||||||
#include "nsUnicharUtils.h"
|
#include "nsUnicharUtils.h"
|
||||||
|
|
|
||||||
Loading…
Reference in a new issue