diff options
Diffstat (limited to 'dom/filesystem/GetFilesHelper.h')
-rw-r--r-- | dom/filesystem/GetFilesHelper.h | 205 |
1 files changed, 205 insertions, 0 deletions
diff --git a/dom/filesystem/GetFilesHelper.h b/dom/filesystem/GetFilesHelper.h new file mode 100644 index 0000000000..a1bb1b27a6 --- /dev/null +++ b/dom/filesystem/GetFilesHelper.h @@ -0,0 +1,205 @@ +/* -*- 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/. */ + +#ifndef mozilla_dom_GetFilesHelper_h +#define mozilla_dom_GetFilesHelper_h + +#include "mozilla/Mutex.h" +#include "mozilla/RefPtr.h" +#include "nsCycleCollectionTraversalCallback.h" +#include "nsTArray.h" +#include "nsTHashtable.h" + +class nsIGlobalObject; + +namespace mozilla { +namespace dom { + +class BlobImpl; +class ContentParent; +class File; +class GetFilesHelperParent; +class OwningFileOrDirectory; +class Promise; + +class GetFilesCallback +{ +public: + NS_INLINE_DECL_REFCOUNTING(GetFilesCallback); + + virtual void + Callback(nsresult aStatus, const Sequence<RefPtr<File>>& aFiles) = 0; + +protected: + virtual ~GetFilesCallback() {} +}; + +class GetFilesHelperBase +{ +protected: + explicit GetFilesHelperBase(bool aRecursiveFlag) + : mRecursiveFlag(aRecursiveFlag) + {} + + virtual ~GetFilesHelperBase() {} + + virtual bool + IsCanceled() + { + return false; + } + + nsresult + ExploreDirectory(const nsAString& aDOMPath, nsIFile* aFile); + + nsresult + AddExploredDirectory(nsIFile* aDirectory); + + bool + ShouldFollowSymLink(nsIFile* aDirectory); + + bool mRecursiveFlag; + + // We populate this array in the I/O thread with the BlobImpl. + FallibleTArray<RefPtr<BlobImpl>> mTargetBlobImplArray; + nsTHashtable<nsCStringHashKey> mExploredDirectories; +}; + +// Retrieving the list of files can be very time/IO consuming. We use this +// helper class to do it just once. +class GetFilesHelper : public Runnable + , public GetFilesHelperBase +{ + friend class GetFilesHelperParent; + +public: + static already_AddRefed<GetFilesHelper> + Create(nsIGlobalObject* aGlobal, + const nsTArray<OwningFileOrDirectory>& aFilesOrDirectory, + bool aRecursiveFlag, ErrorResult& aRv); + + void + AddPromise(Promise* aPromise); + + void + AddCallback(GetFilesCallback* aCallback); + + // CC methods + void Unlink(); + void Traverse(nsCycleCollectionTraversalCallback &cb); + +protected: + GetFilesHelper(nsIGlobalObject* aGlobal, bool aRecursiveFlag); + + virtual ~GetFilesHelper(); + + void + SetDirectoryPath(const nsAString& aDirectoryPath) + { + mDirectoryPath = aDirectoryPath; + } + + virtual bool + IsCanceled() override + { + MutexAutoLock lock(mMutex); + return mCanceled; + } + + virtual void + Work(ErrorResult& aRv); + + virtual void + Cancel() {}; + + NS_IMETHOD + Run() override; + + void + RunIO(); + + void + RunMainThread(); + + void + OperationCompleted(); + + void + ResolveOrRejectPromise(Promise* aPromise); + + void + RunCallback(GetFilesCallback* aCallback); + + nsCOMPtr<nsIGlobalObject> mGlobal; + + bool mListingCompleted; + nsString mDirectoryPath; + + // This is the real File sequence that we expose via Promises. + Sequence<RefPtr<File>> mFiles; + + // Error code to propagate. + nsresult mErrorResult; + + nsTArray<RefPtr<Promise>> mPromises; + nsTArray<RefPtr<GetFilesCallback>> mCallbacks; + + Mutex mMutex; + + // This variable is protected by mutex. + bool mCanceled; +}; + +class GetFilesHelperChild final : public GetFilesHelper +{ +public: + GetFilesHelperChild(nsIGlobalObject* aGlobal, bool aRecursiveFlag) + : GetFilesHelper(aGlobal, aRecursiveFlag) + , mPendingOperation(false) + {} + + virtual void + Work(ErrorResult& aRv) override; + + virtual void + Cancel() override; + + bool + AppendBlobImpl(BlobImpl* aBlobImpl); + + void + Finished(nsresult aResult); + +private: + nsID mUUID; + bool mPendingOperation; +}; + +class GetFilesHelperParentCallback; + +class GetFilesHelperParent final : public GetFilesHelper +{ + friend class GetFilesHelperParentCallback; + +public: + static already_AddRefed<GetFilesHelperParent> + Create(const nsID& aUUID, const nsAString& aDirectoryPath, + bool aRecursiveFlag, ContentParent* aContentParent, ErrorResult& aRv); + +private: + GetFilesHelperParent(const nsID& aUUID, ContentParent* aContentParent, + bool aRecursiveFlag); + + ~GetFilesHelperParent(); + + RefPtr<ContentParent> mContentParent; + nsID mUUID; +}; + +} // dom namespace +} // mozilla namespace + +#endif // mozilla_dom_GetFilesHelper_h |