зеркало из https://github.com/mozilla/gecko-dev.git
Bug 1893683 - Remove ns{A,C}String and other xpcom dependencies from nsStringBuffer. r=smaug,media-playback-reviewers,karlt
* nsStringBuffer::FromString -> nsTSubString::GetStringBuffer * nsStringBuffer::ToString -> nsTSubString::Assign(nsStringBuffer*, len) * Move refcounting inline but refcount-logging and other XPCOM-related things out-of-line. Differential Revision: https://phabricator.services.mozilla.com/D208771
This commit is contained in:
Родитель
597a1ab19f
Коммит
8aaf44fea9
|
@ -141,7 +141,7 @@ bool MiscContainer::GetString(nsAString& aString) const {
|
|||
}
|
||||
if (isString) {
|
||||
auto* buffer = static_cast<nsStringBuffer*>(ptr);
|
||||
buffer->ToString(buffer->StorageSize() / sizeof(char16_t) - 1, aString);
|
||||
aString.Assign(buffer, buffer->StorageSize() / sizeof(char16_t) - 1);
|
||||
} else {
|
||||
static_cast<nsAtom*>(ptr)->ToString(aString);
|
||||
}
|
||||
|
@ -280,11 +280,9 @@ void nsAttrValue::Shutdown() {
|
|||
void nsAttrValue::Reset() {
|
||||
switch (BaseType()) {
|
||||
case eStringBase: {
|
||||
nsStringBuffer* str = static_cast<nsStringBuffer*>(GetPtr());
|
||||
if (str) {
|
||||
if (auto* str = static_cast<nsStringBuffer*>(GetPtr())) {
|
||||
str->Release();
|
||||
}
|
||||
|
||||
break;
|
||||
}
|
||||
case eOtherBase: {
|
||||
|
@ -320,8 +318,7 @@ void nsAttrValue::SetTo(const nsAttrValue& aOther) {
|
|||
switch (aOther.BaseType()) {
|
||||
case eStringBase: {
|
||||
ResetIfSet();
|
||||
nsStringBuffer* str = static_cast<nsStringBuffer*>(aOther.GetPtr());
|
||||
if (str) {
|
||||
if (auto* str = static_cast<nsStringBuffer*>(aOther.GetPtr())) {
|
||||
str->AddRef();
|
||||
SetPtrValueAndType(str, eStringBase);
|
||||
}
|
||||
|
@ -623,18 +620,16 @@ void nsAttrValue::ToString(nsAString& aResult) const {
|
|||
|
||||
switch (Type()) {
|
||||
case eString: {
|
||||
nsStringBuffer* str = static_cast<nsStringBuffer*>(GetPtr());
|
||||
if (str) {
|
||||
str->ToString(str->StorageSize() / sizeof(char16_t) - 1, aResult);
|
||||
if (auto* str = static_cast<nsStringBuffer*>(GetPtr())) {
|
||||
aResult.Assign(str, str->StorageSize() / sizeof(char16_t) - 1);
|
||||
} else {
|
||||
aResult.Truncate();
|
||||
}
|
||||
break;
|
||||
}
|
||||
case eAtom: {
|
||||
nsAtom* atom = static_cast<nsAtom*>(GetPtr());
|
||||
auto* atom = static_cast<nsAtom*>(GetPtr());
|
||||
atom->ToString(aResult);
|
||||
|
||||
break;
|
||||
}
|
||||
case eInteger: {
|
||||
|
@ -895,8 +890,7 @@ nsAtom* nsAttrValue::AtomAt(int32_t aIndex) const {
|
|||
uint32_t nsAttrValue::HashValue() const {
|
||||
switch (BaseType()) {
|
||||
case eStringBase: {
|
||||
nsStringBuffer* str = static_cast<nsStringBuffer*>(GetPtr());
|
||||
if (str) {
|
||||
if (auto* str = static_cast<nsStringBuffer*>(GetPtr())) {
|
||||
uint32_t len = str->StorageSize() / sizeof(char16_t) - 1;
|
||||
return HashString(static_cast<char16_t*>(str->Data()), len);
|
||||
}
|
||||
|
@ -1208,8 +1202,7 @@ bool nsAttrValue::SubstringCheck(const nsAString& aValue,
|
|||
nsCaseTreatment aCaseSensitive) const {
|
||||
switch (BaseType()) {
|
||||
case eStringBase: {
|
||||
auto str = static_cast<nsStringBuffer*>(GetPtr());
|
||||
if (str) {
|
||||
if (auto* str = static_cast<nsStringBuffer*>(GetPtr())) {
|
||||
return F::Check(static_cast<char16_t*>(str->Data()),
|
||||
str->StorageSize() / sizeof(char16_t) - 1, aValue,
|
||||
aCaseSensitive);
|
||||
|
@ -1217,7 +1210,7 @@ bool nsAttrValue::SubstringCheck(const nsAString& aValue,
|
|||
return aValue.IsEmpty();
|
||||
}
|
||||
case eAtomBase: {
|
||||
auto atom = static_cast<nsAtom*>(GetPtr());
|
||||
auto* atom = static_cast<nsAtom*>(GetPtr());
|
||||
return F::Check(atom->GetUTF16String(), atom->GetLength(), aValue,
|
||||
aCaseSensitive);
|
||||
}
|
||||
|
@ -2107,12 +2100,11 @@ already_AddRefed<nsStringBuffer> nsAttrValue::GetStringBuffer(
|
|||
if (!len) {
|
||||
return nullptr;
|
||||
}
|
||||
|
||||
RefPtr<nsStringBuffer> buf = nsStringBuffer::FromString(aValue);
|
||||
if (buf && (buf->StorageSize() / sizeof(char16_t) - 1) == len) {
|
||||
if (nsStringBuffer* buf = aValue.GetStringBuffer();
|
||||
buf && (buf->StorageSize() / sizeof(char16_t) - 1) == len) {
|
||||
// We can only reuse the buffer if it's exactly sized, since we rely on
|
||||
// StorageSize() to get the string length in ToString().
|
||||
return buf.forget();
|
||||
return do_AddRef(buf);
|
||||
}
|
||||
return nsStringBuffer::Create(aValue.Data(), aValue.Length());
|
||||
}
|
||||
|
|
|
@ -108,7 +108,9 @@ const uintptr_t NS_ATTRVALUE_BASETYPE_MASK = 3;
|
|||
class nsCheapString : public nsString {
|
||||
public:
|
||||
explicit nsCheapString(nsStringBuffer* aBuf) {
|
||||
if (aBuf) aBuf->ToString(aBuf->StorageSize() / sizeof(char16_t) - 1, *this);
|
||||
if (aBuf) {
|
||||
Assign(aBuf, aBuf->StorageSize() / sizeof(char16_t) - 1);
|
||||
}
|
||||
}
|
||||
};
|
||||
|
||||
|
|
|
@ -7010,25 +7010,6 @@ bool nsContentUtils::PlatformToDOMLineBreaks(nsString& aString,
|
|||
return true;
|
||||
}
|
||||
|
||||
void nsContentUtils::PopulateStringFromStringBuffer(nsStringBuffer* aBuf,
|
||||
nsAString& aResultString) {
|
||||
MOZ_ASSERT(aBuf, "Expecting a non-null string buffer");
|
||||
|
||||
uint32_t stringLen = NS_strlen(static_cast<char16_t*>(aBuf->Data()));
|
||||
|
||||
// SANITY CHECK: In case the nsStringBuffer isn't correctly
|
||||
// null-terminated, let's clamp its length using the allocated size, to be
|
||||
// sure the resulting string doesn't sample past the end of the the buffer.
|
||||
// (Note that StorageSize() is in units of bytes, so we have to convert that
|
||||
// to units of PRUnichars, and subtract 1 for the null-terminator.)
|
||||
uint32_t allocStringLen = (aBuf->StorageSize() / sizeof(char16_t)) - 1;
|
||||
MOZ_ASSERT(stringLen <= allocStringLen,
|
||||
"string buffer lacks null terminator!");
|
||||
stringLen = std::min(stringLen, allocStringLen);
|
||||
|
||||
aBuf->ToString(stringLen, aResultString);
|
||||
}
|
||||
|
||||
already_AddRefed<nsContentList> nsContentUtils::GetElementsByClassName(
|
||||
nsINode* aRootNode, const nsAString& aClasses) {
|
||||
MOZ_ASSERT(aRootNode, "Must have root node");
|
||||
|
|
|
@ -115,7 +115,6 @@ class nsNodeInfoManager;
|
|||
class nsParser;
|
||||
class nsPIWindowRoot;
|
||||
class nsPresContext;
|
||||
class nsStringBuffer;
|
||||
class nsTextFragment;
|
||||
class nsView;
|
||||
class nsWrapperCache;
|
||||
|
@ -2446,14 +2445,6 @@ class nsContentUtils {
|
|||
[[nodiscard]] static bool PlatformToDOMLineBreaks(nsString& aString,
|
||||
const mozilla::fallible_t&);
|
||||
|
||||
/**
|
||||
* Populates aResultString with the contents of the string-buffer aBuf, up
|
||||
* to aBuf's null-terminator. aBuf must not be null. Ownership of the string
|
||||
* is not transferred.
|
||||
*/
|
||||
static void PopulateStringFromStringBuffer(nsStringBuffer* aBuf,
|
||||
nsAString& aResultString);
|
||||
|
||||
static bool IsHandlingKeyBoardEvent() { return sIsHandlingKeyBoardEvent; }
|
||||
|
||||
static void SetIsHandlingKeyBoardEvent(bool aHandling) {
|
||||
|
|
|
@ -113,8 +113,7 @@ class nsTextFragment final {
|
|||
}
|
||||
ReleaseText();
|
||||
if (aForce2b && !aUpdateBidi) {
|
||||
nsStringBuffer* buffer = nsStringBuffer::FromString(aString);
|
||||
if (buffer) {
|
||||
if (nsStringBuffer* buffer = aString.GetStringBuffer()) {
|
||||
NS_ADDREF(m2b = buffer);
|
||||
mState.mInHeap = true;
|
||||
mState.mIs2b = true;
|
||||
|
@ -154,19 +153,13 @@ class nsTextFragment final {
|
|||
const mozilla::fallible_t& aFallible) const {
|
||||
if (mState.mIs2b) {
|
||||
if (aString.IsEmpty()) {
|
||||
m2b->ToString(mState.mLength, aString);
|
||||
aString.Assign(m2b, mState.mLength);
|
||||
return true;
|
||||
}
|
||||
bool ok = aString.Append(Get2b(), mState.mLength, aFallible);
|
||||
if (!ok) {
|
||||
return false;
|
||||
}
|
||||
|
||||
return true;
|
||||
} else {
|
||||
return AppendASCIItoUTF16(Substring(m1b, mState.mLength), aString,
|
||||
aFallible);
|
||||
return aString.Append(Get2b(), mState.mLength, aFallible);
|
||||
}
|
||||
return AppendASCIItoUTF16(Substring(m1b, mState.mLength), aString,
|
||||
aFallible);
|
||||
}
|
||||
|
||||
/**
|
||||
|
|
|
@ -169,8 +169,7 @@ class MOZ_STACK_CLASS DOMString {
|
|||
if (MOZ_UNLIKELY(aString.IsVoid())) {
|
||||
SetNull();
|
||||
} else if (!aString.IsEmpty()) {
|
||||
nsStringBuffer* buf = nsStringBuffer::FromString(aString);
|
||||
if (buf) {
|
||||
if (nsStringBuffer* buf = aString.GetStringBuffer()) {
|
||||
SetKnownLiveStringBuffer(buf, aString.Length());
|
||||
} else if (aString.IsLiteral()) {
|
||||
SetLiteralInternal(aString.BeginReading(), aString.Length());
|
||||
|
@ -236,7 +235,7 @@ class MOZ_STACK_CLASS DOMString {
|
|||
auto chars = static_cast<char16_t*>(buf->Data());
|
||||
if (chars[len] == '\0') {
|
||||
// Safe to share the buffer.
|
||||
buf->ToString(len, aString);
|
||||
aString.Assign(buf, len);
|
||||
} else {
|
||||
// We need to copy, unfortunately.
|
||||
aString.Assign(chars, len);
|
||||
|
|
|
@ -51,7 +51,7 @@ struct FakeString {
|
|||
// depend upon aString's data. aString should outlive this instance of
|
||||
// FakeString.
|
||||
void ShareOrDependUpon(const AString& aString) {
|
||||
RefPtr<nsStringBuffer> sharedBuffer = nsStringBuffer::FromString(aString);
|
||||
RefPtr<nsStringBuffer> sharedBuffer = aString.GetStringBuffer();
|
||||
if (!sharedBuffer) {
|
||||
InitData(aString.BeginReading(), aString.Length());
|
||||
if (!aString.IsTerminated()) {
|
||||
|
|
|
@ -66,8 +66,7 @@ void TestFunctions::GetStringDataAsDOMString(const Optional<uint32_t>& aLength,
|
|||
length = mStringData.Length();
|
||||
}
|
||||
|
||||
nsStringBuffer* buf = nsStringBuffer::FromString(mStringData);
|
||||
if (buf) {
|
||||
if (nsStringBuffer* buf = mStringData.GetStringBuffer()) {
|
||||
aString.SetKnownLiveStringBuffer(buf, length);
|
||||
return;
|
||||
}
|
||||
|
@ -134,7 +133,7 @@ StringType TestFunctions::GetStringType(const nsAString& aString) {
|
|||
return StringType::Literal;
|
||||
}
|
||||
|
||||
if (nsStringBuffer::FromString(aString)) {
|
||||
if (aString.GetStringBuffer()) {
|
||||
return StringType::Stringbuffer;
|
||||
}
|
||||
|
||||
|
@ -146,9 +145,8 @@ StringType TestFunctions::GetStringType(const nsAString& aString) {
|
|||
}
|
||||
|
||||
bool TestFunctions::StringbufferMatchesStored(const nsAString& aString) {
|
||||
return nsStringBuffer::FromString(aString) &&
|
||||
nsStringBuffer::FromString(aString) ==
|
||||
nsStringBuffer::FromString(mStringData);
|
||||
return aString.GetStringBuffer() &&
|
||||
aString.GetStringBuffer() == mStringData.GetStringBuffer();
|
||||
}
|
||||
|
||||
void TestFunctions::TestThrowNsresult(ErrorResult& aError) {
|
||||
|
|
|
@ -1083,7 +1083,7 @@ already_AddRefed<nsITransferable> DataTransfer::GetTransferable(
|
|||
static_cast<char*>(stringBuffer->Data())[amountRead] = 0;
|
||||
|
||||
nsCString str;
|
||||
stringBuffer->ToString(totalCustomLength, str);
|
||||
str.Assign(stringBuffer, totalCustomLength);
|
||||
nsCOMPtr<nsISupportsCString> strSupports(
|
||||
do_CreateInstance(NS_SUPPORTS_CSTRING_CONTRACTID));
|
||||
strSupports->SetData(str);
|
||||
|
|
|
@ -9,7 +9,7 @@
|
|||
|
||||
#include "nsString.h" // Required before 'mozilla/ErrorNames.h'!?
|
||||
#include "mozilla/ErrorNames.h"
|
||||
#include "mozilla/TimeStamp.h"
|
||||
#include "mozilla/IntegerPrintfMacros.h"
|
||||
#include "nsError.h"
|
||||
#include "nsPrintfCString.h"
|
||||
|
||||
|
|
|
@ -5,6 +5,7 @@
|
|||
* file, You can obtain one at http://mozilla.org/MPL/2.0/. */
|
||||
|
||||
#include "DDLifetime.h"
|
||||
#include "mozilla/IntegerPrintfMacros.h"
|
||||
|
||||
namespace mozilla {
|
||||
|
||||
|
|
|
@ -6,7 +6,7 @@
|
|||
#include "CDMStorageIdProvider.h"
|
||||
#include "GMPLog.h"
|
||||
#include "nsCOMPtr.h"
|
||||
#include "nsComponentManagerUtils.h"
|
||||
#include "mozilla/IntegerPrintfMacros.h"
|
||||
#include "nsICryptoHash.h"
|
||||
|
||||
#ifdef SUPPORT_STORAGE_ID
|
||||
|
|
|
@ -341,7 +341,7 @@ class nsDocumentEncoder : public nsIDocumentEncoder {
|
|||
// argument of nsIContentSerializer::Init().
|
||||
bool mNeedsPreformatScanning;
|
||||
bool mIsCopying; // Set to true only while copying
|
||||
nsStringBuffer* mCachedBuffer;
|
||||
RefPtr<nsStringBuffer> mCachedBuffer;
|
||||
|
||||
class NodeSerializer {
|
||||
public:
|
||||
|
@ -701,11 +701,7 @@ nsresult nsDocumentEncoder::SerializeWholeDocument(uint32_t aMaxLength) {
|
|||
return rv;
|
||||
}
|
||||
|
||||
nsDocumentEncoder::~nsDocumentEncoder() {
|
||||
if (mCachedBuffer) {
|
||||
mCachedBuffer->Release();
|
||||
}
|
||||
}
|
||||
nsDocumentEncoder::~nsDocumentEncoder() = default;
|
||||
|
||||
NS_IMETHODIMP
|
||||
nsDocumentEncoder::Init(Document* aDocument, const nsAString& aMimeType,
|
||||
|
@ -1372,7 +1368,7 @@ nsDocumentEncoder::EncodeToStringWithMaxLength(uint32_t aMaxLength,
|
|||
nsString output;
|
||||
static const size_t kStringBufferSizeInBytes = 2048;
|
||||
if (!mCachedBuffer) {
|
||||
mCachedBuffer = nsStringBuffer::Alloc(kStringBufferSizeInBytes).take();
|
||||
mCachedBuffer = nsStringBuffer::Alloc(kStringBufferSizeInBytes);
|
||||
if (NS_WARN_IF(!mCachedBuffer)) {
|
||||
return NS_ERROR_OUT_OF_MEMORY;
|
||||
}
|
||||
|
@ -1381,9 +1377,7 @@ nsDocumentEncoder::EncodeToStringWithMaxLength(uint32_t aMaxLength,
|
|||
!mCachedBuffer->IsReadonly(),
|
||||
"nsIDocumentEncoder shouldn't keep reference to non-readonly buffer!");
|
||||
static_cast<char16_t*>(mCachedBuffer->Data())[0] = char16_t(0);
|
||||
mCachedBuffer->ToString(0, output, true);
|
||||
// output owns the buffer now!
|
||||
mCachedBuffer = nullptr;
|
||||
output.Assign(mCachedBuffer.forget(), 0);
|
||||
|
||||
if (!mSerializer) {
|
||||
nsAutoCString progId(NS_CONTENTSERIALIZER_CONTRACTID_PREFIX);
|
||||
|
@ -1407,21 +1401,18 @@ nsDocumentEncoder::EncodeToStringWithMaxLength(uint32_t aMaxLength,
|
|||
|
||||
rv = mSerializer->FlushAndFinish();
|
||||
|
||||
mCachedBuffer = nsStringBuffer::FromString(output);
|
||||
// We have to be careful how we set aOutputString, because we don't
|
||||
// want it to end up sharing mCachedBuffer if we plan to reuse it.
|
||||
bool setOutput = false;
|
||||
MOZ_ASSERT(!mCachedBuffer);
|
||||
// Try to cache the buffer.
|
||||
if (mCachedBuffer) {
|
||||
if ((mCachedBuffer->StorageSize() == kStringBufferSizeInBytes) &&
|
||||
!mCachedBuffer->IsReadonly()) {
|
||||
mCachedBuffer->AddRef();
|
||||
} else {
|
||||
if (NS_SUCCEEDED(rv)) {
|
||||
mCachedBuffer->ToString(output.Length(), aOutputString);
|
||||
setOutput = true;
|
||||
}
|
||||
mCachedBuffer = nullptr;
|
||||
if (nsStringBuffer* outputBuffer = output.GetStringBuffer()) {
|
||||
if (outputBuffer->StorageSize() == kStringBufferSizeInBytes &&
|
||||
!outputBuffer->IsReadonly()) {
|
||||
mCachedBuffer = outputBuffer;
|
||||
} else if (NS_SUCCEEDED(rv)) {
|
||||
aOutputString.Assign(outputBuffer, output.Length());
|
||||
setOutput = true;
|
||||
}
|
||||
}
|
||||
|
||||
|
|
|
@ -11,6 +11,7 @@
|
|||
#include "mozilla/AlreadyAddRefed.h"
|
||||
#include "mozilla/dom/NonRefcountedDOMObject.h"
|
||||
#include "mozilla/webgpu/WebGPUTypes.h"
|
||||
#include "mozilla/IntegerPrintfMacros.h"
|
||||
#include "nsPrintfCString.h"
|
||||
#include "nsString.h"
|
||||
#include "ObjectModel.h"
|
||||
|
|
|
@ -58,8 +58,7 @@ class XMLHttpRequestStringBuffer final {
|
|||
|
||||
// XXX: Bug 1408793 suggests encapsulating the following sequence within
|
||||
// DOMString.
|
||||
nsStringBuffer* buf = nsStringBuffer::FromString(mData);
|
||||
if (buf) {
|
||||
if (nsStringBuffer* buf = mData.GetStringBuffer()) {
|
||||
// We have to use SetStringBuffer, because once we release our mutex mData
|
||||
// can get mutated from some other thread while the DOMString is still
|
||||
// alive.
|
||||
|
|
|
@ -8,7 +8,8 @@
|
|||
|
||||
#include <ostream>
|
||||
#include "mozilla/HashFunctions.h" // for HashGeneric
|
||||
#include "nsPrintfCString.h" // for nsPrintfCString
|
||||
#include "mozilla/IntegerPrintfMacros.h"
|
||||
#include "nsPrintfCString.h" // for nsPrintfCString
|
||||
|
||||
namespace mozilla {
|
||||
namespace layers {
|
||||
|
|
|
@ -7,6 +7,7 @@
|
|||
#include "FocusState.h"
|
||||
|
||||
#include "mozilla/Logging.h"
|
||||
#include "mozilla/IntegerPrintfMacros.h"
|
||||
#include "mozilla/layers/APZThreadUtils.h"
|
||||
|
||||
static mozilla::LazyLogModule sApzFstLog("apz.focusstate");
|
||||
|
|
|
@ -104,8 +104,7 @@ bool XPCStringConvert::ReadableToJSVal(JSContext* cx, const nsAString& readable,
|
|||
return StringLiteralToJSVal(cx, readable.BeginReading(), length, vp);
|
||||
}
|
||||
|
||||
nsStringBuffer* buf = nsStringBuffer::FromString(readable);
|
||||
if (buf) {
|
||||
if (nsStringBuffer* buf = readable.GetStringBuffer()) {
|
||||
bool shared;
|
||||
if (!UCStringBufferToJSVal(cx, buf, length, vp, &shared)) {
|
||||
return false;
|
||||
|
@ -138,8 +137,7 @@ bool XPCStringConvert::Latin1ToJSVal(JSContext* cx, const nsACString& latin1,
|
|||
length, vp);
|
||||
}
|
||||
|
||||
nsStringBuffer* buf = nsStringBuffer::FromString(latin1);
|
||||
if (buf) {
|
||||
if (nsStringBuffer* buf = latin1.GetStringBuffer()) {
|
||||
bool shared;
|
||||
if (!Latin1StringBufferToJSVal(cx, buf, length, vp, &shared)) {
|
||||
return false;
|
||||
|
@ -170,8 +168,7 @@ bool XPCStringConvert::UTF8ToJSVal(JSContext* cx, const nsACString& utf8,
|
|||
cx, JS::UTF8Chars(utf8.BeginReading(), length), vp);
|
||||
}
|
||||
|
||||
nsStringBuffer* buf = nsStringBuffer::FromString(utf8);
|
||||
if (buf) {
|
||||
if (nsStringBuffer* buf = utf8.GetStringBuffer()) {
|
||||
bool shared;
|
||||
if (!UTF8StringBufferToJSVal(cx, buf, length, vp, &shared)) {
|
||||
return false;
|
||||
|
|
|
@ -238,11 +238,11 @@ extern JS::UniqueChars xpc_PrintJSStack(JSContext* cx, bool showArgs,
|
|||
|
||||
inline void AssignFromStringBuffer(nsStringBuffer* buffer, size_t len,
|
||||
nsAString& dest) {
|
||||
buffer->ToString(len, dest);
|
||||
dest.Assign(buffer, len);
|
||||
}
|
||||
inline void AssignFromStringBuffer(nsStringBuffer* buffer, size_t len,
|
||||
nsACString& dest) {
|
||||
buffer->ToString(len, dest);
|
||||
dest.Assign(buffer, len);
|
||||
}
|
||||
|
||||
// readable string conversions, static methods and members only
|
||||
|
|
|
@ -8,6 +8,7 @@
|
|||
#include "CacheFile.h"
|
||||
#include "nsStreamUtils.h"
|
||||
#include "nsThreadUtils.h"
|
||||
#include "mozilla/IntegerPrintfMacros.h"
|
||||
#include <algorithm>
|
||||
|
||||
namespace mozilla::net {
|
||||
|
|
|
@ -9,7 +9,7 @@
|
|||
#include "CacheEntry.h"
|
||||
#include "nsStreamUtils.h"
|
||||
#include "nsThreadUtils.h"
|
||||
#include "mozilla/DebugOnly.h"
|
||||
#include "mozilla/IntegerPrintfMacros.h"
|
||||
#include <algorithm>
|
||||
|
||||
namespace mozilla::net {
|
||||
|
|
|
@ -9,6 +9,7 @@
|
|||
|
||||
#include "nsIObserverService.h"
|
||||
#include "mozilla/StaticPrefs_network.h"
|
||||
#include "mozilla/IntegerPrintfMacros.h"
|
||||
#include "mozilla/Services.h"
|
||||
#include "mozilla/Logging.h"
|
||||
|
||||
|
|
|
@ -8,6 +8,7 @@
|
|||
#include "nsNetworkLinkService.h"
|
||||
#include "nsString.h"
|
||||
#include "mozilla/Logging.h"
|
||||
#include "mozilla/IntegerPrintfMacros.h"
|
||||
#include "nsNetAddr.h"
|
||||
|
||||
#include "mozilla/StaticPrefs_network.h"
|
||||
|
|
|
@ -5,12 +5,11 @@
|
|||
#include "nsHtml5String.h"
|
||||
#include "nsCharTraits.h"
|
||||
#include "nsHtml5TreeBuilder.h"
|
||||
#include "nsUTF8Utils.h"
|
||||
|
||||
void nsHtml5String::ToString(nsAString& aString) {
|
||||
switch (GetKind()) {
|
||||
case eStringBuffer:
|
||||
return AsStringBuffer()->ToString(Length(), aString);
|
||||
return aString.Assign(AsStringBuffer(), Length());
|
||||
case eAtom:
|
||||
return AsAtom()->ToString(aString);
|
||||
case eEmpty:
|
||||
|
@ -157,12 +156,14 @@ nsHtml5String nsHtml5String::FromString(const nsAString& aString) {
|
|||
if (!length) {
|
||||
return nsHtml5String(eEmpty);
|
||||
}
|
||||
RefPtr<nsStringBuffer> buffer = nsStringBuffer::FromString(aString);
|
||||
if (buffer && (length == buffer->StorageSize() / sizeof(char16_t) - 1)) {
|
||||
return nsHtml5String(reinterpret_cast<uintptr_t>(buffer.forget().take()) |
|
||||
eStringBuffer);
|
||||
if (nsStringBuffer* buffer = aString.GetStringBuffer()) {
|
||||
if (length == buffer->StorageSize() / sizeof(char16_t) - 1) {
|
||||
buffer->AddRef();
|
||||
return nsHtml5String(reinterpret_cast<uintptr_t>(buffer) | eStringBuffer);
|
||||
}
|
||||
}
|
||||
buffer = nsStringBuffer::Alloc((length + 1) * sizeof(char16_t));
|
||||
RefPtr<nsStringBuffer> buffer =
|
||||
nsStringBuffer::Alloc((length + 1) * sizeof(char16_t));
|
||||
if (!buffer) {
|
||||
MOZ_CRASH("Out of memory.");
|
||||
}
|
||||
|
|
|
@ -7,6 +7,7 @@
|
|||
#include "EnterpriseRoots.h"
|
||||
|
||||
#include "mozilla/ArrayUtils.h"
|
||||
#include "mozilla/IntegerPrintfMacros.h"
|
||||
#include "mozilla/Casting.h"
|
||||
#include "mozilla/Logging.h"
|
||||
#include "mozilla/Unused.h"
|
||||
|
|
|
@ -15,17 +15,12 @@
|
|||
#include "nsIFile.h"
|
||||
#include "nsThreadUtils.h"
|
||||
#include "mozilla/Logging.h"
|
||||
#include "mozilla/IntegerPrintfMacros.h"
|
||||
#include "prtime.h"
|
||||
#include "mozilla/StaticPrefs_storage.h"
|
||||
|
||||
#include "mozStorageConnection.h"
|
||||
#include "mozStoragePrivateHelpers.h"
|
||||
#include "mozIStorageStatement.h"
|
||||
#include "mozIStorageCompletionCallback.h"
|
||||
#include "mozIStorageAsyncStatement.h"
|
||||
#include "mozIStoragePendingStatement.h"
|
||||
#include "mozIStorageError.h"
|
||||
#include "mozStorageHelper.h"
|
||||
#include "nsXULAppAPI.h"
|
||||
#include "xpcpublic.h"
|
||||
|
||||
|
|
|
@ -15,9 +15,8 @@
|
|||
#include "mozStorageCID.h"
|
||||
#include "mozilla/Components.h"
|
||||
#include "mozilla/Monitor.h"
|
||||
#include "mozilla/AppShutdown.h"
|
||||
#include "mozilla/IntegerPrintfMacros.h"
|
||||
#include "mozilla/Services.h"
|
||||
#include "mozilla/ShutdownPhase.h"
|
||||
#include "nsCOMPtr.h"
|
||||
#include "nsDirectoryServiceUtils.h"
|
||||
#include "nsIObserverService.h"
|
||||
|
|
|
@ -9,6 +9,7 @@
|
|||
#include "ErrorList.h"
|
||||
#include "mozilla/Assertions.h"
|
||||
#include "mozilla/Logging.h"
|
||||
#include "mozilla/IntegerPrintfMacros.h"
|
||||
#include "nsIPrincipal.h"
|
||||
|
||||
namespace mozilla {
|
||||
|
|
|
@ -12,6 +12,7 @@
|
|||
#include "mozilla/ClearOnShutdown.h"
|
||||
#include "mozilla/glean/bindings/jog/jog_ffi_generated.h"
|
||||
#include "mozilla/Logging.h"
|
||||
#include "mozilla/IntegerPrintfMacros.h"
|
||||
#include "mozilla/StaticPrefs_telemetry.h"
|
||||
#include "mozilla/AppShutdown.h"
|
||||
#include "nsDirectoryServiceDefs.h"
|
||||
|
@ -22,8 +23,7 @@
|
|||
|
||||
namespace mozilla::glean {
|
||||
|
||||
using mozilla::LogLevel;
|
||||
static mozilla::LazyLogModule sLog("jog");
|
||||
static LazyLogModule sLog("jog");
|
||||
|
||||
// Storage
|
||||
// Thread Safety: Only used on the main thread.
|
||||
|
|
|
@ -15,6 +15,7 @@
|
|||
#include "nsCOMPtr.h"
|
||||
#include "mozilla/Services.h"
|
||||
#include "mozilla/Atomics.h"
|
||||
#include "mozilla/IntegerPrintfMacros.h"
|
||||
|
||||
#ifdef ANDROID
|
||||
# include <stdio.h>
|
||||
|
|
|
@ -82,7 +82,7 @@ nsDynamicAtom* nsDynamicAtom::Create(const nsAString& aString, uint32_t aHash) {
|
|||
// We tack the chars onto the end of the nsDynamicAtom object.
|
||||
const bool isAsciiLower =
|
||||
::IsAsciiLowercase(aString.Data(), aString.Length());
|
||||
RefPtr<nsStringBuffer> buffer = nsStringBuffer::FromString(aString);
|
||||
RefPtr<nsStringBuffer> buffer = aString.GetStringBuffer();
|
||||
if (!buffer) {
|
||||
buffer = nsStringBuffer::Create(aString.Data(), aString.Length());
|
||||
if (MOZ_UNLIKELY(!buffer)) {
|
||||
|
@ -111,7 +111,7 @@ void nsAtom::ToString(nsAString& aString) const {
|
|||
// which is what's important.
|
||||
aString.AssignLiteral(AsStatic()->String(), mLength);
|
||||
} else {
|
||||
AsDynamic()->StringBuffer()->ToString(mLength, aString);
|
||||
aString.Assign(AsDynamic()->StringBuffer(), mLength);
|
||||
}
|
||||
}
|
||||
|
||||
|
@ -577,7 +577,7 @@ already_AddRefed<nsAtom> nsAtomTable::Atomize(const nsACString& aUTF8String) {
|
|||
|
||||
nsString str;
|
||||
CopyUTF8toUTF16(aUTF8String, str);
|
||||
MOZ_ASSERT(nsStringBuffer::FromString(str), "Should create a string buffer");
|
||||
MOZ_ASSERT(str.GetStringBuffer(), "Should create a string buffer");
|
||||
RefPtr<nsAtom> atom = dont_AddRef(nsDynamicAtom::Create(str, key.mHash));
|
||||
|
||||
he->mAtom = atom;
|
||||
|
|
|
@ -10,6 +10,7 @@
|
|||
#include "mozilla/Maybe.h"
|
||||
#include "mozilla/Mutex.h"
|
||||
#include "mozilla/Attributes.h"
|
||||
#include "mozilla/IntegerPrintfMacros.h"
|
||||
#include "nsIInputStreamTee.h"
|
||||
#include "nsIInputStream.h"
|
||||
#include "nsIOutputStream.h"
|
||||
|
|
|
@ -7,64 +7,7 @@
|
|||
#include "nsStringBuffer.h"
|
||||
|
||||
#include "mozilla/MemoryReporting.h"
|
||||
#include "nsISupportsImpl.h"
|
||||
#include "nsString.h"
|
||||
|
||||
void nsStringBuffer::AddRef() {
|
||||
// Memory synchronization is not required when incrementing a
|
||||
// reference count. The first increment of a reference count on a
|
||||
// thread is not important, since the first use of the object on a
|
||||
// thread can happen before it. What is important is the transfer
|
||||
// of the pointer to that thread, which may happen prior to the
|
||||
// first increment on that thread. The necessary memory
|
||||
// synchronization is done by the mechanism that transfers the
|
||||
// pointer between threads.
|
||||
#ifdef NS_BUILD_REFCNT_LOGGING
|
||||
uint32_t count =
|
||||
#endif
|
||||
mRefCount.fetch_add(1, std::memory_order_relaxed)
|
||||
#ifdef NS_BUILD_REFCNT_LOGGING
|
||||
+ 1
|
||||
#endif
|
||||
;
|
||||
NS_LOG_ADDREF(this, count, "nsStringBuffer", sizeof(*this));
|
||||
}
|
||||
|
||||
void nsStringBuffer::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 that destroys the object when it reads mValue with
|
||||
// acquire semantics.
|
||||
uint32_t count = mRefCount.fetch_sub(1, std::memory_order_release) - 1;
|
||||
NS_LOG_RELEASE(this, count, "nsStringBuffer");
|
||||
if (count == 0) {
|
||||
// We're going to destroy the object on this thread, so we need
|
||||
// acquire semantics to synchronize with the memory released by
|
||||
// the last release on other threads, that is, to ensure that
|
||||
// writes prior to that release are now visible on this thread.
|
||||
count = mRefCount.load(std::memory_order_acquire);
|
||||
|
||||
free(this); // we were allocated with |malloc|
|
||||
}
|
||||
}
|
||||
|
||||
/**
|
||||
* Alloc returns a pointer to a new string header with set capacity.
|
||||
*/
|
||||
already_AddRefed<nsStringBuffer> nsStringBuffer::Alloc(size_t aSize) {
|
||||
NS_ASSERTION(aSize != 0, "zero capacity allocation not allowed");
|
||||
NS_ASSERTION(sizeof(nsStringBuffer) + aSize <= size_t(uint32_t(-1)) &&
|
||||
sizeof(nsStringBuffer) + aSize > aSize,
|
||||
"mStorageSize will truncate");
|
||||
|
||||
auto* hdr = (nsStringBuffer*)malloc(sizeof(nsStringBuffer) + aSize);
|
||||
if (hdr) {
|
||||
hdr->mRefCount = 1;
|
||||
hdr->mStorageSize = aSize;
|
||||
NS_LOG_ADDREF(hdr, 1, "nsStringBuffer", sizeof(*hdr));
|
||||
}
|
||||
return already_AddRefed(hdr);
|
||||
}
|
||||
#include "mozilla/RefPtr.h"
|
||||
|
||||
template <typename CharT>
|
||||
static already_AddRefed<nsStringBuffer> DoCreate(const CharT* aData,
|
||||
|
@ -91,78 +34,31 @@ already_AddRefed<nsStringBuffer> nsStringBuffer::Create(const char16_t* aData,
|
|||
}
|
||||
|
||||
nsStringBuffer* nsStringBuffer::Realloc(nsStringBuffer* aHdr, size_t aSize) {
|
||||
NS_ASSERTION(aSize != 0, "zero capacity allocation not allowed");
|
||||
NS_ASSERTION(sizeof(nsStringBuffer) + aSize <= size_t(uint32_t(-1)) &&
|
||||
sizeof(nsStringBuffer) + aSize > aSize,
|
||||
"mStorageSize will truncate");
|
||||
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
|
||||
NS_ASSERTION(!aHdr->IsReadonly(), "|Realloc| attempted on readonly string");
|
||||
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.
|
||||
NS_LOG_RELEASE(aHdr, 0, "nsStringBuffer");
|
||||
{
|
||||
mozilla::detail::RefCountLogger::ReleaseLogger logger(aHdr);
|
||||
logger.logRelease(0);
|
||||
}
|
||||
|
||||
aHdr = (nsStringBuffer*)realloc(aHdr, sizeof(nsStringBuffer) + aSize);
|
||||
if (aHdr) {
|
||||
NS_LOG_ADDREF(aHdr, 1, "nsStringBuffer", sizeof(*aHdr));
|
||||
mozilla::detail::RefCountLogger::logAddRef(aHdr, 1);
|
||||
aHdr->mStorageSize = aSize;
|
||||
}
|
||||
|
||||
return aHdr;
|
||||
}
|
||||
|
||||
nsStringBuffer* nsStringBuffer::FromString(const nsAString& aStr) {
|
||||
if (!(aStr.mDataFlags & nsAString::DataFlags::REFCOUNTED)) {
|
||||
return nullptr;
|
||||
}
|
||||
|
||||
return FromData(aStr.mData);
|
||||
}
|
||||
|
||||
nsStringBuffer* nsStringBuffer::FromString(const nsACString& aStr) {
|
||||
if (!(aStr.mDataFlags & nsACString::DataFlags::REFCOUNTED)) {
|
||||
return nullptr;
|
||||
}
|
||||
|
||||
return FromData(aStr.mData);
|
||||
}
|
||||
|
||||
void nsStringBuffer::ToString(uint32_t aLen, nsAString& aStr,
|
||||
bool aMoveOwnership) {
|
||||
char16_t* data = static_cast<char16_t*>(Data());
|
||||
|
||||
MOZ_DIAGNOSTIC_ASSERT(data[aLen] == char16_t(0),
|
||||
"data should be null terminated");
|
||||
|
||||
nsAString::DataFlags flags =
|
||||
nsAString::DataFlags::REFCOUNTED | nsAString::DataFlags::TERMINATED;
|
||||
|
||||
if (!aMoveOwnership) {
|
||||
AddRef();
|
||||
}
|
||||
aStr.Finalize();
|
||||
aStr.SetData(data, aLen, flags);
|
||||
}
|
||||
|
||||
void nsStringBuffer::ToString(uint32_t aLen, nsACString& aStr,
|
||||
bool aMoveOwnership) {
|
||||
char* data = static_cast<char*>(Data());
|
||||
|
||||
MOZ_DIAGNOSTIC_ASSERT(data[aLen] == char(0),
|
||||
"data should be null terminated");
|
||||
|
||||
nsACString::DataFlags flags =
|
||||
nsACString::DataFlags::REFCOUNTED | nsACString::DataFlags::TERMINATED;
|
||||
|
||||
if (!aMoveOwnership) {
|
||||
AddRef();
|
||||
}
|
||||
aStr.Finalize();
|
||||
aStr.SetData(data, aLen, flags);
|
||||
}
|
||||
|
||||
size_t nsStringBuffer::SizeOfIncludingThisIfUnshared(
|
||||
mozilla::MallocSizeOf aMallocSizeOf) const {
|
||||
return IsReadonly() ? 0 : aMallocSizeOf(this);
|
||||
|
|
|
@ -9,10 +9,9 @@
|
|||
|
||||
#include <atomic>
|
||||
#include "mozilla/MemoryReporting.h"
|
||||
#include "nsStringFwd.h"
|
||||
|
||||
template <class T>
|
||||
struct already_AddRefed;
|
||||
#include "mozilla/Assertions.h"
|
||||
#include "mozilla/AlreadyAddRefed.h"
|
||||
#include "mozilla/RefCounted.h"
|
||||
|
||||
/**
|
||||
* This structure precedes the string buffers "we" allocate. It may be the
|
||||
|
@ -25,12 +24,12 @@ struct already_AddRefed;
|
|||
*/
|
||||
class nsStringBuffer {
|
||||
private:
|
||||
friend class CheckStaticAtomSizes;
|
||||
|
||||
std::atomic<uint32_t> mRefCount;
|
||||
uint32_t mStorageSize;
|
||||
|
||||
public:
|
||||
MOZ_DECLARE_REFCOUNTED_TYPENAME(nsStringBuffer)
|
||||
|
||||
/**
|
||||
* Allocates a new string buffer, with given size in bytes and a
|
||||
* reference count of one. When the string buffer is no longer needed,
|
||||
|
@ -43,12 +42,25 @@ class nsStringBuffer {
|
|||
* (i.e., it is not required that the null terminator appear in the last
|
||||
* storage unit of the string buffer's data).
|
||||
*
|
||||
* This guarantees that StorageSize() returns aStorageSize if the returned
|
||||
* This guarantees that StorageSize() returns aSize if the returned
|
||||
* buffer is non-null. Some callers like nsAttrValue rely on it.
|
||||
*
|
||||
* @return new string buffer or null if out of memory.
|
||||
*/
|
||||
static already_AddRefed<nsStringBuffer> Alloc(size_t aStorageSize);
|
||||
static already_AddRefed<nsStringBuffer> Alloc(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");
|
||||
|
||||
auto* hdr = (nsStringBuffer*)malloc(sizeof(nsStringBuffer) + aSize);
|
||||
if (hdr) {
|
||||
hdr->mRefCount = 1;
|
||||
hdr->mStorageSize = aSize;
|
||||
mozilla::detail::RefCountLogger::logAddRef(hdr, 1);
|
||||
}
|
||||
return already_AddRefed(hdr);
|
||||
}
|
||||
|
||||
/**
|
||||
* Returns a string buffer initialized with the given string on it, or null on
|
||||
|
@ -74,16 +86,35 @@ class nsStringBuffer {
|
|||
*/
|
||||
static nsStringBuffer* Realloc(nsStringBuffer* aBuf, size_t aStorageSize);
|
||||
|
||||
/**
|
||||
* Increment the reference count on this string buffer.
|
||||
*/
|
||||
void NS_FASTCALL AddRef();
|
||||
void AddRef() {
|
||||
// Memory synchronization is not required when incrementing a
|
||||
// reference count. The first increment of a reference count on a
|
||||
// thread is not important, since the first use of the object on a
|
||||
// thread can happen before it. What is important is the transfer
|
||||
// of the pointer to that thread, which may happen prior to the
|
||||
// first increment on that thread. The necessary memory
|
||||
// synchronization is done by the mechanism that transfers the
|
||||
// pointer between threads.
|
||||
uint32_t count = mRefCount.fetch_add(1, std::memory_order_relaxed) + 1;
|
||||
mozilla::detail::RefCountLogger::logAddRef(this, count);
|
||||
}
|
||||
|
||||
/**
|
||||
* Decrement the reference count on this string buffer. The string
|
||||
* buffer will be destroyed when its reference count reaches zero.
|
||||
*/
|
||||
void NS_FASTCALL Release();
|
||||
void 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
|
||||
// that destroys the object when it reads mValue with acquire semantics.
|
||||
mozilla::detail::RefCountLogger::ReleaseLogger logger(this);
|
||||
uint32_t count = mRefCount.fetch_sub(1, std::memory_order_release) - 1;
|
||||
logger.logRelease(count);
|
||||
if (count == 0) {
|
||||
// We're going to destroy the object on this thread, so we need acquire
|
||||
// semantics to synchronize with the memory released by the last release
|
||||
// on other threads, that is, to ensure that writes prior to that release
|
||||
// are now visible on this thread.
|
||||
count = mRefCount.load(std::memory_order_acquire);
|
||||
free(this); // We were allocated with malloc.
|
||||
}
|
||||
}
|
||||
|
||||
/**
|
||||
* This method returns the string buffer corresponding to the given data
|
||||
|
@ -148,34 +179,6 @@ class nsStringBuffer {
|
|||
#endif
|
||||
}
|
||||
|
||||
/**
|
||||
* The FromString methods return a string buffer for the given string
|
||||
* object or null if the string object does not have a string buffer.
|
||||
* The reference count of the string buffer is NOT incremented by these
|
||||
* methods. If the caller wishes to hold onto the returned value, then
|
||||
* the returned string buffer must have its reference count incremented
|
||||
* via a call to the AddRef method.
|
||||
*/
|
||||
static nsStringBuffer* FromString(const nsAString& aStr);
|
||||
static nsStringBuffer* FromString(const nsACString& aStr);
|
||||
|
||||
/**
|
||||
* The ToString methods assign this string buffer to a given string
|
||||
* object. If the string object does not support sharable string
|
||||
* buffers, then its value will be set to a copy of the given string
|
||||
* buffer. Otherwise, these methods increment the reference count of the
|
||||
* given string buffer. It is important to specify the length (in
|
||||
* storage units) of the string contained in the string buffer since the
|
||||
* length of the string may be less than its storage size. The string
|
||||
* must have a null terminator at the offset specified by |len|.
|
||||
*
|
||||
* NOTE: storage size is measured in bytes even for wide strings;
|
||||
* however, string length is always measured in storage units
|
||||
* (2-byte units for wide strings).
|
||||
*/
|
||||
void ToString(uint32_t aLen, nsAString& aStr, bool aMoveOwnership = false);
|
||||
void ToString(uint32_t aLen, nsACString& aStr, bool aMoveOwnership = false);
|
||||
|
||||
/**
|
||||
* This measures the size only if the StringBuffer is unshared.
|
||||
*/
|
||||
|
|
|
@ -403,6 +403,17 @@ void nsTSubstring<T>::Assign(const char_type* aData, size_type aLength) {
|
|||
}
|
||||
}
|
||||
|
||||
template <typename T>
|
||||
void nsTSubstring<T>::Assign(already_AddRefed<nsStringBuffer> aBuffer,
|
||||
size_type aLength) {
|
||||
nsStringBuffer* buffer = aBuffer.take();
|
||||
auto* data = reinterpret_cast<char_type*>(buffer->Data());
|
||||
MOZ_DIAGNOSTIC_ASSERT(data[aLength] == char_type(0),
|
||||
"data should be null terminated");
|
||||
Finalize();
|
||||
SetData(data, aLength, DataFlags::REFCOUNTED | DataFlags::TERMINATED);
|
||||
}
|
||||
|
||||
template <typename T>
|
||||
bool nsTSubstring<T>::Assign(const char_type* aData,
|
||||
const fallible_t& aFallible) {
|
||||
|
|
|
@ -8,20 +8,17 @@
|
|||
#ifndef nsTSubstring_h
|
||||
#define nsTSubstring_h
|
||||
|
||||
#include <iterator>
|
||||
#include <type_traits>
|
||||
|
||||
#include "mozilla/Casting.h"
|
||||
#include "mozilla/Attributes.h"
|
||||
#include "mozilla/DebugOnly.h"
|
||||
#include "mozilla/IntegerPrintfMacros.h"
|
||||
#include "mozilla/UniquePtr.h"
|
||||
#include "mozilla/Maybe.h"
|
||||
#include "mozilla/MemoryReporting.h"
|
||||
#include "mozilla/IntegerTypeTraits.h"
|
||||
#include "mozilla/ResultExtensions.h"
|
||||
#include "mozilla/Span.h"
|
||||
#include "mozilla/Try.h"
|
||||
#include "mozilla/Unused.h"
|
||||
#include "nsStringBuffer.h"
|
||||
|
||||
#include "nsTStringRepr.h"
|
||||
|
||||
|
@ -422,6 +419,13 @@ class nsTSubstring : public mozilla::detail::nsTStringRepr<T> {
|
|||
[[nodiscard]] bool NS_FASTCALL Assign(const substring_tuple_type&,
|
||||
const fallible_t&);
|
||||
|
||||
void Assign(nsStringBuffer* aBuffer, size_type aLength) {
|
||||
aBuffer->AddRef();
|
||||
Assign(already_AddRefed<nsStringBuffer>(aBuffer), aLength);
|
||||
}
|
||||
void NS_FASTCALL Assign(already_AddRefed<nsStringBuffer> aBuffer,
|
||||
size_type aLength);
|
||||
|
||||
#if defined(MOZ_USE_CHAR16_WRAPPER)
|
||||
template <typename Q = T, typename EnableIfChar16 = mozilla::Char16OnlyT<Q>>
|
||||
void Assign(char16ptr_t aData) {
|
||||
|
@ -1142,11 +1146,22 @@ class nsTSubstring : public mozilla::detail::nsTStringRepr<T> {
|
|||
* clears the pointer without releasing the buffer.
|
||||
*/
|
||||
void ForgetSharedBuffer() {
|
||||
if (base_string_type::mDataFlags & DataFlags::REFCOUNTED) {
|
||||
if (this->mDataFlags & DataFlags::REFCOUNTED) {
|
||||
SetToEmptyBuffer();
|
||||
}
|
||||
}
|
||||
|
||||
/**
|
||||
* If the string uses a reference-counted buffer, this method returns a
|
||||
* pointer to it without incrementing the buffer's refcount.
|
||||
*/
|
||||
nsStringBuffer* GetStringBuffer() const {
|
||||
if (this->mDataFlags & DataFlags::REFCOUNTED) {
|
||||
return nsStringBuffer::FromData(this->mData);
|
||||
}
|
||||
return nullptr;
|
||||
}
|
||||
|
||||
protected:
|
||||
void AssertValid() {
|
||||
MOZ_DIAGNOSTIC_ASSERT(!(this->mClassFlags & ClassFlags::INVALID_MASK));
|
||||
|
|
|
@ -23,6 +23,7 @@
|
|||
#include "nsAppDirectoryServiceDefs.h"
|
||||
#include "nsDirectoryServiceDefs.h"
|
||||
#include "nsDirectoryServiceUtils.h"
|
||||
#include "mozilla/IntegerPrintfMacros.h"
|
||||
#include "nsIDirectoryService.h"
|
||||
#include "nsIFile.h"
|
||||
#include "nsIObserverService.h"
|
||||
|
|
|
@ -1183,11 +1183,9 @@ TEST_F(Strings, stringbuffer) {
|
|||
memcpy(data, kData, sizeof(kData));
|
||||
|
||||
nsCString str;
|
||||
buf->ToString(sizeof(kData) - 1, str);
|
||||
|
||||
nsStringBuffer* buf2;
|
||||
buf2 = nsStringBuffer::FromString(str);
|
||||
str.Assign(buf, sizeof(kData) - 1);
|
||||
|
||||
nsStringBuffer* buf2 = str.GetStringBuffer();
|
||||
EXPECT_EQ(buf, buf2);
|
||||
}
|
||||
|
||||
|
|
Загрузка…
Ссылка в новой задаче