Commit 49010866f86d07978ca9f2c726a3b20bc9ea381b

Authored by m-holger
1 parent 4ba6377f

Refactor `QPDF` configuration: encapsulate related fields in `Doc::Config`, upda…

…te usage throughout the codebase, and streamline configurations.
libqpdf/QPDF.cc
@@ -27,9 +27,9 @@ @@ -27,9 +27,9 @@
27 using namespace qpdf; 27 using namespace qpdf;
28 using namespace std::literals; 28 using namespace std::literals;
29 29
30 -using Doc = QPDF::Doc;  
31 -using Common = Doc::Common;  
32 -using Objects = Doc::Objects; 30 +using QDoc = QPDF::Doc;
  31 +using Common = QDoc::Common;
  32 +using Objects = QDoc::Objects;
33 using Foreign = Objects::Foreign; 33 using Foreign = Objects::Foreign;
34 using Streams = Objects::Streams; 34 using Streams = Objects::Streams;
35 35
@@ -133,7 +133,6 @@ QPDF::Members::Members(QPDF& qpdf) : @@ -133,7 +133,6 @@ QPDF::Members::Members(QPDF& qpdf) :
133 lin(*this), 133 lin(*this),
134 objects(*this), 134 objects(*this),
135 pages(*this), 135 pages(*this),
136 - log(QPDFLogger::defaultLogger()),  
137 file(std::make_shared<InvalidInputSource>()), 136 file(std::make_shared<InvalidInputSource>()),
138 encp(std::make_shared<EncryptionParameters>()) 137 encp(std::make_shared<EncryptionParameters>())
139 { 138 {
@@ -232,7 +231,7 @@ QPDF::closeInputSource() @@ -232,7 +231,7 @@ QPDF::closeInputSource()
232 void 231 void
233 QPDF::setPasswordIsHexKey(bool val) 232 QPDF::setPasswordIsHexKey(bool val)
234 { 233 {
235 - m->provided_password_is_hex_key = val; 234 + m->cf.provided_password_is_hex_key_ = val;
236 } 235 }
237 236
238 void 237 void
@@ -251,56 +250,56 @@ QPDF::registerStreamFilter( @@ -251,56 +250,56 @@ QPDF::registerStreamFilter(
251 void 250 void
252 QPDF::setIgnoreXRefStreams(bool val) 251 QPDF::setIgnoreXRefStreams(bool val)
253 { 252 {
254 - m->ignore_xref_streams = val; 253 + m->cf.ignore_xref_streams_ = val;
255 } 254 }
256 255
257 std::shared_ptr<QPDFLogger> 256 std::shared_ptr<QPDFLogger>
258 QPDF::getLogger() 257 QPDF::getLogger()
259 { 258 {
260 - return m->log; 259 + return m->cf.log_;
261 } 260 }
262 261
263 void 262 void
264 QPDF::setLogger(std::shared_ptr<QPDFLogger> l) 263 QPDF::setLogger(std::shared_ptr<QPDFLogger> l)
265 { 264 {
266 - m->log = l; 265 + m->cf.log_ = l;
267 } 266 }
268 267
269 void 268 void
270 QPDF::setOutputStreams(std::ostream* out, std::ostream* err) 269 QPDF::setOutputStreams(std::ostream* out, std::ostream* err)
271 { 270 {
272 setLogger(QPDFLogger::create()); 271 setLogger(QPDFLogger::create());
273 - m->log->setOutputStreams(out, err); 272 + m->cf.log_->setOutputStreams(out, err);
274 } 273 }
275 274
276 void 275 void
277 QPDF::setSuppressWarnings(bool val) 276 QPDF::setSuppressWarnings(bool val)
278 { 277 {
279 - m->suppress_warnings = val; 278 + m->cf.suppress_warnings_ = val;
280 } 279 }
281 280
282 void 281 void
283 QPDF::setMaxWarnings(size_t val) 282 QPDF::setMaxWarnings(size_t val)
284 { 283 {
285 - m->max_warnings = val; 284 + m->cf.max_warnings_ = val;
286 } 285 }
287 286
288 void 287 void
289 QPDF::setAttemptRecovery(bool val) 288 QPDF::setAttemptRecovery(bool val)
290 { 289 {
291 - m->attempt_recovery = val; 290 + m->cf.attempt_recovery_ = val;
292 } 291 }
293 292
294 void 293 void
295 QPDF::setImmediateCopyFrom(bool val) 294 QPDF::setImmediateCopyFrom(bool val)
296 { 295 {
297 - m->immediate_copy_from = val; 296 + m->cf.immediate_copy_from_ = val;
298 } 297 }
299 298
300 std::vector<QPDFExc> 299 std::vector<QPDFExc>
301 QPDF::getWarnings() 300 QPDF::getWarnings()
302 { 301 {
303 - std::vector<QPDFExc> result = m->warnings; 302 + std::vector<QPDFExc> result = std::move(m->warnings);
304 m->warnings.clear(); 303 m->warnings.clear();
305 return result; 304 return result;
306 } 305 }
@@ -372,12 +371,12 @@ QPDF::warn(QPDFExc const&amp; e) @@ -372,12 +371,12 @@ QPDF::warn(QPDFExc const&amp; e)
372 void 371 void
373 Common::warn(QPDFExc const& e) 372 Common::warn(QPDFExc const& e)
374 { 373 {
375 - if (m->max_warnings > 0 && m->warnings.size() >= m->max_warnings) { 374 + if (m->cf.max_warnings_ > 0 && m->warnings.size() >= m->cf.max_warnings_) {
376 stopOnError("Too many warnings - file is too badly damaged"); 375 stopOnError("Too many warnings - file is too badly damaged");
377 } 376 }
378 - m->warnings.push_back(e);  
379 - if (!m->suppress_warnings) {  
380 - *m->log->getWarn() << "WARNING: " << m->warnings.back().what() << "\n"; 377 + m->warnings.emplace_back(e);
  378 + if (!m->cf.suppress_warnings_) {
  379 + *m->cf.log_->getWarn() << "WARNING: " << m->warnings.back().what() << "\n";
381 } 380 }
382 } 381 }
383 382
@@ -715,7 +714,7 @@ QPDF::getRoot() @@ -715,7 +714,7 @@ QPDF::getRoot()
715 } else if ( 714 } else if (
716 // Check_mode is an interim solution to request #810 pending a more comprehensive review of 715 // Check_mode is an interim solution to request #810 pending a more comprehensive review of
717 // the approach to more extensive checks and warning levels. 716 // the approach to more extensive checks and warning levels.
718 - m->check_mode && !root.getKey("/Type").isNameAndEquals("/Catalog")) { 717 + m->cf.check_mode_ && !root.getKey("/Type").isNameAndEquals("/Catalog")) {
719 warn(m->c.damagedPDF("", -1, "catalog /Type entry missing or invalid")); 718 warn(m->c.damagedPDF("", -1, "catalog /Type entry missing or invalid"));
720 root.replaceKey("/Type", "/Catalog"_qpdf); 719 root.replaceKey("/Type", "/Catalog"_qpdf);
721 } 720 }
libqpdf/QPDFJob.cc
@@ -30,18 +30,18 @@ @@ -30,18 +30,18 @@
30 30
31 using namespace qpdf; 31 using namespace qpdf;
32 32
33 -using Doc = QPDF::Doc;  
34 -using Pages = Doc::Pages; 33 +using QDoc = QPDF::Doc;
  34 +using Pages = QDoc::Pages;
35 35
36 // JobSetter class is restricted to QPDFJob. 36 // JobSetter class is restricted to QPDFJob.
37 -class Doc::JobSetter 37 +class QDoc::JobSetter
38 { 38 {
39 public: 39 public:
40 // Enable enhanced warnings for pdf file checking. 40 // Enable enhanced warnings for pdf file checking.
41 static void 41 static void
42 setCheckMode(QPDF& qpdf, bool val) 42 setCheckMode(QPDF& qpdf, bool val)
43 { 43 {
44 - qpdf.m->check_mode = val; 44 + qpdf.m->cf.check_mode_ = val;
45 } 45 }
46 }; 46 };
47 47
@@ -749,7 +749,7 @@ QPDFJob::doCheck(QPDF&amp; pdf) @@ -749,7 +749,7 @@ QPDFJob::doCheck(QPDF&amp; pdf)
749 bool okay = true; 749 bool okay = true;
750 auto& cout = *m->log->getInfo(); 750 auto& cout = *m->log->getInfo();
751 cout << "checking " << m->infile_name() << "\n"; 751 cout << "checking " << m->infile_name() << "\n";
752 - Doc::JobSetter::setCheckMode(pdf, true); 752 + QDoc::JobSetter::setCheckMode(pdf, true);
753 try { 753 try {
754 int extension_level = pdf.getExtensionLevel(); 754 int extension_level = pdf.getExtensionLevel();
755 cout << "PDF Version: " << pdf.getPDFVersion(); 755 cout << "PDF Version: " << pdf.getPDFVersion();
libqpdf/QPDFWriter.cc
@@ -27,8 +27,8 @@ @@ -27,8 +27,8 @@
27 using namespace std::literals; 27 using namespace std::literals;
28 using namespace qpdf; 28 using namespace qpdf;
29 29
30 -using Doc = QPDF::Doc;  
31 -using Encryption = Doc::Encryption; 30 +using QDoc = QPDF::Doc;
  31 +using Encryption = QDoc::Encryption;
32 32
33 QPDFWriter::ProgressReporter::~ProgressReporter() // NOLINT (modernize-use-equals-default) 33 QPDFWriter::ProgressReporter::~ProgressReporter() // NOLINT (modernize-use-equals-default)
34 { 34 {
@@ -263,7 +263,7 @@ Pl_stack::Popper::pop() @@ -263,7 +263,7 @@ Pl_stack::Popper::pop()
263 } 263 }
264 264
265 // Writer class is restricted to QPDFWriter so that only it can call certain methods. 265 // Writer class is restricted to QPDFWriter so that only it can call certain methods.
266 -class Doc::Writer: Doc::Common 266 +class QPDF::Doc::Writer: QPDF::Doc::Common
267 { 267 {
268 friend class QPDFWriter; 268 friend class QPDFWriter;
269 Writer(QPDF& qpdf) : 269 Writer(QPDF& qpdf) :
libqpdf/QPDF_Stream.cc
@@ -30,7 +30,7 @@ using Streams = QPDF::Doc::Objects::Streams; @@ -30,7 +30,7 @@ using Streams = QPDF::Doc::Objects::Streams;
30 bool 30 bool
31 Streams::immediate_copy_from() const 31 Streams::immediate_copy_from() const
32 { 32 {
33 - return qpdf.m->immediate_copy_from; 33 + return qpdf.m->cf.immediate_copy_from_;
34 } 34 }
35 35
36 class Streams::Copier final: public QPDFObjectHandle::StreamDataProvider 36 class Streams::Copier final: public QPDFObjectHandle::StreamDataProvider
libqpdf/QPDF_encryption.cc
@@ -904,7 +904,7 @@ QPDF::EncryptionParameters::initialize(QPDF&amp; qpdf) @@ -904,7 +904,7 @@ QPDF::EncryptionParameters::initialize(QPDF&amp; qpdf)
904 } 904 }
905 905
906 Encryption data(V, R, Length / 8, p, O, U, OE, UE, Perms, id1, encrypt_metadata); 906 Encryption data(V, R, Length / 8, p, O, U, OE, UE, Perms, id1, encrypt_metadata);
907 - if (qm.provided_password_is_hex_key) { 907 + if (qm.cf.provided_password_is_hex_key_) {
908 // ignore passwords in file 908 // ignore passwords in file
909 encryption_key = QUtil::hex_decode(provided_password); 909 encryption_key = QUtil::hex_decode(provided_password);
910 return; 910 return;
libqpdf/QPDF_linearization.cc
@@ -1095,25 +1095,27 @@ QPDF::showLinearizationData() @@ -1095,25 +1095,27 @@ QPDF::showLinearizationData()
1095 void 1095 void
1096 Lin::dumpLinearizationDataInternal() 1096 Lin::dumpLinearizationDataInternal()
1097 { 1097 {
1098 - *m->log->getInfo() << m->file->getName() << ": linearization data:\n\n";  
1099 -  
1100 - *m->log->getInfo() << "file_size: " << m->linp.file_size << "\n"  
1101 - << "first_page_object: " << m->linp.first_page_object << "\n"  
1102 - << "first_page_end: " << m->linp.first_page_end << "\n"  
1103 - << "npages: " << m->linp.npages << "\n"  
1104 - << "xref_zero_offset: " << m->linp.xref_zero_offset << "\n"  
1105 - << "first_page: " << m->linp.first_page << "\n"  
1106 - << "H_offset: " << m->linp.H_offset << "\n"  
1107 - << "H_length: " << m->linp.H_length << "\n"  
1108 - << "\n";  
1109 -  
1110 - *m->log->getInfo() << "Page Offsets Hint Table\n\n"; 1098 + auto& info = *m->cf.log_->getInfo();
  1099 +
  1100 + info << m->file->getName() << ": linearization data:\n\n";
  1101 +
  1102 + info << "file_size: " << m->linp.file_size << "\n"
  1103 + << "first_page_object: " << m->linp.first_page_object << "\n"
  1104 + << "first_page_end: " << m->linp.first_page_end << "\n"
  1105 + << "npages: " << m->linp.npages << "\n"
  1106 + << "xref_zero_offset: " << m->linp.xref_zero_offset << "\n"
  1107 + << "first_page: " << m->linp.first_page << "\n"
  1108 + << "H_offset: " << m->linp.H_offset << "\n"
  1109 + << "H_length: " << m->linp.H_length << "\n"
  1110 + << "\n";
  1111 +
  1112 + info << "Page Offsets Hint Table\n\n";
1111 dumpHPageOffset(); 1113 dumpHPageOffset();
1112 - *m->log->getInfo() << "\nShared Objects Hint Table\n\n"; 1114 + info << "\nShared Objects Hint Table\n\n";
1113 dumpHSharedObject(); 1115 dumpHSharedObject();
1114 1116
1115 if (m->outline_hints.nobjects > 0) { 1117 if (m->outline_hints.nobjects > 0) {
1116 - *m->log->getInfo() << "\nOutlines Hint Table\n\n"; 1118 + info << "\nOutlines Hint Table\n\n";
1117 dumpHGeneric(m->outline_hints); 1119 dumpHGeneric(m->outline_hints);
1118 } 1120 }
1119 } 1121 }
@@ -1132,38 +1134,35 @@ Lin::adjusted_offset(qpdf_offset_t offset) @@ -1132,38 +1134,35 @@ Lin::adjusted_offset(qpdf_offset_t offset)
1132 void 1134 void
1133 Lin::dumpHPageOffset() 1135 Lin::dumpHPageOffset()
1134 { 1136 {
  1137 + auto& info = *m->cf.log_->getInfo();
1135 HPageOffset& t = m->page_offset_hints; 1138 HPageOffset& t = m->page_offset_hints;
1136 - *m->log->getInfo() << "min_nobjects: " << t.min_nobjects << "\n"  
1137 - << "first_page_offset: " << adjusted_offset(t.first_page_offset) << "\n"  
1138 - << "nbits_delta_nobjects: " << t.nbits_delta_nobjects << "\n"  
1139 - << "min_page_length: " << t.min_page_length << "\n"  
1140 - << "nbits_delta_page_length: " << t.nbits_delta_page_length << "\n"  
1141 - << "min_content_offset: " << t.min_content_offset << "\n"  
1142 - << "nbits_delta_content_offset: " << t.nbits_delta_content_offset << "\n"  
1143 - << "min_content_length: " << t.min_content_length << "\n"  
1144 - << "nbits_delta_content_length: " << t.nbits_delta_content_length << "\n"  
1145 - << "nbits_nshared_objects: " << t.nbits_nshared_objects << "\n"  
1146 - << "nbits_shared_identifier: " << t.nbits_shared_identifier << "\n"  
1147 - << "nbits_shared_numerator: " << t.nbits_shared_numerator << "\n"  
1148 - << "shared_denominator: " << t.shared_denominator << "\n"; 1139 + info << "min_nobjects: " << t.min_nobjects << "\n"
  1140 + << "first_page_offset: " << adjusted_offset(t.first_page_offset) << "\n"
  1141 + << "nbits_delta_nobjects: " << t.nbits_delta_nobjects << "\n"
  1142 + << "min_page_length: " << t.min_page_length << "\n"
  1143 + << "nbits_delta_page_length: " << t.nbits_delta_page_length << "\n"
  1144 + << "min_content_offset: " << t.min_content_offset << "\n"
  1145 + << "nbits_delta_content_offset: " << t.nbits_delta_content_offset << "\n"
  1146 + << "min_content_length: " << t.min_content_length << "\n"
  1147 + << "nbits_delta_content_length: " << t.nbits_delta_content_length << "\n"
  1148 + << "nbits_nshared_objects: " << t.nbits_nshared_objects << "\n"
  1149 + << "nbits_shared_identifier: " << t.nbits_shared_identifier << "\n"
  1150 + << "nbits_shared_numerator: " << t.nbits_shared_numerator << "\n"
  1151 + << "shared_denominator: " << t.shared_denominator << "\n";
1149 1152
1150 for (size_t i1 = 0; i1 < m->linp.npages; ++i1) { 1153 for (size_t i1 = 0; i1 < m->linp.npages; ++i1) {
1151 HPageOffsetEntry& pe = t.entries.at(i1); 1154 HPageOffsetEntry& pe = t.entries.at(i1);
1152 - *m->log->getInfo() << "Page " << i1 << ":\n"  
1153 - << " nobjects: " << pe.delta_nobjects + t.min_nobjects << "\n"  
1154 - << " length: " << pe.delta_page_length + t.min_page_length  
1155 - << "\n"  
1156 - // content offset is relative to page, not file  
1157 - << " content_offset: " << pe.delta_content_offset + t.min_content_offset  
1158 - << "\n"  
1159 - << " content_length: " << pe.delta_content_length + t.min_content_length  
1160 - << "\n"  
1161 - << " nshared_objects: " << pe.nshared_objects << "\n"; 1155 + info << "Page " << i1 << ":\n"
  1156 + << " nobjects: " << pe.delta_nobjects + t.min_nobjects << "\n"
  1157 + << " length: " << pe.delta_page_length + t.min_page_length
  1158 + << "\n"
  1159 + // content offset is relative to page, not file
  1160 + << " content_offset: " << pe.delta_content_offset + t.min_content_offset << "\n"
  1161 + << " content_length: " << pe.delta_content_length + t.min_content_length << "\n"
  1162 + << " nshared_objects: " << pe.nshared_objects << "\n";
1162 for (size_t i2 = 0; i2 < toS(pe.nshared_objects); ++i2) { 1163 for (size_t i2 = 0; i2 < toS(pe.nshared_objects); ++i2) {
1163 - *m->log->getInfo() << " identifier " << i2 << ": " << pe.shared_identifiers.at(i2)  
1164 - << "\n";  
1165 - *m->log->getInfo() << " numerator " << i2 << ": " << pe.shared_numerators.at(i2)  
1166 - << "\n"; 1164 + info << " identifier " << i2 << ": " << pe.shared_identifiers.at(i2) << "\n";
  1165 + info << " numerator " << i2 << ": " << pe.shared_numerators.at(i2) << "\n";
1167 } 1166 }
1168 } 1167 }
1169 } 1168 }
@@ -1171,27 +1170,27 @@ Lin::dumpHPageOffset() @@ -1171,27 +1170,27 @@ Lin::dumpHPageOffset()
1171 void 1170 void
1172 Lin::dumpHSharedObject() 1171 Lin::dumpHSharedObject()
1173 { 1172 {
  1173 + auto& info = *m->cf.log_->getInfo();
1174 HSharedObject& t = m->shared_object_hints; 1174 HSharedObject& t = m->shared_object_hints;
1175 - *m->log->getInfo() << "first_shared_obj: " << t.first_shared_obj << "\n"  
1176 - << "first_shared_offset: " << adjusted_offset(t.first_shared_offset) << "\n"  
1177 - << "nshared_first_page: " << t.nshared_first_page << "\n"  
1178 - << "nshared_total: " << t.nshared_total << "\n"  
1179 - << "nbits_nobjects: " << t.nbits_nobjects << "\n"  
1180 - << "min_group_length: " << t.min_group_length << "\n"  
1181 - << "nbits_delta_group_length: " << t.nbits_delta_group_length << "\n"; 1175 + info << "first_shared_obj: " << t.first_shared_obj << "\n"
  1176 + << "first_shared_offset: " << adjusted_offset(t.first_shared_offset) << "\n"
  1177 + << "nshared_first_page: " << t.nshared_first_page << "\n"
  1178 + << "nshared_total: " << t.nshared_total << "\n"
  1179 + << "nbits_nobjects: " << t.nbits_nobjects << "\n"
  1180 + << "min_group_length: " << t.min_group_length << "\n"
  1181 + << "nbits_delta_group_length: " << t.nbits_delta_group_length << "\n";
1182 1182
1183 for (size_t i = 0; i < toS(t.nshared_total); ++i) { 1183 for (size_t i = 0; i < toS(t.nshared_total); ++i) {
1184 HSharedObjectEntry& se = t.entries.at(i); 1184 HSharedObjectEntry& se = t.entries.at(i);
1185 - *m->log->getInfo() << "Shared Object " << i << ":\n"  
1186 - << " group length: " << se.delta_group_length + t.min_group_length  
1187 - << "\n"; 1185 + info << "Shared Object " << i << ":\n"
  1186 + << " group length: " << se.delta_group_length + t.min_group_length << "\n";
1188 // PDF spec says signature present nobjects_minus_one are always 0, so print them only if 1187 // PDF spec says signature present nobjects_minus_one are always 0, so print them only if
1189 // they have a non-zero value. 1188 // they have a non-zero value.
1190 if (se.signature_present) { 1189 if (se.signature_present) {
1191 - *m->log->getInfo() << " signature present\n"; 1190 + info << " signature present\n";
1192 } 1191 }
1193 if (se.nobjects_minus_one != 0) { 1192 if (se.nobjects_minus_one != 0) {
1194 - *m->log->getInfo() << " nobjects: " << se.nobjects_minus_one + 1 << "\n"; 1193 + info << " nobjects: " << se.nobjects_minus_one + 1 << "\n";
1195 } 1194 }
1196 } 1195 }
1197 } 1196 }
@@ -1199,10 +1198,11 @@ Lin::dumpHSharedObject() @@ -1199,10 +1198,11 @@ Lin::dumpHSharedObject()
1199 void 1198 void
1200 Lin::dumpHGeneric(HGeneric& t) 1199 Lin::dumpHGeneric(HGeneric& t)
1201 { 1200 {
1202 - *m->log->getInfo() << "first_object: " << t.first_object << "\n"  
1203 - << "first_object_offset: " << adjusted_offset(t.first_object_offset) << "\n"  
1204 - << "nobjects: " << t.nobjects << "\n"  
1205 - << "group_length: " << t.group_length << "\n"; 1201 + *m->cf.log_->getInfo() << "first_object: " << t.first_object << "\n"
  1202 + << "first_object_offset: " << adjusted_offset(t.first_object_offset)
  1203 + << "\n"
  1204 + << "nobjects: " << t.nobjects << "\n"
  1205 + << "group_length: " << t.group_length << "\n";
1206 } 1206 }
1207 1207
1208 template <typename T> 1208 template <typename T>
libqpdf/QPDF_objects.cc
@@ -157,7 +157,7 @@ Objects::parse(char const* password) @@ -157,7 +157,7 @@ Objects::parse(char const* password)
157 throw damagedPDF("", -1, std::string("error reading xref: ") + e.what()); 157 throw damagedPDF("", -1, std::string("error reading xref: ") + e.what());
158 } 158 }
159 } catch (QPDFExc& e) { 159 } catch (QPDFExc& e) {
160 - if (m->attempt_recovery) { 160 + if (m->cf.attempt_recovery_) {
161 reconstruct_xref(e, xref_offset > 0); 161 reconstruct_xref(e, xref_offset > 0);
162 } else { 162 } else {
163 throw; 163 throw;
@@ -736,7 +736,7 @@ Objects::read_xrefTable(qpdf_offset_t xref_offset) @@ -736,7 +736,7 @@ Objects::read_xrefTable(qpdf_offset_t xref_offset)
736 } 736 }
737 737
738 if (cur_trailer.hasKey("/XRefStm")) { 738 if (cur_trailer.hasKey("/XRefStm")) {
739 - if (m->ignore_xref_streams) { 739 + if (m->cf.ignore_xref_streams_) {
740 QTC::TC("qpdf", "QPDF ignoring XRefStm in trailer"); 740 QTC::TC("qpdf", "QPDF ignoring XRefStm in trailer");
741 } else { 741 } else {
742 if (cur_trailer.getKey("/XRefStm").isInteger()) { 742 if (cur_trailer.getKey("/XRefStm").isInteger()) {
@@ -763,7 +763,7 @@ Objects::read_xrefTable(qpdf_offset_t xref_offset) @@ -763,7 +763,7 @@ Objects::read_xrefTable(qpdf_offset_t xref_offset)
763 qpdf_offset_t 763 qpdf_offset_t
764 Objects::read_xrefStream(qpdf_offset_t xref_offset, bool in_stream_recovery) 764 Objects::read_xrefStream(qpdf_offset_t xref_offset, bool in_stream_recovery)
765 { 765 {
766 - if (!m->ignore_xref_streams) { 766 + if (!m->cf.ignore_xref_streams_) {
767 QPDFObjectHandle xref_obj; 767 QPDFObjectHandle xref_obj;
768 try { 768 try {
769 m->in_read_xref_stream = true; 769 m->in_read_xref_stream = true;
@@ -1073,7 +1073,7 @@ Objects::insertFreeXrefEntry(QPDFObjGen og) @@ -1073,7 +1073,7 @@ Objects::insertFreeXrefEntry(QPDFObjGen og)
1073 void 1073 void
1074 QPDF::showXRefTable() 1074 QPDF::showXRefTable()
1075 { 1075 {
1076 - auto& cout = *m->log->getInfo(); 1076 + auto& cout = *m->cf.log_->getInfo();
1077 for (auto const& iter: m->xref_table) { 1077 for (auto const& iter: m->xref_table) {
1078 QPDFObjGen const& og = iter.first; 1078 QPDFObjGen const& og = iter.first;
1079 QPDFXRefEntry const& entry = iter.second; 1079 QPDFXRefEntry const& entry = iter.second;
@@ -1084,15 +1084,15 @@ QPDF::showXRefTable() @@ -1084,15 +1084,15 @@ QPDF::showXRefTable()
1084 break; 1084 break;
1085 1085
1086 case 2: 1086 case 2:
1087 - *m->log->getInfo() << "compressed; stream = " << entry.getObjStreamNumber()  
1088 - << ", index = " << entry.getObjStreamIndex(); 1087 + *m->cf.log_->getInfo() << "compressed; stream = " << entry.getObjStreamNumber()
  1088 + << ", index = " << entry.getObjStreamIndex();
1089 break; 1089 break;
1090 1090
1091 default: 1091 default:
1092 throw std::logic_error("unknown cross-reference table type while showing xref_table"); 1092 throw std::logic_error("unknown cross-reference table type while showing xref_table");
1093 break; 1093 break;
1094 } 1094 }
1095 - m->log->info("\n"); 1095 + m->cf.log_->info("\n");
1096 } 1096 }
1097 } 1097 }
1098 1098
@@ -1248,7 +1248,7 @@ Objects::readStream(QPDFObjectHandle&amp; object, QPDFObjGen og, qpdf_offset_t offse @@ -1248,7 +1248,7 @@ Objects::readStream(QPDFObjectHandle&amp; object, QPDFObjGen og, qpdf_offset_t offse
1248 throw damagedPDF("expected endstream"); 1248 throw damagedPDF("expected endstream");
1249 } 1249 }
1250 } catch (QPDFExc& e) { 1250 } catch (QPDFExc& e) {
1251 - if (m->attempt_recovery) { 1251 + if (m->cf.attempt_recovery_) {
1252 warn(e); 1252 warn(e);
1253 length = recoverStreamLength(m->file, og, stream_offset); 1253 length = recoverStreamLength(m->file, og, stream_offset);
1254 } else { 1254 } else {
@@ -1431,7 +1431,7 @@ Objects::readObjectAtOffset( @@ -1431,7 +1431,7 @@ Objects::readObjectAtOffset(
1431 QPDFObjGen og; 1431 QPDFObjGen og;
1432 setLastObjectDescription(description, exp_og); 1432 setLastObjectDescription(description, exp_og);
1433 1433
1434 - if (!m->attempt_recovery) { 1434 + if (!m->cf.attempt_recovery_) {
1435 try_recovery = false; 1435 try_recovery = false;
1436 } 1436 }
1437 1437
libqpdf/qpdf/QPDF_private.hh
@@ -5,6 +5,7 @@ @@ -5,6 +5,7 @@
5 5
6 #include <qpdf/QPDFAcroFormDocumentHelper.hh> 6 #include <qpdf/QPDFAcroFormDocumentHelper.hh>
7 #include <qpdf/QPDFEmbeddedFileDocumentHelper.hh> 7 #include <qpdf/QPDFEmbeddedFileDocumentHelper.hh>
  8 +#include <qpdf/QPDFLogger.hh>
8 #include <qpdf/QPDFObject_private.hh> 9 #include <qpdf/QPDFObject_private.hh>
9 #include <qpdf/QPDFOutlineDocumentHelper.hh> 10 #include <qpdf/QPDFOutlineDocumentHelper.hh>
10 #include <qpdf/QPDFPageDocumentHelper.hh> 11 #include <qpdf/QPDFPageDocumentHelper.hh>
@@ -20,6 +21,31 @@ namespace qpdf @@ -20,6 +21,31 @@ namespace qpdf
20 { 21 {
21 class OffsetBuffer; 22 class OffsetBuffer;
22 } // namespace is 23 } // namespace is
  24 +
  25 + class Doc: public QPDF
  26 + {
  27 + public:
  28 + class Config
  29 + {
  30 + friend class QPDF;
  31 +
  32 + Config() :
  33 + log_(QPDFLogger::defaultLogger())
  34 + {
  35 + }
  36 +
  37 + std::shared_ptr<QPDFLogger> log_;
  38 +
  39 + size_t max_warnings_{0};
  40 +
  41 + bool provided_password_is_hex_key_{false};
  42 + bool ignore_xref_streams_{false};
  43 + bool suppress_warnings_{false};
  44 + bool attempt_recovery_{true};
  45 + bool check_mode_{false};
  46 + bool immediate_copy_from_{false};
  47 + }; // Class Config
  48 + }; // class Doc
23 } // namespace qpdf 49 } // namespace qpdf
24 50
25 class BitStream; 51 class BitStream;
@@ -421,10 +447,13 @@ class QPDF::Doc @@ -421,10 +447,13 @@ class QPDF::Doc
421 return *page_labels_; 447 return *page_labels_;
422 } 448 }
423 449
424 - private: 450 + protected:
425 QPDF& qpdf; 451 QPDF& qpdf;
426 QPDF::Members* m; 452 QPDF::Members* m;
427 453
  454 + qpdf::Doc::Config cf;
  455 +
  456 + private:
428 // Document Helpers; 457 // Document Helpers;
429 std::unique_ptr<QPDFAcroFormDocumentHelper> acroform_; 458 std::unique_ptr<QPDFAcroFormDocumentHelper> acroform_;
430 std::unique_ptr<QPDFEmbeddedFileDocumentHelper> embedded_files_; 459 std::unique_ptr<QPDFEmbeddedFileDocumentHelper> embedded_files_;
@@ -969,18 +998,11 @@ class QPDF::Members: Doc @@ -969,18 +998,11 @@ class QPDF::Members: Doc
969 Doc::Linearization lin; 998 Doc::Linearization lin;
970 Doc::Objects objects; 999 Doc::Objects objects;
971 Doc::Pages pages; 1000 Doc::Pages pages;
972 - std::shared_ptr<QPDFLogger> log;  
973 unsigned long long unique_id{0}; 1001 unsigned long long unique_id{0};
974 qpdf::Tokenizer tokenizer; 1002 qpdf::Tokenizer tokenizer;
975 std::shared_ptr<InputSource> file; 1003 std::shared_ptr<InputSource> file;
976 std::string last_object_description; 1004 std::string last_object_description;
977 std::shared_ptr<QPDFObject::Description> last_ostream_description; 1005 std::shared_ptr<QPDFObject::Description> last_ostream_description;
978 - bool provided_password_is_hex_key{false};  
979 - bool ignore_xref_streams{false};  
980 - bool suppress_warnings{false};  
981 - size_t max_warnings{0};  
982 - bool attempt_recovery{true};  
983 - bool check_mode{false};  
984 std::shared_ptr<EncryptionParameters> encp; 1006 std::shared_ptr<EncryptionParameters> encp;
985 std::string pdf_version; 1007 std::string pdf_version;
986 std::map<QPDFObjGen, QPDFXRefEntry> xref_table; 1008 std::map<QPDFObjGen, QPDFXRefEntry> xref_table;
@@ -995,7 +1017,6 @@ class QPDF::Members: Doc @@ -995,7 +1017,6 @@ class QPDF::Members: Doc
995 bool reconstructed_xref{false}; 1017 bool reconstructed_xref{false};
996 bool in_read_xref_stream{false}; 1018 bool in_read_xref_stream{false};
997 bool fixed_dangling_refs{false}; 1019 bool fixed_dangling_refs{false};
998 - bool immediate_copy_from{false};  
999 bool in_parse{false}; 1020 bool in_parse{false};
1000 bool parsed{false}; 1021 bool parsed{false};
1001 std::set<int> resolved_object_streams; 1022 std::set<int> resolved_object_streams;