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