new
[libcurl.git] / lib / progress.c
blob22ec912e0bed8f5ef100a00c3e703cf18851a0b6
1 /*****************************************************************************
2 * _ _ ____ _
3 * Project ___| | | | _ \| |
4 * / __| | | | |_) | |
5 * | (__| |_| | _ <| |___
6 * \___|\___/|_| \_\_____|
8 * The contents of this file are subject to the Mozilla Public License
9 * Version 1.0 (the "License"); you may not use this file except in
10 * compliance with the License. You may obtain a copy of the License at
11 * http://www.mozilla.org/MPL/
13 * Software distributed under the License is distributed on an "AS IS"
14 * basis, WITHOUT WARRANTY OF ANY KIND, either express or implied. See the
15 * License for the specific language governing rights and limitations
16 * under the License.
18 * The Original Code is Curl.
20 * The Initial Developer of the Original Code is Daniel Stenberg.
22 * Portions created by the Initial Developer are Copyright (C) 1998.
23 * All Rights Reserved.
25 * ------------------------------------------------------------
26 * Main author:
27 * - Daniel Stenberg <Daniel.Stenberg@haxx.nu>
29 * http://curl.haxx.nu
31 * $Source: /cvsroot/curl/curl/lib/progress.c,v $
32 * $Revision: 1.1.1.1 $
33 * $Date: 1999-12-29 14:21:35 $
34 * $Author: bagder $
35 * $State: Exp $
36 * $Locker: $
38 * ------------------------------------------------------------
39 ****************************************************************************/
41 #include <string.h>
42 #include "setup.h"
44 #if defined(WIN32) && !defined(__GNUC__) || defined(__MINGW32__)
45 #if defined(__MINGW32__)
46 #include <winsock.h>
47 #endif
48 #include <time.h>
49 #endif
51 #include <curl/curl.h>
52 #include "urldata.h"
54 #include "progress.h"
56 /* --- start of progress routines --- */
57 int progressmax=-1;
59 static int prev = 0;
60 static int width = 0;
62 void ProgressInit(struct UrlData *data, int max)
64 if(data->conf&(CONF_NOPROGRESS|CONF_MUTE))
65 return;
67 prev = 0;
69 /* TODO: get terminal width through ansi escapes or something similar.
70 try to update width when xterm is resized... - 19990617 larsa */
71 if (curl_GetEnv("COLUMNS") != NULL)
72 width = atoi(curl_GetEnv("COLUMNS"));
73 else
74 width = 80;
76 progressmax = max;
77 if(-1 == max)
78 return;
79 if(progressmax <= LEAST_SIZE_PROGRESS) {
80 progressmax = -1; /* disable */
81 return;
84 if ( data->progressmode == CURL_PROGRESS_STATS )
85 fprintf(data->err,
86 " %% Received Total Speed Time left Total Curr.Speed\n");
89 void time2str(char *r, int t)
91 int h = (t/3600);
92 int m = (t-(h*3600))/60;
93 int s = (t-(h*3600)-(m*60));
94 sprintf(r,"%3d:%02d:%02d",h,m,s);
97 void ProgressShow(struct UrlData *data,
98 int point, struct timeval start, struct timeval now, bool force)
100 switch ( data->progressmode ) {
101 case CURL_PROGRESS_STATS:
103 static long lastshow;
104 double percen;
106 double spent;
107 double speed;
109 #define CURR_TIME 5
111 static int speeder[ CURR_TIME ];
112 static int speeder_c=0;
114 int nowindex = speeder_c% CURR_TIME;
115 int checkindex;
116 int count;
118 if(!force && (point != progressmax) && (lastshow == tvlong(now)))
119 return; /* never update this more than once a second if the end isn't
120 reached */
122 spent = tvdiff (now, start);
123 speed = point/(spent!=0.0?spent:1.0);
124 if(!speed)
125 speed=1;
127 /* point is where we are right now */
128 speeder[ nowindex ] = point;
129 speeder_c++; /* increase */
130 count = ((speeder_c>=CURR_TIME)?CURR_TIME:speeder_c) - 1;
131 checkindex = (speeder_c>=CURR_TIME)?speeder_c%CURR_TIME:0;
133 /* find out the average speed the last CURR_TIME seconds */
134 data->current_speed = (speeder[nowindex]-speeder[checkindex])/(count?count:1);
136 #if 0
137 printf("NOW %d(%d) THEN %d(%d) DIFF %lf COUNT %d\n",
138 speeder[nowindex], nowindex,
139 speeder[checkindex], checkindex,
140 data->current_speed, count);
141 #endif
143 if(data->conf&(CONF_NOPROGRESS|CONF_MUTE))
144 return;
146 if(-1 != progressmax) {
147 char left[20],estim[20];
148 int estimate = progressmax/(int) speed;
150 time2str(left,estimate-(int) spent);
151 time2str(estim,estimate);
153 percen=(double)point/progressmax;
154 percen=percen*100;
156 fprintf(data->err, "\r%3d %8d %8d %6.0lf %s %s %6.0lf ",
157 (int)percen, point, progressmax,
158 speed, left, estim, data->current_speed);
160 else
161 fprintf(data->err,
162 "\r%d bytes received in %.3lf seconds (%.0lf bytes/sec)",
163 point, spent, speed);
165 lastshow = now.tv_sec;
166 break;
168 case CURL_PROGRESS_BAR: /* 19990617 larsa */
170 if (point == prev) break;
171 if (progressmax == -1) {
172 int prevblock = prev / 1024;
173 int thisblock = point / 1024;
174 while ( thisblock > prevblock ) {
175 fprintf( data->err, "#" );
176 prevblock++;
178 prev = point;
179 } else {
180 char line[256];
181 char outline[256];
182 char format[40];
183 float frac = (float) point / (float) progressmax;
184 float percent = frac * 100.0f;
185 int barwidth = width - 7;
186 int num = (int) (((float)barwidth) * frac);
187 int i = 0;
188 for ( i = 0; i < num; i++ ) {
189 line[i] = '#';
191 line[i] = '\0';
192 sprintf( format, "%%-%ds %%5.1f%%%%", barwidth );
193 sprintf( outline, format, line, percent );
194 fprintf( data->err, "\r%s", outline );
196 prev = point;
197 break;
199 default: /* 19990617 larsa */
201 int prevblock = prev / 1024;
202 int thisblock = point / 1024;
203 if (prev == point) break;
204 while ( thisblock > prevblock ) {
205 fprintf( data->err, "#" );
206 prevblock++;
208 prev = point;
209 break;
214 void ProgressEnd(struct UrlData *data)
216 if(data->conf&(CONF_NOPROGRESS|CONF_MUTE))
217 return;
218 fputs("\n", data->err);
221 /* --- end of progress routines --- */