| 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/fileapi/local_file_util.h" | |
| 6 | |
| 7 #include "base/file_util.h" | |
| 8 #include "base/files/file_util_proxy.h" | |
| 9 #include "googleurl/src/gurl.h" | |
| 10 #include "webkit/browser/fileapi/file_system_mount_point_provider.h" | |
| 11 #include "webkit/fileapi/file_system_context.h" | |
| 12 #include "webkit/fileapi/file_system_operation_context.h" | |
| 13 #include "webkit/fileapi/file_system_types.h" | |
| 14 #include "webkit/fileapi/file_system_url.h" | |
| 15 #include "webkit/fileapi/file_system_util.h" | |
| 16 #include "webkit/fileapi/native_file_util.h" | |
| 17 | |
| 18 namespace fileapi { | |
| 19 | |
| 20 using base::PlatformFileError; | |
| 21 | |
| 22 class LocalFileEnumerator : public FileSystemFileUtil::AbstractFileEnumerator { | |
| 23 public: | |
| 24 LocalFileEnumerator(const base::FilePath& platform_root_path, | |
| 25 const base::FilePath& virtual_root_path, | |
| 26 int file_type) | |
| 27 : file_enum_(platform_root_path, false /* recursive */, file_type), | |
| 28 platform_root_path_(platform_root_path), | |
| 29 virtual_root_path_(virtual_root_path) { | |
| 30 #if defined(OS_WIN) | |
| 31 memset(&file_util_info_, 0, sizeof(file_util_info_)); | |
| 32 #endif // defined(OS_WIN) | |
| 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 file_util::FileEnumerator file_enum_; | |
| 44 file_util::FileEnumerator::FindInfo 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() && file_util::IsLink(next)) | |
| 53 next = file_enum_.Next(); | |
| 54 if (next.empty()) | |
| 55 return next; | |
| 56 file_enum_.GetFindInfo(&file_util_info_); | |
| 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::FileEnumerator::GetFilesize(file_util_info_); | |
| 65 } | |
| 66 | |
| 67 base::Time LocalFileEnumerator::LastModifiedTime() { | |
| 68 return file_util::FileEnumerator::GetLastModifiedTime(file_util_info_); | |
| 69 } | |
| 70 | |
| 71 bool LocalFileEnumerator::IsDirectory() { | |
| 72 return file_util::FileEnumerator::IsDirectory(file_util_info_); | |
| 73 } | |
| 74 | |
| 75 LocalFileUtil::LocalFileUtil() { | |
| 76 } | |
| 77 | |
| 78 LocalFileUtil::~LocalFileUtil() { | |
| 79 } | |
| 80 | |
| 81 PlatformFileError LocalFileUtil::CreateOrOpen( | |
| 82 FileSystemOperationContext* context, | |
| 83 const FileSystemURL& url, int file_flags, | |
| 84 base::PlatformFile* file_handle, bool* created) { | |
| 85 *created = false; | |
| 86 base::FilePath file_path; | |
| 87 PlatformFileError error = GetLocalFilePath(context, url, &file_path); | |
| 88 if (error != base::PLATFORM_FILE_OK) | |
| 89 return error; | |
| 90 // Disallow opening files in symlinked paths. | |
| 91 if (file_util::IsLink(file_path)) | |
| 92 return base::PLATFORM_FILE_ERROR_NOT_FOUND; | |
| 93 return NativeFileUtil::CreateOrOpen( | |
| 94 file_path, file_flags, file_handle, created); | |
| 95 } | |
| 96 | |
| 97 PlatformFileError LocalFileUtil::Close(FileSystemOperationContext* context, | |
| 98 base::PlatformFile file) { | |
| 99 return NativeFileUtil::Close(file); | |
| 100 } | |
| 101 | |
| 102 PlatformFileError LocalFileUtil::EnsureFileExists( | |
| 103 FileSystemOperationContext* context, | |
| 104 const FileSystemURL& url, | |
| 105 bool* created) { | |
| 106 base::FilePath file_path; | |
| 107 PlatformFileError error = GetLocalFilePath(context, url, &file_path); | |
| 108 if (error != base::PLATFORM_FILE_OK) | |
| 109 return error; | |
| 110 return NativeFileUtil::EnsureFileExists(file_path, created); | |
| 111 } | |
| 112 | |
| 113 PlatformFileError LocalFileUtil::CreateDirectory( | |
| 114 FileSystemOperationContext* context, | |
| 115 const FileSystemURL& url, | |
| 116 bool exclusive, | |
| 117 bool recursive) { | |
| 118 base::FilePath file_path; | |
| 119 PlatformFileError error = GetLocalFilePath(context, url, &file_path); | |
| 120 if (error != base::PLATFORM_FILE_OK) | |
| 121 return error; | |
| 122 return NativeFileUtil::CreateDirectory(file_path, exclusive, recursive); | |
| 123 } | |
| 124 | |
| 125 PlatformFileError LocalFileUtil::GetFileInfo( | |
| 126 FileSystemOperationContext* context, | |
| 127 const FileSystemURL& url, | |
| 128 base::PlatformFileInfo* file_info, | |
| 129 base::FilePath* platform_file_path) { | |
| 130 base::FilePath file_path; | |
| 131 PlatformFileError error = GetLocalFilePath(context, url, &file_path); | |
| 132 if (error != base::PLATFORM_FILE_OK) | |
| 133 return error; | |
| 134 // We should not follow symbolic links in sandboxed file system. | |
| 135 if (file_util::IsLink(file_path)) | |
| 136 return base::PLATFORM_FILE_ERROR_NOT_FOUND; | |
| 137 error = NativeFileUtil::GetFileInfo(file_path, file_info); | |
| 138 if (error == base::PLATFORM_FILE_OK) | |
| 139 *platform_file_path = file_path; | |
| 140 return error; | |
| 141 } | |
| 142 | |
| 143 scoped_ptr<FileSystemFileUtil::AbstractFileEnumerator> LocalFileUtil:: | |
| 144 CreateFileEnumerator( | |
| 145 FileSystemOperationContext* context, | |
| 146 const FileSystemURL& root_url) { | |
| 147 base::FilePath file_path; | |
| 148 if (GetLocalFilePath(context, root_url, &file_path) != | |
| 149 base::PLATFORM_FILE_OK) { | |
| 150 return make_scoped_ptr(new EmptyFileEnumerator) | |
| 151 .PassAs<FileSystemFileUtil::AbstractFileEnumerator>(); | |
| 152 } | |
| 153 return make_scoped_ptr(new LocalFileEnumerator( | |
| 154 file_path, root_url.path(), | |
| 155 file_util::FileEnumerator::FILES | | |
| 156 file_util::FileEnumerator::DIRECTORIES)) | |
| 157 .PassAs<FileSystemFileUtil::AbstractFileEnumerator>(); | |
| 158 } | |
| 159 | |
| 160 PlatformFileError LocalFileUtil::GetLocalFilePath( | |
| 161 FileSystemOperationContext* context, | |
| 162 const FileSystemURL& url, | |
| 163 base::FilePath* local_file_path) { | |
| 164 FileSystemMountPointProvider* provider = | |
| 165 context->file_system_context()->GetMountPointProvider(url.type()); | |
| 166 DCHECK(provider); | |
| 167 base::FilePath root = provider->GetFileSystemRootPathOnFileThread(url, false); | |
| 168 if (root.empty()) | |
| 169 return base::PLATFORM_FILE_ERROR_NOT_FOUND; | |
| 170 *local_file_path = root.Append(url.path()); | |
| 171 return base::PLATFORM_FILE_OK; | |
| 172 } | |
| 173 | |
| 174 PlatformFileError LocalFileUtil::Touch( | |
| 175 FileSystemOperationContext* context, | |
| 176 const FileSystemURL& url, | |
| 177 const base::Time& last_access_time, | |
| 178 const base::Time& last_modified_time) { | |
| 179 base::FilePath file_path; | |
| 180 PlatformFileError error = GetLocalFilePath(context, url, &file_path); | |
| 181 if (error != base::PLATFORM_FILE_OK) | |
| 182 return error; | |
| 183 return NativeFileUtil::Touch(file_path, last_access_time, last_modified_time); | |
| 184 } | |
| 185 | |
| 186 PlatformFileError LocalFileUtil::Truncate( | |
| 187 FileSystemOperationContext* context, | |
| 188 const FileSystemURL& url, | |
| 189 int64 length) { | |
| 190 base::FilePath file_path; | |
| 191 PlatformFileError error = GetLocalFilePath(context, url, &file_path); | |
| 192 if (error != base::PLATFORM_FILE_OK) | |
| 193 return error; | |
| 194 return NativeFileUtil::Truncate(file_path, length); | |
| 195 } | |
| 196 | |
| 197 PlatformFileError LocalFileUtil::CopyOrMoveFile( | |
| 198 FileSystemOperationContext* context, | |
| 199 const FileSystemURL& src_url, | |
| 200 const FileSystemURL& dest_url, | |
| 201 bool copy) { | |
| 202 base::FilePath src_file_path; | |
| 203 PlatformFileError error = GetLocalFilePath(context, src_url, &src_file_path); | |
| 204 if (error != base::PLATFORM_FILE_OK) | |
| 205 return error; | |
| 206 | |
| 207 base::FilePath dest_file_path; | |
| 208 error = GetLocalFilePath(context, dest_url, &dest_file_path); | |
| 209 if (error != base::PLATFORM_FILE_OK) | |
| 210 return error; | |
| 211 | |
| 212 return NativeFileUtil::CopyOrMoveFile(src_file_path, dest_file_path, copy); | |
| 213 } | |
| 214 | |
| 215 PlatformFileError LocalFileUtil::CopyInForeignFile( | |
| 216 FileSystemOperationContext* context, | |
| 217 const base::FilePath& src_file_path, | |
| 218 const FileSystemURL& dest_url) { | |
| 219 if (src_file_path.empty()) | |
| 220 return base::PLATFORM_FILE_ERROR_INVALID_OPERATION; | |
| 221 | |
| 222 base::FilePath dest_file_path; | |
| 223 PlatformFileError error = | |
| 224 GetLocalFilePath(context, dest_url, &dest_file_path); | |
| 225 if (error != base::PLATFORM_FILE_OK) | |
| 226 return error; | |
| 227 return NativeFileUtil::CopyOrMoveFile(src_file_path, dest_file_path, true); | |
| 228 } | |
| 229 | |
| 230 PlatformFileError LocalFileUtil::DeleteFile( | |
| 231 FileSystemOperationContext* context, | |
| 232 const FileSystemURL& url) { | |
| 233 base::FilePath file_path; | |
| 234 PlatformFileError error = GetLocalFilePath(context, url, &file_path); | |
| 235 if (error != base::PLATFORM_FILE_OK) | |
| 236 return error; | |
| 237 return NativeFileUtil::DeleteFile(file_path); | |
| 238 } | |
| 239 | |
| 240 PlatformFileError LocalFileUtil::DeleteDirectory( | |
| 241 FileSystemOperationContext* context, | |
| 242 const FileSystemURL& url) { | |
| 243 base::FilePath file_path; | |
| 244 PlatformFileError error = GetLocalFilePath(context, url, &file_path); | |
| 245 if (error != base::PLATFORM_FILE_OK) | |
| 246 return error; | |
| 247 return NativeFileUtil::DeleteDirectory(file_path); | |
| 248 } | |
| 249 | |
| 250 webkit_blob::ScopedFile LocalFileUtil::CreateSnapshotFile( | |
| 251 FileSystemOperationContext* context, | |
| 252 const FileSystemURL& url, | |
| 253 base::PlatformFileError* error, | |
| 254 base::PlatformFileInfo* file_info, | |
| 255 base::FilePath* platform_path) { | |
| 256 DCHECK(file_info); | |
| 257 // We're just returning the local file information. | |
| 258 *error = GetFileInfo(context, url, file_info, platform_path); | |
| 259 if (*error == base::PLATFORM_FILE_OK && file_info->is_directory) | |
| 260 *error = base::PLATFORM_FILE_ERROR_NOT_A_FILE; | |
| 261 return webkit_blob::ScopedFile(); | |
| 262 } | |
| 263 | |
| 264 } // namespace fileapi | |
| OLD | NEW |