1 // Copyright 2014 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 // Original code copyright 2014 Foxit Software Inc. http://www.foxitsoftware.com
6 
7 #include "public/fpdf_dataavail.h"
8 
9 #include "fpdfsdk/include/fsdk_define.h"
10 #include "public/fpdf_formfill.h"
11 
12 // These checks are here because core/ and public/ cannot depend on each other.
13 static_assert(IPDF_DataAvail::DataError == PDF_DATA_ERROR,
14               "IPDF_DataAvail::DataError value mismatch");
15 static_assert(IPDF_DataAvail::DataNotAvailable == PDF_DATA_NOTAVAIL,
16               "IPDF_DataAvail::DataNotAvailable value mismatch");
17 static_assert(IPDF_DataAvail::DataAvailable == PDF_DATA_AVAIL,
18               "IPDF_DataAvail::DataAvailable value mismatch");
19 
20 static_assert(IPDF_DataAvail::LinearizationUnknown == PDF_LINEARIZATION_UNKNOWN,
21               "IPDF_DataAvail::LinearizationUnknown value mismatch");
22 static_assert(IPDF_DataAvail::NotLinearized == PDF_NOT_LINEARIZED,
23               "IPDF_DataAvail::NotLinearized value mismatch");
24 static_assert(IPDF_DataAvail::Linearized == PDF_LINEARIZED,
25               "IPDF_DataAvail::Linearized value mismatch");
26 
27 static_assert(IPDF_DataAvail::FormError == PDF_FORM_ERROR,
28               "IPDF_DataAvail::FormError value mismatch");
29 static_assert(IPDF_DataAvail::FormNotAvailable == PDF_FORM_NOTAVAIL,
30               "IPDF_DataAvail::FormNotAvailable value mismatch");
31 static_assert(IPDF_DataAvail::FormAvailable == PDF_FORM_AVAIL,
32               "IPDF_DataAvail::FormAvailable value mismatch");
33 static_assert(IPDF_DataAvail::FormNotExist == PDF_FORM_NOTEXIST,
34               "IPDF_DataAvail::FormNotExist value mismatch");
35 
36 class CFPDF_FileAvailWrap : public IFX_FileAvail {
37  public:
CFPDF_FileAvailWrap()38   CFPDF_FileAvailWrap() { m_pfileAvail = NULL; }
~CFPDF_FileAvailWrap()39   ~CFPDF_FileAvailWrap() override {}
40 
Set(FX_FILEAVAIL * pfileAvail)41   void Set(FX_FILEAVAIL* pfileAvail) { m_pfileAvail = pfileAvail; }
42 
43   // IFX_FileAvail
IsDataAvail(FX_FILESIZE offset,FX_DWORD size)44   FX_BOOL IsDataAvail(FX_FILESIZE offset, FX_DWORD size) override {
45     return m_pfileAvail->IsDataAvail(m_pfileAvail, offset, size);
46   }
47 
48  private:
49   FX_FILEAVAIL* m_pfileAvail;
50 };
51 
52 class CFPDF_FileAccessWrap : public IFX_FileRead {
53  public:
CFPDF_FileAccessWrap()54   CFPDF_FileAccessWrap() { m_pFileAccess = NULL; }
~CFPDF_FileAccessWrap()55   ~CFPDF_FileAccessWrap() override {}
56 
Set(FPDF_FILEACCESS * pFile)57   void Set(FPDF_FILEACCESS* pFile) { m_pFileAccess = pFile; }
58 
59   // IFX_FileRead
GetSize()60   FX_FILESIZE GetSize() override { return m_pFileAccess->m_FileLen; }
61 
ReadBlock(void * buffer,FX_FILESIZE offset,size_t size)62   FX_BOOL ReadBlock(void* buffer, FX_FILESIZE offset, size_t size) override {
63     return m_pFileAccess->m_GetBlock(m_pFileAccess->m_Param, offset,
64                                      (uint8_t*)buffer, size);
65   }
66 
Release()67   void Release() override {}
68 
69  private:
70   FPDF_FILEACCESS* m_pFileAccess;
71 };
72 
73 class CFPDF_DownloadHintsWrap : public IFX_DownloadHints {
74  public:
CFPDF_DownloadHintsWrap(FX_DOWNLOADHINTS * pDownloadHints)75   explicit CFPDF_DownloadHintsWrap(FX_DOWNLOADHINTS* pDownloadHints) {
76     m_pDownloadHints = pDownloadHints;
77   }
~CFPDF_DownloadHintsWrap()78   ~CFPDF_DownloadHintsWrap() override {}
79 
80  public:
81   // IFX_DownloadHints
AddSegment(FX_FILESIZE offset,FX_DWORD size)82   void AddSegment(FX_FILESIZE offset, FX_DWORD size) override {
83     m_pDownloadHints->AddSegment(m_pDownloadHints, offset, size);
84   }
85 
86  private:
87   FX_DOWNLOADHINTS* m_pDownloadHints;
88 };
89 
90 class CFPDF_DataAvail {
91  public:
CFPDF_DataAvail()92   CFPDF_DataAvail() { m_pDataAvail = NULL; }
93 
~CFPDF_DataAvail()94   ~CFPDF_DataAvail() { delete m_pDataAvail; }
95 
96   IPDF_DataAvail* m_pDataAvail;
97   CFPDF_FileAvailWrap m_FileAvail;
98   CFPDF_FileAccessWrap m_FileRead;
99 };
100 
FPDFAvail_Create(FX_FILEAVAIL * file_avail,FPDF_FILEACCESS * file)101 DLLEXPORT FPDF_AVAIL STDCALL FPDFAvail_Create(FX_FILEAVAIL* file_avail,
102                                               FPDF_FILEACCESS* file) {
103   CFPDF_DataAvail* pAvail = new CFPDF_DataAvail;
104   pAvail->m_FileAvail.Set(file_avail);
105   pAvail->m_FileRead.Set(file);
106   pAvail->m_pDataAvail =
107       IPDF_DataAvail::Create(&pAvail->m_FileAvail, &pAvail->m_FileRead);
108   return pAvail;
109 }
110 
FPDFAvail_Destroy(FPDF_AVAIL avail)111 DLLEXPORT void STDCALL FPDFAvail_Destroy(FPDF_AVAIL avail) {
112   delete (CFPDF_DataAvail*)avail;
113 }
114 
115 DLLEXPORT int STDCALL
FPDFAvail_IsDocAvail(FPDF_AVAIL avail,FX_DOWNLOADHINTS * hints)116 FPDFAvail_IsDocAvail(FPDF_AVAIL avail, FX_DOWNLOADHINTS* hints) {
117   if (!avail || !hints)
118     return PDF_DATA_ERROR;
119   CFPDF_DownloadHintsWrap hints_wrap(hints);
120   return ((CFPDF_DataAvail*)avail)->m_pDataAvail->IsDocAvail(&hints_wrap);
121 }
122 
123 DLLEXPORT FPDF_DOCUMENT STDCALL
FPDFAvail_GetDocument(FPDF_AVAIL avail,FPDF_BYTESTRING password)124 FPDFAvail_GetDocument(FPDF_AVAIL avail, FPDF_BYTESTRING password) {
125   if (!avail)
126     return NULL;
127   CPDF_Parser* pParser = new CPDF_Parser;
128   pParser->SetPassword(password);
129 
130   FX_DWORD err_code = pParser->StartAsynParse(
131       ((CFPDF_DataAvail*)avail)->m_pDataAvail->GetFileRead());
132   if (err_code) {
133     delete pParser;
134     ProcessParseError(err_code);
135     return NULL;
136   }
137   ((CFPDF_DataAvail*)avail)->m_pDataAvail->SetDocument(pParser->GetDocument());
138   CheckUnSupportError(pParser->GetDocument(), FPDF_ERR_SUCCESS);
139   return FPDFDocumentFromCPDFDocument(pParser->GetDocument());
140 }
141 
FPDFAvail_GetFirstPageNum(FPDF_DOCUMENT doc)142 DLLEXPORT int STDCALL FPDFAvail_GetFirstPageNum(FPDF_DOCUMENT doc) {
143   CPDF_Document* pDoc = CPDFDocumentFromFPDFDocument(doc);
144   return pDoc ? pDoc->GetParser()->GetFirstPageNo() : 0;
145 }
146 
FPDFAvail_IsPageAvail(FPDF_AVAIL avail,int page_index,FX_DOWNLOADHINTS * hints)147 DLLEXPORT int STDCALL FPDFAvail_IsPageAvail(FPDF_AVAIL avail,
148                                             int page_index,
149                                             FX_DOWNLOADHINTS* hints) {
150   if (!avail || !hints)
151     return PDF_DATA_ERROR;
152   CFPDF_DownloadHintsWrap hints_wrap(hints);
153   return ((CFPDF_DataAvail*)avail)
154       ->m_pDataAvail->IsPageAvail(page_index, &hints_wrap);
155 }
156 
FPDFAvail_IsFormAvail(FPDF_AVAIL avail,FX_DOWNLOADHINTS * hints)157 DLLEXPORT int STDCALL FPDFAvail_IsFormAvail(FPDF_AVAIL avail,
158                                             FX_DOWNLOADHINTS* hints) {
159   if (!avail || !hints)
160     return PDF_FORM_ERROR;
161   CFPDF_DownloadHintsWrap hints_wrap(hints);
162   return ((CFPDF_DataAvail*)avail)->m_pDataAvail->IsFormAvail(&hints_wrap);
163 }
164 
FPDFAvail_IsLinearized(FPDF_AVAIL avail)165 DLLEXPORT int STDCALL FPDFAvail_IsLinearized(FPDF_AVAIL avail) {
166   if (!avail)
167     return PDF_LINEARIZATION_UNKNOWN;
168   return ((CFPDF_DataAvail*)avail)->m_pDataAvail->IsLinearizedPDF();
169 }
170