Commit d7853db8f86613bae02f446b6d3ae9c06bc4d8dc

Authored by m-holger
1 parent 65e7e3db

In QPDFWriter::willFilterStream use Pl_String instead of Pl_Buffer

Also,
- use Pl_Discard when only checking whether stream is filterable
- get last char directly from output string
include/qpdf/QPDFWriter.hh
... ... @@ -493,7 +493,7 @@ class QPDFWriter
493 493 QPDFObjectHandle stream,
494 494 bool& compress_stream,
495 495 bool& is_metadata,
496   - std::shared_ptr<Buffer>* stream_data);
  496 + std::string* stream_data);
497 497 void unparseObject(
498 498 QPDFObjectHandle object,
499 499 int level,
... ...
libqpdf/QPDFWriter.cc
... ... @@ -13,6 +13,7 @@
13 13 #include <qpdf/Pl_PNGFilter.hh>
14 14 #include <qpdf/Pl_RC4.hh>
15 15 #include <qpdf/Pl_StdioFile.hh>
  16 +#include <qpdf/Pl_String.hh>
16 17 #include <qpdf/QIntC.hh>
17 18 #include <qpdf/QPDFObjectHandle_private.hh>
18 19 #include <qpdf/QPDFObject_private.hh>
... ... @@ -1244,7 +1245,7 @@ QPDFWriter::willFilterStream(
1244 1245 QPDFObjectHandle stream,
1245 1246 bool& compress_stream, // out only
1246 1247 bool& is_metadata, // out only
1247   - std::shared_ptr<Buffer>* stream_data)
  1248 + std::string* stream_data)
1248 1249 {
1249 1250 compress_stream = false;
1250 1251 is_metadata = false;
... ... @@ -1290,8 +1291,12 @@ QPDFWriter::willFilterStream(
1290 1291  
1291 1292 bool filtered = false;
1292 1293 for (bool first_attempt: {true, false}) {
1293   - pushPipeline(new Pl_Buffer("stream data"));
1294   - PipelinePopper pp_stream_data(this, stream_data);
  1294 + if (stream_data != nullptr) {
  1295 + pushPipeline(new Pl_String("stream data", nullptr, *stream_data));
  1296 + } else {
  1297 + pushPipeline(new Pl_Discard());
  1298 + }
  1299 + PipelinePopper pp_stream_data(this);
1295 1300 activatePipelineStack(pp_stream_data);
1296 1301 try {
1297 1302 filtered = stream.pipeStreamData(
... ... @@ -1320,6 +1325,9 @@ QPDFWriter::willFilterStream(
1320 1325 throw std::runtime_error(
1321 1326 "error while getting stream data for " + stream.unparse() + ": " + e.what());
1322 1327 }
  1328 + if (stream_data) {
  1329 + stream_data->clear();
  1330 + }
1323 1331 }
1324 1332 if (!filtered) {
1325 1333 compress_stream = false;
... ... @@ -1545,29 +1553,28 @@ QPDFWriter::unparseObject(
1545 1553 flags |= f_stream;
1546 1554 bool compress_stream = false;
1547 1555 bool is_metadata = false;
1548   - std::shared_ptr<Buffer> stream_data;
  1556 + std::string stream_data;
1549 1557 if (willFilterStream(object, compress_stream, is_metadata, &stream_data)) {
1550 1558 flags |= f_filtered;
1551 1559 }
1552 1560 QPDFObjectHandle stream_dict = object.getDict();
1553 1561  
1554   - m->cur_stream_length = stream_data->getSize();
  1562 + m->cur_stream_length = stream_data.size();
1555 1563 if (is_metadata && m->encrypted && (!m->encrypt_metadata)) {
1556 1564 // Don't encrypt stream data for the metadata stream
1557 1565 m->cur_data_key.clear();
1558 1566 }
1559 1567 adjustAESStreamLength(m->cur_stream_length);
1560 1568 unparseObject(stream_dict, 0, flags, m->cur_stream_length, compress_stream);
1561   - unsigned char last_char = '\0';
  1569 + char last_char = stream_data.empty() ? '\0' : stream_data.back();
1562 1570 writeString("\nstream\n");
1563 1571 {
1564 1572 PipelinePopper pp_enc(this);
1565 1573 pushEncryptionFilter(pp_enc);
1566   - writeBuffer(stream_data);
1567   - last_char = m->pipeline->getLastChar();
  1574 + writeString(stream_data);
1568 1575 }
1569 1576  
1570   - if (m->newline_before_endstream || (m->qdf_mode && (last_char != '\n'))) {
  1577 + if (m->newline_before_endstream || (m->qdf_mode && last_char != '\n')) {
1571 1578 writeString("\n");
1572 1579 m->added_newline = true;
1573 1580 } else {
... ...