1 // Copyright (c) 2013 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/browser/fileapi/upload_file_system_file_element_reader.h" 6 7 #include "base/bind.h" 8 #include "net/base/net_errors.h" 9 #include "webkit/browser/blob/file_stream_reader.h" 10 #include "webkit/browser/fileapi/file_system_context.h" 11 #include "webkit/browser/fileapi/file_system_url.h" 12 13 namespace fileapi { 14 15 UploadFileSystemFileElementReader::UploadFileSystemFileElementReader( 16 FileSystemContext* file_system_context, 17 const GURL& url, 18 uint64 range_offset, 19 uint64 range_length, 20 const base::Time& expected_modification_time) 21 : file_system_context_(file_system_context), 22 url_(url), 23 range_offset_(range_offset), 24 range_length_(range_length), 25 expected_modification_time_(expected_modification_time), 26 stream_length_(0), 27 position_(0), 28 weak_ptr_factory_(this) { 29 } 30 31 UploadFileSystemFileElementReader::~UploadFileSystemFileElementReader() { 32 } 33 34 int UploadFileSystemFileElementReader::Init( 35 const net::CompletionCallback& callback) { 36 // Reset states. 37 weak_ptr_factory_.InvalidateWeakPtrs(); 38 stream_length_ = 0; 39 position_ = 0; 40 41 // Initialize the stream reader and the length. 42 stream_reader_ = 43 file_system_context_->CreateFileStreamReader( 44 file_system_context_->CrackURL(url_), 45 range_offset_, 46 expected_modification_time_); 47 DCHECK(stream_reader_); 48 49 const int64 result = stream_reader_->GetLength( 50 base::Bind(&UploadFileSystemFileElementReader::OnGetLength, 51 weak_ptr_factory_.GetWeakPtr(), 52 callback)); 53 if (result >= 0) { 54 stream_length_ = result; 55 return net::OK; 56 } 57 58 // The error code can be casted to int. 59 return static_cast<int>(result); 60 } 61 62 uint64 UploadFileSystemFileElementReader::GetContentLength() const { 63 return std::min(stream_length_, range_length_); 64 } 65 66 uint64 UploadFileSystemFileElementReader::BytesRemaining() const { 67 return GetContentLength() - position_; 68 } 69 70 int UploadFileSystemFileElementReader::Read( 71 net::IOBuffer* buf, 72 int buf_length, 73 const net::CompletionCallback& callback) { 74 DCHECK_LT(0, buf_length); 75 DCHECK(stream_reader_); 76 77 const uint64 num_bytes_to_read = 78 std::min(BytesRemaining(), static_cast<uint64>(buf_length)); 79 80 if (num_bytes_to_read == 0) 81 return 0; 82 83 const int result = stream_reader_->Read( 84 buf, num_bytes_to_read, 85 base::Bind(&UploadFileSystemFileElementReader::OnRead, 86 weak_ptr_factory_.GetWeakPtr(), 87 callback)); 88 if (result >= 0) 89 OnRead(net::CompletionCallback(), result); 90 return result; 91 } 92 93 void UploadFileSystemFileElementReader::OnGetLength( 94 const net::CompletionCallback& callback, 95 int64 result) { 96 if (result >= 0) { 97 stream_length_ = result; 98 callback.Run(net::OK); 99 return; 100 } 101 callback.Run(result); 102 } 103 104 void UploadFileSystemFileElementReader::OnRead( 105 const net::CompletionCallback& callback, 106 int result) { 107 if (result > 0) { 108 position_ += result; 109 DCHECK_LE(position_, GetContentLength()); 110 } 111 if (!callback.is_null()) 112 callback.Run(result); 113 } 114 115 } // namespace fileapi 116