| OLD | NEW | 
|---|
| 1 // Copyright 2014 PDFium Authors. All rights reserved. | 1 // Copyright 2014 PDFium Authors. All rights reserved. | 
| 2 // Use of this source code is governed by a BSD-style license that can be | 2 // Use of this source code is governed by a BSD-style license that can be | 
| 3 // found in the LICENSE file. | 3 // found in the LICENSE file. | 
| 4 | 4 | 
| 5 // Original code copyright 2014 Foxit Software Inc. http://www.foxitsoftware.com | 5 // Original code copyright 2014 Foxit Software Inc. http://www.foxitsoftware.com | 
| 6 | 6 | 
| 7 #include "public/fpdf_save.h" | 7 #include "public/fpdf_save.h" | 
| 8 | 8 | 
| 9 #include <memory> | 9 #include <memory> | 
| 10 #include <utility> | 10 #include <utility> | 
| (...skipping 21 matching lines...) Expand all  Loading... | 
| 32 #endif | 32 #endif | 
| 33 | 33 | 
| 34 #if _FX_OS_ == _FX_ANDROID_ | 34 #if _FX_OS_ == _FX_ANDROID_ | 
| 35 #include <time.h> | 35 #include <time.h> | 
| 36 #else | 36 #else | 
| 37 #include <ctime> | 37 #include <ctime> | 
| 38 #endif | 38 #endif | 
| 39 | 39 | 
| 40 class CFX_IFileWrite final : public IFX_WriteStream { | 40 class CFX_IFileWrite final : public IFX_WriteStream { | 
| 41  public: | 41  public: | 
| 42   CFX_IFileWrite(); | 42   static CFX_RetainPtr<CFX_IFileWrite> Create(); | 
| 43   bool Init(FPDF_FILEWRITE* pFileWriteStruct); | 43   bool Init(FPDF_FILEWRITE* pFileWriteStruct); | 
| 44   bool WriteBlock(const void* pData, size_t size) override; | 44   bool WriteBlock(const void* pData, size_t size) override; | 
| 45   void Release() override; |  | 
| 46 | 45 | 
| 47  protected: | 46  protected: | 
|  | 47   CFX_IFileWrite(); | 
| 48   ~CFX_IFileWrite() override {} | 48   ~CFX_IFileWrite() override {} | 
| 49 | 49 | 
| 50   FPDF_FILEWRITE* m_pFileWriteStruct; | 50   FPDF_FILEWRITE* m_pFileWriteStruct; | 
| 51 }; | 51 }; | 
| 52 | 52 | 
| 53 CFX_IFileWrite::CFX_IFileWrite() { | 53 CFX_RetainPtr<CFX_IFileWrite> CFX_IFileWrite::Create() { | 
| 54   m_pFileWriteStruct = nullptr; | 54   return CFX_RetainPtr<CFX_IFileWrite>(new CFX_IFileWrite()); | 
| 55 } | 55 } | 
| 56 | 56 | 
|  | 57 CFX_IFileWrite::CFX_IFileWrite() : m_pFileWriteStruct(nullptr) {} | 
|  | 58 | 
| 57 bool CFX_IFileWrite::Init(FPDF_FILEWRITE* pFileWriteStruct) { | 59 bool CFX_IFileWrite::Init(FPDF_FILEWRITE* pFileWriteStruct) { | 
| 58   if (!pFileWriteStruct) | 60   if (!pFileWriteStruct) | 
| 59     return false; | 61     return false; | 
| 60 | 62 | 
| 61   m_pFileWriteStruct = pFileWriteStruct; | 63   m_pFileWriteStruct = pFileWriteStruct; | 
| 62   return true; | 64   return true; | 
| 63 } | 65 } | 
| 64 | 66 | 
| 65 bool CFX_IFileWrite::WriteBlock(const void* pData, size_t size) { | 67 bool CFX_IFileWrite::WriteBlock(const void* pData, size_t size) { | 
| 66   if (!m_pFileWriteStruct) | 68   if (!m_pFileWriteStruct) | 
| 67     return false; | 69     return false; | 
| 68 | 70 | 
| 69   m_pFileWriteStruct->WriteBlock(m_pFileWriteStruct, pData, size); | 71   m_pFileWriteStruct->WriteBlock(m_pFileWriteStruct, pData, size); | 
| 70   return true; | 72   return true; | 
| 71 } | 73 } | 
| 72 | 74 | 
| 73 void CFX_IFileWrite::Release() { |  | 
| 74   delete this; |  | 
| 75 } |  | 
| 76 |  | 
| 77 namespace { | 75 namespace { | 
| 78 | 76 | 
| 79 #ifdef PDF_ENABLE_XFA | 77 #ifdef PDF_ENABLE_XFA | 
| 80 bool SaveXFADocumentData(CPDFXFA_Context* pContext, | 78 bool SaveXFADocumentData( | 
| 81                          std::vector<ScopedFileStream>* fileList) { | 79     CPDFXFA_Context* pContext, | 
|  | 80     std::vector<CFX_RetainPtr<IFX_SeekableStream>>* fileList) { | 
| 82   if (!pContext) | 81   if (!pContext) | 
| 83     return false; | 82     return false; | 
| 84 | 83 | 
| 85   if (pContext->GetDocType() != DOCTYPE_DYNAMIC_XFA && | 84   if (pContext->GetDocType() != DOCTYPE_DYNAMIC_XFA && | 
| 86       pContext->GetDocType() != DOCTYPE_STATIC_XFA) | 85       pContext->GetDocType() != DOCTYPE_STATIC_XFA) | 
| 87     return true; | 86     return true; | 
| 88 | 87 | 
| 89   CXFA_FFDocView* pXFADocView = pContext->GetXFADocView(); | 88   CXFA_FFDocView* pXFADocView = pContext->GetXFADocView(); | 
| 90   if (!pXFADocView) | 89   if (!pXFADocView) | 
| 91     return true; | 90     return true; | 
| (...skipping 37 matching lines...) Expand 10 before | Expand all | Expand 10 after  Loading... | 
| 129   std::unique_ptr<CXFA_ChecksumContext> pChecksum(new CXFA_ChecksumContext); | 128   std::unique_ptr<CXFA_ChecksumContext> pChecksum(new CXFA_ChecksumContext); | 
| 130   pChecksum->StartChecksum(); | 129   pChecksum->StartChecksum(); | 
| 131 | 130 | 
| 132   // template | 131   // template | 
| 133   if (iTemplate > -1) { | 132   if (iTemplate > -1) { | 
| 134     CPDF_Stream* pTemplateStream = pArray->GetStreamAt(iTemplate); | 133     CPDF_Stream* pTemplateStream = pArray->GetStreamAt(iTemplate); | 
| 135     CPDF_StreamAcc streamAcc; | 134     CPDF_StreamAcc streamAcc; | 
| 136     streamAcc.LoadAllData(pTemplateStream); | 135     streamAcc.LoadAllData(pTemplateStream); | 
| 137     uint8_t* pData = (uint8_t*)streamAcc.GetData(); | 136     uint8_t* pData = (uint8_t*)streamAcc.GetData(); | 
| 138     uint32_t dwSize2 = streamAcc.GetSize(); | 137     uint32_t dwSize2 = streamAcc.GetSize(); | 
| 139     ScopedFileStream pTemplate(IFX_MemoryStream::Create(pData, dwSize2)); | 138     CFX_RetainPtr<IFX_SeekableStream> pTemplate = | 
| 140     pChecksum->UpdateChecksum(pTemplate.get()); | 139         IFX_MemoryStream::Create(pData, dwSize2); | 
|  | 140     pChecksum->UpdateChecksum(pTemplate); | 
| 141   } | 141   } | 
| 142   CPDF_Stream* pFormStream = nullptr; | 142   CPDF_Stream* pFormStream = nullptr; | 
| 143   CPDF_Stream* pDataSetsStream = nullptr; | 143   CPDF_Stream* pDataSetsStream = nullptr; | 
| 144   if (iFormIndex != -1) { | 144   if (iFormIndex != -1) { | 
| 145     // Get form CPDF_Stream | 145     // Get form CPDF_Stream | 
| 146     CPDF_Object* pFormPDFObj = pArray->GetObjectAt(iFormIndex); | 146     CPDF_Object* pFormPDFObj = pArray->GetObjectAt(iFormIndex); | 
| 147     if (pFormPDFObj->IsReference()) { | 147     if (pFormPDFObj->IsReference()) { | 
| 148       CPDF_Object* pFormDirectObj = pFormPDFObj->GetDirect(); | 148       CPDF_Object* pFormDirectObj = pFormPDFObj->GetDirect(); | 
| 149       if (pFormDirectObj && pFormDirectObj->IsStream()) { | 149       if (pFormDirectObj && pFormDirectObj->IsStream()) { | 
| 150         pFormStream = (CPDF_Stream*)pFormDirectObj; | 150         pFormStream = (CPDF_Stream*)pFormDirectObj; | 
| (...skipping 11 matching lines...) Expand all  Loading... | 
| 162       CPDF_Object* pDataSetsDirectObj = pDataSetsRefObj->GetDirect(); | 162       CPDF_Object* pDataSetsDirectObj = pDataSetsRefObj->GetDirect(); | 
| 163       if (pDataSetsDirectObj && pDataSetsDirectObj->IsStream()) { | 163       if (pDataSetsDirectObj && pDataSetsDirectObj->IsStream()) { | 
| 164         pDataSetsStream = (CPDF_Stream*)pDataSetsDirectObj; | 164         pDataSetsStream = (CPDF_Stream*)pDataSetsDirectObj; | 
| 165       } | 165       } | 
| 166     } else if (pDataSetsPDFObj->IsStream()) { | 166     } else if (pDataSetsPDFObj->IsStream()) { | 
| 167       pDataSetsStream = (CPDF_Stream*)pDataSetsPDFObj; | 167       pDataSetsStream = (CPDF_Stream*)pDataSetsPDFObj; | 
| 168     } | 168     } | 
| 169   } | 169   } | 
| 170   // L"datasets" | 170   // L"datasets" | 
| 171   { | 171   { | 
| 172     ScopedFileStream pDsfileWrite(IFX_MemoryStream::Create()); | 172     CFX_RetainPtr<IFX_SeekableStream> pDsfileWrite = IFX_MemoryStream::Create(); | 
| 173     if (pXFADocView->GetDoc()->SavePackage(XFA_HASHCODE_Datasets, | 173     if (pXFADocView->GetDoc()->SavePackage(XFA_HASHCODE_Datasets, pDsfileWrite, | 
| 174                                            pDsfileWrite.get(), nullptr) && | 174                                            nullptr) && | 
| 175         pDsfileWrite->GetSize() > 0) { | 175         pDsfileWrite->GetSize() > 0) { | 
| 176       // Datasets | 176       // Datasets | 
| 177       pChecksum->UpdateChecksum(pDsfileWrite.get()); | 177       pChecksum->UpdateChecksum(pDsfileWrite); | 
| 178       pChecksum->FinishChecksum(); | 178       pChecksum->FinishChecksum(); | 
| 179       auto pDataDict = pdfium::MakeUnique<CPDF_Dictionary>( | 179       auto pDataDict = pdfium::MakeUnique<CPDF_Dictionary>( | 
| 180           pPDFDocument->GetByteStringPool()); | 180           pPDFDocument->GetByteStringPool()); | 
| 181       if (iDataSetsIndex != -1) { | 181       if (iDataSetsIndex != -1) { | 
| 182         if (pDataSetsStream) { | 182         if (pDataSetsStream) { | 
| 183           pDataSetsStream->InitStreamFromFile(pDsfileWrite.get(), | 183           pDataSetsStream->InitStreamFromFile(pDsfileWrite, | 
| 184                                               std::move(pDataDict)); | 184                                               std::move(pDataDict)); | 
| 185         } | 185         } | 
| 186       } else { | 186       } else { | 
| 187         CPDF_Stream* pData = pPDFDocument->NewIndirect<CPDF_Stream>(); | 187         CPDF_Stream* pData = pPDFDocument->NewIndirect<CPDF_Stream>(); | 
| 188         pData->InitStreamFromFile(pDsfileWrite.get(), std::move(pDataDict)); | 188         pData->InitStreamFromFile(pDsfileWrite, std::move(pDataDict)); | 
| 189         iLast = pArray->GetCount() - 2; | 189         iLast = pArray->GetCount() - 2; | 
| 190         pArray->InsertNewAt<CPDF_String>(iLast, "datasets", false); | 190         pArray->InsertNewAt<CPDF_String>(iLast, "datasets", false); | 
| 191         pArray->InsertNewAt<CPDF_Reference>(iLast + 1, pPDFDocument, | 191         pArray->InsertNewAt<CPDF_Reference>(iLast + 1, pPDFDocument, | 
| 192                                             pData->GetObjNum()); | 192                                             pData->GetObjNum()); | 
| 193       } | 193       } | 
| 194       fileList->push_back(std::move(pDsfileWrite)); | 194       fileList->push_back(std::move(pDsfileWrite)); | 
| 195     } | 195     } | 
| 196   } | 196   } | 
| 197   // L"form" | 197   // L"form" | 
| 198   { | 198   { | 
| 199     ScopedFileStream pfileWrite(IFX_MemoryStream::Create()); | 199     CFX_RetainPtr<IFX_SeekableStream> pfileWrite = IFX_MemoryStream::Create(); | 
| 200     if (pXFADocView->GetDoc()->SavePackage(XFA_HASHCODE_Form, pfileWrite.get(), | 200     if (pXFADocView->GetDoc()->SavePackage(XFA_HASHCODE_Form, pfileWrite, | 
| 201                                            pChecksum.get()) && | 201                                            pChecksum.get()) && | 
| 202         pfileWrite->GetSize() > 0) { | 202         pfileWrite->GetSize() > 0) { | 
| 203       auto pDataDict = pdfium::MakeUnique<CPDF_Dictionary>( | 203       auto pDataDict = pdfium::MakeUnique<CPDF_Dictionary>( | 
| 204           pPDFDocument->GetByteStringPool()); | 204           pPDFDocument->GetByteStringPool()); | 
| 205       if (iFormIndex != -1) { | 205       if (iFormIndex != -1) { | 
| 206         if (pFormStream) { | 206         if (pFormStream) | 
| 207           pFormStream->InitStreamFromFile(pfileWrite.get(), | 207           pFormStream->InitStreamFromFile(pfileWrite, std::move(pDataDict)); | 
| 208                                           std::move(pDataDict)); |  | 
| 209         } |  | 
| 210       } else { | 208       } else { | 
| 211         CPDF_Stream* pData = pPDFDocument->NewIndirect<CPDF_Stream>(); | 209         CPDF_Stream* pData = pPDFDocument->NewIndirect<CPDF_Stream>(); | 
| 212         pData->InitStreamFromFile(pfileWrite.get(), std::move(pDataDict)); | 210         pData->InitStreamFromFile(pfileWrite, std::move(pDataDict)); | 
| 213         iLast = pArray->GetCount() - 2; | 211         iLast = pArray->GetCount() - 2; | 
| 214         pArray->InsertNewAt<CPDF_String>(iLast, "form", false); | 212         pArray->InsertNewAt<CPDF_String>(iLast, "form", false); | 
| 215         pArray->InsertNewAt<CPDF_Reference>(iLast + 1, pPDFDocument, | 213         pArray->InsertNewAt<CPDF_Reference>(iLast + 1, pPDFDocument, | 
| 216                                             pData->GetObjNum()); | 214                                             pData->GetObjNum()); | 
| 217       } | 215       } | 
| 218       fileList->push_back(std::move(pfileWrite)); | 216       fileList->push_back(std::move(pfileWrite)); | 
| 219     } | 217     } | 
| 220   } | 218   } | 
| 221   return true; | 219   return true; | 
| 222 } | 220 } | 
| (...skipping 16 matching lines...) Expand all  Loading... | 
| 239   while (CXFA_WidgetAcc* pWidgetAcc = pWidgetAccIterator->MoveToNext()) { | 237   while (CXFA_WidgetAcc* pWidgetAcc = pWidgetAccIterator->MoveToNext()) { | 
| 240     CXFA_EventParam preParam; | 238     CXFA_EventParam preParam; | 
| 241     preParam.m_eType = XFA_EVENT_PostSave; | 239     preParam.m_eType = XFA_EVENT_PostSave; | 
| 242     pWidgetHander->ProcessEvent(pWidgetAcc, &preParam); | 240     pWidgetHander->ProcessEvent(pWidgetAcc, &preParam); | 
| 243   } | 241   } | 
| 244   pXFADocView->UpdateDocView(); | 242   pXFADocView->UpdateDocView(); | 
| 245   pContext->ClearChangeMark(); | 243   pContext->ClearChangeMark(); | 
| 246   return true; | 244   return true; | 
| 247 } | 245 } | 
| 248 | 246 | 
| 249 bool SendPreSaveToXFADoc(CPDFXFA_Context* pContext, | 247 bool SendPreSaveToXFADoc( | 
| 250                          std::vector<ScopedFileStream>* fileList) { | 248     CPDFXFA_Context* pContext, | 
|  | 249     std::vector<CFX_RetainPtr<IFX_SeekableStream>>* fileList) { | 
| 251   if (pContext->GetDocType() != DOCTYPE_DYNAMIC_XFA && | 250   if (pContext->GetDocType() != DOCTYPE_DYNAMIC_XFA && | 
| 252       pContext->GetDocType() != DOCTYPE_STATIC_XFA) | 251       pContext->GetDocType() != DOCTYPE_STATIC_XFA) | 
| 253     return true; | 252     return true; | 
| 254 | 253 | 
| 255   CXFA_FFDocView* pXFADocView = pContext->GetXFADocView(); | 254   CXFA_FFDocView* pXFADocView = pContext->GetXFADocView(); | 
| 256   if (!pXFADocView) | 255   if (!pXFADocView) | 
| 257     return true; | 256     return true; | 
| 258 | 257 | 
| 259   CXFA_FFWidgetHandler* pWidgetHander = pXFADocView->GetWidgetHandler(); | 258   CXFA_FFWidgetHandler* pWidgetHander = pXFADocView->GetWidgetHandler(); | 
| 260   std::unique_ptr<CXFA_WidgetAccIterator> pWidgetAccIterator( | 259   std::unique_ptr<CXFA_WidgetAccIterator> pWidgetAccIterator( | 
| (...skipping 12 matching lines...) Expand all  Loading... | 
| 273                    FPDF_FILEWRITE* pFileWrite, | 272                    FPDF_FILEWRITE* pFileWrite, | 
| 274                    FPDF_DWORD flags, | 273                    FPDF_DWORD flags, | 
| 275                    FPDF_BOOL bSetVersion, | 274                    FPDF_BOOL bSetVersion, | 
| 276                    int fileVerion) { | 275                    int fileVerion) { | 
| 277   CPDF_Document* pPDFDoc = CPDFDocumentFromFPDFDocument(document); | 276   CPDF_Document* pPDFDoc = CPDFDocumentFromFPDFDocument(document); | 
| 278   if (!pPDFDoc) | 277   if (!pPDFDoc) | 
| 279     return 0; | 278     return 0; | 
| 280 | 279 | 
| 281 #ifdef PDF_ENABLE_XFA | 280 #ifdef PDF_ENABLE_XFA | 
| 282   CPDFXFA_Context* pContext = static_cast<CPDFXFA_Context*>(document); | 281   CPDFXFA_Context* pContext = static_cast<CPDFXFA_Context*>(document); | 
| 283   std::vector<ScopedFileStream> fileList; | 282   std::vector<CFX_RetainPtr<IFX_SeekableStream>> fileList; | 
| 284   SendPreSaveToXFADoc(pContext, &fileList); | 283   SendPreSaveToXFADoc(pContext, &fileList); | 
| 285 #endif  // PDF_ENABLE_XFA | 284 #endif  // PDF_ENABLE_XFA | 
| 286 | 285 | 
| 287   if (flags < FPDF_INCREMENTAL || flags > FPDF_REMOVE_SECURITY) | 286   if (flags < FPDF_INCREMENTAL || flags > FPDF_REMOVE_SECURITY) | 
| 288     flags = 0; | 287     flags = 0; | 
| 289 | 288 | 
| 290   CPDF_Creator FileMaker(pPDFDoc); | 289   CPDF_Creator FileMaker(pPDFDoc); | 
| 291   if (bSetVersion) | 290   if (bSetVersion) | 
| 292     FileMaker.SetFileVersion(fileVerion); | 291     FileMaker.SetFileVersion(fileVerion); | 
| 293   if (flags == FPDF_REMOVE_SECURITY) { | 292   if (flags == FPDF_REMOVE_SECURITY) { | 
| 294     flags = 0; | 293     flags = 0; | 
| 295     FileMaker.RemoveSecurity(); | 294     FileMaker.RemoveSecurity(); | 
| 296   } | 295   } | 
| 297 | 296 | 
| 298   CFX_IFileWrite* pStreamWrite = new CFX_IFileWrite; | 297   CFX_RetainPtr<CFX_IFileWrite> pStreamWrite = CFX_IFileWrite::Create(); | 
| 299   pStreamWrite->Init(pFileWrite); | 298   pStreamWrite->Init(pFileWrite); | 
| 300   bool bRet = FileMaker.Create(pStreamWrite, flags); | 299   bool bRet = FileMaker.Create(pStreamWrite, flags); | 
| 301 #ifdef PDF_ENABLE_XFA | 300 #ifdef PDF_ENABLE_XFA | 
| 302   SendPostSaveToXFADoc(pContext); | 301   SendPostSaveToXFADoc(pContext); | 
| 303 #endif  // PDF_ENABLE_XFA | 302 #endif  // PDF_ENABLE_XFA | 
| 304   pStreamWrite->Release(); |  | 
| 305   return bRet; | 303   return bRet; | 
| 306 } | 304 } | 
| 307 | 305 | 
| 308 }  // namespace | 306 }  // namespace | 
| 309 | 307 | 
| 310 DLLEXPORT FPDF_BOOL STDCALL FPDF_SaveAsCopy(FPDF_DOCUMENT document, | 308 DLLEXPORT FPDF_BOOL STDCALL FPDF_SaveAsCopy(FPDF_DOCUMENT document, | 
| 311                                             FPDF_FILEWRITE* pFileWrite, | 309                                             FPDF_FILEWRITE* pFileWrite, | 
| 312                                             FPDF_DWORD flags) { | 310                                             FPDF_DWORD flags) { | 
| 313   return FPDF_Doc_Save(document, pFileWrite, flags, false, 0); | 311   return FPDF_Doc_Save(document, pFileWrite, flags, false, 0); | 
| 314 } | 312 } | 
| 315 | 313 | 
| 316 DLLEXPORT FPDF_BOOL STDCALL FPDF_SaveWithVersion(FPDF_DOCUMENT document, | 314 DLLEXPORT FPDF_BOOL STDCALL FPDF_SaveWithVersion(FPDF_DOCUMENT document, | 
| 317                                                  FPDF_FILEWRITE* pFileWrite, | 315                                                  FPDF_FILEWRITE* pFileWrite, | 
| 318                                                  FPDF_DWORD flags, | 316                                                  FPDF_DWORD flags, | 
| 319                                                  int fileVersion) { | 317                                                  int fileVersion) { | 
| 320   return FPDF_Doc_Save(document, pFileWrite, flags, true, fileVersion); | 318   return FPDF_Doc_Save(document, pFileWrite, flags, true, fileVersion); | 
| 321 } | 319 } | 
| OLD | NEW | 
|---|