Bug 1861467 - [wpt-sync] Update web-platform-tests to eedf737ce39c512d0ca3471f988972e...
[gecko.git] / dom / xhr / XMLHttpRequestString.cpp
blob41e40c36560b2d67a4bbea6b1a1f3b48fe90ec44
1 /* -*- Mode: C++; tab-width: 8; indent-tabs-mode: nil; c-basic-offset: 2 -*- */
2 /* vim: set ts=8 sts=2 et sw=2 tw=80: */
3 /* This Source Code Form is subject to the terms of the Mozilla Public
4 * License, v. 2.0. If a copy of the MPL was not distributed with this
5 * file, You can obtain one at http://mozilla.org/MPL/2.0/. */
7 #include "XMLHttpRequestString.h"
8 #include "nsISupportsImpl.h"
9 #include "mozilla/dom/DOMString.h"
11 namespace mozilla::dom {
13 class XMLHttpRequestStringBuffer final {
14 friend class XMLHttpRequestStringWriterHelper;
15 friend class XMLHttpRequestStringSnapshotReaderHelper;
17 public:
18 NS_INLINE_DECL_THREADSAFE_REFCOUNTING(XMLHttpRequestStringBuffer)
19 NS_DECL_OWNINGTHREAD
21 XMLHttpRequestStringBuffer() : mMutex("XMLHttpRequestStringBuffer::mMutex") {}
23 uint32_t Length() {
24 MutexAutoLock lock(mMutex);
25 return mData.Length();
28 uint32_t UnsafeLength() const MOZ_NO_THREAD_SAFETY_ANALYSIS {
29 return mData.Length();
32 mozilla::Result<mozilla::BulkWriteHandle<char16_t>, nsresult> UnsafeBulkWrite(
33 uint32_t aCapacity) MOZ_NO_THREAD_SAFETY_ANALYSIS {
34 return mData.BulkWrite(aCapacity, UnsafeLength(), false);
37 void Append(const nsAString& aString) {
38 NS_ASSERT_OWNINGTHREAD(XMLHttpRequestStringBuffer);
40 MutexAutoLock lock(mMutex);
41 mData.Append(aString);
44 [[nodiscard]] bool GetAsString(nsAString& aString) {
45 MutexAutoLock lock(mMutex);
46 return aString.Assign(mData, mozilla::fallible);
49 size_t SizeOfThis(MallocSizeOf aMallocSizeOf) {
50 MutexAutoLock lock(mMutex);
51 return mData.SizeOfExcludingThisIfUnshared(aMallocSizeOf);
54 [[nodiscard]] bool GetAsString(DOMString& aString, uint32_t aLength) {
55 MutexAutoLock lock(mMutex);
56 MOZ_ASSERT(aLength <= mData.Length());
58 // XXX: Bug 1408793 suggests encapsulating the following sequence within
59 // DOMString.
60 nsStringBuffer* buf = nsStringBuffer::FromString(mData);
61 if (buf) {
62 // We have to use SetStringBuffer, because once we release our mutex mData
63 // can get mutated from some other thread while the DOMString is still
64 // alive.
65 aString.SetStringBuffer(buf, aLength);
66 return true;
69 // We can get here if mData is empty. In that case it won't have an
70 // nsStringBuffer....
71 MOZ_ASSERT(mData.IsEmpty());
72 return aString.AsAString().Assign(mData.BeginReading(), aLength,
73 mozilla::fallible);
76 void CreateSnapshot(XMLHttpRequestStringSnapshot& aSnapshot) {
77 MutexAutoLock lock(mMutex);
78 aSnapshot.Set(this, mData.Length());
81 private:
82 ~XMLHttpRequestStringBuffer() = default;
84 nsString& UnsafeData() MOZ_NO_THREAD_SAFETY_ANALYSIS { return mData; }
86 Mutex mMutex;
88 // The following member variable is protected by mutex.
89 nsString mData MOZ_GUARDED_BY(mMutex);
92 // ---------------------------------------------------------------------------
93 // XMLHttpRequestString
95 XMLHttpRequestString::XMLHttpRequestString()
96 : mBuffer(new XMLHttpRequestStringBuffer()) {}
98 XMLHttpRequestString::~XMLHttpRequestString() = default;
100 void XMLHttpRequestString::Truncate() {
101 mBuffer = new XMLHttpRequestStringBuffer();
104 uint32_t XMLHttpRequestString::Length() const { return mBuffer->Length(); }
106 void XMLHttpRequestString::Append(const nsAString& aString) {
107 mBuffer->Append(aString);
110 bool XMLHttpRequestString::GetAsString(nsAString& aString) const {
111 return mBuffer->GetAsString(aString);
114 size_t XMLHttpRequestString::SizeOfThis(MallocSizeOf aMallocSizeOf) const {
115 return mBuffer->SizeOfThis(aMallocSizeOf);
118 bool XMLHttpRequestString::IsEmpty() const { return !mBuffer->Length(); }
120 void XMLHttpRequestString::CreateSnapshot(
121 XMLHttpRequestStringSnapshot& aSnapshot) {
122 mBuffer->CreateSnapshot(aSnapshot);
125 // ---------------------------------------------------------------------------
126 // XMLHttpRequestStringSnapshot
128 XMLHttpRequestStringSnapshot::XMLHttpRequestStringSnapshot()
129 : mLength(0), mVoid(false) {}
131 XMLHttpRequestStringSnapshot::~XMLHttpRequestStringSnapshot() = default;
133 void XMLHttpRequestStringSnapshot::ResetInternal(bool aIsVoid) {
134 mBuffer = nullptr;
135 mLength = 0;
136 mVoid = aIsVoid;
139 void XMLHttpRequestStringSnapshot::Set(XMLHttpRequestStringBuffer* aBuffer,
140 uint32_t aLength) {
141 MOZ_ASSERT(aBuffer);
142 MOZ_ASSERT(aLength <= aBuffer->UnsafeLength());
144 mBuffer = aBuffer;
145 mLength = aLength;
146 mVoid = false;
149 bool XMLHttpRequestStringSnapshot::GetAsString(DOMString& aString) const {
150 if (mBuffer) {
151 MOZ_ASSERT(!mVoid);
152 return mBuffer->GetAsString(aString, mLength);
155 if (mVoid) {
156 aString.SetNull();
159 return true;
162 // ---------------------------------------------------------------------------
163 // XMLHttpRequestStringWriterHelper
165 XMLHttpRequestStringWriterHelper::XMLHttpRequestStringWriterHelper(
166 XMLHttpRequestString& aString)
167 : mBuffer(aString.mBuffer), mLock(aString.mBuffer->mMutex) {}
169 XMLHttpRequestStringWriterHelper::~XMLHttpRequestStringWriterHelper() = default;
171 uint32_t XMLHttpRequestStringWriterHelper::Length() const {
172 return mBuffer->UnsafeLength();
175 mozilla::Result<mozilla::BulkWriteHandle<char16_t>, nsresult>
176 XMLHttpRequestStringWriterHelper::BulkWrite(uint32_t aCapacity) {
177 return mBuffer->UnsafeBulkWrite(aCapacity);
180 // ---------------------------------------------------------------------------
181 // XMLHttpRequestStringReaderHelper
183 XMLHttpRequestStringSnapshotReaderHelper::
184 XMLHttpRequestStringSnapshotReaderHelper(
185 XMLHttpRequestStringSnapshot& aSnapshot)
186 : mBuffer(aSnapshot.mBuffer), mLock(aSnapshot.mBuffer->mMutex) {}
188 XMLHttpRequestStringSnapshotReaderHelper::
189 ~XMLHttpRequestStringSnapshotReaderHelper() = default;
191 const char16_t* XMLHttpRequestStringSnapshotReaderHelper::Buffer() const {
192 return mBuffer->UnsafeData().BeginReading();
195 uint32_t XMLHttpRequestStringSnapshotReaderHelper::Length() const {
196 return mBuffer->UnsafeLength();
199 } // namespace mozilla::dom