Commit 59191ebbc4c017385c6dbf69cb7d7823336f4509

Authored by m-holger
Committed by Jay Berkenbilt
1 parent 942a2c3f

Tune QPDFWriter::unparseObject

Showing 1 changed file with 30 additions and 27 deletions
libqpdf/QPDFWriter.cc
@@ -23,6 +23,7 @@ @@ -23,6 +23,7 @@
23 #include <qpdf/RC4.hh> 23 #include <qpdf/RC4.hh>
24 24
25 #include <algorithm> 25 #include <algorithm>
  26 +#include <stdexcept>
26 #include <stdlib.h> 27 #include <stdlib.h>
27 28
28 QPDFWriter::ProgressReporter::~ProgressReporter() 29 QPDFWriter::ProgressReporter::~ProgressReporter()
@@ -1482,13 +1483,13 @@ QPDFWriter::unparseObject( @@ -1482,13 +1483,13 @@ QPDFWriter::unparseObject(
1482 { 1483 {
1483 QPDFObjGen old_og = object.getObjGen(); 1484 QPDFObjGen old_og = object.getObjGen();
1484 int child_flags = flags & ~f_stream; 1485 int child_flags = flags & ~f_stream;
1485 -  
1486 - std::string indent;  
1487 - for (int i = 0; i < level; ++i) {  
1488 - indent += " "; 1486 + if (level < 0) {
  1487 + throw std::logic_error("invalid level in QPDFWriter::unparseObject");
1489 } 1488 }
1490 1489
1491 - if (object.isArray()) { 1490 + std::string const indent(static_cast<size_t>(2 * level), ' ');
  1491 +
  1492 + if (auto const tc = object.getTypeCode(); tc == ::ot_array) {
1492 // Note: PDF spec 1.4 implementation note 121 states that 1493 // Note: PDF spec 1.4 implementation note 121 states that
1493 // Acrobat requires a space after the [ in the /H key of the 1494 // Acrobat requires a space after the [ in the /H key of the
1494 // linearization parameter dictionary. We'll do this 1495 // linearization parameter dictionary. We'll do this
@@ -1496,18 +1497,17 @@ QPDFWriter::unparseObject( @@ -1496,18 +1497,17 @@ QPDFWriter::unparseObject(
1496 // doesn't make the files that much bigger. 1497 // doesn't make the files that much bigger.
1497 writeString("["); 1498 writeString("[");
1498 writeStringQDF("\n"); 1499 writeStringQDF("\n");
1499 - int n = object.getArrayNItems();  
1500 - for (int i = 0; i < n; ++i) { 1500 + for (auto const& item: object.getArrayAsVector()) {
1501 writeStringQDF(indent); 1501 writeStringQDF(indent);
1502 writeStringQDF(" "); 1502 writeStringQDF(" ");
1503 writeStringNoQDF(" "); 1503 writeStringNoQDF(" ");
1504 - unparseChild(object.getArrayItem(i), level + 1, child_flags); 1504 + unparseChild(item, level + 1, child_flags);
1505 writeStringQDF("\n"); 1505 writeStringQDF("\n");
1506 } 1506 }
1507 writeStringQDF(indent); 1507 writeStringQDF(indent);
1508 writeStringNoQDF(" "); 1508 writeStringNoQDF(" ");
1509 writeString("]"); 1509 writeString("]");
1510 - } else if (object.isDictionary()) { 1510 + } else if (tc == ::ot_dictionary) {
1511 // Make a shallow copy of this object so we can modify it 1511 // Make a shallow copy of this object so we can modify it
1512 // safely without affecting the original. This code has logic 1512 // safely without affecting the original. This code has logic
1513 // to skip certain keys in agreement with prepareFileForWrite 1513 // to skip certain keys in agreement with prepareFileForWrite
@@ -1668,23 +1668,26 @@ QPDFWriter::unparseObject( @@ -1668,23 +1668,26 @@ QPDFWriter::unparseObject(
1668 writeString("<<"); 1668 writeString("<<");
1669 writeStringQDF("\n"); 1669 writeStringQDF("\n");
1670 1670
1671 - for (auto const& key: object.getKeys()) {  
1672 - writeStringQDF(indent);  
1673 - writeStringQDF(" ");  
1674 - writeStringNoQDF(" ");  
1675 - writeString(QPDF_Name::normalizeName(key));  
1676 - writeString(" ");  
1677 - if (key == "/Contents" && object.isDictionaryOfType("/Sig") &&  
1678 - object.hasKey("/ByteRange")) {  
1679 - QTC::TC("qpdf", "QPDFWriter no encryption sig contents");  
1680 - unparseChild(  
1681 - object.getKey(key),  
1682 - level + 1,  
1683 - child_flags | f_hex_string | f_no_encryption);  
1684 - } else {  
1685 - unparseChild(object.getKey(key), level + 1, child_flags); 1671 + for (auto& item: object.getDictAsMap()) {
  1672 + if (!item.second.isNull()) {
  1673 + auto const& key = item.first;
  1674 + writeStringQDF(indent);
  1675 + writeStringQDF(" ");
  1676 + writeStringNoQDF(" ");
  1677 + writeString(QPDF_Name::normalizeName(key));
  1678 + writeString(" ");
  1679 + if (key == "/Contents" && object.isDictionaryOfType("/Sig") &&
  1680 + object.hasKey("/ByteRange")) {
  1681 + QTC::TC("qpdf", "QPDFWriter no encryption sig contents");
  1682 + unparseChild(
  1683 + item.second,
  1684 + level + 1,
  1685 + child_flags | f_hex_string | f_no_encryption);
  1686 + } else {
  1687 + unparseChild(item.second, level + 1, child_flags);
  1688 + }
  1689 + writeStringQDF("\n");
1686 } 1690 }
1687 - writeStringQDF("\n");  
1688 } 1691 }
1689 1692
1690 if (flags & f_stream) { 1693 if (flags & f_stream) {
@@ -1710,7 +1713,7 @@ QPDFWriter::unparseObject( @@ -1710,7 +1713,7 @@ QPDFWriter::unparseObject(
1710 writeStringQDF(indent); 1713 writeStringQDF(indent);
1711 writeStringNoQDF(" "); 1714 writeStringNoQDF(" ");
1712 writeString(">>"); 1715 writeString(">>");
1713 - } else if (object.isStream()) { 1716 + } else if (tc == ::ot_stream) {
1714 // Write stream data to a buffer. 1717 // Write stream data to a buffer.
1715 int new_id = this->m->obj_renumber[old_og]; 1718 int new_id = this->m->obj_renumber[old_og];
1716 if (!this->m->direct_stream_lengths) { 1719 if (!this->m->direct_stream_lengths) {
@@ -1752,7 +1755,7 @@ QPDFWriter::unparseObject( @@ -1752,7 +1755,7 @@ QPDFWriter::unparseObject(
1752 this->m->added_newline = false; 1755 this->m->added_newline = false;
1753 } 1756 }
1754 writeString("endstream"); 1757 writeString("endstream");
1755 - } else if (object.isString()) { 1758 + } else if (tc == ::ot_string) {
1756 std::string val; 1759 std::string val;
1757 if (this->m->encrypted && (!(flags & f_in_ostream)) && 1760 if (this->m->encrypted && (!(flags & f_in_ostream)) &&
1758 (!(flags & f_no_encryption)) && (!this->m->cur_data_key.empty())) { 1761 (!(flags & f_no_encryption)) && (!this->m->cur_data_key.empty())) {