Bug 1892041 - Part 1: Update test262 features. r=spidermonkey-reviewers,dminor
[gecko.git] / dom / filesystem / GetFilesTask.cpp
blob280df0b0bcee726233851704fcee9abfe25ab78b
1 /* -*- Mode: C++; tab-width: 8; indent-tabs-mode: nil; c-basic-offset: 2 -*- */
2 /* vim: set ts=8 sts=2 et sw=2 tw=80: */
3 /* This Source Code Form is subject to the terms of the Mozilla Public
4 * License, v. 2.0. If a copy of the MPL was not distributed with this file,
5 * You can obtain one at http://mozilla.org/MPL/2.0/. */
7 #include "GetFilesTask.h"
9 #include "HTMLSplitOnSpacesTokenizer.h"
10 #include "js/Value.h"
11 #include "mozilla/dom/BlobImpl.h"
12 #include "mozilla/dom/File.h"
13 #include "mozilla/dom/FileSystemBase.h"
14 #include "mozilla/dom/FileSystemUtils.h"
15 #include "mozilla/dom/IPCBlobUtils.h"
16 #include "mozilla/dom/PFileSystemParams.h"
17 #include "mozilla/dom/Promise.h"
18 #include "mozilla/ipc/BackgroundParent.h"
19 #include "nsIFile.h"
20 #include "nsString.h"
22 namespace mozilla::dom {
24 /**
25 * GetFilesTaskChild
28 /* static */
29 already_AddRefed<GetFilesTaskChild> GetFilesTaskChild::Create(
30 FileSystemBase* aFileSystem, Directory* aDirectory, nsIFile* aTargetPath,
31 bool aRecursiveFlag, ErrorResult& aRv) {
32 MOZ_ASSERT(aFileSystem);
33 MOZ_ASSERT(aDirectory);
34 aFileSystem->AssertIsOnOwningThread();
36 nsCOMPtr<nsIGlobalObject> globalObject = aFileSystem->GetParentObject();
37 if (NS_WARN_IF(!globalObject)) {
38 aRv.Throw(NS_ERROR_FAILURE);
39 return nullptr;
42 RefPtr<GetFilesTaskChild> task = new GetFilesTaskChild(
43 globalObject, aFileSystem, aDirectory, aTargetPath, aRecursiveFlag);
45 // aTargetPath can be null. In this case SetError will be called.
47 task->mPromise = Promise::Create(globalObject, aRv);
48 if (NS_WARN_IF(aRv.Failed())) {
49 return nullptr;
52 return task.forget();
55 GetFilesTaskChild::GetFilesTaskChild(nsIGlobalObject* aGlobalObject,
56 FileSystemBase* aFileSystem,
57 Directory* aDirectory,
58 nsIFile* aTargetPath, bool aRecursiveFlag)
59 : FileSystemTaskChildBase(aGlobalObject, aFileSystem),
60 mDirectory(aDirectory),
61 mTargetPath(aTargetPath),
62 mRecursiveFlag(aRecursiveFlag) {
63 MOZ_ASSERT(aFileSystem);
64 MOZ_ASSERT(aDirectory);
65 aFileSystem->AssertIsOnOwningThread();
68 GetFilesTaskChild::~GetFilesTaskChild() {
69 mFileSystem->AssertIsOnOwningThread();
72 already_AddRefed<Promise> GetFilesTaskChild::GetPromise() {
73 mFileSystem->AssertIsOnOwningThread();
74 return RefPtr<Promise>(mPromise).forget();
77 FileSystemParams GetFilesTaskChild::GetRequestParams(
78 const nsString& aSerializedDOMPath, ErrorResult& aRv) const {
79 mFileSystem->AssertIsOnOwningThread();
81 nsAutoString path;
82 aRv = mTargetPath->GetPath(path);
83 if (NS_WARN_IF(aRv.Failed())) {
84 return FileSystemGetFilesParams();
87 nsAutoString domPath;
88 mDirectory->GetPath(domPath, aRv);
89 if (NS_WARN_IF(aRv.Failed())) {
90 return FileSystemGetFilesParams();
93 return FileSystemGetFilesParams(aSerializedDOMPath, path, domPath,
94 mRecursiveFlag);
97 void GetFilesTaskChild::SetSuccessRequestResult(
98 const FileSystemResponseValue& aValue, ErrorResult& aRv) {
99 mFileSystem->AssertIsOnOwningThread();
100 MOZ_ASSERT(aValue.type() ==
101 FileSystemResponseValue::TFileSystemFilesResponse);
103 FileSystemFilesResponse r = aValue;
105 if (!mTargetData.SetLength(r.data().Length(), mozilla::fallible_t())) {
106 aRv.Throw(NS_ERROR_OUT_OF_MEMORY);
107 return;
110 nsCOMPtr<nsIGlobalObject> globalObject = mFileSystem->GetParentObject();
111 MOZ_ASSERT(globalObject);
113 for (uint32_t i = 0; i < r.data().Length(); ++i) {
114 const FileSystemFileResponse& data = r.data()[i];
115 RefPtr<BlobImpl> blobImpl = IPCBlobUtils::Deserialize(data.blob());
116 MOZ_ASSERT(blobImpl);
118 mTargetData[i] = File::Create(globalObject, blobImpl);
119 if (NS_WARN_IF(!mTargetData[i])) {
120 aRv.Throw(NS_ERROR_FAILURE);
121 return;
126 void GetFilesTaskChild::HandlerCallback() {
127 mFileSystem->AssertIsOnOwningThread();
128 if (mFileSystem->IsShutdown()) {
129 mPromise = nullptr;
130 return;
133 if (HasError()) {
134 mPromise->MaybeReject(NS_ERROR_DOM_INVALID_STATE_ERR);
135 mPromise = nullptr;
136 return;
139 mPromise->MaybeResolve(mTargetData);
140 mPromise = nullptr;
144 * GetFilesTaskParent
147 /* static */
148 already_AddRefed<GetFilesTaskParent> GetFilesTaskParent::Create(
149 FileSystemBase* aFileSystem, const FileSystemGetFilesParams& aParam,
150 FileSystemRequestParent* aParent, ErrorResult& aRv) {
151 MOZ_ASSERT(XRE_IsParentProcess(), "Only call from parent process!");
152 mozilla::ipc::AssertIsOnBackgroundThread();
153 MOZ_ASSERT(aFileSystem);
155 RefPtr<GetFilesTaskParent> task =
156 new GetFilesTaskParent(aFileSystem, aParam, aParent);
158 aRv = NS_NewLocalFile(aParam.realPath(), true,
159 getter_AddRefs(task->mTargetPath));
160 if (NS_WARN_IF(aRv.Failed())) {
161 return nullptr;
164 return task.forget();
167 GetFilesTaskParent::GetFilesTaskParent(FileSystemBase* aFileSystem,
168 const FileSystemGetFilesParams& aParam,
169 FileSystemRequestParent* aParent)
170 : FileSystemTaskParentBase(aFileSystem, aParam, aParent),
171 GetFilesHelperBase(aParam.recursiveFlag()),
172 mDirectoryDOMPath(aParam.domPath()) {
173 MOZ_ASSERT(XRE_IsParentProcess(), "Only call from parent process!");
174 mozilla::ipc::AssertIsOnBackgroundThread();
175 MOZ_ASSERT(aFileSystem);
178 FileSystemResponseValue GetFilesTaskParent::GetSuccessRequestResult(
179 ErrorResult& aRv) const {
180 mozilla::ipc::AssertIsOnBackgroundThread();
182 FallibleTArray<FileSystemFileResponse> inputs;
183 if (!inputs.SetLength(mTargetBlobImplArray.Length(), mozilla::fallible_t())) {
184 FileSystemFilesResponse response;
185 aRv.Throw(NS_ERROR_OUT_OF_MEMORY);
186 return response;
189 for (unsigned i = 0; i < mTargetBlobImplArray.Length(); i++) {
190 IPCBlob ipcBlob;
191 aRv = IPCBlobUtils::Serialize(mTargetBlobImplArray[i], ipcBlob);
192 if (NS_WARN_IF(aRv.Failed())) {
193 FileSystemFilesResponse response;
194 return response;
197 inputs[i] = FileSystemFileResponse(ipcBlob);
200 FileSystemFilesResponse response;
201 response.data() = std::move(inputs);
202 return response;
205 nsresult GetFilesTaskParent::IOWork() {
206 MOZ_ASSERT(XRE_IsParentProcess(), "Only call from parent process!");
207 MOZ_ASSERT(!NS_IsMainThread(), "Only call on I/O thread!");
209 if (mFileSystem->IsShutdown()) {
210 return NS_ERROR_FAILURE;
213 bool exists;
214 nsresult rv = mTargetPath->Exists(&exists);
215 if (NS_WARN_IF(NS_FAILED(rv))) {
216 return rv;
219 if (!exists) {
220 return NS_OK;
223 bool isDir;
224 rv = mTargetPath->IsDirectory(&isDir);
225 if (NS_WARN_IF(NS_FAILED(rv))) {
226 return rv;
229 if (!isDir) {
230 return NS_ERROR_DOM_FILESYSTEM_TYPE_MISMATCH_ERR;
233 // Get isDirectory.
234 rv = ExploreDirectory(mDirectoryDOMPath, mTargetPath);
235 if (NS_WARN_IF(NS_FAILED(rv))) {
236 return rv;
239 return NS_OK;
242 nsresult GetFilesTaskParent::GetTargetPath(nsAString& aPath) const {
243 return mTargetPath->GetPath(aPath);
246 } // namespace mozilla::dom