Home | History | Annotate | Download | only in fileapi
      1 // Copyright (c) 2012 The Chromium Authors. All rights reserved.
      2 // Use of this source code is governed by a BSD-style license that can be
      3 // found in the LICENSE file.
      4 
      5 #include "webkit/browser/fileapi/isolated_file_util.h"
      6 
      7 #include <string>
      8 #include <vector>
      9 
     10 #include "base/file_util.h"
     11 #include "webkit/browser/fileapi/file_system_context.h"
     12 #include "webkit/browser/fileapi/file_system_operation_context.h"
     13 #include "webkit/browser/fileapi/file_system_url.h"
     14 #include "webkit/browser/fileapi/isolated_context.h"
     15 #include "webkit/browser/fileapi/native_file_util.h"
     16 #include "webkit/common/blob/shareable_file_reference.h"
     17 
     18 using base::PlatformFileError;
     19 using base::PlatformFileInfo;
     20 
     21 namespace fileapi {
     22 
     23 typedef IsolatedContext::MountPointInfo FileInfo;
     24 
     25 namespace {
     26 
     27 // Simply enumerate each path from a given fileinfo set.
     28 // Used to enumerate top-level paths of an isolated filesystem.
     29 class SetFileEnumerator : public FileSystemFileUtil::AbstractFileEnumerator {
     30  public:
     31   explicit SetFileEnumerator(const std::vector<FileInfo>& files)
     32       : files_(files) {
     33     file_iter_ = files_.begin();
     34   }
     35   virtual ~SetFileEnumerator() {}
     36 
     37   // AbstractFileEnumerator overrides.
     38   virtual base::FilePath Next() OVERRIDE {
     39     if (file_iter_ == files_.end())
     40       return base::FilePath();
     41     base::FilePath platform_file = (file_iter_++)->path;
     42     NativeFileUtil::GetFileInfo(platform_file, &file_info_);
     43     return platform_file;
     44   }
     45   virtual int64 Size() OVERRIDE { return file_info_.size; }
     46   virtual bool IsDirectory() OVERRIDE { return file_info_.is_directory; }
     47   virtual base::Time LastModifiedTime() OVERRIDE {
     48     return file_info_.last_modified;
     49   }
     50 
     51  private:
     52   std::vector<FileInfo> files_;
     53   std::vector<FileInfo>::const_iterator file_iter_;
     54   base::PlatformFileInfo file_info_;
     55 };
     56 
     57 }  // namespace
     58 
     59 //-------------------------------------------------------------------------
     60 
     61 IsolatedFileUtil::IsolatedFileUtil() {}
     62 
     63 PlatformFileError IsolatedFileUtil::GetLocalFilePath(
     64     FileSystemOperationContext* context,
     65     const FileSystemURL& url,
     66     base::FilePath* local_file_path) {
     67   DCHECK(local_file_path);
     68   DCHECK(url.is_valid());
     69   if (url.path().empty()) {
     70     // Root direcory case, which should not be accessed.
     71     return base::PLATFORM_FILE_ERROR_ACCESS_DENIED;
     72   }
     73   *local_file_path = url.path();
     74   return base::PLATFORM_FILE_OK;
     75 }
     76 
     77 //-------------------------------------------------------------------------
     78 
     79 DraggedFileUtil::DraggedFileUtil() {}
     80 
     81 PlatformFileError DraggedFileUtil::GetFileInfo(
     82     FileSystemOperationContext* context,
     83     const FileSystemURL& url,
     84     PlatformFileInfo* file_info,
     85     base::FilePath* platform_path) {
     86   DCHECK(file_info);
     87   std::string filesystem_id;
     88   DCHECK(url.is_valid());
     89   if (url.path().empty()) {
     90     // The root directory case.
     91     // For now we leave three time fields (modified/accessed/creation time)
     92     // NULL as it is not really clear what to be set for this virtual directory.
     93     // TODO(kinuko): Maybe we want to set the time when this filesystem is
     94     // created (i.e. when the files/directories are dropped).
     95     file_info->is_directory = true;
     96     file_info->is_symbolic_link = false;
     97     file_info->size = 0;
     98     return base::PLATFORM_FILE_OK;
     99   }
    100   base::PlatformFileError error =
    101       NativeFileUtil::GetFileInfo(url.path(), file_info);
    102   if (file_util::IsLink(url.path()) && !base::FilePath().IsParent(url.path())) {
    103     // Don't follow symlinks unless it's the one that are selected by the user.
    104     return base::PLATFORM_FILE_ERROR_NOT_FOUND;
    105   }
    106   if (error == base::PLATFORM_FILE_OK)
    107     *platform_path = url.path();
    108   return error;
    109 }
    110 
    111 scoped_ptr<FileSystemFileUtil::AbstractFileEnumerator>
    112     DraggedFileUtil::CreateFileEnumerator(
    113         FileSystemOperationContext* context,
    114         const FileSystemURL& root) {
    115   DCHECK(root.is_valid());
    116   if (!root.path().empty())
    117     return LocalFileUtil::CreateFileEnumerator(context, root);
    118 
    119   // Root path case.
    120   std::vector<FileInfo> toplevels;
    121   IsolatedContext::GetInstance()->GetDraggedFileInfo(
    122       root.filesystem_id(), &toplevels);
    123   return scoped_ptr<AbstractFileEnumerator>(new SetFileEnumerator(toplevels));
    124 }
    125 
    126 }  // namespace fileapi
    127