aboutsummaryrefslogtreecommitdiffstats
path: root/libqpdf
diff options
context:
space:
mode:
authorJay Berkenbilt <ejb@ql.org>2022-01-22 22:29:13 +0100
committerJay Berkenbilt <ejb@ql.org>2022-01-30 19:11:03 +0100
commit1d099ab7439104759a421bc20c809e64fef29f03 (patch)
tree53319f1f124a80ae3b731c7929113cf8535d04e3 /libqpdf
parent1c8d53465ff4d8e732498b39e49595b16d6754af (diff)
downloadqpdf-1d099ab7439104759a421bc20c809e64fef29f03.tar.zst
QPDFJob: placeholder for initializeFromJson
Diffstat (limited to 'libqpdf')
-rw-r--r--libqpdf/QPDFJob_argv.cc120
-rw-r--r--libqpdf/qpdf/auto_job_decl.hh2
-rw-r--r--libqpdf/qpdf/auto_job_help.hh41
-rw-r--r--libqpdf/qpdf/auto_job_init.hh2
4 files changed, 148 insertions, 17 deletions
diff --git a/libqpdf/QPDFJob_argv.cc b/libqpdf/QPDFJob_argv.cc
index 8da5e836..f4a4219a 100644
--- a/libqpdf/QPDFJob_argv.cc
+++ b/libqpdf/QPDFJob_argv.cc
@@ -8,6 +8,7 @@
#include <cstdio>
#include <ctype.h>
#include <memory>
+#include <sstream>
#include <qpdf/QUtil.hh>
#include <qpdf/QTC.hh>
@@ -15,6 +16,10 @@
#include <qpdf/QPDFArgParser.hh>
#include <qpdf/QPDFJob.hh>
#include <qpdf/QIntC.hh>
+#include <qpdf/JSONHandler.hh>
+
+#include <qpdf/auto_job_schema.hh>
+static JSON JOB_SCHEMA = JSON::parse(JOB_SCHEMA_DATA);
namespace
{
@@ -1329,6 +1334,31 @@ ArgParser::argEndCopyAttachment()
}
void
+ArgParser::argJobJsonFile(char* parameter)
+{
+ PointerHolder<char> file_buf;
+ size_t size;
+ QUtil::read_file_into_memory(parameter, file_buf, size);
+ try
+ {
+ o.initializeFromJson(std::string(file_buf.getPointer(), size));
+ }
+ catch (std::exception& e)
+ {
+ throw std::runtime_error(
+ "error with job-json file " + std::string(parameter) + " " +
+ e.what() + "\nRun " + this->ap.getProgname() +
+ "--job-json-help for information on the file format.");
+ }
+}
+
+void
+ArgParser::argJobJsonHelp()
+{
+ std::cout << JOB_SCHEMA_DATA << std::endl;
+}
+
+void
ArgParser::usage(std::string const& message)
{
this->ap.usage(message);
@@ -1534,3 +1564,93 @@ QPDFJob::initializeFromArgv(int argc, char* argv[], char const* progname_env)
ArgParser ap(qap, *this);
ap.parseOptions();
}
+
+void
+QPDFJob::initializeFromJson(std::string const& json)
+{
+ std::list<std::string> errors;
+ JSON j = JSON::parse(json);
+ if (! j.checkSchema(JOB_SCHEMA, JSON::f_optional, errors))
+ {
+ std::ostringstream msg;
+ msg << this->m->message_prefix
+ << ": job json has errors:";
+ for (auto const& error: errors)
+ {
+ msg << std::endl << " " << error;
+ }
+ throw std::runtime_error(msg.str());
+ }
+
+ JSONHandler jh;
+ {
+ jh.addDictHandlers(
+ [](std::string const&){},
+ [](std::string const&){});
+
+ auto input = std::make_shared<JSONHandler>();
+ auto input_file = std::make_shared<JSONHandler>();
+ auto input_file_name = std::make_shared<JSONHandler>();
+ auto output = std::make_shared<JSONHandler>();
+ auto output_file = std::make_shared<JSONHandler>();
+ auto output_file_name = std::make_shared<JSONHandler>();
+ auto output_options = std::make_shared<JSONHandler>();
+ auto output_options_qdf = std::make_shared<JSONHandler>();
+
+ input->addDictHandlers(
+ [](std::string const&){},
+ [](std::string const&){});
+ input_file->addDictHandlers(
+ [](std::string const&){},
+ [](std::string const&){});
+ output->addDictHandlers(
+ [](std::string const&){},
+ [](std::string const&){});
+ output_file->addDictHandlers(
+ [](std::string const&){},
+ [](std::string const&){});
+ output_options->addDictHandlers(
+ [](std::string const&){},
+ [](std::string const&){});
+
+ jh.addDictKeyHandler("input", input);
+ input->addDictKeyHandler("file", input_file);
+ input_file->addDictKeyHandler("name", input_file_name);
+ jh.addDictKeyHandler("output", output);
+ output->addDictKeyHandler("file", output_file);
+ output_file->addDictKeyHandler("name", output_file_name);
+ output->addDictKeyHandler("options", output_options);
+ output_options->addDictKeyHandler("qdf", output_options_qdf);
+
+ input_file_name->addStringHandler(
+ [this](std::string const&, std::string const& v) {
+ this->infilename = QUtil::make_shared_cstr(v);
+ });
+ output_file_name->addStringHandler(
+ [this](std::string const&, std::string const& v) {
+ this->outfilename = QUtil::make_shared_cstr(v);
+ });
+ output_options_qdf->addBoolHandler(
+ [this](std::string const&, bool v) {
+ this->qdf_mode = v;
+ });
+ }
+
+ // {
+ // "input": {
+ // "file": {
+ // "name": "/home/ejb/source/examples/pdf/minimal.pdf"
+ // }
+ // },
+ // "output": {
+ // "file": {
+ // "name": "/tmp/a.pdf"
+ // },
+ // "options": {
+ // "qdf": true
+ // }
+ // }
+ // }
+
+ jh.handle(".", j);
+}
diff --git a/libqpdf/qpdf/auto_job_decl.hh b/libqpdf/qpdf/auto_job_decl.hh
index 1f2b4263..6d5c8228 100644
--- a/libqpdf/qpdf/auto_job_decl.hh
+++ b/libqpdf/qpdf/auto_job_decl.hh
@@ -16,6 +16,7 @@ void argVersion();
void argCopyright();
void argJsonHelp();
void argShowCrypto();
+void argJobJsonHelp();
void argPositional(char*);
void argAddAttachment();
void argAllowWeakCrypto();
@@ -74,6 +75,7 @@ void argCopyEncryption(char *);
void argEncryptionFilePassword(char *);
void argForceVersion(char *);
void argIiMinBytes(char *);
+void argJobJsonFile(char *);
void argJsonObject(char *);
void argKeepFilesOpenThreshold(char *);
void argLinearizePass1(char *);
diff --git a/libqpdf/qpdf/auto_job_help.hh b/libqpdf/qpdf/auto_job_help.hh
index dd55fb0c..982509ee 100644
--- a/libqpdf/qpdf/auto_job_help.hh
+++ b/libqpdf/qpdf/auto_job_help.hh
@@ -27,6 +27,11 @@ with --pages.
)");
ap.addOptionHelp("--replace-input", "usage", "replace input with output", R"(Use in place of outfile to overwrite the input file with the output.
)");
+ap.addOptionHelp("--job-json-file", "usage", "job JSON file", R"(--job-json-file=file
+
+Specify the name of a file whose contents are expected to
+contain a QPDFJob json file.
+)");
ap.addHelpTopic("exit-status", "meanings of qpdf's exit codes", R"(Meaning of exit codes:
0: no errors or warnings
@@ -78,14 +83,14 @@ performed.
)");
ap.addOptionHelp("--progress", "general", "show progress when writing", R"(Indicate progress when writing files.
)");
+}
+static void add_help_2(QPDFArgParser& ap)
+{
ap.addOptionHelp("--no-warn", "general", "suppress printing warning messages", R"(Suppress printing warning messages. If warnings were
encountered, qpdf still exits with exit status 3.
Use --warning-exit-0 with --no-warn to completely ignore
warnings.
)");
-}
-static void add_help_2(QPDFArgParser& ap)
-{
ap.addOptionHelp("--deterministic-id", "general", "generate ID deterministically", R"(Generate a secure, random document ID only using static
information, such as the page contents. Does not use the file's
name or attributes or the current time.
@@ -164,15 +169,15 @@ chapter about it in the manual.
ap.addOptionHelp("--no-original-object-ids", "transformation", "omit original object ID in qdf", R"(Omit comments in a QDF file indicating the object ID an object
had in the original file.
)");
+}
+static void add_help_3(QPDFArgParser& ap)
+{
ap.addOptionHelp("--compress-streams", "transformation", "compress uncompressed streams", R"(--compress-streams=[yn]
Setting --compress-streams=n prevents qpdf from compressing
uncompressed streams. This can be useful if you are leaving some
streams uncompressed intentionally.
)");
-}
-static void add_help_3(QPDFArgParser& ap)
-{
ap.addOptionHelp("--decode-level", "transformation", "control which streams to uncompress", R"(--decode-level=parameter
When uncompressing streams, control which types of compression
@@ -280,15 +285,15 @@ ap.addOptionHelp("--pages", "modification", "begin page selection", R"(--pages f
Run qpdf --help=page-selection for details.
)");
+}
+static void add_help_4(QPDFArgParser& ap)
+{
ap.addOptionHelp("--collate", "modification", "collate with --pages", R"(--collate=n
Collate rather than concatenate pages specified with --pages.
With a numeric parameter, collate in groups of n. The default
is 1. Run qpdf --help=page-selection for additional details.
)");
-}
-static void add_help_4(QPDFArgParser& ap)
-{
ap.addOptionHelp("--split-pages", "modification", "write pages to separate files", R"(--split-pages=[n]
This option causes qpdf to create separate output files for each
@@ -451,15 +456,15 @@ ap.addOptionHelp("--extract", "encryption", "restrict text/graphic extraction",
Enable/disable text/graphic extraction for purposes other than
accessibility.
)");
+}
+static void add_help_5(QPDFArgParser& ap)
+{
ap.addOptionHelp("--form", "encryption", "restrict form filling", R"(--form=[yn]
Enable/disable whether filling form fields is allowed even if
modification of annotations is disabled. This option is not
available with 40-bit encryption.
)");
-}
-static void add_help_5(QPDFArgParser& ap)
-{
ap.addOptionHelp("--modify-other", "encryption", "restrict other modifications", R"(--modify-other=[yn]
Enable/disable modifications not controlled by --assemble,
@@ -625,15 +630,15 @@ ap.addOptionHelp("--remove-attachment", "attachments", "remove an embedded file"
Remove an embedded file using its key. Get the key with
--list-attachments.
)");
+}
+static void add_help_6(QPDFArgParser& ap)
+{
ap.addOptionHelp("--copy-attachments-from", "attachments", "start copy attachment options", R"(--copy-attachments-from file options --
The --copy-attachments-from flag and its options may be repeated
to copy attachments from multiple files. Run
qpdf --help=copy-attachments for details.
)");
-}
-static void add_help_6(QPDFArgParser& ap)
-{
ap.addHelpTopic("pdf-dates", "PDF date format", R"(When a date is required, the date should conform to the PDF date
format specification, which is "D:yyyymmddhhmmssz" where "z" is
either literally upper case "Z" for UTC or a timezone offset in
@@ -738,11 +743,11 @@ encryption key to be displayed.
ap.addOptionHelp("--check-linearization", "inspection", "check linearization tables", R"(Check to see whether a file is linearized and, if so, whether
the linearization hint tables are correct.
)");
-ap.addOptionHelp("--show-linearization", "inspection", "show linearization hint tables", R"(Check and display all data in the linearization hint tables.
-)");
}
static void add_help_7(QPDFArgParser& ap)
{
+ap.addOptionHelp("--show-linearization", "inspection", "show linearization hint tables", R"(Check and display all data in the linearization hint tables.
+)");
ap.addOptionHelp("--show-xref", "inspection", "show cross reference data", R"(Show the contents of the cross-reference table or stream (object
locations in the file) in a human-readable form. This is
especially useful for files with cross-reference streams, which
@@ -793,6 +798,8 @@ This option is repeatable. If given, only specified objects will
be shown in the "objects" key of the JSON output. Otherwise, all
objects will be shown.
)");
+ap.addOptionHelp("--job-json-help", "json", "show format of job json", R"(Describe the format of the QPDFJob JSON input.
+)");
ap.addHelpTopic("testing", "options for testing or debugging", R"(The options below are useful when writing automated test code that
includes files created by qpdf or when testing qpdf itself.
)");
diff --git a/libqpdf/qpdf/auto_job_init.hh b/libqpdf/qpdf/auto_job_init.hh
index 3d7cdd7b..f9de9f90 100644
--- a/libqpdf/qpdf/auto_job_init.hh
+++ b/libqpdf/qpdf/auto_job_init.hh
@@ -26,6 +26,7 @@ this->ap.addBare("version", b(&ArgParser::argVersion));
this->ap.addBare("copyright", b(&ArgParser::argCopyright));
this->ap.addBare("json-help", b(&ArgParser::argJsonHelp));
this->ap.addBare("show-crypto", b(&ArgParser::argShowCrypto));
+this->ap.addBare("job-json-help", b(&ArgParser::argJobJsonHelp));
this->ap.selectMainOptionTable();
this->ap.addPositional(p(&ArgParser::argPositional));
this->ap.addBare("add-attachment", b(&ArgParser::argAddAttachment));
@@ -85,6 +86,7 @@ this->ap.addRequiredParameter("copy-encryption", p(&ArgParser::argCopyEncryption
this->ap.addRequiredParameter("encryption-file-password", p(&ArgParser::argEncryptionFilePassword), "password");
this->ap.addRequiredParameter("force-version", p(&ArgParser::argForceVersion), "version");
this->ap.addRequiredParameter("ii-min-bytes", p(&ArgParser::argIiMinBytes), "minimum");
+this->ap.addRequiredParameter("job-json-file", p(&ArgParser::argJobJsonFile), "file");
this->ap.addRequiredParameter("json-object", p(&ArgParser::argJsonObject), "trailer");
this->ap.addRequiredParameter("keep-files-open-threshold", p(&ArgParser::argKeepFilesOpenThreshold), "count");
this->ap.addRequiredParameter("linearize-pass1", p(&ArgParser::argLinearizePass1), "filename");