1// Copyright 2013 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/dragged_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 18namespace fileapi { 19 20typedef IsolatedContext::MountPointInfo FileInfo; 21 22namespace { 23 24// Simply enumerate each path from a given fileinfo set. 25// Used to enumerate top-level paths of an isolated filesystem. 26class SetFileEnumerator : public FileSystemFileUtil::AbstractFileEnumerator { 27 public: 28 explicit SetFileEnumerator(const std::vector<FileInfo>& files) 29 : files_(files) { 30 file_iter_ = files_.begin(); 31 } 32 virtual ~SetFileEnumerator() {} 33 34 // AbstractFileEnumerator overrides. 35 virtual base::FilePath Next() OVERRIDE { 36 if (file_iter_ == files_.end()) 37 return base::FilePath(); 38 base::FilePath platform_file = (file_iter_++)->path; 39 NativeFileUtil::GetFileInfo(platform_file, &file_info_); 40 return platform_file; 41 } 42 virtual int64 Size() OVERRIDE { return file_info_.size; } 43 virtual bool IsDirectory() OVERRIDE { return file_info_.is_directory; } 44 virtual base::Time LastModifiedTime() OVERRIDE { 45 return file_info_.last_modified; 46 } 47 48 private: 49 std::vector<FileInfo> files_; 50 std::vector<FileInfo>::const_iterator file_iter_; 51 base::File::Info file_info_; 52}; 53 54} // namespace 55 56//------------------------------------------------------------------------- 57 58DraggedFileUtil::DraggedFileUtil() {} 59 60base::File::Error DraggedFileUtil::GetFileInfo( 61 FileSystemOperationContext* context, 62 const FileSystemURL& url, 63 base::File::Info* file_info, 64 base::FilePath* platform_path) { 65 DCHECK(file_info); 66 std::string filesystem_id; 67 DCHECK(url.is_valid()); 68 if (url.path().empty()) { 69 // The root directory case. 70 // For now we leave three time fields (modified/accessed/creation time) 71 // NULL as it is not really clear what to be set for this virtual directory. 72 // TODO(kinuko): Maybe we want to set the time when this filesystem is 73 // created (i.e. when the files/directories are dropped). 74 file_info->is_directory = true; 75 file_info->is_symbolic_link = false; 76 file_info->size = 0; 77 return base::File::FILE_OK; 78 } 79 base::File::Error error = 80 NativeFileUtil::GetFileInfo(url.path(), file_info); 81 if (base::IsLink(url.path()) && !base::FilePath().IsParent(url.path())) { 82 // Don't follow symlinks unless it's the one that are selected by the user. 83 return base::File::FILE_ERROR_NOT_FOUND; 84 } 85 if (error == base::File::FILE_OK) 86 *platform_path = url.path(); 87 return error; 88} 89 90scoped_ptr<FileSystemFileUtil::AbstractFileEnumerator> 91 DraggedFileUtil::CreateFileEnumerator( 92 FileSystemOperationContext* context, 93 const FileSystemURL& root) { 94 DCHECK(root.is_valid()); 95 if (!root.path().empty()) 96 return LocalFileUtil::CreateFileEnumerator(context, root); 97 98 // Root path case. 99 std::vector<FileInfo> toplevels; 100 IsolatedContext::GetInstance()->GetDraggedFileInfo( 101 root.filesystem_id(), &toplevels); 102 return scoped_ptr<AbstractFileEnumerator>(new SetFileEnumerator(toplevels)); 103} 104 105} // namespace fileapi 106