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/fileapi/file_writer_delegate.h" | 5 #include "webkit/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/file_util_proxy.h" | 9 #include "base/file_util_proxy.h" |
10 #include "base/message_loop.h" | 10 #include "base/message_loop.h" |
(...skipping 73 matching lines...) Expand 10 before | Expand all | Expand 10 after Loading... | |
84 }; | 84 }; |
85 | 85 |
86 } // namespace (anonymous) | 86 } // namespace (anonymous) |
87 | 87 |
88 FileWriterDelegate::FileWriterDelegate( | 88 FileWriterDelegate::FileWriterDelegate( |
89 FileSystemOperation* file_system_operation, | 89 FileSystemOperation* file_system_operation, |
90 const FileSystemPath& path, | 90 const FileSystemPath& path, |
91 int64 offset, | 91 int64 offset, |
92 scoped_refptr<base::MessageLoopProxy> proxy) | 92 scoped_refptr<base::MessageLoopProxy> proxy) |
93 : file_system_operation_(file_system_operation), | 93 : file_system_operation_(file_system_operation), |
94 state_(FILE_WRITER_STATE_CREATED), | |
94 file_(base::kInvalidPlatformFileValue), | 95 file_(base::kInvalidPlatformFileValue), |
95 path_(path), | 96 path_(path), |
96 offset_(offset), | 97 offset_(offset), |
97 proxy_(proxy), | 98 proxy_(proxy), |
98 bytes_written_backlog_(0), | 99 bytes_written_backlog_(0), |
99 bytes_written_(0), | 100 bytes_written_(0), |
100 bytes_read_(0), | 101 bytes_read_(0), |
101 total_bytes_written_(0), | 102 total_bytes_written_(0), |
102 allowed_bytes_to_write_(0), | 103 allowed_bytes_to_write_(0), |
103 io_buffer_(new net::IOBufferWithSize(kReadBufSize)), | 104 io_buffer_(new net::IOBufferWithSize(kReadBufSize)), |
104 ALLOW_THIS_IN_INITIALIZER_LIST(weak_factory_(this)) { | 105 ALLOW_THIS_IN_INITIALIZER_LIST(weak_factory_(this)) { |
105 } | 106 } |
106 | 107 |
107 FileWriterDelegate::~FileWriterDelegate() { | 108 FileWriterDelegate::~FileWriterDelegate() { |
108 } | 109 } |
109 | 110 |
110 void FileWriterDelegate::OnGetFileInfoAndCallStartUpdate( | 111 void FileWriterDelegate::OnGetFileInfoAndCallStartUpdate( |
111 base::PlatformFileError error, | 112 base::PlatformFileError error, |
112 const base::PlatformFileInfo& file_info) { | 113 const base::PlatformFileInfo& file_info) { |
114 if (state_ == FILE_WRITER_STATE_CANCELED) { | |
ericu
2012/04/10 22:10:32
If we cancel while starting up, we call OnError(AB
kinuko
2012/04/11 01:11:46
We will eventually call OnError (or OnProgress(com
| |
115 OnError(base::PLATFORM_FILE_ERROR_ABORT); | |
116 return; | |
117 } | |
113 if (error) { | 118 if (error) { |
114 OnError(error); | 119 OnError(error); |
115 return; | 120 return; |
116 } | 121 } |
117 int64 allowed_bytes_growth = | 122 int64 allowed_bytes_growth = |
118 file_system_operation_context()->allowed_bytes_growth(); | 123 file_system_operation_context()->allowed_bytes_growth(); |
119 if (allowed_bytes_growth < 0) | 124 if (allowed_bytes_growth < 0) |
120 allowed_bytes_growth = 0; | 125 allowed_bytes_growth = 0; |
121 int64 overlap = file_info.size - offset_; | 126 int64 overlap = file_info.size - offset_; |
122 allowed_bytes_to_write_ = allowed_bytes_growth; | 127 allowed_bytes_to_write_ = allowed_bytes_growth; |
123 if (kint64max - overlap > allowed_bytes_growth) | 128 if (kint64max - overlap > allowed_bytes_growth) |
124 allowed_bytes_to_write_ += overlap; | 129 allowed_bytes_to_write_ += overlap; |
125 size_ = file_info.size; | 130 size_ = file_info.size; |
126 file_stream_.reset(new net::FileStream( | 131 file_stream_.reset(new net::FileStream( |
127 file_, | 132 file_, |
128 base::PLATFORM_FILE_OPEN | base::PLATFORM_FILE_WRITE | | 133 base::PLATFORM_FILE_OPEN | base::PLATFORM_FILE_WRITE | |
129 base::PLATFORM_FILE_ASYNC, | 134 base::PLATFORM_FILE_ASYNC, |
130 NULL)); | 135 NULL)); |
136 DCHECK_EQ(FILE_WRITER_STATE_CREATED, state_); | |
137 state_ = FILE_WRITER_STATE_REQUEST_STARTED; | |
131 request_->Start(); | 138 request_->Start(); |
132 } | 139 } |
133 | 140 |
134 void FileWriterDelegate::Start(base::PlatformFile file, | 141 void FileWriterDelegate::Start(base::PlatformFile file, |
135 net::URLRequest* request) { | 142 scoped_ptr<net::URLRequest> request) { |
143 DCHECK(!request_.get()); | |
144 DCHECK_EQ(FILE_WRITER_STATE_CREATED, state_); | |
145 | |
136 file_ = file; | 146 file_ = file; |
137 request_ = request; | 147 request_ = request.Pass(); |
138 | 148 |
139 scoped_refptr<InitializeTask> relay = new InitializeTask( | 149 scoped_refptr<InitializeTask> relay = new InitializeTask( |
140 file_, path_, | 150 file_, path_, |
141 file_system_operation_context(), | 151 file_system_operation_context(), |
142 base::Bind(&FileWriterDelegate::OnGetFileInfoAndCallStartUpdate, | 152 base::Bind(&FileWriterDelegate::OnGetFileInfoAndCallStartUpdate, |
143 weak_factory_.GetWeakPtr())); | 153 weak_factory_.GetWeakPtr())); |
144 relay->Start(proxy_, FROM_HERE); | 154 relay->Start(proxy_, FROM_HERE); |
145 } | 155 } |
146 | 156 |
157 void FileWriterDelegate::Cancel() { | |
158 if (state_ == FILE_WRITER_STATE_REQUEST_STARTED) { | |
159 DCHECK(request_.get()); | |
160 // This halts any callbacks on this delegate. | |
161 request_->Cancel(); | |
162 } | |
163 state_ = FILE_WRITER_STATE_CANCELED; | |
ericu
2012/04/10 22:10:32
This doesn't call quota_util()->proxy()->EndUpdate
kinuko
2012/04/11 01:11:46
We'll eventually call it.
If we've already starte
ericu
2012/04/11 03:24:13
The URLRequest header comments say
// ...It is g
kinuko
2012/04/11 09:06:02
Oh ok, I dived into the code before looking at the
| |
164 } | |
165 | |
147 void FileWriterDelegate::OnReceivedRedirect(net::URLRequest* request, | 166 void FileWriterDelegate::OnReceivedRedirect(net::URLRequest* request, |
148 const GURL& new_url, | 167 const GURL& new_url, |
149 bool* defer_redirect) { | 168 bool* defer_redirect) { |
150 NOTREACHED(); | 169 NOTREACHED(); |
151 OnError(base::PLATFORM_FILE_ERROR_SECURITY); | 170 OnError(base::PLATFORM_FILE_ERROR_SECURITY); |
152 } | 171 } |
153 | 172 |
154 void FileWriterDelegate::OnAuthRequired(net::URLRequest* request, | 173 void FileWriterDelegate::OnAuthRequired(net::URLRequest* request, |
155 net::AuthChallengeInfo* auth_info) { | 174 net::AuthChallengeInfo* auth_info) { |
156 NOTREACHED(); | 175 NOTREACHED(); |
157 OnError(base::PLATFORM_FILE_ERROR_SECURITY); | 176 OnError(base::PLATFORM_FILE_ERROR_SECURITY); |
158 } | 177 } |
159 | 178 |
160 void FileWriterDelegate::OnCertificateRequested( | 179 void FileWriterDelegate::OnCertificateRequested( |
161 net::URLRequest* request, | 180 net::URLRequest* request, |
162 net::SSLCertRequestInfo* cert_request_info) { | 181 net::SSLCertRequestInfo* cert_request_info) { |
163 NOTREACHED(); | 182 NOTREACHED(); |
164 OnError(base::PLATFORM_FILE_ERROR_SECURITY); | 183 OnError(base::PLATFORM_FILE_ERROR_SECURITY); |
165 } | 184 } |
166 | 185 |
167 void FileWriterDelegate::OnSSLCertificateError(net::URLRequest* request, | 186 void FileWriterDelegate::OnSSLCertificateError(net::URLRequest* request, |
168 const net::SSLInfo& ssl_info, | 187 const net::SSLInfo& ssl_info, |
169 bool fatal) { | 188 bool fatal) { |
170 NOTREACHED(); | 189 NOTREACHED(); |
171 OnError(base::PLATFORM_FILE_ERROR_SECURITY); | 190 OnError(base::PLATFORM_FILE_ERROR_SECURITY); |
172 } | 191 } |
173 | 192 |
174 void FileWriterDelegate::OnResponseStarted(net::URLRequest* request) { | 193 void FileWriterDelegate::OnResponseStarted(net::URLRequest* request) { |
175 DCHECK_EQ(request_, request); | 194 DCHECK_EQ(request_.get(), request); |
176 // file_stream_->Seek() blocks the IO thread. | 195 // file_stream_->Seek() blocks the IO thread. |
177 // See http://crbug.com/75548. | 196 // See http://crbug.com/75548. |
178 base::ThreadRestrictions::ScopedAllowIO allow_io; | 197 base::ThreadRestrictions::ScopedAllowIO allow_io; |
179 if (!request->status().is_success() || request->GetResponseCode() != 200) { | 198 if (!request->status().is_success() || request->GetResponseCode() != 200) { |
180 OnError(base::PLATFORM_FILE_ERROR_FAILED); | 199 OnError(base::PLATFORM_FILE_ERROR_FAILED); |
181 return; | 200 return; |
182 } | 201 } |
183 int64 error = file_stream_->Seek(net::FROM_BEGIN, offset_); | 202 int64 error = file_stream_->Seek(net::FROM_BEGIN, offset_); |
184 if (error != offset_) { | 203 if (error != offset_) { |
185 OnError(base::PLATFORM_FILE_ERROR_FAILED); | 204 OnError(base::PLATFORM_FILE_ERROR_FAILED); |
186 return; | 205 return; |
187 } | 206 } |
188 Read(); | 207 Read(); |
189 } | 208 } |
190 | 209 |
191 void FileWriterDelegate::OnReadCompleted(net::URLRequest* request, | 210 void FileWriterDelegate::OnReadCompleted(net::URLRequest* request, |
192 int bytes_read) { | 211 int bytes_read) { |
193 DCHECK_EQ(request_, request); | 212 DCHECK_EQ(request_.get(), request); |
194 if (!request->status().is_success()) { | 213 if (!request->status().is_success()) { |
195 OnError(base::PLATFORM_FILE_ERROR_FAILED); | 214 OnError(base::PLATFORM_FILE_ERROR_FAILED); |
196 return; | 215 return; |
197 } | 216 } |
198 OnDataReceived(bytes_read); | 217 OnDataReceived(bytes_read); |
199 } | 218 } |
200 | 219 |
201 void FileWriterDelegate::Read() { | 220 void FileWriterDelegate::Read() { |
202 bytes_written_ = 0; | 221 bytes_written_ = 0; |
203 bytes_read_ = 0; | 222 bytes_read_ = 0; |
(...skipping 46 matching lines...) Expand 10 before | Expand all | Expand 10 after Loading... | |
250 MessageLoop::current()->PostTask( | 269 MessageLoop::current()->PostTask( |
251 FROM_HERE, | 270 FROM_HERE, |
252 base::Bind(&FileWriterDelegate::OnDataWritten, | 271 base::Bind(&FileWriterDelegate::OnDataWritten, |
253 weak_factory_.GetWeakPtr(), write_response)); | 272 weak_factory_.GetWeakPtr(), write_response)); |
254 else if (net::ERR_IO_PENDING != write_response) | 273 else if (net::ERR_IO_PENDING != write_response) |
255 OnError(base::PLATFORM_FILE_ERROR_FAILED); | 274 OnError(base::PLATFORM_FILE_ERROR_FAILED); |
256 } | 275 } |
257 | 276 |
258 void FileWriterDelegate::OnDataWritten(int write_response) { | 277 void FileWriterDelegate::OnDataWritten(int write_response) { |
259 if (write_response > 0) { | 278 if (write_response > 0) { |
279 if (state_ == FILE_WRITER_STATE_CANCELED) { | |
280 // If the request has been cancelled (we could still be here if Cancel | |
281 // is made right after the last write) OnProgress will delete this | |
282 // (in FileWriterDelegate::DidWrite). | |
ericu
2012/04/10 22:10:32
s/FileWriterDelete/FileSystemOperation/?
kinuko
2012/04/11 01:11:46
Done.
| |
283 OnProgress(write_response, true); | |
284 return; | |
285 } | |
260 OnProgress(write_response, false); | 286 OnProgress(write_response, false); |
261 cursor_->DidConsume(write_response); | 287 cursor_->DidConsume(write_response); |
262 bytes_written_ += write_response; | 288 bytes_written_ += write_response; |
263 total_bytes_written_ += write_response; | 289 total_bytes_written_ += write_response; |
264 if (bytes_written_ == bytes_read_) | 290 if (bytes_written_ == bytes_read_) |
265 Read(); | 291 Read(); |
266 else | 292 else |
267 Write(); | 293 Write(); |
268 } else { | 294 } else { |
269 OnError(base::PLATFORM_FILE_ERROR_FAILED); | 295 OnError(base::PLATFORM_FILE_ERROR_FAILED); |
270 } | 296 } |
271 } | 297 } |
272 | 298 |
273 void FileWriterDelegate::OnError(base::PlatformFileError error) { | 299 void FileWriterDelegate::OnError(base::PlatformFileError error) { |
274 request_->set_delegate(NULL); | 300 if (state_ == FILE_WRITER_STATE_REQUEST_STARTED) { |
275 request_->Cancel(); | 301 DCHECK(request_.get()); |
302 request_->set_delegate(NULL); | |
303 request_->Cancel(); | |
304 } | |
276 | 305 |
277 if (quota_util()) | 306 if (quota_util()) |
278 quota_util()->proxy()->EndUpdateOrigin(path_.origin(), path_.type()); | 307 quota_util()->proxy()->EndUpdateOrigin(path_.origin(), path_.type()); |
279 | 308 |
280 file_system_operation_->DidWrite(error, 0, true); | 309 file_system_operation_->DidWrite(error, 0, true); |
281 } | 310 } |
282 | 311 |
283 void FileWriterDelegate::OnProgress(int bytes_written, bool done) { | 312 void FileWriterDelegate::OnProgress(int bytes_written, bool done) { |
284 DCHECK(bytes_written + bytes_written_backlog_ >= bytes_written_backlog_); | 313 DCHECK(bytes_written + bytes_written_backlog_ >= bytes_written_backlog_); |
285 if (quota_util() && | 314 if (quota_util() && |
(...skipping 33 matching lines...) Expand 10 before | Expand all | Expand 10 after Loading... | |
319 | 348 |
320 FileSystemQuotaUtil* FileWriterDelegate::quota_util() const { | 349 FileSystemQuotaUtil* FileWriterDelegate::quota_util() const { |
321 DCHECK(file_system_operation_); | 350 DCHECK(file_system_operation_); |
322 DCHECK(file_system_operation_->file_system_context()); | 351 DCHECK(file_system_operation_->file_system_context()); |
323 DCHECK(file_system_operation_->file_system_operation_context()); | 352 DCHECK(file_system_operation_->file_system_operation_context()); |
324 return file_system_operation_->file_system_context()->GetQuotaUtil( | 353 return file_system_operation_->file_system_context()->GetQuotaUtil( |
325 path_.type()); | 354 path_.type()); |
326 } | 355 } |
327 | 356 |
328 } // namespace fileapi | 357 } // namespace fileapi |
OLD | NEW |