Home | History | Annotate | Download | only in testing
      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