Avoid unique_ptrs to string streams in CPDF_PageContentGenerator.
Move-assignment of a string stream should be a reasonably efficient
no-copy operation, so the additional indirection through the unique_ptr
isn't needed.
The only complication is we hit a "const" issue in one place, so
convert one method to take an rvalue reference from its only caller
to avoid passing args by non-const ref (and avoid unintended copies).
Change-Id: Ie7b8aa1a2b1a864521faa30ebcb2343861064620
Reviewed-on: https://pdfium-review.googlesource.com/c/pdfium/+/78713
Commit-Queue: Tom Sepez <tsepez@chromium.org>
Reviewed-by: Lei Zhang <thestig@chromium.org>
diff --git a/core/fpdfapi/edit/cpdf_pagecontentgenerator.cpp b/core/fpdfapi/edit/cpdf_pagecontentgenerator.cpp
index d182d89..8fb52b7 100644
--- a/core/fpdfapi/edit/cpdf_pagecontentgenerator.cpp
+++ b/core/fpdfapi/edit/cpdf_pagecontentgenerator.cpp
@@ -71,7 +71,7 @@
UpdateContentStreams(GenerateModifiedStreams());
}
-std::map<int32_t, std::unique_ptr<std::ostringstream>>
+std::map<int32_t, std::ostringstream>
CPDF_PageContentGenerator::GenerateModifiedStreams() {
// Make sure default graphics are created.
GetOrCreateDefaultGraphics();
@@ -87,23 +87,21 @@
marked_dirty_streams.end());
// Start regenerating dirty streams.
- std::map<int32_t, std::unique_ptr<std::ostringstream>> streams;
+ std::map<int32_t, std::ostringstream> streams;
std::set<int32_t> empty_streams;
std::unique_ptr<const CPDF_ContentMarks> empty_content_marks =
std::make_unique<CPDF_ContentMarks>();
std::map<int32_t, const CPDF_ContentMarks*> current_content_marks;
for (int32_t dirty_stream : all_dirty_streams) {
- std::unique_ptr<std::ostringstream> buf =
- std::make_unique<std::ostringstream>();
+ std::ostringstream buf;
// Set the default graphic state values
- *buf << "q\n";
+ buf << "q\n";
if (!m_pObjHolder->GetLastCTM().IsIdentity())
- *buf << m_pObjHolder->GetLastCTM().GetInverse() << " cm\n";
+ buf << m_pObjHolder->GetLastCTM().GetInverse() << " cm\n";
- ProcessDefaultGraphics(buf.get());
-
+ ProcessDefaultGraphics(&buf);
streams[dirty_stream] = std::move(buf);
empty_streams.insert(dirty_stream);
current_content_marks[dirty_stream] = empty_content_marks.get();
@@ -116,7 +114,7 @@
if (it == streams.end())
continue;
- std::ostringstream* buf = it->second.get();
+ std::ostringstream* buf = &it->second;
empty_streams.erase(stream_index);
current_content_marks[stream_index] = ProcessContentMarks(
buf, pPageObj.Get(), current_content_marks[stream_index]);
@@ -125,7 +123,7 @@
// Finish dirty streams.
for (int32_t dirty_stream : all_dirty_streams) {
- std::ostringstream* buf = streams[dirty_stream].get();
+ std::ostringstream* buf = &streams[dirty_stream];
if (pdfium::Contains(empty_streams, dirty_stream)) {
// Clear to show that this stream needs to be deleted.
buf->str("");
@@ -141,8 +139,7 @@
}
void CPDF_PageContentGenerator::UpdateContentStreams(
- const std::map<int32_t, std::unique_ptr<std::ostringstream>>&
- new_stream_data) {
+ std::map<int32_t, std::ostringstream>&& new_stream_data) {
// If no streams were regenerated or removed, nothing to do here.
if (new_stream_data.empty())
return;
@@ -151,7 +148,7 @@
for (auto& pair : new_stream_data) {
int32_t stream_index = pair.first;
- std::ostringstream* buf = pair.second.get();
+ std::ostringstream* buf = &pair.second;
if (stream_index == CPDF_PageObject::kNoContentStream) {
int new_stream_index = page_content_manager.AddStream(buf);
diff --git a/core/fpdfapi/edit/cpdf_pagecontentgenerator.h b/core/fpdfapi/edit/cpdf_pagecontentgenerator.h
index 79bcdff..ac9fd8a 100644
--- a/core/fpdfapi/edit/cpdf_pagecontentgenerator.h
+++ b/core/fpdfapi/edit/cpdf_pagecontentgenerator.h
@@ -8,7 +8,6 @@
#define CORE_FPDFAPI_EDIT_CPDF_PAGECONTENTGENERATOR_H_
#include <map>
-#include <memory>
#include <sstream>
#include <vector>
@@ -55,13 +54,11 @@
// Returns a map from content stream index to new stream data. Unmodified
// streams are not touched.
- std::map<int32_t, std::unique_ptr<std::ostringstream>>
- GenerateModifiedStreams();
+ std::map<int32_t, std::ostringstream> GenerateModifiedStreams();
// Add buffer as a stream in page's 'Contents'
void UpdateContentStreams(
- const std::map<int32_t, std::unique_ptr<std::ostringstream>>&
- new_stream_data);
+ std::map<int32_t, std::ostringstream>&& new_stream_data);
// Set the stream index of all page objects with stream index ==
// |CPDF_PageObject::kNoContentStream|. These are new objects that had not