2016-09-12 10:06:06 +03:00
|
|
|
/* -*- 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 "XMLHttpRequestString.h"
|
|
|
|
#include "nsISupportsImpl.h"
|
2017-01-19 06:20:15 +03:00
|
|
|
#include "mozilla/dom/DOMString.h"
|
2016-09-12 10:06:06 +03:00
|
|
|
|
|
|
|
namespace mozilla {
|
|
|
|
namespace dom {
|
|
|
|
|
|
|
|
class XMLHttpRequestStringBuffer final {
|
|
|
|
friend class XMLHttpRequestStringWriterHelper;
|
2016-09-12 10:06:33 +03:00
|
|
|
friend class XMLHttpRequestStringSnapshotReaderHelper;
|
2016-09-12 10:06:06 +03:00
|
|
|
|
|
|
|
public:
|
2016-09-12 10:06:33 +03:00
|
|
|
NS_INLINE_DECL_THREADSAFE_REFCOUNTING(XMLHttpRequestStringBuffer)
|
|
|
|
NS_DECL_OWNINGTHREAD
|
|
|
|
|
|
|
|
XMLHttpRequestStringBuffer() : mMutex("XMLHttpRequestStringBuffer::mMutex") {}
|
2016-09-12 10:06:06 +03:00
|
|
|
|
|
|
|
uint32_t Length() {
|
2016-09-12 10:06:33 +03:00
|
|
|
MutexAutoLock lock(mMutex);
|
|
|
|
return mData.Length();
|
|
|
|
}
|
|
|
|
|
2016-09-12 10:06:06 +03:00
|
|
|
uint32_t UnsafeLength() const { return mData.Length(); }
|
|
|
|
|
2018-08-30 17:24:58 +03:00
|
|
|
mozilla::BulkWriteHandle<char16_t> UnsafeBulkWrite(uint32_t aCapacity,
|
|
|
|
nsresult& aRv) {
|
|
|
|
return mData.BulkWrite(aCapacity, UnsafeLength(), false, aRv);
|
|
|
|
}
|
|
|
|
|
2016-09-12 10:06:06 +03:00
|
|
|
void Append(const nsAString& aString) {
|
2016-09-12 10:06:33 +03:00
|
|
|
NS_ASSERT_OWNINGTHREAD(XMLHttpRequestStringBuffer);
|
|
|
|
|
|
|
|
MutexAutoLock lock(mMutex);
|
2016-09-12 10:06:06 +03:00
|
|
|
mData.Append(aString);
|
|
|
|
}
|
|
|
|
|
|
|
|
MOZ_MUST_USE bool GetAsString(nsAString& aString) {
|
2016-09-12 10:06:33 +03:00
|
|
|
MutexAutoLock lock(mMutex);
|
2016-09-16 01:09:17 +03:00
|
|
|
return aString.Assign(mData, mozilla::fallible);
|
2016-09-12 10:06:06 +03:00
|
|
|
}
|
|
|
|
|
|
|
|
size_t SizeOfThis(MallocSizeOf aMallocSizeOf) const {
|
|
|
|
return mData.SizeOfExcludingThisIfUnshared(aMallocSizeOf);
|
|
|
|
}
|
|
|
|
|
2017-01-19 06:20:15 +03:00
|
|
|
MOZ_MUST_USE bool GetAsString(DOMString& aString, uint32_t aLength) {
|
2016-09-12 10:06:33 +03:00
|
|
|
MutexAutoLock lock(mMutex);
|
|
|
|
MOZ_ASSERT(aLength <= mData.Length());
|
2017-10-12 02:52:17 +03:00
|
|
|
|
|
|
|
// XXX: Bug 1408793 suggests encapsulating the following sequence within
|
|
|
|
// DOMString.
|
2017-01-19 06:20:15 +03:00
|
|
|
nsStringBuffer* buf = nsStringBuffer::FromString(mData);
|
|
|
|
if (buf) {
|
2017-12-22 21:02:51 +03:00
|
|
|
// 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.
|
|
|
|
aString.SetStringBuffer(buf, aLength);
|
2017-01-19 06:20:15 +03:00
|
|
|
return true;
|
|
|
|
}
|
|
|
|
|
|
|
|
// We can get here if mData is empty. In that case it won't have an
|
|
|
|
// nsStringBuffer....
|
|
|
|
MOZ_ASSERT(mData.IsEmpty());
|
|
|
|
return aString.AsAString().Assign(mData.BeginReading(), aLength,
|
|
|
|
mozilla::fallible);
|
2016-09-12 10:06:33 +03:00
|
|
|
}
|
|
|
|
|
|
|
|
void CreateSnapshot(XMLHttpRequestStringSnapshot& aSnapshot) {
|
|
|
|
MutexAutoLock lock(mMutex);
|
|
|
|
aSnapshot.Set(this, mData.Length());
|
|
|
|
}
|
|
|
|
|
2016-09-12 10:06:06 +03:00
|
|
|
private:
|
|
|
|
~XMLHttpRequestStringBuffer() {}
|
|
|
|
|
2016-09-12 10:06:33 +03:00
|
|
|
nsString& UnsafeData() { return mData; }
|
2016-09-12 10:06:06 +03:00
|
|
|
|
2016-09-12 10:06:33 +03:00
|
|
|
Mutex mMutex;
|
|
|
|
|
|
|
|
// The following member variable is protected by mutex.
|
2016-09-12 10:06:06 +03:00
|
|
|
nsString mData;
|
|
|
|
};
|
|
|
|
|
|
|
|
// ---------------------------------------------------------------------------
|
|
|
|
// XMLHttpRequestString
|
|
|
|
|
|
|
|
XMLHttpRequestString::XMLHttpRequestString()
|
|
|
|
: mBuffer(new XMLHttpRequestStringBuffer()) {}
|
|
|
|
|
|
|
|
XMLHttpRequestString::~XMLHttpRequestString() {}
|
|
|
|
|
|
|
|
void XMLHttpRequestString::Truncate() {
|
|
|
|
mBuffer = new XMLHttpRequestStringBuffer();
|
|
|
|
}
|
|
|
|
|
|
|
|
uint32_t XMLHttpRequestString::Length() const { return mBuffer->Length(); }
|
|
|
|
|
|
|
|
void XMLHttpRequestString::Append(const nsAString& aString) {
|
|
|
|
mBuffer->Append(aString);
|
|
|
|
}
|
|
|
|
|
|
|
|
bool XMLHttpRequestString::GetAsString(nsAString& aString) const {
|
|
|
|
return mBuffer->GetAsString(aString);
|
|
|
|
}
|
|
|
|
|
|
|
|
size_t XMLHttpRequestString::SizeOfThis(MallocSizeOf aMallocSizeOf) const {
|
|
|
|
return mBuffer->SizeOfThis(aMallocSizeOf);
|
|
|
|
}
|
|
|
|
|
|
|
|
bool XMLHttpRequestString::IsEmpty() const { return !mBuffer->Length(); }
|
|
|
|
|
2016-09-12 10:06:33 +03:00
|
|
|
void XMLHttpRequestString::CreateSnapshot(
|
|
|
|
XMLHttpRequestStringSnapshot& aSnapshot) {
|
|
|
|
mBuffer->CreateSnapshot(aSnapshot);
|
|
|
|
}
|
|
|
|
|
|
|
|
// ---------------------------------------------------------------------------
|
|
|
|
// XMLHttpRequestStringSnapshot
|
|
|
|
|
|
|
|
XMLHttpRequestStringSnapshot::XMLHttpRequestStringSnapshot()
|
|
|
|
: mLength(0), mVoid(false) {}
|
|
|
|
|
|
|
|
XMLHttpRequestStringSnapshot::~XMLHttpRequestStringSnapshot() {}
|
|
|
|
|
|
|
|
XMLHttpRequestStringSnapshot& XMLHttpRequestStringSnapshot::operator=(
|
|
|
|
const XMLHttpRequestStringSnapshot& aOther) {
|
|
|
|
mBuffer = aOther.mBuffer;
|
|
|
|
mLength = aOther.mLength;
|
|
|
|
mVoid = aOther.mVoid;
|
|
|
|
return *this;
|
|
|
|
}
|
|
|
|
|
|
|
|
void XMLHttpRequestStringSnapshot::ResetInternal(bool aIsVoid) {
|
|
|
|
mBuffer = nullptr;
|
|
|
|
mLength = 0;
|
|
|
|
mVoid = aIsVoid;
|
|
|
|
}
|
|
|
|
|
|
|
|
void XMLHttpRequestStringSnapshot::Set(XMLHttpRequestStringBuffer* aBuffer,
|
|
|
|
uint32_t aLength) {
|
|
|
|
MOZ_ASSERT(aBuffer);
|
|
|
|
MOZ_ASSERT(aLength <= aBuffer->UnsafeLength());
|
|
|
|
|
|
|
|
mBuffer = aBuffer;
|
|
|
|
mLength = aLength;
|
|
|
|
mVoid = false;
|
|
|
|
}
|
|
|
|
|
2017-01-19 06:20:15 +03:00
|
|
|
bool XMLHttpRequestStringSnapshot::GetAsString(DOMString& aString) const {
|
2016-09-12 10:06:33 +03:00
|
|
|
if (mBuffer) {
|
|
|
|
MOZ_ASSERT(!mVoid);
|
2016-09-16 01:09:17 +03:00
|
|
|
return mBuffer->GetAsString(aString, mLength);
|
2016-09-12 10:06:33 +03:00
|
|
|
}
|
|
|
|
|
|
|
|
if (mVoid) {
|
2017-01-19 06:20:15 +03:00
|
|
|
aString.SetNull();
|
2016-09-12 10:06:33 +03:00
|
|
|
}
|
2016-09-16 01:09:17 +03:00
|
|
|
|
|
|
|
return true;
|
2016-09-12 10:06:33 +03:00
|
|
|
}
|
|
|
|
|
2016-09-12 10:06:06 +03:00
|
|
|
// ---------------------------------------------------------------------------
|
|
|
|
// XMLHttpRequestStringWriterHelper
|
|
|
|
|
|
|
|
XMLHttpRequestStringWriterHelper::XMLHttpRequestStringWriterHelper(
|
|
|
|
XMLHttpRequestString& aString)
|
2016-09-12 10:06:33 +03:00
|
|
|
: mBuffer(aString.mBuffer), mLock(aString.mBuffer->mMutex) {}
|
2016-09-12 10:06:06 +03:00
|
|
|
|
2018-08-30 17:24:58 +03:00
|
|
|
uint32_t XMLHttpRequestStringWriterHelper::Length() const {
|
|
|
|
return mBuffer->UnsafeLength();
|
2018-08-29 12:16:24 +03:00
|
|
|
}
|
|
|
|
|
2018-08-30 17:24:58 +03:00
|
|
|
mozilla::BulkWriteHandle<char16_t> XMLHttpRequestStringWriterHelper::BulkWrite(
|
|
|
|
uint32_t aCapacity, nsresult& aRv) {
|
|
|
|
return mBuffer->UnsafeBulkWrite(aCapacity, aRv);
|
2016-09-12 10:06:33 +03:00
|
|
|
}
|
|
|
|
|
|
|
|
// ---------------------------------------------------------------------------
|
|
|
|
// XMLHttpRequestStringReaderHelper
|
|
|
|
|
|
|
|
XMLHttpRequestStringSnapshotReaderHelper::
|
|
|
|
XMLHttpRequestStringSnapshotReaderHelper(
|
|
|
|
XMLHttpRequestStringSnapshot& aSnapshot)
|
|
|
|
: mBuffer(aSnapshot.mBuffer), mLock(aSnapshot.mBuffer->mMutex) {}
|
|
|
|
|
|
|
|
const char16_t* XMLHttpRequestStringSnapshotReaderHelper::Buffer() const {
|
|
|
|
return mBuffer->UnsafeData().BeginReading();
|
|
|
|
}
|
|
|
|
|
|
|
|
uint32_t XMLHttpRequestStringSnapshotReaderHelper::Length() const {
|
|
|
|
return mBuffer->UnsafeLength();
|
2016-09-12 10:06:06 +03:00
|
|
|
}
|
|
|
|
|
|
|
|
} // namespace dom
|
|
|
|
} // namespace mozilla
|