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/chromeos/fileapi/remote_file_stream_writer.h" | |
6 | |
7 #include "net/base/io_buffer.h" | |
8 #include "net/base/net_errors.h" | |
9 #include "webkit/browser/blob/local_file_stream_reader.h" | |
10 #include "webkit/browser/fileapi/local_file_stream_writer.h" | |
11 #include "webkit/browser/fileapi/remote_file_system_proxy.h" | |
12 #include "webkit/common/blob/shareable_file_reference.h" | |
13 | |
14 namespace fileapi { | |
15 | |
16 RemoteFileStreamWriter::RemoteFileStreamWriter( | |
17 const scoped_refptr<RemoteFileSystemProxyInterface>& remote_filesystem, | |
18 const FileSystemURL& url, | |
19 int64 offset, | |
20 base::TaskRunner *local_task_runner) | |
21 : remote_filesystem_(remote_filesystem), | |
22 url_(url), | |
23 initial_offset_(offset), | |
24 has_pending_create_snapshot_(false), | |
25 weak_factory_(this), | |
26 local_task_runner_(local_task_runner) { | |
27 } | |
28 | |
29 RemoteFileStreamWriter::~RemoteFileStreamWriter() { | |
30 } | |
31 | |
32 int RemoteFileStreamWriter::Write(net::IOBuffer* buf, | |
33 int buf_len, | |
34 const net::CompletionCallback& callback) { | |
35 DCHECK(!has_pending_create_snapshot_); | |
36 DCHECK(pending_cancel_callback_.is_null()); | |
37 | |
38 if (!local_file_writer_) { | |
39 has_pending_create_snapshot_ = true; | |
40 // In this RemoteFileStreamWriter, we only create snapshot file and don't | |
41 // have explicit close operation. This is ok, because close is automatically | |
42 // triggered by a refcounted |file_ref_| passed to OnFileOpened, from the | |
43 // destructor of RemoteFileStreamWriter. | |
44 remote_filesystem_->CreateWritableSnapshotFile( | |
45 url_, | |
46 base::Bind(&RemoteFileStreamWriter::OnFileOpened, | |
47 weak_factory_.GetWeakPtr(), | |
48 make_scoped_refptr(buf), | |
49 buf_len, | |
50 callback)); | |
51 return net::ERR_IO_PENDING; | |
52 } | |
53 return local_file_writer_->Write(buf, buf_len, callback); | |
54 } | |
55 | |
56 void RemoteFileStreamWriter::OnFileOpened( | |
57 net::IOBuffer* buf, | |
58 int buf_len, | |
59 const net::CompletionCallback& callback, | |
60 base::PlatformFileError open_result, | |
61 const base::FilePath& local_path, | |
62 const scoped_refptr<webkit_blob::ShareableFileReference>& file_ref) { | |
63 has_pending_create_snapshot_ = false; | |
64 if (!pending_cancel_callback_.is_null()) { | |
65 InvokePendingCancelCallback(net::OK); | |
66 return; | |
67 } | |
68 | |
69 if (open_result != base::PLATFORM_FILE_OK) { | |
70 callback.Run(net::PlatformFileErrorToNetError(open_result)); | |
71 return; | |
72 } | |
73 | |
74 // Hold the reference to the file. Releasing the reference notifies the file | |
75 // system about to close file. | |
76 file_ref_ = file_ref; | |
77 | |
78 DCHECK(!local_file_writer_.get()); | |
79 local_file_writer_.reset(new fileapi::LocalFileStreamWriter( | |
80 local_task_runner_, local_path, initial_offset_)); | |
81 int result = local_file_writer_->Write(buf, buf_len, callback); | |
82 if (result != net::ERR_IO_PENDING) | |
83 callback.Run(result); | |
84 } | |
85 | |
86 int RemoteFileStreamWriter::Cancel(const net::CompletionCallback& callback) { | |
87 DCHECK(!callback.is_null()); | |
88 DCHECK(pending_cancel_callback_.is_null()); | |
89 | |
90 // If file open operation is in-flight, wait for its completion and cancel | |
91 // further write operation in OnFileOpened. | |
92 if (has_pending_create_snapshot_) { | |
93 pending_cancel_callback_ = callback; | |
94 return net::ERR_IO_PENDING; | |
95 } | |
96 | |
97 // If LocalFileWriter is already created, just delegate the cancel to it. | |
98 if (local_file_writer_) { | |
99 pending_cancel_callback_ = callback; | |
100 return local_file_writer_->Cancel( | |
101 base::Bind(&RemoteFileStreamWriter::InvokePendingCancelCallback, | |
102 weak_factory_.GetWeakPtr())); | |
103 } | |
104 | |
105 // Write() is not called yet. | |
106 return net::ERR_UNEXPECTED; | |
107 } | |
108 | |
109 int RemoteFileStreamWriter::Flush(const net::CompletionCallback& callback) { | |
110 // For remote file writer, Flush() is a no-op. Synchronization to the remote | |
111 // server is not done until the file is closed. | |
112 return net::OK; | |
113 } | |
114 | |
115 void RemoteFileStreamWriter::InvokePendingCancelCallback(int result) { | |
116 net::CompletionCallback callback = pending_cancel_callback_; | |
117 pending_cancel_callback_.Reset(); | |
118 callback.Run(result); | |
119 } | |
120 | |
121 } // namespace gdata | |
OLD | NEW |