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

Side by Side Diff: pdf/chunk_stream.cc

Issue 2558573002: Revert "reland of Improve linearized pdf load/show time." (Closed)
Patch Set: Changes to make tests pass ... Created 4 years 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/chunk_stream.h ('k') | pdf/chunk_stream_unittest.cc » ('j') | no next file with comments »
Toggle Intra-line Diffs ('i') | Expand Comments ('e') | Collapse Comments ('c') | Show Comments Hide Comments ('s')
OLDNEW
(Empty)
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
3 // found in the LICENSE file.
4
5 #include "pdf/chunk_stream.h"
6
7 #include <stddef.h>
8 #include <string.h>
9
10 #define __STDC_LIMIT_MACROS
11 #ifdef _WIN32
12 #include <limits.h>
13 #else
14 #include <stdint.h>
15 #endif
16
17 #include <algorithm>
18
19 namespace chrome_pdf {
20
21 ChunkStream::ChunkStream() : stream_size_(0) {
22 }
23
24 ChunkStream::~ChunkStream() {
25 }
26
27 void ChunkStream::Clear() {
28 chunks_.clear();
29 data_.clear();
30 stream_size_ = 0;
31 }
32
33 void ChunkStream::Preallocate(size_t stream_size) {
34 data_.reserve(stream_size);
35 stream_size_ = stream_size;
36 }
37
38 size_t ChunkStream::GetSize() const {
39 return data_.size();
40 }
41
42 bool ChunkStream::WriteData(size_t offset, void* buffer, size_t size) {
43 if (SIZE_MAX - size < offset)
44 return false;
45
46 if (data_.size() < offset + size)
47 data_.resize(offset + size);
48
49 memcpy(&data_[offset], buffer, size);
50
51 if (chunks_.empty()) {
52 chunks_[offset] = size;
53 return true;
54 }
55
56 std::map<size_t, size_t>::iterator start = chunks_.upper_bound(offset);
57 if (start != chunks_.begin())
58 --start; // start now points to the key equal or lower than offset.
59 if (start->first + start->second < offset)
60 ++start; // start element is entirely before current chunk, skip it.
61
62 std::map<size_t, size_t>::iterator end = chunks_.upper_bound(offset + size);
63 if (start == end) { // No chunks to merge.
64 chunks_[offset] = size;
65 return true;
66 }
67
68 --end;
69
70 size_t new_offset = std::min<size_t>(start->first, offset);
71 size_t new_size =
72 std::max<size_t>(end->first + end->second, offset + size) - new_offset;
73
74 chunks_.erase(start, ++end);
75
76 chunks_[new_offset] = new_size;
77
78 return true;
79 }
80
81 bool ChunkStream::ReadData(size_t offset, size_t size, void* buffer) const {
82 if (!IsRangeAvailable(offset, size))
83 return false;
84
85 memcpy(buffer, &data_[offset], size);
86 return true;
87 }
88
89 bool ChunkStream::GetMissedRanges(
90 size_t offset, size_t size,
91 std::vector<std::pair<size_t, size_t> >* ranges) const {
92 if (IsRangeAvailable(offset, size))
93 return false;
94
95 ranges->clear();
96 if (chunks_.empty()) {
97 ranges->push_back(std::pair<size_t, size_t>(offset, size));
98 return true;
99 }
100
101 std::map<size_t, size_t>::const_iterator start = chunks_.upper_bound(offset);
102 if (start != chunks_.begin())
103 --start; // start now points to the key equal or lower than offset.
104 if (start->first + start->second < offset)
105 ++start; // start element is entirely before current chunk, skip it.
106
107 std::map<size_t, size_t>::const_iterator end =
108 chunks_.upper_bound(offset + size);
109 if (start == end) { // No data in the current range available.
110 ranges->push_back(std::pair<size_t, size_t>(offset, size));
111 return true;
112 }
113
114 size_t cur_offset = offset;
115 std::map<size_t, size_t>::const_iterator it;
116 for (it = start; it != end; ++it) {
117 if (cur_offset < it->first) {
118 size_t new_size = it->first - cur_offset;
119 ranges->push_back(std::pair<size_t, size_t>(cur_offset, new_size));
120 cur_offset = it->first + it->second;
121 } else if (cur_offset < it->first + it->second) {
122 cur_offset = it->first + it->second;
123 }
124 }
125
126 // Add last chunk.
127 if (cur_offset < offset + size)
128 ranges->push_back(std::pair<size_t, size_t>(cur_offset,
129 offset + size - cur_offset));
130
131 return true;
132 }
133
134 bool ChunkStream::IsRangeAvailable(size_t offset, size_t size) const {
135 if (chunks_.empty())
136 return false;
137
138 if (SIZE_MAX - size < offset)
139 return false;
140
141 std::map<size_t, size_t>::const_iterator it = chunks_.upper_bound(offset);
142 if (it == chunks_.begin())
143 return false; // No chunks includes offset byte.
144
145 --it; // Now it starts equal or before offset.
146 return (it->first + it->second) >= (offset + size);
147 }
148
149 size_t ChunkStream::GetFirstMissingByte() const {
150 if (chunks_.empty())
151 return 0;
152 std::map<size_t, size_t>::const_iterator begin = chunks_.begin();
153 return begin->first > 0 ? 0 : begin->second;
154 }
155
156 size_t ChunkStream::GetFirstMissingByteInInterval(size_t offset) const {
157 if (chunks_.empty())
158 return 0;
159 std::map<size_t, size_t>::const_iterator it = chunks_.upper_bound(offset);
160 if (it == chunks_.begin())
161 return 0;
162 --it;
163 return it->first + it->second;
164 }
165
166 size_t ChunkStream::GetLastMissingByteInInterval(size_t offset) const {
167 if (chunks_.empty())
168 return stream_size_ - 1;
169 std::map<size_t, size_t>::const_iterator it = chunks_.upper_bound(offset);
170 if (it == chunks_.end())
171 return stream_size_ - 1;
172 return it->first - 1;
173 }
174
175 } // namespace chrome_pdf
OLDNEW
« no previous file with comments | « pdf/chunk_stream.h ('k') | pdf/chunk_stream_unittest.cc » ('j') | no next file with comments »

Powered by Google App Engine
This is Rietveld 408576698