OLD | NEW |
---|---|
(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. | |
ericu
2011/08/03 22:59:26
This file seems to be based on file_system_file_ut
Dai Mikurube (NOT FULLTIME)
2011/08/04 03:54:48
Actually I used git mv for this class, but Rietvel
| |
4 | |
5 #include "webkit/fileapi/native_file_util.h" | |
6 | |
7 #include <vector> | |
8 | |
9 #include "base/file_util.h" | |
10 #include "base/memory/scoped_ptr.h" | |
11 #include "webkit/fileapi/file_system_operation_context.h" | |
12 | |
13 namespace fileapi { | |
14 | |
15 namespace { | |
16 | |
17 // This assumes that the root exists. | |
18 bool ParentExists(FileSystemOperationContext* context, | |
ericu
2011/08/03 22:59:26
This function isn't used.
Dai Mikurube (NOT FULLTIME)
2011/08/04 03:54:48
Exactly. Removed.
| |
19 FileUtil* file_util, const FilePath& file_path) { | |
20 // If file_path is in the root, file_path.DirName() will be ".", | |
21 // since we use paths with no leading '/'. | |
22 FilePath parent = file_path.DirName(); | |
23 if (parent == FilePath(FILE_PATH_LITERAL("."))) | |
24 return true; | |
25 return file_util->DirectoryExists(context, parent); | |
26 } | |
27 | |
28 } // namespace | |
29 | |
30 PlatformFileError NativeFileUtil::CreateOrOpen( | |
31 FileSystemOperationContext* unused, | |
32 const FilePath& file_path, int file_flags, | |
33 PlatformFile* file_handle, bool* created) { | |
34 if (!file_util::DirectoryExists(file_path.DirName())) { | |
35 // If its parent does not exist, should return NOT_FOUND error. | |
36 return base::PLATFORM_FILE_ERROR_NOT_FOUND; | |
37 } | |
38 PlatformFileError error_code = base::PLATFORM_FILE_OK; | |
39 *file_handle = base::CreatePlatformFile(file_path, file_flags, | |
40 created, &error_code); | |
41 return error_code; | |
42 } | |
43 | |
44 PlatformFileError NativeFileUtil::Close( | |
45 FileSystemOperationContext* unused, | |
46 PlatformFile file_handle) { | |
47 if (!base::ClosePlatformFile(file_handle)) | |
48 return base::PLATFORM_FILE_ERROR_FAILED; | |
49 return base::PLATFORM_FILE_OK; | |
50 } | |
51 | |
52 PlatformFileError NativeFileUtil::EnsureFileExists( | |
53 FileSystemOperationContext* unused, | |
54 const FilePath& file_path, | |
55 bool* created) { | |
56 if (!file_util::DirectoryExists(file_path.DirName())) | |
57 // If its parent does not exist, should return NOT_FOUND error. | |
58 return base::PLATFORM_FILE_ERROR_NOT_FOUND; | |
59 PlatformFileError error_code = base::PLATFORM_FILE_OK; | |
60 // Tries to create the |file_path| exclusively. This should fail | |
61 // with base::PLATFORM_FILE_ERROR_EXISTS if the path already exists. | |
62 PlatformFile handle = base::CreatePlatformFile( | |
63 file_path, | |
64 base::PLATFORM_FILE_CREATE | base::PLATFORM_FILE_READ, | |
65 created, &error_code); | |
66 if (error_code == base::PLATFORM_FILE_ERROR_EXISTS) { | |
67 // Make sure created_ is false. | |
68 if (created) | |
69 *created = false; | |
70 error_code = base::PLATFORM_FILE_OK; | |
71 } | |
72 if (handle != base::kInvalidPlatformFileValue) | |
73 base::ClosePlatformFile(handle); | |
74 return error_code; | |
75 } | |
76 | |
77 PlatformFileError NativeFileUtil::GetLocalFilePath( | |
78 FileSystemOperationContext* unused, | |
79 const FilePath& virtual_path, | |
80 FilePath* local_path) { | |
81 *local_path = virtual_path; | |
82 return base::PLATFORM_FILE_OK; | |
83 } | |
84 | |
85 PlatformFileError NativeFileUtil::GetFileInfo( | |
86 FileSystemOperationContext* unused, | |
87 const FilePath& file_path, | |
88 base::PlatformFileInfo* file_info, | |
89 FilePath* platform_file_path) { | |
90 if (!file_util::PathExists(file_path)) | |
91 return base::PLATFORM_FILE_ERROR_NOT_FOUND; | |
92 // TODO(rkc): Fix this hack once we have refactored file_util to handle | |
93 // symlinks correctly. | |
94 // http://code.google.com/p/chromium-os/issues/detail?id=15948 | |
95 if (file_util::IsLink(file_path)) | |
96 return base::PLATFORM_FILE_ERROR_NOT_FOUND; | |
97 if (!file_util::GetFileInfo(file_path, file_info)) | |
98 return base::PLATFORM_FILE_ERROR_FAILED; | |
99 *platform_file_path = file_path; | |
100 return base::PLATFORM_FILE_OK; | |
101 } | |
102 | |
103 PlatformFileError NativeFileUtil::ReadDirectory( | |
104 FileSystemOperationContext* unused, | |
105 const FilePath& file_path, | |
106 std::vector<base::FileUtilProxy::Entry>* entries) { | |
107 // TODO(kkanetkar): Implement directory read in multiple chunks. | |
108 if (!file_util::DirectoryExists(file_path)) | |
109 return base::PLATFORM_FILE_ERROR_NOT_FOUND; | |
110 | |
111 file_util::FileEnumerator file_enum( | |
112 file_path, false, static_cast<file_util::FileEnumerator::FILE_TYPE>( | |
113 file_util::FileEnumerator::FILES | | |
114 file_util::FileEnumerator::DIRECTORIES)); | |
115 FilePath current; | |
116 while (!(current = file_enum.Next()).empty()) { | |
117 base::FileUtilProxy::Entry entry; | |
118 file_util::FileEnumerator::FindInfo info; | |
119 file_enum.GetFindInfo(&info); | |
120 entry.is_directory = file_enum.IsDirectory(info); | |
121 // This will just give the entry's name instead of entire path | |
122 // if we use current.value(). | |
123 entry.name = file_util::FileEnumerator::GetFilename(info).value(); | |
124 entry.size = file_util::FileEnumerator::GetFilesize(info); | |
125 entry.last_modified_time = | |
126 file_util::FileEnumerator::GetLastModifiedTime(info); | |
127 // TODO(rkc): Fix this also once we've refactored file_util | |
128 // http://code.google.com/p/chromium-os/issues/detail?id=15948 | |
129 // This currently just prevents a file from showing up at all | |
130 // if it's a link, hence preventing arbitary 'read' exploits. | |
131 if (!file_util::IsLink(file_path.Append(entry.name))) | |
132 entries->push_back(entry); | |
133 } | |
134 return base::PLATFORM_FILE_OK; | |
135 } | |
136 | |
137 PlatformFileError NativeFileUtil::CreateDirectory( | |
138 FileSystemOperationContext* context, | |
139 const FilePath& file_path, | |
140 bool exclusive, | |
141 bool recursive) { | |
142 if (context->do_not_write_actually()) | |
143 return base::PLATFORM_FILE_OK; | |
144 | |
145 // If parent dir of file doesn't exist. | |
146 if (!recursive && !file_util::PathExists(file_path.DirName())) | |
147 return base::PLATFORM_FILE_ERROR_NOT_FOUND; | |
148 | |
149 bool path_exists = file_util::PathExists(file_path); | |
150 if (exclusive && path_exists) | |
151 return base::PLATFORM_FILE_ERROR_EXISTS; | |
152 | |
153 // If file exists at the path. | |
154 if (path_exists && !file_util::DirectoryExists(file_path)) | |
155 return base::PLATFORM_FILE_ERROR_EXISTS; | |
156 | |
157 if (!file_util::CreateDirectory(file_path)) | |
158 return base::PLATFORM_FILE_ERROR_FAILED; | |
159 return base::PLATFORM_FILE_OK; | |
160 } | |
161 | |
162 PlatformFileError NativeFileUtil::Touch( | |
163 FileSystemOperationContext* unused, | |
164 const FilePath& file_path, | |
165 const base::Time& last_access_time, | |
166 const base::Time& last_modified_time) { | |
167 if (!file_util::TouchFile( | |
168 file_path, last_access_time, last_modified_time)) | |
169 return base::PLATFORM_FILE_ERROR_FAILED; | |
170 return base::PLATFORM_FILE_OK; | |
171 } | |
172 | |
173 PlatformFileError NativeFileUtil::Truncate( | |
174 FileSystemOperationContext* unused, | |
175 const FilePath& file_path, | |
176 int64 length) { | |
177 PlatformFileError error_code(base::PLATFORM_FILE_ERROR_FAILED); | |
178 PlatformFile file = | |
179 base::CreatePlatformFile( | |
180 file_path, | |
181 base::PLATFORM_FILE_OPEN | base::PLATFORM_FILE_WRITE, | |
182 NULL, | |
183 &error_code); | |
184 if (error_code != base::PLATFORM_FILE_OK) { | |
185 return error_code; | |
186 } | |
187 DCHECK_NE(base::kInvalidPlatformFileValue, file); | |
188 if (!base::TruncatePlatformFile(file, length)) | |
189 error_code = base::PLATFORM_FILE_ERROR_FAILED; | |
190 base::ClosePlatformFile(file); | |
191 return error_code; | |
192 } | |
193 | |
194 PlatformFileError NativeFileUtil::CopyOrMoveFile( | |
195 FileSystemOperationContext* unused, | |
196 const FilePath& src_file_path, | |
197 const FilePath& dest_file_path, | |
198 bool copy) { | |
199 if (copy) { | |
200 if (file_util::CopyFile(src_file_path, dest_file_path)) | |
201 return base::PLATFORM_FILE_OK; | |
202 } else { | |
203 DCHECK(!file_util::DirectoryExists(src_file_path)); | |
204 if (file_util::Move(src_file_path, dest_file_path)) | |
205 return base::PLATFORM_FILE_OK; | |
206 } | |
207 return base::PLATFORM_FILE_ERROR_FAILED; | |
208 } | |
209 | |
210 PlatformFileError NativeFileUtil::CopyInForeignFile( | |
211 FileSystemOperationContext* context, | |
212 const FilePath& src_file_path, | |
213 const FilePath& dest_file_path) { | |
214 return CopyOrMoveFile(context, src_file_path, dest_file_path, true); | |
215 } | |
216 | |
217 PlatformFileError NativeFileUtil::DeleteFile( | |
218 FileSystemOperationContext* unused, | |
219 const FilePath& file_path) { | |
220 if (!file_util::PathExists(file_path)) | |
221 return base::PLATFORM_FILE_ERROR_NOT_FOUND; | |
222 if (file_util::DirectoryExists(file_path)) | |
223 return base::PLATFORM_FILE_ERROR_NOT_A_FILE; | |
224 if (!file_util::Delete(file_path, false)) | |
225 return base::PLATFORM_FILE_ERROR_FAILED; | |
226 return base::PLATFORM_FILE_OK; | |
227 } | |
228 | |
229 PlatformFileError NativeFileUtil::DeleteSingleDirectory( | |
230 FileSystemOperationContext* unused, | |
231 const FilePath& file_path) { | |
232 if (!file_util::PathExists(file_path)) | |
233 return base::PLATFORM_FILE_ERROR_NOT_FOUND; | |
234 if (!file_util::DirectoryExists(file_path)) { | |
235 // TODO(dmikurube): Check if this error code is appropriate. | |
236 return base::PLATFORM_FILE_ERROR_NOT_A_DIRECTORY; | |
237 } | |
238 if (!file_util::IsDirectoryEmpty(file_path)) { | |
239 // TODO(dmikurube): Check if this error code is appropriate. | |
240 return base::PLATFORM_FILE_ERROR_NOT_EMPTY; | |
241 } | |
242 if (!file_util::Delete(file_path, false)) | |
243 return base::PLATFORM_FILE_ERROR_FAILED; | |
244 return base::PLATFORM_FILE_OK; | |
245 } | |
246 | |
247 bool NativeFileUtil::PathExists( | |
248 FileSystemOperationContext* unused, | |
249 const FilePath& file_path) { | |
250 return file_util::PathExists(file_path); | |
251 } | |
252 | |
253 bool NativeFileUtil::DirectoryExists( | |
254 FileSystemOperationContext* unused, | |
255 const FilePath& file_path) { | |
256 return file_util::DirectoryExists(file_path); | |
257 } | |
258 | |
259 bool NativeFileUtil::IsDirectoryEmpty( | |
260 FileSystemOperationContext* unused, | |
261 const FilePath& file_path) { | |
262 return file_util::IsDirectoryEmpty(file_path); | |
263 } | |
264 | |
265 class FileSystemFileEnumerator | |
266 : public FileUtil::AbstractFileEnumerator { | |
267 public: | |
268 FileSystemFileEnumerator(const FilePath& root_path, | |
269 bool recursive, | |
270 file_util::FileEnumerator::FILE_TYPE file_type) | |
271 : file_enum_(root_path, recursive, file_type) { | |
272 } | |
273 | |
274 ~FileSystemFileEnumerator() {} | |
275 | |
276 virtual FilePath Next(); | |
277 virtual bool IsDirectory(); | |
278 | |
279 private: | |
280 file_util::FileEnumerator file_enum_; | |
281 }; | |
282 | |
283 FilePath FileSystemFileEnumerator::Next() { | |
284 return file_enum_.Next(); | |
285 } | |
286 | |
287 bool FileSystemFileEnumerator::IsDirectory() { | |
288 file_util::FileEnumerator::FindInfo file_util_info; | |
289 file_enum_.GetFindInfo(&file_util_info); | |
290 return file_util::FileEnumerator::IsDirectory(file_util_info); | |
291 } | |
292 | |
293 FileUtil::AbstractFileEnumerator* NativeFileUtil::CreateFileEnumerator( | |
294 FileSystemOperationContext* unused, | |
295 const FilePath& root_path) { | |
296 return new FileSystemFileEnumerator( | |
297 root_path, true, static_cast<file_util::FileEnumerator::FILE_TYPE>( | |
298 file_util::FileEnumerator::FILES | | |
299 file_util::FileEnumerator::DIRECTORIES)); | |
300 } | |
301 | |
302 } // namespace fileapi | |
OLD | NEW |