Chromium Code Reviews
chromiumcodereview-hr@appspot.gserviceaccount.com (chromiumcodereview-hr) | Please choose your nickname with Settings | Help | Chromium Project | Gerrit Changes | Sign out
(8)

Side by Side Diff: webkit/fileapi/file_system_file_util_base.cc

Issue 6471019: Stackable file_util for FileAPIs. Sample code for discussion. Incomplete. Cannot be compiled. (Closed) Base URL: http://git.chromium.org/git/chromium.git@trunk
Patch Set: Fixed the Patch Set 3 before reflecting the comments. -UtilBase can be built and works. Created 9 years, 10 months ago
Use n/p to move between diff chunks; N/P to move between comments. Draft comments are only viewable by you.
Jump to:
View unified diff | Download patch | Annotate | Revision Log
OLDNEW
(Empty)
1 // Copyright (c) 2011 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/file_system_file_util_base.h"
6
7 #include "base/file_util.h"
8
9 namespace {
10
11 // Performs common checks for move and copy.
12 // This also removes the destination directory if it's non-empty and all other
13 // checks are passed (so that the copy/move correctly overwrites the
14 // destination).
15 static base::PlatformFileError PerformCommonCheckAndPreparationForMoveAndCopy(
16 const FilePath& src_file_path,
17 const FilePath& dest_file_path) {
18 // Exits earlier if the source path does not exist.
19 if (!file_util::PathExists(src_file_path))
20 return base::PLATFORM_FILE_ERROR_NOT_FOUND;
21
22 // The parent of the |dest_file_path| does not exist.
23 if (!file_util::DirectoryExists(dest_file_path.DirName()))
24 return base::PLATFORM_FILE_ERROR_NOT_FOUND;
25
26 // It is an error to try to copy/move an entry into its child.
27 if (src_file_path.IsParent(dest_file_path))
28 return base::PLATFORM_FILE_ERROR_INVALID_OPERATION;
29
30 // Now it is ok to return if the |dest_file_path| does not exist.
31 if (!file_util::PathExists(dest_file_path))
32 return base::PLATFORM_FILE_OK;
33
34 // |src_file_path| exists and is a directory.
35 // |dest_file_path| exists and is a file.
36 bool src_is_directory = file_util::DirectoryExists(src_file_path);
37 bool dest_is_directory = file_util::DirectoryExists(dest_file_path);
38 if (src_is_directory && !dest_is_directory)
39 return base::PLATFORM_FILE_ERROR_NOT_A_DIRECTORY;
40
41 // |src_file_path| exists and is a file.
42 // |dest_file_path| exists and is a directory.
43 if (!src_is_directory && dest_is_directory)
44 return base::PLATFORM_FILE_ERROR_NOT_A_FILE;
45
46 // It is an error to copy/move an entry into the same path.
47 if (src_file_path.value() == dest_file_path.value())
48 return base::PLATFORM_FILE_ERROR_EXISTS;
49
50 if (dest_is_directory) {
51 // It is an error to copy/move an entry to a non-empty directory.
52 // Otherwise the copy/move attempt must overwrite the destination, but
53 // the file_util's Copy or Move method doesn't perform overwrite
54 // on all platforms, so we delete the destination directory here.
55 // TODO(kinuko): may be better to change the file_util::{Copy,Move}.
56 if (!file_util::Delete(dest_file_path, false /* recursive */)) {
57 if (!file_util::IsDirectoryEmpty(dest_file_path))
58 return base::PLATFORM_FILE_ERROR_NOT_EMPTY;
59 return base::PLATFORM_FILE_ERROR_FAILED;
60 }
61 }
62 return base::PLATFORM_FILE_OK;
63 }
64
65 } // namespace
66
67 namespace fileapi {
68
69 // static
70 FileSystemFileUtilBase* FileSystemFileUtilBase::GetInstance() {
71 return Singleton<FileSystemFileUtilBase>::get();
72 }
73
74 base::PlatformFileError FileSystemFileUtilBase::CreateOrOpen(
75 FileSystemOperationContext* fs_context,
76 const FilePath& file_path,
77 int file_flags,
78 base::PlatformFile& file_handle,
79 bool& created) {
80 if (!file_util::DirectoryExists(file_path.DirName()))
81 // If its parent does not exist, should return NOT_FOUND error.
82 return base::PLATFORM_FILE_ERROR_NOT_FOUND;
83 base::PlatformFileError error_code = base::PLATFORM_FILE_OK;
84 file_handle = base::CreatePlatformFile(file_path, file_flags,
85 &created, &error_code);
86 return error_code;
87 }
88
89 base::PlatformFileError FileSystemFileUtilBase::CreateTemporary(
90 FileSystemOperationContext* fs_context,
91 FilePath& file_path,
92 base::PlatformFile& file_handle) {
93 // TODO(darin): file_util should have a variant of CreateTemporaryFile
94 // that returns a FilePath and a PlatformFile.
95 file_util::CreateTemporaryFile(&file_path);
96
97 // Use a fixed set of flags that are appropriate for writing to a temporary
98 // file from the IO thread using a net::FileStream.
99 int file_flags =
100 base::PLATFORM_FILE_CREATE_ALWAYS |
101 base::PLATFORM_FILE_WRITE |
102 base::PLATFORM_FILE_ASYNC |
103 base::PLATFORM_FILE_TEMPORARY;
104 base::PlatformFileError error_code = base::PLATFORM_FILE_OK;
105 file_handle = base::CreatePlatformFile(file_path, file_flags,
106 NULL, &error_code);
107 return error_code;
108 }
109
110 base::PlatformFileError FileSystemFileUtilBase::Close(
111 FileSystemOperationContext* fs_context,
112 base::PlatformFile file_handle) {
113 if (!base::ClosePlatformFile(file_handle))
114 return base::PLATFORM_FILE_ERROR_FAILED;
115 return base::PLATFORM_FILE_OK;
116 }
117
118 base::PlatformFileError FileSystemFileUtilBase::EnsureFileExists(
119 FileSystemOperationContext* fs_context,
120 const FilePath& file_path,
121 bool *created) {
122 if (!file_util::DirectoryExists(file_path.DirName()))
123 // If its parent does not exist, should return NOT_FOUND error.
124 return base::PLATFORM_FILE_ERROR_NOT_FOUND;
125 base::PlatformFileError error_code = base::PLATFORM_FILE_OK;
126 // Tries to create the |file_path| exclusively. This should fail
127 // with PLATFORM_FILE_ERROR_EXISTS if the path already exists.
128 base::PlatformFile handle = base::CreatePlatformFile(
129 file_path,
130 base::PLATFORM_FILE_CREATE | base::PLATFORM_FILE_READ,
131 created, &error_code);
132 if (error_code == base::PLATFORM_FILE_ERROR_EXISTS) {
133 // Make sure *created is false.
134 *created = false;
135 error_code = base::PLATFORM_FILE_OK;
136 }
137 if (handle != base::kInvalidPlatformFileValue)
138 base::ClosePlatformFile(handle);
139 return error_code;
140 }
141
142 base::PlatformFileError FileSystemFileUtilBase::Delete(
143 FileSystemOperationContext* fs_context,
144 const FilePath& file_path,
145 bool recursive) {
146 if (!file_util::PathExists(file_path))
147 return base::PLATFORM_FILE_ERROR_NOT_FOUND;
148 if (!file_util::Delete(file_path, recursive)) {
149 if (!recursive && !file_util::IsDirectoryEmpty(file_path))
150 return base::PLATFORM_FILE_ERROR_NOT_EMPTY;
151 return base::PLATFORM_FILE_ERROR_FAILED;
152 }
153 return base::PLATFORM_FILE_OK;
154 }
155
156 base::PlatformFileError FileSystemFileUtilBase::Copy(
157 FileSystemOperationContext* fs_context,
158 const FilePath& src_file_path,
159 const FilePath& dest_file_path) {
160 // TODO(dmikurube): move the checking function
161 base::PlatformFileError error =
162 PerformCommonCheckAndPreparationForMoveAndCopy(
163 src_file_path, dest_file_path);
164 if (error != base::PLATFORM_FILE_OK)
165 return error;
166 if (!file_util::CopyDirectory(src_file_path, dest_file_path,
167 true /* recursive */))
168 return base::PLATFORM_FILE_ERROR_FAILED;
169 return base::PLATFORM_FILE_OK;
170 }
171
172 base::PlatformFileError FileSystemFileUtilBase::Move(
173 FileSystemOperationContext* fs_context,
174 const FilePath& src_file_path,
175 const FilePath& dest_file_path) {
176 // TODO(dmikurube): move the checking function
177 base::PlatformFileError error =
178 PerformCommonCheckAndPreparationForMoveAndCopy(
179 src_file_path, dest_file_path);
180 if (error != base::PLATFORM_FILE_OK)
181 return error;
182 if (!file_util::Move(src_file_path, dest_file_path))
183 return base::PLATFORM_FILE_ERROR_FAILED;
184 return base::PLATFORM_FILE_OK;
185 }
186
187 base::PlatformFileError FileSystemFileUtilBase::CreateDirectory(
188 FileSystemOperationContext* fs_context,
189 const FilePath& file_path,
190 bool exclusive,
191 bool recursive) {
192 bool path_exists = file_util::PathExists(file_path);
193 // If parent dir of file doesn't exist.
194 if (!recursive && !file_util::PathExists(file_path.DirName()))
195 return base::PLATFORM_FILE_ERROR_NOT_FOUND;
196 if (exclusive && path_exists)
197 return base::PLATFORM_FILE_ERROR_EXISTS;
198 // If file exists at the path.
199 if (path_exists && !file_util::DirectoryExists(file_path))
200 return base::PLATFORM_FILE_ERROR_EXISTS;
201 if (!file_util::CreateDirectory(file_path))
202 return base::PLATFORM_FILE_ERROR_FAILED;
203 return base::PLATFORM_FILE_OK;
204 }
205
206 base::PlatformFileError FileSystemFileUtilBase::ReadDirectory(
207 FileSystemOperationContext* fs_context,
208 const FilePath& file_path,
209 std::vector<base::FileUtilProxy::Entry>& entries) {
210 // TODO(kkanetkar): Implement directory read in multiple chunks.
211 if (!file_util::DirectoryExists(file_path))
212 return base::PLATFORM_FILE_ERROR_NOT_FOUND;
213
214 file_util::FileEnumerator file_enum(
215 file_path, false, static_cast<file_util::FileEnumerator::FILE_TYPE>(
216 file_util::FileEnumerator::FILES |
217 file_util::FileEnumerator::DIRECTORIES));
218 FilePath current;
219 while (!(current = file_enum.Next()).empty()) {
220 base::FileUtilProxy::Entry entry;
221 file_util::FileEnumerator::FindInfo info;
222 file_enum.GetFindInfo(&info);
223 entry.is_directory = file_enum.IsDirectory(info);
224 // This will just give the entry's name instead of entire path
225 // if we use current.value().
226 entry.name = file_util::FileEnumerator::GetFilename(info).value();
227 entries.push_back(entry);
228 }
229 return base::PLATFORM_FILE_OK;
230 }
231
232 base::PlatformFileError FileSystemFileUtilBase::GetFileInfo(
233 FileSystemOperationContext* fs_context,
234 const FilePath& file_path,
235 base::PlatformFileInfo& file_info) {
236 if (!file_util::PathExists(file_path))
237 return base::PLATFORM_FILE_ERROR_NOT_FOUND;
238 if (!file_util::GetFileInfo(file_path, &file_info))
239 return base::PLATFORM_FILE_ERROR_FAILED;
240 return base::PLATFORM_FILE_OK;
241 }
242
243 base::PlatformFileError FileSystemFileUtilBase::GetFileInfoFromPlatformFile(
244 FileSystemOperationContext* fs_context,
245 base::PlatformFile file,
246 base::PlatformFileInfo& file_info) {
247 if (!base::GetPlatformFileInfo(file, &file_info))
248 return base::PLATFORM_FILE_ERROR_FAILED;
249 return base::PLATFORM_FILE_OK;
250 }
251
252 base::PlatformFileError FileSystemFileUtilBase::Read(
253 FileSystemOperationContext* fs_context,
254 base::PlatformFile file,
255 int64 offset,
256 int bytes_to_read,
257 int& bytes_read,
258 char* buffer) {
259 bytes_read = base::ReadPlatformFile(file, offset, buffer, bytes_to_read);
260 if (bytes_read < 0)
261 return base::PLATFORM_FILE_ERROR_FAILED;
262 return base::PLATFORM_FILE_OK;
263 }
264
265 base::PlatformFileError FileSystemFileUtilBase::Write(
266 FileSystemOperationContext* fs_context,
267 base::PlatformFile file,
268 int64 offset,
269 int bytes_to_write,
270 int& bytes_written,
271 char* buffer) {
272 bytes_written = base::WritePlatformFile(file, offset, buffer,
273 bytes_to_write);
274 if (bytes_written < 0)
275 return base::PLATFORM_FILE_ERROR_FAILED;
276 return base::PLATFORM_FILE_OK;
277 }
278
279 base::PlatformFileError FileSystemFileUtilBase::Touch(
280 FileSystemOperationContext* fs_context,
281 base::PlatformFile file,
282 const base::Time& last_access_time,
283 const base::Time& last_modified_time) {
284 if (!base::TouchPlatformFile(file, last_access_time, last_modified_time))
285 return base::PLATFORM_FILE_ERROR_FAILED;
286 return base::PLATFORM_FILE_OK;
287 }
288
289 base::PlatformFileError FileSystemFileUtilBase::TouchFilePath(
290 FileSystemOperationContext* fs_context,
291 const FilePath& file_path,
292 const base::Time& last_access_time,
293 const base::Time& last_modified_time) {
294 if (!file_util::TouchFile(
295 file_path, last_access_time, last_modified_time))
296 return base::PLATFORM_FILE_ERROR_FAILED;
297 return base::PLATFORM_FILE_OK;
298 }
299
300 base::PlatformFileError FileSystemFileUtilBase::TruncatePlatformFile(
301 FileSystemOperationContext* fs_context,
302 base::PlatformFile file,
303 int64 length) {
304 if (!base::TruncatePlatformFile(file, length))
305 return base::PLATFORM_FILE_ERROR_FAILED;
306 return base::PLATFORM_FILE_OK;
307 }
308
309 base::PlatformFileError FileSystemFileUtilBase::Truncate(
310 FileSystemOperationContext* fs_context,
311 const FilePath& path,
312 int64 length) {
313 base::PlatformFileError error_code(base::PLATFORM_FILE_ERROR_FAILED);
314 base::PlatformFile file =
315 base::CreatePlatformFile(
316 path,
317 base::PLATFORM_FILE_OPEN | base::PLATFORM_FILE_WRITE,
318 NULL,
319 &error_code);
320 if (error_code != base::PLATFORM_FILE_OK)
321 return error_code;
322 error_code = base::PLATFORM_FILE_OK;
323 if (!base::TruncatePlatformFile(file, length))
324 error_code = base::PLATFORM_FILE_ERROR_FAILED;
325 base::ClosePlatformFile(file);
326 return error_code;
327 }
328
329 base::PlatformFileError FileSystemFileUtilBase::Flush(
330 FileSystemOperationContext* fs_context,
331 base::PlatformFile file) {
332 if (!base::FlushPlatformFile(file))
333 return base::PLATFORM_FILE_ERROR_FAILED;
334 return base::PLATFORM_FILE_OK;
335 }
336
337 } // namespace fileapi
OLDNEW
« no previous file with comments | « webkit/fileapi/file_system_file_util_base.h ('k') | webkit/fileapi/file_system_file_util_proxy.h » ('j') | no next file with comments »

Powered by Google App Engine
This is Rietveld 408576698