| OLD | NEW |
| (Empty) |
| 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/local_file_util.h" | |
| 6 | |
| 7 #include "base/file_util.h" | |
| 8 #include "base/files/file_enumerator.h" | |
| 9 #include "base/files/file_util_proxy.h" | |
| 10 #include "url/gurl.h" | |
| 11 #include "webkit/browser/fileapi/async_file_util_adapter.h" | |
| 12 #include "webkit/browser/fileapi/file_system_context.h" | |
| 13 #include "webkit/browser/fileapi/file_system_operation_context.h" | |
| 14 #include "webkit/browser/fileapi/file_system_url.h" | |
| 15 #include "webkit/browser/fileapi/native_file_util.h" | |
| 16 #include "webkit/common/fileapi/file_system_types.h" | |
| 17 #include "webkit/common/fileapi/file_system_util.h" | |
| 18 | |
| 19 namespace storage { | |
| 20 | |
| 21 AsyncFileUtil* AsyncFileUtil::CreateForLocalFileSystem() { | |
| 22 return new AsyncFileUtilAdapter(new LocalFileUtil()); | |
| 23 } | |
| 24 | |
| 25 class LocalFileEnumerator : public FileSystemFileUtil::AbstractFileEnumerator { | |
| 26 public: | |
| 27 LocalFileEnumerator(const base::FilePath& platform_root_path, | |
| 28 const base::FilePath& virtual_root_path, | |
| 29 int file_type) | |
| 30 : file_enum_(platform_root_path, false /* recursive */, file_type), | |
| 31 platform_root_path_(platform_root_path), | |
| 32 virtual_root_path_(virtual_root_path) { | |
| 33 } | |
| 34 | |
| 35 virtual ~LocalFileEnumerator() {} | |
| 36 | |
| 37 virtual base::FilePath Next() OVERRIDE; | |
| 38 virtual int64 Size() OVERRIDE; | |
| 39 virtual base::Time LastModifiedTime() OVERRIDE; | |
| 40 virtual bool IsDirectory() OVERRIDE; | |
| 41 | |
| 42 private: | |
| 43 base::FileEnumerator file_enum_; | |
| 44 base::FileEnumerator::FileInfo file_util_info_; | |
| 45 base::FilePath platform_root_path_; | |
| 46 base::FilePath virtual_root_path_; | |
| 47 }; | |
| 48 | |
| 49 base::FilePath LocalFileEnumerator::Next() { | |
| 50 base::FilePath next = file_enum_.Next(); | |
| 51 // Don't return symlinks. | |
| 52 while (!next.empty() && base::IsLink(next)) | |
| 53 next = file_enum_.Next(); | |
| 54 if (next.empty()) | |
| 55 return next; | |
| 56 file_util_info_ = file_enum_.GetInfo(); | |
| 57 | |
| 58 base::FilePath path; | |
| 59 platform_root_path_.AppendRelativePath(next, &path); | |
| 60 return virtual_root_path_.Append(path); | |
| 61 } | |
| 62 | |
| 63 int64 LocalFileEnumerator::Size() { | |
| 64 return file_util_info_.GetSize(); | |
| 65 } | |
| 66 | |
| 67 base::Time LocalFileEnumerator::LastModifiedTime() { | |
| 68 return file_util_info_.GetLastModifiedTime(); | |
| 69 } | |
| 70 | |
| 71 bool LocalFileEnumerator::IsDirectory() { | |
| 72 return file_util_info_.IsDirectory(); | |
| 73 } | |
| 74 | |
| 75 LocalFileUtil::LocalFileUtil() {} | |
| 76 | |
| 77 LocalFileUtil::~LocalFileUtil() {} | |
| 78 | |
| 79 base::File LocalFileUtil::CreateOrOpen( | |
| 80 FileSystemOperationContext* context, | |
| 81 const FileSystemURL& url, int file_flags) { | |
| 82 base::FilePath file_path; | |
| 83 base::File::Error error = GetLocalFilePath(context, url, &file_path); | |
| 84 if (error != base::File::FILE_OK) | |
| 85 return base::File(error); | |
| 86 // Disallow opening files in symlinked paths. | |
| 87 if (base::IsLink(file_path)) | |
| 88 return base::File(base::File::FILE_ERROR_NOT_FOUND); | |
| 89 | |
| 90 return NativeFileUtil::CreateOrOpen(file_path, file_flags); | |
| 91 } | |
| 92 | |
| 93 base::File::Error LocalFileUtil::EnsureFileExists( | |
| 94 FileSystemOperationContext* context, | |
| 95 const FileSystemURL& url, | |
| 96 bool* created) { | |
| 97 base::FilePath file_path; | |
| 98 base::File::Error error = GetLocalFilePath(context, url, &file_path); | |
| 99 if (error != base::File::FILE_OK) | |
| 100 return error; | |
| 101 return NativeFileUtil::EnsureFileExists(file_path, created); | |
| 102 } | |
| 103 | |
| 104 base::File::Error LocalFileUtil::CreateDirectory( | |
| 105 FileSystemOperationContext* context, | |
| 106 const FileSystemURL& url, | |
| 107 bool exclusive, | |
| 108 bool recursive) { | |
| 109 base::FilePath file_path; | |
| 110 base::File::Error error = GetLocalFilePath(context, url, &file_path); | |
| 111 if (error != base::File::FILE_OK) | |
| 112 return error; | |
| 113 return NativeFileUtil::CreateDirectory(file_path, exclusive, recursive); | |
| 114 } | |
| 115 | |
| 116 base::File::Error LocalFileUtil::GetFileInfo( | |
| 117 FileSystemOperationContext* context, | |
| 118 const FileSystemURL& url, | |
| 119 base::File::Info* file_info, | |
| 120 base::FilePath* platform_file_path) { | |
| 121 base::FilePath file_path; | |
| 122 base::File::Error error = GetLocalFilePath(context, url, &file_path); | |
| 123 if (error != base::File::FILE_OK) | |
| 124 return error; | |
| 125 // We should not follow symbolic links in sandboxed file system. | |
| 126 if (base::IsLink(file_path)) | |
| 127 return base::File::FILE_ERROR_NOT_FOUND; | |
| 128 | |
| 129 error = NativeFileUtil::GetFileInfo(file_path, file_info); | |
| 130 if (error == base::File::FILE_OK) | |
| 131 *platform_file_path = file_path; | |
| 132 return error; | |
| 133 } | |
| 134 | |
| 135 scoped_ptr<FileSystemFileUtil::AbstractFileEnumerator> LocalFileUtil:: | |
| 136 CreateFileEnumerator( | |
| 137 FileSystemOperationContext* context, | |
| 138 const FileSystemURL& root_url) { | |
| 139 base::FilePath file_path; | |
| 140 if (GetLocalFilePath(context, root_url, &file_path) != | |
| 141 base::File::FILE_OK) { | |
| 142 return make_scoped_ptr(new EmptyFileEnumerator) | |
| 143 .PassAs<FileSystemFileUtil::AbstractFileEnumerator>(); | |
| 144 } | |
| 145 return make_scoped_ptr(new LocalFileEnumerator( | |
| 146 file_path, root_url.path(), | |
| 147 base::FileEnumerator::FILES | base::FileEnumerator::DIRECTORIES)) | |
| 148 .PassAs<FileSystemFileUtil::AbstractFileEnumerator>(); | |
| 149 } | |
| 150 | |
| 151 base::File::Error LocalFileUtil::GetLocalFilePath( | |
| 152 FileSystemOperationContext* context, | |
| 153 const FileSystemURL& url, | |
| 154 base::FilePath* local_file_path) { | |
| 155 DCHECK(local_file_path); | |
| 156 DCHECK(url.is_valid()); | |
| 157 if (url.path().empty()) { | |
| 158 // Root direcory case, which should not be accessed. | |
| 159 return base::File::FILE_ERROR_ACCESS_DENIED; | |
| 160 } | |
| 161 *local_file_path = url.path(); | |
| 162 return base::File::FILE_OK; | |
| 163 } | |
| 164 | |
| 165 base::File::Error LocalFileUtil::Touch( | |
| 166 FileSystemOperationContext* context, | |
| 167 const FileSystemURL& url, | |
| 168 const base::Time& last_access_time, | |
| 169 const base::Time& last_modified_time) { | |
| 170 base::FilePath file_path; | |
| 171 base::File::Error error = GetLocalFilePath(context, url, &file_path); | |
| 172 if (error != base::File::FILE_OK) | |
| 173 return error; | |
| 174 return NativeFileUtil::Touch(file_path, last_access_time, last_modified_time); | |
| 175 } | |
| 176 | |
| 177 base::File::Error LocalFileUtil::Truncate( | |
| 178 FileSystemOperationContext* context, | |
| 179 const FileSystemURL& url, | |
| 180 int64 length) { | |
| 181 base::FilePath file_path; | |
| 182 base::File::Error error = GetLocalFilePath(context, url, &file_path); | |
| 183 if (error != base::File::FILE_OK) | |
| 184 return error; | |
| 185 return NativeFileUtil::Truncate(file_path, length); | |
| 186 } | |
| 187 | |
| 188 base::File::Error LocalFileUtil::CopyOrMoveFile( | |
| 189 FileSystemOperationContext* context, | |
| 190 const FileSystemURL& src_url, | |
| 191 const FileSystemURL& dest_url, | |
| 192 CopyOrMoveOption option, | |
| 193 bool copy) { | |
| 194 base::FilePath src_file_path; | |
| 195 base::File::Error error = GetLocalFilePath(context, src_url, &src_file_path); | |
| 196 if (error != base::File::FILE_OK) | |
| 197 return error; | |
| 198 | |
| 199 base::FilePath dest_file_path; | |
| 200 error = GetLocalFilePath(context, dest_url, &dest_file_path); | |
| 201 if (error != base::File::FILE_OK) | |
| 202 return error; | |
| 203 | |
| 204 return NativeFileUtil::CopyOrMoveFile( | |
| 205 src_file_path, | |
| 206 dest_file_path, | |
| 207 option, | |
| 208 storage::NativeFileUtil::CopyOrMoveModeForDestination(dest_url, copy)); | |
| 209 } | |
| 210 | |
| 211 base::File::Error LocalFileUtil::CopyInForeignFile( | |
| 212 FileSystemOperationContext* context, | |
| 213 const base::FilePath& src_file_path, | |
| 214 const FileSystemURL& dest_url) { | |
| 215 if (src_file_path.empty()) | |
| 216 return base::File::FILE_ERROR_INVALID_OPERATION; | |
| 217 | |
| 218 base::FilePath dest_file_path; | |
| 219 base::File::Error error = | |
| 220 GetLocalFilePath(context, dest_url, &dest_file_path); | |
| 221 if (error != base::File::FILE_OK) | |
| 222 return error; | |
| 223 return NativeFileUtil::CopyOrMoveFile( | |
| 224 src_file_path, | |
| 225 dest_file_path, | |
| 226 FileSystemOperation::OPTION_NONE, | |
| 227 storage::NativeFileUtil::CopyOrMoveModeForDestination(dest_url, | |
| 228 true /* copy */)); | |
| 229 } | |
| 230 | |
| 231 base::File::Error LocalFileUtil::DeleteFile( | |
| 232 FileSystemOperationContext* context, | |
| 233 const FileSystemURL& url) { | |
| 234 base::FilePath file_path; | |
| 235 base::File::Error error = GetLocalFilePath(context, url, &file_path); | |
| 236 if (error != base::File::FILE_OK) | |
| 237 return error; | |
| 238 return NativeFileUtil::DeleteFile(file_path); | |
| 239 } | |
| 240 | |
| 241 base::File::Error LocalFileUtil::DeleteDirectory( | |
| 242 FileSystemOperationContext* context, | |
| 243 const FileSystemURL& url) { | |
| 244 base::FilePath file_path; | |
| 245 base::File::Error error = GetLocalFilePath(context, url, &file_path); | |
| 246 if (error != base::File::FILE_OK) | |
| 247 return error; | |
| 248 return NativeFileUtil::DeleteDirectory(file_path); | |
| 249 } | |
| 250 | |
| 251 storage::ScopedFile LocalFileUtil::CreateSnapshotFile( | |
| 252 FileSystemOperationContext* context, | |
| 253 const FileSystemURL& url, | |
| 254 base::File::Error* error, | |
| 255 base::File::Info* file_info, | |
| 256 base::FilePath* platform_path) { | |
| 257 DCHECK(file_info); | |
| 258 // We're just returning the local file information. | |
| 259 *error = GetFileInfo(context, url, file_info, platform_path); | |
| 260 if (*error == base::File::FILE_OK && file_info->is_directory) | |
| 261 *error = base::File::FILE_ERROR_NOT_A_FILE; | |
| 262 return storage::ScopedFile(); | |
| 263 } | |
| 264 | |
| 265 } // namespace storage | |
| OLD | NEW |