| OLD | NEW |
| 1 // Copyright (c) 2012 The Chromium Authors. All rights reserved. | 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 | 2 // Use of this source code is governed by a BSD-style license that can be |
| 3 // found in the LICENSE file. | 3 // found in the LICENSE file. |
| 4 | 4 |
| 5 #include "webkit/browser/fileapi/file_writer_delegate.h" | 5 #include "webkit/browser/fileapi/file_writer_delegate.h" |
| 6 | 6 |
| 7 #include "base/bind.h" | 7 #include "base/bind.h" |
| 8 #include "base/callback.h" | 8 #include "base/callback.h" |
| 9 #include "base/files/file_util_proxy.h" | 9 #include "base/files/file_util_proxy.h" |
| 10 #include "base/message_loop/message_loop.h" | 10 #include "base/message_loop/message_loop.h" |
| (...skipping 36 matching lines...) Expand 10 before | Expand all | Expand 10 after Loading... |
| 47 request_->set_delegate(NULL); | 47 request_->set_delegate(NULL); |
| 48 request_->Cancel(); | 48 request_->Cancel(); |
| 49 } | 49 } |
| 50 | 50 |
| 51 const int status = file_stream_writer_->Cancel( | 51 const int status = file_stream_writer_->Cancel( |
| 52 base::Bind(&FileWriterDelegate::OnWriteCancelled, | 52 base::Bind(&FileWriterDelegate::OnWriteCancelled, |
| 53 weak_factory_.GetWeakPtr())); | 53 weak_factory_.GetWeakPtr())); |
| 54 // Return true to finish immediately if we have no pending writes. | 54 // Return true to finish immediately if we have no pending writes. |
| 55 // Otherwise we'll do the final cleanup in the Cancel callback. | 55 // Otherwise we'll do the final cleanup in the Cancel callback. |
| 56 if (status != net::ERR_IO_PENDING) { | 56 if (status != net::ERR_IO_PENDING) { |
| 57 write_callback_.Run(base::PLATFORM_FILE_ERROR_ABORT, 0, | 57 write_callback_.Run(base::File::FILE_ERROR_ABORT, 0, |
| 58 GetCompletionStatusOnError()); | 58 GetCompletionStatusOnError()); |
| 59 } | 59 } |
| 60 } | 60 } |
| 61 | 61 |
| 62 void FileWriterDelegate::OnReceivedRedirect(net::URLRequest* request, | 62 void FileWriterDelegate::OnReceivedRedirect(net::URLRequest* request, |
| 63 const GURL& new_url, | 63 const GURL& new_url, |
| 64 bool* defer_redirect) { | 64 bool* defer_redirect) { |
| 65 NOTREACHED(); | 65 NOTREACHED(); |
| 66 OnError(base::PLATFORM_FILE_ERROR_SECURITY); | 66 OnError(base::File::FILE_ERROR_SECURITY); |
| 67 } | 67 } |
| 68 | 68 |
| 69 void FileWriterDelegate::OnAuthRequired(net::URLRequest* request, | 69 void FileWriterDelegate::OnAuthRequired(net::URLRequest* request, |
| 70 net::AuthChallengeInfo* auth_info) { | 70 net::AuthChallengeInfo* auth_info) { |
| 71 NOTREACHED(); | 71 NOTREACHED(); |
| 72 OnError(base::PLATFORM_FILE_ERROR_SECURITY); | 72 OnError(base::File::FILE_ERROR_SECURITY); |
| 73 } | 73 } |
| 74 | 74 |
| 75 void FileWriterDelegate::OnCertificateRequested( | 75 void FileWriterDelegate::OnCertificateRequested( |
| 76 net::URLRequest* request, | 76 net::URLRequest* request, |
| 77 net::SSLCertRequestInfo* cert_request_info) { | 77 net::SSLCertRequestInfo* cert_request_info) { |
| 78 NOTREACHED(); | 78 NOTREACHED(); |
| 79 OnError(base::PLATFORM_FILE_ERROR_SECURITY); | 79 OnError(base::File::FILE_ERROR_SECURITY); |
| 80 } | 80 } |
| 81 | 81 |
| 82 void FileWriterDelegate::OnSSLCertificateError(net::URLRequest* request, | 82 void FileWriterDelegate::OnSSLCertificateError(net::URLRequest* request, |
| 83 const net::SSLInfo& ssl_info, | 83 const net::SSLInfo& ssl_info, |
| 84 bool fatal) { | 84 bool fatal) { |
| 85 NOTREACHED(); | 85 NOTREACHED(); |
| 86 OnError(base::PLATFORM_FILE_ERROR_SECURITY); | 86 OnError(base::File::FILE_ERROR_SECURITY); |
| 87 } | 87 } |
| 88 | 88 |
| 89 void FileWriterDelegate::OnResponseStarted(net::URLRequest* request) { | 89 void FileWriterDelegate::OnResponseStarted(net::URLRequest* request) { |
| 90 DCHECK_EQ(request_.get(), request); | 90 DCHECK_EQ(request_.get(), request); |
| 91 if (!request->status().is_success() || request->GetResponseCode() != 200) { | 91 if (!request->status().is_success() || request->GetResponseCode() != 200) { |
| 92 OnError(base::PLATFORM_FILE_ERROR_FAILED); | 92 OnError(base::File::FILE_ERROR_FAILED); |
| 93 return; | 93 return; |
| 94 } | 94 } |
| 95 Read(); | 95 Read(); |
| 96 } | 96 } |
| 97 | 97 |
| 98 void FileWriterDelegate::OnReadCompleted(net::URLRequest* request, | 98 void FileWriterDelegate::OnReadCompleted(net::URLRequest* request, |
| 99 int bytes_read) { | 99 int bytes_read) { |
| 100 DCHECK_EQ(request_.get(), request); | 100 DCHECK_EQ(request_.get(), request); |
| 101 if (!request->status().is_success()) { | 101 if (!request->status().is_success()) { |
| 102 OnError(base::PLATFORM_FILE_ERROR_FAILED); | 102 OnError(base::File::FILE_ERROR_FAILED); |
| 103 return; | 103 return; |
| 104 } | 104 } |
| 105 OnDataReceived(bytes_read); | 105 OnDataReceived(bytes_read); |
| 106 } | 106 } |
| 107 | 107 |
| 108 void FileWriterDelegate::Read() { | 108 void FileWriterDelegate::Read() { |
| 109 bytes_written_ = 0; | 109 bytes_written_ = 0; |
| 110 bytes_read_ = 0; | 110 bytes_read_ = 0; |
| 111 if (request_->Read(io_buffer_.get(), io_buffer_->size(), &bytes_read_)) { | 111 if (request_->Read(io_buffer_.get(), io_buffer_->size(), &bytes_read_)) { |
| 112 base::MessageLoop::current()->PostTask( | 112 base::MessageLoop::current()->PostTask( |
| 113 FROM_HERE, | 113 FROM_HERE, |
| 114 base::Bind(&FileWriterDelegate::OnDataReceived, | 114 base::Bind(&FileWriterDelegate::OnDataReceived, |
| 115 weak_factory_.GetWeakPtr(), bytes_read_)); | 115 weak_factory_.GetWeakPtr(), bytes_read_)); |
| 116 } else if (!request_->status().is_io_pending()) { | 116 } else if (!request_->status().is_io_pending()) { |
| 117 OnError(base::PLATFORM_FILE_ERROR_FAILED); | 117 OnError(base::File::FILE_ERROR_FAILED); |
| 118 } | 118 } |
| 119 } | 119 } |
| 120 | 120 |
| 121 void FileWriterDelegate::OnDataReceived(int bytes_read) { | 121 void FileWriterDelegate::OnDataReceived(int bytes_read) { |
| 122 bytes_read_ = bytes_read; | 122 bytes_read_ = bytes_read; |
| 123 if (!bytes_read_) { // We're done. | 123 if (!bytes_read_) { // We're done. |
| 124 OnProgress(0, true); | 124 OnProgress(0, true); |
| 125 } else { | 125 } else { |
| 126 // This could easily be optimized to rotate between a pool of buffers, so | 126 // This could easily be optimized to rotate between a pool of buffers, so |
| 127 // that we could read and write at the same time. It's not yet clear that | 127 // that we could read and write at the same time. It's not yet clear that |
| (...skipping 10 matching lines...) Expand all Loading... |
| 138 file_stream_writer_->Write(cursor_.get(), | 138 file_stream_writer_->Write(cursor_.get(), |
| 139 static_cast<int>(bytes_to_write), | 139 static_cast<int>(bytes_to_write), |
| 140 base::Bind(&FileWriterDelegate::OnDataWritten, | 140 base::Bind(&FileWriterDelegate::OnDataWritten, |
| 141 weak_factory_.GetWeakPtr())); | 141 weak_factory_.GetWeakPtr())); |
| 142 if (write_response > 0) { | 142 if (write_response > 0) { |
| 143 base::MessageLoop::current()->PostTask( | 143 base::MessageLoop::current()->PostTask( |
| 144 FROM_HERE, | 144 FROM_HERE, |
| 145 base::Bind(&FileWriterDelegate::OnDataWritten, | 145 base::Bind(&FileWriterDelegate::OnDataWritten, |
| 146 weak_factory_.GetWeakPtr(), write_response)); | 146 weak_factory_.GetWeakPtr(), write_response)); |
| 147 } else if (net::ERR_IO_PENDING != write_response) { | 147 } else if (net::ERR_IO_PENDING != write_response) { |
| 148 OnError(NetErrorToPlatformFileError(write_response)); | 148 OnError(NetErrorToFileError(write_response)); |
| 149 } | 149 } |
| 150 } | 150 } |
| 151 | 151 |
| 152 void FileWriterDelegate::OnDataWritten(int write_response) { | 152 void FileWriterDelegate::OnDataWritten(int write_response) { |
| 153 if (write_response > 0) { | 153 if (write_response > 0) { |
| 154 OnProgress(write_response, false); | 154 OnProgress(write_response, false); |
| 155 cursor_->DidConsume(write_response); | 155 cursor_->DidConsume(write_response); |
| 156 bytes_written_ += write_response; | 156 bytes_written_ += write_response; |
| 157 if (bytes_written_ == bytes_read_) | 157 if (bytes_written_ == bytes_read_) |
| 158 Read(); | 158 Read(); |
| 159 else | 159 else |
| 160 Write(); | 160 Write(); |
| 161 } else { | 161 } else { |
| 162 OnError(NetErrorToPlatformFileError(write_response)); | 162 OnError(NetErrorToFileError(write_response)); |
| 163 } | 163 } |
| 164 } | 164 } |
| 165 | 165 |
| 166 FileWriterDelegate::WriteProgressStatus | 166 FileWriterDelegate::WriteProgressStatus |
| 167 FileWriterDelegate::GetCompletionStatusOnError() const { | 167 FileWriterDelegate::GetCompletionStatusOnError() const { |
| 168 return writing_started_ ? ERROR_WRITE_STARTED : ERROR_WRITE_NOT_STARTED; | 168 return writing_started_ ? ERROR_WRITE_STARTED : ERROR_WRITE_NOT_STARTED; |
| 169 } | 169 } |
| 170 | 170 |
| 171 void FileWriterDelegate::OnError(base::PlatformFileError error) { | 171 void FileWriterDelegate::OnError(base::File::Error error) { |
| 172 if (request_) { | 172 if (request_) { |
| 173 request_->set_delegate(NULL); | 173 request_->set_delegate(NULL); |
| 174 request_->Cancel(); | 174 request_->Cancel(); |
| 175 } | 175 } |
| 176 | 176 |
| 177 if (writing_started_) | 177 if (writing_started_) |
| 178 FlushForCompletion(error, 0, ERROR_WRITE_STARTED); | 178 FlushForCompletion(error, 0, ERROR_WRITE_STARTED); |
| 179 else | 179 else |
| 180 write_callback_.Run(error, 0, ERROR_WRITE_NOT_STARTED); | 180 write_callback_.Run(error, 0, ERROR_WRITE_NOT_STARTED); |
| 181 } | 181 } |
| 182 | 182 |
| 183 void FileWriterDelegate::OnProgress(int bytes_written, bool done) { | 183 void FileWriterDelegate::OnProgress(int bytes_written, bool done) { |
| 184 DCHECK(bytes_written + bytes_written_backlog_ >= bytes_written_backlog_); | 184 DCHECK(bytes_written + bytes_written_backlog_ >= bytes_written_backlog_); |
| 185 static const int kMinProgressDelayMS = 200; | 185 static const int kMinProgressDelayMS = 200; |
| 186 base::Time currentTime = base::Time::Now(); | 186 base::Time currentTime = base::Time::Now(); |
| 187 if (done || last_progress_event_time_.is_null() || | 187 if (done || last_progress_event_time_.is_null() || |
| 188 (currentTime - last_progress_event_time_).InMilliseconds() > | 188 (currentTime - last_progress_event_time_).InMilliseconds() > |
| 189 kMinProgressDelayMS) { | 189 kMinProgressDelayMS) { |
| 190 bytes_written += bytes_written_backlog_; | 190 bytes_written += bytes_written_backlog_; |
| 191 last_progress_event_time_ = currentTime; | 191 last_progress_event_time_ = currentTime; |
| 192 bytes_written_backlog_ = 0; | 192 bytes_written_backlog_ = 0; |
| 193 | 193 |
| 194 if (done) { | 194 if (done) { |
| 195 FlushForCompletion(base::PLATFORM_FILE_OK, bytes_written, | 195 FlushForCompletion(base::File::FILE_OK, bytes_written, |
| 196 SUCCESS_COMPLETED); | 196 SUCCESS_COMPLETED); |
| 197 } else { | 197 } else { |
| 198 write_callback_.Run(base::PLATFORM_FILE_OK, bytes_written, | 198 write_callback_.Run(base::File::FILE_OK, bytes_written, |
| 199 SUCCESS_IO_PENDING); | 199 SUCCESS_IO_PENDING); |
| 200 } | 200 } |
| 201 return; | 201 return; |
| 202 } | 202 } |
| 203 bytes_written_backlog_ += bytes_written; | 203 bytes_written_backlog_ += bytes_written; |
| 204 } | 204 } |
| 205 | 205 |
| 206 void FileWriterDelegate::OnWriteCancelled(int status) { | 206 void FileWriterDelegate::OnWriteCancelled(int status) { |
| 207 write_callback_.Run(base::PLATFORM_FILE_ERROR_ABORT, 0, | 207 write_callback_.Run(base::File::FILE_ERROR_ABORT, 0, |
| 208 GetCompletionStatusOnError()); | 208 GetCompletionStatusOnError()); |
| 209 } | 209 } |
| 210 | 210 |
| 211 void FileWriterDelegate::FlushForCompletion( | 211 void FileWriterDelegate::FlushForCompletion( |
| 212 base::PlatformFileError error, | 212 base::File::Error error, |
| 213 int bytes_written, | 213 int bytes_written, |
| 214 WriteProgressStatus progress_status) { | 214 WriteProgressStatus progress_status) { |
| 215 int flush_error = file_stream_writer_->Flush( | 215 int flush_error = file_stream_writer_->Flush( |
| 216 base::Bind(&FileWriterDelegate::OnFlushed, weak_factory_.GetWeakPtr(), | 216 base::Bind(&FileWriterDelegate::OnFlushed, weak_factory_.GetWeakPtr(), |
| 217 error, bytes_written, progress_status)); | 217 error, bytes_written, progress_status)); |
| 218 if (flush_error != net::ERR_IO_PENDING) | 218 if (flush_error != net::ERR_IO_PENDING) |
| 219 OnFlushed(error, bytes_written, progress_status, flush_error); | 219 OnFlushed(error, bytes_written, progress_status, flush_error); |
| 220 } | 220 } |
| 221 | 221 |
| 222 void FileWriterDelegate::OnFlushed(base::PlatformFileError error, | 222 void FileWriterDelegate::OnFlushed(base::File::Error error, |
| 223 int bytes_written, | 223 int bytes_written, |
| 224 WriteProgressStatus progress_status, | 224 WriteProgressStatus progress_status, |
| 225 int flush_error) { | 225 int flush_error) { |
| 226 if (error == base::PLATFORM_FILE_OK && flush_error != net::OK) { | 226 if (error == base::File::FILE_OK && flush_error != net::OK) { |
| 227 // If the Flush introduced an error, overwrite the status. | 227 // If the Flush introduced an error, overwrite the status. |
| 228 // Otherwise, keep the original error status. | 228 // Otherwise, keep the original error status. |
| 229 error = NetErrorToPlatformFileError(flush_error); | 229 error = NetErrorToFileError(flush_error); |
| 230 progress_status = GetCompletionStatusOnError(); | 230 progress_status = GetCompletionStatusOnError(); |
| 231 } | 231 } |
| 232 write_callback_.Run(error, bytes_written, progress_status); | 232 write_callback_.Run(error, bytes_written, progress_status); |
| 233 } | 233 } |
| 234 | 234 |
| 235 } // namespace fileapi | 235 } // namespace fileapi |
| OLD | NEW |