2
1
mirror of https://github.com/qpdf/qpdf.git synced 2024-12-22 10:58:58 +00:00

QPDFJob: fix logic errors in handling arrays

The code was assuming everything was happening inside dictionaries.
Instead, make the dictionary key handler creatino explicit only when
iterating through dictionary keys.
This commit is contained in:
Jay Berkenbilt 2022-01-31 07:34:40 -05:00
parent f99e0af49c
commit 81b6314cb5
6 changed files with 613 additions and 340 deletions

View File

@ -454,7 +454,7 @@ class Main:
identifier = self.to_identifier(table, 'argEnd', False)
self.decls.append(f'void {identifier}();')
def handle_json_trivial(self, key, fdata):
def handle_json_trivial(self, flag_key, fdata):
config = None
for t, [kind, v] in fdata['tables'].items():
# We have determined that all tables, if multiple, have
@ -463,106 +463,98 @@ class Main:
config = tdata['config']
if kind == 'bare':
self.json_init.append(
f'addBare("{key}", [this]() {{ {config}->{key}(); }});')
f'addBare([this]() {{ {config}->{flag_key}(); }});')
elif kind == 'optional_parameter' or kind == 'required_parameter':
# No optional parameters in json
self.json_init.append(
f'addParameter("{key}", [this](char const* p)'
f' {{ {config}->{key}(p); }});')
f'addParameter([this](char const* p)'
f' {{ {config}->{flag_key}(p); }});')
elif kind == 'optional_choices' or kind == 'required_choices':
# No optional choices in json
self.json_init.append(
f'addChoices("{key}", {v}_choices,'
f' [this](char const* p) {{ {config}->{key}(p); }});')
f'addChoices({v}_choices,'
f' [this](char const* p) {{ {config}->{flag_key}(p); }});')
def handle_json_manual(self, key, path):
def handle_json_manual(self, path):
method = re.sub(r'\.([a-zA-Z0-9])',
lambda x: x.group(1).upper(),
f'setup{path}.{key}')
self.json_decls.append(
f'void {method}(std::string const&);')
self.json_init.append(
f'doSetup("{key}", bindSetup(&Handlers::{method}));')
f'setup{path}')
self.json_decls.append(f'void {method}();')
self.json_init.append(f'{method}();')
def option_to_json_key(self, s):
return self.to_identifier(s, '', False)
def build_schema(self, j, s, flag, path, expected, options_seen):
def flag_to_schema_key(self, k):
if k.startswith('_'):
schema_key = k[1:]
else:
schema_key = re.sub(r'[^\.]+\.', '', k)
return self.option_to_json_key(schema_key)
def build_schema(self, j, path, flag, expected, options_seen):
if flag in expected:
options_seen.add(flag)
elif not (flag == '' or flag.startswith('_') or isinstance(j, str)):
raise Exception(f'json: unknown key {flag}')
if isinstance(j, dict):
schema_value = {}
if flag:
identifier = self.to_identifier(path, '', False)
self.json_decls.append(f'void begin{identifier}(JSON);')
self.json_decls.append(f'void end{identifier}();')
self.json_init.append(
f'beginDict("{flag}",'
f' bindJSON(&Handlers::begin{identifier}),'
f'beginDict(bindJSON(&Handlers::begin{identifier}),'
f' bindBare(&Handlers::end{identifier})); // {path}')
for k, v in j.items():
schema_key = self.flag_to_schema_key(k)
subpath = f'{path}.{schema_key}'
self.json_init.append(f'pushKey("{schema_key}");')
schema_value[schema_key] = self.build_schema(
v, subpath, k, expected, options_seen)
self.json_init.append(f'popHandler(); // key: {schema_key}')
elif isinstance(j, list):
if len(j) != 1:
raise Exception('json contains array with length != 1')
identifier = self.to_identifier(path, '', False)
self.json_decls.append(f'void begin{identifier}Array(JSON);')
self.json_decls.append(f'void end{identifier}Array();')
self.json_init.append(
f'beginArray(bindJSON(&Handlers::begin{identifier}Array),'
f' bindBare(&Handlers::end{identifier}Array));'
f' // {path}[]')
schema_value = [
self.build_schema(j[0], path, flag,
expected, options_seen)
]
self.json_init.append(
f'popHandler(); // array: {path}[]')
else:
schema_value = j
if schema_value is None:
schema_value = re.sub(
r'--(\S+)',
lambda x: self.option_to_json_key(x.group(1)),
expected[flag]['help'])
is_trivial = False
if k in expected:
if flag in expected:
is_trivial = True
common_config = None
for t in expected[k]['tables']:
for t in expected[flag]['tables']:
tdata = self.by_table[t]
if k in tdata['manual']:
if flag in tdata['manual']:
is_trivial = False
if common_config is None:
common_config = tdata['config']
elif common_config != tdata['config']:
is_trivial = False
elif not (k.startswith('_') or isinstance(v, str)):
raise Exception(f'json: unknown key {k}')
if k.startswith('_'):
schema_key = k[1:]
else:
schema_key = re.sub(r'[^\.]+\.', '', k)
schema_key = self.option_to_json_key(schema_key)
schema_value = v
is_dict = False
if k in expected:
options_seen.add(re.sub('^_', '', k))
if v is None:
schema_value = re.sub(
r'--(\S+)',
lambda x: self.option_to_json_key(x.group(1)),
expected[k]['help'])
if (isinstance(v, dict)):
is_dict = True
schema_value = {}
self.build_schema(v, schema_value,
schema_key, f'{path}.{schema_key}',
expected, options_seen)
elif (isinstance(v, list)):
if len(v) != 1:
raise Exception('json contains array with length != 1')
if isinstance(v[0], dict):
is_dict = True
schema_value = [{}]
subpath = f'{path}.{schema_key}'
identifier = self.to_identifier(subpath, '', False)
self.json_decls.append(
f'void begin{identifier}Array(JSON);')
self.json_decls.append(
f'void end{identifier}Array();')
self.json_init.append(
f'beginArray("{flag}",'
f' bindJSON(&Handlers::begin{identifier}Array),'
f' bindBare(&Handlers::end{identifier}Array));'
f' // {subpath}[]')
self.build_schema(v[0], schema_value[0],
schema_key, subpath,
expected, options_seen)
self.json_init.append(
f'endContainer(); // {subpath}[]')
elif schema_value is None:
raise Exception(f'unknown schema value for {k}')
s[schema_key] = schema_value
if not is_dict:
config_key = self.flag_to_schema_key(flag)
if is_trivial:
self.handle_json_trivial(schema_key, expected[k])
self.handle_json_trivial(config_key, expected[flag])
else:
self.handle_json_manual(schema_key, path)
if flag:
self.json_init.append(f'endContainer(); // {path}')
self.handle_json_manual(path)
return schema_value
def generate_schema(self, data):
# Check to make sure that every command-line option is
@ -588,9 +580,8 @@ class Main:
# go. This verifies consistency between command-line options
# and the json section of the data and builds up a schema by
# populating with help information as available.
self.schema = {}
self.build_schema(data['json'], self.schema, '', '',
expected, options_seen)
self.schema = self.build_schema(
data['json'], '', '', expected, options_seen)
if options_seen != set(expected.keys()):
raise Exception('missing from json: ' +
str(set(expected.keys()) - options_seen))

