Chromium Code Reviews
chromiumcodereview-hr@appspot.gserviceaccount.com (chromiumcodereview-hr) | Please choose your nickname with Settings | Help | Chromium Project | Gerrit Changes | Sign out
(79)

Side by Side Diff: pdf/document_loader.cc

Issue 2911853002: Refactor PDF ChunkStream and DocumentLoader code. (Closed)
Patch Set: Created 3 years, 6 months ago
Use n/p to move between diff chunks; N/P to move between comments. Draft comments are only viewable by you.
Jump to:
View unified diff | Download patch
« no previous file with comments | « pdf/document_loader.h ('k') | no next file » | no next file with comments »
Toggle Intra-line Diffs ('i') | Expand Comments ('e') | Collapse Comments ('c') | Show Comments Hide Comments ('s')
OLDNEW
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 "pdf/document_loader.h" 5 #include "pdf/document_loader.h"
6 6
7 #include <stddef.h> 7 #include <stddef.h>
8 #include <stdint.h> 8 #include <stdint.h>
9 9
10 #include "base/logging.h" 10 #include "base/logging.h"
(...skipping 34 matching lines...) Expand 10 before | Expand all | Expand 10 after
45 } 45 }
46 } 46 }
47 return false; 47 return false;
48 } 48 }
49 49
50 // If the headers have a multi-part response, returns the boundary name. 50 // If the headers have a multi-part response, returns the boundary name.
51 // Otherwise returns an empty string. 51 // Otherwise returns an empty string.
52 std::string GetMultiPartBoundary(const std::string& headers) { 52 std::string GetMultiPartBoundary(const std::string& headers) {
53 net::HttpUtil::HeadersIterator it(headers.begin(), headers.end(), "\n"); 53 net::HttpUtil::HeadersIterator it(headers.begin(), headers.end(), "\n");
54 while (it.GetNext()) { 54 while (it.GetNext()) {
55 if (base::LowerCaseEqualsASCII(it.name(), "content-type")) { 55 if (!base::LowerCaseEqualsASCII(it.name(), "content-type"))
56 std::string type = base::ToLowerASCII(it.values()); 56 continue;
57 if (base::StartsWith(type, "multipart/", base::CompareCase::SENSITIVE)) {
58 const char* boundary = strstr(type.c_str(), "boundary=");
59 if (!boundary) {
60 NOTREACHED();
61 break;
62 }
63 57
64 return std::string(boundary + 9); 58 std::string type = base::ToLowerASCII(it.values());
65 } 59 if (!base::StartsWith(type, "multipart/", base::CompareCase::SENSITIVE))
60 continue;
61
62 static constexpr char kBoundary[] = "boundary=";
63 const char* boundary = strstr(type.c_str(), kBoundary);
64 if (!boundary) {
65 NOTREACHED();
66 return std::string();
66 } 67 }
68
69 return std::string(boundary + strlen(kBoundary));
67 } 70 }
68 return std::string(); 71 return std::string();
69 } 72 }
70 73
71 // Return true if the HTTP response of |loader| is a successful one and loading 74 // Return true if the HTTP response of |loader| is a successful one and loading
72 // should continue. 4xx error indicate subsequent requests will fail too. 75 // should continue. 4xx error indicate subsequent requests will fail too.
73 // e.g. resource has been removed from the server while loading it. 301 76 // e.g. resource has been removed from the server while loading it. 301
74 // indicates a redirect was returned which won't be successful because we 77 // indicates a redirect was returned which won't be successful because we
75 // disable following redirects for PDF loading (we assume they are already 78 // disable following redirects for PDF loading (we assume they are already
76 // resolved by the browser. 79 // resolved by the browser.
77 bool ResponseStatusSuccess(const pp::URLLoader& loader) { 80 bool ResponseStatusSuccess(const pp::URLLoader& loader) {
78 int32_t http_code = loader.GetResponseInfo().GetStatusCode(); 81 int32_t http_code = loader.GetResponseInfo().GetStatusCode();
79 return (http_code < 400 && http_code != 301) || http_code >= 500; 82 return (http_code < 400 && http_code != 301) || http_code >= 500;
80 } 83 }
81 84
82 bool IsValidContentType(const std::string& type) { 85 bool IsValidContentType(const std::string& type) {
83 return base::EndsWith(type, "/pdf", base::CompareCase::INSENSITIVE_ASCII) || 86 return base::EndsWith(type, "/pdf", base::CompareCase::INSENSITIVE_ASCII) ||
84 base::EndsWith(type, ".pdf", base::CompareCase::INSENSITIVE_ASCII) || 87 base::EndsWith(type, ".pdf", base::CompareCase::INSENSITIVE_ASCII) ||
85 base::EndsWith(type, "/x-pdf", base::CompareCase::INSENSITIVE_ASCII) || 88 base::EndsWith(type, "/x-pdf", base::CompareCase::INSENSITIVE_ASCII) ||
86 base::EndsWith(type, "/*", base::CompareCase::INSENSITIVE_ASCII) || 89 base::EndsWith(type, "/*", base::CompareCase::INSENSITIVE_ASCII) ||
87 base::EndsWith(type, "/acrobat", 90 base::EndsWith(type, "/acrobat",
88 base::CompareCase::INSENSITIVE_ASCII) || 91 base::CompareCase::INSENSITIVE_ASCII) ||
89 base::EndsWith(type, "/unknown", base::CompareCase::INSENSITIVE_ASCII); 92 base::EndsWith(type, "/unknown", base::CompareCase::INSENSITIVE_ASCII);
90 } 93 }
91 94
95 bool IsDoubleNewlines(const char* buffer, int index) {
96 DCHECK_GE(index, 2);
97 static constexpr char kLF2[] = "\n\n";
98 static constexpr char kCRLF2[] = "\r\n\r\n";
99 if (strncmp(&buffer[index - 2], kLF2, strlen(kLF2)) == 0)
100 return true;
101 return index >= 4 && strncmp(&buffer[index - 4], kCRLF2, strlen(kCRLF2)) == 0;
102 }
103
92 } // namespace 104 } // namespace
93 105
94 DocumentLoader::Client::~Client() {} 106 DocumentLoader::Client::~Client() {}
95 107
96 DocumentLoader::DocumentLoader(Client* client) 108 DocumentLoader::DocumentLoader(Client* client)
97 : client_(client), 109 : client_(client),
98 partial_document_(false), 110 partial_document_(false),
99 request_pending_(false), 111 request_pending_(false),
100 current_pos_(0), 112 current_pos_(0),
101 current_chunk_size_(0), 113 current_chunk_size_(0),
(...skipping 111 matching lines...) Expand 10 before | Expand all | Expand 10 after
213 ReadMore(); 225 ReadMore();
214 } 226 }
215 227
216 bool DocumentLoader::IsDocumentComplete() const { 228 bool DocumentLoader::IsDocumentComplete() const {
217 if (document_size_ == 0) // Document size unknown. 229 if (document_size_ == 0) // Document size unknown.
218 return false; 230 return false;
219 return IsDataAvailable(0, document_size_); 231 return IsDataAvailable(0, document_size_);
220 } 232 }
221 233
222 uint32_t DocumentLoader::GetAvailableData() const { 234 uint32_t DocumentLoader::GetAvailableData() const {
223 if (document_size_ == 0) { // If document size is unknown. 235 if (document_size_ == 0) // Document size unknown.
224 return current_pos_; 236 return current_pos_;
225 }
226 237
227 std::vector<std::pair<size_t, size_t>> ranges; 238 std::vector<std::pair<size_t, size_t>> ranges;
228 chunk_stream_.GetMissedRanges(0, document_size_, &ranges); 239 chunk_stream_.GetMissedRanges(0, document_size_, &ranges);
229 uint32_t available = document_size_; 240 uint32_t available = document_size_;
230 for (const auto& range : ranges) 241 for (const auto& range : ranges)
231 available -= range.second; 242 available -= range.second;
232 return available; 243 return available;
233 } 244 }
234 245
235 void DocumentLoader::ClearPendingRequests() { 246 void DocumentLoader::ClearPendingRequests() {
236 pending_requests_.erase(pending_requests_.begin(), pending_requests_.end()); 247 pending_requests_.clear();
237 } 248 }
238 249
239 bool DocumentLoader::GetBlock(uint32_t position, 250 bool DocumentLoader::GetBlock(uint32_t position,
240 uint32_t size, 251 uint32_t size,
241 void* buf) const { 252 void* buf) const {
242 return chunk_stream_.ReadData(position, size, buf); 253 return chunk_stream_.ReadData(position, size, buf);
243 } 254 }
244 255
245 bool DocumentLoader::IsDataAvailable(uint32_t position, uint32_t size) const { 256 bool DocumentLoader::IsDataAvailable(uint32_t position, uint32_t size) const {
246 return chunk_stream_.IsRangeAvailable(position, size); 257 return chunk_stream_.IsRangeAvailable(position, size);
(...skipping 147 matching lines...) Expand 10 before | Expand all | Expand 10 after
394 // Leave position untouched for now, when we read the data we'll get it. 405 // Leave position untouched for now, when we read the data we'll get it.
395 is_multipart_ = true; 406 is_multipart_ = true;
396 multipart_boundary_ = boundary; 407 multipart_boundary_ = boundary;
397 } else { 408 } else {
398 // Need to make sure that the server returned a byte-range, since it's 409 // Need to make sure that the server returned a byte-range, since it's
399 // possible for a server to just ignore our byte-range request and just 410 // possible for a server to just ignore our byte-range request and just
400 // return the entire document even if it supports byte-range requests. 411 // return the entire document even if it supports byte-range requests.
401 // i.e. sniff response to 412 // i.e. sniff response to
402 // http://www.act.org/compass/sample/pdf/geometry.pdf 413 // http://www.act.org/compass/sample/pdf/geometry.pdf
403 current_pos_ = 0; 414 current_pos_ = 0;
404 uint32_t start_pos, end_pos; 415 uint32_t start_pos;
416 uint32_t end_pos;
405 if (GetByteRange(headers, &start_pos, &end_pos)) { 417 if (GetByteRange(headers, &start_pos, &end_pos)) {
406 current_pos_ = start_pos; 418 current_pos_ = start_pos;
407 if (end_pos && end_pos > start_pos) 419 if (end_pos && end_pos > start_pos)
408 current_chunk_size_ = end_pos - start_pos + 1; 420 current_chunk_size_ = end_pos - start_pos + 1;
409 } else { 421 } else {
410 partial_document_ = false; 422 partial_document_ = false;
411 } 423 }
412 } 424 }
413 425
414 ReadMore(); 426 ReadMore();
(...skipping 14 matching lines...) Expand all
429 // case where an error occurred, the renderer will detect that we're missing 441 // case where an error occurred, the renderer will detect that we're missing
430 // data and will display a message. 442 // data and will display a message.
431 ReadComplete(); 443 ReadComplete();
432 return; 444 return;
433 } 445 }
434 446
435 char* start = buffer_; 447 char* start = buffer_;
436 size_t length = result; 448 size_t length = result;
437 if (is_multipart_ && result > 2) { 449 if (is_multipart_ && result > 2) {
438 for (int i = 2; i < result; ++i) { 450 for (int i = 2; i < result; ++i) {
439 if ((buffer_[i - 1] == '\n' && buffer_[i - 2] == '\n') || 451 if (IsDoubleNewlines(buffer_, i)) {
440 (i >= 4 && buffer_[i - 1] == '\n' && buffer_[i - 2] == '\r' && 452 uint32_t start_pos;
441 buffer_[i - 3] == '\n' && buffer_[i - 4] == '\r')) { 453 uint32_t end_pos;
442 uint32_t start_pos, end_pos;
443 if (GetByteRange(std::string(buffer_, i), &start_pos, &end_pos)) { 454 if (GetByteRange(std::string(buffer_, i), &start_pos, &end_pos)) {
444 current_pos_ = start_pos; 455 current_pos_ = start_pos;
445 start += i; 456 start += i;
446 length -= i; 457 length -= i;
447 if (end_pos && end_pos > start_pos) 458 if (end_pos && end_pos > start_pos)
448 current_chunk_size_ = end_pos - start_pos + 1; 459 current_chunk_size_ = end_pos - start_pos + 1;
449 } 460 }
450 break; 461 break;
451 } 462 }
452 } 463 }
(...skipping 97 matching lines...) Expand 10 before | Expand all | Expand 10 after
550 561
551 void DocumentLoader::UpdateRendering() { 562 void DocumentLoader::UpdateRendering() {
552 if (header_request_) 563 if (header_request_)
553 client_->OnPartialDocumentLoaded(); 564 client_->OnPartialDocumentLoaded();
554 else 565 else
555 client_->OnPendingRequestComplete(); 566 client_->OnPendingRequestComplete();
556 header_request_ = false; 567 header_request_ = false;
557 } 568 }
558 569
559 } // namespace chrome_pdf 570 } // namespace chrome_pdf
OLDNEW
« no previous file with comments | « pdf/document_loader.h ('k') | no next file » | no next file with comments »

Powered by Google App Engine
This is Rietveld 408576698