strbuf: create strbuf_humanise_bytes() to show byte sizes
Humanization of downloaded size is done in the same function as text formatting in 'process.c'. The code cannot be reused easily elsewhere. Separate text formatting from size simplification and make the function public in strbuf so that it can easily be used by other callers. We now can use strbuf_humanise_bytes() for both downloaded size and download speed calculation. One of the drawbacks is that speed will now look like this when download is stalled: "0 bytes/s" instead of "0 KiB/s". Signed-off-by: Antoine Pelisse <apelisse@gmail.com> Signed-off-by: Junio C Hamano <gitster@pobox.com>
Antoine Pelisse committed
Apr 10, 2013 at 21:03 UTC
079b546a2940a84989893254a318c8414e13a13e
4 files changed
+40
-28
Documentation/technical/api-strbuf.txt
+5
@@ -230,6 +230,11 @@ which can be used by the programmer of the callback as she sees fit.
230
destination. This is useful for literal data to be fed to either
231
strbuf_expand or to the *printf family of functions.
232
233
+`strbuf_humanise_bytes`::
234
+
235
+ Append the given byte size as a human-readable string (i.e. 12.23 KiB,
236
+ 3.50 MiB).
237
+
238
`strbuf_addf`::
239
240
Add a formatted string to the buffer.
progress.c
+15
-28
@@ -10,6 +10,7 @@
10
11
#include "git-compat-util.h"
12
#include "progress.h"
13
+#include "strbuf.h"
14
15
#define TP_IDX_MAX 8
16
@@ -112,34 +113,14 @@ static int display(struct progress *progress, unsigned n, const char *done)
113
return 0;
114
}
115
115
-static void throughput_string(struct throughput *tp, off_t total,
116
+static void throughput_string(struct strbuf *buf, off_t total,
117
unsigned int rate)
118
{
118
- int l = sizeof(tp->display);
119
- if (total > 1 << 30) {
120
- l -= snprintf(tp->display, l, ", %u.%2.2u GiB",
121
- (int)(total >> 30),
122
- (int)(total & ((1 << 30) - 1)) / 10737419);
123
- } else if (total > 1 << 20) {
124
- int x = total + 5243; /* for rounding */
125
- l -= snprintf(tp->display, l, ", %u.%2.2u MiB",
126
- x >> 20, ((x & ((1 << 20) - 1)) * 100) >> 20);
127
- } else if (total > 1 << 10) {
128
- int x = total + 5; /* for rounding */
129
- l -= snprintf(tp->display, l, ", %u.%2.2u KiB",
130
- x >> 10, ((x & ((1 << 10) - 1)) * 100) >> 10);
131
- } else {
132
- l -= snprintf(tp->display, l, ", %u bytes", (int)total);
133
- }
134
-
135
- if (rate > 1 << 10) {
136
- int x = rate + 5; /* for rounding */
137
- snprintf(tp->display + sizeof(tp->display) - l, l,
138
- " | %u.%2.2u MiB/s",
139
- x >> 10, ((x & ((1 << 10) - 1)) * 100) >> 10);
140
- } else if (rate)
141
- snprintf(tp->display + sizeof(tp->display) - l, l,
142
- " | %u KiB/s", rate);
119
+ strbuf_addstr(buf, ", ");
120
+ strbuf_humanise_bytes(buf, total);
121
+ strbuf_addstr(buf, " | ");
122
+ strbuf_humanise_bytes(buf, rate * 1024);
123
+ strbuf_addstr(buf, "/s");
124
}
125
126
void display_throughput(struct progress *progress, off_t total)
@@ -183,6 +164,7 @@ void display_throughput(struct progress *progress, off_t total)
164
misecs += (int)(tv.tv_usec - tp->prev_tv.tv_usec) / 977;
165
166
if (misecs > 512) {
167
+ struct strbuf buf = STRBUF_INIT;
168
unsigned int count, rate;
169
170
count = total - tp->prev_total;
@@ -197,7 +179,9 @@ void display_throughput(struct progress *progress, off_t total)
179
tp->last_misecs[tp->idx] = misecs;
180
tp->idx = (tp->idx + 1) % TP_IDX_MAX;
181
200
- throughput_string(tp, total, rate);
182
+ throughput_string(&buf, total, rate);
183
+ strncpy(tp->display, buf.buf, sizeof(tp->display));
184
+ strbuf_release(&buf);
185
if (progress->last_value != -1 && progress_update)
186
display(progress, progress->last_value, NULL);
187
}
@@ -253,9 +237,12 @@ void stop_progress_msg(struct progress **p_progress, const char *msg)
237
238
bufp = (len < sizeof(buf)) ? buf : xmalloc(len + 1);
239
if (tp) {
240
+ struct strbuf strbuf = STRBUF_INIT;
241
unsigned int rate = !tp->avg_misecs ? 0 :
242
tp->avg_bytes / tp->avg_misecs;
258
- throughput_string(tp, tp->curr_total, rate);
243
+ throughput_string(&strbuf, tp->curr_total, rate);
244
+ strncpy(tp->display, strbuf.buf, sizeof(tp->display));
245
+ strbuf_release(&strbuf);
246
}
247
progress_update = 1;
248
sprintf(bufp, ", %s.\n", msg);
strbuf.c
+19
@@ -528,6 +528,25 @@ void strbuf_addstr_urlencode(struct strbuf *sb, const char *s,
528
strbuf_add_urlencode(sb, s, strlen(s), reserved);
529
}
530
531
+void strbuf_humanise_bytes(struct strbuf *buf, off_t bytes)
532
+{
533
+ if (bytes > 1 << 30) {
534
+ strbuf_addf(buf, "%u.%2.2u GiB",
535
+ (int)(bytes >> 30),
536
+ (int)(bytes & ((1 << 30) - 1)) / 10737419);
537
+ } else if (bytes > 1 << 20) {
538
+ int x = bytes + 5243; /* for rounding */
539
+ strbuf_addf(buf, "%u.%2.2u MiB",
540
+ x >> 20, ((x & ((1 << 20) - 1)) * 100) >> 20);
541
+ } else if (bytes > 1 << 10) {
542
+ int x = bytes + 5; /* for rounding */
543
+ strbuf_addf(buf, "%u.%2.2u KiB",
544
+ x >> 10, ((x & ((1 << 10) - 1)) * 100) >> 10);
545
+ } else {
546
+ strbuf_addf(buf, "%u bytes", (int)bytes);
547
+ }
548
+}
549
+
550
int printf_ln(const char *fmt, ...)
551
{
552
int ret;
strbuf.h
+1
@@ -170,6 +170,7 @@ extern int strbuf_check_branch_ref(struct strbuf *sb, const char *name);
170
171
extern void strbuf_addstr_urlencode(struct strbuf *, const char *,
172
int reserved);
173
+extern void strbuf_humanise_bytes(struct strbuf *buf, off_t bytes);
174
175
__attribute__((format (printf,1,2)))
176
extern int printf_ln(const char *fmt, ...);