Chromium Code Reviews| 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 321 matching lines...) Expand 10 before | Expand all | Expand 10 after Loading... | |
| 332 int DriveFileStreamReader::Read(net::IOBuffer* buffer, int buffer_length, | 332 int DriveFileStreamReader::Read(net::IOBuffer* buffer, int buffer_length, |
| 333 const net::CompletionCallback& callback) { | 333 const net::CompletionCallback& callback) { |
| 334 DCHECK(BrowserThread::CurrentlyOn(BrowserThread::IO)); | 334 DCHECK(BrowserThread::CurrentlyOn(BrowserThread::IO)); |
| 335 DCHECK(reader_proxy_); | 335 DCHECK(reader_proxy_); |
| 336 DCHECK(buffer); | 336 DCHECK(buffer); |
| 337 DCHECK(!callback.is_null()); | 337 DCHECK(!callback.is_null()); |
| 338 return reader_proxy_->Read(buffer, buffer_length, callback); | 338 return reader_proxy_->Read(buffer, buffer_length, callback); |
| 339 } | 339 } |
| 340 | 340 |
| 341 void DriveFileStreamReader::InitializeAfterGetFileContentInitialized( | 341 void DriveFileStreamReader::InitializeAfterGetFileContentInitialized( |
| 342 const net::HttpByteRange& in_byte_range, | 342 const net::HttpByteRange& byte_range, |
| 343 const InitializeCompletionCallback& callback, | 343 const InitializeCompletionCallback& callback, |
| 344 FileError error, | 344 FileError error, |
| 345 scoped_ptr<ResourceEntry> entry, | 345 scoped_ptr<ResourceEntry> entry, |
| 346 const base::FilePath& local_cache_file_path, | 346 const base::FilePath& local_cache_file_path, |
| 347 const base::Closure& ui_cancel_download_closure) { | 347 const base::Closure& ui_cancel_download_closure) { |
| 348 DCHECK(BrowserThread::CurrentlyOn(BrowserThread::IO)); | 348 DCHECK(BrowserThread::CurrentlyOn(BrowserThread::IO)); |
| 349 | 349 |
| 350 if (error != FILE_ERROR_OK) { | 350 if (error != FILE_ERROR_OK) { |
| 351 callback.Run(FileErrorToNetError(error), scoped_ptr<ResourceEntry>()); | 351 callback.Run(FileErrorToNetError(error), scoped_ptr<ResourceEntry>()); |
| 352 return; | 352 return; |
| 353 } | 353 } |
| 354 DCHECK(entry); | 354 DCHECK(entry); |
| 355 | 355 |
| 356 net::HttpByteRange byte_range = in_byte_range; | 356 // Note: both boundary of |byte_range| are inclusive. |
| 357 if (!byte_range.ComputeBounds(entry->file_info().size())) { | 357 // Convert it to half-exclusive range with missing bounds filled. |
|
hashimoto
2013/12/19 08:53:40
Is it OK to ignore suffix byte range?
kinaba
2013/12/20 03:57:55
Good catch. Recovered the support for suffix range
| |
| 358 const int64 range_start = byte_range.HasFirstBytePosition() ? | |
| 359 byte_range.first_byte_position() : 0; | |
| 360 const int64 range_end = byte_range.HasLastBytePosition() ? | |
| 361 byte_range.last_byte_position() + 1 : entry->file_info().size(); | |
| 362 | |
| 363 if (range_start > range_end || entry->file_info().size() < range_end) { | |
| 358 // If |byte_range| is invalid (e.g. out of bounds), return with an error. | 364 // If |byte_range| is invalid (e.g. out of bounds), return with an error. |
| 359 // At the same time, we cancel the in-flight downloading operation if | 365 // At the same time, we cancel the in-flight downloading operation if |
| 360 // needed and and invalidate weak pointers so that we won't | 366 // needed and and invalidate weak pointers so that we won't |
| 361 // receive unwanted callbacks. | 367 // receive unwanted callbacks. |
| 362 if (!ui_cancel_download_closure.is_null()) | 368 if (!ui_cancel_download_closure.is_null()) |
| 363 RunTaskOnUIThread(ui_cancel_download_closure); | 369 RunTaskOnUIThread(ui_cancel_download_closure); |
| 364 weak_ptr_factory_.InvalidateWeakPtrs(); | 370 weak_ptr_factory_.InvalidateWeakPtrs(); |
| 365 callback.Run( | 371 callback.Run( |
| 366 net::ERR_REQUEST_RANGE_NOT_SATISFIABLE, scoped_ptr<ResourceEntry>()); | 372 net::ERR_REQUEST_RANGE_NOT_SATISFIABLE, scoped_ptr<ResourceEntry>()); |
| 367 return; | 373 return; |
| 368 } | 374 } |
| 369 | 375 |
| 370 // Note: both boundary of |byte_range| are inclusive. | |
| 371 int64 range_length = | |
| 372 byte_range.last_byte_position() - byte_range.first_byte_position() + 1; | |
| 373 DCHECK_GE(range_length, 0); | |
| 374 | |
| 375 if (local_cache_file_path.empty()) { | 376 if (local_cache_file_path.empty()) { |
| 376 // The file is not cached, and being downloaded. | 377 // The file is not cached, and being downloaded. |
| 377 DCHECK(!ui_cancel_download_closure.is_null()); | 378 DCHECK(!ui_cancel_download_closure.is_null()); |
| 378 reader_proxy_.reset( | 379 reader_proxy_.reset( |
| 379 new internal::NetworkReaderProxy( | 380 new internal::NetworkReaderProxy( |
| 380 byte_range.first_byte_position(), range_length, | 381 range_start, range_end - range_start, |
| 381 base::Bind(&RunTaskOnUIThread, ui_cancel_download_closure))); | 382 base::Bind(&RunTaskOnUIThread, ui_cancel_download_closure))); |
| 382 callback.Run(net::OK, entry.Pass()); | 383 callback.Run(net::OK, entry.Pass()); |
| 383 return; | 384 return; |
| 384 } | 385 } |
| 385 | 386 |
| 386 // Otherwise, open the stream for file. | 387 // Otherwise, open the stream for file. |
| 387 scoped_ptr<util::LocalFileReader> file_reader( | 388 scoped_ptr<util::LocalFileReader> file_reader( |
| 388 new util::LocalFileReader(file_task_runner_.get())); | 389 new util::LocalFileReader(file_task_runner_.get())); |
| 389 util::LocalFileReader* file_reader_ptr = file_reader.get(); | 390 util::LocalFileReader* file_reader_ptr = file_reader.get(); |
| 390 file_reader_ptr->Open( | 391 file_reader_ptr->Open( |
| 391 local_cache_file_path, | 392 local_cache_file_path, |
| 392 byte_range.first_byte_position(), | 393 range_start, |
| 393 base::Bind( | 394 base::Bind( |
| 394 &DriveFileStreamReader::InitializeAfterLocalFileOpen, | 395 &DriveFileStreamReader::InitializeAfterLocalFileOpen, |
| 395 weak_ptr_factory_.GetWeakPtr(), | 396 weak_ptr_factory_.GetWeakPtr(), |
| 396 range_length, | 397 range_end - range_start, |
| 397 callback, | 398 callback, |
| 398 base::Passed(&entry), | 399 base::Passed(&entry), |
| 399 base::Passed(&file_reader))); | 400 base::Passed(&file_reader))); |
| 400 } | 401 } |
| 401 | 402 |
| 402 void DriveFileStreamReader::InitializeAfterLocalFileOpen( | 403 void DriveFileStreamReader::InitializeAfterLocalFileOpen( |
| 403 int64 length, | 404 int64 length, |
| 404 const InitializeCompletionCallback& callback, | 405 const InitializeCompletionCallback& callback, |
| 405 scoped_ptr<ResourceEntry> entry, | 406 scoped_ptr<ResourceEntry> entry, |
| 406 scoped_ptr<util::LocalFileReader> file_reader, | 407 scoped_ptr<util::LocalFileReader> file_reader, |
| (...skipping 35 matching lines...) Expand 10 before | Expand all | Expand 10 after Loading... | |
| 442 // Note: due to the same reason, LocalReaderProxy::OnCompleted may | 443 // Note: due to the same reason, LocalReaderProxy::OnCompleted may |
| 443 // or may not be called. This is timing issue, and it is difficult to avoid | 444 // or may not be called. This is timing issue, and it is difficult to avoid |
| 444 // unfortunately. | 445 // unfortunately. |
| 445 if (error != FILE_ERROR_OK) { | 446 if (error != FILE_ERROR_OK) { |
| 446 callback.Run(FileErrorToNetError(error), scoped_ptr<ResourceEntry>()); | 447 callback.Run(FileErrorToNetError(error), scoped_ptr<ResourceEntry>()); |
| 447 } | 448 } |
| 448 } | 449 } |
| 449 } | 450 } |
| 450 | 451 |
| 451 } // namespace drive | 452 } // namespace drive |
| OLD | NEW |