/***************************************************************************** Example program for vtzero library. vtzero-encode-geom - Encode geometry on command line This can be used for debugging. Uses internals of vtzero! *****************************************************************************/ #include "utils.hpp" #include #include #include #include #include #include #include int64_t get_int(const char* arg) { char* endptr = nullptr; const int64_t value = std::strtoll(arg, &endptr, 10); if (*endptr == '\0') { return value; } throw std::runtime_error{"not a valid number"}; } uint32_t move_to(const char* arg) { if (!std::isdigit(arg[0])) { throw std::runtime_error{"need count after M command"}; } const auto scount = get_int(arg); if (scount <= 0) { throw std::runtime_error{"count after M command must be 1 or larger"}; } const auto count = static_cast(scount); std::cout << "MOVE_TO(" << count << ")\t" << vtzero::detail::command_move_to(count) << '\n'; return vtzero::detail::command_move_to(count); } uint32_t line_to(const char* arg) { if (!std::isdigit(arg[0])) { throw std::runtime_error{"need count after L command"}; } const auto scount = get_int(arg); if (scount <= 0) { throw std::runtime_error{"count after L command must be 1 or larger"}; } const auto count = static_cast(scount); std::cout << "LINE_TO(" << count << ")\t" << vtzero::detail::command_line_to(count) << '\n'; return vtzero::detail::command_line_to(count); } uint32_t close_path(const char* arg) { if (arg[0] != '\0') { throw std::runtime_error{"extra data after C command"}; } std::cout << "CLOSE_PATH\t" << vtzero::detail::command_close_path() << '\n'; return vtzero::detail::command_close_path(); } uint32_t number(const char* arg) { const auto num = static_cast(get_int(arg)); std::cout << "number(" << num << ")\t" << protozero::encode_zigzag32(num) << '\n'; return protozero::encode_zigzag32(num); } int main(int argc, char* argv[]) { if (argc < 2) { std::cerr << "Usage: " << argv[0] << " GEOMETRY ELEMENTS...\n" << "GEOMETRY ELEMENTS are:\n" << " M[count] -- MOVE_TO count\n" << " L[count] -- LINE_TO count\n" << " C -- CLOSE_PATH\n" << " [number] -- number that will be zigzag encoded\n"; return 1; } std::vector values; std::cout << "raw data\tencoded\n-----------------------------------\n"; for (int i = 1; i < argc; ++i) { try { switch (argv[i][0]) { case '\0': break; case 'M': values.push_back(move_to(argv[i] + 1)); break; case 'L': values.push_back(line_to(argv[i] + 1)); break; case 'C': values.push_back(close_path(argv[i] + 1)); break; case '-': case '0': case '1': case '2': case '3': case '4': case '5': case '6': case '7': case '8': case '9': values.push_back(number(argv[i])); break; default: throw std::runtime_error{std::string{"unknown data: "} + argv[i]}; return 1; } } catch (const std::runtime_error& e) { std::cerr << "error(" << i << "): " << e.what() << '\n'; return 1; } } std::string out{"["}; for (auto value : values) { out += ' '; out += std::to_string(value); out += ','; } out.back() = ' '; std::cout << '\n' << out << "]\n"; }