toolbox/format_time/src/format_time_ns.cpp
2024-11-07 22:23:49 +01:00

74 lines
2.0 KiB
C++

#include <string>
#include <array>
#include <stdint.h>
#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<const char* const, N_TIMES> time_formats = { "ns", "us", "ms", "s", "m", "h", "j", "w", "M", "y", "c" };
static constexpr const std::array<const uint64_t, N_TIMES> 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