blob: 8293c371dc0bf66b046e4d0da04cff14ea8bceca [file] [log] [blame]
John Abd-El-Malek3f3b45c2014-05-23 17:28:10 -07001// 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.
Lei Zhanga6d9f0e2015-06-13 00:48:38 -07004
John Abd-El-Malek3f3b45c2014-05-23 17:28:10 -07005// Original code copyright 2014 Foxit Software Inc. http://www.foxitsoftware.com
6
Lei Zhangb4e7f302015-11-06 15:52:32 -08007#include "public/fpdf_save.h"
8
Dan Sinclair3ebd1212016-03-09 09:59:23 -05009#include <vector>
10
Dan Sinclairaa403d32016-03-15 14:57:22 -040011#include "core/fpdfapi/fpdf_edit/include/cpdf_creator.h"
12#include "core/fpdfapi/fpdf_parser/include/cpdf_array.h"
13#include "core/fpdfapi/fpdf_parser/include/cpdf_document.h"
14#include "core/fpdfapi/fpdf_parser/include/cpdf_reference.h"
Dan Sinclair584b1e62016-03-21 09:15:45 -040015#include "core/fpdfapi/fpdf_parser/include/cpdf_stream_acc.h"
Dan Sinclairaa403d32016-03-15 14:57:22 -040016#include "core/fpdfapi/fpdf_parser/include/cpdf_string.h"
Dan Sinclaira8a28e02016-03-23 15:41:39 -040017#include "core/fxcrt/include/fx_ext.h"
Tom Sepez40e9ff32015-11-30 12:39:54 -080018#include "fpdfsdk/include/fsdk_define.h"
19#include "public/fpdf_edit.h"
20
Tom Sepez51da0932015-11-25 16:05:49 -080021#ifdef PDF_ENABLE_XFA
dsinclair89bdd082016-04-06 10:47:54 -070022#include "fpdfsdk/fpdfxfa/include/fpdfxfa_app.h"
23#include "fpdfsdk/fpdfxfa/include/fpdfxfa_doc.h"
24#include "fpdfsdk/fpdfxfa/include/fpdfxfa_util.h"
Lei Zhangb4e7f302015-11-06 15:52:32 -080025#include "public/fpdf_formfill.h"
weili625ad662016-06-15 11:21:33 -070026#include "xfa/fxfa/include/cxfa_eventparam.h"
dsinclair7222ea62016-04-06 14:33:07 -070027#include "xfa/fxfa/include/xfa_checksum.h"
28#include "xfa/fxfa/include/xfa_ffapp.h"
29#include "xfa/fxfa/include/xfa_ffdocview.h"
30#include "xfa/fxfa/include/xfa_ffwidgethandler.h"
Tom Sepez51da0932015-11-25 16:05:49 -080031#endif
Tom Sepez1ed8a212015-05-11 15:25:39 -070032
John Abd-El-Malek3f3b45c2014-05-23 17:28:10 -070033#if _FX_OS_ == _FX_ANDROID_
34#include "time.h"
35#else
36#include <ctime>
37#endif
38
Nico Weber9d8ec5a2015-08-04 13:00:21 -070039class CFX_IFileWrite final : public IFX_StreamWrite {
40 public:
41 CFX_IFileWrite();
42 FX_BOOL Init(FPDF_FILEWRITE* pFileWriteStruct);
Lei Zhang2b1a2d52015-08-14 22:16:22 -070043 FX_BOOL WriteBlock(const void* pData, size_t size) override;
44 void Release() override;
Lei Zhanga6d9f0e2015-06-13 00:48:38 -070045
Nico Weber9d8ec5a2015-08-04 13:00:21 -070046 protected:
Lei Zhang2b1a2d52015-08-14 22:16:22 -070047 ~CFX_IFileWrite() override {}
48
Nico Weber9d8ec5a2015-08-04 13:00:21 -070049 FPDF_FILEWRITE* m_pFileWriteStruct;
John Abd-El-Malek3f3b45c2014-05-23 17:28:10 -070050};
51
Nico Weber9d8ec5a2015-08-04 13:00:21 -070052CFX_IFileWrite::CFX_IFileWrite() {
thestig1cd352e2016-06-07 17:53:06 -070053 m_pFileWriteStruct = nullptr;
John Abd-El-Malek3f3b45c2014-05-23 17:28:10 -070054}
55
Nico Weber9d8ec5a2015-08-04 13:00:21 -070056FX_BOOL CFX_IFileWrite::Init(FPDF_FILEWRITE* pFileWriteStruct) {
57 if (!pFileWriteStruct)
58 return FALSE;
Tom Sepez2f2ffec2015-07-23 14:42:09 -070059
Nico Weber9d8ec5a2015-08-04 13:00:21 -070060 m_pFileWriteStruct = pFileWriteStruct;
61 return TRUE;
62}
63
64FX_BOOL CFX_IFileWrite::WriteBlock(const void* pData, size_t size) {
65 if (!m_pFileWriteStruct)
66 return FALSE;
67
68 m_pFileWriteStruct->WriteBlock(m_pFileWriteStruct, pData, size);
69 return TRUE;
70}
71
Lei Zhang2b1a2d52015-08-14 22:16:22 -070072void CFX_IFileWrite::Release() {
73 delete this;
74}
75
Tom Sepez7a73eff2016-02-08 13:39:53 -080076namespace {
77
Tom Sepez51da0932015-11-25 16:05:49 -080078#ifdef PDF_ENABLE_XFA
Tom Sepez7a73eff2016-02-08 13:39:53 -080079bool SaveXFADocumentData(CPDFXFA_Document* pDocument,
80 std::vector<ScopedFileStream>* fileList) {
Nico Weber9d8ec5a2015-08-04 13:00:21 -070081 if (!pDocument)
Tom Sepez7a73eff2016-02-08 13:39:53 -080082 return false;
83
Tom Sepezd3116dc2015-11-24 15:58:06 -080084 if (pDocument->GetDocType() != DOCTYPE_DYNAMIC_XFA &&
Nico Weber9d8ec5a2015-08-04 13:00:21 -070085 pDocument->GetDocType() != DOCTYPE_STATIC_XFA)
Tom Sepez7a73eff2016-02-08 13:39:53 -080086 return true;
87
Nico Weber9d8ec5a2015-08-04 13:00:21 -070088 if (!CPDFXFA_App::GetInstance()->GetXFAApp())
Tom Sepez7a73eff2016-02-08 13:39:53 -080089 return true;
John Abd-El-Malek3f3b45c2014-05-23 17:28:10 -070090
dsinclairdf4bc592016-03-31 20:34:43 -070091 CXFA_FFDocView* pXFADocView = pDocument->GetXFADocView();
Tom Sepez7a73eff2016-02-08 13:39:53 -080092 if (!pXFADocView)
93 return true;
Bo Xufdc00a72014-10-28 23:03:33 -070094
Nico Weber9d8ec5a2015-08-04 13:00:21 -070095 CPDF_Document* pPDFDocument = pDocument->GetPDFDoc();
Tom Sepez7a73eff2016-02-08 13:39:53 -080096 if (!pDocument)
97 return false;
Bo Xufdc00a72014-10-28 23:03:33 -070098
Nico Weber9d8ec5a2015-08-04 13:00:21 -070099 CPDF_Dictionary* pRoot = pPDFDocument->GetRoot();
Tom Sepez7a73eff2016-02-08 13:39:53 -0800100 if (!pRoot)
101 return false;
102
dsinclair38fd8442016-09-15 10:15:32 -0700103 CPDF_Dictionary* pAcroForm = pRoot->GetDictFor("AcroForm");
Tom Sepez7a73eff2016-02-08 13:39:53 -0800104 if (!pAcroForm)
105 return false;
106
dsinclair38fd8442016-09-15 10:15:32 -0700107 CPDF_Object* pXFA = pAcroForm->GetObjectFor("XFA");
Tom Sepez7a73eff2016-02-08 13:39:53 -0800108 if (!pXFA)
109 return true;
110
thestigb8bf55f2016-05-21 21:08:05 -0700111 CPDF_Array* pArray = pXFA->AsArray();
Tom Sepez7a73eff2016-02-08 13:39:53 -0800112 if (!pArray)
113 return false;
114
Nico Weber9d8ec5a2015-08-04 13:00:21 -0700115 int size = pArray->GetCount();
116 int iFormIndex = -1;
117 int iDataSetsIndex = -1;
118 int iTemplate = -1;
119 int iLast = size - 2;
120 for (int i = 0; i < size - 1; i++) {
tsepezbd567552016-03-29 14:51:50 -0700121 CPDF_Object* pPDFObj = pArray->GetObjectAt(i);
Tom Sepez8e5cd192016-01-26 13:20:26 -0800122 if (!pPDFObj->IsString())
Nico Weber9d8ec5a2015-08-04 13:00:21 -0700123 continue;
124 if (pPDFObj->GetString() == "form")
125 iFormIndex = i + 1;
126 else if (pPDFObj->GetString() == "datasets")
127 iDataSetsIndex = i + 1;
Lei Zhangd983b092015-12-14 16:58:33 -0800128 else if (pPDFObj->GetString() == "template")
Nico Weber9d8ec5a2015-08-04 13:00:21 -0700129 iTemplate = i + 1;
130 }
tsepez501e8cd2016-05-18 11:39:15 -0700131 std::unique_ptr<CXFA_ChecksumContext> pContext(new CXFA_ChecksumContext);
Nico Weber9d8ec5a2015-08-04 13:00:21 -0700132 pContext->StartChecksum();
Lei Zhanga6d9f0e2015-06-13 00:48:38 -0700133
Nico Weber9d8ec5a2015-08-04 13:00:21 -0700134 // template
135 if (iTemplate > -1) {
Wei Li9b761132016-01-29 15:44:20 -0800136 CPDF_Stream* pTemplateStream = pArray->GetStreamAt(iTemplate);
Nico Weber9d8ec5a2015-08-04 13:00:21 -0700137 CPDF_StreamAcc streamAcc;
138 streamAcc.LoadAllData(pTemplateStream);
139 uint8_t* pData = (uint8_t*)streamAcc.GetData();
tsepezc3255f52016-03-25 14:52:27 -0700140 uint32_t dwSize2 = streamAcc.GetSize();
Tom Sepez7a73eff2016-02-08 13:39:53 -0800141 ScopedFileStream pTemplate(FX_CreateMemoryStream(pData, dwSize2));
142 pContext->UpdateChecksum(pTemplate.get());
Nico Weber9d8ec5a2015-08-04 13:00:21 -0700143 }
thestig1cd352e2016-06-07 17:53:06 -0700144 CPDF_Stream* pFormStream = nullptr;
145 CPDF_Stream* pDataSetsStream = nullptr;
Nico Weber9d8ec5a2015-08-04 13:00:21 -0700146 if (iFormIndex != -1) {
147 // Get form CPDF_Stream
tsepezbd567552016-03-29 14:51:50 -0700148 CPDF_Object* pFormPDFObj = pArray->GetObjectAt(iFormIndex);
Tom Sepez8e5cd192016-01-26 13:20:26 -0800149 if (pFormPDFObj->IsReference()) {
150 CPDF_Object* pFormDirectObj = pFormPDFObj->GetDirect();
151 if (pFormDirectObj && pFormDirectObj->IsStream()) {
152 pFormStream = (CPDF_Stream*)pFormDirectObj;
Nico Weber9d8ec5a2015-08-04 13:00:21 -0700153 }
Tom Sepez8e5cd192016-01-26 13:20:26 -0800154 } else if (pFormPDFObj->IsStream()) {
Nico Weber9d8ec5a2015-08-04 13:00:21 -0700155 pFormStream = (CPDF_Stream*)pFormPDFObj;
Tom Sepez2f2ffec2015-07-23 14:42:09 -0700156 }
Nico Weber9d8ec5a2015-08-04 13:00:21 -0700157 }
Lei Zhanga6d9f0e2015-06-13 00:48:38 -0700158
Nico Weber9d8ec5a2015-08-04 13:00:21 -0700159 if (iDataSetsIndex != -1) {
160 // Get datasets CPDF_Stream
tsepezbd567552016-03-29 14:51:50 -0700161 CPDF_Object* pDataSetsPDFObj = pArray->GetObjectAt(iDataSetsIndex);
Tom Sepez8e5cd192016-01-26 13:20:26 -0800162 if (pDataSetsPDFObj->IsReference()) {
Nico Weber9d8ec5a2015-08-04 13:00:21 -0700163 CPDF_Reference* pDataSetsRefObj = (CPDF_Reference*)pDataSetsPDFObj;
Tom Sepez8e5cd192016-01-26 13:20:26 -0800164 CPDF_Object* pDataSetsDirectObj = pDataSetsRefObj->GetDirect();
165 if (pDataSetsDirectObj && pDataSetsDirectObj->IsStream()) {
166 pDataSetsStream = (CPDF_Stream*)pDataSetsDirectObj;
Nico Weber9d8ec5a2015-08-04 13:00:21 -0700167 }
Tom Sepez8e5cd192016-01-26 13:20:26 -0800168 } else if (pDataSetsPDFObj->IsStream()) {
Nico Weber9d8ec5a2015-08-04 13:00:21 -0700169 pDataSetsStream = (CPDF_Stream*)pDataSetsPDFObj;
Tom Sepez2f2ffec2015-07-23 14:42:09 -0700170 }
Nico Weber9d8ec5a2015-08-04 13:00:21 -0700171 }
Nico Weber9d8ec5a2015-08-04 13:00:21 -0700172 // L"datasets"
173 {
Tom Sepez7a73eff2016-02-08 13:39:53 -0800174 ScopedFileStream pDsfileWrite(FX_CreateMemoryStream());
dsinclaircbfef572016-05-18 13:16:12 -0700175 if (pXFADocView->GetDoc()->SavePackage(XFA_HASHCODE_Datasets,
176 pDsfileWrite.get(), nullptr) &&
Nico Weber9d8ec5a2015-08-04 13:00:21 -0700177 pDsfileWrite->GetSize() > 0) {
Nico Weber9d8ec5a2015-08-04 13:00:21 -0700178 // Datasets
Tom Sepez7a73eff2016-02-08 13:39:53 -0800179 pContext->UpdateChecksum(pDsfileWrite.get());
Nico Weber9d8ec5a2015-08-04 13:00:21 -0700180 pContext->FinishChecksum();
Tom Sepezae51c812015-08-05 12:34:06 -0700181 CPDF_Dictionary* pDataDict = new CPDF_Dictionary;
Nico Weber9d8ec5a2015-08-04 13:00:21 -0700182 if (iDataSetsIndex != -1) {
183 if (pDataSetsStream)
Tom Sepez7a73eff2016-02-08 13:39:53 -0800184 pDataSetsStream->InitStreamFromFile(pDsfileWrite.get(), pDataDict);
Nico Weber9d8ec5a2015-08-04 13:00:21 -0700185 } else {
tsepeze6db16e2016-09-19 10:45:09 -0700186 CPDF_Stream* pData = new CPDF_Stream;
Tom Sepez7a73eff2016-02-08 13:39:53 -0800187 pData->InitStreamFromFile(pDsfileWrite.get(), pDataDict);
Tom Sepez3343d142015-11-02 09:54:54 -0800188 iLast = pArray->GetCount() - 2;
Lei Zhang4880d1a2015-12-18 17:05:11 -0800189 pArray->InsertAt(iLast, new CPDF_String("datasets", FALSE));
tsepezbb577af2016-09-21 19:10:19 -0700190 pArray->InsertAt(
191 iLast + 1,
192 new CPDF_Reference(pPDFDocument,
193 pPDFDocument->AddIndirectObject(pData)));
Nico Weber9d8ec5a2015-08-04 13:00:21 -0700194 }
Tom Sepez7a73eff2016-02-08 13:39:53 -0800195 fileList->push_back(std::move(pDsfileWrite));
Nico Weber9d8ec5a2015-08-04 13:00:21 -0700196 }
197 }
Nico Weber9d8ec5a2015-08-04 13:00:21 -0700198 // L"form"
199 {
Tom Sepez7a73eff2016-02-08 13:39:53 -0800200 ScopedFileStream pfileWrite(FX_CreateMemoryStream());
dsinclaircbfef572016-05-18 13:16:12 -0700201 if (pXFADocView->GetDoc()->SavePackage(XFA_HASHCODE_Form, pfileWrite.get(),
202 pContext.get()) &&
Tom Sepez7a73eff2016-02-08 13:39:53 -0800203 pfileWrite->GetSize() > 0) {
Tom Sepezae51c812015-08-05 12:34:06 -0700204 CPDF_Dictionary* pDataDict = new CPDF_Dictionary;
Nico Weber9d8ec5a2015-08-04 13:00:21 -0700205 if (iFormIndex != -1) {
206 if (pFormStream)
Tom Sepez7a73eff2016-02-08 13:39:53 -0800207 pFormStream->InitStreamFromFile(pfileWrite.get(), pDataDict);
Nico Weber9d8ec5a2015-08-04 13:00:21 -0700208 } else {
tsepeze6db16e2016-09-19 10:45:09 -0700209 CPDF_Stream* pData = new CPDF_Stream;
Tom Sepez7a73eff2016-02-08 13:39:53 -0800210 pData->InitStreamFromFile(pfileWrite.get(), pDataDict);
Tom Sepez3343d142015-11-02 09:54:54 -0800211 iLast = pArray->GetCount() - 2;
Lei Zhang4880d1a2015-12-18 17:05:11 -0800212 pArray->InsertAt(iLast, new CPDF_String("form", FALSE));
tsepezbb577af2016-09-21 19:10:19 -0700213 pArray->InsertAt(
214 iLast + 1,
215 new CPDF_Reference(pPDFDocument,
216 pPDFDocument->AddIndirectObject(pData)));
Nico Weber9d8ec5a2015-08-04 13:00:21 -0700217 }
Tom Sepez7a73eff2016-02-08 13:39:53 -0800218 fileList->push_back(std::move(pfileWrite));
Tom Sepez2f2ffec2015-07-23 14:42:09 -0700219 }
Nico Weber9d8ec5a2015-08-04 13:00:21 -0700220 }
Tom Sepez7a73eff2016-02-08 13:39:53 -0800221 return true;
Nico Weber9d8ec5a2015-08-04 13:00:21 -0700222}
223
Tom Sepez7a73eff2016-02-08 13:39:53 -0800224bool SendPostSaveToXFADoc(CPDFXFA_Document* pDocument) {
Nico Weber9d8ec5a2015-08-04 13:00:21 -0700225 if (!pDocument)
Tom Sepez7a73eff2016-02-08 13:39:53 -0800226 return false;
Nico Weber9d8ec5a2015-08-04 13:00:21 -0700227
Tom Sepezd3116dc2015-11-24 15:58:06 -0800228 if (pDocument->GetDocType() != DOCTYPE_DYNAMIC_XFA &&
Nico Weber9d8ec5a2015-08-04 13:00:21 -0700229 pDocument->GetDocType() != DOCTYPE_STATIC_XFA)
Tom Sepez7a73eff2016-02-08 13:39:53 -0800230 return true;
Nico Weber9d8ec5a2015-08-04 13:00:21 -0700231
dsinclairdf4bc592016-03-31 20:34:43 -0700232 CXFA_FFDocView* pXFADocView = pDocument->GetXFADocView();
Tom Sepez7a73eff2016-02-08 13:39:53 -0800233 if (!pXFADocView)
234 return false;
Nico Weber9d8ec5a2015-08-04 13:00:21 -0700235
dsinclairdf4bc592016-03-31 20:34:43 -0700236 CXFA_FFWidgetHandler* pWidgetHander = pXFADocView->GetWidgetHandler();
tsepeze7b28532016-05-18 12:10:49 -0700237 std::unique_ptr<CXFA_WidgetAccIterator> pWidgetAccIterator(
238 pXFADocView->CreateWidgetAccIterator());
239 while (CXFA_WidgetAcc* pWidgetAcc = pWidgetAccIterator->MoveToNext()) {
Nico Weber9d8ec5a2015-08-04 13:00:21 -0700240 CXFA_EventParam preParam;
241 preParam.m_eType = XFA_EVENT_PostSave;
242 pWidgetHander->ProcessEvent(pWidgetAcc, &preParam);
Nico Weber9d8ec5a2015-08-04 13:00:21 -0700243 }
Nico Weber9d8ec5a2015-08-04 13:00:21 -0700244 pXFADocView->UpdateDocView();
dsinclair89f8fa82016-09-14 06:11:08 -0700245 pDocument->ClearChangeMark();
Tom Sepez7a73eff2016-02-08 13:39:53 -0800246 return true;
Bo Xufdc00a72014-10-28 23:03:33 -0700247}
248
Tom Sepez7a73eff2016-02-08 13:39:53 -0800249bool SendPreSaveToXFADoc(CPDFXFA_Document* pDocument,
250 std::vector<ScopedFileStream>* fileList) {
Tom Sepezd3116dc2015-11-24 15:58:06 -0800251 if (pDocument->GetDocType() != DOCTYPE_DYNAMIC_XFA &&
Nico Weber9d8ec5a2015-08-04 13:00:21 -0700252 pDocument->GetDocType() != DOCTYPE_STATIC_XFA)
Tom Sepez7a73eff2016-02-08 13:39:53 -0800253 return true;
254
dsinclairdf4bc592016-03-31 20:34:43 -0700255 CXFA_FFDocView* pXFADocView = pDocument->GetXFADocView();
Tom Sepez7a73eff2016-02-08 13:39:53 -0800256 if (!pXFADocView)
257 return true;
258
dsinclairdf4bc592016-03-31 20:34:43 -0700259 CXFA_FFWidgetHandler* pWidgetHander = pXFADocView->GetWidgetHandler();
tsepeze7b28532016-05-18 12:10:49 -0700260 std::unique_ptr<CXFA_WidgetAccIterator> pWidgetAccIterator(
261 pXFADocView->CreateWidgetAccIterator());
262 while (CXFA_WidgetAcc* pWidgetAcc = pWidgetAccIterator->MoveToNext()) {
Nico Weber9d8ec5a2015-08-04 13:00:21 -0700263 CXFA_EventParam preParam;
264 preParam.m_eType = XFA_EVENT_PreSave;
265 pWidgetHander->ProcessEvent(pWidgetAcc, &preParam);
Nico Weber9d8ec5a2015-08-04 13:00:21 -0700266 }
Nico Weber9d8ec5a2015-08-04 13:00:21 -0700267 pXFADocView->UpdateDocView();
Tom Sepez7a73eff2016-02-08 13:39:53 -0800268 return SaveXFADocumentData(pDocument, fileList);
Bo Xufdc00a72014-10-28 23:03:33 -0700269}
Tom Sepez40e9ff32015-11-30 12:39:54 -0800270#endif // PDF_ENABLE_XFA
Bo Xufdc00a72014-10-28 23:03:33 -0700271
Tom Sepez7a73eff2016-02-08 13:39:53 -0800272bool FPDF_Doc_Save(FPDF_DOCUMENT document,
273 FPDF_FILEWRITE* pFileWrite,
274 FPDF_DWORD flags,
275 FPDF_BOOL bSetVersion,
276 int fileVerion) {
Tom Sepez1b246282015-11-25 15:15:31 -0800277 CPDF_Document* pPDFDoc = CPDFDocumentFromFPDFDocument(document);
Nico Weber9d8ec5a2015-08-04 13:00:21 -0700278 if (!pPDFDoc)
279 return 0;
Lei Zhanga6d9f0e2015-06-13 00:48:38 -0700280
Tom Sepez51da0932015-11-25 16:05:49 -0800281#ifdef PDF_ENABLE_XFA
Tom Sepez7a73eff2016-02-08 13:39:53 -0800282 CPDFXFA_Document* pDoc = static_cast<CPDFXFA_Document*>(document);
283 std::vector<ScopedFileStream> fileList;
284 SendPreSaveToXFADoc(pDoc, &fileList);
Tom Sepez40e9ff32015-11-30 12:39:54 -0800285#endif // PDF_ENABLE_XFA
Tom Sepez1b246282015-11-25 15:15:31 -0800286
Tom Sepez7a73eff2016-02-08 13:39:53 -0800287 if (flags < FPDF_INCREMENTAL || flags > FPDF_REMOVE_SECURITY)
Nico Weber9d8ec5a2015-08-04 13:00:21 -0700288 flags = 0;
Lei Zhanga6d9f0e2015-06-13 00:48:38 -0700289
Nico Weber9d8ec5a2015-08-04 13:00:21 -0700290 CPDF_Creator FileMaker(pPDFDoc);
291 if (bSetVersion)
292 FileMaker.SetFileVersion(fileVerion);
293 if (flags == FPDF_REMOVE_SECURITY) {
294 flags = 0;
295 FileMaker.RemoveSecurity();
296 }
Tom Sepez1b246282015-11-25 15:15:31 -0800297
thestig1cd352e2016-06-07 17:53:06 -0700298 CFX_IFileWrite* pStreamWrite = new CFX_IFileWrite;
Nico Weber9d8ec5a2015-08-04 13:00:21 -0700299 pStreamWrite->Init(pFileWrite);
Wei Li97da9762016-03-11 17:00:48 -0800300 bool bRet = FileMaker.Create(pStreamWrite, flags);
Tom Sepez51da0932015-11-25 16:05:49 -0800301#ifdef PDF_ENABLE_XFA
Tom Sepez7a73eff2016-02-08 13:39:53 -0800302 SendPostSaveToXFADoc(pDoc);
Tom Sepez40e9ff32015-11-30 12:39:54 -0800303#endif // PDF_ENABLE_XFA
Lei Zhang2b1a2d52015-08-14 22:16:22 -0700304 pStreamWrite->Release();
Nico Weber9d8ec5a2015-08-04 13:00:21 -0700305 return bRet;
John Abd-El-Malek3f3b45c2014-05-23 17:28:10 -0700306}
307
Tom Sepez7a73eff2016-02-08 13:39:53 -0800308} // namespace
309
Nico Weber9d8ec5a2015-08-04 13:00:21 -0700310DLLEXPORT FPDF_BOOL STDCALL FPDF_SaveAsCopy(FPDF_DOCUMENT document,
311 FPDF_FILEWRITE* pFileWrite,
312 FPDF_DWORD flags) {
Tom Sepez7a73eff2016-02-08 13:39:53 -0800313 return FPDF_Doc_Save(document, pFileWrite, flags, FALSE, 0);
John Abd-El-Malek3f3b45c2014-05-23 17:28:10 -0700314}
315
Nico Weber9d8ec5a2015-08-04 13:00:21 -0700316DLLEXPORT FPDF_BOOL STDCALL FPDF_SaveWithVersion(FPDF_DOCUMENT document,
317 FPDF_FILEWRITE* pFileWrite,
318 FPDF_DWORD flags,
319 int fileVersion) {
Tom Sepez7a73eff2016-02-08 13:39:53 -0800320 return FPDF_Doc_Save(document, pFileWrite, flags, TRUE, fileVersion);
John Abd-El-Malek3f3b45c2014-05-23 17:28:10 -0700321}