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"
|
2016-09-12 10:06:33 +03:00
|
|
|
#include "mozilla/Mutex.h"
|
2016-09-12 10:06:06 +03:00
|
|
|
#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();
|
|
|
|
}
|
|
|
|
|
|
|
|
uint32_t
|
|
|
|
UnsafeLength() const
|
2016-09-12 10:06:06 +03:00
|
|
|
{
|
|
|
|
return mData.Length();
|
|
|
|
}
|
|
|
|
|
|
|
|
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);
|
|
|
|
}
|
|
|
|
|
2016-09-16 01:09:17 +03:00
|
|
|
MOZ_MUST_USE bool
|
2016-09-12 10:06:06 +03:00
|
|
|
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);
|
|
|
|
}
|
|
|
|
|
2016-09-16 01:09:17 +03:00
|
|
|
MOZ_MUST_USE bool
|
2017-01-19 06:20:15 +03:00
|
|
|
GetAsString(DOMString& aString, uint32_t aLength)
|
2016-09-12 10:06:33 +03:00
|
|
|
{
|
|
|
|
MutexAutoLock lock(mMutex);
|
|
|
|
MOZ_ASSERT(aLength <= mData.Length());
|
2017-01-19 06:20:15 +03:00
|
|
|
nsStringBuffer* buf = nsStringBuffer::FromString(mData);
|
|
|
|
if (buf) {
|
|
|
|
// We have to use SetEphemeralStringBuffer, because once we release our
|
|
|
|
// mutex mData can get mutated from some other thread while the DOMString
|
|
|
|
// is still alive.
|
|
|
|
aString.SetEphemeralStringBuffer(buf, aLength);
|
|
|
|
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()
|
2016-09-12 10:06:06 +03:00
|
|
|
{
|
|
|
|
return mData;
|
|
|
|
}
|
|
|
|
|
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);
|
|
|
|
}
|
|
|
|
|
2016-09-16 01:09:17 +03:00
|
|
|
bool
|
2016-09-12 10:06:06 +03:00
|
|
|
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;
|
|
|
|
}
|
|
|
|
|
2016-09-16 01:09:17 +03:00
|
|
|
bool
|
2017-01-19 06:20:15 +03:00
|
|
|
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)
|
|
|
|
: mBuffer(aString.mBuffer)
|
2016-09-12 10:06:33 +03:00
|
|
|
, mLock(aString.mBuffer->mMutex)
|
2016-09-12 10:06:06 +03:00
|
|
|
{
|
|
|
|
}
|
|
|
|
|
|
|
|
bool
|
|
|
|
XMLHttpRequestStringWriterHelper::AddCapacity(int32_t aCapacity)
|
|
|
|
{
|
2016-09-12 10:06:33 +03:00
|
|
|
return mBuffer->UnsafeData().SetCapacity(mBuffer->UnsafeLength() + aCapacity, fallible);
|
2016-09-12 10:06:06 +03:00
|
|
|
}
|
|
|
|
|
|
|
|
char16_t*
|
|
|
|
XMLHttpRequestStringWriterHelper::EndOfExistingData()
|
|
|
|
{
|
2016-09-12 10:06:33 +03:00
|
|
|
return mBuffer->UnsafeData().BeginWriting() + mBuffer->UnsafeLength();
|
2016-09-12 10:06:06 +03:00
|
|
|
}
|
|
|
|
|
|
|
|
void
|
|
|
|
XMLHttpRequestStringWriterHelper::AddLength(int32_t aLength)
|
|
|
|
{
|
2016-09-12 10:06:33 +03:00
|
|
|
mBuffer->UnsafeData().SetLength(mBuffer->UnsafeLength() + aLength);
|
|
|
|
}
|
|
|
|
|
|
|
|
// ---------------------------------------------------------------------------
|
|
|
|
// 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
|
|
|
}
|
|
|
|
|
|
|
|
} // dom namespace
|
|
|
|
} // mozilla namespace
|