#include #include #include #include "toolbox.hpp" static constexpr const size_t STR_BUFFER_SIZE = 64; static constexpr const int8_t N_TIMES = 11; static constexpr const std::array time_formats = { "ns", "us", "ms", "s", "m", "h", "j", "w", "M", "y", "c" }; static constexpr const std::array time_numbers = { 1, 1000, 1000000, u64(1e9), u64(6e10), u64(36e11), u64(864e11), u64(6048e11), u64(26298e11), u64(315576e11), u64(315576e13) }; #define STRING_BUFFER_SIZE 64 /** * @brief Convert a given number of nanoseconds to a human readable format * * @param time Number of nanoseconds * @return Human readable formatted string */ std::string format_time_ns(uint64_t time) noexcept { char s[STRING_BUFFER_SIZE] = {0}; size_t j = 0; if (time == 0){ sprintf(s, "0%s", time_formats[0]); return s; } uint64_t res; for (int8_t i = time_numbers.size() - 1; i >= 0; --i) { if (time >= time_numbers[i]) { res = time / time_numbers[i]; time %= time_numbers[i]; j += ullstr(res, j, s); for(int k = 0; time_formats[i][k] > 0; ++k) s[j++] = time_formats[i][k]; s[j++] = ' '; } } /* Remove trailing character */ s[j - 1] = '\0'; std::string ss(s); return ss; } #ifndef TEST int32_t main(const int32_t argc, const char* const* argv) noexcept { uint64_t n = 0; if (argc > 2) return fprintf(stderr, "Invalid usage : (%s $NUMBER) or (echo $NUMBER | %s)\n", argv[0], argv[0]); else if (argc == 2){ if(sstrtoull(argv[1], n) == EXIT_FAILURE) return EXIT_FAILURE; } else { size_t i = 0; char c, BUFFER[STR_BUFFER_SIZE]; for(; i < STR_BUFFER_SIZE && (c = fgetc(stdin)) != EOF; ++i) BUFFER[i] = c; if(i == STR_BUFFER_SIZE){ fprintf(stderr, "Error while converting to integer : invalid stdin input (too large)\n"); return EXIT_FAILURE; } if(sstrtoull(BUFFER, n) == EXIT_FAILURE) return EXIT_FAILURE; } printf("%s\n", format_time_ns(n).c_str()); return EXIT_SUCCESS; } #endif