Home | History | Annotate | Download | only in fileapi
      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 
     18 using content::BrowserThread;
     19 
     20 namespace drive {
     21 namespace internal {
     22 
     23 WebkitFileStreamReaderImpl::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 
     39 WebkitFileStreamReaderImpl::~WebkitFileStreamReaderImpl() {
     40 }
     41 
     42 int 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 
     68 int64 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 
     93 void 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 
    115 void 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 
    134 void 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