1 #include <sys/ioctl.h>
2 #include <math.h>
3 #include <unistd.h>
4 #include <stdio.h>
5 
6 #include "ProgressBar.hh"
7 
8 namespace gr
9 {
10 
ProgressBar()11 ProgressBar::ProgressBar(): showProgressBar(false), last(1000)
12 {
13 }
14 
~ProgressBar()15 ProgressBar::~ProgressBar()
16 {
17 }
18 
setShowProgressBar(bool showProgressBar)19 void ProgressBar::setShowProgressBar(bool showProgressBar)
20 {
21 	this->showProgressBar = showProgressBar;
22 }
23 
determineTerminalSize()24 unsigned short int ProgressBar::determineTerminalSize()
25 {
26 	struct winsize w;
27 	ioctl(STDOUT_FILENO, TIOCGWINSZ, &w);
28 	return w.ws_col;
29 }
30 
printBytes(u64_t bytes)31 void ProgressBar::printBytes(u64_t bytes)
32 {
33 	if (bytes >= 1024*1024*1024)
34 		printf("%.3f GB", (double)bytes/1024/1024/1024);
35 	else if (bytes >= 1024*1024)
36 		printf("%.3f MB", (double)bytes/1024/1024);
37 	else
38 		printf("%.3f KB", (double)bytes/1024);
39 }
40 
reportProgress(u64_t total,u64_t processed)41 void ProgressBar::reportProgress(u64_t total, u64_t processed)
42 {
43 	if (showProgressBar && total)
44 	{
45 		// libcurl seems to process more bytes then the actual file size :)
46 		if (processed > total)
47 			processed = total;
48 		double fraction = (double)processed/total;
49 
50 		int point = fraction*1000;
51 		if (this->last < 1000 || point != this->last)
52 		{
53 			// do not print 100% progress multiple times (it will duplicate the progressbar)
54 			this->last = point;
55 
56 			// 10 for prefix of percent and 26 for suffix of file size
57 			int availableSize = determineTerminalSize() - 36;
58 			int totalDots;
59 			if (availableSize > 100)
60 				totalDots = 100;
61 			else if (availableSize < 0)
62 				totalDots = 10;
63 			else
64 				totalDots = availableSize;
65 
66 			int dotz = round(fraction * totalDots);
67 			int count = 0;
68 			// delete previous output line
69 			printf("\r  [%3.0f%%] [", fraction * 100);
70 			for (; count < dotz - 1; count++)
71 				putchar('=');
72 			putchar('>');
73 			for (; count < totalDots - 1; count++)
74 				putchar(' ');
75 			printf("] ");
76 			printBytes(processed);
77 			putchar('/');
78 			printBytes(total);
79 			printf("\33[K\r");
80 			if (point == 1000)
81 				putchar('\n');
82 			fflush(stdout);
83 		}
84 	}
85 }
86 
87 }
88