| 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 |