diff --git a/libqpdf/QPDFAcroFormDocumentHelper.cc b/libqpdf/QPDFAcroFormDocumentHelper.cc index 7fe779a..da5db4c 100644 --- a/libqpdf/QPDFAcroFormDocumentHelper.cc +++ b/libqpdf/QPDFAcroFormDocumentHelper.cc @@ -1,6 +1,7 @@ #include #include +#include #include #include #include @@ -975,17 +976,14 @@ QPDFAcroFormDocumentHelper::transformAnnotations( auto replace_stream = [](auto& dict, auto& key, auto& old) { return dict.replaceKeyAndGetNew(key, old.copyStream()); }; - if (apdict.isDictionary()) { - for (auto& ap: apdict.ditems()) { - if (ap.second.isStream()) { - streams.push_back(replace_stream(apdict, ap.first, ap.second)); - } else if (ap.second.isDictionary()) { - for (auto& ap2: ap.second.ditems()) { - if (ap2.second.isStream()) { - streams.push_back( - // line-break - replace_stream(ap.second, ap2.first, ap2.second)); - } + + for (auto& [key1, value1]: apdict.as_dictionary()) { + if (value1.isStream()) { + streams.emplace_back(replace_stream(apdict, key1, value1)); + } else { + for (auto& [key2, value2]: value1.as_dictionary()) { + if (value2.isStream()) { + streams.emplace_back(replace_stream(value1, key2, value2)); } } } diff --git a/libqpdf/QPDFFormFieldObjectHelper.cc b/libqpdf/QPDFFormFieldObjectHelper.cc index 0f9c936..1e62c24 100644 --- a/libqpdf/QPDFFormFieldObjectHelper.cc +++ b/libqpdf/QPDFFormFieldObjectHelper.cc @@ -4,6 +4,7 @@ #include #include #include +#include #include #include #include @@ -442,13 +443,10 @@ QPDFFormFieldObjectHelper::setCheckBoxValue(bool value) // Set the "on" value to the first value in the appearance stream's normal state dictionary // that isn't /Off. If not found, fall back to /Yes. if (AP.isDictionary()) { - auto N = AP.getKey("/N"); - if (N.isDictionary()) { - for (auto const& iter: N.ditems()) { - if (iter.first != "/Off") { - on_value = iter.first; - break; - } + for (auto const& item: AP.getKey("/N").as_dictionary()) { + if (item.first != "/Off") { + on_value = item.first; + break; } } } diff --git a/libqpdf/QPDFJob.cc b/libqpdf/QPDFJob.cc index 7553554..0aa5609 100644 --- a/libqpdf/QPDFJob.cc +++ b/libqpdf/QPDFJob.cc @@ -917,10 +917,13 @@ QPDFJob::doListAttachments(QPDF& pdf) v << " " << i2.first << " -> " << i2.second << "\n"; } v << " all data streams:\n"; - for (auto const& i2: efoh->getEmbeddedFileStreams().ditems()) { - auto efs = QPDFEFStreamObjectHelper(i2.second); - v << " " << i2.first << " -> " - << efs.getObjectHandle().getObjGen().unparse(',') << "\n"; + for (auto const& [key2, value2]: efoh->getEmbeddedFileStreams().as_dictionary()) { + if (value2.null()) { + continue; + } + auto efs = QPDFEFStreamObjectHelper(value2); + v << " " << key2 << " -> " << efs.getObjectHandle().getObjGen().unparse(',') + << "\n"; v << " creation date: " << efs.getCreationDate() << "\n" << " modification date: " << efs.getModDate() << "\n" << " mime type: " << efs.getSubtype() << "\n" @@ -1339,9 +1342,12 @@ QPDFJob::doJSONAttachments(Pipeline* p, bool& first, QPDF& pdf) j_names.addDictionaryMember(i2.first, JSON::makeString(i2.second)); } auto j_streams = j_details.addDictionaryMember("streams", JSON::makeDictionary()); - for (auto const& i2: fsoh->getEmbeddedFileStreams().ditems()) { - auto efs = QPDFEFStreamObjectHelper(i2.second); - auto j_stream = j_streams.addDictionaryMember(i2.first, JSON::makeDictionary()); + for (auto const& [key2, value2]: fsoh->getEmbeddedFileStreams().as_dictionary()) { + if (value2.null()) { + continue; + } + auto efs = QPDFEFStreamObjectHelper(value2); + auto j_stream = j_streams.addDictionaryMember(key2, JSON::makeDictionary()); j_stream.addDictionaryMember( "creationdate", null_or_string(to_iso8601(efs.getCreationDate()))); j_stream.addDictionaryMember( diff --git a/libqpdf/QPDFObjectHandle.cc b/libqpdf/QPDFObjectHandle.cc index 8ea2bae..263fdcc 100644 --- a/libqpdf/QPDFObjectHandle.cc +++ b/libqpdf/QPDFObjectHandle.cc @@ -1141,19 +1141,10 @@ QPDFObjectHandle::isOrHasName(std::string const& value) const void QPDFObjectHandle::makeResourcesIndirect(QPDF& owning_qpdf) { - if (!isDictionary()) { - return; - } - for (auto const& i1: ditems()) { - QPDFObjectHandle sub = i1.second; - if (!sub.isDictionary()) { - continue; - } - for (auto const& i2: sub.ditems()) { - std::string const& key = i2.first; - QPDFObjectHandle val = i2.second; - if (!val.isIndirect()) { - sub.replaceKey(key, owning_qpdf.makeIndirectObject(val)); + for (auto const& i1: as_dictionary()) { + for (auto& i2: i1.second.as_dictionary()) { + if (!i2.second.null() && !i2.second.isIndirect()) { + i2.second = owning_qpdf.makeIndirectObject(i2.second); } } } @@ -1170,18 +1161,17 @@ QPDFObjectHandle::mergeResources( auto make_og_to_name = [](QPDFObjectHandle& dict, std::map& og_to_name) { - for (auto const& i: dict.ditems()) { - if (i.second.isIndirect()) { - og_to_name[i.second.getObjGen()] = i.first; + for (auto const& [key, value]: dict.as_dictionary()) { + if (!value.null() && value.isIndirect()) { + og_to_name.insert_or_assign(value.getObjGen(), key); } } }; // This algorithm is described in comments in QPDFObjectHandle.hh // above the declaration of mergeResources. - for (auto const& o_top: other.ditems()) { - std::string const& rtype = o_top.first; - QPDFObjectHandle other_val = o_top.second; + for (auto const& [rtype, value1]: other.as_dictionary()) { + auto other_val = value1; if (hasKey(rtype)) { QPDFObjectHandle this_val = getKey(rtype); if (this_val.isDictionary() && other_val.isDictionary()) { @@ -1196,9 +1186,8 @@ QPDFObjectHandle::mergeResources( std::set rnames; int min_suffix = 1; bool initialized_maps = false; - for (auto const& ov_iter: other_val.ditems()) { - std::string const& key = ov_iter.first; - QPDFObjectHandle rval = ov_iter.second; + for (auto const& [key, value2]: other_val.as_dictionary()) { + QPDFObjectHandle rval = value2; if (!this_val.hasKey(key)) { if (!rval.isIndirect()) { QTC::TC("qpdf", "QPDFObjectHandle merge shallow copy");