OLD | NEW |
1 // Copyright (c) 2010 The Chromium Authors. All rights reserved. | 1 // Copyright (c) 2010 The Chromium Authors. All rights reserved. |
2 // Use of this source code is governed by a BSD-style license that can be | 2 // Use of this source code is governed by a BSD-style license that can be |
3 // found in the LICENSE file. | 3 // found in the LICENSE file. |
4 | 4 |
5 #include "net/url_request/url_request_file_dir_job.h" | 5 #include "net/url_request/url_request_file_dir_job.h" |
6 | 6 |
7 #include "base/compiler_specific.h" | 7 #include "base/compiler_specific.h" |
8 #include "base/file_util.h" | 8 #include "base/file_util.h" |
9 #include "base/message_loop.h" | 9 #include "base/message_loop.h" |
10 #include "base/sys_string_conversions.h" | 10 #include "base/sys_string_conversions.h" |
(...skipping 15 matching lines...) Expand all Loading... |
26 : URLRequestJob(request), | 26 : URLRequestJob(request), |
27 dir_path_(dir_path), | 27 dir_path_(dir_path), |
28 canceled_(false), | 28 canceled_(false), |
29 list_complete_(false), | 29 list_complete_(false), |
30 wrote_header_(false), | 30 wrote_header_(false), |
31 read_pending_(false), | 31 read_pending_(false), |
32 read_buffer_length_(0), | 32 read_buffer_length_(0), |
33 ALLOW_THIS_IN_INITIALIZER_LIST(method_factory_(this)) { | 33 ALLOW_THIS_IN_INITIALIZER_LIST(method_factory_(this)) { |
34 } | 34 } |
35 | 35 |
36 URLRequestFileDirJob::~URLRequestFileDirJob() { | |
37 DCHECK(read_pending_ == false); | |
38 DCHECK(lister_ == NULL); | |
39 } | |
40 | |
41 void URLRequestFileDirJob::Start() { | |
42 // Start reading asynchronously so that all error reporting and data | |
43 // callbacks happen as they would for network requests. | |
44 MessageLoop::current()->PostTask( | |
45 FROM_HERE, | |
46 method_factory_.NewRunnableMethod( | |
47 &URLRequestFileDirJob::StartAsync)); | |
48 } | |
49 | |
50 void URLRequestFileDirJob::StartAsync() { | 36 void URLRequestFileDirJob::StartAsync() { |
51 DCHECK(!lister_); | 37 DCHECK(!lister_); |
52 | 38 |
53 // TODO(willchan): This is stupid. We should tell |lister_| not to call us | 39 // TODO(willchan): This is stupid. We should tell |lister_| not to call us |
54 // back. Fix this stupidity. | 40 // back. Fix this stupidity. |
55 | 41 |
56 // AddRef so that *this* cannot be destroyed while the lister_ | 42 // AddRef so that *this* cannot be destroyed while the lister_ |
57 // is trying to feed us data. | 43 // is trying to feed us data. |
58 | 44 |
59 AddRef(); | 45 AddRef(); |
60 lister_ = new DirectoryLister(dir_path_, this); | 46 lister_ = new DirectoryLister(dir_path_, this); |
61 lister_->Start(); | 47 lister_->Start(); |
62 | 48 |
63 NotifyHeadersComplete(); | 49 NotifyHeadersComplete(); |
64 } | 50 } |
65 | 51 |
| 52 void URLRequestFileDirJob::Start() { |
| 53 // Start reading asynchronously so that all error reporting and data |
| 54 // callbacks happen as they would for network requests. |
| 55 MessageLoop::current()->PostTask( |
| 56 FROM_HERE, |
| 57 method_factory_.NewRunnableMethod( |
| 58 &URLRequestFileDirJob::StartAsync)); |
| 59 } |
| 60 |
66 void URLRequestFileDirJob::Kill() { | 61 void URLRequestFileDirJob::Kill() { |
67 if (canceled_) | 62 if (canceled_) |
68 return; | 63 return; |
69 | 64 |
70 canceled_ = true; | 65 canceled_ = true; |
71 | 66 |
72 // Don't call CloseLister or dispatch an error to the URLRequest because | 67 // Don't call CloseLister or dispatch an error to the URLRequest because |
73 // we want OnListDone to be called to also write the error to the output | 68 // we want OnListDone to be called to also write the error to the output |
74 // stream. OnListDone will notify the URLRequest at this time. | 69 // stream. OnListDone will notify the URLRequest at this time. |
75 if (lister_) | 70 if (lister_) |
(...skipping 91 matching lines...) Expand 10 before | Expand all | Expand 10 after Loading... |
167 read_pending_ = false; | 162 read_pending_ = false; |
168 NotifyDone(URLRequestStatus(URLRequestStatus::FAILED, error)); | 163 NotifyDone(URLRequestStatus(URLRequestStatus::FAILED, error)); |
169 } else { | 164 } else { |
170 list_complete_ = true; | 165 list_complete_ = true; |
171 CompleteRead(); | 166 CompleteRead(); |
172 } | 167 } |
173 | 168 |
174 Release(); // The Lister is finished; may delete *this* | 169 Release(); // The Lister is finished; may delete *this* |
175 } | 170 } |
176 | 171 |
| 172 URLRequestFileDirJob::~URLRequestFileDirJob() { |
| 173 DCHECK(read_pending_ == false); |
| 174 DCHECK(lister_ == NULL); |
| 175 } |
| 176 |
177 void URLRequestFileDirJob::CloseLister() { | 177 void URLRequestFileDirJob::CloseLister() { |
178 if (lister_) { | 178 if (lister_) { |
179 lister_->Cancel(); | 179 lister_->Cancel(); |
180 lister_->set_delegate(NULL); | 180 lister_->set_delegate(NULL); |
181 lister_ = NULL; | 181 lister_ = NULL; |
182 } | 182 } |
183 } | 183 } |
184 | 184 |
185 bool URLRequestFileDirJob::FillReadBuffer(char *buf, int buf_size, | |
186 int *bytes_read) { | |
187 DCHECK(bytes_read); | |
188 | |
189 *bytes_read = 0; | |
190 | |
191 int count = std::min(buf_size, static_cast<int>(data_.size())); | |
192 if (count) { | |
193 memcpy(buf, &data_[0], count); | |
194 data_.erase(0, count); | |
195 *bytes_read = count; | |
196 return true; | |
197 } else if (list_complete_) { | |
198 // EOF | |
199 return true; | |
200 } | |
201 return false; | |
202 } | |
203 | |
204 void URLRequestFileDirJob::CompleteRead() { | 185 void URLRequestFileDirJob::CompleteRead() { |
205 if (read_pending_) { | 186 if (read_pending_) { |
206 int bytes_read; | 187 int bytes_read; |
207 if (FillReadBuffer(read_buffer_->data(), read_buffer_length_, | 188 if (FillReadBuffer(read_buffer_->data(), read_buffer_length_, |
208 &bytes_read)) { | 189 &bytes_read)) { |
209 // We completed the read, so reset the read buffer. | 190 // We completed the read, so reset the read buffer. |
210 read_pending_ = false; | 191 read_pending_ = false; |
211 read_buffer_ = NULL; | 192 read_buffer_ = NULL; |
212 read_buffer_length_ = 0; | 193 read_buffer_length_ = 0; |
213 | 194 |
214 SetStatus(URLRequestStatus()); | 195 SetStatus(URLRequestStatus()); |
215 NotifyReadComplete(bytes_read); | 196 NotifyReadComplete(bytes_read); |
216 } else { | 197 } else { |
217 NOTREACHED(); | 198 NOTREACHED(); |
218 // TODO: Better error code. | 199 // TODO: Better error code. |
219 NotifyDone(URLRequestStatus(URLRequestStatus::FAILED, 0)); | 200 NotifyDone(URLRequestStatus(URLRequestStatus::FAILED, 0)); |
220 } | 201 } |
221 } | 202 } |
222 } | 203 } |
223 | 204 |
| 205 bool URLRequestFileDirJob::FillReadBuffer(char *buf, int buf_size, |
| 206 int *bytes_read) { |
| 207 DCHECK(bytes_read); |
| 208 |
| 209 *bytes_read = 0; |
| 210 |
| 211 int count = std::min(buf_size, static_cast<int>(data_.size())); |
| 212 if (count) { |
| 213 memcpy(buf, &data_[0], count); |
| 214 data_.erase(0, count); |
| 215 *bytes_read = count; |
| 216 return true; |
| 217 } else if (list_complete_) { |
| 218 // EOF |
| 219 return true; |
| 220 } |
| 221 return false; |
| 222 } |
| 223 |
224 } // namespace net | 224 } // namespace net |
OLD | NEW |