View File

@ -1,5 +1,5 @@
# Generated by generate_auto_job
generate_auto_job 8c88accfa988c8d6035c3e7e012bbde3da0c76fdfaba8e1460112bf344dc7b4f
generate_auto_job e28f3fb4938f6307bb4c23c084c239832dbee3bbaedf19a22fb19215312b30b0
include/qpdf/auto_job_c_att.hh 7ad43bb374c1370ef32ebdcdcb7b73a61d281f7f4e3f12755585872ab30fb60e
include/qpdf/auto_job_c_copy_att.hh 32275d03cdc69b703dd7e02ba0bbe15756e714e9ad185484773a6178dc09e1ee
include/qpdf/auto_job_c_enc.hh 72e138c7b96ed5aacdce78c1dec04b1c20d361faec4f8faf52f64c1d6be99265
@ -10,8 +10,8 @@ job.yml 14622557f5c96f379645f01c3d21b3d03bb8fd9c6062a3af429430d5348f5538
libqpdf/qpdf/auto_job_decl.hh 9f79396ec459f191be4c5fe34cf88c265cf47355a1a945fa39169d1c94cf04f6
libqpdf/qpdf/auto_job_help.hh 23c79f1d2c02bda28f64aace17f69487205c797e7ae2234892cbbabab49d6d47
libqpdf/qpdf/auto_job_init.hh 8e9e31b6099a662497339b27f6e2d7f779f35011e88a834bee8811c33405a0fe
libqpdf/qpdf/auto_job_json_decl.hh f349b55cf85d07a28aeb4bef257bdbcbe16f76b8065d01154161897b1e0fa643
libqpdf/qpdf/auto_job_json_init.hh 60d08982781bd568ab6083d325441f99a6bc39f72492558b8a64757373b2cfbe
libqpdf/qpdf/auto_job_schema.hh a483911bb1fda9cca53f3021bcdf26998604eabb23f131c78055c52d33ff5a4f
libqpdf/qpdf/auto_job_json_decl.hh 4846055075dcb7365c56c02150e955979b522d14f4329ce7a8a302ccd1d7aa2a
libqpdf/qpdf/auto_job_json_init.hh a8053ffcd4cc8c533a269805c79bba6757e5d17800f0d18938adf16e896694a3
libqpdf/qpdf/auto_job_schema.hh 3cd89b775118e09aa99fed200ca36c8a8dec8d17bc039012ca210b6a33ce1d8a
manual/_ext/qpdf.py e9ac9d6c70642a3d29281ee5ad92ae2422dee8be9306fb8a0bc9dba0ed5e28f3
manual/cli.rst 79140e023faa0cb77afe0b1dc512dd120ee5617f4db82f842596e4f239f93882

View File

