1 // Copyright 2017 The PDFium Authors
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 "testing/fake_file_access.h"
6
7 #include <utility>
8
9 #include "core/fxcrt/fx_system.h"
10 #include "third_party/base/check.h"
11
12 namespace {
13
14 class FileAccessWrapper final : public FPDF_FILEACCESS {
15 public:
FileAccessWrapper(FakeFileAccess * simulator)16 explicit FileAccessWrapper(FakeFileAccess* simulator)
17 : simulator_(simulator) {
18 m_FileLen = simulator_->GetFileSize();
19 m_GetBlock = &GetBlockImpl;
20 m_Param = this;
21 }
22
GetBlockImpl(void * param,unsigned long position,unsigned char * pBuf,unsigned long size)23 static int GetBlockImpl(void* param,
24 unsigned long position,
25 unsigned char* pBuf,
26 unsigned long size) {
27 return static_cast<FileAccessWrapper*>(param)->simulator_->GetBlock(
28 position, pBuf, size);
29 }
30
31 private:
32 UnownedPtr<FakeFileAccess> simulator_;
33 };
34
35 class FileAvailImpl final : public FX_FILEAVAIL {
36 public:
FileAvailImpl(FakeFileAccess * simulator)37 explicit FileAvailImpl(FakeFileAccess* simulator) : simulator_(simulator) {
38 version = 1;
39 IsDataAvail = &IsDataAvailImpl;
40 }
41
IsDataAvailImpl(FX_FILEAVAIL * pThis,size_t offset,size_t size)42 static FPDF_BOOL IsDataAvailImpl(FX_FILEAVAIL* pThis,
43 size_t offset,
44 size_t size) {
45 return static_cast<FileAvailImpl*>(pThis)->simulator_->IsDataAvail(offset,
46 size);
47 }
48
49 private:
50 UnownedPtr<FakeFileAccess> simulator_;
51 };
52
53 class DownloadHintsImpl final : public FX_DOWNLOADHINTS {
54 public:
DownloadHintsImpl(FakeFileAccess * simulator)55 explicit DownloadHintsImpl(FakeFileAccess* simulator)
56 : simulator_(simulator) {
57 version = 1;
58 AddSegment = &AddSegmentImpl;
59 }
60
AddSegmentImpl(FX_DOWNLOADHINTS * pThis,size_t offset,size_t size)61 static void AddSegmentImpl(FX_DOWNLOADHINTS* pThis,
62 size_t offset,
63 size_t size) {
64 return static_cast<DownloadHintsImpl*>(pThis)->simulator_->AddSegment(
65 offset, size);
66 }
67
68 private:
69 UnownedPtr<FakeFileAccess> simulator_;
70 };
71
72 } // namespace
73
FakeFileAccess(FPDF_FILEACCESS * file_access)74 FakeFileAccess::FakeFileAccess(FPDF_FILEACCESS* file_access)
75 : file_access_(file_access),
76 file_access_wrapper_(std::make_unique<FileAccessWrapper>(this)),
77 file_avail_(std::make_unique<FileAvailImpl>(this)),
78 download_hints_(std::make_unique<DownloadHintsImpl>(this)) {
79 DCHECK(file_access_);
80 }
81
82 FakeFileAccess::~FakeFileAccess() = default;
83
IsDataAvail(size_t offset,size_t size) const84 FPDF_BOOL FakeFileAccess::IsDataAvail(size_t offset, size_t size) const {
85 return available_data_.Contains(RangeSet::Range(offset, offset + size));
86 }
87
AddSegment(size_t offset,size_t size)88 void FakeFileAccess::AddSegment(size_t offset, size_t size) {
89 requested_data_.Union(RangeSet::Range(offset, offset + size));
90 }
91
GetFileSize()92 unsigned long FakeFileAccess::GetFileSize() {
93 return file_access_->m_FileLen;
94 }
95
GetBlock(unsigned long position,unsigned char * pBuf,unsigned long size)96 int FakeFileAccess::GetBlock(unsigned long position,
97 unsigned char* pBuf,
98 unsigned long size) {
99 if (!pBuf || !size)
100 return false;
101
102 if (!IsDataAvail(static_cast<size_t>(position), static_cast<size_t>(size)))
103 return false;
104
105 return file_access_->m_GetBlock(file_access_->m_Param, position, pBuf, size);
106 }
107
SetRequestedDataAvailable()108 void FakeFileAccess::SetRequestedDataAvailable() {
109 available_data_.Union(requested_data_);
110 requested_data_.Clear();
111 }
112
SetWholeFileAvailable()113 void FakeFileAccess::SetWholeFileAvailable() {
114 available_data_.Union(RangeSet::Range(0, static_cast<size_t>(GetFileSize())));
115 requested_data_.Clear();
116 }
117