| /***************************************************************************** |
| * _ _ ____ _ |
| * Project ___| | | | _ \| | |
| * / __| | | | |_) | | |
| * | (__| |_| | _ <| |___ |
| * \___|\___/|_| \_\_____| |
| * |
| * The contents of this file are subject to the Mozilla Public License |
| * Version 1.0 (the "License"); you may not use this file except in |
| * compliance with the License. You may obtain a copy of the License at |
| * http://www.mozilla.org/MPL/ |
| * |
| * Software distributed under the License is distributed on an "AS IS" |
| * basis, WITHOUT WARRANTY OF ANY KIND, either express or implied. See the |
| * License for the specific language governing rights and limitations |
| * under the License. |
| * |
| * The Original Code is Curl. |
| * |
| * The Initial Developer of the Original Code is Daniel Stenberg. |
| * |
| * Portions created by the Initial Developer are Copyright (C) 1998. |
| * All Rights Reserved. |
| * |
| * ------------------------------------------------------------ |
| * Main author: |
| * - Daniel Stenberg <Daniel.Stenberg@haxx.nu> |
| * |
| * http://curl.haxx.nu |
| * |
| * $Source$ |
| * $Revision$ |
| * $Date$ |
| * $Author$ |
| * $State$ |
| * $Locker$ |
| * |
| * ------------------------------------------------------------ |
| ****************************************************************************/ |
| |
| #include <string.h> |
| #include "setup.h" |
| |
| #if defined(WIN32) && !defined(__GNUC__) || defined(__MINGW32__) |
| #if defined(__MINGW32__) |
| #include <winsock.h> |
| #endif |
| #include <time.h> |
| #endif |
| |
| #include <curl/curl.h> |
| #include "urldata.h" |
| |
| #include "progress.h" |
| |
| /* --- start of progress routines --- */ |
| int progressmax=-1; |
| |
| static int prev = 0; |
| static int width = 0; |
| |
| void ProgressInit(struct UrlData *data, int max) |
| { |
| if(data->conf&(CONF_NOPROGRESS|CONF_MUTE)) |
| return; |
| |
| prev = 0; |
| |
| /* TODO: get terminal width through ansi escapes or something similar. |
| try to update width when xterm is resized... - 19990617 larsa */ |
| if (curl_GetEnv("COLUMNS") != NULL) |
| width = atoi(curl_GetEnv("COLUMNS")); |
| else |
| width = 80; |
| |
| progressmax = max; |
| if(-1 == max) |
| return; |
| if(progressmax <= LEAST_SIZE_PROGRESS) { |
| progressmax = -1; /* disable */ |
| return; |
| } |
| |
| if ( data->progressmode == CURL_PROGRESS_STATS ) |
| fprintf(data->err, |
| " %% Received Total Speed Time left Total Curr.Speed\n"); |
| } |
| |
| void time2str(char *r, int t) |
| { |
| int h = (t/3600); |
| int m = (t-(h*3600))/60; |
| int s = (t-(h*3600)-(m*60)); |
| sprintf(r,"%3d:%02d:%02d",h,m,s); |
| } |
| |
| void ProgressShow(struct UrlData *data, |
| int point, struct timeval start, struct timeval now, bool force) |
| { |
| switch ( data->progressmode ) { |
| case CURL_PROGRESS_STATS: |
| { |
| static long lastshow; |
| double percen; |
| |
| double spent; |
| double speed; |
| |
| #define CURR_TIME 5 |
| |
| static int speeder[ CURR_TIME ]; |
| static int speeder_c=0; |
| |
| int nowindex = speeder_c% CURR_TIME; |
| int checkindex; |
| int count; |
| |
| if(!force && (point != progressmax) && (lastshow == tvlong(now))) |
| return; /* never update this more than once a second if the end isn't |
| reached */ |
| |
| spent = tvdiff (now, start); |
| speed = point/(spent!=0.0?spent:1.0); |
| if(!speed) |
| speed=1; |
| |
| /* point is where we are right now */ |
| speeder[ nowindex ] = point; |
| speeder_c++; /* increase */ |
| count = ((speeder_c>=CURR_TIME)?CURR_TIME:speeder_c) - 1; |
| checkindex = (speeder_c>=CURR_TIME)?speeder_c%CURR_TIME:0; |
| |
| /* find out the average speed the last CURR_TIME seconds */ |
| data->current_speed = (speeder[nowindex]-speeder[checkindex])/(count?count:1); |
| |
| #if 0 |
| printf("NOW %d(%d) THEN %d(%d) DIFF %lf COUNT %d\n", |
| speeder[nowindex], nowindex, |
| speeder[checkindex], checkindex, |
| data->current_speed, count); |
| #endif |
| |
| if(data->conf&(CONF_NOPROGRESS|CONF_MUTE)) |
| return; |
| |
| if(-1 != progressmax) { |
| char left[20],estim[20]; |
| int estimate = progressmax/(int) speed; |
| |
| time2str(left,estimate-(int) spent); |
| time2str(estim,estimate); |
| |
| percen=(double)point/progressmax; |
| percen=percen*100; |
| |
| fprintf(data->err, "\r%3d %8d %8d %6.0lf %s %s %6.0lf ", |
| (int)percen, point, progressmax, |
| speed, left, estim, data->current_speed); |
| } |
| else |
| fprintf(data->err, |
| "\r%d bytes received in %.3lf seconds (%.0lf bytes/sec)", |
| point, spent, speed); |
| |
| lastshow = now.tv_sec; |
| break; |
| } |
| case CURL_PROGRESS_BAR: /* 19990617 larsa */ |
| { |
| if (point == prev) break; |
| if (progressmax == -1) { |
| int prevblock = prev / 1024; |
| int thisblock = point / 1024; |
| while ( thisblock > prevblock ) { |
| fprintf( data->err, "#" ); |
| prevblock++; |
| } |
| prev = point; |
| } else { |
| char line[256]; |
| char outline[256]; |
| char format[40]; |
| float frac = (float) point / (float) progressmax; |
| float percent = frac * 100.0f; |
| int barwidth = width - 7; |
| int num = (int) (((float)barwidth) * frac); |
| int i = 0; |
| for ( i = 0; i < num; i++ ) { |
| line[i] = '#'; |
| } |
| line[i] = '\0'; |
| sprintf( format, "%%-%ds %%5.1f%%%%", barwidth ); |
| sprintf( outline, format, line, percent ); |
| fprintf( data->err, "\r%s", outline ); |
| } |
| prev = point; |
| break; |
| } |
| default: /* 19990617 larsa */ |
| { |
| int prevblock = prev / 1024; |
| int thisblock = point / 1024; |
| if (prev == point) break; |
| while ( thisblock > prevblock ) { |
| fprintf( data->err, "#" ); |
| prevblock++; |
| } |
| prev = point; |
| break; |
| } |
| } |
| } |
| |
| void ProgressEnd(struct UrlData *data) |
| { |
| if(data->conf&(CONF_NOPROGRESS|CONF_MUTE)) |
| return; |
| fputs("\n", data->err); |
| } |
| |
| /* --- end of progress routines --- */ |