OLD | NEW |
| (Empty) |
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 | |
OLD | NEW |