]> git.ipfire.org Git - thirdparty/curl.git/commitdiff
all new progress stuff on the way in
authorDaniel Stenberg <daniel@haxx.se>
Mon, 14 Feb 2000 23:15:08 +0000 (23:15 +0000)
committerDaniel Stenberg <daniel@haxx.se>
Mon, 14 Feb 2000 23:15:08 +0000 (23:15 +0000)
lib/progress.c
lib/progress.h

index dc1073a01791efd81256dec19543f05f8b0898f5..a54be86d6cedd5a539ef7c5edd0567d51b96710c 100644 (file)
 
 #include "progress.h"
 
-/* --- start of progress routines --- */
+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,"%d:%02d:%02d",h,m,s);
+}
+
+/* The point of this function would be to return a string of the input data,
+   but never longer than 5 columns. Add suffix k, M, G when suitable... */
+char *max5data(double bytes, char *max5)
+{
+  if(bytes < 100000) {
+    sprintf(max5, "%5d", (int)bytes);
+    return max5;
+  }
+  if(bytes < (9999*1024)) {
+    sprintf(max5, "%4dk", (int)bytes/1024);
+    return max5;
+  }
+  sprintf(max5, "%4dM", (int)bytes/(1024*1024));
+  return max5;
+}
+
+/* 
+
+   New proposed interface, 9th of February 2000:
+
+   pgrsStartNow() - sets start time
+   pgrsMode(type) - kind of display
+   pgrsSetDownloadSize(x) - known expected download size
+   pgrsSetUploadSize(x) - known expected upload size
+   pgrsSetDownloadCounter() - amount of data currently downloaded
+   pgrsSetUploadCounter() - amount of data currently uploaded
+   pgrsUpdate() - show progress
+   pgrsDone() - transfer complete
+
+*/
+#if 1
+void pgrsDone(struct UrlData *data)
+{
+  if(!(data->progress.flags & PGRS_HIDE))
+    fprintf(stderr, "\n");
+}
+void pgrsMode(struct UrlData *data, int mode)
+{
+  /* mode should include a hidden mode as well */
+  if(data->conf&(CONF_NOPROGRESS|CONF_MUTE))
+    data->progress.flags |= PGRS_HIDE; /* don't show anything */
+  else {
+    data->progress.mode = mode; /* store type */
+  }
+
+}
+
+void pgrsStartNow(struct UrlData *data)
+{
+  data->progress.start = tvnow();
+}
+
+void pgrsSetDownloadCounter(struct UrlData *data, double size)
+{
+  data->progress.downloaded = size;
+}
+
+void pgrsSetUploadCounter(struct UrlData *data, double size)
+{
+  data->progress.uploaded = size;
+}
+
+void pgrsSetDownloadSize(struct UrlData *data, double size)
+{
+  data->progress.size_dl = size;
+  data->progress.flags |= PGRS_DL_SIZE_KNOWN;
+}
+
+void pgrsSetUploadSize(struct UrlData *data, double size)
+{
+  data->progress.size_ul = size;
+  data->progress.flags |= PGRS_UL_SIZE_KNOWN;
+}
+
+/* EXAMPLE OUTPUT to follow:
+
+  % Total    % Received % Xferd  Average Speed          Time            Curr.
+                                Download Upload Total   Current  Left   Speed
+100 12345  100 12345  100 12345  12345   12345  2:47:33 2:00:02 2:00:02 12345
+
+ */
+
+void pgrsUpdate(struct UrlData *data)
+{
+  struct timeval now;
+
+  if(data->progress.flags & PGRS_HIDE)
+    ; /* We do enter this function even if we don't wanna see anything, since
+         this is were lots of the calculations are being made that will be used
+         even when not displayed! */
+  else if(!(data->progress.flags & PGRS_HEADERS_OUT)) {
+    if ( data->progress.mode == CURL_PROGRESS_STATS ) {
+      fprintf(data->err,
+              "  %% Total    %% Received %% Xferd  Average Speed          Time            Curr.\n"
+              "                                Download Upload Total   Current  Left   Speed\n");
+    }
+    data->progress.flags |= PGRS_HEADERS_OUT; /* headers are shown */
+  }
+
+  now = tvnow(); /* what time is it */
+
+  switch(data->progress.mode) {
+  case CURL_PROGRESS_STATS:
+    {
+      static long lastshow;
+      char max5[6][6];
+      double dlpercen=0;
+      double ulpercen=0;
+      double total_percen=0;
+
+      double total_transfer;
+      double total_expected_transfer;
+
+      double timespent;
+      double dlspeed;
+      double ulspeed;
+      
+#define CURR_TIME 5
+
+      static double speeder[ CURR_TIME ];
+      static int speeder_c=0;
+
+      int nowindex = speeder_c% CURR_TIME;
+      int checkindex;
+      int count;
+
+      char time_left[10];
+      char time_total[10];
+      char time_current[10];
+
+      double ulestimate=0;
+      double dlestimate=0;
+          
+      double total_estimate;
+
+      if(lastshow == tvlong(now))
+        return; /* never update this more than once a second if the end isn't 
+                   reached */
+      lastshow = now.tv_sec;
+
+      /* The exact time spent so far */
+      timespent = tvdiff (now, data->progress.start);
+
+      /* The average download speed this far */
+      dlspeed = data->progress.downloaded/(timespent!=0.0?timespent:1.0);
+
+      /* The average upload speed this far */
+      ulspeed = data->progress.uploaded/(timespent!=0.0?timespent:1.0);
+
+      /* Let's do the "current speed" thing, which should use the fastest
+         of the dl/ul speeds */
+
+      speeder[ nowindex ] = data->progress.downloaded>data->progress.uploaded?
+        data->progress.downloaded:data->progress.uploaded;
+      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->progress.current_speed =
+        (speeder[nowindex]-speeder[checkindex])/(count?count:1);
+
+      if(data->progress.flags & PGRS_HIDE)
+        return;
+
+      /* Figure out the estimated time of arrival for the upload */
+      if(data->progress.flags & PGRS_UL_SIZE_KNOWN) {
+        if(!ulspeed)
+          ulspeed=1;
+        ulestimate = data->progress.size_ul / ulspeed;
+        ulpercen = (data->progress.uploaded / data->progress.size_ul)*100;
+      }
+
+      /* ... and the download */
+      if(data->progress.flags & PGRS_DL_SIZE_KNOWN) {
+        if(!dlspeed)
+          dlspeed=1;
+        dlestimate = data->progress.size_dl / dlspeed;
+        dlpercen = (data->progress.downloaded / data->progress.size_dl)*100;
+      }
+    
+      /* Now figure out which of them that is slower and use for the for
+         total estimate! */
+      total_estimate = ulestimate>dlestimate?ulestimate:dlestimate;
+
+      /* If we have a total estimate, we can display that and the expected
+         time left */
+      if(total_estimate) {
+        time2str(time_left, total_estimate-(int) timespent); 
+        time2str(time_total, total_estimate);
+      }
+      else {
+        /* otherwise we blank those times */
+        strcpy(time_left,  "--:--:--");
+        strcpy(time_total, "--:--:--");
+      }
+      /* The time spent so far is always known */
+      time2str(time_current, timespent);
+
+      /* Get the total amount of data expected to get transfered */
+      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);
+      
+      /* We have transfered this much so far */
+      total_transfer = data->progress.downloaded + data->progress.uploaded;
+
+      /* Get the percentage of data transfered so far */
+      if(total_expected_transfer)
+        total_percen=(double)(total_transfer/total_expected_transfer)*100;
+
+
+      fprintf(stderr,
+              "\r%3d %s  %3d %s  %3d %s  %s   %s  %s %s %s %s",
+              (int)total_percen,                    /* total % */
+              max5data(total_expected_transfer, max5[2]),    /* total size */
+              (int)dlpercen,                        /* rcvd % */
+              max5data(data->progress.downloaded, max5[0]), /* rcvd size */
+              (int)ulpercen,                        /* xfer % */
+              max5data(data->progress.uploaded, max5[1]), /* xfer size */
+
+              max5data(dlspeed, max5[3]),           /* avrg dl speed */
+              max5data(ulspeed, max5[4]),           /* avrg ul speed */
+              time_total,                           /* total time */
+              time_current,                         /* current time */
+              time_left,                            /* time left */
+              max5data(data->progress.current_speed, max5[5]) /* current speed */
+              );
+    }
+
+
+  }
+}
+
+
+#endif
+
+#if 0
+/* --- start of (the former) progress routines --- */
 int progressmax=-1;
 
 static int prev = 0;
 static int width = 0;
 
