data->progress.speeder_c = 0; /* reset the progress meter display */
data->progress.start = Curl_now();
data->progress.is_t_startransfer_set = false;
- data->progress.ul_limit_start = data->progress.start;
- data->progress.dl_limit_start = data->progress.start;
- data->progress.ul_limit_size = 0;
- data->progress.dl_limit_size = 0;
- data->progress.downloaded = 0;
- data->progress.uploaded = 0;
+ data->progress.ul.limit.start = data->progress.start;
+ data->progress.dl.limit.start = data->progress.start;
+ data->progress.ul.limit.start_size = 0;
+ data->progress.dl.limit.start_size = 0;
+ data->progress.dl.cur_size = 0;
+ data->progress.ul.cur_size = 0;
/* clear all bits except HIDE and HEADERS_OUT */
data->progress.flags &= PGRS_HIDE|PGRS_HEADERS_OUT;
Curl_ratelimit(data, data->progress.start);
* starting point should be reset (to current); or the number of milliseconds
* to wait to get back under the speed limit.
*/
-timediff_t Curl_pgrsLimitWaitTime(curl_off_t cursize,
- curl_off_t startsize,
- curl_off_t limit,
- struct curltime start,
+timediff_t Curl_pgrsLimitWaitTime(struct pgrs_dir *d,
+ curl_off_t speed_limit,
struct curltime now)
{
- curl_off_t size = cursize - startsize;
+ curl_off_t size = d->cur_size - d->limit.start_size;
timediff_t minimum;
timediff_t actual;
- if(!limit || !size)
+ if(!speed_limit || !size)
return 0;
/*
* stay below 'limit'.
*/
if(size < CURL_OFF_T_MAX/1000)
- minimum = (timediff_t) (CURL_OFF_T_C(1000) * size / limit);
+ minimum = (timediff_t) (CURL_OFF_T_C(1000) * size / speed_limit);
else {
- minimum = (timediff_t) (size / limit);
+ minimum = (timediff_t) (size / speed_limit);
if(minimum < TIMEDIFF_T_MAX/1000)
minimum *= 1000;
else
* 'actual' is the time in milliseconds it took to actually download the
* last 'size' bytes.
*/
- actual = Curl_timediff_ceil(now, start);
+ actual = Curl_timediff_ceil(now, d->limit.start);
if(actual < minimum) {
/* if it downloaded the data faster than the limit, make it wait the
difference */
*/
CURLcode Curl_pgrsSetDownloadCounter(struct Curl_easy *data, curl_off_t size)
{
- data->progress.downloaded = size;
+ data->progress.dl.cur_size = size;
return CURLE_OK;
}
{
/* do not set a new stamp unless the time since last update is long enough */
if(data->set.max_recv_speed) {
- if(Curl_timediff(now, data->progress.dl_limit_start) >=
+ if(Curl_timediff(now, data->progress.dl.limit.start) >=
MIN_RATE_LIMIT_PERIOD) {
- data->progress.dl_limit_start = now;
- data->progress.dl_limit_size = data->progress.downloaded;
+ data->progress.dl.limit.start = now;
+ data->progress.dl.limit.start_size = data->progress.dl.cur_size;
}
}
if(data->set.max_send_speed) {
- if(Curl_timediff(now, data->progress.ul_limit_start) >=
+ if(Curl_timediff(now, data->progress.ul.limit.start) >=
MIN_RATE_LIMIT_PERIOD) {
- data->progress.ul_limit_start = now;
- data->progress.ul_limit_size = data->progress.uploaded;
+ data->progress.ul.limit.start = now;
+ data->progress.ul.limit.start_size = data->progress.ul.cur_size;
}
}
}
*/
void Curl_pgrsSetUploadCounter(struct Curl_easy *data, curl_off_t size)
{
- data->progress.uploaded = size;
+ data->progress.ul.cur_size = size;
}
void Curl_pgrsSetDownloadSize(struct Curl_easy *data, curl_off_t size)
{
if(size >= 0) {
- data->progress.size_dl = size;
+ data->progress.dl.total_size = size;
data->progress.flags |= PGRS_DL_SIZE_KNOWN;
}
else {
- data->progress.size_dl = 0;
+ data->progress.dl.total_size = 0;
data->progress.flags &= ~PGRS_DL_SIZE_KNOWN;
}
}
void Curl_pgrsSetUploadSize(struct Curl_easy *data, curl_off_t size)
{
if(size >= 0) {
- data->progress.size_ul = size;
+ data->progress.ul.total_size = size;
data->progress.flags |= PGRS_UL_SIZE_KNOWN;
}
else {
- data->progress.size_ul = 0;
+ data->progress.ul.total_size = 0;
data->progress.flags &= ~PGRS_UL_SIZE_KNOWN;
}
}
/* The time spent so far (from the start) in microseconds */
p->timespent = Curl_timediff_us(now, p->start);
- p->dlspeed = trspeed(p->downloaded, p->timespent);
- p->ulspeed = trspeed(p->uploaded, p->timespent);
+ p->dl.speed = trspeed(p->dl.cur_size, p->timespent);
+ p->ul.speed = trspeed(p->ul.cur_size, p->timespent);
/* Calculations done at most once a second, unless end is reached */
if(p->lastshow != now.tv_sec) {
/* Let's do the "current speed" thing, with the dl + ul speeds
combined. Store the speed at entry 'nowindex'. */
- p->speeder[ nowindex ] = p->downloaded + p->uploaded;
+ p->speeder[ nowindex ] = p->dl.cur_size + p->ul.cur_size;
/* remember the exact time for this moment */
p->speeder_time [ nowindex ] = now;
}
else
/* the first second we use the average */
- p->current_speed = p->ulspeed + p->dlspeed;
+ p->current_speed = p->ul.speed + p->dl.speed;
} /* Calculations end */
return timetoshow;
}
#ifndef CURL_DISABLE_PROGRESS_METER
+
+struct pgrs_estimate {
+ curl_off_t secs;
+ curl_off_t percent;
+};
+
+static curl_off_t pgrs_est_percent(curl_off_t total, curl_off_t cur)
+{
+ if(total > CURL_OFF_T_C(10000))
+ return cur / (total/CURL_OFF_T_C(100));
+ else if(total > CURL_OFF_T_C(0))
+ return (cur*100) / total;
+ return 0;
+}
+
+static void pgrs_estimates(struct pgrs_dir *d,
+ bool total_known,
+ struct pgrs_estimate *est)
+{
+ est->secs = 0;
+ est->percent = 0;
+ if(total_known && (d->speed > CURL_OFF_T_C(0))) {
+ est->secs = d->total_size / d->speed;
+ est->percent = pgrs_est_percent(d->total_size, d->cur_size);
+ }
+}
+
static void progress_meter(struct Curl_easy *data)
{
+ struct Progress *p = &data->progress;
char max5[6][10];
- curl_off_t dlpercen = 0;
- curl_off_t ulpercen = 0;
- curl_off_t total_percen = 0;
- curl_off_t total_transfer;
- curl_off_t total_expected_transfer;
+ struct pgrs_estimate dl_estm;
+ struct pgrs_estimate ul_estm;
+ struct pgrs_estimate total_estm;
+ curl_off_t total_cur_size;
+ curl_off_t total_expected_size;
char time_left[10];
char time_total[10];
char time_spent[10];
- curl_off_t ulestimate = 0;
- curl_off_t dlestimate = 0;
- curl_off_t total_estimate;
- curl_off_t timespent =
- (curl_off_t)data->progress.timespent/1000000; /* seconds */
+ curl_off_t cur_secs = (curl_off_t)p->timespent/1000000; /* seconds */
- if(!(data->progress.flags & PGRS_HEADERS_OUT)) {
+ if(!(p->flags & PGRS_HEADERS_OUT)) {
if(data->state.resume_from) {
fprintf(data->set.err,
"** Resuming transfer from byte position %"
"Time Time Time Current\n"
" Dload Upload "
"Total Spent Left Speed\n");
- data->progress.flags |= PGRS_HEADERS_OUT; /* headers are shown */
- }
-
- /* Figure out the estimated time of arrival for the upload */
- if((data->progress.flags & PGRS_UL_SIZE_KNOWN) &&
- (data->progress.ulspeed > CURL_OFF_T_C(0))) {
- ulestimate = data->progress.size_ul / data->progress.ulspeed;
-
- if(data->progress.size_ul > CURL_OFF_T_C(10000))
- ulpercen = data->progress.uploaded /
- (data->progress.size_ul/CURL_OFF_T_C(100));
- else if(data->progress.size_ul > CURL_OFF_T_C(0))
- ulpercen = (data->progress.uploaded*100) /
- data->progress.size_ul;
- }
-
- /* ... and the download */
- if((data->progress.flags & PGRS_DL_SIZE_KNOWN) &&
- (data->progress.dlspeed > CURL_OFF_T_C(0))) {
- dlestimate = data->progress.size_dl / data->progress.dlspeed;
-
- if(data->progress.size_dl > CURL_OFF_T_C(10000))
- dlpercen = data->progress.downloaded /
- (data->progress.size_dl/CURL_OFF_T_C(100));
- else if(data->progress.size_dl > CURL_OFF_T_C(0))
- dlpercen = (data->progress.downloaded*100) /
- data->progress.size_dl;
+ p->flags |= PGRS_HEADERS_OUT; /* headers are shown */
}
- /* Now figure out which of them is slower and use that one for the
- total estimate! */
- total_estimate = ulestimate>dlestimate?ulestimate:dlestimate;
+ /* Figure out the estimated time of arrival for upload and download */
+ pgrs_estimates(&p->ul, (p->flags & PGRS_UL_SIZE_KNOWN), &ul_estm);
+ pgrs_estimates(&p->dl, (p->flags & PGRS_DL_SIZE_KNOWN), &dl_estm);
+ /* Since both happen at the same time, total expected duration is max. */
+ total_estm.secs = CURLMAX(ul_estm.secs, dl_estm.secs);
/* create the three time strings */
- time2str(time_left, total_estimate > 0?(total_estimate - timespent):0);
- time2str(time_total, total_estimate);
- time2str(time_spent, timespent);
+ time2str(time_left, total_estm.secs > 0?(total_estm.secs - cur_secs):0);
+ time2str(time_total, total_estm.secs);
+ time2str(time_spent, cur_secs);
/* Get the total amount of data expected to get transferred */
- total_expected_transfer =
- ((data->progress.flags & PGRS_UL_SIZE_KNOWN)?
- data->progress.size_ul:data->progress.uploaded)+
- ((data->progress.flags & PGRS_DL_SIZE_KNOWN)?
- data->progress.size_dl:data->progress.downloaded);
+ total_expected_size =
+ ((p->flags & PGRS_UL_SIZE_KNOWN)? p->ul.total_size:p->ul.cur_size) +
+ ((p->flags & PGRS_DL_SIZE_KNOWN)? p->dl.total_size:p->dl.cur_size);
/* We have transferred this much so far */
- total_transfer = data->progress.downloaded + data->progress.uploaded;
+ total_cur_size = p->dl.cur_size + p->ul.cur_size;
/* Get the percentage of data transferred so far */
- if(total_expected_transfer > CURL_OFF_T_C(10000))
- total_percen = total_transfer /
- (total_expected_transfer/CURL_OFF_T_C(100));
- else if(total_expected_transfer > CURL_OFF_T_C(0))
- total_percen = (total_transfer*100) / total_expected_transfer;
+ total_estm.percent = pgrs_est_percent(total_expected_size, total_cur_size);
fprintf(data->set.err,
"\r"
"%3" CURL_FORMAT_CURL_OFF_T " %s "
"%3" CURL_FORMAT_CURL_OFF_T " %s "
"%3" CURL_FORMAT_CURL_OFF_T " %s %s %s %s %s %s %s",
- total_percen, /* 3 letters */ /* total % */
- max5data(total_expected_transfer, max5[2]), /* total size */
- dlpercen, /* 3 letters */ /* rcvd % */
- max5data(data->progress.downloaded, max5[0]), /* rcvd size */
- ulpercen, /* 3 letters */ /* xfer % */
- max5data(data->progress.uploaded, max5[1]), /* xfer size */
- max5data(data->progress.dlspeed, max5[3]), /* avrg dl speed */
- max5data(data->progress.ulspeed, max5[4]), /* avrg ul speed */
+ total_estm.percent, /* 3 letters */ /* total % */
+ max5data(total_expected_size, max5[2]), /* total size */
+ dl_estm.percent, /* 3 letters */ /* rcvd % */
+ max5data(p->dl.cur_size, max5[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 */
time_total, /* 8 letters */ /* total time */
time_spent, /* 8 letters */ /* time spent */
time_left, /* 8 letters */ /* time left */
- max5data(data->progress.current_speed, max5[5])
+ max5data(p->current_speed, max5[5])
);
/* we flush the output stream to make it appear as soon as possible */
/* There is a callback set, call that */
Curl_set_in_callback(data, true);
result = data->set.fxferinfo(data->set.progress_client,
- data->progress.size_dl,
- data->progress.downloaded,
- data->progress.size_ul,
- data->progress.uploaded);
+ data->progress.dl.total_size,
+ data->progress.dl.cur_size,
+ data->progress.ul.total_size,
+ data->progress.ul.cur_size);
Curl_set_in_callback(data, false);
if(result != CURL_PROGRESSFUNC_CONTINUE) {
if(result)
/* The older deprecated callback is set, call that */
Curl_set_in_callback(data, true);
result = data->set.fprogress(data->set.progress_client,
- (double)data->progress.size_dl,
- (double)data->progress.downloaded,
- (double)data->progress.size_ul,
- (double)data->progress.uploaded);
+ (double)data->progress.dl.total_size,
+ (double)data->progress.dl.cur_size,
+ (double)data->progress.ul.total_size,
+ (double)data->progress.ul.cur_size);
Curl_set_in_callback(data, false);
if(result != CURL_PROGRESSFUNC_CONTINUE) {
if(result)