1 /***************************************************************************** 2 3 Example program for vtzero library. 4 5 vtzero-encode-geom - Encode geometry on command line 6 7 This can be used for debugging. Uses internals of vtzero! 8 9 *****************************************************************************/ 10 11 #include "utils.hpp" 12 13 #include <vtzero/geometry.hpp> 14 15 #include <cctype> 16 #include <cstdlib> 17 #include <iostream> 18 #include <stdexcept> 19 #include <string> 20 #include <vector> 21 get_int(const char * arg)22int64_t get_int(const char* arg) { 23 char* endptr = nullptr; 24 const int64_t value = std::strtoll(arg, &endptr, 10); 25 26 if (*endptr == '\0') { 27 return value; 28 } 29 30 throw std::runtime_error{"not a valid number"}; 31 } 32 move_to(const char * arg)33uint32_t move_to(const char* arg) { 34 if (!std::isdigit(arg[0])) { 35 throw std::runtime_error{"need count after M command"}; 36 } 37 38 const auto scount = get_int(arg); 39 if (scount <= 0) { 40 throw std::runtime_error{"count after M command must be 1 or larger"}; 41 } 42 const auto count = static_cast<uint32_t>(scount); 43 std::cout << "MOVE_TO(" << count << ")\t" << vtzero::detail::command_move_to(count) << '\n'; 44 45 return vtzero::detail::command_move_to(count); 46 } 47 line_to(const char * arg)48uint32_t line_to(const char* arg) { 49 if (!std::isdigit(arg[0])) { 50 throw std::runtime_error{"need count after L command"}; 51 } 52 53 const auto scount = get_int(arg); 54 if (scount <= 0) { 55 throw std::runtime_error{"count after L command must be 1 or larger"}; 56 } 57 const auto count = static_cast<uint32_t>(scount); 58 std::cout << "LINE_TO(" << count << ")\t" << vtzero::detail::command_line_to(count) << '\n'; 59 60 return vtzero::detail::command_line_to(count); 61 } 62 close_path(const char * arg)63uint32_t close_path(const char* arg) { 64 if (arg[0] != '\0') { 65 throw std::runtime_error{"extra data after C command"}; 66 } 67 std::cout << "CLOSE_PATH\t" << vtzero::detail::command_close_path() << '\n'; 68 69 return vtzero::detail::command_close_path(); 70 } 71 number(const char * arg)72uint32_t number(const char* arg) { 73 const auto num = static_cast<int32_t>(get_int(arg)); 74 std::cout << "number(" << num << ")\t" << protozero::encode_zigzag32(num) << '\n'; 75 76 return protozero::encode_zigzag32(num); 77 } 78 main(int argc,char * argv[])79int main(int argc, char* argv[]) { 80 if (argc < 2) { 81 std::cerr << "Usage: " << argv[0] << " GEOMETRY ELEMENTS...\n" 82 << "GEOMETRY ELEMENTS are:\n" 83 << " M[count] -- MOVE_TO count\n" 84 << " L[count] -- LINE_TO count\n" 85 << " C -- CLOSE_PATH\n" 86 << " [number] -- number that will be zigzag encoded\n"; 87 return 1; 88 } 89 90 std::vector<uint32_t> values; 91 92 std::cout << "raw data\tencoded\n-----------------------------------\n"; 93 for (int i = 1; i < argc; ++i) { 94 try { 95 switch (argv[i][0]) { 96 case '\0': 97 break; 98 case 'M': 99 values.push_back(move_to(argv[i] + 1)); 100 break; 101 case 'L': 102 values.push_back(line_to(argv[i] + 1)); 103 break; 104 case 'C': 105 values.push_back(close_path(argv[i] + 1)); 106 break; 107 case '-': 108 case '0': 109 case '1': 110 case '2': 111 case '3': 112 case '4': 113 case '5': 114 case '6': 115 case '7': 116 case '8': 117 case '9': 118 values.push_back(number(argv[i])); 119 break; 120 default: 121 throw std::runtime_error{std::string{"unknown data: "} + argv[i]}; 122 return 1; 123 } 124 } catch (const std::runtime_error& e) { 125 std::cerr << "error(" << i << "): " << e.what() << '\n'; 126 return 1; 127 } 128 } 129 130 std::string out{"["}; 131 132 for (auto value : values) { 133 out += ' '; 134 out += std::to_string(value); 135 out += ','; 136 } 137 138 out.back() = ' '; 139 140 std::cout << '\n' << out << "]\n"; 141 } 142 143