diff --git a/lib/progress.c b/lib/progress.c index fdae3194c5..2fa0fa1228 100644 --- a/lib/progress.c +++ b/lib/progress.c @@ -63,54 +63,37 @@ static void time2str(char *r, curl_off_t seconds) } /* The point of this function would be to return a string of the input data, - but never longer than 5 columns (+ one zero byte). + but never longer than 6 columns (+ one zero byte). Add suffix k, M, G when suitable... */ -static char *max5data(curl_off_t bytes, char *max5) +static char *max6data(curl_off_t bytes, char *max6) { -#define ONE_KILOBYTE (curl_off_t)1024 -#define ONE_MEGABYTE (1024 * ONE_KILOBYTE) -#define ONE_GIGABYTE (1024 * ONE_MEGABYTE) -#define ONE_TERABYTE (1024 * ONE_GIGABYTE) -#define ONE_PETABYTE (1024 * ONE_TERABYTE) + /* a signed 64-bit value is 8192 petabytes maximum */ + const char unit[] = { 'k', 'M', 'G', 'T', 'P', 0 }; + int k = 0; + if(bytes < 1000000) { + msnprintf(max6, 7, "%5" CURL_FORMAT_CURL_OFF_T, bytes); + return max6; + } - if(bytes < 100000) - msnprintf(max5, 6, "%5" FMT_OFF_T, bytes); - - else if(bytes < 10000 * ONE_KILOBYTE) - msnprintf(max5, 6, "%4" FMT_OFF_T "k", bytes/ONE_KILOBYTE); - - else if(bytes < 100 * ONE_MEGABYTE) - /* 'XX.XM' is good as long as we are less than 100 megs */ - msnprintf(max5, 6, "%2" FMT_OFF_T ".%0" - FMT_OFF_T "M", bytes/ONE_MEGABYTE, - (bytes%ONE_MEGABYTE) / (ONE_MEGABYTE/10) ); - - else if(bytes < 10000 * ONE_MEGABYTE) - /* 'XXXXM' is good until we are at 10000MB or above */ - msnprintf(max5, 6, "%4" FMT_OFF_T "M", bytes/ONE_MEGABYTE); - - else if(bytes < 100 * ONE_GIGABYTE) - /* 10000 MB - 100 GB, we show it as XX.XG */ - msnprintf(max5, 6, "%2" FMT_OFF_T ".%0" - FMT_OFF_T "G", bytes/ONE_GIGABYTE, - (bytes%ONE_GIGABYTE) / (ONE_GIGABYTE/10) ); - - else if(bytes < 10000 * ONE_GIGABYTE) - /* up to 10000GB, display without decimal: XXXXG */ - msnprintf(max5, 6, "%4" FMT_OFF_T "G", bytes/ONE_GIGABYTE); - - else if(bytes < 10000 * ONE_TERABYTE) - /* up to 10000TB, display without decimal: XXXXT */ - msnprintf(max5, 6, "%4" FMT_OFF_T "T", bytes/ONE_TERABYTE); - - else - /* up to 10000PB, display without decimal: XXXXP */ - msnprintf(max5, 6, "%4" FMT_OFF_T "P", bytes/ONE_PETABYTE); - - /* 16384 petabytes (16 exabytes) is the maximum a 64-bit unsigned number can - hold, but our data type is signed so 8192PB will be the maximum. */ - - return max5; + do { + curl_off_t nbytes = bytes / 1024; + if(nbytes < 1000) { + /* xxx.yU */ + msnprintf(max6, 7, "%3" CURL_FORMAT_CURL_OFF_T + ".%" CURL_FORMAT_CURL_OFF_T "%c", nbytes, + (bytes%1024) / (1024/10), unit[k]); + break; + } + else if(nbytes < 100000) { + /* xxxxxU */ + msnprintf(max6, 7, "%5" CURL_FORMAT_CURL_OFF_T "%c", nbytes, unit[k]); + break; + } + bytes = nbytes; + k++; + DEBUGASSERT(unit[k]); + } while(unit[k]); + return max6; } #endif @@ -503,7 +486,7 @@ static void pgrs_estimates(struct pgrs_dir *d, static void progress_meter(struct Curl_easy *data) { struct Progress *p = &data->progress; - char max5[6][10]; + char max6[6][7]; struct pgrs_estimate dl_estm; struct pgrs_estimate ul_estm; struct pgrs_estimate total_estm; @@ -561,21 +544,21 @@ static void progress_meter(struct Curl_easy *data) fprintf(data->set.err, "\r" - "%3" FMT_OFF_T " %s " - "%3" FMT_OFF_T " %s " - "%3" FMT_OFF_T " %s %s %s %s %s %s %s", + "%3" FMT_OFF_T " %s " + "%3" FMT_OFF_T " %s " + "%3" FMT_OFF_T " %s %s %s %s %s %s %s", total_estm.percent, /* 3 letters */ /* total % */ - max5data(total_expected_size, max5[2]), /* total size */ + max6data(total_expected_size, max6[2]), /* total size */ dl_estm.percent, /* 3 letters */ /* rcvd % */ - max5data(p->dl.cur_size, max5[0]), /* rcvd size */ + max6data(p->dl.cur_size, max6[0]), /* rcvd size */ ul_estm.percent, /* 3 letters */ /* xfer % */ - max5data(p->ul.cur_size, max5[1]), /* xfer size */ - max5data(p->dl.speed, max5[3]), /* avrg dl speed */ - max5data(p->ul.speed, max5[4]), /* avrg ul speed */ + max6data(p->ul.cur_size, max6[1]), /* xfer size */ + max6data(p->dl.speed, max6[3]), /* avrg dl speed */ + max6data(p->ul.speed, max6[4]), /* avrg ul speed */ time_total, /* 8 letters */ /* total time */ time_spent, /* 8 letters */ /* time spent */ time_left, /* 8 letters */ /* time left */ - max5data(p->current_speed, max5[5]) + max6data(p->current_speed, max6[5]) ); /* we flush the output stream to make it appear as soon as possible */