Upstream version 11.40.277.0
[platform/framework/web/crosswalk.git] / src / chrome / browser / chromeos / drive / fileapi / webkit_file_stream_reader_impl.cc
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