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