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