aboutsummaryrefslogtreecommitdiffstatshomepage
path: root/utils/block_cmd_parser.hpp
diff options
context:
space:
mode:
authorEgor Tensin <Egor.Tensin@gmail.com>2015-12-27 12:56:13 +0300
committerEgor Tensin <Egor.Tensin@gmail.com>2015-12-27 12:56:13 +0300
commit1db94ae5d2201edb5f9421c2c30be049efc678f6 (patch)
treecb67b8f1e8a04dda4de297cc011dc9de57d1e824 /utils/block_cmd_parser.hpp
parentREADME update (diff)
downloadaes-tools-1db94ae5d2201edb5f9421c2c30be049efc678f6.tar.gz
aes-tools-1db94ae5d2201edb5f9421c2c30be049efc678f6.zip
utils: refactor command line parsing
Diffstat (limited to 'utils/block_cmd_parser.hpp')
-rw-r--r--utils/block_cmd_parser.hpp143
1 files changed, 128 insertions, 15 deletions
diff --git a/utils/block_cmd_parser.hpp b/utils/block_cmd_parser.hpp
index 3468d58..988ef52 100644
--- a/utils/block_cmd_parser.hpp
+++ b/utils/block_cmd_parser.hpp
@@ -16,8 +16,11 @@
#include <boost/filesystem.hpp>
#include <boost/program_options.hpp>
+#include <iterator>
+#include <deque>
#include <ostream>
#include <string>
+#include <utility>
#include <vector>
namespace
@@ -40,26 +43,87 @@ namespace
"the selected mode of operation is not implemented");
}
+ class CommandLineParser;
+
+ class Input
+ {
+ public:
+ Input(
+ std::string&& key_string,
+ std::string&& iv_string,
+ std::vector<std::string>&& input_block_strings)
+ : key_string(std::move(key_string))
+ , iv_string(std::make_pair<bool, std::string>(true, std::move(iv_string)))
+ , input_block_strings(input_block_strings)
+ { }
+
+ Input(
+ std::string&& key_string,
+ std::vector<std::string>&& input_block_strings)
+ : key_string(std::move(key_string))
+ , iv_string(std::make_pair<bool, std::string>(false, std::string()))
+ , input_block_strings(std::move(input_block_strings))
+ { }
+
+ const std::string& get_key_string() const { return key_string; }
+
+ const std::string& get_iv_string() const
+ {
+ if (!iv_string.first)
+ throw_iv_required();
+ return iv_string.second;
+ }
+
+ const std::vector<std::string>& get_input_block_strings() const
+ {
+ return input_block_strings;
+ }
+
+ private:
+ const std::string key_string;
+ const std::pair<bool, std::string> iv_string;
+ const std::vector<std::string> input_block_strings;
+ };
+
+ class Settings
+ {
+ public:
+ aesni::Algorithm get_algorithm() const { return algorithm; }
+ aesni::Mode get_mode() const { return mode; }
+
+ bool use_boxes() const { return use_boxes_flag; }
+ bool verbose() const { return verbose_flag; }
+
+ private:
+ aesni::Algorithm algorithm;
+ aesni::Mode mode;
+
+ bool use_boxes_flag = false;
+ bool verbose_flag = false;
+
+ friend class CommandLineParser;
+ };
+
class CommandLineParser
{
public:
CommandLineParser(const std::string& argv0)
: prog_name(boost::filesystem::path(argv0).filename().string())
, options("Options")
+ { }
+
+ void parse(Settings& settings, int argc, char** argv, std::vector<Input>& inputs)
{
namespace po = boost::program_options;
options.add_options()
("help,h", "show this message and exit")
- ("box,b", po::bool_switch(&use_boxes)->default_value(false), "use the \"boxes\" interface")
- ("mode,m", po::value<aesni::Mode>(&mode)->required(), "set mode of operation")
- ("algorithm,a", po::value<aesni::Algorithm>(&algorithm)->required(), "set algorithm")
- ("verbose,v", po::bool_switch(&verbose)->default_value(false), "enable verbose output");
- }
+ ("box,b", po::bool_switch(&settings.use_boxes_flag)->default_value(false), "use the \"boxes\" interface")
+ ("mode,m", po::value<aesni::Mode>(&settings.mode)->required(), "set mode of operation")
+ ("algorithm,a", po::value<aesni::Algorithm>(&settings.algorithm)->required(), "set algorithm")
+ ("verbose,v", po::bool_switch(&settings.verbose_flag)->default_value(false), "enable verbose output");
- void parse(int argc, char** argv)
- {
- namespace po = boost::program_options;
+ std::vector<std::string> args;
po::options_description hidden_options;
hidden_options.add_options()
@@ -84,17 +148,66 @@ namespace
}
po::notify(vm);
+
+ parse_inputs(settings, inputs, std::deque<std::string>(
+ std::make_move_iterator(args.begin()),
+ std::make_move_iterator(args.end())
+ ));
}
- bool requested_help() const { return help_flag; }
-
- aesni::Mode mode;
- aesni::Algorithm algorithm;
- bool use_boxes;
- std::vector<std::string> args;
- bool verbose;
+ bool exit_with_usage() const { return help_flag; }
private:
+ static void parse_inputs(
+ const Settings& settings,
+ std::vector<Input>& inputs,
+ std::deque<std::string>&& args)
+ {
+ while (!args.empty())
+ {
+ auto key_string = std::move(args.front());
+ args.pop_front();
+
+ std::string iv_string;
+
+ if (aesni::mode_requires_initialization_vector(settings.get_mode()))
+ {
+ if (args.empty())
+ throw_iv_required();
+ iv_string = std::move(args.front());
+ args.pop_front();
+ }
+
+ std::vector<std::string> input_block_strings;
+
+ while (!args.empty())
+ {
+ if (args.front() == "--")
+ {
+ args.pop_front();
+ break;
+ }
+
+ input_block_strings.emplace_back(std::move(args.front()));
+ args.pop_front();
+ }
+
+ if (aesni::mode_requires_initialization_vector(settings.get_mode()))
+ {
+ inputs.emplace_back(
+ std::move(key_string),
+ std::move(iv_string),
+ std::move(input_block_strings));
+ }
+ else
+ {
+ inputs.emplace_back(
+ std::move(key_string),
+ std::move(input_block_strings));
+ }
+ }
+ }
+
const std::string prog_name;
boost::program_options::options_description options;