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