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

Side by Side Diff: fpdfsdk/fpdf_dataavail_embeddertest.cpp

Issue 2483633002: Do not load main cross refs for first page in linearized pdf. (Closed)
Patch Set: fix compilation. Created 4 years, 1 month 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 | « core/fpdfapi/parser/cpdf_parser.cpp ('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 2015 PDFium Authors. All rights reserved. 1 // Copyright 2015 PDFium 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 <algorithm> 5 #include <algorithm>
6 #include <memory> 6 #include <memory>
7 #include <string> 7 #include <string>
8 #include <vector> 8 #include <vector>
9 9
10 #include "public/fpdfview.h" 10 #include "public/fpdfview.h"
(...skipping 27 matching lines...) Expand all
38 bool IsOpened() const { return !!file_contents_; } 38 bool IsOpened() const { return !!file_contents_; }
39 39
40 FPDF_FILEACCESS* file_access() { return &file_access_; } 40 FPDF_FILEACCESS* file_access() { return &file_access_; }
41 FX_DOWNLOADHINTS* hints() { return this; } 41 FX_DOWNLOADHINTS* hints() { return this; }
42 FX_FILEAVAIL* file_avail() { return this; } 42 FX_FILEAVAIL* file_avail() { return this; }
43 43
44 const std::vector<std::pair<size_t, size_t>>& requested_segments() const { 44 const std::vector<std::pair<size_t, size_t>>& requested_segments() const {
45 return requested_segments_; 45 return requested_segments_;
46 } 46 }
47 47
48 void ClearRequestedSegments() { requested_segments_.clear(); } 48 size_t max_requested_bound() const { return max_requested_bound_; }
49
50 void ClearRequestedSegments() {
51 requested_segments_.clear();
52 max_requested_bound_ = 0;
53 }
49 54
50 bool is_new_data_available() const { return is_new_data_available_; } 55 bool is_new_data_available() const { return is_new_data_available_; }
51 void set_is_new_data_available(bool is_new_data_available) { 56 void set_is_new_data_available(bool is_new_data_available) {
52 is_new_data_available_ = is_new_data_available; 57 is_new_data_available_ = is_new_data_available;
53 } 58 }
54 59
60 size_t max_already_available_bound() const {
61 return available_ranges_.empty() ? 0 : available_ranges_.rbegin()->second;
62 }
63
55 private: 64 private:
56 void SetDataAvailable(size_t start, size_t size) { 65 void SetDataAvailable(size_t start, size_t size) {
57 if (size == 0) 66 if (size == 0)
58 return; 67 return;
59 const auto range = std::make_pair(start, start + size); 68 const auto range = std::make_pair(start, start + size);
60 if (available_ranges_.empty()) { 69 if (available_ranges_.empty()) {
61 available_ranges_.insert(range); 70 available_ranges_.insert(range);
62 return; 71 return;
63 } 72 }
64 auto start_it = available_ranges_.upper_bound(range); 73 auto start_it = available_ranges_.upper_bound(range);
(...skipping 37 matching lines...) Expand 10 before | Expand all | Expand 10 after
102 std::min(static_cast<unsigned long>(file_length_), pos + size); 111 std::min(static_cast<unsigned long>(file_length_), pos + size);
103 if (end <= pos) 112 if (end <= pos)
104 return 0; 113 return 0;
105 memcpy(pBuf, file_contents_.get() + pos, end - pos); 114 memcpy(pBuf, file_contents_.get() + pos, end - pos);
106 SetDataAvailable(pos, end - pos); 115 SetDataAvailable(pos, end - pos);
107 return static_cast<int>(end - pos); 116 return static_cast<int>(end - pos);
108 } 117 }
109 118
110 void AddSegmentImpl(size_t offset, size_t size) { 119 void AddSegmentImpl(size_t offset, size_t size) {
111 requested_segments_.push_back(std::make_pair(offset, size)); 120 requested_segments_.push_back(std::make_pair(offset, size));
121 max_requested_bound_ = std::max(max_requested_bound_, offset + size);
112 } 122 }
113 123
114 bool IsDataAvailImpl(size_t offset, size_t size) { 124 bool IsDataAvailImpl(size_t offset, size_t size) {
115 if (offset + size > file_length_) 125 if (offset + size > file_length_)
116 return false; 126 return false;
117 if (is_new_data_available_) { 127 if (is_new_data_available_) {
118 SetDataAvailable(offset, size); 128 SetDataAvailable(offset, size);
119 return true; 129 return true;
120 } 130 }
121 return CheckDataAlreadyAvailable(offset, size); 131 return CheckDataAlreadyAvailable(offset, size);
(...skipping 14 matching lines...) Expand all
136 size_t offset, 146 size_t offset,
137 size_t size) { 147 size_t size) {
138 return static_cast<TestAsyncLoader*>(pThis)->IsDataAvailImpl(offset, size); 148 return static_cast<TestAsyncLoader*>(pThis)->IsDataAvailImpl(offset, size);
139 } 149 }
140 150
141 FPDF_FILEACCESS file_access_; 151 FPDF_FILEACCESS file_access_;
142 152
143 std::unique_ptr<char, pdfium::FreeDeleter> file_contents_; 153 std::unique_ptr<char, pdfium::FreeDeleter> file_contents_;
144 size_t file_length_; 154 size_t file_length_;
145 std::vector<std::pair<size_t, size_t>> requested_segments_; 155 std::vector<std::pair<size_t, size_t>> requested_segments_;
156 size_t max_requested_bound_ = 0;
146 bool is_new_data_available_ = true; 157 bool is_new_data_available_ = true;
147 158
148 using Range = std::pair<size_t, size_t>; 159 using Range = std::pair<size_t, size_t>;
149 struct range_compare { 160 struct range_compare {
150 bool operator()(const Range& lval, const Range& rval) const { 161 bool operator()(const Range& lval, const Range& rval) const {
151 return lval.first < rval.first; 162 return lval.first < rval.first;
152 } 163 }
153 }; 164 };
154 using RangesContainer = std::set<Range, range_compare>; 165 using RangesContainer = std::set<Range, range_compare>;
155 RangesContainer available_ranges_; 166 RangesContainer available_ranges_;
(...skipping 22 matching lines...) Expand all
178 document_ = FPDFAvail_GetDocument(avail_, nullptr); 189 document_ = FPDFAvail_GetDocument(avail_, nullptr);
179 ASSERT_TRUE(document_); 190 ASSERT_TRUE(document_);
180 ASSERT_EQ(PDF_DATA_AVAIL, FPDFAvail_IsPageAvail(avail_, 1, loader.hints())); 191 ASSERT_EQ(PDF_DATA_AVAIL, FPDFAvail_IsPageAvail(avail_, 1, loader.hints()));
181 192
182 // No new data available, to prevent load "Pages" node. 193 // No new data available, to prevent load "Pages" node.
183 loader.set_is_new_data_available(false); 194 loader.set_is_new_data_available(false);
184 FPDF_PAGE page = LoadPage(1); 195 FPDF_PAGE page = LoadPage(1);
185 EXPECT_TRUE(page); 196 EXPECT_TRUE(page);
186 UnloadPage(page); 197 UnloadPage(page);
187 } 198 }
199
200 TEST_F(FPDFDataAvailEmbeddertest,
201 DoNotLoadMainCrossRefForFirstPageIfLinearized) {
202 TestAsyncLoader loader("feature_linearized_loading.pdf");
203 avail_ = FPDFAvail_Create(loader.file_avail(), loader.file_access());
204 ASSERT_EQ(PDF_DATA_AVAIL, FPDFAvail_IsDocAvail(avail_, loader.hints()));
205 document_ = FPDFAvail_GetDocument(avail_, nullptr);
206 ASSERT_TRUE(document_);
207 const int first_page_num = FPDFAvail_GetFirstPageNum(document_);
208
209 // The main cross ref table should not be processed.
210 // (It is always at file end)
211 EXPECT_GT(loader.file_access()->m_FileLen,
212 loader.max_already_available_bound());
213
214 // Prevent access to non requested data to coerce the parser to send new
215 // request for non available (non requested before) data.
216 loader.set_is_new_data_available(false);
217 FPDFAvail_IsPageAvail(avail_, first_page_num, loader.hints());
218
219 // The main cross ref table should not be requested.
220 // (It is always at file end)
221 EXPECT_GT(loader.file_access()->m_FileLen, loader.max_requested_bound());
222
223 // Allow parse page.
224 loader.set_is_new_data_available(true);
225 ASSERT_EQ(PDF_DATA_AVAIL,
226 FPDFAvail_IsPageAvail(avail_, first_page_num, loader.hints()));
227
228 // The main cross ref table should not be processed.
229 // (It is always at file end)
230 EXPECT_GT(loader.file_access()->m_FileLen,
231 loader.max_already_available_bound());
232
233 // Prevent loading data, while page loading.
234 loader.set_is_new_data_available(false);
235 FPDF_PAGE page = LoadPage(first_page_num);
236 EXPECT_TRUE(page);
237 UnloadPage(page);
238 }
OLDNEW
« no previous file with comments | « core/fpdfapi/parser/cpdf_parser.cpp ('k') | no next file » | no next file with comments »

Powered by Google App Engine
This is Rietveld 408576698