summaryrefslogtreecommitdiff
path: root/core/fpdfapi
diff options
context:
space:
mode:
Diffstat (limited to 'core/fpdfapi')
-rw-r--r--core/fpdfapi/edit/fpdf_edit_create.cpp240
-rw-r--r--core/fpdfapi/parser/cpdf_array.cpp29
-rw-r--r--core/fpdfapi/parser/cpdf_array.h2
-rw-r--r--core/fpdfapi/parser/cpdf_boolean.cpp12
-rw-r--r--core/fpdfapi/parser/cpdf_boolean.h2
-rw-r--r--core/fpdfapi/parser/cpdf_dictionary.cpp39
-rw-r--r--core/fpdfapi/parser/cpdf_dictionary.h2
-rw-r--r--core/fpdfapi/parser/cpdf_name.cpp13
-rw-r--r--core/fpdfapi/parser/cpdf_name.h2
-rw-r--r--core/fpdfapi/parser/cpdf_null.cpp8
-rw-r--r--core/fpdfapi/parser/cpdf_null.h2
-rw-r--r--core/fpdfapi/parser/cpdf_number.cpp12
-rw-r--r--core/fpdfapi/parser/cpdf_number.h2
-rw-r--r--core/fpdfapi/parser/cpdf_object.h4
-rw-r--r--core/fpdfapi/parser/cpdf_reference.cpp13
-rw-r--r--core/fpdfapi/parser/cpdf_reference.h2
-rw-r--r--core/fpdfapi/parser/cpdf_stream.cpp22
-rw-r--r--core/fpdfapi/parser/cpdf_stream.h2
-rw-r--r--core/fpdfapi/parser/cpdf_string.cpp11
-rw-r--r--core/fpdfapi/parser/cpdf_string.h2
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<CPDF_StreamAcc>(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<CPDF_Object> 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_Object> CPDF_Null::Clone() const {
return pdfium::MakeUnique<CPDF_Null>();
}
+
+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<CPDF_Object> 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 <set>
#include <type_traits>
+#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<CPDF_StreamAcc>(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; }