Coverage Report

Created: 2018-09-25 14:53

/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