| // Copyright 2017 PDFium Authors. All rights reserved. | |
| // Use of this source code is governed by a BSD-style license that can be | |
| // found in the LICENSE file. | |
| #include "testing/fake_file_access.h" | |
| #include <algorithm> | |
| #include <set> | |
| #include <utility> | |
| #include "core/fxcrt/fx_system.h" | |
| #include "third_party/base/check.h" | |
| namespace { | |
| class FileAccessWrapper final : public FPDF_FILEACCESS { | |
| public: | |
| explicit FileAccessWrapper(FakeFileAccess* simulator) | |
| : simulator_(simulator) { | |
| m_FileLen = simulator_->GetFileSize(); | |
| m_GetBlock = &GetBlockImpl; | |
| m_Param = this; | |
| } | |
| static int GetBlockImpl(void* param, | |
| unsigned long position, | |
| unsigned char* pBuf, | |
| unsigned long size) { | |
| return static_cast<FileAccessWrapper*>(param)->simulator_->GetBlock( | |
| position, pBuf, size); | |
| } | |
| private: | |
| UnownedPtr<FakeFileAccess> simulator_; | |
| }; | |
| class FileAvailImpl final : public FX_FILEAVAIL { | |
| public: | |
| explicit FileAvailImpl(FakeFileAccess* simulator) : simulator_(simulator) { | |
| version = 1; | |
| IsDataAvail = &IsDataAvailImpl; | |
| } | |
| static FPDF_BOOL IsDataAvailImpl(FX_FILEAVAIL* pThis, | |
| size_t offset, | |
| size_t size) { | |
| return static_cast<FileAvailImpl*>(pThis)->simulator_->IsDataAvail(offset, | |
| size); | |
| } | |
| private: | |
| UnownedPtr<FakeFileAccess> simulator_; | |
| }; | |
| class DownloadHintsImpl final : public FX_DOWNLOADHINTS { | |
| public: | |
| explicit DownloadHintsImpl(FakeFileAccess* simulator) | |
| : simulator_(simulator) { | |
| version = 1; | |
| AddSegment = &AddSegmentImpl; | |
| } | |
| static void AddSegmentImpl(FX_DOWNLOADHINTS* pThis, | |
| size_t offset, | |
| size_t size) { | |
| return static_cast<DownloadHintsImpl*>(pThis)->simulator_->AddSegment( | |
| offset, size); | |
| } | |
| private: | |
| UnownedPtr<FakeFileAccess> simulator_; | |
| }; | |
| } // namespace | |
| FakeFileAccess::FakeFileAccess(FPDF_FILEACCESS* file_access) | |
| : file_access_(file_access), | |
| file_access_wrapper_(std::make_unique<FileAccessWrapper>(this)), | |
| file_avail_(std::make_unique<FileAvailImpl>(this)), | |
| download_hints_(std::make_unique<DownloadHintsImpl>(this)) { | |
| DCHECK(file_access_); | |
| } | |
| FakeFileAccess::~FakeFileAccess() = default; | |
| FPDF_BOOL FakeFileAccess::IsDataAvail(size_t offset, size_t size) const { | |
| return available_data_.Contains(RangeSet::Range(offset, offset + size)); | |
| } | |
| void FakeFileAccess::AddSegment(size_t offset, size_t size) { | |
| requested_data_.Union(RangeSet::Range(offset, offset + size)); | |
| } | |
| unsigned long FakeFileAccess::GetFileSize() { | |
| return file_access_->m_FileLen; | |
| } | |
| int FakeFileAccess::GetBlock(unsigned long position, | |
| unsigned char* pBuf, | |
| unsigned long size) { | |
| if (!pBuf || !size) | |
| return false; | |
| if (!IsDataAvail(static_cast<size_t>(position), static_cast<size_t>(size))) | |
| return false; | |
| return file_access_->m_GetBlock(file_access_->m_Param, position, pBuf, size); | |
| } | |
| void FakeFileAccess::SetRequestedDataAvailable() { | |
| available_data_.Union(requested_data_); | |
| requested_data_.Clear(); | |
| } | |
| void FakeFileAccess::SetWholeFileAvailable() { | |
| available_data_.Union(RangeSet::Range(0, static_cast<size_t>(GetFileSize()))); | |
| requested_data_.Clear(); | |
| } |