| OLD | NEW |
| 1 // Copyright 2013 The Chromium Authors. All rights reserved. | 1 // Copyright 2013 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 "chrome/browser/chromeos/drive/drive_file_stream_reader.h" | 5 #include "chrome/browser/chromeos/drive/drive_file_stream_reader.h" |
| 6 | 6 |
| 7 #include <algorithm> | 7 #include <algorithm> |
| 8 #include <cstring> | 8 #include <cstring> |
| 9 | 9 |
| 10 #include "base/callback_helpers.h" | 10 #include "base/callback_helpers.h" |
| (...skipping 134 matching lines...) Expand 10 before | Expand all | Expand 10 after Loading... |
| 145 } else { | 145 } else { |
| 146 // An error occurs. Close the |file_reader_|. | 146 // An error occurs. Close the |file_reader_|. |
| 147 file_reader_.reset(); | 147 file_reader_.reset(); |
| 148 } | 148 } |
| 149 callback.Run(read_result); | 149 callback.Run(read_result); |
| 150 } | 150 } |
| 151 | 151 |
| 152 NetworkReaderProxy::NetworkReaderProxy( | 152 NetworkReaderProxy::NetworkReaderProxy( |
| 153 int64 offset, | 153 int64 offset, |
| 154 int64 content_length, | 154 int64 content_length, |
| 155 int64 full_content_length, |
| 155 const base::Closure& job_canceller) | 156 const base::Closure& job_canceller) |
| 156 : remaining_offset_(offset), | 157 : remaining_offset_(offset), |
| 157 remaining_content_length_(content_length), | 158 remaining_content_length_(content_length), |
| 159 is_full_download_(offset + content_length == full_content_length), |
| 158 error_code_(net::OK), | 160 error_code_(net::OK), |
| 159 buffer_length_(0), | 161 buffer_length_(0), |
| 160 job_canceller_(job_canceller) { | 162 job_canceller_(job_canceller) { |
| 161 DCHECK(BrowserThread::CurrentlyOn(BrowserThread::IO)); | 163 DCHECK(BrowserThread::CurrentlyOn(BrowserThread::IO)); |
| 162 } | 164 } |
| 163 | 165 |
| 164 NetworkReaderProxy::~NetworkReaderProxy() { | 166 NetworkReaderProxy::~NetworkReaderProxy() { |
| 165 if (!job_canceller_.is_null()) { | 167 if (!job_canceller_.is_null()) { |
| 166 job_canceller_.Run(); | 168 job_canceller_.Run(); |
| 167 } | 169 } |
| (...skipping 30 matching lines...) Expand all Loading... |
| 198 // No data is available. Keep the arguments, and return pending status. | 200 // No data is available. Keep the arguments, and return pending status. |
| 199 buffer_ = buffer; | 201 buffer_ = buffer; |
| 200 buffer_length_ = buffer_length; | 202 buffer_length_ = buffer_length; |
| 201 callback_ = callback; | 203 callback_ = callback; |
| 202 return net::ERR_IO_PENDING; | 204 return net::ERR_IO_PENDING; |
| 203 } | 205 } |
| 204 | 206 |
| 205 int result = ReadInternal(&pending_data_, buffer, buffer_length); | 207 int result = ReadInternal(&pending_data_, buffer, buffer_length); |
| 206 remaining_content_length_ -= result; | 208 remaining_content_length_ -= result; |
| 207 DCHECK_GE(remaining_content_length_, 0); | 209 DCHECK_GE(remaining_content_length_, 0); |
| 210 |
| 211 // Although OnCompleted() should reset |job_canceller_| when download is done, |
| 212 // due to timing issues the ReaderProxy instance may be destructed before the |
| 213 // notification. To fix the case we reset here earlier. |
| 214 if (is_full_download_ && remaining_content_length_ == 0) |
| 215 job_canceller_.Reset(); |
| 216 |
| 208 return result; | 217 return result; |
| 209 } | 218 } |
| 210 | 219 |
| 211 void NetworkReaderProxy::OnGetContent(scoped_ptr<std::string> data) { | 220 void NetworkReaderProxy::OnGetContent(scoped_ptr<std::string> data) { |
| 212 DCHECK(BrowserThread::CurrentlyOn(BrowserThread::IO)); | 221 DCHECK(BrowserThread::CurrentlyOn(BrowserThread::IO)); |
| 213 DCHECK(data && !data->empty()); | 222 DCHECK(data && !data->empty()); |
| 214 | 223 |
| 215 if (remaining_offset_ >= static_cast<int64>(data->length())) { | 224 if (remaining_offset_ >= static_cast<int64>(data->length())) { |
| 216 // Skip unneeded leading data. | 225 // Skip unneeded leading data. |
| 217 remaining_offset_ -= data->length(); | 226 remaining_offset_ -= data->length(); |
| 218 return; | 227 return; |
| 219 } | 228 } |
| 220 | 229 |
| 221 if (remaining_offset_ > 0) { | 230 if (remaining_offset_ > 0) { |
| 222 // Erase unnecessary leading bytes. | 231 // Erase unnecessary leading bytes. |
| 223 data->erase(0, static_cast<size_t>(remaining_offset_)); | 232 data->erase(0, static_cast<size_t>(remaining_offset_)); |
| 224 remaining_offset_ = 0; | 233 remaining_offset_ = 0; |
| 225 } | 234 } |
| 226 | 235 |
| 227 pending_data_.push_back(data.release()); | 236 pending_data_.push_back(data.release()); |
| 228 if (!buffer_.get()) { | 237 if (!buffer_.get()) { |
| 229 // No pending Read operation. | 238 // No pending Read operation. |
| 230 return; | 239 return; |
| 231 } | 240 } |
| 232 | 241 |
| 233 int result = ReadInternal(&pending_data_, buffer_.get(), buffer_length_); | 242 int result = ReadInternal(&pending_data_, buffer_.get(), buffer_length_); |
| 234 remaining_content_length_ -= result; | 243 remaining_content_length_ -= result; |
| 235 DCHECK_GE(remaining_content_length_, 0); | 244 DCHECK_GE(remaining_content_length_, 0); |
| 236 | 245 |
| 246 if (is_full_download_ && remaining_content_length_ == 0) |
| 247 job_canceller_.Reset(); |
| 248 |
| 237 buffer_ = NULL; | 249 buffer_ = NULL; |
| 238 buffer_length_ = 0; | 250 buffer_length_ = 0; |
| 239 DCHECK(!callback_.is_null()); | 251 DCHECK(!callback_.is_null()); |
| 240 base::ResetAndReturn(&callback_).Run(result); | 252 base::ResetAndReturn(&callback_).Run(result); |
| 241 } | 253 } |
| 242 | 254 |
| 243 void NetworkReaderProxy::OnCompleted(FileError error) { | 255 void NetworkReaderProxy::OnCompleted(FileError error) { |
| 244 DCHECK(BrowserThread::CurrentlyOn(BrowserThread::IO)); | 256 DCHECK(BrowserThread::CurrentlyOn(BrowserThread::IO)); |
| 245 // The downloading is completed, so we do not need to cancel the job | 257 // The downloading is completed, so we do not need to cancel the job |
| 246 // in the destructor. | 258 // in the destructor. |
| (...skipping 151 matching lines...) Expand 10 before | Expand all | Expand 10 after Loading... |
| 398 weak_ptr_factory_.InvalidateWeakPtrs(); | 410 weak_ptr_factory_.InvalidateWeakPtrs(); |
| 399 callback.Run( | 411 callback.Run( |
| 400 net::ERR_REQUEST_RANGE_NOT_SATISFIABLE, scoped_ptr<ResourceEntry>()); | 412 net::ERR_REQUEST_RANGE_NOT_SATISFIABLE, scoped_ptr<ResourceEntry>()); |
| 401 return; | 413 return; |
| 402 } | 414 } |
| 403 | 415 |
| 404 if (local_cache_file_path.empty()) { | 416 if (local_cache_file_path.empty()) { |
| 405 // The file is not cached, and being downloaded. | 417 // The file is not cached, and being downloaded. |
| 406 reader_proxy_.reset( | 418 reader_proxy_.reset( |
| 407 new internal::NetworkReaderProxy( | 419 new internal::NetworkReaderProxy( |
| 408 range_start, range_length, cancel_download_closure_)); | 420 range_start, range_length, |
| 421 entry->file_info().size(), cancel_download_closure_)); |
| 409 callback.Run(net::OK, entry.Pass()); | 422 callback.Run(net::OK, entry.Pass()); |
| 410 return; | 423 return; |
| 411 } | 424 } |
| 412 | 425 |
| 413 // Otherwise, open the stream for file. | 426 // Otherwise, open the stream for file. |
| 414 scoped_ptr<util::LocalFileReader> file_reader( | 427 scoped_ptr<util::LocalFileReader> file_reader( |
| 415 new util::LocalFileReader(file_task_runner_.get())); | 428 new util::LocalFileReader(file_task_runner_.get())); |
| 416 util::LocalFileReader* file_reader_ptr = file_reader.get(); | 429 util::LocalFileReader* file_reader_ptr = file_reader.get(); |
| 417 file_reader_ptr->Open( | 430 file_reader_ptr->Open( |
| 418 local_cache_file_path, | 431 local_cache_file_path, |
| (...skipping 50 matching lines...) Expand 10 before | Expand all | Expand 10 after Loading... |
| 469 // Note: due to the same reason, LocalReaderProxy::OnCompleted may | 482 // Note: due to the same reason, LocalReaderProxy::OnCompleted may |
| 470 // or may not be called. This is timing issue, and it is difficult to avoid | 483 // or may not be called. This is timing issue, and it is difficult to avoid |
| 471 // unfortunately. | 484 // unfortunately. |
| 472 if (error != FILE_ERROR_OK) { | 485 if (error != FILE_ERROR_OK) { |
| 473 callback.Run(FileErrorToNetError(error), scoped_ptr<ResourceEntry>()); | 486 callback.Run(FileErrorToNetError(error), scoped_ptr<ResourceEntry>()); |
| 474 } | 487 } |
| 475 } | 488 } |
| 476 } | 489 } |
| 477 | 490 |
| 478 } // namespace drive | 491 } // namespace drive |
| OLD | NEW |