diff options
Diffstat (limited to 'src/cache.c')
-rw-r--r-- | src/cache.c | 38 |
1 files changed, 37 insertions, 1 deletions
diff --git a/src/cache.c b/src/cache.c index e0852f4..f158e44 100644 --- a/src/cache.c +++ b/src/cache.c @@ -2,6 +2,7 @@ /* Copyright (C) 2020-2021 Gediminas Jakutis */ +#include <unistd.h> #include <errno.h> #include <stdlib.h> #include <string.h> @@ -11,6 +12,8 @@ #include "stream.h" #include "cache.h" +static int cache_readfile(struct stream * const in); + int cache_create(struct stream * const in) { int ret = 0; @@ -48,7 +51,7 @@ int cache_populate(struct stream * const in) } } } else if (in->type == stream_in) { - try_s((ret == stream_readfile(in)), err); + try_s((ret == cache_readfile(in)), err); } else { try(1, err, EINVAL, "cannot populate a non-reading stream cache"); } @@ -247,3 +250,36 @@ int cache_rewind(struct stream * const in) return ret; } + +static int cache_readfile(struct stream * const in) +{ + ssize_t ret = 0; + size_t remaining = in->n * in->settings->stride; + ssize_t bytesread = 0; + size_t i; + + try(in->fd < 3, err, EINVAL, "no file open for reading"); + + do { + ret = read(in->fd, in->cache + bytesread, remaining); + if (ret < 0) { + try(errno != EAGAIN, err, errno, "Writing to stream failed with %zi", ret); + } else { + bytesread += ret; + remaining -= ret; + } + } while (ret); + + /* if this is a list, we need to adjust the link pointers from file offsets + * to buffer addresses. 'Cept for the last one, which needs to be NULL. + */ + if (in->settings->format == list) { + for (i = 0; i < (in->n - 1); ++i) { + in->cache_l[i].nextaddr = in->cache + in->cache_l[i].offset; + } + in->cnode = in->cache_l; + } + +err: + return ret; +} |