File: test_document_loader.cc

package info (click to toggle)
chromium 145.0.7632.159-1
  • links: PTS, VCS
  • area: main
  • in suites: forky, sid
  • size: 5,976,224 kB
  • sloc: cpp: 36,198,469; ansic: 7,634,080; javascript: 3,564,060; python: 1,649,622; xml: 838,470; asm: 717,087; pascal: 185,708; sh: 88,786; perl: 88,718; objc: 79,984; sql: 59,811; cs: 42,452; fortran: 24,101; makefile: 21,144; tcl: 15,277; php: 14,022; yacc: 9,066; ruby: 7,553; awk: 3,720; lisp: 3,233; lex: 1,328; ada: 727; jsp: 228; sed: 36
file content (129 lines) | stat: -rw-r--r-- 4,058 bytes parent folder | download | duplicates (5)
1
2
3
4
5
6
7
8
9
10
11
12
13
14
15
16
17
18
19
20
21
22
23
24
25
26
27
28
29
30
31
32
33
34
35
36
37
38
39
40
41
42
43
44
45
46
47
48
49
50
51
52
53
54
55
56
57
58
59
60
61
62
63
64
65
66
67
68
69
70
71
72
73
74
75
76
77
78
79
80
81
82
83
84
85
86
87
88
89
90
91
92
93
94
95
96
97
98
99
100
101
102
103
104
105
106
107
108
109
110
111
112
113
114
115
116
117
118
119
120
121
122
123
124
125
126
127
128
129
// Copyright 2018 The Chromium Authors
// Use of this source code is governed by a BSD-style license that can be
// found in the LICENSE file.

#include "pdf/test/test_document_loader.h"

#include <stdint.h>

#include <utility>

#include "base/check_op.h"
#include "base/containers/span.h"
#include "base/files/file_util.h"
#include "base/notreached.h"
#include "pdf/loader/range_set.h"
#include "pdf/loader/url_loader_wrapper.h"
#include "pdf/test/test_helpers.h"
#include "ui/gfx/range/range.h"

namespace chrome_pdf {

namespace {

std::vector<uint8_t> ReadTestData(const base::FilePath::StringType& pdf_name) {
  auto result =
      base::ReadFileToBytes(GetTestDataFilePath(base::FilePath(pdf_name)));
  CHECK(result.has_value());
  return result.value();
}

}  // namespace

TestDocumentLoader::TestDocumentLoader(
    Client* client,
    const base::FilePath::StringType& pdf_name)
    : TestDocumentLoader(client, ReadTestData(pdf_name)) {}

TestDocumentLoader::TestDocumentLoader(Client* client,
                                       std::vector<uint8_t> pdf_data)
    : client_(client), pdf_data_(std::move(pdf_data)) {}

TestDocumentLoader::~TestDocumentLoader() = default;

// TODO(crbug.com/40120473): Consider faking out URLLoaderWrapper, to avoid
// simulating the behavior of DocumentLoaderImpl (although that would result in
// 64 KiB loads).
bool TestDocumentLoader::SimulateLoadData(uint32_t max_bytes) {
  CHECK_GT(max_bytes, 0U);
  if (IsDocumentComplete())
    return false;

  // Approximate the behavior of DocumentLoaderImpl::ContinueDownload() by
  // either reading from the start of the next pending range, or from the
  // beginning of the document (skipping any received ranges).
  RangeSet candidate_ranges(gfx::Range(
      pending_ranges_.IsEmpty() ? 0 : pending_ranges_.First().start(),
      GetDocumentSize()));
  candidate_ranges.Subtract(received_ranges_);
  CHECK(!candidate_ranges.IsEmpty());

  gfx::Range request_range = candidate_ranges.First();
  if (request_range.length() > max_bytes)
    request_range.set_end(request_range.start() + max_bytes);

  // Simulate fetching the requested range.
  received_bytes_ += request_range.length();
  received_ranges_.Union(request_range);
  pending_ranges_.Subtract(request_range);
  client_->OnNewDataReceived();

  bool is_pending = !IsDocumentComplete();
  if (is_pending)
    client_->OnPendingRequestComplete();
  else
    client_->OnDocumentComplete();
  return is_pending;
}

bool TestDocumentLoader::Init(std::unique_ptr<URLLoaderWrapper> loader,
                              const std::string& url) {
  NOTREACHED() << "PDFiumEngine skips this call when testing";
}

bool TestDocumentLoader::GetBlock(uint32_t position,
                                  base::span<uint8_t> buf) const {
  if (!IsDataAvailable(position, buf.size())) {
    return false;
  }

  buf.copy_from(base::span(pdf_data_).subspan(position, buf.size()));
  return true;
}

bool TestDocumentLoader::IsDataAvailable(uint32_t position,
                                         uint32_t size) const {
  CHECK_LE(position, GetDocumentSize());
  CHECK_LE(size, GetDocumentSize() - position);
  gfx::Range range(position, position + size);
  return range.is_empty() || received_ranges_.Contains(range);
}

void TestDocumentLoader::RequestData(uint32_t position, uint32_t size) {
  if (IsDataAvailable(position, size))
    return;

  // DocumentLoaderImpl requests chunks of 64 KiB, but that is uninteresting for
  // small test files, so use byte ranges instead.
  RangeSet request_ranges(gfx::Range(position, position + size));
  request_ranges.Subtract(received_ranges_);
  pending_ranges_.Union(request_ranges);
}

bool TestDocumentLoader::IsDocumentComplete() const {
  return BytesReceived() == GetDocumentSize();
}

uint32_t TestDocumentLoader::GetDocumentSize() const {
  return pdf_data_.size();
}

uint32_t TestDocumentLoader::BytesReceived() const {
  return received_bytes_;
}

void TestDocumentLoader::ClearPendingRequests() {
  pending_ranges_.Clear();
}

}  // namespace chrome_pdf