dom/filesystem/GetFileOrDirectoryTask.cpp

changeset 0
6474c204b198
     1.1 --- /dev/null	Thu Jan 01 00:00:00 1970 +0000
     1.2 +++ b/dom/filesystem/GetFileOrDirectoryTask.cpp	Wed Dec 31 06:09:35 2014 +0100
     1.3 @@ -0,0 +1,223 @@
     1.4 +/* -*- Mode: c++; c-basic-offset: 2; indent-tabs-mode: nil; tab-width: 40 -*- */
     1.5 +/* vim: set ts=2 et sw=2 tw=80: */
     1.6 +/* This Source Code Form is subject to the terms of the Mozilla Public
     1.7 + * License, v. 2.0. If a copy of the MPL was not distributed with this file,
     1.8 + * You can obtain one at http://mozilla.org/MPL/2.0/. */
     1.9 +
    1.10 +#include "GetFileOrDirectoryTask.h"
    1.11 +
    1.12 +#include "js/Value.h"
    1.13 +#include "mozilla/dom/Directory.h"
    1.14 +#include "mozilla/dom/FileSystemBase.h"
    1.15 +#include "mozilla/dom/FileSystemUtils.h"
    1.16 +#include "mozilla/dom/Promise.h"
    1.17 +#include "nsDOMFile.h"
    1.18 +#include "nsIFile.h"
    1.19 +#include "nsStringGlue.h"
    1.20 +
    1.21 +namespace mozilla {
    1.22 +namespace dom {
    1.23 +
    1.24 +GetFileOrDirectoryTask::GetFileOrDirectoryTask(
    1.25 +  FileSystemBase* aFileSystem,
    1.26 +  const nsAString& aTargetPath,
    1.27 +  bool aDirectoryOnly)
    1.28 +  : FileSystemTaskBase(aFileSystem)
    1.29 +  , mTargetRealPath(aTargetPath)
    1.30 +  , mIsDirectory(aDirectoryOnly)
    1.31 +{
    1.32 +  MOZ_ASSERT(NS_IsMainThread(), "Only call on main thread!");
    1.33 +  MOZ_ASSERT(aFileSystem);
    1.34 +  nsCOMPtr<nsIGlobalObject> globalObject =
    1.35 +    do_QueryInterface(aFileSystem->GetWindow());
    1.36 +  if (!globalObject) {
    1.37 +    return;
    1.38 +  }
    1.39 +  mPromise = new Promise(globalObject);
    1.40 +}
    1.41 +
    1.42 +GetFileOrDirectoryTask::GetFileOrDirectoryTask(
    1.43 +  FileSystemBase* aFileSystem,
    1.44 +  const FileSystemGetFileOrDirectoryParams& aParam,
    1.45 +  FileSystemRequestParent* aParent)
    1.46 +  : FileSystemTaskBase(aFileSystem, aParam, aParent)
    1.47 +  , mIsDirectory(false)
    1.48 +{
    1.49 +  MOZ_ASSERT(FileSystemUtils::IsParentProcess(),
    1.50 +             "Only call from parent process!");
    1.51 +  MOZ_ASSERT(NS_IsMainThread(), "Only call on main thread!");
    1.52 +  MOZ_ASSERT(aFileSystem);
    1.53 +  mTargetRealPath = aParam.realPath();
    1.54 +}
    1.55 +
    1.56 +GetFileOrDirectoryTask::~GetFileOrDirectoryTask()
    1.57 +{
    1.58 +  MOZ_ASSERT(!mPromise || NS_IsMainThread(),
    1.59 +             "mPromise should be released on main thread!");
    1.60 +}
    1.61 +
    1.62 +already_AddRefed<Promise>
    1.63 +GetFileOrDirectoryTask::GetPromise()
    1.64 +{
    1.65 +  MOZ_ASSERT(NS_IsMainThread(), "Only call on main thread!");
    1.66 +  return nsRefPtr<Promise>(mPromise).forget();
    1.67 +}
    1.68 +
    1.69 +FileSystemParams
    1.70 +GetFileOrDirectoryTask::GetRequestParams(const nsString& aFileSystem) const
    1.71 +{
    1.72 +  MOZ_ASSERT(NS_IsMainThread(), "Only call on main thread!");
    1.73 +  return FileSystemGetFileOrDirectoryParams(aFileSystem, mTargetRealPath);
    1.74 +}
    1.75 +
    1.76 +FileSystemResponseValue
    1.77 +GetFileOrDirectoryTask::GetSuccessRequestResult() const
    1.78 +{
    1.79 +  MOZ_ASSERT(NS_IsMainThread(), "Only call on main thread!");
    1.80 +  if (mIsDirectory) {
    1.81 +    return FileSystemDirectoryResponse(mTargetRealPath);
    1.82 +  }
    1.83 +  BlobParent* actor = GetBlobParent(mTargetFile);
    1.84 +  if (!actor) {
    1.85 +    return FileSystemErrorResponse(NS_ERROR_DOM_FILESYSTEM_UNKNOWN_ERR);
    1.86 +  }
    1.87 +  FileSystemFileResponse response;
    1.88 +  response.blobParent() = actor;
    1.89 +  return response;
    1.90 +}
    1.91 +
    1.92 +void
    1.93 +GetFileOrDirectoryTask::SetSuccessRequestResult(const FileSystemResponseValue& aValue)
    1.94 +{
    1.95 +  MOZ_ASSERT(NS_IsMainThread(), "Only call on main thread!");
    1.96 +  switch (aValue.type()) {
    1.97 +    case FileSystemResponseValue::TFileSystemFileResponse: {
    1.98 +      FileSystemFileResponse r = aValue;
    1.99 +      BlobChild* actor = static_cast<BlobChild*>(r.blobChild());
   1.100 +      nsCOMPtr<nsIDOMBlob> blob = actor->GetBlob();
   1.101 +      mTargetFile = do_QueryInterface(blob);
   1.102 +      mIsDirectory = false;
   1.103 +      break;
   1.104 +    }
   1.105 +    case FileSystemResponseValue::TFileSystemDirectoryResponse: {
   1.106 +      FileSystemDirectoryResponse r = aValue;
   1.107 +      mTargetRealPath = r.realPath();
   1.108 +      mIsDirectory = true;
   1.109 +      break;
   1.110 +    }
   1.111 +    default: {
   1.112 +      NS_RUNTIMEABORT("not reached");
   1.113 +      break;
   1.114 +    }
   1.115 +  }
   1.116 +}
   1.117 +
   1.118 +nsresult
   1.119 +GetFileOrDirectoryTask::Work()
   1.120 +{
   1.121 +  MOZ_ASSERT(FileSystemUtils::IsParentProcess(),
   1.122 +             "Only call from parent process!");
   1.123 +  MOZ_ASSERT(!NS_IsMainThread(), "Only call on worker thread!");
   1.124 +
   1.125 +  if (mFileSystem->IsShutdown()) {
   1.126 +    return NS_ERROR_FAILURE;
   1.127 +  }
   1.128 +
   1.129 +  // Whether we want to get the root directory.
   1.130 +  bool getRoot = mTargetRealPath.IsEmpty();
   1.131 +
   1.132 +  nsCOMPtr<nsIFile> file = mFileSystem->GetLocalFile(mTargetRealPath);
   1.133 +  if (!file) {
   1.134 +    return NS_ERROR_DOM_FILESYSTEM_INVALID_PATH_ERR;
   1.135 +  }
   1.136 +
   1.137 +  bool exists;
   1.138 +  nsresult rv = file->Exists(&exists);
   1.139 +  if (NS_WARN_IF(NS_FAILED(rv))) {
   1.140 +    return rv;
   1.141 +  }
   1.142 +
   1.143 +  if (!exists) {
   1.144 +    if (!getRoot) {
   1.145 +      return NS_ERROR_DOM_FILE_NOT_FOUND_ERR;
   1.146 +    }
   1.147 +
   1.148 +    // If the root directory doesn't exit, create it.
   1.149 +    rv = file->Create(nsIFile::DIRECTORY_TYPE, 0777);
   1.150 +    if (NS_WARN_IF(NS_FAILED(rv))) {
   1.151 +      return rv;
   1.152 +    }
   1.153 +  }
   1.154 +
   1.155 +  // Get isDirectory.
   1.156 +  rv = file->IsDirectory(&mIsDirectory);
   1.157 +  if (NS_WARN_IF(NS_FAILED(rv))) {
   1.158 +    return rv;
   1.159 +  }
   1.160 +
   1.161 +  if (mIsDirectory) {
   1.162 +    return NS_OK;
   1.163 +  }
   1.164 +
   1.165 +  // Check if the root is a directory.
   1.166 +  if (getRoot) {
   1.167 +    return NS_ERROR_DOM_FILESYSTEM_TYPE_MISMATCH_ERR;
   1.168 +  }
   1.169 +
   1.170 +  bool isFile;
   1.171 +  // Get isFile
   1.172 +  rv = file->IsFile(&isFile);
   1.173 +  if (NS_WARN_IF(NS_FAILED(rv))) {
   1.174 +    return rv;
   1.175 +  }
   1.176 +
   1.177 +  if (!isFile) {
   1.178 +    // Neither directory or file.
   1.179 +    return NS_ERROR_DOM_FILESYSTEM_TYPE_MISMATCH_ERR;
   1.180 +  }
   1.181 +
   1.182 +  if (!mFileSystem->IsSafeFile(file)) {
   1.183 +    return NS_ERROR_DOM_SECURITY_ERR;
   1.184 +  }
   1.185 +
   1.186 +  mTargetFile = new nsDOMFileFile(file);
   1.187 +
   1.188 +  return NS_OK;
   1.189 +}
   1.190 +
   1.191 +void
   1.192 +GetFileOrDirectoryTask::HandlerCallback()
   1.193 +{
   1.194 +  MOZ_ASSERT(NS_IsMainThread(), "Only call on main thread!");
   1.195 +  if (mFileSystem->IsShutdown()) {
   1.196 +    mPromise = nullptr;
   1.197 +    return;
   1.198 +  }
   1.199 +
   1.200 +  if (HasError()) {
   1.201 +    nsRefPtr<DOMError> domError = new DOMError(mFileSystem->GetWindow(),
   1.202 +      mErrorValue);
   1.203 +    mPromise->MaybeReject(domError);
   1.204 +    mPromise = nullptr;
   1.205 +    return;
   1.206 +  }
   1.207 +
   1.208 +  if (mIsDirectory) {
   1.209 +    nsRefPtr<Directory> dir = new Directory(mFileSystem, mTargetRealPath);
   1.210 +    mPromise->MaybeResolve(dir);
   1.211 +    mPromise = nullptr;
   1.212 +    return;
   1.213 +  }
   1.214 +
   1.215 +  mPromise->MaybeResolve(mTargetFile);
   1.216 +  mPromise = nullptr;
   1.217 +}
   1.218 +
   1.219 +void
   1.220 +GetFileOrDirectoryTask::GetPermissionAccessType(nsCString& aAccess) const
   1.221 +{
   1.222 +  aAccess.AssignLiteral("read");
   1.223 +}
   1.224 +
   1.225 +} // namespace dom
   1.226 +} // namespace mozilla

mercurial