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