webkit_file_stream_reader_impl.cc revision 5c02ac1a9c1b504631c0a3d2b6e737b5d738bae1
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 "chrome/browser/chromeos/drive/fileapi/webkit_file_stream_reader_impl.h" 6 7#include "base/bind.h" 8#include "base/bind_helpers.h" 9#include "base/callback.h" 10#include "base/logging.h" 11#include "chrome/browser/chromeos/drive/drive.pb.h" 12#include "chrome/browser/chromeos/drive/drive_file_stream_reader.h" 13#include "content/public/browser/browser_thread.h" 14#include "net/base/io_buffer.h" 15#include "net/base/net_errors.h" 16#include "net/http/http_byte_range.h" 17 18using content::BrowserThread; 19 20namespace drive { 21namespace internal { 22 23WebkitFileStreamReaderImpl::WebkitFileStreamReaderImpl( 24 const DriveFileStreamReader::FileSystemGetter& file_system_getter, 25 base::SequencedTaskRunner* file_task_runner, 26 const base::FilePath& drive_file_path, 27 int64 offset, 28 const base::Time& expected_modification_time) 29 : stream_reader_( 30 new DriveFileStreamReader(file_system_getter, file_task_runner)), 31 drive_file_path_(drive_file_path), 32 offset_(offset), 33 expected_modification_time_(expected_modification_time), 34 file_size_(-1), 35 weak_ptr_factory_(this) { 36 DCHECK_GE(offset, 0); 37} 38 39WebkitFileStreamReaderImpl::~WebkitFileStreamReaderImpl() { 40} 41 42int WebkitFileStreamReaderImpl::Read(net::IOBuffer* buffer, 43 int buffer_length, 44 const net::CompletionCallback& callback) { 45 DCHECK(BrowserThread::CurrentlyOn(BrowserThread::IO)); 46 DCHECK(stream_reader_); 47 DCHECK(buffer); 48 DCHECK(!callback.is_null()); 49 50 if (stream_reader_->IsInitialized()) 51 return stream_reader_->Read(buffer, buffer_length, callback); 52 53 net::HttpByteRange byte_range; 54 byte_range.set_first_byte_position(offset_); 55 stream_reader_->Initialize( 56 drive_file_path_, 57 byte_range, 58 base::Bind(&WebkitFileStreamReaderImpl::OnStreamReaderInitialized, 59 weak_ptr_factory_.GetWeakPtr(), 60 base::Bind(&WebkitFileStreamReaderImpl 61 ::ReadAfterStreamReaderInitialized, 62 weak_ptr_factory_.GetWeakPtr(), 63 make_scoped_refptr(buffer), 64 buffer_length, callback))); 65 return net::ERR_IO_PENDING; 66} 67 68int64 WebkitFileStreamReaderImpl::GetLength( 69 const net::Int64CompletionCallback& callback) { 70 DCHECK(BrowserThread::CurrentlyOn(BrowserThread::IO)); 71 DCHECK(stream_reader_); 72 DCHECK(!callback.is_null()); 73 74 if (stream_reader_->IsInitialized()) { 75 // Returns file_size regardless of |offset_|. 76 return file_size_; 77 } 78 79 net::HttpByteRange byte_range; 80 byte_range.set_first_byte_position(offset_); 81 stream_reader_->Initialize( 82 drive_file_path_, 83 byte_range, 84 base::Bind(&WebkitFileStreamReaderImpl::OnStreamReaderInitialized, 85 weak_ptr_factory_.GetWeakPtr(), 86 base::Bind(&WebkitFileStreamReaderImpl 87 ::GetLengthAfterStreamReaderInitialized, 88 weak_ptr_factory_.GetWeakPtr(), 89 callback))); 90 return net::ERR_IO_PENDING; 91} 92 93void WebkitFileStreamReaderImpl::OnStreamReaderInitialized( 94 const net::CompletionCallback& callback, 95 int error, 96 scoped_ptr<ResourceEntry> entry) { 97 DCHECK(BrowserThread::CurrentlyOn(BrowserThread::IO)); 98 DCHECK(stream_reader_); 99 DCHECK(!callback.is_null()); 100 101 // TODO(hashimoto): Report ERR_UPLOAD_FILE_CHANGED when modification time 102 // doesn't match. crbug.com/346625 103 if (error != net::OK) { 104 // Found an error. Close the |stream_reader_| and notify it to the caller. 105 stream_reader_.reset(); 106 callback.Run(error); 107 return; 108 } 109 110 // Remember the size of the file. 111 file_size_ = entry->file_info().size(); 112 callback.Run(net::OK); 113} 114 115void WebkitFileStreamReaderImpl::ReadAfterStreamReaderInitialized( 116 scoped_refptr<net::IOBuffer> buffer, 117 int buffer_length, 118 const net::CompletionCallback& callback, 119 int initialization_result) { 120 DCHECK(BrowserThread::CurrentlyOn(BrowserThread::IO)); 121 DCHECK(!callback.is_null()); 122 123 if (initialization_result != net::OK) { 124 callback.Run(initialization_result); 125 return; 126 } 127 128 DCHECK(stream_reader_); 129 int result = stream_reader_->Read(buffer.get(), buffer_length, callback); 130 if (result != net::ERR_IO_PENDING) 131 callback.Run(result); 132} 133 134void WebkitFileStreamReaderImpl::GetLengthAfterStreamReaderInitialized( 135 const net::Int64CompletionCallback& callback, 136 int initialization_result) { 137 DCHECK(BrowserThread::CurrentlyOn(BrowserThread::IO)); 138 DCHECK(!callback.is_null()); 139 140 if (initialization_result != net::OK) { 141 callback.Run(initialization_result); 142 return; 143 } 144 145 DCHECK_GE(file_size_, 0); 146 callback.Run(file_size_); 147} 148 149} // namespace internal 150} // namespace drive 151