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

Side by Side Diff: base/file_util_proxy.cc

Issue 12035111: Move file_util_proxy to base/files. (Closed) Base URL: svn://svn.chromium.org/chrome/trunk/src
Patch Set: Created 7 years, 11 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
« no previous file with comments | « base/file_util_proxy.h ('k') | base/file_util_proxy_unittest.cc » ('j') | no next file with comments »
Toggle Intra-line Diffs ('i') | Expand Comments ('e') | Collapse Comments ('c') | Show Comments Hide Comments ('s')
OLDNEW
(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 "base/file_util_proxy.h"
6
7 #include "base/bind.h"
8 #include "base/bind_helpers.h"
9 #include "base/file_util.h"
10 #include "base/location.h"
11 #include "base/message_loop_proxy.h"
12 #include "base/task_runner.h"
13 #include "base/task_runner_util.h"
14
15 namespace base {
16
17 namespace {
18
19 void CallWithTranslatedParameter(const FileUtilProxy::StatusCallback& callback,
20 bool value) {
21 DCHECK(!callback.is_null());
22 callback.Run(value ? PLATFORM_FILE_OK : PLATFORM_FILE_ERROR_FAILED);
23 }
24
25 // Helper classes or routines for individual methods.
26 class CreateOrOpenHelper {
27 public:
28 CreateOrOpenHelper(TaskRunner* task_runner,
29 const FileUtilProxy::CloseTask& close_task)
30 : task_runner_(task_runner),
31 close_task_(close_task),
32 file_handle_(kInvalidPlatformFileValue),
33 created_(false),
34 error_(PLATFORM_FILE_OK) {}
35
36 ~CreateOrOpenHelper() {
37 if (file_handle_ != kInvalidPlatformFileValue) {
38 task_runner_->PostTask(
39 FROM_HERE,
40 base::Bind(base::IgnoreResult(close_task_), file_handle_));
41 }
42 }
43
44 void RunWork(const FileUtilProxy::CreateOrOpenTask& task) {
45 error_ = task.Run(&file_handle_, &created_);
46 }
47
48 void Reply(const FileUtilProxy::CreateOrOpenCallback& callback) {
49 DCHECK(!callback.is_null());
50 callback.Run(error_, PassPlatformFile(&file_handle_), created_);
51 }
52
53 private:
54 scoped_refptr<TaskRunner> task_runner_;
55 FileUtilProxy::CloseTask close_task_;
56 PlatformFile file_handle_;
57 bool created_;
58 PlatformFileError error_;
59 DISALLOW_COPY_AND_ASSIGN(CreateOrOpenHelper);
60 };
61
62 class CreateTemporaryHelper {
63 public:
64 explicit CreateTemporaryHelper(TaskRunner* task_runner)
65 : task_runner_(task_runner),
66 file_handle_(kInvalidPlatformFileValue),
67 error_(PLATFORM_FILE_OK) {}
68
69 ~CreateTemporaryHelper() {
70 if (file_handle_ != kInvalidPlatformFileValue) {
71 FileUtilProxy::Close(task_runner_, file_handle_,
72 FileUtilProxy::StatusCallback());
73 }
74 }
75
76 void RunWork(int additional_file_flags) {
77 // TODO(darin): file_util should have a variant of CreateTemporaryFile
78 // that returns a FilePath and a PlatformFile.
79 file_util::CreateTemporaryFile(&file_path_);
80
81 int file_flags =
82 PLATFORM_FILE_WRITE |
83 PLATFORM_FILE_TEMPORARY |
84 PLATFORM_FILE_CREATE_ALWAYS |
85 additional_file_flags;
86
87 error_ = PLATFORM_FILE_OK;
88 file_handle_ = CreatePlatformFile(file_path_, file_flags, NULL, &error_);
89 }
90
91 void Reply(const FileUtilProxy::CreateTemporaryCallback& callback) {
92 DCHECK(!callback.is_null());
93 callback.Run(error_, PassPlatformFile(&file_handle_), file_path_);
94 }
95
96 private:
97 scoped_refptr<TaskRunner> task_runner_;
98 PlatformFile file_handle_;
99 FilePath file_path_;
100 PlatformFileError error_;
101 DISALLOW_COPY_AND_ASSIGN(CreateTemporaryHelper);
102 };
103
104 class GetFileInfoHelper {
105 public:
106 GetFileInfoHelper()
107 : error_(PLATFORM_FILE_OK) {}
108
109 void RunWorkForFilePath(const FilePath& file_path) {
110 if (!file_util::PathExists(file_path)) {
111 error_ = PLATFORM_FILE_ERROR_NOT_FOUND;
112 return;
113 }
114 if (!file_util::GetFileInfo(file_path, &file_info_))
115 error_ = PLATFORM_FILE_ERROR_FAILED;
116 }
117
118 void RunWorkForPlatformFile(PlatformFile file) {
119 if (!GetPlatformFileInfo(file, &file_info_))
120 error_ = PLATFORM_FILE_ERROR_FAILED;
121 }
122
123 void Reply(const FileUtilProxy::GetFileInfoCallback& callback) {
124 if (!callback.is_null()) {
125 callback.Run(error_, file_info_);
126 }
127 }
128
129 private:
130 PlatformFileError error_;
131 PlatformFileInfo file_info_;
132 DISALLOW_COPY_AND_ASSIGN(GetFileInfoHelper);
133 };
134
135 class ReadHelper {
136 public:
137 explicit ReadHelper(int bytes_to_read)
138 : buffer_(new char[bytes_to_read]),
139 bytes_to_read_(bytes_to_read),
140 bytes_read_(0) {}
141
142 void RunWork(PlatformFile file, int64 offset) {
143 bytes_read_ = ReadPlatformFile(file, offset, buffer_.get(), bytes_to_read_);
144 }
145
146 void Reply(const FileUtilProxy::ReadCallback& callback) {
147 if (!callback.is_null()) {
148 PlatformFileError error =
149 (bytes_read_ < 0) ? PLATFORM_FILE_ERROR_FAILED : PLATFORM_FILE_OK;
150 callback.Run(error, buffer_.get(), bytes_read_);
151 }
152 }
153
154 private:
155 scoped_ptr<char[]> buffer_;
156 int bytes_to_read_;
157 int bytes_read_;
158 DISALLOW_COPY_AND_ASSIGN(ReadHelper);
159 };
160
161 class WriteHelper {
162 public:
163 WriteHelper(const char* buffer, int bytes_to_write)
164 : buffer_(new char[bytes_to_write]),
165 bytes_to_write_(bytes_to_write),
166 bytes_written_(0) {
167 memcpy(buffer_.get(), buffer, bytes_to_write);
168 }
169
170 void RunWork(PlatformFile file, int64 offset) {
171 bytes_written_ = WritePlatformFile(file, offset, buffer_.get(),
172 bytes_to_write_);
173 }
174
175 void Reply(const FileUtilProxy::WriteCallback& callback) {
176 if (!callback.is_null()) {
177 PlatformFileError error =
178 (bytes_written_ < 0) ? PLATFORM_FILE_ERROR_FAILED : PLATFORM_FILE_OK;
179 callback.Run(error, bytes_written_);
180 }
181 }
182
183 private:
184 scoped_ptr<char[]> buffer_;
185 int bytes_to_write_;
186 int bytes_written_;
187 DISALLOW_COPY_AND_ASSIGN(WriteHelper);
188 };
189
190
191 PlatformFileError CreateOrOpenAdapter(
192 const FilePath& file_path, int file_flags,
193 PlatformFile* file_handle, bool* created) {
194 DCHECK(file_handle);
195 DCHECK(created);
196 if (!file_util::DirectoryExists(file_path.DirName())) {
197 // If its parent does not exist, should return NOT_FOUND error.
198 return PLATFORM_FILE_ERROR_NOT_FOUND;
199 }
200 PlatformFileError error = PLATFORM_FILE_OK;
201 *file_handle = CreatePlatformFile(file_path, file_flags, created, &error);
202 return error;
203 }
204
205 PlatformFileError CloseAdapter(PlatformFile file_handle) {
206 if (!ClosePlatformFile(file_handle)) {
207 return PLATFORM_FILE_ERROR_FAILED;
208 }
209 return PLATFORM_FILE_OK;
210 }
211
212 PlatformFileError DeleteAdapter(const FilePath& file_path, bool recursive) {
213 if (!file_util::PathExists(file_path)) {
214 return PLATFORM_FILE_ERROR_NOT_FOUND;
215 }
216 if (!file_util::Delete(file_path, recursive)) {
217 if (!recursive && !file_util::IsDirectoryEmpty(file_path)) {
218 return PLATFORM_FILE_ERROR_NOT_EMPTY;
219 }
220 return PLATFORM_FILE_ERROR_FAILED;
221 }
222 return PLATFORM_FILE_OK;
223 }
224
225 } // namespace
226
227 // static
228 bool FileUtilProxy::CreateOrOpen(
229 TaskRunner* task_runner,
230 const FilePath& file_path, int file_flags,
231 const CreateOrOpenCallback& callback) {
232 return RelayCreateOrOpen(
233 task_runner,
234 base::Bind(&CreateOrOpenAdapter, file_path, file_flags),
235 base::Bind(&CloseAdapter),
236 callback);
237 }
238
239 // static
240 bool FileUtilProxy::CreateTemporary(
241 TaskRunner* task_runner,
242 int additional_file_flags,
243 const CreateTemporaryCallback& callback) {
244 CreateTemporaryHelper* helper = new CreateTemporaryHelper(task_runner);
245 return task_runner->PostTaskAndReply(
246 FROM_HERE,
247 Bind(&CreateTemporaryHelper::RunWork, Unretained(helper),
248 additional_file_flags),
249 Bind(&CreateTemporaryHelper::Reply, Owned(helper), callback));
250 }
251
252 // static
253 bool FileUtilProxy::Close(
254 TaskRunner* task_runner,
255 base::PlatformFile file_handle,
256 const StatusCallback& callback) {
257 return RelayClose(
258 task_runner,
259 base::Bind(&CloseAdapter),
260 file_handle, callback);
261 }
262
263 // Retrieves the information about a file. It is invalid to pass NULL for the
264 // callback.
265 bool FileUtilProxy::GetFileInfo(
266 TaskRunner* task_runner,
267 const FilePath& file_path,
268 const GetFileInfoCallback& callback) {
269 GetFileInfoHelper* helper = new GetFileInfoHelper;
270 return task_runner->PostTaskAndReply(
271 FROM_HERE,
272 Bind(&GetFileInfoHelper::RunWorkForFilePath,
273 Unretained(helper), file_path),
274 Bind(&GetFileInfoHelper::Reply, Owned(helper), callback));
275 }
276
277 // static
278 bool FileUtilProxy::GetFileInfoFromPlatformFile(
279 TaskRunner* task_runner,
280 PlatformFile file,
281 const GetFileInfoCallback& callback) {
282 GetFileInfoHelper* helper = new GetFileInfoHelper;
283 return task_runner->PostTaskAndReply(
284 FROM_HERE,
285 Bind(&GetFileInfoHelper::RunWorkForPlatformFile,
286 Unretained(helper), file),
287 Bind(&GetFileInfoHelper::Reply, Owned(helper), callback));
288 }
289
290 // static
291 bool FileUtilProxy::Delete(TaskRunner* task_runner,
292 const FilePath& file_path,
293 bool recursive,
294 const StatusCallback& callback) {
295 return base::PostTaskAndReplyWithResult(
296 task_runner, FROM_HERE,
297 Bind(&DeleteAdapter, file_path, recursive),
298 callback);
299 }
300
301 // static
302 bool FileUtilProxy::RecursiveDelete(
303 TaskRunner* task_runner,
304 const FilePath& file_path,
305 const StatusCallback& callback) {
306 return base::PostTaskAndReplyWithResult(
307 task_runner, FROM_HERE,
308 Bind(&DeleteAdapter, file_path, true /* recursive */),
309 callback);
310 }
311
312 // static
313 bool FileUtilProxy::Read(
314 TaskRunner* task_runner,
315 PlatformFile file,
316 int64 offset,
317 int bytes_to_read,
318 const ReadCallback& callback) {
319 if (bytes_to_read < 0) {
320 return false;
321 }
322 ReadHelper* helper = new ReadHelper(bytes_to_read);
323 return task_runner->PostTaskAndReply(
324 FROM_HERE,
325 Bind(&ReadHelper::RunWork, Unretained(helper), file, offset),
326 Bind(&ReadHelper::Reply, Owned(helper), callback));
327 }
328
329 // static
330 bool FileUtilProxy::Write(
331 TaskRunner* task_runner,
332 PlatformFile file,
333 int64 offset,
334 const char* buffer,
335 int bytes_to_write,
336 const WriteCallback& callback) {
337 if (bytes_to_write <= 0 || buffer == NULL) {
338 return false;
339 }
340 WriteHelper* helper = new WriteHelper(buffer, bytes_to_write);
341 return task_runner->PostTaskAndReply(
342 FROM_HERE,
343 Bind(&WriteHelper::RunWork, Unretained(helper), file, offset),
344 Bind(&WriteHelper::Reply, Owned(helper), callback));
345 }
346
347 // static
348 bool FileUtilProxy::Touch(
349 TaskRunner* task_runner,
350 PlatformFile file,
351 const Time& last_access_time,
352 const Time& last_modified_time,
353 const StatusCallback& callback) {
354 return base::PostTaskAndReplyWithResult(
355 task_runner,
356 FROM_HERE,
357 Bind(&TouchPlatformFile, file,
358 last_access_time, last_modified_time),
359 Bind(&CallWithTranslatedParameter, callback));
360 }
361
362 // static
363 bool FileUtilProxy::Touch(
364 TaskRunner* task_runner,
365 const FilePath& file_path,
366 const Time& last_access_time,
367 const Time& last_modified_time,
368 const StatusCallback& callback) {
369 return base::PostTaskAndReplyWithResult(
370 task_runner,
371 FROM_HERE,
372 Bind(&file_util::TouchFile, file_path,
373 last_access_time, last_modified_time),
374 Bind(&CallWithTranslatedParameter, callback));
375 }
376
377 // static
378 bool FileUtilProxy::Truncate(
379 TaskRunner* task_runner,
380 PlatformFile file,
381 int64 length,
382 const StatusCallback& callback) {
383 return base::PostTaskAndReplyWithResult(
384 task_runner,
385 FROM_HERE,
386 Bind(&TruncatePlatformFile, file, length),
387 Bind(&CallWithTranslatedParameter, callback));
388 }
389
390 // static
391 bool FileUtilProxy::Flush(
392 TaskRunner* task_runner,
393 PlatformFile file,
394 const StatusCallback& callback) {
395 return base::PostTaskAndReplyWithResult(
396 task_runner,
397 FROM_HERE,
398 Bind(&FlushPlatformFile, file),
399 Bind(&CallWithTranslatedParameter, callback));
400 }
401
402 // static
403 bool FileUtilProxy::RelayCreateOrOpen(
404 TaskRunner* task_runner,
405 const CreateOrOpenTask& open_task,
406 const CloseTask& close_task,
407 const CreateOrOpenCallback& callback) {
408 CreateOrOpenHelper* helper = new CreateOrOpenHelper(
409 task_runner, close_task);
410 return task_runner->PostTaskAndReply(
411 FROM_HERE,
412 Bind(&CreateOrOpenHelper::RunWork, Unretained(helper), open_task),
413 Bind(&CreateOrOpenHelper::Reply, Owned(helper), callback));
414 }
415
416 // static
417 bool FileUtilProxy::RelayClose(
418 TaskRunner* task_runner,
419 const CloseTask& close_task,
420 PlatformFile file_handle,
421 const StatusCallback& callback) {
422 return base::PostTaskAndReplyWithResult(
423 task_runner, FROM_HERE, Bind(close_task, file_handle), callback);
424 }
425
426 } // namespace base
OLDNEW
« no previous file with comments | « base/file_util_proxy.h ('k') | base/file_util_proxy_unittest.cc » ('j') | no next file with comments »

Powered by Google App Engine
This is Rietveld 408576698