Commit 0a354af02cf51aeb1602596988c8f826b47b3a81

Authored by Jay Berkenbilt
1 parent a87dcba1

QPDFJob: convert AddAttachment handlers

generate_auto_job
@@ -52,19 +52,13 @@ not_yet = set([ @@ -52,19 +52,13 @@ not_yet = set([
52 'annotate', 52 'annotate',
53 'assemble', 53 'assemble',
54 'cleartext-metadata', 54 'cleartext-metadata',
55 - 'creationdate',  
56 'decode-level', 55 'decode-level',
57 - 'description',  
58 'extract', 56 'extract',
59 - 'filename',  
60 'force-R5', 57 'force-R5',
61 'force-V4', 58 'force-V4',
62 'form', 59 'form',
63 'from', 60 'from',
64 'job-json-file', 61 'job-json-file',
65 - 'key',  
66 - 'mimetype',  
67 - 'moddate',  
68 'modify', 62 'modify',
69 'modify-other', 63 'modify-other',
70 'object-streams', 64 'object-streams',
@@ -73,7 +67,6 @@ not_yet = set([ @@ -73,7 +67,6 @@ not_yet = set([
73 'print', 67 'print',
74 'remove-unreferenced-resources', 68 'remove-unreferenced-resources',
75 'repeat', 69 'repeat',
76 - 'replace',  
77 'rotate', 70 'rotate',
78 'show-object', 71 'show-object',
79 'stream-data', 72 'stream-data',
include/qpdf/QPDFJob.hh
@@ -108,14 +108,49 @@ class QPDFJob @@ -108,14 +108,49 @@ class QPDFJob
108 std::string prefix; 108 std::string prefix;
109 }; 109 };
110 110
  111 + struct AddAttachment
  112 + {
  113 + AddAttachment() :
  114 + replace(false)
  115 + {
  116 + }
  117 +
  118 + std::string path;
  119 + std::string key;
  120 + std::string filename;
  121 + std::string creationdate;
  122 + std::string moddate;
  123 + std::string mimetype;
  124 + std::string description;
  125 + bool replace;
  126 + };
  127 +
111 public: 128 public:
112 class Config; 129 class Config;
  130 +
  131 + class AttConfig
  132 + {
  133 + friend class QPDFJob;
  134 + friend class Config;
  135 + public:
  136 + QPDF_DLL AttConfig& path(char const* parameter);
  137 +
  138 +# include <qpdf/auto_job_c_att.hh>
  139 +
  140 + private:
  141 + AttConfig(Config&);
  142 + AttConfig(AttConfig const&) = delete;
  143 +
  144 + Config& config;
  145 + AddAttachment att;
  146 + };
  147 +
113 class CopyAttConfig 148 class CopyAttConfig
114 { 149 {
115 friend class QPDFJob; 150 friend class QPDFJob;
116 friend class Config; 151 friend class Config;
117 public: 152 public:
118 - QPDF_DLL CopyAttConfig& filename(char const* parameter); 153 + QPDF_DLL CopyAttConfig& path(char const* parameter);
119 154
120 # include <qpdf/auto_job_c_copy_att.hh> 155 # include <qpdf/auto_job_c_copy_att.hh>
121 156
@@ -134,6 +169,7 @@ class QPDFJob @@ -134,6 +169,7 @@ class QPDFJob
134 public: 169 public:
135 QPDF_DLL 170 QPDF_DLL
136 std::shared_ptr<CopyAttConfig> copyAttachmentsFrom(); 171 std::shared_ptr<CopyAttConfig> copyAttachmentsFrom();
  172 + std::shared_ptr<AttConfig> addAttachment();
137 173
138 # include <qpdf/auto_job_c_main.hh> 174 # include <qpdf/auto_job_c_main.hh>
139 175
@@ -244,23 +280,6 @@ class QPDFJob @@ -244,23 +280,6 @@ class QPDFJob
244 std::vector<int> repeat_pagenos; 280 std::vector<int> repeat_pagenos;
245 }; 281 };
246 282
247 - struct AddAttachment  
248 - {  
249 - AddAttachment() :  
250 - replace(false)  
251 - {  
252 - }  
253 -  
254 - std::string path;  
255 - std::string key;  
256 - std::string filename;  
257 - std::string creationdate;  
258 - std::string moddate;  
259 - std::string mimetype;  
260 - std::string description;  
261 - bool replace;  
262 - };  
263 -  
264 enum remove_unref_e { re_auto, re_yes, re_no }; 283 enum remove_unref_e { re_auto, re_yes, re_no };
265 284
266 std::shared_ptr<char> password; 285 std::shared_ptr<char> password;
include/qpdf/auto_job_c_att.hh 0 โ†’ 100644
  1 +//
  2 +// This file is automatically generated by generate_auto_job.
  3 +// Edits will be automatically overwritten if the build is
  4 +// run in maintainer mode.
  5 +//
  6 +QPDF_DLL Config& end();
  7 +QPDF_DLL AttConfig& replace();
  8 +QPDF_DLL AttConfig& key(char const* parameter);
  9 +QPDF_DLL AttConfig& filename(char const* parameter);
  10 +QPDF_DLL AttConfig& creationdate(char const* parameter);
  11 +QPDF_DLL AttConfig& moddate(char const* parameter);
  12 +QPDF_DLL AttConfig& mimetype(char const* parameter);
  13 +QPDF_DLL AttConfig& description(char const* parameter);
job.sums
1 # Generated by generate_auto_job 1 # Generated by generate_auto_job
2 -generate_auto_job 36a09904317400caa4a2434f5b2acd59c20905a28479f45bba5e1fcfc654e697 2 +generate_auto_job d9f75a50dd4e503ede676bad54f80f856de096da7f3ad0e4594b0d09a6e1215d
  3 +include/qpdf/auto_job_c_att.hh ecc3f8f711b486b491e811176362a90c022eb225ff12157df3a10ca021be87b1
3 include/qpdf/auto_job_c_copy_att.hh caffae3d1faf2cd92a07ba77da638cce31da3e074a047918834195c0f3ed508a 4 include/qpdf/auto_job_c_copy_att.hh caffae3d1faf2cd92a07ba77da638cce31da3e074a047918834195c0f3ed508a
4 include/qpdf/auto_job_c_main.hh 5fdd9c85aa295a3caec467b9607fe82c874cd3aaeb7806b9d18074f7b96fd085 5 include/qpdf/auto_job_c_main.hh 5fdd9c85aa295a3caec467b9607fe82c874cd3aaeb7806b9d18074f7b96fd085
5 -job.yml 55d272cca0657e1f96ca92f5253edb6c6e24e6ea19e37690446d2111adc13f91  
6 -libqpdf/qpdf/auto_job_decl.hh e9844137bf53345f2c6973378b314a2510ebce83ac8ceb378588cd6afdd87c06 6 +job.yml e649f7dbb3748584f338b330043336ce4a4d51a34b00b42caa89dcfbc7bdcb84
  7 +libqpdf/qpdf/auto_job_decl.hh 38f7462e34fea7d46d5e5519ac1742be6e57ea6f66c47b37d5425f3a2b9ca536
7 libqpdf/qpdf/auto_job_help.hh 383eea80e2c185ef5295fc126246457a7ceeffea759fdb90bb2e6727532ea538 8 libqpdf/qpdf/auto_job_help.hh 383eea80e2c185ef5295fc126246457a7ceeffea759fdb90bb2e6727532ea538
8 -libqpdf/qpdf/auto_job_init.hh e65119793c329630aa243ff20907443f8eaf54c29d02737a598f29bba64b0bf5  
9 -libqpdf/qpdf/auto_job_schema.hh c91a4e182e088797b70dda94af03ca32d360f3564890132da2a8bdc3c4432423 9 +libqpdf/qpdf/auto_job_init.hh b49d839078d84398142f8f14bdae8a71f44fbff13cdf7b350b84ef2410aaa6a3
  10 +libqpdf/qpdf/auto_job_schema.hh 6e6d72e99dacd02c22d9ac70f4dc78a935f879d2a16c89f07f2bdfa936cc2ae3
10 manual/_ext/qpdf.py 855fe12de5af7a10bb24be6ecc4d5dff4c84ac58cf388a13be6bbb394346a67d 11 manual/_ext/qpdf.py 855fe12de5af7a10bb24be6ecc4d5dff4c84ac58cf388a13be6bbb394346a67d
11 manual/cli.rst 68122ff8179c10df3fe6d577adde4973c346f7866ba9a511bab5a6e6f292a6f1 12 manual/cli.rst 68122ff8179c10df3fe6d577adde4973c346f7866ba9a511bab5a6e6f292a6f1
@@ -203,6 +203,7 @@ options: @@ -203,6 +203,7 @@ options:
203 repeat: page-range 203 repeat: page-range
204 password: password 204 password: password
205 - table: attachment 205 - table: attachment
  206 + config: c_att
206 prefix: Att 207 prefix: Att
207 positional: true 208 positional: true
208 bare: 209 bare:
@@ -340,7 +341,7 @@ json: @@ -340,7 +341,7 @@ json:
340 remove-unreferenced-resources: 341 remove-unreferenced-resources:
341 _modify: 342 _modify:
342 add-attachment: 343 add-attachment:
343 - - file: "attachment to add" 344 + - path: "attachment to add"
344 creationdate: 345 creationdate:
345 description: 346 description:
346 filename: 347 filename:
@@ -350,7 +351,7 @@ json: @@ -350,7 +351,7 @@ json:
350 replace: 351 replace:
351 remove-attachment: 352 remove-attachment:
352 copy-attachments-from: 353 copy-attachments-from:
353 - - file: "attachment source filename" 354 + - path: "attachment source filename"
354 CopyAtt.password: 355 CopyAtt.password:
355 prefix: 356 prefix:
356 collate: 357 collate:
libqpdf/QPDFJob_argv.cc
@@ -45,6 +45,7 @@ namespace @@ -45,6 +45,7 @@ namespace
45 QPDFJob& o; 45 QPDFJob& o;
46 std::shared_ptr<QPDFJob::Config> c_main; 46 std::shared_ptr<QPDFJob::Config> c_main;
47 std::shared_ptr<QPDFJob::CopyAttConfig> c_copy_att; 47 std::shared_ptr<QPDFJob::CopyAttConfig> c_copy_att;
  48 + std::shared_ptr<QPDFJob::AttConfig> c_att;
48 std::vector<char*> accumulated_args; // points to member in ap 49 std::vector<char*> accumulated_args; // points to member in ap
49 char* pages_password; 50 char* pages_password;
50 }; 51 };
@@ -441,7 +442,7 @@ ArgParser::argRotate(char* parameter) @@ -441,7 +442,7 @@ ArgParser::argRotate(char* parameter)
441 void 442 void
442 ArgParser::argAddAttachment() 443 ArgParser::argAddAttachment()
443 { 444 {
444 - o.attachments_to_add.push_back(QPDFJob::AddAttachment()); 445 + this->c_att = c_main->addAttachment();
445 this->ap.selectOptionTable(O_ATTACHMENT); 446 this->ap.selectOptionTable(O_ATTACHMENT);
446 } 447 }
447 448
@@ -792,100 +793,20 @@ ArgParser::argEndUnderlayOverlay() @@ -792,100 +793,20 @@ ArgParser::argEndUnderlayOverlay()
792 void 793 void
793 ArgParser::argAttPositional(char* arg) 794 ArgParser::argAttPositional(char* arg)
794 { 795 {
795 - o.attachments_to_add.back().path = arg;  
796 -}  
797 -  
798 -void  
799 -ArgParser::argAttKey(char* parameter)  
800 -{  
801 - o.attachments_to_add.back().key = parameter;  
802 -}  
803 -  
804 -void  
805 -ArgParser::argAttFilename(char* parameter)  
806 -{  
807 - o.attachments_to_add.back().filename = parameter;  
808 -}  
809 -  
810 -void  
811 -ArgParser::argAttCreationdate(char* parameter)  
812 -{  
813 - if (! QUtil::pdf_time_to_qpdf_time(parameter))  
814 - {  
815 - usage(std::string(parameter) + " is not a valid PDF timestamp");  
816 - }  
817 - o.attachments_to_add.back().creationdate = parameter;  
818 -}  
819 -  
820 -void  
821 -ArgParser::argAttModdate(char* parameter)  
822 -{  
823 - if (! QUtil::pdf_time_to_qpdf_time(parameter))  
824 - {  
825 - usage(std::string(parameter) + " is not a valid PDF timestamp");  
826 - }  
827 - o.attachments_to_add.back().moddate = parameter;  
828 -}  
829 -  
830 -void  
831 -ArgParser::argAttMimetype(char* parameter)  
832 -{  
833 - if (strchr(parameter, '/') == nullptr)  
834 - {  
835 - usage("mime type should be specified as type/subtype");  
836 - }  
837 - o.attachments_to_add.back().mimetype = parameter;  
838 -}  
839 -  
840 -void  
841 -ArgParser::argAttDescription(char* parameter)  
842 -{  
843 - o.attachments_to_add.back().description = parameter;  
844 -}  
845 -  
846 -void  
847 -ArgParser::argAttReplace()  
848 -{  
849 - o.attachments_to_add.back().replace = true; 796 + c_att->path(arg);
850 } 797 }
851 798
852 void 799 void
853 ArgParser::argEndAttachment() 800 ArgParser::argEndAttachment()
854 { 801 {
855 - static std::string now = QUtil::qpdf_time_to_pdf_time(  
856 - QUtil::get_current_qpdf_time());  
857 - auto& cur = o.attachments_to_add.back();  
858 - if (cur.path.empty())  
859 - {  
860 - usage("add attachment: no path specified");  
861 - }  
862 - std::string last_element = QUtil::path_basename(cur.path);  
863 - if (last_element.empty())  
864 - {  
865 - usage("path for --add-attachment may not be empty");  
866 - }  
867 - if (cur.filename.empty())  
868 - {  
869 - cur.filename = last_element;  
870 - }  
871 - if (cur.key.empty())  
872 - {  
873 - cur.key = last_element;  
874 - }  
875 - if (cur.creationdate.empty())  
876 - {  
877 - cur.creationdate = now;  
878 - }  
879 - if (cur.moddate.empty())  
880 - {  
881 - cur.moddate = now;  
882 - } 802 + c_att->end();
  803 + c_att = nullptr;
883 } 804 }
884 805
885 void 806 void
886 ArgParser::argCopyAttPositional(char* arg) 807 ArgParser::argCopyAttPositional(char* arg)
887 { 808 {
888 - c_copy_att->filename(arg); 809 + c_copy_att->path(arg);
889 } 810 }
890 811
891 void 812 void
libqpdf/QPDFJob_config.cc
@@ -509,7 +509,7 @@ QPDFJob::CopyAttConfig::CopyAttConfig(Config&amp; c) : @@ -509,7 +509,7 @@ QPDFJob::CopyAttConfig::CopyAttConfig(Config&amp; c) :
509 } 509 }
510 510
511 QPDFJob::CopyAttConfig& 511 QPDFJob::CopyAttConfig&
512 -QPDFJob::CopyAttConfig::filename(char const* parameter) 512 +QPDFJob::CopyAttConfig::path(char const* parameter)
513 { 513 {
514 this->caf.path = parameter; 514 this->caf.path = parameter;
515 return *this; 515 return *this;
@@ -541,3 +541,125 @@ QPDFJob::CopyAttConfig::end() @@ -541,3 +541,125 @@ QPDFJob::CopyAttConfig::end()
541 this->config.o.attachments_to_copy.push_back(this->caf); 541 this->config.o.attachments_to_copy.push_back(this->caf);
542 return this->config; 542 return this->config;
543 } 543 }
  544 +
  545 +QPDFJob::AttConfig::AttConfig(Config& c) :
  546 + config(c)
  547 +{
  548 +}
  549 +
  550 +std::shared_ptr<QPDFJob::AttConfig>
  551 +QPDFJob::Config::addAttachment()
  552 +{
  553 + return std::shared_ptr<AttConfig>(new AttConfig(*this));
  554 +}
  555 +
  556 +QPDFJob::AttConfig&
  557 +QPDFJob::AttConfig::path(char const* parameter)
  558 +{
  559 + this->att.path = parameter;
  560 + return *this;
  561 +}
  562 +
  563 +QPDFJob::AttConfig&
  564 +QPDFJob::AttConfig::key(char const* parameter)
  565 +{
  566 + this->att.key = parameter;
  567 + return *this;
  568 +}
  569 +
  570 +QPDFJob::AttConfig&
  571 +QPDFJob::AttConfig::filename(char const* parameter)
  572 +{
  573 + this->att.filename = parameter;
  574 + return *this;
  575 +}
  576 +
  577 +QPDFJob::AttConfig&
  578 +QPDFJob::AttConfig::creationdate(char const* parameter)
  579 +{
  580 + if (! QUtil::pdf_time_to_qpdf_time(parameter))
  581 + {
  582 + // QXXXQ
  583 + throw std::runtime_error(
  584 + std::string(parameter) + " is not a valid PDF timestamp");
  585 + }
  586 + this->att.creationdate = parameter;
  587 + return *this;
  588 +}
  589 +
  590 +QPDFJob::AttConfig&
  591 +QPDFJob::AttConfig::moddate(char const* parameter)
  592 +{
  593 + if (! QUtil::pdf_time_to_qpdf_time(parameter))
  594 + {
  595 + // QXXXQ
  596 + throw std::runtime_error(
  597 + std::string(parameter) + " is not a valid PDF timestamp");
  598 + }
  599 + this->att.moddate = parameter;
  600 + return *this;
  601 +}
  602 +
  603 +QPDFJob::AttConfig&
  604 +QPDFJob::AttConfig::mimetype(char const* parameter)
  605 +{
  606 + if (strchr(parameter, '/') == nullptr)
  607 + {
  608 + // QXXXQ
  609 + throw std::runtime_error(
  610 + "mime type should be specified as type/subtype");
  611 + }
  612 + this->att.mimetype = parameter;
  613 + return *this;
  614 +}
  615 +
  616 +QPDFJob::AttConfig&
  617 +QPDFJob::AttConfig::description(char const* parameter)
  618 +{
  619 + this->att.description = parameter;
  620 + return *this;
  621 +}
  622 +
  623 +QPDFJob::AttConfig&
  624 +QPDFJob::AttConfig::replace()
  625 +{
  626 + this->att.replace = true;
  627 + return *this;
  628 +}
  629 +
  630 +QPDFJob::Config&
  631 +QPDFJob::AttConfig::end()
  632 +{
  633 + // QXXXQ runtime_error
  634 +
  635 + static std::string now = QUtil::qpdf_time_to_pdf_time(
  636 + QUtil::get_current_qpdf_time());
  637 + if (this->att.path.empty())
  638 + {
  639 + throw std::runtime_error("add attachment: no path specified");
  640 + }
  641 + std::string last_element = QUtil::path_basename(this->att.path);
  642 + if (last_element.empty())
  643 + {
  644 + throw std::runtime_error("path for --add-attachment may not be empty");
  645 + }
  646 + if (this->att.filename.empty())
  647 + {
  648 + this->att.filename = last_element;
  649 + }
  650 + if (this->att.key.empty())
  651 + {
  652 + this->att.key = last_element;
  653 + }
  654 + if (this->att.creationdate.empty())
  655 + {
  656 + this->att.creationdate = now;
  657 + }
  658 + if (this->att.moddate.empty())
  659 + {
  660 + this->att.moddate = now;
  661 + }
  662 +
  663 + this->config.o.attachments_to_add.push_back(this->att);
  664 + return this->config;
  665 +}
libqpdf/qpdf/auto_job_decl.hh
@@ -65,13 +65,6 @@ void argUORepeat(char *); @@ -65,13 +65,6 @@ void argUORepeat(char *);
65 void argUOPassword(char *); 65 void argUOPassword(char *);
66 void argEndUnderlayOverlay(); 66 void argEndUnderlayOverlay();
67 void argAttPositional(char*); 67 void argAttPositional(char*);
68 -void argAttReplace();  
69 -void argAttKey(char *);  
70 -void argAttFilename(char *);  
71 -void argAttCreationdate(char *);  
72 -void argAttModdate(char *);  
73 -void argAttMimetype(char *);  
74 -void argAttDescription(char *);  
75 void argEndAttachment(); 68 void argEndAttachment();
76 void argCopyAttPositional(char*); 69 void argCopyAttPositional(char*);
77 void argEndCopyAttachment(); 70 void argEndCopyAttachment();
libqpdf/qpdf/auto_job_init.hh
@@ -143,13 +143,13 @@ this-&gt;ap.addRequiredParameter(&quot;repeat&quot;, p(&amp;ArgParser::argUORepeat), &quot;page-range&quot; @@ -143,13 +143,13 @@ this-&gt;ap.addRequiredParameter(&quot;repeat&quot;, p(&amp;ArgParser::argUORepeat), &quot;page-range&quot;
143 this->ap.addRequiredParameter("password", p(&ArgParser::argUOPassword), "password"); 143 this->ap.addRequiredParameter("password", p(&ArgParser::argUOPassword), "password");
144 this->ap.registerOptionTable("attachment", b(&ArgParser::argEndAttachment)); 144 this->ap.registerOptionTable("attachment", b(&ArgParser::argEndAttachment));
145 this->ap.addPositional(p(&ArgParser::argAttPositional)); 145 this->ap.addPositional(p(&ArgParser::argAttPositional));
146 -this->ap.addBare("replace", b(&ArgParser::argAttReplace));  
147 -this->ap.addRequiredParameter("key", p(&ArgParser::argAttKey), "attachment-key");  
148 -this->ap.addRequiredParameter("filename", p(&ArgParser::argAttFilename), "filename");  
149 -this->ap.addRequiredParameter("creationdate", p(&ArgParser::argAttCreationdate), "creation-date");  
150 -this->ap.addRequiredParameter("moddate", p(&ArgParser::argAttModdate), "modification-date");  
151 -this->ap.addRequiredParameter("mimetype", p(&ArgParser::argAttMimetype), "mime/type");  
152 -this->ap.addRequiredParameter("description", p(&ArgParser::argAttDescription), "description"); 146 +this->ap.addBare("replace", [this](){c_att->replace();});
  147 +this->ap.addRequiredParameter("key", [this](char *x){c_att->key(x);}, "attachment-key");
  148 +this->ap.addRequiredParameter("filename", [this](char *x){c_att->filename(x);}, "filename");
  149 +this->ap.addRequiredParameter("creationdate", [this](char *x){c_att->creationdate(x);}, "creation-date");
  150 +this->ap.addRequiredParameter("moddate", [this](char *x){c_att->moddate(x);}, "modification-date");
  151 +this->ap.addRequiredParameter("mimetype", [this](char *x){c_att->mimetype(x);}, "mime/type");
  152 +this->ap.addRequiredParameter("description", [this](char *x){c_att->description(x);}, "description");
153 this->ap.registerOptionTable("copy attachment", b(&ArgParser::argEndCopyAttachment)); 153 this->ap.registerOptionTable("copy attachment", b(&ArgParser::argEndCopyAttachment));
154 this->ap.addPositional(p(&ArgParser::argCopyAttPositional)); 154 this->ap.addPositional(p(&ArgParser::argCopyAttPositional));
155 this->ap.addRequiredParameter("prefix", [this](char *x){c_copy_att->prefix(x);}, "prefix"); 155 this->ap.addRequiredParameter("prefix", [this](char *x){c_copy_att->prefix(x);}, "prefix");
libqpdf/qpdf/auto_job_schema.hh
@@ -122,7 +122,7 @@ static constexpr char const* JOB_SCHEMA_DATA = R&quot;({ @@ -122,7 +122,7 @@ static constexpr char const* JOB_SCHEMA_DATA = R&quot;({
122 "modify": { 122 "modify": {
123 "addAttachment": [ 123 "addAttachment": [
124 { 124 {
125 - "file": "attachment to add", 125 + "path": "attachment to add",
126 "creationdate": "set attachment's creation date", 126 "creationdate": "set attachment's creation date",
127 "description": "set attachment's description", 127 "description": "set attachment's description",
128 "filename": "set attachment's displayed filename", 128 "filename": "set attachment's displayed filename",
@@ -135,7 +135,7 @@ static constexpr char const* JOB_SCHEMA_DATA = R&quot;({ @@ -135,7 +135,7 @@ static constexpr char const* JOB_SCHEMA_DATA = R&quot;({
135 "removeAttachment": "remove an embedded file", 135 "removeAttachment": "remove an embedded file",
136 "copyAttachmentsFrom": [ 136 "copyAttachmentsFrom": [
137 { 137 {
138 - "file": "attachment source filename", 138 + "path": "attachment source filename",
139 "password": "specify password", 139 "password": "specify password",
140 "prefix": "key prefix for copying attachments" 140 "prefix": "key prefix for copying attachments"
141 } 141 }