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