-void ProgressInit(struct UrlData *data, int max)
+void ProgressInit(struct UrlData *data, int max/*, int options, int moremax*/)
 {
   if(data->conf&(CONF_NOPROGRESS|CONF_MUTE))
     return;
@@ -87,14 +335,6 @@ void ProgressInit(struct UrlData *data, int max)
 
 }
 
-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)
 {
@@ -223,3 +463,4 @@ void ProgressEnd(struct UrlData *data)
 }
 
 /* --- end of progress routines --- */
+#endif
index 6babd89ca43336d965f01a6bf5dd14b9fae1a10e..be94f9529ae3e9233276ffeb1351959ed1073000 100644 (file)
 
 #include "timeval.h"
 
+#if 0
 void ProgressInit(struct UrlData *data, int max);
 void ProgressShow(struct UrlData *data,
                   int point, struct timeval start, struct timeval now, bool force);
 void ProgressEnd(struct UrlData *data);
 void ProgressMode(int mode);
+#endif
+
+void pgrsMode(struct UrlData *data, int mode);
+void pgrsStartNow(struct UrlData *data);
+void pgrsSetDownloadSize(struct UrlData *data, double size);
+void pgrsSetUploadSize(struct UrlData *data, double size);
+void pgrsSetDownloadCounter(struct UrlData *data, double size);
+     void pgrsSetUploadCounter(struct UrlData *data, double size);
+void pgrsUpdate(struct UrlData *data);
+
 
 /* Don't show progress for sizes smaller than: */
 #define LEAST_SIZE_PROGRESS BUFSIZE
 
+#define PROGRESS_DOWNLOAD (1<<0)
+#define PROGRESS_UPLOAD   (1<<1)
+#define PROGRESS_DOWN_AND_UP (PROGRESS_UPLOAD | PROGRESS_DOWNLOAD)
+
+#define PGRS_SHOW_DL (1<<0)
+#define PGRS_SHOW_UL (1<<1)
+#define PGRS_DONE_DL (1<<2)
+#define PGRS_DONE_UL (1<<3)
+#define PGRS_HIDE    (1<<4)
+#define PGRS_UL_SIZE_KNOWN (1<<5)
+#define PGRS_DL_SIZE_KNOWN (1<<6)
+
+#define PGRS_HEADERS_OUT (1<<7) /* set when the headers have been written */
+
+
 #endif /* __PROGRESS_H */