/* -*- 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/. */
// This class is used in the DTOR of GetFilesHelper to release resources in the // correct thread. class ReleaseRunnable final : public Runnable { public: staticvoid MaybeReleaseOnMainThread(
nsTArray<RefPtr<Promise>>&& aPromises,
nsTArray<RefPtr<GetFilesCallback>>&& aCallbacks) { if (NS_IsMainThread()) { return;
}
RefPtr<ReleaseRunnable> runnable = new ReleaseRunnable(std::move(aPromises), std::move(aCallbacks));
FileSystemUtils::DispatchRunnable(nullptr, runnable.forget());
}
if (XRE_IsParentProcess()) {
helper = new GetFilesHelper(aRecursiveFlag);
} else {
helper = new GetFilesHelperChild(aRecursiveFlag);
}
nsAutoString directoryPath;
for (uint32_t i = 0; i < aFilesOrDirectory.Length(); ++i) { const OwningFileOrDirectory& data = aFilesOrDirectory[i]; if (data.IsFile()) { if (!helper->mTargetBlobImplArray.AppendElement(data.GetAsFile()->Impl(),
fallible)) {
aRv.Throw(NS_ERROR_OUT_OF_MEMORY); return nullptr;
}
} else {
MOZ_ASSERT(data.IsDirectory());
// We support the upload of only 1 top-level directory from our // directory picker. This means that we cannot have more than 1 // Directory object in aFilesOrDirectory array.
MOZ_ASSERT(directoryPath.IsEmpty());
// We are here, but we should not do anything on this thread because, in the // meantime, the operation has been canceled. if (IsCanceled()) { return NS_OK;
}
OperationCompleted(); return NS_OK;
}
void GetFilesHelper::OperationCompleted() { // We mark the operation as completed here.
mListingCompleted = true;
// Let's process the pending promises.
nsTArray<RefPtr<Promise>> promises = std::move(mPromises);
for (uint32_t i = 0; i < promises.Length(); ++i) {
ResolveOrRejectPromise(promises[i]);
}
// Let's process the pending callbacks.
nsTArray<RefPtr<GetFilesCallback>> callbacks = std::move(mCallbacks);
for (uint32_t i = 0; i < callbacks.Length(); ++i) {
RunCallback(callbacks[i]);
}
}
for (;;) {
nsCOMPtr<nsIFile> currFile; if (NS_WARN_IF(NS_FAILED(entries->GetNextFile(getter_AddRefs(currFile)))) ||
!currFile) { break;
} bool isLink, isSpecial, isFile, isDir; if (NS_WARN_IF(NS_FAILED(currFile->IsSymlink(&isLink)) ||
NS_FAILED(currFile->IsSpecial(&isSpecial))) ||
isSpecial || // Although we allow explicit individual selection of symlinks via the // file picker, we do not process symlinks in directory traversal. Our // specific policy decision is documented at // https://bugzilla.mozilla.org/show_bug.cgi?id=1813299#c20
isLink) { continue;
}
// The new domPath
nsAutoString domPath;
domPath.Assign(aDOMPath); if (!aDOMPath.EqualsLiteral(FILESYSTEM_DOM_PATH_SEPARATOR_LITERAL)) {
domPath.AppendLiteral(FILESYSTEM_DOM_PATH_SEPARATOR_LITERAL);
}
nsAutoString leafName; if (NS_WARN_IF(NS_FAILED(currFile->GetLeafName(leafName)))) { continue;
}
domPath.Append(leafName);
if (isFile) {
RefPtr<BlobImpl> blobImpl = new FileBlobImpl(currFile);
blobImpl->SetDOMPath(domPath);
if (!mTargetBlobImplArray.AppendElement(blobImpl, fallible)) { return NS_ERROR_OUT_OF_MEMORY;
}
continue;
}
MOZ_ASSERT(isDir); if (!mRecursiveFlag) { continue;
}
Die Informationen auf dieser Webseite wurden
nach bestem Wissen sorgfältig zusammengestellt. Es wird jedoch weder Vollständigkeit, noch Richtigkeit,
noch Qualität der bereit gestellten Informationen zugesichert.
Bemerkung:
Die farbliche Syntaxdarstellung ist noch experimentell.