67 lines
1.7 KiB
C++
67 lines
1.7 KiB
C++
#include <string>
|
|
#include <array>
|
|
#include <stdint.h>
|
|
#include "toolbox.hpp"
|
|
|
|
static constexpr const size_t STRING_BUFFER_SIZE = 64;
|
|
static constexpr const std::array<const char[3], 7> 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<int8_t>(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
|