xrock/progress.c

75 lines
1.6 KiB
C
Raw Permalink Normal View History

2021-08-02 17:29:22 +08:00
#include <progress.h>
2021-08-05 02:54:51 +08:00
static double gettime(void)
2021-08-02 17:29:22 +08:00
{
struct timeval tv;
gettimeofday(&tv, NULL);
return tv.tv_sec + (double)tv.tv_usec / 1000000.0;
}
2021-08-05 02:54:51 +08:00
static const char * format_eta(double remaining)
2021-08-02 17:29:22 +08:00
{
static char result[6] = "";
int seconds = remaining + 0.5;
if(seconds >= 0 && seconds < 6000)
{
snprintf(result, sizeof(result), "%02d:%02d", seconds / 60, seconds % 60);
return result;
}
return "--:--";
}
static char * ssize(char * buf, double size)
{
const char * unit[] = {"B", "KB", "MB", "GB", "TB", "PB", "EB", "ZB", "YB"};
int count = 0;
2021-08-06 12:29:48 +08:00
while((size > 1024) && (count < 8))
{
2021-08-06 12:29:48 +08:00
size /= 1024;
count++;
}
sprintf(buf, "%5.3f %s", size, unit[count]);
return buf;
}
2021-08-06 11:17:36 +08:00
void progress_start(struct progress_t * p, uint64_t total)
2021-08-02 17:29:22 +08:00
{
if(p && (total > 0))
{
p->total = total;
p->done = 0;
p->start = gettime();
}
}
2021-08-06 11:17:36 +08:00
void progress_update(struct progress_t * p, uint64_t bytes)
2021-08-02 17:29:22 +08:00
{
char buf1[32], buf2[32];
2021-08-02 17:29:22 +08:00
if(p)
{
p->done += bytes;
double ratio = p->total > 0 ? (double)p->done / (double)p->total : 0.0;
double speed = (double)p->done / (gettime() - p->start);
double eta = speed > 0 ? (p->total - p->done) / speed : 0;
int i, pos = 48 * ratio;
printf("\r%3.0f%% [", ratio * 100);
for(i = 0; i < pos; i++)
putchar('=');
for(i = pos; i < 48; i++)
putchar(' ');
if(p->done < p->total)
2021-10-28 10:29:40 +08:00
printf("] %s/s, ETA %s \r", ssize(buf1, speed), format_eta(eta));
2021-08-02 17:29:22 +08:00
else
2021-10-28 10:29:40 +08:00
printf("] %s, %s/s \r", ssize(buf1, p->done), ssize(buf2, speed));
2021-08-02 17:29:22 +08:00
fflush(stdout);
}
}
void progress_stop(struct progress_t * p)
{
if(p)
printf("\r\n");
}