summaryrefslogtreecommitdiffstats
path: root/comm/third_party/botan/src/cli/compress.cpp
diff options
context:
space:
mode:
Diffstat (limited to 'comm/third_party/botan/src/cli/compress.cpp')
-rw-r--r--comm/third_party/botan/src/cli/compress.cpp190
1 files changed, 190 insertions, 0 deletions
diff --git a/comm/third_party/botan/src/cli/compress.cpp b/comm/third_party/botan/src/cli/compress.cpp
new file mode 100644
index 0000000000..e62acd7636
--- /dev/null
+++ b/comm/third_party/botan/src/cli/compress.cpp
@@ -0,0 +1,190 @@
+/*
+* (C) 2014,2015 Jack Lloyd
+*
+* Botan is released under the Simplified BSD License (see license.txt)
+*/
+
+#include "cli.h"
+
+#if defined(BOTAN_HAS_COMPRESSION)
+ #include <botan/compression.h>
+ #include <fstream>
+#endif
+
+namespace Botan_CLI {
+
+#if defined(BOTAN_HAS_COMPRESSION)
+
+class Compress final : public Command
+ {
+ public:
+ Compress() : Command("compress --type=gzip --level=6 --buf-size=8192 file") {}
+
+ std::string output_filename(const std::string& input_fsname, const std::string& comp_type)
+ {
+ const std::map<std::string, std::string> suffixes =
+ {
+ { "zlib", "zlib" },
+ { "gzip", "gz" },
+ { "bzip2", "bz2" },
+ { "lzma", "xz" },
+ };
+
+ auto suffix_info = suffixes.find(comp_type);
+ if(suffixes.count(comp_type) == 0)
+ {
+ throw CLI_Error_Unsupported("Compressing", comp_type);
+ }
+
+ return input_fsname + "." + suffix_info->second;
+ }
+
+ std::string group() const override
+ {
+ return "compression";
+ }
+
+ std::string description() const override
+ {
+ return "Compress a given file";
+ }
+
+ void go() override
+ {
+ const std::string comp_type = get_arg("type");
+ const size_t buf_size = get_arg_sz("buf-size");
+ const size_t comp_level = get_arg_sz("level");
+
+ std::unique_ptr<Botan::Compression_Algorithm> compress;
+
+ compress.reset(Botan::make_compressor(comp_type));
+
+ if(!compress)
+ {
+ throw CLI_Error_Unsupported("Compression", comp_type);
+ }
+
+ const std::string in_file = get_arg("file");
+ std::ifstream in(in_file, std::ios::binary);
+
+ if(!in.good())
+ {
+ throw CLI_IO_Error("reading", in_file);
+ }
+
+ const std::string out_file = output_filename(in_file, comp_type);
+ std::ofstream out(out_file, std::ios::binary);
+ if(!out.good())
+ {
+ throw CLI_IO_Error("writing", out_file);
+ }
+
+ Botan::secure_vector<uint8_t> buf;
+
+ compress->start(comp_level);
+
+ while(in.good())
+ {
+ buf.resize(buf_size);
+ in.read(reinterpret_cast<char*>(buf.data()), buf.size());
+ buf.resize(in.gcount());
+
+ compress->update(buf);
+
+ out.write(reinterpret_cast<const char*>(buf.data()), buf.size());
+ }
+
+ buf.clear();
+ compress->finish(buf);
+ out.write(reinterpret_cast<const char*>(buf.data()), buf.size());
+ out.close();
+ }
+ };
+
+BOTAN_REGISTER_COMMAND("compress", Compress);
+
+class Decompress final : public Command
+ {
+ public:
+ Decompress() : Command("decompress --buf-size=8192 file") {}
+
+ void parse_extension(const std::string& in_file,
+ std::string& out_file,
+ std::string& suffix)
+ {
+ auto last_dot = in_file.find_last_of('.');
+ if(last_dot == std::string::npos || last_dot == 0)
+ {
+ throw CLI_Error("No extension detected in filename '" + in_file + "'");
+ }
+
+ out_file = in_file.substr(0, last_dot);
+ suffix = in_file.substr(last_dot + 1, std::string::npos);
+ }
+
+ std::string group() const override
+ {
+ return "compression";
+ }
+
+ std::string description() const override
+ {
+ return "Decompress a given compressed archive";
+ }
+
+ void go() override
+ {
+ const size_t buf_size = get_arg_sz("buf-size");
+ const std::string in_file = get_arg("file");
+ std::string out_file, suffix;
+ parse_extension(in_file, out_file, suffix);
+
+ std::ifstream in(in_file, std::ios::binary);
+
+ if(!in.good())
+ {
+ throw CLI_IO_Error("reading", in_file);
+ }
+
+ std::unique_ptr<Botan::Decompression_Algorithm> decompress;
+
+ decompress.reset(Botan::make_decompressor(suffix));
+
+ if(!decompress)
+ {
+ throw CLI_Error_Unsupported("Decompression", suffix);
+ }
+
+ std::ofstream out(out_file, std::ios::binary);
+ if(!out.good())
+ {
+ throw CLI_IO_Error("writing", out_file);
+ }
+
+ Botan::secure_vector<uint8_t> buf;
+
+ decompress->start();
+
+ while(in.good())
+ {
+ buf.resize(buf_size);
+ in.read(reinterpret_cast<char*>(buf.data()), buf.size());
+ buf.resize(in.gcount());
+
+ decompress->update(buf);
+
+ out.write(reinterpret_cast<const char*>(buf.data()), buf.size());
+ }
+
+ buf.clear();
+ decompress->finish(buf);
+ out.write(reinterpret_cast<const char*>(buf.data()), buf.size());
+ out.close();
+ }
+ };
+
+BOTAN_REGISTER_COMMAND("decompress", Decompress);
+
+#endif
+
+}