/src/mozilla-central/dom/xhr/XMLHttpRequestString.cpp
Line | Count | Source (jump to first uncovered line) |
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/. */ |
6 | | |
7 | | #include "XMLHttpRequestString.h" |
8 | | #include "nsISupportsImpl.h" |
9 | | #include "mozilla/dom/DOMString.h" |
10 | | |
11 | | namespace mozilla { |
12 | | namespace dom { |
13 | | |
14 | | class XMLHttpRequestStringBuffer final |
15 | | { |
16 | | friend class XMLHttpRequestStringWriterHelper; |
17 | | friend class XMLHttpRequestStringSnapshotReaderHelper; |
18 | | |
19 | | public: |
20 | | NS_INLINE_DECL_THREADSAFE_REFCOUNTING(XMLHttpRequestStringBuffer) |
21 | | NS_DECL_OWNINGTHREAD |
22 | | |
23 | | XMLHttpRequestStringBuffer() |
24 | | : mMutex("XMLHttpRequestStringBuffer::mMutex") |
25 | 0 | { |
26 | 0 | } |
27 | | |
28 | | uint32_t |
29 | | Length() |
30 | 0 | { |
31 | 0 | MutexAutoLock lock(mMutex); |
32 | 0 | return mData.Length(); |
33 | 0 | } |
34 | | |
35 | | uint32_t |
36 | | UnsafeLength() const |
37 | 0 | { |
38 | 0 | return mData.Length(); |
39 | 0 | } |
40 | | |
41 | | mozilla::BulkWriteHandle<char16_t> |
42 | | UnsafeBulkWrite(uint32_t aCapacity, nsresult& aRv) |
43 | 0 | { |
44 | 0 | return mData.BulkWrite(aCapacity, UnsafeLength(), false, aRv); |
45 | 0 | } |
46 | | |
47 | | void |
48 | | Append(const nsAString& aString) |
49 | 0 | { |
50 | 0 | NS_ASSERT_OWNINGTHREAD(XMLHttpRequestStringBuffer); |
51 | 0 |
|
52 | 0 | MutexAutoLock lock(mMutex); |
53 | 0 | mData.Append(aString); |
54 | 0 | } |
55 | | |
56 | | MOZ_MUST_USE bool |
57 | | GetAsString(nsAString& aString) |
58 | 0 | { |
59 | 0 | MutexAutoLock lock(mMutex); |
60 | 0 | return aString.Assign(mData, mozilla::fallible); |
61 | 0 | } |
62 | | |
63 | | size_t |
64 | | SizeOfThis(MallocSizeOf aMallocSizeOf) const |
65 | 0 | { |
66 | 0 | return mData.SizeOfExcludingThisIfUnshared(aMallocSizeOf); |
67 | 0 | } |
68 | | |
69 | | MOZ_MUST_USE bool |
70 | | GetAsString(DOMString& aString, uint32_t aLength) |
71 | 0 | { |
72 | 0 | MutexAutoLock lock(mMutex); |
73 | 0 | MOZ_ASSERT(aLength <= mData.Length()); |
74 | 0 |
|
75 | 0 | // XXX: Bug 1408793 suggests encapsulating the following sequence within |
76 | 0 | // DOMString. |
77 | 0 | nsStringBuffer* buf = nsStringBuffer::FromString(mData); |
78 | 0 | if (buf) { |
79 | 0 | // We have to use SetStringBuffer, because once we release our mutex mData |
80 | 0 | // can get mutated from some other thread while the DOMString is still |
81 | 0 | // alive. |
82 | 0 | aString.SetStringBuffer(buf, aLength); |
83 | 0 | return true; |
84 | 0 | } |
85 | 0 | |
86 | 0 | // We can get here if mData is empty. In that case it won't have an |
87 | 0 | // nsStringBuffer.... |
88 | 0 | MOZ_ASSERT(mData.IsEmpty()); |
89 | 0 | return aString.AsAString().Assign(mData.BeginReading(), aLength, |
90 | 0 | mozilla::fallible); |
91 | 0 | } |
92 | | |
93 | | void |
94 | | CreateSnapshot(XMLHttpRequestStringSnapshot& aSnapshot) |
95 | 0 | { |
96 | 0 | MutexAutoLock lock(mMutex); |
97 | 0 | aSnapshot.Set(this, mData.Length()); |
98 | 0 | } |
99 | | |
100 | | private: |
101 | | ~XMLHttpRequestStringBuffer() |
102 | 0 | {} |
103 | | |
104 | | nsString& UnsafeData() |
105 | 0 | { |
106 | 0 | return mData; |
107 | 0 | } |
108 | | |
109 | | Mutex mMutex; |
110 | | |
111 | | // The following member variable is protected by mutex. |
112 | | nsString mData; |
113 | | }; |
114 | | |
115 | | // --------------------------------------------------------------------------- |
116 | | // XMLHttpRequestString |
117 | | |
118 | | XMLHttpRequestString::XMLHttpRequestString() |
119 | | : mBuffer(new XMLHttpRequestStringBuffer()) |
120 | 0 | { |
121 | 0 | } |
122 | | |
123 | | XMLHttpRequestString::~XMLHttpRequestString() |
124 | 0 | { |
125 | 0 | } |
126 | | |
127 | | void |
128 | | XMLHttpRequestString::Truncate() |
129 | 0 | { |
130 | 0 | mBuffer = new XMLHttpRequestStringBuffer(); |
131 | 0 | } |
132 | | |
133 | | uint32_t |
134 | | XMLHttpRequestString::Length() const |
135 | 0 | { |
136 | 0 | return mBuffer->Length(); |
137 | 0 | } |
138 | | |
139 | | void |
140 | | XMLHttpRequestString::Append(const nsAString& aString) |
141 | 0 | { |
142 | 0 | mBuffer->Append(aString); |
143 | 0 | } |
144 | | |
145 | | bool |
146 | | XMLHttpRequestString::GetAsString(nsAString& aString) const |
147 | 0 | { |
148 | 0 | return mBuffer->GetAsString(aString); |
149 | 0 | } |
150 | | |
151 | | size_t |
152 | | XMLHttpRequestString::SizeOfThis(MallocSizeOf aMallocSizeOf) const |
153 | 0 | { |
154 | 0 | return mBuffer->SizeOfThis(aMallocSizeOf); |
155 | 0 | } |
156 | | |
157 | | bool |
158 | | XMLHttpRequestString::IsEmpty() const |
159 | 0 | { |
160 | 0 | return !mBuffer->Length(); |
161 | 0 | } |
162 | | |
163 | | void |
164 | | XMLHttpRequestString::CreateSnapshot(XMLHttpRequestStringSnapshot& aSnapshot) |
165 | 0 | { |
166 | 0 | mBuffer->CreateSnapshot(aSnapshot); |
167 | 0 | } |
168 | | |
169 | | // --------------------------------------------------------------------------- |
170 | | // XMLHttpRequestStringSnapshot |
171 | | |
172 | | XMLHttpRequestStringSnapshot::XMLHttpRequestStringSnapshot() |
173 | | : mLength(0) |
174 | | , mVoid(false) |
175 | 0 | { |
176 | 0 | } |
177 | | |
178 | | XMLHttpRequestStringSnapshot::~XMLHttpRequestStringSnapshot() |
179 | 0 | { |
180 | 0 | } |
181 | | |
182 | | XMLHttpRequestStringSnapshot& |
183 | | XMLHttpRequestStringSnapshot::operator=(const XMLHttpRequestStringSnapshot& aOther) |
184 | 0 | { |
185 | 0 | mBuffer = aOther.mBuffer; |
186 | 0 | mLength = aOther.mLength; |
187 | 0 | mVoid = aOther.mVoid; |
188 | 0 | return *this; |
189 | 0 | } |
190 | | |
191 | | void |
192 | | XMLHttpRequestStringSnapshot::ResetInternal(bool aIsVoid) |
193 | 0 | { |
194 | 0 | mBuffer = nullptr; |
195 | 0 | mLength = 0; |
196 | 0 | mVoid = aIsVoid; |
197 | 0 | } |
198 | | |
199 | | void |
200 | | XMLHttpRequestStringSnapshot::Set(XMLHttpRequestStringBuffer* aBuffer, |
201 | | uint32_t aLength) |
202 | 0 | { |
203 | 0 | MOZ_ASSERT(aBuffer); |
204 | 0 | MOZ_ASSERT(aLength <= aBuffer->UnsafeLength()); |
205 | 0 |
|
206 | 0 | mBuffer = aBuffer; |
207 | 0 | mLength = aLength; |
208 | 0 | mVoid = false; |
209 | 0 | } |
210 | | |
211 | | bool |
212 | | XMLHttpRequestStringSnapshot::GetAsString(DOMString& aString) const |
213 | 0 | { |
214 | 0 | if (mBuffer) { |
215 | 0 | MOZ_ASSERT(!mVoid); |
216 | 0 | return mBuffer->GetAsString(aString, mLength); |
217 | 0 | } |
218 | 0 |
|
219 | 0 | if (mVoid) { |
220 | 0 | aString.SetNull(); |
221 | 0 | } |
222 | 0 |
|
223 | 0 | return true; |
224 | 0 | } |
225 | | |
226 | | // --------------------------------------------------------------------------- |
227 | | // XMLHttpRequestStringWriterHelper |
228 | | |
229 | | XMLHttpRequestStringWriterHelper::XMLHttpRequestStringWriterHelper(XMLHttpRequestString& aString) |
230 | | : mBuffer(aString.mBuffer) |
231 | | , mLock(aString.mBuffer->mMutex) |
232 | 0 | { |
233 | 0 | } |
234 | | |
235 | | uint32_t |
236 | | XMLHttpRequestStringWriterHelper::Length() const |
237 | 0 | { |
238 | 0 | return mBuffer->UnsafeLength(); |
239 | 0 | } |
240 | | |
241 | | mozilla::BulkWriteHandle<char16_t> |
242 | | XMLHttpRequestStringWriterHelper::BulkWrite(uint32_t aCapacity, nsresult& aRv) |
243 | 0 | { |
244 | 0 | return mBuffer->UnsafeBulkWrite(aCapacity, aRv); |
245 | 0 | } |
246 | | |
247 | | // --------------------------------------------------------------------------- |
248 | | // XMLHttpRequestStringReaderHelper |
249 | | |
250 | | XMLHttpRequestStringSnapshotReaderHelper::XMLHttpRequestStringSnapshotReaderHelper(XMLHttpRequestStringSnapshot& aSnapshot) |
251 | | : mBuffer(aSnapshot.mBuffer) |
252 | | , mLock(aSnapshot.mBuffer->mMutex) |
253 | 0 | { |
254 | 0 | } |
255 | | |
256 | | const char16_t* |
257 | | XMLHttpRequestStringSnapshotReaderHelper::Buffer() const |
258 | 0 | { |
259 | 0 | return mBuffer->UnsafeData().BeginReading(); |
260 | 0 | } |
261 | | |
262 | | uint32_t |
263 | | XMLHttpRequestStringSnapshotReaderHelper::Length() const |
264 | 0 | { |
265 | 0 | return mBuffer->UnsafeLength(); |
266 | 0 | } |
267 | | |
268 | | } // dom namespace |
269 | | } // mozilla namespace |