#include #include #include #include "toolbox.hpp" static constexpr const size_t STRING_BUFFER_SIZE = 64; static constexpr const std::array format_prefix = { "B", "KB", "MB", "GB", "TB", "PB", "EB" }; /** * @brief Convert a given numbers of bytes to a human readable format * * @param n Number of bytes * @return Human readable format of the numbers of bytes */ std::string format_bytes(uint64_t n) noexcept { char s[STRING_BUFFER_SIZE] = { 0 }; if(n == 0){ sprintf(s, "0%s", format_prefix[0]); return s; } size_t j = 0; for(int8_t i = static_cast(format_prefix.size() - 1) * 10; i >= 0; i -= 10){ const uint64_t nsi = n >> i; if(nsi > 0){ const int8_t idx = i / 10; j += ullstr(nsi, j, s); for(int k = 0; format_prefix[idx][k] > 0; ++k) s[j++] = format_prefix[idx][k]; s[j++] = ' '; n &= u64(-1) >> (64 - i); } } /* Remove trailing character */ s[j - 1] = '\0'; return std::string(s); } #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 BUFFER[STRING_BUFFER_SIZE]; for(int c; i < STRING_BUFFER_SIZE && (c = fgetc(stdin)) != EOF; ++i) BUFFER[i] = c; if(i == STRING_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_bytes(n).c_str()); return EXIT_SUCCESS; } #endif