#include "io.hpp"
#include <limits.h>
#ifndef SIZE_MAX
//#pragma message ( "SIZE_MAX undefined" )
#define SIZE_MAX ((size_t)-1)
#endif
static void progress(off_t at, off_t max) {
if (!max || max < 1000*1000) return;
static int last_frac = -1;
int frac = (int)((at * 10) / max); // 0-10
if (frac == last_frac) {
return;
}
last_frac = frac;
static const char* P="############";
printf("\r[%.*s%*s] %3d%%", frac, P, 10-frac, "", (int)frac*10);
fflush(stdout);
if (at >= max) {
printf(" Done.\n");
last_frac = -1;
}
}
bool write_buffered(off_t len, int from, int to) {
const off_t total = len;
static char buf[4096];
while (len) {
progress(total-len, total);
ssize_t rv = read(from, buf, MIN(len, (off_t)sizeof(buf)));
if (rv == 0) {
printf("\n");
LOG("read() - 0");
return false;
} else if (rv == -1) {
LOG_ERRNO("read()");
printf("\n");
return false;
} else {
len -= rv;
}
char* p = buf;
while (rv) {
ssize_t wrv = write(to, p, rv);
if (wrv == 0) {
printf("\n");
LOG("write() - 0");
return false;
} else if (wrv == -1) {
LOG_ERRNO("write()");
printf("\n");
return false;
} else {
rv -= wrv;
}
}
}
progress(total, total);
return true;
}
/*bool write_unbuffered(off_t len, int from, int to) {
bool noop = true;
while (len) {
size_t llen = MIN(len, (off_t)SIZE_MAX);
ssize_t rv = sendfile(to, from, NULL, llen);
if (rv == 0) { // ???
LOG("sendfile() - 0");
return false;
} else if (rv == -1) { // don't check for EINTR etc here?
if (errno == EINVAL && noop) {
#if 0
LOG_ERRNO("switching to buffered io");
#endif
return write_buffered(len, from, to);
}
LOG_ERRNO("sendfile()");
return false;
} else {
noop = false;
len -= rv;
}
}
return true;
}*/