summaryrefslogtreecommitdiff
path: root/core/fpdfapi/parser/cpdf_stream.cpp
diff options
context:
space:
mode:
authorArtem Strygin <art-snake@yandex-team.ru>2018-07-23 19:54:34 +0000
committerChromium commit bot <commit-bot@chromium.org>2018-07-23 19:54:34 +0000
commit2bfa78540c375916ec9973f0ae11271b098180bd (patch)
tree4ec0b11e0014c95acda8a2e0b54e1bacd9f349d1 /core/fpdfapi/parser/cpdf_stream.cpp
parent9f53dc093a9d00342ea76ecc0b4c8c84357ffd6e (diff)
downloadpdfium-2bfa78540c375916ec9973f0ae11271b098180bd.tar.xz
Rework of CPDF_Object writing.
Move writing logic into implementation of related clases. Change-Id: If70dc418b352b562ee681ea34fa6595d6f52eee3 Reviewed-on: https://pdfium-review.googlesource.com/36350 Commit-Queue: Art Snake <art-snake@yandex-team.ru> Reviewed-by: Tom Sepez <tsepez@chromium.org>
Diffstat (limited to 'core/fpdfapi/parser/cpdf_stream.cpp')
-rw-r--r--core/fpdfapi/parser/cpdf_stream.cpp45
1 files changed, 39 insertions, 6 deletions
diff --git a/core/fpdfapi/parser/cpdf_stream.cpp b/core/fpdfapi/parser/cpdf_stream.cpp
index fdbe308878..64478996a8 100644
--- a/core/fpdfapi/parser/cpdf_stream.cpp
+++ b/core/fpdfapi/parser/cpdf_stream.cpp
@@ -7,8 +7,11 @@
#include "core/fpdfapi/parser/cpdf_stream.h"
#include <utility>
+#include <vector>
#include "constants/stream_dict_common.h"
+#include "core/fpdfapi/edit/cpdf_encryptor.h"
+#include "core/fpdfapi/edit/cpdf_flateencoder.h"
#include "core/fpdfapi/parser/cpdf_dictionary.h"
#include "core/fpdfapi/parser/cpdf_number.h"
#include "core/fpdfapi/parser/cpdf_stream_acc.h"
@@ -18,6 +21,15 @@
#include "third_party/base/ptr_util.h"
#include "third_party/base/stl_util.h"
+namespace {
+
+bool IsMetaDataStreamDictionary(const CPDF_Dictionary* dict) {
+ return dict && dict->GetStringFor("Type") == "Metadata" &&
+ dict->GetStringFor("Subtype") == "XML";
+}
+
+} // namespace
+
CPDF_Stream::CPDF_Stream() {}
CPDF_Stream::CPDF_Stream(std::unique_ptr<uint8_t, FxFreeDeleter> pData,
@@ -167,12 +179,33 @@ WideString CPDF_Stream::GetUnicodeText() const {
return PDF_DecodeText(pAcc->GetData(), pAcc->GetSize());
}
-bool CPDF_Stream::WriteTo(IFX_ArchiveStream* archive) const {
- if (!GetDict()->WriteTo(archive) || !archive->WriteString("stream\r\n"))
+bool CPDF_Stream::WriteTo(IFX_ArchiveStream* archive,
+ const CPDF_Encryptor* encryptor) const {
+ const bool is_metadata = IsMetaDataStreamDictionary(GetDict());
+ CPDF_FlateEncoder encoder(this, !is_metadata);
+
+ std::vector<uint8_t> encrypted_data;
+ pdfium::span<const uint8_t> data = encoder.GetSpan();
+
+ if (encryptor && !is_metadata) {
+ encrypted_data = encryptor->Encrypt(data);
+ data = encrypted_data;
+ }
+
+ if (static_cast<uint32_t>(encoder.GetDict()->GetIntegerFor("Length")) !=
+ data.size()) {
+ encoder.CloneDict();
+ encoder.GetClonedDict()->SetNewFor<CPDF_Number>(
+ "Length", static_cast<int>(data.size()));
+ }
+
+ if (!encoder.GetDict()->WriteTo(archive, encryptor))
return false;
- auto pAcc = pdfium::MakeRetain<CPDF_StreamAcc>(this);
- pAcc->LoadAllDataRaw();
- return archive->WriteBlock(pAcc->GetData(), pAcc->GetSize()) &&
- archive->WriteString("\r\nendstream");
+ if (!archive->WriteString("stream\r\n") ||
+ !archive->WriteBlock(data.data(), data.size()) ||
+ !archive->WriteString("\r\nendstream")) {
+ return false;
+ }
+ return true;
}