#include "progressbar.h" #include #include "file.h" const uint_fast8_t ProgressBar::BARLENGTH = 50; ProgressBar::ProgressBar(uint64_t files, uint64_t bytes) : maxFiles(files), maxBytes(bytes) { } void ProgressBar::update(uint64_t addFiles, uint64_t newBytes) { currentFiles += addFiles; currentBytes += newBytes; } std::chrono::duration ProgressBar::getDuration() const { auto currenttime = std::chrono::high_resolution_clock::now(); return std::chrono::duration_cast(currenttime - start); } std::ostream& operator<<(std::ostream& str, const ProgressBar& pb) { double progress = (pb.currentBytes / (double) pb.maxBytes); // not the optimal way, but the easyiest static double lastProgress = 0; if(progress - lastProgress < 0.0001) return str; lastProgress = progress; auto usedtime = pb.getDuration(); std::chrono::duration> eta = std::chrono::duration_cast((usedtime / (double) pb.currentBytes) * (pb.maxBytes - pb.currentBytes) ); // speed uint64_t usedtimes = std::chrono::duration_cast(usedtime).count(); uint64_t speed = (usedtimes != 0) ? (pb.currentBytes / usedtimes) : 0; // B/s // generate bar str << "\r["; for(uint_fast8_t i = 0; i < ProgressBar::BARLENGTH; ++i) { if( (i / (double) ProgressBar::BARLENGTH) < progress ) { str << '#'; } else { str << ' '; } } // print info str << "] " << std::setprecision(2) << std::setfill('0') << std::fixed << std::setw(5) << (progress * 100) << "% " << std::setprecision(6) << std::defaultfloat << FileSize(pb.currentBytes) << '/' << FileSize(pb.maxBytes) << " " << pb.currentFiles << '/' << pb.maxFiles << " Files " << FileSize(speed) << "/s ETA: " << eta.count() << "min " << std::flush; return str; }