[go: nahoru, domu]

blob: 00f8e386fb9b866108264ed867a2ce6c3f4492b0 [file] [log] [blame]
Avi Drissmandb497b32022-09-15 19:47:281// Copyright 2010 The Chromium Authors
jam@chromium.org1b1e9eff2014-05-20 01:56:402// Use of this source code is governed by a BSD-style license that can be
3// found in the LICENSE file.
4
K. Moonefbad4c92022-06-16 20:34:485#ifndef PDF_LOADER_CHUNK_STREAM_H_
6#define PDF_LOADER_CHUNK_STREAM_H_
jam@chromium.org1b1e9eff2014-05-20 01:56:407
8#include <stddef.h>
Artem Stryginaf1b43422017-09-12 18:48:249#include <string.h>
jam@chromium.org1b1e9eff2014-05-20 01:56:4010
Artem Stryginaf1b43422017-09-12 18:48:2411#include <algorithm>
12#include <array>
13#include <memory>
Lei Zhangfc4640d62018-03-28 17:30:3614#include <utility>
jam@chromium.org1b1e9eff2014-05-20 01:56:4015#include <vector>
16
K. Moonefbad4c92022-06-16 20:34:4817#include "pdf/loader/range_set.h"
Artem Stryginaf1b43422017-09-12 18:48:2418
jam@chromium.org1b1e9eff2014-05-20 01:56:4019namespace chrome_pdf {
20
21// This class collects a chunks of data into one data stream. Client can check
22// if data in certain range is available, and get missing chunks of data.
Peter Kasting43fddaaa2022-06-28 02:44:2823template <size_t N>
jam@chromium.org1b1e9eff2014-05-20 01:56:4024class ChunkStream {
25 public:
Peter Kasting43fddaaa2022-06-28 02:44:2826 static constexpr size_t kChunkSize = N;
Artem Stryginaf1b43422017-09-12 18:48:2427 using ChunkData = typename std::array<unsigned char, N>;
jam@chromium.org1b1e9eff2014-05-20 01:56:4028
Artem Stryginaf1b43422017-09-12 18:48:2429 ChunkStream() {}
30 ~ChunkStream() {}
jam@chromium.org1b1e9eff2014-05-20 01:56:4031
Peter Kasting43fddaaa2022-06-28 02:44:2832 void SetChunkData(size_t chunk_index, std::unique_ptr<ChunkData> data) {
Artem Stryginaf1b43422017-09-12 18:48:2433 if (!data)
34 return;
Lei Zhangfc4640d62018-03-28 17:30:3635
36 if (chunk_index >= data_.size())
Artem Stryginaf1b43422017-09-12 18:48:2437 data_.resize(chunk_index + 1);
Lei Zhangfc4640d62018-03-28 17:30:3638
39 if (!data_[chunk_index])
Artem Stryginaf1b43422017-09-12 18:48:2440 ++filled_chunks_count_;
Lei Zhangfc4640d62018-03-28 17:30:3641
Artem Stryginaf1b43422017-09-12 18:48:2442 data_[chunk_index] = std::move(data);
43 filled_chunks_.Union(gfx::Range(chunk_index, chunk_index + 1));
44 }
jam@chromium.org1b1e9eff2014-05-20 01:56:4045
Artem Stryginaf1b43422017-09-12 18:48:2446 bool ReadData(const gfx::Range& range, void* buffer) const {
Lei Zhangfc4640d62018-03-28 17:30:3647 if (!IsRangeAvailable(range))
Artem Stryginaf1b43422017-09-12 18:48:2448 return false;
Lei Zhangfc4640d62018-03-28 17:30:3649
Artem Stryginaf1b43422017-09-12 18:48:2450 unsigned char* data_buffer = static_cast<unsigned char*>(buffer);
Peter Kasting43fddaaa2022-06-28 02:44:2851 size_t start = range.start();
Artem Stryginaf1b43422017-09-12 18:48:2452 while (start != range.end()) {
Peter Kasting43fddaaa2022-06-28 02:44:2853 const size_t chunk_index = GetChunkIndex(start);
54 const size_t chunk_start = start % kChunkSize;
55 const size_t len =
Artem Stryginaf1b43422017-09-12 18:48:2456 std::min(kChunkSize - chunk_start, range.end() - start);
57 memcpy(data_buffer, data_[chunk_index]->data() + chunk_start, len);
58 data_buffer += len;
59 start += len;
60 }
61 return true;
62 }
jam@chromium.org1b1e9eff2014-05-20 01:56:4063
Peter Kasting43fddaaa2022-06-28 02:44:2864 size_t GetChunkIndex(size_t offset) const { return offset / kChunkSize; }
jam@chromium.org1b1e9eff2014-05-20 01:56:4065
Peter Kasting43fddaaa2022-06-28 02:44:2866 gfx::Range GetChunksRange(size_t offset, size_t size) const {
Lei Zhangfc4640d62018-03-28 17:30:3667 return gfx::Range(GetChunkIndex(offset), GetChunkEnd(offset + size));
Artem Stryginaf1b43422017-09-12 18:48:2468 }
69
70 bool IsRangeAvailable(const gfx::Range& range) const {
71 if (!range.IsValid() || range.is_reversed() ||
Lei Zhangfc4640d62018-03-28 17:30:3672 (eof_pos_ > 0 && eof_pos_ < range.end())) {
Artem Stryginaf1b43422017-09-12 18:48:2473 return false;
Lei Zhangfc4640d62018-03-28 17:30:3674 }
75
Artem Stryginaf1b43422017-09-12 18:48:2476 if (range.is_empty())
77 return true;
Lei Zhangfc4640d62018-03-28 17:30:3678
Artem Stryginaf1b43422017-09-12 18:48:2479 const gfx::Range chunks_range(GetChunkIndex(range.start()),
Lei Zhangfc4640d62018-03-28 17:30:3680 GetChunkEnd(range.end()));
Artem Stryginaf1b43422017-09-12 18:48:2481 return filled_chunks_.Contains(chunks_range);
82 }
83
Peter Kasting43fddaaa2022-06-28 02:44:2884 bool IsChunkAvailable(size_t chunk_index) const {
Artem Strygin2cf20af42018-06-14 14:26:5385 return filled_chunks_.Contains(chunk_index);
86 }
87
Peter Kasting43fddaaa2022-06-28 02:44:2888 void set_eof_pos(size_t eof_pos) { eof_pos_ = eof_pos; }
89 size_t eof_pos() const { return eof_pos_; }
Artem Stryginaf1b43422017-09-12 18:48:2490
91 const RangeSet& filled_chunks() const { return filled_chunks_; }
92
93 bool IsComplete() const {
94 return eof_pos_ > 0 && IsRangeAvailable(gfx::Range(0, eof_pos_));
95 }
96
Peter Kasting43fddaaa2022-06-28 02:44:2897 bool IsValidChunkIndex(size_t chunk_index) const {
Artem Strygin2cf20af42018-06-14 14:26:5398 return !eof_pos_ || (chunk_index <= GetChunkIndex(eof_pos_ - 1));
99 }
100
Artem Stryginaf1b43422017-09-12 18:48:24101 void Clear() {
102 data_.clear();
103 eof_pos_ = 0;
104 filled_chunks_.Clear();
105 filled_chunks_count_ = 0;
106 }
107
Peter Kasting43fddaaa2022-06-28 02:44:28108 size_t filled_chunks_count() const { return filled_chunks_count_; }
109 size_t total_chunks_count() const { return GetChunkEnd(eof_pos_); }
jam@chromium.org1b1e9eff2014-05-20 01:56:40110
111 private:
Peter Kasting43fddaaa2022-06-28 02:44:28112 size_t GetChunkEnd(size_t offset) const {
Lei Zhangfc4640d62018-03-28 17:30:36113 return (offset + kChunkSize - 1) / kChunkSize;
114 }
115
Artem Stryginaf1b43422017-09-12 18:48:24116 std::vector<std::unique_ptr<ChunkData>> data_;
Peter Kasting43fddaaa2022-06-28 02:44:28117 size_t eof_pos_ = 0;
Artem Stryginaf1b43422017-09-12 18:48:24118 RangeSet filled_chunks_;
Peter Kasting43fddaaa2022-06-28 02:44:28119 size_t filled_chunks_count_ = 0;
jam@chromium.org1b1e9eff2014-05-20 01:56:40120};
121
Nico Weber40cd26fd2019-02-09 17:37:02122} // namespace chrome_pdf
jam@chromium.org1b1e9eff2014-05-20 01:56:40123
K. Moonefbad4c92022-06-16 20:34:48124#endif // PDF_LOADER_CHUNK_STREAM_H_