Commit ac039c8525407361477f041550db6fb0efbc497a
1 parent
0fae76cf
Refactor `QPDFJob`: replace `infilename` with `infile_name()`, centralize input …
…file handling in `Inputs`, and simplify related logic.
Showing
4 changed files
with
52 additions
and
29 deletions
libqpdf/QPDFJob.cc
| ... | ... | @@ -394,7 +394,7 @@ QPDFJob::createQPDF() |
| 394 | 394 | checkConfiguration(); |
| 395 | 395 | std::unique_ptr<QPDF> pdf_sp; |
| 396 | 396 | try { |
| 397 | - processFile(pdf_sp, m->infilename.data(), m->password.data(), true, true); | |
| 397 | + processFile(pdf_sp, m->infile_nm(), m->password.data(), true, true); | |
| 398 | 398 | } catch (QPDFExc& e) { |
| 399 | 399 | if (e.getErrorCode() == qpdf_e_password) { |
| 400 | 400 | // Allow certain operations to work when an incorrect password is supplied. |
| ... | ... | @@ -567,10 +567,10 @@ QPDFJob::checkConfiguration() |
| 567 | 567 | // standard output. |
| 568 | 568 | m->outfilename = "-"; |
| 569 | 569 | } |
| 570 | - if (m->infilename.empty() && !m->empty_input) { | |
| 570 | + if (m->infile_name().empty() && !m->empty_input) { | |
| 571 | 571 | usage("an input file name is required"); |
| 572 | 572 | } |
| 573 | - if (m->replace_input && m->infilename.empty()) { | |
| 573 | + if (m->replace_input && m->infile_name().empty()) { | |
| 574 | 574 | usage("--replace-input may not be used with --empty"); |
| 575 | 575 | } |
| 576 | 576 | if (m->require_outfile && m->outfilename.empty() && !m->replace_input) { |
| ... | ... | @@ -609,8 +609,7 @@ QPDFJob::checkConfiguration() |
| 609 | 609 | if (save_to_stdout) { |
| 610 | 610 | m->log->saveToStandardOutput(true); |
| 611 | 611 | } |
| 612 | - if (!m->split_pages && QUtil::same_file(m->infilename.data(), m->outfilename.data())) { | |
| 613 | - QTC::TC("qpdf", "QPDFJob same file error"); | |
| 612 | + if (!m->split_pages && QUtil::same_file(m->infile_nm(), m->outfilename.data())) { | |
| 614 | 613 | usage( |
| 615 | 614 | "input file and output file are the same; use --replace-input to intentionally " |
| 616 | 615 | "overwrite the input file"); |
| ... | ... | @@ -734,7 +733,7 @@ QPDFJob::doCheck(QPDF& pdf) |
| 734 | 733 | // may continue to perform additional checks after finding errors. |
| 735 | 734 | bool okay = true; |
| 736 | 735 | auto& cout = *m->log->getInfo(); |
| 737 | - cout << "checking " << m->infilename << "\n"; | |
| 736 | + cout << "checking " << m->infile_name() << "\n"; | |
| 738 | 737 | QPDF::JobSetter::setCheckMode(pdf, true); |
| 739 | 738 | try { |
| 740 | 739 | int extension_level = pdf.getExtensionLevel(); |
| ... | ... | @@ -905,7 +904,7 @@ QPDFJob::doListAttachments(QPDF& pdf) |
| 905 | 904 | }); |
| 906 | 905 | } |
| 907 | 906 | } else { |
| 908 | - *m->log->getInfo() << m->infilename << " has no embedded files\n"; | |
| 907 | + *m->log->getInfo() << m->infile_name() << " has no embedded files\n"; | |
| 909 | 908 | } |
| 910 | 909 | } |
| 911 | 910 | |
| ... | ... | @@ -1671,7 +1670,6 @@ QPDFJob::doInspection(QPDF& pdf) |
| 1671 | 1670 | doCheck(pdf); |
| 1672 | 1671 | } |
| 1673 | 1672 | if (m->show_npages) { |
| 1674 | - QTC::TC("qpdf", "QPDFJob npages"); | |
| 1675 | 1673 | cout << pdf.getRoot().getKey("/Pages").getKey("/Count").getIntValue() << "\n"; |
| 1676 | 1674 | } |
| 1677 | 1675 | if (m->show_encryption) { |
| ... | ... | @@ -1679,9 +1677,9 @@ QPDFJob::doInspection(QPDF& pdf) |
| 1679 | 1677 | } |
| 1680 | 1678 | if (m->check_linearization) { |
| 1681 | 1679 | if (!pdf.isLinearized()) { |
| 1682 | - cout << m->infilename << " is not linearized\n"; | |
| 1680 | + cout << m->infile_name() << " is not linearized\n"; | |
| 1683 | 1681 | } else if (pdf.checkLinearization()) { |
| 1684 | - cout << m->infilename << ": no linearization errors\n"; | |
| 1682 | + cout << m->infile_name() << ": no linearization errors\n"; | |
| 1685 | 1683 | } else { |
| 1686 | 1684 | m->warnings = true; |
| 1687 | 1685 | } |
| ... | ... | @@ -1690,7 +1688,7 @@ QPDFJob::doInspection(QPDF& pdf) |
| 1690 | 1688 | if (pdf.isLinearized()) { |
| 1691 | 1689 | pdf.showLinearizationData(); |
| 1692 | 1690 | } else { |
| 1693 | - cout << m->infilename << " is not linearized\n"; | |
| 1691 | + cout << m->infile_name() << " is not linearized\n"; | |
| 1694 | 1692 | } |
| 1695 | 1693 | } |
| 1696 | 1694 | if (m->show_xref) { |
| ... | ... | @@ -1727,7 +1725,7 @@ QPDFJob::doProcessOnce( |
| 1727 | 1725 | if (empty) { |
| 1728 | 1726 | pdf->emptyPDF(); |
| 1729 | 1727 | } else if (main_input && m->json_input) { |
| 1730 | - pdf->createFromJSON(m->infilename); | |
| 1728 | + pdf->createFromJSON(m->infile_name()); | |
| 1731 | 1729 | } else { |
| 1732 | 1730 | fn(pdf.get(), password); |
| 1733 | 1731 | } |
| ... | ... | @@ -2431,13 +2429,13 @@ QPDFJob::handlePageSpecs(QPDF& pdf) |
| 2431 | 2429 | if (m->inputs.selections.empty()) { |
| 2432 | 2430 | return; |
| 2433 | 2431 | } |
| 2434 | - auto& main_input = m->inputs.files[m->infilename]; | |
| 2432 | + auto& main_input = m->inputs.files[m->infile_name()]; | |
| 2435 | 2433 | main_input.initialize(m->inputs, &pdf); |
| 2436 | 2434 | |
| 2437 | 2435 | // Handle "." as a shortcut for the input file. |
| 2438 | 2436 | for (auto& selection: m->inputs.selections) { |
| 2439 | 2437 | if (selection.filename == ".") { |
| 2440 | - selection.filename = m->infilename; | |
| 2438 | + selection.filename = m->infile_name(); | |
| 2441 | 2439 | } else { |
| 2442 | 2440 | // Force insertion |
| 2443 | 2441 | (void)m->inputs.files[selection.filename]; |
| ... | ... | @@ -3012,7 +3010,7 @@ QPDFJob::doSplitPages(QPDF& pdf) |
| 3012 | 3010 | page_range += "-" + QUtil::uint_to_string(last, QIntC::to_int(pageno_len)); |
| 3013 | 3011 | } |
| 3014 | 3012 | std::string outfile = before + page_range + after; |
| 3015 | - if (QUtil::same_file(m->infilename.data(), outfile.data())) { | |
| 3013 | + if (QUtil::same_file(m->infile_nm(), outfile.data())) { | |
| 3016 | 3014 | throw std::runtime_error("split pages would overwrite input file with " + outfile); |
| 3017 | 3015 | } |
| 3018 | 3016 | QPDFWriter w(outpdf, outfile.c_str()); |
| ... | ... | @@ -3031,7 +3029,7 @@ QPDFJob::writeOutfile(QPDF& pdf) |
| 3031 | 3029 | if (m->replace_input) { |
| 3032 | 3030 | // Append but don't prepend to the path to generate a temporary name. This saves us from |
| 3033 | 3031 | // having to split the path by directory and non-directory. |
| 3034 | - temp_out = m->infilename + ".~qpdf-temp#"; | |
| 3032 | + temp_out = m->infile_name() + ".~qpdf-temp#"; | |
| 3035 | 3033 | // m->outfilename will be restored to 0 before temp_out goes out of scope. |
| 3036 | 3034 | m->outfilename = temp_out; |
| 3037 | 3035 | } else if (m->outfilename == "-") { |
| ... | ... | @@ -3065,13 +3063,13 @@ QPDFJob::writeOutfile(QPDF& pdf) |
| 3065 | 3063 | if (m->replace_input) { |
| 3066 | 3064 | // We must close the input before we can rename files |
| 3067 | 3065 | pdf.closeInputSource(); |
| 3068 | - std::string backup = m->infilename + ".~qpdf-orig"; | |
| 3066 | + std::string backup = m->infile_name() + ".~qpdf-orig"; | |
| 3069 | 3067 | bool warnings = pdf.anyWarnings(); |
| 3070 | 3068 | if (!warnings) { |
| 3071 | 3069 | backup.append(1, '#'); |
| 3072 | 3070 | } |
| 3073 | - QUtil::rename_file(m->infilename.data(), backup.data()); | |
| 3074 | - QUtil::rename_file(temp_out.data(), m->infilename.data()); | |
| 3071 | + QUtil::rename_file(m->infile_nm(), backup.data()); | |
| 3072 | + QUtil::rename_file(temp_out.data(), m->infile_nm()); | |
| 3075 | 3073 | if (warnings) { |
| 3076 | 3074 | *m->log->getError() << m->message_prefix |
| 3077 | 3075 | << ": there are warnings; original file kept in " << backup << "\n"; | ... | ... |
libqpdf/QPDFJob_config.cc
| ... | ... | @@ -15,18 +15,14 @@ QPDFJob::Config::checkConfiguration() |
| 15 | 15 | QPDFJob::Config* |
| 16 | 16 | QPDFJob::Config::inputFile(std::string const& filename) |
| 17 | 17 | { |
| 18 | - if (o.m->infilename.empty()) { | |
| 19 | - o.m->infilename = filename; | |
| 20 | - } else { | |
| 21 | - usage("input file has already been given"); | |
| 22 | - } | |
| 18 | + o.m->inputs.infile_name(filename); | |
| 23 | 19 | return this; |
| 24 | 20 | } |
| 25 | 21 | |
| 26 | 22 | QPDFJob::Config* |
| 27 | 23 | QPDFJob::Config::emptyInput() |
| 28 | 24 | { |
| 29 | - if (o.m->infilename.empty()) { | |
| 25 | + if (o.m->infile_name().empty()) { | |
| 30 | 26 | // Various places in QPDFJob.cc used to know that the empty string for infile means empty. |
| 31 | 27 | // This approach meant that passing "" as the argument to inputFile in job JSON, or |
| 32 | 28 | // equivalently using "" as a positional command-line argument would be the same as | ... | ... |
libqpdf/qpdf/QPDFJob_private.hh
| ... | ... | @@ -69,6 +69,22 @@ struct QPDFJob::Inputs |
| 69 | 69 | void new_selection( |
| 70 | 70 | std::string const& filename, std::string const& password, std::string const& range); |
| 71 | 71 | |
| 72 | + std::string const& | |
| 73 | + infile_name() const | |
| 74 | + { | |
| 75 | + return infile_name_; | |
| 76 | + } | |
| 77 | + | |
| 78 | + void | |
| 79 | + infile_name(std::string const& name) | |
| 80 | + { | |
| 81 | + if (!infile_name_.empty()) { | |
| 82 | + usage("input file has already been given"); | |
| 83 | + } | |
| 84 | + infile_name_ = name; | |
| 85 | + } | |
| 86 | + | |
| 87 | + std::string infile_name_; | |
| 72 | 88 | std::string encryption_file; |
| 73 | 89 | std::string encryption_file_password; |
| 74 | 90 | bool keep_files_open{true}; |
| ... | ... | @@ -145,6 +161,10 @@ class QPDFJob::Members |
| 145 | 161 | Members(Members const&) = delete; |
| 146 | 162 | ~Members() = default; |
| 147 | 163 | |
| 164 | + inline const char* infile_nm() const; | |
| 165 | + | |
| 166 | + inline std::string const& infile_name() const; | |
| 167 | + | |
| 148 | 168 | private: |
| 149 | 169 | // These default values are duplicated in help and docs. |
| 150 | 170 | static int constexpr DEFAULT_OI_MIN_WIDTH = 128; |
| ... | ... | @@ -272,7 +292,6 @@ class QPDFJob::Members |
| 272 | 292 | bool replace_input{false}; |
| 273 | 293 | bool check_is_encrypted{false}; |
| 274 | 294 | bool check_requires_password{false}; |
| 275 | - std::string infilename; | |
| 276 | 295 | bool empty_input{false}; |
| 277 | 296 | std::string outfilename; |
| 278 | 297 | bool json_input{false}; |
| ... | ... | @@ -282,4 +301,16 @@ class QPDFJob::Members |
| 282 | 301 | std::vector<PageLabelSpec> page_label_specs; |
| 283 | 302 | }; |
| 284 | 303 | |
| 285 | -#endif // QPDFOBJECT_PRIVATE_HH | |
| 304 | +inline const char* | |
| 305 | +QPDFJob::Members::infile_nm() const | |
| 306 | +{ | |
| 307 | + return inputs.infile_name().data(); | |
| 308 | +} | |
| 309 | + | |
| 310 | +inline std::string const& | |
| 311 | +QPDFJob::Members::infile_name() const | |
| 312 | +{ | |
| 313 | + return inputs.infile_name(); | |
| 314 | +} | |
| 315 | + | |
| 316 | +#endif // QPDFJOB_PRIVATE_HH | ... | ... |
qpdf/qpdf.testcov
| ... | ... | @@ -208,7 +208,6 @@ QPDF not caching overridden objstm object 0 |
| 208 | 208 | QPDF_optimization indirect outlines 0 |
| 209 | 209 | QPDF xref space 2 |
| 210 | 210 | QPDFJob pages range omitted in middle 0 |
| 211 | -QPDFJob npages 0 | |
| 212 | 211 | QPDFWriter standard deterministic ID 1 |
| 213 | 212 | QPDFWriter linearized deterministic ID 1 |
| 214 | 213 | qpdf-c called qpdf_set_deterministic_ID 0 |
| ... | ... | @@ -221,7 +220,6 @@ QPDFParser found fake 1 |
| 221 | 220 | QPDFParser no val for last key 0 |
| 222 | 221 | QPDF resolve failure to null 0 |
| 223 | 222 | QPDFObjectHandle errors in parsecontent 0 |
| 224 | -QPDFJob same file error 0 | |
| 225 | 223 | QPDFJob split-pages %d 0 |
| 226 | 224 | QPDFJob split-pages .pdf 0 |
| 227 | 225 | QPDFJob split-pages other 0 | ... | ... |