OLD | NEW |
---|---|
1 // Copyright (c) 2011 The Chromium Authors. All rights reserved. | 1 // Copyright (c) 2011 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 "webkit/blob/blob_url_request_job.h" | 5 #include "webkit/blob/blob_url_request_job.h" |
6 | 6 |
7 #include "base/compiler_specific.h" | 7 #include "base/compiler_specific.h" |
8 #include "base/file_path.h" | 8 #include "base/file_path.h" |
9 #include "base/file_util.h" | 9 #include "base/file_util.h" |
10 #include "base/file_util_proxy.h" | 10 #include "base/file_util_proxy.h" |
(...skipping 119 matching lines...) Expand 10 before | Expand all | Expand 10 after Loading... | |
130 return; | 130 return; |
131 } else if (rv != base::PLATFORM_FILE_OK) { | 131 } else if (rv != base::PLATFORM_FILE_OK) { |
132 NotifyFailure(net::ERR_FAILED); | 132 NotifyFailure(net::ERR_FAILED); |
133 return; | 133 return; |
134 } | 134 } |
135 | 135 |
136 // Validate the expected modification time. | 136 // Validate the expected modification time. |
137 // Note that the expected modification time from WebKit is based on | 137 // Note that the expected modification time from WebKit is based on |
138 // time_t precision. So we have to convert both to time_t to compare. | 138 // time_t precision. So we have to convert both to time_t to compare. |
139 const BlobData::Item& item = blob_data_->items().at(item_index_); | 139 const BlobData::Item& item = blob_data_->items().at(item_index_); |
140 DCHECK(item.type() == BlobData::TYPE_FILE); | 140 DCHECK(item.type == BlobData::TYPE_FILE); |
141 | 141 |
142 if (!item.expected_modification_time().is_null() && | 142 if (!item.expected_modification_time.is_null() && |
143 item.expected_modification_time().ToTimeT() != | 143 item.expected_modification_time.ToTimeT() != |
144 file_info.last_modified.ToTimeT()) { | 144 file_info.last_modified.ToTimeT()) { |
145 NotifyFailure(net::ERR_FILE_NOT_FOUND); | 145 NotifyFailure(net::ERR_FILE_NOT_FOUND); |
146 return; | 146 return; |
147 } | 147 } |
148 | 148 |
149 // If item length is -1, we need to use the file size being resolved | 149 // If item length is -1, we need to use the file size being resolved |
150 // in the real time. | 150 // in the real time. |
151 int64 item_length = static_cast<int64>(item.length()); | 151 int64 item_length = static_cast<int64>(item.length); |
152 if (item_length == -1) | 152 if (item_length == -1) |
153 item_length = file_info.size; | 153 item_length = file_info.size; |
154 | 154 |
155 // Cache the size and add it to the total size. | 155 // Cache the size and add it to the total size. |
156 item_length_list_.push_back(item_length); | 156 item_length_list_.push_back(item_length); |
157 total_size_ += item_length; | 157 total_size_ += item_length; |
158 | 158 |
159 // Continue counting the size for the remaining items. | 159 // Continue counting the size for the remaining items. |
160 item_index_++; | 160 item_index_++; |
161 CountSize(); | 161 CountSize(); |
162 } | 162 } |
163 | 163 |
164 void BlobURLRequestJob::CountSize() { | 164 void BlobURLRequestJob::CountSize() { |
165 for (; item_index_ < blob_data_->items().size(); ++item_index_) { | 165 for (; item_index_ < blob_data_->items().size(); ++item_index_) { |
166 const BlobData::Item& item = blob_data_->items().at(item_index_); | 166 const BlobData::Item& item = blob_data_->items().at(item_index_); |
167 int64 item_length = static_cast<int64>(item.length()); | 167 int64 item_length = static_cast<int64>(item.length); |
168 | 168 |
169 // If there is a file item, do the resolving. | 169 // If there is a file item, do the resolving. |
170 if (item.type() == BlobData::TYPE_FILE) { | 170 if (item.type == BlobData::TYPE_FILE) { |
171 ResolveFile(item.file_path()); | 171 ResolveFile(item.file_path); |
172 return; | 172 return; |
173 } | 173 } |
174 | 174 |
175 // Cache the size and add it to the total size. | 175 // Cache the size and add it to the total size. |
176 item_length_list_.push_back(item_length); | 176 item_length_list_.push_back(item_length); |
177 total_size_ += item_length; | 177 total_size_ += item_length; |
178 } | 178 } |
179 | 179 |
180 // Reset item_index_ since it will be reused to read the items. | 180 // Reset item_index_ since it will be reused to read the items. |
181 item_index_ = 0; | 181 item_index_ = 0; |
(...skipping 99 matching lines...) Expand 10 before | Expand all | Expand 10 after Loading... | |
281 bytes_to_read_ = ComputeBytesToRead(); | 281 bytes_to_read_ = ComputeBytesToRead(); |
282 | 282 |
283 // If nothing to read for current item, advance to next item. | 283 // If nothing to read for current item, advance to next item. |
284 if (bytes_to_read_ == 0) { | 284 if (bytes_to_read_ == 0) { |
285 AdvanceItem(); | 285 AdvanceItem(); |
286 return ReadItem(); | 286 return ReadItem(); |
287 } | 287 } |
288 | 288 |
289 // Do the reading. | 289 // Do the reading. |
290 const BlobData::Item& item = blob_data_->items().at(item_index_); | 290 const BlobData::Item& item = blob_data_->items().at(item_index_); |
291 switch (item.type()) { | 291 switch (item.type) { |
292 case BlobData::TYPE_DATA: | 292 case BlobData::TYPE_DATA: |
293 return ReadBytes(item); | 293 return ReadBytes(item); |
294 case BlobData::TYPE_FILE: | 294 case BlobData::TYPE_FILE: |
295 return DispatchReadFile(item); | 295 return DispatchReadFile(item); |
296 default: | 296 default: |
297 DCHECK(false); | 297 DCHECK(false); |
298 return false; | 298 return false; |
299 } | 299 } |
300 } | 300 } |
301 | 301 |
302 bool BlobURLRequestJob::ReadBytes(const BlobData::Item& item) { | 302 bool BlobURLRequestJob::ReadBytes(const BlobData::Item& item) { |
303 DCHECK(read_buf_remaining_bytes_ >= bytes_to_read_); | 303 DCHECK(read_buf_remaining_bytes_ >= bytes_to_read_); |
304 | 304 |
305 memcpy(read_buf_->data() + read_buf_offset_, | 305 memcpy(read_buf_->data() + read_buf_offset_, |
306 &item.data().at(0) + item.offset() + current_item_offset_, | 306 &item.data.at(0) + item.offset + current_item_offset_, |
307 bytes_to_read_); | 307 bytes_to_read_); |
308 | 308 |
309 AdvanceBytesRead(bytes_to_read_); | 309 AdvanceBytesRead(bytes_to_read_); |
310 return true; | 310 return true; |
311 } | 311 } |
312 | 312 |
313 bool BlobURLRequestJob::DispatchReadFile(const BlobData::Item& item) { | 313 bool BlobURLRequestJob::DispatchReadFile(const BlobData::Item& item) { |
314 // If the stream already exists, keep reading from it. | 314 // If the stream already exists, keep reading from it. |
315 if (stream_ != NULL) | 315 if (stream_ != NULL) |
316 return ReadFile(item); | 316 return ReadFile(item); |
317 | 317 |
318 base::FileUtilProxy::CreateOrOpen( | 318 base::FileUtilProxy::CreateOrOpen( |
319 file_thread_proxy_, item.file_path(), kFileOpenFlags, | 319 file_thread_proxy_, item.file_path, kFileOpenFlags, |
320 callback_factory_.NewCallback(&BlobURLRequestJob::DidOpen)); | 320 callback_factory_.NewCallback(&BlobURLRequestJob::DidOpen)); |
321 SetStatus(net::URLRequestStatus(net::URLRequestStatus::IO_PENDING, 0)); | 321 SetStatus(net::URLRequestStatus(net::URLRequestStatus::IO_PENDING, 0)); |
322 return false; | 322 return false; |
323 } | 323 } |
324 | 324 |
325 void BlobURLRequestJob::DidOpen(base::PlatformFileError rv, | 325 void BlobURLRequestJob::DidOpen(base::PlatformFileError rv, |
326 base::PassPlatformFile file, | 326 base::PassPlatformFile file, |
327 bool created) { | 327 bool created) { |
328 if (rv != base::PLATFORM_FILE_OK) { | 328 if (rv != base::PLATFORM_FILE_OK) { |
329 NotifyFailure(net::ERR_FAILED); | 329 NotifyFailure(net::ERR_FAILED); |
330 return; | 330 return; |
331 } | 331 } |
332 | 332 |
333 DCHECK(!stream_.get()); | 333 DCHECK(!stream_.get()); |
334 stream_.reset(new net::FileStream(file.ReleaseValue(), kFileOpenFlags)); | 334 stream_.reset(new net::FileStream(file.ReleaseValue(), kFileOpenFlags)); |
335 | 335 |
336 const BlobData::Item& item = blob_data_->items().at(item_index_); | 336 const BlobData::Item& item = blob_data_->items().at(item_index_); |
337 { | 337 { |
338 // stream_.Seek() blocks the IO thread, see http://crbug.com/75548. | 338 // stream_.Seek() blocks the IO thread, see http://crbug.com/75548. |
michaeln
2011/09/29 19:45:01
might be nice to do the seek on the filethread pri
| |
339 base::ThreadRestrictions::ScopedAllowIO allow_io; | 339 base::ThreadRestrictions::ScopedAllowIO allow_io; |
340 int64 offset = current_item_offset_ + static_cast<int64>(item.offset()); | 340 int64 offset = current_item_offset_ + static_cast<int64>(item.offset); |
341 if (offset > 0 && offset != stream_->Seek(net::FROM_BEGIN, offset)) { | 341 if (offset > 0 && offset != stream_->Seek(net::FROM_BEGIN, offset)) { |
342 NotifyFailure(net::ERR_FAILED); | 342 NotifyFailure(net::ERR_FAILED); |
343 return; | 343 return; |
344 } | 344 } |
345 } | 345 } |
346 | 346 |
347 ReadFile(item); | 347 ReadFile(item); |
348 } | 348 } |
349 | 349 |
350 bool BlobURLRequestJob::ReadFile(const BlobData::Item& item) { | 350 bool BlobURLRequestJob::ReadFile(const BlobData::Item& item) { |
(...skipping 210 matching lines...) Expand 10 before | Expand all | Expand 10 after Loading... | |
561 // We don't support multiple range requests in one single URL request, | 561 // We don't support multiple range requests in one single URL request, |
562 // because we need to do multipart encoding here. | 562 // because we need to do multipart encoding here. |
563 // TODO(jianli): Support multipart byte range requests. | 563 // TODO(jianli): Support multipart byte range requests. |
564 NotifyFailure(net::ERR_REQUEST_RANGE_NOT_SATISFIABLE); | 564 NotifyFailure(net::ERR_REQUEST_RANGE_NOT_SATISFIABLE); |
565 } | 565 } |
566 } | 566 } |
567 } | 567 } |
568 } | 568 } |
569 | 569 |
570 } // namespace webkit_blob | 570 } // namespace webkit_blob |
OLD | NEW |