diff --git a/dom/file/BaseBlobImpl.cpp b/dom/file/BaseBlobImpl.cpp index cc8b8cbac049..476fb207f39f 100644 --- a/dom/file/BaseBlobImpl.cpp +++ b/dom/file/BaseBlobImpl.cpp @@ -53,40 +53,6 @@ int64_t BaseBlobImpl::GetLastModified(ErrorResult& aRv) { int64_t BaseBlobImpl::GetFileId() { return -1; } -nsresult BaseBlobImpl::GetSendInfo(nsIInputStream** aBody, - uint64_t* aContentLength, - nsACString& aContentType, - nsACString& aCharset) { - MOZ_ASSERT(aContentLength); - - ErrorResult rv; - - nsCOMPtr stream; - CreateInputStream(getter_AddRefs(stream), rv); - if (NS_WARN_IF(rv.Failed())) { - return rv.StealNSResult(); - } - - *aContentLength = GetSize(rv); - if (NS_WARN_IF(rv.Failed())) { - return rv.StealNSResult(); - } - - nsAutoString contentType; - GetType(contentType); - - if (contentType.IsEmpty()) { - aContentType.SetIsVoid(true); - } else { - CopyUTF16toUTF8(contentType, aContentType); - } - - aCharset.Truncate(); - - stream.forget(aBody); - return NS_OK; -} - /* static */ uint64_t BaseBlobImpl::NextSerialNumber() { static Atomic nextSerialNumber; diff --git a/dom/file/BaseBlobImpl.h b/dom/file/BaseBlobImpl.h index aaf5bc233a0c..79dba0c5439c 100644 --- a/dom/file/BaseBlobImpl.h +++ b/dom/file/BaseBlobImpl.h @@ -12,7 +12,11 @@ namespace mozilla { namespace dom { +class FileBlobImpl; + class BaseBlobImpl : public BlobImpl { + friend class FileBlobImpl; + public: // File constructor. BaseBlobImpl(const nsAString& aBlobImplType, const nsAString& aName, @@ -104,10 +108,6 @@ class BaseBlobImpl : public BlobImpl { virtual int64_t GetFileId() override; - virtual nsresult GetSendInfo(nsIInputStream** aBody, uint64_t* aContentLength, - nsACString& aContentType, - nsACString& aCharset) override; - virtual void SetLazyData(const nsAString& aName, const nsAString& aContentType, uint64_t aLength, int64_t aLastModifiedDate) override { diff --git a/dom/file/BlobImpl.cpp b/dom/file/BlobImpl.cpp index 6d93306911d9..2da12d01c9fd 100644 --- a/dom/file/BlobImpl.cpp +++ b/dom/file/BlobImpl.cpp @@ -61,6 +61,38 @@ already_AddRefed BlobImpl::Slice(const Optional& aStart, return CreateSlice((uint64_t)start, (uint64_t)(end - start), type, aRv); } +nsresult BlobImpl::GetSendInfo(nsIInputStream** aBody, uint64_t* aContentLength, + nsACString& aContentType, nsACString& aCharset) { + MOZ_ASSERT(aContentLength); + + ErrorResult rv; + + nsCOMPtr stream; + CreateInputStream(getter_AddRefs(stream), rv); + if (NS_WARN_IF(rv.Failed())) { + return rv.StealNSResult(); + } + + *aContentLength = GetSize(rv); + if (NS_WARN_IF(rv.Failed())) { + return rv.StealNSResult(); + } + + nsAutoString contentType; + GetType(contentType); + + if (contentType.IsEmpty()) { + aContentType.SetIsVoid(true); + } else { + CopyUTF16toUTF8(contentType, aContentType); + } + + aCharset.Truncate(); + + stream.forget(aBody); + return NS_OK; +} + NS_IMPL_ISUPPORTS(BlobImpl, BlobImpl) } // namespace dom diff --git a/dom/file/BlobImpl.h b/dom/file/BlobImpl.h index 503beede73b6..a3bfcde4fdfd 100644 --- a/dom/file/BlobImpl.h +++ b/dom/file/BlobImpl.h @@ -83,9 +83,8 @@ class BlobImpl : public nsISupports { virtual int64_t GetFileId() = 0; - virtual nsresult GetSendInfo(nsIInputStream** aBody, uint64_t* aContentLength, - nsACString& aContentType, - nsACString& aCharset) = 0; + nsresult GetSendInfo(nsIInputStream** aBody, uint64_t* aContentLength, + nsACString& aContentType, nsACString& aCharset); virtual void SetLazyData(const nsAString& aName, const nsAString& aContentType, uint64_t aLength, diff --git a/dom/file/FileBlobImpl.cpp b/dom/file/FileBlobImpl.cpp index e9c46b07f1ad..aef20f7ace75 100644 --- a/dom/file/FileBlobImpl.cpp +++ b/dom/file/FileBlobImpl.cpp @@ -19,14 +19,12 @@ namespace mozilla { namespace dom { FileBlobImpl::FileBlobImpl(nsIFile* aFile) - : BaseBlobImpl(NS_LITERAL_STRING("FileBlobImpl"), EmptyString(), - EmptyString(), - // We pass 0 as lastModified and length because FileblobImpl - // has a different way to compute those values. - 0, 0), - mMutex("FileBlobImpl::mMutex"), + : mMutex("FileBlobImpl::mMutex"), mFile(aFile), + mSerialNumber(BaseBlobImpl::NextSerialNumber()), + mStart(0), mFileId(-1), + mIsFile(true), mWholeFile(true) { MOZ_ASSERT(mFile, "must have file"); MOZ_ASSERT(XRE_IsParentProcess()); @@ -39,14 +37,15 @@ FileBlobImpl::FileBlobImpl(nsIFile* aFile) FileBlobImpl::FileBlobImpl(const nsAString& aName, const nsAString& aContentType, uint64_t aLength, nsIFile* aFile) - : BaseBlobImpl(NS_LITERAL_STRING("FileBlobImpl"), aName, aContentType, - // We pass 0 as lastModified and length because FileblobImpl - // has a different way to compute those values. - 0, 0), - mMutex("FileBlobImpl::mMutex"), + : mMutex("FileBlobImpl::mMutex"), mFile(aFile), - mLength(Some(aLength)), + mContentType(aContentType), + mName(aName), + mSerialNumber(BaseBlobImpl::NextSerialNumber()), + mStart(0), mFileId(-1), + mLength(Some(aLength)), + mIsFile(true), mWholeFile(true) { MOZ_ASSERT(mFile, "must have file"); MOZ_ASSERT(XRE_IsParentProcess()); @@ -56,15 +55,16 @@ FileBlobImpl::FileBlobImpl(const nsAString& aName, FileBlobImpl::FileBlobImpl(const nsAString& aName, const nsAString& aContentType, uint64_t aLength, nsIFile* aFile, int64_t aLastModificationDate) - : BaseBlobImpl(NS_LITERAL_STRING("FileBlobImpl"), aName, aContentType, - // We pass 0 as lastModified and length because FileblobImpl - // has a different way to compute those values. - 0, 0), - mMutex("FileBlobImpl::mMutex"), + : mMutex("FileBlobImpl::mMutex"), mFile(aFile), + mContentType(aContentType), + mName(aName), + mSerialNumber(BaseBlobImpl::NextSerialNumber()), + mStart(0), + mFileId(-1), mLength(Some(aLength)), mLastModified(Some(aLastModificationDate)), - mFileId(-1), + mIsFile(true), mWholeFile(true) { MOZ_ASSERT(mFile, "must have file"); MOZ_ASSERT(XRE_IsParentProcess()); @@ -72,15 +72,15 @@ FileBlobImpl::FileBlobImpl(const nsAString& aName, } FileBlobImpl::FileBlobImpl(nsIFile* aFile, const nsAString& aName, - const nsAString& aContentType, - const nsAString& aBlobImplType) - : BaseBlobImpl(aBlobImplType, aName, aContentType, - // We pass 0 as lastModified and length because FileblobImpl - // has a different way to compute those values. - 0, 0), - mMutex("FileBlobImpl::mMutex"), + const nsAString& aContentType) + : mMutex("FileBlobImpl::mMutex"), mFile(aFile), + mContentType(aContentType), + mName(aName), + mSerialNumber(BaseBlobImpl::NextSerialNumber()), + mStart(0), mFileId(-1), + mIsFile(true), mWholeFile(true) { MOZ_ASSERT(mFile, "must have file"); MOZ_ASSERT(XRE_IsParentProcess()); @@ -94,15 +94,14 @@ FileBlobImpl::FileBlobImpl(nsIFile* aFile, const nsAString& aName, FileBlobImpl::FileBlobImpl(const FileBlobImpl* aOther, uint64_t aStart, uint64_t aLength, const nsAString& aContentType) - : BaseBlobImpl(NS_LITERAL_STRING("FileBlobImpl"), aContentType, - aOther->mStart + aStart, - // We pass 0 as length because FileblobImpl has a different - // way to compute the value. - 0), - mMutex("FileBlobImpl::mMutex"), + : mMutex("FileBlobImpl::mMutex"), mFile(aOther->mFile), - mLength(Some(aLength)), + mContentType(aContentType), + mSerialNumber(BaseBlobImpl::NextSerialNumber()), + mStart(aOther->mStart + aStart), mFileId(-1), + mLength(Some(aLength)), + mIsFile(false), mWholeFile(false) { MOZ_ASSERT(mFile, "must have file"); MOZ_ASSERT(XRE_IsParentProcess()); @@ -238,6 +237,10 @@ void FileBlobImpl::GetTypeInternal(nsAString& aType, aType = mContentType; } +void FileBlobImpl::GetBlobImplType(nsAString& aBlobImplType) const { + aBlobImplType = NS_LITERAL_STRING("FileBlobImpl"); +} + int64_t FileBlobImpl::GetLastModified(ErrorResult& aRv) { MOZ_ASSERT(mIsFile, "Should only be called on files"); diff --git a/dom/file/FileBlobImpl.h b/dom/file/FileBlobImpl.h index 778799cf9bc3..4b4438db60b5 100644 --- a/dom/file/FileBlobImpl.h +++ b/dom/file/FileBlobImpl.h @@ -7,7 +7,7 @@ #ifndef mozilla_dom_FileBlobImpl_h #define mozilla_dom_FileBlobImpl_h -#include "mozilla/dom/BaseBlobImpl.h" +#include "mozilla/dom/BlobImpl.h" #include "mozilla/Maybe.h" #include "mozilla/Mutex.h" @@ -16,9 +16,9 @@ class nsIFile; namespace mozilla { namespace dom { -class FileBlobImpl : public BaseBlobImpl { +class FileBlobImpl : public BlobImpl { public: - NS_INLINE_DECL_REFCOUNTING_INHERITED(FileBlobImpl, BaseBlobImpl) + NS_INLINE_DECL_REFCOUNTING_INHERITED(FileBlobImpl, BlobImpl) // Create as a file explicit FileBlobImpl(nsIFile* aFile); @@ -31,35 +31,78 @@ class FileBlobImpl : public BaseBlobImpl { uint64_t aLength, nsIFile* aFile, int64_t aLastModificationDate); // Create as a file with custom name - FileBlobImpl( - nsIFile* aFile, const nsAString& aName, const nsAString& aContentType, - const nsAString& aBlobImplType = NS_LITERAL_STRING("FileBlobImpl")); + FileBlobImpl(nsIFile* aFile, const nsAString& aName, + const nsAString& aContentType); - // Overrides - virtual uint64_t GetSize(ErrorResult& aRv) override; - virtual void GetType(nsAString& aType) override; - virtual int64_t GetLastModified(ErrorResult& aRv) override; - virtual void GetMozFullPathInternal(nsAString& aFullPath, - ErrorResult& aRv) override; - virtual void CreateInputStream(nsIInputStream** aInputStream, - ErrorResult& aRv) override; - - virtual bool IsDirectory() const override; - - virtual void SetLazyData(const nsAString& aName, - const nsAString& aContentType, uint64_t aLength, - int64_t aLastModifiedDate) override { - BaseBlobImpl::SetLazyData(aName, aContentType, 0, 0); - mLength.emplace(aLength); - mLastModified.emplace(aLastModifiedDate); + void GetName(nsAString& aName) const override { + MOZ_ASSERT(mIsFile, "Should only be called on files"); + aName = mName; } void SetName(const nsAString& aName) { mName = aName; } - void SetType(const nsAString& aType) { mContentType = aType; } + void GetDOMPath(nsAString& aPath) const override { + MOZ_ASSERT(mIsFile, "Should only be called on files"); + aPath = mPath; + } + + void SetDOMPath(const nsAString& aPath) override { + MOZ_ASSERT(mIsFile, "Should only be called on files"); + mPath = aPath; + } + + int64_t GetLastModified(ErrorResult& aRv) override; + + void GetMozFullPath(nsAString& aFileName, SystemCallerGuarantee /* unused */, + ErrorResult& aRv) override { + MOZ_ASSERT(mIsFile, "Should only be called on files"); + + GetMozFullPathInternal(aFileName, aRv); + } + + void GetMozFullPathInternal(nsAString& aFilename, ErrorResult& aRv) override; + + uint64_t GetSize(ErrorResult& aRv) override; + + void GetType(nsAString& aType) override; + + virtual void GetBlobImplType(nsAString& aBlobImplType) const override; + + size_t GetAllocationSize() const override { return 0; } + + size_t GetAllocationSize( + FallibleTArray& aVisitedBlobImpls) const override { + return GetAllocationSize(); + } + + uint64_t GetSerialNumber() const override { return mSerialNumber; } + + const nsTArray>* GetSubBlobImpls() const override { + return nullptr; + } + + virtual void CreateInputStream(nsIInputStream** aInputStream, + ErrorResult& aRv) override; int64_t GetFileId() override { return mFileId; } + void SetLazyData(const nsAString& aName, const nsAString& aContentType, + uint64_t aLength, int64_t aLastModifiedDate) override { + mName = aName; + mContentType = aContentType; + mIsFile = !aName.IsVoid(); + mLength.emplace(aLength); + mLastModified.emplace(aLastModifiedDate); + } + + bool IsMemoryFile() const override { return false; } + + bool IsFile() const override { return mIsFile; } + + bool IsDirectory() const override; + + void SetType(const nsAString& aType) { mContentType = aType; } + void SetFileId(int64_t aFileId) { mFileId = aFileId; } void SetEmptySize() { mLength.emplace(0); } @@ -71,34 +114,40 @@ class FileBlobImpl : public BaseBlobImpl { } protected: - virtual ~FileBlobImpl() = default; + ~FileBlobImpl() = default; // Create slice FileBlobImpl(const FileBlobImpl* aOther, uint64_t aStart, uint64_t aLength, const nsAString& aContentType); - virtual already_AddRefed CreateSlice(uint64_t aStart, - uint64_t aLength, - const nsAString& aContentType, - ErrorResult& aRv) override; + already_AddRefed CreateSlice(uint64_t aStart, uint64_t aLength, + const nsAString& aContentType, + ErrorResult& aRv) override; class GetTypeRunnable; void GetTypeInternal(nsAString& aType, const MutexAutoLock& aProofOfLock); - // FileBlobImpl is the only BlobImpl with a few getter methods with lazy - // initialization. Because any BlobImpl must work thread-safe, we use a mutex. - // This is the list of the getter methods and the corresponding lazy members: - // - GetMozFullPathInternal - mMozFullPath - // - GetSize - mLength - // - GetType - mContentType - // - GetLastModified - mLastModifed + // FileBlobImpl has getter methods with lazy initialization. Because any + // BlobImpl must work thread-safe, we use a mutex. Mutex mMutex; nsCOMPtr mFile; + + nsString mContentType; + nsString mName; + nsString mPath; // The path relative to a directory chosen by the user nsString mMozFullPath; - Maybe mLength; - Maybe mLastModified; + + const uint64_t mSerialNumber; + uint64_t mStart; + int64_t mFileId; + + Maybe mLength; + + Maybe mLastModified; + + bool mIsFile; bool mWholeFile; }; diff --git a/dom/file/TemporaryFileBlobImpl.cpp b/dom/file/TemporaryFileBlobImpl.cpp index c563b3587d5e..51d0f128138a 100644 --- a/dom/file/TemporaryFileBlobImpl.cpp +++ b/dom/file/TemporaryFileBlobImpl.cpp @@ -96,8 +96,7 @@ class TemporaryFileInputStream final : public nsFileInputStream { TemporaryFileBlobImpl::TemporaryFileBlobImpl(nsIFile* aFile, const nsAString& aContentType) - : FileBlobImpl(aFile, EmptyString(), aContentType, - NS_LITERAL_STRING("TemporaryBlobImpl")) + : FileBlobImpl(aFile, EmptyString(), aContentType) #ifdef DEBUG , mInputStreamCreated(false) diff --git a/dom/file/TemporaryFileBlobImpl.h b/dom/file/TemporaryFileBlobImpl.h index 74ac349dfd48..4f54540b8331 100644 --- a/dom/file/TemporaryFileBlobImpl.h +++ b/dom/file/TemporaryFileBlobImpl.h @@ -30,6 +30,10 @@ class TemporaryFileBlobImpl final : public FileBlobImpl { virtual void CreateInputStream(nsIInputStream** aInputStream, ErrorResult& aRv) override; + void GetBlobImplType(nsAString& aBlobImplType) const override { + aBlobImplType = NS_LITERAL_STRING("TemporaryFileBlobImpl"); + } + protected: virtual ~TemporaryFileBlobImpl();