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