From a593e0cc33ce3e5108b8d1fd6aaf9fcdede5fefd Mon Sep 17 00:00:00 2001 From: Your Name Date: Wed, 19 Jan 2022 13:23:52 +0100 Subject: [PATCH] Fixed bugs in progress bar. Added size conversion to human readable. --- include/Display.hpp | 5 +++++ src/Display.cpp | 44 ++++++++++++++++++++++++++++++++++++++++++++ src/main.cpp | 26 ++++++++++++++++++++++++++ 3 files changed, 75 insertions(+) diff --git a/include/Display.hpp b/include/Display.hpp index c9a50b8..abb0270 100644 --- a/include/Display.hpp +++ b/include/Display.hpp @@ -29,4 +29,9 @@ class Display /// Creates a progress bar std::string GenerateProgressBar(unsigned int width, unsigned int current, unsigned int total, bool showPercentage = true, std::string const& fillChar = "\u25A0"); +/// Converts a size in bytes to a human readable size (To, Go, Mo, ko, o). +/// If SI_units is false, the size will be displayed using powers of 1024 instead of 1000, producing Mio, kio etc. +/// The suffix can be specified. Default is 'o' for 'octet'. Use 'b' for bits or 'B' for bytes. +std::string Bytes2HumanReadable(uint64_t size, bool SI_units = true, const char* suffix = "o"); + #endif diff --git a/src/Display.cpp b/src/Display.cpp index 5487379..6d3f306 100644 --- a/src/Display.cpp +++ b/src/Display.cpp @@ -27,6 +27,12 @@ std::string GenerateProgressBar(unsigned int width, unsigned int current, unsign unsigned int freeWidth = width-2; char buf[8]; + if(current > total) // Protect against > 100 % + current = total; + + if(total == 0) // Protect against divisions by 0 + total = 1; + progressBar = '['; if(showPercentage) @@ -48,3 +54,41 @@ std::string GenerateProgressBar(unsigned int width, unsigned int current, unsign return progressBar; } + +std::string Bytes2HumanReadable(uint64_t size, bool SI_units, const char* suffix) +{ + const uint64_t kilo = (SI_units) ? 1000ULL : 1024ULL; + const uint64_t mega = kilo*kilo; + const uint64_t giga = mega*kilo; + const uint64_t tera = giga*kilo; + const uint64_t peta = tera*kilo; + const uint64_t exa = peta*kilo; + //const uint64_t zetta = exa*kilo; + //const uint64_t yotta = zetta*kilo; + + char buf[16]; + std::string fullSuffix = (SI_units) ? std::string(suffix) : (std::string("i") + suffix); + + //if(size >= yotta) + // sprintf(buf, "%5.1f Y%s", (double)size/yotta, fullSuffix.c_str()); + //else if(size >= zetta) + // sprintf(buf, "%5.1f Z%s", (double)size/zetta, fullSuffix.c_str()); + + if(size >= exa) + sprintf(buf, "%5.1f E%s", (double)size/exa, fullSuffix.c_str()); + else if(size >= peta) + sprintf(buf, "%5.1f P%s", (double)size/peta, fullSuffix.c_str()); + else if(size >= tera) + sprintf(buf, "%5.1f T%s", (double)size/tera, fullSuffix.c_str()); + else if(size >= giga) + sprintf(buf, "%5.1f G%s", (double)size/giga, fullSuffix.c_str()); + else if(size >= mega) + sprintf(buf, "%5.1f M%s", (double)size/mega, fullSuffix.c_str()); + else if(size >= kilo) + sprintf(buf, "%5.1f k%s", (double)size/kilo, fullSuffix.c_str()); + else + sprintf(buf, "%5.1f %s", (double)size, suffix); + + return std::string(buf); +} + diff --git a/src/main.cpp b/src/main.cpp index 37d05c6..d05d476 100644 --- a/src/main.cpp +++ b/src/main.cpp @@ -86,9 +86,35 @@ int main(int argc, char *argv[]) PRINT_VAR(GenerateProgressBar(20, 100, 100, true)); PRINT_VAR(GenerateProgressBar(50, 666, 1000, true)); PRINT_VAR(GenerateProgressBar(50, 1666, 1000, true)); + PRINT_VAR(GenerateProgressBar(50, 42, 0, true)); + PRINT_VAR(GenerateProgressBar(50, 0, 0, true)); PRINT_VAR(GenerateProgressBar(50, 333, 1000, true, "#")); } + //if(0) + {// test output + PRINT_VAR(Bytes2HumanReadable(123ULL, true)); + PRINT_VAR(Bytes2HumanReadable(1234ULL, true)); + PRINT_VAR(Bytes2HumanReadable(1234567ULL, true)); + PRINT_VAR(Bytes2HumanReadable(1234567890ULL, true)); + PRINT_VAR(Bytes2HumanReadable(1234567890123ULL, true)); + PRINT_VAR(Bytes2HumanReadable(1234567890123456ULL, true)); + PRINT_VAR(Bytes2HumanReadable(1234567890123456789ULL, true)); + cout << "\n"; + PRINT_VAR(Bytes2HumanReadable(123ULL, false)); + PRINT_VAR(Bytes2HumanReadable(1234ULL, false)); + PRINT_VAR(Bytes2HumanReadable(1234567ULL, false)); + PRINT_VAR(Bytes2HumanReadable(1234567890ULL, false)); + PRINT_VAR(Bytes2HumanReadable(1234567890123ULL, false)); + PRINT_VAR(Bytes2HumanReadable(1234567890123456ULL, false)); + PRINT_VAR(Bytes2HumanReadable(1234567890123456789ULL, false)); + cout << "\n"; + PRINT_VAR(Bytes2HumanReadable(1073741824ULL, true)); + PRINT_VAR(Bytes2HumanReadable(1073741824ULL, false)); + PRINT_VAR(Bytes2HumanReadable(1000000000ULL, true)); + PRINT_VAR(Bytes2HumanReadable(1000000000ULL, false)); + + } } else cerr << "Error : No path given !\n";