- add sources.
[platform/framework/web/crosswalk.git] / src / chrome / browser / chromeos / drive / webkit_file_stream_reader_impl.cc
1 // Copyright 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 "chrome/browser/chromeos/drive/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   if (error == net::OK) {
102     DCHECK(entry);
103
104     // Check last modification time.
105     if (!expected_modification_time_.is_null() &&
106         expected_modification_time_.ToInternalValue() !=
107         entry->file_info().last_modified()) {
108       error = net::ERR_UPLOAD_FILE_CHANGED;
109     }
110   }
111
112   if (error != net::OK) {
113     // Found an error. Close the |stream_reader_| and notify it to the caller.
114     stream_reader_.reset();
115     callback.Run(error);
116     return;
117   }
118
119   // Remember the size of the file.
120   file_size_ = entry->file_info().size();
121   callback.Run(net::OK);
122 }
123
124 void WebkitFileStreamReaderImpl::ReadAfterStreamReaderInitialized(
125     scoped_refptr<net::IOBuffer> buffer,
126     int buffer_length,
127     const net::CompletionCallback& callback,
128     int initialization_result) {
129   DCHECK(BrowserThread::CurrentlyOn(BrowserThread::IO));
130   DCHECK(!callback.is_null());
131
132   if (initialization_result != net::OK) {
133     callback.Run(initialization_result);
134     return;
135   }
136
137   DCHECK(stream_reader_);
138   int result = stream_reader_->Read(buffer.get(), buffer_length, callback);
139   if (result != net::ERR_IO_PENDING)
140     callback.Run(result);
141 }
142
143 void WebkitFileStreamReaderImpl::GetLengthAfterStreamReaderInitialized(
144     const net::Int64CompletionCallback& callback,
145     int initialization_result) {
146   DCHECK(BrowserThread::CurrentlyOn(BrowserThread::IO));
147   DCHECK(!callback.is_null());
148
149   if (initialization_result != net::OK) {
150     callback.Run(initialization_result);
151     return;
152   }
153
154   DCHECK_GE(file_size_, 0);
155   callback.Run(file_size_);
156 }
157
158 }  // namespace internal
159 }  // namespace drive