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

Side by Side Diff: pdf/chunk_stream.h

Issue 2349753003: Improve linearized pdf load/show time. (Closed)
Patch Set: Fix heap use after free. Created 4 years, 2 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
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 #ifndef PDF_CHUNK_STREAM_H_ 5 #ifndef PDF_CHUNK_STREAM_H_
6 #define PDF_CHUNK_STREAM_H_ 6 #define PDF_CHUNK_STREAM_H_
7 7
8 #include <stddef.h> 8 #include <stddef.h>
9 #include <string.h>
9 10
10 #include <map> 11 #include <algorithm>
11 #include <utility> 12 #include <array>
13 #include <memory>
12 #include <vector> 14 #include <vector>
13 15
16 #include "pdf/range_set.h"
17
14 namespace chrome_pdf { 18 namespace chrome_pdf {
15 19
16 // This class collects a chunks of data into one data stream. Client can check 20 // This class collects a chunks of data into one data stream. Client can check
17 // if data in certain range is available, and get missing chunks of data. 21 // if data in certain range is available, and get missing chunks of data.
22 template <size_t N>
18 class ChunkStream { 23 class ChunkStream {
19 public: 24 public:
20 ChunkStream(); 25 static const int kChunkSize = N;
21 ~ChunkStream(); 26 typedef typename std::array<unsigned char, N> ChunkData;
22 27
23 void Clear(); 28 ChunkStream() {}
29 ~ChunkStream() {}
24 30
25 void Preallocate(size_t stream_size); 31 void SetChunkData(int chunk_index, std::unique_ptr<ChunkData> data) {
26 size_t GetSize() const; 32 if (!data)
33 return;
34 if (chunk_index >= static_cast<int>(data_.size())) {
35 data_.resize(chunk_index + 1);
36 }
37 if (!data_[chunk_index]) {
38 ++filled_chunks_count_;
39 }
40 data_[chunk_index] = std::move(data);
41 filled_chunks_.Union(gfx::Range(chunk_index, chunk_index + 1));
42 }
27 43
28 bool WriteData(size_t offset, void* buffer, size_t size); 44 bool ReadData(const gfx::Range& range, void* buffer) const {
29 bool ReadData(size_t offset, size_t size, void* buffer) const; 45 if (!IsRangeAvailable(range)) {
46 return false;
47 }
48 unsigned char* data_buffer = static_cast<unsigned char*>(buffer);
49 uint32_t start = range.start();
50 while (start != range.end()) {
51 const uint32_t chunk_index = GetChunkIndex(start);
52 const uint32_t chunk_start = start % kChunkSize;
53 const uint32_t len =
54 std::min(kChunkSize - chunk_start, range.end() - start);
55 memcpy(data_buffer, data_[chunk_index]->data() + chunk_start, len);
56 data_buffer += len;
57 start += len;
58 }
59 return true;
60 }
30 61
31 // Returns vector of pairs where first is an offset, second is a size. 62 uint32_t GetChunkIndex(uint32_t offset) const { return offset / kChunkSize; }
32 bool GetMissedRanges(size_t offset, size_t size,
33 std::vector<std::pair<size_t, size_t> >* ranges) const;
34 bool IsRangeAvailable(size_t offset, size_t size) const;
35 size_t GetFirstMissingByte() const;
36 63
37 // Finds the first byte of the missing byte interval that offset belongs to. 64 gfx::Range GetChunksRange(uint32_t offset, uint32_t size) const {
38 size_t GetFirstMissingByteInInterval(size_t offset) const; 65 return gfx::Range(GetChunkIndex(offset),
39 // Returns the last byte of the missing byte interval that offset belongs to. 66 GetChunkIndex(offset + size + kChunkSize - 1));
40 size_t GetLastMissingByteInInterval(size_t offset) const; 67 }
68
69 bool IsRangeAvailable(const gfx::Range& range) const {
70 if (!range.IsValid() || range.is_reversed() ||
71 (eof_pos_ && eof_pos_ < range.end()))
spelchat 2016/10/12 00:35:31 I may be wrong (other reviewers, please correct me
snake 2016/10/14 11:31:17 Done
72 return false;
73 if (range.is_empty())
74 return true;
75 const gfx::Range chunks_range(GetChunkIndex(range.start()),
76 GetChunkIndex(range.end() + kChunkSize - 1));
77 return filled_chunks_.Contains(chunks_range);
78 }
79
80 void set_eof_pos(uint32_t eof_pos) { eof_pos_ = eof_pos; }
81 uint32_t eof_pos() const { return eof_pos_; }
82
83 const RangeSet& filled_chunks() const { return filled_chunks_; }
84
85 bool IsComplete() const {
86 return eof_pos_ > 0 && IsRangeAvailable(gfx::Range(0, eof_pos_));
87 }
88
89 void Clear() {
90 data_.clear();
91 eof_pos_ = 0;
92 filled_chunks_.Clear();
93 filled_chunks_count_ = 0;
94 }
95
96 uint32_t filled_chunks_count() const { return filled_chunks_count_; }
97 uint32_t total_chunks_count() const {
98 return GetChunkIndex(eof_pos_ + kChunkSize - 1);
99 }
41 100
42 private: 101 private:
43 std::vector<unsigned char> data_; 102 std::vector<std::unique_ptr<ChunkData>> data_;
44 103 uint32_t eof_pos_ = 0;
45 // Pair, first - begining of the chunk, second - size of the chunk. 104 RangeSet filled_chunks_;
46 std::map<size_t, size_t> chunks_; 105 uint32_t filled_chunks_count_ = 0;
47
48 size_t stream_size_;
49 }; 106 };
50 107
51 }; // namespace chrome_pdf 108 }; // namespace chrome_pdf
52 109
53 #endif // PDF_CHUNK_STREAM_H_ 110 #endif // PDF_CHUNK_STREAM_H_
OLDNEW
« no previous file with comments | « pdf/DEPS ('k') | pdf/chunk_stream.cc » ('j') | pdf/document_loader.h » ('J')

Powered by Google App Engine
This is Rietveld 408576698