78 lines
2.0 KiB
C++
78 lines
2.0 KiB
C++
#include "utils.hpp"
|
|
#include <libscerror.hpp>
|
|
#include <cmath>
|
|
#include <iostream>
|
|
#include <iomanip>
|
|
#include <string>
|
|
#include <stdexcept>
|
|
#include "iomanip.hpp"
|
|
|
|
using namespace sc;
|
|
|
|
term::term(int fd) {
|
|
if (isatty(fd)) {
|
|
throw_if_min1(ioctl(fd, TIOCGWINSZ, &_ws));
|
|
}
|
|
switch (fd) {
|
|
case STDOUT_FILENO: _out = &std::cout; break;
|
|
case STDERR_FILENO: _out = &std::cerr; break;
|
|
default: break;
|
|
}
|
|
}
|
|
|
|
int term::rows() const {
|
|
return _ws.ws_row;
|
|
}
|
|
|
|
int term::cols() const {
|
|
return _ws.ws_col;
|
|
}
|
|
|
|
void term::progress(int prefixlen,
|
|
const std::string& prefix,
|
|
double cur,
|
|
double total) const
|
|
{
|
|
// use unicode to make nice bar
|
|
const char* bar[8] = {
|
|
u8"\u258F", u8"\u258E", u8"\u258D", u8"\u258C",
|
|
u8"\u258B", u8"\u258A", u8"\u2589", u8"\u2588"
|
|
};
|
|
if (cur > total) cur = total;
|
|
int perclen = 5;
|
|
int barwidth = cols() - perclen - prefixlen - 1;
|
|
int maxsteps = barwidth * 8;
|
|
int steps = round(cur * maxsteps / total);
|
|
int perc = round(100 * cur / total);
|
|
int fill_len = barwidth - steps / 8;
|
|
*_out << '\r' << std::setw(prefixlen) << prefix.substr(0, prefixlen) << ' ' << io::grayf(8);
|
|
for (int i = 0; i < steps / 8; ++i) {
|
|
*_out << bar[7];
|
|
}
|
|
if (steps % 8) {
|
|
*_out << bar[steps % 8 - 1];
|
|
fill_len--;
|
|
}
|
|
*_out << io::reset << std::string(fill_len, ' ');
|
|
*_out << ' ' << std::setw(3) << perc << '%';
|
|
}
|
|
|
|
// ------------------------------------------------------------------------
|
|
|
|
cursor_hider::cursor_hider(std::ostream* out) : _out {out} {
|
|
*_out << io::hide_cursor;
|
|
}
|
|
|
|
cursor_hider::~cursor_hider() {
|
|
*_out << io::show_cursor;
|
|
}
|
|
|
|
// ------------------------------------------------------------------------
|
|
|
|
sc::io::clear_line::clear_line(const term& t) : _term {t} {}
|
|
|
|
std::ostream& sc::io::operator<<(std::ostream& out, const sc::io::clear_line& obj) {
|
|
out << '\r' << std::string(obj._term.cols(), ' ') << '\r';
|
|
return out;
|
|
}
|