Advertisement
phyrrus9

Progress Bars

Mar 8th, 2018
267
0
Never
Not a member of Pastebin yet? Sign Up, it unlocks many cool features!
C 3.35 KB | None | 0 0
  1. #include <stdlib.h>
  2. #include <stdio.h>
  3. #include <unistd.h>
  4. #include <time.h>
  5. #include <curl/curl.h>
  6. typedef void (*progressCallback)(unsigned, unsigned);
  7. void waitLoop(unsigned ms, unsigned interval, progressCallback callback)
  8. {
  9.         unsigned i, j, s, count = ms/interval;
  10.         for (i = 0, s = 0; i < ms; i += interval, ++s)
  11.         {
  12.                 (*callback)(s % 4, (i * 100) / ms);
  13.                 usleep(interval * 1000);
  14.         }
  15.         (*callback)(0, 100);
  16.         printf("\n");
  17. }
  18. struct cURLProgress
  19. {
  20.         double lastrun;
  21.         CURL *curl;
  22.         progressCallback callback;
  23.         unsigned interval;
  24.         unsigned char step;
  25. };
  26. static int downloadProgress(void *p, curl_off_t dltotal, curl_off_t dlnow, curl_off_t ultotal, curl_off_t ulnow)
  27. {
  28.         struct cURLProgress *info;
  29.         CURL *curl;
  30.         double curtime;
  31.         info = p;
  32.         curl = info->curl;
  33.         curtime = 0;
  34.         curl_easy_getinfo(curl, CURLINFO_TOTAL_TIME, &curtime);
  35.         if ((curtime - info->lastrun) > ((double)info->interval / 1000.0) && dltotal > 0)
  36.         {
  37.                 info->lastrun = curtime;
  38.                 (*info->callback)(info->step++ % 4, (dlnow * 100) / dltotal);
  39.         }
  40.         return 0;
  41. }
  42. size_t cURLWriteData(void *ptr, size_t size, size_t nmemb, FILE *stream)
  43. { return fwrite(ptr, size, nmemb, stream); }
  44. int downloadFile(const char *URL, const char *path, unsigned interval, progressCallback callback)
  45. {
  46.         CURL *curl;
  47.         CURLcode res;
  48.         FILE *fp;
  49.         struct cURLProgress progressInfo;
  50.         res = CURLE_OK;
  51.         if ((curl = curl_easy_init()) != NULL)
  52.         {
  53.                 progressInfo.lastrun = 0;
  54.                 progressInfo.curl = curl;
  55.                 progressInfo.callback = callback;
  56.                 progressInfo.interval = interval;
  57.                 progressInfo.step = 0;
  58.                 fp = fopen(path, "wb");
  59.                 curl_easy_setopt(curl, CURLOPT_URL, URL);
  60.                 curl_easy_setopt(curl, CURLOPT_XFERINFOFUNCTION, downloadProgress);
  61.                 curl_easy_setopt(curl, CURLOPT_XFERINFODATA, &progressInfo);
  62.                 curl_easy_setopt(curl, CURLOPT_NOPROGRESS, 0L);
  63.                 curl_easy_setopt(curl, CURLOPT_WRITEFUNCTION, cURLWriteData);
  64.                 curl_easy_setopt(curl, CURLOPT_WRITEDATA, fp);
  65.                 if ((res = curl_easy_perform(curl)) == CURLE_OK)
  66.                     (*callback)(0, 100);
  67.                 curl_easy_cleanup(curl);
  68.                 fclose(fp);
  69.         }
  70.         printf("\n");
  71.         return res;
  72. }
  73. void progress(unsigned spin, unsigned step)
  74. {
  75.         int i;
  76.         const char *pgstep = "|\\-/";
  77.         printf("\r"); for (i = 0; i < 109; ++i); printf(" "); printf("\r ["); // clear
  78.         for (i = 0; i < step; ++i) printf("#"); // print bar
  79.         for (; i < 100; ++i) printf(" "); // print blank space
  80.         printf("] %c\b", step > 99 ? ' ' : pgstep[spin]);
  81.         fflush(stdout);
  82. }
  83. int main()
  84. {
  85.         int retVal;
  86.         srand(time(NULL));
  87.         waitLoop((rand() % 15 + 1) * 1000, 75, &progress);
  88.         retVal = downloadFile(
  89.                    "http://mirror.digitalnova.at/archlinux/iso/2018.03.01/archlinux-2018.03.01-x86_64.iso",
  90.                    "archlinux.iso", 300, &progress);
  91.         if (retVal != 0) fprintf(stderr, "There was an error downloading your file\n");
  92.         return 0;
  93. }
Advertisement
Add Comment
Please, Sign In to add comment
Advertisement