From c68b1e73ce8210e2b33491da160dda5dd48599c0 Mon Sep 17 00:00:00 2001 From: Dan Sinclair Date: Mon, 8 May 2017 16:59:54 -0400 Subject: Remove AppendObject from CPDF_Creator The AppendObject method has been removed and the functionality moved to the individual CPDF_Object classes. Change-Id: I5446c6cc3e792d849acf77caed34b63a88f3a2d2 Reviewed-on: https://pdfium-review.googlesource.com/5072 Commit-Queue: dsinclair Reviewed-by: Tom Sepez --- core/fpdfapi/edit/fpdf_edit_create.cpp | 240 +++++--------------------------- core/fpdfapi/parser/cpdf_array.cpp | 29 ++++ core/fpdfapi/parser/cpdf_array.h | 2 + core/fpdfapi/parser/cpdf_boolean.cpp | 12 ++ core/fpdfapi/parser/cpdf_boolean.h | 2 + core/fpdfapi/parser/cpdf_dictionary.cpp | 39 ++++++ core/fpdfapi/parser/cpdf_dictionary.h | 2 + core/fpdfapi/parser/cpdf_name.cpp | 13 ++ core/fpdfapi/parser/cpdf_name.h | 2 + core/fpdfapi/parser/cpdf_null.cpp | 8 ++ core/fpdfapi/parser/cpdf_null.h | 2 + core/fpdfapi/parser/cpdf_number.cpp | 12 ++ core/fpdfapi/parser/cpdf_number.h | 2 + core/fpdfapi/parser/cpdf_object.h | 4 + core/fpdfapi/parser/cpdf_reference.cpp | 13 ++ core/fpdfapi/parser/cpdf_reference.h | 2 + core/fpdfapi/parser/cpdf_stream.cpp | 22 +++ core/fpdfapi/parser/cpdf_stream.h | 2 + core/fpdfapi/parser/cpdf_string.cpp | 11 ++ core/fpdfapi/parser/cpdf_string.h | 2 + 20 files changed, 214 insertions(+), 207 deletions(-) diff --git a/core/fpdfapi/edit/fpdf_edit_create.cpp b/core/fpdfapi/edit/fpdf_edit_create.cpp index 63c0930c11..5b4c3ad4d0 100644 --- a/core/fpdfapi/edit/fpdf_edit_create.cpp +++ b/core/fpdfapi/edit/fpdf_edit_create.cpp @@ -34,155 +34,6 @@ namespace { const uint32_t kXRefStreamMaxSize = 10000; const int kObjectStreamMaxLength = 256 * 1024; -int32_t AppendObject(const CPDF_Object* pObj, - CFX_FileBufferArchive* pFile, - FX_FILESIZE& offset) { - int32_t len = 0; - if (!pObj) { - if (pFile->AppendString(" null") < 0) - return -1; - - offset += 5; - return 1; - } - switch (pObj->GetType()) { - case CPDF_Object::NULLOBJ: - if (pFile->AppendString(" null") < 0) - return -1; - - offset += 5; - break; - case CPDF_Object::BOOLEAN: - case CPDF_Object::NUMBER: - if (pFile->AppendString(" ") < 0) - return -1; - if ((len = pFile->AppendString(pObj->GetString().AsStringC())) < 0) - return -1; - - offset += len + 1; - break; - case CPDF_Object::STRING: { - CFX_ByteString str = pObj->GetString(); - bool bHex = pObj->AsString()->IsHex(); - if ((len = pFile->AppendString(PDF_EncodeString(str, bHex).AsStringC())) < - 0) { - return -1; - } - offset += len; - break; - } - case CPDF_Object::NAME: { - if (pFile->AppendString("/") < 0) - return -1; - - CFX_ByteString str = pObj->GetString(); - if ((len = pFile->AppendString(PDF_NameEncode(str).AsStringC())) < 0) - return -1; - - offset += len + 1; - break; - } - case CPDF_Object::REFERENCE: { - if (pFile->AppendString(" ") < 0) - return -1; - if ((len = pFile->AppendDWord(pObj->AsReference()->GetRefObjNum())) < 0) - return -1; - if (pFile->AppendString(" 0 R ") < 0) - return -1; - - offset += len + 6; - break; - } - case CPDF_Object::ARRAY: { - if (pFile->AppendString("[") < 0) - return -1; - - offset += 1; - const CPDF_Array* p = pObj->AsArray(); - for (size_t i = 0; i < p->GetCount(); i++) { - CPDF_Object* pElement = p->GetObjectAt(i); - if (!pElement->IsInline()) { - if (pFile->AppendString(" ") < 0) - return -1; - if ((len = pFile->AppendDWord(pElement->GetObjNum())) < 0) - return -1; - if (pFile->AppendString(" 0 R") < 0) - return -1; - - offset += len + 5; - } else { - if (AppendObject(pElement, pFile, offset) < 0) - return -1; - } - } - if (pFile->AppendString("]") < 0) - return -1; - - offset += 1; - break; - } - case CPDF_Object::DICTIONARY: { - if (pFile->AppendString("<<") < 0) - return -1; - - offset += 2; - const CPDF_Dictionary* p = pObj->AsDictionary(); - for (const auto& it : *p) { - const CFX_ByteString& key = it.first; - CPDF_Object* pValue = it.second.get(); - if (pFile->AppendString("/") < 0) - return -1; - if ((len = pFile->AppendString(PDF_NameEncode(key).AsStringC())) < 0) - return -1; - - offset += len + 1; - if (!pValue->IsInline()) { - if (pFile->AppendString(" ") < 0) - return -1; - if ((len = pFile->AppendDWord(pValue->GetObjNum())) < 0) - return -1; - if (pFile->AppendString(" 0 R") < 0) - return -1; - - offset += len + 5; - } else { - if (AppendObject(pValue, pFile, offset) < 0) - return -1; - } - } - if (pFile->AppendString(">>") < 0) - return -1; - - offset += 2; - break; - } - case CPDF_Object::STREAM: { - const CPDF_Stream* p = pObj->AsStream(); - if (AppendObject(p->GetDict(), pFile, offset) < 0) - return -1; - if (pFile->AppendString("stream\r\n") < 0) - return -1; - - offset += 8; - auto pAcc = pdfium::MakeRetain(p); - pAcc->LoadAllData(true); - if (pFile->AppendBlock(pAcc->GetData(), pAcc->GetSize()) < 0) - return -1; - - offset += pAcc->GetSize(); - if ((len = pFile->AppendString("\r\nendstream")) < 0) - return -1; - - offset += len; - break; - } - default: - ASSERT(false); - break; - } - return 1; -} - int32_t WriteTrailer(CPDF_Document* pDocument, CFX_FileBufferArchive* pFile, CPDF_Array* pIDArray) { @@ -217,7 +68,7 @@ int32_t WriteTrailer(CPDF_Document* pDocument, offset += len + 6; } else { - if (AppendObject(pValue, pFile, offset) < 0) + if (!pValue->WriteTo(pFile, &offset)) return -1; } } @@ -226,7 +77,7 @@ int32_t WriteTrailer(CPDF_Document* pDocument, return -1; offset += 3; - if (AppendObject(pIDArray, pFile, offset) < 0) + if (!pIDArray->WriteTo(pFile, &offset)) return -1; } return offset; @@ -254,7 +105,7 @@ int32_t WriteTrailer(CPDF_Document* pDocument, return -1; offset += 3; - if (AppendObject(pIDArray, pFile, offset) < 0) + if (!pIDArray->WriteTo(pFile, &offset)) return -1; } return offset; @@ -992,40 +843,22 @@ int32_t CPDF_Creator::WriteIndirectObj(const CPDF_Object* pObj) { int32_t CPDF_Creator::WriteDirectObj(uint32_t objnum, const CPDF_Object* pObj, bool bEncrypt) { - int32_t len = 0; - if (!pObj) { - if (m_File.AppendString(" null") < 0) - return -1; - - m_Offset += 5; - return 1; - } - switch (pObj->GetType()) { - case CPDF_Object::NULLOBJ: - if (m_File.AppendString(" null") < 0) - return -1; - - m_Offset += 5; - break; case CPDF_Object::BOOLEAN: + case CPDF_Object::NAME: + case CPDF_Object::NULLOBJ: case CPDF_Object::NUMBER: - if (m_File.AppendString(" ") < 0) - return -1; - if ((len = m_File.AppendString(pObj->GetString().AsStringC())) < 0) + case CPDF_Object::REFERENCE: + if (!pObj->WriteTo(&m_File, &m_Offset)) return -1; - - m_Offset += len + 1; break; + case CPDF_Object::STRING: { CFX_ByteString str = pObj->GetString(); bool bHex = pObj->AsString()->IsHex(); if (!m_pCryptoHandler || !bEncrypt) { - CFX_ByteString content = PDF_EncodeString(str, bHex); - if ((len = m_File.AppendString(content.AsStringC())) < 0) + if (!pObj->WriteTo(&m_File, &m_Offset)) return -1; - - m_Offset += len; break; } CPDF_Encryptor encryptor(m_pCryptoHandler.Get(), objnum, @@ -1033,7 +866,8 @@ int32_t CPDF_Creator::WriteDirectObj(uint32_t objnum, CFX_ByteString content = PDF_EncodeString( CFX_ByteString((const char*)encryptor.m_pData, encryptor.m_dwSize), bHex); - if ((len = m_File.AppendString(content.AsStringC())) < 0) + int32_t len = m_File.AppendString(content.AsStringC()); + if (len < 0) return -1; m_Offset += len; @@ -1052,7 +886,9 @@ int32_t CPDF_Creator::WriteDirectObj(uint32_t objnum, } if (WriteDirectObj(objnum, encoder.m_pDict.Get()) < 0) return -1; - if ((len = m_File.AppendString("stream\r\n")) < 0) + + int32_t len = m_File.AppendString("stream\r\n"); + if (len < 0) return -1; m_Offset += len; @@ -1060,33 +896,13 @@ int32_t CPDF_Creator::WriteDirectObj(uint32_t objnum, return -1; m_Offset += encryptor.m_dwSize; - if ((len = m_File.AppendString("\r\nendstream")) < 0) + len = m_File.AppendString("\r\nendstream"); + if (len < 0) return -1; m_Offset += len; break; } - case CPDF_Object::NAME: { - if (m_File.AppendString("/") < 0) - return -1; - - CFX_ByteString str = pObj->GetString(); - if ((len = m_File.AppendString(PDF_NameEncode(str).AsStringC())) < 0) - return -1; - - m_Offset += len + 1; - break; - } - case CPDF_Object::REFERENCE: { - if (m_File.AppendString(" ") < 0) - return -1; - if ((len = m_File.AppendDWord(pObj->AsReference()->GetRefObjNum())) < 0) - return -1; - if (m_File.AppendString(" 0 R") < 0) - return -1; - m_Offset += len + 5; - break; - } case CPDF_Object::ARRAY: { if (m_File.AppendString("[") < 0) return -1; @@ -1098,7 +914,9 @@ int32_t CPDF_Creator::WriteDirectObj(uint32_t objnum, if (!pElement->IsInline()) { if (m_File.AppendString(" ") < 0) return -1; - if ((len = m_File.AppendDWord(pElement->GetObjNum())) < 0) + + int32_t len = m_File.AppendDWord(pElement->GetObjNum()); + if (len < 0) return -1; if (m_File.AppendString(" 0 R") < 0) return -1; @@ -1116,8 +934,12 @@ int32_t CPDF_Creator::WriteDirectObj(uint32_t objnum, break; } case CPDF_Object::DICTIONARY: { - if (!m_pCryptoHandler || pObj == m_pEncryptDict) - return AppendObject(pObj, &m_File, m_Offset); + if (!m_pCryptoHandler || pObj == m_pEncryptDict) { + if (!pObj->WriteTo(&m_File, &m_Offset)) + return -1; + break; + } + if (m_File.AppendString("<<") < 0) return -1; @@ -1130,7 +952,9 @@ int32_t CPDF_Creator::WriteDirectObj(uint32_t objnum, CPDF_Object* pValue = it.second.get(); if (m_File.AppendString("/") < 0) return -1; - if ((len = m_File.AppendString(PDF_NameEncode(key).AsStringC())) < 0) + + int32_t len = m_File.AppendString(PDF_NameEncode(key).AsStringC()); + if (len < 0) return -1; m_Offset += len + 1; @@ -1140,7 +964,9 @@ int32_t CPDF_Creator::WriteDirectObj(uint32_t objnum, if (!pValue->IsInline()) { if (m_File.AppendString(" ") < 0) return -1; - if ((len = m_File.AppendDWord(pValue->GetObjNum())) < 0) + + len = m_File.AppendDWord(pValue->GetObjNum()); + if (len < 0) return -1; if (m_File.AppendString(" 0 R ") < 0) return -1; @@ -1574,7 +1400,7 @@ int32_t CPDF_Creator::WriteDoc_Stage4() { return -1; } else { FX_FILESIZE offset = 0; - if (AppendObject(pValue, &m_File, offset) < 0) + if (!pValue->WriteTo(&m_File, &offset)) return -1; } } @@ -1631,7 +1457,7 @@ int32_t CPDF_Creator::WriteDoc_Stage4() { return -1; FX_FILESIZE offset = 0; - if (AppendObject(m_pIDArray.get(), &m_File, offset) < 0) + if (!m_pIDArray->WriteTo(&m_File, &offset)) return -1; } if (!bXRefStream) { diff --git a/core/fpdfapi/parser/cpdf_array.cpp b/core/fpdfapi/parser/cpdf_array.cpp index f3c23f37be..aa10588f87 100644 --- a/core/fpdfapi/parser/cpdf_array.cpp +++ b/core/fpdfapi/parser/cpdf_array.cpp @@ -193,3 +193,32 @@ CPDF_Object* CPDF_Array::Add(std::unique_ptr pObj) { m_Objects.push_back(std::move(pObj)); return pRet; } + +bool CPDF_Array::WriteTo(CFX_FileBufferArchive* archive, + FX_FILESIZE* offset) const { + if (archive->AppendString("[") < 0) + return false; + *offset += 1; + + for (size_t i = 0; i < GetCount(); ++i) { + CPDF_Object* pElement = GetObjectAt(i); + if (!pElement->IsInline()) { + if (archive->AppendString(" ") < 0) + return false; + + int32_t len = archive->AppendDWord(pElement->GetObjNum()); + if (len < 0) + return false; + if (archive->AppendString(" 0 R") < 0) + return false; + *offset += len + 5; + } else { + if (!pElement->WriteTo(archive, offset)) + return false; + } + } + if (archive->AppendString("]") < 0) + return false; + *offset += 1; + return true; +} diff --git a/core/fpdfapi/parser/cpdf_array.h b/core/fpdfapi/parser/cpdf_array.h index 8f8b600c7e..b788d1c075 100644 --- a/core/fpdfapi/parser/cpdf_array.h +++ b/core/fpdfapi/parser/cpdf_array.h @@ -34,6 +34,8 @@ class CPDF_Array : public CPDF_Object { bool IsArray() const override; CPDF_Array* AsArray() override; const CPDF_Array* AsArray() const override; + bool WriteTo(CFX_FileBufferArchive* archive, + FX_FILESIZE* offset) const override; bool IsEmpty() const { return m_Objects.empty(); } size_t GetCount() const { return m_Objects.size(); } diff --git a/core/fpdfapi/parser/cpdf_boolean.cpp b/core/fpdfapi/parser/cpdf_boolean.cpp index 0204fd9eb0..1cee3a3a49 100644 --- a/core/fpdfapi/parser/cpdf_boolean.cpp +++ b/core/fpdfapi/parser/cpdf_boolean.cpp @@ -44,3 +44,15 @@ CPDF_Boolean* CPDF_Boolean::AsBoolean() { const CPDF_Boolean* CPDF_Boolean::AsBoolean() const { return this; } + +bool CPDF_Boolean::WriteTo(CFX_FileBufferArchive* archive, + FX_FILESIZE* offset) const { + if (archive->AppendString(" ") < 0) + return false; + + int32_t len = archive->AppendString(GetString().AsStringC()); + if (len < 0) + return false; + *offset += len + 1; + return true; +} diff --git a/core/fpdfapi/parser/cpdf_boolean.h b/core/fpdfapi/parser/cpdf_boolean.h index afebc29448..e859f4cf9c 100644 --- a/core/fpdfapi/parser/cpdf_boolean.h +++ b/core/fpdfapi/parser/cpdf_boolean.h @@ -28,6 +28,8 @@ class CPDF_Boolean : public CPDF_Object { bool IsBoolean() const override; CPDF_Boolean* AsBoolean() override; const CPDF_Boolean* AsBoolean() const override; + bool WriteTo(CFX_FileBufferArchive* archive, + FX_FILESIZE* offset) const override; protected: bool m_bValue; diff --git a/core/fpdfapi/parser/cpdf_dictionary.cpp b/core/fpdfapi/parser/cpdf_dictionary.cpp index d4e4080d31..7d84083829 100644 --- a/core/fpdfapi/parser/cpdf_dictionary.cpp +++ b/core/fpdfapi/parser/cpdf_dictionary.cpp @@ -16,6 +16,7 @@ #include "core/fpdfapi/parser/cpdf_reference.h" #include "core/fpdfapi/parser/cpdf_stream.h" #include "core/fpdfapi/parser/cpdf_string.h" +#include "core/fpdfapi/parser/fpdf_parser_decode.h" #include "third_party/base/logging.h" #include "third_party/base/stl_util.h" @@ -237,3 +238,41 @@ void CPDF_Dictionary::SetMatrixFor(const CFX_ByteString& key, CFX_ByteString CPDF_Dictionary::MaybeIntern(const CFX_ByteString& str) { return m_pPool ? m_pPool->Intern(str) : str; } + +bool CPDF_Dictionary::WriteTo(CFX_FileBufferArchive* archive, + FX_FILESIZE* offset) const { + if (archive->AppendString("<<") < 0) + return false; + *offset += 2; + + for (const auto& it : *this) { + const CFX_ByteString& key = it.first; + CPDF_Object* pValue = it.second.get(); + if (archive->AppendString("/") < 0) + return false; + + int32_t len = archive->AppendString(PDF_NameEncode(key).AsStringC()); + if (len < 0) + return false; + *offset += len + 1; + + if (!pValue->IsInline()) { + if (archive->AppendString(" ") < 0) + return false; + + len = archive->AppendDWord(pValue->GetObjNum()); + if (len < 0) + return false; + if (archive->AppendString(" 0 R") < 0) + return false; + *offset += len + 5; + } else { + if (!pValue->WriteTo(archive, offset)) + return false; + } + } + if (archive->AppendString(">>") < 0) + return false; + *offset += 2; + return true; +} diff --git a/core/fpdfapi/parser/cpdf_dictionary.h b/core/fpdfapi/parser/cpdf_dictionary.h index b14574fd61..e4144c1524 100644 --- a/core/fpdfapi/parser/cpdf_dictionary.h +++ b/core/fpdfapi/parser/cpdf_dictionary.h @@ -37,6 +37,8 @@ class CPDF_Dictionary : public CPDF_Object { bool IsDictionary() const override; CPDF_Dictionary* AsDictionary() override; const CPDF_Dictionary* AsDictionary() const override; + bool WriteTo(CFX_FileBufferArchive* archive, + FX_FILESIZE* offset) const override; size_t GetCount() const { return m_Map.size(); } CPDF_Object* GetObjectFor(const CFX_ByteString& key) const; diff --git a/core/fpdfapi/parser/cpdf_name.cpp b/core/fpdfapi/parser/cpdf_name.cpp index 5be64d39d5..74c83b9d28 100644 --- a/core/fpdfapi/parser/cpdf_name.cpp +++ b/core/fpdfapi/parser/cpdf_name.cpp @@ -49,3 +49,16 @@ const CPDF_Name* CPDF_Name::AsName() const { CFX_WideString CPDF_Name::GetUnicodeText() const { return PDF_DecodeText(m_Name); } + +bool CPDF_Name::WriteTo(CFX_FileBufferArchive* archive, + FX_FILESIZE* offset) const { + if (archive->AppendString("/") < 0) + return false; + + CFX_ByteString str = GetString(); + int32_t len = archive->AppendString(PDF_NameEncode(str).AsStringC()); + if (len < 0) + return false; + *offset += len + 1; + return true; +} diff --git a/core/fpdfapi/parser/cpdf_name.h b/core/fpdfapi/parser/cpdf_name.h index 61318d4afb..8855f9785c 100644 --- a/core/fpdfapi/parser/cpdf_name.h +++ b/core/fpdfapi/parser/cpdf_name.h @@ -27,6 +27,8 @@ class CPDF_Name : public CPDF_Object { bool IsName() const override; CPDF_Name* AsName() override; const CPDF_Name* AsName() const override; + bool WriteTo(CFX_FileBufferArchive* archive, + FX_FILESIZE* offset) const override; protected: CFX_ByteString m_Name; diff --git a/core/fpdfapi/parser/cpdf_null.cpp b/core/fpdfapi/parser/cpdf_null.cpp index 41478d7b4c..b5e07e0c55 100644 --- a/core/fpdfapi/parser/cpdf_null.cpp +++ b/core/fpdfapi/parser/cpdf_null.cpp @@ -16,3 +16,11 @@ CPDF_Object::Type CPDF_Null::GetType() const { std::unique_ptr CPDF_Null::Clone() const { return pdfium::MakeUnique(); } + +bool CPDF_Null::WriteTo(CFX_FileBufferArchive* archive, + FX_FILESIZE* offset) const { + if (archive->AppendString(" null") < 0) + return false; + *offset += 5; + return true; +} diff --git a/core/fpdfapi/parser/cpdf_null.h b/core/fpdfapi/parser/cpdf_null.h index 4f8420f29d..b6b781b01a 100644 --- a/core/fpdfapi/parser/cpdf_null.h +++ b/core/fpdfapi/parser/cpdf_null.h @@ -18,6 +18,8 @@ class CPDF_Null : public CPDF_Object { // CPDF_Object. Type GetType() const override; std::unique_ptr Clone() const override; + bool WriteTo(CFX_FileBufferArchive* archive, + FX_FILESIZE* offset) const override; }; #endif // CORE_FPDFAPI_PARSER_CPDF_NULL_H_ diff --git a/core/fpdfapi/parser/cpdf_number.cpp b/core/fpdfapi/parser/cpdf_number.cpp index c83b9dcd38..24665fff60 100644 --- a/core/fpdfapi/parser/cpdf_number.cpp +++ b/core/fpdfapi/parser/cpdf_number.cpp @@ -55,3 +55,15 @@ CFX_ByteString CPDF_Number::GetString() const { return m_bInteger ? CFX_ByteString::FormatInteger(m_Integer, FXFORMAT_SIGNED) : CFX_ByteString::FormatFloat(m_Float); } + +bool CPDF_Number::WriteTo(CFX_FileBufferArchive* archive, + FX_FILESIZE* offset) const { + if (archive->AppendString(" ") < 0) + return false; + + int32_t len = archive->AppendString(GetString().AsStringC()); + if (len < 0) + return false; + *offset += len + 1; + return true; +} diff --git a/core/fpdfapi/parser/cpdf_number.h b/core/fpdfapi/parser/cpdf_number.h index 6e85044d2a..a5d866f835 100644 --- a/core/fpdfapi/parser/cpdf_number.h +++ b/core/fpdfapi/parser/cpdf_number.h @@ -31,6 +31,8 @@ class CPDF_Number : public CPDF_Object { bool IsNumber() const override; CPDF_Number* AsNumber() override; const CPDF_Number* AsNumber() const override; + bool WriteTo(CFX_FileBufferArchive* archive, + FX_FILESIZE* offset) const override; bool IsInteger() const { return m_bInteger; } diff --git a/core/fpdfapi/parser/cpdf_object.h b/core/fpdfapi/parser/cpdf_object.h index 616573724b..8194256f5a 100644 --- a/core/fpdfapi/parser/cpdf_object.h +++ b/core/fpdfapi/parser/cpdf_object.h @@ -11,6 +11,7 @@ #include #include +#include "core/fxcrt/fx_basic.h" #include "core/fxcrt/fx_string.h" #include "core/fxcrt/fx_system.h" @@ -88,6 +89,9 @@ class CPDF_Object { virtual CPDF_String* AsString(); virtual const CPDF_String* AsString() const; + virtual bool WriteTo(CFX_FileBufferArchive* archive, + FX_FILESIZE* offset) const = 0; + protected: friend class CPDF_Array; friend class CPDF_Dictionary; diff --git a/core/fpdfapi/parser/cpdf_reference.cpp b/core/fpdfapi/parser/cpdf_reference.cpp index 942bae58ba..560fd27934 100644 --- a/core/fpdfapi/parser/cpdf_reference.cpp +++ b/core/fpdfapi/parser/cpdf_reference.cpp @@ -82,3 +82,16 @@ CPDF_Object* CPDF_Reference::GetDirect() const { return m_pObjList ? m_pObjList->GetOrParseIndirectObject(m_RefObjNum) : nullptr; } + +bool CPDF_Reference::WriteTo(CFX_FileBufferArchive* archive, + FX_FILESIZE* offset) const { + if (archive->AppendString(" ") < 0) + return false; + int32_t len = archive->AppendDWord(GetRefObjNum()); + if (len < 0) + return false; + if (archive->AppendString(" 0 R ") < 0) + return false; + *offset += len + 6; + return true; +} diff --git a/core/fpdfapi/parser/cpdf_reference.h b/core/fpdfapi/parser/cpdf_reference.h index ff8875572c..4830cb5bf6 100644 --- a/core/fpdfapi/parser/cpdf_reference.h +++ b/core/fpdfapi/parser/cpdf_reference.h @@ -30,6 +30,8 @@ class CPDF_Reference : public CPDF_Object { bool IsReference() const override; CPDF_Reference* AsReference() override; const CPDF_Reference* AsReference() const override; + bool WriteTo(CFX_FileBufferArchive* archive, + FX_FILESIZE* offset) const override; CPDF_IndirectObjectHolder* GetObjList() const { return m_pObjList; } uint32_t GetRefObjNum() const { return m_RefObjNum; } diff --git a/core/fpdfapi/parser/cpdf_stream.cpp b/core/fpdfapi/parser/cpdf_stream.cpp index e4f279a32d..7e2529e1d7 100644 --- a/core/fpdfapi/parser/cpdf_stream.cpp +++ b/core/fpdfapi/parser/cpdf_stream.cpp @@ -131,3 +131,25 @@ CFX_WideString CPDF_Stream::GetUnicodeText() const { pAcc->LoadAllData(false); return PDF_DecodeText(pAcc->GetData(), pAcc->GetSize()); } + +bool CPDF_Stream::WriteTo(CFX_FileBufferArchive* archive, + FX_FILESIZE* offset) const { + if (!GetDict()->WriteTo(archive, offset)) + return false; + if (archive->AppendString("stream\r\n") < 0) + return false; + *offset += 8; + + auto pAcc = pdfium::MakeRetain(this); + pAcc->LoadAllData(true); + if (archive->AppendBlock(pAcc->GetData(), pAcc->GetSize()) < 0) + return false; + *offset += pAcc->GetSize(); + + int32_t len = archive->AppendString("\r\nendstream"); + if (len < 0) + return false; + + *offset += len; + return true; +} diff --git a/core/fpdfapi/parser/cpdf_stream.h b/core/fpdfapi/parser/cpdf_stream.h index 902cd75365..4f76953efe 100644 --- a/core/fpdfapi/parser/cpdf_stream.h +++ b/core/fpdfapi/parser/cpdf_stream.h @@ -33,6 +33,8 @@ class CPDF_Stream : public CPDF_Object { bool IsStream() const override; CPDF_Stream* AsStream() override; const CPDF_Stream* AsStream() const override; + bool WriteTo(CFX_FileBufferArchive* archive, + FX_FILESIZE* offset) const override; uint32_t GetRawSize() const { return m_dwSize; } uint8_t* GetRawData() const { return m_pDataBuf.get(); } diff --git a/core/fpdfapi/parser/cpdf_string.cpp b/core/fpdfapi/parser/cpdf_string.cpp index 06bae54916..01cf3ff1b0 100644 --- a/core/fpdfapi/parser/cpdf_string.cpp +++ b/core/fpdfapi/parser/cpdf_string.cpp @@ -64,3 +64,14 @@ const CPDF_String* CPDF_String::AsString() const { CFX_WideString CPDF_String::GetUnicodeText() const { return PDF_DecodeText(m_String); } + +bool CPDF_String::WriteTo(CFX_FileBufferArchive* archive, + FX_FILESIZE* offset) const { + CFX_ByteString str = GetString(); + int32_t len = + archive->AppendString(PDF_EncodeString(str, IsHex()).AsStringC()); + if (len < 0) + return false; + *offset += len; + return true; +} diff --git a/core/fpdfapi/parser/cpdf_string.h b/core/fpdfapi/parser/cpdf_string.h index 6698d8c5be..f895535a92 100644 --- a/core/fpdfapi/parser/cpdf_string.h +++ b/core/fpdfapi/parser/cpdf_string.h @@ -33,6 +33,8 @@ class CPDF_String : public CPDF_Object { bool IsString() const override; CPDF_String* AsString() override; const CPDF_String* AsString() const override; + bool WriteTo(CFX_FileBufferArchive* archive, + FX_FILESIZE* offset) const override; bool IsHex() const { return m_bHex; } -- cgit v1.2.3