Wire Sysio Wire Sysion 1.0.0
Loading...
Searching...
No Matches
compress_cmd.cpp
Go to the documentation of this file.
3
4#include <iostream>
5
6#include <boost/program_options.hpp>
7#include <boost/filesystem.hpp>
9
10using namespace sysio::trace_api;
11namespace bpo = boost::program_options;
12namespace bfs = boost::filesystem;
13
14namespace {
15 std::string validate_input_path(const bpo::variables_map& vmap) {
16 if (vmap.count("input-path") == 0) {
17 throw bpo::required_option("input-path");
18 }
19
20 auto input_path = vmap.at("input-path").as<std::string>();
21
22 if (!bfs::exists(input_path)) {
23 throw std::logic_error(input_path + " does not exist or cannot be read");
24 }
25
26 if (bfs::is_directory(input_path)) {
27 throw std::logic_error(input_path + " is a directory and not a trace file");
28 }
29
30 return input_path;
31 }
32
33 std::string validate_output_path(const bpo::variables_map& vmap, const std::string& input_path) {
34 static const std::string default_output_extension = ".clog";
35 std::string output_path;
36 if (vmap.count("output-path")) {
37 output_path = vmap.at("output-path").as<std::string>();
38
39 if (bfs::exists(output_path) && bfs::is_directory(output_path)) {
40 output_path = (bfs::path(output_path) / bfs::path(input_path).filename()).replace_extension(
41 default_output_extension).generic_string();
42 } else {
43 auto output_dir = bfs::path(output_path).parent_path();
44 if (!output_dir.empty() && !bfs::exists(output_dir)) {
45 throw std::logic_error(
46 std::string("Output file parent directory: " + output_dir.generic_string() + " does not exist"));
47 }
48 }
49 } else {
50 auto input = bfs::path(input_path);
51 if (input.extension() != ".log") {
52 throw std::logic_error(std::string("Unrecognized extension: ") + input.extension().generic_string());
53 }
54
55 output_path = input.replace_extension(default_output_extension).generic_string();
56 }
57
58 return output_path;
59 }
60
61 void print_help_text(std::ostream& os, const bpo::options_description& opts) {
62 os <<
63 "Usage: trace_api_util compress <options> input-path [output-path]\n"
64 "\n"
65 "Compress a trace file to into the \"clog\" format. By default the name of the\n"
66 "of the compressed file will the the same as the input-path with a changing the\n"
67 "extension to \"clog\"."
68 "\n\n"
69 "Positional Options:\n"
70 " input-path path to the file to compress\n"
71 " output-path [Optional] output file or directory path.\n"
72 "\n";
73 os << opts << "\n";
74 }
75
76 int do_compress(const bpo::variables_map& global_args, const std::vector<std::string>& args) {
77 bpo::options_description vis_desc("Options");
78 auto opts = vis_desc.add_options();
79 opts("help,h", "show usage help message");
80 opts("seek-point-stride,s", bpo::value<uint32_t>()->default_value(512),
81 "the number of bytes between seek points in a compressed trace. "
82 "A smaller stride may degrade compression efficiency but increase read efficiency");
83
84 if (global_args.count("help")) {
85 print_help_text(std::cout, vis_desc);
86 return 0;
87 }
88
89 bpo::options_description hidden_desc("hidden");
90 auto hidden_opts = hidden_desc.add_options();
91 hidden_opts("input-path,i", bpo::value<std::string>(), "input path");
92 hidden_opts("output-path,o", bpo::value<std::string>(), "output path");
93
94 bpo::positional_options_description pos_desc;
95 pos_desc.add("input-path", 1);
96 pos_desc.add("output-path", 1);
97
98 bpo::options_description cmdline_options;
99 cmdline_options.add(vis_desc).add(hidden_desc);
100
101 bpo::variables_map vmap;
102 try {
103 bpo::store(bpo::command_line_parser(args).options(cmdline_options).positional(pos_desc).run(), vmap);
104 bpo::notify(vmap);
105 if (global_args.count("help") == 0) {
106 auto input_path = validate_input_path(vmap);
107 auto output_path = validate_output_path(vmap, input_path);
108 auto seek_point_stride = vmap.at("seek-point-stride").as<uint32_t>();
109
110 if (!compressed_file::process(input_path, output_path, seek_point_stride)) {
111 throw std::runtime_error("Unexpected compression failure");
112 }
113 } else {
114 print_help_text(std::cout, vis_desc);
115 }
116
117 return 0;
118 } catch (const bpo::error& e) {
119 std::cerr << "Error: " << e.what() << "\n\n";
120 print_help_text(std::cerr, vis_desc);
121 } catch ( const std::bad_alloc& ) {
122 throw;
123 } catch ( const boost::interprocess::bad_alloc& ) {
124 throw;
125 } catch (const fc::exception& e) {
126 std::cerr << "Error: " << e.to_detail_string() << "\n";
127 } catch (const std::exception& e) {
128 std::cerr << "Error: " << e.what() << "\n";
129 } catch (...) {
130 std::cerr << "An Unknown Error Occurred\n";
131 }
132
133 return 1;
134 }
135
136 auto _reg = command_registration("compress", "Compress a trace file to into the \"clog\" format", do_compress);
137}
138
Used to generate a useful error report when an exception is thrown.
Definition exception.hpp:58
std::string to_detail_string(log_level ll=log_level::all) const
static bool process(const fc::path &input_path, const fc::path &output_path, size_t seek_point_stride)
os_t os
Defines exception's used by fc.
bool print_help_text(const fc::exception &e)
unsigned int uint32_t
Definition stdint.h:126