Commit b520c1504a3e217608405b196be897fe3a5b104e

Authored by m-holger
1 parent 49010866

Refactor `Config` interface: add accessor and mutator methods for configuration …

…fields, replace direct member access across the codebase, and streamline related logic.
libqpdf/QPDF.cc
... ... @@ -231,7 +231,7 @@ QPDF::closeInputSource()
231 231 void
232 232 QPDF::setPasswordIsHexKey(bool val)
233 233 {
234   - m->cf.provided_password_is_hex_key_ = val;
  234 + m->cf.provided_password_is_hex_key(val);
235 235 }
236 236  
237 237 void
... ... @@ -250,50 +250,50 @@ QPDF::registerStreamFilter(
250 250 void
251 251 QPDF::setIgnoreXRefStreams(bool val)
252 252 {
253   - m->cf.ignore_xref_streams_ = val;
  253 + m->cf.ignore_xref_streams(val);
254 254 }
255 255  
256 256 std::shared_ptr<QPDFLogger>
257 257 QPDF::getLogger()
258 258 {
259   - return m->cf.log_;
  259 + return m->cf.log();
260 260 }
261 261  
262 262 void
263 263 QPDF::setLogger(std::shared_ptr<QPDFLogger> l)
264 264 {
265   - m->cf.log_ = l;
  265 + m->cf.log(l);
266 266 }
267 267  
268 268 void
269 269 QPDF::setOutputStreams(std::ostream* out, std::ostream* err)
270 270 {
271 271 setLogger(QPDFLogger::create());
272   - m->cf.log_->setOutputStreams(out, err);
  272 + m->cf.log()->setOutputStreams(out, err);
273 273 }
274 274  
275 275 void
276 276 QPDF::setSuppressWarnings(bool val)
277 277 {
278   - m->cf.suppress_warnings_ = val;
  278 + m->cf.suppress_warnings(val);
279 279 }
280 280  
281 281 void
282 282 QPDF::setMaxWarnings(size_t val)
283 283 {
284   - m->cf.max_warnings_ = val;
  284 + m->cf.max_warnings(val);
285 285 }
286 286  
287 287 void
288 288 QPDF::setAttemptRecovery(bool val)
289 289 {
290   - m->cf.attempt_recovery_ = val;
  290 + (void)m->cf.attempt_recovery(val);
291 291 }
292 292  
293 293 void
294 294 QPDF::setImmediateCopyFrom(bool val)
295 295 {
296   - m->cf.immediate_copy_from_ = val;
  296 + (void)m->cf.immediate_copy_from(val);
297 297 }
298 298  
299 299 std::vector<QPDFExc>
... ... @@ -371,12 +371,12 @@ QPDF::warn(QPDFExc const&amp; e)
371 371 void
372 372 Common::warn(QPDFExc const& e)
373 373 {
374   - if (m->cf.max_warnings_ > 0 && m->warnings.size() >= m->cf.max_warnings_) {
  374 + if (cf.max_warnings() > 0 && m->warnings.size() >= cf.max_warnings()) {
375 375 stopOnError("Too many warnings - file is too badly damaged");
376 376 }
377 377 m->warnings.emplace_back(e);
378   - if (!m->cf.suppress_warnings_) {
379   - *m->cf.log_->getWarn() << "WARNING: " << m->warnings.back().what() << "\n";
  378 + if (!cf.suppress_warnings()) {
  379 + *cf.log()->getWarn() << "WARNING: " << m->warnings.back().what() << "\n";
380 380 }
381 381 }
382 382  
... ... @@ -714,7 +714,7 @@ QPDF::getRoot()
714 714 } else if (
715 715 // Check_mode is an interim solution to request #810 pending a more comprehensive review of
716 716 // the approach to more extensive checks and warning levels.
717   - m->cf.check_mode_ && !root.getKey("/Type").isNameAndEquals("/Catalog")) {
  717 + m->cf.check_mode() && !root.getKey("/Type").isNameAndEquals("/Catalog")) {
718 718 warn(m->c.damagedPDF("", -1, "catalog /Type entry missing or invalid"));
719 719 root.replaceKey("/Type", "/Catalog"_qpdf);
720 720 }
... ...
libqpdf/QPDFJob.cc
... ... @@ -33,18 +33,6 @@ using namespace qpdf;
33 33 using QDoc = QPDF::Doc;
34 34 using Pages = QDoc::Pages;
35 35  
36   -// JobSetter class is restricted to QPDFJob.
37   -class QDoc::JobSetter
38   -{
39   - public:
40   - // Enable enhanced warnings for pdf file checking.
41   - static void
42   - setCheckMode(QPDF& qpdf, bool val)
43   - {
44   - qpdf.m->cf.check_mode_ = val;
45   - }
46   -};
47   -
48 36 namespace
49 37 {
50 38 class ImageOptimizer final: public QPDFObjectHandle::StreamDataProvider
... ... @@ -749,7 +737,7 @@ QPDFJob::doCheck(QPDF&amp; pdf)
749 737 bool okay = true;
750 738 auto& cout = *m->log->getInfo();
751 739 cout << "checking " << m->infile_name() << "\n";
752   - QDoc::JobSetter::setCheckMode(pdf, true);
  740 + pdf.doc().config().check_mode(true);
753 741 try {
754 742 int extension_level = pdf.getExtensionLevel();
755 743 cout << "PDF Version: " << pdf.getPDFVersion();
... ...
libqpdf/QPDF_Stream.cc
... ... @@ -27,12 +27,6 @@ using namespace qpdf;
27 27  
28 28 using Streams = QPDF::Doc::Objects::Streams;
29 29  
30   -bool
31   -Streams::immediate_copy_from() const
32   -{
33   - return qpdf.m->cf.immediate_copy_from_;
34   -}
35   -
36 30 class Streams::Copier final: public QPDFObjectHandle::StreamDataProvider
37 31 {
38 32 class Data
... ... @@ -308,14 +302,13 @@ Stream::copy_data_to(Stream&amp; dest)
308 302 {
309 303 qpdf_expect(dest);
310 304 auto s = stream();
311   - auto& streams = qpdf()->doc().objects().streams();
312 305 auto& d_streams = dest.qpdf()->doc().objects().streams();
313 306  
314 307 auto dict = dest.getDict();
315 308  
316 309 // Copy information from the foreign stream so we can pipe its data later without keeping the
317 310 // original QPDF object around.
318   - if (streams.immediate_copy_from() && !s->stream_data) {
  311 + if (qpdf()->doc().config().immediate_copy_from() && !s->stream_data) {
319 312 // Pull the stream data into a buffer before attempting the copy operation. Do it on the
320 313 // source stream so that if the source stream is copied multiple times, we don't have to
321 314 // keep duplicating the memory.
... ...
libqpdf/QPDF_encryption.cc
... ... @@ -904,7 +904,7 @@ QPDF::EncryptionParameters::initialize(QPDF&amp; qpdf)
904 904 }
905 905  
906 906 Encryption data(V, R, Length / 8, p, O, U, OE, UE, Perms, id1, encrypt_metadata);
907   - if (qm.cf.provided_password_is_hex_key_) {
  907 + if (qm.cf.provided_password_is_hex_key()) {
908 908 // ignore passwords in file
909 909 encryption_key = QUtil::hex_decode(provided_password);
910 910 return;
... ...
libqpdf/QPDF_linearization.cc
... ... @@ -1095,7 +1095,7 @@ QPDF::showLinearizationData()
1095 1095 void
1096 1096 Lin::dumpLinearizationDataInternal()
1097 1097 {
1098   - auto& info = *m->cf.log_->getInfo();
  1098 + auto& info = *cf.log()->getInfo();
1099 1099  
1100 1100 info << m->file->getName() << ": linearization data:\n\n";
1101 1101  
... ... @@ -1134,7 +1134,7 @@ Lin::adjusted_offset(qpdf_offset_t offset)
1134 1134 void
1135 1135 Lin::dumpHPageOffset()
1136 1136 {
1137   - auto& info = *m->cf.log_->getInfo();
  1137 + auto& info = *cf.log()->getInfo();
1138 1138 HPageOffset& t = m->page_offset_hints;
1139 1139 info << "min_nobjects: " << t.min_nobjects << "\n"
1140 1140 << "first_page_offset: " << adjusted_offset(t.first_page_offset) << "\n"
... ... @@ -1170,7 +1170,7 @@ Lin::dumpHPageOffset()
1170 1170 void
1171 1171 Lin::dumpHSharedObject()
1172 1172 {
1173   - auto& info = *m->cf.log_->getInfo();
  1173 + auto& info = *cf.log()->getInfo();
1174 1174 HSharedObject& t = m->shared_object_hints;
1175 1175 info << "first_shared_obj: " << t.first_shared_obj << "\n"
1176 1176 << "first_shared_offset: " << adjusted_offset(t.first_shared_offset) << "\n"
... ... @@ -1198,11 +1198,11 @@ Lin::dumpHSharedObject()
1198 1198 void
1199 1199 Lin::dumpHGeneric(HGeneric& t)
1200 1200 {
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";
  1201 + *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 1208 template <typename T>
... ...
libqpdf/QPDF_objects.cc
... ... @@ -157,7 +157,7 @@ Objects::parse(char const* password)
157 157 throw damagedPDF("", -1, std::string("error reading xref: ") + e.what());
158 158 }
159 159 } catch (QPDFExc& e) {
160   - if (m->cf.attempt_recovery_) {
  160 + if (cf.attempt_recovery()) {
161 161 reconstruct_xref(e, xref_offset > 0);
162 162 } else {
163 163 throw;
... ... @@ -736,7 +736,7 @@ Objects::read_xrefTable(qpdf_offset_t xref_offset)
736 736 }
737 737  
738 738 if (cur_trailer.hasKey("/XRefStm")) {
739   - if (m->cf.ignore_xref_streams_) {
  739 + if (cf.ignore_xref_streams()) {
740 740 QTC::TC("qpdf", "QPDF ignoring XRefStm in trailer");
741 741 } else {
742 742 if (cur_trailer.getKey("/XRefStm").isInteger()) {
... ... @@ -763,7 +763,7 @@ Objects::read_xrefTable(qpdf_offset_t xref_offset)
763 763 qpdf_offset_t
764 764 Objects::read_xrefStream(qpdf_offset_t xref_offset, bool in_stream_recovery)
765 765 {
766   - if (!m->cf.ignore_xref_streams_) {
  766 + if (!cf.ignore_xref_streams()) {
767 767 QPDFObjectHandle xref_obj;
768 768 try {
769 769 m->in_read_xref_stream = true;
... ... @@ -1073,7 +1073,7 @@ Objects::insertFreeXrefEntry(QPDFObjGen og)
1073 1073 void
1074 1074 QPDF::showXRefTable()
1075 1075 {
1076   - auto& cout = *m->cf.log_->getInfo();
  1076 + auto& cout = *m->cf.log()->getInfo();
1077 1077 for (auto const& iter: m->xref_table) {
1078 1078 QPDFObjGen const& og = iter.first;
1079 1079 QPDFXRefEntry const& entry = iter.second;
... ... @@ -1084,15 +1084,15 @@ QPDF::showXRefTable()
1084 1084 break;
1085 1085  
1086 1086 case 2:
1087   - *m->cf.log_->getInfo() << "compressed; stream = " << entry.getObjStreamNumber()
1088   - << ", index = " << entry.getObjStreamIndex();
  1087 + *m->cf.log()->getInfo() << "compressed; stream = " << entry.getObjStreamNumber()
  1088 + << ", index = " << entry.getObjStreamIndex();
1089 1089 break;
1090 1090  
1091 1091 default:
1092 1092 throw std::logic_error("unknown cross-reference table type while showing xref_table");
1093 1093 break;
1094 1094 }
1095   - m->cf.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 1248 throw damagedPDF("expected endstream");
1249 1249 }
1250 1250 } catch (QPDFExc& e) {
1251   - if (m->cf.attempt_recovery_) {
  1251 + if (cf.attempt_recovery()) {
1252 1252 warn(e);
1253 1253 length = recoverStreamLength(m->file, og, stream_offset);
1254 1254 } else {
... ... @@ -1431,7 +1431,7 @@ Objects::readObjectAtOffset(
1431 1431 QPDFObjGen og;
1432 1432 setLastObjectDescription(description, exp_og);
1433 1433  
1434   - if (!m->cf.attempt_recovery_) {
  1434 + if (!cf.attempt_recovery()) {
1435 1435 try_recovery = false;
1436 1436 }
1437 1437  
... ...
libqpdf/qpdf/QPDF_private.hh
... ... @@ -27,13 +27,117 @@ namespace qpdf
27 27 public:
28 28 class Config
29 29 {
30   - friend class QPDF;
31   -
  30 + public:
32 31 Config() :
33 32 log_(QPDFLogger::defaultLogger())
34 33 {
35 34 }
36 35  
  36 + bool
  37 + provided_password_is_hex_key() const
  38 + {
  39 + return provided_password_is_hex_key_;
  40 + }
  41 +
  42 + Config&
  43 + provided_password_is_hex_key(bool val)
  44 + {
  45 + provided_password_is_hex_key_ = val;
  46 + return *this;
  47 + }
  48 +
  49 + bool
  50 + ignore_xref_streams() const
  51 + {
  52 + return ignore_xref_streams_;
  53 + }
  54 +
  55 + Config&
  56 + ignore_xref_streams(bool val)
  57 + {
  58 + ignore_xref_streams_ = val;
  59 + return *this;
  60 + }
  61 +
  62 + std::shared_ptr<QPDFLogger>
  63 + log() const
  64 + {
  65 + return log_;
  66 + }
  67 +
  68 + Config&
  69 + log(std::shared_ptr<QPDFLogger> val)
  70 + {
  71 + log_ = val;
  72 + return *this;
  73 + }
  74 +
  75 + bool
  76 + suppress_warnings() const
  77 + {
  78 + return suppress_warnings_;
  79 + }
  80 +
  81 + Config&
  82 + suppress_warnings(bool val)
  83 + {
  84 + suppress_warnings_ = val;
  85 + return *this;
  86 + }
  87 +
  88 + size_t
  89 + max_warnings() const
  90 + {
  91 + return max_warnings_;
  92 + }
  93 +
  94 + Config&
  95 + max_warnings(size_t val)
  96 + {
  97 + max_warnings_ = val;
  98 + return *this;
  99 + }
  100 +
  101 + bool
  102 + attempt_recovery() const
  103 + {
  104 + return attempt_recovery_;
  105 + }
  106 +
  107 + Config&
  108 + attempt_recovery(bool val)
  109 + {
  110 + attempt_recovery_ = val;
  111 + return *this;
  112 + }
  113 +
  114 + bool
  115 + immediate_copy_from() const
  116 + {
  117 + return immediate_copy_from_;
  118 + }
  119 +
  120 + Config&
  121 + immediate_copy_from(bool val)
  122 + {
  123 + immediate_copy_from_ = val;
  124 + return *this;
  125 + }
  126 +
  127 + bool
  128 + check_mode() const
  129 + {
  130 + return check_mode_;
  131 + }
  132 +
  133 + Config&
  134 + check_mode(bool val)
  135 + {
  136 + check_mode_ = val;
  137 + return *this;
  138 + }
  139 +
  140 + private:
37 141 std::shared_ptr<QPDFLogger> log_;
38 142  
39 143 size_t max_warnings_{0};
... ... @@ -322,7 +426,6 @@ class QPDF::Doc
322 426 {
323 427 public:
324 428 class Encryption;
325   - class JobSetter;
326 429 class Linearization;
327 430 class Objects;
328 431 class Pages;
... ... @@ -378,6 +481,7 @@ class QPDF::Doc
378 481 QPDF& qpdf;
379 482 QPDF::Members* m;
380 483  
  484 + qpdf::Doc::Config& cf;
381 485 QPDF::Doc::Pages& pages;
382 486 };
383 487  
... ... @@ -394,6 +498,12 @@ class QPDF::Doc
394 498 {
395 499 }
396 500  
  501 + qpdf::Doc::Config&
  502 + config()
  503 + {
  504 + return cf;
  505 + }
  506 +
397 507 inline Linearization& linearization();
398 508  
399 509 inline Objects& objects();
... ... @@ -772,7 +882,7 @@ class QPDF::Doc::Objects: Common
772 882 return copier_;
773 883 }
774 884  
775   - bool immediate_copy_from() const;
  885 + // bool immediate_copy_from() const;
776 886  
777 887 private:
778 888 std::shared_ptr<Copier> copier_;
... ... @@ -1072,6 +1182,7 @@ class QPDF::Doc::Resolver
1072 1182 inline QPDF::Doc::Common::Common(QPDF& qpdf, QPDF::Members* m) :
1073 1183 qpdf(qpdf),
1074 1184 m(m),
  1185 + cf(m->cf),
1075 1186 pages(m->pages)
1076 1187 {
1077 1188 }
... ...