implement parsing args in blocky CLI tool
This commit is contained in:
parent
d58e4e7168
commit
6ffde38590
@ -2,6 +2,8 @@ cmake_minimum_required(VERSION 3.18)
|
||||
|
||||
project(blocky C CXX)
|
||||
|
||||
option(BLOCKY_STATIC OFF)
|
||||
|
||||
set(CMAKE_CXX_STANDARD 20)
|
||||
set(CMAKE_CXX_STANDARD_REQUIRED ON)
|
||||
|
||||
|
@ -4,8 +4,12 @@ target_compile_options(blocky PRIVATE ${BLOCKY_C_FLAGS})
|
||||
target_sources(blocky
|
||||
PUBLIC
|
||||
main.cc
|
||||
|
||||
bytes.hh
|
||||
common.hh
|
||||
)
|
||||
target_link_libraries(blocky
|
||||
PUBLIC
|
||||
args
|
||||
liblocky
|
||||
)
|
||||
|
26
blocky/bytes.hh
Normal file
26
blocky/bytes.hh
Normal file
@ -0,0 +1,26 @@
|
||||
#pragma once
|
||||
|
||||
#include <cstdint>
|
||||
#include <tuple>
|
||||
#include <vector>
|
||||
|
||||
#include "common.hh"
|
||||
|
||||
|
||||
namespace blky {
|
||||
|
||||
std::vector<Feature> BytesEncoder(
|
||||
const std::vector<uint8_t>& bytes,
|
||||
std::tuple<uint32_t, uint32_t>& feats_num,
|
||||
uint8_t feat_bits,
|
||||
uint32_t first,
|
||||
uint64_t seed) {
|
||||
(void) bytes;
|
||||
(void) feats_num;
|
||||
(void) feat_bits;
|
||||
(void) first;
|
||||
(void) seed;
|
||||
return {};
|
||||
}
|
||||
|
||||
} // namespace blky
|
56
blocky/common.hh
Normal file
56
blocky/common.hh
Normal file
@ -0,0 +1,56 @@
|
||||
#pragma once
|
||||
|
||||
extern "C" {
|
||||
# include <liblocky.h>
|
||||
}
|
||||
|
||||
#include <cstdint>
|
||||
#include <iostream>
|
||||
#include <tuple>
|
||||
#include <unordered_map>
|
||||
#include <vector>
|
||||
|
||||
|
||||
namespace blky {
|
||||
|
||||
enum DataFlow {
|
||||
kBytes,
|
||||
kFeatures,
|
||||
kVideo,
|
||||
};
|
||||
|
||||
static inline const std::string kDataFlowList = "bytes/features/video";
|
||||
static inline const std::unordered_map<std::string, DataFlow> kDataFlowMap = {
|
||||
{"bytes", kBytes},
|
||||
{"features", kFeatures},
|
||||
{"video", kVideo},
|
||||
};
|
||||
|
||||
|
||||
struct Feature final {
|
||||
uint64_t index;
|
||||
uint64_t begin;
|
||||
uint64_t end;
|
||||
};
|
||||
|
||||
|
||||
auto& operator<<(auto& ost, const Feature& feat) {
|
||||
ost << feat.index << " " << feat.begin << " " << feat.end;
|
||||
return ost;
|
||||
}
|
||||
auto& operator>>(auto& ist, Feature& feat) {
|
||||
ist >> feat.index >> feat.begin >> feat.end;
|
||||
return ist;
|
||||
}
|
||||
|
||||
} // namespace blky
|
||||
|
||||
|
||||
namespace args {
|
||||
|
||||
auto& operator>>(auto& ist, std::tuple<uint32_t, uint32_t>& v) {
|
||||
ist >> std::get<0>(v) >> std::get<1>(v);
|
||||
return ist;
|
||||
}
|
||||
|
||||
} // namespace args
|
178
blocky/main.cc
178
blocky/main.cc
@ -1,8 +1,180 @@
|
||||
#include <cassert>
|
||||
#include <exception>
|
||||
#include <iostream>
|
||||
#include <tuple>
|
||||
|
||||
#include "common.hh"
|
||||
#include "bytes.hh"
|
||||
|
||||
#include <args.hxx>
|
||||
|
||||
|
||||
using namespace blky;
|
||||
|
||||
int main(int argc, char** argv) {
|
||||
(void) argc;
|
||||
(void) argv;
|
||||
std::cout << "helloworld" << std::endl;
|
||||
args::ArgumentParser parser(
|
||||
"liblocky command line tool",
|
||||
"liblocky allow you to embed bits into video data secretly");
|
||||
|
||||
args::MapFlag<std::string, DataFlow> from {
|
||||
parser, kDataFlowList, "input layer specifier", {"from"}, kDataFlowMap, args::Options::Required};
|
||||
|
||||
args::MapFlag<std::string, DataFlow> to {
|
||||
parser, kDataFlowList, "output layer specifier", {"to"}, kDataFlowMap, args::Options::Required};
|
||||
|
||||
args::Group src_group {
|
||||
parser, "source specifier", args::Group::Validators::Xor, args::Options::Required};
|
||||
args::Flag src_stdin {src_group, "src-stdin", "read from stdin", {"src-stdin", "stdin"}};
|
||||
|
||||
args::Group dst_group {
|
||||
parser, "destination specifier", args::Group::Validators::Xor, args::Options::Required};
|
||||
args::Flag dst_stdout {dst_group, "dst-stdout", "write to stdout", {"dst-stdout", "stdout"}};
|
||||
|
||||
args::Group param_group {
|
||||
parser, "processing parameters", args::Group::Validators::DontCare
|
||||
};
|
||||
args::ValueFlag<std::tuple<uint32_t, uint32_t>> param_feat_num {
|
||||
param_group,
|
||||
"int>0,int>0",
|
||||
"number of features",
|
||||
{"feature-num"},
|
||||
{16, 16}
|
||||
};
|
||||
args::ValueFlag<uint8_t> param_feat_bits {
|
||||
param_group,
|
||||
"int>0",
|
||||
"number of bits that can be represented by a single feature",
|
||||
{"feature-bits"},
|
||||
1
|
||||
};
|
||||
args::ValueFlag<uint32_t> param_feat_first {
|
||||
param_group,
|
||||
"int>=0",
|
||||
"an index of first feature. used when encoding",
|
||||
{"feature-first-index"},
|
||||
0
|
||||
};
|
||||
args::ValueFlag<uint64_t> param_feat_seed {
|
||||
param_group,
|
||||
"int>0",
|
||||
"seed value for feature hopping",
|
||||
{"feature-hopping-seed"},
|
||||
1
|
||||
};
|
||||
|
||||
try {
|
||||
parser.ParseCLI(argc, argv);
|
||||
|
||||
std::vector<uint8_t> bytes;
|
||||
std::vector<Feature> features;
|
||||
|
||||
// read input
|
||||
switch (args::get(from)) {
|
||||
case kBytes:
|
||||
if (src_stdin) {
|
||||
std::string temp;
|
||||
std::cin >> temp;
|
||||
bytes = {temp.begin(), temp.end()};
|
||||
} else {
|
||||
throw std::runtime_error {"invalid source format for bytes"};
|
||||
}
|
||||
break;
|
||||
|
||||
case kFeatures:
|
||||
if (src_stdin) {
|
||||
while (!std::cin.eof()) {
|
||||
features.push_back({});
|
||||
std::cin >> features.back();
|
||||
}
|
||||
} else {
|
||||
throw std::runtime_error {"invalid source format for bytes"};
|
||||
}
|
||||
break;
|
||||
|
||||
case kVideo:
|
||||
assert(false);
|
||||
}
|
||||
|
||||
if (args::get(from) < args::get(to)) {
|
||||
// execute encoding
|
||||
switch (args::get(from)) {
|
||||
case kBytes:
|
||||
if (args::get(to) == kBytes) break;
|
||||
features = BytesEncoder(
|
||||
bytes,
|
||||
args::get(param_feat_num),
|
||||
args::get(param_feat_bits),
|
||||
args::get(param_feat_first),
|
||||
args::get(param_feat_seed));
|
||||
/* fallthrough */
|
||||
|
||||
case kFeatures:
|
||||
if (args::get(to) == kFeatures) break;
|
||||
// TODO embed into video
|
||||
assert(false);
|
||||
|
||||
case kVideo:
|
||||
if (args::get(to) == kVideo) break;
|
||||
assert(false);
|
||||
}
|
||||
|
||||
} else if (args::get(from) > args::get(to)) {
|
||||
// execute decoding
|
||||
switch (args::get(from)) {
|
||||
case kVideo:
|
||||
if (args::get(to) == kVideo) break;
|
||||
// TODO extract features // features = XX
|
||||
assert(false);
|
||||
|
||||
case kFeatures:
|
||||
if (args::get(to) == kFeatures) break;
|
||||
// TODO bytes = DataDecoder(features);
|
||||
assert(false);
|
||||
/* fallthrough */
|
||||
|
||||
case kBytes:
|
||||
if (args::get(to) == kBytes) break;
|
||||
assert(false);
|
||||
}
|
||||
}
|
||||
|
||||
// output
|
||||
switch (args::get(to)) {
|
||||
case kBytes:
|
||||
if (dst_stdout) {
|
||||
std::cout << std::string {bytes.begin(), bytes.end()} << std::endl;
|
||||
} else {
|
||||
throw std::runtime_error {"invalid destination format for bytes"};
|
||||
}
|
||||
break;
|
||||
case kFeatures:
|
||||
if (dst_stdout) {
|
||||
for (auto& f : features) std::cout << f << "\n";
|
||||
} else {
|
||||
throw std::runtime_error {"invalid destination format for features"};
|
||||
}
|
||||
break;
|
||||
case kVideo:
|
||||
break;
|
||||
}
|
||||
|
||||
} catch (const args::Help&) {
|
||||
std::cout << parser << std::endl;
|
||||
return 0;
|
||||
|
||||
} catch (const args::ParseError& e) {
|
||||
std::cerr << e.what() << std::endl;
|
||||
std::cerr << parser << std::endl;
|
||||
return 1;
|
||||
|
||||
} catch (const args::ValidationError& e) {
|
||||
std::cerr << e.what() << std::endl;
|
||||
std::cerr << parser << std::endl;
|
||||
return 1;
|
||||
|
||||
} catch (const std::runtime_error& e) {
|
||||
std::cerr << "runtime error: " << e.what() << std::endl;
|
||||
return 1;
|
||||
}
|
||||
return 0;
|
||||
}
|
||||
|
16
thirdparty/CMakeLists.txt
vendored
16
thirdparty/CMakeLists.txt
vendored
@ -1,6 +1,20 @@
|
||||
include(FetchContent)
|
||||
|
||||
|
||||
# ---- args ----
|
||||
# repository: https://github.com/Taywee/args
|
||||
# license : MIT
|
||||
|
||||
FetchContent_Declare(
|
||||
args
|
||||
URL "https://github.com/Taywee/args/archive/refs/tags/6.3.0.zip"
|
||||
)
|
||||
|
||||
set(ARGS_BUILD_EXAMPLE OFF)
|
||||
set(ARGS_BUILD_UNITTESTS OFF)
|
||||
FetchContent_MakeAvailable(args)
|
||||
|
||||
|
||||
# ---- GLEW ----
|
||||
# repository: https://github.com/Perlmint/glew-cmake
|
||||
# license : Modified BSD License, the Mesa 3-D License (MIT) and the Khronos License (MIT).
|
||||
@ -11,7 +25,7 @@ FetchContent_Declare(
|
||||
)
|
||||
FetchContent_MakeAvailable(glew)
|
||||
|
||||
if (KINGTAKER_STATIC)
|
||||
if (BLOCKY_STATIC)
|
||||
add_library(glew ALIAS libglew_static)
|
||||
else()
|
||||
add_library(glew ALIAS libglew_shared)
|
||||
|
Loading…
x
Reference in New Issue
Block a user