Home | History | Annotate | Download | only in fileapi
      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