blob: 8e925795183b07886c5329761159706245cbf037 [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"
Dan Sinclair283a0432017-04-20 14:11:21 -040019#include "core/fxcrt/cfx_memorystream.h"
Dan Sinclaircfb19442017-04-20 13:13:04 -040020#include "core/fxcrt/fx_extension.h"
dsinclair114e46a2016-09-29 17:18:21 -070021#include "fpdfsdk/fsdk_define.h"
Tom Sepez40e9ff32015-11-30 12:39:54 -080022#include "public/fpdf_edit.h"
23
Tom Sepez51da0932015-11-25 16:05:49 -080024#ifdef PDF_ENABLE_XFA
Dan Sinclairddb70162017-03-30 14:01:31 -040025#include "core/fxcrt/cfx_checksumcontext.h"
dsinclair521b7502016-11-02 13:02:28 -070026#include "fpdfsdk/fpdfxfa/cpdfxfa_context.h"
dsinclair4d29e782016-10-04 14:02:47 -070027#include "fpdfsdk/fpdfxfa/cxfa_fwladaptertimermgr.h"
Lei Zhangb4e7f302015-11-06 15:52:32 -080028#include "public/fpdf_formfill.h"
dsinclair5b493092016-09-29 20:20:24 -070029#include "xfa/fxfa/cxfa_eventparam.h"
Dan Sinclair80c48782017-03-23 12:11:20 -040030#include "xfa/fxfa/cxfa_ffapp.h"
31#include "xfa/fxfa/cxfa_ffdocview.h"
32#include "xfa/fxfa/cxfa_ffwidgethandler.h"
33#include "xfa/fxfa/cxfa_widgetacciterator.h"
Tom Sepez51da0932015-11-25 16:05:49 -080034#endif
Tom Sepez1ed8a212015-05-11 15:25:39 -070035
John Abd-El-Malek3f3b45c2014-05-23 17:28:10 -070036#if _FX_OS_ == _FX_ANDROID_
Dan Sinclair85c8e7f2016-11-21 13:50:32 -050037#include <time.h>
John Abd-El-Malek3f3b45c2014-05-23 17:28:10 -070038#else
39#include <ctime>
40#endif
41
tsepezad2441e2016-10-24 10:19:11 -070042class CFX_IFileWrite final : public IFX_WriteStream {
Nico Weber9d8ec5a2015-08-04 13:00:21 -070043 public:
tsepez833619b2016-12-07 09:21:17 -080044 static CFX_RetainPtr<CFX_IFileWrite> Create();
Dan Sinclair0bb13332017-03-30 16:12:02 -040045
tsepezf39074c2016-10-26 15:33:58 -070046 bool Init(FPDF_FILEWRITE* pFileWriteStruct);
47 bool WriteBlock(const void* pData, size_t size) override;
Lei Zhanga6d9f0e2015-06-13 00:48:38 -070048
Nico Weber9d8ec5a2015-08-04 13:00:21 -070049 protected:
Dan Sinclair0bb13332017-03-30 16:12:02 -040050 template <typename T, typename... Args>
51 friend CFX_RetainPtr<T> pdfium::MakeRetain(Args&&... args);
52
tsepez833619b2016-12-07 09:21:17 -080053 CFX_IFileWrite();
Lei Zhang2b1a2d52015-08-14 22:16:22 -070054 ~CFX_IFileWrite() override {}
55
Nico Weber9d8ec5a2015-08-04 13:00:21 -070056 FPDF_FILEWRITE* m_pFileWriteStruct;
John Abd-El-Malek3f3b45c2014-05-23 17:28:10 -070057};
58
tsepez833619b2016-12-07 09:21:17 -080059CFX_RetainPtr<CFX_IFileWrite> CFX_IFileWrite::Create() {
Dan Sinclair0bb13332017-03-30 16:12:02 -040060 return pdfium::MakeRetain<CFX_IFileWrite>();
John Abd-El-Malek3f3b45c2014-05-23 17:28:10 -070061}
62
tsepez833619b2016-12-07 09:21:17 -080063CFX_IFileWrite::CFX_IFileWrite() : m_pFileWriteStruct(nullptr) {}
64
tsepezf39074c2016-10-26 15:33:58 -070065bool CFX_IFileWrite::Init(FPDF_FILEWRITE* pFileWriteStruct) {
Nico Weber9d8ec5a2015-08-04 13:00:21 -070066 if (!pFileWriteStruct)
tsepezf39074c2016-10-26 15:33:58 -070067 return false;
Tom Sepez2f2ffec2015-07-23 14:42:09 -070068
Nico Weber9d8ec5a2015-08-04 13:00:21 -070069 m_pFileWriteStruct = pFileWriteStruct;
tsepezf39074c2016-10-26 15:33:58 -070070 return true;
Nico Weber9d8ec5a2015-08-04 13:00:21 -070071}
72
tsepezf39074c2016-10-26 15:33:58 -070073bool CFX_IFileWrite::WriteBlock(const void* pData, size_t size) {
Nico Weber9d8ec5a2015-08-04 13:00:21 -070074 if (!m_pFileWriteStruct)
tsepezf39074c2016-10-26 15:33:58 -070075 return false;
Nico Weber9d8ec5a2015-08-04 13:00:21 -070076
77 m_pFileWriteStruct->WriteBlock(m_pFileWriteStruct, pData, size);
tsepezf39074c2016-10-26 15:33:58 -070078 return true;
Nico Weber9d8ec5a2015-08-04 13:00:21 -070079}
80
Tom Sepez7a73eff2016-02-08 13:39:53 -080081namespace {
82
Tom Sepez51da0932015-11-25 16:05:49 -080083#ifdef PDF_ENABLE_XFA
tsepez833619b2016-12-07 09:21:17 -080084bool SaveXFADocumentData(
85 CPDFXFA_Context* pContext,
86 std::vector<CFX_RetainPtr<IFX_SeekableStream>>* fileList) {
dsinclair521b7502016-11-02 13:02:28 -070087 if (!pContext)
Tom Sepez7a73eff2016-02-08 13:39:53 -080088 return false;
89
Dan Sinclaircdba7472017-03-23 09:17:10 -040090 if (pContext->GetDocType() != XFA_DocType::Dynamic &&
91 pContext->GetDocType() != XFA_DocType::Static) {
Tom Sepez7a73eff2016-02-08 13:39:53 -080092 return true;
Dan Sinclaircdba7472017-03-23 09:17:10 -040093 }
Tom Sepez7a73eff2016-02-08 13:39:53 -080094
dsinclair521b7502016-11-02 13:02:28 -070095 CXFA_FFDocView* pXFADocView = pContext->GetXFADocView();
Tom Sepez7a73eff2016-02-08 13:39:53 -080096 if (!pXFADocView)
97 return true;
Bo Xufdc00a72014-10-28 23:03:33 -070098
dsinclair521b7502016-11-02 13:02:28 -070099 CPDF_Document* pPDFDocument = pContext->GetPDFDoc();
100 if (!pPDFDocument)
Tom Sepez7a73eff2016-02-08 13:39:53 -0800101 return false;
Bo Xufdc00a72014-10-28 23:03:33 -0700102
Nico Weber9d8ec5a2015-08-04 13:00:21 -0700103 CPDF_Dictionary* pRoot = pPDFDocument->GetRoot();
Tom Sepez7a73eff2016-02-08 13:39:53 -0800104 if (!pRoot)
105 return false;
106
dsinclair38fd8442016-09-15 10:15:32 -0700107 CPDF_Dictionary* pAcroForm = pRoot->GetDictFor("AcroForm");
Tom Sepez7a73eff2016-02-08 13:39:53 -0800108 if (!pAcroForm)
109 return false;
110
dsinclair38fd8442016-09-15 10:15:32 -0700111 CPDF_Object* pXFA = pAcroForm->GetObjectFor("XFA");
Tom Sepez7a73eff2016-02-08 13:39:53 -0800112 if (!pXFA)
113 return true;
114
thestigb8bf55f2016-05-21 21:08:05 -0700115 CPDF_Array* pArray = pXFA->AsArray();
Tom Sepez7a73eff2016-02-08 13:39:53 -0800116 if (!pArray)
117 return false;
118
Nico Weber9d8ec5a2015-08-04 13:00:21 -0700119 int size = pArray->GetCount();
120 int iFormIndex = -1;
121 int iDataSetsIndex = -1;
122 int iTemplate = -1;
123 int iLast = size - 2;
124 for (int i = 0; i < size - 1; i++) {
tsepezbd567552016-03-29 14:51:50 -0700125 CPDF_Object* pPDFObj = pArray->GetObjectAt(i);
Tom Sepez8e5cd192016-01-26 13:20:26 -0800126 if (!pPDFObj->IsString())
Nico Weber9d8ec5a2015-08-04 13:00:21 -0700127 continue;
128 if (pPDFObj->GetString() == "form")
129 iFormIndex = i + 1;
130 else if (pPDFObj->GetString() == "datasets")
131 iDataSetsIndex = i + 1;
Lei Zhangd983b092015-12-14 16:58:33 -0800132 else if (pPDFObj->GetString() == "template")
Nico Weber9d8ec5a2015-08-04 13:00:21 -0700133 iTemplate = i + 1;
134 }
Dan Sinclair0bb13332017-03-30 16:12:02 -0400135 auto pChecksum = pdfium::MakeUnique<CFX_ChecksumContext>();
dsinclair521b7502016-11-02 13:02:28 -0700136 pChecksum->StartChecksum();
Lei Zhanga6d9f0e2015-06-13 00:48:38 -0700137
Nico Weber9d8ec5a2015-08-04 13:00:21 -0700138 // template
139 if (iTemplate > -1) {
Wei Li9b761132016-01-29 15:44:20 -0800140 CPDF_Stream* pTemplateStream = pArray->GetStreamAt(iTemplate);
Tom Sepezafd0d1f2017-04-04 14:37:18 -0700141 auto pAcc = pdfium::MakeRetain<CPDF_StreamAcc>(pTemplateStream);
142 pAcc->LoadAllData();
Dan Sinclair283a0432017-04-20 14:11:21 -0400143 CFX_RetainPtr<IFX_SeekableStream> pTemplate =
144 pdfium::MakeRetain<CFX_MemoryStream>(
145 const_cast<uint8_t*>(pAcc->GetData()), pAcc->GetSize(), false);
tsepez833619b2016-12-07 09:21:17 -0800146 pChecksum->UpdateChecksum(pTemplate);
Nico Weber9d8ec5a2015-08-04 13:00:21 -0700147 }
thestig1cd352e2016-06-07 17:53:06 -0700148 CPDF_Stream* pFormStream = nullptr;
149 CPDF_Stream* pDataSetsStream = nullptr;
Nico Weber9d8ec5a2015-08-04 13:00:21 -0700150 if (iFormIndex != -1) {
151 // Get form CPDF_Stream
tsepezbd567552016-03-29 14:51:50 -0700152 CPDF_Object* pFormPDFObj = pArray->GetObjectAt(iFormIndex);
Tom Sepez8e5cd192016-01-26 13:20:26 -0800153 if (pFormPDFObj->IsReference()) {
154 CPDF_Object* pFormDirectObj = pFormPDFObj->GetDirect();
155 if (pFormDirectObj && pFormDirectObj->IsStream()) {
156 pFormStream = (CPDF_Stream*)pFormDirectObj;
Nico Weber9d8ec5a2015-08-04 13:00:21 -0700157 }
Tom Sepez8e5cd192016-01-26 13:20:26 -0800158 } else if (pFormPDFObj->IsStream()) {
Nico Weber9d8ec5a2015-08-04 13:00:21 -0700159 pFormStream = (CPDF_Stream*)pFormPDFObj;
Tom Sepez2f2ffec2015-07-23 14:42:09 -0700160 }
Nico Weber9d8ec5a2015-08-04 13:00:21 -0700161 }
Lei Zhanga6d9f0e2015-06-13 00:48:38 -0700162
Nico Weber9d8ec5a2015-08-04 13:00:21 -0700163 if (iDataSetsIndex != -1) {
164 // Get datasets CPDF_Stream
tsepezbd567552016-03-29 14:51:50 -0700165 CPDF_Object* pDataSetsPDFObj = pArray->GetObjectAt(iDataSetsIndex);
Tom Sepez8e5cd192016-01-26 13:20:26 -0800166 if (pDataSetsPDFObj->IsReference()) {
Nico Weber9d8ec5a2015-08-04 13:00:21 -0700167 CPDF_Reference* pDataSetsRefObj = (CPDF_Reference*)pDataSetsPDFObj;
Tom Sepez8e5cd192016-01-26 13:20:26 -0800168 CPDF_Object* pDataSetsDirectObj = pDataSetsRefObj->GetDirect();
169 if (pDataSetsDirectObj && pDataSetsDirectObj->IsStream()) {
170 pDataSetsStream = (CPDF_Stream*)pDataSetsDirectObj;
Nico Weber9d8ec5a2015-08-04 13:00:21 -0700171 }
Tom Sepez8e5cd192016-01-26 13:20:26 -0800172 } else if (pDataSetsPDFObj->IsStream()) {
Nico Weber9d8ec5a2015-08-04 13:00:21 -0700173 pDataSetsStream = (CPDF_Stream*)pDataSetsPDFObj;
Tom Sepez2f2ffec2015-07-23 14:42:09 -0700174 }
Nico Weber9d8ec5a2015-08-04 13:00:21 -0700175 }
Nico Weber9d8ec5a2015-08-04 13:00:21 -0700176 // L"datasets"
177 {
Dan Sinclair283a0432017-04-20 14:11:21 -0400178 CFX_RetainPtr<IFX_SeekableStream> pDsfileWrite =
179 pdfium::MakeRetain<CFX_MemoryStream>(false);
tsepez833619b2016-12-07 09:21:17 -0800180 if (pXFADocView->GetDoc()->SavePackage(XFA_HASHCODE_Datasets, pDsfileWrite,
181 nullptr) &&
Nico Weber9d8ec5a2015-08-04 13:00:21 -0700182 pDsfileWrite->GetSize() > 0) {
Nico Weber9d8ec5a2015-08-04 13:00:21 -0700183 // Datasets
tsepez833619b2016-12-07 09:21:17 -0800184 pChecksum->UpdateChecksum(pDsfileWrite);
dsinclair521b7502016-11-02 13:02:28 -0700185 pChecksum->FinishChecksum();
tsepez9e05ee12016-11-21 13:19:10 -0800186 auto pDataDict = pdfium::MakeUnique<CPDF_Dictionary>(
187 pPDFDocument->GetByteStringPool());
Nico Weber9d8ec5a2015-08-04 13:00:21 -0700188 if (iDataSetsIndex != -1) {
tsepez9e05ee12016-11-21 13:19:10 -0800189 if (pDataSetsStream) {
tsepez833619b2016-12-07 09:21:17 -0800190 pDataSetsStream->InitStreamFromFile(pDsfileWrite,
tsepez9e05ee12016-11-21 13:19:10 -0800191 std::move(pDataDict));
192 }
Nico Weber9d8ec5a2015-08-04 13:00:21 -0700193 } else {
tsepez70c4afd2016-11-15 11:33:44 -0800194 CPDF_Stream* pData = pPDFDocument->NewIndirect<CPDF_Stream>();
tsepez833619b2016-12-07 09:21:17 -0800195 pData->InitStreamFromFile(pDsfileWrite, std::move(pDataDict));
Tom Sepez3343d142015-11-02 09:54:54 -0800196 iLast = pArray->GetCount() - 2;
tsepez8a3aa452016-11-16 12:26:06 -0800197 pArray->InsertNewAt<CPDF_String>(iLast, "datasets", false);
198 pArray->InsertNewAt<CPDF_Reference>(iLast + 1, pPDFDocument,
199 pData->GetObjNum());
Nico Weber9d8ec5a2015-08-04 13:00:21 -0700200 }
Tom Sepez7a73eff2016-02-08 13:39:53 -0800201 fileList->push_back(std::move(pDsfileWrite));
Nico Weber9d8ec5a2015-08-04 13:00:21 -0700202 }
203 }
Nico Weber9d8ec5a2015-08-04 13:00:21 -0700204 // L"form"
205 {
Dan Sinclair283a0432017-04-20 14:11:21 -0400206 CFX_RetainPtr<IFX_SeekableStream> pfileWrite =
207 pdfium::MakeRetain<CFX_MemoryStream>(false);
tsepez833619b2016-12-07 09:21:17 -0800208 if (pXFADocView->GetDoc()->SavePackage(XFA_HASHCODE_Form, pfileWrite,
dsinclair521b7502016-11-02 13:02:28 -0700209 pChecksum.get()) &&
Tom Sepez7a73eff2016-02-08 13:39:53 -0800210 pfileWrite->GetSize() > 0) {
tsepez9e05ee12016-11-21 13:19:10 -0800211 auto pDataDict = pdfium::MakeUnique<CPDF_Dictionary>(
212 pPDFDocument->GetByteStringPool());
Nico Weber9d8ec5a2015-08-04 13:00:21 -0700213 if (iFormIndex != -1) {
tsepez833619b2016-12-07 09:21:17 -0800214 if (pFormStream)
215 pFormStream->InitStreamFromFile(pfileWrite, std::move(pDataDict));
Nico Weber9d8ec5a2015-08-04 13:00:21 -0700216 } else {
tsepez70c4afd2016-11-15 11:33:44 -0800217 CPDF_Stream* pData = pPDFDocument->NewIndirect<CPDF_Stream>();
tsepez833619b2016-12-07 09:21:17 -0800218 pData->InitStreamFromFile(pfileWrite, std::move(pDataDict));
Tom Sepez3343d142015-11-02 09:54:54 -0800219 iLast = pArray->GetCount() - 2;
tsepez8a3aa452016-11-16 12:26:06 -0800220 pArray->InsertNewAt<CPDF_String>(iLast, "form", false);
221 pArray->InsertNewAt<CPDF_Reference>(iLast + 1, pPDFDocument,
222 pData->GetObjNum());
Nico Weber9d8ec5a2015-08-04 13:00:21 -0700223 }
Tom Sepez7a73eff2016-02-08 13:39:53 -0800224 fileList->push_back(std::move(pfileWrite));
Tom Sepez2f2ffec2015-07-23 14:42:09 -0700225 }
Nico Weber9d8ec5a2015-08-04 13:00:21 -0700226 }
Tom Sepez7a73eff2016-02-08 13:39:53 -0800227 return true;
Nico Weber9d8ec5a2015-08-04 13:00:21 -0700228}
229
dsinclair521b7502016-11-02 13:02:28 -0700230bool SendPostSaveToXFADoc(CPDFXFA_Context* pContext) {
231 if (!pContext)
Tom Sepez7a73eff2016-02-08 13:39:53 -0800232 return false;
Nico Weber9d8ec5a2015-08-04 13:00:21 -0700233
Dan Sinclaircdba7472017-03-23 09:17:10 -0400234 if (pContext->GetDocType() != XFA_DocType::Dynamic &&
235 pContext->GetDocType() != XFA_DocType::Static)
Tom Sepez7a73eff2016-02-08 13:39:53 -0800236 return true;
Nico Weber9d8ec5a2015-08-04 13:00:21 -0700237
dsinclair521b7502016-11-02 13:02:28 -0700238 CXFA_FFDocView* pXFADocView = pContext->GetXFADocView();
Tom Sepez7a73eff2016-02-08 13:39:53 -0800239 if (!pXFADocView)
240 return false;
Nico Weber9d8ec5a2015-08-04 13:00:21 -0700241
dsinclairdf4bc592016-03-31 20:34:43 -0700242 CXFA_FFWidgetHandler* pWidgetHander = pXFADocView->GetWidgetHandler();
tsepeze7b28532016-05-18 12:10:49 -0700243 std::unique_ptr<CXFA_WidgetAccIterator> pWidgetAccIterator(
244 pXFADocView->CreateWidgetAccIterator());
245 while (CXFA_WidgetAcc* pWidgetAcc = pWidgetAccIterator->MoveToNext()) {
Nico Weber9d8ec5a2015-08-04 13:00:21 -0700246 CXFA_EventParam preParam;
247 preParam.m_eType = XFA_EVENT_PostSave;
248 pWidgetHander->ProcessEvent(pWidgetAcc, &preParam);
Nico Weber9d8ec5a2015-08-04 13:00:21 -0700249 }
Nico Weber9d8ec5a2015-08-04 13:00:21 -0700250 pXFADocView->UpdateDocView();
dsinclair521b7502016-11-02 13:02:28 -0700251 pContext->ClearChangeMark();
Tom Sepez7a73eff2016-02-08 13:39:53 -0800252 return true;
Bo Xufdc00a72014-10-28 23:03:33 -0700253}
254
tsepez833619b2016-12-07 09:21:17 -0800255bool SendPreSaveToXFADoc(
256 CPDFXFA_Context* pContext,
257 std::vector<CFX_RetainPtr<IFX_SeekableStream>>* fileList) {
Dan Sinclaircdba7472017-03-23 09:17:10 -0400258 if (pContext->GetDocType() != XFA_DocType::Dynamic &&
259 pContext->GetDocType() != XFA_DocType::Static)
Tom Sepez7a73eff2016-02-08 13:39:53 -0800260 return true;
261
dsinclair521b7502016-11-02 13:02:28 -0700262 CXFA_FFDocView* pXFADocView = pContext->GetXFADocView();
Tom Sepez7a73eff2016-02-08 13:39:53 -0800263 if (!pXFADocView)
264 return true;
265
dsinclairdf4bc592016-03-31 20:34:43 -0700266 CXFA_FFWidgetHandler* pWidgetHander = pXFADocView->GetWidgetHandler();
tsepeze7b28532016-05-18 12:10:49 -0700267 std::unique_ptr<CXFA_WidgetAccIterator> pWidgetAccIterator(
268 pXFADocView->CreateWidgetAccIterator());
269 while (CXFA_WidgetAcc* pWidgetAcc = pWidgetAccIterator->MoveToNext()) {
Nico Weber9d8ec5a2015-08-04 13:00:21 -0700270 CXFA_EventParam preParam;
271 preParam.m_eType = XFA_EVENT_PreSave;
272 pWidgetHander->ProcessEvent(pWidgetAcc, &preParam);
Nico Weber9d8ec5a2015-08-04 13:00:21 -0700273 }
Nico Weber9d8ec5a2015-08-04 13:00:21 -0700274 pXFADocView->UpdateDocView();
dsinclair521b7502016-11-02 13:02:28 -0700275 return SaveXFADocumentData(pContext, fileList);
Bo Xufdc00a72014-10-28 23:03:33 -0700276}
Tom Sepez40e9ff32015-11-30 12:39:54 -0800277#endif // PDF_ENABLE_XFA
Bo Xufdc00a72014-10-28 23:03:33 -0700278
Tom Sepez7a73eff2016-02-08 13:39:53 -0800279bool FPDF_Doc_Save(FPDF_DOCUMENT document,
280 FPDF_FILEWRITE* pFileWrite,
281 FPDF_DWORD flags,
282 FPDF_BOOL bSetVersion,
283 int fileVerion) {
Tom Sepez1b246282015-11-25 15:15:31 -0800284 CPDF_Document* pPDFDoc = CPDFDocumentFromFPDFDocument(document);
Nico Weber9d8ec5a2015-08-04 13:00:21 -0700285 if (!pPDFDoc)
286 return 0;
Lei Zhanga6d9f0e2015-06-13 00:48:38 -0700287
Tom Sepez51da0932015-11-25 16:05:49 -0800288#ifdef PDF_ENABLE_XFA
dsinclair521b7502016-11-02 13:02:28 -0700289 CPDFXFA_Context* pContext = static_cast<CPDFXFA_Context*>(document);
tsepez833619b2016-12-07 09:21:17 -0800290 std::vector<CFX_RetainPtr<IFX_SeekableStream>> fileList;
dsinclair521b7502016-11-02 13:02:28 -0700291 SendPreSaveToXFADoc(pContext, &fileList);
Tom Sepez40e9ff32015-11-30 12:39:54 -0800292#endif // PDF_ENABLE_XFA
Tom Sepez1b246282015-11-25 15:15:31 -0800293
Tom Sepez7a73eff2016-02-08 13:39:53 -0800294 if (flags < FPDF_INCREMENTAL || flags > FPDF_REMOVE_SECURITY)
Nico Weber9d8ec5a2015-08-04 13:00:21 -0700295 flags = 0;
Lei Zhanga6d9f0e2015-06-13 00:48:38 -0700296
Nico Weber9d8ec5a2015-08-04 13:00:21 -0700297 CPDF_Creator FileMaker(pPDFDoc);
298 if (bSetVersion)
299 FileMaker.SetFileVersion(fileVerion);
300 if (flags == FPDF_REMOVE_SECURITY) {
301 flags = 0;
302 FileMaker.RemoveSecurity();
303 }
Tom Sepez1b246282015-11-25 15:15:31 -0800304
tsepez833619b2016-12-07 09:21:17 -0800305 CFX_RetainPtr<CFX_IFileWrite> pStreamWrite = CFX_IFileWrite::Create();
Nico Weber9d8ec5a2015-08-04 13:00:21 -0700306 pStreamWrite->Init(pFileWrite);
Wei Li97da9762016-03-11 17:00:48 -0800307 bool bRet = FileMaker.Create(pStreamWrite, flags);
Tom Sepez51da0932015-11-25 16:05:49 -0800308#ifdef PDF_ENABLE_XFA
dsinclair521b7502016-11-02 13:02:28 -0700309 SendPostSaveToXFADoc(pContext);
Tom Sepez40e9ff32015-11-30 12:39:54 -0800310#endif // PDF_ENABLE_XFA
Nico Weber9d8ec5a2015-08-04 13:00:21 -0700311 return bRet;
John Abd-El-Malek3f3b45c2014-05-23 17:28:10 -0700312}
313
Tom Sepez7a73eff2016-02-08 13:39:53 -0800314} // namespace
315
Nico Weber9d8ec5a2015-08-04 13:00:21 -0700316DLLEXPORT FPDF_BOOL STDCALL FPDF_SaveAsCopy(FPDF_DOCUMENT document,
317 FPDF_FILEWRITE* pFileWrite,
318 FPDF_DWORD flags) {
tsepez4cf55152016-11-02 14:37:54 -0700319 return FPDF_Doc_Save(document, pFileWrite, flags, false, 0);
John Abd-El-Malek3f3b45c2014-05-23 17:28:10 -0700320}
321
Nico Weber9d8ec5a2015-08-04 13:00:21 -0700322DLLEXPORT FPDF_BOOL STDCALL FPDF_SaveWithVersion(FPDF_DOCUMENT document,
323 FPDF_FILEWRITE* pFileWrite,
324 FPDF_DWORD flags,
325 int fileVersion) {
tsepez4cf55152016-11-02 14:37:54 -0700326 return FPDF_Doc_Save(document, pFileWrite, flags, true, fileVersion);
John Abd-El-Malek3f3b45c2014-05-23 17:28:10 -0700327}