@ -27,24 +27,20 @@ namespace
typedef std::function<void()> bare_handler_t;
typedef std::function<void(char const*)> param_handler_t;
typedef std::function<void(JSON)> json_handler_t;
typedef std::function<void(std::string const& key)> setup_handler_t;
void addBare(std::string const& key, bare_handler_t);
void addParameter(std::string const& key, param_handler_t);
void addChoices(std::string const& key, char const** choices,
param_handler_t);
void doSetup(std::string const& key, setup_handler_t);
void beginDict(std::string const& key,
json_handler_t start_fn,
void addBare(bare_handler_t);
void addParameter(param_handler_t);
void addChoices(char const** choices, param_handler_t);
void pushKey(std::string const& key);
void beginDict(json_handler_t start_fn,
bare_handler_t end_fn);
void beginArray(std::string const& key,
json_handler_t start_fn,
void beginArray(json_handler_t start_fn,
bare_handler_t end_fn);
void endContainer();
void ignoreItem();
void popHandler();
bare_handler_t bindBare(void (Handlers::*f)());
json_handler_t bindJSON(void (Handlers::*f)(JSON));
setup_handler_t bindSetup(void (Handlers::*f)(std::string const&));
std::list<std::shared_ptr<JSONHandler>> json_handlers;
bool partial;
@ -84,12 +80,6 @@ Handlers::bindJSON(void (Handlers::*f)(JSON))
return std::bind(std::mem_fn(f), this, std::placeholders::_1);
}
Handlers::setup_handler_t
Handlers::bindSetup(void (Handlers::*f)(std::string const&))
{
return std::bind(std::mem_fn(f), this, std::placeholders::_1);
}
void
Handlers::initHandlers()
{
@ -113,10 +103,9 @@ Handlers::initHandlers()
}
void
Handlers::addBare(std::string const& key, bare_handler_t fn)
Handlers::addBare(bare_handler_t fn)
{
auto h = std::make_shared<JSONHandler>();
h->addBoolHandler([this, fn](std::string const& path, bool v){
jh->addBoolHandler([this, fn](std::string const& path, bool v){
if (! v)
{
usage(path + ": value must be true");
@ -126,26 +115,22 @@ Handlers::addBare(std::string const& key, bare_handler_t fn)
fn();
}
});
jh->addDictKeyHandler(key, h);
}
void
Handlers::addParameter(std::string const& key, param_handler_t fn)
Handlers::addParameter(param_handler_t fn)
{
auto h = std::make_shared<JSONHandler>();
h->addStringHandler(
jh->addStringHandler(
[fn](std::string const& path, std::string const& parameter){
fn(parameter.c_str());
});
jh->addDictKeyHandler(key, h);
}
void
Handlers::addChoices(std::string const& key, char const** choices,
Handlers::addChoices(char const** choices,
param_handler_t fn)
{
auto h = std::make_shared<JSONHandler>();
h->addStringHandler(
jh->addStringHandler(
[fn, choices, this](
std::string const& path, std::string const& parameter){
@ -180,47 +165,45 @@ Handlers::addChoices(std::string const& key, char const** choices,
}
fn(parameter.c_str());
});
jh->addDictKeyHandler(key, h);
}
void
Handlers::doSetup(std::string const& key, setup_handler_t fn)
{
fn(key);
}
void
Handlers::beginDict(std::string const& key,
json_handler_t start_fn,
bare_handler_t end_fn)
Handlers::pushKey(std::string const& key)
{
auto new_jh = std::make_shared<JSONHandler>();
new_jh->addDictHandlers(
[start_fn](std::string const&, JSON j){ start_fn(j); },
[end_fn](std::string const&){ end_fn(); });
this->jh->addDictKeyHandler(key, new_jh);
this->json_handlers.push_back(new_jh);
this->jh = new_jh.get();
}
void
Handlers::beginArray(std::string const& key,
json_handler_t start_fn,
bare_handler_t end_fn)
Handlers::beginDict(json_handler_t start_fn, bare_handler_t end_fn)
{
jh->addDictHandlers(
[start_fn](std::string const&, JSON j){ start_fn(j); },
[end_fn](std::string const&){ end_fn(); });
}
void
Handlers::beginArray(json_handler_t start_fn, bare_handler_t end_fn)
{
auto new_jh = std::make_shared<JSONHandler>();
auto item_jh = std::make_shared<JSONHandler>();
new_jh->addArrayHandlers(
jh->addArrayHandlers(
[start_fn](std::string const&, JSON j){ start_fn(j); },
[end_fn](std::string const&){ end_fn(); },
item_jh);
this->jh->addDictKeyHandler(key, new_jh);
this->json_handlers.push_back(item_jh);
this->jh = item_jh.get();
}
void
Handlers::endContainer()
Handlers::ignoreItem()
{
jh->addAnyHandler([](std::string const&, JSON){});
}
void
Handlers::popHandler()
{
this->json_handlers.pop_back();
this->jh = this->json_handlers.back().get();
@ -245,25 +228,25 @@ Handlers::endInput()
}
void
Handlers::setupInputFilename(std::string const& key)
Handlers::setupInputFilename()
{
addParameter(key, [this](char const* p) {
addParameter([this](char const* p) {
c_main->inputFile(p);
});
}
void
Handlers::setupInputPassword(std::string const& key)
Handlers::setupInputPassword()
{
addParameter(key, [this](char const* p) {
addParameter([this](char const* p) {
c_main->password(p);
});
}
void
Handlers::setupInputEmpty(std::string const& key)
Handlers::setupInputEmpty()
{
addBare(key, [this]() {
addBare([this]() {
c_main->emptyInput();
});
}
@ -281,17 +264,17 @@ Handlers::endOutput()
}
void
Handlers::setupOutputFilename(std::string const& key)
Handlers::setupOutputFilename()
{
addParameter(key, [this](char const* p) {
addParameter([this](char const* p) {
c_main->outputFile(p);
});
}
void
Handlers::setupOutputReplaceInput(std::string const& key)
Handlers::setupOutputReplaceInput()
{
addBare(key, [this]() {
addBare([this]() {
c_main->replaceInput();
});
}
@ -359,15 +342,17 @@ Handlers::endOutputOptionsEncrypt()
}
void
Handlers::setupOutputOptionsEncryptUserPassword(std::string const& key)
Handlers::setupOutputOptionsEncryptUserPassword()
{
// Key handled in beginOutputOptionsEncrypt
// handled in beginOutputOptionsEncrypt
ignoreItem();
}
void
Handlers::setupOutputOptionsEncryptOwnerPassword(std::string const& key)
Handlers::setupOutputOptionsEncryptOwnerPassword()
{
// Key handled in beginOutputOptionsEncrypt
// handled in beginOutputOptionsEncrypt
ignoreItem();
}
void
@ -430,6 +415,30 @@ Handlers::endInspect()
// nothing needed
}
void
Handlers::beginInspectJsonKeyArray(JSON)
{
// nothing needed
}
void
Handlers::endInspectJsonKeyArray()
{
// nothing needed
}
void
Handlers::beginInspectJsonObjectArray(JSON)
{
// nothing needed
}
void
Handlers::endInspectJsonObjectArray()
{
// nothing needed
}
void
Handlers::beginOptionsAddAttachmentArray(JSON)
{
@ -456,9 +465,9 @@ Handlers::endOptionsAddAttachment()
}
void
Handlers::setupOptionsAddAttachmentPath(std::string const& key)
Handlers::setupOptionsAddAttachmentPath()
{
addParameter(key, [this](char const* p) {
addParameter([this](char const* p) {
c_att->path(p);
});
}
@ -489,17 +498,17 @@ Handlers::endOptionsCopyAttachmentsFrom()
}
void
Handlers::setupOptionsCopyAttachmentsFromPath(std::string const& key)
Handlers::setupOptionsCopyAttachmentsFromPath()
{
addParameter(key, [this](char const* p) {
addParameter([this](char const* p) {
c_copy_att->path(p);
});
}
void
Handlers::setupOptionsCopyAttachmentsFromPassword(std::string const& key)
Handlers::setupOptionsCopyAttachmentsFromPassword()
{
addParameter(key, [this](char const* p) {
addParameter([this](char const* p) {
c_copy_att->password(p);
});
}
@ -554,21 +563,24 @@ Handlers::endOptionsPages()
}
void
Handlers::setupOptionsPagesFile(std::string const& key)
Handlers::setupOptionsPagesFile()
{
// handled in beginOptionsPages
ignoreItem();
}
void
Handlers::setupOptionsPagesPassword(std::string const& key)
Handlers::setupOptionsPagesPassword()
{
// handled in beginOptionsPages
ignoreItem();
}
void
Handlers::setupOptionsPagesRange(std::string const& key)
Handlers::setupOptionsPagesRange()
{
// handled in beginOptionsPages
ignoreItem();
}
void
@ -585,17 +597,17 @@ Handlers::endOptionsOverlay()
}
void
Handlers::setupOptionsOverlayFile(std::string const& key)
Handlers::setupOptionsOverlayFile()
{
addParameter(key, [this](char const* p) {
addParameter([this](char const* p) {
c_uo->path(p);
});
}
void
Handlers::setupOptionsOverlayPassword(std::string const& key)
Handlers::setupOptionsOverlayPassword()
{
addParameter(key, [this](char const* p) {
addParameter([this](char const* p) {
c_uo->password(p);
});
}
@ -614,17 +626,17 @@ Handlers::endOptionsUnderlay()
}
void
Handlers::setupOptionsUnderlayFile(std::string const& key)
Handlers::setupOptionsUnderlayFile()
{
addParameter(key, [this](char const* p) {
addParameter([this](char const* p) {
c_uo->path(p);
});
}
void
Handlers::setupOptionsUnderlayPassword(std::string const& key)
Handlers::setupOptionsUnderlayPassword()
{
addParameter(key, [this](char const* p) {
addParameter([this](char const* p) {
c_uo->password(p);
});
}

View File

@ -5,19 +5,19 @@
//
void beginInput(JSON);
void endInput();
void setupInputFilename(std::string const&);
void setupInputPassword(std::string const&);
void setupInputEmpty(std::string const&);
void setupInputFilename();
void setupInputPassword();
void setupInputEmpty();
void beginOutput(JSON);
void endOutput();
void setupOutputFilename(std::string const&);
void setupOutputReplaceInput(std::string const&);
void setupOutputFilename();
void setupOutputReplaceInput();
void beginOutputOptions(JSON);
void endOutputOptions();
void beginOutputOptionsEncrypt(JSON);
void endOutputOptionsEncrypt();
void setupOutputOptionsEncryptUserPassword(std::string const&);
void setupOutputOptionsEncryptOwnerPassword(std::string const&);
void setupOutputOptionsEncryptUserPassword();
void setupOutputOptionsEncryptOwnerPassword();
void beginOutputOptionsEncrypt40bit(JSON);
void endOutputOptionsEncrypt40bit();
void beginOutputOptionsEncrypt128bit(JSON);
@ -26,31 +26,35 @@ void beginOutputOptionsEncrypt256bit(JSON);
void endOutputOptionsEncrypt256bit();
void beginInspect(JSON);
void endInspect();
void beginInspectJsonKeyArray(JSON);
void endInspectJsonKeyArray();
void beginInspectJsonObjectArray(JSON);
void endInspectJsonObjectArray();
void beginOptions(JSON);
void endOptions();
void beginOptionsAddAttachmentArray(JSON);
void endOptionsAddAttachmentArray();
void beginOptionsAddAttachment(JSON);
void endOptionsAddAttachment();
void setupOptionsAddAttachmentPath(std::string const&);
void setupOptionsAddAttachmentPath();
void beginOptionsCopyAttachmentsFromArray(JSON);
void endOptionsCopyAttachmentsFromArray();
void beginOptionsCopyAttachmentsFrom(JSON);
void endOptionsCopyAttachmentsFrom();
void setupOptionsCopyAttachmentsFromPath(std::string const&);
void setupOptionsCopyAttachmentsFromPassword(std::string const&);
void setupOptionsCopyAttachmentsFromPath();
void setupOptionsCopyAttachmentsFromPassword();
void beginOptionsPagesArray(JSON);
void endOptionsPagesArray();
void beginOptionsPages(JSON);
void endOptionsPages();
void setupOptionsPagesFile(std::string const&);
void setupOptionsPagesPassword(std::string const&);
void setupOptionsPagesRange(std::string const&);
void setupOptionsPagesFile();
void setupOptionsPagesPassword();
void setupOptionsPagesRange();
void beginOptionsOverlay(JSON);
void endOptionsOverlay();
void setupOptionsOverlayFile(std::string const&);
void setupOptionsOverlayPassword(std::string const&);
void setupOptionsOverlayFile();
void setupOptionsOverlayPassword();
void beginOptionsUnderlay(JSON);
void endOptionsUnderlay();
void setupOptionsUnderlayFile(std::string const&);
void setupOptionsUnderlayPassword(std::string const&);
void setupOptionsUnderlayFile();
void setupOptionsUnderlayPassword();

View File

@ -14,161 +14,427 @@ static char const* json_key_choices[] = {"acroform", "attachments", "encrypt", "
static char const* print128_choices[] = {"full", "low", "none", 0};
static char const* modify128_choices[] = {"all", "annotate", "form", "assembly", "none", 0};
beginDict("input", bindJSON(&Handlers::beginInput), bindBare(&Handlers::endInput)); // .input
doSetup("filename", bindSetup(&Handlers::setupInputFilename));
doSetup("password", bindSetup(&Handlers::setupInputPassword));
addParameter("passwordFile", [this](char const* p) { c_main->passwordFile(p); });
doSetup("empty", bindSetup(&Handlers::setupInputEmpty));
endContainer(); // .input
beginDict("output", bindJSON(&Handlers::beginOutput), bindBare(&Handlers::endOutput)); // .output
doSetup("filename", bindSetup(&Handlers::setupOutputFilename));
doSetup("replaceInput", bindSetup(&Handlers::setupOutputReplaceInput));
beginDict("options", bindJSON(&Handlers::beginOutputOptions), bindBare(&Handlers::endOutputOptions)); // .output.options
addBare("qdf", [this]() { c_main->qdf(); });
addBare("preserveUnreferenced", [this]() { c_main->preserveUnreferenced(); });
addBare("newlineBeforeEndstream", [this]() { c_main->newlineBeforeEndstream(); });
addChoices("normalizeContent", yn_choices, [this](char const* p) { c_main->normalizeContent(p); });
addChoices("streamData", stream_data_choices, [this](char const* p) { c_main->streamData(p); });
addChoices("compressStreams", yn_choices, [this](char const* p) { c_main->compressStreams(p); });
addBare("recompressFlate", [this]() { c_main->recompressFlate(); });
addChoices("decodeLevel", decode_level_choices, [this](char const* p) { c_main->decodeLevel(p); });
addBare("decrypt", [this]() { c_main->decrypt(); });
addBare("staticAesIv", [this]() { c_main->staticAesIv(); });
addBare("staticId", [this]() { c_main->staticId(); });
addBare("noOriginalObjectIds", [this]() { c_main->noOriginalObjectIds(); });
addParameter("copyEncryption", [this](char const* p) { c_main->copyEncryption(p); });
addParameter("encryptionFilePassword", [this](char const* p) { c_main->encryptionFilePassword(p); });
addBare("linearize", [this]() { c_main->linearize(); });
addParameter("linearizePass1", [this](char const* p) { c_main->linearizePass1(p); });
addChoices("objectStreams", object_streams_choices, [this](char const* p) { c_main->objectStreams(p); });
addParameter("minVersion", [this](char const* p) { c_main->minVersion(p); });
addParameter("forceVersion", [this](char const* p) { c_main->forceVersion(p); });
addBare("progress", [this]() { c_main->progress(); });
addParameter("splitPages", [this](char const* p) { c_main->splitPages(p); });
beginDict("encrypt", bindJSON(&Handlers::beginOutputOptionsEncrypt), bindBare(&Handlers::endOutputOptionsEncrypt)); // .output.options.encrypt
doSetup("userPassword", bindSetup(&Handlers::setupOutputOptionsEncryptUserPassword));
doSetup("ownerPassword", bindSetup(&Handlers::setupOutputOptionsEncryptOwnerPassword));
beginDict("40bit", bindJSON(&Handlers::beginOutputOptionsEncrypt40bit), bindBare(&Handlers::endOutputOptionsEncrypt40bit)); // .output.options.encrypt.40bit
addChoices("annotate", yn_choices, [this](char const* p) { c_enc->annotate(p); });
addChoices("extract", yn_choices, [this](char const* p) { c_enc->extract(p); });
addChoices("modify", modify128_choices, [this](char const* p) { c_enc->modify(p); });
addChoices("print", print128_choices, [this](char const* p) { c_enc->print(p); });
endContainer(); // .output.options.encrypt.40bit
beginDict("128bit", bindJSON(&Handlers::beginOutputOptionsEncrypt128bit), bindBare(&Handlers::endOutputOptionsEncrypt128bit)); // .output.options.encrypt.128bit
addChoices("accessibility", yn_choices, [this](char const* p) { c_enc->accessibility(p); });
addChoices("annotate", yn_choices, [this](char const* p) { c_enc->annotate(p); });
addChoices("assemble", yn_choices, [this](char const* p) { c_enc->assemble(p); });
addBare("cleartextMetadata", [this]() { c_enc->cleartextMetadata(); });
addChoices("extract", yn_choices, [this](char const* p) { c_enc->extract(p); });
addChoices("form", yn_choices, [this](char const* p) { c_enc->form(p); });
addChoices("modifyOther", yn_choices, [this](char const* p) { c_enc->modifyOther(p); });
addChoices("modify", modify128_choices, [this](char const* p) { c_enc->modify(p); });
addChoices("print", print128_choices, [this](char const* p) { c_enc->print(p); });
addBare("forceV4", [this]() { c_enc->forceV4(); });
addChoices("useAes", yn_choices, [this](char const* p) { c_enc->useAes(p); });
endContainer(); // .output.options.encrypt.128bit
beginDict("256bit", bindJSON(&Handlers::beginOutputOptionsEncrypt256bit), bindBare(&Handlers::endOutputOptionsEncrypt256bit)); // .output.options.encrypt.256bit
addChoices("accessibility", yn_choices, [this](char const* p) { c_enc->accessibility(p); });
addChoices("annotate", yn_choices, [this](char const* p) { c_enc->annotate(p); });
addChoices("assemble", yn_choices, [this](char const* p) { c_enc->assemble(p); });
addBare("cleartextMetadata", [this]() { c_enc->cleartextMetadata(); });
addChoices("extract", yn_choices, [this](char const* p) { c_enc->extract(p); });
addChoices("form", yn_choices, [this](char const* p) { c_enc->form(p); });
addChoices("modifyOther", yn_choices, [this](char const* p) { c_enc->modifyOther(p); });
addChoices("modify", modify128_choices, [this](char const* p) { c_enc->modify(p); });
addChoices("print", print128_choices, [this](char const* p) { c_enc->print(p); });
addBare("allowInsecure", [this]() { c_enc->allowInsecure(); });
addBare("forceR5", [this]() { c_enc->forceR5(); });
endContainer(); // .output.options.encrypt.256bit
endContainer(); // .output.options.encrypt
endContainer(); // .output.options
endContainer(); // .output
beginDict("inspect", bindJSON(&Handlers::beginInspect), bindBare(&Handlers::endInspect)); // .inspect
addBare("check", [this]() { c_main->check(); });
addBare("checkLinearization", [this]() { c_main->checkLinearization(); });
addBare("filteredStreamData", [this]() { c_main->filteredStreamData(); });
addBare("rawStreamData", [this]() { c_main->rawStreamData(); });
addBare("showEncryption", [this]() { c_main->showEncryption(); });
addBare("showEncryptionKey", [this]() { c_main->showEncryptionKey(); });
addBare("showLinearization", [this]() { c_main->showLinearization(); });
addBare("showNpages", [this]() { c_main->showNpages(); });
addParameter("showObject", [this](char const* p) { c_main->showObject(p); });
addBare("showPages", [this]() { c_main->showPages(); });
addBare("showXref", [this]() { c_main->showXref(); });
addBare("withImages", [this]() { c_main->withImages(); });
addBare("listAttachments", [this]() { c_main->listAttachments(); });
addParameter("showAttachment", [this](char const* p) { c_main->showAttachment(p); });
addBare("json", [this]() { c_main->json(); });
addChoices("jsonKey", json_key_choices, [this](char const* p) { c_main->jsonKey(p); });
addParameter("jsonObject", [this](char const* p) { c_main->jsonObject(p); });
endContainer(); // .inspect
beginDict("options", bindJSON(&Handlers::beginOptions), bindBare(&Handlers::endOptions)); // .options
addBare("allowWeakCrypto", [this]() { c_main->allowWeakCrypto(); });
addBare("deterministicId", [this]() { c_main->deterministicId(); });
addChoices("keepFilesOpen", yn_choices, [this](char const* p) { c_main->keepFilesOpen(p); });
addParameter("keepFilesOpenThreshold", [this](char const* p) { c_main->keepFilesOpenThreshold(p); });
addBare("noWarn", [this]() { c_main->noWarn(); });
addBare("verbose", [this]() { c_main->verbose(); });
addBare("ignoreXrefStreams", [this]() { c_main->ignoreXrefStreams(); });
addBare("passwordIsHexKey", [this]() { c_main->passwordIsHexKey(); });
addChoices("passwordMode", password_mode_choices, [this](char const* p) { c_main->passwordMode(p); });
addBare("suppressPasswordRecovery", [this]() { c_main->suppressPasswordRecovery(); });
addBare("suppressRecovery", [this]() { c_main->suppressRecovery(); });
addBare("coalesceContents", [this]() { c_main->coalesceContents(); });
addParameter("compressionLevel", [this](char const* p) { c_main->compressionLevel(p); });
addBare("externalizeInlineImages", [this]() { c_main->externalizeInlineImages(); });
addParameter("iiMinBytes", [this](char const* p) { c_main->iiMinBytes(p); });
addChoices("removeUnreferencedResources", remove_unref_choices, [this](char const* p) { c_main->removeUnreferencedResources(p); });
beginArray("options", bindJSON(&Handlers::beginOptionsAddAttachmentArray), bindBare(&Handlers::endOptionsAddAttachmentArray)); // .options.addAttachment[]
beginDict("addAttachment", bindJSON(&Handlers::beginOptionsAddAttachment), bindBare(&Handlers::endOptionsAddAttachment)); // .options.addAttachment
doSetup("path", bindSetup(&Handlers::setupOptionsAddAttachmentPath));
addParameter("creationdate", [this](char const* p) { c_att->creationdate(p); });
addParameter("description", [this](char const* p) { c_att->description(p); });
addParameter("filename", [this](char const* p) { c_att->filename(p); });
addParameter("key", [this](char const* p) { c_att->key(p); });
addParameter("mimetype", [this](char const* p) { c_att->mimetype(p); });
addParameter("moddate", [this](char const* p) { c_att->moddate(p); });
addBare("replace", [this]() { c_att->replace(); });
endContainer(); // .options.addAttachment
endContainer(); // .options.addAttachment[]
addParameter("removeAttachment", [this](char const* p) { c_main->removeAttachment(p); });
beginArray("options", bindJSON(&Handlers::beginOptionsCopyAttachmentsFromArray), bindBare(&Handlers::endOptionsCopyAttachmentsFromArray)); // .options.copyAttachmentsFrom[]
beginDict("copyAttachmentsFrom", bindJSON(&Handlers::beginOptionsCopyAttachmentsFrom), bindBare(&Handlers::endOptionsCopyAttachmentsFrom)); // .options.copyAttachmentsFrom
doSetup("path", bindSetup(&Handlers::setupOptionsCopyAttachmentsFromPath));
doSetup("password", bindSetup(&Handlers::setupOptionsCopyAttachmentsFromPassword));
addParameter("prefix", [this](char const* p) { c_copy_att->prefix(p); });
endContainer(); // .options.copyAttachmentsFrom
endContainer(); // .options.copyAttachmentsFrom[]
addParameter("collate", [this](char const* p) { c_main->collate(p); });
addChoices("flattenAnnotations", flatten_choices, [this](char const* p) { c_main->flattenAnnotations(p); });
addBare("flattenRotation", [this]() { c_main->flattenRotation(); });
addBare("generateAppearances", [this]() { c_main->generateAppearances(); });
addBare("keepInlineImages", [this]() { c_main->keepInlineImages(); });
addParameter("oiMinArea", [this](char const* p) { c_main->oiMinArea(p); });
addParameter("oiMinHeight", [this](char const* p) { c_main->oiMinHeight(p); });
addParameter("oiMinWidth", [this](char const* p) { c_main->oiMinWidth(p); });
addBare("optimizeImages", [this]() { c_main->optimizeImages(); });
beginArray("options", bindJSON(&Handlers::beginOptionsPagesArray), bindBare(&Handlers::endOptionsPagesArray)); // .options.pages[]
beginDict("pages", bindJSON(&Handlers::beginOptionsPages), bindBare(&Handlers::endOptionsPages)); // .options.pages
doSetup("file", bindSetup(&Handlers::setupOptionsPagesFile));
doSetup("password", bindSetup(&Handlers::setupOptionsPagesPassword));
doSetup("range", bindSetup(&Handlers::setupOptionsPagesRange));
endContainer(); // .options.pages
endContainer(); // .options.pages[]
addBare("removePageLabels", [this]() { c_main->removePageLabels(); });
addParameter("rotate", [this](char const* p) { c_main->rotate(p); });
beginDict("overlay", bindJSON(&Handlers::beginOptionsOverlay), bindBare(&Handlers::endOptionsOverlay)); // .options.overlay
doSetup("file", bindSetup(&Handlers::setupOptionsOverlayFile));
doSetup("password", bindSetup(&Handlers::setupOptionsOverlayPassword));
addParameter("from", [this](char const* p) { c_uo->from(p); });
addParameter("repeat", [this](char const* p) { c_uo->repeat(p); });
addParameter("to", [this](char const* p) { c_uo->to(p); });
endContainer(); // .options.overlay
beginDict("underlay", bindJSON(&Handlers::beginOptionsUnderlay), bindBare(&Handlers::endOptionsUnderlay)); // .options.underlay
doSetup("file", bindSetup(&Handlers::setupOptionsUnderlayFile));
doSetup("password", bindSetup(&Handlers::setupOptionsUnderlayPassword));
addParameter("from", [this](char const* p) { c_uo->from(p); });
addParameter("repeat", [this](char const* p) { c_uo->repeat(p); });
addParameter("to", [this](char const* p) { c_uo->to(p); });
endContainer(); // .options.underlay
endContainer(); // .options
pushKey("input");
beginDict(bindJSON(&Handlers::beginInput), bindBare(&Handlers::endInput)); // .input
pushKey("filename");
setupInputFilename();
popHandler(); // key: filename
pushKey("password");
setupInputPassword();
popHandler(); // key: password
pushKey("passwordFile");
addParameter([this](char const* p) { c_main->passwordFile(p); });
popHandler(); // key: passwordFile
pushKey("empty");
setupInputEmpty();
popHandler(); // key: empty
popHandler(); // key: input
pushKey("output");
beginDict(bindJSON(&Handlers::beginOutput), bindBare(&Handlers::endOutput)); // .output
pushKey("filename");
setupOutputFilename();
popHandler(); // key: filename
pushKey("replaceInput");
setupOutputReplaceInput();
popHandler(); // key: replaceInput
pushKey("options");
beginDict(bindJSON(&Handlers::beginOutputOptions), bindBare(&Handlers::endOutputOptions)); // .output.options
pushKey("qdf");
addBare([this]() { c_main->qdf(); });
popHandler(); // key: qdf
pushKey("preserveUnreferenced");
addBare([this]() { c_main->preserveUnreferenced(); });
popHandler(); // key: preserveUnreferenced
pushKey("newlineBeforeEndstream");
addBare([this]() { c_main->newlineBeforeEndstream(); });
popHandler(); // key: newlineBeforeEndstream
pushKey("normalizeContent");
addChoices(yn_choices, [this](char const* p) { c_main->normalizeContent(p); });
popHandler(); // key: normalizeContent
pushKey("streamData");
addChoices(stream_data_choices, [this](char const* p) { c_main->streamData(p); });
popHandler(); // key: streamData
pushKey("compressStreams");
addChoices(yn_choices, [this](char const* p) { c_main->compressStreams(p); });
popHandler(); // key: compressStreams
pushKey("recompressFlate");
addBare([this]() { c_main->recompressFlate(); });
popHandler(); // key: recompressFlate
pushKey("decodeLevel");
addChoices(decode_level_choices, [this](char const* p) { c_main->decodeLevel(p); });
popHandler(); // key: decodeLevel
pushKey("decrypt");
addBare([this]() { c_main->decrypt(); });
popHandler(); // key: decrypt
pushKey("staticAesIv");
addBare([this]() { c_main->staticAesIv(); });
popHandler(); // key: staticAesIv
pushKey("staticId");
addBare([this]() { c_main->staticId(); });
popHandler(); // key: staticId
pushKey("noOriginalObjectIds");
addBare([this]() { c_main->noOriginalObjectIds(); });
popHandler(); // key: noOriginalObjectIds
pushKey("copyEncryption");
addParameter([this](char const* p) { c_main->copyEncryption(p); });
popHandler(); // key: copyEncryption
pushKey("encryptionFilePassword");
addParameter([this](char const* p) { c_main->encryptionFilePassword(p); });
popHandler(); // key: encryptionFilePassword
pushKey("linearize");
addBare([this]() { c_main->linearize(); });
popHandler(); // key: linearize
pushKey("linearizePass1");
addParameter([this](char const* p) { c_main->linearizePass1(p); });
popHandler(); // key: linearizePass1
pushKey("objectStreams");
addChoices(object_streams_choices, [this](char const* p) { c_main->objectStreams(p); });
popHandler(); // key: objectStreams
pushKey("minVersion");
addParameter([this](char const* p) { c_main->minVersion(p); });
popHandler(); // key: minVersion
pushKey("forceVersion");
addParameter([this](char const* p) { c_main->forceVersion(p); });
popHandler(); // key: forceVersion
pushKey("progress");
addBare([this]() { c_main->progress(); });
popHandler(); // key: progress
pushKey("splitPages");
addParameter([this](char const* p) { c_main->splitPages(p); });
popHandler(); // key: splitPages
pushKey("encrypt");
beginDict(bindJSON(&Handlers::beginOutputOptionsEncrypt), bindBare(&Handlers::endOutputOptionsEncrypt)); // .output.options.encrypt
pushKey("userPassword");
setupOutputOptionsEncryptUserPassword();
popHandler(); // key: userPassword
pushKey("ownerPassword");
setupOutputOptionsEncryptOwnerPassword();
popHandler(); // key: ownerPassword
pushKey("40bit");
beginDict(bindJSON(&Handlers::beginOutputOptionsEncrypt40bit), bindBare(&Handlers::endOutputOptionsEncrypt40bit)); // .output.options.encrypt.40bit
pushKey("annotate");
addChoices(yn_choices, [this](char const* p) { c_enc->annotate(p); });
popHandler(); // key: annotate
pushKey("extract");
addChoices(yn_choices, [this](char const* p) { c_enc->extract(p); });
popHandler(); // key: extract
pushKey("modify");
addChoices(modify128_choices, [this](char const* p) { c_enc->modify(p); });
popHandler(); // key: modify
pushKey("print");
addChoices(print128_choices, [this](char const* p) { c_enc->print(p); });
popHandler(); // key: print
popHandler(); // key: 40bit
pushKey("128bit");
beginDict(bindJSON(&Handlers::beginOutputOptionsEncrypt128bit), bindBare(&Handlers::endOutputOptionsEncrypt128bit)); // .output.options.encrypt.128bit
pushKey("accessibility");
addChoices(yn_choices, [this](char const* p) { c_enc->accessibility(p); });
popHandler(); // key: accessibility
pushKey("annotate");
addChoices(yn_choices, [this](char const* p) { c_enc->annotate(p); });
popHandler(); // key: annotate
pushKey("assemble");
addChoices(yn_choices, [this](char const* p) { c_enc->assemble(p); });
popHandler(); // key: assemble
pushKey("cleartextMetadata");
addBare([this]() { c_enc->cleartextMetadata(); });
popHandler(); // key: cleartextMetadata
pushKey("extract");
addChoices(yn_choices, [this](char const* p) { c_enc->extract(p); });
popHandler(); // key: extract
pushKey("form");
addChoices(yn_choices, [this](char const* p) { c_enc->form(p); });
popHandler(); // key: form
pushKey("modifyOther");
addChoices(yn_choices, [this](char const* p) { c_enc->modifyOther(p); });
popHandler(); // key: modifyOther
pushKey("modify");
addChoices(modify128_choices, [this](char const* p) { c_enc->modify(p); });
popHandler(); // key: modify
pushKey("print");
addChoices(print128_choices, [this](char const* p) { c_enc->print(p); });
popHandler(); // key: print
pushKey("forceV4");
addBare([this]() { c_enc->forceV4(); });
popHandler(); // key: forceV4
pushKey("useAes");
addChoices(yn_choices, [this](char const* p) { c_enc->useAes(p); });
popHandler(); // key: useAes
popHandler(); // key: 128bit
pushKey("256bit");
beginDict(bindJSON(&Handlers::beginOutputOptionsEncrypt256bit), bindBare(&Handlers::endOutputOptionsEncrypt256bit)); // .output.options.encrypt.256bit
pushKey("accessibility");
addChoices(yn_choices, [this](char const* p) { c_enc->accessibility(p); });
popHandler(); // key: accessibility
pushKey("annotate");
addChoices(yn_choices, [this](char const* p) { c_enc->annotate(p); });
popHandler(); // key: annotate
pushKey("assemble");
addChoices(yn_choices, [this](char const* p) { c_enc->assemble(p); });
popHandler(); // key: assemble
pushKey("cleartextMetadata");
addBare([this]() { c_enc->cleartextMetadata(); });
popHandler(); // key: cleartextMetadata
pushKey("extract");
addChoices(yn_choices, [this](char const* p) { c_enc->extract(p); });
popHandler(); // key: extract
pushKey("form");
addChoices(yn_choices, [this](char const* p) { c_enc->form(p); });
popHandler(); // key: form
pushKey("modifyOther");
addChoices(yn_choices, [this](char const* p) { c_enc->modifyOther(p); });
popHandler(); // key: modifyOther
pushKey("modify");
addChoices(modify128_choices, [this](char const* p) { c_enc->modify(p); });
popHandler(); // key: modify
pushKey("print");
addChoices(print128_choices, [this](char const* p) { c_enc->print(p); });
popHandler(); // key: print
pushKey("allowInsecure");
addBare([this]() { c_enc->allowInsecure(); });
popHandler(); // key: allowInsecure
pushKey("forceR5");
addBare([this]() { c_enc->forceR5(); });
popHandler(); // key: forceR5
popHandler(); // key: 256bit
popHandler(); // key: encrypt
popHandler(); // key: options
popHandler(); // key: output
pushKey("inspect");
beginDict(bindJSON(&Handlers::beginInspect), bindBare(&Handlers::endInspect)); // .inspect
pushKey("check");
addBare([this]() { c_main->check(); });
popHandler(); // key: check
pushKey("checkLinearization");
addBare([this]() { c_main->checkLinearization(); });
popHandler(); // key: checkLinearization
pushKey("filteredStreamData");
addBare([this]() { c_main->filteredStreamData(); });
popHandler(); // key: filteredStreamData
pushKey("rawStreamData");
addBare([this]() { c_main->rawStreamData(); });
popHandler(); // key: rawStreamData
pushKey("showEncryption");
addBare([this]() { c_main->showEncryption(); });
popHandler(); // key: showEncryption
pushKey("showEncryptionKey");
addBare([this]() { c_main->showEncryptionKey(); });
popHandler(); // key: showEncryptionKey
pushKey("showLinearization");
addBare([this]() { c_main->showLinearization(); });
popHandler(); // key: showLinearization
pushKey("showNpages");
addBare([this]() { c_main->showNpages(); });
popHandler(); // key: showNpages
pushKey("showObject");
addParameter([this](char const* p) { c_main->showObject(p); });
popHandler(); // key: showObject
pushKey("showPages");
addBare([this]() { c_main->showPages(); });
popHandler(); // key: showPages
pushKey("showXref");
addBare([this]() { c_main->showXref(); });
popHandler(); // key: showXref
pushKey("withImages");
addBare([this]() { c_main->withImages(); });
popHandler(); // key: withImages
pushKey("listAttachments");
addBare([this]() { c_main->listAttachments(); });
popHandler(); // key: listAttachments
pushKey("showAttachment");
addParameter([this](char const* p) { c_main->showAttachment(p); });
popHandler(); // key: showAttachment
pushKey("json");
addBare([this]() { c_main->json(); });
popHandler(); // key: json
pushKey("jsonKey");
beginArray(bindJSON(&Handlers::beginInspectJsonKeyArray), bindBare(&Handlers::endInspectJsonKeyArray)); // .inspect.jsonKey[]
addChoices(json_key_choices, [this](char const* p) { c_main->jsonKey(p); });
popHandler(); // array: .inspect.jsonKey[]
popHandler(); // key: jsonKey
pushKey("jsonObject");
beginArray(bindJSON(&Handlers::beginInspectJsonObjectArray), bindBare(&Handlers::endInspectJsonObjectArray)); // .inspect.jsonObject[]
addParameter([this](char const* p) { c_main->jsonObject(p); });
popHandler(); // array: .inspect.jsonObject[]
popHandler(); // key: jsonObject
popHandler(); // key: inspect
pushKey("options");
beginDict(bindJSON(&Handlers::beginOptions), bindBare(&Handlers::endOptions)); // .options
pushKey("allowWeakCrypto");
addBare([this]() { c_main->allowWeakCrypto(); });
popHandler(); // key: allowWeakCrypto
pushKey("deterministicId");
addBare([this]() { c_main->deterministicId(); });
popHandler(); // key: deterministicId
pushKey("keepFilesOpen");
addChoices(yn_choices, [this](char const* p) { c_main->keepFilesOpen(p); });
popHandler(); // key: keepFilesOpen
pushKey("keepFilesOpenThreshold");
addParameter([this](char const* p) { c_main->keepFilesOpenThreshold(p); });
popHandler(); // key: keepFilesOpenThreshold
pushKey("noWarn");
addBare([this]() { c_main->noWarn(); });
popHandler(); // key: noWarn
pushKey("verbose");
addBare([this]() { c_main->verbose(); });
popHandler(); // key: verbose
pushKey("ignoreXrefStreams");
addBare([this]() { c_main->ignoreXrefStreams(); });
popHandler(); // key: ignoreXrefStreams
pushKey("passwordIsHexKey");
addBare([this]() { c_main->passwordIsHexKey(); });
popHandler(); // key: passwordIsHexKey
pushKey("passwordMode");
addChoices(password_mode_choices, [this](char const* p) { c_main->passwordMode(p); });
popHandler(); // key: passwordMode
pushKey("suppressPasswordRecovery");
addBare([this]() { c_main->suppressPasswordRecovery(); });
popHandler(); // key: suppressPasswordRecovery
pushKey("suppressRecovery");
addBare([this]() { c_main->suppressRecovery(); });
popHandler(); // key: suppressRecovery
pushKey("coalesceContents");
addBare([this]() { c_main->coalesceContents(); });
popHandler(); // key: coalesceContents
pushKey("compressionLevel");
addParameter([this](char const* p) { c_main->compressionLevel(p); });
popHandler(); // key: compressionLevel
pushKey("externalizeInlineImages");
addBare([this]() { c_main->externalizeInlineImages(); });
popHandler(); // key: externalizeInlineImages
pushKey("iiMinBytes");
addParameter([this](char const* p) { c_main->iiMinBytes(p); });
popHandler(); // key: iiMinBytes
pushKey("removeUnreferencedResources");
addChoices(remove_unref_choices, [this](char const* p) { c_main->removeUnreferencedResources(p); });
popHandler(); // key: removeUnreferencedResources
pushKey("addAttachment");
beginArray(bindJSON(&Handlers::beginOptionsAddAttachmentArray), bindBare(&Handlers::endOptionsAddAttachmentArray)); // .options.addAttachment[]
beginDict(bindJSON(&Handlers::beginOptionsAddAttachment), bindBare(&Handlers::endOptionsAddAttachment)); // .options.addAttachment
pushKey("path");
setupOptionsAddAttachmentPath();
popHandler(); // key: path
pushKey("creationdate");
addParameter([this](char const* p) { c_att->creationdate(p); });
popHandler(); // key: creationdate
pushKey("description");
addParameter([this](char const* p) { c_att->description(p); });
popHandler(); // key: description
pushKey("filename");
addParameter([this](char const* p) { c_att->filename(p); });
popHandler(); // key: filename
pushKey("key");
addParameter([this](char const* p) { c_att->key(p); });
popHandler(); // key: key
pushKey("mimetype");
addParameter([this](char const* p) { c_att->mimetype(p); });
popHandler(); // key: mimetype
pushKey("moddate");
addParameter([this](char const* p) { c_att->moddate(p); });
popHandler(); // key: moddate
pushKey("replace");
addBare([this]() { c_att->replace(); });
popHandler(); // key: replace
popHandler(); // array: .options.addAttachment[]
popHandler(); // key: addAttachment
pushKey("removeAttachment");
addParameter([this](char const* p) { c_main->removeAttachment(p); });
popHandler(); // key: removeAttachment
pushKey("copyAttachmentsFrom");
beginArray(bindJSON(&Handlers::beginOptionsCopyAttachmentsFromArray), bindBare(&Handlers::endOptionsCopyAttachmentsFromArray)); // .options.copyAttachmentsFrom[]
beginDict(bindJSON(&Handlers::beginOptionsCopyAttachmentsFrom), bindBare(&Handlers::endOptionsCopyAttachmentsFrom)); // .options.copyAttachmentsFrom
pushKey("path");
setupOptionsCopyAttachmentsFromPath();
popHandler(); // key: path
pushKey("password");
setupOptionsCopyAttachmentsFromPassword();
popHandler(); // key: password
pushKey("prefix");
addParameter([this](char const* p) { c_copy_att->prefix(p); });
popHandler(); // key: prefix
popHandler(); // array: .options.copyAttachmentsFrom[]
popHandler(); // key: copyAttachmentsFrom
pushKey("collate");
addParameter([this](char const* p) { c_main->collate(p); });
popHandler(); // key: collate
pushKey("flattenAnnotations");
addChoices(flatten_choices, [this](char const* p) { c_main->flattenAnnotations(p); });
popHandler(); // key: flattenAnnotations
pushKey("flattenRotation");
addBare([this]() { c_main->flattenRotation(); });
popHandler(); // key: flattenRotation
pushKey("generateAppearances");
addBare([this]() { c_main->generateAppearances(); });
popHandler(); // key: generateAppearances
pushKey("keepInlineImages");
addBare([this]() { c_main->keepInlineImages(); });
popHandler(); // key: keepInlineImages
pushKey("oiMinArea");
addParameter([this](char const* p) { c_main->oiMinArea(p); });
popHandler(); // key: oiMinArea
pushKey("oiMinHeight");
addParameter([this](char const* p) { c_main->oiMinHeight(p); });
popHandler(); // key: oiMinHeight
pushKey("oiMinWidth");
addParameter([this](char const* p) { c_main->oiMinWidth(p); });
popHandler(); // key: oiMinWidth
pushKey("optimizeImages");
addBare([this]() { c_main->optimizeImages(); });
popHandler(); // key: optimizeImages
pushKey("pages");
beginArray(bindJSON(&Handlers::beginOptionsPagesArray), bindBare(&Handlers::endOptionsPagesArray)); // .options.pages[]
beginDict(bindJSON(&Handlers::beginOptionsPages), bindBare(&Handlers::endOptionsPages)); // .options.pages
pushKey("file");
setupOptionsPagesFile();
popHandler(); // key: file
pushKey("password");
setupOptionsPagesPassword();
popHandler(); // key: password
pushKey("range");
setupOptionsPagesRange();
popHandler(); // key: range
popHandler(); // array: .options.pages[]
popHandler(); // key: pages
pushKey("removePageLabels");
addBare([this]() { c_main->removePageLabels(); });
popHandler(); // key: removePageLabels
pushKey("rotate");
addParameter([this](char const* p) { c_main->rotate(p); });
popHandler(); // key: rotate
pushKey("overlay");
beginDict(bindJSON(&Handlers::beginOptionsOverlay), bindBare(&Handlers::endOptionsOverlay)); // .options.overlay
pushKey("file");
setupOptionsOverlayFile();
popHandler(); // key: file
pushKey("password");
setupOptionsOverlayPassword();
popHandler(); // key: password
pushKey("from");
addParameter([this](char const* p) { c_uo->from(p); });
popHandler(); // key: from
pushKey("repeat");
addParameter([this](char const* p) { c_uo->repeat(p); });
popHandler(); // key: repeat
pushKey("to");
addParameter([this](char const* p) { c_uo->to(p); });
popHandler(); // key: to
popHandler(); // key: overlay
pushKey("underlay");
beginDict(bindJSON(&Handlers::beginOptionsUnderlay), bindBare(&Handlers::endOptionsUnderlay)); // .options.underlay
pushKey("file");
setupOptionsUnderlayFile();
popHandler(); // key: file
pushKey("password");
setupOptionsUnderlayPassword();
popHandler(); // key: password
pushKey("from");
addParameter([this](char const* p) { c_uo->from(p); });
popHandler(); // key: from
pushKey("repeat");
addParameter([this](char const* p) { c_uo->repeat(p); });
popHandler(); // key: repeat
pushKey("to");
addParameter([this](char const* p) { c_uo->to(p); });
popHandler(); // key: to
popHandler(); // key: underlay
popHandler(); // key: options

View File

@ -85,10 +85,10 @@ static constexpr char const* JOB_SCHEMA_DATA = R"({
"showAttachment": "export an embedded file",
"json": "show file in json format",
"jsonKey": [
null
"restrict which keys are in json output"
],
"jsonObject": [
null
"restrict which objects are in JSON"
]
},
"options": {