blob: bc67cbba239e310cc3bd02878b2c43c8f78e3875 [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 Sinclair85c8e7f2016-11-21 13:50:32 -05009#include <memory>
10#include <utility>
Dan Sinclair3ebd1212016-03-09 09:59:23 -050011#include <vector>
12
dsinclair24154352016-10-04 11:01:48 -070013#include "core/fpdfapi/edit/cpdf_creator.h"
dsinclair488b7ad2016-10-04 11:55:50 -070014#include "core/fpdfapi/parser/cpdf_array.h"
15#include "core/fpdfapi/parser/cpdf_document.h"
16#include "core/fpdfapi/parser/cpdf_reference.h"
17#include "core/fpdfapi/parser/cpdf_stream_acc.h"
18#include "core/fpdfapi/parser/cpdf_string.h"
dsinclaira52ab742016-09-29 13:59:29 -070019#include "core/fxcrt/fx_ext.h"
dsinclair114e46a2016-09-29 17:18:21 -070020#include "fpdfsdk/fsdk_define.h"
Tom Sepez40e9ff32015-11-30 12:39:54 -080021#include "public/fpdf_edit.h"
22
Tom Sepez51da0932015-11-25 16:05:49 -080023#ifdef PDF_ENABLE_XFA
dsinclair521b7502016-11-02 13:02:28 -070024#include "fpdfsdk/fpdfxfa/cpdfxfa_context.h"
dsinclair4d29e782016-10-04 14:02:47 -070025#include "fpdfsdk/fpdfxfa/cxfa_fwladaptertimermgr.h"
Lei Zhangb4e7f302015-11-06 15:52:32 -080026#include "public/fpdf_formfill.h"
dsinclair5b493092016-09-29 20:20:24 -070027#include "xfa/fxfa/cxfa_eventparam.h"
28#include "xfa/fxfa/xfa_checksum.h"
29#include "xfa/fxfa/xfa_ffapp.h"
30#include "xfa/fxfa/xfa_ffdocview.h"
31#include "xfa/fxfa/xfa_ffwidgethandler.h"
Tom Sepez51da0932015-11-25 16:05:49 -080032#endif
Tom Sepez1ed8a212015-05-11 15:25:39 -070033
John Abd-El-Malek3f3b45c2014-05-23 17:28:10 -070034#if _FX_OS_ == _FX_ANDROID_
Dan Sinclair85c8e7f2016-11-21 13:50:32 -050035#include <time.h>
John Abd-El-Malek3f3b45c2014-05-23 17:28:10 -070036#else
37#include <ctime>
38#endif
39
tsepezad2441e2016-10-24 10:19:11 -070040class CFX_IFileWrite final : public IFX_WriteStream {
Nico Weber9d8ec5a2015-08-04 13:00:21 -070041 public:
tsepez833619b2016-12-07 09:21:17 -080042 static CFX_RetainPtr<CFX_IFileWrite> Create();
tsepezf39074c2016-10-26 15:33:58 -070043 bool Init(FPDF_FILEWRITE* pFileWriteStruct);
44 bool WriteBlock(const void* pData, size_t size) override;
Lei Zhanga6d9f0e2015-06-13 00:48:38 -070045
Nico Weber9d8ec5a2015-08-04 13:00:21 -070046 protected:
tsepez833619b2016-12-07 09:21:17 -080047 CFX_IFileWrite();
Lei Zhang2b1a2d52015-08-14 22:16:22 -070048 ~CFX_IFileWrite() override {}
49
Nico Weber9d8ec5a2015-08-04 13:00:21 -070050 FPDF_FILEWRITE* m_pFileWriteStruct;
John Abd-El-Malek3f3b45c2014-05-23 17:28:10 -070051};
52
tsepez833619b2016-12-07 09:21:17 -080053CFX_RetainPtr<CFX_IFileWrite> CFX_IFileWrite::Create() {
54 return CFX_RetainPtr<CFX_IFileWrite>(new CFX_IFileWrite());
John Abd-El-Malek3f3b45c2014-05-23 17:28:10 -070055}
56
tsepez833619b2016-12-07 09:21:17 -080057CFX_IFileWrite::CFX_IFileWrite() : m_pFileWriteStruct(nullptr) {}
58
tsepezf39074c2016-10-26 15:33:58 -070059bool CFX_IFileWrite::Init(FPDF_FILEWRITE* pFileWriteStruct) {
Nico Weber9d8ec5a2015-08-04 13:00:21 -070060 if (!pFileWriteStruct)
tsepezf39074c2016-10-26 15:33:58 -070061 return false;
Tom Sepez2f2ffec2015-07-23 14:42:09 -070062
Nico Weber9d8ec5a2015-08-04 13:00:21 -070063 m_pFileWriteStruct = pFileWriteStruct;
tsepezf39074c2016-10-26 15:33:58 -070064 return true;
Nico Weber9d8ec5a2015-08-04 13:00:21 -070065}
66
tsepezf39074c2016-10-26 15:33:58 -070067bool CFX_IFileWrite::WriteBlock(const void* pData, size_t size) {
Nico Weber9d8ec5a2015-08-04 13:00:21 -070068 if (!m_pFileWriteStruct)
tsepezf39074c2016-10-26 15:33:58 -070069 return false;
Nico Weber9d8ec5a2015-08-04 13:00:21 -070070
71 m_pFileWriteStruct->WriteBlock(m_pFileWriteStruct, pData, size);
tsepezf39074c2016-10-26 15:33:58 -070072 return true;
Nico Weber9d8ec5a2015-08-04 13:00:21 -070073}
74
Tom Sepez7a73eff2016-02-08 13:39:53 -080075namespace {
76
Tom Sepez51da0932015-11-25 16:05:49 -080077#ifdef PDF_ENABLE_XFA
tsepez833619b2016-12-07 09:21:17 -080078bool SaveXFADocumentData(
79 CPDFXFA_Context* pContext,
80 std::vector<CFX_RetainPtr<IFX_SeekableStream>>* fileList) {
dsinclair521b7502016-11-02 13:02:28 -070081 if (!pContext)
Tom Sepez7a73eff2016-02-08 13:39:53 -080082 return false;
83
Dan Sinclaircdba7472017-03-23 09:17:10 -040084 if (pContext->GetDocType() != XFA_DocType::Dynamic &&
85 pContext->GetDocType() != XFA_DocType::Static) {
Tom Sepez7a73eff2016-02-08 13:39:53 -080086 return true;
Dan Sinclaircdba7472017-03-23 09:17:10 -040087 }
Tom Sepez7a73eff2016-02-08 13:39:53 -080088
dsinclair521b7502016-11-02 13:02:28 -070089 CXFA_FFDocView* pXFADocView = pContext->GetXFADocView();
Tom Sepez7a73eff2016-02-08 13:39:53 -080090 if (!pXFADocView)
91 return true;
Bo Xufdc00a72014-10-28 23:03:33 -070092
dsinclair521b7502016-11-02 13:02:28 -070093 CPDF_Document* pPDFDocument = pContext->GetPDFDoc();
94 if (!pPDFDocument)
Tom Sepez7a73eff2016-02-08 13:39:53 -080095 return false;
Bo Xufdc00a72014-10-28 23:03:33 -070096
Nico Weber9d8ec5a2015-08-04 13:00:21 -070097 CPDF_Dictionary* pRoot = pPDFDocument->GetRoot();
Tom Sepez7a73eff2016-02-08 13:39:53 -080098 if (!pRoot)
99 return false;
100
dsinclair38fd8442016-09-15 10:15:32 -0700101 CPDF_Dictionary* pAcroForm = pRoot->GetDictFor("AcroForm");
Tom Sepez7a73eff2016-02-08 13:39:53 -0800102 if (!pAcroForm)
103 return false;
104
dsinclair38fd8442016-09-15 10:15:32 -0700105 CPDF_Object* pXFA = pAcroForm->GetObjectFor("XFA");
Tom Sepez7a73eff2016-02-08 13:39:53 -0800106 if (!pXFA)
107 return true;
108
thestigb8bf55f2016-05-21 21:08:05 -0700109 CPDF_Array* pArray = pXFA->AsArray();
Tom Sepez7a73eff2016-02-08 13:39:53 -0800110 if (!pArray)
111 return false;
112
Nico Weber9d8ec5a2015-08-04 13:00:21 -0700113 int size = pArray->GetCount();
114 int iFormIndex = -1;
115 int iDataSetsIndex = -1;
116 int iTemplate = -1;
117 int iLast = size - 2;
118 for (int i = 0; i < size - 1; i++) {
tsepezbd567552016-03-29 14:51:50 -0700119 CPDF_Object* pPDFObj = pArray->GetObjectAt(i);
Tom Sepez8e5cd192016-01-26 13:20:26 -0800120 if (!pPDFObj->IsString())
Nico Weber9d8ec5a2015-08-04 13:00:21 -0700121 continue;
122 if (pPDFObj->GetString() == "form")
123 iFormIndex = i + 1;
124 else if (pPDFObj->GetString() == "datasets")
125 iDataSetsIndex = i + 1;
Lei Zhangd983b092015-12-14 16:58:33 -0800126 else if (pPDFObj->GetString() == "template")
Nico Weber9d8ec5a2015-08-04 13:00:21 -0700127 iTemplate = i + 1;
128 }
dsinclair521b7502016-11-02 13:02:28 -0700129 std::unique_ptr<CXFA_ChecksumContext> pChecksum(new CXFA_ChecksumContext);
130 pChecksum->StartChecksum();
Lei Zhanga6d9f0e2015-06-13 00:48:38 -0700131
Nico Weber9d8ec5a2015-08-04 13:00:21 -0700132 // template
133 if (iTemplate > -1) {
Wei Li9b761132016-01-29 15:44:20 -0800134 CPDF_Stream* pTemplateStream = pArray->GetStreamAt(iTemplate);
Nico Weber9d8ec5a2015-08-04 13:00:21 -0700135 CPDF_StreamAcc streamAcc;
136 streamAcc.LoadAllData(pTemplateStream);
137 uint8_t* pData = (uint8_t*)streamAcc.GetData();
tsepezc3255f52016-03-25 14:52:27 -0700138 uint32_t dwSize2 = streamAcc.GetSize();
tsepez833619b2016-12-07 09:21:17 -0800139 CFX_RetainPtr<IFX_SeekableStream> pTemplate =
140 IFX_MemoryStream::Create(pData, dwSize2);
141 pChecksum->UpdateChecksum(pTemplate);
Nico Weber9d8ec5a2015-08-04 13:00:21 -0700142 }
thestig1cd352e2016-06-07 17:53:06 -0700143 CPDF_Stream* pFormStream = nullptr;
144 CPDF_Stream* pDataSetsStream = nullptr;
Nico Weber9d8ec5a2015-08-04 13:00:21 -0700145 if (iFormIndex != -1) {
146 // Get form CPDF_Stream
tsepezbd567552016-03-29 14:51:50 -0700147 CPDF_Object* pFormPDFObj = pArray->GetObjectAt(iFormIndex);
Tom Sepez8e5cd192016-01-26 13:20:26 -0800148 if (pFormPDFObj->IsReference()) {
149 CPDF_Object* pFormDirectObj = pFormPDFObj->GetDirect();
150 if (pFormDirectObj && pFormDirectObj->IsStream()) {
151 pFormStream = (CPDF_Stream*)pFormDirectObj;
Nico Weber9d8ec5a2015-08-04 13:00:21 -0700152 }
Tom Sepez8e5cd192016-01-26 13:20:26 -0800153 } else if (pFormPDFObj->IsStream()) {
Nico Weber9d8ec5a2015-08-04 13:00:21 -0700154 pFormStream = (CPDF_Stream*)pFormPDFObj;
Tom Sepez2f2ffec2015-07-23 14:42:09 -0700155 }
Nico Weber9d8ec5a2015-08-04 13:00:21 -0700156 }
Lei Zhanga6d9f0e2015-06-13 00:48:38 -0700157
Nico Weber9d8ec5a2015-08-04 13:00:21 -0700158 if (iDataSetsIndex != -1) {
159 // Get datasets CPDF_Stream
tsepezbd567552016-03-29 14:51:50 -0700160 CPDF_Object* pDataSetsPDFObj = pArray->GetObjectAt(iDataSetsIndex);
Tom Sepez8e5cd192016-01-26 13:20:26 -0800161 if (pDataSetsPDFObj->IsReference()) {
Nico Weber9d8ec5a2015-08-04 13:00:21 -0700162 CPDF_Reference* pDataSetsRefObj = (CPDF_Reference*)pDataSetsPDFObj;
Tom Sepez8e5cd192016-01-26 13:20:26 -0800163 CPDF_Object* pDataSetsDirectObj = pDataSetsRefObj->GetDirect();
164 if (pDataSetsDirectObj && pDataSetsDirectObj->IsStream()) {
165 pDataSetsStream = (CPDF_Stream*)pDataSetsDirectObj;
Nico Weber9d8ec5a2015-08-04 13:00:21 -0700166 }
Tom Sepez8e5cd192016-01-26 13:20:26 -0800167 } else if (pDataSetsPDFObj->IsStream()) {
Nico Weber9d8ec5a2015-08-04 13:00:21 -0700168 pDataSetsStream = (CPDF_Stream*)pDataSetsPDFObj;
Tom Sepez2f2ffec2015-07-23 14:42:09 -0700169 }
Nico Weber9d8ec5a2015-08-04 13:00:21 -0700170 }
Nico Weber9d8ec5a2015-08-04 13:00:21 -0700171 // L"datasets"
172 {
tsepez833619b2016-12-07 09:21:17 -0800173 CFX_RetainPtr<IFX_SeekableStream> pDsfileWrite = IFX_MemoryStream::Create();
174 if (pXFADocView->GetDoc()->SavePackage(XFA_HASHCODE_Datasets, pDsfileWrite,
175 nullptr) &&
Nico Weber9d8ec5a2015-08-04 13:00:21 -0700176 pDsfileWrite->GetSize() > 0) {
Nico Weber9d8ec5a2015-08-04 13:00:21 -0700177 // Datasets
tsepez833619b2016-12-07 09:21:17 -0800178 pChecksum->UpdateChecksum(pDsfileWrite);
dsinclair521b7502016-11-02 13:02:28 -0700179 pChecksum->FinishChecksum();
tsepez9e05ee12016-11-21 13:19:10 -0800180 auto pDataDict = pdfium::MakeUnique<CPDF_Dictionary>(
181 pPDFDocument->GetByteStringPool());
Nico Weber9d8ec5a2015-08-04 13:00:21 -0700182 if (iDataSetsIndex != -1) {
tsepez9e05ee12016-11-21 13:19:10 -0800183 if (pDataSetsStream) {
tsepez833619b2016-12-07 09:21:17 -0800184 pDataSetsStream->InitStreamFromFile(pDsfileWrite,
tsepez9e05ee12016-11-21 13:19:10 -0800185 std::move(pDataDict));
186 }
Nico Weber9d8ec5a2015-08-04 13:00:21 -0700187 } else {
tsepez70c4afd2016-11-15 11:33:44 -0800188 CPDF_Stream* pData = pPDFDocument->NewIndirect<CPDF_Stream>();
tsepez833619b2016-12-07 09:21:17 -0800189 pData->InitStreamFromFile(pDsfileWrite, std::move(pDataDict));
Tom Sepez3343d142015-11-02 09:54:54 -0800190 iLast = pArray->GetCount() - 2;
tsepez8a3aa452016-11-16 12:26:06 -0800191 pArray->InsertNewAt<CPDF_String>(iLast, "datasets", false);
192 pArray->InsertNewAt<CPDF_Reference>(iLast + 1, pPDFDocument,
193 pData->GetObjNum());
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 {
tsepez833619b2016-12-07 09:21:17 -0800200 CFX_RetainPtr<IFX_SeekableStream> pfileWrite = IFX_MemoryStream::Create();
201 if (pXFADocView->GetDoc()->SavePackage(XFA_HASHCODE_Form, pfileWrite,
dsinclair521b7502016-11-02 13:02:28 -0700202 pChecksum.get()) &&
Tom Sepez7a73eff2016-02-08 13:39:53 -0800203 pfileWrite->GetSize() > 0) {
tsepez9e05ee12016-11-21 13:19:10 -0800204 auto pDataDict = pdfium::MakeUnique<CPDF_Dictionary>(
205 pPDFDocument->GetByteStringPool());
Nico Weber9d8ec5a2015-08-04 13:00:21 -0700206 if (iFormIndex != -1) {
tsepez833619b2016-12-07 09:21:17 -0800207 if (pFormStream)
208 pFormStream->InitStreamFromFile(pfileWrite, std::move(pDataDict));
Nico Weber9d8ec5a2015-08-04 13:00:21 -0700209 } else {
tsepez70c4afd2016-11-15 11:33:44 -0800210 CPDF_Stream* pData = pPDFDocument->NewIndirect<CPDF_Stream>();
tsepez833619b2016-12-07 09:21:17 -0800211 pData->InitStreamFromFile(pfileWrite, std::move(pDataDict));
Tom Sepez3343d142015-11-02 09:54:54 -0800212 iLast = pArray->GetCount() - 2;
tsepez8a3aa452016-11-16 12:26:06 -0800213 pArray->InsertNewAt<CPDF_String>(iLast, "form", false);
214 pArray->InsertNewAt<CPDF_Reference>(iLast + 1, pPDFDocument,
215 pData->GetObjNum());
Nico Weber9d8ec5a2015-08-04 13:00:21 -0700216 }
Tom Sepez7a73eff2016-02-08 13:39:53 -0800217 fileList->push_back(std::move(pfileWrite));
Tom Sepez2f2ffec2015-07-23 14:42:09 -0700218 }
Nico Weber9d8ec5a2015-08-04 13:00:21 -0700219 }
Tom Sepez7a73eff2016-02-08 13:39:53 -0800220 return true;
Nico Weber9d8ec5a2015-08-04 13:00:21 -0700221}
222
dsinclair521b7502016-11-02 13:02:28 -0700223bool SendPostSaveToXFADoc(CPDFXFA_Context* pContext) {
224 if (!pContext)
Tom Sepez7a73eff2016-02-08 13:39:53 -0800225 return false;
Nico Weber9d8ec5a2015-08-04 13:00:21 -0700226
Dan Sinclaircdba7472017-03-23 09:17:10 -0400227 if (pContext->GetDocType() != XFA_DocType::Dynamic &&
228 pContext->GetDocType() != XFA_DocType::Static)
Tom Sepez7a73eff2016-02-08 13:39:53 -0800229 return true;
Nico Weber9d8ec5a2015-08-04 13:00:21 -0700230
dsinclair521b7502016-11-02 13:02:28 -0700231 CXFA_FFDocView* pXFADocView = pContext->GetXFADocView();
Tom Sepez7a73eff2016-02-08 13:39:53 -0800232 if (!pXFADocView)
233 return false;
Nico Weber9d8ec5a2015-08-04 13:00:21 -0700234
dsinclairdf4bc592016-03-31 20:34:43 -0700235 CXFA_FFWidgetHandler* pWidgetHander = pXFADocView->GetWidgetHandler();
tsepeze7b28532016-05-18 12:10:49 -0700236 std::unique_ptr<CXFA_WidgetAccIterator> pWidgetAccIterator(
237 pXFADocView->CreateWidgetAccIterator());
238 while (CXFA_WidgetAcc* pWidgetAcc = pWidgetAccIterator->MoveToNext()) {
Nico Weber9d8ec5a2015-08-04 13:00:21 -0700239 CXFA_EventParam preParam;
240 preParam.m_eType = XFA_EVENT_PostSave;
241 pWidgetHander->ProcessEvent(pWidgetAcc, &preParam);
Nico Weber9d8ec5a2015-08-04 13:00:21 -0700242 }
Nico Weber9d8ec5a2015-08-04 13:00:21 -0700243 pXFADocView->UpdateDocView();
dsinclair521b7502016-11-02 13:02:28 -0700244 pContext->ClearChangeMark();
Tom Sepez7a73eff2016-02-08 13:39:53 -0800245 return true;
Bo Xufdc00a72014-10-28 23:03:33 -0700246}
247
tsepez833619b2016-12-07 09:21:17 -0800248bool SendPreSaveToXFADoc(
249 CPDFXFA_Context* pContext,
250 std::vector<CFX_RetainPtr<IFX_SeekableStream>>* fileList) {
Dan Sinclaircdba7472017-03-23 09:17:10 -0400251 if (pContext->GetDocType() != XFA_DocType::Dynamic &&
252 pContext->GetDocType() != XFA_DocType::Static)
Tom Sepez7a73eff2016-02-08 13:39:53 -0800253 return true;
254
dsinclair521b7502016-11-02 13:02:28 -0700255 CXFA_FFDocView* pXFADocView = pContext->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();
dsinclair521b7502016-11-02 13:02:28 -0700268 return SaveXFADocumentData(pContext, 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
dsinclair521b7502016-11-02 13:02:28 -0700282 CPDFXFA_Context* pContext = static_cast<CPDFXFA_Context*>(document);
tsepez833619b2016-12-07 09:21:17 -0800283 std::vector<CFX_RetainPtr<IFX_SeekableStream>> fileList;
dsinclair521b7502016-11-02 13:02:28 -0700284 SendPreSaveToXFADoc(pContext, &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
tsepez833619b2016-12-07 09:21:17 -0800298 CFX_RetainPtr<CFX_IFileWrite> pStreamWrite = CFX_IFileWrite::Create();
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
dsinclair521b7502016-11-02 13:02:28 -0700302 SendPostSaveToXFADoc(pContext);
Tom Sepez40e9ff32015-11-30 12:39:54 -0800303#endif // PDF_ENABLE_XFA
Nico Weber9d8ec5a2015-08-04 13:00:21 -0700304 return bRet;
John Abd-El-Malek3f3b45c2014-05-23 17:28:10 -0700305}
306
Tom Sepez7a73eff2016-02-08 13:39:53 -0800307} // namespace
308
Nico Weber9d8ec5a2015-08-04 13:00:21 -0700309DLLEXPORT FPDF_BOOL STDCALL FPDF_SaveAsCopy(FPDF_DOCUMENT document,
310 FPDF_FILEWRITE* pFileWrite,
311 FPDF_DWORD flags) {
tsepez4cf55152016-11-02 14:37:54 -0700312 return FPDF_Doc_Save(document, pFileWrite, flags, false, 0);
John Abd-El-Malek3f3b45c2014-05-23 17:28:10 -0700313}
314
Nico Weber9d8ec5a2015-08-04 13:00:21 -0700315DLLEXPORT FPDF_BOOL STDCALL FPDF_SaveWithVersion(FPDF_DOCUMENT document,
316 FPDF_FILEWRITE* pFileWrite,
317 FPDF_DWORD flags,
318 int fileVersion) {
tsepez4cf55152016-11-02 14:37:54 -0700319 return FPDF_Doc_Save(document, pFileWrite, flags, true, fileVersion);
John Abd-El-Malek3f3b45c2014-05-23 17:28:10 -0700320}