Bug 827823 - patch 1 - CC in DOMFile class, r=ehsan

This commit is contained in:
Andrea Marchesini 2014-06-26 20:46:34 -07:00
Родитель 7a4ab2f151
Коммит 6197f631af
22 изменённых файлов: 425 добавлений и 359 удалений

Просмотреть файл

@ -39,6 +39,18 @@ class nsIFile;
class nsIInputStream;
class nsIClassInfo;
#define PIDOMFILEIMPL_IID \
{ 0x218ee173, 0xf44f, 0x4d30, \
{ 0xab, 0x0c, 0xd6, 0x66, 0xea, 0xc2, 0x84, 0x47 } }
class PIDOMFileImpl : public nsISupports
{
public:
NS_DECLARE_STATIC_IID_ACCESSOR(PIDOMFILEIMPL_IID)
};
NS_DEFINE_STATIC_IID_ACCESSOR(PIDOMFileImpl, PIDOMFILEIMPL_IID)
namespace mozilla {
namespace dom {
@ -48,67 +60,19 @@ class FileInfo;
class DOMFileImpl;
// XXX bug 827823 will get rid of DOMFileBase
class DOMFileBase : public nsIDOMFile
, public nsIXHRSendable
, public nsIMutable
, public nsIJSNativeInitializer
class DOMFile MOZ_FINAL : public nsIDOMFile
, public nsIXHRSendable
, public nsIMutable
, public nsIJSNativeInitializer
{
// XXX bug 827823 will get rid of DOMFileCC
friend class DOMFileCC;
public:
NS_DECL_NSIDOMBLOB
NS_DECL_NSIDOMFILE
NS_DECL_NSIXHRSENDABLE
NS_DECL_NSIMUTABLE
DOMFileBase(DOMFileImpl* aImpl)
: mImpl(aImpl)
{
MOZ_ASSERT(mImpl);
}
DOMFileImpl* Impl() const
{
return mImpl;
}
const nsTArray<nsCOMPtr<nsIDOMBlob>>* GetSubBlobs() const;
bool IsSizeUnknown() const;
bool IsDateUnknown() const;
bool IsFile() const;
void SetLazyData(const nsAString& aName, const nsAString& aContentType,
uint64_t aLength, uint64_t aLastModifiedDate);
already_AddRefed<nsIDOMBlob>
CreateSlice(uint64_t aStart, uint64_t aLength,
const nsAString& aContentType);
// nsIJSNativeInitializer
NS_IMETHOD Initialize(nsISupports* aOwner, JSContext* aCx, JSObject* aObj,
const JS::CallArgs& aArgs) MOZ_OVERRIDE;
protected:
virtual ~DOMFileBase() {};
private:
// The member is the real backend implementation of this DOMFile/DOMBlob.
// It's thread-safe and not CC-able and it's the only element that is moved
// between threads.
const nsRefPtr<DOMFileImpl> mImpl;
};
// XXX bug 827823 - this class should be MOZ_FINAL
class DOMFile : public DOMFileBase
{
public:
// XXX bug 827823 will make this class CC and not thread-safe
NS_DECL_THREADSAFE_ISUPPORTS
NS_DECL_CYCLE_COLLECTING_ISUPPORTS
NS_DECL_CYCLE_COLLECTION_CLASS_AMBIGUOUS(DOMFile, nsIDOMFile)
static already_AddRefed<DOMFile>
Create(const nsAString& aName, const nsAString& aContentType,
@ -159,37 +123,54 @@ public:
const nsAString& aContentType);
explicit DOMFile(DOMFileImpl* aImpl)
: DOMFileBase(aImpl)
{}
protected:
virtual ~DOMFile() {};
};
// XXX bug 827823 will get rid of this class
class DOMFileCC MOZ_FINAL : public DOMFileBase
{
public:
DOMFileCC(DOMFileImpl* aImpl)
: DOMFileBase(aImpl)
{}
NS_DECL_CYCLE_COLLECTING_ISUPPORTS
NS_DECL_CYCLE_COLLECTION_CLASS_AMBIGUOUS(DOMFileCC, nsIDOMFile)
protected:
virtual ~DOMFileCC() {};
};
// This is the virtual class for any DOMFile backend. It must be nsISupports
// because this class must be ref-counted and it has to work with IPC.
class DOMFileImpl : public nsISupports
{
public:
DOMFileImpl()
: mImpl(aImpl)
{
MOZ_ASSERT(mImpl);
}
DOMFileImpl* Impl() const
{
return mImpl;
}
const nsTArray<nsRefPtr<DOMFileImpl>>* GetSubBlobImpls() const;
bool IsSizeUnknown() const;
bool IsDateUnknown() const;
bool IsFile() const;
void SetLazyData(const nsAString& aName, const nsAString& aContentType,
uint64_t aLength, uint64_t aLastModifiedDate);
already_AddRefed<nsIDOMBlob>
CreateSlice(uint64_t aStart, uint64_t aLength,
const nsAString& aContentType);
// nsIJSNativeInitializer
NS_IMETHOD Initialize(nsISupports* aOwner, JSContext* aCx, JSObject* aObj,
const JS::CallArgs& aArgs) MOZ_OVERRIDE;
private:
~DOMFile() {};
// The member is the real backend implementation of this DOMFile/DOMBlob.
// It's thread-safe and not CC-able and it's the only element that is moved
// between threads.
// Note: we should not store any other state in this class!
const nsRefPtr<DOMFileImpl> mImpl;
};
// This is the abstract class for any DOMFile backend. It must be nsISupports
// because this class must be ref-counted and it has to work with IPC.
class DOMFileImpl : public PIDOMFileImpl
{
public:
NS_DECL_THREADSAFE_ISUPPORTS
DOMFileImpl() {}
virtual nsresult GetName(nsAString& aName) = 0;
virtual nsresult GetPath(nsAString& aName) = 0;
@ -215,8 +196,8 @@ public:
CreateSlice(uint64_t aStart, uint64_t aLength,
const nsAString& aContentType) = 0;
virtual const nsTArray<nsCOMPtr<nsIDOMBlob>>*
GetSubBlobs() const = 0;
virtual const nsTArray<nsRefPtr<DOMFileImpl>>*
GetSubBlobImpls() const = 0;
virtual nsresult GetInternalStream(nsIInputStream** aStream) = 0;
@ -259,6 +240,11 @@ public:
virtual void Unlink() = 0;
virtual void Traverse(nsCycleCollectionTraversalCallback &aCb) = 0;
virtual bool IsCCed() const
{
return false;
}
protected:
virtual ~DOMFileImpl() {}
};
@ -266,8 +252,6 @@ protected:
class DOMFileImplBase : public DOMFileImpl
{
public:
NS_DECL_THREADSAFE_ISUPPORTS
DOMFileImplBase(const nsAString& aName, const nsAString& aContentType,
uint64_t aLength, uint64_t aLastModifiedDate)
: mIsFile(true)
@ -344,8 +328,8 @@ public:
CreateSlice(uint64_t aStart, uint64_t aLength,
const nsAString& aContentType) MOZ_OVERRIDE;
virtual const nsTArray<nsCOMPtr<nsIDOMBlob>>*
GetSubBlobs() const MOZ_OVERRIDE
virtual const nsTArray<nsRefPtr<DOMFileImpl>>*
GetSubBlobImpls() const MOZ_OVERRIDE
{
return nullptr;
}
@ -462,6 +446,8 @@ protected:
class DOMFileImplMemory MOZ_FINAL : public DOMFileImplBase
{
public:
NS_DECL_ISUPPORTS_INHERITED
DOMFileImplMemory(void* aMemoryBuffer, uint64_t aLength,
const nsAString& aName,
const nsAString& aContentType,
@ -556,6 +542,8 @@ private:
class DOMFileImplTemporaryFileBlob MOZ_FINAL : public DOMFileImplBase
{
public:
NS_DECL_ISUPPORTS_INHERITED
DOMFileImplTemporaryFileBlob(PRFileDesc* aFD, uint64_t aStartPos,
uint64_t aLength, const nsAString& aContentType)
: DOMFileImplBase(aContentType, aLength)
@ -593,6 +581,8 @@ private:
class DOMFileImplFile MOZ_FINAL : public DOMFileImplBase
{
public:
NS_DECL_ISUPPORTS_INHERITED
// Create as a file
explicit DOMFileImplFile(nsIFile* aFile)
: DOMFileImplBase(EmptyString(), EmptyString(), UINT64_MAX, UINT64_MAX)

Просмотреть файл

@ -21,6 +21,8 @@
using namespace mozilla;
using namespace mozilla::dom;
NS_IMPL_ISUPPORTS_INHERITED0(DOMMultipartFileImpl, DOMFileImpl)
nsresult
DOMMultipartFileImpl::GetSize(uint64_t* aLength)
{
@ -39,11 +41,11 @@ DOMMultipartFileImpl::GetInternalStream(nsIInputStream** aStream)
NS_ENSURE_TRUE(stream, NS_ERROR_FAILURE);
uint32_t i;
for (i = 0; i < mBlobs.Length(); i++) {
for (i = 0; i < mBlobImpls.Length(); i++) {
nsCOMPtr<nsIInputStream> scratchStream;
nsIDOMBlob* blob = mBlobs.ElementAt(i).get();
DOMFileImpl* blobImpl = mBlobImpls.ElementAt(i).get();
rv = blob->GetInternalStream(getter_AddRefs(scratchStream));
rv = blobImpl->GetInternalStream(getter_AddRefs(scratchStream));
NS_ENSURE_SUCCESS(rv, rv);
rv = stream->AppendStream(scratchStream);
@ -58,27 +60,27 @@ DOMMultipartFileImpl::CreateSlice(uint64_t aStart, uint64_t aLength,
const nsAString& aContentType)
{
// If we clamped to nothing we create an empty blob
nsTArray<nsCOMPtr<nsIDOMBlob> > blobs;
nsTArray<nsRefPtr<DOMFileImpl>> blobImpls;
uint64_t length = aLength;
uint64_t skipStart = aStart;
// Prune the list of blobs if we can
uint32_t i;
for (i = 0; length && skipStart && i < mBlobs.Length(); i++) {
nsIDOMBlob* blob = mBlobs[i].get();
for (i = 0; length && skipStart && i < mBlobImpls.Length(); i++) {
DOMFileImpl* blobImpl = mBlobImpls[i].get();
uint64_t l;
nsresult rv = blob->GetSize(&l);
nsresult rv = blobImpl->GetSize(&l);
NS_ENSURE_SUCCESS(rv, nullptr);
if (skipStart < l) {
uint64_t upperBound = std::min<uint64_t>(l - skipStart, length);
nsCOMPtr<nsIDOMBlob> firstBlob;
rv = blob->Slice(skipStart, skipStart + upperBound,
aContentType, 3,
getter_AddRefs(firstBlob));
rv = blobImpl->Slice(skipStart, skipStart + upperBound,
aContentType, 3,
getter_AddRefs(firstBlob));
NS_ENSURE_SUCCESS(rv, nullptr);
// Avoid wrapping a single blob inside an DOMMultipartFileImpl
@ -86,7 +88,7 @@ DOMMultipartFileImpl::CreateSlice(uint64_t aStart, uint64_t aLength,
return firstBlob.forget();
}
blobs.AppendElement(firstBlob);
blobImpls.AppendElement(static_cast<DOMFile*>(firstBlob.get())->Impl());
length -= upperBound;
i++;
break;
@ -95,29 +97,29 @@ DOMMultipartFileImpl::CreateSlice(uint64_t aStart, uint64_t aLength,
}
// Now append enough blobs until we're done
for (; length && i < mBlobs.Length(); i++) {
nsIDOMBlob* blob = mBlobs[i].get();
for (; length && i < mBlobImpls.Length(); i++) {
DOMFileImpl* blobImpl = mBlobImpls[i].get();
uint64_t l;
nsresult rv = blob->GetSize(&l);
nsresult rv = blobImpl->GetSize(&l);
NS_ENSURE_SUCCESS(rv, nullptr);
if (length < l) {
nsCOMPtr<nsIDOMBlob> lastBlob;
rv = blob->Slice(0, length, aContentType, 3,
getter_AddRefs(lastBlob));
rv = blobImpl->Slice(0, length, aContentType, 3,
getter_AddRefs(lastBlob));
NS_ENSURE_SUCCESS(rv, nullptr);
blobs.AppendElement(lastBlob);
blobImpls.AppendElement(static_cast<DOMFile*>(lastBlob.get())->Impl());
} else {
blobs.AppendElement(blob);
blobImpls.AppendElement(blobImpl);
}
length -= std::min<uint64_t>(l, length);
}
// we can create our blob now
nsCOMPtr<nsIDOMBlob> blob =
new DOMFile(new DOMMultipartFileImpl(blobs, aContentType));
new DOMFile(new DOMMultipartFileImpl(blobImpls, aContentType));
return blob.forget();
}
@ -225,13 +227,16 @@ DOMMultipartFileImpl::ParseBlobArrayArgument(JSContext* aCx, JS::Value& aValue,
JS::Rooted<JSObject*> obj(aCx, &element.toObject());
nsCOMPtr<nsIDOMBlob> blob = aUnwrapFunc(aCx, obj);
if (blob) {
nsRefPtr<DOMFileImpl> blobImpl =
static_cast<DOMFile*>(blob.get())->Impl();
// Flatten so that multipart blobs will never nest
DOMFile* file = static_cast<DOMFile*>(static_cast<nsIDOMBlob*>(blob));
const nsTArray<nsCOMPtr<nsIDOMBlob>>* subBlobs = file->GetSubBlobs();
if (subBlobs) {
blobSet.AppendBlobs(*subBlobs);
const nsTArray<nsRefPtr<DOMFileImpl>>* subBlobImpls =
blobImpl->GetSubBlobImpls();
if (subBlobImpls) {
blobSet.AppendBlobImpls(*subBlobImpls);
} else {
blobSet.AppendBlob(blob);
blobSet.AppendBlobImpl(blobImpl);
}
continue;
}
@ -257,7 +262,7 @@ DOMMultipartFileImpl::ParseBlobArrayArgument(JSContext* aCx, JS::Value& aValue,
NS_ENSURE_SUCCESS(rv, rv);
}
mBlobs = blobSet.GetBlobs();
mBlobImpls = blobSet.GetBlobImpls();
SetLengthAndModifiedDate();
@ -272,18 +277,12 @@ DOMMultipartFileImpl::SetLengthAndModifiedDate()
uint64_t totalLength = 0;
for (uint32_t index = 0, count = mBlobs.Length(); index < count; index++) {
nsCOMPtr<nsIDOMBlob>& blob = mBlobs[index];
for (uint32_t index = 0, count = mBlobImpls.Length(); index < count; index++) {
nsRefPtr<DOMFileImpl>& blob = mBlobImpls[index];
#ifdef DEBUG
{
// XXX This is only safe so long as all blob implementations in our tree
// inherit nsDOMFileBase.
const auto* blobBase = static_cast<DOMFile*>(blob.get());
MOZ_ASSERT(!blobBase->IsSizeUnknown());
MOZ_ASSERT(!blobBase->IsDateUnknown());
}
MOZ_ASSERT(!blob->IsSizeUnknown());
MOZ_ASSERT(!blob->IsDateUnknown());
#endif
uint64_t subBlobLength;
@ -303,17 +302,16 @@ DOMMultipartFileImpl::SetLengthAndModifiedDate()
nsresult
DOMMultipartFileImpl::GetMozFullPathInternal(nsAString& aFilename)
{
if (!mIsFromNsiFile || mBlobs.Length() == 0) {
if (!mIsFromNsiFile || mBlobImpls.Length() == 0) {
return DOMFileImplBase::GetMozFullPathInternal(aFilename);
}
nsIDOMBlob* blob = mBlobs.ElementAt(0).get();
if (!blob) {
DOMFileImpl* blobImpl = mBlobImpls.ElementAt(0).get();
if (!blobImpl) {
return DOMFileImplBase::GetMozFullPathInternal(aFilename);
}
DOMFile* domFile = static_cast<DOMFile*>(blob);
return domFile->GetMozFullPathInternal(aFilename);
return blobImpl->GetMozFullPathInternal(aFilename);
}
nsresult
@ -412,8 +410,8 @@ DOMMultipartFileImpl::InitChromeFile(JSContext* aCx,
}
BlobSet blobSet;
blobSet.AppendBlob(blob);
mBlobs = blobSet.GetBlobs();
blobSet.AppendBlobImpl(static_cast<DOMFile*>(blob.get())->Impl());
mBlobImpls = blobSet.GetBlobImpls();
SetLengthAndModifiedDate();
@ -496,21 +494,21 @@ BlobSet::AppendString(JSString* aString, bool nativeEOL, JSContext* aCx)
}
nsresult
BlobSet::AppendBlob(nsIDOMBlob* aBlob)
BlobSet::AppendBlobImpl(DOMFileImpl* aBlobImpl)
{
NS_ENSURE_ARG_POINTER(aBlob);
NS_ENSURE_ARG_POINTER(aBlobImpl);
Flush();
mBlobs.AppendElement(aBlob);
mBlobImpls.AppendElement(aBlobImpl);
return NS_OK;
}
nsresult
BlobSet::AppendBlobs(const nsTArray<nsCOMPtr<nsIDOMBlob> >& aBlob)
BlobSet::AppendBlobImpls(const nsTArray<nsRefPtr<DOMFileImpl>>& aBlobImpls)
{
Flush();
mBlobs.AppendElements(aBlob);
mBlobImpls.AppendElements(aBlobImpls);
return NS_OK;
}

Просмотреть файл

@ -20,25 +20,29 @@
{ 0x94, 0x96, 0xdf, 0x5d, 0x6f, 0xcd, 0xd7, 0x8f } }
#define NS_DOMMULTIPARTFILE_CONTRACTID "@mozilla.org/dom/multipart-file;1"
class DOMMultipartFileImpl MOZ_FINAL : public mozilla::dom::DOMFileImplBase
using namespace mozilla::dom;
class DOMMultipartFileImpl MOZ_FINAL : public DOMFileImplBase
{
public:
NS_DECL_ISUPPORTS_INHERITED
// Create as a file
DOMMultipartFileImpl(const nsTArray<nsCOMPtr<nsIDOMBlob>>& aBlobs,
DOMMultipartFileImpl(const nsTArray<nsRefPtr<DOMFileImpl>>& aBlobImpls,
const nsAString& aName,
const nsAString& aContentType)
: mozilla::dom::DOMFileImplBase(aName, aContentType, UINT64_MAX),
mBlobs(aBlobs),
: DOMFileImplBase(aName, aContentType, UINT64_MAX),
mBlobImpls(aBlobImpls),
mIsFromNsiFile(false)
{
SetLengthAndModifiedDate();
}
// Create as a blob
DOMMultipartFileImpl(const nsTArray<nsCOMPtr<nsIDOMBlob>>& aBlobs,
DOMMultipartFileImpl(const nsTArray<nsRefPtr<DOMFileImpl>>& aBlobImpls,
const nsAString& aContentType)
: mozilla::dom::DOMFileImplBase(aContentType, UINT64_MAX),
mBlobs(aBlobs),
: DOMFileImplBase(aContentType, UINT64_MAX),
mBlobImpls(aBlobImpls),
mIsFromNsiFile(false)
{
SetLengthAndModifiedDate();
@ -46,14 +50,14 @@ public:
// Create as a file to be later initialized
explicit DOMMultipartFileImpl(const nsAString& aName)
: mozilla::dom::DOMFileImplBase(aName, EmptyString(), UINT64_MAX),
: DOMFileImplBase(aName, EmptyString(), UINT64_MAX),
mIsFromNsiFile(false)
{
}
// Create as a blob to be later initialized
DOMMultipartFileImpl()
: mozilla::dom::DOMFileImplBase(EmptyString(), UINT64_MAX),
: DOMFileImplBase(EmptyString(), UINT64_MAX),
mIsFromNsiFile(false)
{
}
@ -96,9 +100,9 @@ public:
return NewFile(EmptyString(), aNewObject);
}
virtual const nsTArray<nsCOMPtr<nsIDOMBlob>>* GetSubBlobs() const MOZ_OVERRIDE
virtual const nsTArray<nsRefPtr<DOMFileImpl>>* GetSubBlobImpls() const MOZ_OVERRIDE
{
return &mBlobs;
return &mBlobImpls;
}
virtual nsresult GetMozFullPathInternal(nsAString& aFullPath) MOZ_OVERRIDE;
@ -109,7 +113,7 @@ protected:
void SetLengthAndModifiedDate();
nsTArray<nsCOMPtr<nsIDOMBlob> > mBlobs;
nsTArray<nsRefPtr<DOMFileImpl>> mBlobImpls;
bool mIsFromNsiFile;
};
@ -126,17 +130,17 @@ public:
nsresult AppendVoidPtr(const void* aData, uint32_t aLength);
nsresult AppendString(JSString* aString, bool nativeEOL, JSContext* aCx);
nsresult AppendBlob(nsIDOMBlob* aBlob);
nsresult AppendBlobImpl(DOMFileImpl* aBlobImpl);
nsresult AppendArrayBuffer(JSObject* aBuffer);
nsresult AppendBlobs(const nsTArray<nsCOMPtr<nsIDOMBlob> >& aBlob);
nsresult AppendBlobImpls(const nsTArray<nsRefPtr<DOMFileImpl>>& aBlobImpls);
nsTArray<nsCOMPtr<nsIDOMBlob> >& GetBlobs() { Flush(); return mBlobs; }
nsTArray<nsRefPtr<DOMFileImpl>>& GetBlobImpls() { Flush(); return mBlobImpls; }
already_AddRefed<nsIDOMBlob>
GetBlobInternal(const nsACString& aContentType)
{
nsCOMPtr<nsIDOMBlob> blob = new mozilla::dom::DOMFile(
new DOMMultipartFileImpl(GetBlobs(), NS_ConvertASCIItoUTF16(aContentType)));
nsCOMPtr<nsIDOMBlob> blob = new DOMFile(
new DOMMultipartFileImpl(GetBlobImpls(), NS_ConvertASCIItoUTF16(aContentType)));
return blob.forget();
}
@ -174,16 +178,16 @@ protected:
// If we have some data, create a blob for it
// and put it on the stack
nsCOMPtr<nsIDOMBlob> blob =
mozilla::dom::DOMFile::CreateMemoryFile(mData, mDataLen, EmptyString());
mBlobs.AppendElement(blob);
nsRefPtr<DOMFileImpl> blobImpl =
new DOMFileImplMemory(mData, mDataLen, EmptyString());
mBlobImpls.AppendElement(blobImpl);
mData = nullptr; // The nsDOMMemoryFile takes ownership of the buffer
mDataLen = 0;
mDataBufferLen = 0;
}
}
nsTArray<nsCOMPtr<nsIDOMBlob> > mBlobs;
nsTArray<nsRefPtr<DOMFileImpl>> mBlobImpls;
void* mData;
uint64_t mDataLen;
uint64_t mDataBufferLen;

Просмотреть файл

@ -125,7 +125,19 @@ nsresult DataOwnerAdapter::Create(DataOwner* aDataOwner,
////////////////////////////////////////////////////////////////////////////
// mozilla::dom::DOMFile implementation
NS_INTERFACE_MAP_BEGIN(DOMFile)
NS_IMPL_CYCLE_COLLECTION_CLASS(DOMFile)
NS_IMPL_CYCLE_COLLECTION_UNLINK_BEGIN(DOMFile)
MOZ_ASSERT(tmp->mImpl);
tmp->mImpl->Unlink();
NS_IMPL_CYCLE_COLLECTION_UNLINK_END
NS_IMPL_CYCLE_COLLECTION_TRAVERSE_BEGIN(DOMFile)
MOZ_ASSERT(tmp->mImpl);
tmp->mImpl->Traverse(cb);
NS_IMPL_CYCLE_COLLECTION_TRAVERSE_END
NS_INTERFACE_MAP_BEGIN_CYCLE_COLLECTION(DOMFile)
// This class should not receive any nsIRemoteBlob QI!
MOZ_ASSERT(!aIID.Equals(NS_GET_IID(nsIRemoteBlob)));
@ -139,8 +151,8 @@ NS_INTERFACE_MAP_BEGIN(DOMFile)
NS_DOM_INTERFACE_MAP_ENTRY_CLASSINFO_CONDITIONAL(Blob, !(IsFile()))
NS_INTERFACE_MAP_END
NS_IMPL_ADDREF(DOMFile)
NS_IMPL_RELEASE(DOMFile)
NS_IMPL_CYCLE_COLLECTING_ADDREF(DOMFile)
NS_IMPL_CYCLE_COLLECTING_RELEASE(DOMFile)
/* static */ already_AddRefed<DOMFile>
DOMFile::Create(const nsAString& aName, const nsAString& aContentType,
@ -251,99 +263,96 @@ DOMFile::CreateFromFile(nsIFile* aFile, const nsAString& aName,
return file.forget();
}
////////////////////////////////////////////////////////////////////////////
// mozilla::dom::DOMFileBase implementation
const nsTArray<nsCOMPtr<nsIDOMBlob>>*
DOMFileBase::GetSubBlobs() const
const nsTArray<nsRefPtr<DOMFileImpl>>*
DOMFile::GetSubBlobImpls() const
{
return mImpl->GetSubBlobs();
return mImpl->GetSubBlobImpls();
}
bool
DOMFileBase::IsSizeUnknown() const
DOMFile::IsSizeUnknown() const
{
return mImpl->IsSizeUnknown();
}
bool
DOMFileBase::IsDateUnknown() const
DOMFile::IsDateUnknown() const
{
return mImpl->IsDateUnknown();
}
bool
DOMFileBase::IsFile() const
DOMFile::IsFile() const
{
return mImpl->IsFile();
}
void
DOMFileBase::SetLazyData(const nsAString& aName, const nsAString& aContentType,
uint64_t aLength, uint64_t aLastModifiedDate)
DOMFile::SetLazyData(const nsAString& aName, const nsAString& aContentType,
uint64_t aLength, uint64_t aLastModifiedDate)
{
return mImpl->SetLazyData(aName, aContentType, aLength, aLastModifiedDate);
}
already_AddRefed<nsIDOMBlob>
DOMFileBase::CreateSlice(uint64_t aStart, uint64_t aLength,
const nsAString& aContentType)
DOMFile::CreateSlice(uint64_t aStart, uint64_t aLength,
const nsAString& aContentType)
{
return mImpl->CreateSlice(aStart, aLength, aContentType);
}
NS_IMETHODIMP
DOMFileBase::Initialize(nsISupports* aOwner, JSContext* aCx, JSObject* aObj,
const JS::CallArgs& aArgs)
DOMFile::Initialize(nsISupports* aOwner, JSContext* aCx, JSObject* aObj,
const JS::CallArgs& aArgs)
{
return mImpl->Initialize(aOwner, aCx, aObj, aArgs);
}
NS_IMETHODIMP
DOMFileBase::GetName(nsAString& aFileName)
DOMFile::GetName(nsAString& aFileName)
{
return mImpl->GetName(aFileName);
}
NS_IMETHODIMP
DOMFileBase::GetPath(nsAString& aPath)
DOMFile::GetPath(nsAString& aPath)
{
return mImpl->GetPath(aPath);
}
NS_IMETHODIMP
DOMFileBase::GetLastModifiedDate(JSContext* aCx,
JS::MutableHandle<JS::Value> aDate)
DOMFile::GetLastModifiedDate(JSContext* aCx,
JS::MutableHandle<JS::Value> aDate)
{
return mImpl->GetLastModifiedDate(aCx, aDate);
}
NS_IMETHODIMP
DOMFileBase::GetMozFullPath(nsAString &aFileName)
DOMFile::GetMozFullPath(nsAString &aFileName)
{
return mImpl->GetMozFullPath(aFileName);
}
NS_IMETHODIMP
DOMFileBase::GetMozFullPathInternal(nsAString &aFileName)
DOMFile::GetMozFullPathInternal(nsAString &aFileName)
{
return mImpl->GetMozFullPathInternal(aFileName);
}
NS_IMETHODIMP
DOMFileBase::GetSize(uint64_t* aSize)
DOMFile::GetSize(uint64_t* aSize)
{
return mImpl->GetSize(aSize);
}
NS_IMETHODIMP
DOMFileBase::GetType(nsAString &aType)
DOMFile::GetType(nsAString &aType)
{
return mImpl->GetType(aType);
}
NS_IMETHODIMP
DOMFileBase::GetMozLastModifiedDate(uint64_t* aDate)
DOMFile::GetMozLastModifiedDate(uint64_t* aDate)
{
return mImpl->GetMozLastModifiedDate(aDate);
}
@ -386,67 +395,67 @@ ParseSize(int64_t aSize, int64_t& aStart, int64_t& aEnd)
}
NS_IMETHODIMP
DOMFileBase::Slice(int64_t aStart, int64_t aEnd,
const nsAString& aContentType, uint8_t aArgc,
nsIDOMBlob **aBlob)
DOMFile::Slice(int64_t aStart, int64_t aEnd,
const nsAString& aContentType, uint8_t aArgc,
nsIDOMBlob **aBlob)
{
MOZ_ASSERT(mImpl);
return mImpl->Slice(aStart, aEnd, aContentType, aArgc, aBlob);
}
NS_IMETHODIMP
DOMFileBase::GetInternalStream(nsIInputStream** aStream)
DOMFile::GetInternalStream(nsIInputStream** aStream)
{
return mImpl->GetInternalStream(aStream);
}
NS_IMETHODIMP
DOMFileBase::GetInternalUrl(nsIPrincipal* aPrincipal, nsAString& aURL)
DOMFile::GetInternalUrl(nsIPrincipal* aPrincipal, nsAString& aURL)
{
return mImpl->GetInternalUrl(aPrincipal, aURL);
}
NS_IMETHODIMP_(int64_t)
DOMFileBase::GetFileId()
DOMFile::GetFileId()
{
return mImpl->GetFileId();
}
NS_IMETHODIMP_(void)
DOMFileBase::AddFileInfo(indexedDB::FileInfo* aFileInfo)
DOMFile::AddFileInfo(indexedDB::FileInfo* aFileInfo)
{
mImpl->AddFileInfo(aFileInfo);
}
indexedDB::FileInfo*
DOMFileBase::GetFileInfo(indexedDB::FileManager* aFileManager)
DOMFile::GetFileInfo(indexedDB::FileManager* aFileManager)
{
return mImpl->GetFileInfo(aFileManager);
}
NS_IMETHODIMP
DOMFileBase::GetSendInfo(nsIInputStream** aBody,
uint64_t* aContentLength,
nsACString& aContentType,
nsACString& aCharset)
DOMFile::GetSendInfo(nsIInputStream** aBody,
uint64_t* aContentLength,
nsACString& aContentType,
nsACString& aCharset)
{
return mImpl->GetSendInfo(aBody, aContentLength, aContentType, aCharset);
}
NS_IMETHODIMP
DOMFileBase::GetMutable(bool* aMutable)
DOMFile::GetMutable(bool* aMutable)
{
return mImpl->GetMutable(aMutable);
}
NS_IMETHODIMP
DOMFileBase::SetMutable(bool aMutable)
DOMFile::SetMutable(bool aMutable)
{
return mImpl->SetMutable(aMutable);
}
NS_IMETHODIMP_(bool)
DOMFileBase::IsMemoryFile()
DOMFile::IsMemoryFile()
{
return mImpl->IsMemoryFile();
}
@ -481,7 +490,14 @@ DOMFileImpl::Slice(int64_t aStart, int64_t aEnd,
}
////////////////////////////////////////////////////////////////////////////
// DOMFileImplBase implementation
// DOMFileImpl implementation
NS_IMPL_ISUPPORTS(DOMFileImpl, PIDOMFileImpl)
////////////////////////////////////////////////////////////////////////////
// DOMFileImplFile implementation
NS_IMPL_ISUPPORTS_INHERITED0(DOMFileImplFile, DOMFileImpl)
nsresult
DOMFileImplBase::GetName(nsAString& aName)
@ -727,35 +743,6 @@ DOMFileImplBase::SetMutable(bool aMutable)
return rv;
}
NS_IMPL_ISUPPORTS0(DOMFileImplBase)
////////////////////////////////////////////////////////////////////////////
// DOMFileCC implementation
NS_IMPL_CYCLE_COLLECTION_CLASS(DOMFileCC)
NS_IMPL_CYCLE_COLLECTION_UNLINK_BEGIN(DOMFileCC)
tmp->mImpl->Unlink();
NS_IMPL_CYCLE_COLLECTION_UNLINK_END
NS_IMPL_CYCLE_COLLECTION_TRAVERSE_BEGIN(DOMFileCC)
tmp->mImpl->Traverse(cb);
NS_IMPL_CYCLE_COLLECTION_TRAVERSE_END
NS_INTERFACE_MAP_BEGIN_CYCLE_COLLECTION(DOMFileCC)
NS_INTERFACE_MAP_ENTRY_AMBIGUOUS(nsISupports, nsIDOMFile)
NS_INTERFACE_MAP_ENTRY(nsIDOMBlob)
NS_INTERFACE_MAP_ENTRY_CONDITIONAL(nsIDOMFile, IsFile())
NS_INTERFACE_MAP_ENTRY(nsIXHRSendable)
NS_INTERFACE_MAP_ENTRY(nsIMutable)
NS_INTERFACE_MAP_ENTRY(nsIJSNativeInitializer)
NS_DOM_INTERFACE_MAP_ENTRY_CLASSINFO_CONDITIONAL(File, IsFile())
NS_DOM_INTERFACE_MAP_ENTRY_CLASSINFO_CONDITIONAL(Blob, !(IsFile()))
NS_INTERFACE_MAP_END
NS_IMPL_CYCLE_COLLECTING_ADDREF(DOMFileCC)
NS_IMPL_CYCLE_COLLECTING_RELEASE(DOMFileCC)
////////////////////////////////////////////////////////////////////////////
// DOMFileImplFile implementation
@ -890,6 +877,8 @@ DOMFileImplFile::SetPath(const nsAString& aPath)
////////////////////////////////////////////////////////////////////////////
// DOMFileImplMemory implementation
NS_IMPL_ISUPPORTS_INHERITED0(DOMFileImplMemory, DOMFileImpl)
already_AddRefed<nsIDOMBlob>
DOMFileImplMemory::CreateSlice(uint64_t aStart, uint64_t aLength,
const nsAString& aContentType)
@ -1013,6 +1002,8 @@ DOMFileImplMemory::DataOwner::EnsureMemoryReporterRegistered()
////////////////////////////////////////////////////////////////////////////
// DOMFileImplTemporaryFileBlob implementation
NS_IMPL_ISUPPORTS_INHERITED0(DOMFileImplTemporaryFileBlob, DOMFileImpl)
already_AddRefed<nsIDOMBlob>
DOMFileImplTemporaryFileBlob::CreateSlice(uint64_t aStart, uint64_t aLength,
const nsAString& aContentType)

Просмотреть файл

@ -10,12 +10,14 @@
#include "nsClassHashtable.h"
#include "nsNetUtil.h"
#include "nsIPrincipal.h"
#include "nsIDOMFile.h"
#include "nsDOMFile.h"
#include "nsIDOMMediaStream.h"
#include "mozilla/dom/MediaSource.h"
#include "nsIMemoryReporter.h"
#include "mozilla/Preferences.h"
using mozilla::dom::DOMFileImpl;
// -----------------------------------------------------------------------
// Hash table
struct DataInfo
@ -478,8 +480,9 @@ nsHostObjectProtocolHandler::NewChannel(nsIURI* uri, nsIChannel* *result)
if (!info) {
return NS_ERROR_DOM_BAD_URI;
}
nsCOMPtr<nsIDOMBlob> blob = do_QueryInterface(info->mObject);
if (!blob) {
nsCOMPtr<PIDOMFileImpl> blobImpl = do_QueryInterface(info->mObject);
if (!blobImpl) {
return NS_ERROR_DOM_BAD_URI;
}
@ -492,6 +495,7 @@ nsHostObjectProtocolHandler::NewChannel(nsIURI* uri, nsIChannel* *result)
}
#endif
DOMFileImpl* blob = static_cast<DOMFileImpl*>(blobImpl.get());
nsCOMPtr<nsIInputStream> stream;
nsresult rv = blob->GetInternalStream(getter_AddRefs(stream));
NS_ENSURE_SUCCESS(rv, rv);
@ -508,10 +512,9 @@ nsHostObjectProtocolHandler::NewChannel(nsIURI* uri, nsIChannel* *result)
rv = blob->GetType(type);
NS_ENSURE_SUCCESS(rv, rv);
nsCOMPtr<nsIDOMFile> file = do_QueryInterface(info->mObject);
if (file) {
if (blob->IsFile()) {
nsString filename;
rv = file->GetName(filename);
rv = blob->GetName(filename);
NS_ENSURE_SUCCESS(rv, rv);
channel->SetContentDispositionFilename(filename);
}
@ -574,11 +577,12 @@ NS_GetStreamForBlobURI(nsIURI* aURI, nsIInputStream** aStream)
*aStream = nullptr;
nsCOMPtr<nsIDOMBlob> blob = do_QueryInterface(GetDataObject(aURI));
if (!blob) {
nsCOMPtr<PIDOMFileImpl> blobImpl = do_QueryInterface(GetDataObject(aURI));
if (!blobImpl) {
return NS_ERROR_DOM_BAD_URI;
}
DOMFileImpl* blob = static_cast<DOMFileImpl*>(blobImpl.get());
return blob->GetInternalStream(aStream);
}

Просмотреть файл

@ -84,7 +84,7 @@ ArchiveZipItem::File(ArchiveReader* aArchiveReader)
return nullptr;
}
return new DOMFileCC(
return new DOMFile(
new ArchiveZipFileImpl(filename,
NS_ConvertUTF8toUTF16(GetType()),
StrToInt32(mCentralStruct.orglen),

Просмотреть файл

@ -402,8 +402,10 @@ ArchiveZipFileImpl::CreateSlice(uint64_t aStart,
const nsAString& aContentType)
{
nsCOMPtr<nsIDOMBlob> t =
new DOMFileCC(new ArchiveZipFileImpl(mFilename, mContentType,
aStart, mLength, mCentral,
mArchiveReader));
new DOMFile(new ArchiveZipFileImpl(mFilename, mContentType,
aStart, mLength, mCentral,
mArchiveReader));
return t.forget();
}
NS_IMPL_ISUPPORTS_INHERITED0(ArchiveZipFileImpl, DOMFileImpl)

Просмотреть файл

@ -23,6 +23,8 @@ BEGIN_ARCHIVEREADER_NAMESPACE
class ArchiveZipFileImpl : public DOMFileImplBase
{
public:
NS_DECL_ISUPPORTS_INHERITED
ArchiveZipFileImpl(const nsAString& aName,
const nsAString& aContentType,
uint64_t aLength,
@ -63,6 +65,11 @@ public:
virtual void Unlink() MOZ_OVERRIDE;
virtual void Traverse(nsCycleCollectionTraversalCallback &aCb) MOZ_OVERRIDE;
virtual bool IsCCed() const MOZ_OVERRIDE
{
return true;
}
protected:
virtual already_AddRefed<nsIDOMBlob> CreateSlice(uint64_t aStart,
uint64_t aLength,

Просмотреть файл

@ -6,7 +6,7 @@
#include "URL.h"
#include "nsGlobalWindow.h"
#include "nsIDOMFile.h"
#include "nsDOMFile.h"
#include "DOMMediaStream.h"
#include "mozilla/dom/MediaSource.h"
#include "mozilla/dom/URLBinding.h"
@ -116,7 +116,10 @@ URL::CreateObjectURL(const GlobalObject& aGlobal,
nsString& aResult,
ErrorResult& aError)
{
CreateObjectURLInternal(aGlobal, aBlob,
DOMFile* blob = static_cast<DOMFile*>(aBlob);
MOZ_ASSERT(blob);
CreateObjectURLInternal(aGlobal, blob->Impl(),
NS_LITERAL_CSTRING(BLOBURI_SCHEME), aOptions, aResult,
aError);
}

Просмотреть файл

@ -7840,7 +7840,22 @@ PostMessageReadStructuredClone(JSContext* cx,
uint32_t data,
void* closure)
{
if (tag == SCTAG_DOM_BLOB || tag == SCTAG_DOM_FILELIST) {
if (tag == SCTAG_DOM_BLOB) {
NS_ASSERTION(!data, "Data should be empty");
// What we get back from the reader is a DOMFileImpl.
// From that we create a new DOMFile.
nsISupports* supports;
if (JS_ReadBytes(reader, &supports, sizeof(supports))) {
nsCOMPtr<nsIDOMBlob> file = new DOMFile(static_cast<DOMFileImpl*>(supports));
JS::Rooted<JS::Value> val(cx);
if (NS_SUCCEEDED(nsContentUtils::WrapNative(cx, file, &val))) {
return val.toObjectOrNull();
}
}
}
if (tag == SCTAG_DOM_FILELIST) {
NS_ASSERTION(!data, "Data should be empty");
nsISupports* supports;
@ -7879,8 +7894,11 @@ PostMessageWriteStructuredClone(JSContext* cx,
nsISupports* supports = wrappedNative->Native();
nsCOMPtr<nsIDOMBlob> blob = do_QueryInterface(supports);
if (blob && scInfo->subsumes)
if (blob && scInfo->subsumes) {
scTag = SCTAG_DOM_BLOB;
DOMFile* file = static_cast<DOMFile*>(blob.get());
supports = file->Impl();
}
nsCOMPtr<nsIDOMFileList> list = do_QueryInterface(supports);
if (list && scInfo->subsumes)

Просмотреть файл

@ -2396,11 +2396,11 @@ private:
class WriteFileEvent : public nsRunnable
{
public:
WriteFileEvent(nsIDOMBlob* aBlob,
WriteFileEvent(DOMFileImpl* aBlobImpl,
DeviceStorageFile *aFile,
already_AddRefed<DOMRequest> aRequest,
int32_t aRequestType)
: mBlob(aBlob)
: mBlobImpl(aBlobImpl)
, mFile(aFile)
, mRequest(aRequest)
, mRequestType(aRequestType)
@ -2417,7 +2417,7 @@ public:
MOZ_ASSERT(!NS_IsMainThread());
nsCOMPtr<nsIInputStream> stream;
mBlob->GetInternalStream(getter_AddRefs(stream));
mBlobImpl->GetInternalStream(getter_AddRefs(stream));
bool check = false;
mFile->mFile->Exists(&check);
@ -2461,7 +2461,7 @@ public:
}
private:
nsCOMPtr<nsIDOMBlob> mBlob;
nsRefPtr<DOMFileImpl> mBlobImpl;
nsRefPtr<DeviceStorageFile> mFile;
nsRefPtr<DOMRequest> mRequest;
int32_t mRequestType;
@ -2887,7 +2887,10 @@ public:
->SendPDeviceStorageRequestConstructor(child, params);
return NS_OK;
}
r = new WriteFileEvent(mBlob, mFile, mRequest.forget(), mRequestType);
DOMFile* blob = static_cast<DOMFile*>(mBlob.get());
r = new WriteFileEvent(blob->Impl(), mFile, mRequest.forget(),
mRequestType);
break;
}
@ -2929,7 +2932,10 @@ public:
->SendPDeviceStorageRequestConstructor(child, params);
return NS_OK;
}
r = new WriteFileEvent(mBlob, mFile, mRequest.forget(), mRequestType);
DOMFile* blob = static_cast<DOMFile*>(mBlob.get());
r = new WriteFileEvent(blob->Impl(), mFile, mRequest.forget(),
mRequestType);
break;
}

Просмотреть файл

@ -15,6 +15,8 @@ namespace dom {
using indexedDB::IndexedDatabaseManager;
NS_IMPL_ISUPPORTS_INHERITED0(FileImpl, DOMFileImpl)
// Create as a file
FileImpl::FileImpl(const nsAString& aName, const nsAString& aContentType,
uint64_t aLength, nsIFile* aFile, FileHandle* aFileHandle)
@ -99,7 +101,7 @@ FileImpl::CreateSlice(uint64_t aStart, uint64_t aLength,
NS_ASSERTION(NS_IsMainThread(), "Wrong thread!");
nsCOMPtr<nsIDOMBlob> t =
new DOMFileCC(new FileImpl(this, aStart, aLength, aContentType));
new DOMFile(new FileImpl(this, aStart, aLength, aContentType));
return t.forget();
}

Просмотреть файл

@ -24,6 +24,8 @@ class FileImpl : public DOMFileImplBase
friend class File;
public:
NS_DECL_ISUPPORTS_INHERITED
// Create as a file
FileImpl(const nsAString& aName, const nsAString& aContentType,
uint64_t aLength, nsIFile* aFile, FileHandle* aFileHandle);
@ -41,6 +43,11 @@ public:
virtual void Unlink() MOZ_OVERRIDE;
virtual void Traverse(nsCycleCollectionTraversalCallback &aCb) MOZ_OVERRIDE;
virtual bool IsCCed() const MOZ_OVERRIDE
{
return true;
}
protected:
// Create slice
FileImpl(const FileImpl* aOther, uint64_t aStart, uint64_t aLength,

Просмотреть файл

@ -106,7 +106,7 @@ already_AddRefed<nsIDOMFile>
MutableFile::CreateFileObject(FileHandle* aFileHandle, uint32_t aFileSize)
{
nsCOMPtr<nsIDOMFile> file =
new DOMFileCC(new FileImpl(mName, mType, aFileSize, mFile, aFileHandle));
new DOMFile(new FileImpl(mName, mType, aFileSize, mFile, aFileHandle));
return file.forget();
}

Просмотреть файл

@ -119,7 +119,8 @@ FileSystemResponseValue
CreateFileTask::GetSuccessRequestResult() const
{
MOZ_ASSERT(NS_IsMainThread(), "Only call on main thread!");
BlobParent* actor = GetBlobParent(mTargetFile);
nsRefPtr<DOMFile> file = new DOMFile(mTargetFileImpl);
BlobParent* actor = GetBlobParent(file);
if (!actor) {
return FileSystemErrorResponse(NS_ERROR_DOM_FILESYSTEM_UNKNOWN_ERR);
}
@ -135,7 +136,7 @@ CreateFileTask::SetSuccessRequestResult(const FileSystemResponseValue& aValue)
FileSystemFileResponse r = aValue;
BlobChild* actor = static_cast<BlobChild*>(r.blobChild());
nsCOMPtr<nsIDOMBlob> blob = actor->GetBlob();
mTargetFile = do_QueryInterface(blob);
mTargetFileImpl = static_cast<DOMFile*>(blob.get())->Impl();
}
nsresult
@ -252,7 +253,7 @@ CreateFileTask::Work()
return NS_ERROR_FAILURE;
}
mTargetFile = DOMFile::CreateFromFile(file);
mTargetFileImpl = new DOMFileImplFile(file);
return NS_OK;
}
@ -271,7 +272,7 @@ CreateFileTask::Work()
return NS_ERROR_DOM_FILESYSTEM_UNKNOWN_ERR;
}
mTargetFile = DOMFile::CreateFromFile(file);
mTargetFileImpl = new DOMFileImplFile(file);
return NS_OK;
}
@ -292,7 +293,8 @@ CreateFileTask::HandlerCallback()
return;
}
mPromise->MaybeResolve(mTargetFile);
nsCOMPtr<nsIDOMFile> file = new DOMFile(mTargetFileImpl);
mPromise->MaybeResolve(file);
mPromise = nullptr;
}

Просмотреть файл

@ -16,6 +16,7 @@ class nsIInputStream;
namespace mozilla {
namespace dom {
class DOMFileImpl;
class Promise;
class CreateFileTask MOZ_FINAL
@ -67,7 +68,10 @@ private:
nsCOMPtr<nsIInputStream> mBlobStream;
InfallibleTArray<uint8_t> mArrayData;
bool mReplace;
nsCOMPtr<nsIDOMFile> mTargetFile;
// This cannot be a DOMFile bacause this object is created on a different
// thread and DOMFile is not thread-safe. Let's use the DOMFileImpl instead.
nsRefPtr<DOMFileImpl> mTargetFileImpl;
};
} // namespace dom

Просмотреть файл

@ -77,7 +77,9 @@ GetFileOrDirectoryTask::GetSuccessRequestResult() const
if (mIsDirectory) {
return FileSystemDirectoryResponse(mTargetRealPath);
}
BlobParent* actor = GetBlobParent(mTargetFile);
nsRefPtr<DOMFile> file = new DOMFile(mTargetFileImpl);
BlobParent* actor = GetBlobParent(file);
if (!actor) {
return FileSystemErrorResponse(NS_ERROR_DOM_FILESYSTEM_UNKNOWN_ERR);
}
@ -95,7 +97,7 @@ GetFileOrDirectoryTask::SetSuccessRequestResult(const FileSystemResponseValue& a
FileSystemFileResponse r = aValue;
BlobChild* actor = static_cast<BlobChild*>(r.blobChild());
nsCOMPtr<nsIDOMBlob> blob = actor->GetBlob();
mTargetFile = do_QueryInterface(blob);
mTargetFileImpl = static_cast<DOMFile*>(blob.get())->Impl();
mIsDirectory = false;
break;
}
@ -180,7 +182,7 @@ GetFileOrDirectoryTask::Work()
return NS_ERROR_DOM_SECURITY_ERR;
}
mTargetFile = DOMFile::CreateFromFile(file);
mTargetFileImpl = new DOMFileImplFile(file);
return NS_OK;
}
@ -209,7 +211,8 @@ GetFileOrDirectoryTask::HandlerCallback()
return;
}
mPromise->MaybeResolve(mTargetFile);
nsCOMPtr<nsIDOMFile> file = new DOMFile(mTargetFileImpl);
mPromise->MaybeResolve(file);
mPromise = nullptr;
}

Просмотреть файл

@ -13,6 +13,8 @@
namespace mozilla {
namespace dom {
class DOMFileImpl;
class GetFileOrDirectoryTask MOZ_FINAL
: public FileSystemTaskBase
{
@ -54,7 +56,10 @@ private:
nsString mTargetRealPath;
// Whether we get a directory.
bool mIsDirectory;
nsCOMPtr<nsIDOMFile> mTargetFile;
// This cannot be a DOMFile bacause this object is created on a different
// thread and DOMFile is not thread-safe. Let's use the DOMFileImpl instead.
nsRefPtr<DOMFileImpl> mTargetFileImpl;
};
} // namespace dom

Просмотреть файл

@ -139,7 +139,7 @@ already_AddRefed<nsIDOMFile>
IDBMutableFile::CreateFileObject(mozilla::dom::FileHandle* aFileHandle,
uint32_t aFileSize)
{
nsCOMPtr<nsIDOMFile> file = new DOMFileCC(
nsCOMPtr<nsIDOMFile> file = new DOMFile(
new FileImpl(mName, mType, aFileSize, mFile, aFileHandle, mFileInfo));
return file.forget();

Просмотреть файл

@ -870,7 +870,7 @@ class BlobChild::RemoteBlob::SliceHelper MOZ_FINAL
{
mozilla::Monitor mMonitor;
BlobChild* mActor;
nsCOMPtr<nsIDOMBlob> mSlice;
nsRefPtr<DOMFileImpl> mSlice;
uint64_t mStart;
uint64_t mLength;
nsString mContentType;
@ -888,14 +888,13 @@ public:
MOZ_ASSERT(aActor);
}
nsresult
DOMFileImpl*
GetSlice(uint64_t aStart,
uint64_t aLength,
const nsAString& aContentType,
nsIDOMBlob** aSlice)
ErrorResult& aRv)
{
// This may be called on any thread.
MOZ_ASSERT(aSlice);
MOZ_ASSERT(mActor);
MOZ_ASSERT(!mSlice);
MOZ_ASSERT(!mDone);
@ -909,10 +908,15 @@ public:
}
else {
nsCOMPtr<nsIThread> mainThread = do_GetMainThread();
NS_ENSURE_TRUE(mainThread, NS_ERROR_FAILURE);
if (!mainThread) {
aRv.Throw(NS_ERROR_FAILURE);
return nullptr;
}
nsresult rv = mainThread->Dispatch(this, NS_DISPATCH_NORMAL);
NS_ENSURE_SUCCESS(rv, rv);
aRv = mainThread->Dispatch(this, NS_DISPATCH_NORMAL);
if (aRv.Failed()) {
return nullptr;
}
{
MonitorAutoLock lock(mMonitor);
@ -926,11 +930,11 @@ public:
MOZ_ASSERT(mDone);
if (!mSlice) {
return NS_ERROR_UNEXPECTED;
aRv.Throw(NS_ERROR_UNEXPECTED);
return nullptr;
}
mSlice.forget(aSlice);
return NS_OK;
return mSlice;
}
NS_IMETHOD
@ -973,7 +977,8 @@ private:
otherSideParams.optionalInputStreamParams() = mozilla::void_t();
if (mActor->Manager()->SendPBlobConstructor(newActor, otherSideParams)) {
mSlice = newActor->GetBlob();
nsCOMPtr<nsIDOMBlob> blob = newActor->GetBlob();
mSlice = static_cast<DOMFile*>(blob.get())->Impl();
}
mActor = nullptr;
@ -993,7 +998,7 @@ private:
* BlobChild::RemoteBlob Implementation
******************************************************************************/
NS_IMPL_ISUPPORTS_INHERITED(BlobChild::RemoteBlob, DOMFileImplBase, nsIRemoteBlob)
NS_IMPL_ISUPPORTS_INHERITED(BlobChild::RemoteBlob, DOMFileImpl, nsIRemoteBlob)
already_AddRefed<nsIDOMBlob>
BlobChild::
@ -1007,12 +1012,15 @@ RemoteBlob::CreateSlice(uint64_t aStart,
nsRefPtr<SliceHelper> helper = new SliceHelper(mActor);
nsCOMPtr<nsIDOMBlob> slice;
nsresult rv =
helper->GetSlice(aStart, aLength, aContentType, getter_AddRefs(slice));
NS_ENSURE_SUCCESS(rv, nullptr);
ErrorResult rv;
nsRefPtr<DOMFileImpl> slice = helper->GetSlice(aStart, aLength,
aContentType, rv);
if (rv.Failed()) {
return nullptr;
}
return slice.forget();
nsRefPtr<DOMFile> file = new DOMFile(slice);
return file.forget();
}
nsresult
@ -1568,7 +1576,7 @@ class BlobParent::RemoteBlob::SliceHelper MOZ_FINAL
{
mozilla::Monitor mMonitor;
BlobParent* mActor;
nsCOMPtr<nsIDOMBlob> mSlice;
nsRefPtr<DOMFileImpl> mSlice;
uint64_t mStart;
uint64_t mLength;
nsString mContentType;
@ -1586,14 +1594,13 @@ public:
MOZ_ASSERT(aActor);
}
nsresult
DOMFileImpl*
GetSlice(uint64_t aStart,
uint64_t aLength,
const nsAString& aContentType,
nsIDOMBlob** aSlice)
ErrorResult& aRv)
{
// This may be called on any thread.
MOZ_ASSERT(aSlice);
MOZ_ASSERT(mActor);
MOZ_ASSERT(!mSlice);
MOZ_ASSERT(!mDone);
@ -1607,10 +1614,15 @@ public:
}
else {
nsCOMPtr<nsIThread> mainThread = do_GetMainThread();
NS_ENSURE_TRUE(mainThread, NS_ERROR_FAILURE);
if (!mainThread) {
aRv.Throw(NS_ERROR_FAILURE);
return nullptr;
}
nsresult rv = mainThread->Dispatch(this, NS_DISPATCH_NORMAL);
NS_ENSURE_SUCCESS(rv, rv);
aRv = mainThread->Dispatch(this, NS_DISPATCH_NORMAL);
if (aRv.Failed()) {
return nullptr;
}
{
MonitorAutoLock lock(mMonitor);
@ -1624,11 +1636,11 @@ public:
MOZ_ASSERT(mDone);
if (!mSlice) {
return NS_ERROR_UNEXPECTED;
aRv.Throw(NS_ERROR_UNEXPECTED);
return nullptr;
}
mSlice.forget(aSlice);
return NS_OK;
return mSlice;
}
NS_IMETHOD
@ -1673,7 +1685,8 @@ private:
ChildBlobConstructorParams otherSideParams = slicedParams;
if (mActor->Manager()->SendPBlobConstructor(newActor, otherSideParams)) {
mSlice = newActor->GetBlob();
nsCOMPtr<nsIDOMBlob> blob =newActor->GetBlob();
mSlice = static_cast<DOMFile*>(blob.get())->Impl();
}
mActor = nullptr;
@ -1693,8 +1706,7 @@ private:
* BlobChild::RemoteBlob Implementation
******************************************************************************/
NS_IMPL_ISUPPORTS_INHERITED(BlobParent::RemoteBlob, DOMFileImplBase,
nsIRemoteBlob)
NS_IMPL_ISUPPORTS_INHERITED(BlobParent::RemoteBlob, DOMFileImpl, nsIRemoteBlob)
already_AddRefed<nsIDOMBlob>
BlobParent::
@ -1708,12 +1720,15 @@ RemoteBlob::CreateSlice(uint64_t aStart,
nsRefPtr<SliceHelper> helper = new SliceHelper(mActor);
nsCOMPtr<nsIDOMBlob> slice;
nsresult rv =
helper->GetSlice(aStart, aLength, aContentType, getter_AddRefs(slice));
NS_ENSURE_SUCCESS(rv, nullptr);
ErrorResult rv;
nsRefPtr<DOMFileImpl> slice = helper->GetSlice(aStart, aLength,
aContentType, rv);
if (rv.Failed()) {
return nullptr;
}
return slice.forget();
nsRefPtr<DOMFile> file = new DOMFile(slice);
return file.forget();
}
nsresult

Просмотреть файл

@ -5,8 +5,8 @@
#include "URL.h"
#include "nsDOMFile.h"
#include "nsIDocument.h"
#include "nsIDOMFile.h"
#include "nsIIOService.h"
#include "nsPIDOMWindow.h"
@ -67,18 +67,18 @@ private:
class CreateURLRunnable : public WorkerMainThreadRunnable
{
private:
nsIDOMBlob* mBlob;
DOMFileImpl* mBlobImpl;
nsString& mURL;
public:
CreateURLRunnable(WorkerPrivate* aWorkerPrivate, nsIDOMBlob* aBlob,
CreateURLRunnable(WorkerPrivate* aWorkerPrivate, DOMFileImpl* aBlobImpl,
const mozilla::dom::objectURLOptions& aOptions,
nsString& aURL)
: WorkerMainThreadRunnable(aWorkerPrivate),
mBlob(aBlob),
mBlobImpl(aBlobImpl),
mURL(aURL)
{
MOZ_ASSERT(aBlob);
MOZ_ASSERT(aBlobImpl);
}
bool
@ -106,7 +106,7 @@ public:
nsCString url;
nsresult rv = nsHostObjectProtocolHandler::AddDataEntry(
NS_LITERAL_CSTRING(BLOBURI_SCHEME),
mBlob, principal, url);
mBlobImpl, principal, url);
if (NS_FAILED(rv)) {
NS_WARNING("Failed to add data entry for the blob!");
@ -857,8 +857,10 @@ URL::CreateObjectURL(const GlobalObject& aGlobal, JSObject* aBlob,
return;
}
DOMFile* domBlob = static_cast<DOMFile*>(blob.get());
nsRefPtr<CreateURLRunnable> runnable =
new CreateURLRunnable(workerPrivate, blob, aOptions, aResult);
new CreateURLRunnable(workerPrivate, domBlob->Impl(), aOptions, aResult);
if (!runnable->Dispatch(cx)) {
JS_ReportPendingException(cx);

Просмотреть файл

@ -304,23 +304,21 @@ struct WorkerStructuredCloneCallbacks
if (aTag == DOMWORKER_SCTAG_FILE) {
MOZ_ASSERT(!aData);
nsIDOMFile* file;
if (JS_ReadBytes(aReader, &file, sizeof(file))) {
MOZ_ASSERT(file);
DOMFileImpl* fileImpl;
if (JS_ReadBytes(aReader, &fileImpl, sizeof(fileImpl))) {
MOZ_ASSERT(fileImpl);
#ifdef DEBUG
{
// File should not be mutable.
nsCOMPtr<nsIMutable> mutableFile = do_QueryInterface(file);
bool isMutable;
NS_ASSERTION(NS_SUCCEEDED(mutableFile->GetMutable(&isMutable)) &&
NS_ASSERTION(NS_SUCCEEDED(fileImpl->GetMutable(&isMutable)) &&
!isMutable,
"Only immutable file should be passed to worker");
}
#endif
// nsIDOMFiles should be threadsafe, thus we will use the same instance
// in the worker.
nsRefPtr<DOMFile> file = new DOMFile(fileImpl);
JSObject* jsFile = file::CreateFile(aCx, file);
return jsFile;
}
@ -329,23 +327,21 @@ struct WorkerStructuredCloneCallbacks
else if (aTag == DOMWORKER_SCTAG_BLOB) {
MOZ_ASSERT(!aData);
nsIDOMBlob* blob;
if (JS_ReadBytes(aReader, &blob, sizeof(blob))) {
MOZ_ASSERT(blob);
DOMFileImpl* blobImpl;
if (JS_ReadBytes(aReader, &blobImpl, sizeof(blobImpl))) {
MOZ_ASSERT(blobImpl);
#ifdef DEBUG
{
// Blob should not be mutable.
nsCOMPtr<nsIMutable> mutableBlob = do_QueryInterface(blob);
bool isMutable;
NS_ASSERTION(NS_SUCCEEDED(mutableBlob->GetMutable(&isMutable)) &&
NS_ASSERTION(NS_SUCCEEDED(blobImpl->GetMutable(&isMutable)) &&
!isMutable,
"Only immutable blob should be passed to worker");
}
#endif
// nsIDOMBlob should be threadsafe, thus we will use the same instance
// in the worker.
nsRefPtr<DOMFile> blob = new DOMFile(blobImpl);
JSObject* jsBlob = file::CreateBlob(aCx, blob);
return jsBlob;
}
@ -389,9 +385,10 @@ struct WorkerStructuredCloneCallbacks
{
nsIDOMFile* file = file::GetDOMFileFromJSObject(aObj);
if (file) {
DOMFileImpl* fileImpl = static_cast<DOMFile*>(file)->Impl();
if (JS_WriteUint32Pair(aWriter, DOMWORKER_SCTAG_FILE, 0) &&
JS_WriteBytes(aWriter, &file, sizeof(file))) {
clonedObjects->AppendElement(file);
JS_WriteBytes(aWriter, &fileImpl, sizeof(fileImpl))) {
clonedObjects->AppendElement(fileImpl);
return true;
}
}
@ -401,11 +398,11 @@ struct WorkerStructuredCloneCallbacks
{
nsIDOMBlob* blob = file::GetDOMBlobFromJSObject(aObj);
if (blob) {
nsCOMPtr<nsIMutable> mutableBlob = do_QueryInterface(blob);
if (mutableBlob && NS_SUCCEEDED(mutableBlob->SetMutable(false)) &&
DOMFileImpl* blobImpl = static_cast<DOMFile*>(blob)->Impl();
if (blobImpl && NS_SUCCEEDED(blobImpl->SetMutable(false)) &&
JS_WriteUint32Pair(aWriter, DOMWORKER_SCTAG_BLOB, 0) &&
JS_WriteBytes(aWriter, &blob, sizeof(blob))) {
clonedObjects->AppendElement(blob);
JS_WriteBytes(aWriter, &blobImpl, sizeof(blobImpl))) {
clonedObjects->AppendElement(blobImpl);
return true;
}
}
@ -461,21 +458,22 @@ struct MainThreadWorkerStructuredCloneCallbacks
if (aTag == DOMWORKER_SCTAG_FILE) {
MOZ_ASSERT(!aData);
nsIDOMFile* file;
if (JS_ReadBytes(aReader, &file, sizeof(file))) {
MOZ_ASSERT(file);
DOMFileImpl* fileImpl;
if (JS_ReadBytes(aReader, &fileImpl, sizeof(fileImpl))) {
MOZ_ASSERT(fileImpl);
#ifdef DEBUG
{
// File should not be mutable.
nsCOMPtr<nsIMutable> mutableFile = do_QueryInterface(file);
bool isMutable;
NS_ASSERTION(NS_SUCCEEDED(mutableFile->GetMutable(&isMutable)) &&
NS_ASSERTION(NS_SUCCEEDED(fileImpl->GetMutable(&isMutable)) &&
!isMutable,
"Only immutable file should be passed to worker");
}
#endif
nsCOMPtr<nsIDOMFile> file = new DOMFile(fileImpl);
// nsIDOMFiles should be threadsafe, thus we will use the same instance
// on the main thread.
JS::Rooted<JS::Value> wrappedFile(aCx);
@ -494,21 +492,22 @@ struct MainThreadWorkerStructuredCloneCallbacks
else if (aTag == DOMWORKER_SCTAG_BLOB) {
MOZ_ASSERT(!aData);
nsIDOMBlob* blob;
if (JS_ReadBytes(aReader, &blob, sizeof(blob))) {
MOZ_ASSERT(blob);
DOMFileImpl* blobImpl;
if (JS_ReadBytes(aReader, &blobImpl, sizeof(blobImpl))) {
MOZ_ASSERT(blobImpl);
#ifdef DEBUG
{
// Blob should not be mutable.
nsCOMPtr<nsIMutable> mutableBlob = do_QueryInterface(blob);
bool isMutable;
NS_ASSERTION(NS_SUCCEEDED(mutableBlob->GetMutable(&isMutable)) &&
NS_ASSERTION(NS_SUCCEEDED(blobImpl->GetMutable(&isMutable)) &&
!isMutable,
"Only immutable blob should be passed to worker");
}
#endif
nsCOMPtr<nsIDOMBlob> blob = new DOMFile(blobImpl);
// nsIDOMBlobs should be threadsafe, thus we will use the same instance
// on the main thread.
JS::Rooted<JS::Value> wrappedBlob(aCx);
@ -550,36 +549,40 @@ struct MainThreadWorkerStructuredCloneCallbacks
nsISupports* wrappedObject = wrappedNative->Native();
NS_ASSERTION(wrappedObject, "Null pointer?!");
nsISupports* ccISupports = nullptr;
wrappedObject->QueryInterface(NS_GET_IID(nsCycleCollectionISupports),
reinterpret_cast<void**>(&ccISupports));
if (ccISupports) {
NS_WARNING("Cycle collected objects are not supported!");
}
else {
// See if the wrapped native is a nsIDOMFile.
nsCOMPtr<nsIDOMFile> file = do_QueryInterface(wrappedObject);
if (file) {
nsCOMPtr<nsIMutable> mutableFile = do_QueryInterface(file);
if (mutableFile && NS_SUCCEEDED(mutableFile->SetMutable(false))) {
nsIDOMFile* filePtr = file;
// See if the wrapped native is a nsIDOMFile.
nsCOMPtr<nsIDOMFile> file = do_QueryInterface(wrappedObject);
if (file) {
nsRefPtr<DOMFileImpl> fileImpl =
static_cast<DOMFile*>(file.get())->Impl();
if (fileImpl->IsCCed()) {
NS_WARNING("Cycle collected file objects are not supported!");
} else {
if (NS_SUCCEEDED(fileImpl->SetMutable(false))) {
DOMFileImpl* fileImplPtr = fileImpl;
if (JS_WriteUint32Pair(aWriter, DOMWORKER_SCTAG_FILE, 0) &&
JS_WriteBytes(aWriter, &filePtr, sizeof(filePtr))) {
clonedObjects->AppendElement(file);
JS_WriteBytes(aWriter, &fileImplPtr, sizeof(fileImplPtr))) {
clonedObjects->AppendElement(fileImpl);
return true;
}
}
}
}
// See if the wrapped native is a nsIDOMBlob.
nsCOMPtr<nsIDOMBlob> blob = do_QueryInterface(wrappedObject);
if (blob) {
nsCOMPtr<nsIMutable> mutableBlob = do_QueryInterface(blob);
if (mutableBlob && NS_SUCCEEDED(mutableBlob->SetMutable(false))) {
nsIDOMBlob* blobPtr = blob;
// See if the wrapped native is a nsIDOMBlob.
nsCOMPtr<nsIDOMBlob> blob = do_QueryInterface(wrappedObject);
if (blob) {
nsRefPtr<DOMFileImpl> blobImpl =
static_cast<DOMFile*>(blob.get())->Impl();
if (blobImpl->IsCCed()) {
NS_WARNING("Cycle collected blob objects are not supported!");
} else {
if (NS_SUCCEEDED(blobImpl->SetMutable(false))) {
DOMFileImpl* blobImplPtr = blobImpl;
if (JS_WriteUint32Pair(aWriter, DOMWORKER_SCTAG_BLOB, 0) &&
JS_WriteBytes(aWriter, &blobPtr, sizeof(blobPtr))) {
clonedObjects->AppendElement(blob);
JS_WriteBytes(aWriter, &blobImplPtr, sizeof(blobImplPtr))) {
clonedObjects->AppendElement(blobImpl);
return true;
}
}