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: 19 explicit FileAccessWrapper(FakeFileAccess* simulator) 20 : simulator_(simulator) { 21 m_FileLen = simulator_->GetFileSize(); 22 m_GetBlock = &GetBlockImpl; 23 m_Param = this; 24 } 25 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: 40 explicit FileAvailImpl(FakeFileAccess* simulator) : simulator_(simulator) { 41 version = 1; 42 IsDataAvail = &IsDataAvailImpl; 43 } 44 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: 58 explicit DownloadHintsImpl(FakeFileAccess* simulator) 59 : simulator_(simulator) { 60 version = 1; 61 AddSegment = &AddSegmentImpl; 62 } 63 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 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 85 FakeFileAccess::~FakeFileAccess() {} 86 87 FPDF_BOOL FakeFileAccess::IsDataAvail(size_t offset, size_t size) const { 88 return available_data_.Contains(RangeSet::Range(offset, offset + size)); 89 } 90 91 void FakeFileAccess::AddSegment(size_t offset, size_t size) { 92 requested_data_.Union(RangeSet::Range(offset, offset + size)); 93 } 94 95 unsigned long FakeFileAccess::GetFileSize() { 96 return file_access_->m_FileLen; 97 } 98 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 107 void FakeFileAccess::SetRequestedDataAvailable() { 108 available_data_.Union(requested_data_); 109 requested_data_.Clear(); 110 } 111 112 void FakeFileAccess::SetWholeFileAvailable() { 113 available_data_.Union(RangeSet::Range(0, static_cast<size_t>(GetFileSize()))); 114 requested_data_.Clear(); 115 } 116