blob: 257f1fc0fc5fd13210a8301649c0a2528d5f746e [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
dsinclair24154352016-10-04 11:01:48 -070011#include "core/fpdfapi/edit/cpdf_creator.h"
dsinclair488b7ad2016-10-04 11:55:50 -070012#include "core/fpdfapi/parser/cpdf_array.h"
13#include "core/fpdfapi/parser/cpdf_document.h"
14#include "core/fpdfapi/parser/cpdf_reference.h"
15#include "core/fpdfapi/parser/cpdf_stream_acc.h"
16#include "core/fpdfapi/parser/cpdf_string.h"
dsinclaira52ab742016-09-29 13:59:29 -070017#include "core/fxcrt/fx_ext.h"
dsinclair114e46a2016-09-29 17:18:21 -070018#include "fpdfsdk/fsdk_define.h"
Tom Sepez40e9ff32015-11-30 12:39:54 -080019#include "public/fpdf_edit.h"
20
Tom Sepez51da0932015-11-25 16:05:49 -080021#ifdef PDF_ENABLE_XFA
dsinclair521b7502016-11-02 13:02:28 -070022#include "fpdfsdk/fpdfxfa/cpdfxfa_context.h"
dsinclair4d29e782016-10-04 14:02:47 -070023#include "fpdfsdk/fpdfxfa/cxfa_fwladaptertimermgr.h"
Lei Zhangb4e7f302015-11-06 15:52:32 -080024#include "public/fpdf_formfill.h"
dsinclair5b493092016-09-29 20:20:24 -070025#include "xfa/fxfa/cxfa_eventparam.h"
26#include "xfa/fxfa/xfa_checksum.h"
27#include "xfa/fxfa/xfa_ffapp.h"
28#include "xfa/fxfa/xfa_ffdocview.h"
29#include "xfa/fxfa/xfa_ffwidgethandler.h"
Tom Sepez51da0932015-11-25 16:05:49 -080030#endif
Tom Sepez1ed8a212015-05-11 15:25:39 -070031
John Abd-El-Malek3f3b45c2014-05-23 17:28:10 -070032#if _FX_OS_ == _FX_ANDROID_
33#include "time.h"
34#else
35#include <ctime>
36#endif
37
tsepezad2441e2016-10-24 10:19:11 -070038class CFX_IFileWrite final : public IFX_WriteStream {
Nico Weber9d8ec5a2015-08-04 13:00:21 -070039 public:
40 CFX_IFileWrite();
tsepezf39074c2016-10-26 15:33:58 -070041 bool Init(FPDF_FILEWRITE* pFileWriteStruct);
42 bool WriteBlock(const void* pData, size_t size) override;
Lei Zhang2b1a2d52015-08-14 22:16:22 -070043 void Release() override;
Lei Zhanga6d9f0e2015-06-13 00:48:38 -070044
Nico Weber9d8ec5a2015-08-04 13:00:21 -070045 protected:
Lei Zhang2b1a2d52015-08-14 22:16:22 -070046 ~CFX_IFileWrite() override {}
47
Nico Weber9d8ec5a2015-08-04 13:00:21 -070048 FPDF_FILEWRITE* m_pFileWriteStruct;
John Abd-El-Malek3f3b45c2014-05-23 17:28:10 -070049};
50
Nico Weber9d8ec5a2015-08-04 13:00:21 -070051CFX_IFileWrite::CFX_IFileWrite() {
thestig1cd352e2016-06-07 17:53:06 -070052 m_pFileWriteStruct = nullptr;
John Abd-El-Malek3f3b45c2014-05-23 17:28:10 -070053}
54
tsepezf39074c2016-10-26 15:33:58 -070055bool CFX_IFileWrite::Init(FPDF_FILEWRITE* pFileWriteStruct) {
Nico Weber9d8ec5a2015-08-04 13:00:21 -070056 if (!pFileWriteStruct)
tsepezf39074c2016-10-26 15:33:58 -070057 return false;
Tom Sepez2f2ffec2015-07-23 14:42:09 -070058
Nico Weber9d8ec5a2015-08-04 13:00:21 -070059 m_pFileWriteStruct = pFileWriteStruct;
tsepezf39074c2016-10-26 15:33:58 -070060 return true;
Nico Weber9d8ec5a2015-08-04 13:00:21 -070061}
62
tsepezf39074c2016-10-26 15:33:58 -070063bool CFX_IFileWrite::WriteBlock(const void* pData, size_t size) {
Nico Weber9d8ec5a2015-08-04 13:00:21 -070064 if (!m_pFileWriteStruct)
tsepezf39074c2016-10-26 15:33:58 -070065 return false;
Nico Weber9d8ec5a2015-08-04 13:00:21 -070066
67 m_pFileWriteStruct->WriteBlock(m_pFileWriteStruct, pData, size);
tsepezf39074c2016-10-26 15:33:58 -070068 return true;
Nico Weber9d8ec5a2015-08-04 13:00:21 -070069}
70
Lei Zhang2b1a2d52015-08-14 22:16:22 -070071void CFX_IFileWrite::Release() {
72 delete this;
73}
74
Tom Sepez7a73eff2016-02-08 13:39:53 -080075namespace {
76
Tom Sepez51da0932015-11-25 16:05:49 -080077#ifdef PDF_ENABLE_XFA
dsinclair521b7502016-11-02 13:02:28 -070078bool SaveXFADocumentData(CPDFXFA_Context* pContext,
Tom Sepez7a73eff2016-02-08 13:39:53 -080079 std::vector<ScopedFileStream>* fileList) {
dsinclair521b7502016-11-02 13:02:28 -070080 if (!pContext)
Tom Sepez7a73eff2016-02-08 13:39:53 -080081 return false;
82
dsinclair521b7502016-11-02 13:02:28 -070083 if (pContext->GetDocType() != DOCTYPE_DYNAMIC_XFA &&
84 pContext->GetDocType() != DOCTYPE_STATIC_XFA)
Tom Sepez7a73eff2016-02-08 13:39:53 -080085 return true;
86
dsinclair521b7502016-11-02 13:02:28 -070087 CXFA_FFDocView* pXFADocView = pContext->GetXFADocView();
Tom Sepez7a73eff2016-02-08 13:39:53 -080088 if (!pXFADocView)
89 return true;
Bo Xufdc00a72014-10-28 23:03:33 -070090
dsinclair521b7502016-11-02 13:02:28 -070091 CPDF_Document* pPDFDocument = pContext->GetPDFDoc();
92 if (!pPDFDocument)
Tom Sepez7a73eff2016-02-08 13:39:53 -080093 return false;
Bo Xufdc00a72014-10-28 23:03:33 -070094
Nico Weber9d8ec5a2015-08-04 13:00:21 -070095 CPDF_Dictionary* pRoot = pPDFDocument->GetRoot();
Tom Sepez7a73eff2016-02-08 13:39:53 -080096 if (!pRoot)
97 return false;
98
dsinclair38fd8442016-09-15 10:15:32 -070099 CPDF_Dictionary* pAcroForm = pRoot->GetDictFor("AcroForm");
Tom Sepez7a73eff2016-02-08 13:39:53 -0800100 if (!pAcroForm)
101 return false;
102
dsinclair38fd8442016-09-15 10:15:32 -0700103 CPDF_Object* pXFA = pAcroForm->GetObjectFor("XFA");
Tom Sepez7a73eff2016-02-08 13:39:53 -0800104 if (!pXFA)
105 return true;
106
thestigb8bf55f2016-05-21 21:08:05 -0700107 CPDF_Array* pArray = pXFA->AsArray();
Tom Sepez7a73eff2016-02-08 13:39:53 -0800108 if (!pArray)
109 return false;
110
Nico Weber9d8ec5a2015-08-04 13:00:21 -0700111 int size = pArray->GetCount();
112 int iFormIndex = -1;
113 int iDataSetsIndex = -1;
114 int iTemplate = -1;
115 int iLast = size - 2;
116 for (int i = 0; i < size - 1; i++) {
tsepezbd567552016-03-29 14:51:50 -0700117 CPDF_Object* pPDFObj = pArray->GetObjectAt(i);
Tom Sepez8e5cd192016-01-26 13:20:26 -0800118 if (!pPDFObj->IsString())
Nico Weber9d8ec5a2015-08-04 13:00:21 -0700119 continue;
120 if (pPDFObj->GetString() == "form")
121 iFormIndex = i + 1;
122 else if (pPDFObj->GetString() == "datasets")
123 iDataSetsIndex = i + 1;
Lei Zhangd983b092015-12-14 16:58:33 -0800124 else if (pPDFObj->GetString() == "template")
Nico Weber9d8ec5a2015-08-04 13:00:21 -0700125 iTemplate = i + 1;
126 }
dsinclair521b7502016-11-02 13:02:28 -0700127 std::unique_ptr<CXFA_ChecksumContext> pChecksum(new CXFA_ChecksumContext);
128 pChecksum->StartChecksum();
Lei Zhanga6d9f0e2015-06-13 00:48:38 -0700129
Nico Weber9d8ec5a2015-08-04 13:00:21 -0700130 // template
131 if (iTemplate > -1) {
Wei Li9b761132016-01-29 15:44:20 -0800132 CPDF_Stream* pTemplateStream = pArray->GetStreamAt(iTemplate);
Nico Weber9d8ec5a2015-08-04 13:00:21 -0700133 CPDF_StreamAcc streamAcc;
134 streamAcc.LoadAllData(pTemplateStream);
135 uint8_t* pData = (uint8_t*)streamAcc.GetData();
tsepezc3255f52016-03-25 14:52:27 -0700136 uint32_t dwSize2 = streamAcc.GetSize();
Tom Sepez7a73eff2016-02-08 13:39:53 -0800137 ScopedFileStream pTemplate(FX_CreateMemoryStream(pData, dwSize2));
dsinclair521b7502016-11-02 13:02:28 -0700138 pChecksum->UpdateChecksum(pTemplate.get());
Nico Weber9d8ec5a2015-08-04 13:00:21 -0700139 }
thestig1cd352e2016-06-07 17:53:06 -0700140 CPDF_Stream* pFormStream = nullptr;
141 CPDF_Stream* pDataSetsStream = nullptr;
Nico Weber9d8ec5a2015-08-04 13:00:21 -0700142 if (iFormIndex != -1) {
143 // Get form CPDF_Stream
tsepezbd567552016-03-29 14:51:50 -0700144 CPDF_Object* pFormPDFObj = pArray->GetObjectAt(iFormIndex);
Tom Sepez8e5cd192016-01-26 13:20:26 -0800145 if (pFormPDFObj->IsReference()) {
146 CPDF_Object* pFormDirectObj = pFormPDFObj->GetDirect();
147 if (pFormDirectObj && pFormDirectObj->IsStream()) {
148 pFormStream = (CPDF_Stream*)pFormDirectObj;
Nico Weber9d8ec5a2015-08-04 13:00:21 -0700149 }
Tom Sepez8e5cd192016-01-26 13:20:26 -0800150 } else if (pFormPDFObj->IsStream()) {
Nico Weber9d8ec5a2015-08-04 13:00:21 -0700151 pFormStream = (CPDF_Stream*)pFormPDFObj;
Tom Sepez2f2ffec2015-07-23 14:42:09 -0700152 }
Nico Weber9d8ec5a2015-08-04 13:00:21 -0700153 }
Lei Zhanga6d9f0e2015-06-13 00:48:38 -0700154
Nico Weber9d8ec5a2015-08-04 13:00:21 -0700155 if (iDataSetsIndex != -1) {
156 // Get datasets CPDF_Stream
tsepezbd567552016-03-29 14:51:50 -0700157 CPDF_Object* pDataSetsPDFObj = pArray->GetObjectAt(iDataSetsIndex);
Tom Sepez8e5cd192016-01-26 13:20:26 -0800158 if (pDataSetsPDFObj->IsReference()) {
Nico Weber9d8ec5a2015-08-04 13:00:21 -0700159 CPDF_Reference* pDataSetsRefObj = (CPDF_Reference*)pDataSetsPDFObj;
Tom Sepez8e5cd192016-01-26 13:20:26 -0800160 CPDF_Object* pDataSetsDirectObj = pDataSetsRefObj->GetDirect();
161 if (pDataSetsDirectObj && pDataSetsDirectObj->IsStream()) {
162 pDataSetsStream = (CPDF_Stream*)pDataSetsDirectObj;
Nico Weber9d8ec5a2015-08-04 13:00:21 -0700163 }
Tom Sepez8e5cd192016-01-26 13:20:26 -0800164 } else if (pDataSetsPDFObj->IsStream()) {
Nico Weber9d8ec5a2015-08-04 13:00:21 -0700165 pDataSetsStream = (CPDF_Stream*)pDataSetsPDFObj;
Tom Sepez2f2ffec2015-07-23 14:42:09 -0700166 }
Nico Weber9d8ec5a2015-08-04 13:00:21 -0700167 }
Nico Weber9d8ec5a2015-08-04 13:00:21 -0700168 // L"datasets"
169 {
Tom Sepez7a73eff2016-02-08 13:39:53 -0800170 ScopedFileStream pDsfileWrite(FX_CreateMemoryStream());
dsinclaircbfef572016-05-18 13:16:12 -0700171 if (pXFADocView->GetDoc()->SavePackage(XFA_HASHCODE_Datasets,
172 pDsfileWrite.get(), nullptr) &&
Nico Weber9d8ec5a2015-08-04 13:00:21 -0700173 pDsfileWrite->GetSize() > 0) {
Nico Weber9d8ec5a2015-08-04 13:00:21 -0700174 // Datasets
dsinclair521b7502016-11-02 13:02:28 -0700175 pChecksum->UpdateChecksum(pDsfileWrite.get());
176 pChecksum->FinishChecksum();
tsepez698c5712016-09-28 16:47:07 -0700177 CPDF_Dictionary* pDataDict =
178 new CPDF_Dictionary(pPDFDocument->GetByteStringPool());
Nico Weber9d8ec5a2015-08-04 13:00:21 -0700179 if (iDataSetsIndex != -1) {
180 if (pDataSetsStream)
Tom Sepez7a73eff2016-02-08 13:39:53 -0800181 pDataSetsStream->InitStreamFromFile(pDsfileWrite.get(), pDataDict);
Nico Weber9d8ec5a2015-08-04 13:00:21 -0700182 } else {
Tom Sepezc25a4212016-10-14 17:45:56 -0700183 CPDF_Stream* pData = new CPDF_Stream;
Tom Sepez7a73eff2016-02-08 13:39:53 -0800184 pData->InitStreamFromFile(pDsfileWrite.get(), pDataDict);
Tom Sepez3343d142015-11-02 09:54:54 -0800185 iLast = pArray->GetCount() - 2;
Tom Sepezc25a4212016-10-14 17:45:56 -0700186 pArray->InsertAt(iLast, new CPDF_String("datasets", FALSE));
187 pArray->InsertAt(
188 iLast + 1,
189 new CPDF_Reference(pPDFDocument,
190 pPDFDocument->AddIndirectObject(pData)));
Nico Weber9d8ec5a2015-08-04 13:00:21 -0700191 }
Tom Sepez7a73eff2016-02-08 13:39:53 -0800192 fileList->push_back(std::move(pDsfileWrite));
Nico Weber9d8ec5a2015-08-04 13:00:21 -0700193 }
194 }
Nico Weber9d8ec5a2015-08-04 13:00:21 -0700195 // L"form"
196 {
Tom Sepez7a73eff2016-02-08 13:39:53 -0800197 ScopedFileStream pfileWrite(FX_CreateMemoryStream());
dsinclaircbfef572016-05-18 13:16:12 -0700198 if (pXFADocView->GetDoc()->SavePackage(XFA_HASHCODE_Form, pfileWrite.get(),
dsinclair521b7502016-11-02 13:02:28 -0700199 pChecksum.get()) &&
Tom Sepez7a73eff2016-02-08 13:39:53 -0800200 pfileWrite->GetSize() > 0) {
tsepez698c5712016-09-28 16:47:07 -0700201 CPDF_Dictionary* pDataDict =
202 new CPDF_Dictionary(pPDFDocument->GetByteStringPool());
Nico Weber9d8ec5a2015-08-04 13:00:21 -0700203 if (iFormIndex != -1) {
204 if (pFormStream)
Tom Sepez7a73eff2016-02-08 13:39:53 -0800205 pFormStream->InitStreamFromFile(pfileWrite.get(), pDataDict);
Nico Weber9d8ec5a2015-08-04 13:00:21 -0700206 } else {
Tom Sepezc25a4212016-10-14 17:45:56 -0700207 CPDF_Stream* pData = new CPDF_Stream;
Tom Sepez7a73eff2016-02-08 13:39:53 -0800208 pData->InitStreamFromFile(pfileWrite.get(), pDataDict);
Tom Sepez3343d142015-11-02 09:54:54 -0800209 iLast = pArray->GetCount() - 2;
Lei Zhang4880d1a2015-12-18 17:05:11 -0800210 pArray->InsertAt(iLast, new CPDF_String("form", FALSE));
Tom Sepezc25a4212016-10-14 17:45:56 -0700211 pArray->InsertAt(
212 iLast + 1,
213 new CPDF_Reference(pPDFDocument,
214 pPDFDocument->AddIndirectObject(pData)));
Nico Weber9d8ec5a2015-08-04 13:00:21 -0700215 }
Tom Sepez7a73eff2016-02-08 13:39:53 -0800216 fileList->push_back(std::move(pfileWrite));
Tom Sepez2f2ffec2015-07-23 14:42:09 -0700217 }
Nico Weber9d8ec5a2015-08-04 13:00:21 -0700218 }
Tom Sepez7a73eff2016-02-08 13:39:53 -0800219 return true;
Nico Weber9d8ec5a2015-08-04 13:00:21 -0700220}
221
dsinclair521b7502016-11-02 13:02:28 -0700222bool SendPostSaveToXFADoc(CPDFXFA_Context* pContext) {
223 if (!pContext)
Tom Sepez7a73eff2016-02-08 13:39:53 -0800224 return false;
Nico Weber9d8ec5a2015-08-04 13:00:21 -0700225
dsinclair521b7502016-11-02 13:02:28 -0700226 if (pContext->GetDocType() != DOCTYPE_DYNAMIC_XFA &&
227 pContext->GetDocType() != DOCTYPE_STATIC_XFA)
Tom Sepez7a73eff2016-02-08 13:39:53 -0800228 return true;
Nico Weber9d8ec5a2015-08-04 13:00:21 -0700229
dsinclair521b7502016-11-02 13:02:28 -0700230 CXFA_FFDocView* pXFADocView = pContext->GetXFADocView();
Tom Sepez7a73eff2016-02-08 13:39:53 -0800231 if (!pXFADocView)
232 return false;
Nico Weber9d8ec5a2015-08-04 13:00:21 -0700233
dsinclairdf4bc592016-03-31 20:34:43 -0700234 CXFA_FFWidgetHandler* pWidgetHander = pXFADocView->GetWidgetHandler();
tsepeze7b28532016-05-18 12:10:49 -0700235 std::unique_ptr<CXFA_WidgetAccIterator> pWidgetAccIterator(
236 pXFADocView->CreateWidgetAccIterator());
237 while (CXFA_WidgetAcc* pWidgetAcc = pWidgetAccIterator->MoveToNext()) {
Nico Weber9d8ec5a2015-08-04 13:00:21 -0700238 CXFA_EventParam preParam;
239 preParam.m_eType = XFA_EVENT_PostSave;
240 pWidgetHander->ProcessEvent(pWidgetAcc, &preParam);
Nico Weber9d8ec5a2015-08-04 13:00:21 -0700241 }
Nico Weber9d8ec5a2015-08-04 13:00:21 -0700242 pXFADocView->UpdateDocView();
dsinclair521b7502016-11-02 13:02:28 -0700243 pContext->ClearChangeMark();
Tom Sepez7a73eff2016-02-08 13:39:53 -0800244 return true;
Bo Xufdc00a72014-10-28 23:03:33 -0700245}
246
dsinclair521b7502016-11-02 13:02:28 -0700247bool SendPreSaveToXFADoc(CPDFXFA_Context* pContext,
Tom Sepez7a73eff2016-02-08 13:39:53 -0800248 std::vector<ScopedFileStream>* fileList) {
dsinclair521b7502016-11-02 13:02:28 -0700249 if (pContext->GetDocType() != DOCTYPE_DYNAMIC_XFA &&
250 pContext->GetDocType() != DOCTYPE_STATIC_XFA)
Tom Sepez7a73eff2016-02-08 13:39:53 -0800251 return true;
252
dsinclair521b7502016-11-02 13:02:28 -0700253 CXFA_FFDocView* pXFADocView = pContext->GetXFADocView();
Tom Sepez7a73eff2016-02-08 13:39:53 -0800254 if (!pXFADocView)
255 return true;
256
dsinclairdf4bc592016-03-31 20:34:43 -0700257 CXFA_FFWidgetHandler* pWidgetHander = pXFADocView->GetWidgetHandler();
tsepeze7b28532016-05-18 12:10:49 -0700258 std::unique_ptr<CXFA_WidgetAccIterator> pWidgetAccIterator(
259 pXFADocView->CreateWidgetAccIterator());
260 while (CXFA_WidgetAcc* pWidgetAcc = pWidgetAccIterator->MoveToNext()) {
Nico Weber9d8ec5a2015-08-04 13:00:21 -0700261 CXFA_EventParam preParam;
262 preParam.m_eType = XFA_EVENT_PreSave;
263 pWidgetHander->ProcessEvent(pWidgetAcc, &preParam);
Nico Weber9d8ec5a2015-08-04 13:00:21 -0700264 }
Nico Weber9d8ec5a2015-08-04 13:00:21 -0700265 pXFADocView->UpdateDocView();
dsinclair521b7502016-11-02 13:02:28 -0700266 return SaveXFADocumentData(pContext, fileList);
Bo Xufdc00a72014-10-28 23:03:33 -0700267}
Tom Sepez40e9ff32015-11-30 12:39:54 -0800268#endif // PDF_ENABLE_XFA
Bo Xufdc00a72014-10-28 23:03:33 -0700269
Tom Sepez7a73eff2016-02-08 13:39:53 -0800270bool FPDF_Doc_Save(FPDF_DOCUMENT document,
271 FPDF_FILEWRITE* pFileWrite,
272 FPDF_DWORD flags,
273 FPDF_BOOL bSetVersion,
274 int fileVerion) {
Tom Sepez1b246282015-11-25 15:15:31 -0800275 CPDF_Document* pPDFDoc = CPDFDocumentFromFPDFDocument(document);
Nico Weber9d8ec5a2015-08-04 13:00:21 -0700276 if (!pPDFDoc)
277 return 0;
Lei Zhanga6d9f0e2015-06-13 00:48:38 -0700278
Tom Sepez51da0932015-11-25 16:05:49 -0800279#ifdef PDF_ENABLE_XFA
dsinclair521b7502016-11-02 13:02:28 -0700280 CPDFXFA_Context* pContext = static_cast<CPDFXFA_Context*>(document);
Tom Sepez7a73eff2016-02-08 13:39:53 -0800281 std::vector<ScopedFileStream> fileList;
dsinclair521b7502016-11-02 13:02:28 -0700282 SendPreSaveToXFADoc(pContext, &fileList);
Tom Sepez40e9ff32015-11-30 12:39:54 -0800283#endif // PDF_ENABLE_XFA
Tom Sepez1b246282015-11-25 15:15:31 -0800284
Tom Sepez7a73eff2016-02-08 13:39:53 -0800285 if (flags < FPDF_INCREMENTAL || flags > FPDF_REMOVE_SECURITY)
Nico Weber9d8ec5a2015-08-04 13:00:21 -0700286 flags = 0;
Lei Zhanga6d9f0e2015-06-13 00:48:38 -0700287
Nico Weber9d8ec5a2015-08-04 13:00:21 -0700288 CPDF_Creator FileMaker(pPDFDoc);
289 if (bSetVersion)
290 FileMaker.SetFileVersion(fileVerion);
291 if (flags == FPDF_REMOVE_SECURITY) {
292 flags = 0;
293 FileMaker.RemoveSecurity();
294 }
Tom Sepez1b246282015-11-25 15:15:31 -0800295
thestig1cd352e2016-06-07 17:53:06 -0700296 CFX_IFileWrite* pStreamWrite = new CFX_IFileWrite;
Nico Weber9d8ec5a2015-08-04 13:00:21 -0700297 pStreamWrite->Init(pFileWrite);
Wei Li97da9762016-03-11 17:00:48 -0800298 bool bRet = FileMaker.Create(pStreamWrite, flags);
Tom Sepez51da0932015-11-25 16:05:49 -0800299#ifdef PDF_ENABLE_XFA
dsinclair521b7502016-11-02 13:02:28 -0700300 SendPostSaveToXFADoc(pContext);
Tom Sepez40e9ff32015-11-30 12:39:54 -0800301#endif // PDF_ENABLE_XFA
Lei Zhang2b1a2d52015-08-14 22:16:22 -0700302 pStreamWrite->Release();
Nico Weber9d8ec5a2015-08-04 13:00:21 -0700303 return bRet;
John Abd-El-Malek3f3b45c2014-05-23 17:28:10 -0700304}
305
Tom Sepez7a73eff2016-02-08 13:39:53 -0800306} // namespace
307
Nico Weber9d8ec5a2015-08-04 13:00:21 -0700308DLLEXPORT FPDF_BOOL STDCALL FPDF_SaveAsCopy(FPDF_DOCUMENT document,
309 FPDF_FILEWRITE* pFileWrite,
310 FPDF_DWORD flags) {
Tom Sepez7a73eff2016-02-08 13:39:53 -0800311 return FPDF_Doc_Save(document, pFileWrite, flags, FALSE, 0);
John Abd-El-Malek3f3b45c2014-05-23 17:28:10 -0700312}
313
Nico Weber9d8ec5a2015-08-04 13:00:21 -0700314DLLEXPORT FPDF_BOOL STDCALL FPDF_SaveWithVersion(FPDF_DOCUMENT document,
315 FPDF_FILEWRITE* pFileWrite,
316 FPDF_DWORD flags,
317 int fileVersion) {
Tom Sepez7a73eff2016-02-08 13:39:53 -0800318 return FPDF_Doc_Save(document, pFileWrite, flags, TRUE, fileVersion);
John Abd-El-Malek3f3b45c2014-05-23 17:28:10 -0700319}