#include <stdio.h>
#include <string.h>
#include <stdlib.h>
typedef unsigned long long U64;
static int g_utilDisplayLevel;
static int g_displayLevel;
typedef struct { double value; int precision; const char* suffix; } HRS;
static HRS UTIL_makeHumanReadableSize(U64 size)
{
HRS hrs;
if (g_utilDisplayLevel > 3) {
if (size >= (1ull << 53)) {
hrs.value = (double)size / (1ull << 20);
hrs.suffix = " MiB";
hrs.precision = 2;
} else {
hrs.value = (double)size;
hrs.suffix = " B";
hrs.precision = 0;
}
} else {
if (size >= (1ull << 60)) {
hrs.value = (double)size / (1ull << 60); hrs.suffix = " EiB";
} else if (size >= (1ull << 50)) {
hrs.value = (double)size / (1ull << 50); hrs.suffix = " PiB";
} else if (size >= (1ull << 40)) {
hrs.value = (double)size / (1ull << 40); hrs.suffix = " TiB";
} else if (size >= (1ull << 30)) {
hrs.value = (double)size / (1ull << 30); hrs.suffix = " GiB";
} else if (size >= (1ull << 20)) {
hrs.value = (double)size / (1ull << 20); hrs.suffix = " MiB";
} else if (size >= (1ull << 10)) {
hrs.value = (double)size / (1ull << 10); hrs.suffix = " KiB";
} else {
hrs.value = (double)size; hrs.suffix = " B";
}
if (hrs.value >= 100 || (U64)hrs.value == size) hrs.precision = 0;
else if (hrs.value >= 10) hrs.precision = 1;
else if (hrs.value > 1) hrs.precision = 2;
else hrs.precision = 3;
}
return hrs;
}
static void show(const char* buf)
{
for (; *buf; buf++) {
if (*buf == '\r') fputs("\\r", stdout);
else if (*buf == '\n') fputs("\\n", stdout);
else putchar(*buf);
}
putchar('\n');
}
#define DISPLAY_PROGRESS(...) { p += sprintf(p, __VA_ARGS__); }
int main(void)
{
char line[1024];
while (fgets(line, sizeof line, stdin)) {
char kind[32], name[256];
char out[4096]; char* p = out;
unsigned dl, nbFilesTotal, idx;
line[strcspn(line, "\n")] = 0;
if (sscanf(line, "%31s", kind) != 1) continue;
printf("%s\t", line);
if (!strcmp(kind, "compress")) {
long long fileSizeIn; int compressionLevel;
U64 ingested, consumed, produced;
sscanf(line, "%*s %u %u %u %255s %lld %d %llu %llu %llu", &dl, &nbFilesTotal, &idx, name,
&fileSizeIn, &compressionLevel, &ingested, &consumed, &produced);
g_displayLevel = g_utilDisplayLevel = (int)dl;
const char* srcFileName = name;
U64 fileSize = (U64)fileSizeIn;
HRS file_hrs = UTIL_makeHumanReadableSize(fileSize);
double const cShare = (double)produced / (double)(consumed + !consumed) * 100;
HRS buffered_hrs = UTIL_makeHumanReadableSize(ingested - consumed);
HRS consumed_hrs = UTIL_makeHumanReadableSize(consumed);
HRS produced_hrs = UTIL_makeHumanReadableSize(produced);
DISPLAY_PROGRESS("\r%79s\r", "");
if (g_displayLevel >= 3) {
DISPLAY_PROGRESS(
"(L%i) Buffered:%5.*f%s - Consumed:%5.*f%s - Compressed:%5.*f%s => %.2f%% ",
compressionLevel,
buffered_hrs.precision, buffered_hrs.value, buffered_hrs.suffix,
consumed_hrs.precision, consumed_hrs.value, consumed_hrs.suffix,
produced_hrs.precision, produced_hrs.value, produced_hrs.suffix,
cShare );
} else {
if (nbFilesTotal > 1) {
size_t srcFileNameSize = strlen(srcFileName);
if (srcFileNameSize > 18) {
const char* truncatedSrcFileName = srcFileName + srcFileNameSize - 15;
DISPLAY_PROGRESS("Compress: %u/%u files. Current: ...%s ",
idx+1, nbFilesTotal, truncatedSrcFileName);
} else {
DISPLAY_PROGRESS("Compress: %u/%u files. Current: %*s ",
idx+1, nbFilesTotal, (int)(18-srcFileNameSize), srcFileName);
}
}
DISPLAY_PROGRESS("Read:%6.*f%4s ", consumed_hrs.precision, consumed_hrs.value, consumed_hrs.suffix);
if (fileSize != (U64)-1)
DISPLAY_PROGRESS("/%6.*f%4s", file_hrs.precision, file_hrs.value, file_hrs.suffix);
DISPLAY_PROGRESS(" ==> %2.f%%", cShare);
}
} else {
U64 bytes;
sscanf(line, "%*s %u %u %u %255s %llu", &dl, &nbFilesTotal, &idx, name, &bytes);
g_displayLevel = g_utilDisplayLevel = (int)dl;
const char* srcFName20 = name;
size_t srcFileLength = strlen(name);
if ((srcFileLength>20) && (g_displayLevel<3)) srcFName20 += srcFileLength-20;
HRS hrs = UTIL_makeHumanReadableSize(bytes);
if (nbFilesTotal > 1) {
DISPLAY_PROGRESS(
"\rDecompress: %2u/%2u files. Current: %s : %.*f%s... ",
idx+1, nbFilesTotal, srcFName20, hrs.precision, hrs.value, hrs.suffix);
} else {
DISPLAY_PROGRESS("\r%-20.20s : %.*f%s... ",
srcFName20, hrs.precision, hrs.value, hrs.suffix);
}
}
show(out);
}
return 0;
}